Houston, we have a trunk.
authorjcorgan <jcorgan@221aa14e-8319-0410-a670-987f0aec2ac5>
Thu, 3 Aug 2006 04:51:51 +0000 (04:51 +0000)
committerjcorgan <jcorgan@221aa14e-8319-0410-a670-987f0aec2ac5>
Thu, 3 Aug 2006 04:51:51 +0000 (04:51 +0000)
git-svn-id: http://gnuradio.org/svn/gnuradio/trunk@3122 221aa14e-8319-0410-a670-987f0aec2ac5

2048 files changed:
AUTHORS [new file with mode: 0644]
COPYING [new file with mode: 0644]
ChangeLog [new file with mode: 0644]
INSTALL [new file with mode: 0644]
Makefile.am [new file with mode: 0644]
Makefile.common [new file with mode: 0644]
NEWS [new file with mode: 0644]
README [new file with mode: 0644]
bootstrap [new file with mode: 0755]
config.guess [new file with mode: 0755]
config.sub [new file with mode: 0755]
config/Makefile.am [new file with mode: 0644]
config/acx_pthread.m4 [new file with mode: 0644]
config/bnv_have_qt.m4 [new file with mode: 0644]
config/cppunit.m4 [new file with mode: 0644]
config/gr_as.m4 [new file with mode: 0644]
config/gr_atsc.m4 [new file with mode: 0644]
config/gr_audio_alsa.m4 [new file with mode: 0644]
config/gr_audio_jack.m4 [new file with mode: 0644]
config/gr_audio_oss.m4 [new file with mode: 0644]
config/gr_audio_osx.m4 [new file with mode: 0644]
config/gr_audio_portaudio.m4 [new file with mode: 0644]
config/gr_audio_windows.m4 [new file with mode: 0644]
config/gr_boost.m4 [new file with mode: 0644]
config/gr_check_createfilemapping.m4 [new file with mode: 0644]
config/gr_check_mc4020.m4 [new file with mode: 0644]
config/gr_check_shm_open.m4 [new file with mode: 0644]
config/gr_check_usrp.m4 [new file with mode: 0644]
config/gr_comedi.m4 [new file with mode: 0644]
config/gr_doxygen.m4 [new file with mode: 0644]
config/gr_error_correcting_codes.m4 [new file with mode: 0644]
config/gr_fortran.m4 [new file with mode: 0644]
config/gr_gnuradio_core.m4 [new file with mode: 0644]
config/gr_gnuradio_examples.m4 [new file with mode: 0644]
config/gr_gprof.m4 [new file with mode: 0644]
config/gr_gsm_fr_vocoder.m4 [new file with mode: 0644]
config/gr_libgnuradio_core_extra_ldflags.m4 [new file with mode: 0644]
config/gr_no_undefined.m4 [new file with mode: 0644]
config/gr_omnithread.m4 [new file with mode: 0644]
config/gr_pmt.m4 [new file with mode: 0644]
config/gr_pwin32.m4 [new file with mode: 0644]
config/gr_python.m4 [new file with mode: 0644]
config/gr_radar.m4 [new file with mode: 0644]
config/gr_radio_astronomy.m4 [new file with mode: 0644]
config/gr_require_mc4020.m4 [new file with mode: 0644]
config/gr_scripting.m4 [new file with mode: 0644]
config/gr_set_md_cpu.m4 [new file with mode: 0644]
config/gr_swig.m4 [new file with mode: 0644]
config/gr_sysv_shm.m4 [new file with mode: 0644]
config/gr_usrp.m4 [new file with mode: 0644]
config/gr_video_sdl.m4 [new file with mode: 0644]
config/gr_wxgui.m4 [new file with mode: 0644]
config/gr_x86_64.m4 [new file with mode: 0644]
config/lf_cc.m4 [new file with mode: 0644]
config/lf_cxx.m4 [new file with mode: 0644]
config/lf_warnings.m4 [new file with mode: 0644]
config/lf_x11.m4 [new file with mode: 0644]
config/macosx_audiounit.m4 [new file with mode: 0644]
config/mkstemp.m4 [new file with mode: 0644]
config/onceonly.m4 [new file with mode: 0644]
config/pkg.m4 [new file with mode: 0644]
config/sdl.m4 [new file with mode: 0644]
config/usrp_fusb_tech.m4 [new file with mode: 0644]
config/usrp_libusb.m4 [new file with mode: 0644]
config/usrp_sdcc.m4 [new file with mode: 0644]
configure.ac [new file with mode: 0644]
docs/COPYING [new file with mode: 0644]
docs/ChangeLog [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/README [new file with mode: 0644]
dtools/COPYING [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/incr_release [new file with mode: 0755]
dtools/bin/make-upload [new file with mode: 0755]
dtools/bin/show_release [new file with mode: 0755]
dtools/bin/tag_release [new file with mode: 0755]
dtools/python/release_tools.py [new file with mode: 0644]
gnuradio-core/ChangeLog [new file with mode: 0644]
gnuradio-core/Makefile.am [new file with mode: 0644]
gnuradio-core/NEWS [new file with mode: 0644]
gnuradio-core/README [new file with mode: 0644]
gnuradio-core/README-win32-mingw-short.txt [new file with mode: 0644]
gnuradio-core/README.hacking [new file with mode: 0644]
gnuradio-core/THANKS [new file with mode: 0644]
gnuradio-core/TODO [new file with mode: 0644]
gnuradio-core/doc/Doxyfile.in [new file with mode: 0644]
gnuradio-core/doc/Makefile.am [new file with mode: 0644]
gnuradio-core/doc/other/Makefile.am [new file with mode: 0644]
gnuradio-core/doc/other/group_defs.dox [new file with mode: 0644]
gnuradio-core/doc/other/main_page.dox [new file with mode: 0644]
gnuradio-core/doc/other/omnithread.html [new file with mode: 0644]
gnuradio-core/doc/other/omnithread.pdf [new file with mode: 0644]
gnuradio-core/doc/other/omnithread.ps [new file with mode: 0644]
gnuradio-core/doc/other/shared_ptr_docstub.h [new file with mode: 0755]
gnuradio-core/doc/other/tv-channel-frequencies [new file with mode: 0644]
gnuradio-core/doc/other/vector_docstub.h [new file with mode: 0644]
gnuradio-core/doc/xml/Makefile.am [new file with mode: 0644]
gnuradio-core/doc/xml/README [new file with mode: 0644]
gnuradio-core/doc/xml/doxy2swig.py [new file with mode: 0644]
gnuradio-core/doc/xml/swig.xsl [new file with mode: 0644]
gnuradio-core/gnuradio-core.conf [new file with mode: 0644]
gnuradio-core/gnuradio-core.pc.in [new file with mode: 0644]
gnuradio-core/src/Makefile.am [new file with mode: 0644]
gnuradio-core/src/gen_interpolator_taps/Makefile.am [new file with mode: 0644]
gnuradio-core/src/gen_interpolator_taps/README [new file with mode: 0644]
gnuradio-core/src/gen_interpolator_taps/gen_interpolator_taps.c [new file with mode: 0644]
gnuradio-core/src/gen_interpolator_taps/objective_fct.c [new file with mode: 0644]
gnuradio-core/src/gen_interpolator_taps/praxis.f [new file with mode: 0644]
gnuradio-core/src/gen_interpolator_taps/praxis.txt [new file with mode: 0644]
gnuradio-core/src/gen_interpolator_taps/simpson.c [new file with mode: 0644]
gnuradio-core/src/gen_interpolator_taps/simpson.h [new file with mode: 0644]
gnuradio-core/src/lib/Makefile.am [new file with mode: 0644]
gnuradio-core/src/lib/bug_work_around_6.cc [new file with mode: 0644]
gnuradio-core/src/lib/filter/3dnow_float_dotprod_really_simple.S [new file with mode: 0644]
gnuradio-core/src/lib/filter/3dnow_float_dotprod_simple.S [new file with mode: 0644]
gnuradio-core/src/lib/filter/Makefile.am [new file with mode: 0644]
gnuradio-core/src/lib/filter/Makefile.gen [new file with mode: 0644]
gnuradio-core/src/lib/filter/README [new file with mode: 0644]
gnuradio-core/src/lib/filter/assembly.h [new file with mode: 0644]
gnuradio-core/src/lib/filter/ccomplex_dotprod_3dnow.S [new file with mode: 0644]
gnuradio-core/src/lib/filter/ccomplex_dotprod_3dnow64.S [new file with mode: 0644]
gnuradio-core/src/lib/filter/ccomplex_dotprod_3dnowext.S [new file with mode: 0644]
gnuradio-core/src/lib/filter/ccomplex_dotprod_3dnowext64.S [new file with mode: 0644]
gnuradio-core/src/lib/filter/ccomplex_dotprod_generic.cc [new file with mode: 0644]
gnuradio-core/src/lib/filter/ccomplex_dotprod_generic.h [new file with mode: 0644]
gnuradio-core/src/lib/filter/ccomplex_dotprod_sse.S [new file with mode: 0644]
gnuradio-core/src/lib/filter/ccomplex_dotprod_sse64.S [new file with mode: 0644]
gnuradio-core/src/lib/filter/ccomplex_dotprod_x86.h [new file with mode: 0644]
gnuradio-core/src/lib/filter/complex_dotprod_3dnow.S [new file with mode: 0644]
gnuradio-core/src/lib/filter/complex_dotprod_3dnow64.S [new file with mode: 0644]
gnuradio-core/src/lib/filter/complex_dotprod_3dnowext.S [new file with mode: 0644]
gnuradio-core/src/lib/filter/complex_dotprod_3dnowext64.S [new file with mode: 0644]
gnuradio-core/src/lib/filter/complex_dotprod_generic.cc [new file with mode: 0644]
gnuradio-core/src/lib/filter/complex_dotprod_generic.h [new file with mode: 0644]
gnuradio-core/src/lib/filter/complex_dotprod_sse.S [new file with mode: 0644]
gnuradio-core/src/lib/filter/complex_dotprod_sse64.S [new file with mode: 0644]
gnuradio-core/src/lib/filter/complex_dotprod_x86.h [new file with mode: 0644]
gnuradio-core/src/lib/filter/cpuid_x86.S [new file with mode: 0644]
gnuradio-core/src/lib/filter/cpuid_x86_64.S [new file with mode: 0644]
gnuradio-core/src/lib/filter/fcomplex_dotprod_3dnow.S [new file with mode: 0644]
gnuradio-core/src/lib/filter/fcomplex_dotprod_3dnow64.S [new file with mode: 0644]
gnuradio-core/src/lib/filter/fcomplex_dotprod_sse.S [new file with mode: 0644]
gnuradio-core/src/lib/filter/fcomplex_dotprod_sse64.S [new file with mode: 0644]
gnuradio-core/src/lib/filter/fcomplex_dotprod_x86.h [new file with mode: 0644]
gnuradio-core/src/lib/filter/filter.i [new file with mode: 0644]
gnuradio-core/src/lib/filter/float_dotprod_3dnow.S [new file with mode: 0644]
gnuradio-core/src/lib/filter/float_dotprod_3dnow64.S [new file with mode: 0644]
gnuradio-core/src/lib/filter/float_dotprod_generic.c [new file with mode: 0644]
gnuradio-core/src/lib/filter/float_dotprod_generic.h [new file with mode: 0644]
gnuradio-core/src/lib/filter/float_dotprod_sse.S [new file with mode: 0644]
gnuradio-core/src/lib/filter/float_dotprod_sse64.S [new file with mode: 0644]
gnuradio-core/src/lib/filter/float_dotprod_x86.h [new file with mode: 0644]
gnuradio-core/src/lib/filter/generate_all.py [new file with mode: 0755]
gnuradio-core/src/lib/filter/generate_gr_fir_XXX.py [new file with mode: 0755]
gnuradio-core/src/lib/filter/generate_gr_fir_filter_XXX.py [new file with mode: 0755]
gnuradio-core/src/lib/filter/generate_gr_fir_sysconfig.py [new file with mode: 0755]
gnuradio-core/src/lib/filter/generate_gr_fir_sysconfig_generic.py [new file with mode: 0755]
gnuradio-core/src/lib/filter/generate_gr_fir_util.py [new file with mode: 0755]
gnuradio-core/src/lib/filter/generate_gr_freq_xlating_fir_filter_XXX.py [new file with mode: 0755]
gnuradio-core/src/lib/filter/generate_gr_interp_fir_filter_XXX.py [new file with mode: 0644]
gnuradio-core/src/lib/filter/generate_gr_rational_resampler_base_XXX.py [new file with mode: 0644]
gnuradio-core/src/lib/filter/generate_utils.py [new file with mode: 0644]
gnuradio-core/src/lib/filter/gr_adaptive_fir_ccf.cc [new file with mode: 0644]
gnuradio-core/src/lib/filter/gr_adaptive_fir_ccf.h [new file with mode: 0644]
gnuradio-core/src/lib/filter/gr_adaptive_fir_ccf.i [new file with mode: 0644]
gnuradio-core/src/lib/filter/gr_cma_equalizer_cc.cc [new file with mode: 0644]
gnuradio-core/src/lib/filter/gr_cma_equalizer_cc.h [new file with mode: 0644]
gnuradio-core/src/lib/filter/gr_cma_equalizer_cc.i [new file with mode: 0644]
gnuradio-core/src/lib/filter/gr_cpu.cc [new file with mode: 0644]
gnuradio-core/src/lib/filter/gr_cpu.h [new file with mode: 0644]
gnuradio-core/src/lib/filter/gr_fft_filter_ccc.cc [new file with mode: 0644]
gnuradio-core/src/lib/filter/gr_fft_filter_ccc.h [new file with mode: 0644]
gnuradio-core/src/lib/filter/gr_fft_filter_ccc.i [new file with mode: 0644]
gnuradio-core/src/lib/filter/gr_fft_filter_fff.cc [new file with mode: 0644]
gnuradio-core/src/lib/filter/gr_fft_filter_fff.h [new file with mode: 0644]
gnuradio-core/src/lib/filter/gr_fft_filter_fff.i [new file with mode: 0644]
gnuradio-core/src/lib/filter/gr_filter_delay_fc.cc [new file with mode: 0644]
gnuradio-core/src/lib/filter/gr_filter_delay_fc.h [new file with mode: 0644]
gnuradio-core/src/lib/filter/gr_filter_delay_fc.i [new file with mode: 0644]
gnuradio-core/src/lib/filter/gr_fir_XXX.cc.t [new file with mode: 0644]
gnuradio-core/src/lib/filter/gr_fir_XXX.h.t [new file with mode: 0644]
gnuradio-core/src/lib/filter/gr_fir_XXX_generic.cc.t [new file with mode: 0644]
gnuradio-core/src/lib/filter/gr_fir_XXX_generic.h.t [new file with mode: 0644]
gnuradio-core/src/lib/filter/gr_fir_ccc_simd.cc [new file with mode: 0644]
gnuradio-core/src/lib/filter/gr_fir_ccc_simd.h [new file with mode: 0644]
gnuradio-core/src/lib/filter/gr_fir_ccc_x86.cc [new file with mode: 0644]
gnuradio-core/src/lib/filter/gr_fir_ccc_x86.h [new file with mode: 0644]
gnuradio-core/src/lib/filter/gr_fir_ccf_simd.cc [new file with mode: 0644]
gnuradio-core/src/lib/filter/gr_fir_ccf_simd.h [new file with mode: 0644]
gnuradio-core/src/lib/filter/gr_fir_ccf_x86.cc [new file with mode: 0644]
gnuradio-core/src/lib/filter/gr_fir_ccf_x86.h [new file with mode: 0644]
gnuradio-core/src/lib/filter/gr_fir_fcc_simd.cc [new file with mode: 0644]
gnuradio-core/src/lib/filter/gr_fir_fcc_simd.h [new file with mode: 0644]
gnuradio-core/src/lib/filter/gr_fir_fcc_x86.cc [new file with mode: 0644]
gnuradio-core/src/lib/filter/gr_fir_fcc_x86.h [new file with mode: 0644]
gnuradio-core/src/lib/filter/gr_fir_fff_simd.cc [new file with mode: 0644]
gnuradio-core/src/lib/filter/gr_fir_fff_simd.h [new file with mode: 0644]
gnuradio-core/src/lib/filter/gr_fir_fff_x86.cc [new file with mode: 0644]
gnuradio-core/src/lib/filter/gr_fir_fff_x86.h [new file with mode: 0644]
gnuradio-core/src/lib/filter/gr_fir_filter_XXX.cc.t [new file with mode: 0644]
gnuradio-core/src/lib/filter/gr_fir_filter_XXX.h.t [new file with mode: 0644]
gnuradio-core/src/lib/filter/gr_fir_filter_XXX.i.t [new file with mode: 0644]
gnuradio-core/src/lib/filter/gr_fir_fsf_simd.cc [new file with mode: 0644]
gnuradio-core/src/lib/filter/gr_fir_fsf_simd.h [new file with mode: 0644]
gnuradio-core/src/lib/filter/gr_fir_fsf_x86.cc [new file with mode: 0644]
gnuradio-core/src/lib/filter/gr_fir_fsf_x86.h [new file with mode: 0644]
gnuradio-core/src/lib/filter/gr_fir_scc_simd.cc [new file with mode: 0644]
gnuradio-core/src/lib/filter/gr_fir_scc_simd.h [new file with mode: 0644]
gnuradio-core/src/lib/filter/gr_fir_scc_x86.cc [new file with mode: 0644]
gnuradio-core/src/lib/filter/gr_fir_scc_x86.h [new file with mode: 0644]
gnuradio-core/src/lib/filter/gr_fir_sysconfig_x86.cc [new file with mode: 0644]
gnuradio-core/src/lib/filter/gr_fir_sysconfig_x86.h [new file with mode: 0644]
gnuradio-core/src/lib/filter/gr_fractional_interpolator.cc [new file with mode: 0644]
gnuradio-core/src/lib/filter/gr_fractional_interpolator.h [new file with mode: 0644]
gnuradio-core/src/lib/filter/gr_freq_xlating_fir_filter_XXX.cc.t [new file with mode: 0644]
gnuradio-core/src/lib/filter/gr_freq_xlating_fir_filter_XXX.h.t [new file with mode: 0644]
gnuradio-core/src/lib/filter/gr_freq_xlating_fir_filter_XXX.i.t [new file with mode: 0644]
gnuradio-core/src/lib/filter/gr_goertzel_fc.cc [new file with mode: 0644]
gnuradio-core/src/lib/filter/gr_goertzel_fc.h [new file with mode: 0644]
gnuradio-core/src/lib/filter/gr_goertzel_fc.i [new file with mode: 0644]
gnuradio-core/src/lib/filter/gr_hilbert_fc.cc [new file with mode: 0644]
gnuradio-core/src/lib/filter/gr_hilbert_fc.h [new file with mode: 0644]
gnuradio-core/src/lib/filter/gr_hilbert_fc.i [new file with mode: 0644]
gnuradio-core/src/lib/filter/gr_iir_filter_ffd.cc [new file with mode: 0644]
gnuradio-core/src/lib/filter/gr_iir_filter_ffd.h [new file with mode: 0644]
gnuradio-core/src/lib/filter/gr_iir_filter_ffd.i [new file with mode: 0644]
gnuradio-core/src/lib/filter/gr_interp_fir_filter_XXX.cc.t [new file with mode: 0644]
gnuradio-core/src/lib/filter/gr_interp_fir_filter_XXX.h.t [new file with mode: 0644]
gnuradio-core/src/lib/filter/gr_interp_fir_filter_XXX.i.t [new file with mode: 0644]
gnuradio-core/src/lib/filter/gr_rational_resampler_base_XXX.cc.t [new file with mode: 0644]
gnuradio-core/src/lib/filter/gr_rational_resampler_base_XXX.h.t [new file with mode: 0644]
gnuradio-core/src/lib/filter/gr_rational_resampler_base_XXX.i.t [new file with mode: 0644]
gnuradio-core/src/lib/filter/gr_rotator.h [new file with mode: 0644]
gnuradio-core/src/lib/filter/gr_sincos.c [new file with mode: 0644]
gnuradio-core/src/lib/filter/gr_sincos.h [new file with mode: 0644]
gnuradio-core/src/lib/filter/gr_single_pole_avg.h [new file with mode: 0644]
gnuradio-core/src/lib/filter/gr_single_pole_avg_filter_ff.cc [new file with mode: 0644]
gnuradio-core/src/lib/filter/gr_single_pole_avg_filter_ff.h [new file with mode: 0644]
gnuradio-core/src/lib/filter/gr_single_pole_avg_filter_ff.i [new file with mode: 0644]
gnuradio-core/src/lib/filter/gr_single_pole_iir.h [new file with mode: 0644]
gnuradio-core/src/lib/filter/gr_single_pole_iir_filter_cc.cc [new file with mode: 0644]
gnuradio-core/src/lib/filter/gr_single_pole_iir_filter_cc.h [new file with mode: 0644]
gnuradio-core/src/lib/filter/gr_single_pole_iir_filter_cc.i [new file with mode: 0644]
gnuradio-core/src/lib/filter/gr_single_pole_iir_filter_ff.cc [new file with mode: 0644]
gnuradio-core/src/lib/filter/gr_single_pole_iir_filter_ff.h [new file with mode: 0644]
gnuradio-core/src/lib/filter/gr_single_pole_iir_filter_ff.i [new file with mode: 0644]
gnuradio-core/src/lib/filter/gr_single_pole_rec.h [new file with mode: 0644]
gnuradio-core/src/lib/filter/gr_single_pole_rec_filter_ff.cc [new file with mode: 0644]
gnuradio-core/src/lib/filter/gr_single_pole_rec_filter_ff.h [new file with mode: 0644]
gnuradio-core/src/lib/filter/gr_single_pole_rec_filter_ff.i [new file with mode: 0644]
gnuradio-core/src/lib/filter/gr_single_zero_avg.h [new file with mode: 0644]
gnuradio-core/src/lib/filter/gr_single_zero_avg_filter_ff.cc [new file with mode: 0644]
gnuradio-core/src/lib/filter/gr_single_zero_avg_filter_ff.h [new file with mode: 0644]
gnuradio-core/src/lib/filter/gr_single_zero_avg_filter_ff.i [new file with mode: 0644]
gnuradio-core/src/lib/filter/gr_single_zero_rec.h [new file with mode: 0644]
gnuradio-core/src/lib/filter/gr_single_zero_rec_filter_ff.cc [new file with mode: 0644]
gnuradio-core/src/lib/filter/gr_single_zero_rec_filter_ff.h [new file with mode: 0644]
gnuradio-core/src/lib/filter/gr_single_zero_rec_filter_ff.i [new file with mode: 0644]
gnuradio-core/src/lib/filter/gri_goertzel.cc [new file with mode: 0644]
gnuradio-core/src/lib/filter/gri_goertzel.h [new file with mode: 0644]
gnuradio-core/src/lib/filter/gri_iir.h [new file with mode: 0644]
gnuradio-core/src/lib/filter/gri_mmse_fir_interpolator.cc [new file with mode: 0644]
gnuradio-core/src/lib/filter/gri_mmse_fir_interpolator.h [new file with mode: 0644]
gnuradio-core/src/lib/filter/gri_mmse_fir_interpolator_cc.cc [new file with mode: 0644]
gnuradio-core/src/lib/filter/gri_mmse_fir_interpolator_cc.h [new file with mode: 0644]
gnuradio-core/src/lib/filter/interpolator_taps.h [new file with mode: 0644]
gnuradio-core/src/lib/filter/qa_ccomplex_dotprod_x86.cc [new file with mode: 0644]
gnuradio-core/src/lib/filter/qa_ccomplex_dotprod_x86.h [new file with mode: 0644]
gnuradio-core/src/lib/filter/qa_complex_dotprod_x86.cc [new file with mode: 0644]
gnuradio-core/src/lib/filter/qa_complex_dotprod_x86.h [new file with mode: 0644]
gnuradio-core/src/lib/filter/qa_dotprod.h [new file with mode: 0644]
gnuradio-core/src/lib/filter/qa_dotprod_generic.cc [new file with mode: 0644]
gnuradio-core/src/lib/filter/qa_dotprod_x86.cc [new file with mode: 0644]
gnuradio-core/src/lib/filter/qa_filter.cc [new file with mode: 0644]
gnuradio-core/src/lib/filter/qa_filter.h [new file with mode: 0644]
gnuradio-core/src/lib/filter/qa_float_dotprod_x86.cc [new file with mode: 0644]
gnuradio-core/src/lib/filter/qa_float_dotprod_x86.h [new file with mode: 0644]
gnuradio-core/src/lib/filter/qa_gr_fir_ccc.cc [new file with mode: 0644]
gnuradio-core/src/lib/filter/qa_gr_fir_ccc.h [new file with mode: 0644]
gnuradio-core/src/lib/filter/qa_gr_fir_ccf.cc [new file with mode: 0644]
gnuradio-core/src/lib/filter/qa_gr_fir_ccf.h [new file with mode: 0644]
gnuradio-core/src/lib/filter/qa_gr_fir_fcc.cc [new file with mode: 0644]
gnuradio-core/src/lib/filter/qa_gr_fir_fcc.h [new file with mode: 0644]
gnuradio-core/src/lib/filter/qa_gr_fir_fff.cc [new file with mode: 0644]
gnuradio-core/src/lib/filter/qa_gr_fir_fff.h [new file with mode: 0644]
gnuradio-core/src/lib/filter/qa_gr_fir_scc.cc [new file with mode: 0644]
gnuradio-core/src/lib/filter/qa_gr_fir_scc.h [new file with mode: 0644]
gnuradio-core/src/lib/filter/qa_gri_mmse_fir_interpolator.cc [new file with mode: 0644]
gnuradio-core/src/lib/filter/qa_gri_mmse_fir_interpolator.h [new file with mode: 0644]
gnuradio-core/src/lib/filter/short_dotprod_generic.c [new file with mode: 0644]
gnuradio-core/src/lib/filter/short_dotprod_generic.h [new file with mode: 0644]
gnuradio-core/src/lib/filter/short_dotprod_mmx.S [new file with mode: 0644]
gnuradio-core/src/lib/filter/short_dotprod_mmx64.S [new file with mode: 0644]
gnuradio-core/src/lib/filter/short_dotprod_x86.h [new file with mode: 0644]
gnuradio-core/src/lib/filter/sse_debug.c [new file with mode: 0644]
gnuradio-core/src/lib/filter/sse_debug.h [new file with mode: 0644]
gnuradio-core/src/lib/filter/sysconfig_generic.cc [new file with mode: 0644]
gnuradio-core/src/lib/filter/sysconfig_x86.cc [new file with mode: 0644]
gnuradio-core/src/lib/g72x/Makefile.am [new file with mode: 0644]
gnuradio-core/src/lib/g72x/README [new file with mode: 0644]
gnuradio-core/src/lib/g72x/decode.c [new file with mode: 0644]
gnuradio-core/src/lib/g72x/encode.c [new file with mode: 0644]
gnuradio-core/src/lib/g72x/g711.c [new file with mode: 0644]
gnuradio-core/src/lib/g72x/g721.c [new file with mode: 0644]
gnuradio-core/src/lib/g72x/g723_24.c [new file with mode: 0644]
gnuradio-core/src/lib/g72x/g723_40.c [new file with mode: 0644]
gnuradio-core/src/lib/g72x/g72x.c [new file with mode: 0644]
gnuradio-core/src/lib/g72x/g72x.h [new file with mode: 0644]
gnuradio-core/src/lib/general/Makefile.am [new file with mode: 0644]
gnuradio-core/src/lib/general/Makefile.gen [new file with mode: 0644]
gnuradio-core/src/lib/general/README [new file with mode: 0644]
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/gen_sine_table.py [new file with mode: 0755]
gnuradio-core/src/lib/general/general.i [new file with mode: 0644]
gnuradio-core/src/lib/general/general_generated.i [new file with mode: 0644]
gnuradio-core/src/lib/general/generate_all.py [new file with mode: 0755]
gnuradio-core/src/lib/general/generate_common.py [new file with mode: 0755]
gnuradio-core/src/lib/general/gr_add_XX.cc.t [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_add_XX.h.t [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_add_XX.i.t [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_add_const_XX.cc.t [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_add_const_XX.h.t [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_add_const_XX.i.t [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_add_const_vXX.cc.t [new file with mode: 0755]
gnuradio-core/src/lib/general/gr_add_const_vXX.h.t [new file with mode: 0755]
gnuradio-core/src/lib/general/gr_add_const_vXX.i.t [new file with mode: 0755]
gnuradio-core/src/lib/general/gr_add_vXX.cc.t [new file with mode: 0755]
gnuradio-core/src/lib/general/gr_add_vXX.h.t [new file with mode: 0755]
gnuradio-core/src/lib/general/gr_add_vXX.i.t [new file with mode: 0755]
gnuradio-core/src/lib/general/gr_agc_cc.cc [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_agc_cc.h [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_agc_cc.i [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_agc_ff.cc [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_agc_ff.h [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_agc_ff.i [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_align_on_samplenumbers_ss.cc [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_align_on_samplenumbers_ss.h [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_align_on_samplenumbers_ss.i [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_binary_slicer_fb.cc [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_binary_slicer_fb.h [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_binary_slicer_fb.i [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_bytes_to_syms.cc [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_bytes_to_syms.h [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_bytes_to_syms.i [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_char_to_float.cc [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_char_to_float.h [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_char_to_float.i [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_check_counting_s.cc [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_check_counting_s.h [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_check_counting_s.i [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_check_lfsr_32k_s.cc [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_check_lfsr_32k_s.h [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_check_lfsr_32k_s.i [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_chunks_to_symbols_XX.cc.t [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_chunks_to_symbols_XX.h.t [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_chunks_to_symbols_XX.i.t [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_circular_file.cc [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_circular_file.h [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_clock_recovery_mm_cc.cc [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_clock_recovery_mm_cc.h [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_clock_recovery_mm_cc.i [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_clock_recovery_mm_ff.cc [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_clock_recovery_mm_ff.h [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_clock_recovery_mm_ff.i [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_complex_to_interleaved_short.cc [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_complex_to_interleaved_short.h [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_complex_to_interleaved_short.i [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_complex_to_xxx.cc [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_complex_to_xxx.h [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_complex_to_xxx.i [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_conjugate_cc.cc [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_conjugate_cc.h [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_conjugate_cc.i [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_constellation_decoder_cb.cc [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_constellation_decoder_cb.h [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_constellation_decoder_cb.i [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_correlate_access_code_bb.cc [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_correlate_access_code_bb.h [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_correlate_access_code_bb.i [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_costas_loop_cc.cc [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_costas_loop_cc.h [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_costas_loop_cc.i [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_count_bits.cc [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_count_bits.h [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_crc32.cc [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_crc32.h [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_crc32.i [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_ctcss_squelch_ff.cc [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_ctcss_squelch_ff.h [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_ctcss_squelch_ff.i [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_dd_mpsk_sync_cc.cc [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_dd_mpsk_sync_cc.h [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_dd_mpsk_sync_cc.i [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_deinterleave.cc [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_deinterleave.h [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_deinterleave.i [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_diff_decoder_bb.cc [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_diff_decoder_bb.h [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_diff_decoder_bb.i [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_diff_encoder_bb.cc [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_diff_encoder_bb.h [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_diff_encoder_bb.i [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_diff_phasor_cc.cc [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_diff_phasor_cc.h [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_diff_phasor_cc.i [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_divide_XX.cc.t [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_divide_XX.h.t [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_divide_XX.i.t [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_endianness.h [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_endianness.i [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_expj.h [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_fake_channel_coder_pp.cc [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_fake_channel_coder_pp.h [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_fake_channel_coder_pp.i [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_fast_atan2f.cc [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_feval.cc [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_feval.h [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_feval.i [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_fft_vcc.cc [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_fft_vcc.h [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_fft_vcc.i [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_fft_vfc.cc [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_fft_vfc.h [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_fft_vfc.i [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_firdes.cc [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_firdes.h [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_firdes.i [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_float_to_char.cc [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_float_to_char.h [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_float_to_char.i [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_float_to_complex.cc [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_float_to_complex.h [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_float_to_complex.i [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_float_to_short.cc [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_float_to_short.h [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_float_to_short.i [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_float_to_uchar.cc [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_float_to_uchar.h [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_float_to_uchar.i [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_framer_sink_1.cc [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_framer_sink_1.h [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_framer_sink_1.i [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_frequency_modulator_fc.cc [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_frequency_modulator_fc.h [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_frequency_modulator_fc.i [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_fxpt.cc [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_fxpt.h [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_fxpt_nco.h [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_fxpt_vco.h [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_head.cc [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_head.h [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_head.i [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_interleave.cc [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_interleave.h [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_interleave.i [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_interleaved_short_to_complex.cc [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_interleaved_short_to_complex.h [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_interleaved_short_to_complex.i [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_keep_one_in_n.cc [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_keep_one_in_n.h [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_keep_one_in_n.i [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_kludge_copy.cc [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_kludge_copy.h [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_kludge_copy.i [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_lfsr_32k_source_s.cc [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_lfsr_32k_source_s.h [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_lfsr_32k_source_s.i [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_lms_dfe_cc.cc [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_lms_dfe_cc.h [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_lms_dfe_cc.i [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_lms_dfe_ff.cc [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_lms_dfe_ff.h [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_lms_dfe_ff.i [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_log2_const.h [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_map_bb.cc [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_map_bb.h [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_map_bb.i [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_math.cc [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_math.h [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_misc.cc [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_misc.h [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_multiply_XX.cc.t [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_multiply_XX.h.t [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_multiply_XX.i.t [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_multiply_const_XX.cc.t [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_multiply_const_XX.h.t [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_multiply_const_XX.i.t [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_multiply_const_vXX.cc.t [new file with mode: 0755]
gnuradio-core/src/lib/general/gr_multiply_const_vXX.h.t [new file with mode: 0755]
gnuradio-core/src/lib/general/gr_multiply_const_vXX.i.t [new file with mode: 0755]
gnuradio-core/src/lib/general/gr_multiply_vXX.cc.t [new file with mode: 0755]
gnuradio-core/src/lib/general/gr_multiply_vXX.h.t [new file with mode: 0755]
gnuradio-core/src/lib/general/gr_multiply_vXX.i.t [new file with mode: 0755]
gnuradio-core/src/lib/general/gr_mute_XX.cc.t [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_mute_XX.h.t [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_mute_XX.i.t [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_nco.h [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_nlog10_ff.cc [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_nlog10_ff.h [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_nlog10_ff.i [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_noise_source_X.cc.t [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_noise_source_X.h.t [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_noise_source_X.i.t [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_noise_type.h [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_nop.cc [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_nop.h [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_nop.i [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_null_sink.cc [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_null_sink.h [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_null_sink.i [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_null_source.cc [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_null_source.h [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_null_source.i [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_pa_2x2_phase_combiner.cc [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_pa_2x2_phase_combiner.h [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_pa_2x2_phase_combiner.i [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_packed_to_unpacked_XX.cc.t [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_packed_to_unpacked_XX.h.t [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_packed_to_unpacked_XX.i.t [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_packet_sink.cc [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_packet_sink.h [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_packet_sink.i [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_phase_modulator_fc.cc [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_phase_modulator_fc.h [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_phase_modulator_fc.i [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_pll_carriertracking_cc.cc [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_pll_carriertracking_cc.h [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_pll_carriertracking_cc.i [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_pll_freqdet_cf.cc [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_pll_freqdet_cf.h [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_pll_freqdet_cf.i [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_pll_refout_cc.cc [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_pll_refout_cc.h [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_pll_refout_cc.i [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_prefix.cc.in [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_prefix.h [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_prefix.i [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_prefs.cc [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_prefs.h [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_prefs.i [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_probe_avg_mag_sqrd_c.cc [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_probe_avg_mag_sqrd_c.h [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_probe_avg_mag_sqrd_c.i [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_probe_avg_mag_sqrd_f.cc [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_probe_avg_mag_sqrd_f.h [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_probe_avg_mag_sqrd_f.i [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_probe_signal_f.cc [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_probe_signal_f.h [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_probe_signal_f.i [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_pwr_squelch_cc.cc [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_pwr_squelch_cc.h [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_pwr_squelch_cc.i [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_pwr_squelch_ff.cc [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_pwr_squelch_ff.h [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_pwr_squelch_ff.i [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_quadrature_demod_cf.cc [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_quadrature_demod_cf.h [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_quadrature_demod_cf.i [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_random.cc [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_random.h [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_remez.cc [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_remez.h [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_remez.i [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_reverse.cc [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_reverse.h [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_rms_cf.cc [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_rms_cf.h [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_rms_cf.i [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_rms_ff.cc [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_rms_ff.h [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_rms_ff.i [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_short_to_float.cc [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_short_to_float.h [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_short_to_float.i [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_sig_source_X.cc.t [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_sig_source_X.h.t [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_sig_source_X.i.t [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_sig_source_waveform.h [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_simple_correlator.cc [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_simple_correlator.h [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_simple_correlator.i [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_simple_framer.cc [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_simple_framer.h [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_simple_framer.i [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_simple_framer_sync.h [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_simple_squelch_cc.cc [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_simple_squelch_cc.h [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_simple_squelch_cc.i [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_skiphead.cc [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_skiphead.h [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_skiphead.i [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_squelch_base_cc.cc [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_squelch_base_cc.h [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_squelch_base_cc.i [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_squelch_base_ff.cc [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_squelch_base_ff.h [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_squelch_base_ff.i [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_stream_to_streams.cc [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_stream_to_streams.h [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_stream_to_streams.i [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_stream_to_vector.cc [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_stream_to_vector.h [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_stream_to_vector.i [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_streams_to_stream.cc [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_streams_to_stream.h [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_streams_to_stream.i [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_streams_to_vector.cc [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_streams_to_vector.h [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_streams_to_vector.i [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_sub_XX.cc.t [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_sub_XX.h.t [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_sub_XX.i.t [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_sync_block.cc [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_sync_block.h [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_sync_block.i [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_sync_decimator.cc [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_sync_decimator.h [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_sync_decimator.i [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_sync_interpolator.cc [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_sync_interpolator.h [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_sync_interpolator.i [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_test.cc [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_test.h [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_test.i [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_test_types.h [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_threshold_ff.cc [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_threshold_ff.h [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_threshold_ff.i [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_throttle.cc [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_throttle.h [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_throttle.i [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_uchar_to_float.cc [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_uchar_to_float.h [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_uchar_to_float.i [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_unpack_k_bits_bb.cc [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_unpack_k_bits_bb.h [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_unpack_k_bits_bb.i [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_unpacked_to_packed_XX.cc.t [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_unpacked_to_packed_XX.h.t [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_unpacked_to_packed_XX.i.t [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_vco.h [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_vco_f.cc [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_vco_f.h [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_vco_f.i [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_vector_sink_X.cc.t [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_vector_sink_X.h.t [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_vector_sink_X.i.t [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_vector_source_X.cc.t [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_vector_source_X.h.t [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_vector_source_X.i.t [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_vector_to_stream.cc [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_vector_to_stream.h [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_vector_to_stream.i [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_vector_to_streams.cc [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_vector_to_streams.h [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_vector_to_streams.i [new file with mode: 0644]
gnuradio-core/src/lib/general/gri_add_const_ss.h [new file with mode: 0644]
gnuradio-core/src/lib/general/gri_add_const_ss_generic.cc [new file with mode: 0644]
gnuradio-core/src/lib/general/gri_agc.h [new file with mode: 0644]
gnuradio-core/src/lib/general/gri_agc.i [new file with mode: 0644]
gnuradio-core/src/lib/general/gri_agc_cc.h [new file with mode: 0644]
gnuradio-core/src/lib/general/gri_agc_cc.i [new file with mode: 0644]
gnuradio-core/src/lib/general/gri_char_to_float.cc [new file with mode: 0644]
gnuradio-core/src/lib/general/gri_char_to_float.h [new file with mode: 0644]
gnuradio-core/src/lib/general/gri_debugger_hook.cc [new file with mode: 0644]
gnuradio-core/src/lib/general/gri_debugger_hook.h [new file with mode: 0644]
gnuradio-core/src/lib/general/gri_fft.cc [new file with mode: 0644]
gnuradio-core/src/lib/general/gri_fft.h [new file with mode: 0644]
gnuradio-core/src/lib/general/gri_float_to_char.cc [new file with mode: 0644]
gnuradio-core/src/lib/general/gri_float_to_char.h [new file with mode: 0644]
gnuradio-core/src/lib/general/gri_float_to_short.cc [new file with mode: 0644]
gnuradio-core/src/lib/general/gri_float_to_short.h [new file with mode: 0644]
gnuradio-core/src/lib/general/gri_float_to_uchar.cc [new file with mode: 0644]
gnuradio-core/src/lib/general/gri_float_to_uchar.h [new file with mode: 0644]
gnuradio-core/src/lib/general/gri_interleaved_short_to_complex.cc [new file with mode: 0644]
gnuradio-core/src/lib/general/gri_interleaved_short_to_complex.h [new file with mode: 0644]
gnuradio-core/src/lib/general/gri_lfsr_15_1_0.h [new file with mode: 0644]
gnuradio-core/src/lib/general/gri_lfsr_32k.h [new file with mode: 0644]
gnuradio-core/src/lib/general/gri_short_to_float.cc [new file with mode: 0644]
gnuradio-core/src/lib/general/gri_short_to_float.h [new file with mode: 0644]
gnuradio-core/src/lib/general/gri_uchar_to_float.cc [new file with mode: 0644]
gnuradio-core/src/lib/general/gri_uchar_to_float.h [new file with mode: 0644]
gnuradio-core/src/lib/general/malloc16.c [new file with mode: 0644]
gnuradio-core/src/lib/general/malloc16.h [new file with mode: 0644]
gnuradio-core/src/lib/general/qa_general.cc [new file with mode: 0644]
gnuradio-core/src/lib/general/qa_general.h [new file with mode: 0644]
gnuradio-core/src/lib/general/qa_gr_circular_file.cc [new file with mode: 0644]
gnuradio-core/src/lib/general/qa_gr_circular_file.h [new file with mode: 0644]
gnuradio-core/src/lib/general/qa_gr_firdes.cc [new file with mode: 0644]
gnuradio-core/src/lib/general/qa_gr_firdes.h [new file with mode: 0644]
gnuradio-core/src/lib/general/qa_gr_fxpt.cc [new file with mode: 0644]
gnuradio-core/src/lib/general/qa_gr_fxpt.h [new file with mode: 0644]
gnuradio-core/src/lib/general/qa_gr_fxpt_nco.cc [new file with mode: 0644]
gnuradio-core/src/lib/general/qa_gr_fxpt_nco.h [new file with mode: 0644]
gnuradio-core/src/lib/general/qa_gr_fxpt_vco.cc [new file with mode: 0644]
gnuradio-core/src/lib/general/qa_gr_fxpt_vco.h [new file with mode: 0644]
gnuradio-core/src/lib/general/random.h [new file with mode: 0644]
gnuradio-core/src/lib/general/sine_table.h [new file with mode: 0644]
gnuradio-core/src/lib/io/Makefile.am [new file with mode: 0644]
gnuradio-core/src/lib/io/gr_file_descriptor_sink.cc [new file with mode: 0644]
gnuradio-core/src/lib/io/gr_file_descriptor_sink.h [new file with mode: 0644]
gnuradio-core/src/lib/io/gr_file_descriptor_sink.i [new file with mode: 0644]
gnuradio-core/src/lib/io/gr_file_descriptor_source.cc [new file with mode: 0644]
gnuradio-core/src/lib/io/gr_file_descriptor_source.h [new file with mode: 0644]
gnuradio-core/src/lib/io/gr_file_descriptor_source.i [new file with mode: 0644]
gnuradio-core/src/lib/io/gr_file_sink.cc [new file with mode: 0644]
gnuradio-core/src/lib/io/gr_file_sink.h [new file with mode: 0644]
gnuradio-core/src/lib/io/gr_file_sink.i [new file with mode: 0644]
gnuradio-core/src/lib/io/gr_file_source.cc [new file with mode: 0644]
gnuradio-core/src/lib/io/gr_file_source.h [new file with mode: 0644]
gnuradio-core/src/lib/io/gr_file_source.i [new file with mode: 0644]
gnuradio-core/src/lib/io/gr_message_sink.cc [new file with mode: 0644]
gnuradio-core/src/lib/io/gr_message_sink.h [new file with mode: 0644]
gnuradio-core/src/lib/io/gr_message_sink.i [new file with mode: 0644]
gnuradio-core/src/lib/io/gr_message_source.cc [new file with mode: 0644]
gnuradio-core/src/lib/io/gr_message_source.h [new file with mode: 0644]
gnuradio-core/src/lib/io/gr_message_source.i [new file with mode: 0644]
gnuradio-core/src/lib/io/gr_oscope_guts.cc [new file with mode: 0644]
gnuradio-core/src/lib/io/gr_oscope_guts.h [new file with mode: 0644]
gnuradio-core/src/lib/io/gr_oscope_sink.i [new file with mode: 0644]
gnuradio-core/src/lib/io/gr_oscope_sink_f.cc [new file with mode: 0644]
gnuradio-core/src/lib/io/gr_oscope_sink_f.h [new file with mode: 0644]
gnuradio-core/src/lib/io/gr_oscope_sink_x.cc [new file with mode: 0644]
gnuradio-core/src/lib/io/gr_oscope_sink_x.h [new file with mode: 0644]
gnuradio-core/src/lib/io/gr_trigger_mode.h [new file with mode: 0644]
gnuradio-core/src/lib/io/gri_logger.cc [new file with mode: 0644]
gnuradio-core/src/lib/io/gri_logger.h [new file with mode: 0644]
gnuradio-core/src/lib/io/i2c.cc [new file with mode: 0644]
gnuradio-core/src/lib/io/i2c.h [new file with mode: 0644]
gnuradio-core/src/lib/io/i2c_bbio.cc [new file with mode: 0644]
gnuradio-core/src/lib/io/i2c_bbio.h [new file with mode: 0644]
gnuradio-core/src/lib/io/i2c_bbio_pp.cc [new file with mode: 0644]
gnuradio-core/src/lib/io/i2c_bbio_pp.h [new file with mode: 0644]
gnuradio-core/src/lib/io/i2c_bitbang.cc [new file with mode: 0644]
gnuradio-core/src/lib/io/i2c_bitbang.h [new file with mode: 0644]
gnuradio-core/src/lib/io/io.i [new file with mode: 0644]
gnuradio-core/src/lib/io/microtune_4702.cc [new file with mode: 0644]
gnuradio-core/src/lib/io/microtune_4702.h [new file with mode: 0644]
gnuradio-core/src/lib/io/microtune_4702_eval_board.cc [new file with mode: 0644]
gnuradio-core/src/lib/io/microtune_4702_eval_board.h [new file with mode: 0644]
gnuradio-core/src/lib/io/microtune_4702_eval_board.i [new file with mode: 0644]
gnuradio-core/src/lib/io/microtune_4937.cc [new file with mode: 0644]
gnuradio-core/src/lib/io/microtune_4937.h [new file with mode: 0644]
gnuradio-core/src/lib/io/microtune_4937_eval_board.cc [new file with mode: 0644]
gnuradio-core/src/lib/io/microtune_4937_eval_board.h [new file with mode: 0644]
gnuradio-core/src/lib/io/microtune_4937_eval_board.i [new file with mode: 0644]
gnuradio-core/src/lib/io/microtune_eval_board.i [new file with mode: 0644]
gnuradio-core/src/lib/io/microtune_eval_board_defs.h [new file with mode: 0644]
gnuradio-core/src/lib/io/microtune_xxxx.cc [new file with mode: 0644]
gnuradio-core/src/lib/io/microtune_xxxx.h [new file with mode: 0644]
gnuradio-core/src/lib/io/microtune_xxxx_eval_board.cc [new file with mode: 0644]
gnuradio-core/src/lib/io/microtune_xxxx_eval_board.h [new file with mode: 0644]
gnuradio-core/src/lib/io/microtune_xxxx_eval_board.i [new file with mode: 0644]
gnuradio-core/src/lib/io/ppio.cc [new file with mode: 0644]
gnuradio-core/src/lib/io/ppio.h [new file with mode: 0644]
gnuradio-core/src/lib/io/ppio.i [new file with mode: 0644]
gnuradio-core/src/lib/io/ppio_ppdev.cc [new file with mode: 0644]
gnuradio-core/src/lib/io/ppio_ppdev.h [new file with mode: 0644]
gnuradio-core/src/lib/io/sdr_1000.cc [new file with mode: 0644]
gnuradio-core/src/lib/io/sdr_1000.h [new file with mode: 0644]
gnuradio-core/src/lib/io/sdr_1000.i [new file with mode: 0644]
gnuradio-core/src/lib/missing/Makefile.am [new file with mode: 0644]
gnuradio-core/src/lib/missing/bug_work_around_8.cc [new file with mode: 0644]
gnuradio-core/src/lib/missing/getopt.c [new file with mode: 0644]
gnuradio-core/src/lib/missing/getopt.h [new file with mode: 0644]
gnuradio-core/src/lib/missing/gettimeofday.c [new file with mode: 0644]
gnuradio-core/src/lib/missing/usleep.c [new file with mode: 0644]
gnuradio-core/src/lib/omnithread/Makefile.am [new file with mode: 0644]
gnuradio-core/src/lib/omnithread/dir.mk [new file with mode: 0644]
gnuradio-core/src/lib/omnithread/mach.cc [new file with mode: 0644]
gnuradio-core/src/lib/omnithread/nt.cc [new file with mode: 0644]
gnuradio-core/src/lib/omnithread/omnithread.h [new file with mode: 0644]
gnuradio-core/src/lib/omnithread/ot_VxThread.h [new file with mode: 0644]
gnuradio-core/src/lib/omnithread/ot_mach.h [new file with mode: 0644]
gnuradio-core/src/lib/omnithread/ot_nt.h [new file with mode: 0644]
gnuradio-core/src/lib/omnithread/ot_posix.h [new file with mode: 0644]
gnuradio-core/src/lib/omnithread/ot_pthread_nt.h [new file with mode: 0644]
gnuradio-core/src/lib/omnithread/ot_solaris.h [new file with mode: 0644]
gnuradio-core/src/lib/omnithread/posix.cc [new file with mode: 0644]
gnuradio-core/src/lib/omnithread/solaris.cc [new file with mode: 0644]
gnuradio-core/src/lib/omnithread/threaddata.cc [new file with mode: 0644]
gnuradio-core/src/lib/omnithread/vxWorks.cc [new file with mode: 0644]
gnuradio-core/src/lib/reed-solomon/Makefile.am [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/README [new file with mode: 0644]
gnuradio-core/src/lib/reed-solomon/README.karn [new file with mode: 0644]
gnuradio-core/src/lib/reed-solomon/ccsds.h [new file with mode: 0644]
gnuradio-core/src/lib/reed-solomon/char.h [new file with mode: 0644]
gnuradio-core/src/lib/reed-solomon/decode_rs.c [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.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/exercise.c [new file with mode: 0644]
gnuradio-core/src/lib/reed-solomon/fixed.h [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/init_rs.c [new file with mode: 0644]
gnuradio-core/src/lib/reed-solomon/int.h [new file with mode: 0644]
gnuradio-core/src/lib/reed-solomon/rs.3 [new file with mode: 0644]
gnuradio-core/src/lib/reed-solomon/rs.h [new file with mode: 0644]
gnuradio-core/src/lib/reed-solomon/rstest.c [new file with mode: 0644]
gnuradio-core/src/lib/runtime/Makefile.am [new file with mode: 0644]
gnuradio-core/src/lib/runtime/gr_block.cc [new file with mode: 0644]
gnuradio-core/src/lib/runtime/gr_block.h [new file with mode: 0644]
gnuradio-core/src/lib/runtime/gr_block.i [new file with mode: 0644]
gnuradio-core/src/lib/runtime/gr_block_detail.cc [new file with mode: 0644]
gnuradio-core/src/lib/runtime/gr_block_detail.h [new file with mode: 0644]
gnuradio-core/src/lib/runtime/gr_block_detail.i [new file with mode: 0644]
gnuradio-core/src/lib/runtime/gr_buffer.cc [new file with mode: 0644]
gnuradio-core/src/lib/runtime/gr_buffer.h [new file with mode: 0644]
gnuradio-core/src/lib/runtime/gr_buffer.i [new file with mode: 0644]
gnuradio-core/src/lib/runtime/gr_complex.h [new file with mode: 0644]
gnuradio-core/src/lib/runtime/gr_dispatcher.cc [new file with mode: 0644]
gnuradio-core/src/lib/runtime/gr_dispatcher.h [new file with mode: 0644]
gnuradio-core/src/lib/runtime/gr_dispatcher.i [new file with mode: 0644]
gnuradio-core/src/lib/runtime/gr_error_handler.cc [new file with mode: 0644]
gnuradio-core/src/lib/runtime/gr_error_handler.h [new file with mode: 0644]
gnuradio-core/src/lib/runtime/gr_error_handler.i [new file with mode: 0644]
gnuradio-core/src/lib/runtime/gr_io_signature.cc [new file with mode: 0644]
gnuradio-core/src/lib/runtime/gr_io_signature.h [new file with mode: 0644]
gnuradio-core/src/lib/runtime/gr_io_signature.i [new file with mode: 0644]
gnuradio-core/src/lib/runtime/gr_local_sighandler.cc [new file with mode: 0644]
gnuradio-core/src/lib/runtime/gr_local_sighandler.h [new file with mode: 0644]
gnuradio-core/src/lib/runtime/gr_message.cc [new file with mode: 0644]
gnuradio-core/src/lib/runtime/gr_message.h [new file with mode: 0644]
gnuradio-core/src/lib/runtime/gr_message.i [new file with mode: 0644]
gnuradio-core/src/lib/runtime/gr_msg_handler.cc [new file with mode: 0644]
gnuradio-core/src/lib/runtime/gr_msg_handler.h [new file with mode: 0644]
gnuradio-core/src/lib/runtime/gr_msg_handler.i [new file with mode: 0644]
gnuradio-core/src/lib/runtime/gr_msg_queue.cc [new file with mode: 0644]
gnuradio-core/src/lib/runtime/gr_msg_queue.h [new file with mode: 0644]
gnuradio-core/src/lib/runtime/gr_msg_queue.i [new file with mode: 0644]
gnuradio-core/src/lib/runtime/gr_pagesize.cc [new file with mode: 0644]
gnuradio-core/src/lib/runtime/gr_pagesize.h [new file with mode: 0644]
gnuradio-core/src/lib/runtime/gr_preferences.cc [new file with mode: 0644]
gnuradio-core/src/lib/runtime/gr_preferences.h [new file with mode: 0644]
gnuradio-core/src/lib/runtime/gr_realtime.cc [new file with mode: 0644]
gnuradio-core/src/lib/runtime/gr_realtime.h [new file with mode: 0644]
gnuradio-core/src/lib/runtime/gr_realtime.i [new file with mode: 0644]
gnuradio-core/src/lib/runtime/gr_runtime.h [new file with mode: 0644]
gnuradio-core/src/lib/runtime/gr_select_handler.cc [new file with mode: 0644]
gnuradio-core/src/lib/runtime/gr_select_handler.h [new file with mode: 0644]
gnuradio-core/src/lib/runtime/gr_single_threaded_scheduler.cc [new file with mode: 0644]
gnuradio-core/src/lib/runtime/gr_single_threaded_scheduler.h [new file with mode: 0644]
gnuradio-core/src/lib/runtime/gr_single_threaded_scheduler.i [new file with mode: 0644]
gnuradio-core/src/lib/runtime/gr_swig_block_magic.i [new file with mode: 0644]
gnuradio-core/src/lib/runtime/gr_timer.h [new file with mode: 0644]
gnuradio-core/src/lib/runtime/gr_tmp_path.cc [new file with mode: 0644]
gnuradio-core/src/lib/runtime/gr_tmp_path.h [new file with mode: 0644]
gnuradio-core/src/lib/runtime/gr_types.h [new file with mode: 0644]
gnuradio-core/src/lib/runtime/gr_vmcircbuf.cc [new file with mode: 0644]
gnuradio-core/src/lib/runtime/gr_vmcircbuf.h [new file with mode: 0644]
gnuradio-core/src/lib/runtime/gr_vmcircbuf_createfilemapping.cc [new file with mode: 0644]
gnuradio-core/src/lib/runtime/gr_vmcircbuf_createfilemapping.h [new file with mode: 0644]
gnuradio-core/src/lib/runtime/gr_vmcircbuf_mmap_shm_open.cc [new file with mode: 0644]
gnuradio-core/src/lib/runtime/gr_vmcircbuf_mmap_shm_open.h [new file with mode: 0644]
gnuradio-core/src/lib/runtime/gr_vmcircbuf_mmap_tmpfile.cc [new file with mode: 0644]
gnuradio-core/src/lib/runtime/gr_vmcircbuf_mmap_tmpfile.h [new file with mode: 0644]
gnuradio-core/src/lib/runtime/gr_vmcircbuf_sysv_shm.cc [new file with mode: 0644]
gnuradio-core/src/lib/runtime/gr_vmcircbuf_sysv_shm.h [new file with mode: 0644]
gnuradio-core/src/lib/runtime/qa_gr_block.cc [new file with mode: 0644]
gnuradio-core/src/lib/runtime/qa_gr_block.h [new file with mode: 0644]
gnuradio-core/src/lib/runtime/qa_gr_buffer.cc [new file with mode: 0644]
gnuradio-core/src/lib/runtime/qa_gr_buffer.h [new file with mode: 0644]
gnuradio-core/src/lib/runtime/qa_gr_io_signature.cc [new file with mode: 0644]
gnuradio-core/src/lib/runtime/qa_gr_io_signature.h [new file with mode: 0644]
gnuradio-core/src/lib/runtime/qa_gr_vmcircbuf.cc [new file with mode: 0644]
gnuradio-core/src/lib/runtime/qa_gr_vmcircbuf.h [new file with mode: 0644]
gnuradio-core/src/lib/runtime/qa_runtime.cc [new file with mode: 0644]
gnuradio-core/src/lib/runtime/qa_runtime.h [new file with mode: 0644]
gnuradio-core/src/lib/runtime/runtime.i [new file with mode: 0644]
gnuradio-core/src/lib/runtime/test_shared_block_ptr.cc [new file with mode: 0644]
gnuradio-core/src/lib/swig/Makefile.am [new file with mode: 0644]
gnuradio-core/src/lib/swig/atsc.i [new file with mode: 0644]
gnuradio-core/src/lib/swig/gen-swig-bug-fix [new file with mode: 0755]
gnuradio-core/src/lib/swig/gnuradio.i [new file with mode: 0644]
gnuradio-core/src/lib/swig/shared_ptr.i [new file with mode: 0644]
gnuradio-core/src/python/Makefile.am [new file with mode: 0644]
gnuradio-core/src/python/bin/Makefile.am [new file with mode: 0644]
gnuradio-core/src/python/bin/microtune.py [new file with mode: 0755]
gnuradio-core/src/python/build_utils.py [new file with mode: 0644]
gnuradio-core/src/python/build_utils_codes.py [new file with mode: 0644]
gnuradio-core/src/python/gnuradio/Makefile.am [new file with mode: 0644]
gnuradio-core/src/python/gnuradio/__init__.py [new file with mode: 0644]
gnuradio-core/src/python/gnuradio/audio.py [new file with mode: 0644]
gnuradio-core/src/python/gnuradio/blks/Makefile.am [new file with mode: 0644]
gnuradio-core/src/python/gnuradio/blks/__init__.py [new file with mode: 0644]
gnuradio-core/src/python/gnuradio/blksimpl/Makefile.am [new file with mode: 0644]
gnuradio-core/src/python/gnuradio/blksimpl/__init__.py [new file with mode: 0644]
gnuradio-core/src/python/gnuradio/blksimpl/am_demod.py [new file with mode: 0644]
gnuradio-core/src/python/gnuradio/blksimpl/digital_voice.py.real [new file with mode: 0644]
gnuradio-core/src/python/gnuradio/blksimpl/filterbank.py [new file with mode: 0644]
gnuradio-core/src/python/gnuradio/blksimpl/fm_demod.py [new file with mode: 0644]
gnuradio-core/src/python/gnuradio/blksimpl/fm_emph.py [new file with mode: 0644]
gnuradio-core/src/python/gnuradio/blksimpl/gmsk2.py [new file with mode: 0644]
gnuradio-core/src/python/gnuradio/blksimpl/gmsk2_pkt.py [new file with mode: 0644]
gnuradio-core/src/python/gnuradio/blksimpl/nbfm_rx.py [new file with mode: 0644]
gnuradio-core/src/python/gnuradio/blksimpl/nbfm_tx.py [new file with mode: 0644]
gnuradio-core/src/python/gnuradio/blksimpl/pkt.py [new file with mode: 0644]
gnuradio-core/src/python/gnuradio/blksimpl/rational_resampler.py [new file with mode: 0644]
gnuradio-core/src/python/gnuradio/blksimpl/standard_squelch.py [new file with mode: 0644]
gnuradio-core/src/python/gnuradio/blksimpl/wfm_rcv.py [new file with mode: 0644]
gnuradio-core/src/python/gnuradio/blksimpl/wfm_rcv_pll.py [new file with mode: 0644]
gnuradio-core/src/python/gnuradio/blksimpl/wfm_tx.py [new file with mode: 0644]
gnuradio-core/src/python/gnuradio/eng_notation.py [new file with mode: 0644]
gnuradio-core/src/python/gnuradio/eng_option.py [new file with mode: 0644]
gnuradio-core/src/python/gnuradio/gr/Makefile.am [new file with mode: 0644]
gnuradio-core/src/python/gnuradio/gr/__init__.py [new file with mode: 0644]
gnuradio-core/src/python/gnuradio/gr/basic_flow_graph.py [new file with mode: 0644]
gnuradio-core/src/python/gnuradio/gr/benchmark_filters.py [new file with mode: 0755]
gnuradio-core/src/python/gnuradio/gr/exceptions.py [new file with mode: 0644]
gnuradio-core/src/python/gnuradio/gr/flow_graph.py [new file with mode: 0644]
gnuradio-core/src/python/gnuradio/gr/gr_threading.py [new file with mode: 0644]
gnuradio-core/src/python/gnuradio/gr/gr_threading_23.py [new file with mode: 0644]
gnuradio-core/src/python/gnuradio/gr/gr_threading_24.py [new file with mode: 0644]
gnuradio-core/src/python/gnuradio/gr/hier_block.py [new file with mode: 0644]
gnuradio-core/src/python/gnuradio/gr/prefs.py [new file with mode: 0644]
gnuradio-core/src/python/gnuradio/gr/qa_add_and_friends.py [new file with mode: 0755]
gnuradio-core/src/python/gnuradio/gr/qa_add_v_and_friends.py [new file with mode: 0755]
gnuradio-core/src/python/gnuradio/gr/qa_basic_flow_graph.py [new file with mode: 0755]
gnuradio-core/src/python/gnuradio/gr/qa_cma_equalizer.py [new file with mode: 0755]
gnuradio-core/src/python/gnuradio/gr/qa_complex_to_xxx.py [new file with mode: 0755]
gnuradio-core/src/python/gnuradio/gr/qa_constellation_decoder_cb.py [new file with mode: 0755]
gnuradio-core/src/python/gnuradio/gr/qa_correlate_access_code.py [new file with mode: 0755]
gnuradio-core/src/python/gnuradio/gr/qa_diff_encoder.py [new file with mode: 0755]
gnuradio-core/src/python/gnuradio/gr/qa_diff_phasor_cc.py [new file with mode: 0755]
gnuradio-core/src/python/gnuradio/gr/qa_feval.py [new file with mode: 0755]
gnuradio-core/src/python/gnuradio/gr/qa_fft_filter.py [new file with mode: 0755]
gnuradio-core/src/python/gnuradio/gr/qa_filter_delay_fc.py [new file with mode: 0755]
gnuradio-core/src/python/gnuradio/gr/qa_flow_graph.py [new file with mode: 0755]
gnuradio-core/src/python/gnuradio/gr/qa_frequency_modulator.py [new file with mode: 0755]
gnuradio-core/src/python/gnuradio/gr/qa_fsk_stuff.py [new file with mode: 0755]
gnuradio-core/src/python/gnuradio/gr/qa_goertzel.py [new file with mode: 0755]
gnuradio-core/src/python/gnuradio/gr/qa_head.py [new file with mode: 0755]
gnuradio-core/src/python/gnuradio/gr/qa_hilbert.py [new file with mode: 0755]
gnuradio-core/src/python/gnuradio/gr/qa_iir.py [new file with mode: 0755]
gnuradio-core/src/python/gnuradio/gr/qa_interleave.py [new file with mode: 0755]
gnuradio-core/src/python/gnuradio/gr/qa_interp_fir_filter.py [new file with mode: 0755]
gnuradio-core/src/python/gnuradio/gr/qa_kludge_copy.py [new file with mode: 0755]
gnuradio-core/src/python/gnuradio/gr/qa_kludged_imports.py [new file with mode: 0755]
gnuradio-core/src/python/gnuradio/gr/qa_message.py [new file with mode: 0755]
gnuradio-core/src/python/gnuradio/gr/qa_mute.py [new file with mode: 0755]
gnuradio-core/src/python/gnuradio/gr/qa_nlog10.py [new file with mode: 0755]
gnuradio-core/src/python/gnuradio/gr/qa_packed_to_unpacked.py [new file with mode: 0755]
gnuradio-core/src/python/gnuradio/gr/qa_pipe_fittings.py [new file with mode: 0755]
gnuradio-core/src/python/gnuradio/gr/qa_rational_resampler.py [new file with mode: 0755]
gnuradio-core/src/python/gnuradio/gr/qa_sig_source.py [new file with mode: 0755]
gnuradio-core/src/python/gnuradio/gr/qa_single_pole_iir.py [new file with mode: 0755]
gnuradio-core/src/python/gnuradio/gr/qa_single_pole_iir_cc.py [new file with mode: 0755]
gnuradio-core/src/python/gnuradio/gr/qa_unpack_k_bits.py [new file with mode: 0755]
gnuradio-core/src/python/gnuradio/gr/run_tests.in [new file with mode: 0755]
gnuradio-core/src/python/gnuradio/gr/scheduler.py [new file with mode: 0644]
gnuradio-core/src/python/gnuradio/gr_unittest.py [new file with mode: 0755]
gnuradio-core/src/python/gnuradio/gru/Makefile.am [new file with mode: 0644]
gnuradio-core/src/python/gnuradio/gru/__init__.py [new file with mode: 0644]
gnuradio-core/src/python/gnuradio/gruimpl/Makefile.am [new file with mode: 0644]
gnuradio-core/src/python/gnuradio/gruimpl/__init__.py [new file with mode: 0644]
gnuradio-core/src/python/gnuradio/gruimpl/crc.py [new file with mode: 0644]
gnuradio-core/src/python/gnuradio/gruimpl/freqz.py [new file with mode: 0644]
gnuradio-core/src/python/gnuradio/gruimpl/gnuplot_freqz.py [new file with mode: 0755]
gnuradio-core/src/python/gnuradio/gruimpl/hexint.py [new file with mode: 0644]
gnuradio-core/src/python/gnuradio/gruimpl/listmisc.py [new file with mode: 0644]
gnuradio-core/src/python/gnuradio/gruimpl/lmx2306.py [new file with mode: 0755]
gnuradio-core/src/python/gnuradio/gruimpl/mathmisc.py [new file with mode: 0644]
gnuradio-core/src/python/gnuradio/gruimpl/os_read_exactly.py [new file with mode: 0644]
gnuradio-core/src/python/gnuradio/gruimpl/sdr_1000.py [new file with mode: 0644]
gnuradio-core/src/python/gnuradio/gruimpl/seq_with_cursor.py [new file with mode: 0644]
gnuradio-core/src/python/gnuradio/gruimpl/socket_stuff.py [new file with mode: 0644]
gnuradio-core/src/python/gnuradio/optfir.py [new file with mode: 0644]
gnuradio-core/src/python/gnuradio/packet_utils.py [new file with mode: 0644]
gnuradio-core/src/python/gnuradio/window.py [new file with mode: 0644]
gnuradio-core/src/tests/Makefile.am [new file with mode: 0644]
gnuradio-core/src/tests/benchmark_dotprod.cc [new file with mode: 0644]
gnuradio-core/src/tests/benchmark_dotprod_ccc.cc [new file with mode: 0644]
gnuradio-core/src/tests/benchmark_dotprod_ccf.cc [new file with mode: 0644]
gnuradio-core/src/tests/benchmark_dotprod_fcc.cc [new file with mode: 0644]
gnuradio-core/src/tests/benchmark_dotprod_fsf.cc [new file with mode: 0644]
gnuradio-core/src/tests/benchmark_dotprod_scc.cc [new file with mode: 0644]
gnuradio-core/src/tests/benchmark_nco.cc [new file with mode: 0644]
gnuradio-core/src/tests/benchmark_vco.cc [new file with mode: 0644]
gnuradio-core/src/tests/nco_results [new file with mode: 0644]
gnuradio-core/src/tests/test_all.cc [new file with mode: 0644]
gnuradio-core/src/tests/test_atsc.cc [new file with mode: 0644]
gnuradio-core/src/tests/test_buffers.py [new file with mode: 0755]
gnuradio-core/src/tests/test_filter.cc [new file with mode: 0644]
gnuradio-core/src/tests/test_general.cc [new file with mode: 0644]
gnuradio-core/src/tests/test_runtime.cc [new file with mode: 0644]
gnuradio-core/src/tests/test_vmcircbuf.cc [new file with mode: 0644]
gnuradio-core/src/utils/Makefile.am [new file with mode: 0644]
gnuradio-core/src/utils/cool.m [new file with mode: 0644]
gnuradio-core/src/utils/db_width.m [new file with mode: 0644]
gnuradio-core/src/utils/filter_tools.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/plot_freq_response.m [new file with mode: 0644]
gnuradio-core/src/utils/plot_freq_response_db.m [new file with mode: 0644]
gnuradio-core/src/utils/plot_freq_response_phase.m [new file with mode: 0644]
gnuradio-core/src/utils/plotfft.m [new file with mode: 0644]
gnuradio-core/src/utils/plotfftavgk.m [new file with mode: 0644]
gnuradio-core/src/utils/plotfftavgk_db.m [new file with mode: 0644]
gnuradio-core/src/utils/plotfftk.m [new file with mode: 0644]
gnuradio-core/src/utils/plotfftk_db.m [new file with mode: 0644]
gnuradio-core/src/utils/put_markers.m [new file with mode: 0644]
gnuradio-core/src/utils/rainbow.m [new file with mode: 0644]
gnuradio-core/src/utils/read_char_binary.m [new file with mode: 0644]
gnuradio-core/src/utils/read_complex_binary.m [new file with mode: 0644]
gnuradio-core/src/utils/read_float_binary.m [new file with mode: 0644]
gnuradio-core/src/utils/read_int_binary.m [new file with mode: 0644]
gnuradio-core/src/utils/read_short_binary.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/single_pole_iir.m [new file with mode: 0644]
gnuradio-core/src/utils/write_float_binary.m [new file with mode: 0644]
gnuradio-core/src/utils/write_short_binary.m [new file with mode: 0644]
gnuradio-examples/AUTHORS [new file with mode: 0644]
gnuradio-examples/ChangeLog [new file with mode: 0644]
gnuradio-examples/Makefile.am [new file with mode: 0644]
gnuradio-examples/NEWS [new file with mode: 0644]
gnuradio-examples/README [new file with mode: 0644]
gnuradio-examples/README.hacking [new file with mode: 0644]
gnuradio-examples/python/Makefile.am [new file with mode: 0644]
gnuradio-examples/python/apps/README [new file with mode: 0644]
gnuradio-examples/python/apps/hf_explorer/README [new file with mode: 0644]
gnuradio-examples/python/apps/hf_explorer/hfx2.py [new file with mode: 0755]
gnuradio-examples/python/apps/hf_explorer/hfx_help [new file with mode: 0644]
gnuradio-examples/python/apps/hf_radio/README.TXT [new file with mode: 0644]
gnuradio-examples/python/apps/hf_radio/hfir.sci [new file with mode: 0644]
gnuradio-examples/python/apps/hf_radio/input.py [new file with mode: 0644]
gnuradio-examples/python/apps/hf_radio/output.py [new file with mode: 0644]
gnuradio-examples/python/apps/hf_radio/radio.py [new file with mode: 0755]
gnuradio-examples/python/apps/hf_radio/radio.xml [new file with mode: 0644]
gnuradio-examples/python/apps/hf_radio/ssb_taps [new file with mode: 0644]
gnuradio-examples/python/apps/hf_radio/ssbagc.py [new file with mode: 0644]
gnuradio-examples/python/apps/hf_radio/ssbdemod.py [new file with mode: 0644]
gnuradio-examples/python/apps/hf_radio/startup.py [new file with mode: 0644]
gnuradio-examples/python/apps/hf_radio/ui.py [new file with mode: 0755]
gnuradio-examples/python/audio/Makefile.am [new file with mode: 0644]
gnuradio-examples/python/audio/audio_copy.py [new file with mode: 0755]
gnuradio-examples/python/audio/audio_play.py [new file with mode: 0755]
gnuradio-examples/python/audio/audio_to_file.py [new file with mode: 0755]
gnuradio-examples/python/audio/dial_squelch.py [new file with mode: 0755]
gnuradio-examples/python/audio/dial_tone.py [new file with mode: 0755]
gnuradio-examples/python/audio/dialtone_v.py [new file with mode: 0755]
gnuradio-examples/python/audio/mono_tone.py [new file with mode: 0755]
gnuradio-examples/python/audio/multi_tone.py [new file with mode: 0755]
gnuradio-examples/python/audio/spectrum_inversion.py [new file with mode: 0755]
gnuradio-examples/python/audio/test_resampler.py [new file with mode: 0755]
gnuradio-examples/python/digital_voice/Makefile.am [new file with mode: 0644]
gnuradio-examples/python/digital_voice/encdec.py [new file with mode: 0755]
gnuradio-examples/python/gmsk2/Makefile.am [new file with mode: 0644]
gnuradio-examples/python/gmsk2/README [new file with mode: 0644]
gnuradio-examples/python/gmsk2/benchmark_gmsk_rx.py [new file with mode: 0755]
gnuradio-examples/python/gmsk2/benchmark_gmsk_tx.py [new file with mode: 0755]
gnuradio-examples/python/gmsk2/benchmark_mpsk_rx.py [new file with mode: 0755]
gnuradio-examples/python/gmsk2/benchmark_mpsk_tx.py [new file with mode: 0755]
gnuradio-examples/python/gmsk2/bpsk.py [new file with mode: 0644]
gnuradio-examples/python/gmsk2/dbpsk.py [new file with mode: 0644]
gnuradio-examples/python/gmsk2/dqpsk.py [new file with mode: 0644]
gnuradio-examples/python/gmsk2/fusb_options.py [new file with mode: 0644]
gnuradio-examples/python/gmsk2/gen_whitener.py [new file with mode: 0755]
gnuradio-examples/python/gmsk2/gmsk_test.py [new file with mode: 0755]
gnuradio-examples/python/gmsk2/mpsk_test.py [new file with mode: 0755]
gnuradio-examples/python/gmsk2/pick_bitrate.py [new file with mode: 0644]
gnuradio-examples/python/gmsk2/qpsk.py [new file with mode: 0644]
gnuradio-examples/python/gmsk2/qpsk_tester.py [new file with mode: 0644]
gnuradio-examples/python/gmsk2/qpsk_usrp_tester.py [new file with mode: 0644]
gnuradio-examples/python/gmsk2/receive_path.py [new file with mode: 0644]
gnuradio-examples/python/gmsk2/rx_voice.py [new file with mode: 0755]
gnuradio-examples/python/gmsk2/transmit_path.py [new file with mode: 0644]
gnuradio-examples/python/gmsk2/tunnel.py [new file with mode: 0755]
gnuradio-examples/python/gmsk2/tx_voice.py [new file with mode: 0755]
gnuradio-examples/python/mc4020/Makefile.am [new file with mode: 0644]
gnuradio-examples/python/mc4020/fm_demod.py [new file with mode: 0755]
gnuradio-examples/python/mc4020/mc4020_fft.py [new file with mode: 0755]
gnuradio-examples/python/multi-antenna/multi_fft.py [new file with mode: 0755]
gnuradio-examples/python/multi-antenna/multi_file.py [new file with mode: 0755]
gnuradio-examples/python/multi-antenna/multi_scope.py [new file with mode: 0755]
gnuradio-examples/python/multi_usrp/Makefile.am [new file with mode: 0644]
gnuradio-examples/python/multi_usrp/README [new file with mode: 0644]
gnuradio-examples/python/multi_usrp/multi_usrp_oscope.py [new file with mode: 0755]
gnuradio-examples/python/multi_usrp/multi_usrp_rx_cfile.py [new file with mode: 0755]
gnuradio-examples/python/networking/measurement_slave.py [new file with mode: 0755]
gnuradio-examples/python/usrp/Makefile.am [new file with mode: 0644]
gnuradio-examples/python/usrp/am_rcv.py [new file with mode: 0755]
gnuradio-examples/python/usrp/ayfabtu.dat [new file with mode: 0644]
gnuradio-examples/python/usrp/ayfabtu.py [new file with mode: 0755]
gnuradio-examples/python/usrp/benchmark_usb.py [new file with mode: 0755]
gnuradio-examples/python/usrp/dsb_tx.py [new file with mode: 0755]
gnuradio-examples/python/usrp/flexrf_debug.py [new file with mode: 0755]
gnuradio-examples/python/usrp/flexrf_siggen.py [new file with mode: 0755]
gnuradio-examples/python/usrp/fm_tx4.py [new file with mode: 0755]
gnuradio-examples/python/usrp/fm_tx_2_daughterboards.py [new file with mode: 0755]
gnuradio-examples/python/usrp/max_power.py [new file with mode: 0755]
gnuradio-examples/python/usrp/siggen_min2.py [new file with mode: 0755]
gnuradio-examples/python/usrp/test_counting.py [new file with mode: 0755]
gnuradio-examples/python/usrp/test_dft_analysis.py [new file with mode: 0755]
gnuradio-examples/python/usrp/test_dft_synth.py [new file with mode: 0755]
gnuradio-examples/python/usrp/test_digital_loopback_counting.py [new file with mode: 0755]
gnuradio-examples/python/usrp/test_digital_loopback_lfsr.py [new file with mode: 0755]
gnuradio-examples/python/usrp/tvrx_am_rcv_gui.py [new file with mode: 0755]
gnuradio-examples/python/usrp/usrp_fft.py [new file with mode: 0755]
gnuradio-examples/python/usrp/usrp_fft_old.py [new file with mode: 0755]
gnuradio-examples/python/usrp/usrp_nbfm_ptt.py [new file with mode: 0755]
gnuradio-examples/python/usrp/usrp_nbfm_rcv.py [new file with mode: 0755]
gnuradio-examples/python/usrp/usrp_oscope.py [new file with mode: 0755]
gnuradio-examples/python/usrp/usrp_rx_cfile.py [new file with mode: 0755]
gnuradio-examples/python/usrp/usrp_rx_nogui.py [new file with mode: 0755]
gnuradio-examples/python/usrp/usrp_siggen.py [new file with mode: 0755]
gnuradio-examples/python/usrp/usrp_tv_rcv.py [new file with mode: 0755]
gnuradio-examples/python/usrp/usrp_tv_rcv_nogui.py [new file with mode: 0755]
gnuradio-examples/python/usrp/usrp_wfm_rcv.py [new file with mode: 0755]
gnuradio-examples/python/usrp/usrp_wfm_rcv2_nogui.py [new file with mode: 0755]
gnuradio-examples/python/usrp/usrp_wfm_rcv_nogui.py [new file with mode: 0755]
gnuradio-examples/python/usrp/usrp_wfm_rcv_pll.py [new file with mode: 0755]
gnuradio-examples/python/usrp/usrp_wxapt_rcv.py [new file with mode: 0755]
gnuradio-examples/python/usrp/wfm_rcv_file.py [new file with mode: 0755]
gr-atsc/AUTHORS [new file with mode: 0644]
gr-atsc/ChangeLog [new file with mode: 0644]
gr-atsc/Makefile.am [new file with mode: 0644]
gr-atsc/NEWS [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/Makefile.am [new file with mode: 0644]
gr-atsc/src/Makefile.am [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/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_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/Makefile.am [new file with mode: 0644]
gr-atsc/src/python/atsc_utils.py [new file with mode: 0644]
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-audio-alsa/AUTHORS [new file with mode: 0644]
gr-audio-alsa/ChangeLog [new file with mode: 0644]
gr-audio-alsa/Makefile.am [new file with mode: 0644]
gr-audio-alsa/README [new file with mode: 0644]
gr-audio-alsa/build-stamp [new file with mode: 0644]
gr-audio-alsa/gr-audio-alsa.conf [new file with mode: 0644]
gr-audio-alsa/src/Makefile.am [new file with mode: 0644]
gr-audio-alsa/src/audio_alsa.i [new file with mode: 0644]
gr-audio-alsa/src/audio_alsa_sink.cc [new file with mode: 0644]
gr-audio-alsa/src/audio_alsa_sink.h [new file with mode: 0644]
gr-audio-alsa/src/audio_alsa_source.cc [new file with mode: 0644]
gr-audio-alsa/src/audio_alsa_source.h [new file with mode: 0644]
gr-audio-alsa/src/gri_alsa.cc [new file with mode: 0644]
gr-audio-alsa/src/gri_alsa.h [new file with mode: 0644]
gr-audio-alsa/src/qa_alsa.py [new file with mode: 0755]
gr-audio-alsa/src/run_tests.in [new file with mode: 0644]
gr-audio-jack/AUTHORS [new file with mode: 0644]
gr-audio-jack/ChangeLog [new file with mode: 0644]
gr-audio-jack/Makefile.am [new file with mode: 0644]
gr-audio-jack/gr-audio-jack.conf [new file with mode: 0644]
gr-audio-jack/src/Makefile.am [new file with mode: 0644]
gr-audio-jack/src/audio_jack.i [new file with mode: 0644]
gr-audio-jack/src/audio_jack_sink.cc [new file with mode: 0644]
gr-audio-jack/src/audio_jack_sink.h [new file with mode: 0644]
gr-audio-jack/src/audio_jack_source.cc [new file with mode: 0644]
gr-audio-jack/src/audio_jack_source.h [new file with mode: 0644]
gr-audio-jack/src/gri_jack.cc [new file with mode: 0644]
gr-audio-jack/src/gri_jack.h [new file with mode: 0644]
gr-audio-jack/src/qa_jack.py [new file with mode: 0755]
gr-audio-jack/src/run_tests.in [new file with mode: 0644]
gr-audio-oss/AUTHORS [new file with mode: 0644]
gr-audio-oss/ChangeLog [new file with mode: 0644]
gr-audio-oss/Makefile.am [new file with mode: 0644]
gr-audio-oss/gr-audio-oss.conf [new file with mode: 0644]
gr-audio-oss/src/Makefile.am [new file with mode: 0644]
gr-audio-oss/src/audio_oss.i [new file with mode: 0644]
gr-audio-oss/src/audio_oss_sink.cc [new file with mode: 0644]
gr-audio-oss/src/audio_oss_sink.h [new file with mode: 0644]
gr-audio-oss/src/audio_oss_source.cc [new file with mode: 0644]
gr-audio-oss/src/audio_oss_source.h [new file with mode: 0644]
gr-audio-oss/src/qa_oss.py [new file with mode: 0755]
gr-audio-oss/src/run_tests.in [new file with mode: 0644]
gr-audio-osx/AUTHORS [new file with mode: 0644]
gr-audio-osx/ChangeLog [new file with mode: 0644]
gr-audio-osx/Makefile.am [new file with mode: 0644]
gr-audio-osx/README_OSX [new file with mode: 0644]
gr-audio-osx/TODO [new file with mode: 0644]
gr-audio-osx/src/Makefile.am [new file with mode: 0644]
gr-audio-osx/src/audio_osx.h [new file with mode: 0644]
gr-audio-osx/src/audio_osx.i [new file with mode: 0644]
gr-audio-osx/src/audio_osx_sink.cc [new file with mode: 0644]
gr-audio-osx/src/audio_osx_sink.h [new file with mode: 0644]
gr-audio-osx/src/audio_osx_source.cc [new file with mode: 0644]
gr-audio-osx/src/audio_osx_source.h [new file with mode: 0644]
gr-audio-osx/src/circular_buffer.h [new file with mode: 0644]
gr-audio-osx/src/mld_threads.h [new file with mode: 0644]
gr-audio-osx/src/qa_osx.py [new file with mode: 0755]
gr-audio-osx/src/run_tests.in [new file with mode: 0644]
gr-audio-osx/src/test_audio_loop.py [new file with mode: 0755]
gr-audio-portaudio/AUTHORS [new file with mode: 0644]
gr-audio-portaudio/ChangeLog [new file with mode: 0644]
gr-audio-portaudio/Makefile.am [new file with mode: 0644]
gr-audio-portaudio/README [new file with mode: 0644]
gr-audio-portaudio/autoconfiscate.patch [new file with mode: 0755]
gr-audio-portaudio/gr-audio-portaudio.conf [new file with mode: 0644]
gr-audio-portaudio/src/Makefile.am [new file with mode: 0644]
gr-audio-portaudio/src/audio_portaudio.i [new file with mode: 0644]
gr-audio-portaudio/src/audio_portaudio_sink.cc [new file with mode: 0644]
gr-audio-portaudio/src/audio_portaudio_sink.h [new file with mode: 0644]
gr-audio-portaudio/src/audio_portaudio_source.cc [new file with mode: 0644]
gr-audio-portaudio/src/audio_portaudio_source.h [new file with mode: 0644]
gr-audio-portaudio/src/gri_portaudio.cc [new file with mode: 0644]
gr-audio-portaudio/src/gri_portaudio.h [new file with mode: 0644]
gr-audio-portaudio/src/qa_portaudio.py [new file with mode: 0755]
gr-audio-portaudio/src/run_tests.in [new file with mode: 0644]
gr-audio-windows/AUTHORS [new file with mode: 0644]
gr-audio-windows/ChangeLog [new file with mode: 0644]
gr-audio-windows/Makefile.am [new file with mode: 0644]
gr-audio-windows/README [new file with mode: 0644]
gr-audio-windows/src/Makefile.am [new file with mode: 0644]
gr-audio-windows/src/audio_windows.i [new file with mode: 0644]
gr-audio-windows/src/audio_windows_sink.cc [new file with mode: 0644]
gr-audio-windows/src/audio_windows_sink.h [new file with mode: 0644]
gr-audio-windows/src/audio_windows_source.cc [new file with mode: 0644]
gr-audio-windows/src/audio_windows_source.h [new file with mode: 0644]
gr-audio-windows/src/qa_audio_windows.py [new file with mode: 0755]
gr-audio-windows/src/run_tests.in [new file with mode: 0755]
gr-comedi/AUTHORS [new file with mode: 0644]
gr-comedi/ChangeLog [new file with mode: 0644]
gr-comedi/Makefile.am [new file with mode: 0644]
gr-comedi/src/Makefile.am [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-error-correcting-codes/AUTHORS [new file with mode: 0644]
gr-error-correcting-codes/ChangeLog [new file with mode: 0644]
gr-error-correcting-codes/Makefile.am [new file with mode: 0644]
gr-error-correcting-codes/src/Makefile.am [new file with mode: 0644]
gr-error-correcting-codes/src/lib/Makefile.am [new file with mode: 0644]
gr-error-correcting-codes/src/lib/__init__.py [new file with mode: 0644]
gr-error-correcting-codes/src/lib/ecc.i [new file with mode: 0644]
gr-error-correcting-codes/src/lib/gr_metrics_decode_viterbi_full_block.cc [new file with mode: 0644]
gr-error-correcting-codes/src/lib/gr_metrics_decode_viterbi_full_block.h [new file with mode: 0644]
gr-error-correcting-codes/src/lib/gr_metrics_decode_viterbi_full_block.i [new file with mode: 0644]
gr-error-correcting-codes/src/lib/gr_streams_encode_convolutional.cc [new file with mode: 0644]
gr-error-correcting-codes/src/lib/gr_streams_encode_convolutional.h [new file with mode: 0644]
gr-error-correcting-codes/src/lib/gr_streams_encode_convolutional.i [new file with mode: 0644]
gr-error-correcting-codes/src/lib/gr_streams_encode_turbo.cc [new file with mode: 0644]
gr-error-correcting-codes/src/lib/gr_streams_encode_turbo.h [new file with mode: 0644]
gr-error-correcting-codes/src/lib/gr_streams_encode_turbo.i [new file with mode: 0644]
gr-error-correcting-codes/src/lib/gr_syms_to_metrics.cc [new file with mode: 0644]
gr-error-correcting-codes/src/lib/gr_syms_to_metrics.h [new file with mode: 0644]
gr-error-correcting-codes/src/lib/gr_syms_to_metrics.i [new file with mode: 0644]
gr-error-correcting-codes/src/lib/libecc/Makefile.am [new file with mode: 0644]
gr-error-correcting-codes/src/lib/libecc/code_convolutional_trellis.cc [new file with mode: 0644]
gr-error-correcting-codes/src/lib/libecc/code_convolutional_trellis.h [new file with mode: 0644]
gr-error-correcting-codes/src/lib/libecc/code_metrics.cc [new file with mode: 0644]
gr-error-correcting-codes/src/lib/libecc/code_metrics.h [new file with mode: 0644]
gr-error-correcting-codes/src/lib/libecc/code_types.h [new file with mode: 0644]
gr-error-correcting-codes/src/lib/libecc/decoder.cc [new file with mode: 0644]
gr-error-correcting-codes/src/lib/libecc/decoder.h [new file with mode: 0644]
gr-error-correcting-codes/src/lib/libecc/decoder_viterbi.cc [new file with mode: 0644]
gr-error-correcting-codes/src/lib/libecc/decoder_viterbi.h [new file with mode: 0644]
gr-error-correcting-codes/src/lib/libecc/decoder_viterbi_full_block.cc [new file with mode: 0644]
gr-error-correcting-codes/src/lib/libecc/decoder_viterbi_full_block.h [new file with mode: 0644]
gr-error-correcting-codes/src/lib/libecc/decoder_viterbi_full_block_i1_ic1.cc [new file with mode: 0644]
gr-error-correcting-codes/src/lib/libecc/decoder_viterbi_full_block_i1_ic1.h [new file with mode: 0644]
gr-error-correcting-codes/src/lib/libecc/encoder.cc [new file with mode: 0644]
gr-error-correcting-codes/src/lib/libecc/encoder.h [new file with mode: 0644]
gr-error-correcting-codes/src/lib/libecc/encoder_convolutional.cc [new file with mode: 0644]
gr-error-correcting-codes/src/lib/libecc/encoder_convolutional.h [new file with mode: 0644]
gr-error-correcting-codes/src/lib/libecc/encoder_convolutional_ic1_ic1.cc [new file with mode: 0644]
gr-error-correcting-codes/src/lib/libecc/encoder_convolutional_ic1_ic1.h [new file with mode: 0644]
gr-error-correcting-codes/src/lib/libecc/encoder_convolutional_ic8_ic8.cc [new file with mode: 0644]
gr-error-correcting-codes/src/lib/libecc/encoder_convolutional_ic8_ic8.h [new file with mode: 0644]
gr-error-correcting-codes/src/lib/libecc/encoder_turbo.cc [new file with mode: 0644]
gr-error-correcting-codes/src/lib/libecc/encoder_turbo.h [new file with mode: 0644]
gr-error-correcting-codes/src/lib/libecc/mld/Makefile.am [new file with mode: 0644]
gr-error-correcting-codes/src/lib/libecc/mld/mld_timer.cc [new file with mode: 0644]
gr-error-correcting-codes/src/lib/libecc/mld/mld_timer.h [new file with mode: 0644]
gr-error-correcting-codes/src/lib/libecc/mld/n2bs.cc [new file with mode: 0644]
gr-error-correcting-codes/src/lib/libecc/mld/n2bs.h [new file with mode: 0644]
gr-error-correcting-codes/src/lib/libecc/tests/Makefile.am [new file with mode: 0644]
gr-error-correcting-codes/src/lib/libecc/tests/qa_ecc.cc [new file with mode: 0644]
gr-error-correcting-codes/src/lib/libecc/tests/qa_ecc.h [new file with mode: 0644]
gr-error-correcting-codes/src/lib/libecc/tests/qa_encoder_convolutional_ic1_ic1.cc [new file with mode: 0644]
gr-error-correcting-codes/src/lib/libecc/tests/qa_encoder_convolutional_ic1_ic1.h [new file with mode: 0644]
gr-error-correcting-codes/src/lib/libecc/tests/test_all.cc [new file with mode: 0644]
gr-error-correcting-codes/src/lib/qa_ecc.py [new file with mode: 0755]
gr-error-correcting-codes/src/python/Makefile.am [new file with mode: 0644]
gr-error-correcting-codes/src/python/qa_test_coding_1.py [new file with mode: 0755]
gr-error-correcting-codes/src/python/qa_test_coding_2.py [new file with mode: 0755]
gr-error-correcting-codes/src/python/qa_test_encoder_convolutional_1.py [new file with mode: 0755]
gr-error-correcting-codes/src/python/qa_test_encoder_convolutional_2.py [new file with mode: 0755]
gr-error-correcting-codes/src/python/run_tests.in [new file with mode: 0644]
gr-gsm-fr-vocoder/AUTHORS [new file with mode: 0644]
gr-gsm-fr-vocoder/ChangeLog [new file with mode: 0644]
gr-gsm-fr-vocoder/INSTALL [new file with mode: 0644]
gr-gsm-fr-vocoder/Makefile.am [new file with mode: 0644]
gr-gsm-fr-vocoder/src/Makefile.am [new file with mode: 0644]
gr-gsm-fr-vocoder/src/lib/Makefile.am [new file with mode: 0644]
gr-gsm-fr-vocoder/src/lib/__init__.py [new file with mode: 0644]
gr-gsm-fr-vocoder/src/lib/gsm/COPYRIGHT [new file with mode: 0644]
gr-gsm-fr-vocoder/src/lib/gsm/Makefile.am [new file with mode: 0644]
gr-gsm-fr-vocoder/src/lib/gsm/README [new file with mode: 0644]
gr-gsm-fr-vocoder/src/lib/gsm/README.orig [new file with mode: 0644]
gr-gsm-fr-vocoder/src/lib/gsm/add.c [new file with mode: 0644]
gr-gsm-fr-vocoder/src/lib/gsm/code.c [new file with mode: 0644]
gr-gsm-fr-vocoder/src/lib/gsm/config.h [new file with mode: 0644]
gr-gsm-fr-vocoder/src/lib/gsm/debug.c [new file with mode: 0644]
gr-gsm-fr-vocoder/src/lib/gsm/decode.c [new file with mode: 0644]
gr-gsm-fr-vocoder/src/lib/gsm/gsm.h [new file with mode: 0644]
gr-gsm-fr-vocoder/src/lib/gsm/gsm_create.c [new file with mode: 0644]
gr-gsm-fr-vocoder/src/lib/gsm/gsm_decode.c [new file with mode: 0644]
gr-gsm-fr-vocoder/src/lib/gsm/gsm_destroy.c [new file with mode: 0644]
gr-gsm-fr-vocoder/src/lib/gsm/gsm_encode.c [new file with mode: 0644]
gr-gsm-fr-vocoder/src/lib/gsm/gsm_explode.c [new file with mode: 0644]
gr-gsm-fr-vocoder/src/lib/gsm/gsm_implode.c [new file with mode: 0644]
gr-gsm-fr-vocoder/src/lib/gsm/gsm_option.c [new file with mode: 0644]
gr-gsm-fr-vocoder/src/lib/gsm/gsm_print.c [new file with mode: 0644]
gr-gsm-fr-vocoder/src/lib/gsm/long_term.c [new file with mode: 0644]
gr-gsm-fr-vocoder/src/lib/gsm/lpc.c [new file with mode: 0644]
gr-gsm-fr-vocoder/src/lib/gsm/preprocess.c [new file with mode: 0644]
gr-gsm-fr-vocoder/src/lib/gsm/private.h [new file with mode: 0644]
gr-gsm-fr-vocoder/src/lib/gsm/proto.h [new file with mode: 0644]
gr-gsm-fr-vocoder/src/lib/gsm/rpe.c [new file with mode: 0644]
gr-gsm-fr-vocoder/src/lib/gsm/short_term.c [new file with mode: 0644]
gr-gsm-fr-vocoder/src/lib/gsm/table.c [new file with mode: 0644]
gr-gsm-fr-vocoder/src/lib/gsm/unproto.h [new file with mode: 0644]
gr-gsm-fr-vocoder/src/lib/gsm_fr_decode_ps.cc [new file with mode: 0644]
gr-gsm-fr-vocoder/src/lib/gsm_fr_decode_ps.h [new file with mode: 0644]
gr-gsm-fr-vocoder/src/lib/gsm_fr_encode_sp.cc [new file with mode: 0644]
gr-gsm-fr-vocoder/src/lib/gsm_fr_encode_sp.h [new file with mode: 0644]
gr-gsm-fr-vocoder/src/lib/gsm_full_rate.i [new file with mode: 0644]
gr-gsm-fr-vocoder/src/python/Makefile.am [new file with mode: 0644]
gr-gsm-fr-vocoder/src/python/encdec.py [new file with mode: 0755]
gr-gsm-fr-vocoder/src/python/qa_gsm_full_rate.py [new file with mode: 0755]
gr-gsm-fr-vocoder/src/python/run_tests.in [new file with mode: 0644]
gr-howto-write-a-block/.buildpri [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/NEWS [new file with mode: 0644]
gr-howto-write-a-block/README [new file with mode: 0644]
gr-howto-write-a-block/bootstrap [new file with mode: 0755]
gr-howto-write-a-block/config.guess [new file with mode: 0644]
gr-howto-write-a-block/config.sub [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/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_as.m4 [new file with mode: 0644]
gr-howto-write-a-block/config/gr_boost.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_gprof.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_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_x86_64.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/doc/Makefile.am [new file with mode: 0644]
gr-howto-write-a-block/doc/howto-write-a-block.xml [new file with mode: 0644]
gr-howto-write-a-block/doc/howto_1.i [new file with mode: 0644]
gr-howto-write-a-block/doc/make_numbered_listing.py [new file with mode: 0755]
gr-howto-write-a-block/doc/qa_howto_1.py [new file with mode: 0755]
gr-howto-write-a-block/doc/src_lib_Makefile_1.am [new file with mode: 0644]
gr-howto-write-a-block/doc/src_lib_Makefile_2.am [new file with mode: 0644]
gr-howto-write-a-block/src/Makefile.am [new file with mode: 0644]
gr-howto-write-a-block/src/lib/Makefile.am [new file with mode: 0644]
gr-howto-write-a-block/src/lib/howto.i [new file with mode: 0644]
gr-howto-write-a-block/src/lib/howto_square2_ff.cc [new file with mode: 0644]
gr-howto-write-a-block/src/lib/howto_square2_ff.h [new file with mode: 0644]
gr-howto-write-a-block/src/lib/howto_square_ff.cc [new file with mode: 0644]
gr-howto-write-a-block/src/lib/howto_square_ff.h [new file with mode: 0644]
gr-howto-write-a-block/src/python/Makefile.am [new file with mode: 0644]
gr-howto-write-a-block/src/python/qa_howto.py [new file with mode: 0755]
gr-howto-write-a-block/src/python/run_tests.in [new file with mode: 0644]
gr-radar/AUTHORS [new file with mode: 0644]
gr-radar/ChangeLog [new file with mode: 0644]
gr-radar/Makefile.am [new file with mode: 0644]
gr-radar/doc/Makefile.am [new file with mode: 0644]
gr-radar/src/Makefile.am [new file with mode: 0644]
gr-radar/src/lib/Makefile.am [new file with mode: 0644]
gr-radar/src/lib/eb-xambi.cc [new file with mode: 0644]
gr-radar/src/lib/gen_run [new file with mode: 0755]
gr-radar/src/lib/plot_rd.m [new file with mode: 0644]
gr-radar/src/lib/plot_xambi.m [new file with mode: 0755]
gr-radar/src/lib/plot_xambi_to_file.m [new file with mode: 0755]
gr-radar/src/lib/plot_xambi_tool.m [new file with mode: 0755]
gr-radar/src/lib/sim-airplane.cc [new file with mode: 0644]
gr-radar/src/lib/sim-airplane2.cc [new file with mode: 0644]
gr-radar/src/lib/simulation.cc [new file with mode: 0644]
gr-radar/src/lib/simulation.h [new file with mode: 0644]
gr-radar/src/lib/time_series.cc [new file with mode: 0644]
gr-radar/src/lib/time_series.h [new file with mode: 0644]
gr-radar/src/lib/xambi.cc [new file with mode: 0644]
gr-radar/src/python/Makefile.am [new file with mode: 0644]
gr-radar/src/python/complex_to_short.py [new file with mode: 0755]
gr-radar/src/python/fm_demod_file.py [new file with mode: 0755]
gr-radar/src/python/gen_fm_signal.py [new file with mode: 0755]
gr-radar/src/python/gen_random_signal.py [new file with mode: 0755]
gr-radar/src/python/qa_nothing.py [new file with mode: 0755]
gr-radar/src/python/run_tests.in [new file with mode: 0644]
gr-radar/src/python/signal_levels.py [new file with mode: 0755]
gr-radar/src/python/split_files.py [new file with mode: 0755]
gr-radar/src/python/usrp_rx_radar.py [new file with mode: 0755]
gr-radio-astronomy/AUTHORS [new file with mode: 0644]
gr-radio-astronomy/ChangeLog [new file with mode: 0644]
gr-radio-astronomy/Makefile.am [new file with mode: 0644]
gr-radio-astronomy/README [new file with mode: 0644]
gr-radio-astronomy/src/Makefile.am [new file with mode: 0644]
gr-radio-astronomy/src/lib/Makefile.am [new file with mode: 0644]
gr-radio-astronomy/src/lib/ra.i [new file with mode: 0644]
gr-radio-astronomy/src/python/Makefile.am [new file with mode: 0644]
gr-radio-astronomy/src/python/local_calibrator.py [new file with mode: 0755]
gr-radio-astronomy/src/python/qa_ra.py [new file with mode: 0755]
gr-radio-astronomy/src/python/ra_fftsink.py [new file with mode: 0755]
gr-radio-astronomy/src/python/ra_stripchartsink.py [new file with mode: 0755]
gr-radio-astronomy/src/python/run_tests.in [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 [new file with mode: 0755]
gr-radio-astronomy/src/python/usrp_ra_receiver.help [new file with mode: 0644]
gr-radio-astronomy/src/python/usrp_ra_receiver.py [new file with mode: 0755]
gr-usrp/AUTHORS [new file with mode: 0644]
gr-usrp/ChangeLog [new file with mode: 0644]
gr-usrp/Makefile.am [new file with mode: 0644]
gr-usrp/README_MULTI_USRP.txt [new file with mode: 0644]
gr-usrp/src/Makefile.am [new file with mode: 0644]
gr-usrp/src/db_base.py [new file with mode: 0644]
gr-usrp/src/db_basic.py [new file with mode: 0644]
gr-usrp/src/db_dbs_rx.py [new file with mode: 0644]
gr-usrp/src/db_flexrf.py [new file with mode: 0644]
gr-usrp/src/db_flexrf_mimo.py [new file with mode: 0644]
gr-usrp/src/db_instantiator.py [new file with mode: 0644]
gr-usrp/src/db_tv_rx.py [new file with mode: 0644]
gr-usrp/src/flexrf_debug_gui.py [new file with mode: 0755]
gr-usrp/src/qa_usrp.py [new file with mode: 0755]
gr-usrp/src/run_tests.in [new file with mode: 0644]
gr-usrp/src/tx_debug_gui.py [new file with mode: 0755]
gr-usrp/src/usrp.py [new file with mode: 0644]
gr-usrp/src/usrp1.i [new file with mode: 0644]
gr-usrp/src/usrp1_sink_base.cc [new file with mode: 0644]
gr-usrp/src/usrp1_sink_base.h [new file with mode: 0644]
gr-usrp/src/usrp1_sink_c.cc [new file with mode: 0644]
gr-usrp/src/usrp1_sink_c.h [new file with mode: 0644]
gr-usrp/src/usrp1_sink_s.cc [new file with mode: 0644]
gr-usrp/src/usrp1_sink_s.h [new file with mode: 0644]
gr-usrp/src/usrp1_source_base.cc [new file with mode: 0644]
gr-usrp/src/usrp1_source_base.h [new file with mode: 0644]
gr-usrp/src/usrp1_source_c.cc [new file with mode: 0644]
gr-usrp/src/usrp1_source_c.h [new file with mode: 0644]
gr-usrp/src/usrp1_source_s.cc [new file with mode: 0644]
gr-usrp/src/usrp1_source_s.h [new file with mode: 0644]
gr-usrp/src/usrp_multi.py [new file with mode: 0644]
gr-video-sdl/AUTHORS [new file with mode: 0644]
gr-video-sdl/ChangeLog [new file with mode: 0644]
gr-video-sdl/Makefile.am [new file with mode: 0644]
gr-video-sdl/src/Makefile.am [new file with mode: 0644]
gr-video-sdl/src/qa_video_sdl.py [new file with mode: 0755]
gr-video-sdl/src/run_tests.in [new file with mode: 0644]
gr-video-sdl/src/video_sdl.i [new file with mode: 0644]
gr-video-sdl/src/video_sdl_sink_s.cc [new file with mode: 0644]
gr-video-sdl/src/video_sdl_sink_s.h [new file with mode: 0644]
gr-video-sdl/src/video_sdl_sink_uc.cc [new file with mode: 0644]
gr-video-sdl/src/video_sdl_sink_uc.h [new file with mode: 0644]
gr-wxgui/ChangeLog [new file with mode: 0644]
gr-wxgui/Makefile.am [new file with mode: 0644]
gr-wxgui/README [new file with mode: 0644]
gr-wxgui/gr-wxgui.conf [new file with mode: 0644]
gr-wxgui/src/Makefile.am [new file with mode: 0644]
gr-wxgui/src/python/Makefile.am [new file with mode: 0644]
gr-wxgui/src/python/__init__.py [new file with mode: 0644]
gr-wxgui/src/python/fftsink.py [new file with mode: 0755]
gr-wxgui/src/python/form.py [new file with mode: 0755]
gr-wxgui/src/python/plot.py [new file with mode: 0644]
gr-wxgui/src/python/powermate.py [new file with mode: 0755]
gr-wxgui/src/python/scopesink.py [new file with mode: 0755]
gr-wxgui/src/python/slider.py [new file with mode: 0755]
gr-wxgui/src/python/stdgui.py [new file with mode: 0644]
gr-wxgui/src/python/waterfallsink.py [new file with mode: 0755]
pmt/AUTHORS [new file with mode: 0644]
pmt/ChangeLog [new file with mode: 0644]
pmt/Makefile.am [new file with mode: 0644]
pmt/README [new file with mode: 0644]
pmt/doc/Makefile.am [new file with mode: 0644]
pmt/src/Makefile.am [new file with mode: 0644]
pmt/src/lib/Makefile.am [new file with mode: 0644]
pmt/src/lib/pmt.cc [new file with mode: 0644]
pmt/src/lib/pmt.h [new file with mode: 0644]
pmt/src/lib/pmt_int.h [new file with mode: 0644]
pmt/src/lib/qa_pmt.cc [new file with mode: 0644]
pmt/src/lib/qa_pmt.h [new file with mode: 0644]
pmt/src/lib/qa_pmt_prims.cc [new file with mode: 0644]
pmt/src/lib/qa_pmt_prims.h [new file with mode: 0644]
pmt/src/lib/test_pmt.cc [new file with mode: 0644]
usrp/AUTHORS [new file with mode: 0644]
usrp/ChangeLog [new file with mode: 0644]
usrp/Makefile.am [new file with mode: 0644]
usrp/README [new file with mode: 0644]
usrp/doc/Doxyfile.in [new file with mode: 0644]
usrp/doc/Makefile.am [new file with mode: 0644]
usrp/doc/ddc.eps [new file with mode: 0644]
usrp/doc/ddc.png [new file with mode: 0644]
usrp/doc/other/Makefile.am [new file with mode: 0644]
usrp/doc/other/mainpage.dox [new file with mode: 0644]
usrp/doc/usrp-block-diagram.eps [new file with mode: 0644]
usrp/doc/usrp-block-diagram.png [new file with mode: 0644]
usrp/doc/usrp.jpg [new file with mode: 0644]
usrp/doc/usrp_guide.xml [new file with mode: 0644]
usrp/firmware/Makefile.am [new file with mode: 0644]
usrp/firmware/include/Makefile.am [new file with mode: 0644]
usrp/firmware/include/delay.h [new file with mode: 0644]
usrp/firmware/include/fpga_regs0.h [new file with mode: 0644]
usrp/firmware/include/fpga_regs_common.h [new file with mode: 0644]
usrp/firmware/include/fpga_regs_common.v [new file with mode: 0644]
usrp/firmware/include/fpga_regs_standard.h [new file with mode: 0644]
usrp/firmware/include/fpga_regs_standard.v [new file with mode: 0644]
usrp/firmware/include/fx2regs.h [new file with mode: 0644]
usrp/firmware/include/fx2utils.h [new file with mode: 0644]
usrp/firmware/include/generate_regs.py [new file with mode: 0755]
usrp/firmware/include/i2c.h [new file with mode: 0644]
usrp/firmware/include/isr.h [new file with mode: 0644]
usrp/firmware/include/syncdelay.h [new file with mode: 0644]
usrp/firmware/include/timer.h [new file with mode: 0644]
usrp/firmware/include/usb_common.h [new file with mode: 0644]
usrp/firmware/include/usb_descriptors.h [new file with mode: 0644]
usrp/firmware/include/usb_requests.h [new file with mode: 0644]
usrp/firmware/include/usrp_commands.h [new file with mode: 0644]
usrp/firmware/include/usrp_config.h [new file with mode: 0644]
usrp/firmware/include/usrp_i2c_addr.h [new file with mode: 0644]
usrp/firmware/include/usrp_ids.h [new file with mode: 0644]
usrp/firmware/include/usrp_interfaces.h [new file with mode: 0644]
usrp/firmware/include/usrp_spi_defs.h [new file with mode: 0644]
usrp/firmware/lib/Makefile.am [new file with mode: 0644]
usrp/firmware/lib/delay.c [new file with mode: 0644]
usrp/firmware/lib/fx2utils.c [new file with mode: 0644]
usrp/firmware/lib/i2c-compiler-bug.c [new file with mode: 0644]
usrp/firmware/lib/i2c.c [new file with mode: 0644]
usrp/firmware/lib/isr.c [new file with mode: 0644]
usrp/firmware/lib/timer.c [new file with mode: 0644]
usrp/firmware/lib/usb_common.c [new file with mode: 0644]
usrp/firmware/src/Makefile.am [new file with mode: 0644]
usrp/firmware/src/common/Makefile.am [new file with mode: 0644]
usrp/firmware/src/common/_startup.a51 [new file with mode: 0644]
usrp/firmware/src/common/_startup.a51.brittle [new file with mode: 0644]
usrp/firmware/src/common/blink_leds.c [new file with mode: 0644]
usrp/firmware/src/common/build_eeprom.py [new file with mode: 0755]
usrp/firmware/src/common/check_mdelay.c [new file with mode: 0644]
usrp/firmware/src/common/check_udelay.c [new file with mode: 0644]
usrp/firmware/src/common/edit-gpif [new file with mode: 0755]
usrp/firmware/src/common/fpga.h [new file with mode: 0644]
usrp/firmware/src/common/fpga_load.c [new file with mode: 0644]
usrp/firmware/src/common/fpga_load.h [new file with mode: 0644]
usrp/firmware/src/common/gpif.c [new file with mode: 0755]
usrp/firmware/src/common/gpif.gpf [new file with mode: 0755]
usrp/firmware/src/common/init_gpif.c [new file with mode: 0644]
usrp/firmware/src/common/usrp_common.c [new file with mode: 0644]
usrp/firmware/src/common/usrp_globals.h [new file with mode: 0644]
usrp/firmware/src/common/vectors.a51 [new file with mode: 0644]
usrp/firmware/src/usrp2/Makefile.am [new file with mode: 0644]
usrp/firmware/src/usrp2/_startup.a51 [new file with mode: 0644]
usrp/firmware/src/usrp2/blink_leds.c [new file with mode: 0644]
usrp/firmware/src/usrp2/board_specific.c [new file with mode: 0644]
usrp/firmware/src/usrp2/check_mdelay.c [new file with mode: 0644]
usrp/firmware/src/usrp2/check_udelay.c [new file with mode: 0644]
usrp/firmware/src/usrp2/edit-gpif [new file with mode: 0755]
usrp/firmware/src/usrp2/eeprom_boot.a51 [new file with mode: 0644]
usrp/firmware/src/usrp2/eeprom_init.c [new file with mode: 0644]
usrp/firmware/src/usrp2/eeprom_io.c [new file with mode: 0644]
usrp/firmware/src/usrp2/eeprom_io.h [new file with mode: 0644]
usrp/firmware/src/usrp2/fpga_load.c [new file with mode: 0644]
usrp/firmware/src/usrp2/fpga_rev2.c [new file with mode: 0644]
usrp/firmware/src/usrp2/fpga_rev2.h [new file with mode: 0644]
usrp/firmware/src/usrp2/gpif.c [new file with mode: 0644]
usrp/firmware/src/usrp2/gpif.gpf [new file with mode: 0755]
usrp/firmware/src/usrp2/init_gpif.c [new file with mode: 0644]
usrp/firmware/src/usrp2/spi.c [new file with mode: 0644]
usrp/firmware/src/usrp2/spi.h [new file with mode: 0644]
usrp/firmware/src/usrp2/usb_descriptors.a51 [new file with mode: 0644]
usrp/firmware/src/usrp2/usrp_common.c [new file with mode: 0644]
usrp/firmware/src/usrp2/usrp_common.h [new file with mode: 0644]
usrp/firmware/src/usrp2/usrp_main.c [new file with mode: 0644]
usrp/firmware/src/usrp2/usrp_rev2_regs.h [new file with mode: 0644]
usrp/firmware/src/usrp2/vectors.a51 [new file with mode: 0644]
usrp/fpga/Makefile.am [new file with mode: 0644]
usrp/fpga/Makefile.extra [new file with mode: 0644]
usrp/fpga/TODO [new file with mode: 0644]
usrp/fpga/gen_makefile_extra.py [new file with mode: 0755]
usrp/fpga/megacells/accum32.bsf [new file with mode: 0755]
usrp/fpga/megacells/accum32.cmp [new file with mode: 0755]
usrp/fpga/megacells/accum32.inc [new file with mode: 0755]
usrp/fpga/megacells/accum32.v [new file with mode: 0755]
usrp/fpga/megacells/accum32_bb.v [new file with mode: 0755]
usrp/fpga/megacells/accum32_inst.v [new file with mode: 0755]
usrp/fpga/megacells/add32.bsf [new file with mode: 0755]
usrp/fpga/megacells/add32.cmp [new file with mode: 0755]
usrp/fpga/megacells/add32.inc [new file with mode: 0755]
usrp/fpga/megacells/add32.v [new file with mode: 0755]
usrp/fpga/megacells/add32_bb.v [new file with mode: 0755]
usrp/fpga/megacells/add32_inst.v [new file with mode: 0755]
usrp/fpga/megacells/addsub16.bsf [new file with mode: 0755]
usrp/fpga/megacells/addsub16.cmp [new file with mode: 0755]
usrp/fpga/megacells/addsub16.inc [new file with mode: 0755]
usrp/fpga/megacells/addsub16.v [new file with mode: 0755]
usrp/fpga/megacells/addsub16_bb.v [new file with mode: 0755]
usrp/fpga/megacells/addsub16_inst.v [new file with mode: 0755]
usrp/fpga/megacells/bustri.bsf [new file with mode: 0755]
usrp/fpga/megacells/bustri.cmp [new file with mode: 0755]
usrp/fpga/megacells/bustri.inc [new file with mode: 0755]
usrp/fpga/megacells/bustri.v [new file with mode: 0755]
usrp/fpga/megacells/bustri_bb.v [new file with mode: 0755]
usrp/fpga/megacells/bustri_inst.v [new file with mode: 0755]
usrp/fpga/megacells/clk_doubler.v [new file with mode: 0644]
usrp/fpga/megacells/clk_doubler_bb.v [new file with mode: 0644]
usrp/fpga/megacells/dspclkpll.v [new file with mode: 0644]
usrp/fpga/megacells/dspclkpll_bb.v [new file with mode: 0644]
usrp/fpga/megacells/fifo_2k.v [new file with mode: 0644]
usrp/fpga/megacells/fifo_2k_bb.v [new file with mode: 0644]
usrp/fpga/megacells/fifo_4k.v [new file with mode: 0644]
usrp/fpga/megacells/fifo_4k_bb.v [new file with mode: 0644]
usrp/fpga/megacells/mylpm_addsub.bsf [new file with mode: 0755]
usrp/fpga/megacells/mylpm_addsub.cmp [new file with mode: 0755]
usrp/fpga/megacells/mylpm_addsub.inc [new file with mode: 0755]
usrp/fpga/megacells/mylpm_addsub.v [new file with mode: 0755]
usrp/fpga/megacells/mylpm_addsub_bb.v [new file with mode: 0755]
usrp/fpga/megacells/mylpm_addsub_inst.v [new file with mode: 0755]
usrp/fpga/megacells/pll.v [new file with mode: 0644]
usrp/fpga/megacells/pll_bb.v [new file with mode: 0644]
usrp/fpga/megacells/pll_inst.v [new file with mode: 0644]
usrp/fpga/megacells/sub32.bsf [new file with mode: 0755]
usrp/fpga/megacells/sub32.cmp [new file with mode: 0755]
usrp/fpga/megacells/sub32.inc [new file with mode: 0755]
usrp/fpga/megacells/sub32.v [new file with mode: 0755]
usrp/fpga/megacells/sub32_bb.v [new file with mode: 0755]
usrp/fpga/megacells/sub32_inst.v [new file with mode: 0755]
usrp/fpga/models/bustri.v [new file with mode: 0644]
usrp/fpga/models/fifo.v [new file with mode: 0644]
usrp/fpga/models/fifo_1c_1k.v [new file with mode: 0644]
usrp/fpga/models/fifo_1c_2k.v [new file with mode: 0644]
usrp/fpga/models/fifo_1c_4k.v [new file with mode: 0644]
usrp/fpga/models/fifo_1k.v [new file with mode: 0644]
usrp/fpga/models/fifo_2k.v [new file with mode: 0644]
usrp/fpga/models/fifo_4k.v [new file with mode: 0644]
usrp/fpga/models/pll.v [new file with mode: 0644]
usrp/fpga/models/ssram.v [new file with mode: 0644]
usrp/fpga/rbf/Makefile.am [new file with mode: 0644]
usrp/fpga/rbf/rev2/multi_2rxhb_2tx.rbf [new file with mode: 0755]
usrp/fpga/rbf/rev2/multi_4rx_0tx.rbf [new file with mode: 0755]
usrp/fpga/rbf/rev2/std_2rxhb_2tx.rbf [new file with mode: 0755]
usrp/fpga/rbf/rev2/std_4rx_0tx.rbf [new file with mode: 0755]
usrp/fpga/rbf/rev4/multi_2rxhb_2tx.rbf [new file with mode: 0755]
usrp/fpga/rbf/rev4/multi_4rx_0tx.rbf [new file with mode: 0755]
usrp/fpga/rbf/rev4/std_2rxhb_2tx.rbf [new file with mode: 0755]
usrp/fpga/rbf/rev4/std_4rx_0tx.rbf [new file with mode: 0755]
usrp/fpga/sdr_lib/adc_interface.v [new file with mode: 0644]
usrp/fpga/sdr_lib/bidir_reg.v [new file with mode: 0644]
usrp/fpga/sdr_lib/bus_interface.v [new file with mode: 0755]
usrp/fpga/sdr_lib/cic_decim.v [new file with mode: 0755]
usrp/fpga/sdr_lib/cic_int_shifter.v [new file with mode: 0644]
usrp/fpga/sdr_lib/cic_interp.v [new file with mode: 0755]
usrp/fpga/sdr_lib/clk_divider.v [new file with mode: 0755]
usrp/fpga/sdr_lib/cordic.v [new file with mode: 0755]
usrp/fpga/sdr_lib/cordic_stage.v [new file with mode: 0755]
usrp/fpga/sdr_lib/ddc.v [new file with mode: 0755]
usrp/fpga/sdr_lib/dpram.v [new file with mode: 0644]
usrp/fpga/sdr_lib/duc.v [new file with mode: 0755]
usrp/fpga/sdr_lib/ext_fifo.v [new file with mode: 0644]
usrp/fpga/sdr_lib/gen_cordic_consts.py [new file with mode: 0755]
usrp/fpga/sdr_lib/gen_sync.v [new file with mode: 0644]
usrp/fpga/sdr_lib/hb/acc.v [new file with mode: 0644]
usrp/fpga/sdr_lib/hb/coeff_ram.v [new file with mode: 0644]
usrp/fpga/sdr_lib/hb/coeff_rom.v [new file with mode: 0644]
usrp/fpga/sdr_lib/hb/halfband_decim.v [new file with mode: 0644]
usrp/fpga/sdr_lib/hb/halfband_interp.v [new file with mode: 0644]
usrp/fpga/sdr_lib/hb/hbd_tb/HBD [new file with mode: 0644]
usrp/fpga/sdr_lib/hb/hbd_tb/really_golden [new file with mode: 0644]
usrp/fpga/sdr_lib/hb/hbd_tb/regression [new file with mode: 0644]
usrp/fpga/sdr_lib/hb/hbd_tb/run_hbd [new file with mode: 0755]
usrp/fpga/sdr_lib/hb/hbd_tb/test_hbd.v [new file with mode: 0644]
usrp/fpga/sdr_lib/hb/mac.v [new file with mode: 0644]
usrp/fpga/sdr_lib/hb/mult.v [new file with mode: 0644]
usrp/fpga/sdr_lib/hb/ram16_2port.v [new file with mode: 0644]
usrp/fpga/sdr_lib/hb/ram16_2sum.v [new file with mode: 0644]
usrp/fpga/sdr_lib/hb/ram32_2sum.v [new file with mode: 0644]
usrp/fpga/sdr_lib/io_pins.v [new file with mode: 0644]
usrp/fpga/sdr_lib/master_control.v [new file with mode: 0644]
usrp/fpga/sdr_lib/master_control_multi.v [new file with mode: 0644]
usrp/fpga/sdr_lib/phase_acc.v [new file with mode: 0755]
usrp/fpga/sdr_lib/ram.v [new file with mode: 0644]
usrp/fpga/sdr_lib/ram16.v [new file with mode: 0644]
usrp/fpga/sdr_lib/ram32.v [new file with mode: 0644]
usrp/fpga/sdr_lib/ram64.v [new file with mode: 0644]
usrp/fpga/sdr_lib/rssi.v [new file with mode: 0644]
usrp/fpga/sdr_lib/rx_buffer.v [new file with mode: 0644]
usrp/fpga/sdr_lib/rx_chain.v [new file with mode: 0644]
usrp/fpga/sdr_lib/rx_chain_dual.v [new file with mode: 0644]
usrp/fpga/sdr_lib/rx_dcoffset.v [new file with mode: 0644]
usrp/fpga/sdr_lib/serial_io.v [new file with mode: 0644]
usrp/fpga/sdr_lib/setting_reg.v [new file with mode: 0644]
usrp/fpga/sdr_lib/setting_reg_masked.v [new file with mode: 0644]
usrp/fpga/sdr_lib/sign_extend.v [new file with mode: 0644]
usrp/fpga/sdr_lib/strobe_gen.v [new file with mode: 0644]
usrp/fpga/sdr_lib/tx_buffer.v [new file with mode: 0644]
usrp/fpga/sdr_lib/tx_chain.v [new file with mode: 0644]
usrp/fpga/sdr_lib/tx_chain_hb.v [new file with mode: 0644]
usrp/fpga/tb/cbus_tb.v [new file with mode: 0644]
usrp/fpga/tb/cordic_tb.v [new file with mode: 0644]
usrp/fpga/tb/decim_tb.v [new file with mode: 0644]
usrp/fpga/tb/fullchip_tb.v [new file with mode: 0755]
usrp/fpga/tb/interp_tb.v [new file with mode: 0755]
usrp/fpga/tb/justinterp_tb.v [new file with mode: 0644]
usrp/fpga/tb/makesine.pl [new file with mode: 0755]
usrp/fpga/tb/run_cordic [new file with mode: 0755]
usrp/fpga/tb/run_fullchip [new file with mode: 0755]
usrp/fpga/tb/usrp_tasks.v [new file with mode: 0755]
usrp/fpga/toplevel/mrfm/biquad_2stage.v [new file with mode: 0644]
usrp/fpga/toplevel/mrfm/biquad_6stage.v [new file with mode: 0644]
usrp/fpga/toplevel/mrfm/mrfm.csf [new file with mode: 0644]
usrp/fpga/toplevel/mrfm/mrfm.esf [new file with mode: 0644]
usrp/fpga/toplevel/mrfm/mrfm.psf [new file with mode: 0644]
usrp/fpga/toplevel/mrfm/mrfm.py [new file with mode: 0644]
usrp/fpga/toplevel/mrfm/mrfm.qpf [new file with mode: 0644]
usrp/fpga/toplevel/mrfm/mrfm.qsf [new file with mode: 0644]
usrp/fpga/toplevel/mrfm/mrfm.v [new file with mode: 0644]
usrp/fpga/toplevel/mrfm/mrfm.vh [new file with mode: 0644]
usrp/fpga/toplevel/mrfm/mrfm_compensator.v [new file with mode: 0644]
usrp/fpga/toplevel/mrfm/mrfm_fft.py [new file with mode: 0755]
usrp/fpga/toplevel/mrfm/mrfm_proc.v [new file with mode: 0644]
usrp/fpga/toplevel/mrfm/shifter.v [new file with mode: 0644]
usrp/fpga/toplevel/sizetest/sizetest.csf [new file with mode: 0644]
usrp/fpga/toplevel/sizetest/sizetest.psf [new file with mode: 0644]
usrp/fpga/toplevel/sizetest/sizetest.quartus [new file with mode: 0644]
usrp/fpga/toplevel/sizetest/sizetest.ssf [new file with mode: 0644]
usrp/fpga/toplevel/sizetest/sizetest.v [new file with mode: 0644]
usrp/fpga/toplevel/usrp_multi/usrp_multi.csf [new file with mode: 0644]
usrp/fpga/toplevel/usrp_multi/usrp_multi.esf [new file with mode: 0644]
usrp/fpga/toplevel/usrp_multi/usrp_multi.psf [new file with mode: 0644]
usrp/fpga/toplevel/usrp_multi/usrp_multi.qpf [new file with mode: 0644]
usrp/fpga/toplevel/usrp_multi/usrp_multi.qsf [new file with mode: 0644]
usrp/fpga/toplevel/usrp_multi/usrp_multi.v [new file with mode: 0644]
usrp/fpga/toplevel/usrp_multi/usrp_multi.vh [new file with mode: 0644]
usrp/fpga/toplevel/usrp_multi/usrp_multi_config_2rx_0tx.vh [new file with mode: 0644]
usrp/fpga/toplevel/usrp_multi/usrp_multi_config_2rxhb_0tx.vh [new file with mode: 0644]
usrp/fpga/toplevel/usrp_multi/usrp_multi_config_2rxhb_2tx.vh [new file with mode: 0644]
usrp/fpga/toplevel/usrp_multi/usrp_multi_config_4rx_0tx.vh [new file with mode: 0644]
usrp/fpga/toplevel/usrp_multi/usrp_std.vh [new file with mode: 0644]
usrp/fpga/toplevel/usrp_std/usrp_std.csf [new file with mode: 0644]
usrp/fpga/toplevel/usrp_std/usrp_std.esf [new file with mode: 0644]
usrp/fpga/toplevel/usrp_std/usrp_std.psf [new file with mode: 0644]
usrp/fpga/toplevel/usrp_std/usrp_std.qpf [new file with mode: 0644]
usrp/fpga/toplevel/usrp_std/usrp_std.qsf [new file with mode: 0644]
usrp/fpga/toplevel/usrp_std/usrp_std.v [new file with mode: 0644]
usrp/fpga/toplevel/usrp_std/usrp_std.vh [new file with mode: 0644]
usrp/fpga/toplevel/usrp_std/usrp_std_config_2rxhb_2tx.vh [new file with mode: 0644]
usrp/fpga/toplevel/usrp_std/usrp_std_config_4rx_0tx.vh [new file with mode: 0644]
usrp/host/Makefile.am [new file with mode: 0644]
usrp/host/apps/Makefile.am [new file with mode: 0644]
usrp/host/apps/burn-db-eeprom [new file with mode: 0755]
usrp/host/apps/burn-serial-number [new file with mode: 0755]
usrp/host/apps/check_order [new file with mode: 0755]
usrp/host/apps/check_order_quickly.cc [new file with mode: 0644]
usrp/host/apps/dump_12bit_shorts [new file with mode: 0755]
usrp/host/apps/dump_shorts [new file with mode: 0755]
usrp/host/apps/print-db [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 [new file with mode: 0644]
usrp/host/apps/test_usrp_standard_tx.cc [new file with mode: 0644]
usrp/host/apps/time_stuff.c [new file with mode: 0644]
usrp/host/apps/time_stuff.h [new file with mode: 0644]
usrp/host/apps/usrp_cal_dc_offset.cc [new file with mode: 0644]
usrp/host/apps/usrper.cc [new file with mode: 0644]
usrp/host/lib/Makefile.am [new file with mode: 0644]
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/dump_data.py [new file with mode: 0755]
usrp/host/lib/dxc-io-assignments.gnumeric [new file with mode: 0644]
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_linux.cc [new file with mode: 0644]
usrp/host/lib/fusb_linux.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_linux.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/md5.c [new file with mode: 0644]
usrp/host/lib/md5.h [new file with mode: 0644]
usrp/host/lib/mld_threads.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_basic.h [new file with mode: 0644]
usrp/host/lib/usrp_bytesex.h [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_local_sighandler.h [new file with mode: 0644]
usrp/host/lib/usrp_prims.cc [new file with mode: 0644]
usrp/host/lib/usrp_prims.h [new file with mode: 0644]
usrp/host/lib/usrp_slots.h [new file with mode: 0644]
usrp/host/lib/usrp_standard.cc [new file with mode: 0644]
usrp/host/lib/usrp_standard.h [new file with mode: 0644]
usrp/host/misc/Makefile.am [new file with mode: 0644]
usrp/host/misc/bug_work_around_8.cc [new file with mode: 0644]
usrp/host/misc/getopt.c [new file with mode: 0644]
usrp/host/misc/getopt.h [new file with mode: 0644]
usrp/host/misc/gettimeofday.c [new file with mode: 0644]
usrp/host/misc/mkstemp.c [new file with mode: 0644]
usrp/host/misc/tempname.c [new file with mode: 0644]
usrp/host/misc/usleep.c [new file with mode: 0644]
usrp/host/swig/Makefile.am [new file with mode: 0644]
usrp/host/swig/__init__.py [new file with mode: 0644]
usrp/host/swig/prims.i [new file with mode: 0644]
usrp/host/swig/usrp_fpga_regs.py [new file with mode: 0644]
usrp/host/swig/util.py [new file with mode: 0644]
usrp/usrp.inf [new file with mode: 0644]
usrp/usrp.iss.in [new file with mode: 0644]
usrp/usrp.pc.in [new file with mode: 0644]

diff --git a/AUTHORS b/AUTHORS
new file mode 100644 (file)
index 0000000..d1fb4dd
--- /dev/null
+++ b/AUTHORS
@@ -0,0 +1,12 @@
+Eric Blossom <eb@comsec.com>          Most of the guts
+Matt Ettus <matt@ettus.com>           ongoing code, ideas, bugfixes, the USRP
+John Gilmore  <gnu@toad.com>          ideas, bug fixes, financial support
+Stephane Fillod  <f8cfe@free.fr>       SIMD speed ups, lots of other good stuff
+Chuck Swiger  <cswiger@widomaker.com>  hf stuff, enthusiasm ;)
+Ramakrishnan Muthukrishnan <rkrishnan@symonds.net> Debian pkgs + misc stuff
+Martin Dudok van Heel <nldudok1@olifantasia.com> lots of stuff
+Bob McGwier N4HY <rwmcgwier@comcast.net>        wisdom, code, bugfixes.
+Krzysztof Kamieniecki <krys@kamieniecki.com>    bugfixes
+Andrew Thomas Beck <Andrew.Beck@postgrads.unisa.edu.au> bugfixes
+Joshua Lackey <jl@noether.uoregon.edu> Original GMSK implementation.
+Johnathan Corgan <jcorgan@aeinet.com>  Goertzel, squelch, adaptive filtering, misc.
diff --git a/COPYING b/COPYING
new file mode 100644 (file)
index 0000000..2b7b643
--- /dev/null
+++ b/COPYING
@@ -0,0 +1,340 @@
+                   GNU GENERAL PUBLIC LICENSE
+                      Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+     59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                           Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.)  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
+this service 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 make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  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.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+\f
+                   GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute 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 and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+  2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+\f
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of Sections
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable.  However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+\f
+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+  5. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+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
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+\f
+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the 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 a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+                           NO WARRANTY
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, 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.
+
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE 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.
+
+                    END OF TERMS AND CONDITIONS
+\f
+           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
+convey 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) 19yy <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 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
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) 19yy name of author
+    Gnomovision 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, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+  `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+  <signature of Ty Coon>, 1 April 1989
+  Ty Coon, President of Vice
+
+This 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 Library General
+Public License instead of this License.
diff --git a/ChangeLog b/ChangeLog
new file mode 100644 (file)
index 0000000..2237a4a
--- /dev/null
+++ b/ChangeLog
@@ -0,0 +1,20 @@
+#
+# Copyright 2001,2002,2003,2004,2005,2006 Free Software Foundation, Inc.
+# 
+# This file is part of GNU Radio
+# 
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 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.
+# 
diff --git a/INSTALL b/INSTALL
new file mode 100644 (file)
index 0000000..54caf7c
--- /dev/null
+++ b/INSTALL
@@ -0,0 +1,229 @@
+Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002 Free Software
+Foundation, Inc.
+
+   This file is free documentation; the Free Software Foundation gives
+unlimited permission to copy, distribute and modify it.
+
+Basic Installation
+==================
+
+   These are generic installation instructions.
+
+   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 only 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.  If you're
+     using `csh' on an old version of System V, you might need to type
+     `sh ./configure' instead to prevent `csh' from trying to execute
+     `configure' itself.
+
+     Running `configure' takes awhile.  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.
+
+  4. Type `make install' to install the programs and any data files and
+     documentation.
+
+  5. 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.
+
+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=c89 CFLAGS=-O2 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 must use a version of `make' that
+supports the `VPATH' variable, such as 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 `..'.
+
+   If you have to use a `make' that does not support the `VPATH'
+variable, you have 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.
+
+Installation Names
+==================
+
+   By default, `make install' will install the package's files in
+`/usr/local/bin', `/usr/local/man', etc.  You can specify an
+installation prefix other than `/usr/local' by giving `configure' the
+option `--prefix=PATH'.
+
+   You can specify separate installation prefixes for
+architecture-specific files and architecture-independent files.  If you
+give `configure' the option `--exec-prefix=PATH', the package will use
+PATH as the prefix for installing programs and libraries.
+Documentation and other data files will still use the regular prefix.
+
+   In addition, if you use an unusual directory layout you can give
+options like `--bindir=PATH' 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.
+
+   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'.
+
+Optional Features
+=================
+
+   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.
+
+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 `--target=TYPE' option 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
+
+will cause the specified gcc to be used as the C compiler (unless it is
+overridden in the site shell script).
+
+`configure' Invocation
+======================
+
+   `configure' recognizes the following options to control how it
+operates.
+
+`--help'
+`-h'
+     Print a summary of the options to `configure', and exit.
+
+`--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.
+
+`configure' also accepts some other, not widely useful, options.  Run
+`configure --help' for more details.
+
diff --git a/Makefile.am b/Makefile.am
new file mode 100644 (file)
index 0000000..883a490
--- /dev/null
@@ -0,0 +1,29 @@
+#
+# 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 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.
+# 
+
+include $(top_srcdir)/Makefile.common
+
+EXTRA_DIST =                           \
+       bootstrap                       \
+       configure                       \
+       config.h.in                     
+
+SUBDIRS = @subdirs@
diff --git a/Makefile.common b/Makefile.common
new file mode 100644 (file)
index 0000000..2259cac
--- /dev/null
@@ -0,0 +1,40 @@
+# -*- Makefile -*-
+#
+# 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 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.
+# 
+
+# includes
+grincludedir   = $(includedir)/gnuradio
+
+# swig includes 
+swigincludedir = $(grincludedir)/swig
+
+# Install this stuff in the appropriate subdirectory
+# This usually ends up at:
+#   ${prefix}/lib/python${python_version}/site-packages/gnuradio
+
+grpythondir = $(pythondir)/gnuradio
+grpyexecdir = $(pyexecdir)/gnuradio
+
+# swig flags
+SWIGPYTHONFLAGS = -fvirtual -python -modern
+
+# gnuradio-core library link command
+GNURADIO_CORE_LIBS = -L$(top_srcdir)/gnuradio-core/src/lib/.libs -lgnuradio-core -lfftw3f -lm
diff --git a/NEWS b/NEWS
new file mode 100644 (file)
index 0000000..d93a0dd
--- /dev/null
+++ b/NEWS
@@ -0,0 +1,15 @@
+-------------------------------------------------------
+Copying information:
+
+Copyright (C) 2001, Free Software Foundation, Inc.
+
+   Permission is granted to anyone to make or distribute verbatim copies
+   of this document as received, in any medium, provided that the
+   copyright notice and this permission notice are preserved,
+   thus giving the recipient permission to redistribute in turn.
+
+   Permission is granted to distribute modified versions
+   of this document, or of portions of it,
+   under the above conditions, provided also that they
+   carry prominent notices stating who last changed them.
+
diff --git a/README b/README
new file mode 100644 (file)
index 0000000..dfc0ac8
--- /dev/null
+++ b/README
@@ -0,0 +1,190 @@
+#
+# Copyright 2001,2002,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 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.
+# 
+
+-------------------------------------------------------------------------------
+
+                               IMPORTANT
+
+-------------------------------------------------------------------------------
+
+GNU Radio is now broken up into several packages.  You're looking at
+the gnuradio-core.  You'll probably want some or all of these too.
+Build and install them in the order listed here:
+
+  gnuradio-core     # main library
+  gnuradio-examples # examples
+  gr-audio-alsa     # support for sounds cards using ALSA (prefered under GNU/Linux)
+  gr-audio-oss      # support for sounds cards using OSS
+  gr-audio-jack     # support for JACK Audio Connection Kit
+  gr-audio-windows  # support for sounds cards using Windows Wave
+  gr-comedi         # support for DAQ cards using COMEDI
+  gr-wxgui         # GUI framework built on wxPython
+  usrp             # non-GNU Radio specific portion of usrp
+  gr-usrp          # glues usrp into GNU Radio
+  mc4020           # GNU/Linux driver for Measurement Computing PCI-DAS4020/12 A/D board
+  gr-mc4020        # the glue that ties the mc4020 driver into GNU Radio
+
+
+-------------------------------------------------------------------------------
+
+                      KNOWN INCOMPATIBILITIES
+
+
+  GNU Radio triggers bugs in g++ 3.3 for X86.  DO NOT USE GCC 3.3.
+  gcc 3.2 and 3.4 are known to work well.
+
+-------------------------------------------------------------------------------
+
+Prerequisites (you may already have these):
+
+(1)  pkgconfig 0.15.0 or later  http://www.freedesktop.org/Software/pkgconfig
+
+From the web site:
+
+pkgconfig is a system for managing library compile/link flags that
+works with automake and autoconf. It replaces the ubiquitous *-config
+scripts you may have seen with a single tool.
+
+
+(2)  FFTW 3.0 or later       http://www.fftw.org
+
+IMPORTANT!!!  When building FFTW, you MUST use the --enable-single and
+--enable-shared configure options.  This builds the single precision
+floating point version which we use.  You should also use either the
+--enable-3dnow or --enable-sse options if you're on an Athlon or Pentium
+respectively.
+
+
+(3) Python 2.3 or later              http://www.python.org
+
+Python 2.3 or later is now required.  If your distribution splits
+python into a bunch of separate RPMS including python-devel or
+libpython you'll most likely need those too.
+
+
+(4) Numeric python library   http://numeric.scipy.org
+
+Provides a high performance array type for Python.
+
+
+(5) The Boost C++ Libraries    http://www.boost.org
+
+We use the Smart Pointer library.  Fedore Core 2 has a package for
+this, boost-devel-1.31.0-7.  Otherwise download the source and follow
+the build instructions.  They're a bit different from the normal
+./configure && make
+
+
+(6) cppunit 1.9.14 or later.   http://cppunit.sourceforge.net
+
+Unit testing framework for C++.
+
+
+(7) Simple Wrapper Interface Generator.  http://www.swig.org
+
+These versions are known to work:
+  1.3.23, 1.3.24, 1.3.25, 1.3.27, 1.3.28, 1.3.29
+
+----------------------------------------------------------------
+
+For the impatient, just do the following:
+
+       $ ./configure
+       $ make
+       $ make check
+       $ make install
+
+If it doesn't work, fix it and send us a patch...
+
+
+See http://www.gnu.org/software/gnuradio/ for an overview.
+The project is hosted at http://savannah.gnu.org/projects/gnuradio/
+
+
+If you've got doxygen installed and provide the --enable-doxygen
+configure option, the build process creates documentation for the
+class hierarchy etc.  Point your browser at
+gnuradio-core/doc/html/index.html
+
+
+To run the examples you'll need to set PYTHONPATH.
+Note that the python version number in the path needs to match your
+installed version of python.
+
+  $ export PYTHONPATH=/usr/local/lib/python2.3/site-packages
+
+You may want to add this to your ~/.bash_profile
+
+
+
+----------------------------------------------------------------
+
+    Notes on building GNU Radio from the CVS repository
+
+----------------------------------------------------------------
+
+If you're building from the CVS repository YOU MUST BE PLAYING BY THE
+RULES THAT THE OTHER DEVELOPERS ARE USING.  This is especially true
+with regard to the versions of the tools below...
+
+Ensure that you've got THESE VERSIONS of the following tools:
+
+       autoconf 2.57    or later
+       automake 1.7.4   or later
+       libtool  1.5     or later
+       swig     1.3.{23,24,25,27,28,29}
+
+If you're using earlier versions than these, don't expect the system
+to build.  Get these versions or something later.  They're available
+at any of the GNU mirrors.
+
+Then, check out a copy of GNU Radio.  
+
+See http://www.gnu.org/software/gnuradio for directions on anonymous
+access to the CVS repository.
+
+Then in the top level directory, execute
+
+     $ ./bootstrap
+
+This builds configure from configure.ac and also builds all the
+Makefile.in's from the Makefile.am's.
+
+Then carry on as usual:
+
+     $ ./configure
+     $ make
+     $ make check
+     $ make install
+
+
+For the easiest way to build from CVS, see
+http://comsec.com/wiki?HowtoBuildFromCVS
+
+
+
+Another handy trick if for example your fftw includes and libs are
+installed in, say ~/local/include and ~/local/lib, instead of
+/usr/local is this:
+
+    $ export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$HOME/local/lib
+    $ make CPPFLAGS="-I$HOME/local/include"
+
diff --git a/bootstrap b/bootstrap
new file mode 100755 (executable)
index 0000000..7df375e
--- /dev/null
+++ b/bootstrap
@@ -0,0 +1,29 @@
+#!/bin/sh
+
+# 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 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.
+
+
+rm -fr config.cache autom4te*.cache
+
+aclocal -I config
+autoconf
+autoheader
+libtoolize --automake
+automake --add-missing
diff --git a/config.guess b/config.guess
new file mode 100755 (executable)
index 0000000..52c01be
--- /dev/null
@@ -0,0 +1,1465 @@
+#! /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 Free Software Foundation, Inc.
+
+timestamp='2005-11-11'
+
+# 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
+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 -q "$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 ;;
+           *) 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 ;;
+    macppc:MirBSD:*:*)
+       echo powerppc-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.*:*)
+       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:*:[45])
+       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:*:*)
+       echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
+       exit ;;
+    i*:CYGWIN*:*)
+       echo ${UNAME_MACHINE}-pc-cygwin
+       exit ;;
+    i*: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 ;;
+    x86:Interix*:[345]*)
+       echo i586-pc-interix${UNAME_RELEASE}|sed -e 's/\..*//'
+       exit ;;
+    [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:*:*)
+       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 | grep ^CPU=`
+       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 | grep ^CPU=`
+       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 ;;
+    x86_64:Linux:*:*)
+       echo x86_64-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
+       #ifdef __INTEL_COMPILER
+       LIBC=gnu
+       #else
+       LIBC=gnuaout
+       #endif
+       #endif
+       #ifdef __dietlibc__
+       LIBC=dietlibc
+       #endif
+EOF
+       eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=`
+       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 ;;
+    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 ;;
+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://savannah.gnu.org/cgi-bin/viewcvs/*checkout*/config/config/config.guess
+and
+  http://savannah.gnu.org/cgi-bin/viewcvs/*checkout*/config/config/config.sub
+
+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/config.sub b/config.sub
new file mode 100755 (executable)
index 0000000..a4aba16
--- /dev/null
@@ -0,0 +1,1587 @@
+#! /bin/sh
+# Configuration validation subroutine script.
+#   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+#   2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+
+timestamp='2005-11-13'
+
+# 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
+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-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 \
+       | bfin \
+       | c4x | clipper \
+       | d10v | d30v | dlx | dsp16xx \
+       | fr30 | frv \
+       | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
+       | i370 | i860 | i960 | ia64 \
+       | ip2k | iq2000 \
+       | m32r | m32rle | m68000 | m68k | 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 \
+       | mn10200 | mn10300 \
+       | ms1 \
+       | msp430 \
+       | ns16k | ns32k \
+       | or32 \
+       | pdp10 | pdp11 | pj | pjl \
+       | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \
+       | pyramid \
+       | sh | sh[1234] | sh[24]a | sh[23]e | sh[34]eb | shbe | shle | sh[1234]le | sh3ele \
+       | sh64 | sh64le \
+       | sparc | sparc64 | sparc64b | sparc86x | sparclet | sparclite \
+       | sparcv8 | sparcv9 | sparcv9b \
+       | strongarm \
+       | tahoe | thumb | tic4x | tic80 | tron \
+       | v850 | v850e \
+       | we32k \
+       | x86 | xscale | xscalee[bl] | xstormy16 | xtensa \
+       | z8k)
+               basic_machine=$basic_machine-unknown
+               ;;
+       m32c)
+               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)
+               ;;
+
+       # 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-* \
+       | bfin-* | bs2000-* \
+       | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \
+       | clipper-* | craynv-* | cydra-* \
+       | d10v-* | d30v-* | dlx-* \
+       | elxsi-* \
+       | f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \
+       | h8300-* | h8500-* \
+       | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
+       | i*86-* | i860-* | i960-* | ia64-* \
+       | ip2k-* | iq2000-* \
+       | 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-* \
+       | ms1-* \
+       | msp430-* \
+       | 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-* | shbe-* \
+       | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
+       | sparc-* | sparc64-* | sparc64b-* | sparc86x-* | sparclet-* \
+       | sparclite-* \
+       | sparcv8-* | sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \
+       | tahoe-* | thumb-* \
+       | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
+       | tron-* \
+       | v850-* | v850e-* | vax-* \
+       | we32k-* \
+       | x86-* | x86_64-* | xps100-* | xscale-* | xscalee[bl]-* \
+       | xstormy16-* | xtensa-* \
+       | ymp-* \
+       | z8k-*)
+               ;;
+       m32c-*)
+               ;;
+       # 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
+               ;;
+       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
+               ;;
+       cr16c)
+               basic_machine=cr16c-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
+               ;;
+       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
+               ;;
+       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
+               ;;
+       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
+               ;;
+       pbd)
+               basic_machine=sparc-tti
+               ;;
+       pbb)
+               basic_machine=m68k-tti
+               ;;
+       pc532 | pc532-*)
+               basic_machine=ns32k-pc532
+               ;;
+       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
+               ;;
+       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
+               ;;
+       sei)
+               basic_machine=mips-sei
+               os=-seiux
+               ;;
+       sequent)
+               basic_machine=i386-sequent
+               ;;
+       sh)
+               basic_machine=sh-hitachi
+               os=-hms
+               ;;
+       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
+               ;;
+       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)
+               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* \
+             | -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-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*)
+       # 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
+       *-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
+               ;;
+       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/config/Makefile.am b/config/Makefile.am
new file mode 100644 (file)
index 0000000..fd33c62
--- /dev/null
@@ -0,0 +1,66 @@
+#
+# 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 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.
+# 
+
+include $(top_srcdir)/Makefile.common
+
+# Install m4 macros in this directory
+m4datadir = $(datadir)/aclocal
+
+# List your m4 macros here
+m4macros =                     \
+       acx_pthread.m4          \
+       bnv_have_qt.m4          \
+       cppunit.m4              \
+       gr_as.m4                \
+       gr_boost.m4             \
+       gr_check_createfilemapping.m4 \
+       gr_check_usrp.m4        \
+       gr_check_mc4020.m4      \
+       gr_check_shm_open.m4    \
+       gr_doxygen.m4           \
+       gr_gprof.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_swig.m4              \
+       gr_sysv_shm.m4          \
+       gr_x86_64.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/config/acx_pthread.m4 b/config/acx_pthread.m4
new file mode 100644 (file)
index 0000000..d318ab0
--- /dev/null
@@ -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
diff --git a/config/bnv_have_qt.m4 b/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/config/cppunit.m4 b/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/config/gr_as.m4 b/config/gr_as.m4
new file mode 100644 (file)
index 0000000..a069547
--- /dev/null
@@ -0,0 +1,34 @@
+# Figure out how to run the assembler.             -*- Autoconf -*-
+
+# serial 2
+
+# Copyright 2001 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, 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.
+
+# I just copy and renamed this from automake-1.6.3 so we should work 
+# under both 1.4-p6 and later.  -eb
+
+# GR_PROG_AS
+# ----------
+AC_DEFUN([GR_PROG_AS],
+[# By default we simply use the C compiler to build assembly code.
+AC_REQUIRE([AC_PROG_CC])
+: ${CCAS='$(CC)'}
+# Set ASFLAGS if not already set.
+: ${CCASFLAGS='$(CFLAGS)'}
+AC_SUBST(CCAS)
+AC_SUBST(CCASFLAGS)])
diff --git a/config/gr_atsc.m4 b/config/gr_atsc.m4
new file mode 100644 (file)
index 0000000..e409667
--- /dev/null
@@ -0,0 +1,36 @@
+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 2, 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., 59 Temple Place - Suite 330,
+dnl Boston, MA 02111-1307, USA.
+
+AC_DEFUN([GR_ATSC],[
+    AC_CONFIG_SRCDIR([gr-atsc/src/lib/atsc.i])
+
+    AC_CONFIG_FILES([\
+       gr-atsc/Makefile \
+       gr-atsc/doc/Makefile \
+       gr-atsc/src/Makefile \
+       gr-atsc/src/lib/Makefile \
+       gr-atsc/src/python/Makefile \
+       gr-atsc/src/python/run_tests \
+    ])
+
+    dnl run_tests is created from run_tests.in.  Make it executable.
+    AC_CONFIG_COMMANDS([run_tests_atsc], [chmod +x gr-atsc/src/python/run_tests])
+
+    subdirs="$subdirs gr-atsc"
+])
diff --git a/config/gr_audio_alsa.m4 b/config/gr_audio_alsa.m4
new file mode 100644 (file)
index 0000000..2675ec9
--- /dev/null
@@ -0,0 +1,41 @@
+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 2, 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., 59 Temple Place - Suite 330,
+dnl Boston, MA 02111-1307, USA.
+
+AC_DEFUN([GR_AUDIO_ALSA],[
+    AC_CONFIG_SRCDIR([gr-audio-alsa/src/audio_alsa.i])
+
+    succeeded=yes
+    PKG_CHECK_MODULES(ALSA, alsa >= 0.9,[],[succeeded=no])
+    if test $succeeded = yes; then
+        LIBS="$LIBS $ALSA_LIBS"
+
+        AC_CONFIG_FILES([\
+         gr-audio-alsa/Makefile \
+         gr-audio-alsa/src/Makefile \
+         gr-audio-alsa/src/run_tests \
+       ])
+
+       dnl run_tests is created from run_tests.in.  Make it executable.
+        AC_CONFIG_COMMANDS([run_tests_alsa], [chmod +x gr-audio-alsa/src/run_tests])
+        subdirs="$subdirs gr-audio-alsa"
+    else
+       AC_MSG_RESULT([failed: $ALSA_PKG_ERRORS])
+       failed="$failed gr-audio-alsa"
+    fi
+])
diff --git a/config/gr_audio_jack.m4 b/config/gr_audio_jack.m4
new file mode 100644 (file)
index 0000000..628ce03
--- /dev/null
@@ -0,0 +1,41 @@
+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 2, 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., 59 Temple Place - Suite 330,
+dnl Boston, MA 02111-1307, USA.
+
+AC_DEFUN([GR_AUDIO_JACK],[
+    AC_CONFIG_SRCDIR([gr-audio-jack/src/audio_jack.i])
+
+    succeeded=yes
+    PKG_CHECK_MODULES(JACK, jack >= 0.8,[],[succeeded=no])
+    if test $succeeded = yes; then
+        LIBS="$LIBS $JACK_LIBS"
+
+        AC_CONFIG_FILES([\
+          gr-audio-jack/Makefile \
+          gr-audio-jack/src/Makefile \
+         gr-audio-jack/src/run_tests \
+       ])
+
+       dnl run_tests is created from run_tests.in.  Make it executable.
+        AC_CONFIG_COMMANDS([run_tests_jack], [chmod +x gr-audio-jack/src/run_tests])
+        subdirs="$subdirs gr-audio-jack"
+    else
+       AC_MSG_RESULT([failed: $JACK_PKG_ERRORS])
+       failed="$failed gr-audio-jack"
+    fi
+])
diff --git a/config/gr_audio_oss.m4 b/config/gr_audio_oss.m4
new file mode 100644 (file)
index 0000000..c8dfebe
--- /dev/null
@@ -0,0 +1,45 @@
+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 2, 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., 59 Temple Place - Suite 330,
+dnl Boston, MA 02111-1307, USA.
+
+AC_DEFUN([GR_AUDIO_OSS],[
+    AC_CONFIG_SRCDIR([gr-audio-oss/src/audio_oss.i])
+
+    succeeded=yes
+
+    dnl needed for NetBSD
+    dnl FIXME: conditionalize on NetBSD platform
+    dnl AC_HAVE_LIBRARY(ossaudio,[],[succeeded=no])
+
+    AC_CHECK_HEADER(sys/soundcard.h,[],[succeeded=no])
+    if test $succeeded = yes; then
+
+        AC_CONFIG_FILES([\
+         gr-audio-oss/Makefile \
+         gr-audio-oss/src/Makefile \
+         gr-audio-oss/src/run_tests \
+       ])
+
+       dnl run_tests is created from run_tests.in.  Make it executable.
+        AC_CONFIG_COMMANDS([run_tests_oss], [chmod +x gr-audio-oss/src/run_tests])
+        subdirs="$subdirs gr-audio-oss"
+    else
+       AC_MSG_RESULT([failed: $OSS_PKG_ERRORS])
+       failed="$failed gr-audio-oss"
+    fi
+])
diff --git a/config/gr_audio_osx.m4 b/config/gr_audio_osx.m4
new file mode 100644 (file)
index 0000000..2ddb4b3
--- /dev/null
@@ -0,0 +1,38 @@
+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 2, 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., 59 Temple Place - Suite 330,
+dnl Boston, MA 02111-1307, USA.
+
+AC_DEFUN([GR_AUDIO_OSX],[
+    AC_CONFIG_SRCDIR([gr-audio-osx/src/audio_osx.i])
+
+    succeeded=yes
+    MACOSX_AUDIOUNIT([],[succeeded=no])
+    if test $succeeded = yes; then
+        AC_CONFIG_FILES([\
+         gr-audio-osx/Makefile \
+         gr-audio-osx/src/Makefile \
+         gr-audio-osx/src/run_tests \
+       ])
+
+       dnl run_tests is created from run_tests.in.  Make it executable.
+        AC_CONFIG_COMMANDS([run_tests_osx], [chmod +x gr-audio-osx/src/run_tests])
+        subdirs="$subdirs gr-audio-osx"
+    else
+       failed="$failed gr-audio-osx"
+    fi
+])
diff --git a/config/gr_audio_portaudio.m4 b/config/gr_audio_portaudio.m4
new file mode 100644 (file)
index 0000000..2ad3719
--- /dev/null
@@ -0,0 +1,43 @@
+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 2, 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., 59 Temple Place - Suite 330,
+dnl Boston, MA 02111-1307, USA.
+
+AC_DEFUN([GR_AUDIO_PORTAUDIO],[
+    AC_CONFIG_SRCDIR([gr-audio-portaudio/src/audio_portaudio.i])
+
+    succeeded=yes
+    #PKG_CHECK_MODULES(PORTAUDIO, portaudio-2.0 >= 19,[],[succeeded=no])
+    AC_HAVE_LIBRARY([portaudio], [], [succeeded=no])
+    AC_CHECK_HEADER([portaudio.h], [], [succeeded=no])
+    if test $succeeded = yes; then
+        LIBS="$LIBS -lportaudio"
+
+        AC_CONFIG_FILES([\
+         gr-audio-portaudio/Makefile \
+         gr-audio-portaudio/src/Makefile \
+         gr-audio-portaudio/src/run_tests \
+       ])
+
+       dnl run_tests is created from run_tests.in.  Make it executable.
+        AC_CONFIG_COMMANDS([run_tests_portaudio], [chmod +x gr-audio-portaudio/src/run_tests])
+        subdirs="$subdirs gr-audio-portaudio"
+    else
+       AC_MSG_RESULT([failed: $PORTAUDIO_PKG_ERRORS])
+       failed="$failed gr-audio-portaudio"
+    fi
+])
diff --git a/config/gr_audio_windows.m4 b/config/gr_audio_windows.m4
new file mode 100644 (file)
index 0000000..d0a445e
--- /dev/null
@@ -0,0 +1,39 @@
+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 2, 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., 59 Temple Place - Suite 330,
+dnl Boston, MA 02111-1307, USA.
+
+AC_DEFUN([GR_AUDIO_WINDOWS],[
+    AC_CONFIG_SRCDIR([gr-audio-windows/src/audio_windows.i])
+
+    succeeded=yes
+    AC_HAVE_LIBRARY(winmm,[],[succeeded=no])
+
+    if test $succeeded = yes; then
+        AC_CONFIG_FILES([\
+         gr-audio-windows/Makefile \
+         gr-audio-windows/src/Makefile \
+         gr-audio-windows/src/run_tests \
+       ])
+
+       dnl run_tests is created from run_tests.in.  Make it executable.
+        AC_CONFIG_COMMANDS([run_tests_windows], [chmod +x gr-audio-windows/src/run_tests])
+        subdirs="$subdirs gr-audio-windows"
+    else
+       failed="$failed gr-audio-windows"
+    fi
+])
diff --git a/config/gr_boost.m4 b/config/gr_boost.m4
new file mode 100644 (file)
index 0000000..b1751c0
--- /dev/null
@@ -0,0 +1,111 @@
+dnl
+dnl Copyright 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 2, 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., 59 Temple Place - Suite 330,
+dnl Boston, MA 02111-1307, USA.
+dnl
+
+dnl This tries to do the "right thing" to locate the boost include files.
+dnl If the user explicitly specified --with-boost-include-dir=<foo>
+dnl we believe them and use it.  Otherwise,
+dnl
+dnl We look for boost/shared_ptr.hpp in the "normal places".  That is,
+dnl wherever AC_CHECK_HEADER looks.  If the boost includes are in /usr/local/include
+dnl this step will find them.
+dnl
+dnl Otherwise, we check to see if the boost stuff was installed in a version-specific
+dnl directory under /usr/local/include.  These look like: /usr/local/include/boost-1_33_1
+dnl If there's more than one version installed, we select the
+dnl lexicographically greatest one.
+dnl
+dnl If none of these work, we bail.
+
+AC_DEFUN([GR_REQUIRE_BOOST_INCLUDES],
+[
+  AC_LANG_PUSH(C++)
+  gr_boost_include_dir=
+  AC_ARG_WITH([boost-include-dir],
+    AC_HELP_STRING([--with-boost-include-dir=<path>],
+                  [path to boost c++ include files]),
+    [
+      # "yes" and "no" are bogus answers
+      if test x"$with_boost_include_dir" == xyes ||
+         test x"$with_boost_include_dir" == xno; then
+       gr_boost_include_dir=
+      else
+        gr_boost_include_dir=$with_boost_include_dir
+      fi
+    ])
+  echo "gr_boost_include_dir = $gr_boost_include_dir"
+  if test x$gr_boost_include_dir != x; then
+    #
+    # If the user specified a directory, then we use it
+    #
+    OLD_CPPFLAGS=$CPPFLAGS
+    CPPFLAGS="$CPPFLAGS -I$gr_boost_include_dir"
+    AC_CHECK_HEADER([boost/shared_ptr.hpp],
+      [BOOST_CFLAGS="-I$gr_boost_include_dir"],
+      [AC_MSG_ERROR(
+        [Failed to locate boost/shared_ptr.hpp.
+Try using --with-boost-include-dir=<path>, 
+E.g., --with-boost-include-dir=/usr/local/include/boost-1_33_1])])
+    CPPFLAGS=$OLD_CPPFLAGS
+  else
+    #
+    # Otherwise we check in the default places
+    # 
+    AC_CHECK_HEADER([boost/shared_ptr.hpp],
+      [BOOST_CFLAGS=""],
+      [ # Nope, look for latest version if any in $prefix/include/boost-*
+
+        # Wipe out cached value.  KLUDGE: AC should have API for this
+       unset AS_TR_SH([ac_cv_header_boost/shared_ptr.hpp])
+
+       boost_last_match(){
+         #echo "boost_last_match: [$]*"
+         pattern="[$]1"
+         shift
+         if test "[$]pattern" = "[$]1"
+         then
+           LM=''
+         else
+           shift `expr [$]# - 1`
+           LM=[$]1
+         fi
+         #echo "LM(1)='[$]LM'"
+       }
+
+       pattern="/usr/local/include/boost-*"
+       boost_last_match "$pattern" $pattern
+       #echo "LM(2)='$LM'"
+
+        OLD_CPPFLAGS=$CPP_FLAGS
+        CPPFLAGS="$CPPFLAGS -I$LM"
+        AC_CHECK_HEADER([boost/shared_ptr.hpp],
+          [BOOST_CFLAGS="-I$LM"],
+          [AC_MSG_ERROR(
+            [Failed to locate boost/shared_ptr.hpp.  
+Try using --with-boost-include-dir=<path>, 
+E.g., --with-boost-include-dir=/usr/local/include/boost-1_33_1])])
+        CPPFLAGS=$OLD_CPPFLAGS
+      ])
+
+   fi
+   unset boost_last_match LM
+   AC_LANG_POP
+   AC_SUBST(BOOST_CFLAGS)
+])
diff --git a/config/gr_check_createfilemapping.m4 b/config/gr_check_createfilemapping.m4
new file mode 100644 (file)
index 0000000..9cb94f5
--- /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 2, 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., 59 Temple Place - Suite 330,
+dnl Boston, MA 02111-1307, 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/config/gr_check_mc4020.m4 b/config/gr_check_mc4020.m4
new file mode 100644 (file)
index 0000000..0c4318e
--- /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 2, 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., 59 Temple Place - Suite 330,
+dnl Boston, MA 02111-1307, 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/config/gr_check_shm_open.m4 b/config/gr_check_shm_open.m4
new file mode 100644 (file)
index 0000000..27c9ee6
--- /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 2, 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., 59 Temple Place - Suite 330,
+dnl Boston, MA 02111-1307, 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/config/gr_check_usrp.m4 b/config/gr_check_usrp.m4
new file mode 100644 (file)
index 0000000..b818a69
--- /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 2, 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., 59 Temple Place - Suite 330,
+dnl Boston, MA 02111-1307, 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/config/gr_comedi.m4 b/config/gr_comedi.m4
new file mode 100644 (file)
index 0000000..89ee30f
--- /dev/null
@@ -0,0 +1,41 @@
+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 2, 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., 59 Temple Place - Suite 330,
+dnl Boston, MA 02111-1307, USA.
+
+AC_DEFUN([GR_COMEDI],[
+    AC_CONFIG_SRCDIR([gr-comedi/src/comedi.i])
+
+    succeeded=yes
+    PKG_CHECK_MODULES(COMEDI, comedilib >= 0.7,[],[succeeded=no])
+    if test $succeeded = yes; then
+        LIBS="$LIBS $COMEDI_LIBS"
+
+        AC_CONFIG_FILES([\
+         gr-comedi/Makefile \
+         gr-comedi/src/Makefile \
+         gr-comedi/src/run_tests \
+       ])
+
+       dnl run_tests is created from run_tests.in.  Make it executable.
+        AC_CONFIG_COMMANDS([run_tests_comedi], [chmod +x gr-comedi/src/run_tests])
+        subdirs="$subdirs gr-comedi"
+    else
+       AC_MSG_WARN([$COMEDI_PKG_ERRORS])
+       failed="$failed gr-comedi"
+    fi
+])
diff --git a/config/gr_doxygen.m4 b/config/gr_doxygen.m4
new file mode 100644 (file)
index 0000000..82aea35
--- /dev/null
@@ -0,0 +1,59 @@
+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 2, 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., 59 Temple Place - Suite 330,
+dnl Boston, MA 02111-1307, USA.
+dnl 
+
+AC_DEFUN([GR_CHECK_DOXYGEN],[
+  AC_ARG_ENABLE(doxygen, [  --enable-doxygen        enable documentation generation with doxygen (no)])
+  AC_ARG_ENABLE(dot, [  --enable-dot            use 'dot' to generate graphs in doxygen (auto)])
+  AC_ARG_ENABLE(html-docs, [  --enable-html-docs      enable HTML generation with doxygen (yes)], [], [ enable_html_docs=yes])
+  AC_ARG_ENABLE(latex-docs, [  --enable-latex-docs     enable LaTeX doc generation with doxygen (no)], [], [ enable_latex_docs=no])
+
+  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_html_docs)
+  AC_SUBST(enable_latex_docs)
+  AC_SUBST(generate_docs)
+])
diff --git a/config/gr_error_correcting_codes.m4 b/config/gr_error_correcting_codes.m4
new file mode 100644 (file)
index 0000000..84d5560
--- /dev/null
@@ -0,0 +1,38 @@
+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 2, 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., 59 Temple Place - Suite 330,
+dnl Boston, MA 02111-1307, USA.
+
+AC_DEFUN([GR_ERROR_CORRECTING_CODES],[
+    AC_CONFIG_SRCDIR([gr-error-correcting-codes/src/lib/ecc.i])
+
+    AC_CONFIG_FILES([\
+       gr-error-correcting-codes/Makefile \
+       gr-error-correcting-codes/src/Makefile \
+       gr-error-correcting-codes/src/lib/Makefile \
+       gr-error-correcting-codes/src/lib/libecc/Makefile \
+       gr-error-correcting-codes/src/lib/libecc/mld/Makefile \
+       gr-error-correcting-codes/src/lib/libecc/tests/Makefile \
+       gr-error-correcting-codes/src/python/Makefile \
+       gr-error-correcting-codes/src/python/run_tests \
+    ])
+
+    dnl run_tests is created from run_tests.in.  Make it executable.
+    AC_CONFIG_COMMANDS([run_tests_error_correcting_codes], [chmod +x gr-error-correcting-codes/src/python/run_tests])
+
+    subdirs="$subdirs gr-error-correcting-codes"
+])
diff --git a/config/gr_fortran.m4 b/config/gr_fortran.m4
new file mode 100644 (file)
index 0000000..345936f
--- /dev/null
@@ -0,0 +1,31 @@
+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 2, 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., 59 Temple Place - Suite 330,
+dnl Boston, MA 02111-1307, 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, [  --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
+])
diff --git a/config/gr_gnuradio_core.m4 b/config/gr_gnuradio_core.m4
new file mode 100644 (file)
index 0000000..661555e
--- /dev/null
@@ -0,0 +1,63 @@
+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 2, 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., 59 Temple Place - Suite 330,
+dnl Boston, MA 02111-1307, USA.
+
+AC_DEFUN([GR_GNURADIO_CORE],[
+    AC_CONFIG_SRCDIR([gnuradio-core/src/lib/runtime/gr_vmcircbuf.cc])
+
+    AC_CONFIG_FILES([ \
+         gnuradio-core/Makefile
+         gnuradio-core/gnuradio-core.pc \
+         gnuradio-core/doc/Doxyfile \
+         gnuradio-core/doc/Makefile \
+         gnuradio-core/doc/other/Makefile \
+         gnuradio-core/doc/xml/Makefile \
+         gnuradio-core/src/Makefile \
+         gnuradio-core/src/gen_interpolator_taps/Makefile \
+         gnuradio-core/src/lib/Makefile \
+         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/io/Makefile \
+         gnuradio-core/src/lib/missing/Makefile \
+         gnuradio-core/src/lib/omnithread/Makefile \
+         gnuradio-core/src/lib/reed-solomon/Makefile \
+         gnuradio-core/src/lib/runtime/Makefile \
+         gnuradio-core/src/lib/swig/Makefile \
+         gnuradio-core/src/python/Makefile \
+         gnuradio-core/src/python/bin/Makefile \
+         gnuradio-core/src/python/gnuradio/Makefile \
+         gnuradio-core/src/python/gnuradio/blks/Makefile \
+         gnuradio-core/src/python/gnuradio/blksimpl/Makefile \
+         gnuradio-core/src/python/gnuradio/gr/Makefile \
+         gnuradio-core/src/python/gnuradio/gr/run_tests \
+         gnuradio-core/src/python/gnuradio/gru/Makefile \
+         gnuradio-core/src/python/gnuradio/gruimpl/Makefile \
+         gnuradio-core/src/tests/Makefile \
+         gnuradio-core/src/utils/Makefile \
+       ])
+
+    dnl run_tests is created from run_tests.in.  Make it executable.
+    AC_CONFIG_COMMANDS([run_tests_core], [chmod +x gnuradio-core/src/python/gnuradio/gr/run_tests])
+
+    dnl kludge up initial swig dependency file
+    AC_CONFIG_COMMANDS([swig_deps], [touch gnuradio-core/src/lib/swig/gnuradio_swig_python.d])
+
+    subdirs="$subdirs gnuradio-core"
+])
diff --git a/config/gr_gnuradio_examples.m4 b/config/gr_gnuradio_examples.m4
new file mode 100644 (file)
index 0000000..6ab51a2
--- /dev/null
@@ -0,0 +1,35 @@
+# Copyright 2001,2002,2003,2004,2005,2006 Free Software Foundation, Inc.
+# 
+# This file is part of GNU Radio
+# 
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 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.
+
+AC_DEFUN([GR_GNURADIO_EXAMPLES],[
+    AC_CONFIG_SRCDIR([gnuradio-examples/README])
+
+    AC_CONFIG_FILES([\
+         gnuradio-examples/Makefile \
+         gnuradio-examples/python/Makefile \
+         gnuradio-examples/python/audio/Makefile \
+         gnuradio-examples/python/digital_voice/Makefile \
+         gnuradio-examples/python/gmsk2/Makefile \
+         gnuradio-examples/python/mc4020/Makefile \
+         gnuradio-examples/python/usrp/Makefile \
+         gnuradio-examples/python/multi_usrp/Makefile \
+       ])
+
+    subdirs="$subdirs gnuradio-examples"
+])
diff --git a/config/gr_gprof.m4 b/config/gr_gprof.m4
new file mode 100644 (file)
index 0000000..cc50508
--- /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 2, 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., 59 Temple Place - Suite 330,
+dnl Boston, MA 02111-1307, 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/config/gr_gsm_fr_vocoder.m4 b/config/gr_gsm_fr_vocoder.m4
new file mode 100644 (file)
index 0000000..97408e9
--- /dev/null
@@ -0,0 +1,36 @@
+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 2, 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., 59 Temple Place - Suite 330,
+dnl Boston, MA 02111-1307, USA.
+
+AC_DEFUN([GR_GSM_FR_VOCODER],[
+    AC_CONFIG_SRCDIR([gr-gsm-fr-vocoder/src/lib/gsm_full_rate.i])
+
+    AC_CONFIG_FILES([\
+       gr-gsm-fr-vocoder/Makefile \
+       gr-gsm-fr-vocoder/src/Makefile \
+       gr-gsm-fr-vocoder/src/lib/Makefile \
+       gr-gsm-fr-vocoder/src/lib/gsm/Makefile \
+       gr-gsm-fr-vocoder/src/python/Makefile \
+       gr-gsm-fr-vocoder/src/python/run_tests \
+    ])
+
+    dnl run_tests is created from run_tests.in.  Make it executable.
+    AC_CONFIG_COMMANDS([run_tests_gsm], [chmod +x gr-gsm-fr-vocoder/src/python/run_tests])
+
+    subdirs="$subdirs gr-gsm-fr-vocoder"
+])
diff --git a/config/gr_libgnuradio_core_extra_ldflags.m4 b/config/gr_libgnuradio_core_extra_ldflags.m4
new file mode 100644 (file)
index 0000000..491f7a0
--- /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 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.
+
+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/config/gr_no_undefined.m4 b/config/gr_no_undefined.m4
new file mode 100644 (file)
index 0000000..8780fab
--- /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 2, 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., 59 Temple Place - Suite 330,
+dnl Boston, MA 02111-1307, 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/config/gr_omnithread.m4 b/config/gr_omnithread.m4
new file mode 100644 (file)
index 0000000..7c3150b
--- /dev/null
@@ -0,0 +1,51 @@
+# Check for Omnithread (pthread/NT) thread 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 2, 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.
+
+AC_DEFUN([GR_OMNITHREAD],
+[
+  # Check first for POSIX
+  ACX_PTHREAD(
+  [ ot_posix="yes"
+    AC_DEFINE(OMNITHREAD_POSIX,[1],[Define to 1 to enable pthread])
+  ],[
+    # 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"
+       AC_DEFINE(OMNITHREAD_NT,[1],[Define to 1 to enable NT thread])
+      ],
+      [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/config/gr_pmt.m4 b/config/gr_pmt.m4
new file mode 100644 (file)
index 0000000..573f07d
--- /dev/null
@@ -0,0 +1,34 @@
+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 2, 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., 59 Temple Place - Suite 330,
+dnl Boston, MA 02111-1307, USA.
+
+AC_DEFUN([GR_PMT],[
+    AC_CONFIG_SRCDIR([pmt/src/lib/pmt.h])
+
+    AC_CONFIG_FILES([\
+       pmt/Makefile \
+       pmt/doc/Makefile \
+       pmt/src/Makefile \
+       pmt/src/lib/Makefile
+    ])
+
+    dnl run_tests is created from run_tests.in.  Make it executable.
+    dnl AC_CONFIG_COMMANDS([run_tests_pmt], [chmod +x pmt/src/python/run_tests])
+
+    subdirs="$subdirs pmt"
+])
diff --git a/config/gr_pwin32.m4 b/config/gr_pwin32.m4
new file mode 100644 (file)
index 0000000..5f748af
--- /dev/null
@@ -0,0 +1,146 @@
+# 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 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.
+
+
+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
+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/config/gr_python.m4 b/config/gr_python.m4
new file mode 100644 (file)
index 0000000..760a0f7
--- /dev/null
@@ -0,0 +1,116 @@
+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 2, 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., 59 Temple Place - Suite 330,
+dnl Boston, MA 02111-1307, USA.
+dnl 
+
+# PYTHON_DEVEL()
+#
+# Checks for Python and tries to get the include path to 'Python.h'.
+# It provides the $(PYTHON_CPPFLAGS) and $(PYTHON_LDFLAGS) output variables.
+#
+AC_DEFUN([PYTHON_DEVEL],[
+       AC_REQUIRE([AM_PATH_PYTHON])
+       AC_REQUIRE([AC_CANONICAL_HOST])
+
+       # 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
+          AC_MSG_CHECKING([for pythondir])
+          pythondir=`echo $pythondir |sed 's,\\\\,/,g'`
+          AC_MSG_RESULT($pythondir)
+          AC_SUBST([pythondir])
+          AC_MSG_CHECKING([for pkgpythondir])
+          pkgpythondir=`echo $pkgpythondir |sed 's,\\\\,/,g'`
+          AC_MSG_RESULT($pkgpythondir)
+          AC_SUBST([pkgpythondir])
+          AC_MSG_CHECKING([for pyexecdir])
+          pyexecdir=`echo $pyexecdir |sed 's,\\\\,/,g'`
+          AC_MSG_RESULT($pyexecdir)
+          AC_SUBST([pyexecdir])
+          AC_MSG_CHECKING([for pkgpyexecdir])
+          pkgpyexecdir=`echo $pkgpyexecdir |sed 's,\\\\,/,g'`
+          AC_MSG_RESULT($pkgpyexecdir)
+          AC_SUBST([pkgpyexecdir])
+         ;;
+        esac
+
+       AC_SUBST([PYTHON_LDFLAGS])
+])
diff --git a/config/gr_radar.m4 b/config/gr_radar.m4
new file mode 100644 (file)
index 0000000..b9a42d6
--- /dev/null
@@ -0,0 +1,36 @@
+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 2, 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., 59 Temple Place - Suite 330,
+dnl Boston, MA 02111-1307, USA.
+
+AC_DEFUN([GR_RADAR],[
+    AC_CONFIG_SRCDIR([gr-radar/src/python/usrp_rx_radar.py])
+
+    AC_CONFIG_FILES([\
+       gr-radar/Makefile \
+       gr-radar/doc/Makefile \
+       gr-radar/src/Makefile \
+       gr-radar/src/lib/Makefile \
+       gr-radar/src/python/Makefile \
+       gr-radar/src/python/run_tests \
+    ])
+
+    dnl run_tests is created from run_tests.in.  Make it executable.
+    AC_CONFIG_COMMANDS([run_tests_radar], [chmod +x gr-radar/src/python/run_tests])
+
+    subdirs="$subdirs gr-radar"
+])
diff --git a/config/gr_radio_astronomy.m4 b/config/gr_radio_astronomy.m4
new file mode 100644 (file)
index 0000000..db0ca61
--- /dev/null
@@ -0,0 +1,35 @@
+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 2, 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., 59 Temple Place - Suite 330,
+dnl Boston, MA 02111-1307, USA.
+
+AC_DEFUN([GR_RADIO_ASTRONOMY],[
+    AC_CONFIG_SRCDIR([gr-radio-astronomy/src/lib/ra.i])
+
+    AC_CONFIG_FILES([\
+       gr-radio-astronomy/Makefile \
+       gr-radio-astronomy/src/Makefile \
+       gr-radio-astronomy/src/lib/Makefile \
+       gr-radio-astronomy/src/python/Makefile \
+       gr-radio-astronomy/src/python/run_tests \
+    ])
+
+    dnl run_tests is created from run_tests.in.  Make it executable.
+    AC_CONFIG_COMMANDS([run_tests_astronomy], [chmod +x gr-radio-astronomy/src/python/run_tests])
+
+    subdirs="$subdirs gr-radio-astronomy"
+])
diff --git a/config/gr_require_mc4020.m4 b/config/gr_require_mc4020.m4
new file mode 100644 (file)
index 0000000..8a03eeb
--- /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 2, 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., 59 Temple Place - Suite 330,
+dnl Boston, MA 02111-1307, 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/config/gr_scripting.m4 b/config/gr_scripting.m4
new file mode 100644 (file)
index 0000000..7f3abde
--- /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 2, 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., 59 Temple Place - Suite 330,
+dnl Boston, MA 02111-1307, 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.23)
+  SWIG_ENABLE_CXX
+  SWIG_PYTHON
+])
diff --git a/config/gr_set_md_cpu.m4 b/config/gr_set_md_cpu.m4
new file mode 100644 (file)
index 0000000..1bb2f34
--- /dev/null
@@ -0,0 +1,44 @@
+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 2, 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., 59 Temple Place - Suite 330,
+dnl Boston, MA 02111-1307, USA.
+dnl 
+
+AC_DEFUN([GR_SET_MD_CPU],[
+  AC_REQUIRE([AC_CANONICAL_HOST])
+  AC_ARG_WITH(md-cpu,
+       [  --with-md-cpu=ARCH      set machine dependent speedups (auto)],
+               [cf_with_md_cpu="$withval"],
+               [cf_with_md_cpu="$host_cpu"])
+
+  AC_MSG_CHECKING([for machine dependent speedups])
+  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        ;;
+#  sparc)       MD_CPU=sparc    ;;
+   *)           MD_CPU=generic   ;;
+  esac
+  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_generic, test $MD_CPU = generic)
+])
+
diff --git a/config/gr_swig.m4 b/config/gr_swig.m4
new file mode 100644 (file)
index 0000000..a587c6d
--- /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 2, 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., 59 Temple Place - Suite 330,
+dnl Boston, MA 02111-1307, 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/config/gr_sysv_shm.m4 b/config/gr_sysv_shm.m4
new file mode 100644 (file)
index 0000000..5e11e49
--- /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 2, 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.
+
+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/config/gr_usrp.m4 b/config/gr_usrp.m4
new file mode 100644 (file)
index 0000000..a51d77c
--- /dev/null
@@ -0,0 +1,113 @@
+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 2, 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., 59 Temple Place - Suite 330,
+dnl Boston, MA 02111-1307, USA.
+
+AC_DEFUN([GR_USRP_HW],[
+    AC_CONFIG_SRCDIR([usrp/host/lib/usrp_prims.h])
+
+    AC_CHECK_PROG([XMLTO],[xmlto],[yes],[])
+    AM_CONDITIONAL(HAS_XMLTO, test x$XMLTO = xyes)
+
+    # gnulib.
+    # FIXME: this needs to fail gracefully and continue, not implemented yet
+    UTILS_FUNC_MKSTEMP
+
+    succeeded=yes
+    dnl Checks for library functions.
+    USRP_LIBUSB([],[succeeded=no])
+    USRP_SET_FUSB_TECHNIQUE([],[succeeded=no])
+
+    dnl check for firmware cross compilation tools
+    dnl check for SDCC 2.4.0
+    USRP_SDCC([2.4.0],[],[succeeded=no])
+    
+    AC_CHECK_FUNCS([getrusage sched_setscheduler],[],[succeeded=no])
+    AC_CHECK_FUNCS([sigaction snprintf],[],[succeeded=no])
+
+    dnl we use these to handle possible byteswapping to and from the USRP.
+    AC_CHECK_HEADERS([byteswap.h],[],[succeeeded=no])
+    AC_C_BIGENDIAN
+
+    if test $succeeded = yes; then
+       dnl Define where to look for USRP includes
+       USRP_INCLUDES='-I$(top_srcdir)/host/lib -I$(top_srcdir)/firmware/include'
+       AC_SUBST(USRP_INCLUDES)
+
+        USRP_DEFINES=''
+        AC_SUBST(USRP_DEFINES)
+
+        DEFINES="$USRP_DEFINES"
+        AC_SUBST(DEFINES)
+
+        AC_CONFIG_FILES([ \
+         usrp/Makefile                         \
+         usrp/usrp.pc                          \
+         usrp/usrp.iss                         \
+         usrp/doc/Doxyfile                     \
+         usrp/doc/Makefile                     \
+         usrp/doc/other/Makefile               \
+         usrp/host/Makefile                    \
+         usrp/host/misc/Makefile               \
+         usrp/host/lib/Makefile                \
+         usrp/host/lib/std_paths.h             \
+         usrp/host/swig/Makefile               \
+         usrp/host/apps/Makefile               \
+         usrp/firmware/Makefile                \
+         usrp/firmware/include/Makefile        \
+         usrp/firmware/lib/Makefile            \
+         usrp/firmware/src/Makefile            \
+         usrp/firmware/src/common/Makefile     \
+         usrp/firmware/src/usrp2/Makefile      \
+         usrp/fpga/Makefile                    \
+         usrp/fpga/rbf/Makefile                \
+       ])
+    
+       subdirs="$subdirs usrp"
+    else
+       failed="$failed usrp"
+    fi
+])
+
+AC_DEFUN([GR_USRP],[
+    AC_CONFIG_SRCDIR([gr-usrp/src/usrp1.i])
+
+    # Don't do gr-usrp if usrp failed
+    # There *has* to be a better way to check if a value is in a string
+    succeeded=yes
+    for dir in $failed
+    do
+       if test $dir = usrp; then
+           succeeded=no
+       fi
+    done
+
+    if test $succeeded = yes; then
+       AC_CONFIG_FILES([\
+         gr-usrp/Makefile \
+         gr-usrp/src/Makefile \
+         gr-usrp/src/run_tests \
+       ])
+
+       dnl run_tests is created from run_tests.in.  Make it executable.
+       AC_CONFIG_COMMANDS([run_tests_usrp], [chmod +x gr-usrp/src/run_tests])
+
+       subdirs="$subdirs gr-usrp"
+    else
+       failed="$failed gr-usrp"
+    fi
+])
diff --git a/config/gr_video_sdl.m4 b/config/gr_video_sdl.m4
new file mode 100644 (file)
index 0000000..2f52498
--- /dev/null
@@ -0,0 +1,45 @@
+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 2, 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., 59 Temple Place - Suite 330,
+dnl Boston, MA 02111-1307, USA.
+
+AC_DEFUN([GR_VIDEO_SDL],[
+    AC_CONFIG_SRCDIR([gr-video-sdl/src/video_sdl.i])
+
+    succeeded=yes
+
+    dnl Check for SDL
+    SDL_VERSION=1.2.0
+    AM_PATH_SDL($SDL_VERSION,[],[succeeded=no])
+
+    if test $succeeded = yes; then
+        AM_CFLAGS="$AM_CFLAGS $SDL_CFLAGS"
+        AM_LDFLAGS="$AM_LDFLAGS $SDL_LIBS"
+
+        AC_CONFIG_FILES([\
+         gr-video-sdl/Makefile \
+         gr-video-sdl/src/Makefile \
+         gr-video-sdl/src/run_tests \
+       ])
+
+       dnl run_tests is created from run_tests.in.  Make it executable.
+        AC_CONFIG_COMMANDS([run_tests_sdl], [chmod +x gr-video-sdl/src/run_tests])
+        subdirs="$subdirs gr-video-sdl"
+    else
+       failed="$failed gr-video-sdl"
+    fi
+])
diff --git a/config/gr_wxgui.m4 b/config/gr_wxgui.m4
new file mode 100644 (file)
index 0000000..4ff5650
--- /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 2, 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., 59 Temple Place - Suite 330,
+dnl Boston, MA 02111-1307, USA.
+
+AC_DEFUN([GR_WXGUI],[
+    AC_CONFIG_SRCDIR([gr-wxgui/src/python/stdgui.py])
+
+    # FIXME: Should we actually check for wxPython, even though
+    # this is a runtime requirement, not a compile/install time one?
+
+    AC_CONFIG_FILES([ \
+         gr-wxgui/Makefile \
+         gr-wxgui/src/Makefile \
+         gr-wxgui/src/python/Makefile \
+    ])
+
+    subdirs="$subdirs gr-wxgui"
+])
diff --git a/config/gr_x86_64.m4 b/config/gr_x86_64.m4
new file mode 100644 (file)
index 0000000..3d6f5ea
--- /dev/null
@@ -0,0 +1,39 @@
+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 2, 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., 59 Temple Place - Suite 330,
+dnl Boston, MA 02111-1307, USA.
+dnl 
+
+# GR_X86_64()
+#
+# Checks to see if we're on a x86_64 machine, and if so, ensure
+# that libdir ends in "64"
+#
+AC_DEFUN([GR_X86_64],[
+  AC_REQUIRE([AC_CANONICAL_HOST])
+  if test "$host_cpu" = "x86_64"; then
+    AC_MSG_CHECKING([libdir for lib64 suffix])
+    t=${libdir##*/lib}
+    if test "$t" != 64 && test -d /lib64 && ! test -L /lib64; then
+      libdir=${libdir}64
+      AC_MSG_RESULT([no. Setting libdir to $libdir])
+    else
+      AC_MSG_RESULT([yes])
+    fi
+  fi
+])
diff --git a/config/lf_cc.m4 b/config/lf_cc.m4
new file mode 100644 (file)
index 0000000..f9bd715
--- /dev/null
@@ -0,0 +1,42 @@
+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 2 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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_MINIX])dnl
+  AC_REQUIRE([AC_HEADER_STDC])dnl
+])
+
diff --git a/config/lf_cxx.m4 b/config/lf_cxx.m4
new file mode 100644 (file)
index 0000000..8ade1fb
--- /dev/null
@@ -0,0 +1,121 @@
+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 2 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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.
+# 1. Defines CXX_HAS_NO_BOOL if the compiler does not support the bool
+#    data type
+# 2. Defines CXX_HAS_BUGGY_FOR_LOOPS if the compiler has buggy
+#    scoping for the for-loop
+# 3. Defines USE_ASSERT if the user wants to use assertions
+# -----------------------------------------------------------------------
+
+
+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 Check whether we have bool
+  AC_MSG_CHECKING(whether C++ has bool)
+  AC_TRY_RUN([main() { bool b1=true; bool b2=false; }],
+             [ AC_MSG_RESULT(yes) ],
+             [ AC_MSG_RESULT(no)
+               AC_DEFINE(CXX_HAS_NO_BOOL,[],[Define if C++ is missing bool type]) ],
+             [ AC_MSG_WARN(Don't cross-compile)]
+            )
+
+  dnl Test whether C++ has buggy for-loops
+  AC_MSG_CHECKING(whether C++ has buggy scoping in for-loops)
+  AC_TRY_COMPILE([#include <iostream.h>], [
+   for (int i=0;i<10;i++) { }
+   for (int i=0;i<10;i++) { }
+], [ AC_MSG_RESULT(no) ],
+   [ AC_MSG_RESULT(yes)
+     AC_DEFINE(CXX_HAS_BUGGY_FOR_LOOPS,[],[Define if for loop scoping is broken]) ])
+
+  dnl Test whether the user wants to enable assertions
+  AC_MSG_CHECKING(whether user wants assertions)
+  AC_ARG_ENABLE(assert,
+                [  --disable-assert        don't use cpp.h assert],
+                [ AC_DEFINE(NDEBUG,[],[Define to disable asserts (don't doit!)])
+                  AC_MSG_RESULT(no)  ],
+                [ AC_MSG_RESULT(yes) ],
+               )
+
+  dnl Test whether C++ has std::isnan
+  AC_MSG_CHECKING(whether C++ has std::isnan)
+  AC_TRY_COMPILE([#include <math.h>], [
+   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
+])
+
+AH_BOTTOM([// Workaround for compilers with buggy for-loop scoping
+// That's quite a few compilers actually including recent versions of
+// Dec Alpha cxx, HP-UX CC and SGI CC.
+// The trivial "if" statement provides the correct scoping to the 
+// for loop
+
+#ifdef CXX_HAS_BUGGY_FOR_LOOPS
+#undef for
+#define for if(1) for
+#endif
+])
+
+AH_BOTTOM([// If the C++ compiler we use doesn't have bool, then
+// the following is a near-perfect work-around. 
+// You must make sure your code does not depend on "int" and "bool"
+// being two different types, in overloading for instance.
+
+#ifdef CXX_HAS_NO_BOOL
+#define bool int
+#define true 1
+#define false 0
+#endif
+])
diff --git a/config/lf_warnings.m4 b/config/lf_warnings.m4
new file mode 100644 (file)
index 0000000..0ebb97e
--- /dev/null
@@ -0,0 +1,128 @@
+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 2 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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 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
+      CXXFLAGS="${CXXFLAGS} $i"
+      AC_MSG_RESULT(yes)
+    else
+      AC_MSG_RESULT(no)
+    fi
+  done
+  rm -f conftest.cc conftest.o
+])
+
+# --------------------------------------------------------------------------
+# Check whether the C compiler accepts a certain flag
+# If it does it adds the flag to 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
+      CFLAGS="${CFLAGS} $i"
+      AC_MSG_RESULT(yes)
+    else
+      AC_MSG_RESULT(no)
+    fi
+  done
+  rm -f conftest.c conftest.o
+])
+
+# --------------------------------------------------------------------------
+# Check whether the Fortran compiler accepts a certain flag
+# If it does it adds the flag to 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
+      FFLAGS="${FFLAGS} $i"
+      AC_MSG_RESULT(yes)  
+    else
+      AC_MSG_RESULT(no)
+    fi
+  done
+  rm -f conftest.f conftest.o
+])
+
+# ----------------------------------------------------------------------
+# Provide the configure script with an --with-warnings option that
+# turns on warnings. Call this command AFTER you have configured ALL your
+# compilers. 
+# ----------------------------------------------------------------------
+
+AC_DEFUN([LF_SET_WARNINGS],[
+  dnl Check for --with-warnings
+  AC_MSG_CHECKING([whether user wants warnings])
+  AC_ARG_WITH(warnings,
+              [  --with-warnings         Turn on warnings],
+              [ lf_warnings=yes ], [ lf_warnings=no ])
+  lf_warnings=yes # hard code for now -eb
+  AC_MSG_RESULT($lf_warnings)
+  
+  dnl Warnings for the two main compilers
+  cc_warning_flags="-Wall"
+  cxx_warning_flags="-Wall -Woverloaded-virtual"
+  if test $lf_warnings = yes
+  then
+    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
+  fi
+])
diff --git a/config/lf_x11.m4 b/config/lf_x11.m4
new file mode 100644 (file)
index 0000000..3bd19f2
--- /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 2 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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/config/macosx_audiounit.m4 b/config/macosx_audiounit.m4
new file mode 100644 (file)
index 0000000..313feb3
--- /dev/null
@@ -0,0 +1,49 @@
+# Copyright 2006 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, 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.
+
+AC_DEFUN([MACOSX_AUDIOUNIT],
+[
+    audiounitok=yes
+    case "$host_os" in
+       darwin*);;
+       *) 
+          audiounitok=no
+          AC_MSG_WARN([gr-audio-osx requires darwin or MacOS X.])
+    esac
+
+    AC_CHECK_HEADERS([AudioUnit/AudioUnit.h],
+         [],
+         [ 
+           audiounitok=no,
+           AC_MSG_WARN([gr-audio-osx requires AudioUnit/AudioUnit.h, which is available on MacOS X.])
+         ]
+    )
+
+    AC_CHECK_HEADERS([AudioToolbox/AudioToolbox.h],
+         [],
+         [ 
+           audiounitok=no,
+           AC_MSG_WARN([gr-audio-osx requires AudioToolbox/AudioToolbox.h, which is available on MacOS X.])
+         ]
+    )    
+
+    if test $audiounitok = yes; then
+        ifelse([$1], , :, [$1])
+    else
+        ifelse([$2], , :, [$2])
+    fi
+])
diff --git a/config/mkstemp.m4 b/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/config/onceonly.m4 b/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/config/pkg.m4 b/config/pkg.m4
new file mode 100644 (file)
index 0000000..770f062
--- /dev/null
@@ -0,0 +1,68 @@
+dnl PKG_CHECK_MODULES(GSTUFF, gtk+-2.0 >= 1.3 glib = 1.3.4, action-if, action-not)
+dnl defines GSTUFF_LIBS, GSTUFF_CFLAGS, see pkg-config man page
+dnl also defines GSTUFF_PKG_ERRORS on error
+AC_DEFUN([PKG_CHECK_MODULES], [
+  succeeded=no
+
+  if test -z "$PKG_CONFIG"; then
+    AC_PATH_PROG(PKG_CONFIG, pkg-config, no)
+  fi
+
+  if test "$PKG_CONFIG" = "no" ; then
+     echo "*** The pkg-config script could not be found. Make sure it is"
+     echo "*** in your path, or set the PKG_CONFIG environment variable"
+     echo "*** to the full path to pkg-config."
+     echo "*** Or see http://www.freedesktop.org/software/pkgconfig to get pkg-config."
+  else
+     dnl If PKG_CONFIG_PATH is not already set, add /usr/local/lib/pkgconfig.
+     dnl If it's set, assume the user knows what they're doing.
+     dnl This should help avoid failures while looking for fftw3f
+     if test -z "$PKG_CONFIG_PATH"; then
+       export PKG_CONFIG_PATH="/usr/local/lib/pkgconfig"
+     fi
+
+     PKG_CONFIG_MIN_VERSION=0.9.0
+     if $PKG_CONFIG --atleast-pkgconfig-version $PKG_CONFIG_MIN_VERSION; then
+        AC_MSG_CHECKING(for $2)
+
+        if $PKG_CONFIG --exists "$2" ; then
+            AC_MSG_RESULT(yes)
+            succeeded=yes
+
+            AC_MSG_CHECKING($1_CFLAGS)
+            $1_CFLAGS=`$PKG_CONFIG --cflags "$2"`
+            AC_MSG_RESULT($$1_CFLAGS)
+
+            AC_MSG_CHECKING($1_LIBS)
+            $1_LIBS=`$PKG_CONFIG --libs "$2"`
+            AC_MSG_RESULT($$1_LIBS)
+
+            AC_MSG_CHECKING($1_INCLUDEDIR)
+            $1_INCLUDEDIR=`$PKG_CONFIG --variable=includedir "$2"`
+            AC_MSG_RESULT($$1_INCLUDEDIR)
+        else
+            $1_CFLAGS=""
+            $1_LIBS=""
+            ## If we have a custom action on failure, don't print errors, but 
+            ## do set a variable so people can do so.
+            $1_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "$2"`
+            ifelse([$4], ,echo $$1_PKG_ERRORS,)
+        fi
+
+        AC_SUBST($1_CFLAGS)
+        AC_SUBST($1_LIBS)
+        AC_SUBST($1_INCLUDEDIR)
+     else
+        echo "*** Your version of pkg-config is too old. You need version $PKG_CONFIG_MIN_VERSION or newer."
+        echo "*** See http://www.freedesktop.org/software/pkgconfig"
+     fi
+  fi
+
+  if test $succeeded = yes; then
+     ifelse([$3], , :, [$3])
+  else
+     ifelse([$4], , AC_MSG_ERROR([Library requirements ($2) not met; consider adjusting the PKG_CONFIG_PATH environment variable if your libraries are in a nonstandard prefix so pkg-config can find them.]), [$4])
+  fi
+])
+
+
diff --git a/config/sdl.m4 b/config/sdl.m4
new file mode 100644 (file)
index 0000000..ada3a41
--- /dev/null
@@ -0,0 +1,175 @@
+# Configure paths for SDL
+# Sam Lantinga 9/21/99
+# stolen from Manish Singh
+# stolen back from Frank Belew
+# stolen from Manish Singh
+# Shamelessly stolen from Owen Taylor
+
+dnl AM_PATH_SDL([MINIMUM-VERSION, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]])
+dnl Test for SDL, and define SDL_CFLAGS and SDL_LIBS
+dnl
+AC_DEFUN([AM_PATH_SDL],
+[dnl 
+dnl Get the cflags and libraries from the sdl-config script
+dnl
+AC_ARG_WITH(sdl-prefix,[  --with-sdl-prefix=PFX   Prefix where SDL is installed (optional)],
+            sdl_prefix="$withval", sdl_prefix="")
+AC_ARG_WITH(sdl-exec-prefix,[  --with-sdl-exec-prefix=PFX Exec prefix where SDL is installed (optional)],
+            sdl_exec_prefix="$withval", sdl_exec_prefix="")
+AC_ARG_ENABLE(sdltest, [  --disable-sdltest       Do not try to compile and run a test SDL program],
+                   , enable_sdltest=yes)
+
+  if test x$sdl_exec_prefix != x ; then
+     sdl_args="$sdl_args --exec-prefix=$sdl_exec_prefix"
+     if test x${SDL_CONFIG+set} != xset ; then
+        SDL_CONFIG=$sdl_exec_prefix/bin/sdl-config
+     fi
+  fi
+  if test x$sdl_prefix != x ; then
+     sdl_args="$sdl_args --prefix=$sdl_prefix"
+     if test x${SDL_CONFIG+set} != xset ; then
+        SDL_CONFIG=$sdl_prefix/bin/sdl-config
+     fi
+  fi
+
+  AC_REQUIRE([AC_CANONICAL_TARGET])
+  PATH="$prefix/bin:$prefix/usr/bin:$PATH"
+  AC_PATH_PROG(SDL_CONFIG, sdl-config, no, [$PATH])
+  min_sdl_version=ifelse([$1], ,0.11.0,$1)
+  AC_MSG_CHECKING(for SDL - version >= $min_sdl_version)
+  no_sdl=""
+  if test "$SDL_CONFIG" = "no" ; then
+    no_sdl=yes
+  else
+    SDL_CFLAGS=`$SDL_CONFIG $sdlconf_args --cflags`
+    SDL_LIBS=`$SDL_CONFIG $sdlconf_args --libs`
+
+    sdl_major_version=`$SDL_CONFIG $sdl_args --version | \
+           sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'`
+    sdl_minor_version=`$SDL_CONFIG $sdl_args --version | \
+           sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\2/'`
+    sdl_micro_version=`$SDL_CONFIG $sdl_config_args --version | \
+           sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'`
+    if test "x$enable_sdltest" = "xyes" ; then
+      ac_save_CFLAGS="$CFLAGS"
+      ac_save_LIBS="$LIBS"
+      CFLAGS="$CFLAGS $SDL_CFLAGS"
+      LIBS="$LIBS $SDL_LIBS"
+dnl
+dnl Now check if the installed SDL is sufficiently new. (Also sanity
+dnl checks the results of sdl-config to some extent
+dnl
+      rm -f conf.sdltest
+      AC_TRY_RUN([
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "SDL.h"
+
+char*
+my_strdup (char *str)
+{
+  char *new_str;
+  
+  if (str)
+    {
+      new_str = (char *)malloc ((strlen (str) + 1) * sizeof(char));
+      strcpy (new_str, str);
+    }
+  else
+    new_str = NULL;
+  
+  return new_str;
+}
+
+int main (int argc, char *argv[])
+{
+  int major, minor, micro;
+  char *tmp_version;
+
+  /* This hangs on some systems (?)
+  system ("touch conf.sdltest");
+  */
+  { FILE *fp = fopen("conf.sdltest", "a"); if ( fp ) fclose(fp); }
+
+  /* HP/UX 9 (%@#!) writes to sscanf strings */
+  tmp_version = my_strdup("$min_sdl_version");
+  if (sscanf(tmp_version, "%d.%d.%d", &major, &minor, &micro) != 3) {
+     printf("%s, bad version string\n", "$min_sdl_version");
+     exit(1);
+   }
+
+   if (($sdl_major_version > major) ||
+      (($sdl_major_version == major) && ($sdl_minor_version > minor)) ||
+      (($sdl_major_version == major) && ($sdl_minor_version == minor) && ($sdl_micro_version >= micro)))
+    {
+      return 0;
+    }
+  else
+    {
+      printf("\n*** 'sdl-config --version' returned %d.%d.%d, but the minimum version\n", $sdl_major_version, $sdl_minor_version, $sdl_micro_version);
+      printf("*** of SDL required is %d.%d.%d. If sdl-config is correct, then it is\n", major, minor, micro);
+      printf("*** best to upgrade to the required version.\n");
+      printf("*** If sdl-config was wrong, set the environment variable SDL_CONFIG\n");
+      printf("*** to point to the correct copy of sdl-config, and remove the file\n");
+      printf("*** config.cache before re-running configure\n");
+      return 1;
+    }
+}
+
+],, no_sdl=yes,[echo $ac_n "cross compiling; assumed OK... $ac_c"])
+       CFLAGS="$ac_save_CFLAGS"
+       LIBS="$ac_save_LIBS"
+     fi
+  fi
+  if test "x$no_sdl" = x ; then
+     AC_MSG_RESULT(yes)
+     ifelse([$2], , :, [$2])     
+  else
+     AC_MSG_RESULT(no)
+     if test "$SDL_CONFIG" = "no" ; then
+       echo "*** The sdl-config script installed by SDL could not be found"
+       echo "*** If SDL was installed in PREFIX, make sure PREFIX/bin is in"
+       echo "*** your path, or set the SDL_CONFIG environment variable to the"
+       echo "*** full path to sdl-config."
+     else
+       if test -f conf.sdltest ; then
+        :
+       else
+          echo "*** Could not run SDL test program, checking why..."
+          CFLAGS="$CFLAGS $SDL_CFLAGS"
+          LIBS="$LIBS $SDL_LIBS"
+          AC_TRY_LINK([
+#include <stdio.h>
+#include "SDL.h"
+
+int main(int argc, char *argv[])
+{ return 0; }
+#undef  main
+#define main K_and_R_C_main
+],      [ return 0; ],
+        [ echo "*** The test program compiled, but did not run. This usually means"
+          echo "*** that the run-time linker is not finding SDL or finding the wrong"
+          echo "*** version of SDL. If it is not finding SDL, you'll need to set your"
+          echo "*** LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.conf to point"
+          echo "*** to the installed location  Also, make sure you have run ldconfig if that"
+          echo "*** is required on your system"
+         echo "***"
+          echo "*** If you have an old version installed, it is best to remove it, although"
+          echo "*** you may also be able to get things to work by modifying LD_LIBRARY_PATH"],
+        [ echo "*** The test program failed to compile or link. See the file config.log for the"
+          echo "*** exact error that occured. This usually means SDL was incorrectly installed"
+          echo "*** or that you have moved SDL since it was installed. In the latter case, you"
+          echo "*** may want to edit the sdl-config script: $SDL_CONFIG" ])
+          CFLAGS="$ac_save_CFLAGS"
+          LIBS="$ac_save_LIBS"
+       fi
+     fi
+     SDL_CFLAGS=""
+     SDL_LIBS=""
+     ifelse([$3], , :, [$3])
+  fi
+  AC_SUBST(SDL_CFLAGS)
+  AC_SUBST(SDL_LIBS)
+  rm -f conf.sdltest
+])
diff --git a/config/usrp_fusb_tech.m4 b/config/usrp_fusb_tech.m4
new file mode 100644 (file)
index 0000000..78b5af5
--- /dev/null
@@ -0,0 +1,55 @@
+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 2, 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., 59 Temple Place - Suite 330,
+dnl Boston, MA 02111-1307, USA.
+dnl 
+
+AC_DEFUN([USRP_SET_FUSB_TECHNIQUE],[
+  AC_ARG_WITH(fusb-tech,
+       [  --with-fusb-tech=OS     set fast usb technique (auto)],
+               [cf_with_fusb_tech="$withval"],
+               [cf_with_fusb_tech="$host_os"])
+       
+
+  AC_CHECK_HEADER([linux/usbdevice_fs.h],
+       [x_have_usbdevice_fs_h=yes],
+       [x_have_usbdevice_fs_h=no])
+
+  AC_MSG_CHECKING([for fast usb technique to use])
+  case "$cf_with_fusb_tech" in
+    linux*)    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         ;;
+    *)         FUSB_TECH=generic       ;;
+  esac 
+
+  AC_MSG_RESULT($FUSB_TECH)
+  AC_SUBST(FUSB_TECH)
+
+  AM_CONDITIONAL(FUSB_TECH_darwin,   test $FUSB_TECH = darwin)
+  AM_CONDITIONAL(FUSB_TECH_win32,    test $FUSB_TECH = win32)
+  AM_CONDITIONAL(FUSB_TECH_generic,  test $FUSB_TECH = generic)
+  AM_CONDITIONAL(FUSB_TECH_linux,    test $FUSB_TECH = linux)
+])
+
diff --git a/config/usrp_libusb.m4 b/config/usrp_libusb.m4
new file mode 100644 (file)
index 0000000..9f67014
--- /dev/null
@@ -0,0 +1,51 @@
+# Check for libusb 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 2, 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.
+
+AC_DEFUN([USRP_LIBUSB],
+[
+       AC_LANG_PUSH(C)
+
+       libusbok=yes
+       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 $libusbok = yes; then
+           AC_SUBST(USB_LIBS)
+           ifelse([$1], , :, [$1])
+       else
+           ifelse([$2], , :, [$2])
+       fi
+])
diff --git a/config/usrp_sdcc.m4 b/config/usrp_sdcc.m4
new file mode 100644 (file)
index 0000000..eaf7fdd
--- /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 2, 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.
+
+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/configure.ac b/configure.ac
new file mode 100644 (file)
index 0000000..410567f
--- /dev/null
@@ -0,0 +1,200 @@
+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 2, 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., 59 Temple Place - Suite 330,
+dnl Boston, MA 02111-1307, USA.
+
+AC_INIT
+AC_PREREQ(2.57)
+AM_CONFIG_HEADER(config.h)
+AC_CANONICAL_HOST
+AC_CANONICAL_TARGET([])
+AM_INIT_AUTOMAKE(gnuradio,2.8svn)
+
+GR_X86_64              dnl check for lib64 suffix
+LF_CONFIGURE_CC
+LF_CONFIGURE_CXX
+LF_SET_WARNINGS
+GR_SET_GPROF
+GR_SET_PROF
+GR_PROG_AS
+AC_PROG_LN_S
+AC_PROG_MAKE_SET
+AC_PROG_INSTALL
+
+AC_LIBTOOL_WIN32_DLL
+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
+AC_PROG_LIBTOOL
+GR_FORTRAN
+
+GR_NO_UNDEFINED                dnl do we need the -no-undefined linker flag
+GR_SCRIPTING
+
+dnl Checks for libraries.
+AC_CHECK_LIB(socket,socket)
+
+dnl check for threads (mandatory)
+GR_OMNITHREAD
+
+CFLAGS="${CFLAGS} $PTHREAD_CFLAGS"
+CXXFLAGS="${CXXFLAGS} $PTHREAD_CFLAGS"
+
+if test "x$CXX_FOR_BUILD" = x
+then
+  CXX_FOR_BUILD=${CXX}
+fi
+AC_SUBST(CXX_FOR_BUILD)
+
+dnl Check for SysV shm (mandatory)
+dnl FIXME this is no longer mandatory.  Check the macro.
+GR_SYSV_SHM
+
+dnl Checks for header files.
+AC_HEADER_STDC
+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 sys/mman.h sys/select.h sys/types.h)
+AC_CHECK_HEADERS(sys/resource.h stdint.h sched.h)
+
+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 Checks for library functions.
+AC_FUNC_ALLOCA
+AC_FUNC_SETVBUF_REVERSED
+AC_FUNC_VPRINTF
+AC_CHECK_FUNCS([mmap select socket strcspn strerror strspn getpagesize sysconf])
+AC_CHECK_FUNCS([snprintf gettimeofday nanosleep sched_setscheduler])
+
+AC_CHECK_LIB(m, sincos, [AC_DEFINE([HAVE_SINCOS],[1],[Define to 1 if your system has `sincos'.])])
+AC_CHECK_LIB(m, sincosf,[AC_DEFINE([HAVE_SINCOSF],[1],[Define to 1 if your system has `sincosf'.])])
+AC_CHECK_LIB(m, sinf, [AC_DEFINE([HAVE_SINF],[1],[Define to 1 if your system has `sinf'.])])
+AC_CHECK_LIB(m, cosf, [AC_DEFINE([HAVE_COSF],[1],[Define to 1 if your system has `cosf'.])])
+AC_CHECK_LIB(m, trunc, [AC_DEFINE([HAVE_TRUNC],[1],[Define to 1 if your system has `trunc'.])])
+AH_BOTTOM([
+#ifndef HAVE_TRUNC
+#include <math.h>
+inline static double trunc(double x)
+{
+  return x >= 0 ? floor(x) : ceil(x);
+}
+#endif
+])
+
+GR_CHECK_SHM_OPEN
+GR_LIBGNURADIO_CORE_EXTRA_LDFLAGS
+GR_CHECK_CREATEFILEMAPPING
+
+dnl Check for Mingw support
+GR_PWIN32
+
+dnl Do we have "dot", part of the graphviz package from AT&T?
+dnl Doxgen will use it to draw pretty diagrams ;-)
+AC_CHECK_PROG(HAVE_DOT, [dot],[YES],[NO])
+
+PKG_CHECK_MODULES(FFTW3F, fftw3f >= 3.0)
+AC_SUBST(FFTW3F_LIBS)
+
+dnl conditional build stuff
+GR_CHECK_DOXYGEN
+GR_SET_MD_CPU
+
+dnl Define where to look for GNURADIO includes
+GNURADIO_INCLUDES='-I$(top_srcdir)/gnuradio-core/src/lib/runtime -I$(top_srcdir)/gnuradio-core/src/lib/general -I$(top_srcdir)/gnuradio-core/src/lib/filter -I$(top_srcdir)/gnuradio-core/src/lib/io -I$(top_srcdir)/gnuradio-core/src/lib/g72x -I$(top_srcdir)/gnuradio-core/src/lib/atsc -I$(top_srcdir)/gnuradio-core/src/lib/omnithread -I$(top_builddir)/gnuradio-core/src/lib/general -I$(top_builddir)/gnuradio-core/src/lib/filter -I$(top_builddir)/gnuradio-core/src/lib/reed-solomon -I$(top_builddir)/gnuradio-core/src/lib/swig $(FFTW3F_CFLAGS)'
+AC_SUBST(GNURADIO_INCLUDES)
+
+dnl Define where to look for cppunit includes and libs
+dnl sets CPPUNIT_CFLAGS and CPPUNIT_LIBS
+AM_PATH_CPPUNIT([1.9.14],[],
+               [AC_MSG_ERROR([GNU Radio requires cppunit.  Stop])])
+
+CPPUNIT_INCLUDES=$CPPUNIT_CFLAGS
+AC_SUBST(CPPUNIT_INCLUDES)
+
+dnl Define where to find boost includes
+dnl defines BOOST_CFLAGS
+GR_REQUIRE_BOOST_INCLUDES
+
+DEFINES=""
+AC_SUBST(DEFINES)
+
+STD_DEFINES_AND_INCLUDES="$DEFINES $GNURADIO_INCLUDES $BOOST_CFLAGS"
+AC_SUBST(STD_DEFINES_AND_INCLUDES)
+
+dnl Component specific configuration
+dnl The order of the GR_ macros determines the order of compilation
+subdirs="config"
+GR_GNURADIO_CORE
+GR_GNURADIO_EXAMPLES
+GR_USRP_HW
+GR_USRP                                dnl this must come after GR_USRP_HW
+GR_AUDIO_ALSA
+GR_AUDIO_JACK
+GR_AUDIO_OSS
+#GR_AUDIO_PORTAUDIO            dnl Disabled until portaudio patch figured out
+GR_AUDIO_OSX                   dnl ***NOT TESTED***
+GR_AUDIO_WINDOWS               dnl ***NOT TESTED***
+GR_ATSC
+GR_COMEDI
+#GR_ERROR_CORRECTING_CODES     dnl Disabled until compile error fixed from CVS
+GR_GSM_FR_VOCODER
+GR_RADAR
+GR_RADIO_ASTRONOMY
+GR_PMT
+GR_VIDEO_SDL
+GR_WXGUI
+
+dnl Has list of successfully configured components
+AC_SUBST([subdirs],$subdirs)
+AC_CONFIG_FILES([\
+         Makefile \
+         config/Makefile
+])
+
+AC_OUTPUT
+
+echo
+echo "*******************************************************************"
+echo The following GNU Radio components have been successfully configured:
+echo 
+for dir in $subdirs
+do
+    echo $dir
+done
+echo
+if test "$failed" != ""; then
+    echo However, the following components did not configure successfully due to 
+    echo missing dependencies:
+    echo
+    for dir in $failed
+    do
+        echo $dir
+    done
+    echo
+    echo You may still run the 'make' command to build the successfully configured
+    echo components.
+    echo
+    exit 1
+fi
+echo You my now run the 'make' command to build these packages.
+echo
diff --git a/docs/COPYING b/docs/COPYING
new file mode 100644 (file)
index 0000000..2b7b643
--- /dev/null
@@ -0,0 +1,340 @@
+                   GNU GENERAL PUBLIC LICENSE
+                      Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+     59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                           Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.)  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
+this service 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 make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  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.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+\f
+                   GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute 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 and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+  2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+\f
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of Sections
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable.  However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+\f
+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+  5. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+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
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+\f
+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the 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 a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+                           NO WARRANTY
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, 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.
+
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE 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.
+
+                    END OF TERMS AND CONDITIONS
+\f
+           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
+convey 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) 19yy <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 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
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) 19yy name of author
+    Gnomovision 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, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+  `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+  <signature of Ty Coon>, 1 April 1989
+  Ty Coon, President of Vice
+
+This 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 Library General
+Public License instead of this License.
diff --git a/docs/ChangeLog b/docs/ChangeLog
new file mode 100644 (file)
index 0000000..f63303f
--- /dev/null
@@ -0,0 +1,24 @@
+2004-11-29  Eric Blossom  <eb@comsec.com>
+
+       * exploring-gnuradio/exploring-gnuradio.xml: new.  revision 1.1
+
+#
+# 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.
+# 
diff --git a/docs/exploring-gnuradio/Makefile b/docs/exploring-gnuradio/Makefile
new file mode 100644 (file)
index 0000000..837c2c6
--- /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 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.
+# 
+
+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..3139ba3
--- /dev/null
@@ -0,0 +1,43 @@
+#!/usr/bin/env 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.
+# 
+
+from gnuradio import gr
+from gnuradio import audio
+
+def build_graph ():
+    sampling_freq = 32000
+    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, (dst, 0))
+    fg.connect (src1, (dst, 1))
+
+    return fg
+
+if __name__ == '__main__':
+    fg = build_graph ()
+    fg.start ()
+    raw_input ('Press Enter to quit: ')
+    fg.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/README b/docs/howto-write-a-block/README
new file mode 100644 (file)
index 0000000..73b8e60
--- /dev/null
@@ -0,0 +1,3 @@
+If you're looking for howto-write-a-block, it was moved into it's own
+tarball: gr-howto-write-a-block.  It includes the document source
+and a full build tree, Makefiles, examples, etc. 
diff --git a/dtools/COPYING b/dtools/COPYING
new file mode 100644 (file)
index 0000000..2b7b643
--- /dev/null
@@ -0,0 +1,340 @@
+                   GNU GENERAL PUBLIC LICENSE
+                      Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+     59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                           Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.)  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
+this service 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 make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  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.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+\f
+                   GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute 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 and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+  2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+\f
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of Sections
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable.  However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+\f
+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+  5. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+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
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+\f
+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the 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 a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+                           NO WARRANTY
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, 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.
+
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE 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.
+
+                    END OF TERMS AND CONDITIONS
+\f
+           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
+convey 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) 19yy <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 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
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) 19yy name of author
+    Gnomovision 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, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+  `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+  <signature of Ty Coon>, 1 April 1989
+  Ty Coon, President of Vice
+
+This 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 Library General
+Public License instead of this License.
diff --git a/dtools/README b/dtools/README
new file mode 100644 (file)
index 0000000..e0c7658
--- /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 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 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..f94832c
--- /dev/null
@@ -0,0 +1,23 @@
+#!/bin/bash
+
+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)$'   \
+  | sed -e "s/$path/./"  \
+  | sort >/tmp/tarball-h-files
+
+find . \( -name '*.h' -o -name '*.py' \) -print | grep -v ./$path | sort >/tmp/build-h-files
+
+comm -23 /tmp/build-h-files /tmp/tarball-h-files
+
+# 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..9bdffc1
--- /dev/null
@@ -0,0 +1,6 @@
+#!/bin/bash
+
+# fetch latest config.guess and config.sub
+
+wget http://savannah.gnu.org/cgi-bin/viewcvs/config/config/config.guess?rev=HEAD&content-type=text/plain
+wget http://savannah.gnu.org/cgi-bin/viewcvs/config/config/config.sub?rev=HEAD&content-type=text/plain
diff --git a/dtools/bin/incr_release b/dtools/bin/incr_release
new file mode 100755 (executable)
index 0000000..167192e
--- /dev/null
@@ -0,0 +1,37 @@
+#!/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 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.
+# 
+
+from optparse import OptionParser
+import release_tools
+import os.path
+
+def main():
+    parser = OptionParser()
+    parser.add_option('-f', '--final', action='store_true', default=False)
+    (options, args) = parser.parse_args()
+
+    for f in args:
+        release_tools.incr_release(os.path.join(f, 'configure.ac'), options.final)
+
+if __name__ == '__main__':
+    main()
+    
diff --git a/dtools/bin/make-upload b/dtools/bin/make-upload
new file mode 100755 (executable)
index 0000000..73a0feb
--- /dev/null
@@ -0,0 +1,12 @@
+#!/bin/bash
+
+read -s -p "GPG Passphrase: " passphrase
+
+for file in "$@"
+do
+       echo "directory: gnuradio" > $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/show_release b/dtools/bin/show_release
new file mode 100755 (executable)
index 0000000..a4eff60
--- /dev/null
@@ -0,0 +1,36 @@
+#!/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 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.
+# 
+
+from optparse import OptionParser
+import release_tools
+import os.path
+
+def main():
+    parser = OptionParser()
+    (options, args) = parser.parse_args()
+
+    for f in args:
+        print release_tools.get_release(os.path.join(f, 'configure.ac'))
+
+if __name__ == '__main__':
+    main()
+    
diff --git a/dtools/bin/tag_release b/dtools/bin/tag_release
new file mode 100755 (executable)
index 0000000..883b94b
--- /dev/null
@@ -0,0 +1,47 @@
+#!/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 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.
+# 
+
+from optparse import OptionParser
+import release_tools
+import os
+import os.path
+import sys
+
+def main():
+    parser = OptionParser()
+    (options, args) = parser.parse_args()
+
+    exit_code = 0
+    for d in args:
+        f = os.path.join(d, 'configure.ac')
+        rel = release_tools.get_release(f)
+        if rel is None:
+            raise ValueError, "%s: couldn't find version" % (f,)
+        tag = release_tools.make_tag(rel)
+        cmd = '(cd %s; cvs tag %s)' % (d, tag)
+        print cmd
+        exit_code = exit_code | os.system(cmd)
+
+    sys.exit(exit_code)
+
+if __name__ == '__main__':
+    main()
diff --git a/dtools/python/release_tools.py b/dtools/python/release_tools.py
new file mode 100644 (file)
index 0000000..788ede5
--- /dev/null
@@ -0,0 +1,87 @@
+#
+# 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 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.
+# 
+
+import re
+import os
+
+def get_release(configure_ac_filename):
+    f = open(configure_ac_filename,'r')
+    contents = f.read()
+    pat = re.compile('^AM_INIT_AUTOMAKE\((.*),(\d+)\.(\d+)(.*)\)', re.M)
+    mo = pat.search(contents)
+    if mo:
+        return mo.groups()
+
+def set_release(configure_ac_filename, new_release):
+    f = open(configure_ac_filename,'r')
+    contents = f.read()
+    pat = re.compile('^AM_INIT_AUTOMAKE\(((.*),(\d+)\.(\d+)(.*))\)', re.M)
+    repl = ''.join(('AM_INIT_AUTOMAKE(',
+                    new_release[0],
+                    ',',
+                    new_release[1],
+                    '.',
+                    new_release[2],new_release[3],')'))
+    new = pat.sub(repl, contents)
+    return new
+
+def incr_release(configure_ac_filename, final=False):
+    cur = get_release(configure_ac_filename)
+    if cur is None:
+        raise ValueError, "%s: couldn't find version" % (configure_ac_filename,)
+    new = set_release(configure_ac_filename, up_rev(cur, final))
+    os.rename(configure_ac_filename, configure_ac_filename + '.bak')
+    f = open(configure_ac_filename,'w')
+    f.write(new)
+    f.close()
+
+def up_rev(current_rev, final=False):
+    """
+    X.Y -> X.Ycvs
+    if final:
+      X.Ycvs -> X.(Y+1)rc1
+    else:
+      X.Ycvs -> X.(Y+1)
+    if final:
+      X.YrcN -> X.Y
+    else
+      X.YrcN -> X.Yrc(N+1)
+    """
+    pkg, major, minor, suffix = current_rev
+
+    if len(suffix) == 0:
+        if final:
+            raise RuntimeError, ("Can't go from current to final.  current = " + str(current_rev))
+        return (pkg, major, minor, "cvs")
+    if suffix == "cvs":
+        if final:
+            return (pkg, major, str(int(minor)+1), "")
+        return (pkg, major, str(int(minor)+1), "rc1")
+    elif suffix.startswith('rc'):
+        if final:
+            return (pkg, major, minor, "")
+        return (pkg, major, minor, "rc" + (str(int(suffix[2:]) + 1)))
+
+def make_tag(current_rev):
+    pkg, major, minor, suffix = current_rev
+    if suffix == "cvs":
+        raise ValueError, "You tried to tag a X.Ycvs release..."
+    return 'REL_%s_%s%s' % (major, minor, suffix)
diff --git a/gnuradio-core/ChangeLog b/gnuradio-core/ChangeLog
new file mode 100644 (file)
index 0000000..776ab8c
--- /dev/null
@@ -0,0 +1,1893 @@
+2006-07-06  Tom Rondeau  <trondeau@vt.edu>
+
+       * src/python/gnuradio/blksimpl/gmsk2.py:
+       Added AGC to GMSK code.
+       
+2006-07-06  Tom Rondeau  <trondeau@vt.edu>
+
+       * src/python/gnuradio/blksimpl/Makefile.am: 
+       Call to gmsk.py was causing error after removal of gmsk.py file.
+       Removed call in Makefile.am to this.
+
+2006-07-05  Eric Blossom  <eb@comsec.com>
+
+       * src/python/gnuradio/blksimpl/gmsk.py: Removed long deprecated
+       code.  We'll give this a week or so for the dust to settle, then
+       we'll rename gmsk2.py to gmsk.py
+
+2006-06-29  Tom Rondeau  <trondeau@vt.edu>
+
+       * src/lib/general/gr_correlate_access_code_bb.cc (work): 
+       Removed branches; cleaned up code to only deal with a 180 degree phase shift in
+       BPSK.
+
+2006-06-28  Tom Rondeau   <trondeau@vt.edu>
+
+       * src/python/gnuradio/gr/qa_correlate_access_code.py (test_correlate_access_code.test_001):
+       Changes to access code correlator to handle BPSK phase reversal 
+       killed qa_correlate_access_code. Modified the access code search in
+       test_001 to all the test to pass properly.
+
+2006-06-28  Tom Rondeau  <trondeau@vt.edu>
+
+       * src/lib/general/gr_constellation_decoder_cb.cc: 
+       Set Compute_EVN=false by default (to clean up the output)
+
+2006-06-20  Tom Rondeau  <trondeau@vt.edu>
+
+       * src/lib/general/gr_costas_loop_cc.{h,cc,i}: modified to support
+       both BPSK and QPSK via "order" constructor argument.  Removed
+       unused ref_phase ctor arg.
+       
+2006-06-20  Eric Blossom  <eb@comsec.com>
+
+       * src/lib/general/gr_probe_avg_mag_sqrd_{f,c}.{h,cc,i}: added accessor
+       for threshold.
+
+       * src/python/gnuradio/blksimpl/pkt.py: result of refactoring
+       gmsk2_pkt.py.  This is the common packet handling framework, and
+       is modulation independent.  gmsk2_pkt is now deprecated.
+
+       * src/python/gnuradio/blksimpl/gmsk2_pkt.py: added deprecation warning.
+       
+       * src/python/gnuradio/packet_utils.py (make_packet): added
+       bits_per_baud parameter to handle QPSK, etc in the future.
+
+2006-06-17  Eric Blossom  <eb@comsec.com>
+
+       * src/lib/runtime/gr_realtime.{h,cc,i}: new function to enable
+       realtime scheduling.
+
+2006-06-15  Eric Blossom  <eb@comsec.com>
+
+       * src/lib/io/gr_oscope_guts.{h,cc,i},
+       src/lib/io/gr_oscope_sink_x.{h,cc}: added set_sample_rate method.
+
+       * src/lib/general/gr_keep_one_in_n.{h,cc,i}: added set_n method.
+
+2006-06-13  Eric Blossom  <eb@comsec.com>
+
+       * src/lib/general/gr_binary_slicer_fb.h: corrected calling sequence.
+
+2006-06-08  Eric Blossom  <eb@comsec.com>
+
+       * src/lib/general/gr_feval.{h,cc,i},
+       src/python/gnuradio/gr/qa_feval.py: new C++/python helper that
+       allows C++ code to evaluate a function defined in Python.  Uses
+       SWIG directors.
+
+2006-06-06  Eric Blossom  <eb@comsec.com>
+
+       * src/lib/general/gr_unpack_k_bits_bb.cc (work): bug fix.  Was
+       computing the wrong answer and writing *way* too much data if k was > 1.
+       * src/python/gnuradio/gr/qa_unpack_k_bits.py: new ;)
+
+       * src/lib/general/gr_diff_decoder_bb.{h,cc,i}: new.  differential
+       decoder.  constellation index in / constellation index out.
+
+       * src/lib/general/gr_map_bb.{h,cc,i}: new.  map any byte into any
+       other byte.
+
+2006-06-01  Eric Blossom  <eb@comsec.com>
+
+       * src/lib/filter/ccomplex_dotprod_3dnow64.S,
+       src/lib/filter/3dnow_float_dotprod_really_simple.S,
+       src/lib/filter/3dnow_float_dotprod_simple.S,
+       src/lib/filter/assembly.h,
+       src/lib/filter/ccomplex_dotprod_3dnow.S,
+       src/lib/filter/ccomplex_dotprod_3dnow64.S,
+       src/lib/filter/ccomplex_dotprod_3dnowext.S,
+       src/lib/filter/ccomplex_dotprod_3dnowext64.S,
+       src/lib/filter/ccomplex_dotprod_sse.S,
+       src/lib/filter/ccomplex_dotprod_sse64.S,
+       src/lib/filter/complex_dotprod_3dnow.S,
+       src/lib/filter/complex_dotprod_3dnow64.S,
+       src/lib/filter/complex_dotprod_3dnowext.S,
+       src/lib/filter/complex_dotprod_3dnowext64.S,
+       src/lib/filter/complex_dotprod_sse.S,
+       src/lib/filter/complex_dotprod_sse64.S,
+       src/lib/filter/fcomplex_dotprod_3dnow.S,
+       src/lib/filter/fcomplex_dotprod_3dnow64.S,
+       src/lib/filter/fcomplex_dotprod_sse.S,
+       src/lib/filter/fcomplex_dotprod_sse64.S,
+       src/lib/filter/float_dotprod_3dnow.S,
+       src/lib/filter/float_dotprod_3dnow64.S,
+       src/lib/filter/float_dotprod_sse.S,
+       src/lib/filter/float_dotprod_sse64.S,
+       src/lib/filter/short_dotprod_mmx.S,
+       src/lib/filter/short_dotprod_mmx64.S: changed all occurrences of
+       .align 16 to .p2align 4 to avoid ambiguous interpretation of .align
+       argument.
+
+       
+2006-05-29  Eric Blossom  <eb@comsec.com>
+
+       * src/python/gnuradio/blksimpl/gmsk2_pkt.py: now uses string of 1's
+       and 0's for access_code representation.  Refactored to use
+       correlate_access_code_bb and frame_sink_1 instead of packet_sink.
+
+       * src/lib/general/gr_binary_slicer_fb.{h,cc,i}: new
+       * src/lib/general/gr_qpsk_slicer_cb.{h,cc,i}: deleted.  Use
+       gr_constellation_decoder_cb instead.
+
+2006-05-29  Eric Blossom  <eb@comsec.com>
+       
+       * src/lib/general/gr_clock_recovery_mm_cc.cc: revised
+       implementation based on G. R. Danesfahani, T.G. Jeans,
+       "Optimisation of modified Mueller and Muller algorithm,"
+       Electronics Letters, Vol. 31, no. 13, 22 June 1995, pp. 1032 - 1033.
+       Thanks Tom!
+       
+       * src/utils/cool.m, src/utils/db_width.m, src/utils/filter_tools.m,
+       src/utils/read_char_binary.m, src/utils/read_complex_binary.m,
+       src/utils/read_float_binary.m, src/utils/read_int_binary.m, 
+       src/utils/read_short_binary.m: modified to be compatible with
+       MATLAB.
+       
+2006-05-26  Eric Blossom  <eb@comsec.com>
+
+       * src/lib/general/gr_framer_sink_1.{h,cc,i}: new.  Refactored from
+       gr_packet_sink.  Use in combination with gr_correlate_access_code_bb.
+
+2006-05-24  Eric Blossom  <eb@comsec.com>
+
+       * src/lib/general/gr_diff_encoder_bb.{h,cc,i}: new. differential encoder.
+
+       * src/lib/general/gr_constellation_decoder_cb.{h,cc,i}: new.
+       Maps i/q value to closest constellation point and return value
+       associated with the point. This probably obsoletes 
+       gr_qpsk_slicer_cb.
+
+       * src/lib/general/gr_qpsk_slicer_cb.{h,cc,i}: new.
+       * src/lib/general/gr_unpack_k_bits_bb.{h,cc,i}: unpack bytes
+       containing k valid bits, into bytes, 1 bit per byte.
+
+       * src/lib/general/gr_correlate_access_code_bb.{h,cc,i}: new.
+       General purpose block for searching for access codes (sync
+       vectors).  Can handle any sync vector between 1 and 64 bits.
+
+2006-05-23  Eric Blossom  <eb@comsec.com>
+
+       * src/lib/general/gr_diff_phasor_cc.{h,cc,i}: new.  Compute phase
+       difference as a complex number between adjacent complex items in
+       stream.  This is useful for demodulating differentially encoded PSK.
+
+       * src/python/gnuradio/gruimpl/mathmisc.py (log2): new function.
+
+       * src/lib/general/gr_firdes.cc (root_raised_cosine): force ntaps
+       to be odd.
+
+2006-05-21  Martin Dudok van Heel <nldudok1 at olifantasia.com>
+
+       Added generic test class gr_test.
+       gr_test is a gnuradio block meant to be used in a flow_graph.
+       It doesn't do much processing, but you can specify from python every parameter you need to for testing.
+       For example history, output_multiple, input and output signature, decimation and such.
+       Especially handy for testing setting up the buffers.
+       It also touches every available input and output to check for segfaults.
+       You can also instruct it to not consume all ninput_items or not produce all noutput_items.
+       
+       There is also a new script test_buffers.py in src/tests which uses gr_test to test setting up the buffers.
+       It is NOT automatically run by make check yet, because it will fail with an assert when it reaches circbuf memory limit of the system.
+       (On linux: Trying to setup a buffer >shmmax
+        Note that you can set the smmax limit manually on a linux 2.6 system in the following way in a root console)
+       #set shmmax limit manually to 300MB
+       echo 300000000 >/proc/sys/kernel/shmmax
+
+       * src/lib/general/Makefile.am: added gr_test
+       * src/lib/general/general.i: added gr_test
+       * src/lib/general/gr_test.cc: new
+       * src/lib/general/gr_test.h: new
+       * src/lib/general/gr_test.i: new
+       * src/lib/general/gr_test_types.h: new
+       * src/tests/test_buffers.py: new script to test setting up the buffers using gr_test
+
+2006-05-21  Martin Dudok van Heel <nldudok1 at olifantasia.com>
+
+       Solved the following bugs which result from incorrect buffersize setup:
+       sched: <gr_block gr_test (21)> is requesting more input data
+         than we can provide.
+         ninput_items_required = 8192
+         max_possible_items_available = 8191
+         If this is a filter, consider reducing the number of taps.
+
+       python: src/lib/runtime/gr_buffer.h:108: unsigned int gr_buffer::index_sub(unsigned int, unsigned int):
+        Assertion `(unsigned) s < d_bufsize' failed.
+       Aborted
+
+       * src/python/gnuradio/gr/flow_graph.py: resolved above bugs by adding + mdown.history() to nitems when appropriate
+
+2006-04-24  Eric Blossom  <eb@comsec.com>
+
+       * src/lib/general/gr_chunks_to_symbols_XX.{h,cc,i}.t,
+       src/lib/general/gr_packed_to_unpacked_XX.{h,cc,i}.t,
+       src/lib/general/gr_unpacked_to_packed_XX.{h,cc,i}.t: 
+       new pseudo-templates for generating family of blocks.  Patch
+       submitted by Achilleas Anastasopoulos <anastas@umich.edu>, touched
+       up by Eric.
+
+2006-04-24  Martin Dudok van Heel <nldudok1 at olifantasia.com>
+
+       * src/python/gnuradio/gr/flow_graph.py (buffer_sizes.allocate):
+       increase buffer size allocation for blocks with a large
+       output_multiple, not just those that are decimators.
+
+2006-04-05  Eric Blossom  <eb@comsec.com>
+
+       * src/lib/general/gr_pll_carriertracking_cc.i: added
+       squelch_enable and set_lock_threshold methods.
+
+       * src/lib/general/gr_clock_recovery_mm_cc.h: removed erroneous
+       class prefix to method.  GCC 4.1.0 complains ;)
+
+2006-04-03  Eric Blossom  <eb@comsec.com>
+
+       * src/lib/general/gr_pll_carriertracking_cc.cc (phase_detector):
+       fixed typo.
+
+       * src/python/gnuradio/gr/prefs.py: don't load prefs if
+       GR_DONT_LOAD_PREFS environment variable is set.  run_tests sets
+       this to avoid interactions with system and user prefs during
+       make check.
+
+       * src/python/gnuradio/gr/qa_rational_resampler.py: disabled two
+       tests that were causing hangs on SuSE 10.0.  Should be investigated.
+
+2006-03-30  Eric Blossom  <eb@comsec.com>
+
+       * src/lib/filter/gr_fft_filter_ccc.{h,cc},
+       src/lib/filter/gr_fft_filter_fff.{h,cc}: reworked to allow
+       safer setting of new taps after instantiation.
+
+2006-03-29  Eric Blossom  <eb@comsec.com>
+
+       * src/lib/general/gr_prefix.{h,cc,i}: new function that returns
+       installation prefix directory (--prefix argument to configure).
+
+       * src/lib/general/gr_prefs.{h,cc,i}: reworked implementation to
+       use python ConfigParser.
+       * src/python/gnuradio/gr/prefs.py: moved from
+       src/python/gnuradio/prefs.py to solve initialization problem.
+
+       * src/lib/general/gr_stream_to_vector.{h,cc,i}: renamed from gr_serial_to_parallel
+       * src/lib/general/gr_vector_to_stream.{h,cc,i}: renamed from gr_parallel_to_serial
+       * src/lib/python/gnuradio/gr/__init__.py: new aliases for
+       backwards compatibility with rename.
+
+       * src/lib/swig/Makefile.am: cleanup for make distcheck.
+
+       * src/lib/atsc/GrAtscBitTimingLoop.cc, GrAtscBitTimingLoop.h,
+       GrAtscBitTimingLoop2.cc, GrAtscBitTimingLoop2.h,
+       GrAtscBitTimingLoop3.cc, GrAtscBitTimingLoop3.h,
+       GrAtscConvert2xTo20.cc, GrAtscConvert2xTo20.h,
+       GrAtscDataSegToSoftDataSeg.cc, GrAtscDataSegToSoftDataSeg.h,
+       GrAtscDeinterleaver.cc, GrAtscDeinterleaver.h,
+       GrAtscDerandomizer.cc, GrAtscDerandomizer.h,
+       GrAtscEqualizer.cc, GrAtscEqualizer.h, GrAtscFPLL.cc,
+       GrAtscFPLL.h, GrAtscFieldSyncChecker.cc,
+       GrAtscFieldSyncChecker.h, GrAtscFieldSyncCorrelator.cc,
+       GrAtscFieldSyncCorrelator.h, GrAtscFieldSyncDemux.cc,
+       GrAtscFieldSyncDemux.h, GrAtscFieldSyncMux.cc,
+       GrAtscFieldSyncMux.h, GrAtscInterleaver.cc,
+       GrAtscInterleaver.h, GrAtscRSDecoder.cc, GrAtscRSDecoder.h,
+       GrAtscRSEncoder.cc, GrAtscRSEncoder.h, GrAtscRandomizer.cc,
+       GrAtscRandomizer.h, GrAtscSegSymSync.cc, GrAtscSegSymSync.h,
+       GrAtscSegSymSyncImpl.cc, GrAtscSegSymSyncImpl.h,
+       GrAtscSegSymSyncImpl_export.h, GrAtscSymbolMapper.h,
+       GrAtscTrellisEncoder.cc, GrAtscTrellisEncoder.h,
+       GrAtscViterbiDecoder.cc, GrAtscViterbiDecoder.h, Makefile.am,
+       README, atsc_basic_trellis_encoder.cc,
+       atsc_basic_trellis_encoder.h, atsc_consts.h,
+       atsc_data_interleaver.cc, atsc_data_interleaver.h,
+       atsc_diag_output.h, atsc_equalizer.cc, atsc_equalizer.h,
+       atsc_equalizer_lms.cc, atsc_equalizer_lms.h,
+       atsc_equalizer_lms2.cc, atsc_equalizer_lms2.h,
+       atsc_equalizer_nop.cc, atsc_equalizer_nop.h, atsc_exp2_lp.cc,
+       atsc_exp2_lp.h, atsc_exp2_lp20.dat, atsc_exp2_lp2x.dat,
+       atsc_fake_single_viterbi.cc, atsc_fake_single_viterbi.h,
+       atsc_fs_checker.cc, atsc_fs_checker.h,
+       atsc_fs_checker_naive.cc, atsc_fs_checker_naive.h,
+       atsc_fs_correlator.cc, atsc_fs_correlator.h,
+       atsc_fs_correlator_naive.cc, atsc_fs_correlator_naive.h,
+       atsc_pnXXX.cc, atsc_pnXXX.h, atsc_randomizer.cc,
+       atsc_randomizer.h, atsc_reed_solomon.cc, atsc_reed_solomon.h,
+       atsc_root_raised_cosine.cc, atsc_root_raised_cosine.h,
+       atsc_root_raised_cosine_bandpass.cc,
+       atsc_root_raised_cosine_bandpass.h, atsc_single_viterbi.cc,
+       atsc_single_viterbi.h, atsc_slicer_agc.h,
+       atsc_sliding_correlator.cc, atsc_sliding_correlator.h,
+       atsc_sssr.cc, atsc_sssr.h, atsc_syminfo.h, atsc_sync_tag.h,
+       atsc_trellis_encoder.cc, atsc_trellis_encoder.h, atsc_types.h,
+       atsc_viterbi_decoder.cc, atsc_viterbi_decoder.h,
+       atsc_viterbi_gen.cc, atsc_vsbtx_lp.cc, atsc_vsbtx_lp.dat,
+       atsc_vsbtx_lp.h, convolutional_interleaver.h,
+       create_atsc_equalizer.cc, create_atsc_equalizer.h,
+       create_atsc_fs_checker.cc, create_atsc_fs_checker.h,
+       create_atsc_fs_correlator.cc, create_atsc_fs_correlator.h,
+       fpll_btloop_coupling.h, gen_encoder.py, interleaver_fifo.h,
+       plinfo.cc, qa_atsc.cc, qa_atsc.h,
+       qa_atsc_basic_trellis_encoder.cc,
+       qa_atsc_basic_trellis_encoder.h, qa_atsc_data_interleaver.cc,
+       qa_atsc_data_interleaver.h, qa_atsc_equalizer_nop.cc,
+       qa_atsc_equalizer_nop.h, qa_atsc_fake_single_viterbi.cc,
+       qa_atsc_fake_single_viterbi.h, qa_atsc_fs_correlator.cc,
+       qa_atsc_fs_correlator.h, qa_atsc_randomizer.cc,
+       qa_atsc_randomizer.h, qa_atsc_reed_solomon.cc,
+       qa_atsc_reed_solomon.h, qa_atsc_single_viterbi.cc,
+       qa_atsc_single_viterbi.h, qa_atsc_sliding_correlator.cc,
+       qa_atsc_sliding_correlator.h, qa_atsc_trellis_encoder.cc,
+       qa_atsc_trellis_encoder.h,
+       qa_atsc_trellis_encoder_t1_input.dat,
+       qa_atsc_trellis_encoder_t1_output.dat,
+       qa_atsc_viterbi_decoder.cc, qa_atsc_viterbi_decoder.h,
+       qa_atsc_viterbi_decoder_t1_input.dat,
+       qa_atsc_viterbi_decoder_t1_output.dat,
+       qa_convolutional_interleaver.cc,
+       qa_convolutional_interleaver.h, qa_interleaver_fifo.cc,
+       qa_interleaver_fifo.h: Moved all atsc code from src/lib/atsc to
+       new gr-atsc CVS module.
+       
+       * src/lib/general/gri_ringbuffer.{h,cc}: removed.  Use
+       gr_buffer/gr_buffer_reader instead.
+
+2006-03-27  Eric Blossom  <eb@comsec.com>
+
+       * src/lib/general/gr_prefs.{h,cc,i}: renamed parameter from "val" to
+       "v" to work around issue in SWIG 1.3.{28,29} and/or g++ 4.0.2.
+
+       * src/lib/general/gr_prefs.{h,cc,i}, src/python/gnuradio/prefs.py:
+       new class for user preferences.  This uses SWIG directors (serious
+       magic), to have the actual implementation be in python, but
+       callable transparently from C++.  We'll use this for user prefs
+       such as audio module, audio module options, etc.
+
+2006-03-25  Eric Blossom  <eb@comsec.com>
+
+       * src/lib/io/gri_logger.h (class gri_logger): new class that can
+       safely log to a file from within a JACK or portaudio callback.
+       Uses a ringbuffer to communicate with a separate thread that
+       writes the file.
+
+2006-03-17  Eric Blossom  <eb@comsec.com>
+
+       * src/lib/runtime/gr_buffer.cc (gr_buffer_reader): added missing
+       drop_reader call to destructor.  Fixed latent bug.
+
+2006-03-15  Eric Blossom  <eb@comsec.com>
+
+       * src/lib/omnithread.h,
+       src/lib/omnithread/ot_posix.h, src/lib/omnithread/posix.cc,
+       src/lib/omnithread/nt.cc: mods to
+       allow specifying a max count on semaphores. This allows the
+       construction of binary semaphores by passing max_count=1 to the ctor.
+       The default behavior is unchanged.
+
+2006-03-13  Eric Blossom  <eb@comsec.com>
+
+       * src/lib/general/gr_pll_carriertracking_cc.cc (work): refactored
+       loop control.
+
+2006-03-12  Stephane Fillod  <f8cfe@free.fr>
+       * src/lib/general/gri_ringbuffer.{cc,h},
+         src/lib/general/Makefile.am: new lockless ringbuffer (single
+         reader/single writer) taken from JACK software (GPL).
+       * * src/lib/omnithread/omnithread.h: add omni_mutex::trylock
+       * * src/lib/omnithread/ot_posix.h: POSIX trylock implementation
+       * * src/lib/omnithread/ot_nt.h: Win32 trylock implementation
+
+2006-03-12  Eric Blossom  <eb@comsec.com>
+
+       * src/lib/general/gr_firdes.h, src/lib/io/gr_file_source.h: Fix
+       for g++ 4.1.  Removed extra class:: qualification.  Patch
+       submitted by Martin Michlmayr <tbm@cyrius.com>
+
+2006-03-10  Eric Blossom  <eb@comsec.com>
+
+       * src/lib/general/gr_dd_mpsk_sync_cc.cc: doc fixes.  reworked
+       delay line handling.
+       * src/lib/general/gr_dd_mpsk_sync_cc.h: doc fixes.  Added DLLEN const.
+       * src/lib/general/gr_costas_loop_cc.h: doc fixes.
+       * src/lib/general/gr_costas_loop_cc.cc (work): cosmetic tweak to
+       loop control.
+
+2006-03-07  Eric Blossom  <eb@comsec.com>
+
+       * src/lib/general/gr_multiply_const_XX.h.t,
+       src/lib/general/gr_quadrature_demod_cf.h,
+       src/lib/general/gr_frequency_modulator_fc.h,
+       src/lib/general/gr_packed_to_unpacked_bb.h,
+       src/lib/general/gr_unpacked_to_packed_bb.h,
+       src/lib/general/gr_chunks_to_symbols_bf.h,
+       src/lib/general/gr_chunks_to_symbols_bc.h: doc fixs.
+
+2006-02-22  Martin Dudok van Heel <nldudok1 at olifantasia.com>
+
+        Addded new blocks gr_single_pole_iir_filter_cc
+                          gr_agc_cc
+                          gr_phase_modulator_fc
+        Changed gr_single_pole_iir.h  to make this work
+        Bugfix, to make make_check work again.
+
+        * src/lib/filter/Makefile.am: Added gr_single_pole_iir_filter_cc
+       Added missing gr_single_pole_avg.h and gr_single_pole_rec.h (fix make check bug)
+        * src/lib/filter/filter.i: changed. Added gr_single_pole_iir_filter_cc
+        * src/lib/filter/gr_single_pole_iir.h: changed template to have
+       partial specialization for <gr_complex,i_type,double>.  Needed
+       because calculations and temporary variables have to be
+       gr_complexd in this special case
+        * src/lib/filter/gr_single_pole_iir_filter_cc.cc: new
+        * src/lib/filter/gr_single_pole_iir_filter_cc.h: new
+        * src/lib/filter/gr_single_pole_iir_filter_cc.i: new
+        * src/lib/general/Makefile.am: changed. Added gr_agc_cc, gr_phase_modulator_fc,gri_agc_cc
+        * src/lib/general/general.i: changed. Added gr_agc_cc, gr_phase_modulator_fc
+        * src/lib/general/gr_agc_cc.cc: new
+        * src/lib/general/gr_agc_cc.h: new
+        * src/lib/general/gr_agc_cc.i: new
+        * src/lib/general/gr_phase_modulator_fc.cc: new
+        * src/lib/general/gr_phase_modulator_fc.h: new
+        * src/lib/general/gr_phase_modulator_fc.i: new
+        * src/lib/general/gri_agc_cc.h: new
+        * src/lib/general/gri_agc_cc.i: new
+        * src/python/gnuradio/gr/Makefile.am: changed. Added qa_single_pole_iir_cc.py
+        * src/python/gnuradio/gr/qa_single_pole_iir_cc.py: new
+       
+2006-02-17  Stephane Fillod  <f8cfe@free.fr>
+
+       * configure.ac, src/lib/filter/ccomplex_dotprod_generic.cc,
+       src/lib/filter/complex_dotprod_generic.cc,
+       src/lib/filter/generate_gr_fir_sysconfig.py,
+       src/lib/filter/generate_gr_fir_sysconfig_generic.py,
+       src/lib/filter/generate_gr_fir_util.py,
+       src/lib/filter/gr_fir_XXX.cc.t,
+       src/lib/filter/gr_fir_XXX_generic.cc.t,
+       src/lib/filter/gr_fir_ccc_simd.cc,
+       src/lib/filter/gr_fir_ccc_x86.cc,
+       src/lib/filter/gr_fir_ccf_simd.cc,
+       src/lib/filter/gr_fir_ccf_x86.cc,
+       src/lib/filter/gr_fir_fcc_simd.cc,
+       src/lib/filter/gr_fir_fcc_x86.cc,
+       src/lib/filter/gr_fir_fff_simd.cc,
+       src/lib/filter/gr_fir_fff_x86.cc,
+       src/lib/filter/gr_fir_fsf_simd.cc,
+       src/lib/filter/gr_fir_fsf_x86.cc,
+       src/lib/filter/gr_fir_scc_simd.cc,
+       src/lib/filter/gr_fir_scc_x86.cc,
+       src/lib/filter/gr_fir_sysconfig_x86.cc,
+       src/lib/filter/gri_mmse_fir_interpolator.cc,
+       src/lib/filter/gri_mmse_fir_interpolator_cc.cc,
+       src/lib/filter/sysconfig_x86.cc,
+       src/lib/general/gr_align_on_samplenumbers_ss.cc,
+       src/lib/general/gr_crc32.cc,
+       src/lib/general/gr_head.cc,
+       src/lib/general/gr_lfsr_32k_source_s.cc,
+       src/lib/general/gr_noise_source_X.cc.t,
+       src/lib/general/gr_nop.cc,
+       src/lib/general/gr_reverse.cc,
+       src/lib/general/gr_sig_source_X.cc.t,
+       src/lib/general/gr_simple_correlator.cc,
+       src/lib/general/gr_simple_framer.cc,
+       src/lib/general/gr_skiphead.cc,
+       src/lib/general/gr_vector_sink_X.cc.t,
+       src/lib/general/gr_vector_source_X.cc.t,
+       src/lib/general/qa_gr_fxpt.cc,
+       src/lib/general/qa_gr_fxpt_nco.cc,
+       src/lib/general/qa_gr_fxpt_vco.cc,
+       src/lib/io/gr_oscope_guts.cc,
+       src/lib/runtime/gr_io_signature.cc,
+       src/lib/runtime/gr_types.h,
+       src/lib/runtime/qa_gr_block.cc,
+       src/lib/runtime/qa_gr_buffer.cc,
+       src/lib/runtime/qa_gr_io_signature.cc: added proper config check
+       for stdint.h to define gr_int* types.
+
+2006-02-16  Eric Blossom  <eb@comsec.com>
+
+       * src/lib/runtime/gr_types.h: added typedef for gr_int64 and
+       gr_uint64.  Need proper autoconf fix for these.
+
+2006-02-08  Eric Blossom  <eb@comsec.com>
+
+       * src/lib/io/gr_file_sink.{h,cc,i}: added new methods: enable &
+       disable.  Thanks Marcus!
+
+2006-02-06  Eric Blossom  <eb@comsec.com>
+
+       * src/lib/general/gr_kludge_copy.{h,cc,i}: new. Copies input to output.
+       * src/python/gnuradio/gr/qa_kludge_copy.py: new QA code.
+
+2006-02-05  Eric Blossom  <eb@comsec.com>
+
+       * src/python/gnuradio/gr/qa_iir.py (test_iir.test_iir_direct_008):
+       accept either RuntimeError or ValueError in test case.  The return
+       value changed in swig 1.3.28.
+
+       * src/lib/swig/gnuradio.i: now use anonymous templates for
+       std::vector's.  This was a tip from one of the SWIG developers.
+       It generates less code.
+
+2006-02-02  Eric Blossom  <eb@comsec.com>
+
+       * src/python/gnuradio/gruimpl/seq_with_cursor.py: added method to
+       select closest index by value.
+
+2006-01-30  Eric Blossom  <eb@comsec.com>
+
+       * src/lib/general/gr_packet_sink.{h,i}: Added new "carrier_sensed"
+       method.  Naive implementation, but it just might work ;)
+       * src/python/gnuradio/blksimpl/gmsk2_pkt.py (carrier_sensed): new method.
+
+2006-01-28  Eric Blossom  <eb@comsec.com>
+
+       * src/lib/general/gr_pa_2x2_phase_combiner.{h,cc,i}: new.  
+       four antenna phase combiner for phased array experiments.
+       
+       * src/lib/general/gr_simple_squelch_cc.{h,cc,i}: added threshold
+       and squelch_range methods.
+
+2006-01-24  Eric Blossom  <eb@comsec.com>
+
+       * src/lib/general/gr_sync_block.cc (forecast): removed duplicated code.
+       * src/lib/general/gr_sync_interpolator.cc (forecast): removed duplicated code.
+       * src/lib/general/gr_sync_decimation.cc (forecast): removed duplicated code.
+       * src/lib/runtime/gr_single_threaded_scheduler.cc (main_loop):
+       take advantage of fixed_rate() method so that we can consume all
+       available input.  Fixed bad audio sound with encdec.
+
+2005-12-23  Eric Blossom  <eb@comsec.com>
+
+       * src/lib/general/gr_interleaved_short_to_complex.i (class
+       gr_interleaved_short_to_complex): corrected superclass spec.
+
+2005-12-19  Martin Dudok van Heel <nldudok1 at olifantasia.com>
+
+        Addded a new blocks to convert from unsigned char to float and for char to float.
+        Added new agc block gr_agc_ff based on existing gr_agc block
+       (which can't be directly used in a flowgraph).  All needed for
+       tv-reception.
+
+        * src/lib/general/gr_uchar_to_float.{cc,h,i}: new
+        * src/lib/general/gri_uchar_to_float.{cc,h}: new
+        * src/lib/general/gr_char_to_float.{cc,h,i}: new
+        * src/lib/general/gri_char_to_float.{cc,h}: new
+        * src/lib/general/gr_agc_ff.cc: new
+        * src/lib/general/gr_agc_ff.h: new
+        * src/lib/general/gr_agc_ff.i: new
+       * src/lib/general/Makefile.am: changed. Added gr_agc_ff,
+       gr_(u)char_to_float and gri_(u)char_to_float.
+       * src/lib/general/general.i: changed. Added
+       gr_agc_ff,gr_(u)char_to_float and gri_(u)char_to_float.
+
+2005-12-17  Eric Blossom  <eb@comsec.com>
+
+       * src/lib/general/gr_quadrature_demod_cf.cc: use fast arctan code.
+
+2005-12-17  Bob McGwier N4HY <rwmcgwier@comcast.net>
+
+       * src/lib/general/gr_lms_dfe_cc.{h,cc,i}: new.
+       * src/lib/general/gr_fast_atan2f.cc:  new.  Fast arc tangent using
+       table lookup and interpolation.  Declaration added to gr_math.h
+
+2005-12-17  Eric Blossom  <eb@comsec.com>
+
+       * src/lib/general/gr_lms_dfe_ff.h: doc fix.
+       * src/lib/general/gr_lms_dfe_ff.cc: refactored.  Moved common
+       functions to gr_misc
+       * src/lib/general/gr_misc.{h,cc}: new.  Collect misc functions in
+       one place.
+       * doc/Makefile.am: --enable-doxygen default is now "no"
+
+2005-12-16  Eric Blossom  <eb@comsec.com>
+
+       * src/lib/swig/gnuradio_swig_bug_workaround.h: removed from CVS.
+       It's generated when it's needed.
+
+2005-12-09  Eric Blossom  <eb@comsec.com>
+
+       made 2.6 release.
+
+2005-12-08  Chuck Swiger  <cswiger@widomaker.com>
+
+       * src/lib/general/gr_probe_signal_f.{h,cc,i}: new.  Return a
+       single sample from the stream.
+
+2005-12-07  Chuck Swiger  <cswiger@widomaker.com>
+
+       * src/lib/general/gr_probe_avg_mag_sqrd_{f,c}.{h,cc,i}: new.
+       Sinks that measure the average magnitude squared and allow the
+       value to be retrieved via accessors.
+
+2005-12-06  Eric Blossom  <eb@comsec.com>
+
+       * src/lib/general/gr_clock_recovery_mm_ff.cc: doc fix: added reference to book.
+
+2005-12-01  Eric Blossom  <eb@comsec.com>
+
+       * src/lib/general/gr_packet_sink.h (class gr_packet_sink): changed
+       d_threshold to unsigned to eliminate warning.
+       * src/lib/general/gr_simple_correlator.cc: removed duplicate
+       definition of slice.
+
+2005-12-01  Stephane Fillod  <f8cfe@free.fr>
+
+       * src/lib/general/gr_count_bits.cc (gr_count_bits32): faster
+       implementation.  No branching.
+
+2005-11-22  Ramakrishnan Muthukrishnan <rkrishnan@symonds.net>
+
+       * src/python/gnuradio/gr/qa_filter_delay_fc.py,
+       src/python/gnuradio/gr/qa_hilbert.py: updated QA code to reflect
+       change in delay line handling.
+
+2005-11-21  Eric Blossom  <eb@comsec.com>
+
+       * config/gr_boost.m4: reworked to look for latest version if
+       installed in version-specific subdir of /usr/local/include.
+       * src/lib/swig/Makefile.am (DISTCLEANFILES): added gnuradio_swig_python.d
+
+2005-11-19  Eric Blossom  <eb@comsec.com>
+
+       * config/usrp_libusb.m4 (USRP_LIBUSB): add -lIOKit under darwin.
+       * config/gr_no_undefinedm4, config/gr_set_md_cpu.m4,
+       config/gr_x86_64.m3, config/usrp_fusb_tech.m4,
+       config/usrp_libusb.m4: changed incorrect use of
+       AC_CANONICAL_TARGET to HOST.
+
+2005-11-18  Eric Blossom  <eb@comsec.com>
+
+       These changes enabled discontinous transmission of usrp packets.
+       The treatment of history was slightly changed.  Now we provide
+       zeros for the initial delay lines and produce N outputs for N
+       inputs.  In the past we would produce N-history-1 outputs for N inputs.
+       
+       * src/python/gnuradio/packet_utils.py: ensure at least a single
+       byte of padding to flush filters.
+       * src/lib/runtime/gr_block.{h,cc,i},
+       src/lib/general/gr_sync_block.{h,cc,i},
+       src/lib/general/gr_sync_decimator.{h,cc,i},
+       src/lib/general/gr_sync_interpolator.{h,cc,i}: moved history into
+       gr_block from gr_sync_block.  Added new methods to support fast
+       path through scheduler: fixed_rate, fixed_rate_ninput_to_output
+       and fixed_rate_noutput_to_input.
+       
+       * src/python/gnuradio/gr/flow_graph.py (flow_graph._connect_inputs):
+       account for initial history when attaching buffer reader.
+       * src/lib/runtime/gr_buffer.{h,cc,i} (gr_buffer_add_reader): modified to
+       provide zeros for initial history.
+
+       * src/python/gnuradio/gr/qa_fft_filter.py,
+       src/python/gnuradio/gr/qa_filter_delay_fc.py,
+       src/python/gnuradio/gr/qa_hilbert.py,
+       src/python/gnuradio/gr/qa_interp_fir_filter.py,
+       src/python/gnuradio/gr/qa_rational_resampler.py: tweaked QA code
+       to work with new history behavior.
+
+       
+2005-11-17  Eric Blossom  <eb@comsec.com>
+
+       * src/lib/filter/gr_interp_fir_filter_XXX.cc.t,
+       gr_rational_resampler_base_XXX.cc.t: ensure that history is set in
+       constructor.
+
+       * src/lib/runtime/gr_msg_queue.i: more evil hackery to release
+       Python global interpreter lock around blocking msg_queue methods.
+
+       * src/python/gnuradio/packet_utils.py (make_packet): conditionally
+       add padding such that final packet is a multiple of 512 bytes on the USB.
+
+2005-11-16  Eric Blossom  <eb@comsec.com>
+
+       * src/lib/io/gr_message_source.h (class gr_message_source): added
+       msgq limit to constructor args.
+
+       * src/lib/general/gr_packet_sink.{h,cc,i}: added access code
+       detection threshold to ctor args.
+
+       * src/lib/filter/gri_mmse_fir_interpolator.{h,cc}: declared interpolate const.
+
+       * src/lib/general/gr_clock_recovery_mm_ff.cc: limit excursions of
+       omega using omega_relative_limit.  Added conditional diagnostic logging.
+
+       * src/lib/runtime/gr_msg_queue.{h,cc}: block when inserting into a
+       full msg queue.
+
+       * src/lib/filter/gr_fractional_interpolator.cc (general_work):
+       1.0 - d_mu -> d_mu to match revised filter defs.
+
+2005-11-15  Eric Blossom  <eb@comsec.com>
+
+       * src/lib/io/gr_oscope_guts.{h,cc},
+       src/lib/io/gr_oscope_sink_f.{h,cc,i}: Refactored to use messages
+       and message queues to communicate to Python.  This code will never
+       block waiting for the gui.
+       * src/lib/io/gr_message_sink.{h,cc,i}: new. A sink that packages up its
+       input and puts it in a message queue.
+
+2005-11-14  Eric Blossom  <eb@comsec.com>
+
+       * doc/Doxyfile.in: updated to latest version.  Turned off serveral
+       options to reduce documentation generation time.
+
+2005-11-13  Eric Blossom  <eb@comsec.com>
+
+       * src/python/gnuradio/blksimpl/gmsk2.py,
+       src/python/gnuradio/blksimpl/gmsk2_pkt.py: new GMSK mod/demod.
+       * src/python/gnuradio/gruimpl/mathmisc.py: new: gcd, lcm.
+       * src/python/gnuradio/blksimpl/rational_resampler.py: If neither
+       taps nor fractional_bw is supplied, provide a reasonable default.
+
+2005-11-11  Eric Blossom  <eb@comsec.com>
+
+       * src/lib/filter/qa_gri_mmse_fir_interpolator.cc (t1): revised sign.
+
+       * src/lib/filter/gr_fir_filter_XXX.cc.t (work): if taps updated, return 0.
+       * src/lib/filter/gr_interp_fir_filter_XXX.cc.t (work): if taps updated, return 0.
+
+2005-11-09  Matt Ettus  <matt@ettus.com>
+
+       * src/lib/general/gr_packet_sink.cc (gr_make_packet_sink): new.
+       slices, correlates for packet access code, checks header and
+       assembles packets.
+
+2005-11-09  Eric Blossom  <eb@comsec.com>
+
+       * src/lib/io/gr_message_source.h: new class.  Messages sent to
+       this class are streamed to its single output.
+
+       * src/lib/runtime/gr_message.{h,cc,i}: removed unused methods; new
+       constructor from string; get contents as string.
+
+       * src/lib/filter/gri_mmse_fir_interpolator.{h,cc}: renamed from gr_mmse_fir_interpolator.
+       * src/lib/filter/gr_fractional_interpolator.{h,cc,i}: new.
+
+2005-11-08  Eric Blossom  <eb@comsec.com>
+       
+       * src/lib/general/gr_crc32.{h,cc,i}: new.  ISO 3309 CRC-32 generator.
+
+2005-11-08  Matt Ettus  <matt@ettus.com>
+
+       * src/lib/general/gr_threshold_ff.{h,cc,i}: new.
+       * src/python/gnuradio/blksimpl/standard_squelch.py: new
+       * src/python/gnuradio/blksimpl/nbfm_rx.py: removed squelch from
+       block.
+
+2005-11-07  Eric Blossom  <eb@comsec.com>
+
+       * src/python/gnuradio/blksimpl/rational_resampler.py
+       (design_filter): added code to automatically design filter.
+
+       * src/lib/general/gr_firdes.cc (window): fixed Kaiser window.
+
+2005-10-28  Eric Blossom  <eb@comsec.com>
+
+       * src/lib/io/gr_oscope_sink_f.cc (gr_oscope_sink_f): fixed del of
+       unowned variable that was causing double-free.
+
+2005-10-23  Eric Blossom  <eb@comsec.com>
+
+       * src/lib/general/gr_nco.h (gr_nco): removed unused local var.
+
+2005-10-17  Eric Blossom  <eb@comsec.com>
+
+       * src/lib/general/gr_fxpt_vco.h: use floats instead of double.
+       Gives 30% speedup on Opteron under gcc 3.3.5
+
+2005-10-17  Stephane Fillod  <f8cfe@free.fr>
+
+       * src/lib/general/gr_fxpt_nco.h, src/lib/general/gr_nco.h,
+       src/lib/general/gr_sig_source_X.cc.t: set primitives in shape
+       for an eventual simd speedup. fix bug in sincos() of gr_nco.h.
+
+       * src/lib/general/Makefile.am, src/lib/general/gr_vco.h,
+       src/lib/general/gr_vco_f.cc, src/lib/general/gr_vco_f.h,
+       src/lib/general/qa_gr_fxpt_vco.h, src/lib/general/qa_gr_fxpt_vco.cc,
+       src/lib/general/qa_general.cc, src/tests/benchmark_vco.cc,
+       src/lib/general/gr_fxpt_vco.h: make use of fixed point cosine for VCO,
+       with appropriate QA code, set primitives in shape for an eventual 
+       simd speedup.
+       * src/lib/general/qa_gr_fxpt_vco.cc, src/lib/general/gr_vco.h,
+       src/lib/general/qa_gr_fxpt_vco.h, src/lib/general/gr_fxpt_vco.h: new
+
+       * README: reference gr-audio-jack, gr-audio-windows and gr-comedi
+
+2005-10-12  Eric Blossom  <eb@comsec.com>
+
+       * src/lib/runtime/gr_vmcircbuf_mmap_tmpfile.{h,cc}: resurrected
+       rev 1.1 then added check for contiguous mapping.
+       * src/lib/runtime/gr_vmcircbuf.cc: enable gr_vmcircbuf_mmap_tmpfile.
+
+2005-10-11  Eric Blossom  <eb@comsec.com>
+
+       * src/lib/runtime/gr_vmcircbuf_mmap_shm_open.cc
+       (gr_vmcircbuf_mmap_shm_open): corrected error message.
+
+2005-10-10  Eric Blossom  <eb@comsec.com>
+
+       * src/lib/runtime/gr_vmcircbuf_mmap_tmpfile.{h,cc}: removed.
+
+2005-10-10  Stephane Fillod  <f8cfe@free.fr>
+
+       * src/lib/general/gr_check_counting_s.cc,
+       src/lib/general/gr_check_lfsr_32k_s.cc,
+       src/lib/general/gr_vector_source_X.cc.t,
+       src/lib/runtime/gr_vmcircbuf_createfilemapping.cc,
+       src/lib/runtime/gr_vmcircbuf_mmap_shm_open.cc: compiler warning
+       silencing.
+
+       * src/lib/general/gr_sig_source_X.cc.t,
+       src/lib/general/gr_fxpt_nco.h,
+       src/lib/general/gr_nco.h: added sincos block primitive.
+       * src/lib/general/qa_gr_fxpt_nco.cc: qa code for new sincos
+       block primitive. cleanup.
+       * src/tests/benchmark_nco.cc: benchmark the new sincos block
+
+       * src/tests/Makefile.am: added benchmark_vco
+       src/tests/benchmark_vco.cc: new
+
+2005-10-05  Eric Blossom  <eb@comsec.com>
+
+       * src/python/gnuradio/gr/hier_block.py (hier_block_base.__init__):
+       reenabled weakref to break circular graph.
+       * src/python/gnuradio/gr/basic_flow_graph.py (basic_flow_graph),
+       src/python/gnuradio/gr/flow_graph.py (flow_graph):
+       removed __slots__ class attribute so we can create weakrefs to
+       flow graphs.
+
+       * src/python/gnuradio/gr/gr_threading.py: New.  Load appropriate bug fix.
+       * src/python/gnuradio/gr/gr_threading_23.py (Thread.join): bug fixed
+       version of python 2.3 threading.py.
+       * src/python/gnuradio/gr/gr_threading_24.py (Thread.join): bug fixed
+       version of python 2.4 threading.py.
+
+       * src/lib/general/gr_vco_f.{h,cc,i}: new VCO block.
+
+2005-10-03  Eric Blossom  <eb@comsec.com>
+
+       * src/python/gnuradio/gr/hier_block.py (hier_block_base.__init__):
+       backed out use of weakref.
+       * src/python/gnuradio/gr/scheduler.py (scheduler.wait): backed out
+       "Control-C fix".
+
+2005-10-02  Eric Blossom  <eb@comsec.com>
+
+       * src/python/gnuradio/blksimpl/wfm_tx.py: New. Wide band FM tx block.
+
+2005-09-29  Eric Blossom  <eb@comsec.com>
+
+       * src/python/gnuradio/gr/hier_block.py (hier_block_base.__init__):
+       store weakref to flow_graph to break circular graph so that flow
+       graph can be reclaimed right away.
+
+       * src/python/gnuradio/gr/flow_graph.py (flow_graph.__del__): call
+       self.stop() to ensure that i/o devices get shutdown gracefully.
+
+       * src/python/gnuradio/gr/scheduler.py (scheduler.wait): calling
+       thread.join was keeping us from seeing SIGINT.  Replaced with
+       alternate implementation.
+
+2005-09-27  Eric Blossom  <eb@comsec.com>
+
+       * src/python/gnuradio/eng_option.py (check_subdev): removed the
+       (0, None) and (1, None) results.
+
+2005-09-21  Eric Blossom  <eb@comsec.com>
+
+       * src/python/gnuradio/eng_option.py (check_subdev): added new
+       command line parser type, "subdev", for selecting usrp daughterboards.
+
+2005-09-17  Krzysztof Kamieniecki <krys@kamieniecki.com>
+
+       * src/lib/filter/qa_gr_fir_ccf.cc: alignment fix for gcc 4.x
+
+2005-08-28  Stephane Fillod  <f8cfe@free.fr>
+       
+       * config/gr_set_md_cpu.m4, src/lib/filter/Makefile.am: add simd 
+       support for x86_64 platform.
+
+       * src/lib/filter/ccomplex_dotprod_3dnow64.S,
+       src/lib/filter/ccomplex_dotprod_3dnowext64.S,
+       src/lib/filter/ccomplex_dotprod_sse64.S,
+       src/lib/filter/complex_dotprod_3dnow64.S,
+       src/lib/filter/complex_dotprod_3dnowext64.S,
+       src/lib/filter/complex_dotprod_sse64.S,
+       src/lib/filter/fcomplex_dotprod_3dnow64.S,
+       src/lib/filter/fcomplex_dotprod_sse64.S,
+       src/lib/filter/float_dotprod_3dnow64.S,
+       src/lib/filter/float_dotprod_sse64.S,
+       src/lib/filter/short_dotprod_mmx64.S,
+       src/lib/filter/cpuid_x86_64.S: new
+
+       * src/lib/filter/ccomplex_dotprod_3dnow.S,
+       src/lib/filter/ccomplex_dotprod_3dnowext.S,
+       src/lib/filter/ccomplex_dotprod_sse.S,
+       src/lib/filter/complex_dotprod_3dnow.S,
+       src/lib/filter/complex_dotprod_3dnowext.S,
+       src/lib/filter/complex_dotprod_sse.S,
+       src/lib/filter/fcomplex_dotprod_3dnow.S,
+       src/lib/filter/fcomplex_dotprod_sse.S,
+       src/lib/filter/float_dotprod_3dnow.S,
+       src/lib/filter/float_dotprod_sse.S,
+       src/lib/filter/short_dotprod_mmx.S
+       src/lib/filter/cpuid_x86.S: filename debug info fix, 
+       removed useless emms instruction in pure SSE.
+       * src/lib/filter/qa_gr_fir_ccc.cc: comment fix
+       
+2005-08-28  Eric Blossom  <eb@comsec.com>
+
+       * src/lib/general/malloc16.c: fixed 64-bit pointer to int cast problem.
+
+2005-08-26  Eric Blossom  <eb@comsec.com>
+
+       * src/python/gnuradio/gr/qa_rational_resampler.py
+       (test_rational_resampler.test_002_interp):  reduced random test
+       from 10k cases to 1000 cases.  The 10k case turns up a single
+       failure.  FIXME figure out why!
+
+       * src/python/gnuradio/gr/qa_fsk_stuff.py
+       (test_bytes_to_syms.test_simple_framer):  fixed test case to
+       reflect 0x55 trailing tail.
+
+       * src/lib/filter/qa_gr_fir_ccc.cc (test_random_io): Ensure 16-byte
+       input alignment to meet contract with SIMD ccc kernel.
+
+2005-08-25  Eric Blossom  <eb@comsec.com>
+
+       * src/lib/general/gr_simple_correlator.cc: average the samples in
+       the sync field and use this to set the slicing level for the
+       payload.  This helps account for frequency offsets between the Tx
+       and Rx sides.
+
+2005-08-24  Eric Blossom  <eb@comsec.com>
+
+       * src/lib/general/gr_simple_framer_sync.h: include GRSF_TAIL_PAD
+       in GRSF_OVERHEAD.
+
+       * src/lib/runtime/gr_single_threaded_scheduler.cc (main_loop): now
+       only invoke sources if we are not making progress.  This avoids
+       blocking (in most cases) unless we've got nothing better to do.
+
+       * src/lib/filter/gr_freq_xlating_fir_filter_XXX.cc.t
+       (build_composite_fir): reversed taps to fix problem introduced
+       when we "rationalized" the tap ordering a while ago.  [We are
+       missing a unit test for this...]
+
+2005-08-22  Matt Ettus  <matt@ettus.com>
+
+       * src/python/gnuradio/blksimpl/gmsk.py:
+               made several changes to the filters on both TX and RX.
+               The demod filter (integrate_taps) should not average
+               over multiple samples.  In reality, a few samples should 
+               work, so I'm not sure why it doesn't here.
+
+2005-08-22  Eric Blossom  <eb@comsec.com>
+
+       * src/lib/general/gr_simple_correlator.cc (general_work): removed
+       incorrect magic number and replaced with constant expression.
+       [Almost as embarrassing as a buffer overflow]
+
+2005-08-21  Eric Blossom  <eb@comsec.com>
+
+       * src/lib/general/gr_simple_framer_sync.h: added one byte tail
+       padding to ensure that correlator has a chance to get synced in
+       case it was later on the previous packet.
+
+       * src/lib/general/gr_simple_correlator.cc (general_work):
+       corrected to use count_bits64.
+
+2005-08-19  Eric Blossom  <eb@comsec.com>
+
+       * doc/Makefile.am: clean-local now uses $(RM) -fr
+
+2005-08-18  Eric Blossom  <eb@comsec.com>
+
+       * src/lib/general/gr_count_bits.{h,cc}: new gr_count_bits64.
+       
+       * src/lib/general/gr_simple_correlator.{h,cc},
+       src/lib/general/gr_simple_framer.{h,cc},
+       src/lib/general/gr_simple_framer_sync.h,
+       src/python/gnuradio/gr/qa_fsk_stuff.py: changed length of SYNC
+       code from 32 to 64 bits.
+
+2005-08-16  Andrew Thomas Beck <Andrew.Beck@postgrads.unisa.edu.au>
+
+       * src/lib/runtime/gr_vmcircbuf_createfilemapping.cc (gr_vmcircbuf_createfilemapping): fixes.
+
+2005-08-15  Eric Blossom  <eb@comsec.com>
+
+       * src/lib/runtime/gr_single_threaded_scheduler.i,
+       src/lib/runtime/gr_block_detail.i, src/lib/runtime/gr_buffer.i:
+       fixes for SWIG 1.3.25.  Thanks to Job de Haas for a big clue!
+
+2005-08-08  Martin Dudok van Heel <nldudok1 at olifantasia.com>
+
+       Addded a new block to convert from float to unsigned char. Needed for new tv-reception example.
+
+       * src/lib/general/gr_float_to_uchar.{cc,h,i}: new
+       * src/lib/general/gri_float_to_uchar.{cc,h}: new
+       * src/lib/general/Makefile.am: changed. Added gr_float_to_uchar and gri_float_to_uchar. (Also added gr_float_to_char.h which was
+         forgotten in previous patch to add gr_float_to_char)   
+       * src/lib/general/general.i: changed. Added gr_float_to_uchar and gri_float_to_uchar.
+
+2005-07-28  Eric Blossom  <eb@comsec.com>
+
+       * src/lib/general/qa_gr_circular_file.cc (t1): conditionalized
+       base on HAVE_MMAP.
+
+2005-07-24  Stephane Fillod  <f8cfe@free.fr>
+
+        * src/lib/runtime/gr_vmcircbuf_mmap_tmpfile.cc: get correct
+        granularity under Cygwin.
+
+        * src/lib/filter/Makefile.am: renamed .s files to .S in order
+        to enable preprocessor support in assembly source
+        * src/lib/general/README: misc status update
+        * src/lib/filter/assembly.h: new
+        * src/lib/filter/3dnow_float_dotprod_really_simple.S,
+        src/lib/filter/3dnow_float_dotprod_simple.S,
+        src/lib/filter/ccomplex_dotprod_3dnow.S,
+        src/lib/filter/ccomplex_dotprod_3dnowext.S,
+        src/lib/filter/ccomplex_dotprod_sse.S,
+        src/lib/filter/complex_dotprod_3dnow.S,
+        src/lib/filter/complex_dotprod_3dnowext.S,
+        src/lib/filter/complex_dotprod_sse.S,
+        src/lib/filter/fcomplex_dotprod_3dnow.S,
+        src/lib/filter/fcomplex_dotprod_sse.S,
+        src/lib/filter/float_dotprod_3dnow.S,
+        src/lib/filter/float_dotprod_sse.S,
+        src/lib/filter/short_dotprod_mmx.S,
+        src/lib/filter/cpuid_x86.S: new, moved from .s files with
+        added preprocessor macros to handle both ELF and Windows
+        x86 assembly.
+        * src/lib/filter/3dnow_float_dotprod_really_simple.s,
+        src/lib/filter/3dnow_float_dotprod_simple.s,
+        src/lib/filter/ccomplex_dotprod_3dnow.s,
+        src/lib/filter/ccomplex_dotprod_3dnowext.s,
+        src/lib/filter/ccomplex_dotprod_sse.s,
+        src/lib/filter/complex_dotprod_3dnow.s,
+        src/lib/filter/complex_dotprod_3dnowext.s,
+        src/lib/filter/complex_dotprod_sse.s,
+        src/lib/filter/fcomplex_dotprod_3dnow.s,
+        src/lib/filter/fcomplex_dotprod_sse.s,
+        src/lib/filter/float_dotprod_3dnow.s,
+        src/lib/filter/float_dotprod_sse.s,
+       src/lib/filter/short_dotprod_mmx.s,
+        src/lib/filter/cpuid_x86.s: removed (renamed)
+
+
+2005-07-21  Eric Blossom  <eb@comsec.com>
+
+       * src/lib/filter/gr_fft_filter_fff.cc (compute_sizes): turned off
+       debugging output.
+
+2005-07-20  Eric Blossom  <eb@comsec.com>
+
+       * src/python/gnuradio/blksimpl/filterbank.py: documented channel
+       number to frequency mapping.  Fixed a couple of problems related
+       to reversing filter tap order.
+
+2005-07-20  Martin Dvh <gnuradiomail@olifantasia.com>
+
+       * src/lib/runtime/gr_vmcircbuf_createfilemapping.{h,cc}: new.
+       Native implementation for Windows NT/W2K/XP.
+       * config/gr_python.m4: MinGW mods.
+
+2005-07-19  Eric Blossom  <eb@comsec.com>
+
+       * src/lib/filter/gr_fft_filter_fff.{h,cc,i}: new.  Work in
+       progress.  Not yet ready for prime time.
+
+       * src/lib/runtime/gr_single_threaded_scheduler.cc: fixed spinning when
+       sink's upstream was done, but there was a non-zero but too small
+       amount of data left in the sink's input buffer.
+
+2005-07-18  Stephane Fillod  <f8cfe@free.fr>
+
+       * config/gr_libgnuradio_core_extra_ldflags.m4,
+       config/gr_no_undefined.m4, config/gr_python.m4: mods for MinGW.
+
+2005-07-17  Eric Blossom  <eb@comsec.com>
+
+       * src/lib/filter/gr_rational_resampler_base_XXX.{h,cc,i}: new.
+
+       * src/python/gnuradio/blksimpl/rational_resampler.py
+       (rational_resampler_ccc.__init__): new.  High-level wrapper for
+       gr.rational_resampler_base_???
+       
+2005-07-15  Eric Blossom  <eb@comsec.com>
+
+       * src/lib/filter/gr_fft_filter_ccc.cc,  src/lib/filter/gr_fir_XXX.h.t,
+       src/lib/filter/gr_fir_ccc_simd.cc, src/lib/filter/gr_fir_ccc_simd.h,
+       src/lib/filter/gr_fir_ccf_simd.cc, src/lib/filter/gr_fir_ccf_simd.h,
+       src/lib/filter/gr_fir_fcc_simd.cc, src/lib/filter/gr_fir_fcc_simd.h,
+       src/lib/filter/gr_fir_fff_simd.cc, src/lib/filter/gr_fir_fsf_simd.cc,
+       src/lib/filter/gr_fir_scc_simd.cc, src/lib/filter/gr_fir_scc_simd.h,
+       src/lib/filter/gr_hilbert_fc.cc, src/lib/filter/gr_interp_fir_filter_XXX.cc.t,
+       src/lib/filter/gr_mmse_fir_interpolator.cc, src/lib/filter/qa_ccomplex_dotprod_x86.cc,
+       src/lib/filter/qa_gr_fir_ccc.cc, src/lib/filter/qa_gr_fir_ccf.cc,
+       src/lib/filter/qa_gr_fir_fcc.cc, src/lib/filter/qa_gr_fir_fff.cc,
+       src/lib/filter/qa_gr_fir_scc.cc, src/lib/general/Makefile.am,
+       src/lib/general/gr_firdes.cc, src/lib/general/gr_firdes.h,
+       src/lib/general/gr_firdes.i, src/python/gnuradio/gr/qa_filter_delay_fc.py,
+       src/python/gnuradio/gr/qa_interp_fir_filter.py: reversed order of
+       "taps" arguments constructors and set_taps, fixed taps() so it
+       returns the right order.  We now require the "right" order for
+       taps, instead of the reversed order ("dot product order") we used to
+       require.
+
+2005-07-13  Martin Dvh <gnuradiomail@olifantasia.com>
+
+       * config/gr_check_createfilemapping.m4,
+          config/gr_libgnuradio_core_extra_ldflags.m4: new files
+        * configure.ac, config/Makefile.am, src/lib/Makefile.am: added
+          support for extra ld flags and future createfilemapping
+          factory.
+        * src/lib/io/gr_file_source.cc, src/lib/io/gr_file_sink.cc:
+          binary mode support under Windows.
+
+2005-07-02  Eric Blossom  <eb@comsec.com>
+
+       * config/gr_no_undefined.m4, config/gr_x86_64.m4: new, x86_64 support.
+       * config/gr_python.m4: backed out search for libpython, making
+       x86_64 work and breaking Cygwin/MinGW.
+       * configure.ac, src/lib/Makefile.am: mods for x86_64, $(NO_UNDEFINED)
+
+       * src/python/gnuradio/gr/qa_complex_to_xxx.py: loosened up passing
+       threshold so that we pass on x86_64.
+
+2005-06-23  Eric Blossom  <eb@comsec.com>
+
+       * src/lib/runtime/gr_error_handler.cc: added #include <unistd.h>
+
+2005-06-19  Eric Blossom  <eb@comsec.com>
+
+       * src/lib/runtime/gr_single_threaded_scheduler.cc (main_loop):
+       added diagnostic logging.  Fixed problem where data was dribbling
+       through pipeline.
+
+       * src/lib/general/gr_fxpt.cc: gcc 4.x fix.
+
+2005-06-16  Eric Blossom  <eb@comsec.com>
+       
+       * src/lib/general/gr_nco.h: increase precision: float->double.
+       * src/lib/general/qa_gr_fxpt_nco.h: changed initial test frequency
+       
+2005-06-16  Stephane Fillod  <f8cfe@free.fr>
+
+        * gnuradio-core.pc.in, src/lib/Makefile.am, src/lib/atsc/Makefile.am,
+        src/lib/filter/Makefile.am, src/lib/general/Makefile.am,
+        src/lib/runtime/Makefile.am, src/tests/Makefile.am: put qa code
+        in separate library.
+       
+2005-06-12  Eric Blossom  <eb@comsec.com>
+
+       * src/python/gnuradio/blksimpl/filterbank.py: new. DFT filterbank.
+       * src/lib/general/gr_vector_to_streams.{h,cc,i}: new.
+       * src/lib/general/gr_streams_to_vector.{h,cc,i}: new.
+       * src/lib/general/gr_streams_to_stream.{h,cc,i}: new. Convert
+       streams of 1 item into a stream of N items.
+       * src/lib/general/gr_stream_to_streams.{h,cc,i}: new. Convert 
+       a stream of N items into N streams of 1 items.
+
+2005-06-11  Eric Blossom  <eb@comsec.com>
+
+       * src/lib/general/gr_nlog10_ff.{h,cc,i}: added addition constructor arg,
+       k, that is added to the return value.  Handy for normalizing FFTs.
+
+       * src/lib/filter/gr_fft_filter_ccc.{h,cc,i}: new.  FFT based FIR filtering.
+
+2005-06-10  Eric Blossom  <eb@comsec.com>
+
+       * src/python/gnuradio/gr/flow_graph.py (buffer_sizes.allocate),
+       src/python/gnuradio/gr/basic_flow_graph.py (downstream_verticies_port):
+       modified to take into account downstream block decimation ratio.
+       This allows us to compute big FFTs, FIRs with lots of taps, etc.
+
+2005-05-18  Eric Blossom  <eb@comsec.com>
+
+       * src/lib/runtime/gr_block.{h,cc,i}: new start/stop methods.  These are
+       useful for minimizing latency due to startup overhead.
+       * src/lib/runtime/gr_single_threaded_scheduler.cc: call new methods.
+
+2005-05-18  John Gilmore  <gnu@toad.com>
+
+       * src/python/gnuradio/gruimpl/hexint.py: new.  Convert hex
+       constants to negative ints for long ints >= 2**31.
+
+2005-05-11  Eric Blossom  <eb@comsec.com>
+
+       * src/lib/runtime/gr_vmcircbuf_sysv_shm.cc
+       (gr_vmcircbuf_sysv_shm): add read-only guard page on either side
+       of buffer.
+
+       * src/lib/general/gr_throttle.{h,cc,i}: new block to rate-limit
+       samples.  Mostly useful where there's nothing stopping us from
+       sucking down all CPU.  E.g., reading from files, gr.sig_source, etc.
+
+2005-05-09  Stephane Fillod  <f8cfe@free.fr>
+       
+       * src/lib/filter/fcomplex_dotprod_{3dnow,sse}.s,
+       src/lib/filter/fcomplex_dotprod_x86.h,
+       src/lib/filter/gr_fir_ccf_simd.{cc,h},
+       src/lib/filter/gr_fir_ccf_x86.{cc,h},
+       src/lib/filter/gr_fir_fcc_simd.{cc,h},
+       src/lib/filter/gr_fir_fcc_x86.{cc,h},
+       src/tests/benchmark_dotprod_ccf.cc,
+       src/tests/benchmark_dotprod_fsf.cc: new files
+       * src/lib/filter/Makefile.am, src/tests/Makefile.am,
+       src/lib/filter/gr_fir_sysconfig_x86.{cc,h}: support for FCC and
+       CCF filter speedup
+       * src/tests/benchmark_dotprod_{ccc,fcc,scc}.cc: copy/paste fixes
+       which should not change benchmark results
+
+2005-05-09  Stephane Fillod  <f8cfe@free.fr>
+
+        * config/gr_sysv_shm.m4: SysV shared memory not mandatory
+       * config/gr_pwin32.m4, config/gr_python.m4, config/lf_cxx.m4:
+       fixes for Cygwin, MinGW
+       * src/lib/runtime/gr_error_handler.cc, src/lib/runtime/gr_local_sighandler.{h,cc},
+       src/lib/runtime/gr_vmcircbuf.cc, src/lib/runtime/gr_vmcircbuf_mmap_tmpfile.cc: 
+       modifications for Cygin, MinGW
+
+2005-04-27  Eric Blossom  <eb@comsec.com>
+
+       * src/lib/general/gr_fake_channel_coder_pp.{h,cc,i}: new classes
+       the pretend to do channel encoding and decoding, but really only
+       add and strip padding...
+
+       * src/lib/runtime/gr_buffer.cc (allocate_buffer): cleaned up formatting
+       on allocation warning message.
+       
+       * src/python/gnuradio/blksimpl/digital_voice.py: GSM vocoder + GMSK.
+
+2005-04-03  Eric Blossom  <eb@comsec.com>
+
+       * src/lib/io/gr_oscope_guts.cc (found_trigger): fixed trigger
+       problem where value was exactly equal to trigger value.
+
+2005-03-29  Eric Blossom  <eb@comsec.com>
+
+       * src/python/gnuradio/blksimpl/gmsk.py: new GMSK mod and demod
+       from Joshua Lackey <jl@noether.uoregon.edu>
+
+2005-03-29  Ramakrishnan Muthukrishnan <rkrishnan@symonds.net>
+
+       * src/lib/filter/gr_filter_delay_fc.{h,cc,i},
+       src/python/gnuradio/gr/qa_filter_delay_fc.py:  New block that
+       pairs a filter with a delay.
+
+2005-03-26  Eric Blossom  <eb@comsec.com>
+
+       * src/lib/runtime/gr_dispatcher.{h,cc,i},
+       src/lib/runtime/gr_select_handler.{h,cc,i}: new.  Framework for
+       callbacks based on select(2).
+       
+       * src/lib/runtime/gr_error_handler.{h,cc,i}: new.
+
+2005-03-14  Eric Blossom  <eb@comsec.com>
+
+       * src/lib/general/gr_complex_to_xxx.{h,cc,i}: now support
+       vector length argument, vlen.
+       * src/lib/general/gr_nlog10_ff.{h,cc,i}: new.
+       * src/lib/general/gr_parallel_to_serial.{h,cc,i}: new.
+       * src/lib/filter/gr_single_pole_iir_filter_ff.{h,cc,i}: new
+       * src/python/gnuradio/gr/qa_single_pole_iir.py: new
+       * src/python/gnuradio/gr/qa_nlog10.py: new
+
+2005-03-08  Eric Blossom  <eb@comsec.com>
+
+       * src/python/gnuradio/gr/qa_fsk_stuff.py: enabled simple_framer qa code.
+       * src/lib/general/gr_simple_framer.{h,cc}: added forecast method.
+
+2005-03-07  Eric Blossom  <eb@comsec.com>
+
+       * configure.ac: test for trunc and work around if missing.
+
+2005-03-02  Eric Blossom  <eb@comsec.com>
+
+       * src/python/gnuradio/blks/__init__.py, src/python/gnuradio/blksimpl/__init__.py,
+       src/python/gnuradio/gru/__init__.py,
+       src/python/gnuradio/gruimpl/__init__.py: refactored organization
+       so that hierarchical blocks are physically contained in the
+       blkimpl directory, but that for convenience in naming, all blocks
+       appear in the gnuradio.blks package.  Same story for gruimpl vs gru.
+
+       Rearranged a bunch of stuff under src/python.  CVS sucks!
+
+2005-02-28  Eric Blossom  <eb@comsec.com>
+
+       * src/lib/general/gr_frequency_modulator_fc.cc (work): fixed
+       floating point loss of precision.
+       * src/lib/general/gr_simple_correlator.cc (general_work): fixed
+       bug that had it processing only a single sample at a time.
+
+2005-02-25  Matt Ettus  <matt@ettus.com>
+
+       * lib/general/Makefile.am, lib/general/general.i, 
+       lib/general/gr_rms_[ff,cf].[cc,h,i]: new rms measuring block
+
+2005-02-25  Eric Blossom  <eb@comsec.com>
+
+       * python/gnuradio/gr/qa_mute.py, lib/general/gr_mute_XX.cc.t,
+       lib/general/gr_mute_XX.h.t, lib/general/gr_mute_XX.i.t: new block.
+       * lib/general/Makefile.am, lib/general/Makefile.gen, 
+       lib/general/general_generated.i, lib/general/generate_common.py:
+       mods to generate new block.
+
+2005-02-23  Eric Blossom  <eb@comsec.com>
+
+       * src/python/gnuradio/gr/hier_block.py: new. support for
+       hierarchical signal processing blocks.
+       * src/python/gnuradio/gr/basic_flow_graph.py,
+       src/python/gnuradio/gr/qa_basic_flow_graph.py: modified to support
+       hierarchical signal processing blocks.
+
+2005-02-22  Eric Blossom  <eb@comsec.com>
+
+       * src/lib/general/gr_simple_squelch_cc.{h,cc,i}: new.
+
+       * src/lib/runtime/gr_message.{h,cc,i},
+       src/lib/runtime/gr_msg_handler.{h,cc,i}, 
+       src/lib/runtime/gr_msg_queue.{h,cc,i}, 
+       src/lib/runtime/gr_timer.h: new. work-in-progress.
+
+2005-02-09  Eric Blossom  <eb@comsec.com>
+
+       * src/lib/io/gr_file_descriptor_source.{h,cc}(work): reworked to
+       return as soon as any data is available.  This make it much more
+       friendly for reading sockets, named pipes, etc.
+
+2005-02-07  Eric Blossom  <eb@comsec.com>
+
+       * src/python/gnuradio/gr/basic_flow_graph.py (coerce_endpoint):
+       fix exception message.
+
+2005-02-06  Eric Blossom  <eb@comsec.com>
+
+       * src/python/gnuradio/gr/basic_flow_graph.py
+       (basic_flow_graph.connect): connect now takes >= 2 args, per
+       Thomas Traber's suggestion.
+       * src/python/gnuradio/gr/qa_flow_graph.py,
+       src/python/gnuradio/gr/qa_basic_flow_grapy.py:  additional test code.
+
+2005-02-05  Eric Blossom  <eb@comsec.com>
+
+       * src/python/gnuradio/gr/basic_flow_graph.py
+       (basic_flow_graph.connect): removed unnecessary None
+
+2005-02-02  Chuck Swiger <cswiger@widomaker.com>
+
+       * src/lib/io/gr_file_source.{h,cc,i}: added seek method.
+
+2005-01-29  Eric Blossom  <eb@comsec.com>
+
+       * src/lib/runtime/gr_io_signature.i: mods for SWIG 1.3.24
+
+2005-01-24  Eric Blossom  <eb@comsec.com>
+
+       * src/python/gnuradio/freqz.py (freqz): New. Compute frequency
+       response of filter.
+       * src/python/gnuradio/gnuplot_freqz.py: New. Plot output of freqz.
+
+2005-01-17  Eric Blossom  <eb@comsec.com>
+
+       * src/lib/runtime/gr_single_threaded_scheduler.cc (main_loop):
+       Make better initial estimate of noutput_items when current block
+       is a decimator.  Removed old diagnostic code.
+
+       * src/lib/general/gr_vector_source_X.cc.t (work): reorganized the
+       repeat case so that we always return the number of items requested.
+       This fixes the excessive latency we were seeing in
+       spectrum_inversion.py
+
+       * src/python/gnuradio/gr/flow_graph.py: Set noutputs correctly.
+       * src/python/gnuradio/gr/qa_flow_graph.py: Test value of noutputs.
+       
+2005-01-16  Eric Blossom  <eb@comsec.com>
+
+       * src/lib/runtime/gr_single_threaded_scheduler.cc (main_loop):
+       check for situation where block is requesting more input data than
+       we will ever provide.
+
+       * src/python/gnuradio/gr/flow_graph.py (buffer_sizes.allocate):
+       set minimum buffersize to 2 * output_multiple()
+
+       * src/lib/runtime/gr_buffer.cc (space_available): fixed degenerate
+       case to be consistent with normal case.
+
+2005-01-01  Eric Blossom  <eb@comsec.com>
+
+       * src/lib/io/sdr_1000.i (class sdr_1000_base): removed default arg
+       to work around SWIG 1.3.23 bug.
+
+2004-12-22  Eric Blossom  <eb@comsec.com>
+
+       * src/lib/general/qa_gr_fxpt.cc (t0): disabled float_to_fixed test
+       to avoid spurious failures.
+
+2004-12-21  Eric Blossom  <eb@comsec.com>
+
+       * src/lib/general/gr_fxpt.h (class gr_fxpt): added explicit float cast.
+       * src/lib/general/Makefile.am (grinclude_HEADERS): added gr_fxpt_nco.h
+
+2004-12-18  Eric Blossom  <eb@comsec.com>
+
+       * src/lib/general/gr_fxpt.{h,cc},src/lib/general/gr_fxpt_nco.{h,cc},
+       src/lib/general/qa_gr_fxpt.{h,cc},src/lib/general/qa_gr_fxpt_nco.{h,cc},
+       src/tests/benchmark_nco.cc: new.  Faster sine and cosine
+       calculation.  Uses table lookup with linear interpolation.  This
+       is about 3x faster than the original code.
+
+2004-12-17  Eric Blossom  <eb@comsec.com>
+
+       * src/lib/general/Makefile.am (swiginclude_HEADERS): fixed typo.
+       * src/lib/general/gr_deinterleave.{h,cc,i}: new.
+
+2004-12-11  Eric Blossom  <eb@comsec.com>
+
+       * src/lib/general/gr_interleave.{h,cc,i}: new.
+
+2004-12-10  Eric Blossom  <eb@comsec.com>
+
+       * src/python/gnuradio/eng_option.py (check_intx): now parses hex
+       numbers too.
+
+2004-12-09  Eric Blossom  <eb@comsec.com>
+
+       * src/lib/filter/Makefile.am: fixed problem with gr_hilbert_fc on
+       OS/X (it was in the wrong place in the makefile).  Now builds and
+       checks on OS/X.
+
+2004-12-06  Ramakrishnan Muthukrishnan <rkrishnan@symonds.net>
+
+       * src/lib/filter/Makefile.am, src/lib/general/Makefile.am,
+       src/python/gnuradio/Makefile.am,
+       src/python/gnuradio/gr/Makefile.am: added *.pyc to CLEANFILES
+
+2004-11-30  Eric Blossom  <eb@comsec.com>
+
+       * src/python/gnuradio/gr/Makefile.am, configure.ac: modified to 
+       no longer require run_test_trampoline.  Now uses AC_CONFIG_COMMANDS to
+       set execute bit on run_tests.
+       * src/python/gnuradio/gr/run_test_trampoline: removed.
+
+       * src/lib/filter/Makefile.am (swiginclude_HEADERS): fix typo in gr_hilbert_fc.i
+
+2004-11-27  Eric Blossom  <eb@comsec.com>
+
+       * src/python/gnuradio/gr/qa_hilbert.py: new
+       * src/lib/general/gr_firdes.i: moved from filter to general.
+       * src/lib/general/gr_firdes.{h,cc}: new method: reverse.
+       * src/lib/filter/gr_hilbert_fc.i: new.
+       * src/lib/filter/gr_hilbert_fc.cc: ensure ntaps is odd.
+
+2004-11-08  Stephane Fillod <f8cfe@free.fr>
+       
+       * src/lib/filter/Makefile.am, src/tests/Makefile.am,
+        src/lib/filter/complex_dotprod_generic.cc,
+        src/lib/filter/gr_fir_sysconfig_x86.{cc,h},
+        src/lib/filter/qa_dotprod_x86.cc, src/lib/filter/qa_filter.cc:
+        added support for x86 SIMD CCC dotproduct.
+        * src/lib/filter/ccomplex_dotprod_3dnow.s,
+        src/lib/filter/ccomplex_dotprod_3dnowext.s,
+        src/lib/filter/ccomplex_dotprod_generic.{cc,h},
+        src/lib/filter/ccomplex_dotprod_sse.s,
+        src/lib/filter/ccomplex_dotprod_x86.h,
+        src/lib/filter/gr_fir_ccc_simd.{cc,h},
+        src/lib/filter/gr_fir_ccc_x86.{cc,h},
+        src/lib/filter/qa_ccomplex_dotprod_x86.{cc,h},
+        src/lib/filter/qa_gr_fir_ccc.{cc,h},
+        src/tests/benchmark_dotprod.cc,
+        src/tests/benchmark_dotprod_{ccc,fcc,scc}.cc: new
+
+2004-11-08  Eric Blossom  <eb@comsec.com>
+
+       * src/lib/runtime/gr_block.h: new methods: set_input_signature and
+       set_output_signature.
+
+2004-11-04  Eric Blossom  <eb@comsec.com>
+
+       * configure.ac: upped version to 2.3cvs
+       
+       * configure.ac: set version to 2.3.  Made release.
+       * src/python/gnuradio/audio.py (__init__): raise error if no audio
+       module found.
+
+2004-11-02  Eric Blossom  <eb@comsec.com>
+
+       * src/lib/runtime/gr_local_sighandler.cc (name): conditionalized
+       based on signal names.
+
+2004-10-30  Eric Blossom  <eb@comsec.com>
+
+       * src/lib/runtime/gr_local_sighandler.{h,cc}: new.  get and set
+       signal handlers.
+       * src/lib/runtime/gr_vmcircbuf.cc (test_factory): install handlers
+       for SIGBUS and SIGSEGV while running tests.
+
+2004-10-18  Stephane Fillod <f8cfe@free.fr>
+       
+        * config/gr_pwin32.m4, src/lib/runtime/gr_preferences.cc: proper
+        detect Sleep() support, check for mkdir that takes only one arg
+        under win32.
+        * src/lib/runtime/gr_io_signature.cc,
+        src/lib/runtime/gr_io_signature.h,
+        src/lib/runtime/gr_io_signature.i,
+        src/lib/runtime/qa_gr_io_signature.cc: resolve a clash with
+        INFINITE already defined.
+        * src/lib/runtime/gr_pagesize.cc: declare missing prototype of
+        getpagesize() under win32.
+
+2004-10-18  Eric Blossom  <eb@comsec.com>
+
+       * src/python/gnuradio/gr/run_tests.in: allow VPATH building.
+
+2004-10-18  Stephane Fillod <f8cfe@free.fr>
+
+       * configure.ac, src/lib/filter/Makefile.am,
+        src/lib/general/Makefile.am: allow VPATH building.
+
+2004-10-17  Eric Blossom  <eb@comsec.com>
+
+       * doc/Makefile.am (install-data-local): install html documentation.
+       * src/lib/filter/gr_iir_filter_ffd.cc (gr_iir_filter_ffd): removed
+       debug message.
+       * src/python/gnuradio/gr/run_tests.in: changed == to = for POSIX
+       compatibility.
+       * src/python/gnuradio/gr/qa_basic_flow_graph.py: use /usr/bin/env
+       to find python.
+
+2004-10-13  Eric Blossom  <eb@comsec.com>
+
+       * configure.ac: upped rev to 2.2cvs
+
+2004-10-11  Eric Blossom  <eb@comsec.com>
+
+       * configure.ac: bumped rev to 2.2, make release
+       * Makefile.am (EXTRA_DIST): added config.h.in
+
+2004-10-07  Eric Blossom  <eb@comsec.com>
+
+       * src/python/gnuradio/lmx2306.py: now works!
+
+2004-09-29  Eric Blossom  <eb@comsec.com>
+
+       * src/lib/filter/gri_iir.h: renamed from gr_iir.h.  Also, changed
+       the sign back.  We're consistent with Oppenheim and Schafer,
+       "Discrete-Time Signal Processing."  Documented exactly what we
+       compute.  Faster delay line implementation.
+       * src/lib/filter/gr_iir_filter_ffd.{h,cc,i}: new direct form IIR block.
+       
+2004-09-23  Eric Blossom  <eb@comsec.com>
+
+       * config/usrp_fusb_tech.m4, config/bnv_have_qt.m4, config/cppunit.m4,
+       config/gr_check_mc4020.m4, config/gr_check_usrp.m4, config/gr_doxygen.m4,
+       config/gr_gprof.m4, config/gr_scripting.m4, config/gr_set_md_cpu.m4,
+       config/pkg.m4, config/usrp_fusb_tech.m4: added additional quoting
+       to first arg of AC_DEFUN to silence automake warning.
+
+2004-09-22  Eric Blossom  <eb@comsec.com>
+
+       * src/lib/io/gr_file_descriptor_sink.cc: added missing #include <errno.h>
+       * src/lib/io/gr_file_descriptor_source.cc: added missing #include <errno.h>
+
+2004-09-21  Matthew Hall  <mahall@ncsa.uiuc.edu>
+                                                                              
+        * src/gnu/lib/gr/gr_iir.h: rewrote ctor docs. Fixed sign error
+        in filter method. Now gr_iir uses Direct Form I of IIR.
+       
+2004-09-19  Eric Blossom  <eb@comsec.com>
+
+       * src/lib/general/gr_complex_to_xxx.{h,cc,i}: new blocks.
+       * src/python/gnuradio/gr/qa_complex_xxx.py: new qa code.
+       
+       * src/lib/general/gr_simple_correlator.{h,cc,i}: payload size is
+       now in bytes, not bits.
+       * src/lib/general/gr_simple_framer.{h,cc,i}: payload size is
+       now in bytes, not bits.
+
+       * src/lib/swig/Makefile.am: now tracks swig .i file dependencies.
+       * src/lib/swig/gnuradio.i: simplification and cleanup.
+
+2004-09-18  Eric Blossom  <eb@comsec.com>
+
+       These modifications happened sometime between 2004-09-08 and 2004-09-18.
+       The details are lost in the swirl around preparing the TAPR DCC.
+
+       * src/lib/filter/gr_interp_fir_filter_XXX.{h,cc,i}.t: new
+       * src/lib/filter/generate_gr_interp_fir_filter_XXX.py: new
+       * src/lib/filter/generate_all.py: modified for to generate interpolating fir filter
+       * src/lib/general/gr_bytes_to_syms.{h,cc,i}: new
+       * src/lib/general/gr_frequency_modulator_fc.{h,cc,i}: new
+       * src/lib/general/gr_simple_framer.{h,cc,i}: new
+       * src/lib/general/gr_simple_framer_sync.h: new
+       * src/lib/general/gr_simple_correlator.{h,cc,i}: new
+       * src/lib/io/gr_oscope_guts.{h,cc}: new
+       * src/lib/io/gr_oscope_sink_{f,x}.{h,cc}: new
+       * src/lib/io/gr_trigger_mode.h: new
+       * src/lib/io/ppio.i: new
+
+       The following changes are related to moving from SWIG 1.3.21 to 1.3.22
+       
+       * src/lib/runtime/gr_block_detail.i: removed unneccesary global decl of friend.
+       * src/lib/runtime/gr_buffer.i: removed unneccesary global decl of friend.
+       * src/lib/runtime/gr_io_signature.i: removed unneccesary global decl of friend.
+       * src/lib/runtime/gr_single_threaded_scheduler.i: removed unneccesary global decl of friend.
+       * src/lib/swig/gnuradio.i: mods for improved STL support
+       
+       * src/lib/runtime/gr_types.h: new typedefs
+       * src/lib/swig/gen-swig-bug-fix: new.  generate gnuradio_swig_bug_workaround.h
+
+       * src/python/gnuradio/eng_notation.py: new
+       * src/python/gnuradio/grutil.py: new
+       * src/python/gnuradio/gr_unittest.py: new subclass of unittest
+       * src/python/gnuradio/lmx2306.py: new.  Control National PLL synthesizer
+       * src/python/gnuradio/microtune.py: new.  Command line interface
+       to microtune boards.
+       * src/python/gnuradio/gr/qa_frequency_modulator.py: new
+       * src/python/gnuradio/gr/qa_fsk_stuff.py: new
+       * src/python/gnuradio/gr/qa_head.py: new
+       * src/python/gnuradio/gr/qa_interp_fir_filter.py: new
+       * src/python/gnuradio/gr/qa_sig_source.py: new
+       
+2004-09-08  Eric Blossom  <eb@comsec.com>
+
+       * src/python/gnuradio/gr/basic_flow_graph.py
+       (basic_flow_graph.validate): now calls check_topology.
+       * src/lib/runtime/gr_block.{h,cc,i} (check_topology): new method.
+       
+       * src/lib/general/gr_short_to_float.{h,cc,i}: new
+       * src/lib/general/gr_float_to_short.{h,cc,i}: new
+
+2004-08-26  Eric Blossom  <eb@comsec.com>
+
+       * src/lib/general/gr_fft_vfc.{h,cc,i}: new
+       * src/lib/general/gr_fft_vcc.{h,cc,i}: new
+       * src/lib/general/gri_fft.{h,cc}: renamed from gr_fft.{h,cc}
+       * src/lib/general/gr_serial_to_parallel.{h,cc,i}: new
+       * src/lib/general/gr_keep_one_in_n.{h,cc,i}: new
+
+2004-08-25  Eric Blossom  <eb@comsec.com>
+
+       * src/lib/io/gr_file_descriptor_source.{h,cc,i}: new
+       * src/lib/io/gr_file_descriptor_sink.{h,cc,i}: new
+
+2004-08-19  Eric Blossom  <eb@comsec.com>
+
+       * src/lib/general/gr_sig_source_X.cc.t (work): performance tweak
+       for constant case.
+
+       * src/python/gnuradio/eng_option.py (check_eng_float): support
+       engineering notation in option parsing.  E.g., 32k, 106.5M
+
+2004-08-18  Eric Blossom  <eb@comsec.com>
+
+       * src/python/gnuradio/gr/scheduler.py,
+       src/python/gnuradio/gr/basic_flow_graph.py,
+       src/python/gnuradio/gr/flow_graph.py,
+       src/python/gnuradio/gr/qa_flowgraph.py: modified to partition
+       graphs and assign separate threads to each disjoint set of
+       verticies.
+       
+
+2004-08-05  Eric Blossom  <eb@comsec.com>
+
+       * src/lib/general/gr_lfsr_32k_source_s.{h,cc,i}: new.
+
+       * src/lib/general/gr_check_counting_s.{h,cc,i}: renamed from gr_counting_sink.
+       * src/lib/general/gri_lfsr_15_1_0.h: new LFSR generator with
+       period 32K-1 bits.
+       * src/lib/general/gri_lfsr_32k.h: new LFSR generator with period
+       32K bits.
+       * src/lib/general/gr_counting_sink_s.{h,cc,i}: new.  checks that
+       it's input is a counting sequence.
+       * src/lib/filter/Makefile.am: added missing .t files
+
+2004-07-31  Eric Blossom  <eb@comsec.com>
+
+       * src/lib/general/gr_vector_source_X.{h,cc,i}.t: added repeat
+       argument to constructor.
+
+2004-07-30  Eric Blossom  <eb@comsec.com>
+
+       * src/lib/general/gr_sig_source_X.cc.t (work): now use gr_sincos
+       to compute both at same time.
+
+       * src/lib/general/gr_nco.h (gr_nco): renamed method cossin -> sincos
+       and use gr_sincos to compute value.
+
+       * configure.ac: upped rev to 2.1cvs.
+
+2004-07-21  Eric Blossom  <eb@comsec.com>
+
+       * configure.ac: upped rev to 2.1.  Made release.
+
+2004-07-20  Eric Blossom  <eb@comsec.com>
+
+       * src/python/gnuradio/optfir.py: new.  High level routines for optimal FIR design.
+       * src/lib/general/gr_remez.{h,cc}: new.  Parks-McClellan method
+       for optimal FIR design.
+
+2004-07-19  Eric Blossom  <eb@comsec.com>
+
+       * src/lib/general/gri_add_const_ss_generic.cc: new.
+       * src/lib/general/gri_add_const_ss.h: new.
+
+2004-07-17  Eric Blossom  <eb@comsec.com>
+
+       * src/python/gnuradio/gr/flow_graph.py (buffer_sizes.allocate):
+       take into account output_multiple when computing buffer size.
+
+       * src/lib/runtime/gr_block.i: added output_multiple and
+       relative_rate to swig interface.
+
+2004-07-12  Eric Blossom  <eb@comsec.com>
+
+       * configure.ac: upped rev to 2.0cvs
+
+       * src/python/gnuradio/sdr_1000.py: added back in.
+       * src/lib/io/sdr_1000.{h,cc}: added back in.
+
+2004-07-11  Eric Blossom  <eb@comsec.com>
+
+       * config/gr_boost.m4 (GR_REQUIRE_BOOST_INCLUDES): new m4 macro.
+
+2004-07-09  Eric Blossom  <eb@comsec.com>
+
+       * src/lib/audio-oss: removed all files and moved to gr-audio-oss package.
+
+2004-07-04  Eric Blossom  <eb@comsec.com>
+
+       * src/lib/general/gr_{add,sub,multiply,divide}_XX.{h,i,cc}.t: new
+       * src/lib/general/gr_multiply_const_XX.{h,i,cc}.t: new
+       * src/lib/runtime/gr_block.{h,cc} (class gr_block): renamed
+       basic_work method to general_work
+       * src/lib/general/gr_sync_block.{h,cc} (class gr_sync_block): 
+       renamed sync_work method to work.
+
+2004-07-03  Eric Blossom  <eb@comsec.com>
+
+       * src/python/gnuradio/gr/scheduler.py: new.  Now run graph in
+       separate thread.
+       * src/lib/runtime/gr_single_threaded_scheduler.{h,i,cc}: added
+       stop method.
+       * src/lib/general/gr_noise_source_X.{h,i,cc}.t: new random noise source.
+       * config/gr_swig.m4: fail, not warn, if the right version isn't found.
+       * src/lib/general/gr_random.{h,cc}: moved implementation specific
+       defines out of header and into implementation.  Also moved statics
+       into class and cleaned up a couple of other annoyances.
+
+2004-07-01  Eric Blossom  <eb@comsec.com>
+
+       * src/python/gnuradio/gr/run_tests.in: new.  Sets PYTHONPATH
+       for sucessful testing in build tree; runs all tests.
+       * src/lib/runtime/{gr_block.i,gr_swig_block_magic.i}: revised to
+       use lambda expression for repr printing instead of referencing global.
+       * src/lib/swig/Makefile.am: now generate standalone swig runtime
+       library that all other swig modules link against.
+       
+2004-06-21  Eric Blossom  <eb@comsec.com>
+
+       Cleaned up interface to microtune modules and eval boards.
+       Now uses boost::shared_ptr's.  Refactored all uses 4937 and 4702,
+       and corresponding eval board classes.
+       
+       * src/lib/io/i2c.{h,cc}: split into i2c.{h,cc} and i2c_bitbang.{h,cc}
+       * src/lib/io/eval_board_4702_defs.h: deleted.
+       * src/lib/io/i2cio.{h,cc}: renamed to i2c_bbio.{h,cc}
+       * src/lib/io/i2cio_pp.{h,cc}: renamed to i2c_bbio_pp.{h,cc}
+
+2004-06-13  Eric Blossom  <eb@comsec.com>
+
+       * src/lib/general/gr_quadrature_demod_cf.{i,h,cc}: new.
+
+       * src/lib/audio-oss/gr_audio_sink_oss.{i,h,cc}: new.
+       FIXME: should be moved into a different build tree to decouple oss
+       dependency.
+
+       * src/lib/io/gr_file_{sink,source}.{i,h,cc} io.i: new.
+       
+2004-06-12  Eric Blossom  <eb@comsec.com>
+
+       * src/lib/general/gr_sig_source_X.{h,cc,i}.t: new
+       * src/lib/general/gr_sig_source_waveform.h: new
+       * src/lib/general/gr_head.{h,cc,i}: new
+
+       * src/lib/runtime/gr_block_detail.cc (set_done), gr_buffer.h:
+       propagate "done" upstream
+
+
+2004-XX-XX  Eric Blossom  <eb@comsec.com>
+
+       Months of changes...  This was whatever it took to get
+       the beginning of the new code base working...
+       
+2004-03-11  Eric Blossom  <eb@comsec.com>
+
+       * src/lib/runtime/io_signature.{h,cc},
+       * src/lib/runtime/qa_io_signature.{h,cc}: new.
+
+2004-03-08  Eric Blossom  <eb@comsec.com>
+
+       Removed cppunit from our build tree and updated qa code to work
+       with cppunit-1.9.12
+
+       * Makefile.am
+       * bootstrap
+       * configure.ac
+       * config/Makefile.am
+       * config/cppunit.m4
+       * src/lib/Makefile.am
+       * src/lib/atsc/convolutional_interleaver.h
+       * src/lib/atsc/qa_atsc_basic_trellis_encoder.cc
+       * src/lib/atsc/qa_atsc_data_interleaver.cc
+       * src/lib/atsc/qa_atsc_equalizer_nop.cc
+       * src/lib/atsc/qa_atsc_fake_single_viterbi.cc
+       * src/lib/atsc/qa_atsc_fs_correlator.cc
+       * src/lib/atsc/qa_atsc_randomizer.cc
+       * src/lib/atsc/qa_atsc_reed_solomon.cc
+       * src/lib/atsc/qa_atsc_single_viterbi.cc
+       * src/lib/atsc/qa_atsc_trellis_encoder.cc
+       * src/lib/atsc/qa_atsc_viterbi_decoder.cc
+       * src/lib/atsc/qa_convolutional_interleaver.cc
+       * src/lib/atsc/qa_interleaver_fifo.cc
+       * src/lib/filter/qa_complex_dotprod_x86.cc
+       * src/lib/filter/qa_float_dotprod_x86.cc
+       * src/lib/filter/qa_gr_fir_CCF.cc
+       * src/lib/filter/qa_gr_fir_FCC.cc
+       * src/lib/filter/qa_gr_fir_FFF.cc
+       * src/lib/filter/qa_gr_fir_SCC.cc
+       * src/lib/filter/qa_gr_mmse_fir_interpolator.cc
+       * src/lib/filter/qa_sse_float_dotprod.cc
+       * src/lib/general/qa_gr_circular_file.cc
+       * src/lib/general/qa_gr_firdes.cc
+       * src/lib/general/old/qa_gr_fir_SSS.cc
+       * src/lib/general/old/qa_gr_fir_sse.cc
+       * src/lib/runtime/qa_gr_vmcircbuf.cc
+       * src/lib/vrx/VrComplex.h
+       * src/tests/GrTestSink.cc
+       * src/tests/GrTestSkippingSink.cc
+       * src/tests/GrTestSource.cc
+
+       
+
+This code was derived from gnuradio-0.9 with a massive amount of hacking.
+       
+#
+# Copyright 2001,2002,2003,2004,2005,2006 Free Software Foundation, Inc.
+# 
+# This file is part of GNU Radio
+# 
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 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.
+# 
diff --git a/gnuradio-core/Makefile.am b/gnuradio-core/Makefile.am
new file mode 100644 (file)
index 0000000..b4b619b
--- /dev/null
@@ -0,0 +1,36 @@
+#
+# 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 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.
+# 
+
+include $(top_srcdir)/Makefile.common
+
+EXTRA_DIST =                           \
+       gnuradio-core.conf              \
+       gnuradio-core.pc.in             \
+       README.hacking                  \
+       README-win32-mingw-short.txt
+
+SUBDIRS = src doc
+
+pkgconfigdir = $(libdir)/pkgconfig
+pkgconfig_DATA = gnuradio-core.pc
+
+etcdir = $(sysconfdir)/gnuradio/conf.d
+etc_DATA = gnuradio-core.conf
diff --git a/gnuradio-core/NEWS b/gnuradio-core/NEWS
new file mode 100644 (file)
index 0000000..bd9ab53
--- /dev/null
@@ -0,0 +1,35 @@
+GNU Radio -- History of visible changes.
+
+Copyright (C) 2001, Free Software Foundation, Inc.
+See the end for copying conditions.
+
+Please send GNU Radio bug reports to bug-gnuradio@fsf.org
+
+Version 0.2
+
+* This the first "real release"
+
+
+Version 0.1
+
+* We're working toward the first alpha distribution
+
+* The build strategy is in the processes of being converted to use
+  automake.  It is mostly complete, but there are still some untested directories
+  which still contain Makefile.in's
+
+-------------------------------------------------------
+Copying information:
+
+Copyright (C) 2001, Free Software Foundation, Inc.
+
+   Permission is granted to anyone to make or distribute verbatim copies
+   of this document as received, in any medium, provided that the
+   copyright notice and this permission notice are preserved,
+   thus giving the recipient permission to redistribute in turn.
+
+   Permission is granted to distribute modified versions
+   of this document, or of portions of it,
+   under the above conditions, provided also that they
+   carry prominent notices stating who last changed them.
+
diff --git a/gnuradio-core/README b/gnuradio-core/README
new file mode 100644 (file)
index 0000000..dfc0ac8
--- /dev/null
@@ -0,0 +1,190 @@
+#
+# Copyright 2001,2002,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 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.
+# 
+
+-------------------------------------------------------------------------------
+
+                               IMPORTANT
+
+-------------------------------------------------------------------------------
+
+GNU Radio is now broken up into several packages.  You're looking at
+the gnuradio-core.  You'll probably want some or all of these too.
+Build and install them in the order listed here:
+
+  gnuradio-core     # main library
+  gnuradio-examples # examples
+  gr-audio-alsa     # support for sounds cards using ALSA (prefered under GNU/Linux)
+  gr-audio-oss      # support for sounds cards using OSS
+  gr-audio-jack     # support for JACK Audio Connection Kit
+  gr-audio-windows  # support for sounds cards using Windows Wave
+  gr-comedi         # support for DAQ cards using COMEDI
+  gr-wxgui         # GUI framework built on wxPython
+  usrp             # non-GNU Radio specific portion of usrp
+  gr-usrp          # glues usrp into GNU Radio
+  mc4020           # GNU/Linux driver for Measurement Computing PCI-DAS4020/12 A/D board
+  gr-mc4020        # the glue that ties the mc4020 driver into GNU Radio
+
+
+-------------------------------------------------------------------------------
+
+                      KNOWN INCOMPATIBILITIES
+
+
+  GNU Radio triggers bugs in g++ 3.3 for X86.  DO NOT USE GCC 3.3.
+  gcc 3.2 and 3.4 are known to work well.
+
+-------------------------------------------------------------------------------
+
+Prerequisites (you may already have these):
+
+(1)  pkgconfig 0.15.0 or later  http://www.freedesktop.org/Software/pkgconfig
+
+From the web site:
+
+pkgconfig is a system for managing library compile/link flags that
+works with automake and autoconf. It replaces the ubiquitous *-config
+scripts you may have seen with a single tool.
+
+
+(2)  FFTW 3.0 or later       http://www.fftw.org
+
+IMPORTANT!!!  When building FFTW, you MUST use the --enable-single and
+--enable-shared configure options.  This builds the single precision
+floating point version which we use.  You should also use either the
+--enable-3dnow or --enable-sse options if you're on an Athlon or Pentium
+respectively.
+
+
+(3) Python 2.3 or later              http://www.python.org
+
+Python 2.3 or later is now required.  If your distribution splits
+python into a bunch of separate RPMS including python-devel or
+libpython you'll most likely need those too.
+
+
+(4) Numeric python library   http://numeric.scipy.org
+
+Provides a high performance array type for Python.
+
+
+(5) The Boost C++ Libraries    http://www.boost.org
+
+We use the Smart Pointer library.  Fedore Core 2 has a package for
+this, boost-devel-1.31.0-7.  Otherwise download the source and follow
+the build instructions.  They're a bit different from the normal
+./configure && make
+
+
+(6) cppunit 1.9.14 or later.   http://cppunit.sourceforge.net
+
+Unit testing framework for C++.
+
+
+(7) Simple Wrapper Interface Generator.  http://www.swig.org
+
+These versions are known to work:
+  1.3.23, 1.3.24, 1.3.25, 1.3.27, 1.3.28, 1.3.29
+
+----------------------------------------------------------------
+
+For the impatient, just do the following:
+
+       $ ./configure
+       $ make
+       $ make check
+       $ make install
+
+If it doesn't work, fix it and send us a patch...
+
+
+See http://www.gnu.org/software/gnuradio/ for an overview.
+The project is hosted at http://savannah.gnu.org/projects/gnuradio/
+
+
+If you've got doxygen installed and provide the --enable-doxygen
+configure option, the build process creates documentation for the
+class hierarchy etc.  Point your browser at
+gnuradio-core/doc/html/index.html
+
+
+To run the examples you'll need to set PYTHONPATH.
+Note that the python version number in the path needs to match your
+installed version of python.
+
+  $ export PYTHONPATH=/usr/local/lib/python2.3/site-packages
+
+You may want to add this to your ~/.bash_profile
+
+
+
+----------------------------------------------------------------
+
+    Notes on building GNU Radio from the CVS repository
+
+----------------------------------------------------------------
+
+If you're building from the CVS repository YOU MUST BE PLAYING BY THE
+RULES THAT THE OTHER DEVELOPERS ARE USING.  This is especially true
+with regard to the versions of the tools below...
+
+Ensure that you've got THESE VERSIONS of the following tools:
+
+       autoconf 2.57    or later
+       automake 1.7.4   or later
+       libtool  1.5     or later
+       swig     1.3.{23,24,25,27,28,29}
+
+If you're using earlier versions than these, don't expect the system
+to build.  Get these versions or something later.  They're available
+at any of the GNU mirrors.
+
+Then, check out a copy of GNU Radio.  
+
+See http://www.gnu.org/software/gnuradio for directions on anonymous
+access to the CVS repository.
+
+Then in the top level directory, execute
+
+     $ ./bootstrap
+
+This builds configure from configure.ac and also builds all the
+Makefile.in's from the Makefile.am's.
+
+Then carry on as usual:
+
+     $ ./configure
+     $ make
+     $ make check
+     $ make install
+
+
+For the easiest way to build from CVS, see
+http://comsec.com/wiki?HowtoBuildFromCVS
+
+
+
+Another handy trick if for example your fftw includes and libs are
+installed in, say ~/local/include and ~/local/lib, instead of
+/usr/local is this:
+
+    $ export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$HOME/local/lib
+    $ make CPPFLAGS="-I$HOME/local/include"
+
diff --git a/gnuradio-core/README-win32-mingw-short.txt b/gnuradio-core/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/gnuradio-core/README.hacking b/gnuradio-core/README.hacking
new file mode 100644 (file)
index 0000000..7e211e0
--- /dev/null
@@ -0,0 +1,178 @@
+# -*- Outline -*-
+#
+# 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.
+# 
+
+
+Random notes on coding conventions, some explanations about why things
+aren't done differently, etc, etc,
+
+
+* C++ and Python
+
+GNU Radio is now a hybrid system.  Some parts of the system are built
+in C++ and some of it in Python.  In general, prefer Python to C++.
+Signal processing primitives are still built in C++ for performance.
+
+It is no longer possible to build user applications entirely in C++.
+Essential parts of the runtime system have been moved into Python.
+
+
+* C++ namespaces
+
+In the cleanup process, I considered putting everything in the
+gnuradio namespace and dropping the Gr|gr prefix.  In fact, I think
+it's probably the right idea, but when I tested it out, I ran into
+problems with SWIG's handling of namespaces.  Bottom line, SWIG
+(1.3.21) got confused and generated bad code when I started playing
+around with namespaces in a not particularly convoluted way.  I saw
+problems using the boost::shared_ptr template in combination with
+classes defined in the gnuradio namespace.  It wasn't pretty...
+
+
+* Naming conventions
+
+Death to CamelCaseNames!  We've returned to a kinder, gentler era.
+We're now using the "STL style" naming convention with a couple of
+modifications since we're not using namespaces.
+
+With the exception of macros and other constant values, all
+identifiers shall be lower case with words_separated_like_this.
+
+Macros and constant values (e.g., enumerated values,
+static const int FOO = 23) shall be in UPPER_CASE.
+
+
+** Global names
+
+All globally visible names (types, functions, variables, consts, etc)
+shall begin with a "package prefix", followed by an '_'.  The bulk of
+the code in GNU Radio logically belongs to the "gr" package, hence
+names look like gr_open_file (...).
+
+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.
+
+*** Package prefixes
+
+These are the current package prefixes:
+
+    gr_                Almost everything
+
+    gri_       Implementation primitives.  Sometimes we
+               have both a gr_<foo> and a gri_<foo>.  In that case,
+               gr_<foo> would be derived from gr_block and gri_<foo>
+               would be the low level guts of the function.
+
+    atsc_      Code related to the Advanced Television
+               Standards Committee HDTV implementation
+
+    usrp_      Universal Software Radio Peripheral
+
+    qa_                Quality Assurance.  Test code.
+
+
+** Class data members (instance variables)
+
+All class data members shall begin with d_<foo>.
+
+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_. 
+
+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)
+  {
+    ...
+  }
+  ...
+};
+
+
+** Class static data members (class variables)
+
+All class static data members shall begin with s_<foo>.
+
+
+** File names
+
+Each significant class shall be contained in it's own file.  The
+declaration of class gr_foo shall be in gr_foo.h, the definition in
+gr_foo.cc.
+
+
+
+* Storage management
+
+Strongly consider using the boost smart pointer templates, scoped_ptr
+and shared_ptr.  scoped_ptr should be used for locals that contain
+pointers to objects that we need to delete when we exit the current
+scope.  shared_ptr implements transparent reference counting and is a
+major win.  You never have to worry about calling delete.  The right
+thing happens.
+
+See http://www.boost.org/libs/smart_ptr/smart_ptr.htm
+
+
+* Unit tests
+
+Build unit tests for everything non-trivial and run them after every
+change.  Check out Extreme Programming: 
+http://c2.com/cgi/wiki?ExtremeProgrammingRoadmap
+
+Unit tests should also be written for all examples.  This should kill
+off the bit rot we've been plagued with.
+
+** C++ unit tests
+
+For C++ we're using the cppunit framework.  cppunit has its bad
+smells, but it's mostly workable.  http://cppunit.sf.net
+
+Currently each directory <dirname> contains files qa_<dirname>.{h,cc}
+that bring together all the qa_<foo> test suites in the directory.
+We ought to be able to automate this without too much trouble.
+
+The directory gnuradio-core/src/tests contains programs that run
+the tests.  test_all runs all of the registered C++ unit tests.
+
+As far as I can tell, the cppunit TestFactoryRegistry maybe able to be
+tricked into doing what we want.  As is, I don't think it's enough by
+itself, since there's nothing dragging the qa* files out of the
+library and into the program.   I haven't tested out this idea.
+
+** Python unit tests
+
+We use the standard unittest package for unit testing of Python code.
+
+
+* Misc tips
+
+ccache, a compiler cache, can really speed up your builds.
+See http://ccache.samba.org/
+
+Be sure to create links for gcc and g++
diff --git a/gnuradio-core/THANKS b/gnuradio-core/THANKS
new file mode 100644 (file)
index 0000000..00e4488
--- /dev/null
@@ -0,0 +1,7 @@
+GNU Radio THANKS file
+
+GNU Radio has originally been written by Free Software Foundation, Inc.
+Many people have further contributed to GNU Radio by reporting problems, 
+suggesting various improvements, or submitting actual code. Here is
+a list of these people. Help me keep it complete and exempt of errors.
+
diff --git a/gnuradio-core/TODO b/gnuradio-core/TODO
new file mode 100644 (file)
index 0000000..f9521c2
--- /dev/null
@@ -0,0 +1,14 @@
+Have configure check for correct version of SWIG.
+gr_swig checks, but doesn't set any variable that can be checked
+afterwards.
+
+Failure to find SWIG should disable build of scripting directory
+
+
+Have configure search for FFTW includes and libraries (use pkg-config
+to find them)
+
+Come up with a consistent naming strategy and implement it!
+
+make o'scope display fast enough
+
diff --git a/gnuradio-core/doc/Doxyfile.in b/gnuradio-core/doc/Doxyfile.in
new file mode 100644 (file)
index 0000000..7283a7b
--- /dev/null
@@ -0,0 +1,1224 @@
+# Doxyfile 1.4.1
+
+# This file describes the settings to be used by the documentation system
+# doxygen (www.doxygen.org) for a project
+#
+# All text after a hash (#) is considered a comment and will be ignored
+# The format is:
+#       TAG = value [value, ...]
+# For lists items can also be appended using:
+#       TAG += value [value, ...]
+# Values that contain spaces should be placed between quotes (" ")
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+
+# The PROJECT_NAME tag is a single word (or a sequence of words surrounded 
+# by quotes) that should identify the project.
+
+PROJECT_NAME           = "GNU Radio 2.x"
+
+# The PROJECT_NUMBER tag can be used to enter a project or revision number. 
+# This could be handy for archiving the generated documentation or 
+# if some version control system is used.
+
+PROJECT_NUMBER         = 
+
+# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) 
+# base path where the generated documentation will be put. 
+# If a relative path is entered, it will be relative to the location 
+# where doxygen was started. If left blank the current directory will be used.
+
+OUTPUT_DIRECTORY       = 
+
+# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create 
+# 4096 sub-directories (in 2 levels) under the output directory of each output 
+# format and will distribute the generated files over these directories. 
+# Enabling this option can be useful when feeding doxygen a huge amount of 
+# source files, where putting all generated files in the same directory would 
+# otherwise cause performance problems for the file system.
+
+CREATE_SUBDIRS         = NO
+
+# The OUTPUT_LANGUAGE tag is used to specify the language in which all 
+# documentation generated by doxygen is written. Doxygen will use this 
+# information to generate all constant output in the proper language. 
+# The default language is English, other supported languages are: 
+# Brazilian, Catalan, Chinese, Chinese-Traditional, Croatian, Czech, Danish, 
+# Dutch, Finnish, French, German, Greek, Hungarian, Italian, Japanese, 
+# Japanese-en (Japanese with English messages), Korean, Korean-en, Norwegian, 
+# Polish, Portuguese, Romanian, Russian, Serbian, Slovak, Slovene, Spanish, 
+# Swedish, and Ukrainian.
+
+OUTPUT_LANGUAGE        = English
+
+# This tag can be used to specify the encoding used in the generated output. 
+# The encoding is not always determined by the language that is chosen, 
+# but also whether or not the output is meant for Windows or non-Windows users. 
+# In case there is a difference, setting the USE_WINDOWS_ENCODING tag to YES 
+# forces the Windows encoding (this is the default for the Windows binary), 
+# whereas setting the tag to NO uses a Unix-style encoding (the default for 
+# all platforms other than Windows).
+
+USE_WINDOWS_ENCODING   = NO
+
+# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will 
+# include brief member descriptions after the members that are listed in 
+# the file and class documentation (similar to JavaDoc). 
+# Set to NO to disable this.
+
+BRIEF_MEMBER_DESC      = YES
+
+# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend 
+# the brief description of a member or function before the detailed description. 
+# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the 
+# brief descriptions will be completely suppressed.
+
+REPEAT_BRIEF           = YES
+
+# This tag implements a quasi-intelligent brief description abbreviator 
+# that is used to form the text in various listings. Each string 
+# in this list, if found as the leading text of the brief description, will be 
+# stripped from the text and the result after processing the whole list, is 
+# used as the annotated text. Otherwise, the brief description is used as-is. 
+# If left blank, the following values are used ("$name" is automatically 
+# replaced with the name of the entity): "The $name class" "The $name widget" 
+# "The $name file" "is" "provides" "specifies" "contains" 
+# "represents" "a" "an" "the"
+
+ABBREVIATE_BRIEF       = 
+
+# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then 
+# Doxygen will generate a detailed section even if there is only a brief 
+# description.
+
+ALWAYS_DETAILED_SEC    = NO
+
+# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all 
+# inherited members of a class in the documentation of that class as if those 
+# members were ordinary class members. Constructors, destructors and assignment 
+# operators of the base classes will not be shown.
+
+INLINE_INHERITED_MEMB  = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full 
+# path before files name in the file list and in the header files. If set 
+# to NO the shortest path that makes the file name unique will be used.
+
+FULL_PATH_NAMES        = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag 
+# can be used to strip a user-defined part of the path. Stripping is 
+# only done if one of the specified strings matches the left-hand part of 
+# the path. The tag can be used to show relative paths in the file list. 
+# If left blank the directory from which doxygen is run is used as the 
+# path to strip.
+
+STRIP_FROM_PATH        = 
+
+# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of 
+# the path mentioned in the documentation of a class, which tells 
+# the reader which header file to include in order to use a class. 
+# If left blank only the name of the header file containing the class 
+# definition is used. Otherwise one should specify the include paths that 
+# are normally passed to the compiler using the -I flag.
+
+STRIP_FROM_INC_PATH    = 
+
+# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter 
+# (but less readable) file names. This can be useful is your file systems 
+# doesn't support long names like on DOS, Mac, or CD-ROM.
+
+SHORT_NAMES            = NO
+
+# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen 
+# will interpret the first line (until the first dot) of a JavaDoc-style 
+# comment as the brief description. If set to NO, the JavaDoc 
+# comments will behave just like the Qt-style comments (thus requiring an 
+# explicit @brief command for a brief description.
+
+JAVADOC_AUTOBRIEF      = NO
+
+# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen 
+# treat a multi-line C++ special comment block (i.e. a block of //! or /// 
+# comments) as a brief description. This used to be the default behaviour. 
+# The new default is to treat a multi-line C++ comment block as a detailed 
+# description. Set this tag to YES if you prefer the old behaviour instead.
+
+MULTILINE_CPP_IS_BRIEF = NO
+
+# If the DETAILS_AT_TOP tag is set to YES then Doxygen 
+# will output the detailed description near the top, like JavaDoc.
+# If set to NO, the detailed description appears after the member 
+# documentation.
+
+DETAILS_AT_TOP         = YES
+
+# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented 
+# member inherits the documentation from any documented member that it 
+# re-implements.
+
+INHERIT_DOCS           = YES
+
+# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC 
+# tag is set to YES, then doxygen will reuse the documentation of the first 
+# member in the group (if any) for the other members of the group. By default 
+# all members of a group must be documented explicitly.
+
+DISTRIBUTE_GROUP_DOC   = NO
+
+# The TAB_SIZE tag can be used to set the number of spaces in a tab. 
+# Doxygen uses this value to replace tabs by spaces in code fragments.
+
+TAB_SIZE               = 8
+
+# This tag can be used to specify a number of aliases that acts 
+# as commands in the documentation. An alias has the form "name=value". 
+# For example adding "sideeffect=\par Side Effects:\n" will allow you to 
+# put the command \sideeffect (or @sideeffect) in the documentation, which 
+# will result in a user-defined paragraph with heading "Side Effects:". 
+# You can put \n's in the value part of an alias to insert newlines.
+
+ALIASES                = 
+
+# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C 
+# sources only. Doxygen will then generate output that is more tailored for C. 
+# For instance, some of the names that are used will be different. The list 
+# of all members will be omitted, etc.
+
+OPTIMIZE_OUTPUT_FOR_C  = NO
+
+# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java sources 
+# only. Doxygen will then generate output that is more tailored for Java. 
+# For instance, namespaces will be presented as packages, qualified scopes 
+# will look different, etc.
+
+OPTIMIZE_OUTPUT_JAVA   = NO
+
+# Set the SUBGROUPING tag to YES (the default) to allow class member groups of 
+# the same type (for instance a group of public functions) to be put as a 
+# subgroup of that type (e.g. under the Public Functions section). Set it to 
+# NO to prevent subgrouping. Alternatively, this can be done per class using 
+# the \nosubgrouping command.
+
+SUBGROUPING            = YES
+
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+
+# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in 
+# documentation are documented, even if no documentation was available. 
+# Private class members and static file members will be hidden unless 
+# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
+
+EXTRACT_ALL            = YES
+
+# If the EXTRACT_PRIVATE tag is set to YES all private members of a class 
+# will be included in the documentation.
+
+EXTRACT_PRIVATE        = NO
+
+# If the EXTRACT_STATIC tag is set to YES all static members of a file 
+# will be included in the documentation.
+
+EXTRACT_STATIC         = NO
+
+# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) 
+# defined locally in source files will be included in the documentation. 
+# If set to NO only classes defined in header files are included.
+
+EXTRACT_LOCAL_CLASSES  = YES
+
+# This flag is only useful for Objective-C code. When set to YES local 
+# methods, which are defined in the implementation section but not in 
+# the interface are included in the documentation. 
+# If set to NO (the default) only methods in the interface are included.
+
+EXTRACT_LOCAL_METHODS  = NO
+
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all 
+# undocumented members of documented classes, files or namespaces. 
+# If set to NO (the default) these members will be included in the 
+# various overviews, but no documentation section is generated. 
+# This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_MEMBERS     = NO
+
+# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all 
+# undocumented classes that are normally visible in the class hierarchy. 
+# If set to NO (the default) these classes will be included in the various 
+# overviews. This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_CLASSES     = NO
+
+# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all 
+# friend (class|struct|union) declarations. 
+# If set to NO (the default) these declarations will be included in the 
+# documentation.
+
+HIDE_FRIEND_COMPOUNDS  = NO
+
+# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any 
+# documentation blocks found inside the body of a function. 
+# If set to NO (the default) these blocks will be appended to the 
+# function's detailed documentation block.
+
+HIDE_IN_BODY_DOCS      = NO
+
+# The INTERNAL_DOCS tag determines if documentation 
+# that is typed after a \internal command is included. If the tag is set 
+# to NO (the default) then the documentation will be excluded. 
+# Set it to YES to include the internal documentation.
+
+INTERNAL_DOCS          = NO
+
+# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate 
+# file names in lower-case letters. If set to YES upper-case letters are also 
+# allowed. This is useful if you have classes or files whose names only differ 
+# in case and if your file system supports case sensitive file names. Windows 
+# and Mac users are advised to set this option to NO.
+
+CASE_SENSE_NAMES       = YES
+
+# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen 
+# will show members with their full class and namespace scopes in the 
+# documentation. If set to YES the scope will be hidden.
+
+HIDE_SCOPE_NAMES       = NO
+
+# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen 
+# will put a list of the files that are included by a file in the documentation 
+# of that file.
+
+SHOW_INCLUDE_FILES     = YES
+
+# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] 
+# is inserted in the documentation for inline members.
+
+INLINE_INFO            = YES
+
+# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen 
+# will sort the (detailed) documentation of file and class members 
+# alphabetically by member name. If set to NO the members will appear in 
+# declaration order.
+
+SORT_MEMBER_DOCS       = YES
+
+# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the 
+# brief documentation of file, namespace and class members alphabetically 
+# by member name. If set to NO (the default) the members will appear in 
+# declaration order.
+
+SORT_BRIEF_DOCS        = NO
+
+# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be 
+# sorted by fully-qualified names, including namespaces. If set to 
+# NO (the default), the class list will be sorted only by class name, 
+# not including the namespace part. 
+# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
+# Note: This option applies only to the class list, not to the 
+# alphabetical list.
+
+SORT_BY_SCOPE_NAME     = NO
+
+# The GENERATE_TODOLIST tag can be used to enable (YES) or 
+# disable (NO) the todo list. This list is created by putting \todo 
+# commands in the documentation.
+
+GENERATE_TODOLIST      = YES
+
+# The GENERATE_TESTLIST tag can be used to enable (YES) or 
+# disable (NO) the test list. This list is created by putting \test 
+# commands in the documentation.
+
+GENERATE_TESTLIST      = YES
+
+# The GENERATE_BUGLIST tag can be used to enable (YES) or 
+# disable (NO) the bug list. This list is created by putting \bug 
+# commands in the documentation.
+
+GENERATE_BUGLIST       = YES
+
+# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or 
+# disable (NO) the deprecated list. This list is created by putting 
+# \deprecated commands in the documentation.
+
+GENERATE_DEPRECATEDLIST= YES
+
+# The ENABLED_SECTIONS tag can be used to enable conditional 
+# documentation sections, marked by \if sectionname ... \endif.
+
+ENABLED_SECTIONS       = 
+
+# The MAX_INITIALIZER_LINES tag determines the maximum number of lines 
+# the initial value of a variable or define consists of for it to appear in 
+# the documentation. If the initializer consists of more lines than specified 
+# here it will be hidden. Use a value of 0 to hide initializers completely. 
+# The appearance of the initializer of individual variables and defines in the 
+# documentation can be controlled using \showinitializer or \hideinitializer 
+# command in the documentation regardless of this setting.
+
+MAX_INITIALIZER_LINES  = 30
+
+# Set the SHOW_USED_FILES tag to NO to disable the list of files generated 
+# at the bottom of the documentation of classes and structs. If set to YES the 
+# list will mention the files that were used to generate the documentation.
+
+SHOW_USED_FILES        = YES
+
+# If the sources in your project are distributed over multiple directories 
+# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy 
+# in the documentation.
+
+# -eb
+SHOW_DIRECTORIES       = NO
+
+# The FILE_VERSION_FILTER tag can be used to specify a program or script that 
+# doxygen should invoke to get the current version for each file (typically from the 
+# version control system). Doxygen will invoke the program by executing (via 
+# popen()) the command <command> <input-file>, where <command> is the value of 
+# the FILE_VERSION_FILTER tag, and <input-file> is the name of an input file 
+# provided by doxygen. Whatever the progam writes to standard output 
+# is used as the file version. See the manual for examples.
+
+FILE_VERSION_FILTER    = 
+
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+
+# The QUIET tag can be used to turn on/off the messages that are generated 
+# by doxygen. Possible values are YES and NO. If left blank NO is used.
+
+QUIET                  = NO
+
+# The WARNINGS tag can be used to turn on/off the warning messages that are 
+# generated by doxygen. Possible values are YES and NO. If left blank 
+# NO is used.
+
+WARNINGS               = YES
+
+# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings 
+# for undocumented members. If EXTRACT_ALL is set to YES then this flag will 
+# automatically be disabled.
+
+WARN_IF_UNDOCUMENTED   = YES
+
+# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for 
+# potential errors in the documentation, such as not documenting some 
+# parameters in a documented function, or documenting parameters that 
+# don't exist or using markup commands wrongly.
+
+WARN_IF_DOC_ERROR      = YES
+
+# This WARN_NO_PARAMDOC option can be abled to get warnings for 
+# functions that are documented, but have no documentation for their parameters 
+# or return value. If set to NO (the default) doxygen will only warn about 
+# wrong or incomplete parameter documentation, but not about the absence of 
+# documentation.
+
+WARN_NO_PARAMDOC       = NO
+
+# The WARN_FORMAT tag determines the format of the warning messages that 
+# doxygen can produce. The string should contain the $file, $line, and $text 
+# tags, which will be replaced by the file and line number from which the 
+# warning originated and the warning text. Optionally the format may contain 
+# $version, which will be replaced by the version of the file (if it could 
+# be obtained via FILE_VERSION_FILTER)
+
+WARN_FORMAT            = "$file:$line: $text"
+
+# The WARN_LOGFILE tag can be used to specify a file to which warning 
+# and error messages should be written. If left blank the output is written 
+# to stderr.
+
+WARN_LOGFILE           = 
+
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+
+# The INPUT tag can be used to specify the files and/or directories that contain 
+# documented source files. You may enter file names like "myfile.cpp" or 
+# directories like "/usr/src/myproject". Separate the files or directories 
+# with spaces.
+
+INPUT                  = @top_srcdir@/src/lib \
+                         @top_srcdir@/src/tests \
+                         @top_srcdir@/doc/other
+
+# If the value of the INPUT tag contains directories, you can use the 
+# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp 
+# and *.h) to filter out the source-files in the directories. If left 
+# blank the following patterns are tested: 
+# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx 
+# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm
+
+FILE_PATTERNS          = *.h \
+                         *.cc \
+                         *.dox
+
+# The RECURSIVE tag can be used to turn specify whether or not subdirectories 
+# should be searched for input files as well. Possible values are YES and NO. 
+# If left blank NO is used.
+
+RECURSIVE              = YES
+
+# The EXCLUDE tag can be used to specify files and/or directories that should 
+# excluded from the INPUT source files. This way you can easily exclude a 
+# subdirectory from a directory tree whose root is specified with the INPUT tag.
+
+EXCLUDE                = CVS \
+                         @top_srcdir@/src/lib/swig/gnuradio_swig_python.cc \
+                         @top_srcdir@/src/lib/atsc \
+                         @top_srcdir@/src/lib/io-orig \
+                         @top_srcdir@/src/lib/vrx
+
+# The EXCLUDE_SYMLINKS tag can be used select whether or not files or 
+# directories that are symbolic links (a Unix filesystem feature) are excluded 
+# from the input.
+
+EXCLUDE_SYMLINKS       = NO
+
+# If the value of the INPUT tag contains directories, you can use the 
+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude 
+# certain files from those directories.
+
+EXCLUDE_PATTERNS       = moc_*.cc
+
+# The EXAMPLE_PATH tag can be used to specify one or more files or 
+# directories that contain example code fragments that are included (see 
+# the \include command).
+
+EXAMPLE_PATH           = 
+
+# If the value of the EXAMPLE_PATH tag contains directories, you can use the 
+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp 
+# and *.h) to filter out the source-files in the directories. If left 
+# blank all files are included.
+
+EXAMPLE_PATTERNS       = 
+
+# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be 
+# searched for input files to be used with the \include or \dontinclude 
+# commands irrespective of the value of the RECURSIVE tag. 
+# Possible values are YES and NO. If left blank NO is used.
+
+EXAMPLE_RECURSIVE      = NO
+
+# The IMAGE_PATH tag can be used to specify one or more files or 
+# directories that contain image that are included in the documentation (see 
+# the \image command).
+
+IMAGE_PATH             = 
+
+# The INPUT_FILTER tag can be used to specify a program that doxygen should 
+# invoke to filter for each input file. Doxygen will invoke the filter program 
+# by executing (via popen()) the command <filter> <input-file>, where <filter> 
+# is the value of the INPUT_FILTER tag, and <input-file> is the name of an 
+# input file. Doxygen will then use the output that the filter program writes 
+# to standard output.  If FILTER_PATTERNS is specified, this tag will be 
+# ignored.
+
+INPUT_FILTER           = 
+
+# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern 
+# basis.  Doxygen will compare the file name with each pattern and apply the 
+# filter if there is a match.  The filters are a list of the form: 
+# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further 
+# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER 
+# is applied to all files.
+
+FILTER_PATTERNS        = 
+
+# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using 
+# INPUT_FILTER) will be used to filter the input files when producing source 
+# files to browse (i.e. when SOURCE_BROWSER is set to YES).
+
+FILTER_SOURCE_FILES    = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+
+# If the SOURCE_BROWSER tag is set to YES then a list of source files will 
+# be generated. Documented entities will be cross-referenced with these sources. 
+# Note: To get rid of all source code in the generated output, make sure also 
+# VERBATIM_HEADERS is set to NO.
+
+SOURCE_BROWSER         = NO
+
+# Setting the INLINE_SOURCES tag to YES will include the body 
+# of functions and classes directly in the documentation.
+
+INLINE_SOURCES         = NO
+
+# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct 
+# doxygen to hide any special comment blocks from generated source code 
+# fragments. Normal C and C++ comments will always remain visible.
+
+STRIP_CODE_COMMENTS    = YES
+
+# If the REFERENCED_BY_RELATION tag is set to YES (the default) 
+# then for each documented function all documented 
+# functions referencing it will be listed.
+
+REFERENCED_BY_RELATION = YES
+
+# If the REFERENCES_RELATION tag is set to YES (the default) 
+# then for each documented function all documented entities 
+# called/used by that function will be listed.
+
+REFERENCES_RELATION    = YES
+
+# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen 
+# will generate a verbatim copy of the header file for each class for 
+# which an include is specified. Set to NO to disable this.
+
+VERBATIM_HEADERS       = YES
+
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+
+# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index 
+# of all compounds will be generated. Enable this if the project 
+# contains a lot of classes, structs, unions or interfaces.
+
+ALPHABETICAL_INDEX     = NO
+
+# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then 
+# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns 
+# in which this list will be split (can be a number in the range [1..20])
+
+COLS_IN_ALPHA_INDEX    = 5
+
+# In case all classes in a project start with a common prefix, all 
+# classes will be put under the same header in the alphabetical index. 
+# The IGNORE_PREFIX tag can be used to specify one or more prefixes that 
+# should be ignored while generating the index headers.
+
+IGNORE_PREFIX          = 
+
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_HTML tag is set to YES (the default) Doxygen will 
+# generate HTML output.
+
+GENERATE_HTML          = YES
+
+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `html' will be used as the default path.
+
+HTML_OUTPUT            = html
+
+# The HTML_FILE_EXTENSION tag can be used to specify the file extension for 
+# each generated HTML page (for example: .htm,.php,.asp). If it is left blank 
+# doxygen will generate files with .html extension.
+
+HTML_FILE_EXTENSION    = .html
+
+# The HTML_HEADER tag can be used to specify a personal HTML header for 
+# each generated HTML page. If it is left blank doxygen will generate a 
+# standard header.
+
+HTML_HEADER            = 
+
+# The HTML_FOOTER tag can be used to specify a personal HTML footer for 
+# each generated HTML page. If it is left blank doxygen will generate a 
+# standard footer.
+
+HTML_FOOTER            = 
+
+# The HTML_STYLESHEET tag can be used to specify a user-defined cascading 
+# style sheet that is used by each HTML page. It can be used to 
+# fine-tune the look of the HTML output. If the tag is left blank doxygen 
+# will generate a default style sheet. Note that doxygen will try to copy 
+# the style sheet file to the HTML output directory, so don't put your own 
+# stylesheet in the HTML output directory as well, or it will be erased!
+
+HTML_STYLESHEET        = 
+
+# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, 
+# files or namespaces will be aligned in HTML using tables. If set to 
+# NO a bullet list will be used.
+
+HTML_ALIGN_MEMBERS     = YES
+
+# If the GENERATE_HTMLHELP tag is set to YES, additional index files 
+# will be generated that can be used as input for tools like the 
+# Microsoft HTML help workshop to generate a compressed HTML help file (.chm) 
+# of the generated HTML documentation.
+
+GENERATE_HTMLHELP      = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can 
+# be used to specify the file name of the resulting .chm file. You 
+# can add a path in front of the file if the result should not be 
+# written to the html output directory.
+
+CHM_FILE               = 
+
+# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can 
+# be used to specify the location (absolute path including file name) of 
+# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run 
+# the HTML help compiler on the generated index.hhp.
+
+HHC_LOCATION           = 
+
+# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag 
+# controls if a separate .chi index file is generated (YES) or that 
+# it should be included in the master .chm file (NO).
+
+GENERATE_CHI           = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag 
+# controls whether a binary table of contents is generated (YES) or a 
+# normal table of contents (NO) in the .chm file.
+
+BINARY_TOC             = NO
+
+# The TOC_EXPAND flag can be set to YES to add extra items for group members 
+# to the contents of the HTML help documentation and to the tree view.
+
+TOC_EXPAND             = NO
+
+# The DISABLE_INDEX tag can be used to turn on/off the condensed index at 
+# top of each HTML page. The value NO (the default) enables the index and 
+# the value YES disables it.
+
+DISABLE_INDEX          = NO
+
+# This tag can be used to set the number of enum values (range [1..20]) 
+# that doxygen will group on one line in the generated HTML documentation.
+
+ENUM_VALUES_PER_LINE   = 4
+
+# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be
+# generated containing a tree-like index structure (just like the one that 
+# is generated for HTML Help). For this to work a browser that supports 
+# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, 
+# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are 
+# probably better off using the HTML help feature.
+
+GENERATE_TREEVIEW      = NO
+
+# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be 
+# used to set the initial width (in pixels) of the frame in which the tree 
+# is shown.
+
+TREEVIEW_WIDTH         = 250
+
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will 
+# generate Latex output.
+
+# -eb
+GENERATE_LATEX         = NO
+
+# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `latex' will be used as the default path.
+
+LATEX_OUTPUT           = latex
+
+# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be 
+# invoked. If left blank `latex' will be used as the default command name.
+
+LATEX_CMD_NAME         = latex
+
+# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to 
+# generate index for LaTeX. If left blank `makeindex' will be used as the 
+# default command name.
+
+MAKEINDEX_CMD_NAME     = makeindex
+
+# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact 
+# LaTeX documents. This may be useful for small projects and may help to 
+# save some trees in general.
+
+COMPACT_LATEX          = NO
+
+# The PAPER_TYPE tag can be used to set the paper type that is used 
+# by the printer. Possible values are: a4, a4wide, letter, legal and 
+# executive. If left blank a4wide will be used.
+
+PAPER_TYPE             = letter
+
+# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX 
+# packages that should be included in the LaTeX output.
+
+EXTRA_PACKAGES         = 
+
+# The LATEX_HEADER tag can be used to specify a personal LaTeX header for 
+# the generated latex document. The header should contain everything until 
+# the first chapter. If it is left blank doxygen will generate a 
+# standard header. Notice: only use this tag if you know what you are doing!
+
+LATEX_HEADER           = 
+
+# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated 
+# is prepared for conversion to pdf (using ps2pdf). The pdf file will 
+# contain links (just like the HTML output) instead of page references 
+# This makes the output suitable for online browsing using a pdf viewer.
+
+PDF_HYPERLINKS         = YES
+
+# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of 
+# plain latex in the generated Makefile. Set this option to YES to get a 
+# higher quality PDF documentation.
+
+USE_PDFLATEX           = NO
+
+# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. 
+# command to the generated LaTeX files. This will instruct LaTeX to keep 
+# running if errors occur, instead of asking the user for help. 
+# This option is also used when generating formulas in HTML.
+
+LATEX_BATCHMODE        = NO
+
+# If LATEX_HIDE_INDICES is set to YES then doxygen will not 
+# include the index chapters (such as File Index, Compound Index, etc.) 
+# in the output.
+
+LATEX_HIDE_INDICES     = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output 
+# The RTF output is optimized for Word 97 and may not look very pretty with 
+# other RTF readers or editors.
+
+GENERATE_RTF           = NO
+
+# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `rtf' will be used as the default path.
+
+RTF_OUTPUT             = rtf
+
+# If the COMPACT_RTF tag is set to YES Doxygen generates more compact 
+# RTF documents. This may be useful for small projects and may help to 
+# save some trees in general.
+
+COMPACT_RTF            = NO
+
+# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated 
+# will contain hyperlink fields. The RTF file will 
+# contain links (just like the HTML output) instead of page references. 
+# This makes the output suitable for online browsing using WORD or other 
+# programs which support those fields. 
+# Note: wordpad (write) and others do not support links.
+
+RTF_HYPERLINKS         = NO
+
+# Load stylesheet definitions from file. Syntax is similar to doxygen's 
+# config file, i.e. a series of assignments. You only have to provide 
+# replacements, missing definitions are set to their default value.
+
+RTF_STYLESHEET_FILE    = 
+
+# Set optional variables used in the generation of an rtf document. 
+# Syntax is similar to doxygen's config file.
+
+RTF_EXTENSIONS_FILE    = 
+
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_MAN tag is set to YES (the default) Doxygen will 
+# generate man pages
+
+GENERATE_MAN           = NO
+
+# The MAN_OUTPUT tag is used to specify where the man pages will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `man' will be used as the default path.
+
+MAN_OUTPUT             = man
+
+# The MAN_EXTENSION tag determines the extension that is added to 
+# the generated man pages (default is the subroutine's section .3)
+
+MAN_EXTENSION          = .3
+
+# If the MAN_LINKS tag is set to YES and Doxygen generates man output, 
+# then it will generate one additional man file for each entity 
+# documented in the real man page(s). These additional files 
+# only source the real man page, but without them the man command 
+# would be unable to find the correct page. The default is NO.
+
+MAN_LINKS              = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_XML tag is set to YES Doxygen will 
+# generate an XML file that captures the structure of 
+# the code including all documentation.
+
+GENERATE_XML           = YES
+
+# The XML_OUTPUT tag is used to specify where the XML pages will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `xml' will be used as the default path.
+
+XML_OUTPUT             = xml
+
+# The XML_SCHEMA tag can be used to specify an XML schema, 
+# which can be used by a validating XML parser to check the 
+# syntax of the XML files.
+
+XML_SCHEMA             = 
+
+# The XML_DTD tag can be used to specify an XML DTD, 
+# which can be used by a validating XML parser to check the 
+# syntax of the XML files.
+
+XML_DTD                = 
+
+# If the XML_PROGRAMLISTING tag is set to YES Doxygen will 
+# dump the program listings (including syntax highlighting 
+# and cross-referencing information) to the XML output. Note that 
+# enabling this will significantly increase the size of the XML output.
+
+# -eb
+XML_PROGRAMLISTING     = NO
+
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will 
+# generate an AutoGen Definitions (see autogen.sf.net) file 
+# that captures the structure of the code including all 
+# documentation. Note that this feature is still experimental 
+# and incomplete at the moment.
+
+GENERATE_AUTOGEN_DEF   = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_PERLMOD tag is set to YES Doxygen will 
+# generate a Perl module file that captures the structure of 
+# the code including all documentation. Note that this 
+# feature is still experimental and incomplete at the 
+# moment.
+
+GENERATE_PERLMOD       = NO
+
+# If the PERLMOD_LATEX tag is set to YES Doxygen will generate 
+# the necessary Makefile rules, Perl scripts and LaTeX code to be able 
+# to generate PDF and DVI output from the Perl module output.
+
+PERLMOD_LATEX          = NO
+
+# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be 
+# nicely formatted so it can be parsed by a human reader.  This is useful 
+# if you want to understand what is going on.  On the other hand, if this 
+# tag is set to NO the size of the Perl module output will be much smaller 
+# and Perl will parse it just the same.
+
+PERLMOD_PRETTY         = YES
+
+# The names of the make variables in the generated doxyrules.make file 
+# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. 
+# This is useful so different doxyrules.make files included by the same 
+# Makefile don't overwrite each other's variables.
+
+PERLMOD_MAKEVAR_PREFIX = 
+
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor   
+#---------------------------------------------------------------------------
+
+# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will 
+# evaluate all C-preprocessor directives found in the sources and include 
+# files.
+
+ENABLE_PREPROCESSING   = YES
+
+# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro 
+# names in the source code. If set to NO (the default) only conditional 
+# compilation will be performed. Macro expansion can be done in a controlled 
+# way by setting EXPAND_ONLY_PREDEF to YES.
+
+MACRO_EXPANSION        = NO
+
+# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES 
+# then the macro expansion is limited to the macros specified with the 
+# PREDEFINED and EXPAND_AS_PREDEFINED tags.
+
+EXPAND_ONLY_PREDEF     = NO
+
+# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files 
+# in the INCLUDE_PATH (see below) will be search if a #include is found.
+
+SEARCH_INCLUDES        = YES
+
+# The INCLUDE_PATH tag can be used to specify one or more directories that 
+# contain include files that are not input files but should be processed by 
+# the preprocessor.
+
+INCLUDE_PATH           = 
+
+# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard 
+# patterns (like *.h and *.hpp) to filter out the header-files in the 
+# directories. If left blank, the patterns specified with FILE_PATTERNS will 
+# be used.
+
+INCLUDE_FILE_PATTERNS  = 
+
+# The PREDEFINED tag can be used to specify one or more macro names that 
+# are defined before the preprocessor is started (similar to the -D option of 
+# gcc). The argument of the tag is a list of macros of the form: name 
+# or name=definition (no spaces). If the definition and the = are 
+# omitted =1 is assumed. To prevent a macro definition from being 
+# undefined via #undef or recursively expanded use the := operator 
+# instead of the = operator.
+
+PREDEFINED             = 
+
+# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then 
+# this tag can be used to specify a list of macro names that should be expanded. 
+# The macro definition that is found in the sources will be used. 
+# Use the PREDEFINED tag if you want to use a different macro definition.
+
+EXPAND_AS_DEFINED      = 
+
+# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then 
+# doxygen's preprocessor will remove all function-like macros that are alone 
+# on a line, have an all uppercase name, and do not end with a semicolon. Such 
+# function macros are typically used for boiler-plate code, and will confuse 
+# the parser if not removed.
+
+SKIP_FUNCTION_MACROS   = YES
+
+#---------------------------------------------------------------------------
+# Configuration::additions related to external references   
+#---------------------------------------------------------------------------
+
+# The TAGFILES option can be used to specify one or more tagfiles. 
+# Optionally an initial location of the external documentation 
+# can be added for each tagfile. The format of a tag file without 
+# this location is as follows: 
+#   TAGFILES = file1 file2 ... 
+# Adding location for the tag files is done as follows: 
+#   TAGFILES = file1=loc1 "file2 = loc2" ... 
+# where "loc1" and "loc2" can be relative or absolute paths or 
+# URLs. If a location is present for each tag, the installdox tool 
+# does not have to be run to correct the links.
+# Note that each tag file must have a unique name
+# (where the name does NOT include the path)
+# If a tag file is not located in the directory in which doxygen 
+# is run, you must also specify the path to the tagfile here.
+
+TAGFILES               = 
+
+# When a file name is specified after GENERATE_TAGFILE, doxygen will create 
+# a tag file that is based on the input files it reads.
+
+GENERATE_TAGFILE       = 
+
+# If the ALLEXTERNALS tag is set to YES all external classes will be listed 
+# in the class index. If set to NO only the inherited external classes 
+# will be listed.
+
+ALLEXTERNALS           = NO
+
+# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed 
+# in the modules index. If set to NO, only the current project's groups will 
+# be listed.
+
+EXTERNAL_GROUPS        = YES
+
+# The PERL_PATH should be the absolute path and name of the perl script 
+# interpreter (i.e. the result of `which perl').
+
+PERL_PATH              = /usr/bin/perl
+
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool   
+#---------------------------------------------------------------------------
+
+# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will 
+# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base 
+# or super classes. Setting the tag to NO turns the diagrams off. Note that 
+# this option is superseded by the HAVE_DOT option below. This is only a 
+# fallback. It is recommended to install and use dot, since it yields more 
+# powerful graphs.
+
+CLASS_DIAGRAMS         = YES
+
+# If set to YES, the inheritance and collaboration graphs will hide 
+# inheritance and usage relations if the target is undocumented 
+# or is not a class.
+
+HIDE_UNDOC_RELATIONS   = YES
+
+# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is 
+# available from the path. This tool is part of Graphviz, a graph visualization 
+# toolkit from AT&T and Lucent Bell Labs. The other options in this section 
+# have no effect if this option is set to NO (the default)
+
+HAVE_DOT               = @HAVE_DOT@
+
+# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen 
+# will generate a graph for each documented class showing the direct and 
+# indirect inheritance relations. Setting this tag to YES will force the 
+# the CLASS_DIAGRAMS tag to NO.
+
+CLASS_GRAPH            = YES
+
+# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen 
+# will generate a graph for each documented class showing the direct and 
+# indirect implementation dependencies (inheritance, containment, and 
+# class references variables) of the class with other documented classes.
+
+COLLABORATION_GRAPH    = YES
+
+# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen 
+# will generate a graph for groups, showing the direct groups dependencies
+
+GROUP_GRAPHS           = YES
+
+# If the UML_LOOK tag is set to YES doxygen will generate inheritance and 
+# collaboration diagrams in a style similar to the OMG's Unified Modeling 
+# Language.
+
+UML_LOOK               = NO
+
+# If set to YES, the inheritance and collaboration graphs will show the 
+# relations between templates and their instances.
+
+TEMPLATE_RELATIONS     = NO
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT 
+# tags are set to YES then doxygen will generate a graph for each documented 
+# file showing the direct and indirect include dependencies of the file with 
+# other documented files.
+
+INCLUDE_GRAPH          = YES
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and 
+# HAVE_DOT tags are set to YES then doxygen will generate a graph for each 
+# documented header file showing the documented files that directly or 
+# indirectly include this file.
+
+INCLUDED_BY_GRAPH      = YES
+
+# If the CALL_GRAPH and HAVE_DOT tags are set to YES then doxygen will 
+# generate a call dependency graph for every global function or class method. 
+# Note that enabling this option will significantly increase the time of a run. 
+# So in most cases it will be better to enable call graphs for selected 
+# functions only using the \callgraph command.
+
+CALL_GRAPH             = NO
+
+# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen 
+# will graphical hierarchy of all classes instead of a textual one.
+
+GRAPHICAL_HIERARCHY    = YES
+
+# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES 
+# then doxygen will show the dependencies a directory has on other directories 
+# in a graphical way. The dependency relations are determined by the #include
+# relations between the files in the directories.
+
+DIRECTORY_GRAPH        = YES
+
+# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images 
+# generated by dot. Possible values are png, jpg, or gif
+# If left blank png will be used.
+
+DOT_IMAGE_FORMAT       = png
+
+# The tag DOT_PATH can be used to specify the path where the dot tool can be 
+# found. If left blank, it is assumed the dot tool can be found in the path.
+
+DOT_PATH               = 
+
+# The DOTFILE_DIRS tag can be used to specify one or more directories that 
+# contain dot files that are included in the documentation (see the 
+# \dotfile command).
+
+DOTFILE_DIRS           = 
+
+# The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width 
+# (in pixels) of the graphs generated by dot. If a graph becomes larger than 
+# this value, doxygen will try to truncate the graph, so that it fits within 
+# the specified constraint. Beware that most browsers cannot cope with very 
+# large images.
+
+MAX_DOT_GRAPH_WIDTH    = 1024
+
+# The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height 
+# (in pixels) of the graphs generated by dot. If a graph becomes larger than 
+# this value, doxygen will try to truncate the graph, so that it fits within 
+# the specified constraint. Beware that most browsers cannot cope with very 
+# large images.
+
+MAX_DOT_GRAPH_HEIGHT   = 1024
+
+# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the 
+# graphs generated by dot. A depth value of 3 means that only nodes reachable 
+# from the root by following a path via at most 3 edges will be shown. Nodes 
+# that lay further from the root node will be omitted. Note that setting this 
+# option to 1 or 2 may greatly reduce the computation time needed for large 
+# code bases. Also note that a graph may be further truncated if the graph's 
+# image dimensions are not sufficient to fit the graph (see MAX_DOT_GRAPH_WIDTH 
+# and MAX_DOT_GRAPH_HEIGHT). If 0 is used for the depth value (the default), 
+# the graph is not depth-constrained.
+
+MAX_DOT_GRAPH_DEPTH    = 0
+
+# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent 
+# background. This is disabled by default, which results in a white background. 
+# Warning: Depending on the platform used, enabling this option may lead to 
+# badly anti-aliased labels on the edges of a graph (i.e. they become hard to 
+# read).
+
+DOT_TRANSPARENT        = NO
+
+# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output 
+# files in one run (i.e. multiple -o and -T options on the command line). This 
+# makes dot run faster, but since only newer versions of dot (>1.8.10) 
+# support this, this feature is disabled by default.
+
+# -eb
+DOT_MULTI_TARGETS      = YES
+
+# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will 
+# generate a legend page explaining the meaning of the various boxes and 
+# arrows in the dot generated graphs.
+
+GENERATE_LEGEND        = YES
+
+# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will 
+# remove the intermediate dot files that are used to generate 
+# the various graphs.
+
+DOT_CLEANUP            = YES
+
+#---------------------------------------------------------------------------
+# Configuration::additions related to the search engine   
+#---------------------------------------------------------------------------
+
+# The SEARCHENGINE tag specifies whether or not a search engine should be 
+# used. If set to NO the values of all tags below this one will be ignored.
+
+SEARCHENGINE           = NO
diff --git a/gnuradio-core/doc/Makefile.am b/gnuradio-core/doc/Makefile.am
new file mode 100644 (file)
index 0000000..562b366
--- /dev/null
@@ -0,0 +1,71 @@
+#
+# 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 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.
+# 
+
+include $(top_srcdir)/Makefile.common
+
+SUBDIRS = other xml
+
+man3dir = $(mandir)/man3
+docdir  = $(prefix)/share/doc/@PACKAGE@-@VERSION@
+
+EXTRA_DIST = 
+
+all-local: prep @generate_docs@
+doc: docs            # alias
+
+docs: prep html/index.html
+html/index.html:
+       @DOXYGEN@
+
+prep:
+       mkdir -p html
+
+#install-data-local:
+#      $(mkinstalldirs) $(DESTDIR)$(man3dir)
+#      @for i in ./man/man3/*.3; do \
+#              inst=`basename $$i | sed 's/_/:/g'`; \
+#              echo "$(INSTALL_DATA) $$i $(DESTDIR)$(man3dir)/$$inst"; \
+#              $(INSTALL_DATA) $$i $(DESTDIR)$(man3dir)/$$inst; \
+#      done
+#      $(mkinstalldirs) $(DESTDIR)$(docdir)
+##     @for i in ../README ../ChangeLog @PACKAGE@.ps @PACKAGE@.pdf; do \
+##             echo "$(INSTALL_DATA) $$i $(DESTDIR)$(docdir)"; \
+##             $(INSTALL_DATA) $$i $(DESTDIR)$(docdir); \
+##     done
+#      cp -r html $(docdir)
+
+install-data-local:
+       $(mkinstalldirs) $(DESTDIR)$(docdir)
+       @for i in $(top_srcdir)/README $(top_srcdir)/README.hacking $(top_srcdir)/ChangeLog; do \
+               echo "$(INSTALL_DATA) $$i $(DESTDIR)$(docdir)"; \
+               $(INSTALL_DATA) $$i $(DESTDIR)$(docdir); \
+       done
+       cp -r html $(DESTDIR)$(docdir)
+
+uninstall-local:
+       @for i in README README.hacking ChangeLog; do \
+               echo "$(RM) $(DESTDIR)$(docdir)/$$i;"; \
+               $(RM) $(DESTDIR)$(docdir)/$$i; \
+       done
+       $(RM) -fr $(DESTDIR)$(docdir)/html
+
+clean-local:
+       $(RM) -fr latex html man
diff --git a/gnuradio-core/doc/other/Makefile.am b/gnuradio-core/doc/other/Makefile.am
new file mode 100644 (file)
index 0000000..25685ed
--- /dev/null
@@ -0,0 +1,31 @@
+#
+# Copyright 2001,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.
+# 
+
+include $(top_srcdir)/Makefile.common
+
+EXTRA_DIST = \
+       tv-channel-frequencies          \
+       vector_docstub.h                \
+       shared_ptr_docstub.h            \
+       omnithread.html                 \
+       omnithread.pdf                  \
+       omnithread.ps                   \
+       group_defs.dox                  
diff --git a/gnuradio-core/doc/other/group_defs.dox b/gnuradio-core/doc/other/group_defs.dox
new file mode 100644 (file)
index 0000000..47cce21
--- /dev/null
@@ -0,0 +1,31 @@
+/*!
+ * \defgroup block Signal Processing Blocks
+ * These are the signal processing blocks, blah, blah blah...
+ * @{
+ */
+
+/*!
+ * \defgroup source Signal Sources
+ * signal sources docs...
+ */
+
+/*!
+ * \defgroup sink Signal Sinks
+ * docs for sinks...
+ */
+
+/*!
+ * \defgroup filter Filters
+ */
+
+/*!
+ * \defgroup converter Type Conversions
+ */
+
+/*! @} */
+
+/*! \defgroup filter_design Filter Design              */
+/*! \defgroup filter_primitive Filter Primitives       */
+/*! \defgroup internal Implementation Details          */
+/*! \defgroup qa Quality Assurance                     */
+
diff --git a/gnuradio-core/doc/other/main_page.dox b/gnuradio-core/doc/other/main_page.dox
new file mode 100644 (file)
index 0000000..5c37905
--- /dev/null
@@ -0,0 +1,5 @@
+/*! \mainpage
+
+Welcome to GNU Radio!
+
+*/
diff --git a/gnuradio-core/doc/other/omnithread.html b/gnuradio-core/doc/other/omnithread.html
new file mode 100644 (file)
index 0000000..5682d1d
--- /dev/null
@@ -0,0 +1,411 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"
+            "http://www.w3.org/TR/REC-html40/loose.dtd">
+<HTML>
+<HEAD><TITLE>The OMNI Thread Abstraction</TITLE>
+
+<META http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+<META name="GENERATOR" content="hevea 1.06">
+</HEAD>
+<BODY >
+<!--HEVEA command line is: /usr/local/bin/hevea omnithread -->
+<!--HTMLHEAD-->
+<!--ENDHTML-->
+<!--PREFIX <ARG ></ARG>-->
+<!--CUT DEF section 1 -->
+
+
+<H1 ALIGN=center>The OMNI Thread Abstraction</H1>
+
+<H3 ALIGN=center>Tristan Richardson<BR>
+AT&amp;T Laboratories Cambridge<BR>
+</H3>
+
+<H3 ALIGN=center><I>Revised</I> November 2001</H3>
+<!--TOC section Introduction-->
+
+<H2><A NAME="htoc1">1</A>&nbsp;&nbsp;Introduction</H2><!--SEC END -->
+
+The OMNI thread abstraction is designed to provide a common set of
+thread operations for use in programs written in C++. Programs
+written using the abstraction should be much easier to port between
+different architectures with different underlying threads primitives.<BR>
+<BR>
+The programming interface is designed to be similar to the C language
+interface to POSIX threads (IEEE draft standard 1003.1c --- previously
+1003.4a, often known as ``pthreads'' [<A HREF="#pthreads"><CITE>POSIX94</CITE></A>]).<BR>
+<BR>
+Much of the abstraction consists of simple C++ object wrappers around
+pthread calls. However for some features such as thread-specific
+data, a better interface can be offered because of the use of C++.<BR>
+<BR>
+Some of the more complex features of pthreads are not supported
+because of the difficulty of ensuring the same features can be offered
+on top of other thread systems. Such features include thread
+cancellation and complex scheduling control (though simple thread
+priorities are supported).<BR>
+<BR>
+The abstraction layer is currently implemented for the following
+architectures / thread systems:
+<UL><LI>Solaris 2.x using pthreads draft 10
+<LI>Solaris 2.x using solaris threads (but pthreads version is now standard)
+<LI>Alpha OSF1 using pthreads draft 4
+<LI>Windows NT using NT threads
+<LI>Linux 2.x using Linuxthread 0.5 (which is based on pthreads draft 10)
+<LI>Linux 2.x using MIT pthreads (which is based on draft 8)
+<LI>ATMos using pthreads draft 6 (but not Virata ATMos)</UL>
+See the <TT>omnithread.h</TT> header file for full details of the API.
+The descriptions below assume you have some previous knowledge of
+threads, mutexes, condition variables and semaphores. Also refer to
+other documentation ([<A HREF="#birrell"><CITE>Birrell89</CITE></A>], [<A HREF="#pthreads"><CITE>POSIX94</CITE></A>]) for further
+explanation of these ideas (particularly condition variables, the use
+of which may not be particularly intuitive when first encountered).<BR>
+<BR>
+<!--TOC section Synchronisation objects-->
+
+<H2><A NAME="htoc2">2</A>&nbsp;&nbsp;Synchronisation objects</H2><!--SEC END -->
+
+Synchronisation objects are used to synchronise threads within the
+same process. There is no inter-process synchronisation provided.
+The synchronisation objects provided are mutexes, condition variables
+and counting semaphores.<BR>
+<BR>
+<!--TOC subsection Mutex-->
+
+<H3><A NAME="htoc3">2.1</A>&nbsp;&nbsp;Mutex</H3><!--SEC END -->
+
+An object of type <TT>omni_mutex</TT> is used for mutual exclusion.
+It provides two operations, <TT>lock()</TT> and <TT>unlock()</TT>.
+The alternative names <TT>acquire()</TT> and <TT>release()</TT> can be
+used if preferred. Behaviour is undefined when a thread attempts to
+lock the same mutex again or when a mutex is locked by one thread and
+unlocked by a different thread.<BR>
+<BR>
+<!--TOC subsection Condition Variable-->
+
+<H3><A NAME="htoc4">2.2</A>&nbsp;&nbsp;Condition Variable</H3><!--SEC END -->
+
+A condition variable is represented by an <TT>omni_condition</TT> and
+is used for signalling between threads. A call to <TT>wait()</TT>
+causes a thread to wait on the condition variable. A call to
+<TT>signal()</TT> wakes up at least one thread if any are waiting. A
+call to <TT>broadcast()</TT> wakes up all threads waiting on the
+condition variable.<BR>
+<BR>
+When constructed, a pointer to an <TT>omni_mutex</TT> must be given.
+A condition variable <TT>wait()</TT> has an implicit mutex
+<TT>unlock()</TT> and <TT>lock()</TT> around it. The link between
+condition variable and mutex lasts for the lifetime of the condition
+variable (unlike pthreads where the link is only for the duration of
+the wait). The same mutex may be used with several condition
+variables.<BR>
+<BR>
+A wait with a timeout can be achieved by calling
+<TT>timed_wait()</TT>. This is given an absolute time to wait until.
+The routine <TT>omni_thread::get_time()</TT> can be used to turn a
+relative time into an absolute time. <TT>timed_wait()</TT> returns
+<TT>true</TT> if the condition was signalled, <TT>false</TT> if the
+time expired before the condition variable was signalled.<BR>
+<BR>
+<!--TOC subsection Counting semaphores-->
+
+<H3><A NAME="htoc5">2.3</A>&nbsp;&nbsp;Counting semaphores</H3><!--SEC END -->
+
+An <TT>omni_semaphore</TT> is a counting semaphore. When created it
+is given an initial unsigned integer value. When <TT>wait()</TT> is
+called, the value is decremented if non-zero. If the value is zero
+then the thread blocks instead. When <TT>post()</TT> is called, if
+any threads are blocked in <TT>wait()</TT>, exactly one thread is
+woken. If no threads were blocked then the value of the semaphore is
+incremented.<BR>
+<BR>
+If a thread calls <TT>try_wait()</TT>, then the thread won't block if
+the semaphore's value is 0, returning <TT>false</TT> instead.<BR>
+<BR>
+There is no way of querying the value of the semaphore.<BR>
+<BR>
+<!--TOC section Thread object-->
+
+<H2><A NAME="htoc6">3</A>&nbsp;&nbsp;Thread object</H2><!--SEC END -->
+
+A thread is represented by an <TT>omni_thread</TT> object. There are
+broadly two different ways in which it can be used.<BR>
+<BR>
+The first way is simply to create an <TT>omni_thread</TT> object,
+giving a particular function which the thread should execute. This is
+like the POSIX (or any other) C language interface.<BR>
+<BR>
+The second method of use is to create a new class which inherits from
+<TT>omni_thread</TT>. In this case the thread will execute the
+<TT>run()</TT> member function of the new class. One advantage of
+this scheme is that thread-specific data can be implemented simply by
+having data members of the new class.<BR>
+<BR>
+When constructed a thread is in the "new" state and has not actually
+started. A call to <TT>start()</TT> causes the thread to begin
+executing. A static member function <TT>create()</TT> is provided to
+construct and start a thread in a single call. A thread exits by
+calling <TT>exit()</TT> or by returning from the thread function.<BR>
+<BR>
+Threads can be either detached or undetached. Detached threads are
+threads for which all state will be lost upon exit. Other threads
+cannot determine when a detached thread will disappear, and therefore
+should not attempt to access the thread object unless some explicit
+synchronisation with the detached thread guarantees that it still
+exists.<BR>
+<BR>
+Undetached threads are threads for which storage is not reclaimed
+until another thread waits for its termination by calling
+<TT>join()</TT>. An exit value can be passed from an undetached
+thread to the thread which joins it.<BR>
+<BR>
+Detached / undetached threads are distinguished on creation by the
+type of function they execute. Undetached threads execute a function
+which has a <TT>void*</TT> return type, whereas detached threads
+execute a function which has a <TT>void</TT> return type.
+Unfortunately C++ member functions are not allowed to be distinguished
+simply by their return type. Thus in the case of a derived class of
+<TT>omni_thread</TT> which needs an undetached thread, the member
+function executed by the thread is called <TT>run_undetached()</TT>
+rather than <TT>run()</TT>, and it is started by calling
+<TT>start_undetached()</TT> instead of <TT>start()</TT>.<BR>
+<BR>
+The abstraction currently supports three priorities of thread, but no
+guarantee is made of how this will affect underlying thread
+scheduling. The three priorities are <TT>PRIORITY_LOW</TT>,
+<TT>PRIORITY_NORMAL</TT> and <TT>PRIORITY_HIGH</TT>. By default all
+threads run at <TT>PRIORITY_NORMAL</TT>. A different priority can be
+specified on thread creation, or while the thread is running using
+<TT>set_priority().</TT> A thread's current priority is returned by
+<TT>priority()</TT>.<BR>
+<BR>
+Other functions provided are <TT>self()</TT> which returns the calling
+thread's <TT>omni_thread</TT> object, <TT>yield()</TT> which
+requests that other threads be allowed to run, <TT>id()</TT> which
+returns an integer id for the thread for use in debugging,
+<TT>state()</TT>, <TT>sleep()</TT> and <TT>get_time()</TT>.<BR>
+<BR>
+<!--TOC section Per-thread data-->
+
+<H2><A NAME="htoc7">4</A>&nbsp;&nbsp;Per-thread data</H2><!--SEC END -->
+
+omnithread supports per-thread data, via member functions of the
+<TT>omni_thread</TT> object.<BR>
+<BR>
+First, you must allocate a key for with the
+<TT>omni_thread::allocate_key()</TT> function. Then, any object
+whose class is derived from <TT>omni_thread::value_t</TT> can be
+stored using the <TT>set_value()</TT> function. Values are retrieved
+or removed with <TT>get_value()</TT> and <TT>remove_value()</TT>
+respectively.<BR>
+<BR>
+When the thread exits, all per-thread data is deleted (hence the base
+class with virtual destructor).<BR>
+<BR>
+Note that the per-thread data functions are <B>not</B> thread safe,
+so although you can access one thread's storage from another thread,
+there is no concurrency control. Unless you really know what you are
+doing, it is best to only access per-thread data from the thread it is
+attached to.<BR>
+<BR>
+<!--TOC section Using OMNI threads in your program-->
+
+<H2><A NAME="htoc8">5</A>&nbsp;&nbsp;Using OMNI threads in your program</H2><!--SEC END -->
+
+Obviously you need to include the <TT>omnithread.h</TT> header file in
+your source code, and link in the omnithread library with your
+executable. Because there is a single <TT>omnithread.h</TT> for all
+platforms, certain preprocessor defines must be given as compiler
+options. The easiest way to do this is to study the makefiles given
+in the examples provided with this distribution. If you are to
+include OMNI threads in your own development environment, these are
+the necessary preprocessor defines:<BR>
+<TABLE BORDER=1 CELLSPACING=0 CELLPADDING=1>
+<TR><TD ALIGN=left NOWRAP>Platform</TD>
+<TD ALIGN=left NOWRAP>Preprocessor Defines</TD>
+</TR>
+<TR><TD ALIGN=left NOWRAP>Sun Solaris 2.x</TD>
+<TD ALIGN=left NOWRAP><CODE>-D__sunos__ -D__sparc__ -D__OSVERSION__=5</CODE></TD>
+</TR>
+<TR><TD ALIGN=left NOWRAP>&nbsp;</TD>
+<TD ALIGN=left NOWRAP><CODE>-DSVR4 -DUsePthread -D_REENTRANT</CODE></TD>
+</TR>
+<TR><TD ALIGN=left NOWRAP>x86 Linux 2.0</TD>
+<TD ALIGN=left NOWRAP><CODE>-D__linux__ -D__i86__ -D__OSVERSION__=2</CODE></TD>
+</TR>
+<TR><TD ALIGN=left NOWRAP>with linuxthreads 0.5</TD>
+<TD ALIGN=left NOWRAP><CODE>-D_REENTRANT</CODE></TD>
+</TR>
+<TR><TD ALIGN=left NOWRAP>Digital Unix 3.2</TD>
+<TD ALIGN=left NOWRAP><CODE>-D__osf1__ -D__alpha__ -D__OSVERSION__=3</CODE></TD>
+</TR>
+<TR><TD ALIGN=left NOWRAP>&nbsp;</TD>
+<TD ALIGN=left NOWRAP><CODE>-D_REENTRANT</CODE></TD>
+</TR>
+<TR><TD ALIGN=left NOWRAP>Windows NT</TD>
+<TD ALIGN=left NOWRAP><CODE>-D__NT__ -MD</CODE></TD>
+</TR></TABLE><BR>
+<!--TOC section Threaded I/O shutdown for Unix-->
+
+<H2><A NAME="htoc9">6</A>&nbsp;&nbsp;Threaded I/O shutdown for Unix</H2><!--SEC END -->
+
+or, how one thread should tell another thread to shut down when it
+might be doing a blocking call on a socket.<BR>
+<BR>
+<B>If you are using omniORB, you don't need to worry about all
+this, since omniORB does it for you.</B> This section is only relevant
+if you are using omnithread in your own socket-based programming. It
+is also seriously out of date.<BR>
+<BR>
+Unfortunately there doesn't seem to be a standard way of doing this
+which works across all Unix systems. I have investigated the
+behaviour of Solaris 2.5 and Digital Unix 3.2. On Digital Unix
+everything is fine, as the obvious method using shutdown() seems to
+work OK. Unfortunately on Solaris shutdown can only be used on a
+connected socket, so we need devious means to get around this
+limitation. The details are summarised below:<BR>
+<BR>
+<!--TOC subsection read()-->
+
+<H3><A NAME="htoc10">6.1</A>&nbsp;&nbsp;read()</H3><!--SEC END -->
+
+Thread A is in a loop, doing <CODE>read(sock)</CODE>, processing the data,
+then going back into the read.<BR>
+<BR>
+Thread B comes along and wants to shut it down --- it can't cancel
+thread A since (i) working out how to clean up according to where A is
+in its loop is a nightmare, and (ii) this isn't available in
+omnithread anyway.<BR>
+<BR>
+On Solaris 2.5 and Digital Unix 3.2 the following strategy works:<BR>
+<BR>
+Thread B does <CODE>shutdown(sock,2)</CODE>.<BR>
+<BR>
+At this point thread A is either blocked inside <CODE>read(sock)</CODE>, or
+is elsewhere in the loop. If the former then read will return 0,
+indicating that the socket is closed. If the latter then eventually
+thread A will call <CODE>read(sock)</CODE> and then this will return 0.
+Thread A should <CODE>close(sock)</CODE>, do any other tidying up, and exit.<BR>
+<BR>
+If there is another point in the loop that thread A can block then
+obviously thread B needs to be aware of this and be able to wake it up
+in the appropriate way from that point.<BR>
+<BR>
+<!--TOC subsection accept()-->
+
+<H3><A NAME="htoc11">6.2</A>&nbsp;&nbsp;accept()</H3><!--SEC END -->
+
+Again thread A is in a loop, this time doing an accept on listenSock,
+dealing with a new connection and going back into accept. Thread B
+wants to cancel it.<BR>
+<BR>
+On Digital Unix 3.2 the strategy is identical to that for read:<BR>
+<BR>
+Thread B does <CODE>shutdown(listenSock,2)</CODE>. Wherever thread A is in
+the loop, eventually it will return <CODE>ECONNABORTED</CODE> from the
+accept call. It should <CODE>close(listenSock)</CODE>, tidy up as necessary
+and exit.<BR>
+<BR>
+On Solaris 2.5 thread B can't do <CODE>shutdown(listenSock,2)</CODE> ---
+this returns <CODE>ENOTCONN</CODE>. Instead the following strategy can be
+used:<BR>
+<BR>
+First thread B sets some sort of "shutdown flag" associated with
+listenSock. Then it does <CODE>getsockaddr(listenSock)</CODE> to find out
+which port listenSock is on (or knows already), sets up a socket
+dummySock, does <CODE>connect(dummySock,</CODE> <CODE>this host, port)</CODE> and
+finally does <CODE>close(dummySock)</CODE>.<BR>
+<BR>
+Wherever thread A is in the loop, eventually it will call
+<CODE>accept(listenSock)</CODE>. This will return successfully with a new
+socket, say connSock. Thread A then checks to see if the "shutdown
+flag" is set. If not, then it's a normal connection. If it is set,
+then thread A closes listenSock and connSock, tidies up and exits.<BR>
+<BR>
+<!--TOC subsection write()-->
+
+<H3><A NAME="htoc12">6.3</A>&nbsp;&nbsp;write()</H3><!--SEC END -->
+
+Thread A may be blocked in write, or about to go in to a
+potentially-blocking write. Thread B wants to shut it down.<BR>
+<BR>
+On Solaris 2.5:<BR>
+<BR>
+Thread B does <CODE>shutdown(sock,2)</CODE>.<BR>
+<BR>
+If thread A is already in <CODE>write(sock)</CODE> then it will return with
+<CODE>ENXIO</CODE>. If thread A calls write after thread B calls shutdown
+this will return <CODE>EIO</CODE>.<BR>
+<BR>
+On Digital Unix 3.2:<BR>
+<BR>
+Thread B does <CODE>shutdown(sock,2)</CODE>.<BR>
+<BR>
+If thread A is already in <CODE>write(sock)</CODE> then it will return the
+number of bytes written before it became blocked. A subsequent call
+to write will then generate <CODE>SIGPIPE</CODE> (or <CODE>EPIPE</CODE> will be
+returned if <CODE>SIGPIPE</CODE> is ignored by the thread).<BR>
+<BR>
+<!--TOC subsection connect()-->
+
+<H3><A NAME="htoc13">6.4</A>&nbsp;&nbsp;connect()</H3><!--SEC END -->
+
+Thread A may be blocked in connect, or about to go in to a
+potentially-blocking connect. Thread B wants to shut it down.<BR>
+<BR>
+On Digital Unix 3.2:<BR>
+<BR>
+Thread B does <CODE>shutdown(sock,2)</CODE>.<BR>
+<BR>
+If thread A is already in <CODE>connect(sock)</CODE> then it will return a
+successful connection. Subsequent reading or writing will show that
+the socket has been shut down (i.e. read returns 0, write generates
+<CODE>SIGPIPE</CODE> or returns <CODE>EPIPE</CODE>). If thread A calls connect
+after thread B calls shutdown this will return <CODE>EINVAL</CODE>.<BR>
+<BR>
+On Solaris 2.5:<BR>
+<BR>
+There is no way to wake up a thread which is blocked in connect.
+Instead Solaris forces us through a ridiculous procedure whichever way
+we try it. One way is this:<BR>
+<BR>
+First thread A creates a pipe in addition to the socket. Instead of
+shutting down the socket, thread B simply writes a byte to the pipe.<BR>
+<BR>
+Thread A meanwhile sets the socket to non-blocking mode using
+<CODE>fcntl(sock,</CODE> <CODE>F_SETFL, O_NONBLOCK)</CODE>. Then it calls connect
+on the socket --- this will return <CODE>EINPROGRESS</CODE>. Then it must
+call <CODE>select()</CODE>, waiting for either sock to become writable or
+for the pipe to become readable. If select returns that just sock is
+writable then the connection has succeeded. It then needs to set the
+socket back to blocking mode using <CODE>fcntl(sock, F_SETFL, 0)</CODE>. If
+instead select returns that the pipe is readable, thread A closes the
+socket, tidies up and exits.<BR>
+<BR>
+An alternative method is similar but to use polling instead of the
+pipe. Thread B justs sets a flag and thread A calls select with a
+timeout, periodically waking up to see if the flag has been set.<BR>
+<BR>
+<!--TOC section References-->
+
+<H2>References</H2><!--SEC END -->
+<DL COMPACT=compact><DT><A NAME="pthreads"><FONT COLOR=purple>[POSIX94]</FONT></A><DD>
+<EM>Portable Operating System Interface (POSIX) Threads Extension</EM>,
+P1003.1c Draft 10,
+IEEE,
+September 1994.<BR>
+<BR>
+<DT><A NAME="birrell"><FONT COLOR=purple>[Birrell89]</FONT></A><DD>
+<EM>An Introduction to Programming with Threads</EM>,
+Research Report 35,
+DEC Systems Research Center,
+Palo Alto, CA,
+January 1989.</DL>
+<!--HTMLFOOT-->
+<!--ENDHTML-->
+<!--FOOTER-->
+<HR SIZE=2>
+<BLOCKQUOTE><EM>This document was translated from L<sup>A</sup>T<sub>E</sub>X by
+</EM><A HREF="http://pauillac.inria.fr/~maranget/hevea/index.html"><EM>H<FONT SIZE=2><sup>E</sup></FONT>V<FONT SIZE=2><sup>E</sup></FONT>A</EM></A><EM>.
+</EM></BLOCKQUOTE>
+</BODY>
+</HTML>
diff --git a/gnuradio-core/doc/other/omnithread.pdf b/gnuradio-core/doc/other/omnithread.pdf
new file mode 100644 (file)
index 0000000..b542187
Binary files /dev/null and b/gnuradio-core/doc/other/omnithread.pdf differ
diff --git a/gnuradio-core/doc/other/omnithread.ps b/gnuradio-core/doc/other/omnithread.ps
new file mode 100644 (file)
index 0000000..9e858f0
--- /dev/null
@@ -0,0 +1,730 @@
+%!PS-Adobe-2.0
+%%Creator: dvipsk 5.86 p1.5d Copyright 1996-2001 ASCII Corp.(www-ptex@ascii.co.jp)
+%%based on dvipsk 5.86 Copyright 1999 Radical Eye Software (www.radicaleye.com)
+%%Title: omnithread.dvi
+%%Pages: 7
+%%PageOrder: Ascend
+%%BoundingBox: 0 0 596 842
+%%DocumentFonts: Palatino-Roman Palatino-Italic Palatino-Bold Courier
+%%EndComments
+%DVIPSWebPage: (www.radicaleye.com)
+%DVIPSCommandLine: dvips omnithread
+%DVIPSParameters: dpi=600, compressed
+%DVIPSSource:  TeX output 2002.08.15:1756
+%%BeginProcSet: texc.pro
+%!
+/TeXDict 300 dict def TeXDict begin/N{def}def/B{bind def}N/S{exch}N/X{S
+N}B/A{dup}B/TR{translate}N/isls false N/vsize 11 72 mul N/hsize 8.5 72
+mul N/landplus90{false}def/@rigin{isls{[0 landplus90{1 -1}{-1 1}ifelse 0
+0 0]concat}if 72 Resolution div 72 VResolution div neg scale isls{
+landplus90{VResolution 72 div vsize mul 0 exch}{Resolution -72 div hsize
+mul 0}ifelse TR}if Resolution VResolution vsize -72 div 1 add mul TR[
+matrix currentmatrix{A A round sub abs 0.00001 lt{round}if}forall round
+exch round exch]setmatrix}N/@landscape{/isls true N}B/@manualfeed{
+statusdict/manualfeed true put}B/@copies{/#copies X}B/FMat[1 0 0 -1 0 0]
+N/FBB[0 0 0 0]N/nn 0 N/IEn 0 N/ctr 0 N/df-tail{/nn 8 dict N nn begin
+/FontType 3 N/FontMatrix fntrx N/FontBBox FBB N string/base X array
+/BitMaps X/BuildChar{CharBuilder}N/Encoding IEn N end A{/foo setfont}2
+array copy cvx N load 0 nn put/ctr 0 N[}B/sf 0 N/df{/sf 1 N/fntrx FMat N
+df-tail}B/dfs{div/sf X/fntrx[sf 0 0 sf neg 0 0]N df-tail}B/E{pop nn A
+definefont setfont}B/Cw{Cd A length 5 sub get}B/Ch{Cd A length 4 sub get
+}B/Cx{128 Cd A length 3 sub get sub}B/Cy{Cd A length 2 sub get 127 sub}
+B/Cdx{Cd A length 1 sub get}B/Ci{Cd A type/stringtype ne{ctr get/ctr ctr
+1 add N}if}B/id 0 N/rw 0 N/rc 0 N/gp 0 N/cp 0 N/G 0 N/CharBuilder{save 3
+1 roll S A/base get 2 index get S/BitMaps get S get/Cd X pop/ctr 0 N Cdx
+0 Cx Cy Ch sub Cx Cw add Cy setcachedevice Cw Ch true[1 0 0 -1 -.1 Cx
+sub Cy .1 sub]/id Ci N/rw Cw 7 add 8 idiv string N/rc 0 N/gp 0 N/cp 0 N{
+rc 0 ne{rc 1 sub/rc X rw}{G}ifelse}imagemask restore}B/G{{id gp get/gp
+gp 1 add N A 18 mod S 18 idiv pl S get exec}loop}B/adv{cp add/cp X}B
+/chg{rw cp id gp 4 index getinterval putinterval A gp add/gp X adv}B/nd{
+/cp 0 N rw exit}B/lsh{rw cp 2 copy get A 0 eq{pop 1}{A 255 eq{pop 254}{
+A A add 255 and S 1 and or}ifelse}ifelse put 1 adv}B/rsh{rw cp 2 copy
+get A 0 eq{pop 128}{A 255 eq{pop 127}{A 2 idiv S 128 and or}ifelse}
+ifelse put 1 adv}B/clr{rw cp 2 index string putinterval adv}B/set{rw cp
+fillstr 0 4 index getinterval putinterval adv}B/fillstr 18 string 0 1 17
+{2 copy 255 put pop}for N/pl[{adv 1 chg}{adv 1 chg nd}{1 add chg}{1 add
+chg nd}{adv lsh}{adv lsh nd}{adv rsh}{adv rsh nd}{1 add adv}{/rc X nd}{
+1 add set}{1 add clr}{adv 2 chg}{adv 2 chg nd}{pop nd}]A{bind pop}
+forall N/D{/cc X A type/stringtype ne{]}if nn/base get cc ctr put nn
+/BitMaps get S ctr S sf 1 ne{A A length 1 sub A 2 index S get sf div put
+}if put/ctr ctr 1 add N}B/I{cc 1 add D}B/bop{userdict/bop-hook known{
+bop-hook}if/SI save N @rigin 0 0 moveto/V matrix currentmatrix A 1 get A
+mul exch 0 get A mul add .99 lt{/QV}{/RV}ifelse load def pop pop}N/eop{
+SI restore userdict/eop-hook known{eop-hook}if showpage}N/@start{
+userdict/start-hook known{start-hook}if pop/VResolution X/Resolution X
+1000 div/DVImag X/IEn 256 array N 2 string 0 1 255{IEn S A 360 add 36 4
+index cvrs cvn put}for pop 65781.76 div/vsize X 65781.76 div/hsize X}N
+/dir 0 def/dyy{/dir 0 def}B/dyt{/dir 1 def}B/dty{/dir 2 def}B/dtt{/dir 3
+def}B/p{dir 2 eq{-90 rotate show 90 rotate}{dir 3 eq{-90 rotate show 90
+rotate}{show}ifelse}ifelse}N/RMat[1 0 0 -1 0 0]N/BDot 260 string N/Rx 0
+N/Ry 0 N/V{}B/RV/v{/Ry X/Rx X V}B statusdict begin/product where{pop
+false[(Display)(NeXT)(LaserWriter 16/600)]{A length product length le{A
+length product exch 0 exch getinterval eq{pop true exit}if}{pop}ifelse}
+forall}{false}ifelse end{{gsave TR -.1 .1 TR 1 1 scale Rx Ry false RMat{
+BDot}imagemask grestore}}{{gsave TR -.1 .1 TR Rx Ry scale 1 1 false RMat
+{BDot}imagemask grestore}}ifelse B/QV{gsave newpath transform round exch
+round exch itransform moveto Rx 0 rlineto 0 Ry neg rlineto Rx neg 0
+rlineto fill grestore}B/a{moveto}B/delta 0 N/tail{A/delta X 0 rmoveto}B
+/M{S p delta add tail}B/b{S p tail}B/c{-4 M}B/d{-3 M}B/e{-2 M}B/f{-1 M}
+B/g{0 M}B/h{1 M}B/i{2 M}B/j{3 M}B/k{4 M}B/w{0 rmoveto}B/l{p -4 w}B/m{p
+-3 w}B/n{p -2 w}B/o{p -1 w}B/q{p 1 w}B/r{p 2 w}B/s{p 3 w}B/t{p 4 w}B/x{
+0 S rmoveto}B/y{3 2 roll p a}B/bos{/SS save N}B/eos{SS restore}B end
+
+%%EndProcSet
+%%BeginProcSet: 8r.enc
+% @@psencodingfile@{
+%   author = "S. Rahtz, P. MacKay, Alan Jeffrey, B. Horn, K. Berry",
+%   version = "0.6",
+%   date = "1 July 1998",
+%   filename = "8r.enc",
+%   email = "tex-fonts@@tug.org",
+%   docstring = "Encoding for TrueType or Type 1 fonts
+%                to be used with TeX."
+% @}
+% 
+% Idea is to have all the characters normally included in Type 1 fonts
+% available for typesetting. This is effectively the characters in Adobe
+% Standard Encoding + ISO Latin 1 + extra characters from Lucida.
+% 
+% Character code assignments were made as follows:
+% 
+% (1) the Windows ANSI characters are almost all in their Windows ANSI
+% positions, because some Windows users cannot easily reencode the
+% fonts, and it makes no difference on other systems. The only Windows
+% ANSI characters not available are those that make no sense for
+% typesetting -- rubout (127 decimal), nobreakspace (160), softhyphen
+% (173). quotesingle and grave are moved just because it's such an
+% irritation not having them in TeX positions.
+% 
+% (2) Remaining characters are assigned arbitrarily to the lower part
+% of the range, avoiding 0, 10 and 13 in case we meet dumb software.
+% 
+% (3) Y&Y Lucida Bright includes some extra text characters; in the
+% hopes that other PostScript fonts, perhaps created for public
+% consumption, will include them, they are included starting at 0x12.
+% 
+% (4) Remaining positions left undefined are for use in (hopefully)
+% upward-compatible revisions, if someday more characters are generally
+% available.
+% 
+% (5) hyphen appears twice for compatibility with both 
+% ASCII and Windows.
+% 
+/TeXBase1Encoding [
+% 0x00 (encoded characters from Adobe Standard not in Windows 3.1)
+  /.notdef /dotaccent /fi /fl
+  /fraction /hungarumlaut /Lslash /lslash
+  /ogonek /ring /.notdef
+  /breve /minus /.notdef 
+% These are the only two remaining unencoded characters, so may as
+% well include them.
+  /Zcaron /zcaron 
+% 0x10
+ /caron /dotlessi 
+% (unusual TeX characters available in, e.g., Lucida Bright)
+ /dotlessj /ff /ffi /ffl 
+ /.notdef /.notdef /.notdef /.notdef
+ /.notdef /.notdef /.notdef /.notdef
+ % very contentious; it's so painful not having quoteleft and quoteright
+ % at 96 and 145 that we move the things normally found there to here.
+ /grave /quotesingle 
+% 0x20 (ASCII begins)
+ /space /exclam /quotedbl /numbersign
+ /dollar /percent /ampersand /quoteright
+ /parenleft /parenright /asterisk /plus /comma /hyphen /period /slash
+% 0x30
+ /zero /one /two /three /four /five /six /seven
+ /eight /nine /colon /semicolon /less /equal /greater /question
+% 0x40
+ /at /A /B /C /D /E /F /G /H /I /J /K /L /M /N /O
+% 0x50
+ /P /Q /R /S /T /U /V /W
+ /X /Y /Z /bracketleft /backslash /bracketright /asciicircum /underscore
+% 0x60
+ /quoteleft /a /b /c /d /e /f /g /h /i /j /k /l /m /n /o
+% 0x70
+ /p /q /r /s /t /u /v /w
+ /x /y /z /braceleft /bar /braceright /asciitilde
+ /.notdef % rubout; ASCII ends
+% 0x80
+ /.notdef /.notdef /quotesinglbase /florin
+ /quotedblbase /ellipsis /dagger /daggerdbl
+ /circumflex /perthousand /Scaron /guilsinglleft
+ /OE /.notdef /.notdef /.notdef
+% 0x90
+ /.notdef /.notdef /.notdef /quotedblleft
+ /quotedblright /bullet /endash /emdash
+ /tilde /trademark /scaron /guilsinglright
+ /oe /.notdef /.notdef /Ydieresis
+% 0xA0
+ /.notdef % nobreakspace
+ /exclamdown /cent /sterling
+ /currency /yen /brokenbar /section
+ /dieresis /copyright /ordfeminine /guillemotleft
+ /logicalnot
+ /hyphen % Y&Y (also at 45); Windows' softhyphen
+ /registered
+ /macron
+% 0xD0
+ /degree /plusminus /twosuperior /threesuperior
+ /acute /mu /paragraph /periodcentered
+ /cedilla /onesuperior /ordmasculine /guillemotright
+ /onequarter /onehalf /threequarters /questiondown
+% 0xC0
+ /Agrave /Aacute /Acircumflex /Atilde /Adieresis /Aring /AE /Ccedilla
+ /Egrave /Eacute /Ecircumflex /Edieresis
+ /Igrave /Iacute /Icircumflex /Idieresis
+% 0xD0
+ /Eth /Ntilde /Ograve /Oacute
+ /Ocircumflex /Otilde /Odieresis /multiply
+ /Oslash /Ugrave /Uacute /Ucircumflex
+ /Udieresis /Yacute /Thorn /germandbls
+% 0xE0
+ /agrave /aacute /acircumflex /atilde
+ /adieresis /aring /ae /ccedilla
+ /egrave /eacute /ecircumflex /edieresis
+ /igrave /iacute /icircumflex /idieresis
+% 0xF0
+ /eth /ntilde /ograve /oacute
+ /ocircumflex /otilde /odieresis /divide
+ /oslash /ugrave /uacute /ucircumflex
+ /udieresis /yacute /thorn /ydieresis
+] def
+
+%%EndProcSet
+%%BeginProcSet: texps.pro
+%!
+TeXDict begin/rf{findfont dup length 1 add dict begin{1 index/FID ne 2
+index/UniqueID ne and{def}{pop pop}ifelse}forall[1 index 0 6 -1 roll
+exec 0 exch 5 -1 roll VResolution Resolution div mul neg 0 0]/Metrics
+exch def dict begin 0 1 255{exch dup type/integertype ne{pop pop 1 sub
+dup 0 le{pop}{[}ifelse}{FontMatrix 0 get div Metrics 0 get div def}
+ifelse}for Metrics/Metrics currentdict end def[2 index currentdict end
+definefont 3 -1 roll makefont/setfont cvx]cvx def}def/ObliqueSlant{dup
+sin S cos div neg}B/SlantFont{4 index mul add}def/ExtendFont{3 -1 roll
+mul exch}def/ReEncodeFont{CharStrings rcheck{/Encoding false def dup[
+exch{dup CharStrings exch known not{pop/.notdef/Encoding true def}if}
+forall Encoding{]exch pop}{cleartomark}ifelse}if/Encoding exch def}def
+end
+
+%%EndProcSet
+TeXDict begin 39158280 55380996 1000 600 600 (omnithread.dvi)
+@start /Fa 134[ 45 45 66 1[ 51 30 35 35 1[ 45 40 51 71
+25 2[ 25 45 45 25 35 45 37 42 40 8[ 66 3[ 56 51 2[ 56
+71 5[ 30 3[ 56 3[ 66 23[ 30 30 40[{ TeXBase1Encoding ReEncodeFont} 31
+90.9091 /Palatino-Italic rf /Fb 134[ 51 1[ 76 1[ 56 30
+40 35 2[ 51 56 81 30 2[ 30 56 51 35 45 56 40 56 45 14[ 66
+2[ 76 5[ 35 6[ 61 19[ 23 30 23 4[ 25 39[{ TeXBase1Encoding ReEncodeFont}
+27 90.9091 /Palatino-Bold rf /Fc 135[ 50 83 1[ 61 33
+44 39 1[ 61 55 61 89 33 2[ 33 61 55 1[ 50 61 44 61 50
+10[ 78 8[ 100 9[ 72 12[ 50 1[ 50 50 50 50 2[ 25 4[ 33
+33 40[{ TeXBase1Encoding ReEncodeFont} 30 99.6264 /Palatino-Bold
+rf /Fd 134[ 55 55 55 55 55 55 55 55 55 55 55 55 55 55
+55 55 55 55 55 55 55 55 55 55 55 1[ 55 5[ 55 55 55 55
+55 55 55 55 1[ 55 55 55 55 55 55 1[ 55 55 55 55 55 55
+55 55 55 3[ 55 2[ 55 1[ 55 1[ 55 55 55 55 55 55 55 1[ 55
+55 55 1[ 55 55 55 40[{ TeXBase1Encoding ReEncodeFont} 65
+90.9091 /Courier rf /Fe 141[ 36 12[ 44 56 2[ 45 7[ 61
+61 91 1[ 71 56 48 61 2[ 71 76 3[ 30 31 76 1[ 51 56 70
+64 56 71 10[ 45 3[ 45 45 1[ 55 23 4[ 30 30 40[{
+.167 SlantFont TeXBase1Encoding ReEncodeFont} 29 90.9091
+/Palatino-Roman rf
+%DVIPSBitmapFont: Ff cmsy10 10.95 1
+/Ff 1 16 df<EB0FFCEB3FFF90B512C0000314F04880488048804880A2481580A3B712C0
+AA6C1580A36C1500A26C5C6C5C6C5C6C5CC614C0013F90C7FCEB0FFC22227BA72D> 15
+D E
+%EndDVIPSBitmapFont
+/Fg 104[ 91 2[ 45 45 24[ 45 51 47 76 51 55 30 39 36 51
+55 50 53 80 26 51 21 26 53 51 30 44 56 40 50 45 3[ 30
+1[ 30 2[ 61 91 66 71 56 48 61 1[ 55 71 76 86 56 66 30
+31 76 1[ 51 56 70 64 56 71 6[ 23 45 45 45 45 45 45 45
+45 45 45 55 23 30 23 55 1[ 30 30 25 4[ 34 30[ 55 55 2[{
+TeXBase1Encoding ReEncodeFont} 75 90.9091 /Palatino-Roman
+rf /Fh 134[ 66 60 100 1[ 73 40 53 47 1[ 73 66 73 106
+2[ 40 40 73 66 47 60 73 53 73 60 11[ 93 80 73 86 1[ 73
+100 100 120 3[ 47 18[ 60 60 60 60 60 60 1[ 35 1[ 40 45[{
+TeXBase1Encoding ReEncodeFont} 38 119.552 /Palatino-Bold
+rf /Fi 137[ 50 2[ 39 9[ 28 3[ 39 50 17[ 66 82[{
+TeXBase1Encoding ReEncodeFont} 6 99.6264 /Palatino-Italic
+rf /Fj 137[ 56 1[ 32 42 39 2[ 54 58 88 3[ 29 58 55 1[ 48
+61 44 55 50 12[ 61 1[ 67 3[ 83 1[ 61 8[ 71 1[ 78 14[ 50
+50 50 9[ 78 38[{ TeXBase1Encoding ReEncodeFont} 25 99.6264
+/Palatino-Roman rf /Fk 139[ 47 61 57 2[ 78 83 4[ 42 83
+2[ 69 88 64 79 72 12[ 88 4[ 113 119 136 3[ 48 7[ 112
+65[{ TeXBase1Encoding ReEncodeFont} 18 143.462 /Palatino-Roman
+rf end
+%%EndProlog
+%%BeginSetup
+%%Feature: *Resolution 600dpi
+TeXDict begin
+%%PaperSize: A4
+
+%%EndSetup
+%%Page: 1 1
+1 0 bop Fk 728 918 a(The) 36 b(OMNI) g(Thr) m(ead) f(Abstracti) n(on) p
+Fj 1293 1176 a(T) -9 b(ristan) 26 b(Richar) n(dson) 1022
+1293 y(A) -7 b(T&T) 24 b(Laboratories) i(Cambridge) p
+Fi 1192 1504 a(Revised) p Fj 24 w(November) f(2001) p
+Fh 63 1961 a(1) 119 b(Introduction) p Fg 63 2183 a(The) 20
+b(OMNI) h(thr) n(ead) g(abstraction) g(is) h(des) n(igned) f(to) f(pr) n
+(ovide) h(a) h(common) f(set) f(of) h(thr) n(ead) g(oper) n(-) 63
+2296 y(ations) h(for) g(use) g(in) h(pr) n(ograms) f(written) f(in) i
+(C++.) 29 b(Pr) n(ograms) 22 b(written) g(using) f(the) h(abstraction)
+63 2409 y(should) 30 b(be) g(much) i(easier) e(to) g(port) g(betwee) n
+(n) h(dif) n(fer) n(ent) g(ar) n(chi) r(tectur) l(es) g(with) g(dif) n
+(fer) n(ent) f(un-) 63 2522 y(derlying) 21 b(thr) n(eads) h
+(primitives.) 204 2640 y(The) 17 b(pr) n(ogramming) h(interface) g(is) f
+(designed) f(to) h(be) h(similar) h(to) e(the) g(C) i(language) e
+(interface) 63 2753 y(to) k(POSIX) h(thr) n(eads) f(\(IEEE) g(draft) h
+(standar) n(d) f(100) r(3.1c) i(\227) f(pr) n(eviously) g(1003) r(.4a,)
+g(often) g(known) 63 2866 y(as) g(\223pthr) n(eads\224) h([POSIX94]\).)
+204 2985 y(Much) 18 b(of) f(the) g(abstraction) i(consists) d(of) i
+(simple) g(C++) g(object) g(wrappers) e(ar) n(ound) h(pthr) n(ead) 63
+3098 y(calls.) 28 b(Howe) n(ver) 20 b(for) f(some) f(featur) n(es) g
+(such) h(as) h(thr) n(ead-spe) n(ci\002c) h(data,) f(a) f(better) f
+(interface) i(can) 63 3211 y(be) i(of) n(fer) n(ed) g(because) h(of) f
+(the) g(use) g(of) g(C++.) 204 3329 y(Some) 28 b(of) h(the) f(mor) n(e)
+h(complex) f(featur) n(es) g(of) h(pthr) n(eads) f(ar) n(e) h(not) f
+(suppo) n(rted) g(because) h(of) 63 3442 y(the) e(dif) n(\002culty) i
+(of) f(ensuring) g(the) f(same) h(featur) n(es) g(can) h(be) f(of) n
+(fer) n(ed) g(on) g(top) g(of) g(other) f(thr) n(ead) 63
+3555 y(sys) n(tems.) f(Such) 17 b(featur) n(es) g(include) h(thr) n
+(ead) f(cancell) r(ation) g(and) h(complex) g(schedu) n(ling) h(contr) n
+(ol) 63 3668 y(\(thoug) n(h) k(simple) g(thr) n(ead) f(priorities) g
+(ar) n(e) h(supp) n(orted\).) 204 3787 y(The) i(abstraction) h(layer) h
+(is) f(curr) n(ently) f(implemented) g(for) h(the) f(following) i(ar) n
+(chitectur) n(es) 63 3900 y(/) 22 b(thr) n(ead) h(sys) n(tems:) p
+Ff 199 4141 a(\017) p Fg 46 w(Solaris) g(2.x) g(using) f(pthr) n(eads) f
+(draft) h(10) p Ff 199 4351 a(\017) p Fg 46 w(Solaris) h(2.x) g(using) f
+(solaris) g(thr) n(eads) g(\(but) h(pthr) n(eads) e(version) h(is) h
+(now) f(standar) n(d\)) p Ff 199 4561 a(\017) p Fg 46
+w(Alpha) h(OSF1) g(using) f(pthr) n(eads) f(draft) i(4) p
+Ff 199 4772 a(\017) p Fg 46 w(W) -5 b(indows) 21 b(NT) h(using) g(NT) g
+(thr) n(eads) p Ff 199 4982 a(\017) p Fg 46 w(Linux) g(2.x) h(using) f
+(Linuxthr) n(ead) g(0.5) h(\(which) h(is) e(based) g(on) h(pthr) n
+(eads) e(draft) i(10\)) p Ff 199 5193 a(\017) p Fg 46
+w(Linux) f(2.x) h(using) f(MIT) g(pthr) n(eads) f(\(which) j(is) f
+(based) f(on) g(draft) h(8\)) p Ff 199 5403 a(\017) p
+Fg 46 w(A) -7 b(TMos) 22 b(using) g(pthr) n(eads) f(draft) h(6) i
+(\(but) e(not) g(V) -5 b(irata) 23 b(A) -7 b(TMos\)) 1684
+5652 y(1) p 90 rotate dyy eop
+%%Page: 2 2
+2 1 bop Fg 221 249 a(2) p Fe 1797 w(2) 91 b(SYNCHRONI) n(SA) -7
+b(TION) 22 b(OBJECTS) p Fg 362 548 a(See) h(the) p Fd
+22 w(omni) n(thre) n(ad.h) p Fg 22 w(header) f(\002le) i(for) f(full) i
+(det) n(ail) r(s) e(of) g(the) g(API.) f(The) h(des) n(criptions) 221
+661 y(below) 35 b(assume) g(you) g(have) h(some) e(pr) n(evious) h
+(knowled) n(ge) g(of) h(thr) n(eads) n(,) j(mutexes) n(,) g(condi-) 221
+774 y(tion) f(varia) r(bles) g(and) g(semaphor) n(es) n(.) 75
+b(Also) 38 b(r) n(efer) f(to) h(other) f(document) n(ation) i(\([Birr) n
+(ell89) r(],) 221 887 y([POSIX94) q(]\)) 22 b(for) g(further) f
+(explanation) i(of) f(thes) n(e) g(ideas) g(\(particularly) h
+(condition) f(variab) r(les,) 221 1000 y(the) g(use) g(of) g(which) h
+(may) g(not) f(be) h(particularly) h(intuitive) f(when) f(\002rst) f
+(encounter) n(ed) n(\).) p Fh 221 1299 a(2) 119 b(Synchronisation) 31
+b(objects) p Fg 221 1510 a(Synchr) n(onisation) 26 b(objects) h(ar) n
+(e) g(used) e(to) h(synchr) n(onise) g(thr) n(eads) g(within) h(the) f
+(same) h(pr) n(ocess) n(.) 221 1623 y(Ther) n(e) j(is) i(no) f(inter) n
+(-pr) n(ocess) f(synchr) n(onisation) g(pr) n(ovided.) 53
+b(The) 30 b(synchr) n(onisation) h(objects) 221 1735
+y(pr) n(ovided) 22 b(ar) n(e) h(mutexes) n(,) g(condition) f(variab) r
+(les) g(and) h(counting) f(semaphor) n(e) n(s.) p Fc
+221 1991 a(2.1) 99 b(Mutex) p Fg 221 2168 a(An) 26 b(object) g(of) h
+(typ) n(e) p Fd 26 w(omni) n(_mute) n(x) p Fg 26 w(is) g(use) n(d) f
+(for) h(mutual) f(exclusion.) 39 b(It) 26 b(pr) n(ovides) f(two) g(op-)
+221 2281 y(erations,) p Fd 37 w(lock\() n(\)) p Fg 35
+w(and) p Fd 35 w(unloc) n(k\(\)) p Fg(.) 64 b(The) 35
+b(alternative) h(names) p Fd 35 w(acq) n(uire\() n(\)) p
+Fg 35 w(and) p Fd 35 w(re-) 221 2393 y(leas) n(e\(\)) p
+Fg 19 w(can) 21 b(be) f(used) f(if) i(pr) n(eferr) n(ed) n(.) 27
+b(Behaviour) 20 b(is) g(unde\002ne) n(d) g(when) f(a) i(thr) n(ead) f
+(attempt) n(s) 221 2506 y(to) 30 b(lock) h(the) e(same) i(mutex) f
+(again) h(or) f(when) g(a) h(mutex) f(is) h(locked) e(by) i(one) e(thr)
+n(ead) h(and) h(un-) 221 2619 y(locked) 22 b(by) h(a) g(dif) n(fer) n
+(ent) f(thr) n(ead.) p Fc 221 2874 a(2.2) 99 b(Condition) 26
+b(V) -11 b(ariable) p Fg 221 3051 a(A) 28 b(condition) f(varia) r(ble) h
+(is) g(r) n(epr) n(ese) n(nted) f(by) h(an) p Fd 28 w(omn) n(i_con) n
+(diti) n(on) p Fg 27 w(and) g(is) g(used) e(for) i(sig-) 221
+3164 y(nalli) r(ng) 20 b(betwee) n(n) g(thr) n(eads.) 26
+b(A) 21 b(call) h(to) p Fd 19 w(wait\() n(\)) p Fg 20
+w(causes) e(a) h(thr) n(ead) e(to) h(wait) h(on) f(the) f(condition) 221
+3277 y(varia) r(ble.) 45 b(A) 28 b(call) i(to) p Fd 27
+w(sign) n(al\(\)) p Fg 27 w(wakes) d(up) h(at) g(least) g(one) f(thr) n
+(ead) h(if) h(any) f(ar) n(e) g(waiting.) 45 b(A) 221
+3390 y(call) 25 b(to) p Fd 22 w(bro) n(adca) n(st\(\)) p
+Fg 21 w(wakes) d(up) g(all) i(thr) n(eads) e(waiting) h(on) f(the) g
+(condition) g(varia) r(ble.) 362 3503 y(When) 30 b(constr) o(ucte) n
+(d,) i(a) e(pointer) f(to) h(an) p Fd 30 w(omni) n(_mute) n(x) p
+Fg 30 w(must) f(be) h(given.) 50 b(A) 30 b(condition) 221
+3616 y(varia) r(ble) p Fd 33 w(wait\() n(\)) p Fg 33
+w(has) j(an) h(implic) r(it) f(mutex) p Fd 33 w(unlo) n(ck\(\)) p
+Fg 32 w(and) p Fd 33 w(lock) n(\(\)) p Fg 33 w(ar) n(ound) g(it.) 60
+b(The) 221 3729 y(link) 30 b(between) f(condition) g(varia) r(ble) h
+(and) g(mutex) f(lasts) g(for) h(the) f(lifetime) i(of) e(the) g
+(condition) 221 3842 y(varia) r(ble) c(\(unlike) h(pthr) n(eads) e
+(wher) n(e) g(the) h(link) h(is) f(only) g(for) g(the) g(duration) f
+(of) i(the) e(wait\).) 37 b(The) 221 3955 y(same) 23
+b(mutex) f(may) h(be) f(used) f(with) i(several) f(condition) h(variab)
+r(les.) 362 4068 y(A) c(wait) g(with) g(a) g(timeout) f(can) i(be) e
+(achieved) h(by) g(call) r(ing) p Fd 19 w(tim) n(ed_w) n(ait\(\)) p
+Fg -2 w(.) 27 b(This) 18 b(is) h(given) 221 4181 y(an) 27
+b(absolute) e(time) h(to) f(wait) h(until.) 38 b(The) 26
+b(r) n(outine) p Fd 25 w(omn) n(i_thr) n(ead:) n(:get_) n(time) n(\(\))
+p Fg 25 w(can) h(be) 221 4293 y(used) 21 b(to) h(turn) g(a) h(r) n
+(elativ) r(e) f(time) g(into) h(an) g(absolute) f(time.) p
+Fd 28 w(tim) n(ed_wa) n(it\(\)) p Fg 21 w(r) n(eturns) p
+Fd 21 w(true) p Fg 21 w(if) 221 4406 y(the) 27 b(condition) h(was) g
+(signalled,) p Fd 29 w(false) p Fg 26 w(if) h(the) f(time) g(expir) n
+(ed) f(befor) n(e) g(the) h(condition) f(vari) r(-) 221
+4519 y(able) d(was) e(signalled.) p Fc 221 4774 a(2.3) 99
+b(Counting) 26 b(semaphores) p Fg 221 4951 a(An) p Fd
+21 w(omn) n(i_sem) n(apho) n(re) p Fg 20 w(is) 21 b(a) h(counting) e
+(semaphor) n(e) n(.) 28 b(When) 20 b(cr) n(eated) g(it) h(is) g(given) g
+(an) g(initial) 221 5064 y(unsigned) j(intege) n(r) i(value.) 36
+b(When) p Fd 25 w(wai) n(t\(\)) p Fg 24 w(is) 26 b(called,) g(the) f
+(value) h(is) f(decr) n(emente) n(d) g(if) h(non-) 221
+5177 y(zer) n(o.) 43 b(If) 27 b(the) g(value) h(is) f(zer) n(o) h(then)
+f(the) f(thr) n(ead) h(blocks) h(instead.) 41 b(When) p
+Fd 27 w(post) n(\(\)) p Fg 27 w(is) 27 b(cal) r(led,) 221
+5290 y(if) h(any) g(thr) n(eads) e(ar) n(e) i(blocked) f(in) p
+Fd 27 w(wait\() n(\)) p Fg(,) h(exactly) f(one) g(thr) n(ead) g(is) g
+(woken.) 41 b(If) 27 b(no) g(thr) n(eads) 221 5403 y(wer) n(e) 22
+b(blocked) g(then) g(the) g(value) h(of) g(the) e(semaphor) n(e) h(is) h
+(incr) n(emented.) p 90 rotate dyy eop
+%%Page: 3 3
+3 2 bop Fg 3306 249 a(3) 204 548 y(If) 27 b(a) h(thr) n(ead) e(cal) r
+(ls) p Fd 27 w(try) n(_wait) n(\(\)) p Fg(,) h(then) g(the) f(thr) n
+(ead) g(won't) h(block) h(if) f(the) g(semaphor) n(e's) 63
+661 y(value) c(is) g(0,) g(r) n(eturning) p Fd 21 w(false) p
+Fg 21 w(instead.) 204 777 y(Ther) n(e) f(is) g(no) h(way) f(of) h
+(query) n(ing) g(the) f(value) h(of) g(the) f(semaphor) n(e) n(.) p
+Fh 63 1095 a(3) 119 b(Thread) 29 b(object) p Fg 63 1313
+a(A) 23 b(thr) n(ead) g(is) h(r) n(epr) n(ese) n(nted) e(by) i(an) p
+Fd 24 w(omni) n(_thr) n(ead) p Fg 23 w(object.) 30 b(Ther) n(e) 23
+b(ar) n(e) h(br) n(oadly) g(two) e(dif) n(fer) n(-) 63
+1426 y(ent) f(ways) i(in) g(which) g(it) g(can) g(be) g(used) n(.) 204
+1542 y(The) 28 b(\002rst) g(way) h(is) h(simply) f(to) f(cr) n(eate) h
+(an) p Fd 30 w(omn) n(i_thr) n(ead) p Fg 28 w(object,) h(giving) g(a) f
+(particula) r(r) 63 1655 y(function) c(which) h(the) e(thr) n(ead) h
+(should) f(execute) n(.) 36 b(This) 25 b(is) g(like) g(the) g(POSIX) f
+(\(or) i(any) f(other) n(\)) h(C) 63 1768 y(language) c(interface.) 204
+1884 y(The) k(second) f(method) h(of) h(use) e(is) i(to) f(cr) n(eate) h
+(a) g(new) g(class) g(which) g(inherits) f(fr) n(om) p
+Fd 28 w(omn) n(i_) 63 1997 y(thr) n(ead) p Fg(.) 50 b(In) 31
+b(this) f(case) g(the) g(thr) n(ead) g(will) i(execute) d(the) p
+Fd 29 w(run\(\)) p Fg 29 w(member) h(function) h(of) f(the) 63
+2109 y(new) 22 b(class.) 29 b(One) 23 b(advantage) g(of) g(this) g
+(scheme) f(is) h(that) g(thr) n(ead-speci\002c) g(data) g(can) h(be) f
+(imple-) 63 2222 y(mented) e(simply) h(by) h(having) g(data) g(members)
+f(of) h(the) f(new) g(class.) 204 2339 y(When) f(constr) o(ucted) g(a) i
+(thr) n(ead) f(is) g(in) h(the) e("new") h(state) f(and) h(has) g(not) g
+(actuall) r(y) g(starte) n(d.) 28 b(A) 63 2451 y(call) j(to) p
+Fd 29 w(sta) n(rt\(\)) p Fg 28 w(causes) e(the) g(thr) n(ead) g(to) g
+(begin) g(executing.) 47 b(A) 29 b(static) h(member) f(function) p
+Fd 63 2564 a(cre) n(ate\() n(\)) p Fg 32 w(is) j(pr) n(ovided) f(to) g
+(constr) o(uct) g(and) g(start) g(a) i(thr) n(ead) e(in) h(a) g(single)
+g(call.) 57 b(A) 31 b(thr) n(ead) 63 2677 y(exits) 21
+b(by) i(call) r(ing) p Fd 22 w(exit\() n(\)) p Fg 22
+w(or) g(by) f(r) n(eturning) g(fr) n(om) h(the) f(thr) n(ead) g
+(function.) 204 2793 y(Thr) n(eads) 27 b(can) j(be) e(either) g
+(detached) f(or) h(undetached) n(.) 46 b(Detached) 28
+b(thr) n(eads) g(ar) n(e) h(thr) n(eads) 63 2906 y(for) h(which) i(all)
+g(state) e(will) i(be) f(lost) f(upon) g(exit.) 52 b(Other) 30
+b(thr) n(eads) g(cannot) h(dete) n(rmine) g(when) 63
+3019 y(a) e(detached) f(thr) n(ead) h(will) h(disappear) -7
+b(,) 31 b(and) e(ther) n(efor) n(e) f(should) g(not) h(attempt) f(to) g
+(access) h(the) 63 3132 y(thr) n(ead) 23 b(object) g(unless) f(some) h
+(explicit) h(synchr) n(onisation) f(with) g(the) g(detached) f(thr) n
+(ead) h(guar) n(-) 63 3245 y(antees) e(that) h(it) h(still) g(exists.)
+204 3361 y(Undet) n(ached) 33 b(thr) n(eads) f(ar) n(e) i(thr) n(eads) e
+(for) h(which) g(storage) f(is) h(not) f(r) n(eclai) r(med) g(until) i
+(an-) 63 3474 y(othe) n(r) g(thr) n(ead) g(waits) g(for) g(its) g
+(termination) g(by) g(call) r(ing) p Fd 34 w(joi) n(n\(\)) p
+Fg(.) 61 b(An) 34 b(exit) g(value) h(can) g(be) 63 3587
+y(passe) n(d) 23 b(fr) n(om) g(an) g(undet) n(ached) g(thr) n(ead) f
+(to) g(the) g(thr) n(ead) g(which) h(joins) g(it.) 204
+3703 y(Detached) 31 b(/) h(undetached) e(thr) n(eads) h(ar) n(e) i
+(distinguish) n(ed) f(on) f(cr) n(eation) h(by) g(the) f(type) g(of) 63
+3816 y(function) 24 b(they) e(execute.) 30 b(Undetached) 22
+b(thr) n(eads) h(execute) g(a) h(function) g(which) g(has) g(a) p
+Fd 25 w(voi) n(d*) p Fg 63 3929 a(r) n(eturn) c(typ) n(e,) h(wher) n
+(eas) f(detached) f(thr) n(eads) h(execute) f(a) j(function) f(which) g
+(has) g(a) p Fd 21 w(void) p Fg 19 w(r) n(eturn) 63 4042
+y(typ) n(e.) 52 b(Unfortunate) n(ly) 31 b(C++) g(member) g(functions) f
+(ar) n(e) h(not) f(allowed) g(to) g(be) h(distingu) n(ished) 63
+4155 y(simply) 26 b(by) h(their) f(r) n(eturn) g(type) n(.) 40
+b(Thus) 26 b(in) h(the) f(case) h(of) g(a) g(derived) f(class) h(of) p
+Fd 26 w(omni_) n(thre) n(ad) p Fg 63 4268 a(which) 20
+b(needs) e(an) j(undet) n(ached) f(thr) n(ead,) g(the) f(member) h
+(function) g(execute) n(d) g(by) g(the) f(thr) n(ead) g(is) 63
+4380 y(called) p Fd 19 w(run_u) n(ndet) n(ache) n(d\(\)) p
+Fg 18 w(rather) f(than) p Fd 19 w(run\() n(\)) p Fg(,) h(and) g(it) g
+(is) g(started) e(by) i(calli) r(ng) p Fd 18 w(star) n(t_) 63
+4493 y(und) n(etac) n(hed\(\)) p Fg 21 w(instead) j(of) p
+Fd 22 w(start) n(\(\)) p Fg(.) 204 4610 y(The) i(abstraction) i(curr) n
+(ently) e(suppo) n(rts) h(thr) n(ee) f(priorities) g(of) h(thr) n(ead,)
+g(but) g(no) g(guarantee) 63 4722 y(is) 33 b(made) g(of) h(how) f(this)
+g(will) h(af) n(f) r(ect) f(underlying) f(thr) n(ead) h(scheduling.) 59
+b(The) 33 b(thr) n(ee) f(priori-) 63 4835 y(ties) 18
+b(ar) n(e) p Fd 20 w(PRIO) n(RITY) n(_LOW) p Fg(,) p
+Fd 18 w(PRIO) n(RITY) n(_NOR) n(MAL) p Fg 19 w(and) p
+Fd 19 w(PRIO) n(RITY) n(_HIG) n(H) p Fg(.) h(By) g(default) g(all) 63
+4948 y(thr) n(eads) i(r) o(un) i(at) p Fd 23 w(PRIO) n(RITY) n(_NORM) n
+(AL) p Fg(.) f(A) g(dif) n(fer) n(ent) h(priority) f(can) i(be) e
+(speci\002ed) g(on) g(thr) n(ead) 63 5061 y(cr) n(eation,) h(or) f
+(while) h(the) f(thr) n(ead) g(is) h(r) o(unning) g(using) p
+Fd 22 w(set_) n(prio) n(rity\() n(\).) p Fg 28 w(A) g(thr) n(ead's) f
+(cur) n(-) 63 5174 y(r) n(ent) g(priority) g(is) g(r) n(eturned) f(by) p
+Fd 23 w(pri) n(ority) n(\(\)) p Fg(.) 204 5290 y(Other) d(functions) g
+(pr) n(ovided) g(ar) n(e) p Fd 19 w(sel) n(f\(\)) p Fg
+18 w(which) h(r) n(eturns) e(the) h(calli) r(ng) g(thr) n(ead's) p
+Fd 18 w(omn) n(i_) 63 5403 y(thr) n(ead) p Fg 36 w(object,) p
+Fd 40 w(yie) n(ld\(\)) p Fg 35 w(which) 38 b(r) n(eques) n(ts) e(that) h
+(other) e(thr) n(eads) h(be) h(allowed) g(to) f(r) o(un,) p
+90 rotate dyy eop
+%%Page: 4 4
+4 3 bop Fg 221 249 a(4) p Fe 1367 w(6) 91 b(THRE) n(ADED) 23
+b(I/O) g(SHUTDOWN) f(FOR) g(UNIX) p Fd 221 548 a(id\(\)) p
+Fg 27 w(which) 29 b(r) n(eturns) e(an) i(intege) n(r) g(id) f(for) h
+(the) e(thr) n(ead) h(for) g(use) g(in) h(debug) n(ging,) p
+Fd 29 w(state) n(\(\)) p Fg(,) p Fd 221 661 a(slee) n(p\(\)) p
+Fg 22 w(and) p Fd 22 w(get_t) n(ime\() n(\)) p Fg(.) p
+Fh 221 953 a(4) 119 b(Per) n(-threa) n(d) 30 b(data) p
+Fg 221 1164 a(omnithr) n(ead) 22 b(suppo) n(rts) g(per) n(-thr) n(ead) f
+(data,) h(via) i(member) e(functions) f(of) i(the) p
+Fd 21 w(omni) n(_thr) n(ead) p Fg 221 1277 a(object.) 362
+1390 y(First,) d(you) g(must) h(allocate) h(a) f(key) f(for) g(with) h
+(the) p Fd 20 w(omni) n(_thre) n(ad::) n(allo) n(cate_) n(key\() n(\)) p
+Fg 221 1502 a(function.) 28 b(Then,) 21 b(any) h(object) g(whose) f
+(class) h(is) g(derived) f(fr) n(om) p Fd 23 w(omni) n(_thr) n(ead::) n
+(valu) n(e_t) p Fg 221 1615 a(can) 27 b(be) f(stor) n(e) n(d) g(using) f
+(the) p Fd 26 w(set) n(_val) n(ue\(\)) p Fg 25 w(function.) 38
+b(V) -8 b(alues) 25 b(ar) n(e) h(r) n(etrieved) f(or) h(r) n(emoved) 221
+1728 y(with) p Fd 23 w(get) n(_valu) n(e\(\)) p Fg 21
+w(and) p Fd 23 w(remo) n(ve_v) n(alue\() n(\)) p Fg 22
+w(r) n(espectively) -10 b(.) 362 1841 y(When) 23 b(the) g(thr) n(ead) g
+(exits,) g(all) i(per) n(-thr) n(ead) e(data) h(is) g(delet) n(ed) f
+(\(hence) h(the) e(base) i(class) g(with) 221 1954 y(virtual) g(dest) n
+(r) o(uctor\).) 362 2067 y(Note) 17 b(that) i(the) f(per) n(-thr) n
+(ead) f(data) i(functions) f(ar) n(e) p Fb 19 w(not) p
+Fg 18 w(thr) n(ead) g(safe,) i(so) d(although) i(you) e(can) 221
+2180 y(access) 29 b(one) e(thr) n(ead's) h(storage) f(fr) n(om) i
+(another) f(thr) n(ead,) h(ther) n(e) e(is) i(no) f(concurr) n(ency) g
+(contr) n(ol.) 221 2293 y(Unless) j(you) g(r) n(eall) r(y) h(know) f
+(what) h(you) f(ar) n(e) i(doing,) g(it) g(is) f(best) f(to) h(only) g
+(access) g(per) n(-thr) n(ead) 221 2406 y(data) 23 b(fr) n(om) g(the) f
+(thr) n(ead) g(it) h(is) g(attached) f(to.) p Fh 221
+2698 a(5) 119 b(Using) 31 b(OMNI) d(threads) h(in) h(your) g(program) p
+Fg 221 2909 a(Obvi) r(ously) 16 b(you) h(need) g(to) g(include) h(the) p
+Fd 16 w(omnit) n(hrea) n(d.h) p Fg 17 w(header) e(\002le) i(in) g(your)
+f(sour) n(ce) g(code,) 221 3021 y(and) 25 b(link) g(in) h(the) e
+(omnithr) n(ead) g(libra) r(ry) g(with) h(your) f(execut) n(abl) r(e.)
+34 b(Because) 23 b(ther) n(e) h(is) h(a) g(single) p
+Fd 221 3134 a(omni) n(threa) n(d.h) p Fg 30 w(for) 32
+b(all) h(platforms,) h(certain) e(pr) n(epr) n(oces) n(sor) f
+(de\002nes) f(must) h(be) g(given) h(as) 221 3247 y(compiler) 25
+b(options) n(.) 33 b(The) 23 b(easiest) g(way) h(to) g(do) f(this) h
+(is) g(to) g(stud) n(y) g(the) g(make\002les) f(given) h(in) h(the) 221
+3360 y(examples) i(pr) n(ovided) g(with) g(this) g(distribution.) 42
+b(If) 27 b(you) g(ar) n(e) g(to) g(include) h(OMNI) f(thr) n(eads) g
+(in) 221 3473 y(your) 18 b(own) g(development) g(envir) n(onment,) h
+(thes) n(e) g(ar) n(e) g(the) f(necessary) g(pr) n(epr) n(oce) n(ssor) g
+(de\002nes) n(:) p 362 3567 3287 4 v 360 3680 4 113 v
+412 3646 a(Platform) p 1312 3680 V 599 w(Pr) n(epr) n(ocess) n(or) 23
+b(De\002nes) p 3648 3680 V 362 3683 3287 4 v 362 3700
+V 360 3813 4 113 v 412 3779 a(Sun) f(Solaris) h(2.x) p
+1312 3813 V Fd 365 w(-D__) n(suno) n(s__) 54 b(-D_) n(_spa) n(rc__) f
+(-D__) n(OSVER) n(SION) n(__=5) p 3648 3813 V 360 3926
+V 1312 3926 V 1363 3892 a(-DSV) n(R4) h(-DUs) n(ePth) n(read) f(-D_R) n
+(EENT) n(RANT) p 3648 3926 V 362 3929 3287 4 v 360 4042
+4 113 v Fg 412 4008 a(x86) 24 b(Linux) e(2.0) p 1312
+4042 V Fd 418 w(-D__) n(linu) n(x__) 54 b(-D_) n(_i86) n(__) g(-D__) n
+(OSVE) n(RSION) n(__=2) p 3648 4042 V 360 4155 V Fg 412
+4121 a(with) 23 b(linuxthr) n(eads) f(0.5) p 1312 4155
+V Fd 100 w(-D_R) n(EENT) n(RANT) p 3648 4155 V 362 4158
+3287 4 v 360 4271 4 113 v Fg 412 4237 a(Digital) i(Unix) f(3.2) p
+1312 4271 V Fd 320 w(-D__) n(osf1) n(__) 54 b(-D__) n(alph) n(a__) g
+(-D_) n(_OSV) n(ERSIO) n(N__=) n(3) p 3648 4271 V 360
+4384 V 1312 4384 V 1363 4350 a(-D_R) n(EENT) n(RANT) p
+3648 4384 V 362 4387 3287 4 v 360 4500 4 113 v Fg 412
+4466 a(W) -5 b(indows) 22 b(NT) p 1312 4500 V Fd 411
+w(-D__) n(NT__) 53 b(-MD) p 3648 4500 V 362 4503 3287
+4 v Fh 221 4740 a(6) 119 b(Threaded) 29 b(I/O) g(shutdown) h(for) g
+(Unix) p Fg 221 4951 a(or) -7 b(,) 20 b(how) e(one) g(thr) n(ead) h
+(shou) n(ld) h(tell) f(another) f(thr) n(ead) g(to) h(shut) f(down) g
+(when) g(it) h(might) g(be) g(doing) 221 5064 y(a) k(blocking) g(cal) r
+(l) g(on) f(a) h(socket) n(.) p Fb 362 5177 a(If) h(you) e(are) i
+(using) e(omniOR) n(B,) h(you) e(don') n(t) i(need) g(to) g(worry) f
+(about) g(all) i(this,) f(since) h(om-) 221 5290 y(niORB) i(does) h(it)
+h(for) f(you) n(.) p Fg 41 w(This) g(section) f(is) h(only) g(r) n
+(elevant) g(if) h(you) e(ar) n(e) h(using) f(omnithr) n(ead) 221
+5403 y(in) d(your) f(own) g(socket) n(-based) h(pr) n(ogramming.) k(It)
+22 b(is) h(also) g(serious) n(ly) g(out) f(of) h(date.) p
+90 rotate dyy eop
+%%Page: 5 5
+5 4 bop Fe 63 249 a(6.1) 91 b(r) n(ead\(\)) p Fg 2800
+w(5) 204 548 y(Unfortunate) n(ly) 35 b(ther) n(e) e(doe) n(sn't) h
+(seem) f(to) h(be) g(a) h(standar) n(d) e(way) i(of) f(doing) f(this) h
+(which) 63 661 y(works) 19 b(acr) n(oss) i(all) i(Unix) e(syst) n(ems.)
+27 b(I) 21 b(have) g(investigated) f(the) h(behaviour) g(of) g(Solaris)
+h(2.5) g(and) 63 774 y(Digital) k(Unix) g(3.2.) 36 b(On) 26
+b(Digital) h(Unix) e(everyth) n(ing) h(is) f(\002ne,) g(as) h(the) e
+(obvious) h(method) f(using) 63 887 y(shutd) n(own\(\)) 32
+b(seems) f(to) h(work) f(OK.) h(Unfortunately) f(on) h(Solaris) h(shut)
+n(down) f(can) h(only) f(be) 63 1000 y(used) 25 b(on) h(a) h(connected)
+e(socke) n(t,) i(so) f(we) g(need) f(devious) h(means) g(to) g(get) f
+(ar) n(ound) h(this) g(lim) r(ita-) 63 1112 y(tion.) h(The) 22
+b(details) g(ar) n(e) h(summarised) g(below:) p Fc 63
+1429 a(6.1) 99 b(read\(\)) p Fg 63 1627 a(Thr) n(ead) 28
+b(A) h(is) g(in) h(a) g(loop,) g(doing) p Fd 28 w(rea) n(d\(soc) n(k\))
+p Fg(,) g(pr) n(ocess) n(ing) f(the) g(data,) h(then) f(going) f(back)
+63 1739 y(into) 22 b(the) g(r) n(ead.) 204 1862 y(Thr) n(ead) 30
+b(B) h(comes) f(along) h(and) g(wants) f(to) g(shut) g(it) h(down) f
+(\227) h(it) g(can't) g(cancel) h(thr) n(ead) f(A) 63
+1975 y(since) 21 b(\(i\)) h(working) e(out) g(how) g(to) h(clean) h(up)
+e(accor) n(ding) i(to) e(wher) n(e) g(A) h(is) g(in) h(its) f(loop) f
+(is) h(a) h(night-) 63 2088 y(mar) n(e,) h(and) f(\(ii\)) i(this) f
+(isn't) f(ava) r(ilabl) r(e) g(in) h(omnithr) n(ead) f(anyway) -10
+b(.) 204 2211 y(On) 23 b(Solaris) g(2.5) g(and) g(Digital) h(Unix) f
+(3.2) g(the) f(following) h(strate) n(gy) f(works:) 204
+2334 y(Thr) n(ead) g(B) g(does) p Fd 21 w(shut) n(down\() n(sock) n
+(,2\)) p Fg(.) 204 2457 y(At) g(this) g(point) h(thr) n(ead) f(A) g(is)
+h(either) f(blocked) g(inside) p Fd 23 w(rea) n(d\(so) n(ck\)) p
+Fg(,) g(or) g(is) h(elsewhe) n(r) n(e) g(in) 63 2570
+y(the) 18 b(loop.) 26 b(If) 18 b(the) g(former) h(then) f(r) n(ead) h
+(will) h(r) n(eturn) e(0,) i(indicating) f(that) g(the) f(socke) n(t) h
+(is) g(closed.) 26 b(If) 63 2683 y(the) 21 b(latter) h(then) f
+(eventually) h(thr) n(ead) g(A) g(will) i(call) p Fd
+24 w(rea) n(d\(so) n(ck\)) p Fg 21 w(and) f(then) e(this) h(will) h(r) n
+(eturn) 63 2796 y(0.) 28 b(Thr) n(ead) 22 b(A) h(should) p
+Fd 21 w(clos) n(e\(soc) n(k\)) p Fg(,) f(do) g(any) g(other) g(tidying)
+f(up,) h(and) h(exit.) 204 2919 y(If) 34 b(ther) n(e) g(is) h(another) f
+(point) g(in) h(the) e(loop) i(that) f(thr) n(ead) g(A) h(can) g(block)
+g(then) f(obviously) 63 3032 y(thr) n(ead) 19 b(B) h(needs) f(to) h(be)
+g(awar) n(e) h(of) f(this) g(and) g(be) h(able) g(to) e(wake) h(it) h
+(up) f(in) g(the) g(appr) n(opriate) g(way) 63 3145 y(fr) n(om) j(that)
+f(point.) p Fc 63 3462 a(6.2) 99 b(accept\(\)) p Fg 63
+3659 a(Again) 25 b(thr) n(ead) g(A) h(is) f(in) h(a) g(loop,) g(this) f
+(time) h(doing) e(an) i(acc) r(ept) e(on) h(listenSock,) g(dealing) h
+(with) 63 3772 y(a) d(new) f(connection) g(and) h(going) e(back) j
+(into) e(accept.) 28 b(Thr) n(ead) 22 b(B) g(wants) h(to) f(cancel) h
+(it.) 204 3895 y(On) g(Digital) h(Unix) f(3.2) g(the) f(strateg) n(y) g
+(is) h(identical) h(to) e(that) g(for) h(r) n(ead:) 204
+4018 y(Thr) n(ead) 39 b(B) g(does) p Fd 38 w(shut) n(down) n(\(list) n
+(enSo) n(ck,2) n(\)) p Fg(.) 79 b(Wher) n(ever) 38 b(thr) n(ead) h(A) h
+(is) f(in) h(the) 63 4131 y(loop,) i(eventually) c(it) h(will) h(r) n
+(eturn) p Fd 38 w(ECONN) n(ABOR) n(TED) p Fg 38 w(fr) n(om) f(the) f
+(accept) h(call) r(.) 76 b(It) 39 b(shou) n(ld) p Fd
+63 4244 a(clo) n(se\(l) n(isten) n(Sock) n(\)) p Fg(,) 22
+b(tidy) g(up) g(as) h(necessary) e(and) i(exit.) 204
+4367 y(On) 30 b(Solaris) f(2.5) i(thr) n(ead) e(B) g(can't) h(do) p
+Fd 29 w(shu) n(tdow) n(n\(lis) n(tenS) n(ock,2) n(\)) p
+Fg 29 w(\227) g(this) f(r) n(eturns) p Fd 63 4480 a(ENO) n(TCON) n(N) p
+Fg(.) 22 b(Instead) f(the) h(following) h(strateg) n(y) g(can) g(be) g
+(used) n(:) 204 4603 y(First) 35 b(thr) n(ead) h(B) g(set) n(s) g(some)
+f(sort) g(of) h("shutdo) n(wn) g(\003ag") g(associated) g(with) g
+(listenSock.) 63 4716 y(Then) 31 b(it) h(does) p Fd 30
+w(gets) n(ocka) n(ddr\(l) n(iste) n(nSock) n(\)) p Fg
+32 w(to) f(\002nd) g(out) g(which) i(port) e(listenSock) f(is) 63
+4828 y(on) 18 b(\(or) h(knows) e(alr) n(eady\),) j(sets) d(up) h(a) h
+(socket) e(dummySock,) i(doe) n(s) p Fd 19 w(con) n(nect) n(\(dumm) n
+(ySoc) n(k,) 63 4941 y(thi) n(s) 54 b(host,) f(por) n(t\)) p
+Fg 22 w(and) 23 b(\002nally) g(does) p Fd 21 w(clos) n(e\(dum) n(mySo) n
+(ck\)) p Fg(.) 204 5064 y(Wher) n(ever) 16 b(thr) n(ead) h(A) g(is) g
+(in) h(the) e(loop,) h(eventually) g(it) h(will) g(call) p
+Fd 19 w(acce) n(pt\(li) n(sten) n(Sock) n(\)) p Fg(.) 63
+5177 y(This) 35 b(will) j(r) n(eturn) d(successfully) g(with) h(a) h
+(new) e(socket,) j(say) e(connSock.) 67 b(Thr) n(ead) 36
+b(A) f(then) 63 5290 y(checks) 20 b(to) h(see) f(if) i(the) f("shutd) n
+(own) g(\003ag") h(is) f(set.) 26 b(If) c(not,) e(then) h(it's) g(a) h
+(normal) g(connection.) 27 b(If) 21 b(it) 63 5403 y(is) h(set,) g(then)
+f(thr) n(ead) h(A) h(closes) f(listenSock) f(and) i(connSock,) e
+(tidies) h(up) g(and) h(exits.) p 90 rotate dyy eop
+%%Page: 6 6
+6 5 bop Fg 221 249 a(6) p Fe 1367 w(6) 91 b(THRE) n(ADED) 23
+b(I/O) g(SHUTDOWN) f(FOR) g(UNIX) p Fc 221 548 a(6.3) 99
+b(write\(\)) p Fg 221 768 a(Thr) n(ead) 19 b(A) f(may) h(be) g(blocked)
+f(in) i(write,) f(or) f(about) h(to) f(go) g(in) h(to) g(a) g(poten) n
+(tiall) r(y-blocking) g(write.) 221 881 y(Thr) n(ead) j(B) h(wants) f
+(to) g(shut) f(it) i(down.) 362 1016 y(On) g(Solaris) g(2.5:) 362
+1150 y(Thr) n(ead) f(B) h(doe) n(s) p Fd 23 w(shu) n(tdown) n(\(soc) n
+(k,2\)) p Fg -2 w(.) 362 1285 y(If) c(thr) n(ead) f(A) h(is) g(alr) n
+(eady) g(in) p Fd 20 w(wri) n(te\(s) n(ock\)) p Fg 17
+w(then) f(it) h(will) i(r) n(eturn) d(with) p Fd 18 w(ENXIO) p
+Fg -2 w(.) h(If) g(thr) n(ead) 221 1398 y(A) k(calls) h(write) e(after)
+g(thr) n(ead) g(B) h(calls) h(shut) n(down) e(this) g(will) i(r) n
+(eturn) p Fd 22 w(EIO) p Fg(.) 362 1532 y(On) f(Digital) h(Unix) f
+(3.2:) 362 1666 y(Thr) n(ead) f(B) h(doe) n(s) p Fd 23
+w(shu) n(tdown) n(\(soc) n(k,2\)) p Fg -2 w(.) 362 1801
+y(If) h(thr) n(ead) f(A) g(is) h(alr) n(eady) g(in) p
+Fd 24 w(writ) n(e\(so) n(ck\)) p Fg 23 w(then) e(it) i(will) h(r) n
+(eturn) e(the) f(number) i(of) f(bytes) 221 1914 y(written) 31
+b(befor) n(e) h(it) g(became) g(blocked.) 55 b(A) 32
+b(subseq) n(uent) f(cal) r(l) h(to) f(write) h(will) h(then) e(gene) n
+(rate) p Fd 221 2027 a(SIGP) n(IPE) p Fg 22 w(\(or) p
+Fd 22 w(EPIP) n(E) p Fg 23 w(will) 24 b(be) e(r) n(eturned) f(if) p
+Fd 24 w(SIG) n(PIPE) p Fg 21 w(is) i(ignor) n(ed) e(by) i(the) f(thr) n
+(ead\).) p Fc 221 2413 a(6.4) 99 b(connect\(\)) p Fg
+221 2634 a(Thr) n(ead) 30 b(A) f(may) h(be) g(blocked) f(in) i
+(connect,) g(or) e(about) h(to) f(go) g(in) i(to) e(a) h(poten) n
+(tiall) r(y-blocking) 221 2747 y(connect.) d(Thr) n(ead) c(B) f(wants) g
+(to) g(shut) g(it) g(down.) 362 2881 y(On) h(Digital) h(Unix) f(3.2:)
+362 3016 y(Thr) n(ead) f(B) h(doe) n(s) p Fd 23 w(shu) n(tdown) n
+(\(soc) n(k,2\)) p Fg -2 w(.) 362 3150 y(If) j(thr) n(ead) f(A) g(is) h
+(alr) n(eady) g(in) p Fd 26 w(conn) n(ect\() n(sock) n(\)) p
+Fg 26 w(then) e(it) i(will) h(r) n(eturn) e(a) h(successful) f(con-) 221
+3263 y(nection.) 54 b(Subsequ) n(ent) 31 b(r) n(eading) g(or) g
+(writing) g(will) i(show) d(that) i(the) e(socket) g(has) h(been) g
+(shut) 221 3376 y(down) 22 b(\(i.e.) 28 b(r) n(ead) 23
+b(r) n(eturns) e(0,) i(write) f(generate) n(s) p Fd 23
+w(SIG) n(PIPE) p Fg 21 w(or) g(r) n(eturns) p Fd 22 w(EPI) n(PE) p
+Fg(\).) g(If) h(thr) n(ead) f(A) 221 3489 y(call) r(s) g(connect) g
+(after) h(thr) n(ead) f(B) g(call) r(s) g(shutdo) n(wn) h(this) f(will)
+i(r) n(eturn) p Fd 22 w(EIN) n(VAL) p Fg(.) 362 3623
+y(On) f(Solaris) g(2.5:) 362 3758 y(Ther) n(e) 35 b(is) h(no) f(way) g
+(to) g(wake) g(up) g(a) h(thr) n(ead) f(which) h(is) g(blocked) f(in) h
+(connect.) 66 b(Inst) n(ead) 221 3871 y(Solaris) 33 b(for) n(ces) g(us)
+f(thr) n(ough) g(a) i(ridiculous) f(pr) n(oced) n(ur) n(e) g(whichever)
+g(way) g(we) f(try) g(it.) 59 b(One) 221 3984 y(way) 23
+b(is) f(this:) 362 4118 y(First) d(thr) n(ead) h(A) g(cr) n(eates) f(a)
+h(pipe) g(in) g(addition) g(to) f(the) g(socket) n(.) 27
+b(Instead) 19 b(of) h(shut) n(ting) g(down) 221 4231
+y(the) i(socket) n(,) h(thr) n(ead) f(B) g(simply) h(writes) e(a) i
+(byte) f(to) g(the) g(pipe.) 362 4365 y(Thr) n(ead) 17
+b(A) g(meanwhile) h(set) n(s) f(the) g(socke) n(t) g(to) g
+(non-blocking) g(mode) f(using) p Fd 17 w(fcn) n(tl\(s) n(ock,) 221
+4478 y(F_SE) n(TFL,) 53 b(O_NO) n(NBLO) n(CK\)) p Fg(.) 26
+b(Then) h(it) g(cal) r(ls) g(connect) g(on) g(the) f(socket) g(\227) h
+(this) g(will) i(r) n(eturn) p Fd 221 4591 a(EINP) n(ROGRE) n(SS) p
+Fg(.) k(Then) h(it) h(must) e(cal) r(l) p Fd 35 w(sel) n(ect\() n(\)) p
+Fg(,) k(waiting) e(for) f(either) g(sock) g(to) f(become) 221
+4704 y(writable) 39 b(or) f(for) h(the) e(pipe) h(to) g(become) g(r) n
+(eadable.) 75 b(If) 39 b(select) e(r) n(eturns) g(that) i(just) e(sock)
+h(is) 221 4817 y(writable) 30 b(then) f(the) g(connection) g(has) h
+(succeede) n(d.) 49 b(It) 29 b(then) g(need) n(s) h(to) f(set) f(the) h
+(socket) f(back) 221 4930 y(to) i(blocking) h(mode) f(using) p
+Fd 30 w(fcnt) n(l\(so) n(ck,) 54 b(F_S) n(ETFL) n(,) h(0\)) p
+Fg(.) c(If) 31 b(instead) e(select) h(r) n(eturns) 221
+5043 y(that) 23 b(the) e(pipe) h(is) h(r) n(eadable,) g(thr) n(ead) f
+(A) h(closes) e(the) h(socket) n(,) h(tidies) f(up) g(and) h(exits.) 362
+5177 y(An) g(alternative) h(method) e(is) i(similar) h(but) e(to) g
+(use) f(polling) i(instead) e(of) i(the) e(pipe.) 29
+b(Thr) n(ead) 221 5290 y(B) 24 b(justs) e(sets) g(a) j(\003ag) f(and) g
+(thr) n(ead) f(A) h(calls) h(select) e(with) g(a) i(timeout,) e(period)
+n(ica) r(lly) h(waking) f(up) 221 5403 y(to) f(see) g(if) h(the) f
+(\003ag) h(has) f(been) g(set.) p 90 rotate dyy eop
+%%Page: 7 7
+7 6 bop Fe 63 249 a(REF) n(ERENCES) p Fg 2660 w(7) p
+Fh 63 548 a(Refere) n(nces) p Fg 63 759 a([POSIX94]) p
+Fa 46 w(Portable) 29 b(Operat) r(ing) f(System) g(Interface) h
+(\(POSIX\)) e(Thr) n(ea) r(ds) h(Extension) p Fg(,) h(P1003) r(.1c) 245
+872 y(Draft) 23 b(10,) g(IEEE,) e(Septe) n(mber) i(1994) r(.) 63
+1059 y([Birr) n(ell89]) p Fa 47 w(An) 28 b(Intr) n(od) r(uction) g(to) h
+(Pr) n(ogr) r(amming) g(with) g(Thr) n(ead) r(s) p Fg(,) h(Rese) n(ar) n
+(ch) g(Repo) n(rt) e(35,) j(DEC) 245 1172 y(Syst) n(ems) 22
+b(Resear) n(ch) g(Center) -7 b(,) 22 b(Palo) h(Alto,) f(CA,) h(January)
+g(1989) r(.) p 90 rotate dyy eop
+%%Trailer
+end
+userdict /end-hook known{end-hook}if
+%%EOF
diff --git a/gnuradio-core/doc/other/shared_ptr_docstub.h b/gnuradio-core/doc/other/shared_ptr_docstub.h
new file mode 100755 (executable)
index 0000000..428dd03
--- /dev/null
@@ -0,0 +1,24 @@
+namespace boost
+{
+  /*!
+   * \brief shared_ptr documentation stub
+   *
+   * \warning
+   * This isn't the real shared_ptr template.  It's just enough to get doxygen
+   * to draw pretty collaboration diagrams.
+   *
+   * An enhanced relative of scoped_ptr with reference counted copy semantics.
+   * The object pointed to is deleted when the last shared_ptr pointing to it
+   * is destroyed or reset.
+   */
+
+template<class T> class shared_ptr
+{
+public:
+
+    T * px;                     // contained pointer
+
+};  // shared_ptr
+
+
+} // namespace boost
diff --git a/gnuradio-core/doc/other/tv-channel-frequencies b/gnuradio-core/doc/other/tv-channel-frequencies
new file mode 100644 (file)
index 0000000..e2780ec
--- /dev/null
@@ -0,0 +1,79 @@
+# These are the center frequencies in MHz for North American broadcast
+# TV channels.  Each channel is 6 MHz wide, hence the bottom edge of the
+# channel is 3 MHz below the value in this table.
+# 
+# For NTSC (Analog) TV, the picture carrier is 1.25 MHz up from the
+# bottom edge.  NTSC has the FM audio at bottom + 5.75 and the spike is easily
+# visible.
+# 
+# For ATSC, the pilot tone is 0.31 MHz up from the bottom.
+# 
+#
+  2     57.00
+  3     63.00
+  4     69.00
+  5     79.00
+  6     85.00
+  7    177.00
+  8    183.00
+  9    189.00
+ 10    195.00
+ 11    201.00
+ 12    207.00
+ 13    213.00
+ 14    473.00
+ 15    479.00
+ 16    485.00
+ 17    491.00
+ 18    497.00
+ 19    503.00
+ 20    509.00
+ 21    515.00
+ 22    521.00
+ 23    527.00
+ 24    533.00
+ 25    539.00
+ 26    545.00
+ 27    551.00
+ 28    557.00
+ 29    563.00
+ 30    569.00
+ 31    575.00
+ 32    581.00
+ 33    587.00
+ 34    593.00
+ 35    599.00
+ 36    605.00
+ 37    611.00
+ 38    617.00
+ 39    623.00
+ 40    629.00
+ 41    635.00
+ 42    641.00
+ 43    647.00
+ 44    653.00
+ 45    659.00
+ 46    665.00
+ 47    671.00
+ 48    677.00
+ 49    683.00
+ 50    689.00
+ 51    695.00
+ 52    701.00
+ 53    707.00
+ 54    713.00
+ 55    719.00
+ 56    725.00
+ 57    731.00
+ 58    737.00
+ 59    743.00
+ 60    749.00
+ 61    755.00
+ 62    761.00
+ 63    767.00
+ 64    773.00
+ 65    779.00
+ 66    785.00
+ 67    791.00
+ 68    797.00
+ 69    803.00
diff --git a/gnuradio-core/doc/other/vector_docstub.h b/gnuradio-core/doc/other/vector_docstub.h
new file mode 100644 (file)
index 0000000..139ce65
--- /dev/null
@@ -0,0 +1,16 @@
+namespace std
+{
+  /*!
+   * \brief vector documentation stub
+   *
+   * \warning
+   * This isn't the real vector template.  It's just enough to get doxygen
+   * to draw pretty collaboration diagrams.
+   */
+  template<class T> class vector
+  {
+  public:
+    T          *p;
+  };
+  
+} // namespace std
diff --git a/gnuradio-core/doc/xml/Makefile.am b/gnuradio-core/doc/xml/Makefile.am
new file mode 100644 (file)
index 0000000..848a468
--- /dev/null
@@ -0,0 +1,25 @@
+#
+# 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 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.
+# 
+
+EXTRA_DIST = README doxy2swig.py swig.xsl
+
+CLEANFILES = *.xml combine.xslt compound.xsd index.xsd
+
diff --git a/gnuradio-core/doc/xml/README b/gnuradio-core/doc/xml/README
new file mode 100644 (file)
index 0000000..317dbb4
--- /dev/null
@@ -0,0 +1,129 @@
+#
+# 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 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.
+#
+
+#
+# Generating Python docstrings from C++ code using doxygen
+#
+
+There are at least two strategies for this:
+  - use xsltproc as described below
+  - use doxy2swig.py (included in this directory)
+
+FIXME: get one of these working (probably doxy2swig since it doesn't
+add any additional dependencies).
+
+----------------------------------------------------------------
+
+Note: Robin's patch is in SWIG >= 1.3.23
+
+--------------------------------------------------------------------------------
+From: http://mailman.cs.uchicago.edu/pipermail/swig/2004-October/010604.html
+
+> I applied the docstring patch. '%feature("autodoc",1");' is working as 
+> expected ...
+
+[problem solved. ...]
+
+> I can not agree more with the doxygen idea. I am using doxygen for 
+> documentation and I have been trying to put doxygen output to the 
+> python interface. Automatic generation of %feature("docstring") lines 
+> from doxygen output is the closest solution I can think of but the 
+> workload is still pretty big. How I wish this feature can be 
+> implemented in the near future.
+
+I have successfully extracted function/class description from doxygen 
+generated xml files, using an xslt script. To add doxygen generated 
+description to each class/function, you will need to (tested under 
+linux, note that this works only for Python, using Robin's docstring 
+patch)
+
+1. download swig source, apply Robin's docstring patch from
+   https://sourceforge.net/tracker/index.php?func=detail&aid=1023309&group_id=1645&atid=301645
+   compile and install
+
+2. generate doxygen document with option "GENERATE_XML = YES"
+
+3. copy the attached script (save as swig.xsl) to the doc/xml directory 
+   and run
+
+     > xsltproc swig.xsl index.xml > temp_doc.i
+     > cat temp_doc.i | sed 's/"/\\"/g' | sed 's/__QuOtE__/"/g' > swig_doc.i
+
+   you will get an interface file with lines like
+     %feature("docstring") class "class description";
+     %feature("docstring") class::function "member function 
+         description";
+
+   the second step is necessary since there might be " in descriptions 
+   and I need to backquote them before I replace __QuOtE__ by real 
+   quotes. (xslt experts may know how to post-process <xsl:value-of> and 
+   make the script easier to use.)
+
+4. in your interface file, add
+     %include "siwg_doc.i"
+     %feature("autodoc","1") ;
+
+Hope this helps.
+
+swig.xsl:
+=========================================================
+
+<!-- XSLT script to extract document for class/function for swig docstring
+     If you have xsltproc you could use:
+     xsltproc swig.xsl index.xml > swig_doc.i
+-->
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
+  <xsl:output method="text"/>
+   <xsl:template match="/">
+      <!-- process each compound -->
+      <xsl:for-each select="doxygenindex/compound">
+        <xsl:apply-templates select="document( concat( @refid, '.xml' ) )/*" />
+      </xsl:for-each>
+   </xsl:template>
+
+  <xsl:template match="doxygen">
+    <xsl:for-each select="compounddef[@kind='class']">  
+      <xsl:text>%feature(__QuOtE__docstring__QuOtE__) </xsl:text>
+      <xsl:value-of select="compoundname"/>
+      <xsl:text> __QuOtE__ &#10;</xsl:text>
+      <xsl:value-of select="briefdescription"/><xsl:text>
+      </xsl:text>
+      <xsl:value-of select="detaileddescription"/>
+      <xsl:text> see also: </xsl:text>
+      <xsl:value-of select="includes"/>
+      <xsl:text>__QuOtE__;&#10;&#10;</xsl:text>
+
+      <!-- output for each function individually -->
+      <xsl:for-each select="*/memberdef[@kind='function' and not(starts-with(name,'operator'))]"> 
+        <xsl:text>%feature(__QuOtE__docstring__QuOtE__) </xsl:text><xsl:value-of select="../../compoundname"/>::<xsl:value-of select="name"/>
+        <xsl:text> __QuOtE__&#10;</xsl:text>
+        <xsl:value-of select="definition"/> <xsl:value-of select="argsstring"/>
+        <xsl:text>
+        </xsl:text><xsl:value-of select="briefdescription"/><xsl:text>
+        </xsl:text><xsl:value-of select="detaileddescription"/>
+        <xsl:text>__QuOtE__; &#10;&#10;</xsl:text>
+      </xsl:for-each>
+    </xsl:for-each>  
+  </xsl:template>
+</xsl:stylesheet>
+
+--
+Bo Peng
\ No newline at end of file
diff --git a/gnuradio-core/doc/xml/doxy2swig.py b/gnuradio-core/doc/xml/doxy2swig.py
new file mode 100644 (file)
index 0000000..1e379d9
--- /dev/null
@@ -0,0 +1,371 @@
+#!/usr/bin/env python
+"""Doxygen XML to SWIG docstring converter.
+
+Converts Doxygen generated XML files into a file containing docstrings
+that can be used by SWIG-1.3.x.  Note that you need to get SWIG
+version > 1.3.23 or use Robin Dunn's docstring patch to be able to use
+the resulting output.
+
+Usage:
+
+  doxy2swig.py input.xml output.i
+
+input.xml is your doxygen generated XML file and output.i is where the
+output will be written (the file will be clobbered).
+
+"""
+
+# This code is implemented using Mark Pilgrim's code as a guideline:
+#   http://www.faqs.org/docs/diveintopython/kgp_divein.html
+#
+# Author: Prabhu Ramachandran
+# License: BSD style
+
+
+from xml.dom import minidom
+import re
+import textwrap
+import sys
+import types
+import os.path
+
+
+def my_open_read(source):
+    if hasattr(source, "read"):
+        return source
+    else:
+        return open(source)
+
+def my_open_write(dest):
+    if hasattr(dest, "write"):
+        return dest
+    else:
+        return open(dest, 'w')
+
+
+class Doxy2SWIG:    
+    """Converts Doxygen generated XML files into a file containing
+    docstrings that can be used by SWIG-1.3.x that have support for
+    feature("docstring").  Once the data is parsed it is stored in
+    self.pieces.
+
+    """    
+    
+    def __init__(self, src):
+        """Initialize the instance given a source object (file or
+        filename).
+
+        """
+        f = my_open_read(src)
+        self.my_dir = os.path.dirname(f.name)
+        self.xmldoc = minidom.parse(f).documentElement
+        f.close()
+
+        self.pieces = []
+        self.pieces.append('\n// File: %s\n'%\
+                           os.path.basename(f.name))
+
+        self.space_re = re.compile(r'\s+')
+        self.lead_spc = re.compile(r'^(%feature\S+\s+\S+\s*?)"\s+(\S)')
+        self.multi = 0
+        self.ignores = ('inheritancegraph', 'param', 'listofallmembers',
+                        'innerclass', 'name', 'declname', 'incdepgraph',
+                        'invincdepgraph', 'programlisting', 'type',
+                        'references', 'referencedby', 'location',
+                        'collaborationgraph', 'reimplements',
+                        'reimplementedby', 'derivedcompoundref',
+                        'basecompoundref')
+        #self.generics = []
+        
+    def generate(self):
+        """Parses the file set in the initialization.  The resulting
+        data is stored in `self.pieces`.
+
+        """
+        self.parse(self.xmldoc)
+    
+    def parse(self, node):
+        """Parse a given node.  This function in turn calls the
+        `parse_<nodeType>` functions which handle the respective
+        nodes.
+
+        """
+        pm = getattr(self, "parse_%s"%node.__class__.__name__)
+        pm(node)
+
+    def parse_Document(self, node):
+        self.parse(node.documentElement)
+
+    def parse_Text(self, node):
+        txt = node.data
+        txt = txt.replace('\\', r'\\\\')
+        txt = txt.replace('"', r'\"')
+        # ignore pure whitespace
+        m = self.space_re.match(txt)
+        if m and len(m.group()) == len(txt):
+            pass
+        else:
+            self.add_text(textwrap.fill(txt))
+
+    def parse_Element(self, node):
+        """Parse an `ELEMENT_NODE`.  This calls specific
+        `do_<tagName>` handers for different elements.  If no handler
+        is available the `generic_parse` method is called.  All
+        tagNames specified in `self.ignores` are simply ignored.
+        
+        """
+        name = node.tagName
+        ignores = self.ignores
+        if name in ignores:
+            return
+        attr = "do_%s" % name
+        if hasattr(self, attr):
+            handlerMethod = getattr(self, attr)
+            handlerMethod(node)
+        else:
+            self.generic_parse(node)
+            #if name not in self.generics: self.generics.append(name)
+
+    def add_text(self, value):
+        """Adds text corresponding to `value` into `self.pieces`."""
+        if type(value) in (types.ListType, types.TupleType):
+            self.pieces.extend(value)
+        else:
+            self.pieces.append(value)
+
+    def get_specific_nodes(self, node, names):
+        """Given a node and a sequence of strings in `names`, return a
+        dictionary containing the names as keys and child
+        `ELEMENT_NODEs`, that have a `tagName` equal to the name.
+
+        """
+        nodes = [(x.tagName, x) for x in node.childNodes \
+                 if x.nodeType == x.ELEMENT_NODE and \
+                 x.tagName in names]
+        return dict(nodes)
+
+    def generic_parse(self, node, pad=0):
+        """A Generic parser for arbitrary tags in a node.
+
+        Parameters:
+
+         - node:  A node in the DOM.
+         - pad: `int` (default: 0)
+
+           If 0 the node data is not padded with newlines.  If 1 it
+           appends a newline after parsing the childNodes.  If 2 it
+           pads before and after the nodes are processed.  Defaults to
+           0.
+
+        """
+        npiece = 0
+        if pad:
+            npiece = len(self.pieces)
+            if pad == 2:
+                self.add_text('\n')                
+        for n in node.childNodes:
+            self.parse(n)
+        if pad:
+            if len(self.pieces) > npiece:
+                self.add_text('\n')
+
+    def space_parse(self, node):
+        self.add_text(' ')
+        self.generic_parse(node)
+
+    do_ref = space_parse
+    do_emphasis = space_parse
+    do_bold = space_parse
+    do_computeroutput = space_parse
+    do_formula = space_parse
+
+    def do_compoundname(self, node):
+        self.add_text('\n\n')
+        data = node.firstChild.data
+        self.add_text('%%feature("docstring") %s "\n'%data)
+
+    def do_compounddef(self, node):
+        kind = node.attributes['kind'].value
+        if kind in ('class', 'struct'):
+            prot = node.attributes['prot'].value
+            if prot <> 'public':
+                return
+            names = ('compoundname', 'briefdescription',
+                     'detaileddescription', 'includes')
+            first = self.get_specific_nodes(node, names)
+            for n in names:
+                if first.has_key(n):
+                    self.parse(first[n])
+            self.add_text(['";','\n'])
+            for n in node.childNodes:
+                if n not in first.values():
+                    self.parse(n)
+        elif kind in ('file', 'namespace'):
+            nodes = node.getElementsByTagName('sectiondef')
+            for n in nodes:
+                self.parse(n)
+
+    def do_includes(self, node):
+        self.add_text('C++ includes: ')
+        self.generic_parse(node, pad=1)
+
+    def do_parameterlist(self, node):
+        self.add_text(['\n', '\n', 'Parameters:', '\n'])
+        self.generic_parse(node, pad=1)
+
+    def do_para(self, node):
+        self.add_text('\n')
+        self.generic_parse(node, pad=1)
+
+    def do_parametername(self, node):
+        self.add_text('\n')
+        self.add_text("%s: "%node.firstChild.data)
+
+    def do_parameterdefinition(self, node):
+        self.generic_parse(node, pad=1)
+
+    def do_detaileddescription(self, node):
+        self.generic_parse(node, pad=1)
+
+    def do_briefdescription(self, node):
+        self.generic_parse(node, pad=1)
+
+    def do_memberdef(self, node):
+        prot = node.attributes['prot'].value
+        id = node.attributes['id'].value
+        kind = node.attributes['kind'].value
+        tmp = node.parentNode.parentNode.parentNode
+        compdef = tmp.getElementsByTagName('compounddef')[0]
+        cdef_kind = compdef.attributes['kind'].value
+        
+        if prot == 'public':
+            first = self.get_specific_nodes(node, ('definition', 'name'))
+            name = first['name'].firstChild.data
+            if name[:8] == 'operator': # Don't handle operators yet.
+                return
+
+            defn = first['definition'].firstChild.data
+            self.add_text('\n')
+            self.add_text('%feature("docstring") ')
+            
+            anc = node.parentNode.parentNode
+            if cdef_kind in ('file', 'namespace'):
+                ns_node = anc.getElementsByTagName('innernamespace')
+                if not ns_node and cdef_kind == 'namespace':
+                    ns_node = anc.getElementsByTagName('compoundname')
+                if ns_node:
+                    ns = ns_node[0].firstChild.data
+                    self.add_text(' %s::%s "\n%s'%(ns, name, defn))
+                else:
+                    self.add_text(' %s "\n%s'%(name, defn))
+            elif cdef_kind in ('class', 'struct'):
+                # Get the full function name.
+                anc_node = anc.getElementsByTagName('compoundname')
+                cname = anc_node[0].firstChild.data
+                self.add_text(' %s::%s "\n%s'%(cname, name, defn))
+
+            for n in node.childNodes:
+                if n not in first.values():
+                    self.parse(n)
+            self.add_text(['";', '\n'])
+        
+    def do_definition(self, node):
+        data = node.firstChild.data
+        self.add_text('%s "\n%s'%(data, data))
+
+    def do_sectiondef(self, node):
+        kind = node.attributes['kind'].value
+        if kind in ('public-func', 'func'):
+            self.generic_parse(node)
+
+    def do_simplesect(self, node):
+        kind = node.attributes['kind'].value
+        if kind in ('date', 'rcs', 'version'):
+            pass
+        elif kind == 'warning':
+            self.add_text(['\n', 'WARNING: '])
+            self.generic_parse(node)
+        elif kind == 'see':
+            self.add_text('\n')
+            self.add_text('See: ')
+            self.generic_parse(node)
+        else:
+            self.generic_parse(node)
+
+    def do_argsstring(self, node):
+        self.generic_parse(node, pad=1)
+
+    def do_member(self, node):
+        kind = node.attributes['kind'].value
+        refid = node.attributes['refid'].value
+        if kind == 'function' and refid[:9] == 'namespace':
+            self.generic_parse(node)
+
+    def do_doxygenindex(self, node):
+        self.multi = 1
+        comps = node.getElementsByTagName('compound')
+        for c in comps:
+            refid = c.attributes['refid'].value
+            fname = refid + '.xml'
+            if not os.path.exists(fname):
+                fname = os.path.join(self.my_dir,  fname)
+            print "parsing file: %s"%fname
+            p = Doxy2SWIG(fname)
+            p.generate()
+            self.pieces.extend(self.clean_pieces(p.pieces))
+
+    def write(self, fname):
+        o = my_open_write(fname)
+        if self.multi:
+            o.write("".join(self.pieces))
+        else:
+            o.write("".join(self.clean_pieces(self.pieces)))
+        o.close()
+
+    def clean_pieces(self, pieces):
+        """Cleans the list of strings given as `pieces`.  It replaces
+        multiple newlines by a maximum of 2 and returns a new list.
+        It also wraps the paragraphs nicely.
+        
+        """
+        ret = []
+        count = 0
+        for i in pieces:
+            if i == '\n':
+                count = count + 1
+            else:
+                if i == '";':
+                    if count:
+                        ret.append('\n')
+                elif count > 2:
+                    ret.append('\n\n')
+                elif count:
+                    ret.append('\n'*count)
+                count = 0
+                ret.append(i)
+
+        _data = "".join(ret)
+        ret = []
+        for i in _data.split('\n\n'):
+            if i == 'Parameters:':
+                ret.extend(['Parameters:\n-----------', '\n\n'])
+            elif i.find('// File:') > -1: # leave comments alone.
+                ret.extend([i, '\n'])
+            else:
+                _tmp = textwrap.fill(i.strip())
+                _tmp = self.lead_spc.sub(r'\1"\2', _tmp)
+                ret.extend([_tmp, '\n\n'])
+        return ret
+
+
+def main(input, output):
+    p = Doxy2SWIG(input)
+    p.generate()
+    p.write(output)
+
+
+if __name__ == '__main__':
+    if len(sys.argv) != 3:
+        print __doc__
+        sys.exit(1)
+    main(sys.argv[1], sys.argv[2])
diff --git a/gnuradio-core/doc/xml/swig.xsl b/gnuradio-core/doc/xml/swig.xsl
new file mode 100644 (file)
index 0000000..6163c2d
--- /dev/null
@@ -0,0 +1,38 @@
+<!-- XSLT script to extract document for class/function for swig docstring
+     If you have xsltproc you could use:
+     xsltproc swig.xsl index.xml > swig_doc.i
+-->
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
+  <xsl:output method="text"/>
+   <xsl:template match="/">
+      <!-- process each compound -->
+      <xsl:for-each select="doxygenindex/compound">
+        <xsl:apply-templates select="document( concat( @refid, '.xml' ) )/*" />
+      </xsl:for-each>
+   </xsl:template>
+
+  <xsl:template match="doxygen">
+    <xsl:for-each select="compounddef[@kind='class']">  
+      <xsl:text>%feature(__QuOtE__docstring__QuOtE__) </xsl:text>
+      <xsl:value-of select="compoundname"/>
+      <xsl:text> __QuOtE__ &#10;</xsl:text>
+      <xsl:value-of select="briefdescription"/><xsl:text>
+      </xsl:text>
+      <xsl:value-of select="detaileddescription"/>
+      <xsl:text> see also: </xsl:text>
+      <xsl:value-of select="includes"/>
+      <xsl:text>__QuOtE__;&#10;&#10;</xsl:text>
+
+      <!-- output for each function individually -->
+      <xsl:for-each select="*/memberdef[@kind='function' and not(starts-with(name,'operator'))]"> 
+        <xsl:text>%feature(__QuOtE__docstring__QuOtE__) </xsl:text><xsl:value-of select="../../compoundname"/>::<xsl:value-of select="name"/>
+        <xsl:text> __QuOtE__&#10;</xsl:text>
+        <xsl:value-of select="definition"/> <xsl:value-of select="argsstring"/>
+        <xsl:text>
+        </xsl:text><xsl:value-of select="briefdescription"/><xsl:text>
+        </xsl:text><xsl:value-of select="detaileddescription"/>
+        <xsl:text>__QuOtE__; &#10;&#10;</xsl:text>
+      </xsl:for-each>
+    </xsl:for-each>  
+  </xsl:template>
+</xsl:stylesheet>
diff --git a/gnuradio-core/gnuradio-core.conf b/gnuradio-core/gnuradio-core.conf
new file mode 100644 (file)
index 0000000..d64f584
--- /dev/null
@@ -0,0 +1,19 @@
+# This file contains system wide configuration data for GNU Radio.
+# You may override any setting on a per-user basis by editing
+# ~/.gnuradio/config.conf
+
+[DEFAULT]
+
+verbose = False
+
+
+[audio]
+
+# specify which audio module to load, or use "auto" to have the system
+# select one.  Valid choices depend on your OS and which modules
+# you've installed, but typically include: auto, audio_alsa,
+# audio_oss, audio_portaudio, audio_jack, audio_osx, audio_windows
+
+audio_module = auto
+
+
diff --git a/gnuradio-core/gnuradio-core.pc.in b/gnuradio-core/gnuradio-core.pc.in
new file mode 100644 (file)
index 0000000..cc6c03a
--- /dev/null
@@ -0,0 +1,11 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@/gnuradio
+
+Name: gnuradio-core
+Description: GNU Software Radio toolkit
+Requires:
+Version: @VERSION@
+Libs: -L${libdir} -lgnuradio-core @FFTW3F_LIBS@
+Cflags: -I${includedir} @DEFINES@ @PTHREAD_CFLAGS@
diff --git a/gnuradio-core/src/Makefile.am b/gnuradio-core/src/Makefile.am
new file mode 100644 (file)
index 0000000..8d00cca
--- /dev/null
@@ -0,0 +1,26 @@
+#
+# Copyright 2001,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.
+# 
+
+include $(top_srcdir)/Makefile.common
+
+SUBDIRS = gen_interpolator_taps lib tests python
+
+DIST_SUBDIRS = gen_interpolator_taps lib tests python utils
diff --git a/gnuradio-core/src/gen_interpolator_taps/Makefile.am b/gnuradio-core/src/gen_interpolator_taps/Makefile.am
new file mode 100644 (file)
index 0000000..fff6372
--- /dev/null
@@ -0,0 +1,33 @@
+#
+# 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 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.
+# 
+
+include $(top_srcdir)/Makefile.common
+
+EXTRA_DIST                     = praxis.txt simpson.h
+
+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/gen_interpolator_taps/README b/gnuradio-core/src/gen_interpolator_taps/README
new file mode 100644 (file)
index 0000000..cc2f1ac
--- /dev/null
@@ -0,0 +1,47 @@
+#
+# 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 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 file contains the source for gen_interpolator_taps, a program
+which generates optimal interpolator taps for a fractional
+interpolator.  
+
+The ideal interpolator requires an infinite tap FIR filter to
+realize.  We design a separate 8 tap filter for each value of mu,
+the fractional delay, that we are interested in.  The taps are
+selected such that the mean squared error between the ideal frequency
+response and the approximation is mininimized over all frequencies of
+interest.  In this implementation we define ``frequencies of
+interest'' as those from -B to +B, where B = 1/(4*Ts), where Ts is the
+sampling period.
+
+For a detailed look at what this is all about, please see Chapter 9 of
+"Digital Communication Receivers: Synchronization, Channel Estimation
+and Signal Processing" by Meyr, Moeneclaey and Fechtel, ISBN 0-471-50275-8
+
+NOTE, if you're running gen_interpolator_taps and it seg faults in
+RANDOM, you're probably using g77-2.96.  The fix is to use g77 3.0 or later
+
+       cd <top_of_build_tree>
+       rm config.cache
+       export F77=g77-3.0.4
+       ./configure
+       make
diff --git a/gnuradio-core/src/gen_interpolator_taps/gen_interpolator_taps.c b/gnuradio-core/src/gen_interpolator_taps/gen_interpolator_taps.c
new file mode 100644 (file)
index 0000000..0dd0565
--- /dev/null
@@ -0,0 +1,186 @@
+/* -*- 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 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.
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+
+#define        NSTEPS           10     // how many steps of mu are in the generated table
+#define        MAX_NSTEPS      256
+#define        NTAPS             8     // # of taps in the interpolator
+#define        MAX_NTAPS       128
+
+extern void initpt (double x[], int ntaps);
+extern double objective (double x[], int *ntaps);
+extern double global_mu;
+extern double global_B;
+
+// fortran
+extern double prax2_ (double (fct)(double x[], int *ntaps),
+                     double initv[], int *ntaps, double result[]);
+
+static void 
+usage (char *name)
+{
+  fprintf (stderr, "usage: %s [-v] [-n <nsteps>] [-t <ntaps>] [-B <bw>]\n", name);
+  exit (1);
+}
+
+static void
+printline (double x[], int ntaps, int imu, int nsteps)
+{
+  int  i;
+  
+  printf ("  { ");
+  for (i = 0; i < ntaps; i++){
+    printf ("%12.5e", x[i]);
+    if (i != ntaps - 1)
+      printf (", ");
+    else
+      printf (" }, // %3d/%d\n", imu, nsteps);
+  }
+}
+
+int 
+main (int argc, char **argv)
+{
+  double       xx[MAX_NSTEPS+1][MAX_NTAPS];
+  int          ntaps = NTAPS;
+  int          nsteps = NSTEPS;
+  int          i, j;
+  double       result;
+  double       step_size;
+  int          c;
+  int          verbose = 0;
+
+  global_B = 0.25;
+
+  while ((c = getopt (argc, argv, "n:t:B:v")) != EOF){
+    switch (c){
+    case 'n':
+      nsteps = strtol (optarg, 0, 0);
+      break;
+
+    case 't':
+      ntaps = strtol (optarg, 0, 0);
+      break;
+
+    case 'B':
+      global_B = strtod (optarg, 0);
+      break;
+      
+    case 'v':
+      verbose = 1;
+      break;
+      
+    default:
+      usage (argv[0]);
+      break;
+    }
+  }
+
+  if ((nsteps & 1) != 0){
+    fprintf (stderr, "%s: nsteps must be even\n", argv[0]);
+    exit (1);
+  }
+
+  if (nsteps > MAX_NSTEPS){
+    fprintf (stderr, "%s: nsteps must be < %d\n", argv[0], MAX_NSTEPS);
+    exit (1);
+  }
+    
+  if ((ntaps & 1) != 0){
+    fprintf (stderr, "%s: ntaps must be even\n", argv[0]);
+    exit (1);
+  }
+
+  if (nsteps > MAX_NTAPS){
+    fprintf (stderr, "%s: ntaps must be < %d\n", argv[0], MAX_NTAPS);
+    exit (1);
+  }
+
+  if (global_B < 0 || global_B > 0.5){
+    fprintf (stderr, "%s: bandwidth must be in the range (0, 0.5)\n", argv[0]);
+    exit (1);
+  }
+    
+  step_size = 1.0/nsteps;
+  
+  // the optimizer chokes on the two easy cases (0/N and N/N).  We do them by hand...
+
+  for (i = 0; i < ntaps; i++)
+    xx[0][i] = 0.0;
+  xx[0][ntaps/2] = 1.0;
+
+
+  // compute optimal values for mu <= 0.5
+
+  for (j = 1; j <= nsteps/2; j++){
+
+    global_mu = j * step_size;         // this determines the MU for which we're computing the taps
+
+    // initialize X to a reasonable starting value
+
+    initpt (&xx[j][0], ntaps);
+
+    // find the value of X that minimizes the value of OBJECTIVE
+
+    result = prax2_ (objective, &xx[j][0], &ntaps, &xx[j][0]);
+
+    if (verbose){
+      fprintf (stderr, "Mu: %10.8f\t", global_mu);
+      fprintf (stderr, "Objective: %g\n", result);
+    }
+  }
+
+  // now compute remaining values via symmetry
+
+  for (j = 0; j < nsteps/2; j++){
+    for (i = 0; i < ntaps; i++){
+      xx[nsteps - j][i] = xx[j][ntaps-i-1];
+    }
+  }
+
+  // now print out the table
+
+  printf ("\
+/*\n\
+ * This file was machine generated by gen_interpolator_taps.\n\
+ * DO NOT EDIT BY HAND.\n\
+ */\n\n");
+
+
+  printf ("static const int    NTAPS     = %4d;\n", ntaps);
+  printf ("static const int    NSTEPS    = %4d;\n", nsteps);
+  printf ("static const double BANDWIDTH = %g;\n\n", global_B);
+  
+  printf ("static const float taps[NSTEPS+1][NTAPS] = {\n");
+  printf ("  //    -4            -3            -2            -1             0             1             2             3                mu\n");
+
+
+  for (i = 0; i <= nsteps; i++)
+    printline (xx[i], ntaps, i, nsteps);
+  
+  printf ("};\n\n");
+
+  return 0;
+}
diff --git a/gnuradio-core/src/gen_interpolator_taps/objective_fct.c b/gnuradio-core/src/gen_interpolator_taps/objective_fct.c
new file mode 100644 (file)
index 0000000..aab0008
--- /dev/null
@@ -0,0 +1,124 @@
+/* -*- 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 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.
+ */
+
+/*
+ * generate MMSE FIR interpolation table values
+ */
+
+#include <math.h>
+#include <assert.h>
+#include "simpson.h"
+
+#define        MU      0.5                     /* the MU for which we're computing coeffs */
+
+#define        Ts      (1.0)                   /* sampling period              */
+#define        B       (1.0/(4*Ts))            /* one-sided signal bandwidth   */
+//#define      B       (1.0/(8./3*Ts))         /* one-sided signal bandwidth   */
+
+static unsigned global_n;
+static double  *global_h;
+double         global_mu = MU;
+double         global_B  = B;
+
+/*
+ * This function computes the difference squared between the ideal
+ * interpolator frequency response at frequency OMEGA and the
+ * approximation defined by the FIR coefficients in global_h[]
+ *
+ * See eqn (9-7), "Digital Communication Receivers", Meyr, Moeneclaey
+ * and Fechtel, Wiley, 1998.
+ */
+
+static double 
+integrand (double omega)
+{
+  double real_ideal;
+  double real_approx;
+  double real_diff;
+  double imag_ideal;
+  double imag_approx;
+  double imag_diff;
+
+  int   i, n;
+  int   I1;
+  double *h;
+
+  real_ideal = cos (omega * Ts * global_mu);
+  imag_ideal = sin (omega * Ts * global_mu);
+
+  n = global_n;
+  h = global_h;
+  I1 = -(n / 2);
+
+  real_approx = 0;
+  imag_approx = 0;
+
+  for (i = 0; i < n; i++){
+    real_approx += h[i] * cos (-omega * Ts * (i + I1));
+    imag_approx += h[i] * sin (-omega * Ts * (i + I1));
+  }
+
+  real_diff = real_ideal - real_approx;
+  imag_diff = imag_ideal - imag_approx;
+
+  return real_diff * real_diff + imag_diff * imag_diff;
+}
+
+/*
+ * Integrate the difference squared over all frequencies of interest.
+ */
+double
+c_fcn (double *x, int n)
+{
+  assert ((n & 1) == 0);       /* assert n is even */
+  global_n = n;
+  global_h = x;
+  return qsimp (integrand, -2 * M_PI * global_B, 2 * M_PI * global_B);
+}
+
+/* this is the interface expected by the calling fortran code */
+
+double
+objective (double x[], int *ndim)
+{
+  return c_fcn (x, *ndim);
+}
+
+static double 
+si (double x)
+{
+  if (fabs (x) < 1e-9)
+    return 1.0;
+
+  return sin(x) / x;
+}
+
+/*
+ * starting guess for optimization
+ */
+void initpt (double x[], int ndim)
+{
+  int i;
+  for (i = 0; i < ndim; i++){
+    x[i] = si (M_PI * ((double) (i - ndim/2) + global_mu));
+  }
+}
diff --git a/gnuradio-core/src/gen_interpolator_taps/praxis.f b/gnuradio-core/src/gen_interpolator_taps/praxis.f
new file mode 100644 (file)
index 0000000..1b648b9
--- /dev/null
@@ -0,0 +1,1705 @@
+C
+C Copyright 2002 Free Software Foundation, Inc.
+C
+C This file is part of GNU Radio
+C
+C GNU Radio is free software; you can redistribute it and/or modify
+C it under the terms of the GNU General Public License as published by
+C the Free Software Foundation; either version 2, or (at your option)
+C any later version.
+C
+C GNU Radio is distributed in the hope that it will be useful,
+C but WITHOUT ANY WARRANTY; without even the implied warranty of
+C MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+C GNU General Public License for more details.
+C
+C You should have received a copy of the GNU General Public License
+C along with GNU Radio; see the file COPYING.  If not, write to
+C the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+C Boston, MA 02111-1307, USA.
+C
+      DOUBLE PRECISION FUNCTION PRAX2(F,INITV,NDIM,OUT)
+      DOUBLE PRECISION INITV(128),OUT(128), F
+      INTEGER NDIM
+      EXTERNAL F
+C
+      DOUBLE PRECISION V,X,D,Q0,Q1,DMIN,EPSMCH,FX,H,QD0,QD1,QF1,
+     *   SMALL,T,XLDT,XM2,XM4,DSEED,SCBD
+C
+      COMMON /CPRAX/ V(128,128),X(128),D(128),Q0(128),Q1(128),
+     *   DMIN,EPSMCH,FX,H,QD0,QD1,QF1,SMALL,T,XLDT,XM2,XM4,DSEED,SCBD,
+     *   N,NL,NF,LP,JPRINT,NMAX,ILLCIN,KTM,NFMAX,JRANCH
+
+C
+      N=NDIM
+      do 10 I=1,N
+ 10      X(I) = INITV(I)
+
+C
+      call praset
+
+C -1 produces no diagnostic output
+      jprint = -1
+      nfmax = 3000
+C tighter tolerance
+      T=1.0D-6
+C
+      call praxis(f)
+C
+      do 30 I=1,N
+ 30      OUT(I) = X(I)
+C
+      prax2 = fx
+      return
+      end
+
+
+      SUBROUTINE PRASET
+C
+C  PRASET 1.0           JUNE 1995
+C
+C  SET INITIAL VALUES FOR SOME QUANTITIES USED IN SUBROUTINE PRAXIS.
+C  THE USER CAN RESET THESE, IF DESIRED,
+C  AFTER CALLING PRASET AND BEFORE CALLING PRAXIS.
+C
+C  J. P. CHANDLER, COMPUTER SCIENCE DEPARTMENT,
+C     OKLAHOMA STATE UNIVERSITY
+C
+C  ON MANY MACHINES, SUBROUTINE PRAXIS WILL CAUSE UNDERFLOW AND/OR
+C  DIVIDE CHECK WHEN COMPUTING EPSMCH**4 AND EPSMCH**(-4).
+C  IN THAT CASE, SET EPSMCH=1.0D-9 (OR POSSIBLY EPSMCH=1.0D-8)
+C  AFTER CALLING SUBROUTINE PRASET.
+C
+      INTEGER N,NL,NF,LP,JPRINT,NMAX,ILLCIN,KTM,NFMAX,JRANCH
+      INTEGER J
+C
+      DOUBLE PRECISION V,X,D,Q0,Q1,DMIN,EPSMCH,FX,H,QD0,QD1,QF1,
+     *   SMALL,T,XLDT,XM2,XM4,DSEED,SCBD
+      DOUBLE PRECISION A,B,XMID,XPLUS,RZERO,UNITR,RTWO
+C
+      COMMON /CPRAX/ V(128,128),X(128),D(128),Q0(128),Q1(128),
+     *   DMIN,EPSMCH,FX,H,QD0,QD1,QF1,SMALL,T,XLDT,XM2,XM4,DSEED,SCBD,
+     *   N,NL,NF,LP,JPRINT,NMAX,ILLCIN,KTM,NFMAX,JRANCH
+C
+      RZERO=0.0D0
+      UNITR=1.0D0
+      RTWO=2.0D0
+C
+C  NMAX IS THE DIMENSION OF THE ARRAYS V(*,*), X(*), D(*),
+C  Q0(*), AND Q1(*).
+C
+      NMAX=128
+C
+C  NFMAX IS THE MAXIMUM NUMBER OF FUNCTION EVALUATIONS PERMITTED.
+C
+      NFMAX=100000
+C
+C  LP IS THE LOGICAL UNIT NUMBER FOR PRINTED OUTPUT.
+C
+      LP=6
+C
+C  T IS A CONVERGENCE TOLERANCE USED IN SUBROUTINE PRAXIS.
+C
+      T=1.0D-5
+C
+C  JPRINT CONTROLS PRINTED OUTPUT IN PRAXIS.
+C
+      JPRINT=4
+C
+C  H IS AN ESTIMATE OF THE DISTANCE FROM THE INITIAL POINT
+C  TO THE SOLUTION.
+C
+      H=1.0D0
+C
+C  USE BISECTION TO COMPUTE THE VALUE OF EPSMCH, "MACHINE EPSILON".
+C  EPSMCH IS THE SMALLEST FLOATING POINT (REAL OR DOUBLE PRECISION)
+C  NUMBER WHICH, WHEN ADDED TO ONE, GIVES A RESULT GREATER THAN ONE.
+C
+      A=RZERO
+      B=UNITR
+   10 XMID=A+(B-A)/RTWO
+      IF(XMID.LE.A .OR. XMID.GE.B) GO TO 20
+      XPLUS=UNITR+XMID
+      IF(XPLUS.GT.UNITR) THEN
+         B=XMID
+      ELSE
+         A=XMID
+      ENDIF
+      GO TO 10
+C
+   20 EPSMCH=B
+C
+      DO 30 J=1,NMAX
+         X(J)=RZERO
+   30 CONTINUE
+C
+C  JRANCH = 1 TO USE BRENT'S RANDOM,
+C  JRANCH = 2 TO USE FUNCTION DRANDM.
+C
+      JRANCH=1
+C
+      CALL RANINI(4.0D0)
+C
+C  DSEED IS AN INITIAL SEED FOR DRANDM,
+C  A SUBROUTINE THAT GENERATES PSEUDORANDOM NUMBERS
+C  UNIFORMLY DISTRIBUTED ON (0,1).
+C
+      DSEED=1234567.0D0
+C
+C  SCBD IS AN UPPER BOUND ON THE SCALE FACTORS IN PRAXIS.
+C  IF THE AXES MAY BE BADLY SCALED (WHICH IS TO BE AVOIDED IF
+C  POSSIBLE) THEN SET SCBD = 10, OTHERWISE 1.
+C
+      SCBD=1.0D0
+C
+C  ILLCIN IS THE INITIAL VALUE OF ILLC,
+C  THE FLAG THAT SIGNALS AN ILL-CONDITIONED PROBLEM.
+C  IF THE PROBLEM IS KNOWN TO BE ILL-CONDITIONED SET ILLCIN=1,
+C  OTHERWISE 0.
+C
+      ILLCIN=0
+C
+C  KTM IS A CONVERGENCE SWITCH USED IN PRAXIS.
+C  KTM+1 IS THE NUMBER OF ITERATIONS WITHOUT IMPROVEMENT
+C  BEFORE THE ALGORITHM TERMINATES.
+C  KTM=4 IS VERY CAUTIOUS.
+C  USUALLY KTM=1 IS SATISFACTORY.
+C
+      KTM=1
+C
+      RETURN
+C
+C  END PRASET
+C
+      END
+      SUBROUTINE PRAXIS(F)
+C
+C  PRAXIS 2.0        JUNE 1995
+C
+C  THE PRAXIS PACKAGE MINIMIZES THE FUNCTION F(X,N) OF N
+C  VARIABLES X(1),...,X(N), USING THE PRINCIPAL AXIS METHOD.
+C  F MUST BE A SMOOTH (CONTINUOUSLY DIFFERENTIABLE) FUNCTION.
+C
+C  "ALGORITHMS FOR MINIMIZATION WITHOUT DERIVATIVES",
+C     RICHARD P. BRENT, PRENTICE-HALL 1973 (ISBN 0-13-022335-2),
+C     PAGES 156-167
+C
+C  TRANSLATED FROM ALGOL W TO A.N.S.I. 1966 STANDARD BASIC FORTRAN
+C     BY ROSALEE TAYLOR AND SUE PINSKI, COMPUTER SCIENCE DEPARTMENT,
+C     OKLAHOMA STATE UNIVERSITY (DECEMBER 1973).
+C
+C  UPDATED TO A.N.S.I. STANDARD FORTRAN 77 BY J. P. CHANDLER
+C     COMPUTER SCIENCE DEPARTMENT, OKLAHOMA STATE UNIVERSITY
+C
+C
+C  SUBROUTINE PRAXIS CALLS SUBPROGRAMS
+C     F, MINX, RANDOM (OR DRANDM), QUAD, MINFIT, SORT.
+C
+C  SUBROUTINE QUAD CALLS MINX.
+C
+C  SUBROUTINE MINX CALLS FLIN.
+C
+C  SUBROUTINE FLIN CALLS F.
+C
+C
+C  INPUT QUANTITIES (SET IN THE CALLING PROGRAM)...
+C
+C     F        FUNCTION F(X,N) TO BE MINIMIZED
+C
+C     X(*)     INITIAL GUESS OF MINIMUM
+C
+C     N        DIMENSION OF X  (NOTE...  N MUST BE .GE. 2)
+C
+C     H        MAXIMUM STEP SIZE
+C
+C     T        TOLERANCE
+C
+C     EPSMCH   MACHINE PRECISION
+C
+C     JPRINT   PRINT SWITCH
+C
+C
+C  OUTPUT QUANTITIES...
+C
+C     X(*)     ESTIMATED POINT OF MINIMUM
+C
+C     FX       VALUE OF F AT X
+C
+C     NL       NUMBER OF LINEAR SEARCHES
+C
+C     NF       NUMBER OF FUNCTION EVALUATIONS
+C
+C     V(*,*)   EIGENVECTORS OF A
+C                 NEW DIRECTIONS
+C
+C     D(*)     EIGENVALUES OF A
+C                 NEW D
+C
+C     Z(*)     SCALE FACTORS
+C
+C
+C  ON ENTRY X(*) HOLDS A GUESS.  ON RETURN IT HOLDS THE ESTIMATED
+C  POINT OF MINIMUM, WITH (HOPEFULLY)
+C  ABS(ERROR) LESS THAN SQRT(EPSMCH)*ABS(X) + T, WHERE
+C  EPSMCH IS THE MACHINE PRECISION, THE SMALLEST NUMBER SUCH THAT
+C  (1 + EPSMCH) IS GREATER THAN 1.
+C
+C  T IS A TOLERANCE.
+C
+C  H IS THE MAXIMUM STEP SIZE, SET TO ABOUT THE MAXIMUM EXPECTED
+C  DISTANCE FROM THE GUESS TO THE MINIMUM.  IF H IS SET TOO
+C  SMALL OR TOO LARGE THEN THE INITIAL RATE OF CONVERGENCE WILL
+C  BE SLOW.
+C
+C  THE USER SHOULD OBSERVE THE COMMENT ON HEURISTIC NUMBERS
+C  AT THE BEGINNING OF THE SUBROUTINE.
+C
+C  JPRINT CONTROLS THE PRINTING OF INTERMEDIATE RESULTS.
+C  IT USES SUBROUTINES FLIN, MINX, QUAD, SORT, AND MINFIT.
+C  IF JPRINT = 1, F IS PRINTED AFTER EVERY N+1 OR N+2 LINEAR
+C  MINIMIZATIONS, AND FINAL X IS PRINTED, BUT INTERMEDIATE
+C  X ONLY IF N IS LESS THAN OR EQUAL TO 4.
+C  IF JPRINT = 2, EIGENVALUES OF A AND SCALE FACTORS ARE ALSO PRINTED.
+C  IF JPRINT = 3, F AND X ARE PRINTED AFTER EVERY FEW LINEAR
+C  MINIMIZATIONS.
+C  IF JPRINT = 4, EIGENVECTORS ARE ALSO PRINTED.
+C  IF JPRINT = 5, ADDITIONAL DEBUGGING INFORMATION IS ALSO PRINTED.
+C
+C  RANDOM RETURNS A RANDOM NUMBER UNIFORMLY DISTRIBUTED IN (0, 1).
+C
+C  THIS SUBROUTINE IS MACHINE-INDEPENDENT, APART FROM THE
+C  SPECIFICATION OF EPSMCH.  WE ASSUME THAT EPSMCH**(-4) DOES NOT
+C  OVERFLOW (IF IT DOES THEN EPSMCH MUST BE INCREASED), AND THAT ON
+C  FLOATING-POINT UNDERFLOW THE RESULT IS SET TO ZERO.
+C
+      INTEGER N,NL,NF,LP,JPRINT,NMAX,ILLCIN,KTM,NFMAX,JRANCH
+      INTEGER ILLC,I,IK,IM,IMU,J,K,KL,KM1,KT,K2
+C
+      DOUBLE PRECISION V,X,D,Q0,Q1,DMIN,EPSMCH,FX,H,QD0,QD1,QF1,
+     *   SMALL,T,XLDT,XM2,XM4,DSEED,SCBD
+      DOUBLE PRECISION F,   Y,Z,E,   DABS,DSQRT,ZABS,ZSQRT,DRANDM,
+     *   HUNDRD,HUNDTH,ONE,PT9,RHALF,TEN,TENTH,TWO,ZERO,
+     *   DF,DLDFAC,DN,F1,XF,XL,T2,RANVAL,ARG,
+     *   VLARGE,VSMALL,XLARGE,XLDS,FXVALU,F1VALU,S,SF,SL
+C
+      EXTERNAL F
+C
+      DIMENSION Y(128),Z(128),E(128)
+C
+      COMMON /CPRAX/ V(128,128),X(128),D(128),Q0(128),Q1(128),
+     *   DMIN,EPSMCH,FX,H,QD0,QD1,QF1,SMALL,T,XLDT,XM2,XM4,DSEED,SCBD,
+     *   N,NL,NF,LP,JPRINT,NMAX,ILLCIN,KTM,NFMAX,JRANCH
+C
+      ZABS(ARG)=DABS(ARG)
+      ZSQRT(ARG)=DSQRT(ARG)
+C
+C  INITIALIZATION...
+C
+      RHALF=0.5D0
+      ONE=1.0D0
+      TENTH=0.1D0
+      HUNDTH=0.01D0
+      HUNDRD=100.0D0
+      ZERO=0.0D0
+      PT9=0.9D0
+      TEN=10.0D0
+      TWO=2.0D0
+C
+C  MACHINE DEPENDENT NUMBERS...
+C
+C  ON MANY COMPUTERS, VSMALL WILL UNDERFLOW,
+C  AND COMPUTING XLARGE MAY CAUSE A DIVISION BY ZERO.
+C  IN THAT CASE, EPSMCH SHOULD BE SET EQUAL TO 1.0D-9
+C  (OR POSSIBLY 1.0D-8) BEFORE CALLING PRAXIS.
+C
+      SMALL=EPSMCH*EPSMCH
+      VSMALL=SMALL*SMALL
+      XLARGE=ONE/SMALL
+      VLARGE=ONE/VSMALL
+      XM2=ZSQRT(EPSMCH)
+      XM4=ZSQRT(XM2)
+C
+C  HEURISTIC NUMBERS...
+C
+C  IF THE AXES MAY BE BADLY SCALED (WHICH IS TO BE AVOIDED IF
+C  POSSIBLE) THEN SET SCBD = 10, OTHERWISE 1.
+C
+C  IF THE PROBLEM IS KNOWN TO BE ILL-CONDITIONED SET ILLC = 1,
+C  OTHERWISE 0.
+C
+C  KTM+1 IS THE NUMBER OF ITERATIONS WITHOUT IMPROVEMENT
+C  BEFORE THE ALGORITHM TERMINATES.
+C  KTM=4 IS VERY CAUTIOUS.
+C  USUALLY KTM=1 IS SATISFACTORY.
+C
+C  BRENT RECOMMENDED THE FOLLOWING VALUES FOR MOST PROBLEMS...
+C
+C                    SCBD=1.0
+C                    ILLC=0
+C                    KTM=1
+C
+C  SCBD, ILLCIN, AND KTM ARE NOW IN COMMON.
+C  THEY ARE INITIALIZED IN SUBROUTINE PRASET,
+C  AND CAN BE RESET BY THE USER AFTER CALLING PRASET.
+C
+      ILLC=ILLCIN
+C
+      IF(ILLC.EQ.1) THEN
+         DLDFAC=TENTH
+      ELSE
+         DLDFAC=HUNDTH
+      ENDIF
+C
+      KT=0
+      NL=0
+      NF=1
+      FX=F(X,N)
+      QF1=FX
+      T=SMALL+ZABS(T)
+      T2=T
+      DMIN=SMALL
+      IF(H.LT.HUNDRD*T) H=HUNDRD*T
+      XLDT=H
+C
+      DO 20 I=1,N
+         DO 10 J=1,N
+            V(I,J)=ZERO
+   10    CONTINUE
+         V(I,I)=ONE
+   20 CONTINUE
+C
+      QD0=ZERO
+      D(1)=ZERO
+C
+C  Q0(*) AND Q1(*) ARE PREVIOUS X(*) POINTS,
+C  INITIALIZED IN PRAXIS, USED IN FLIN,
+C  AND CHANGED IN QUAD.
+C
+      DO 30 I=1,N
+         Q1(I)=X(I)
+C
+C  Q0(*) WAS NOT INITIALIZED IN BRENT'S ALGOL PROCEDURE.
+C
+         Q0(I)=X(I)
+   30 CONTINUE
+C
+      IF(JPRINT.GT.0) THEN
+         WRITE(LP,40)NL,NF,FX
+   40    FORMAT(/' NL =',I10,5X,'NF =',I10/5X,'FX =',1PG15.7)
+C
+         IF(N.LE.4 .OR. JPRINT.GT.2) THEN
+            WRITE(LP,50)(X(I),I=1,N)
+   50       FORMAT(/8X,'X'/(1X,1PG15.7,4G15.7))
+         ENDIF
+      ENDIF
+C
+C  MAIN LOOP...
+C  LABEL L0...
+C
+   60 SF=D(1)
+      S=ZERO
+      D(1)=ZERO
+C
+C  MINIMIZE ALONG THE FIRST DIRECTION.
+C
+      IF(JPRINT.GE.5) WRITE(LP,70)D(1),S,FX
+   70 FORMAT(/' CALL NO. 1 TO MINX.'/
+     *   5X,'D(1) =',1PG15.7,5X,'S =',G15.7,5X,'FX =',G15.7)
+C
+      FXVALU=FX
+      CALL MINX(1,2,D(1),S,FXVALU,0,F)
+C
+      IF(S.LE.ZERO) THEN
+         DO 80 I=1,N
+            V(I,1)=-V(I,1)
+   80    CONTINUE
+      ENDIF
+C
+      IF(SF.LE.PT9*D(1) .OR. PT9*SF.GE.D(1)) THEN
+C
+         IF(N.GE.2) THEN
+            DO 90 I=2,N
+               D(I)=ZERO
+   90       CONTINUE
+         ENDIF
+C
+      ENDIF
+C
+      IF(N.LT.2) GO TO 320
+      DO 310 K=2,N
+C
+         DO 100 I=1,N
+            Y(I)=X(I)
+  100    CONTINUE
+C
+         SF=FX
+         IF(KT.GT.0) ILLC=1
+C
+C  LABEL L1...
+C
+  110    KL=K
+         DF=ZERO
+C
+         IF(ILLC.EQ.1) THEN
+C
+C  TAKE A RANDOM STEP TO GET OUT OF A RESOLUTION VALLEY.
+C
+C  PRAXIS ASSUMES THAT RANDOM (OR DRANDM) RETURNS
+C  A PSEUDORANDOM NUMBER UNIFORMLY DISTRIBUTED IN (0,1),
+C  AND THAT ANY INITIALIZATION OF THE RANDOM NUMBER GENERATOR
+C  HAS ALREADY BEEN DONE.
+C
+            DO 130 I=1,N
+C
+               IF(JRANCH.EQ.1) THEN
+                  CALL RANDOM(RANVAL)
+               ELSE
+                  RANVAL=DRANDM(DSEED)
+               ENDIF
+C
+               S=(TENTH*XLDT+T2*TEN**KT)*(RANVAL-RHALF)
+               Z(I)=S
+C
+               DO 120 J=1,N
+                  X(J)=X(J)+S*V(J,I)
+  120          CONTINUE
+  130       CONTINUE
+C
+            FX=F(X,N)
+            NF=NF+1
+C
+            IF(JPRINT.GE.1) WRITE(LP,140)NF,SF,FX
+  140       FORMAT(/' *****  RANDOM STEP IN PRAXIS.   NF =',I11/
+     *         5X,'SF =',1PG15.7,5X,'FX =',G15.7)
+         ENDIF
+C
+         IF(K.GT.N) GO TO 170
+         DO 160 K2=K,N
+            SL=FX
+            S=ZERO
+C
+C  MINIMIZE ALONG NON-CONJUGATE DIRECTIONS.
+C
+            IF(JPRINT.GE.5) WRITE(LP,150)K2,D(K2),S,FX
+  150       FORMAT(/' CALL NO. 2 TO MINX.'/
+     *         5X,'K2 =',I4,5X,'D(K2) =',1PG15.7,5X,
+     *         'S =',G15.7/5X,'FX =',G15.7)
+C
+            FXVALU=FX
+            CALL MINX(K2,2,D(K2),S,FXVALU,0,F)
+C
+            IF(ILLC.EQ.1) THEN
+               S=D(K2)*(S+Z(K2))**2
+            ELSE
+               S=SL-FX
+            ENDIF
+C
+            IF(DF.LT.S) THEN
+               DF=S
+               KL=K2
+            ENDIF
+  160    CONTINUE
+C
+  170    IF(ILLC.EQ.0 .AND. DF.LT.ZABS(HUNDRD*EPSMCH*FX)) THEN
+C
+C  NO SUCCESS WITH ILLC=0, SO TRY ONCE WITH ILLC=1 .
+C
+            ILLC=1
+C
+C  GO TO L1.
+C
+            GO TO 110
+         ENDIF
+C
+         IF(K.EQ.2 .AND. JPRINT.GT.1) THEN
+            WRITE(LP,180)(D(I),I=1,N)
+  180       FORMAT(/' NEW D'/(1X,1PG15.7,4G15.7))
+         ENDIF
+C
+         KM1=K-1
+         IF(KM1.LT.1) GO TO 210
+         DO 200 K2=1,KM1
+C
+C  MINIMIZE ALONG CONJUGATE DIRECTIONS.
+C
+            IF(JPRINT.GE.5) WRITE(LP,190)K2,D(K2),S,FX
+  190       FORMAT(/' CALL NO. 3 TO MINX.'/
+     *         5X,'K2 =',I4,5X,'D(K2) =',1PG15.7,5X,
+     *         'S =',G15.7/5X,'FX =',G15.7)
+C
+            S=ZERO
+            FXVALU=FX
+            CALL MINX(K2,2,D(K2),S,FXVALU,0,F)
+  200    CONTINUE
+C
+  210    F1=FX
+         FX=SF
+C
+         XLDS=ZERO
+         DO 220 I=1,N
+            SL=X(I)
+            X(I)=Y(I)
+            SL=SL-Y(I)
+            Y(I)=SL
+            XLDS=XLDS+SL*SL
+  220    CONTINUE
+C
+         XLDS=ZSQRT(XLDS)
+         IF(XLDS.GT.SMALL) THEN
+C
+C  THROW AWAY THE DIRECTION KL AND MINIMIZE ALONG
+C  THE NEW CONJUGATE DIRECTION.
+C
+            IK=KL-1
+            IF(K.GT.IK) GO TO 250
+            DO 240 IM=K,IK
+               I=IK-IM+K
+C
+               DO 230 J=1,N
+                  V(J,I+1)=V(J,I)
+  230          CONTINUE
+C
+               D(I+1)=D(I)
+  240       CONTINUE
+C
+  250       D(K)=ZERO
+C
+            DO 260 I=1,N
+               V(I,K)=Y(I)/XLDS
+  260       CONTINUE
+C
+            IF(JPRINT.GE.5) WRITE(LP,270)K,D(K),XLDS,F1
+  270       FORMAT(/' CALL NO. 4 TO MINX.'/
+     *         5X,'K =',I4,5X,'D(K) =',1PG15.7,5X,
+     *         'XLDS =',G15.7/5X,'F1 =',G15.7)
+C
+            F1VALU=F1
+            CALL MINX(K,4,D(K),XLDS,F1VALU,1,F)
+C
+            IF(XLDS.LE.ZERO) THEN
+               XLDS=-XLDS
+C
+               DO 280 I=1,N
+                  V(I,K)=-V(I,K)
+  280          CONTINUE
+            ENDIF
+         ENDIF
+C
+         XLDT=DLDFAC*XLDT
+         IF(XLDT.LT.XLDS) XLDT=XLDS
+C
+         IF(JPRINT.GT.0) THEN
+            WRITE(LP,40)NL,NF,FX
+            IF(N.LE.4 .OR. JPRINT.GT.2) THEN
+               WRITE(LP,50)(X(I),I=1,N)
+            ENDIF
+         ENDIF
+C
+         T2=ZERO
+         DO 290 I=1,N
+            T2=T2+X(I)**2
+  290    CONTINUE
+         T2=XM2*ZSQRT(T2)+T
+C
+C  SEE IF THE STEP LENGTH EXCEEDS HALF THE TOLERANCE.
+C
+         IF(XLDT.GT.RHALF*T2) THEN
+            KT=0
+         ELSE
+            KT=KT+1
+         ENDIF
+C
+C  IF(...) GO TO L2
+C
+         IF(KT.GT.KTM) GO TO 550
+C
+         IF(NF.GE.NFMAX) THEN
+            WRITE(LP,300)NFMAX
+  300       FORMAT(/' IN PRAXIS, NF REACHED THE LIMIT NFMAX =',I11/
+     *         5X,'THIS IS AN ABNORMAL TERMINATION.'/
+     *         5X,'THE FUNCTION HAS NOT BEEN MINIMIZED AND',
+     *         ' THE RESULTING X(*) VECTOR SHOULD NOT BE USED.')
+            GO TO 550
+         ENDIF
+C
+  310 CONTINUE
+C
+C  TRY QUADRATIC EXTRAPOLATION IN CASE WE ARE STUCK IN A CURVED VALLEY.
+C
+  320 CALL QUAD(F)
+C
+      DN=ZERO
+      DO 330 I=1,N
+         D(I)=ONE/ZSQRT(D(I))
+         IF(DN.LT.D(I)) DN=D(I)
+  330 CONTINUE
+C
+      IF(JPRINT.GT.3) THEN
+C
+         WRITE(LP,340)
+  340    FORMAT(/' NEW DIRECTIONS')
+C
+         DO 360 I=1,N
+            WRITE(LP,350)I,(V(I,J),J=1,N)
+  350       FORMAT(1X,I5,4X,1PG15.7,4G15.7/(10X,5G15.7))
+  360    CONTINUE
+      ENDIF
+C
+      DO 380 J=1,N
+C
+         S=D(J)/DN
+         DO 370 I=1,N
+            V(I,J)=S*V(I,J)
+  370    CONTINUE
+  380 CONTINUE
+C
+      IF(SCBD.GT.ONE) THEN
+C
+C  SCALE THE AXES TO TRY TO REDUCE THE CONDITION NUMBER.
+C
+         S=VLARGE
+         DO 400 I=1,N
+C
+            SL=ZERO
+            DO 390 J=1,N
+               SL=SL+V(I,J)**2
+  390       CONTINUE
+C
+            Z(I)=ZSQRT(SL)
+            IF(Z(I).LT.XM4) Z(I)=XM4
+            IF(S.GT.Z(I)) S=Z(I)
+  400    CONTINUE
+C
+         DO 410 I=1,N
+            SL=S/Z(I)
+            Z(I)=ONE/SL
+C
+            IF(Z(I).GT.SCBD) THEN
+               SL=ONE/SCBD
+               Z(I)=SCBD
+            ENDIF
+C
+C  IT APPEARS THAT THERE ARE TWO MISSING END; STATEMENTS
+C  AT THIS POINT IN BRENT'S LISTING.
+C
+  410    CONTINUE
+      ENDIF
+C
+C  TRANSPOSE V FOR MINFIT.
+C
+      IF(N.LT.2) GO TO 440
+      DO 430 I=2,N
+C
+         IMU=I-1
+         DO 420 J=1,IMU
+            S=V(I,J)
+            V(I,J)=V(J,I)
+            V(J,I)=S
+  420    CONTINUE
+  430 CONTINUE
+C
+C  FIND THE SINGULAR VALUE DECOMPOSITION OF V.
+C  THIS GIVES THE EIGENVALUES AND PRINCIPAL AXES
+C  OF THE APPROXIMATING QUADRATIC FORM
+C  WITHOUT SQUARING THE CONDITION NUMBER.
+C
+  440 CALL MINFIT(N,EPSMCH,VSMALL,V,D,E,NMAX,LP)
+C
+      IF(SCBD.GT.ONE) THEN
+C
+C  UNSCALING...
+C
+         DO 460 I=1,N
+C
+            S=Z(I)
+            DO 450 J=1,N
+               V(I,J)=S*V(I,J)
+  450       CONTINUE
+  460    CONTINUE
+C
+         DO 490 I=1,N
+C
+            S=ZERO
+            DO 470 J=1,N
+               S=S+V(J,I)**2
+  470       CONTINUE
+            S=ZSQRT(S)
+C
+            D(I)=S*D(I)
+C
+            S=ONE/S
+            DO 480 J=1,N
+               V(J,I)=S*V(J,I)
+  480       CONTINUE
+  490    CONTINUE
+      ENDIF
+C
+      DO 500 I=1,N
+C
+         IF(DN*D(I).GT.XLARGE) THEN
+            D(I)=VSMALL
+         ELSE IF(DN*D(I).LT.SMALL) THEN
+            D(I)=VLARGE
+         ELSE
+            D(I)=ONE/(DN*D(I))**2
+         ENDIF
+  500 CONTINUE
+C
+C  SORT THE NEW EIGENVALUES AND EIGENVECTORS.
+C
+      CALL SORT
+C
+      DMIN=D(N)
+      IF(DMIN.LT.SMALL) DMIN=SMALL
+C
+      IF(XM2*D(1).GT.DMIN) THEN
+         ILLC=1
+      ELSE
+         ILLC=0
+      ENDIF
+C
+      IF(JPRINT.GT.1 .AND. SCBD.GT.ONE) THEN
+         WRITE(LP,510)(Z(I),I=1,N)
+  510    FORMAT(/' SCALE FACTORS'/(1X,1PG15.7,4G15.7))
+      ENDIF
+C
+      IF(JPRINT.GT.1) THEN
+         WRITE(LP,520)(D(I),I=1,N)
+  520    FORMAT(/' EIGENVALUES OF A'/(1X,1PG15.7,4G15.7))
+      ENDIF
+C
+      IF(JPRINT.GT.3) THEN
+C
+         WRITE(LP,530)
+  530    FORMAT(/' EIGENVECTORS OF A')
+C
+         DO 540 I=1,N
+            WRITE(LP,350)I,(V(I,J),J=1,N)
+  540    CONTINUE
+      ENDIF
+C
+C  GO BACK TO THE MAIN LOOP.
+C  GO TO L0
+C
+C  HANDLE THE CASE N .EQ. 1 IN AN AD HOC WAY.
+C  (BRENT DID NOT PROVIDE FOR THIS CASE.)
+C
+      IF(N.GE.2) GO TO 60
+C
+C  LABEL L2...
+C
+  550 IF(JPRINT.GT.0) THEN
+         WRITE(LP,560)(X(I),I=1,N)
+  560    FORMAT(//7X,'X'/(1X,1PG15.7,4G15.7))
+      ENDIF
+C
+      FX=F(X,N)
+C
+      IF(JPRINT.GE.0) WRITE(LP,570)FX,NL,NF
+  570 FORMAT(/' EXIT PRAXIS.   FX =',1PG25.17,5X,'NL =',I8,
+     *   5X,'NF =',I9)
+C
+      RETURN
+C
+C  END PRAXIS
+C
+      END
+      SUBROUTINE QUAD(F)
+C
+C  THIS SUBROUTINE LOOKS FOR THE MINIMUM ALONG
+C  A CURVE DEFINED BY Q0, Q1, AND X.
+C
+C  "ALGORITHMS FOR MINIMIZATION WITHOUT DERIVATIVES",
+C  RICHARD P. BRENT, PRENTICE-HALL 1973, PAGE 161
+C
+C  SUBROUTINE QUAD IS CALLED BY SUBROUTINE PRAXIS.
+C
+      INTEGER N,NL,NF,LP,JPRINT,NMAX,ILLCIN,KTM,NFMAX,JRANCH
+      INTEGER I
+C
+      DOUBLE PRECISION V,X,D,Q0,Q1,DMIN,EPSMCH,FX,H,QD0,QD1,QF1,
+     *   SMALL,T,XLDT,XM2,XM4,DSEED,SCBD
+      DOUBLE PRECISION F,   DSQRT,ZSQRT,ARG,
+     *   ONE,QA,QB,QC,S,TWO,XL,ZERO,QF1VAL
+C
+      EXTERNAL F
+C
+      COMMON /CPRAX/ V(128,128),X(128),D(128),Q0(128),Q1(128),
+     *   DMIN,EPSMCH,FX,H,QD0,QD1,QF1,SMALL,T,XLDT,XM2,XM4,DSEED,SCBD,
+     *   N,NL,NF,LP,JPRINT,NMAX,ILLCIN,KTM,NFMAX,JRANCH
+C
+      ZSQRT(ARG)=DSQRT(ARG)
+C
+      ZERO=0.0D0
+      ONE=1.0D0
+C
+      S=FX
+      FX=QF1
+      QF1=S
+      QD1=ZERO
+C
+      DO 10 I=1,N
+         S=X(I)
+         XL=Q1(I)
+         X(I)=XL
+         Q1(I)=S
+         QD1=QD1+(S-XL)**2
+   10 CONTINUE
+C
+      QD1=ZSQRT(QD1)
+      XL=QD1
+      S=ZERO
+C
+      IF(QD0.GT.ZERO .AND. QD1.GT.ZERO .AND. NL.GE.3*N*N) THEN
+C
+         IF(JPRINT.GE.1) WRITE(LP,20)NF,QD0,QD1,FX,QF1
+   20    FORMAT(/' *****  CALL MINX FROM QUAD.   NF =',I11/
+     *      5X,'QD0 =',1PG15.7,5X,'QD1 =',G15.7/
+     *      5X,'FX  =',G15.7,5X,'QF1 =',G15.7)
+C
+         QF1VAL=QF1
+         CALL MINX(0,2,S,XL,QF1VAL,1,F)
+         QA=XL*(XL-QD1)/(QD0*(QD0+QD1))
+         QB=(XL+QD0)*(QD1-XL)/(QD0*QD1)
+         QC=XL*(XL+QD0)/(QD1*(QD0+QD1))
+      ELSE
+         FX=QF1
+         QA=ZERO
+         QB=ZERO
+         QC=ONE
+      ENDIF
+C
+      QD0=QD1
+C
+      DO 30 I=1,N
+         S=Q0(I)
+         Q0(I)=X(I)
+         X(I)=QA*S+QB*X(I)+QC*Q1(I)
+   30 CONTINUE
+C
+      RETURN
+C
+C  END QUAD
+C
+      END
+      SUBROUTINE MINX(J,NITS,D2,X1,F1,IFK,F)
+C
+C  SUBROUTINE MINX MINIMIZES F FROM X IN THE DIRECTION V(*,J)
+C  UNLESS J IS LESS THAN 1, WHEN A QUADRATIC SEARCH IS DONE IN
+C  THE PLANE DEFINED BY Q0, Q1, AND X.
+C
+C  "ALGORITHMS FOR MINIMIZATION WITHOUT DERIVATIVES",
+C  RICHARD P. BRENT, PRENTICE-HALL 1973, PAGES 159-160
+C
+C  SUBROUTINE MINX IS CALLED BY SUBROUTINES PRAXIS AND QUAD.
+C
+C  D2 AND X1 RETURN RESULTS.
+C  J, NITS, F1 AND IFK ARE VALUE PARAMETERS THAT RETURN NOTHING.
+C  DO NOT SEND A COMMON VARIABLE TO MINX FOR PARAMETER F1.
+C
+C
+C  D2 IS AN APPROXIMATION TO HALF OF
+C  THE SECOND DERIVATIVE OF F (OR ZERO).
+C
+C  X1 IS AN ESTIMATE OF DISTANCE TO MINIMUM,
+C  RETURNED AS THE DISTANCE FOUND.
+C
+C  IF IFK = 1 THEN F1 IS FLIN(X1), OTHERWISE X1 AND F1 ARE
+C  IGNORED ON ENTRY UNLESS FINAL FX IS GREATER THAN F1.
+C
+C  NITS CONTROLS THE NUMBER OF TIMES AN ATTEMPT IS MADE TO
+C  HALVE THE INTERVAL.
+C
+      EXTERNAL F
+C
+      INTEGER N,NL,NF,LP,JPRINT,NMAX,ILLCIN,KTM,NFMAX,JRANCH
+      INTEGER IFK,J,NITS,     I,IDZ,K
+C
+      DOUBLE PRECISION V,X,D,Q0,Q1,DMIN,EPSMCH,FX,H,QD0,QD1,QF1,
+     *   SMALL,T,XLDT,XM2,XM4,DSEED,SCBD
+      DOUBLE PRECISION D2,X1,
+     *   DABS,DSQRT,ZABS,ZSQRT,ARG,
+     *   HUNDTH,RHALF,TWO,ZERO,
+     *   DENOM,D1,FM,F0,F1,F2,S,SF1,SX1,T2,XM,X2
+C
+      COMMON /CPRAX/ V(128,128),X(128),D(128),Q0(128),Q1(128),
+     *   DMIN,EPSMCH,FX,H,QD0,QD1,QF1,SMALL,T,XLDT,XM2,XM4,DSEED,SCBD,
+     *   N,NL,NF,LP,JPRINT,NMAX,ILLCIN,KTM,NFMAX,JRANCH
+C
+      ZSQRT(ARG)=DSQRT(ARG)
+      ZABS(ARG)=DABS(ARG)
+C
+      HUNDTH=0.01D0
+      ZERO=0.0D0
+      TWO=2.0D0
+      RHALF=0.5D0
+C
+      SF1=F1
+      SX1=X1
+      K=0
+      XM=ZERO
+      FM=FX
+      F0=FX
+C
+      IF(D2.LT.EPSMCH) THEN
+         IDZ=1
+      ELSE
+         IDZ=0
+      ENDIF
+C
+C  FIND THE STEP SIZE.
+C
+      S=ZERO
+      DO 10 I=1,N
+         S=S+X(I)**2
+   10 CONTINUE
+      S=ZSQRT(S)
+C
+      IF(IDZ.EQ.1) THEN
+         DENOM=DMIN
+      ELSE
+         DENOM=D2
+      ENDIF
+C
+      T2=XM4*ZSQRT(ZABS(FX)/DENOM+S*XLDT)+XM2*XLDT
+      S=XM4*S+T
+      IF(IDZ.EQ.1 .AND. T2.GT.S) T2=S
+      IF(T2.LT.SMALL) T2=SMALL
+      IF(T2.GT.HUNDTH*H) T2=HUNDTH*H
+C
+      IF(IFK.EQ.1 .AND. F1.LE.FM) THEN
+         XM=X1
+         FM=F1
+      ENDIF
+C
+      IF(IFK.EQ.0 .OR. ZABS(X1).LT.T2) THEN
+C
+         IF(X1.GE.ZERO) THEN
+            X1=T2
+         ELSE
+            X1=-T2
+         ENDIF
+C
+         CALL FLIN(X1,J,F,F1)
+      ENDIF
+C
+      IF(F1.LT.FM) THEN
+         XM=X1
+         FM=F1
+      ENDIF
+C
+C  LABEL L0...
+C
+   20 IF(IDZ.EQ.1) THEN
+C
+C  EVALUATE FLIN AT ANOTHER POINT,
+C  AND ESTIMATE THE SECOND DERIVATIVE.
+C
+         IF(F0.LT.F1) THEN
+            X2=-X1
+         ELSE
+            X2=TWO*X1
+         ENDIF
+C
+         CALL FLIN(X2,J,F,F2)
+C
+         IF(F2.LE.FM) THEN
+            XM=X2
+            FM=F2
+         ENDIF
+C
+         D2=(X2*(F1-F0)-X1*(F2-F0))/(X1*X2*(X1-X2))
+C
+         IF(JPRINT.GE.5) WRITE(LP,30)X1,X2,F0,F1,F2,D2
+   30    FORMAT(/' COMPUTE D2 IN SUBROUTINE MINX.'/
+     *      5X,'X1 =',1PG15.7,5X,'X2 =',G15.7/
+     *      5X,'F0 =',G15.7,5X,'F1 =',G15.7,5X,'F2 =',G15.7/
+     *      5X,'D2 =',G15.7)
+      ENDIF
+C
+C  ESTIMATE THE FIRST DERIVATIVE AT 0.
+C
+      D1=(F1-F0)/X1-X1*D2
+      IDZ=1
+C
+C  PREDICT THE MINIMUM.
+C
+      IF(D2.LE.SMALL) THEN
+C
+         IF(D1.LT.ZERO) THEN
+            X2=H
+         ELSE
+            X2=-H
+         ENDIF
+C
+      ELSE
+         X2=-RHALF*D1/D2
+      ENDIF
+C
+      IF(ZABS(X2).GT.H) THEN
+C
+         IF(X2.GT.ZERO) THEN
+            X2=H
+         ELSE
+            X2=-H
+         ENDIF
+      ENDIF
+C
+C  EVALUATE F AT THE PREDICTED MINIMUM.
+C  LABEL L1...
+C
+   40 CALL FLIN(X2,J,F,F2)
+C
+      IF(K.LT.NITS .AND. F2.GT.F0) THEN
+C
+C  NO SUCCESS, SO TRY AGAIN.
+C
+         K=K+1
+C
+C  IF(...) GO TO L0
+C
+         IF(F0.LT.F1 .AND. X1*X2.GT.ZERO) GO TO 20
+         X2=X2/TWO
+C
+C  GO TO L1
+C
+         GO TO 40
+C
+      ENDIF
+C
+C  INCREMENT THE ONE-DIMENSIONAL SEARCH COUNTER.
+C
+      NL=NL+1
+C
+      IF(F2.GT.FM) THEN
+         X2=XM
+      ELSE
+         FM=F2
+      ENDIF
+C
+C  GET A NEW ESTIMATE OF THE SECOND DERIVATIVE.
+C
+      IF(ZABS(X2*(X2-X1)).GT.SMALL) THEN
+         D2=(X2*(F1-F0)-X1*(FM-F0))/(X1*X2*(X1-X2))
+C
+         IF(JPRINT.GE.5) WRITE(LP,50)X1,X2,F0,FM,F1,D2
+   50    FORMAT(/' RECOMPUTE D2 IN SUBROUTINE MINX.'/
+     *      5X,'X1 =',1PG15.7,5X,'X2 =',G15.7/
+     *      5X,'F0 =',G15.7,5X,'FM =',G15.7,5X,'F1 =',G15.7/
+     *      5X,'D2 =',G15.7)
+C
+      ELSE IF(K.GT.0) THEN
+         D2=ZERO
+C
+         IF(JPRINT.GE.5) WRITE(LP,60)
+   60    FORMAT(/' SET D2=0 IN SUBROUTINE MINX.')
+      ELSE
+         D2=D2
+      ENDIF
+C
+      IF(D2.LE.SMALL) THEN
+         D2=SMALL
+C
+         IF(JPRINT.GE.5) WRITE(LP,70)D2
+   70    FORMAT(/' SET D2=SMALL=',1PG15.7,' IN SUBROUTINE MINX.')
+      ENDIF
+C
+      IF(JPRINT.GE.5) WRITE(LP,80)X1,X2,FX,FM,SF1
+   80 FORMAT(/' SUBROUTINE MINX.   X1 =',1PG15.7,5X,'X2 =',G15.7/
+     *   5X,'FX =',G15.7,5X,'FM =',G15.7,5X,'SF1 =',G15.7)
+C
+      X1=X2
+      FX=FM
+      IF(SF1.LT.FX) THEN
+         FX=SF1
+         X1=SX1
+      ENDIF
+C
+C  UPDATE X FOR A LINEAR SEARCH BUT NOT FOR A PARABOLIC SEARCH.
+C
+      IF(J.GT.0) THEN
+C
+         DO 90 I=1,N
+            X(I)=X(I)+X1*V(I,J)
+   90    CONTINUE
+      ENDIF
+C
+      IF(JPRINT.GE.5) WRITE(LP,100)D2,X1,F1,FX
+  100 FORMAT(/' LEAVE SUBROUTINE MINX.'/
+     *   5X,'D2 =',1PG15.7,5X,'X1 =',G15.7,5X,'F1 =',G15.7/
+     *   5X,'FX =',G15.7)
+C
+      RETURN
+C
+C  END MINX
+C
+      END
+      SUBROUTINE FLIN(XL,J,F,FLN)
+C
+C  FLIN IS A FUNCTION OF ONE VARIABLE XL WHICH IS MINIMIZED BY
+C  SUBROUTINE MINX.
+C
+C  "ALGORITHMS FOR MINIMIZATION WITHOUT DERIVATIVES",
+C  RICHARD P. BRENT, PRENTICE-HALL 1973, PAGES 159-160
+C
+C  SUBROUTINE FLIN IS CALLED BY SUBROUTINE MINX.
+C
+      INTEGER N,NL,NF,LP,JPRINT,NMAX,ILLCIN,KTM,NFMAX,JRANCH
+      INTEGER J,   I
+C
+      DOUBLE PRECISION V,X,D,Q0,Q1,DMIN,EPSMCH,FX,H,QD0,QD1,QF1,
+     *   SMALL,T,XLDT,XM2,XM4,DSEED,SCBD
+      DOUBLE PRECISION XL,F,FLN,   TT,   QA,QB,QC
+C
+      DIMENSION TT(128)
+C
+      COMMON /CPRAX/ V(128,128),X(128),D(128),Q0(128),Q1(128),
+     *   DMIN,EPSMCH,FX,H,QD0,QD1,QF1,SMALL,T,XLDT,XM2,XM4,DSEED,SCBD,
+     *   N,NL,NF,LP,JPRINT,NMAX,ILLCIN,KTM,NFMAX,JRANCH
+C
+      IF(J.GT.0) THEN
+C
+C  LINEAR SEARCH...
+C
+         DO 10 I=1,N
+            TT(I)=X(I)+XL*V(I,J)
+   10    CONTINUE
+C
+      ELSE
+C
+C  SEARCH ALONG A PARABOLIC SPACE CURVE.
+C
+         QA=XL*(XL-QD1)/(QD0*(QD0+QD1))
+         QB=(XL+QD0)*(QD1-XL)/(QD0*QD1)
+         QC=XL*(XL+QD0)/(QD1*(QD0+QD1))
+C
+         DO 20 I=1,N
+            TT(I)=QA*Q0(I)+QB*X(I)+QC*Q1(I)
+   20    CONTINUE
+      ENDIF
+C
+C  INCREMENT FUNCTION EVALUATION COUNTER.
+C
+      NF=NF+1
+      FLN=F(TT,N)
+C
+      RETURN
+C
+C  END FLIN
+C
+      END
+      SUBROUTINE MINFIT(N,EPS,TOL,AB,Q,E,NMAX,LP)
+C
+C  AN IMPROVED VERSION OF MINFIT, RESTRICTED TO M=N, P=0.
+C  SEE GOLUB AND REINSCH (1970).
+C
+C  "ALGORITHMS FOR MINIMIZATION WITHOUT DERIVATIVES",
+C  RICHARD P. BRENT, PRENTICE-HALL 1973, PAGES 156-158
+C
+C  G. H. GOLUB AND C. REINSCH,
+C  "SINGULAR VALUE DECOMPOSITION AND LEAST SQUARES SOLUTIONS',
+C  NUMERISCHE MATHEMATIK 14 (1970) PAGES 403-420
+C
+C  THE SINGULAR VALUES OF THE ARRAY AB ARE RETURNED IN Q,
+C  AND AB IS OVERWRITTEN WITH THE ORTHOGONAL MATRIX V SUCH THAT
+C  U.DIAG(Q)=AB.V, WHERE U IS ANOTHER ORTHOGONAL MATRIX.
+C
+C  SUBROUTINE MINFIT IS CALLED BY SUBROUTINE PRAXIS.
+C
+      INTEGER N,NMAX,LP,
+     *   I,II,J,JTHIRT,K,KK,KT,L,LL2,LPI,L2
+C
+      DOUBLE PRECISION EPS,TOL,AB,Q,E,
+     *   DABS,DSQRT,ZABS,ZSQRT,ARG,
+     *   C,DENOM,F,G,H,ONE,X,Y,Z,ZERO,S,TWO
+C
+      DIMENSION AB(NMAX,N),Q(N),E(N)
+C
+      ZABS(ARG)=DABS(ARG)
+      ZSQRT(ARG)=DSQRT(ARG)
+C
+      JTHIRT=30
+C
+      ZERO=0.0D0
+      ONE=1.0D0
+      TWO=2.0D0
+C
+C  HOUSEHOLDER'S REDUCTION TO BIDIAGONAL FORM...
+C
+      X=ZERO
+      G=ZERO
+C
+      DO 140 I=1,N
+         E(I)=G
+         S=ZERO
+         L=I+1
+C
+         DO 10 J=I,N
+            S=S+AB(J,I)**2
+   10    CONTINUE
+C
+         IF(S.LT.TOL) THEN
+            G=ZERO
+         ELSE
+            F=AB(I,I)
+C
+            IF(F.LT.ZERO) THEN
+               G=ZSQRT(S)
+            ELSE
+               G=-ZSQRT(S)
+            ENDIF
+C
+            H=F*G-S
+            AB(I,I)=F-G
+C
+            IF(L.GT.N) GO TO 60
+            DO 50 J=L,N
+C
+               F=ZERO
+               IF(I.GT.N) GO TO 30
+               DO 20 K=I,N
+                  F=F+AB(K,I)*AB(K,J)
+   20          CONTINUE
+   30          F=F/H
+C
+               IF(I.GT.N) GO TO 50
+               DO 40 K=I,N
+                  AB(K,J)=AB(K,J)+F*AB(K,I)
+   40          CONTINUE
+   50       CONTINUE
+         ENDIF
+C
+   60    Q(I)=G
+         S=ZERO
+C
+         IF(I.LE.N) THEN
+C
+            IF(L.GT.N) GO TO 80
+            DO 70 J=L,N
+               S=S+AB(I,J)**2
+   70       CONTINUE
+         ENDIF
+C
+   80    IF(S.LT.TOL) THEN
+            G=ZERO
+         ELSE
+            F=AB(I,I+1)
+C
+            IF(F.LT.ZERO) THEN
+               G=ZSQRT(S)
+            ELSE
+               G=-ZSQRT(S)
+            ENDIF
+C
+            H=F*G-S
+            AB(I,I+1)=F-G
+            IF(L.GT.N) GO TO 130
+            DO 90 J=L,N
+               E(J)=AB(I,J)/H
+   90       CONTINUE
+C
+            DO 120 J=L,N
+C
+               S=ZERO
+               DO 100 K=L,N
+                  S=S+AB(J,K)*AB(I,K)
+  100          CONTINUE
+C
+               DO 110 K=L,N
+                  AB(J,K)=AB(J,K)+S*E(K)
+  110          CONTINUE
+  120       CONTINUE
+         ENDIF
+C
+  130    Y=ZABS(Q(I))+ZABS(E(I))
+C
+         IF(Y.GT.X) X=Y
+  140 CONTINUE
+C
+C  ACCUMULATION OF RIGHT-HAND TRANSFORMATIONS...
+C
+      DO 210 II=1,N
+         I=N-II+1
+C
+         IF(G.NE.ZERO) THEN
+            H=AB(I,I+1)*G
+C
+            IF(L.GT.N) GO TO 200
+            DO 150 J=L,N
+               AB(J,I)=AB(I,J)/H
+  150       CONTINUE
+C
+            DO 180 J=L,N
+C
+               S=ZERO
+               DO 160 K=L,N
+                  S=S+AB(I,K)*AB(K,J)
+  160          CONTINUE
+C
+               DO 170 K=L,N
+                  AB(K,J)=AB(K,J)+S*AB(K,I)
+  170          CONTINUE
+  180       CONTINUE
+         ENDIF
+C
+         IF(L.GT.N) GO TO 200
+         DO 190 J=L,N
+            AB(J,I)=ZERO
+            AB(I,J)=ZERO
+  190    CONTINUE
+C
+  200    AB(I,I)=ONE
+         G=E(I)
+         L=I
+  210 CONTINUE
+C
+C  DIAGONALIZATION OF THE BIDIAGONAL FORM...
+C
+      EPS=EPS*X
+      DO 330 KK=1,N
+         K=N-KK+1
+         KT=0
+C
+C  LABEL TESTFSPLITTING...
+C
+  220    KT=KT+1
+C
+         IF(KT.GT.JTHIRT) THEN
+            E(K)=ZERO
+            WRITE(LP,230)
+  230       FORMAT(' QR FAILED.')
+         ENDIF
+C
+         DO 240 LL2=1,K
+            L2=K-LL2+1
+            L=L2
+C
+C  IF(...) GO TO TESTFCONVERGENCE
+C
+            IF(ZABS(E(L)).LE.EPS) GO TO 270
+C
+C  IF(...) GO TO CANCELLATION
+C
+            IF(ZABS(Q(L-1)).LE.EPS) GO TO 250
+  240    CONTINUE
+C
+C  CANCELLATION OF E(L) IF L IS GREATER THAN 1...
+C  LABEL CANCELLATION...
+C
+  250    C=ZERO
+         S=ONE
+         IF(L.GT.K) GO TO 270
+         DO 260 I=L,K
+            F=S*E(I)
+            E(I)=C*E(I)
+C
+C  IF(...) GO TO TESTFCONVERGENCE
+C
+            IF(ZABS(F).LE.EPS) GO TO 270
+            G=Q(I)
+C
+            IF(ZABS(F).LT.ZABS(G)) THEN
+               H=ZABS(G)*ZSQRT(ONE+(F/G)**2)
+            ELSE IF(F.NE.ZERO) THEN
+               H=ZABS(F)*ZSQRT(ONE+(G/F)**2)
+            ELSE
+               H=ZERO
+            ENDIF
+C
+            Q(I)=H
+C
+            IF(H.EQ.ZERO) THEN
+               H=ONE
+               G=ONE
+            ENDIF
+C
+C  THE ABOVE REPLACES Q(I) AND H BY SQUARE ROOT OF (G*G+F*F)
+C  WHICH MAY GIVE INCORRECT RESULTS IF THE SQUARES UNDERFLOW OR IF
+C  F = G = 0 .
+C
+            C=G/H
+            S=-F/H
+  260    CONTINUE
+C
+C  LABEL TESTFCONVERGENCE...
+C
+  270    Z=Q(K)
+C
+C  IF(...) GO TO CONVERGENCE
+C
+         IF(L.EQ.K) GO TO 310
+C
+C  SHIFT FROM BOTTOM 2*2 MINOR.
+C
+         X=Q(L)
+         Y=Q(K-1)
+         G=E(K-1)
+         H=E(K)
+         F=((Y-Z)*(Y+Z)+(G-H)*(G+H))/(TWO*H*Y)
+         G=ZSQRT(F*F+ONE)
+C
+         IF(F.LT.ZERO) THEN
+            DENOM=F-G
+         ELSE
+            DENOM=F+G
+         ENDIF
+C
+         F=((X-Z)*(X+Z)+H*(Y/DENOM-H))/X
+C
+C  NEXT QR TRANSFORMATION...
+C
+         S=ONE
+         C=ONE
+         LPI=L+1
+         IF(LPI.GT.K) GO TO 300
+         DO 290 I=LPI,K
+            G=E(I)
+            Y=Q(I)
+            H=S*G
+            G=G*C
+C
+            IF(ZABS(F).LT.ZABS(H)) THEN
+               Z=ZABS(H)*ZSQRT(ONE+(F/H)**2)
+            ELSE IF(F.NE.ZERO) THEN
+               Z=ZABS(F)*ZSQRT(ONE+(H/F)**2)
+            ELSE
+               Z=ZERO
+            ENDIF
+C
+            E(I-1)=Z
+C
+            IF(Z.EQ.ZERO) THEN
+               F=ONE
+               Z=ONE
+            ENDIF
+C
+            C=F/Z
+            S=H/Z
+            F=X*C+G*S
+            G=-X*S+G*C
+            H=Y*S
+            Y=Y*C
+C
+            DO 280 J=1,N
+               X=AB(J,I-1)
+               Z=AB(J,I)
+               AB(J,I-1)=X*C+Z*S
+               AB(J,I)=-X*S+Z*C
+  280       CONTINUE
+C
+            IF(ZABS(F).LT.ZABS(H)) THEN
+               Z=ZABS(H)*ZSQRT(ONE+(F/H)**2)
+            ELSE IF(F.NE.ZERO) THEN
+               Z=ZABS(F)*ZSQRT(ONE+(H/F)**2)
+            ELSE
+               Z=ZERO
+            ENDIF
+C
+            Q(I-1)=Z
+C
+            IF(Z.EQ.ZERO) THEN
+               F=ONE
+               Z=ONE
+            ENDIF
+C
+            C=F/Z
+            S=H/Z
+            F=C*G+S*Y
+            X=-S*G+C*Y
+  290    CONTINUE
+C
+  300    E(L)=ZERO
+         E(K)=F
+         Q(K)=X
+C
+C  GO TO TESTFSPLITTING
+C
+         GO TO 220
+C
+C  LABEL CONVERGENCE...
+C
+  310    IF(Z.LT.ZERO) THEN
+C
+C  Q(K) IS MADE NON-NEGATIVE.
+C
+            Q(K)=-Z
+            DO 320 J=1,N
+               AB(J,K)=-AB(J,K)
+  320       CONTINUE
+         ENDIF
+  330 CONTINUE
+C
+      RETURN
+C
+C  END MINFIT
+C
+      END
+      SUBROUTINE SORT
+C
+C  THIS SUBROUTINE SORTS THE ELEMENTS OF D
+C  AND THE CORRESPONDING COLUMNS OF V INTO DESCENDING ORDER.
+C
+C  "ALGORITHMS FOR MINIMIZATION WITHOUT DERIVATIVES",
+C  RICHARD P. BRENT, PRENTICE-HALL 1973, PAGES 158-159
+C
+      INTEGER N,NL,NF,LP,JPRINT,NMAX,ILLCIN,KTM,NFMAX,JRANCH
+      INTEGER I,IPI,J,K,NMI
+C
+      DOUBLE PRECISION V,X,D,Q0,Q1,DMIN,EPSMCH,FX,H,QD0,QD1,QF1,
+     *   SMALL,T,XLDT,XM2,XM4,DSEED,SCBD
+      DOUBLE PRECISION S
+C
+      COMMON /CPRAX/ V(128,128),X(128),D(128),Q0(128),Q1(128),
+     *   DMIN,EPSMCH,FX,H,QD0,QD1,QF1,SMALL,T,XLDT,XM2,XM4,DSEED,SCBD,
+     *   N,NL,NF,LP,JPRINT,NMAX,ILLCIN,KTM,NFMAX,JRANCH
+C
+      NMI=N-1
+      IF(NMI.LT.1) GO TO 50
+      DO 40 I=1,NMI
+         K=I
+         S=D(I)
+         IPI=I+1
+         IF(IPI.GT.N) GO TO 20
+C
+         DO 10 J=IPI,N
+C
+            IF(D(J).GT.S) THEN
+               K=J
+               S=D(J)
+            ENDIF
+   10    CONTINUE
+C
+   20    IF(K.GT.I) THEN
+            D(K)=D(I)
+            D(I)=S
+C
+            DO 30 J=1,N
+               S=V(J,I)
+               V(J,I)=V(J,K)
+               V(J,K)=S
+   30       CONTINUE
+         ENDIF
+   40 CONTINUE
+C
+   50 RETURN
+C
+C  END SORT
+C
+      END
+      SUBROUTINE RANINI(RVALUE)
+C
+C  SUBROUTINE RANINI PERFORMS INITIALIZATION FOR SUBROUTINE RANDOM.
+C
+C  "ALGORITHMS FOR MINIMIZATION WITHOUT DERIVATIVES",
+C  RICHARD P. BRENT, PRENTICE-HALL 1973, PAGES 163-164
+C
+      INTEGER JRAN2,I
+C
+      DOUBLE PRECISION RVALUE,R,RAN3,DMOD,DABS,RAN1
+C
+      COMMON /COMRAN/ RAN3(127),RAN1,JRAN2
+C
+      R=DMOD(DABS(RVALUE),8190.0D0)+1
+      JRAN2=127
+C
+   10 IF(JRAN2.GT.0) THEN
+         JRAN2=JRAN2-1
+         RAN1=-2.0D0**55
+C
+         DO 20 I=1,7
+            R=DMOD(1756.0D0*R,8191.0D0)
+            RAN1=(RAN1+(R-DMOD(R,32.0D0))/32.0D0)/256.0D0
+   20    CONTINUE
+C
+         RAN3(JRAN2+1)=RAN1
+         GO TO 10
+      ENDIF
+C
+      RETURN
+C
+C  END RANINI
+C
+      END
+      SUBROUTINE RANDOM(RANVAL)
+C
+C  SUBROUTINE RANDOM RETURNS A DOUBLE PRECISION PSEUDORANDOM NUMBER
+C  UNIFORMLY DISTRIBUTED IN (0,1) (INCLUDING 0 BUT NOT 1).
+C
+C  "ALGORITHMS FOR MINIMIZATION WITHOUT DERIVATIVES",
+C  RICHARD P. BRENT, PRENTICE-HALL 1973, PAGES 163-164
+C
+C  BEFORE THE FIRST CALL TO RANDOM, THE USER MUST
+C  CALL RANINI(R) ONCE (ONLY) WITH R A DOUBLE PRECISION NUMBER
+C  EQUAL TO ANY INTEGER VALUE.
+C  BRENT (PAGE 166) USED THE EQUIVALENT OF
+C     CALL RANINI(4.0D0) .
+C
+C  THE ALGORITHM USED IN SUBROUTINE RANDOM RETURNS X(N)/2**56,
+C  WHERE   X(N) = X(N-1) + X(N-127)  (MOD 2**56) .
+C  SINCE (1 + X + X**127) IS PRIMITIVE (MOD 2),
+C  THE PERIOD IS AT LEAST (2**127 - 1), WHICH EXCEEDS 10**38.
+C
+C  SEE "SEMINUMERICAL ALGORITHMS", VOLUME 2 OF
+C  "THE ART OF COMPUTER PROGRAMMING" BY DONALD E. KNUTH,
+C  ADDISON-WESLEY 1969, PAGES 26, 34, AND 464.
+C
+C  X(N) IS STORED IN DOUBLE PRECISION AS  RAN3 = X(N)/2**56 - 1/2,
+C  AND ALL DOUBLE PRECISION ARITHMETIC IS EXACT.
+C
+      INTEGER JRAN2
+C
+      DOUBLE PRECISION RANVAL,RAN3,RAN1
+C
+      COMMON /COMRAN/ RAN3(127),RAN1,JRAN2
+C
+      IF(JRAN2.EQ.0) THEN
+         JRAN2=126
+      ELSE
+         JRAN2=JRAN2-1
+      ENDIF
+C
+      RAN1=RAN1+RAN3(JRAN2+1)
+      IF(RAN1.LT.0.0D0) THEN
+         RAN1=RAN1+0.5D0
+      ELSE
+         RAN1=RAN1-0.5D0
+      ENDIF
+C
+      RAN3(JRAN2+1)=RAN1
+      RANVAL=RAN1+0.5D0
+C
+      RETURN
+C
+C  END RANDOM
+C
+      END
+      DOUBLE PRECISION FUNCTION DRANDM(DL)
+C
+C  SIMPLE PORTABLE PSEUDORANDOM NUMBER GENERATOR.
+C
+C  DRANDM RETURNS FUNCTION VALUES THAT ARE PSEUDORANDOM
+C  NUMBERS UNIFORMLY DISTRIBUTED ON THE INTERVAL (0,1).
+C
+C  'NUMERICAL MATHEMATICS AND COMPUTING' BY WARD CHENEY AND
+C  DAVID KINCAID, BROOKS/COLE PUBLISHING COMPANY
+C  (FIRST EDITION, 1980), PAGE 203
+C
+C  AT THE BEGINNING OF EXECUTION, OR WHENEVER A NEW SEQUENCE IS
+C  TO BE INITIATED, SET DL EQUAL TO AN INTEGER VALUE BETWEEN
+C  1.0D0 AND 2147483646.0D0, INCLUSIVE.  DO THIS ONLY ONCE.
+C  THEREAFTER, DO NOT SET OR ALTER DL IN ANY WAY.
+C  FUNCTION DRANDM WILL MODIFY DL FOR ITS OWN PURPOSES.
+C
+C  DRANDM USES A MULTIPLICATIVE CONGRUENTIAL METHOD.
+C  THE NUMBERS GENERATED BY DRANDM SUFFER FROM THE PARALLEL
+C  PLANES DEFECT DISCOVERED BY G. MARSAGLIA, AND SHOULD NOT BE
+C  USED WHEN HIGH-QUALITY RANDOMNESS IS REQUIRED.  IN THAT
+C  CASE, USE A "SHUFFLING" METHOD.
+C
+      DOUBLE PRECISION DL,DMOD
+C
+   10 DL=DMOD(16807.0D0*DL,2147483647.0D0)
+      DRANDM=DL/2147483647.0D0
+      IF(DRANDM.LE.0.0D0 .OR. DRANDM.GE.1.0D0) GO TO 10
+      RETURN
+      END
diff --git a/gnuradio-core/src/gen_interpolator_taps/praxis.txt b/gnuradio-core/src/gen_interpolator_taps/praxis.txt
new file mode 100644 (file)
index 0000000..5c4b815
--- /dev/null
@@ -0,0 +1,176 @@
+Brent's PRAXIS minimizer is available in FORTRAN 77.        July 1995
+
+"Algorithms for Minimization Without Derivatives"
+by Richard P. Brent, Prentice-Hall, 1973
+ISBN: 0-13-022335-2
+
+This book by Brent was a groundbreaking effort.
+(I believe that it was his Ph.D. thesis at Stanford.)
+His algorithms for finding roots and minima in
+one dimension have good performance for typical problems
+and guaranteed performance in the worst case.
+(A later rootfinder by J. Bus and Dekker gave
+a much lower bound for the worst case,
+but no better performance in typical problems.)
+These algorithms were implemented in both ALGOL W
+and FORTRAN by Brent, and have been used fairly widely.
+
+Brent also gave a multi-dimensional minimization algorithm,
+PRAXIS, but only shows an implementation in ALGOL W.
+This routine has not been widely used, at least in the U.S.
+The PRAXIS package has been translated into FORTRAN 
+by Rosalee Taylor, Sue Pinski, and me, and 
+I am making it available via anonymous ftp for use as
+freeware (please do not remove our names).
+
+   ftp a.cs.okstate.edu
+   anonymous
+   [enter your userid as password]
+   cd /pub/jpc
+   get praxis.f
+   quit
+
+Brent's method and its performance
+
+Newton's method for minimization can find the minimum of a
+quadratic function in one iteration, but is sometimes not
+convenient to use.  In the 1960s, several researchers found
+iterative methods that solve quadratic problems exactly in a
+finite number of steps.  C. S. Smith (1962) and
+M. J. D. Powell (1964) devised methods
+that had this property and did not require derivatives.
+G. W. Stewart modified the Davidon-Fletcher-Powell quasi-Newton
+method to use finite difference approximations to approximate
+the gradient.  Powell's method, or later versions by Zangwill,
+were the most successful of the early direct search methods
+having the property of finite convergence on quadratic functions.
+
+Powell's method was programmed at Harwell as subroutine VA04A,
+and is available as file va04a.f in the same directory as praxis.f.
+VA04A is not extremely robust, and can give underflow, overflow,
+or division by zero.  va04a.f has several documented patches in it
+where I tried to get around various abnormal terminations.
+I do not recommend VA04A very strongly. 
+
+Brent's PRAXIS added orthogonalization and several other features
+to Powell's method.  Brent also dealt carefully with roundoff.
+
+William H. Press et al. in their book "Numerical Recipes"
+comment that
+"Brent has a number of other cute tricks up his sleeve,
+and his modification of Powell's method is probably
+the best presently known."
+
+Roger Fletcher was less enthusiastic in his review of Brent's book
+in The Computer Journal 16 (1973) 314:
+"... I am not convinced that the modifications to Powell's
+method are the best.  Use of eigenvector directions
+is not independent of scale changes to the variables,
+and the use of searches in random directions is hardly
+appealing.  Nonetheless all the algorithms are demonstrated
+to be competitive by numerical examples."
+
+The methods of Powell, Brent, et al. require that the function
+for which a local minimum is sought must be smooth;
+that is, the function and all of its first partial derivatives
+must be continuous.
+Brent compared his method to the methods of Powell, of Stewart,
+and of Davies, Swann, and Campey.  Indirectly, he compared it
+also to the Davidon-Fletcher-Powell quasi-Newton method.
+He found that his method was about as efficient as the best
+of these in most cases, and that it was more robust than others
+in some cases.  (Pages 139-155 in Brent's book give fair 
+comparisons to other methods.  The results in Table 7.1 on
+page 138 are correct, but do not include progress all the way
+to convergence, and are therefore not too useful.)
+
+On least squares problems, all of these general minimization
+methods are likely to be inefficient compared to least squares
+methods such as the Gauss-Newton or Marquardt methods.
+  
+In addition to the scale dependence that Fletcher deplored,
+PRAXIS also had the disadvantage that it required N, the number
+of parameters, to be greater than or equal to two.
+The failure to handle N=1 is an unnecessary and pointless limitation.
+
+
+The FORTRAN version
+
+We have followed Brent's PRAXIS rather closely.
+I have added a patch to try to handle the case N=1,
+and an option to use a simpler pseudorandom number generator,
+DRANDM.  The handling of N=1 is not guaranteed.
+
+The user writes a main program and a function subprogram
+to compute the function to be minimized.
+All communication between the user's main program and PRAXIS
+is done via COMMON, except for an EXTERNAL parameter giving
+the name of the function subprogram.
+The disadvantages of using COMMON are at least two-fold:
+
+   1)  Arrays cannot have adjustable dimensions.
+
+   2)  Because some actual parameters are COMMON variables,
+       the FORTRAN version of PRAXIS probably will not pass
+       the Bell Labs PFORT package as being 100% standard FORTRAN.
+       Nevertheless, this usage will not cause any conflict in
+       any commercial FORTRAN compiler ever written.
+       (If it does, I will apologize and rewrite PRAXIS.)
+
+The advantage of using COMMON is that it is not necessary to pass
+about fifteen more parameters every time the user calls PRAXIS.
+At present all arrays are dimensioned (20) or (20,20),
+and this can easily be increased using two simple global editing
+commands.  (In this case, increase the value of NMAX.)
+
+There are no DATA statements in PRAXIS, and it was not necessary
+to use any SAVE statements.
+
+We have used DOUBLE PRECISION for all floating point computations,
+as Brent did.  We recommend using DOUBLE PRECISION on all computers
+except possibly Cray computers, in which REAL is reasonably precise.
+The value of "machine epsilon" is computed in subroutine PRASET
+using bisection, and is called EPSMCH.
+Brent computes EPSMCH**4 and 1/EPSMCH**4 in PRAXIS,
+and uses these quantities later.  
+Because EPSMCH in DOUBLE PRECISION is less than 1E-16,
+these fourth powers of EPSMCH and 1/EPSMCH will underflow
+and overflow on such machines as VAXs and PCs,
+which have a range of only about 1E38, grossly insufficient
+for scientific computation.  For such machines, Brent recommends
+increasing the value of EPSMCH.  
+EPSMCH=1E-9 or possibly even 1E-8 might be necessary.
+A better solution would be to eliminate the explicit use of
+these fourth powers, accomplishing the same result implicitly.
+
+A "bug bounty" of $10 U.S. will be paid by me for the first 
+notification of any error in PRAXIS.
+The same bounty also applies to any substantive poor design
+choice (having no redeeming advantages whatever) in the FORTRAN
+package.  (The patch for N=1 is not included, although any
+suggested improvements in that will be considered carefully.)
+
+praxis.f includes test software to run any of the test problems
+that Brent ran, and is set to run at least one case of each problem.
+I have run these on an IBM 3090, essentially the same 
+architecture that Brent used, and obtained essentially the same
+results that Brent shows on pages 140-155.  The Hilbert problem with
+N=12, for which Brent shows no termination results and for which
+the results in Table 7.1 are correct but not relevant,
+runs a long time; I cut it off at 3000 function evaluations.
+I don't particularly like Brent's convergence criterion,
+which allows this sort of extremely slow creeping progress,
+but have not modified it.
+
+Please notify me of any problems with this software,
+or of any suggested modifications.
+
+John Chandler
+Computer Science Department
+Oklahoma State University
+Stillwater, Oklahoma 74078, U.S.A.
+(405) 744-5676
+jpc@a.cs.okstate.edu
+
diff --git a/gnuradio-core/src/gen_interpolator_taps/simpson.c b/gnuradio-core/src/gen_interpolator_taps/simpson.c
new file mode 100644 (file)
index 0000000..fc6dd6c
--- /dev/null
@@ -0,0 +1,76 @@
+/* -*- c -*- */
+#include <math.h>
+#include <stdio.h>
+
+#define        EPS     (1.0e-5)
+#define        JMAX    16
+
+/*
+ * Compute the Nth stage of refinement of an extended trapezoidal
+ * rule.  FUNC is input as a pointer to a function to be integrated
+ * between limits A and B.  When called with N = 1, the routine
+ * returns the crudest estimate of the integral from A to B of f(x)
+ * dx.  Subsequent calls with N=2,3,... (in that sequential order)
+ * will improve the accuracy by adding 2**(N-2) additional interior
+ * points.
+ *
+ * N.B., this function contains static state and IS NEITHER RENTRANT
+ * NOR THREAD SAFE!
+ */
+
+double 
+trapzd (double (*func)(double),
+       double a, double b,
+       int    n)
+{
+  long double          x, tnm, sum, del;
+  static long double   s;
+  static int   it;
+  int          j;
+
+  if (n == 1){
+    it = 1;    /* # of points to add on the next call */
+    s = 0.5 * (b - a) * (func(a) + func(b));
+    return s;
+  }
+  else {
+    tnm = it;
+    del = (b-a)/tnm;           /* this is the spacing of the points to be added */
+    x = a + 0.5*del;
+    for (sum = 0.0, j = 1; j <= it; j++, x += del)
+      sum += func(x);
+    it *= 2;
+    s = 0.5 * (s + (b-a) * sum/tnm);   /* replace s by it's refined value */
+    return s;
+  }
+}
+
+/*
+ * Returns the integral of the function FUNC from A to B.  The
+ * parameters EPS can be set to the desired fractional accuracy and
+ * JMAX so that 2**(JMAX-1) is the maximum allowed number of steps.
+ * Integration is performed by Simpson's rule.
+ */
+
+double
+qsimp (double (*func)(double),
+       double a,       /* lower limit */
+       double b)       /* upper limit */
+{
+  int          j;
+  long double  s, st, ost, os;
+
+  ost = os = -1.0e30;
+  for (j = 1; j <= JMAX; j++){
+    st = trapzd (func, a, b, j);
+    s = (4.0 * st - ost)/3.0;
+    if (fabs (s - os) < EPS * fabs(os))
+      return s;
+    os = s;
+    ost = st;
+  }
+  fprintf (stderr, "Too many steps in routine QSIMP\n");
+  // exit (1);
+  return s;
+}
+
diff --git a/gnuradio-core/src/gen_interpolator_taps/simpson.h b/gnuradio-core/src/gen_interpolator_taps/simpson.h
new file mode 100644 (file)
index 0000000..68774f9
--- /dev/null
@@ -0,0 +1,3 @@
+double qsimp (double (*func)(double),
+             double a, double b);
+
diff --git a/gnuradio-core/src/lib/Makefile.am b/gnuradio-core/src/lib/Makefile.am
new file mode 100644 (file)
index 0000000..2b31b3f
--- /dev/null
@@ -0,0 +1,62 @@
+#
+# Copyright 2001,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.
+# 
+
+include $(top_srcdir)/Makefile.common
+
+## Process this file with automake to produce Makefile.in
+
+# We've got to build . before swig
+# FIXME add atsc back
+SUBDIRS =      missing runtime filter general g72x reed-solomon omnithread io . swig
+
+# generate libgnuradio-core.la from the convenience libraries in subdirs
+
+lib_LTLIBRARIES = libgnuradio-core.la 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_qa_la_SOURCES = bug_work_around_6.cc
+libgnuradio_core_qa_la_LDFLAGS = $(NO_UNDEFINED) -version-info 0:0:0 \
+                               $(LIBGNURADIO_CORE_EXTRA_LDFLAGS)
+
+FIXME = \
+       atsc/libatsc.la                 
+
+libgnuradio_core_la_LIBADD  =          \
+       filter/libfilter.la             \
+       g72x/libccitt.la                \
+       general/libgeneral.la           \
+       io/libio.la                     \
+       missing/libmissing.la           \
+       omnithread/libomnithread.la     \
+       reed-solomon/librs.la           \
+       runtime/libruntime.la           \
+       $(FFTW3F_LIBS)
+
+libgnuradio_core_qa_la_LIBADD  =       \
+       filter/libfilter-qa.la          \
+       general/libgeneral-qa.la        \
+       runtime/libruntime-qa.la        \
+       missing/libmissing.la           \
+       libgnuradio-core.la             \
+       $(CPPUNIT_LIBS)                 
+
diff --git a/gnuradio-core/src/lib/bug_work_around_6.cc b/gnuradio-core/src/lib/bug_work_around_6.cc
new file mode 100644 (file)
index 0000000..929c7f8
--- /dev/null
@@ -0,0 +1,3 @@
+// if libgrio has no sources, it doesn't get built correctly
+
+static int gr_bug_work_around_6;
diff --git a/gnuradio-core/src/lib/filter/3dnow_float_dotprod_really_simple.S b/gnuradio-core/src/lib/filter/3dnow_float_dotprod_really_simple.S
new file mode 100644 (file)
index 0000000..5aee102
--- /dev/null
@@ -0,0 +1,95 @@
+#
+# 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 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.
+# 
+
+
+# input and taps are guarenteed to be 16 byte aligned.
+# n_4_float_blocks is != 0
+#      
+#
+#  float 
+#  sse_float_dotprod (const float *input,
+#                  const float *taps, unsigned n_4_float_blocks)
+#  {
+#    float sum0 = 0;
+#    float sum1 = 0;
+#    float sum2 = 0;
+#    float sum3 = 0;
+#  
+#    do {
+#  
+#      sum0 += input[0] * taps[0];
+#      sum1 += input[1] * taps[1];
+#      sum2 += input[2] * taps[2];
+#      sum3 += input[3] * taps[3];
+#  
+#      input += 4;
+#      taps += 4;
+#  
+#    } while (--n_4_float_blocks != 0);
+#  
+#  
+#    return sum0 + sum1 + sum2 + sum3;
+#  }
+#              
+
+
+       .file   "3dnow_float_dotprod_really_simple.s"
+       .version        "01.01"
+.text
+       .p2align 4
+.globl sse_float_dotprod
+       .type    sse_float_dotprod,@function
+sse_float_dotprod:
+       pushl   %ebp
+       movl    %esp, %ebp
+       movl    8(%ebp), %edx
+       movl    12(%ebp), %eax
+       movl    16(%ebp), %ecx
+
+       
+       # The plan is to get it computing the correct answer, and
+       # then to unroll and schedule the inner loop.
+
+       pxor    %mm4, %mm4              # mm4 = 0 0
+       shll    $1, %ecx                # count * 2
+
+       .p2align 4
+.loop1:
+       movq    (%eax), %mm0
+       pfmul   (%edx), %mm0
+       pfadd   %mm0, %mm4
+       addl    $8, %edx
+       addl    $8, %eax
+       decl    %ecx
+       jne     .loop1
+       
+       # at this point mm4 contains partial sums
+
+       pfacc   %mm4, %mm4
+       movd    %mm4, 16(%ebp)
+       femms
+       flds    16(%ebp)
+
+       popl    %ebp
+       ret
+.Lfe1:
+       .size    sse_float_dotprod,.Lfe1-sse_float_dotprod
+       .ident  "Hand coded x86 3DNow! assembly"
diff --git a/gnuradio-core/src/lib/filter/3dnow_float_dotprod_simple.S b/gnuradio-core/src/lib/filter/3dnow_float_dotprod_simple.S
new file mode 100644 (file)
index 0000000..4c4936d
--- /dev/null
@@ -0,0 +1,102 @@
+#
+# 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 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.
+# 
+
+
+# input and taps are guarenteed to be 16 byte aligned.
+# n_4_float_blocks is != 0
+#      
+#
+#  float 
+#  sse_float_dotprod (const float *input,
+#                  const float *taps, unsigned n_4_float_blocks)
+#  {
+#    float sum0 = 0;
+#    float sum1 = 0;
+#    float sum2 = 0;
+#    float sum3 = 0;
+#  
+#    do {
+#  
+#      sum0 += input[0] * taps[0];
+#      sum1 += input[1] * taps[1];
+#      sum2 += input[2] * taps[2];
+#      sum3 += input[3] * taps[3];
+#  
+#      input += 4;
+#      taps += 4;
+#  
+#    } while (--n_4_float_blocks != 0);
+#  
+#  
+#    return sum0 + sum1 + sum2 + sum3;
+#  }
+#              
+
+
+       .file   "3dnow_float_dotprod_simple.s"
+       .version        "01.01"
+.text
+       .p2align 4
+.globl sse_float_dotprod
+       .type    sse_float_dotprod,@function
+sse_float_dotprod:
+       pushl   %ebp
+       movl    %esp, %ebp
+       movl    8(%ebp), %edx
+       movl    12(%ebp), %eax
+       movl    16(%ebp), %ecx
+
+       
+       # The plan is to get it computing the correct answer, and
+       # then to unroll and schedule the inner loop.
+
+       pxor    %mm4, %mm4              # mm4 = 0 0
+       pxor    %mm5, %mm5              # mm5 = 0 0 
+
+       .p2align 4
+.loop1:
+       movq    0(%eax), %mm0
+       movq    8(%eax), %mm1
+       
+       pfmul   0(%edx), %mm0
+       pfadd   %mm0, %mm4
+       
+       pfmul   8(%edx), %mm1
+       pfadd   %mm1, %mm5
+
+       addl    $16, %edx
+       addl    $16, %eax
+       decl    %ecx
+       jne     .loop1
+       
+       # at this point mm4 and mm5 contain partial sums
+
+       pfadd   %mm5, %mm4
+       pfacc   %mm4, %mm4
+       movd    %mm4, 16(%ebp)
+       femms
+       flds    16(%ebp)
+
+       popl    %ebp
+       ret
+.Lfe1:
+       .size    sse_float_dotprod,.Lfe1-sse_float_dotprod
+       .ident  "Hand coded x86 3DNow! assembly"
diff --git a/gnuradio-core/src/lib/filter/Makefile.am b/gnuradio-core/src/lib/filter/Makefile.am
new file mode 100644 (file)
index 0000000..01885a8
--- /dev/null
@@ -0,0 +1,306 @@
+#
+# Copyright 2001,2002,2004,2005,2006 Free Software Foundation, Inc.
+# 
+# This file is part of GNU Radio
+# 
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 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.
+# 
+
+include $(top_srcdir)/Makefile.common
+
+#
+# This directory contains mostly filter routines, plus a few
+# other performance critical items
+#
+
+INCLUDES = $(STD_DEFINES_AND_INCLUDES) $(CPPUNIT_INCLUDES)
+
+noinst_LTLIBRARIES = libfilter.la libfilter-qa.la
+
+# ----------------------------------------------------------------
+# these scripts generate FIR code
+#
+
+CODE_GENERATOR =                                       \
+       generate_all.py                                 \
+       generate_gr_fir_XXX.py                          \
+       generate_gr_fir_filter_XXX.py                   \
+       generate_gr_interp_fir_filter_XXX.py            \
+       generate_gr_rational_resampler_base_XXX.py      \
+       generate_gr_fir_sysconfig.py                    \
+       generate_gr_fir_sysconfig_generic.py            \
+       generate_gr_fir_util.py                         \
+       generate_gr_freq_xlating_fir_filter_XXX.py      \
+       generate_utils.py                               \
+       gr_fir_XXX.cc.t                                 \
+       gr_fir_XXX.h.t                                  \
+       gr_fir_XXX_generic.cc.t                         \
+       gr_fir_XXX_generic.h.t                          \
+       gr_fir_filter_XXX.cc.t                          \
+       gr_fir_filter_XXX.h.t                           \
+       gr_fir_filter_XXX.i.t                           \
+       gr_interp_fir_filter_XXX.cc.t                   \
+       gr_interp_fir_filter_XXX.h.t                    \
+       gr_interp_fir_filter_XXX.i.t                    \
+       gr_rational_resampler_base_XXX.cc.t             \
+       gr_rational_resampler_base_XXX.h.t              \
+       gr_rational_resampler_base_XXX.i.t              \
+       gr_freq_xlating_fir_filter_XXX.cc.t             \
+       gr_freq_xlating_fir_filter_XXX.h.t              \
+       gr_freq_xlating_fir_filter_XXX.i.t
+
+
+
+# include $(srcdir)/Makefile.gen
+include Makefile.gen
+
+
+$(GENERATED_H) $(GENERATED_I) $(GENERATED_CC): $(CODE_GENERATOR)
+       PYTHONPATH=$(top_srcdir)/gnuradio-core/src/python srcdir=$(srcdir) $(srcdir)/generate_all.py
+
+
+BUILT_SOURCES = $(GENERATED_H) $(GENERATED_I) $(GENERATED_CC)
+
+
+# ----------------------------------------------------------------
+# MD_CPU and MD_SUBCPU are set at configure time by way of 
+#   gnuradio/config/gr_set_md_cpu.m4.  
+#   It indicates which set of machine dependent code we should be building.
+#   We currently implement "generic" and "x86"
+
+#
+# <foo>_CODE entry for each set of machine specific speedups
+#
+
+generic_CODE =                         \
+       sysconfig_generic.cc            
+
+generic_qa_CODE =                      \
+       qa_dotprod_generic.cc
+
+x86_CODE =                             \
+       sysconfig_x86.cc                \
+       gr_fir_sysconfig_x86.cc         \
+       gr_cpu.cc                       \
+       gr_fir_ccc_simd.cc              \
+       gr_fir_ccc_x86.cc               \
+       gr_fir_fff_simd.cc              \
+       gr_fir_fff_x86.cc               \
+       gr_fir_fsf_simd.cc              \
+       gr_fir_fsf_x86.cc               \
+       gr_fir_scc_simd.cc              \
+       gr_fir_scc_x86.cc               \
+       gr_fir_fcc_simd.cc              \
+       gr_fir_fcc_x86.cc               \
+       gr_fir_ccf_simd.cc              \
+       gr_fir_ccf_x86.cc               \
+       sse_debug.c
+
+x86_SUBCODE =                          \
+       float_dotprod_sse.S             \
+       float_dotprod_3dnow.S           \
+       complex_dotprod_3dnowext.S      \
+       complex_dotprod_3dnow.S         \
+       complex_dotprod_sse.S           \
+       ccomplex_dotprod_3dnowext.S     \
+       ccomplex_dotprod_3dnow.S        \
+       ccomplex_dotprod_sse.S          \
+       fcomplex_dotprod_3dnow.S        \
+       fcomplex_dotprod_sse.S          \
+       short_dotprod_mmx.S             \
+       cpuid_x86.S
+
+x86_64_SUBCODE =                       \
+       float_dotprod_sse64.S           \
+       float_dotprod_3dnow64.S         \
+       complex_dotprod_3dnowext64.S    \
+       complex_dotprod_3dnow64.S       \
+       complex_dotprod_sse64.S         \
+       ccomplex_dotprod_3dnowext64.S   \
+       ccomplex_dotprod_3dnow64.S      \
+       ccomplex_dotprod_sse64.S        \
+       fcomplex_dotprod_3dnow64.S      \
+       fcomplex_dotprod_sse64.S        \
+       short_dotprod_mmx64.S           \
+       cpuid_x86_64.S
+
+x86_qa_CODE =                          \
+       qa_dotprod_x86.cc               \
+       qa_float_dotprod_x86.cc         \
+       qa_complex_dotprod_x86.cc       \
+       qa_ccomplex_dotprod_x86.cc      
+
+#
+# include each <foo>_CODE entry here...
+#
+EXTRA_libfilter_la_SOURCES =           \
+       $(generic_CODE)                 \
+       $(generic_qa_CODE)              \
+       $(x86_CODE)                     \
+       $(x86_SUBCODE)                  \
+       $(x86_64_SUBCODE)               \
+       $(x86_qa_CODE)
+
+
+EXTRA_DIST =                                   \
+       3dnow_float_dotprod_really_simple.S     \
+       3dnow_float_dotprod_simple.S            \
+       $(CODE_GENERATOR)
+
+
+# work around automake deficiency
+libfilter_la_common_SOURCES =          \
+       $(GENERATED_CC)                 \
+       gr_adaptive_fir_ccf.cc          \
+       gr_cma_equalizer_cc.cc          \
+       gr_fft_filter_ccc.cc            \
+       gr_fft_filter_fff.cc            \
+       gr_goertzel_fc.cc               \
+       gr_filter_delay_fc.cc           \
+       gr_fractional_interpolator.cc   \
+       gr_hilbert_fc.cc                \
+       gr_iir_filter_ffd.cc            \
+       gr_sincos.c                     \
+       gr_single_pole_iir_filter_ff.cc \
+       gr_single_pole_avg_filter_ff.cc \
+       gr_single_pole_rec_filter_ff.cc \
+       gr_single_zero_avg_filter_ff.cc \
+       gr_single_zero_rec_filter_ff.cc \
+       gr_single_pole_iir_filter_cc.cc \
+       gri_goertzel.cc                 \
+       gri_mmse_fir_interpolator.cc    \
+       gri_mmse_fir_interpolator_cc.cc \
+       complex_dotprod_generic.cc      \
+       ccomplex_dotprod_generic.cc     \
+       float_dotprod_generic.c         \
+       short_dotprod_generic.c         
+
+libfilter_qa_la_common_SOURCES =       \
+       qa_filter.cc                    \
+       qa_gr_fir_ccf.cc                \
+       qa_gr_fir_fcc.cc                \
+       qa_gr_fir_fff.cc                \
+       qa_gr_fir_ccc.cc                \
+       qa_gr_fir_scc.cc                \
+       qa_gri_mmse_fir_interpolator.cc 
+
+if MD_CPU_generic
+libfilter_la_SOURCES = $(libfilter_la_common_SOURCES) $(generic_CODE)
+libfilter_qa_la_SOURCES = $(libfilter_qa_la_common_SOURCES) $(generic_qa_CODE)
+endif
+
+if MD_CPU_x86
+if MD_SUBCPU_x86_64
+libfilter_la_SOURCES = $(libfilter_la_common_SOURCES) $(x86_64_SUBCODE) $(x86_CODE)
+else
+libfilter_la_SOURCES = $(libfilter_la_common_SOURCES) $(x86_SUBCODE) $(x86_CODE)
+endif
+
+libfilter_qa_la_SOURCES = $(libfilter_qa_la_common_SOURCES) $(x86_qa_CODE)
+endif
+
+
+grinclude_HEADERS =                    \
+       $(GENERATED_H)                  \
+       complex_dotprod_generic.h       \
+       complex_dotprod_x86.h           \
+       fcomplex_dotprod_x86.h          \
+       ccomplex_dotprod_generic.h      \
+       ccomplex_dotprod_x86.h          \
+       float_dotprod_generic.h         \
+       float_dotprod_x86.h             \
+       gr_adaptive_fir_ccf.h           \
+       gr_cma_equalizer_cc.h           \
+       gr_cpu.h                        \
+       gr_fft_filter_ccc.h             \
+       gr_fft_filter_fff.h             \
+       gr_filter_delay_fc.h            \
+       gr_fir_sysconfig_x86.h          \
+       gr_fractional_interpolator.h    \
+       gr_goertzel_fc.h                \
+       gr_hilbert_fc.h                 \
+       gr_iir_filter_ffd.h             \
+       gr_rotator.h                    \
+       gr_sincos.h                     \
+       gr_single_pole_avg.h            \
+       gr_single_pole_rec.h            \
+       gr_single_pole_iir.h            \
+       gr_single_pole_iir_filter_ff.h  \
+       gr_single_pole_avg_filter_ff.h  \
+       gr_single_pole_rec_filter_ff.h  \
+       gr_single_zero_avg_filter_ff.h  \
+       gr_single_zero_rec_filter_ff.h  \
+       gr_single_pole_iir_filter_cc.h  \
+       gr_single_zero_avg.h            \
+       gr_single_zero_rec.h            \
+       gri_goertzel.h                  \
+       gri_iir.h                       \
+       gri_mmse_fir_interpolator.h     \
+       gri_mmse_fir_interpolator_cc.h  \
+       qa_filter.h                     \
+       short_dotprod_generic.h         \
+       short_dotprod_x86.h             \
+       sse_debug.h
+
+noinst_HEADERS =                       \
+       assembly.h                      \
+       gr_fir_scc_simd.h               \
+       gr_fir_scc_x86.h                \
+       gr_fir_fcc_simd.h               \
+       gr_fir_fcc_x86.h                \
+       gr_fir_ccf_simd.h               \
+       gr_fir_ccf_x86.h                \
+       gr_fir_ccc_simd.h               \
+       gr_fir_ccc_x86.h                \
+       gr_fir_fff_simd.h               \
+       gr_fir_fff_x86.h                \
+       gr_fir_fsf_simd.h               \
+       gr_fir_fsf_x86.h                \
+       interpolator_taps.h             \
+       qa_complex_dotprod_x86.h        \
+       qa_ccomplex_dotprod_x86.h       \
+       qa_dotprod.h                    \
+       qa_float_dotprod_x86.h          \
+       qa_gr_fir_ccf.h                 \
+       qa_gr_fir_fcc.h                 \
+       qa_gr_fir_fff.h                 \
+       qa_gr_fir_ccc.h                 \
+       qa_gr_fir_scc.h                 \
+       qa_gri_mmse_fir_interpolator.h  
+
+
+
+swiginclude_HEADERS =                  \
+       filter.i                        \
+       filter_generated.i              \
+       gr_adaptive_fir_ccf.i           \
+       gr_cma_equalizer_cc.i           \
+       gr_fft_filter_ccc.i             \
+       gr_fft_filter_fff.i             \
+       gr_filter_delay_fc.i            \
+       gr_goertzel_fc.i                \
+       gr_hilbert_fc.i                 \
+       gr_iir_filter_ffd.i             \
+       gr_single_pole_iir_filter_ff.i  \
+       gr_single_pole_avg_filter_ff.i  \
+       gr_single_pole_rec_filter_ff.i  \
+       gr_single_zero_avg_filter_ff.i  \
+       gr_single_zero_rec_filter_ff.i  \
+       gr_single_pole_iir_filter_cc.i  \
+       $(GENERATED_I)
+
+
+CLEANFILES = $(BUILT_SOURCES) *.pyc
diff --git a/gnuradio-core/src/lib/filter/Makefile.gen b/gnuradio-core/src/lib/filter/Makefile.gen
new file mode 100644 (file)
index 0000000..6809274
--- /dev/null
@@ -0,0 +1,111 @@
+#
+# This file is machine generated.  All edits will be overwritten
+#
+GENERATED_H = \
+       gr_fir_ccc.h \
+       gr_fir_ccc_generic.h \
+       gr_fir_ccf.h \
+       gr_fir_ccf_generic.h \
+       gr_fir_fcc.h \
+       gr_fir_fcc_generic.h \
+       gr_fir_fff.h \
+       gr_fir_fff_generic.h \
+       gr_fir_filter_ccc.h \
+       gr_fir_filter_ccf.h \
+       gr_fir_filter_fcc.h \
+       gr_fir_filter_fff.h \
+       gr_fir_filter_fsf.h \
+       gr_fir_filter_scc.h \
+       gr_fir_fsf.h \
+       gr_fir_fsf_generic.h \
+       gr_fir_scc.h \
+       gr_fir_scc_generic.h \
+       gr_fir_sysconfig.h \
+       gr_fir_sysconfig_generic.h \
+       gr_fir_util.h \
+       gr_freq_xlating_fir_filter_ccc.h \
+       gr_freq_xlating_fir_filter_ccf.h \
+       gr_freq_xlating_fir_filter_fcc.h \
+       gr_freq_xlating_fir_filter_fcf.h \
+       gr_freq_xlating_fir_filter_scc.h \
+       gr_freq_xlating_fir_filter_scf.h \
+       gr_interp_fir_filter_ccc.h \
+       gr_interp_fir_filter_ccf.h \
+       gr_interp_fir_filter_fcc.h \
+       gr_interp_fir_filter_fff.h \
+       gr_interp_fir_filter_fsf.h \
+       gr_interp_fir_filter_scc.h \
+       gr_rational_resampler_base_ccc.h \
+       gr_rational_resampler_base_ccf.h \
+       gr_rational_resampler_base_fcc.h \
+       gr_rational_resampler_base_fff.h \
+       gr_rational_resampler_base_fsf.h \
+       gr_rational_resampler_base_scc.h
+
+GENERATED_I = \
+       gr_fir_filter_ccc.i \
+       gr_fir_filter_ccf.i \
+       gr_fir_filter_fcc.i \
+       gr_fir_filter_fff.i \
+       gr_fir_filter_fsf.i \
+       gr_fir_filter_scc.i \
+       gr_freq_xlating_fir_filter_ccc.i \
+       gr_freq_xlating_fir_filter_ccf.i \
+       gr_freq_xlating_fir_filter_fcc.i \
+       gr_freq_xlating_fir_filter_fcf.i \
+       gr_freq_xlating_fir_filter_scc.i \
+       gr_freq_xlating_fir_filter_scf.i \
+       gr_interp_fir_filter_ccc.i \
+       gr_interp_fir_filter_ccf.i \
+       gr_interp_fir_filter_fcc.i \
+       gr_interp_fir_filter_fff.i \
+       gr_interp_fir_filter_fsf.i \
+       gr_interp_fir_filter_scc.i \
+       gr_rational_resampler_base_ccc.i \
+       gr_rational_resampler_base_ccf.i \
+       gr_rational_resampler_base_fcc.i \
+       gr_rational_resampler_base_fff.i \
+       gr_rational_resampler_base_fsf.i \
+       gr_rational_resampler_base_scc.i
+
+GENERATED_CC = \
+       gr_fir_ccc.cc \
+       gr_fir_ccc_generic.cc \
+       gr_fir_ccf.cc \
+       gr_fir_ccf_generic.cc \
+       gr_fir_fcc.cc \
+       gr_fir_fcc_generic.cc \
+       gr_fir_fff.cc \
+       gr_fir_fff_generic.cc \
+       gr_fir_filter_ccc.cc \
+       gr_fir_filter_ccf.cc \
+       gr_fir_filter_fcc.cc \
+       gr_fir_filter_fff.cc \
+       gr_fir_filter_fsf.cc \
+       gr_fir_filter_scc.cc \
+       gr_fir_fsf.cc \
+       gr_fir_fsf_generic.cc \
+       gr_fir_scc.cc \
+       gr_fir_scc_generic.cc \
+       gr_fir_sysconfig.cc \
+       gr_fir_sysconfig_generic.cc \
+       gr_fir_util.cc \
+       gr_freq_xlating_fir_filter_ccc.cc \
+       gr_freq_xlating_fir_filter_ccf.cc \
+       gr_freq_xlating_fir_filter_fcc.cc \
+       gr_freq_xlating_fir_filter_fcf.cc \
+       gr_freq_xlating_fir_filter_scc.cc \
+       gr_freq_xlating_fir_filter_scf.cc \
+       gr_interp_fir_filter_ccc.cc \
+       gr_interp_fir_filter_ccf.cc \
+       gr_interp_fir_filter_fcc.cc \
+       gr_interp_fir_filter_fff.cc \
+       gr_interp_fir_filter_fsf.cc \
+       gr_interp_fir_filter_scc.cc \
+       gr_rational_resampler_base_ccc.cc \
+       gr_rational_resampler_base_ccf.cc \
+       gr_rational_resampler_base_fcc.cc \
+       gr_rational_resampler_base_fff.cc \
+       gr_rational_resampler_base_fsf.cc \
+       gr_rational_resampler_base_scc.cc
+
diff --git a/gnuradio-core/src/lib/filter/README b/gnuradio-core/src/lib/filter/README
new file mode 100644 (file)
index 0000000..00730f8
--- /dev/null
@@ -0,0 +1,28 @@
+#
+# 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 directory holds filtering code, some of which is machine
+generated.  Which variations are generated is controlled by two
+variables.  For most everything, the global "signatures"
+in generate_utils.py controls.
+
+For GrFreqXlatingFIRfilter<foo>, the global "fx_signatures" in
+generate_GrFreqXlatingFIRfilterXXX.py controls.
diff --git a/gnuradio-core/src/lib/filter/assembly.h b/gnuradio-core/src/lib/filter/assembly.h
new file mode 100644 (file)
index 0000000..9398a0a
--- /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 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.
+ */
+
+#ifndef _ASSEMBLY_H_
+#define _ASSEMBLY_H_
+
+
+
+#ifndef __ELF__
+
+/*
+ * Too bad, the following define does not work as expected --SF
+ *     #define GLOB_SYMB(f)    __USER_LABEL_PREFIX__ ## f
+ */
+#define GLOB_SYMB(f)   _ ## f
+
+#define DEF_FUNC_HEAD(f)       \
+       .def    GLOB_SYMB(f); .scl 2; .type 32; .endef
+
+#define FUNC_TAIL(f)   /* none */
+
+
+#else  /* !__ELF__ */
+
+
+#define GLOB_SYMB(f)   f
+
+#define DEF_FUNC_HEAD(f)       \
+       .type   GLOB_SYMB(f),@function  \
+
+#define FUNC_TAIL(f)   \
+  .Lfe1:               \
+       .size   GLOB_SYMB(f),.Lfe1-GLOB_SYMB(f)
+
+
+#endif /* !__ELF__ */
+
+
+#endif /* _ASSEMBLY_H_ */
diff --git a/gnuradio-core/src/lib/filter/ccomplex_dotprod_3dnow.S b/gnuradio-core/src/lib/filter/ccomplex_dotprod_3dnow.S
new file mode 100644 (file)
index 0000000..79826e8
--- /dev/null
@@ -0,0 +1,216 @@
+#
+# 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 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.
+# 
+
+
+# input and taps are guarenteed to be 16 byte aligned.
+# n_2_ccomplex_blocks is != 0
+#      
+#
+#  ccomplex_dotprod_generic (const float *input,
+#                         const float *taps, unsigned n_2_ccomplex_blocks, float *result)
+#  {
+#    float sum0 = 0;
+#    float sum1 = 0;
+#    float sum2 = 0;
+#    float sum3 = 0;
+#  
+#    do {
+#  
+#      sum0 += input[0] * taps[0] - input[1] * taps[1];
+#      sum1 += input[0] * taps[1] + input[1] * taps[0];
+#      sum2 += input[2] * taps[2] - input[3] * taps[3];
+#      sum3 += input[2] * taps[3] + input[3] * taps[2];
+#  
+#      input += 4;
+#      taps += 4;
+#  
+#    } while (--n_2_ccomplex_blocks != 0);
+#  
+#  
+#    result[0] = sum0 + sum2;
+#    result[1] = sum1 + sum3;
+#  }
+#              
+
+# TODO: prefetch and better scheduling
+
+#include "assembly.h"
+
+       .file   "ccomplex_dotprod_3dnow.S"
+       .version        "01.01"
+.text
+       .p2align 4
+.globl GLOB_SYMB(ccomplex_dotprod_3dnow)
+       DEF_FUNC_HEAD(ccomplex_dotprod_3dnow)
+GLOB_SYMB(ccomplex_dotprod_3dnow):
+       pushl   %ebp
+       movl    %esp, %ebp
+       movl    8(%ebp), %eax           # input
+       movl    12(%ebp), %edx          # taps
+       movl    16(%ebp), %ecx          # n_2_ccomplex_blocks
+
+       # zero accumulators
+       
+       pxor    %mm6, %mm6              # mm6 = 0 0 
+
+       movq    0(%eax), %mm0
+
+       pxor    %mm7, %mm7              # mm7 = 0 0 
+
+       movq    0(%edx), %mm2
+
+       movq    8(%eax), %mm1
+
+       shrl    $1, %ecx                # ecx = n_2_ccomplex_blocks / 2
+
+       movq    8(%edx), %mm3
+
+       jmp     .L1_test
+
+       #
+       # 4 taps / loop
+       # something like ?? cycles / loop
+       #
+       
+       .p2align 4
+.loop1:        
+
+# complex prod: C += A * B,  w/ temp Z, mmPN=$80000000
+#
+#       movq    (%eax), %mmA
+#       movq    (%edx), %mmB
+#
+#      # 3DNow! replacement for: pswapd  %mmA, %mmZ
+#      # TODO: optimize the punpckhdq
+#      movq    %mmA, %mmZ
+#      punpckhdq       %mmZ, %mmZ
+#      punpckldq       %mmA, %mmZ
+#
+#       pfmul   %mmB, %mmA
+#       pfmul   %mmZ, %mmB
+#
+#      # 3DNow! replacement for: pfpnacc %mmB, %mmA
+#      pxor    %mmPN, %mmA
+#      pfacc   %mmB, %mmA
+#
+#       pfadd   %mmA, %mmC
+
+
+# A=mm0, B=mm2, Z=mm4
+# A'=mm1, B'=mm3, Z'=mm5
+
+       movq    %mm0, %mm4
+       movq    %mm1, %mm5
+       punpckhdq       %mm4, %mm4
+       punpckhdq       %mm5, %mm5
+       punpckldq       %mm0, %mm4
+       pfmul   %mm2, %mm0
+       punpckldq       %mm1, %mm5
+       pfmul   %mm4, %mm2
+       pfadd   %mm0, %mm6
+       movq    16(%edx), %mm0
+       pfmul   %mm3, %mm1
+       pfadd   %mm2, %mm7
+       movq    16(%eax), %mm2
+       pfadd   %mm1, %mm6
+       pfmul   %mm5, %mm3
+       movq    24(%edx), %mm1
+
+       movq    %mm0, %mm4
+       movq    %mm1, %mm5
+
+       pfadd   %mm3, %mm7
+       movq    24(%eax), %mm3
+
+# unroll
+
+       punpckhdq       %mm4, %mm4
+       punpckhdq       %mm5, %mm5
+       punpckldq       %mm0, %mm4
+       pfmul   %mm2, %mm0
+       punpckldq       %mm1, %mm5
+       pfmul   %mm4, %mm2
+       pfadd   %mm0, %mm6
+       movq    32(%edx), %mm0
+       pfmul   %mm3, %mm1
+       pfadd   %mm2, %mm7
+       movq    32(%eax), %mm2
+       pfadd   %mm1, %mm6
+       pfmul   %mm5, %mm3
+       movq    40(%edx), %mm1
+
+       addl    $32, %eax
+       addl    $32, %edx
+
+       pfadd   %mm3, %mm7
+       movq    8(%eax), %mm3
+
+.L1_test:
+       decl    %ecx
+       jge     .loop1
+
+       # We've handled the bulk of multiplies up to here.
+       # Let's see if original n_2_ccomplex_blocks was odd.
+       # If so, we've got 2 more taps to do.
+       
+       movl    16(%ebp), %ecx          # n_2_ccomplex_blocks
+       andl    $1, %ecx
+       je      .Leven
+       
+       # The count was odd, do 2 more taps.
+       # Note that we've already got mm0/mm2 & mm1/mm3 preloaded
+       # from the main loop.
+
+       movq    %mm0, %mm4
+       movq    %mm1, %mm5
+       punpckhdq       %mm4, %mm4
+       punpckhdq       %mm5, %mm5
+       punpckldq       %mm0, %mm4
+       pfmul   %mm2, %mm0
+       punpckldq       %mm1, %mm5
+       pfmul   %mm4, %mm2
+       pfadd   %mm0, %mm6
+       pfmul   %mm3, %mm1
+       pfadd   %mm2, %mm7
+       pfmul   %mm5, %mm3
+       pfadd   %mm1, %mm6
+       pfadd   %mm3, %mm7
+
+.Leven:
+       # mmNP: negative inversor
+
+       pcmpeqd %mm0, %mm0              # set all bits to 1
+       psllq   $63, %mm0               # keep only hsb
+
+       pxor    %mm0, %mm6
+       pfacc   %mm7, %mm6
+
+       movl    20(%ebp), %eax          # result
+       movq    %mm6, (%eax)
+
+       femms
+
+       popl    %ebp
+       ret
+
+FUNC_TAIL(ccomplex_dotprod_3dnow)
+       .ident  "Hand coded x86 3DNow! assembly"
+
diff --git a/gnuradio-core/src/lib/filter/ccomplex_dotprod_3dnow64.S b/gnuradio-core/src/lib/filter/ccomplex_dotprod_3dnow64.S
new file mode 100644 (file)
index 0000000..bff045e
--- /dev/null
@@ -0,0 +1,213 @@
+#
+# Copyright 2002,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 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.
+# 
+
+
+# input and taps are guarenteed to be 16 byte aligned.
+# n_2_ccomplex_blocks is != 0
+#      
+#
+#  ccomplex_dotprod_generic (const float *input,
+#                         const float *taps, unsigned n_2_ccomplex_blocks, float *result)
+#  {
+#    float sum0 = 0;
+#    float sum1 = 0;
+#    float sum2 = 0;
+#    float sum3 = 0;
+#  
+#    do {
+#  
+#      sum0 += input[0] * taps[0] - input[1] * taps[1];
+#      sum1 += input[0] * taps[1] + input[1] * taps[0];
+#      sum2 += input[2] * taps[2] - input[3] * taps[3];
+#      sum3 += input[2] * taps[3] + input[3] * taps[2];
+#  
+#      input += 4;
+#      taps += 4;
+#  
+#    } while (--n_2_ccomplex_blocks != 0);
+#  
+#  
+#    result[0] = sum0 + sum2;
+#    result[1] = sum1 + sum3;
+#  }
+#              
+
+# TODO: prefetch and better scheduling
+
+#include "assembly.h"
+
+
+       .file   "ccomplex_dotprod_3dnow64.S"
+       .version        "01.01"
+.text
+       .p2align 4
+.globl GLOB_SYMB(ccomplex_dotprod_3dnow)
+       DEF_FUNC_HEAD(ccomplex_dotprod_3dnow)
+GLOB_SYMB(ccomplex_dotprod_3dnow):
+
+       # intput: rdi, taps: rsi, n_2_ccomplex_blocks: rdx, result: rcx
+
+       mov     %rdx, %rax
+
+       # zero accumulators
+       
+       pxor    %mm6, %mm6              # mm6 = 0 0 
+
+       movq    0(%rdi), %mm0
+
+       pxor    %mm7, %mm7              # mm7 = 0 0 
+
+       movq    0(%rsi), %mm2
+
+       movq    8(%rdi), %mm1
+
+       shr     $1, %rax                # rax = n_2_ccomplex_blocks / 2
+
+       movq    8(%rsi), %mm3
+
+       jmp     .L1_test
+
+       #
+       # 4 taps / loop
+       # something like ?? cycles / loop
+       #
+       
+       .p2align 4
+.loop1:        
+
+# complex prod: C += A * B,  w/ temp Z, mmPN=$80000000
+#
+#       movq    (%rdx), %mmA
+#       movq    (%rsi), %mmB
+#
+#      # 3DNow! replacement for: pswapd  %mmA, %mmZ
+#      # TODO: optimize the punpckhdq
+#      movq    %mmA, %mmZ
+#      punpckhdq       %mmZ, %mmZ
+#      punpckldq       %mmA, %mmZ
+#
+#       pfmul   %mmB, %mmA
+#       pfmul   %mmZ, %mmB
+#
+#      # 3DNow! replacement for: pfpnacc %mmB, %mmA
+#      pxor    %mmPN, %mmA
+#      pfacc   %mmB, %mmA
+#
+#       pfadd   %mmA, %mmC
+
+
+# A=mm0, B=mm2, Z=mm4
+# A'=mm1, B'=mm3, Z'=mm5
+
+       movq    %mm0, %mm4
+       movq    %mm1, %mm5
+       punpckhdq       %mm4, %mm4
+       punpckhdq       %mm5, %mm5
+       punpckldq       %mm0, %mm4
+       pfmul   %mm2, %mm0
+       punpckldq       %mm1, %mm5
+       pfmul   %mm4, %mm2
+       pfadd   %mm0, %mm6
+       movq    16(%rsi), %mm0
+       pfmul   %mm3, %mm1
+       pfadd   %mm2, %mm7
+       movq    16(%rdi), %mm2
+       pfadd   %mm1, %mm6
+       pfmul   %mm5, %mm3
+       movq    24(%rsi), %mm1
+
+       movq    %mm0, %mm4
+       movq    %mm1, %mm5
+
+       pfadd   %mm3, %mm7
+       movq    24(%rdi), %mm3
+
+# unroll
+
+       punpckhdq       %mm4, %mm4
+       punpckhdq       %mm5, %mm5
+       punpckldq       %mm0, %mm4
+       pfmul   %mm2, %mm0
+       punpckldq       %mm1, %mm5
+       pfmul   %mm4, %mm2
+       pfadd   %mm0, %mm6
+       movq    32(%rsi), %mm0
+       pfmul   %mm3, %mm1
+       pfadd   %mm2, %mm7
+       movq    32(%rdi), %mm2
+       pfadd   %mm1, %mm6
+       pfmul   %mm5, %mm3
+       movq    40(%rsi), %mm1
+
+       add     $32, %rdi
+       add     $32, %rsi
+
+       pfadd   %mm3, %mm7
+       movq    8(%rdi), %mm3
+
+.L1_test:
+       dec     %rax
+       jge     .loop1
+
+       # We've handled the bulk of multiplies up to here.
+       # Let's see if original n_2_ccomplex_blocks was odd.
+       # If so, we've got 2 more taps to do.
+       
+       and     $1, %rdx
+       je      .Leven
+       
+       # The count was odd, do 2 more taps.
+       # Note that we've already got mm0/mm2 & mm1/mm3 preloaded
+       # from the main loop.
+
+       movq    %mm0, %mm4
+       movq    %mm1, %mm5
+       punpckhdq       %mm4, %mm4
+       punpckhdq       %mm5, %mm5
+       punpckldq       %mm0, %mm4
+       pfmul   %mm2, %mm0
+       punpckldq       %mm1, %mm5
+       pfmul   %mm4, %mm2
+       pfadd   %mm0, %mm6
+       pfmul   %mm3, %mm1
+       pfadd   %mm2, %mm7
+       pfmul   %mm5, %mm3
+       pfadd   %mm1, %mm6
+       pfadd   %mm3, %mm7
+
+.Leven:
+       # mmNP: negative inversor
+
+       pcmpeqd %mm0, %mm0              # set all bits to 1
+       psllq   $63, %mm0               # keep only hsb
+
+       pxor    %mm0, %mm6
+       pfacc   %mm7, %mm6
+
+       movq    %mm6, (%rcx)
+
+       femms
+
+       retq
+
+FUNC_TAIL(ccomplex_dotprod_3dnow)
+       .ident  "Hand coded x86_64 3DNow! assembly"
+
diff --git a/gnuradio-core/src/lib/filter/ccomplex_dotprod_3dnowext.S b/gnuradio-core/src/lib/filter/ccomplex_dotprod_3dnowext.S
new file mode 100644 (file)
index 0000000..39057e4
--- /dev/null
@@ -0,0 +1,191 @@
+#
+# 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 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.
+# 
+
+
+# input and taps are guarenteed to be 16 byte aligned.
+# n_2_ccomplex_blocks is != 0
+#      
+#
+#  ccomplex_dotprod_generic (const float *input,
+#                         const float *taps, unsigned n_2_ccomplex_blocks, float *result)
+#  {
+#    float sum0 = 0;
+#    float sum1 = 0;
+#    float sum2 = 0;
+#    float sum3 = 0;
+#  
+#    do {
+#  
+#      sum0 += input[0] * taps[0] - input[1] * taps[1];
+#      sum1 += input[0] * taps[1] + input[1] * taps[0];
+#      sum2 += input[2] * taps[2] - input[3] * taps[3];
+#      sum3 += input[2] * taps[3] + input[3] * taps[2];
+#  
+#      input += 4;
+#      taps += 4;
+#  
+#    } while (--n_2_ccomplex_blocks != 0);
+#  
+#  
+#    result[0] = sum0 + sum2;
+#    result[1] = sum1 + sum3;
+#  }
+#              
+
+# TODO: prefetch and better scheduling
+
+#include "assembly.h"
+
+       .file   "ccomplex_dotprod_3dnowext.S"
+       .version        "01.01"
+.text
+       .p2align 4
+.globl GLOB_SYMB(ccomplex_dotprod_3dnowext)
+       DEF_FUNC_HEAD(ccomplex_dotprod_3dnowext)
+GLOB_SYMB(ccomplex_dotprod_3dnowext):
+       pushl   %ebp
+       movl    %esp, %ebp
+       movl    8(%ebp), %eax           # input
+       movl    12(%ebp), %edx          # taps
+       movl    16(%ebp), %ecx          # n_2_ccomplex_blocks
+
+       # zero accumulators
+       
+       pxor    %mm6, %mm6              # mm6 = 0 0 
+       pxor    %mm7, %mm7              # mm7 = 0 0
+
+       movq    0(%eax), %mm0
+       movq    0(%edx), %mm2
+
+       shrl    $1, %ecx                # ecx = n_2_ccomplex_blocks / 2
+
+       movq    8(%eax), %mm1
+       movq    8(%edx), %mm3
+       
+
+       jmp     .L1_test
+
+       #
+       # 4 taps / loop
+       # something like ?? cycles / loop
+       #
+       
+       .p2align 4
+.loop1:        
+
+# complex prod: C += A * B,  w/ temp Z
+#
+#      movq    0(%eax), %mmA
+#      movq    0(%edx), %mmB
+#      pswapd  %mmA, %mmZ
+#      pfmul   %mmB, %mmA
+#      pfmul   %mmZ, %mmB
+#      pfpnacc %mmB, %mmA
+#      pfadd   %mmA, %mmC
+
+
+# A=mm0, B=mm2, Z=mm4
+# A'=mm1, B'=mm3, Z'=mm5
+
+       pswapd  %mm0, %mm4
+       pfmul   %mm2, %mm0
+       pswapd  %mm1, %mm5
+       pfmul   %mm4, %mm2
+       pfmul   %mm3, %mm1
+       pfpnacc %mm2, %mm0
+       pfmul   %mm5, %mm3
+       movq    16(%edx), %mm2
+       pfpnacc %mm3, %mm1
+       movq    24(%edx), %mm3
+
+       pfadd   %mm0, %mm6
+       movq    16(%eax), %mm0
+       pfadd   %mm1, %mm7
+       movq    24(%eax), %mm1
+
+# unroll
+
+       pswapd  %mm0, %mm4
+       pfmul   %mm2, %mm0
+       pswapd  %mm1, %mm5
+       pfmul   %mm4, %mm2
+       pfmul   %mm3, %mm1
+       pfpnacc %mm2, %mm0
+       pfmul   %mm5, %mm3
+       movq    32(%edx), %mm2
+       pfpnacc %mm3, %mm1
+       movq    40(%edx), %mm3
+
+       pfadd   %mm0, %mm6
+       movq    32(%eax), %mm0
+       pfadd   %mm1, %mm7
+       movq    40(%eax), %mm1
+
+       addl    $32, %edx
+       addl    $32, %eax
+
+.L1_test:
+       decl    %ecx
+       jge     .loop1
+
+       # We've handled the bulk of multiplies up to here.
+       # Let's see if original n_2_ccomplex_blocks was odd.
+       # If so, we've got 2 more taps to do.
+       
+       movl    16(%ebp), %ecx          # n_2_ccomplex_blocks
+       andl    $1, %ecx
+       je      .Leven
+       
+       # The count was odd, do 2 more taps.
+       # Note that we've already got mm0/mm2 & mm1/mm3 preloaded
+       # from the main loop.
+       
+# A=mm0, B=mm2, Z=mm4
+# A'=mm1, B'=mm3, Z'=mm5
+
+       pswapd  %mm0, %mm4
+       pfmul   %mm2, %mm0
+       pswapd  %mm1, %mm5
+       pfmul   %mm4, %mm2
+       pfmul   %mm3, %mm1
+       pfpnacc %mm2, %mm0
+       pfmul   %mm5, %mm3
+       pfpnacc %mm3, %mm1
+
+       pfadd   %mm0, %mm6
+       pfadd   %mm1, %mm7
+
+.Leven:
+       # at this point mm6 and mm7 contain partial sums
+       
+       pfadd   %mm7, %mm6
+
+       movl    20(%ebp), %eax          # result
+       movq    %mm6, (%eax)
+
+       femms
+
+       popl    %ebp
+       ret
+
+FUNC_TAIL(ccomplex_dotprod_3dnowext)
+       .ident  "Hand coded x86 3DNow!Ext assembly"
+
diff --git a/gnuradio-core/src/lib/filter/ccomplex_dotprod_3dnowext64.S b/gnuradio-core/src/lib/filter/ccomplex_dotprod_3dnowext64.S
new file mode 100644 (file)
index 0000000..c6f907c
--- /dev/null
@@ -0,0 +1,188 @@
+#
+# Copyright 2002,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 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.
+# 
+
+
+# input and taps are guarenteed to be 16 byte aligned.
+# n_2_ccomplex_blocks is != 0
+#      
+#
+#  ccomplex_dotprod_generic (const float *input,
+#                         const float *taps, unsigned n_2_ccomplex_blocks, float *result)
+#  {
+#    float sum0 = 0;
+#    float sum1 = 0;
+#    float sum2 = 0;
+#    float sum3 = 0;
+#  
+#    do {
+#  
+#      sum0 += input[0] * taps[0] - input[1] * taps[1];
+#      sum1 += input[0] * taps[1] + input[1] * taps[0];
+#      sum2 += input[2] * taps[2] - input[3] * taps[3];
+#      sum3 += input[2] * taps[3] + input[3] * taps[2];
+#  
+#      input += 4;
+#      taps += 4;
+#  
+#    } while (--n_2_ccomplex_blocks != 0);
+#  
+#  
+#    result[0] = sum0 + sum2;
+#    result[1] = sum1 + sum3;
+#  }
+#              
+
+# TODO: prefetch and better scheduling
+
+#include "assembly.h"
+
+       .file   "ccomplex_dotprod_3dnowext64.S"
+       .version        "01.01"
+.text
+       .p2align 4
+.globl GLOB_SYMB(ccomplex_dotprod_3dnowext)
+       DEF_FUNC_HEAD(ccomplex_dotprod_3dnowext)
+GLOB_SYMB(ccomplex_dotprod_3dnowext):
+
+       # intput: rdi, taps: rsi, n_2_ccomplex_blocks: rdx, result: rcx
+
+       mov     %rdx, %rax
+
+
+       # zero accumulators
+       
+       pxor    %mm6, %mm6              # mm6 = 0 0 
+       pxor    %mm7, %mm7              # mm7 = 0 0
+
+       movq    0(%rdi), %mm0
+       movq    0(%rsi), %mm2
+
+       shr     $1, %rax                # rax = n_2_ccomplex_blocks / 2
+
+       movq    8(%rdi), %mm1
+       movq    8(%rsi), %mm3
+       
+
+       jmp     .L1_test
+
+       #
+       # 4 taps / loop
+       # something like ?? cycles / loop
+       #
+       
+       .p2align 4
+.loop1:        
+
+# complex prod: C += A * B,  w/ temp Z
+#
+#      movq    0(%rdi), %mmA
+#      movq    0(%rsi), %mmB
+#      pswapd  %mmA, %mmZ
+#      pfmul   %mmB, %mmA
+#      pfmul   %mmZ, %mmB
+#      pfpnacc %mmB, %mmA
+#      pfadd   %mmA, %mmC
+
+
+# A=mm0, B=mm2, Z=mm4
+# A'=mm1, B'=mm3, Z'=mm5
+
+       pswapd  %mm0, %mm4
+       pfmul   %mm2, %mm0
+       pswapd  %mm1, %mm5
+       pfmul   %mm4, %mm2
+       pfmul   %mm3, %mm1
+       pfpnacc %mm2, %mm0
+       pfmul   %mm5, %mm3
+       movq    16(%rsi), %mm2
+       pfpnacc %mm3, %mm1
+       movq    24(%rsi), %mm3
+
+       pfadd   %mm0, %mm6
+       movq    16(%rdi), %mm0
+       pfadd   %mm1, %mm7
+       movq    24(%rdi), %mm1
+
+# unroll
+
+       pswapd  %mm0, %mm4
+       pfmul   %mm2, %mm0
+       pswapd  %mm1, %mm5
+       pfmul   %mm4, %mm2
+       pfmul   %mm3, %mm1
+       pfpnacc %mm2, %mm0
+       pfmul   %mm5, %mm3
+       movq    32(%rsi), %mm2
+       pfpnacc %mm3, %mm1
+       movq    40(%rsi), %mm3
+
+       pfadd   %mm0, %mm6
+       movq    32(%rdi), %mm0
+       pfadd   %mm1, %mm7
+       movq    40(%rdi), %mm1
+
+       add     $32, %rsi
+       add     $32, %rdi
+
+.L1_test:
+       dec     %rax
+       jge     .loop1
+
+       # We've handled the bulk of multiplies up to here.
+       # Let's see if original n_2_ccomplex_blocks was odd.
+       # If so, we've got 2 more taps to do.
+       
+       and     $1, %rdx
+       je      .Leven
+       
+       # The count was odd, do 2 more taps.
+       # Note that we've already got mm0/mm2 & mm1/mm3 preloaded
+       # from the main loop.
+       
+# A=mm0, B=mm2, Z=mm4
+# A'=mm1, B'=mm3, Z'=mm5
+
+       pswapd  %mm0, %mm4
+       pfmul   %mm2, %mm0
+       pswapd  %mm1, %mm5
+       pfmul   %mm4, %mm2
+       pfmul   %mm3, %mm1
+       pfpnacc %mm2, %mm0
+       pfmul   %mm5, %mm3
+       pfpnacc %mm3, %mm1
+
+       pfadd   %mm0, %mm6
+       pfadd   %mm1, %mm7
+
+.Leven:
+       # at this point mm6 and mm7 contain partial sums
+       
+       pfadd   %mm7, %mm6
+
+       movq    %mm6, (%rcx)            # result
+
+       femms
+
+       retq
+
+FUNC_TAIL(ccomplex_dotprod_3dnowext)
+       .ident  "Hand coded x86_64 3DNow!Ext assembly"
+
diff --git a/gnuradio-core/src/lib/filter/ccomplex_dotprod_generic.cc b/gnuradio-core/src/lib/filter/ccomplex_dotprod_generic.cc
new file mode 100644 (file)
index 0000000..edd5b1b
--- /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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <gr_complex.h>
+#include "gr_fir_ccc_simd.h"
+#include "ccomplex_dotprod_generic.h"
+
+#include <iostream>
+
+void
+ccomplex_dotprod_generic (const float *input,
+                      const float *taps, unsigned n_2_ccomplex_blocks,
+                      float *result)
+{
+  gr_complex sum0(0,0);
+  gr_complex sum1(0,0);
+
+  std::cerr << "Blah!!!\n";
+  do {
+    const gr_complex tap0(taps[0], taps[1]);
+    const gr_complex tap1(taps[2], taps[3]);
+    const gr_complex input0(input[0], input[1]);
+    const gr_complex input1(input[2], input[3]);
+
+    sum0 += input0 * tap0;
+    sum1 += input1 * tap1;
+
+    input += 8;
+    taps += 8;
+
+  } while (--n_2_ccomplex_blocks != 0);
+
+
+  sum0 += sum1;
+  result[0] = sum0.real();
+  result[1] = sum0.imag();
+}
diff --git a/gnuradio-core/src/lib/filter/ccomplex_dotprod_generic.h b/gnuradio-core/src/lib/filter/ccomplex_dotprod_generic.h
new file mode 100644 (file)
index 0000000..70d3b6b
--- /dev/null
@@ -0,0 +1,32 @@
+/* -*- 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 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.
+ */
+
+#ifndef _CCOMPLEX_DOTPROD_GENERIC_H_
+#define _CCOMPLEX_DOTPROD_GENERIC_H_
+
+void
+ccomplex_dotprod_generic (const float *input,
+                      const float *taps, unsigned n_2_ccomplex_blocks,
+                      float *result);
+
+
+#endif /* _CCOMPLEX_DOTPROD_GENERIC_H_ */
diff --git a/gnuradio-core/src/lib/filter/ccomplex_dotprod_sse.S b/gnuradio-core/src/lib/filter/ccomplex_dotprod_sse.S
new file mode 100644 (file)
index 0000000..a16d053
--- /dev/null
@@ -0,0 +1,194 @@
+#
+# 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 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.
+# 
+
+
+# input and taps are guarenteed to be 16 byte aligned.
+# n_2_ccomplex_blocks is != 0
+#      
+#
+#  ccomplex_dotprod_generic (const float *input,
+#                         const float *taps, unsigned n_2_ccomplex_blocks, float *result)
+#  {
+#    float sum0 = 0;
+#    float sum1 = 0;
+#    float sum2 = 0;
+#    float sum3 = 0;
+#  
+#    do {
+#
+#      sum0 += input[0] * taps[0] - input[1] * taps[1];
+#      sum1 += input[0] * taps[1] + input[1] * taps[0];
+#      sum2 += input[2] * taps[2] - input[3] * taps[3];
+#      sum3 += input[2] * taps[3] + input[3] * taps[2];
+#  
+#      input += 4;
+#      taps += 4;  
+#  
+#    } while (--n_2_ccomplex_blocks != 0);
+#  
+#  
+#    result[0] = sum0 + sum2;
+#    result[1] = sum1 + sum3;
+#  }
+#
+
+# TODO: prefetch and better scheduling
+
+#include "assembly.h"
+
+       .file   "ccomplex_dotprod_sse.S"
+       .version        "01.01"
+.text
+       .p2align 4
+.globl GLOB_SYMB(ccomplex_dotprod_sse)
+       DEF_FUNC_HEAD(ccomplex_dotprod_sse)
+GLOB_SYMB(ccomplex_dotprod_sse):
+       pushl   %ebp
+       movl    %esp, %ebp
+       movl    8(%ebp), %eax           # input
+       movl    12(%ebp), %edx          # taps
+       movl    16(%ebp), %ecx          # n_2_ccomplex_blocks
+
+       xorps   %xmm6, %xmm6            # zero accumulators
+       
+       movaps  0(%eax), %xmm0
+
+       xorps   %xmm7, %xmm7            # zero accumulators
+
+       movaps  0(%edx), %xmm2
+
+       shrl    $1, %ecx                # ecx = n_2_ccomplex_blocks / 2
+
+       jmp     .L1_test
+
+       #
+       # 4 taps / loop
+       # something like ?? cycles / loop
+       #
+       
+       .p2align 4
+.loop1:        
+
+# complex prod: C += A * B,  w/ temp Z & Y (or B), xmmPN=$0x8000000080000000
+#
+#      movaps  (%eax), %xmmA
+#      movaps  (%edx), %xmmB
+#
+#      movaps  %xmmA, %xmmZ
+#      shufps  $0xb1, %xmmZ, %xmmZ     # swap internals
+#
+#      mulps   %xmmB, %xmmA
+#      mulps   %xmmZ, %xmmB
+#
+#      # SSE replacement for: pfpnacc %xmmB, %xmmA
+#      xorps   %xmmPN, %xmmA
+#      movaps  %xmmA, %xmmZ
+#      unpcklps %xmmB, %xmmA
+#      unpckhps %xmmB, %xmmZ
+#      movaps  %xmmZ, %xmmY
+#      shufps  $0x44, %xmmA, %xmmZ     # b01000100
+#      shufps  $0xee, %xmmY, %xmmA     # b11101110
+#      addps   %xmmZ, %xmmA
+#
+#      addps   %xmmA, %xmmC
+
+# A=xmm0, B=xmm2, Z=xmm4
+# A'=xmm1, B'=xmm3, Z'=xmm5
+
+       movaps  16(%eax), %xmm1
+
+       movaps  %xmm0, %xmm4
+       mulps   %xmm2, %xmm0
+
+       shufps  $0xb1, %xmm4, %xmm4     # swap internals
+       movaps  16(%edx), %xmm3
+       movaps  %xmm1, %xmm5
+       addps   %xmm0, %xmm6
+       mulps   %xmm3, %xmm1
+       shufps  $0xb1, %xmm5, %xmm5     # swap internals
+       addps   %xmm1, %xmm6
+       mulps   %xmm4, %xmm2
+       movaps  32(%eax), %xmm0
+       addps   %xmm2, %xmm7
+       mulps   %xmm5, %xmm3
+
+       addl    $32, %eax
+
+       movaps  32(%edx), %xmm2
+       addps   %xmm3, %xmm7
+
+       addl    $32, %edx
+
+
+
+.L1_test:
+       decl    %ecx
+       jge     .loop1
+
+       # We've handled the bulk of multiplies up to here.
+       # Let's sse if original n_2_ccomplex_blocks was odd.
+       # If so, we've got 2 more taps to do.
+       
+       movl    16(%ebp), %ecx          # n_2_ccomplex_blocks
+       andl    $1, %ecx
+       je      .Leven
+       
+       # The count was odd, do 2 more taps.
+       # Note that we've already got mm0/mm2 preloaded
+       # from the main loop.
+
+       movaps  %xmm0, %xmm4
+       mulps   %xmm2, %xmm0
+       shufps  $0xb1, %xmm4, %xmm4     # swap internals
+       addps   %xmm0, %xmm6
+       mulps   %xmm4, %xmm2
+       addps   %xmm2, %xmm7
+
+
+.Leven:
+       # neg inversor
+       xorps   %xmm1, %xmm1
+       movl    $0x80000000, 16(%ebp)
+       movss   16(%ebp), %xmm1
+       shufps  $0x11, %xmm1, %xmm1     # b00010001 # 0 -0 0 -0
+
+       # pfpnacc
+       xorps   %xmm1, %xmm6
+
+       movaps  %xmm6, %xmm2
+       unpcklps %xmm7, %xmm6
+       unpckhps %xmm7, %xmm2
+       movaps  %xmm2, %xmm3
+       shufps  $0x44, %xmm6, %xmm2     # b01000100
+       shufps  $0xee, %xmm3, %xmm6     # b11101110
+       addps   %xmm2, %xmm6
+
+                                       # xmm6 = r1 i2 r3 i4
+       movl    20(%ebp), %eax          # @result
+       movhlps %xmm6, %xmm4            # xmm4 = r3 i4 ?? ??
+       addps   %xmm4, %xmm6            # xmm6 = r1+r3 i2+i4 ?? ??
+       movlps  %xmm6, (%eax)           # store low 2x32 bits (complex) to memory
+
+       popl    %ebp
+       ret
+
+FUNC_TAIL(ccomplex_dotprod_sse)
+       .ident  "Hand coded x86 SSE assembly"
diff --git a/gnuradio-core/src/lib/filter/ccomplex_dotprod_sse64.S b/gnuradio-core/src/lib/filter/ccomplex_dotprod_sse64.S
new file mode 100644 (file)
index 0000000..216df6e
--- /dev/null
@@ -0,0 +1,191 @@
+#
+# Copyright 2002,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 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.
+# 
+
+
+# input and taps are guarenteed to be 16 byte aligned.
+# n_2_ccomplex_blocks is != 0
+#      
+#
+#  ccomplex_dotprod_generic (const float *input,
+#                         const float *taps, unsigned n_2_ccomplex_blocks, float *result)
+#  {
+#    float sum0 = 0;
+#    float sum1 = 0;
+#    float sum2 = 0;
+#    float sum3 = 0;
+#  
+#    do {
+#
+#      sum0 += input[0] * taps[0] - input[1] * taps[1];
+#      sum1 += input[0] * taps[1] + input[1] * taps[0];
+#      sum2 += input[2] * taps[2] - input[3] * taps[3];
+#      sum3 += input[2] * taps[3] + input[3] * taps[2];
+#  
+#      input += 4;
+#      taps += 4;  
+#  
+#    } while (--n_2_ccomplex_blocks != 0);
+#  
+#  
+#    result[0] = sum0 + sum2;
+#    result[1] = sum1 + sum3;
+#  }
+#
+
+# TODO: prefetch and better scheduling
+
+#include "assembly.h"
+
+
+       .file   "ccomplex_dotprod_sse64.S"
+       .version        "01.01"
+.text
+       .p2align 4
+.globl GLOB_SYMB(ccomplex_dotprod_sse)
+       DEF_FUNC_HEAD(ccomplex_dotprod_sse)
+GLOB_SYMB(ccomplex_dotprod_sse):
+
+       # intput: rdi, taps: rsi, n_2_ccomplex_blocks: rdx, result: rcx
+
+       mov     %rdx, %rax
+
+       xorps   %xmm6, %xmm6            # zero accumulators
+       
+       movaps  0(%rdi), %xmm0
+
+       xorps   %xmm7, %xmm7            # zero accumulators
+
+       movaps  0(%rsi), %xmm2
+
+       shr     $1, %rax                # rax = n_2_ccomplex_blocks / 2
+
+       jmp     .L1_test
+
+       #
+       # 4 taps / loop
+       # something like ?? cycles / loop
+       #
+       
+       .p2align 4
+.loop1:        
+
+# complex prod: C += A * B,  w/ temp Z & Y (or B), xmmPN=$0x8000000080000000
+#
+#      movaps  (%rdi), %xmmA
+#      movaps  (%rsi), %xmmB
+#
+#      movaps  %xmmA, %xmmZ
+#      shufps  $0xb1, %xmmZ, %xmmZ     # swap internals
+#
+#      mulps   %xmmB, %xmmA
+#      mulps   %xmmZ, %xmmB
+#
+#      # SSE replacement for: pfpnacc %xmmB, %xmmA
+#      xorps   %xmmPN, %xmmA
+#      movaps  %xmmA, %xmmZ
+#      unpcklps %xmmB, %xmmA
+#      unpckhps %xmmB, %xmmZ
+#      movaps  %xmmZ, %xmmY
+#      shufps  $0x44, %xmmA, %xmmZ     # b01000100
+#      shufps  $0xee, %xmmY, %xmmA     # b11101110
+#      addps   %xmmZ, %xmmA
+#
+#      addps   %xmmA, %xmmC
+
+# A=xmm0, B=xmm2, Z=xmm4
+# A'=xmm1, B'=xmm3, Z'=xmm5
+
+       movaps  16(%rdi), %xmm1
+
+       movaps  %xmm0, %xmm4
+       mulps   %xmm2, %xmm0
+
+       shufps  $0xb1, %xmm4, %xmm4     # swap internals
+       movaps  16(%rsi), %xmm3
+       movaps  %xmm1, %xmm5
+       addps   %xmm0, %xmm6
+       mulps   %xmm3, %xmm1
+       shufps  $0xb1, %xmm5, %xmm5     # swap internals
+       addps   %xmm1, %xmm6
+       mulps   %xmm4, %xmm2
+       movaps  32(%rdi), %xmm0
+       addps   %xmm2, %xmm7
+       mulps   %xmm5, %xmm3
+
+       add     $32, %rdi
+
+       movaps  32(%rsi), %xmm2
+       addps   %xmm3, %xmm7
+
+       add     $32, %rsi
+
+
+
+.L1_test:
+       dec     %rax
+       jge     .loop1
+
+       # We've handled the bulk of multiplies up to here.
+       # Let's sse if original n_2_ccomplex_blocks was odd.
+       # If so, we've got 2 more taps to do.
+       
+       and     $1, %rdx
+       je      .Leven
+       
+       # The count was odd, do 2 more taps.
+       # Note that we've already got mm0/mm2 preloaded
+       # from the main loop.
+
+       movaps  %xmm0, %xmm4
+       mulps   %xmm2, %xmm0
+       shufps  $0xb1, %xmm4, %xmm4     # swap internals
+       addps   %xmm0, %xmm6
+       mulps   %xmm4, %xmm2
+       addps   %xmm2, %xmm7
+
+
+.Leven:
+       # neg inversor
+       xorps   %xmm1, %xmm1
+       movl    $0x80000000, -8(%rsp)
+       movss   -8(%rsp), %xmm1
+       shufps  $0x11, %xmm1, %xmm1     # b00010001 # 0 -0 0 -0
+
+       # pfpnacc
+       xorps   %xmm1, %xmm6
+
+       movaps  %xmm6, %xmm2
+       unpcklps %xmm7, %xmm6
+       unpckhps %xmm7, %xmm2
+       movaps  %xmm2, %xmm3
+       shufps  $0x44, %xmm6, %xmm2     # b01000100
+       shufps  $0xee, %xmm3, %xmm6     # b11101110
+       addps   %xmm2, %xmm6
+
+                                       # xmm6 = r1 i2 r3 i4
+       movhlps %xmm6, %xmm4            # xmm4 = r3 i4 ?? ??
+       addps   %xmm4, %xmm6            # xmm6 = r1+r3 i2+i4 ?? ??
+       movlps  %xmm6, (%rcx)           # store low 2x32 bits (complex) to memory
+
+       retq
+
+FUNC_TAIL(ccomplex_dotprod_sse)
+       .ident  "Hand coded x86_64 SSE assembly"
diff --git a/gnuradio-core/src/lib/filter/ccomplex_dotprod_x86.h b/gnuradio-core/src/lib/filter/ccomplex_dotprod_x86.h
new file mode 100644 (file)
index 0000000..0a8c736
--- /dev/null
@@ -0,0 +1,46 @@
+/* -*- 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 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.
+ */
+
+#ifndef _CCOMPLEX_DOTPROD_X86_H_
+#define _CCOMPLEX_DOTPROD_X86_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void
+ccomplex_dotprod_3dnow (const float *input,
+                    const float *taps, unsigned n_2_ccomplex_blocks, float *result);
+
+void
+ccomplex_dotprod_3dnowext (const float *input,
+                    const float *taps, unsigned n_2_ccomplex_blocks, float *result);
+
+void
+ccomplex_dotprod_sse (const float *input,
+                  const float *taps, unsigned n_2_ccomplex_blocks, float *result);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _CCOMPLEX_DOTPROD_X86_H_ */
diff --git a/gnuradio-core/src/lib/filter/complex_dotprod_3dnow.S b/gnuradio-core/src/lib/filter/complex_dotprod_3dnow.S
new file mode 100644 (file)
index 0000000..37608ec
--- /dev/null
@@ -0,0 +1,188 @@
+#
+# 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 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.
+# 
+
+
+# input and taps are guarenteed to be 16 byte aligned.
+# n_2_complex_blocks is != 0
+#      
+#
+#  complex_dotprod_generic (const short *input,
+#                         const float *taps, unsigned n_2_complex_blocks, float *result)
+#  {
+#    float sum0 = 0;
+#    float sum1 = 0;
+#    float sum2 = 0;
+#    float sum3 = 0;
+#  
+#    do {
+#  
+#      sum0 += input[0] * taps[0];
+#      sum1 += input[0] * taps[1];
+#      sum2 += input[1] * taps[2];
+#      sum3 += input[1] * taps[3];
+#  
+#      input += 2;
+#      taps += 4;
+#  
+#    } while (--n_2_complex_blocks != 0);
+#  
+#  
+#    result[0] = sum0 + sum2;
+#    result[1] = sum1 + sum3;
+#  }
+#              
+
+#include "assembly.h"
+
+       .file   "complex_dotprod_3dnow.S"
+       .version        "01.01"
+.text
+       .p2align 4
+.globl GLOB_SYMB(complex_dotprod_3dnow)
+       DEF_FUNC_HEAD(complex_dotprod_3dnow)
+GLOB_SYMB(complex_dotprod_3dnow):
+       pushl   %ebp
+       movl    %esp, %ebp
+       movl    8(%ebp), %eax           # input
+       movl    12(%ebp), %edx          # taps
+       movl    16(%ebp), %ecx
+
+       # zero accumulators
+       
+       pxor    %mm4, %mm4              # mm4 = 0 0
+       pxor    %mm5, %mm5              # mm5 = 0 0 
+       pxor    %mm6, %mm6              # mm6 = 0 0 
+       pxor    %mm7, %mm7              # mm7 = 0 0
+
+
+       shrl    $1, %ecx                # ecx = n_2_complex_blocks / 2
+
+       # pshufw & pi2fw
+       pxor    %mm0, %mm0
+       punpcklwd       0(%eax), %mm0
+       psrad   $16, %mm0
+       punpckldq       %mm0, %mm0
+       pi2fd   %mm0, %mm0
+
+       pxor    %mm1, %mm1
+       punpcklwd       0(%eax), %mm1
+       psrad   $16, %mm1
+       punpckhdq       %mm1, %mm1
+       pi2fd   %mm1, %mm1
+
+       pxor    %mm2, %mm2
+       pxor    %mm3, %mm3
+
+
+       jmp     .L1_test
+
+       #
+       # 4 taps / loop
+       # something like ?? cycles / loop
+       #
+       
+       .p2align 4
+.loop1:        
+       pfmul   0(%edx), %mm0
+       pfadd   %mm2, %mm6
+
+       pxor    %mm2, %mm2
+       punpcklwd       4(%eax), %mm2
+       psrad   $16, %mm2
+       punpckldq       %mm2, %mm2
+
+       pfmul   8(%edx), %mm1
+       pfadd   %mm3, %mm7
+       pi2fd   %mm2, %mm2
+
+       pxor    %mm3, %mm3
+       punpcklwd       4(%eax), %mm3
+       psrad   $16, %mm3
+       punpckhdq       %mm3, %mm3
+
+       pfmul   16(%edx), %mm2
+       pfadd   %mm0, %mm4
+       pi2fd   %mm3, %mm3
+
+       pxor    %mm0, %mm0
+       punpcklwd       8(%eax), %mm0
+       psrad   $16, %mm0
+       punpckldq       %mm0, %mm0
+
+       pfmul   24(%edx), %mm3
+       pfadd   %mm1, %mm5
+
+       pxor    %mm1, %mm1
+       punpcklwd       8(%eax), %mm1
+       psrad   $16, %mm1
+       punpckhdq       %mm1, %mm1
+
+       pi2fd   %mm0, %mm0
+       pi2fd   %mm1, %mm1
+
+#TODO: add prefetch
+
+       addl    $32, %edx
+       addl    $8, %eax
+
+.L1_test:
+       decl    %ecx
+       jge     .loop1
+
+       # We've handled the bulk of multiplies up to here.
+       # Now accumulate the final two additions and see if original
+       # n_2_complex_blocks was odd.  If so, we've got 2 more
+       # taps to do.
+       
+       movl    16(%ebp), %ecx
+       pfadd   %mm2, %mm6
+       andl    $1, %ecx
+       pfadd   %mm3, %mm7
+       je      .Leven
+       
+       # The count was odd, do 2 more taps.
+       # Note that we've already got mm0 and mm1 preloaded
+       # from the main loop.
+       
+       pfmul   0(%edx), %mm0
+       pfadd   %mm0, %mm4
+       pfmul   8(%edx), %mm1
+       pfadd   %mm1, %mm5
+
+.Leven:
+       # at this point mm4, mm5, mm6 and mm7 contain partial sums
+       
+       pfadd   %mm7, %mm6
+       pfadd   %mm5, %mm4
+
+       movl    20(%ebp), %eax          # result
+
+       pfadd   %mm6, %mm4
+
+       movq    %mm4, (%eax)
+       femms
+
+       popl    %ebp
+       ret
+
+FUNC_TAIL(complex_dotprod_3dnow)
+       .ident  "Hand coded x86 3DNow! assembly"
+
diff --git a/gnuradio-core/src/lib/filter/complex_dotprod_3dnow64.S b/gnuradio-core/src/lib/filter/complex_dotprod_3dnow64.S
new file mode 100644 (file)
index 0000000..1413c6c
--- /dev/null
@@ -0,0 +1,183 @@
+#
+# Copyright 2002,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 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.
+# 
+
+
+# input and taps are guarenteed to be 16 byte aligned.
+# n_2_complex_blocks is != 0
+#      
+#
+#  complex_dotprod_generic (const short *input,
+#                         const float *taps, unsigned n_2_complex_blocks, float *result)
+#  {
+#    float sum0 = 0;
+#    float sum1 = 0;
+#    float sum2 = 0;
+#    float sum3 = 0;
+#  
+#    do {
+#  
+#      sum0 += input[0] * taps[0];
+#      sum1 += input[0] * taps[1];
+#      sum2 += input[1] * taps[2];
+#      sum3 += input[1] * taps[3];
+#  
+#      input += 2;
+#      taps += 4;
+#  
+#    } while (--n_2_complex_blocks != 0);
+#  
+#  
+#    result[0] = sum0 + sum2;
+#    result[1] = sum1 + sum3;
+#  }
+#              
+
+#include "assembly.h"
+
+
+       .file   "complex_dotprod_3dnow64.S"
+       .version        "01.01"
+.text
+       .p2align 4
+.globl GLOB_SYMB(complex_dotprod_3dnow)
+       DEF_FUNC_HEAD(complex_dotprod_3dnow)
+GLOB_SYMB(complex_dotprod_3dnow):
+
+       # intput: rdi, taps: rsi, n_2_ccomplex_blocks: rdx, result: rcx
+
+       mov     %rdx, %rax
+
+       # zero accumulators
+       
+       pxor    %mm4, %mm4              # mm4 = 0 0
+       pxor    %mm5, %mm5              # mm5 = 0 0 
+       pxor    %mm6, %mm6              # mm6 = 0 0 
+       pxor    %mm7, %mm7              # mm7 = 0 0
+
+
+       shr     $1, %rax                # rax = n_2_complex_blocks / 2
+
+       # pshufw & pi2fw
+       pxor    %mm0, %mm0
+       punpcklwd       0(%rdi), %mm0
+       psrad   $16, %mm0
+       punpckldq       %mm0, %mm0
+       pi2fd   %mm0, %mm0
+
+       pxor    %mm1, %mm1
+       punpcklwd       0(%rdi), %mm1
+       psrad   $16, %mm1
+       punpckhdq       %mm1, %mm1
+       pi2fd   %mm1, %mm1
+
+       pxor    %mm2, %mm2
+       pxor    %mm3, %mm3
+
+
+       jmp     .L1_test
+
+       #
+       # 4 taps / loop
+       # something like ?? cycles / loop
+       #
+       
+       .p2align 4
+.loop1:        
+       pfmul   0(%rsi), %mm0
+       pfadd   %mm2, %mm6
+
+       pxor    %mm2, %mm2
+       punpcklwd       4(%rdi), %mm2
+       psrad   $16, %mm2
+       punpckldq       %mm2, %mm2
+
+       pfmul   8(%rsi), %mm1
+       pfadd   %mm3, %mm7
+       pi2fd   %mm2, %mm2
+
+       pxor    %mm3, %mm3
+       punpcklwd       4(%rdi), %mm3
+       psrad   $16, %mm3
+       punpckhdq       %mm3, %mm3
+
+       pfmul   16(%rsi), %mm2
+       pfadd   %mm0, %mm4
+       pi2fd   %mm3, %mm3
+
+       pxor    %mm0, %mm0
+       punpcklwd       8(%rdi), %mm0
+       psrad   $16, %mm0
+       punpckldq       %mm0, %mm0
+
+       pfmul   24(%rsi), %mm3
+       pfadd   %mm1, %mm5
+
+       pxor    %mm1, %mm1
+       punpcklwd       8(%rdi), %mm1
+       psrad   $16, %mm1
+       punpckhdq       %mm1, %mm1
+
+       pi2fd   %mm0, %mm0
+       pi2fd   %mm1, %mm1
+
+#TODO: add prefetch
+
+       add     $32, %rsi
+       add     $8, %rdi
+
+.L1_test:
+       dec     %rax
+       jge     .loop1
+
+       # We've handled the bulk of multiplies up to here.
+       # Now accumulate the final two additions and see if original
+       # n_2_complex_blocks was odd.  If so, we've got 2 more
+       # taps to do.
+       
+       pfadd   %mm2, %mm6
+       and     $1, %rdx
+       pfadd   %mm3, %mm7
+       je      .Leven
+       
+       # The count was odd, do 2 more taps.
+       # Note that we've already got mm0 and mm1 preloaded
+       # from the main loop.
+       
+       pfmul   0(%rsi), %mm0
+       pfadd   %mm0, %mm4
+       pfmul   8(%rsi), %mm1
+       pfadd   %mm1, %mm5
+
+.Leven:
+       # at this point mm4, mm5, mm6 and mm7 contain partial sums
+       
+       pfadd   %mm7, %mm6
+       pfadd   %mm5, %mm4
+       pfadd   %mm6, %mm4
+
+       movq    %mm4, (%rcx)
+       femms
+
+       retq
+
+FUNC_TAIL(complex_dotprod_3dnow)
+       .ident  "Hand coded x86_64 3DNow! assembly"
+
diff --git a/gnuradio-core/src/lib/filter/complex_dotprod_3dnowext.S b/gnuradio-core/src/lib/filter/complex_dotprod_3dnowext.S
new file mode 100644 (file)
index 0000000..443949e
--- /dev/null
@@ -0,0 +1,167 @@
+#
+# 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 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.
+# 
+
+
+# input and taps are guarenteed to be 16 byte aligned.
+# n_2_complex_blocks is != 0
+#      
+#
+#  complex_dotprod_generic (const short *input,
+#                         const float *taps, unsigned n_2_complex_blocks, float *result)
+#  {
+#    float sum0 = 0;
+#    float sum1 = 0;
+#    float sum2 = 0;
+#    float sum3 = 0;
+#  
+#    do {
+#  
+#      sum0 += input[0] * taps[0];
+#      sum1 += input[0] * taps[1];
+#      sum2 += input[1] * taps[2];
+#      sum3 += input[1] * taps[3];
+#  
+#      input += 2;
+#      taps += 4;
+#  
+#    } while (--n_2_complex_blocks != 0);
+#  
+#  
+#    result[0] = sum0 + sum2;
+#    result[1] = sum1 + sum3;
+#  }
+#              
+
+#include "assembly.h"
+
+       .file   "complex_dotprod_3dnowext.S"
+       .version        "01.01"
+.text
+       .p2align 4
+.globl GLOB_SYMB(complex_dotprod_3dnowext)
+       DEF_FUNC_HEAD(complex_dotprod_3dnowext)
+GLOB_SYMB(complex_dotprod_3dnowext):
+       pushl   %ebp
+       movl    %esp, %ebp
+       movl    8(%ebp), %eax           # input
+       movl    12(%ebp), %edx          # taps
+       movl    16(%ebp), %ecx
+
+       # zero accumulators
+       
+       pxor    %mm4, %mm4              # mm4 = 0 0
+       pxor    %mm5, %mm5              # mm5 = 0 0 
+       pxor    %mm6, %mm6              # mm6 = 0 0 
+       pxor    %mm7, %mm7              # mm7 = 0 0
+
+
+       shrl    $1, %ecx                # ecx = n_2_complex_blocks / 2
+
+       movd    0(%eax), %mm0
+       pshufw  $0x55, %mm0, %mm1               # b01010101
+       pshufw  $0, %mm0, %mm0
+
+       pxor    %mm2, %mm2
+       pxor    %mm3, %mm3
+
+       pi2fw   %mm1, %mm1
+       pi2fw   %mm0, %mm0
+
+       jmp     .L1_test
+
+       #
+       # 4 taps / loop
+       # something like ?? cycles / loop
+       #
+       
+       .p2align 4
+.loop1:        
+       pfmul   0(%edx), %mm0
+       pfadd   %mm2, %mm6
+
+       pshufw  $0, 4(%eax), %mm2
+
+       pfmul   8(%edx), %mm1
+       pfadd   %mm3, %mm7
+       pi2fw   %mm2, %mm2
+
+       pshufw  $0x55, 4(%eax), %mm3            # b01010101
+
+       pfmul   16(%edx), %mm2
+       pi2fw   %mm3, %mm3
+       pfadd   %mm0, %mm4
+
+       pshufw  $0, 8(%eax), %mm0
+
+       pfmul   24(%edx), %mm3
+       pfadd   %mm1, %mm5
+
+       pshufw  $0x55, 8(%eax), %mm1    # b01010101
+       pi2fw   %mm0, %mm0
+
+#TODO: add prefetch
+
+       addl    $32, %edx
+       addl    $8, %eax
+       pi2fw   %mm1, %mm1
+
+.L1_test:
+       decl    %ecx
+       jge     .loop1
+
+       # We've handled the bulk of multiplies up to here.
+       # Now accumulate the final two additions and see if original
+       # n_2_complex_blocks was odd.  If so, we've got 2 more
+       # taps to do.
+       
+       movl    16(%ebp), %ecx
+       pfadd   %mm2, %mm6
+       andl    $1, %ecx
+       pfadd   %mm3, %mm7
+       je      .Leven
+       
+       # The count was odd, do 2 more taps.
+       # Note that we've already got mm0 and mm1 preloaded
+       # from the main loop.
+       
+       pfmul   0(%edx), %mm0
+       pfadd   %mm0, %mm4
+       pfmul   8(%edx), %mm1
+       pfadd   %mm1, %mm5
+
+.Leven:
+       # at this point mm4, mm5, mm6 and mm7 contain partial sums
+       
+       pfadd   %mm7, %mm6
+       pfadd   %mm5, %mm4
+
+       movl    20(%ebp), %eax          # result
+       pfadd   %mm6, %mm4
+       movq    %mm4, (%eax)
+
+       femms
+
+       popl    %ebp
+       ret
+
+FUNC_TAIL(complex_dotprod_3dnowext)
+       .ident  "Hand coded x86 3DNow!Ext assembly"
+
diff --git a/gnuradio-core/src/lib/filter/complex_dotprod_3dnowext64.S b/gnuradio-core/src/lib/filter/complex_dotprod_3dnowext64.S
new file mode 100644 (file)
index 0000000..195dc37
--- /dev/null
@@ -0,0 +1,164 @@
+#
+# Copyright 2002,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 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.
+# 
+
+
+# input and taps are guarenteed to be 16 byte aligned.
+# n_2_complex_blocks is != 0
+#      
+#
+#  complex_dotprod_generic (const short *input,
+#                         const float *taps, unsigned n_2_complex_blocks, float *result)
+#  {
+#    float sum0 = 0;
+#    float sum1 = 0;
+#    float sum2 = 0;
+#    float sum3 = 0;
+#  
+#    do {
+#  
+#      sum0 += input[0] * taps[0];
+#      sum1 += input[0] * taps[1];
+#      sum2 += input[1] * taps[2];
+#      sum3 += input[1] * taps[3];
+#  
+#      input += 2;
+#      taps += 4;
+#  
+#    } while (--n_2_complex_blocks != 0);
+#  
+#  
+#    result[0] = sum0 + sum2;
+#    result[1] = sum1 + sum3;
+#  }
+#              
+
+#include "assembly.h"
+
+
+       .file   "complex_dotprod_3dnowext64.S"
+       .version        "01.01"
+.text
+       .p2align 4
+.globl GLOB_SYMB(complex_dotprod_3dnowext)
+       DEF_FUNC_HEAD(complex_dotprod_3dnowext)
+GLOB_SYMB(complex_dotprod_3dnowext):
+
+       # intput: rdi, taps: rsi, n_2_ccomplex_blocks: rdx, result: rcx
+
+       mov     %rdx, %rax
+
+       # zero accumulators
+       
+       pxor    %mm4, %mm4              # mm4 = 0 0
+       pxor    %mm5, %mm5              # mm5 = 0 0 
+       pxor    %mm6, %mm6              # mm6 = 0 0 
+       pxor    %mm7, %mm7              # mm7 = 0 0
+
+
+       shr     $1, %rax                # rax = n_2_complex_blocks / 2
+
+       movd    0(%rdi), %mm0
+       pshufw  $0x55, %mm0, %mm1               # b01010101
+       pshufw  $0, %mm0, %mm0
+
+       pxor    %mm2, %mm2
+       pxor    %mm3, %mm3
+
+       pi2fw   %mm1, %mm1
+       pi2fw   %mm0, %mm0
+
+       jmp     .L1_test
+
+       #
+       # 4 taps / loop
+       # something like ?? cycles / loop
+       #
+       
+       .p2align 4
+.loop1:        
+       pfmul   0(%rsi), %mm0
+       pfadd   %mm2, %mm6
+
+       pshufw  $0, 4(%rdi), %mm2
+
+       pfmul   8(%rsi), %mm1
+       pfadd   %mm3, %mm7
+       pi2fw   %mm2, %mm2
+
+       pshufw  $0x55, 4(%rdi), %mm3            # b01010101
+
+       pfmul   16(%rsi), %mm2
+       pi2fw   %mm3, %mm3
+       pfadd   %mm0, %mm4
+
+       pshufw  $0, 8(%rdi), %mm0
+
+       pfmul   24(%rsi), %mm3
+       pfadd   %mm1, %mm5
+
+       pshufw  $0x55, 8(%rdi), %mm1    # b01010101
+       pi2fw   %mm0, %mm0
+
+#TODO: add prefetch
+
+       add     $32, %rsi
+       add     $8, %rdi
+       pi2fw   %mm1, %mm1
+
+.L1_test:
+       dec     %rax
+       jge     .loop1
+
+       # We've handled the bulk of multiplies up to here.
+       # Now accumulate the final two additions and see if original
+       # n_2_complex_blocks was odd.  If so, we've got 2 more
+       # taps to do.
+       
+       pfadd   %mm2, %mm6
+       and     $1, %rdx
+       pfadd   %mm3, %mm7
+       je      .Leven
+       
+       # The count was odd, do 2 more taps.
+       # Note that we've already got mm0 and mm1 preloaded
+       # from the main loop.
+       
+       pfmul   0(%rsi), %mm0
+       pfadd   %mm0, %mm4
+       pfmul   8(%rsi), %mm1
+       pfadd   %mm1, %mm5
+
+.Leven:
+       # at this point mm4, mm5, mm6 and mm7 contain partial sums
+       
+       pfadd   %mm7, %mm6
+       pfadd   %mm5, %mm4
+
+       pfadd   %mm6, %mm4
+       movq    %mm4, (%rcx)
+
+       femms
+
+       retq
+
+FUNC_TAIL(complex_dotprod_3dnowext)
+       .ident  "Hand coded x86_64 3DNow!Ext assembly"
+
diff --git a/gnuradio-core/src/lib/filter/complex_dotprod_generic.cc b/gnuradio-core/src/lib/filter/complex_dotprod_generic.cc
new file mode 100644 (file)
index 0000000..300f470
--- /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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <gr_complex.h>
+#include "gr_fir_scc_simd.h"
+#include "complex_dotprod_generic.h"
+
+
+void
+complex_dotprod_generic (const short *input,
+                      const float *taps, unsigned n_2_complex_blocks,
+                      float *result)
+{
+  gr_complex sum0(0,0);
+  gr_complex sum1(0,0);
+
+  do {
+    const gr_complex tap0(taps[0], taps[1]);
+    const gr_complex tap1(taps[2], taps[3]);
+
+    sum0 += (float)input[0] * tap0;
+    sum1 += (float)input[1] * tap1;
+
+    input += 4;
+    taps += 8;
+
+  } while (--n_2_complex_blocks != 0);
+
+
+  sum0 += sum1;
+  result[0] = sum0.real();
+  result[1] = sum0.imag();
+}
diff --git a/gnuradio-core/src/lib/filter/complex_dotprod_generic.h b/gnuradio-core/src/lib/filter/complex_dotprod_generic.h
new file mode 100644 (file)
index 0000000..44a4ea5
--- /dev/null
@@ -0,0 +1,32 @@
+/* -*- 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 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.
+ */
+
+#ifndef _COMPLEX_DOTPROD_GENERIC_H_
+#define _COMPLEX_DOTPROD_GENERIC_H_
+
+void
+complex_dotprod_generic (const short *input,
+                      const float *taps, unsigned n_2_complex_blocks,
+                      float *result);
+
+
+#endif /* _COMPLEX_DOTPROD_GENERIC_H_ */
diff --git a/gnuradio-core/src/lib/filter/complex_dotprod_sse.S b/gnuradio-core/src/lib/filter/complex_dotprod_sse.S
new file mode 100644 (file)
index 0000000..acafb1a
--- /dev/null
@@ -0,0 +1,202 @@
+#
+# 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 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.
+# 
+
+
+# input and taps are guarenteed to be 16 byte aligned.
+# n_2_complex_blocks is != 0
+#      
+#
+#  complex_dotprod_generic (const short *input,
+#                         const float *taps, unsigned n_2_complex_blocks, float *result)
+#  {
+#    float sum0 = 0;
+#    float sum1 = 0;
+#    float sum2 = 0;
+#    float sum3 = 0;
+#  
+#    do {
+#  
+#      sum0 += input[0] * taps[0];
+#      sum1 += input[0] * taps[1];
+#      sum2 += input[1] * taps[2];
+#      sum3 += input[1] * taps[3];
+#  
+#      input += 2;
+#      taps += 4;
+#  
+#    } while (--n_2_complex_blocks != 0);
+#  
+#  
+#    result[0] = sum0 + sum2;
+#    result[1] = sum1 + sum3;
+#  }
+#
+
+# TODO: prefetch and better scheduling
+
+#include "assembly.h"
+
+
+       .file   "complex_dotprod_sse.S"
+       .version        "01.01"
+.text
+       .p2align 4
+.globl GLOB_SYMB(complex_dotprod_sse)
+       DEF_FUNC_HEAD(complex_dotprod_sse)
+GLOB_SYMB(complex_dotprod_sse):
+       pushl   %ebp
+       movl    %esp, %ebp
+       movl    8(%ebp), %eax           # input
+       movl    12(%ebp), %edx          # taps
+       movl    16(%ebp), %ecx
+
+       
+       # xmm0 xmm1 xmm2 xmm3 are used to hold taps and the result of mults
+       # xmm4 xmm5 xmm6 xmm7 are used to hold the accumulated results
+
+       xorps   %xmm4, %xmm4            # zero two accumulators
+       xorps   %xmm5, %xmm5            # xmm5 holds zero for use below
+
+       # first handle any non-zero remainder of (n_2_complex_blocks % 4)
+
+       andl    $0x3, %ecx
+       jmp     .L1_test
+
+       .p2align 4
+.loop1:        
+
+       pxor    %mm0, %mm0
+       punpcklwd       0(%eax), %mm0
+       psrad   $16, %mm0
+       cvtpi2ps %mm0, %xmm0
+       shufps  $0x50, %xmm0, %xmm0
+
+       mulps   (%edx), %xmm0
+       addl    $0x10, %edx
+       addl    $4, %eax
+       addps   %xmm0, %xmm4
+.L1_test:      
+       decl    %ecx
+       jge     .loop1
+
+       
+       # set up for primary loop which is unrolled 4 times
+       
+       movl    16(%ebp), %ecx
+       movaps  %xmm5, %xmm6            # zero remaining accumulators
+       movaps  %xmm5, %xmm7 
+
+       shrl    $2, %ecx                # n_2_complex_blocks / 4
+       je      .cleanup                # if zero, take short path
+
+       # finish setup and loop priming
+
+       pxor    %mm0, %mm0
+       punpcklwd       0(%eax), %mm0
+       psrad   $16, %mm0
+       cvtpi2ps %mm0, %xmm0
+       shufps  $0x50, %xmm0, %xmm0
+
+       movaps  %xmm5, %xmm2
+
+       pxor    %mm1, %mm1
+       punpcklwd       4(%eax), %mm1
+       psrad   $16, %mm1
+       cvtpi2ps %mm1, %xmm1
+       shufps  $0x50, %xmm1, %xmm1
+
+       movaps  %xmm5, %xmm3
+
+       # we know ecx is not zero, we checked above,
+       # hence enter loop at top
+
+       .p2align 4
+.loop2:
+       mulps   (%edx), %xmm0
+       addps   %xmm2, %xmm6
+
+       pxor    %mm2, %mm2
+       punpcklwd       8(%eax), %mm2
+       psrad   $16, %mm2
+       cvtpi2ps %mm2, %xmm2
+       shufps  $0x50, %xmm2, %xmm2
+
+       mulps   0x10(%edx), %xmm1
+       addps   %xmm3, %xmm7
+
+       pxor    %mm3, %mm3
+       punpcklwd       12(%eax), %mm3
+       psrad   $16, %mm3
+       cvtpi2ps %mm3, %xmm3
+       shufps  $0x50, %xmm3, %xmm3
+
+       mulps   0x20(%edx), %xmm2
+       addps   %xmm0, %xmm4
+
+       pxor    %mm0, %mm0
+       punpcklwd       16(%eax), %mm0
+       psrad   $16, %mm0
+       cvtpi2ps %mm0, %xmm0
+       shufps  $0x50, %xmm0, %xmm0
+
+       mulps   0x30(%edx), %xmm3
+       addps   %xmm1, %xmm5
+
+       pxor    %mm1, %mm1
+       punpcklwd       20(%eax), %mm1
+       psrad   $16, %mm1
+       cvtpi2ps %mm1, %xmm1
+       shufps  $0x50, %xmm1, %xmm1
+
+       addl    $0x40, %edx
+       addl    $0x10, %eax
+       decl    %ecx
+       jne     .loop2
+
+       # OK, now we've done with all the multiplies, but
+       # we still need to handle the unaccumulated
+       # products in xmm2 and xmm3
+
+       addps   %xmm2, %xmm6
+       addps   %xmm3, %xmm7
+
+       # now we want to add all accumulators into xmm4
+
+       addps   %xmm5, %xmm4
+       addps   %xmm6, %xmm7
+       addps   %xmm7, %xmm4
+
+       
+       # At this point, xmm4 contains 2x2 partial sums.  We need
+       # to compute a "horizontal complex add" across xmm4.  
+       
+.cleanup:                              # xmm4 = r1 i2 r3 i4
+       movl    20(%ebp), %eax          # @result
+       movhlps %xmm4, %xmm0            # xmm0 = ?? ?? r1 r2
+       addps   %xmm4, %xmm0            # xmm0 = ?? ?? r1+r3 i2+i4
+       movlps  %xmm0, (%eax)           # store low 2x32 bits (complex) to memory
+
+       emms
+       popl    %ebp
+       ret
+
+FUNC_TAIL(complex_dotprod_sse)
+       .ident  "Hand coded x86 SSE assembly"
diff --git a/gnuradio-core/src/lib/filter/complex_dotprod_sse64.S b/gnuradio-core/src/lib/filter/complex_dotprod_sse64.S
new file mode 100644 (file)
index 0000000..0fb95db
--- /dev/null
@@ -0,0 +1,198 @@
+#
+# Copyright 2002,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 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.
+# 
+
+
+# input and taps are guarenteed to be 16 byte aligned.
+# n_2_complex_blocks is != 0
+#      
+#
+#  complex_dotprod_generic (const short *input,
+#                         const float *taps, unsigned n_2_complex_blocks, float *result)
+#  {
+#    float sum0 = 0;
+#    float sum1 = 0;
+#    float sum2 = 0;
+#    float sum3 = 0;
+#  
+#    do {
+#  
+#      sum0 += input[0] * taps[0];
+#      sum1 += input[0] * taps[1];
+#      sum2 += input[1] * taps[2];
+#      sum3 += input[1] * taps[3];
+#  
+#      input += 2;
+#      taps += 4;
+#  
+#    } while (--n_2_complex_blocks != 0);
+#  
+#  
+#    result[0] = sum0 + sum2;
+#    result[1] = sum1 + sum3;
+#  }
+#
+
+# TODO: prefetch and better scheduling
+
+#include "assembly.h"
+
+
+       .file   "complex_dotprod_sse64.S"
+       .version        "01.01"
+.text
+       .p2align 4
+.globl GLOB_SYMB(complex_dotprod_sse)
+       DEF_FUNC_HEAD(complex_dotprod_sse)
+GLOB_SYMB(complex_dotprod_sse):
+
+       # intput: rdi, taps: rsi, n_2_ccomplex_blocks: rdx, result: rcx
+
+       mov     %rdx, %rax
+
+       
+       # xmm0 xmm1 xmm2 xmm3 are used to hold taps and the result of mults
+       # xmm4 xmm5 xmm6 xmm7 are used to hold the accumulated results
+
+       xorps   %xmm4, %xmm4            # zero two accumulators
+       xorps   %xmm5, %xmm5            # xmm5 holds zero for use below
+
+       # first handle any non-zero remainder of (n_2_complex_blocks % 4)
+
+       and     $0x3, %rax
+       jmp     .L1_test
+
+       .p2align 4
+.loop1:        
+
+       pxor    %mm0, %mm0
+       punpcklwd       0(%rdi), %mm0
+       psrad   $16, %mm0
+       cvtpi2ps %mm0, %xmm0
+       shufps  $0x50, %xmm0, %xmm0
+
+       mulps   (%rsi), %xmm0
+       add     $0x10, %rsi
+       add     $4, %rdi
+       addps   %xmm0, %xmm4
+.L1_test:      
+       dec     %rax
+       jge     .loop1
+
+       
+       # set up for primary loop which is unrolled 4 times
+       
+       movaps  %xmm5, %xmm6            # zero remaining accumulators
+       shr     $2, %rdx                # n_2_complex_blocks / 4
+       movaps  %xmm5, %xmm7 
+
+       je      .cleanup                # if zero, take short path
+
+       # finish setup and loop priming
+
+       pxor    %mm0, %mm0
+       punpcklwd       0(%rdi), %mm0
+       psrad   $16, %mm0
+       cvtpi2ps %mm0, %xmm0
+       shufps  $0x50, %xmm0, %xmm0
+
+       movaps  %xmm5, %xmm2
+
+       pxor    %mm1, %mm1
+       punpcklwd       4(%rdi), %mm1
+       psrad   $16, %mm1
+       cvtpi2ps %mm1, %xmm1
+       shufps  $0x50, %xmm1, %xmm1
+
+       movaps  %xmm5, %xmm3
+
+       # we know rax is not zero, we checked above,
+       # hence enter loop at top
+
+       .p2align 4
+.loop2:
+       mulps   (%rsi), %xmm0
+       addps   %xmm2, %xmm6
+
+       pxor    %mm2, %mm2
+       punpcklwd       8(%rdi), %mm2
+       psrad   $16, %mm2
+       cvtpi2ps %mm2, %xmm2
+       shufps  $0x50, %xmm2, %xmm2
+
+       mulps   0x10(%rsi), %xmm1
+       addps   %xmm3, %xmm7
+
+       pxor    %mm3, %mm3
+       punpcklwd       12(%rdi), %mm3
+       psrad   $16, %mm3
+       cvtpi2ps %mm3, %xmm3
+       shufps  $0x50, %xmm3, %xmm3
+
+       mulps   0x20(%rsi), %xmm2
+       addps   %xmm0, %xmm4
+
+       pxor    %mm0, %mm0
+       punpcklwd       16(%rdi), %mm0
+       psrad   $16, %mm0
+       cvtpi2ps %mm0, %xmm0
+       shufps  $0x50, %xmm0, %xmm0
+
+       mulps   0x30(%rsi), %xmm3
+       addps   %xmm1, %xmm5
+
+       pxor    %mm1, %mm1
+       punpcklwd       20(%rdi), %mm1
+       psrad   $16, %mm1
+       cvtpi2ps %mm1, %xmm1
+       shufps  $0x50, %xmm1, %xmm1
+
+       add     $0x40, %rsi
+       add     $0x10, %rdi
+       dec     %rdx
+       jne     .loop2
+
+       # OK, now we've done with all the multiplies, but
+       # we still need to handle the unaccumulated
+       # products in xmm2 and xmm3
+
+       addps   %xmm2, %xmm6
+       addps   %xmm3, %xmm7
+
+       # now we want to add all accumulators into xmm4
+
+       addps   %xmm5, %xmm4
+       addps   %xmm6, %xmm7
+       addps   %xmm7, %xmm4
+
+       
+       # At this point, xmm4 contains 2x2 partial sums.  We need
+       # to compute a "horizontal complex add" across xmm4.  
+       
+.cleanup:                              # xmm4 = r1 i2 r3 i4
+       movhlps %xmm4, %xmm0            # xmm0 = ?? ?? r1 r2
+       addps   %xmm4, %xmm0            # xmm0 = ?? ?? r1+r3 i2+i4
+       movlps  %xmm0, (%rcx)           # store low 2x32 bits (complex) to memory
+
+       emms
+       retq
+
+FUNC_TAIL(complex_dotprod_sse)
+       .ident  "Hand coded x86_64 SSE assembly"
diff --git a/gnuradio-core/src/lib/filter/complex_dotprod_x86.h b/gnuradio-core/src/lib/filter/complex_dotprod_x86.h
new file mode 100644 (file)
index 0000000..86ac0e7
--- /dev/null
@@ -0,0 +1,46 @@
+/* -*- 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 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.
+ */
+
+#ifndef _COMPLEX_DOTPROD_X86_H_
+#define _COMPLEX_DOTPROD_X86_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void
+complex_dotprod_3dnow (const short *input,
+                    const float *taps, unsigned n_2_complex_blocks, float *result);
+
+void
+complex_dotprod_3dnowext (const short *input,
+                    const float *taps, unsigned n_2_complex_blocks, float *result);
+
+void
+complex_dotprod_sse (const short *input,
+                  const float *taps, unsigned n_2_complex_blocks, float *result);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _COMPLEX_DOTPROD_X86_H_ */
diff --git a/gnuradio-core/src/lib/filter/cpuid_x86.S b/gnuradio-core/src/lib/filter/cpuid_x86.S
new file mode 100644 (file)
index 0000000..3152b91
--- /dev/null
@@ -0,0 +1,56 @@
+#      
+# 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 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.
+# 
+
+#
+# execute CPUID instruction, return EAX, EBX, ECX and EDX values in result
+#
+#  void cpuid_x86 (unsigned int op, unsigned int result[4]);
+#
+
+#include "assembly.h"
+
+.file "cpuid_x86.S"
+       .version        "01.01"
+.text
+.globl GLOB_SYMB(cpuid_x86)
+       DEF_FUNC_HEAD(cpuid_x86)
+GLOB_SYMB(cpuid_x86):
+       pushl   %ebp
+       movl    %esp, %ebp
+       pushl   %ebx            # must save in PIC mode, holds GOT pointer
+       pushl   %esi
+       
+       movl    8(%ebp), %eax   # op
+       movl    12(%ebp), %esi  # result
+       cpuid
+       movl    %eax, 0(%esi)
+       movl    %ebx, 4(%esi)
+       movl    %ecx, 8(%esi)
+       movl    %edx, 12(%esi)
+       
+       popl    %esi
+       popl    %ebx
+       popl    %ebp
+       ret
+
+FUNC_TAIL(cpuid_x86)
+       .ident  "Hand coded cpuid assembly"
+       
diff --git a/gnuradio-core/src/lib/filter/cpuid_x86_64.S b/gnuradio-core/src/lib/filter/cpuid_x86_64.S
new file mode 100644 (file)
index 0000000..98137db
--- /dev/null
@@ -0,0 +1,50 @@
+#      
+# 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 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.
+# 
+
+#
+# execute CPUID instruction, return EAX, EBX, ECX and EDX values in result
+#
+#  void cpuid_x86 (unsigned int op, unsigned int result[4]);
+#
+
+#include "assembly.h"
+
+.file "cpuid_x86_64.S"
+       .version        "01.01"
+.text
+.globl GLOB_SYMB(cpuid_x86)
+       DEF_FUNC_HEAD(cpuid_x86)
+GLOB_SYMB(cpuid_x86):
+       mov     %rbx, %r11      # must save in PIC mode, holds GOT pointer
+       
+       mov     %rdi, %rax      # op
+       cpuid
+       movl    %eax, 0(%rsi)   # result
+       movl    %ebx, 4(%rsi)
+       movl    %ecx, 8(%rsi)
+       movl    %edx, 12(%rsi)
+       
+       mov     %r11, %rbx
+       retq
+
+FUNC_TAIL(cpuid_x86)
+       .ident  "Hand coded cpuid64 assembly"
+       
diff --git a/gnuradio-core/src/lib/filter/fcomplex_dotprod_3dnow.S b/gnuradio-core/src/lib/filter/fcomplex_dotprod_3dnow.S
new file mode 100644 (file)
index 0000000..20dc5b2
--- /dev/null
@@ -0,0 +1,172 @@
+#
+# 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 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.
+# 
+
+# input and taps are guarenteed to be 16 byte aligned.
+# n_2_complex_blocks is != 0
+#      
+#
+#  fcomplex_dotprod_generic (const float *input,
+#                         const float *taps, unsigned n_2_complex_blocks, float *result)
+#  {
+#    float sum0 = 0;
+#    float sum1 = 0;
+#    float sum2 = 0;
+#    float sum3 = 0;
+#  
+#    do {
+#  
+#      sum0 += input[0] * taps[0];
+#      sum1 += input[0] * taps[1];
+#      sum2 += input[1] * taps[2];
+#      sum3 += input[1] * taps[3];
+#  
+#      input += 2;
+#      taps += 4;
+#  
+#    } while (--n_2_complex_blocks != 0);
+#  
+#  
+#    result[0] = sum0 + sum2;
+#    result[1] = sum1 + sum3;
+#  }
+#              
+
+#include "assembly.h"
+
+
+       .file   "fcomplex_dotprod_3dnow.S"
+       .version        "01.01"
+.text
+       .p2align 4
+.globl GLOB_SYMB(fcomplex_dotprod_3dnow)
+       DEF_FUNC_HEAD(fcomplex_dotprod_3dnow)
+GLOB_SYMB(fcomplex_dotprod_3dnow):
+       pushl   %ebp
+       movl    %esp, %ebp
+       movl    8(%ebp), %eax           # input
+       movl    12(%ebp), %edx          # taps
+       movl    16(%ebp), %ecx
+
+       # zero accumulators
+       
+       pxor    %mm4, %mm4              # mm4 = 0 0
+       pxor    %mm5, %mm5              # mm5 = 0 0 
+       pxor    %mm6, %mm6              # mm6 = 0 0 
+       pxor    %mm7, %mm7              # mm7 = 0 0
+
+       shrl    $1, %ecx                # ecx = n_2_complex_blocks / 2
+
+       movq    0(%eax), %mm0
+
+       pxor    %mm2, %mm2
+       pxor    %mm3, %mm3
+
+       movq    %mm0, %mm1
+       punpckldq       %mm0, %mm0
+       punpckhdq       %mm1, %mm1
+
+
+       jmp     .L1_test
+
+       #
+       # 4 taps / loop
+       # something like ?? cycles / loop
+       #
+       
+       .p2align 4
+.loop1:        
+       pfmul   0(%edx), %mm0
+       pfadd   %mm2, %mm6
+
+       movq    8(%eax), %mm2
+
+       pfadd   %mm3, %mm7
+
+       pfmul   8(%edx), %mm1
+
+       movq    %mm2, %mm3
+       punpckldq       %mm2, %mm2
+       punpckhdq       %mm3, %mm3
+
+
+       pfmul   16(%edx), %mm2
+       pfadd   %mm0, %mm4
+
+       movq    16(%eax), %mm0
+
+       pfadd   %mm1, %mm5
+
+       movq    %mm0, %mm1
+       punpckldq       %mm0, %mm0
+
+       pfmul   24(%edx), %mm3
+
+       punpckhdq       %mm1, %mm1
+
+
+#TODO: add prefetch?
+
+       addl    $32, %edx
+       addl    $16, %eax
+
+.L1_test:
+       decl    %ecx
+       jge     .loop1
+
+       # We've handled the bulk of multiplies up to here.
+       # Now accumulate the final two additions and see if original
+       # n_2_complex_blocks was odd.  If so, we've got 2 more
+       # taps to do.
+       
+       movl    16(%ebp), %ecx
+       pfadd   %mm2, %mm6
+       andl    $1, %ecx
+       pfadd   %mm3, %mm7
+       je      .Leven
+       
+       # The count was odd, do 2 more taps.
+       # Note that we've already got mm0 and mm1 preloaded
+       # from the main loop.
+       
+       pfmul   0(%edx), %mm0
+       pfadd   %mm0, %mm4
+       pfmul   8(%edx), %mm1
+       pfadd   %mm1, %mm5
+
+
+.Leven:
+       # at this point mm4, mm5, mm6 and mm7 contain partial sums
+       
+       pfadd   %mm7, %mm6
+       pfadd   %mm5, %mm4
+
+       movl    20(%ebp), %eax          # result
+
+       pfadd   %mm6, %mm4
+
+       movq    %mm4, (%eax)
+       femms
+
+       popl    %ebp
+       ret
+
+FUNC_TAIL(fcomplex_dotprod_3dnow)
+       .ident  "Hand coded x86 3DNow! assembly"
diff --git a/gnuradio-core/src/lib/filter/fcomplex_dotprod_3dnow64.S b/gnuradio-core/src/lib/filter/fcomplex_dotprod_3dnow64.S
new file mode 100644 (file)
index 0000000..32772bf
--- /dev/null
@@ -0,0 +1,166 @@
+#
+# Copyright 2002,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 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.
+# 
+
+# input and taps are guarenteed to be 16 byte aligned.
+# n_2_complex_blocks is != 0
+#      
+#
+#  fcomplex_dotprod_generic (const float *input,
+#                         const float *taps, unsigned n_2_complex_blocks, float *result)
+#  {
+#    float sum0 = 0;
+#    float sum1 = 0;
+#    float sum2 = 0;
+#    float sum3 = 0;
+#  
+#    do {
+#  
+#      sum0 += input[0] * taps[0];
+#      sum1 += input[0] * taps[1];
+#      sum2 += input[1] * taps[2];
+#      sum3 += input[1] * taps[3];
+#  
+#      input += 2;
+#      taps += 4;
+#  
+#    } while (--n_2_complex_blocks != 0);
+#  
+#  
+#    result[0] = sum0 + sum2;
+#    result[1] = sum1 + sum3;
+#  }
+#              
+
+#include "assembly.h"
+
+
+       .file   "fcomplex_dotprod_3dnow64.S"
+       .version        "01.01"
+.text
+       .p2align 4
+.globl GLOB_SYMB(fcomplex_dotprod_3dnow)
+       DEF_FUNC_HEAD(fcomplex_dotprod_3dnow)
+GLOB_SYMB(fcomplex_dotprod_3dnow):
+
+       # intput: rdi, taps: rsi, n_2_ccomplex_blocks: rdx, result: rcx
+
+       mov     %rdx, %rax
+
+       # zero accumulators
+       
+       pxor    %mm4, %mm4              # mm4 = 0 0
+       pxor    %mm5, %mm5              # mm5 = 0 0 
+       pxor    %mm6, %mm6              # mm6 = 0 0 
+       pxor    %mm7, %mm7              # mm7 = 0 0
+
+       shr     $1, %rax                # rax = n_2_complex_blocks / 2
+
+       movq    0(%rdi), %mm0
+
+       pxor    %mm2, %mm2
+       pxor    %mm3, %mm3
+
+       movq    %mm0, %mm1
+       punpckldq       %mm0, %mm0
+       punpckhdq       %mm1, %mm1
+
+
+       jmp     .L1_test
+
+       #
+       # 4 taps / loop
+       # something like ?? cycles / loop
+       #
+       
+       .p2align 4
+.loop1:        
+       pfmul   0(%rsi), %mm0
+       pfadd   %mm2, %mm6
+
+       movq    8(%rdi), %mm2
+
+       pfadd   %mm3, %mm7
+
+       pfmul   8(%rsi), %mm1
+
+       movq    %mm2, %mm3
+       punpckldq       %mm2, %mm2
+       punpckhdq       %mm3, %mm3
+
+
+       pfmul   16(%rsi), %mm2
+       pfadd   %mm0, %mm4
+
+       movq    16(%rdi), %mm0
+
+       pfadd   %mm1, %mm5
+
+       movq    %mm0, %mm1
+       punpckldq       %mm0, %mm0
+
+       pfmul   24(%rsi), %mm3
+
+       punpckhdq       %mm1, %mm1
+
+
+#TODO: add prefetch?
+
+       add     $32, %rsi
+       add     $16, %rdi
+
+.L1_test:
+       dec     %rax
+       jge     .loop1
+
+       # We've handled the bulk of multiplies up to here.
+       # Now accumulate the final two additions and see if original
+       # n_2_complex_blocks was odd.  If so, we've got 2 more
+       # taps to do.
+       
+       pfadd   %mm2, %mm6
+       and     $1, %rdx
+       pfadd   %mm3, %mm7
+       je      .Leven
+       
+       # The count was odd, do 2 more taps.
+       # Note that we've already got mm0 and mm1 preloaded
+       # from the main loop.
+       
+       pfmul   0(%rsi), %mm0
+       pfadd   %mm0, %mm4
+       pfmul   8(%rsi), %mm1
+       pfadd   %mm1, %mm5
+
+
+.Leven:
+       # at this point mm4, mm5, mm6 and mm7 contain partial sums
+       
+       pfadd   %mm7, %mm6
+       pfadd   %mm5, %mm4
+       pfadd   %mm6, %mm4
+
+       movq    %mm4, (%rcx)            # result
+       femms
+
+       retq
+
+FUNC_TAIL(fcomplex_dotprod_3dnow)
+       .ident  "Hand coded x86_64 3DNow! assembly"
diff --git a/gnuradio-core/src/lib/filter/fcomplex_dotprod_sse.S b/gnuradio-core/src/lib/filter/fcomplex_dotprod_sse.S
new file mode 100644 (file)
index 0000000..2d8b4cc
--- /dev/null
@@ -0,0 +1,184 @@
+#
+# 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 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.
+# 
+
+
+# input and taps are guarenteed to be 16 byte aligned.
+# n_2_complex_blocks is != 0
+#      
+#
+#  fcomplex_dotprod_generic (const float *input,
+#                         const float *taps, unsigned n_2_complex_blocks, float *result)
+#  {
+#    float sum0 = 0;
+#    float sum1 = 0;
+#    float sum2 = 0;
+#    float sum3 = 0;
+#  
+#    do {
+#  
+#      sum0 += input[0] * taps[0];
+#      sum1 += input[0] * taps[1];
+#      sum2 += input[1] * taps[2];
+#      sum3 += input[1] * taps[3];
+#  
+#      input += 2;
+#      taps += 4;
+#  
+#    } while (--n_2_complex_blocks != 0);
+#  
+#  
+#    result[0] = sum0 + sum2;
+#    result[1] = sum1 + sum3;
+#  }
+#
+
+# TODO: prefetch and better scheduling
+
+#include "assembly.h"
+
+
+       .file   "fcomplex_dotprod_sse.S"
+       .version        "01.01"
+.text
+       .p2align 4
+.globl GLOB_SYMB(fcomplex_dotprod_sse)
+       DEF_FUNC_HEAD(fcomplex_dotprod_sse)
+GLOB_SYMB(fcomplex_dotprod_sse):
+       pushl   %ebp
+       movl    %esp, %ebp
+       movl    8(%ebp), %eax           # input
+       movl    12(%ebp), %edx          # taps
+       movl    16(%ebp), %ecx
+
+       
+       # xmm0 xmm1 xmm2 xmm3 are used to hold taps and the result of mults
+       # xmm4 xmm5 xmm6 xmm7 are used to hold the accumulated results
+
+       xorps   %xmm4, %xmm4            # zero two accumulators
+       xorps   %xmm5, %xmm5            # xmm5 holds zero for use below
+
+       # first handle any non-zero remainder of (n_2_complex_blocks % 4)
+
+       andl    $0x3, %ecx
+       jmp     .L1_test
+
+       .p2align 4
+.loop1:        
+
+       movlps  0(%eax), %xmm0
+       shufps  $0x50, %xmm0, %xmm0     # b01010000
+
+       mulps   (%edx), %xmm0
+       addl    $0x10, %edx
+       addl    $8, %eax
+       addps   %xmm0, %xmm4
+.L1_test:      
+       decl    %ecx
+       jge     .loop1
+
+       
+       # set up for primary loop which is unrolled 4 times
+       
+       movl    16(%ebp), %ecx
+       movaps  %xmm5, %xmm6            # zero remaining accumulators
+       movaps  %xmm5, %xmm7 
+
+       shrl    $2, %ecx                # n_2_complex_blocks / 4
+       je      .cleanup                # if zero, take short path
+
+       # finish setup and loop priming
+
+       movlps  0(%eax), %xmm0
+
+       movaps  %xmm5, %xmm2
+       movaps  %xmm5, %xmm3
+
+       movlps  8(%eax), %xmm1
+       shufps  $0x50, %xmm0, %xmm0
+
+       shufps  $0x50, %xmm1, %xmm1
+
+       # we know ecx is not zero, we checked above,
+       # hence enter loop at top
+
+       .p2align 4
+.loop2:
+       addps   %xmm2, %xmm6
+       movlps  0x10(%eax), %xmm2
+
+       addps   %xmm3, %xmm7
+
+       mulps   (%edx), %xmm0
+
+       movlps  0x18(%eax), %xmm3
+       shufps  $0x50, %xmm2, %xmm2
+
+       mulps   0x10(%edx), %xmm1
+
+       shufps  $0x50, %xmm3, %xmm3
+
+       addps   %xmm0, %xmm4
+       movlps  0x20(%eax), %xmm0
+
+       addps   %xmm1, %xmm5
+
+       mulps   0x20(%edx), %xmm2
+       
+       movlps  0x28(%eax), %xmm1
+       shufps  $0x50, %xmm0, %xmm0
+
+       mulps   0x30(%edx), %xmm3
+
+       shufps  $0x50, %xmm1, %xmm1
+
+       addl    $0x40, %edx
+       addl    $0x20, %eax
+       decl    %ecx
+       jne     .loop2
+
+       # OK, now we've done with all the multiplies, but
+       # we still need to handle the unaccumulated
+       # products in xmm2 and xmm3
+
+       addps   %xmm2, %xmm6
+       addps   %xmm3, %xmm7
+
+       # now we want to add all accumulators into xmm4
+
+       addps   %xmm5, %xmm4
+       addps   %xmm6, %xmm7
+       addps   %xmm7, %xmm4
+
+       
+       # At this point, xmm4 contains 2x2 partial sums.  We need
+       # to compute a "horizontal complex add" across xmm4.  
+       
+.cleanup:                              # xmm4 = r1 i2 r3 i4
+       movl    20(%ebp), %eax          # @result
+       movhlps %xmm4, %xmm0            # xmm0 = ?? ?? r1 r2
+       addps   %xmm4, %xmm0            # xmm0 = ?? ?? r1+r3 i2+i4
+       movlps  %xmm0, (%eax)           # store low 2x32 bits (complex) to memory
+
+       popl    %ebp
+       ret
+
+FUNC_TAIL(fcomplex_dotprod_sse)
+       .ident  "Hand coded x86 SSE assembly"
diff --git a/gnuradio-core/src/lib/filter/fcomplex_dotprod_sse64.S b/gnuradio-core/src/lib/filter/fcomplex_dotprod_sse64.S
new file mode 100644 (file)
index 0000000..cba0357
--- /dev/null
@@ -0,0 +1,179 @@
+#
+# Copyright 2002,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 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.
+# 
+
+
+# input and taps are guarenteed to be 16 byte aligned.
+# n_2_complex_blocks is != 0
+#      
+#
+#  fcomplex_dotprod_generic (const float *input,
+#                         const float *taps, unsigned n_2_complex_blocks, float *result)
+#  {
+#    float sum0 = 0;
+#    float sum1 = 0;
+#    float sum2 = 0;
+#    float sum3 = 0;
+#  
+#    do {
+#  
+#      sum0 += input[0] * taps[0];
+#      sum1 += input[0] * taps[1];
+#      sum2 += input[1] * taps[2];
+#      sum3 += input[1] * taps[3];
+#  
+#      input += 2;
+#      taps += 4;
+#  
+#    } while (--n_2_complex_blocks != 0);
+#  
+#  
+#    result[0] = sum0 + sum2;
+#    result[1] = sum1 + sum3;
+#  }
+#
+
+# TODO: prefetch and better scheduling
+
+#include "assembly.h"
+
+
+       .file   "fcomplex_dotprod_sse64.S"
+       .version        "01.01"
+.text
+       .p2align 4
+.globl GLOB_SYMB(fcomplex_dotprod_sse)
+       DEF_FUNC_HEAD(fcomplex_dotprod_sse)
+GLOB_SYMB(fcomplex_dotprod_sse):
+
+       # intput: rdi, taps: rsi, n_2_ccomplex_blocks: rdx, result: rcx
+
+       mov     %rdx, %rax
+       
+       # xmm0 xmm1 xmm2 xmm3 are used to hold taps and the result of mults
+       # xmm4 xmm5 xmm6 xmm7 are used to hold the accumulated results
+
+       xorps   %xmm4, %xmm4            # zero two accumulators
+       xorps   %xmm5, %xmm5            # xmm5 holds zero for use below
+
+       # first handle any non-zero remainder of (n_2_complex_blocks % 4)
+
+       and     $0x3, %rax
+       jmp     .L1_test
+
+       .p2align 4
+.loop1:        
+
+       movlps  0(%rdi), %xmm0
+       shufps  $0x50, %xmm0, %xmm0     # b01010000
+
+       mulps   (%rsi), %xmm0
+       add     $0x10, %rsi
+       add     $8, %rdi
+       addps   %xmm0, %xmm4
+.L1_test:      
+       dec     %rax
+       jge     .loop1
+
+       
+       # set up for primary loop which is unrolled 4 times
+       
+       movaps  %xmm5, %xmm6            # zero remaining accumulators
+       movaps  %xmm5, %xmm7 
+
+       shr     $2, %rdx                # n_2_complex_blocks / 4
+       je      .cleanup                # if zero, take short path
+
+       # finish setup and loop priming
+
+       movlps  0(%rdi), %xmm0
+
+       movaps  %xmm5, %xmm2
+       movaps  %xmm5, %xmm3
+
+       movlps  8(%rdi), %xmm1
+       shufps  $0x50, %xmm0, %xmm0
+
+       shufps  $0x50, %xmm1, %xmm1
+
+       # we know rdx is not zero, we checked above,
+       # hence enter loop at top
+
+       .p2align 4
+.loop2:
+       addps   %xmm2, %xmm6
+       movlps  0x10(%rdi), %xmm2
+
+       addps   %xmm3, %xmm7
+
+       mulps   (%rsi), %xmm0
+
+       movlps  0x18(%rdi), %xmm3
+       shufps  $0x50, %xmm2, %xmm2
+
+       mulps   0x10(%rsi), %xmm1
+
+       shufps  $0x50, %xmm3, %xmm3
+
+       addps   %xmm0, %xmm4
+       movlps  0x20(%rdi), %xmm0
+
+       addps   %xmm1, %xmm5
+
+       mulps   0x20(%rsi), %xmm2
+       
+       movlps  0x28(%rdi), %xmm1
+       shufps  $0x50, %xmm0, %xmm0
+
+       mulps   0x30(%rsi), %xmm3
+
+       shufps  $0x50, %xmm1, %xmm1
+
+       add     $0x40, %rsi
+       add     $0x20, %rdi
+       dec     %rdx
+       jne     .loop2
+
+       # OK, now we've done with all the multiplies, but
+       # we still need to handle the unaccumulated
+       # products in xmm2 and xmm3
+
+       addps   %xmm2, %xmm6
+       addps   %xmm3, %xmm7
+
+       # now we want to add all accumulators into xmm4
+
+       addps   %xmm5, %xmm4
+       addps   %xmm6, %xmm7
+       addps   %xmm7, %xmm4
+
+       
+       # At this point, xmm4 contains 2x2 partial sums.  We need
+       # to compute a "horizontal complex add" across xmm4.  
+       
+.cleanup:                              # xmm4 = r1 i2 r3 i4
+       movhlps %xmm4, %xmm0            # xmm0 = ?? ?? r1 r2
+       addps   %xmm4, %xmm0            # xmm0 = ?? ?? r1+r3 i2+i4
+       movlps  %xmm0, (%rcx)           # store low 2x32 bits (complex) to memory
+
+       retq
+
+FUNC_TAIL(fcomplex_dotprod_sse)
+       .ident  "Hand coded x86_64 SSE assembly"
diff --git a/gnuradio-core/src/lib/filter/fcomplex_dotprod_x86.h b/gnuradio-core/src/lib/filter/fcomplex_dotprod_x86.h
new file mode 100644 (file)
index 0000000..d9f7eac
--- /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 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.
+ */
+
+#ifndef _FCOMPLEX_DOTPROD_X86_H_
+#define _FCOMPLEX_DOTPROD_X86_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void
+fcomplex_dotprod_3dnow (const float *input,
+                    const float *taps, unsigned n_2_complex_blocks, float *result);
+
+void
+fcomplex_dotprod_sse (const float *input,
+                  const float *taps, unsigned n_2_complex_blocks, float *result);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _FCOMPLEX_DOTPROD_X86_H_ */
diff --git a/gnuradio-core/src/lib/filter/filter.i b/gnuradio-core/src/lib/filter/filter.i
new file mode 100644 (file)
index 0000000..2d43469
--- /dev/null
@@ -0,0 +1,45 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2005,2006 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 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.
+ */
+
+%{
+#include <gr_iir_filter_ffd.h>
+#include <gr_single_pole_iir_filter_ff.h>
+#include <gr_single_pole_iir_filter_cc.h>
+#include <gr_hilbert_fc.h>
+#include <gr_filter_delay_fc.h>
+#include <gr_fft_filter_ccc.h>
+#include <gr_fft_filter_fff.h>
+#include <gr_goertzel_fc.h>
+#include <gr_cma_equalizer_cc.h>
+%}
+
+%include "gr_iir_filter_ffd.i"
+%include "gr_single_pole_iir_filter_ff.i"
+%include "gr_single_pole_iir_filter_cc.i"
+%include "gr_hilbert_fc.i"
+%include "gr_filter_delay_fc.i"
+%include "gr_fft_filter_ccc.i"
+%include "gr_fft_filter_fff.i"
+%include "gr_goertzel_fc.i"
+%include "gr_cma_equalizer_cc.i"
+
+%include "filter_generated.i"
diff --git a/gnuradio-core/src/lib/filter/float_dotprod_3dnow.S b/gnuradio-core/src/lib/filter/float_dotprod_3dnow.S
new file mode 100644 (file)
index 0000000..784fa0b
--- /dev/null
@@ -0,0 +1,148 @@
+#
+# 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 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.
+# 
+
+
+# input and taps are guarenteed to be 16 byte aligned.
+# n_4_float_blocks is != 0
+#      
+#
+#  float 
+#  float_dotprod_generic (const float *input,
+#                         const float *taps, unsigned n_4_float_blocks)
+#  {
+#    float sum0 = 0;
+#    float sum1 = 0;
+#    float sum2 = 0;
+#    float sum3 = 0;
+#  
+#    do {
+#  
+#      sum0 += input[0] * taps[0];
+#      sum1 += input[1] * taps[1];
+#      sum2 += input[2] * taps[2];
+#      sum3 += input[3] * taps[3];
+#  
+#      input += 4;
+#      taps += 4;
+#  
+#    } while (--n_4_float_blocks != 0);
+#  
+#  
+#    return sum0 + sum1 + sum2 + sum3;
+#  }
+#              
+
+#include "assembly.h"
+
+
+       .file   "float_dotprod_3dnow.S"
+       .version        "01.01"
+.text
+       .p2align 4
+.globl GLOB_SYMB(float_dotprod_3dnow)
+       DEF_FUNC_HEAD(float_dotprod_3dnow)
+GLOB_SYMB(float_dotprod_3dnow):
+       pushl   %ebp
+       movl    %esp, %ebp
+       movl    8(%ebp), %edx
+       movl    12(%ebp), %eax
+       movl    16(%ebp), %ecx
+
+       # zero accumulators
+       
+       pxor    %mm4, %mm4              # mm4 = 0 0
+       pxor    %mm5, %mm5              # mm5 = 0 0 
+       pxor    %mm6, %mm6              # mm6 = 0 0 
+       pxor    %mm7, %mm7              # mm7 = 0 0
+
+       shrl    $1, %ecx                # ecx = n_4_float_blocks / 2
+       movq    0(%eax), %mm0
+       movq    8(%eax), %mm1
+       pxor    %mm2, %mm2
+       pxor    %mm3, %mm3
+       jmp     .L1_test
+
+       #
+       # 8 taps / loop
+       # something like 6 cycles / loop
+       #
+       
+       .p2align 4
+.loop1:        
+       pfmul   0(%edx), %mm0
+       pfadd   %mm2, %mm6
+       movq    16(%eax), %mm2
+       
+       pfmul   8(%edx), %mm1
+       pfadd   %mm3, %mm7
+       movq    24(%eax), %mm3
+
+       pfmul   16(%edx), %mm2
+       pfadd   %mm0, %mm4
+       movq    32(%eax), %mm0
+
+       pfmul   24(%edx), %mm3
+       pfadd   %mm1, %mm5
+       movq    40(%eax), %mm1
+
+       addl    $32, %edx
+       addl    $32, %eax
+.L1_test:
+       decl    %ecx
+       jge     .loop1
+
+       # We've handled the bulk of multiplies up to here.
+       # Now accumulate the final two additions and see if original
+       # n_4_float_blocks was odd.  If so, we've got 4 more
+       # taps to do.
+       
+       movl    16(%ebp), %ecx
+       pfadd   %mm2, %mm6
+       andl    $1, %ecx
+       pfadd   %mm3, %mm7
+       je      .Leven
+       
+       # The count was odd, do 4 more taps.
+       # Note that we've already got mm0 and mm1 preloaded
+       # from the main loop.
+       
+       pfmul   0(%edx), %mm0
+       pfadd   %mm0, %mm4
+       pfmul   8(%edx), %mm1
+       pfadd   %mm1, %mm5
+
+.Leven:                        
+       # at this point mm4, mm5, mm6 and mm7 contain partial sums
+       
+       pfadd   %mm7, %mm6
+       pfadd   %mm5, %mm4
+       pfadd   %mm6, %mm4
+       pfacc   %mm4, %mm4
+       
+       movd    %mm4, 16(%ebp)
+       femms
+       flds    16(%ebp)
+
+       popl    %ebp
+       ret
+
+FUNC_TAIL(float_dotprod_3dnow)
+       .ident  "Hand coded x86 3DNow! assembly"
diff --git a/gnuradio-core/src/lib/filter/float_dotprod_3dnow64.S b/gnuradio-core/src/lib/filter/float_dotprod_3dnow64.S
new file mode 100644 (file)
index 0000000..0f6a948
--- /dev/null
@@ -0,0 +1,145 @@
+#
+# Copyright 2002,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 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.
+# 
+
+
+# input and taps are guarenteed to be 16 byte aligned.
+# n_4_float_blocks is != 0
+#      
+#
+#  float 
+#  float_dotprod_generic (const float *input,
+#                         const float *taps, unsigned n_4_float_blocks)
+#  {
+#    float sum0 = 0;
+#    float sum1 = 0;
+#    float sum2 = 0;
+#    float sum3 = 0;
+#  
+#    do {
+#  
+#      sum0 += input[0] * taps[0];
+#      sum1 += input[1] * taps[1];
+#      sum2 += input[2] * taps[2];
+#      sum3 += input[3] * taps[3];
+#  
+#      input += 4;
+#      taps += 4;
+#  
+#    } while (--n_4_float_blocks != 0);
+#  
+#  
+#    return sum0 + sum1 + sum2 + sum3;
+#  }
+#              
+
+#include "assembly.h"
+
+
+       .file   "float_dotprod_3dnow64.S"
+       .version        "01.01"
+.text
+       .p2align 4
+.globl GLOB_SYMB(float_dotprod_3dnow)
+       DEF_FUNC_HEAD(float_dotprod_3dnow)
+GLOB_SYMB(float_dotprod_3dnow):
+
+       # intput: rdi, taps: rsi, n_2_ccomplex_blocks: rdx
+
+       mov     %rdx, %rax
+
+       # zero accumulators
+       
+       pxor    %mm4, %mm4              # mm4 = 0 0
+       pxor    %mm5, %mm5              # mm5 = 0 0 
+       pxor    %mm6, %mm6              # mm6 = 0 0 
+       pxor    %mm7, %mm7              # mm7 = 0 0
+
+       shr     $1, %rax                # rax = n_4_float_blocks / 2
+       movq    0(%rsi), %mm0
+       movq    8(%rsi), %mm1
+       pxor    %mm2, %mm2
+       pxor    %mm3, %mm3
+       jmp     .L1_test
+
+       #
+       # 8 taps / loop
+       # something like 6 cycles / loop
+       #
+       
+       .p2align 4
+.loop1:        
+       pfmul   0(%rdi), %mm0
+       pfadd   %mm2, %mm6
+       movq    16(%rsi), %mm2
+       
+       pfmul   8(%rdi), %mm1
+       pfadd   %mm3, %mm7
+       movq    24(%rsi), %mm3
+
+       pfmul   16(%rdi), %mm2
+       pfadd   %mm0, %mm4
+       movq    32(%rsi), %mm0
+
+       pfmul   24(%rdi), %mm3
+       pfadd   %mm1, %mm5
+       movq    40(%rsi), %mm1
+
+       add     $32, %rdi
+       add     $32, %rsi
+.L1_test:
+       dec     %rax
+       jge     .loop1
+
+       # We've handled the bulk of multiplies up to here.
+       # Now accumulate the final two additions and see if original
+       # n_4_float_blocks was odd.  If so, we've got 4 more
+       # taps to do.
+       
+       pfadd   %mm2, %mm6
+       and     $1, %rdx
+       pfadd   %mm3, %mm7
+       je      .Leven
+       
+       # The count was odd, do 4 more taps.
+       # Note that we've already got mm0 and mm1 preloaded
+       # from the main loop.
+       
+       pfmul   0(%rdi), %mm0
+       pfadd   %mm0, %mm4
+       pfmul   8(%rdi), %mm1
+       pfadd   %mm1, %mm5
+
+.Leven:                        
+       # at this point mm4, mm5, mm6 and mm7 contain partial sums
+       
+       pfadd   %mm7, %mm6
+       pfadd   %mm5, %mm4
+       pfadd   %mm6, %mm4
+       pfacc   %mm4, %mm4
+       
+       movd    %mm4, -8(%rsp)
+       movss   -8(%rsp), %xmm0
+       femms
+
+       retq
+
+FUNC_TAIL(float_dotprod_3dnow)
+       .ident  "Hand coded x86_64 3DNow! assembly"
diff --git a/gnuradio-core/src/lib/filter/float_dotprod_generic.c b/gnuradio-core/src/lib/filter/float_dotprod_generic.c
new file mode 100644 (file)
index 0000000..21912af
--- /dev/null
@@ -0,0 +1,49 @@
+/* -*- 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 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.
+ */
+
+#include "float_dotprod_generic.h"
+
+
+float 
+float_dotprod_generic (const float *input,
+                      const float *taps, unsigned n_4_float_blocks)
+{
+  float sum0 = 0;
+  float sum1 = 0;
+  float sum2 = 0;
+  float sum3 = 0;
+
+  do {
+
+    sum0 += input[0] * taps[0];
+    sum1 += input[1] * taps[1];
+    sum2 += input[2] * taps[2];
+    sum3 += input[3] * taps[3];
+
+    input += 4;
+    taps += 4;
+
+  } while (--n_4_float_blocks != 0);
+
+
+  return sum0 + sum1 + sum2 + sum3;
+}
diff --git a/gnuradio-core/src/lib/filter/float_dotprod_generic.h b/gnuradio-core/src/lib/filter/float_dotprod_generic.h
new file mode 100644 (file)
index 0000000..4f4d4eb
--- /dev/null
@@ -0,0 +1,41 @@
+/* -*- 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 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.
+ */
+
+#ifndef _FLOAT_DOTPROD_GENERIC_H_
+#define _FLOAT_DOTPROD_GENERIC_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+float 
+float_dotprod_generic (const float *input,
+                      const float *taps, unsigned n_4_float_blocks);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+#endif /* _FLOAT_DOTPROD_GENERIC_H_ */
diff --git a/gnuradio-core/src/lib/filter/float_dotprod_sse.S b/gnuradio-core/src/lib/filter/float_dotprod_sse.S
new file mode 100644 (file)
index 0000000..0e59f5e
--- /dev/null
@@ -0,0 +1,167 @@
+#
+# 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 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.
+# 
+
+
+# input and taps are guarenteed to be 16 byte aligned.
+# n_4_float_blocks is != 0
+#      
+#
+#  float 
+#  float_dotprod_generic (const float *input,
+#                         const float *taps, unsigned n_4_float_blocks)
+#  {
+#    float sum0 = 0;
+#    float sum1 = 0;
+#    float sum2 = 0;
+#    float sum3 = 0;
+#  
+#    do {
+#  
+#      sum0 += input[0] * taps[0];
+#      sum1 += input[1] * taps[1];
+#      sum2 += input[2] * taps[2];
+#      sum3 += input[3] * taps[3];
+#  
+#      input += 4;
+#      taps += 4;
+#  
+#    } while (--n_4_float_blocks != 0);
+#  
+#  
+#    return sum0 + sum1 + sum2 + sum3;
+#  }
+#              
+
+#include "assembly.h"
+
+
+       .file   "float_dotprod_sse.S"
+       .version        "01.01"
+.text
+       .p2align 4
+.globl GLOB_SYMB(float_dotprod_sse)
+       DEF_FUNC_HEAD(float_dotprod_sse)
+GLOB_SYMB(float_dotprod_sse):
+       pushl   %ebp
+       movl    %esp, %ebp
+       movl    8(%ebp), %edx
+       movl    12(%ebp), %eax
+       movl    16(%ebp), %ecx
+
+       
+       # xmm0 xmm1 xmm2 xmm3 are used to hold taps and the result of mults
+       # xmm4 xmm5 xmm6 xmm7 are used to hold the accumulated results
+
+       xorps   %xmm4, %xmm4            # zero two accumulators
+       xorps   %xmm5, %xmm5            # xmm5 holds zero for use below
+
+       # first handle any non-zero remainder of (n_4_float_blocks % 4)
+
+       andl    $0x3, %ecx
+       jmp     .L1_test
+
+       .p2align 4
+.loop1:        
+       movaps  (%eax), %xmm0
+       mulps   (%edx), %xmm0
+       addl    $0x10, %edx
+       addl    $0x10, %eax
+       addps   %xmm0, %xmm4
+.L1_test:      
+       decl    %ecx
+       jge     .loop1
+
+       
+       # set up for primary loop which is unrolled 4 times
+       
+       movl    16(%ebp), %ecx
+       movaps  %xmm5, %xmm6            # zero remaining accumulators
+       movaps  %xmm5, %xmm7 
+
+       shrl    $2, %ecx                # n_4_float_blocks / 4
+       je      .cleanup                # if zero, take short path
+
+       # finish setup and loop priming
+
+       movaps  0x00(%eax), %xmm0
+       movaps  %xmm5, %xmm2            
+       movaps  0x10(%eax), %xmm1
+       movaps  %xmm5, %xmm3
+
+       # we know ecx is not zero, we checked above,
+       # hence enter loop at top
+
+       .p2align 4
+.loop2:
+       mulps   (%edx), %xmm0
+       addps   %xmm2, %xmm6
+       movaps  0x20(%eax), %xmm2
+
+       mulps   0x10(%edx), %xmm1
+       addps   %xmm3, %xmm7
+       movaps  0x30(%eax), %xmm3
+
+       mulps   0x20(%edx), %xmm2
+       addps   %xmm0, %xmm4
+       movaps  0x40(%eax), %xmm0
+
+       mulps   0x30(%edx), %xmm3
+       addps   %xmm1, %xmm5
+       movaps  0x50(%eax), %xmm1
+
+       addl    $0x40, %edx
+       addl    $0x40, %eax
+       decl    %ecx
+       jne     .loop2
+
+       # OK, now we've done with all the multiplies, but
+       # we still need to handle the unaccumulated
+       # products in xmm2 and xmm3
+
+       addps   %xmm2, %xmm6
+       addps   %xmm3, %xmm7
+
+       # now we want to add all accumulators into xmm4
+
+       addps   %xmm5, %xmm4
+       addps   %xmm6, %xmm7
+       addps   %xmm7, %xmm4
+
+       
+       # At this point, xmm4 contains 4 partial sums.  We need
+       # to compute a "horizontal add" across xmm4.  
+       # This is a fairly nasty operation...
+       
+.cleanup:                              # xmm4 = d1 d2 d3 d4
+       xorps   %xmm0, %xmm0            # xmm0 = 0 0 0 0  (may be unnecessary)
+       movhlps %xmm4, %xmm0            # xmm0 = 0 0 d1 d2
+       addps   %xmm4, %xmm0            # xmm0 = d1 d2 d1+d3 d2+d4
+       movaps  %xmm0, %xmm1            # xmm1 = d1 d2 d1+d3 d2+d4
+       shufps  $0xE1, %xmm4, %xmm1     # xmm1 = d1 d2 d2+d4 d1+d3
+       addss   %xmm1, %xmm0            # xmm1 = d1 d2 d1+d3 d1+d2+d3+d4
+       movss   %xmm0, 16(%ebp)         # store low 32 bits (sum) to memory
+       flds    16(%ebp)                # and load onto FPU stack for return
+
+       popl    %ebp
+       ret
+
+FUNC_TAIL(float_dotprod_sse)
+       .ident  "Hand coded x86 SSE assembly"
diff --git a/gnuradio-core/src/lib/filter/float_dotprod_sse64.S b/gnuradio-core/src/lib/filter/float_dotprod_sse64.S
new file mode 100644 (file)
index 0000000..c7f821a
--- /dev/null
@@ -0,0 +1,161 @@
+#
+# Copyright 2002,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 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.
+# 
+
+
+# input and taps are guarenteed to be 16 byte aligned.
+# n_4_float_blocks is != 0
+#      
+#
+#  float 
+#  float_dotprod_generic (const float *input,
+#                         const float *taps, unsigned n_4_float_blocks)
+#  {
+#    float sum0 = 0;
+#    float sum1 = 0;
+#    float sum2 = 0;
+#    float sum3 = 0;
+#  
+#    do {
+#  
+#      sum0 += input[0] * taps[0];
+#      sum1 += input[1] * taps[1];
+#      sum2 += input[2] * taps[2];
+#      sum3 += input[3] * taps[3];
+#  
+#      input += 4;
+#      taps += 4;
+#  
+#    } while (--n_4_float_blocks != 0);
+#  
+#  
+#    return sum0 + sum1 + sum2 + sum3;
+#  }
+#              
+
+#include "assembly.h"
+
+
+       .file   "float_dotprod_sse64.S"
+       .version        "01.01"
+.text
+       .p2align 4
+.globl GLOB_SYMB(float_dotprod_sse)
+       DEF_FUNC_HEAD(float_dotprod_sse)
+GLOB_SYMB(float_dotprod_sse):
+
+       # intput: rdi, taps: rsi, n_2_ccomplex_blocks: rdx
+
+       mov     %rdx, %rax
+
+       # xmm0 xmm1 xmm2 xmm3 are used to hold taps and the result of mults
+       # xmm4 xmm5 xmm6 xmm7 are used to hold the accumulated results
+
+       xorps   %xmm4, %xmm4            # zero two accumulators
+       xorps   %xmm5, %xmm5            # xmm5 holds zero for use below
+
+       # first handle any non-zero remainder of (n_4_float_blocks % 4)
+
+       and     $0x3, %rax
+       jmp     .L1_test
+
+       .p2align 4
+.loop1:        
+       movaps  (%rsi), %xmm0
+       mulps   (%rdi), %xmm0
+       add     $0x10, %rdi
+       add     $0x10, %rsi
+       addps   %xmm0, %xmm4
+.L1_test:      
+       dec     %rax
+       jge     .loop1
+
+       
+       # set up for primary loop which is unrolled 4 times
+       
+       movaps  %xmm5, %xmm6            # zero remaining accumulators
+       movaps  %xmm5, %xmm7 
+
+       shr     $2, %rdx                # n_4_float_blocks / 4
+       je      .cleanup                # if zero, take short path
+
+       # finish setup and loop priming
+
+       movaps  0x00(%rsi), %xmm0
+       movaps  %xmm5, %xmm2            
+       movaps  0x10(%rsi), %xmm1
+       movaps  %xmm5, %xmm3
+
+       # we know rdx is not zero, we checked above,
+       # hence enter loop at top
+
+       .p2align 4
+.loop2:
+       mulps   (%rdi), %xmm0
+       addps   %xmm2, %xmm6
+       movaps  0x20(%rsi), %xmm2
+
+       mulps   0x10(%rdi), %xmm1
+       addps   %xmm3, %xmm7
+       movaps  0x30(%rsi), %xmm3
+
+       mulps   0x20(%rdi), %xmm2
+       addps   %xmm0, %xmm4
+       movaps  0x40(%rsi), %xmm0
+
+       mulps   0x30(%rdi), %xmm3
+       addps   %xmm1, %xmm5
+       movaps  0x50(%rsi), %xmm1
+
+       add     $0x40, %rdi
+       add     $0x40, %rsi
+       dec     %rdx
+       jne     .loop2
+
+       # OK, now we've done with all the multiplies, but
+       # we still need to handle the unaccumulated
+       # products in xmm2 and xmm3
+
+       addps   %xmm2, %xmm6
+       addps   %xmm3, %xmm7
+
+       # now we want to add all accumulators into xmm4
+
+       addps   %xmm5, %xmm4
+       addps   %xmm6, %xmm7
+       addps   %xmm7, %xmm4
+
+       
+       # At this point, xmm4 contains 4 partial sums.  We need
+       # to compute a "horizontal add" across xmm4.  
+       # This is a fairly nasty operation...
+       
+.cleanup:                              # xmm4 = d1 d2 d3 d4
+       xorps   %xmm0, %xmm0            # xmm0 = 0 0 0 0  (may be unnecessary)
+       movhlps %xmm4, %xmm0            # xmm0 = 0 0 d1 d2
+       addps   %xmm4, %xmm0            # xmm0 = d1 d2 d1+d3 d2+d4
+       movaps  %xmm0, %xmm1            # xmm1 = d1 d2 d1+d3 d2+d4
+       shufps  $0xE1, %xmm4, %xmm1     # xmm1 = d1 d2 d2+d4 d1+d3
+       addss   %xmm1, %xmm0            # xmm1 = d1 d2 d1+d3 d1+d2+d3+d4
+
+       retq
+
+FUNC_TAIL(float_dotprod_sse)
+       .ident  "Hand coded x86_64 SSE assembly"
diff --git a/gnuradio-core/src/lib/filter/float_dotprod_x86.h b/gnuradio-core/src/lib/filter/float_dotprod_x86.h
new file mode 100644 (file)
index 0000000..7a10192
--- /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 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.
+ */
+
+#ifndef _FLOAT_DOTPROD_X86_H_
+#define _FLOAT_DOTPROD_X86_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+float 
+float_dotprod_3dnow (const float *input,
+                    const float *taps, unsigned n_4_float_blocks);
+
+float 
+float_dotprod_sse (const float *input,
+                  const float *taps, unsigned n_4_float_blocks);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+#endif /* _FLOAT_DOTPROD_X86_H_ */
diff --git a/gnuradio-core/src/lib/filter/generate_all.py b/gnuradio-core/src/lib/filter/generate_all.py
new file mode 100755 (executable)
index 0000000..dcbe75d
--- /dev/null
@@ -0,0 +1,46 @@
+#!/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 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.
+# 
+
+from build_utils import output_glue
+
+import generate_gr_fir_filter_XXX
+import generate_gr_interp_fir_filter_XXX
+import generate_gr_rational_resampler_base_XXX
+import generate_gr_freq_xlating_fir_filter_XXX
+import generate_gr_fir_sysconfig_generic
+import generate_gr_fir_sysconfig
+import generate_gr_fir_util
+import generate_gr_fir_XXX
+
+def generate_all():
+    generate_gr_fir_XXX.generate()
+    generate_gr_fir_filter_XXX.generate()
+    generate_gr_interp_fir_filter_XXX.generate()
+    generate_gr_rational_resampler_base_XXX.generate()
+    generate_gr_freq_xlating_fir_filter_XXX.generate()
+    generate_gr_fir_sysconfig_generic.generate()
+    generate_gr_fir_sysconfig.generate()
+    generate_gr_fir_util.generate()
+    output_glue('filter')
+
+if __name__ == '__main__':
+    generate_all()
diff --git a/gnuradio-core/src/lib/filter/generate_gr_fir_XXX.py b/gnuradio-core/src/lib/filter/generate_gr_fir_XXX.py
new file mode 100755 (executable)
index 0000000..e55ff85
--- /dev/null
@@ -0,0 +1,75 @@
+#!/bin/env python
+# -*- 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 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.
+# 
+
+import re
+from generate_utils import *
+
+roots = ['gr_fir_XXX', 'gr_fir_XXX_generic']
+
+
+# figure out accumulator type.  Use biggest of input, output and tap type
+
+def code3_to_acc_code (code3):
+    if i_code (code3) == 'c' or o_code (code3) == 'c' or tap_code (code3) == 'c':
+        return 'c'
+    if i_code (code3) == 'f' or o_code (code3) == 'f' or tap_code (code3) == 'f':
+        return 'f'
+    if i_code (code3) == 'i' or o_code (code3) == 'i' or tap_code (code3) == 'i':
+        return 'i'
+    return 'i'                          # even short short short needs int accumulator
+
+
+def code3_to_input_cast (code3):
+    if i_code (code3) == 's' and o_code (code3) == 'c':
+        return '(float)'
+    return ''
+
+def expand_h_cc (root, code3):
+    d = init_dict (root, code3)
+    expand_template (d, root + '.h.t')
+    expand_template (d, root + '.cc.t')
+
+def init_dict (root, code3):
+    name = re.sub ('X+', code3, root)
+    d = standard_dict (name, code3)
+    d['FIR_TYPE'] = 'gr_fir_' + code3
+    d['INPUT_CAST'] = code3_to_input_cast (code3)
+    acc_code = code3_to_acc_code (code3)
+    d['ACC_TYPE'] = char_to_type[acc_code]
+    if acc_code == 'c':
+        d['N_UNROLL'] = '2'
+        d['VRCOMPLEX_INCLUDE'] = '#include <gr_types.h>'
+    else:
+        d['N_UNROLL'] = '4'
+        d['VRCOMPLEX_INCLUDE'] = ''
+    return d
+    
+
+def generate ():
+    for r in roots:
+        for s in fir_signatures:
+            expand_h_cc (r, s)
+
+
+if __name__ == '__main__':
+    generate ()
diff --git a/gnuradio-core/src/lib/filter/generate_gr_fir_filter_XXX.py b/gnuradio-core/src/lib/filter/generate_gr_fir_filter_XXX.py
new file mode 100755 (executable)
index 0000000..e3c0ec7
--- /dev/null
@@ -0,0 +1,49 @@
+#!/bin/env python
+# -*- python -*-
+#
+# Copyright 2003,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.
+# 
+
+import re
+from generate_utils import *
+
+roots = ['gr_fir_filter_XXX']
+
+
+def expand_h_cc_i (root, code3):
+    d = init_dict (root, code3)
+    expand_template (d, root + '.h.t')
+    expand_template (d, root + '.cc.t')
+    expand_template (d, root + '.i.t')
+
+def init_dict (root, code3):
+    name = re.sub ('X+', code3, root)
+    d = standard_dict (name, code3)
+    d['FIR_TYPE'] = 'gr_fir_' + code3
+    return d
+
+def generate ():
+    for r in roots:
+        for s in fir_signatures:
+            expand_h_cc_i (r, s)
+
+if __name__ == '__main__':
+    generate ()
+    
diff --git a/gnuradio-core/src/lib/filter/generate_gr_fir_sysconfig.py b/gnuradio-core/src/lib/filter/generate_gr_fir_sysconfig.py
new file mode 100755 (executable)
index 0000000..3c78daa
--- /dev/null
@@ -0,0 +1,127 @@
+#!/bin/env python
+# -*- 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 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.
+# 
+
+from generate_utils import *
+
+
+# ----------------------------------------------------------------
+
+def make_gr_fir_sysconfig_h ():
+    out = open_and_log_name ('gr_fir_sysconfig.h', 'w')
+    out.write (copyright)
+
+    out.write (
+'''
+/*
+ * WARNING: This file is automatically generated by generate_gr_fir_sysconfig.py
+ * Any changes made to this file will be overwritten.
+ */
+
+#ifndef INCLUDED_GR_FIR_SYSCONFIG_H
+#define INCLUDED_GR_FIR_SYSCONFIG_H
+
+#include <gr_types.h>
+
+''')
+
+    # for sig in fir_signatures:
+    #    out.write ('class gr_fir_' + sig + ';\n')
+
+    out.write ('#include <gr_fir_util.h>\n')
+
+    out.write (
+'''
+/*!
+ * \\brief abstract base class for configuring the automatic selection of the
+ * fastest gr_fir for your platform.
+ *
+ * This is used internally by gr_fir_util.
+ */
+
+class gr_fir_sysconfig {
+public:
+  virtual ~gr_fir_sysconfig ();
+
+''')
+    
+    for sig in fir_signatures:
+      out.write (('  virtual gr_fir_%s *create_gr_fir_%s (const std::vector<%s> &taps) = 0;\n' %
+        (sig, sig, tap_type (sig))))
+
+    out.write ('\n')
+
+    for sig in fir_signatures:
+      out.write (('  virtual void get_gr_fir_%s_info (std::vector<gr_fir_%s_info> *info) = 0;\n' %
+        (sig, sig)))
+
+    out.write (
+'''
+};
+
+/*
+ * This returns the single instance of the appropriate derived class.
+ * This function must be defined only once in the system, and should be defined 
+ * in the platform specific code.
+ */
+
+gr_fir_sysconfig *gr_fir_sysconfig_singleton ();
+
+
+#endif /* INCLUDED_GR_FIR_SYSCONFIG_H */
+''')
+    out.close ()
+    
+
+# ----------------------------------------------------------------
+
+def make_gr_fir_sysconfig_cc ():
+    out = open_and_log_name ('gr_fir_sysconfig.cc', 'w')
+    out.write (copyright)
+
+    out.write (
+'''
+/*
+ * WARNING: This file is automatically generated by generate_gr_fir_sysconfig.py
+ * Any changes made to this file will be overwritten.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <gr_fir_sysconfig.h>
+
+gr_fir_sysconfig::~gr_fir_sysconfig ()
+{
+}
+''')
+    out.close ()
+    
+
+# ----------------------------------------------------------------
+
+def generate ():
+    make_gr_fir_sysconfig_h ()
+    make_gr_fir_sysconfig_cc ()
+
+if __name__ == '__main__':
+    generate ()
diff --git a/gnuradio-core/src/lib/filter/generate_gr_fir_sysconfig_generic.py b/gnuradio-core/src/lib/filter/generate_gr_fir_sysconfig_generic.py
new file mode 100755 (executable)
index 0000000..78cf377
--- /dev/null
@@ -0,0 +1,182 @@
+#!/bin/env python
+# -*- 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 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.
+# 
+
+from generate_utils import *
+
+
+# ----------------------------------------------------------------
+
+def make_gr_fir_sysconfig_generic_h ():
+    out = open_and_log_name ('gr_fir_sysconfig_generic.h', 'w')
+    out.write (copyright)
+
+    out.write (
+'''
+/*
+ * WARNING: This file is automatically generated by
+ * generate_gr_fir_sysconfig_generic.py.
+ *
+ * Any changes made to this file will be overwritten.
+ */
+
+#ifndef _GR_FIR_SYSCONFIG_GENERIC_H_
+#define _GR_FIR_SYSCONFIG_GENERIC_H_
+
+#include <gr_fir_sysconfig.h>
+
+''')
+
+    out.write (
+'''
+class gr_fir_sysconfig_generic : public gr_fir_sysconfig {
+public:
+''')
+    
+    for sig in fir_signatures:
+      out.write (('  virtual gr_fir_%s *create_gr_fir_%s (const std::vector<%s> &taps);\n' %
+        (sig, sig, tap_type (sig))))
+
+    out.write ('\n')
+
+    for sig in fir_signatures:
+      out.write (('  virtual void get_gr_fir_%s_info (std::vector<gr_fir_%s_info> *info);\n' %
+        (sig, sig)))
+
+    out.write (
+'''
+};
+
+
+#endif /* _GR_FIR_SYSCONFIG_GENERIC_H_ */
+''')
+    out.close ()
+    
+
+# ----------------------------------------------------------------
+
+def make_constructor (sig, out):
+    out.write ('''
+static gr_fir_%s *
+make_gr_fir_%s (const std::vector<%s> &taps)
+{
+  return new gr_fir_%s_generic (taps);
+}
+''' % (sig, sig, tap_type (sig), sig))
+  
+
+def make_creator (sig, out):
+    out.write ('''
+gr_fir_%s *
+gr_fir_sysconfig_generic::create_gr_fir_%s (const std::vector<%s> &taps)
+{
+  return make_gr_fir_%s (taps);
+}
+''' % (sig, sig, tap_type (sig), sig))
+    
+
+def make_info (sig, out):
+    out.write ('''
+void
+gr_fir_sysconfig_generic::get_gr_fir_%s_info (std::vector<gr_fir_%s_info> *info)
+{
+  info->resize (1);
+  (*info)[0].name = "generic";
+  (*info)[0].create = make_gr_fir_%s;
+}
+''' % (sig, sig, sig))
+
+    
+# ----------------------------------------------------------------
+
+def make_gr_fir_sysconfig_generic_cc ():
+    out = open_and_log_name ('gr_fir_sysconfig_generic.cc', 'w')
+    out.write (copyright)
+
+    out.write (
+'''
+/*
+ * WARNING: This file is automatically generated by
+ * generate_gr_fir_sysconfig_generic.py.
+ *
+ * Any changes made to this file will be overwritten.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <gr_fir_sysconfig_generic.h>
+
+''')
+    
+    for sig in fir_signatures:
+        out.write ('#include <gr_fir_%s_generic.h>\n' % (sig))
+
+    out.write (
+'''
+/*
+ * ----------------------------------------------------------------
+ * static functions that serve as constructors returned by info
+ * ----------------------------------------------------------------
+ */
+''')
+
+    for sig in fir_signatures:
+        make_constructor (sig, out)
+
+    out.write (
+'''
+/*
+ * ----------------------------------------------------------------
+ * return instances of the generic C++ versions of these classes.
+ * ----------------------------------------------------------------
+ */
+''')
+
+    for sig in fir_signatures:
+        make_creator (sig, out)
+
+    out.write (
+'''
+/*
+ * Return info about available implementations.
+ *
+ * This is the bottom of the concrete hierarchy, so we set the
+ * size of the vector to 1, and install our info.  Classes derived
+ * from us invoke us first, then append their own info.
+ */
+''')
+
+    for sig in fir_signatures:
+        make_info (sig, out)
+
+
+    out.close ()
+
+# ----------------------------------------------------------------
+
+def generate ():
+    make_gr_fir_sysconfig_generic_h ()
+    make_gr_fir_sysconfig_generic_cc ()
+
+if __name__ == '__main__':
+    generate ()
diff --git a/gnuradio-core/src/lib/filter/generate_gr_fir_util.py b/gnuradio-core/src/lib/filter/generate_gr_fir_util.py
new file mode 100755 (executable)
index 0000000..80d9186
--- /dev/null
@@ -0,0 +1,185 @@
+#!/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 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.
+# 
+
+from generate_utils import *
+
+def make_info_struct (out, sig):
+    out.write (
+'''
+struct gr_fir_%s_info {
+  const char    *name;             // implementation name, e.g., "generic", "SSE", "3DNow!"
+  gr_fir_%s    *(*create)(const std::vector<%s> &taps);
+};
+''' % (sig, sig, tap_type(sig)))
+
+def make_create (out, sig):
+    out.write ('''  static gr_fir_%s *create_gr_fir_%s (const std::vector<%s> &taps);
+''' % (sig, sig, tap_type (sig)))
+    
+def make_info (out, sig):
+    out.write ('''  static void get_gr_fir_%s_info (std::vector<gr_fir_%s_info> *info);
+''' % (sig, sig))
+    
+
+# ----------------------------------------------------------------
+
+def make_gr_fir_util_h ():
+    out = open_and_log_name ('gr_fir_util.h', 'w')
+    out.write (copyright)
+
+    out.write (
+'''
+/*
+ * WARNING: This file is automatically generated by
+ * generate_gr_fir_util.py.
+ *
+ * Any changes made to this file will be overwritten.
+ */
+
+#ifndef INCLUDED_GR_FIR_UTIL_H
+#define INCLUDED_GR_FIR_UTIL_H
+
+/*!
+ * \\brief routines to create gr_fir_XXX's
+ *
+ * This class handles selecting the fastest version of the finite
+ * implulse response filter available for your platform.  This
+ * interface should be used by the rest of the system for creating
+ * gr_fir_XXX's.
+ *
+ * The trailing suffix has the form _IOT where I codes the input type,
+ * O codes the output type, and T codes the tap type.
+ * I,O,T are elements of the set 's' (short), 'f' (float), 'c' (gr_complex), 
+ * 'i' (short)
+ */
+
+#include <gr_types.h>
+
+''')
+   
+    for sig in fir_signatures:
+       out.write ('class gr_fir_%s;\n' % sig);
+
+    out.write ('\n// structures returned by get_gr_fir_XXX_info methods\n\n')
+
+    for sig in fir_signatures:
+        make_info_struct (out, sig)
+
+    out.write ('''
+struct gr_fir_util {
+
+  // create a fast version of gr_fir_XXX.
+
+''')
+    
+    for sig in fir_signatures:
+        make_create (out, sig)
+
+    out.write ('''
+  // Get information about all gr_fir_XXX implementations.
+  // This is useful for benchmarking, testing, etc without having to
+  // know a priori what's linked into this image
+  //
+  // The caller must pass in a valid pointer to a vector.
+  // The vector will be filled with structs describing the
+  // available implementations.
+
+''')
+
+    for sig in fir_signatures:
+        make_info (out, sig)
+
+    out.write ('''
+};
+
+#endif /* INCLUDED_GR_FIR_UTIL_H */
+''')
+    out.close ()
+
+
+# ----------------------------------------------------------------
+
+def make_constructor_cc (out, sig):
+    out.write (
+'''
+gr_fir_%s *
+gr_fir_util::create_gr_fir_%s (const std::vector<%s> &taps)
+{
+  return gr_fir_sysconfig_singleton()->create_gr_fir_%s (taps);
+}
+''' % (sig, sig, tap_type (sig), sig))
+
+
+def make_info_cc (out, sig):
+    out.write (
+'''
+void
+gr_fir_util::get_gr_fir_%s_info (std::vector<gr_fir_%s_info> *info)
+{
+  gr_fir_sysconfig_singleton()->get_gr_fir_%s_info (info);
+}
+''' % (sig, sig, sig))
+
+    
+def make_gr_fir_util_cc ():
+    out = open_and_log_name ('gr_fir_util.cc', 'w')
+    out.write (copyright)
+    out.write ('''
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <gr_fir_util.h>
+#include <gr_fir_sysconfig.h>
+
+//
+// There's no problem that can't be solved by the addition of
+// another layer of indirection...
+//
+
+// --- constructors ---
+
+''')
+
+    for sig in fir_signatures:
+        make_constructor_cc (out, sig)
+
+    out.write ('''
+// --- info gatherers ---
+
+''')
+    
+    for sig in fir_signatures:
+        make_info_cc (out, sig)
+
+    out.close ()    
+    
+
+# ----------------------------------------------------------------
+
+def generate ():
+    make_gr_fir_util_h ()
+    make_gr_fir_util_cc ()
+
+if __name__ == '__main__':
+    generate ()
+    
diff --git a/gnuradio-core/src/lib/filter/generate_gr_freq_xlating_fir_filter_XXX.py b/gnuradio-core/src/lib/filter/generate_gr_freq_xlating_fir_filter_XXX.py
new file mode 100755 (executable)
index 0000000..4a34556
--- /dev/null
@@ -0,0 +1,53 @@
+#!/bin/env python
+# -*- python -*-
+#
+# Copyright 2003,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.
+# 
+
+import re
+from generate_utils import *
+
+# files to generate
+
+fx_signatures = [ 'scf', 'scc', 'fcf', 'fcc', 'ccf', 'ccc' ]
+
+roots = ['gr_freq_xlating_fir_filter_XXX']
+
+def expand_h_cc_i (root, code3):
+    d = init_dict (root, code3)
+    expand_template (d, root + '.h.t')
+    expand_template (d, root + '.cc.t')
+    expand_template (d, root + '.i.t')
+
+def init_dict (root, code3):
+    name = re.sub ('X+', code3, root)
+    d = standard_dict (name, code3)
+    d['FIR_TYPE'] = 'gr_fir_' + i_code (code3) + 'cc'
+    return d
+
+
+def generate ():
+    for r in roots:
+        for s in fx_signatures:
+            expand_h_cc_i (r, s)
+
+
+if __name__ == '__main__':
+    generate ()
diff --git a/gnuradio-core/src/lib/filter/generate_gr_interp_fir_filter_XXX.py b/gnuradio-core/src/lib/filter/generate_gr_interp_fir_filter_XXX.py
new file mode 100644 (file)
index 0000000..00b3c78
--- /dev/null
@@ -0,0 +1,48 @@
+#!/bin/env python
+# -*- python -*-
+#
+# Copyright 2003,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.
+# 
+
+import re
+from generate_utils import *
+
+roots = ['gr_interp_fir_filter_XXX']
+
+def expand_h_cc_i (root, code3):
+    d = init_dict (root, code3)
+    expand_template (d, root + '.h.t')
+    expand_template (d, root + '.cc.t')
+    expand_template (d, root + '.i.t')
+
+def init_dict (root, code3):
+    name = re.sub ('X+', code3, root)
+    d = standard_dict (name, code3)
+    d['FIR_TYPE'] = 'gr_fir_' + code3
+    return d
+
+def generate ():
+    for r in roots:
+        for s in fir_signatures:
+            expand_h_cc_i (r, s)
+
+if __name__ == '__main__':
+    generate ()
+    
diff --git a/gnuradio-core/src/lib/filter/generate_gr_rational_resampler_base_XXX.py b/gnuradio-core/src/lib/filter/generate_gr_rational_resampler_base_XXX.py
new file mode 100644 (file)
index 0000000..0f96451
--- /dev/null
@@ -0,0 +1,48 @@
+#!/bin/env python
+# -*- python -*-
+#
+# Copyright 2003,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.
+# 
+
+import re
+from generate_utils import *
+
+roots = ['gr_rational_resampler_base_XXX']
+
+def expand_h_cc_i (root, code3):
+    d = init_dict (root, code3)
+    expand_template (d, root + '.h.t')
+    expand_template (d, root + '.cc.t')
+    expand_template (d, root + '.i.t')
+
+def init_dict (root, code3):
+    name = re.sub ('X+', code3, root)
+    d = standard_dict (name, code3)
+    d['FIR_TYPE'] = 'gr_fir_' + code3
+    return d
+
+def generate ():
+    for r in roots:
+        for s in fir_signatures:
+            expand_h_cc_i (r, s)
+
+if __name__ == '__main__':
+    generate ()
+    
diff --git a/gnuradio-core/src/lib/filter/generate_utils.py b/gnuradio-core/src/lib/filter/generate_utils.py
new file mode 100644 (file)
index 0000000..2eeb38e
--- /dev/null
@@ -0,0 +1,31 @@
+#
+# 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 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.
+# 
+
+## -----------------------------------------------------------------------
+## signatures defines which variations to generate (input, output, taps)
+
+fir_signatures = [ 'ccf', 'fcc', 'ccc', 'fff', 'scc', 'fsf' ]
+
+
+## -----------------------------------------------------------------------
+
+from build_utils import expand_template, copyright, open_and_log_name, standard_dict
+from build_utils_codes import *
diff --git a/gnuradio-core/src/lib/filter/gr_adaptive_fir_ccf.cc b/gnuradio-core/src/lib/filter/gr_adaptive_fir_ccf.cc
new file mode 100644 (file)
index 0000000..f2ab319
--- /dev/null
@@ -0,0 +1,81 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_adaptive_fir_ccf.h>
+#include <gr_io_signature.h>
+
+gr_adaptive_fir_ccf::gr_adaptive_fir_ccf(char *name, int decimation, const std::vector<float> &taps)
+  : gr_sync_decimator (name,
+                      gr_make_io_signature (1, 1, sizeof(gr_complex)),
+                      gr_make_io_signature (1, 1, sizeof(gr_complex)),
+                      decimation),
+    d_updated(false)
+{
+  d_taps = taps;
+  set_history(d_taps.size());
+}
+
+void gr_adaptive_fir_ccf::set_taps(const std::vector<float> &taps)
+{
+  d_new_taps = taps;
+  d_updated = true;
+}
+
+int gr_adaptive_fir_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_taps = d_new_taps;
+    set_history(d_taps.size());
+    d_updated = false;
+    return 0;               // history requirements may have changed.
+  }
+
+  int j = 0, k, l = d_taps.size();
+  for (int i = 0; i < noutput_items; i++) {
+    // Generic dot product of d_taps[] and in[]
+    gr_complex sum(0.0, 0.0);
+    for (k = 0; k < l; k++)
+      sum += d_taps[l-k-1]*in[j+k];
+    out[i] = sum;
+        
+    // Adjust taps
+    d_error = error(sum);
+    for (k = 0; k < l; k++) {
+      //printf("%f ", d_taps[k]);
+      update_tap(d_taps[l-k-1], in[j+k]);
+    }
+    //printf("\n");
+    
+    j += decimation();
+  }
+
+  return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/filter/gr_adaptive_fir_ccf.h b/gnuradio-core/src/lib/filter/gr_adaptive_fir_ccf.h
new file mode 100644 (file)
index 0000000..57a95a3
--- /dev/null
@@ -0,0 +1,57 @@
+/* -*- 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 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.
+ */
+
+#ifndef INCLUDED_GR_ADAPTIVE_FIR_CCF_H
+#define        INCLUDED_GR_ADAPTIVE_FIR_CCF_H
+
+#include <gr_sync_decimator.h>
+
+/*!
+ * \brief Adaptive FIR filter with gr_complex input, gr_complex output and float taps
+ * \ingroup filter
+ */
+class gr_adaptive_fir_ccf : public gr_sync_decimator
+{
+private:
+  std::vector<float>  d_new_taps;
+  bool                d_updated;
+
+protected:
+  float                      d_error;
+  std::vector<float>  d_taps;
+
+  // Override to calculate error signal per output
+  virtual float error(const gr_complex &out) = 0; 
+
+  // Override to calculate new weight from old, corresponding input
+  virtual void update_tap(float &tap, const gr_complex &in) = 0;
+  
+public:
+  gr_adaptive_fir_ccf(char *name, int decimation, const std::vector<float> &taps);
+  void set_taps(const std::vector<float> &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_adaptive_fir_ccf.i b/gnuradio-core/src/lib/filter/gr_adaptive_fir_ccf.i
new file mode 100644 (file)
index 0000000..896fb42
--- /dev/null
@@ -0,0 +1,30 @@
+/* -*- 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 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.
+ */
+
+class gr_adaptive_fir_ccf : public gr_sync_decimator
+{
+private:
+  gr_adaptive_fir_ccf(char *name, int decimation, const std::vector<float> &taps);
+
+public:
+  void set_taps(const std::vector<float> &taps);
+};
diff --git a/gnuradio-core/src/lib/filter/gr_cma_equalizer_cc.cc b/gnuradio-core/src/lib/filter/gr_cma_equalizer_cc.cc
new file mode 100644 (file)
index 0000000..29b8a3e
--- /dev/null
@@ -0,0 +1,41 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_cma_equalizer_cc.h>
+
+gr_cma_equalizer_cc_sptr
+gr_make_cma_equalizer_cc(int num_taps, float modulus, float mu)
+{
+  return gr_cma_equalizer_cc_sptr(new gr_cma_equalizer_cc(num_taps, modulus, mu));
+}
+
+gr_cma_equalizer_cc::gr_cma_equalizer_cc(int num_taps, float modulus, float mu)
+  : gr_adaptive_fir_ccf("cma_equalizer_cc", 1, std::vector<float>(num_taps)),
+    d_modulus(modulus), d_mu(mu)
+{
+  d_taps[0] = 1.0;
+}
+
diff --git a/gnuradio-core/src/lib/filter/gr_cma_equalizer_cc.h b/gnuradio-core/src/lib/filter/gr_cma_equalizer_cc.h
new file mode 100644 (file)
index 0000000..25c9968
--- /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 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.
+ */
+
+#ifndef INCLUDED_GR_CMA_EQUALIZER_CC_H
+#define        INCLUDED_GR_CMA_EQUALIZER_CC_H
+
+#include <gr_adaptive_fir_ccf.h>
+
+class gr_cma_equalizer_cc;
+typedef boost::shared_ptr<gr_cma_equalizer_cc> gr_cma_equalizer_cc_sptr;
+
+gr_cma_equalizer_cc_sptr 
+gr_make_cma_equalizer_cc(int num_taps, float modulus, float mu);
+
+/*!
+ * \brief Implements constant modulus adaptive filter on complex stream
+ * \ingroup filter
+ */
+class gr_cma_equalizer_cc : public gr_adaptive_fir_ccf
+{
+private:
+  float d_modulus;
+  float d_mu;
+  
+  friend gr_cma_equalizer_cc_sptr gr_make_cma_equalizer_cc(int num_taps, float modulus, float mu);
+  gr_cma_equalizer_cc(int num_taps, float modulus, float mu);
+
+protected:
+
+  virtual float error(const gr_complex &out) 
+  { 
+    return (d_modulus - norm(out)); 
+  }
+
+  virtual void update_tap(float &tap, const gr_complex &in) 
+  {
+    tap += d_mu*d_error*abs(in);
+  }
+  
+public:
+};
+
+#endif
diff --git a/gnuradio-core/src/lib/filter/gr_cma_equalizer_cc.i b/gnuradio-core/src/lib/filter/gr_cma_equalizer_cc.i
new file mode 100644 (file)
index 0000000..c64bfc3
--- /dev/null
@@ -0,0 +1,35 @@
+/* -*- 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 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.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,cma_equalizer_cc)
+
+%include <gr_adaptive_fir_ccf.i>
+
+gr_cma_equalizer_cc_sptr gr_make_cma_equalizer_cc(int num_taps, float modulus, float mu);
+
+class gr_cma_equalizer_cc : public gr_adaptive_fir_ccf
+{
+private:
+  gr_cma_equalizer_cc(int num_taps, float modulus, float mu);
+
+public:
+};
diff --git a/gnuradio-core/src/lib/filter/gr_cpu.cc b/gnuradio-core/src/lib/filter/gr_cpu.cc
new file mode 100644 (file)
index 0000000..7e926f3
--- /dev/null
@@ -0,0 +1,107 @@
+/* -*- 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 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.
+ */
+
+#include <gr_cpu.h>
+
+/*
+ * execute CPUID instruction, return EAX, EBX, ECX and EDX values in result
+ */
+extern "C" {
+void cpuid_x86 (unsigned int op, unsigned int result[4]);
+};
+
+/*
+ * CPUID functions returning a single datum
+ */
+
+static inline unsigned int cpuid_eax(unsigned int op)
+{
+  unsigned int regs[4];
+  cpuid_x86 (op, regs);
+  return regs[0];
+}
+
+static inline unsigned int cpuid_ebx(unsigned int op)
+{
+  unsigned int regs[4];
+  cpuid_x86 (op, regs);
+  return regs[1];
+}
+
+static inline unsigned int cpuid_ecx(unsigned int op)
+{
+  unsigned int regs[4];
+  cpuid_x86 (op, regs);
+  return regs[2];
+}
+
+static inline unsigned int cpuid_edx(unsigned int op)
+{
+  unsigned int regs[4];
+  cpuid_x86 (op, regs);
+  return regs[3];
+}
+
+// ----------------------------------------------------------------
+
+bool
+gr_cpu::has_mmx ()
+{
+  unsigned int edx = cpuid_edx (1);    // standard features
+  return (edx & (1 << 23)) != 0;
+}
+
+bool
+gr_cpu::has_sse ()
+{
+  unsigned int edx = cpuid_edx (1);    // standard features
+  return (edx & (1 << 25)) != 0;
+}
+
+bool
+gr_cpu::has_sse2 ()
+{
+  unsigned int edx = cpuid_edx (1);    // standard features
+  return (edx & (1 << 26)) != 0;
+}
+
+bool
+gr_cpu::has_3dnow ()
+{
+  unsigned int extended_fct_count = cpuid_eax (0x80000000);
+  if (extended_fct_count < 0x80000001)
+    return false;
+
+  unsigned int extended_features = cpuid_edx (0x80000001);
+  return (extended_features & (1 << 31)) != 0;
+}
+
+bool
+gr_cpu::has_3dnowext ()
+{
+  unsigned int extended_fct_count = cpuid_eax (0x80000000);
+  if (extended_fct_count < 0x80000001)
+    return false;
+
+  unsigned int extended_features = cpuid_edx (0x80000001);
+  return (extended_features & (1 << 30)) != 0;
+}
diff --git a/gnuradio-core/src/lib/filter/gr_cpu.h b/gnuradio-core/src/lib/filter/gr_cpu.h
new file mode 100644 (file)
index 0000000..563b60c
--- /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 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.
+ */
+
+#ifndef _GR_CPU_H_
+#define _GR_CPU_H_
+
+struct gr_cpu {
+  static bool has_mmx ();
+  static bool has_sse ();
+  static bool has_sse2 ();
+  static bool has_3dnow ();
+  static bool has_3dnowext ();
+};
+
+#endif /* _GR_CPU_H_ */
diff --git a/gnuradio-core/src/lib/filter/gr_fft_filter_ccc.cc b/gnuradio-core/src/lib/filter/gr_fft_filter_ccc.cc
new file mode 100644 (file)
index 0000000..c90e3a0
--- /dev/null
@@ -0,0 +1,210 @@
+/* -*- 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 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.
+ */
+
+/*
+ * WARNING: This file is automatically generated by generate_gr_fft_filter_XXX.py
+ * Any changes made to this file will be overwritten.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_fft_filter_ccc.h>
+#include <gr_io_signature.h>
+#include <gri_fft.h>
+#include <math.h>
+#include <assert.h>
+#include <stdexcept>
+#include <gr_firdes.h>
+
+#include <iostream>
+
+gr_fft_filter_ccc_sptr gr_make_fft_filter_ccc (int decimation, const std::vector<gr_complex> &taps)
+{
+  return gr_fft_filter_ccc_sptr (new gr_fft_filter_ccc (decimation, taps));
+}
+
+
+gr_fft_filter_ccc::gr_fft_filter_ccc (int decimation, const std::vector<gr_complex> &taps)
+  : gr_sync_decimator ("fft_filter_ccc",
+                      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)
+{
+  // if (decimation != 1)
+  //    throw std::invalid_argument("gr_fft_filter_ccc: decimation must be 1");
+
+  set_history(1);
+  actual_set_taps(taps);
+}
+
+gr_fft_filter_ccc::~gr_fft_filter_ccc ()
+{
+  delete d_fwdfft;
+  delete d_invfft;
+}
+
+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";
+}
+
+void
+gr_fft_filter_ccc::set_taps (const std::vector<gr_complex> &taps)
+{
+  d_new_taps = 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];
+  gr_complex *out = (gr_complex *) output_items[0];
+
+  if (d_updated){
+    actual_set_taps(d_new_taps);
+    d_updated = false;
+    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));
+  }
+
+  assert((out - (gr_complex *) output_items[0]) == noutput_items);
+  assert(dec_ctr == 0);
+
+  return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/filter/gr_fft_filter_ccc.h b/gnuradio-core/src/lib/filter/gr_fft_filter_ccc.h
new file mode 100644 (file)
index 0000000..06bc7c1
--- /dev/null
@@ -0,0 +1,77 @@
+/* -*- 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 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.
+ */
+#ifndef INCLUDED_GR_FFT_FILTER_CCC_H
+#define INCLUDED_GR_FFT_FILTER_CCC_H
+
+#include <gr_sync_decimator.h>
+
+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;
+
+/*!
+ * \brief Fast FFT filter with gr_complex input, gr_complex output and gr_complex taps
+ * \ingroup filter
+ */
+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;
+
+  /*!
+   * Construct a FFT filter with the given taps
+   *
+   * \param decimation >= 1
+   * \param taps        complex filter taps
+   */
+  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 ();
+
+  void set_taps (const std::vector<gr_complex> &taps);
+
+  int work (int noutput_items,
+           gr_vector_const_void_star &input_items,
+           gr_vector_void_star &output_items);
+};
+
+
+
+#endif /* INCLUDED_GR_FFT_FILTER_CCC_H */
diff --git a/gnuradio-core/src/lib/filter/gr_fft_filter_ccc.i b/gnuradio-core/src/lib/filter/gr_fft_filter_ccc.i
new file mode 100644 (file)
index 0000000..65cbb36
--- /dev/null
@@ -0,0 +1,39 @@
+/* -*- c++ -*- */
+/*
+ * 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 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.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,fft_filter_ccc)
+
+gr_fft_filter_ccc_sptr 
+gr_make_fft_filter_ccc (int decimation,
+                       const std::vector<gr_complex> &taps
+                       ) throw (std::invalid_argument);
+
+class gr_fft_filter_ccc : public gr_sync_decimator
+{
+ private:
+  gr_fft_filter_ccc (int decimation, const std::vector<gr_complex> &taps);
+
+ public:
+  ~gr_fft_filter_ccc ();
+
+  void set_taps (const std::vector<gr_complex> &taps);
+};
diff --git a/gnuradio-core/src/lib/filter/gr_fft_filter_fff.cc b/gnuradio-core/src/lib/filter/gr_fft_filter_fff.cc
new file mode 100644 (file)
index 0000000..ceb2e82
--- /dev/null
@@ -0,0 +1,211 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_fft_filter_fff.h>
+#include <gr_io_signature.h>
+#include <gri_fft.h>
+#include <math.h>
+#include <assert.h>
+#include <stdexcept>
+#include <gr_firdes.h>
+
+#include <iostream>
+
+gr_fft_filter_fff_sptr gr_make_fft_filter_fff (int decimation, const std::vector<float> &taps)
+{
+  return gr_fft_filter_fff_sptr (new gr_fft_filter_fff (decimation, taps));
+}
+
+
+gr_fft_filter_fff::gr_fft_filter_fff (int decimation, const std::vector<float> &taps)
+  : gr_sync_decimator ("fft_filter_fff",
+                      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)
+{
+  set_history(1);
+  actual_set_taps(taps);
+}
+
+gr_fft_filter_fff::~gr_fft_filter_fff ()
+{
+  delete d_fwdfft;
+  delete d_invfft;
+}
+
+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";
+}
+
+static void 
+print_vector_float(const std::string label, const std::vector<float> &x)
+{
+  std::cout << label;
+  for (unsigned i = 0; i < x.size(); i++)
+    std::cout << x[i] << " ";
+  std::cout << "\n";
+}
+
+void
+gr_fft_filter_fff::set_taps (const std::vector<float> &taps)
+{
+  d_new_taps = 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,
+                        gr_vector_void_star &output_items)
+{
+  const float *in = (const float *) input_items[0];
+  float *out = (float *) output_items[0];
+
+  if (d_updated){
+    actual_set_taps(d_new_taps);
+    d_updated = false;
+    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(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);
+
+  return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/filter/gr_fft_filter_fff.h b/gnuradio-core/src/lib/filter/gr_fft_filter_fff.h
new file mode 100644 (file)
index 0000000..bdd29b7
--- /dev/null
@@ -0,0 +1,76 @@
+/* -*- 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 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.
+ */
+#ifndef INCLUDED_GR_FFT_FILTER_FFF_H
+#define INCLUDED_GR_FFT_FILTER_FFF_H
+
+#include <gr_sync_decimator.h>
+
+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;
+
+/*!
+ * \brief Fast FFT filter with float input, float output and float taps
+ * \ingroup filter
+ */
+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;
+
+  /*!
+   * Construct a FFT filter with the given taps
+   *
+   * \param decimation >= 1
+   * \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 ();
+
+  void set_taps (const std::vector<float> &taps);
+
+  int work (int noutput_items,
+           gr_vector_const_void_star &input_items,
+           gr_vector_void_star &output_items);
+};
+
+#endif /* INCLUDED_GR_FFT_FILTER_FFF_H */
diff --git a/gnuradio-core/src/lib/filter/gr_fft_filter_fff.i b/gnuradio-core/src/lib/filter/gr_fft_filter_fff.i
new file mode 100644 (file)
index 0000000..5ee30eb
--- /dev/null
@@ -0,0 +1,39 @@
+/* -*- c++ -*- */
+/*
+ * 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 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.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,fft_filter_fff)
+
+gr_fft_filter_fff_sptr 
+gr_make_fft_filter_fff (int decimation,
+                       const std::vector<float> &taps
+                       ) throw (std::invalid_argument);
+
+class gr_fft_filter_fff : public gr_sync_decimator
+{
+ private:
+  gr_fft_filter_fff (int decimation, const std::vector<float> &taps);
+
+ public:
+  ~gr_fft_filter_fff ();
+
+  void set_taps (const std::vector<float> &taps);
+};
diff --git a/gnuradio-core/src/lib/filter/gr_filter_delay_fc.cc b/gnuradio-core/src/lib/filter/gr_filter_delay_fc.cc
new file mode 100644 (file)
index 0000000..09f181e
--- /dev/null
@@ -0,0 +1,80 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_filter_delay_fc.h>
+#include <gr_fir_fff.h>
+#include <gr_fir_util.h>
+
+// public constructor
+gr_filter_delay_fc_sptr 
+gr_make_filter_delay_fc (const std::vector<float> &taps) 
+{
+  return gr_filter_delay_fc_sptr (new gr_filter_delay_fc (taps));
+}
+
+gr_filter_delay_fc::gr_filter_delay_fc (const std::vector<float> &taps)
+  : gr_sync_block ("filter_delay_fc",
+                  gr_make_io_signature (1, 2, sizeof (float)),
+                  gr_make_io_signature (1, 1, sizeof (gr_complex)))
+{
+  d_fir = gr_fir_util::create_gr_fir_fff (taps);
+  d_delay = d_fir->ntaps () / 2;
+  set_history (d_fir->ntaps ());
+}
+
+gr_filter_delay_fc::~gr_filter_delay_fc ()
+{
+  delete d_fir;
+}
+
+int
+gr_filter_delay_fc::work (int noutput_items,
+                    gr_vector_const_void_star &input_items,
+                    gr_vector_void_star &output_items)
+{
+  float *in0  = (float *) input_items[0];
+  float *in1  = (float *) input_items[1];
+  gr_complex *out = (gr_complex *) output_items[0];
+
+  switch (input_items.size ()){
+  case 1:
+    for (int i = 0; i < noutput_items; i++)
+      out[i] = gr_complex (in0[i + d_delay], 
+                          d_fir->filter (&in0[i]));
+    break;
+
+  case 2:
+    for (int j = 0; j < noutput_items; j++)
+      out[j] = gr_complex (in0[j + d_delay],
+                          d_fir->filter (&in1[j]));
+    break;
+
+  default:
+    assert (0);
+  }
+
+  return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/filter/gr_filter_delay_fc.h b/gnuradio-core/src/lib/filter/gr_filter_delay_fc.h
new file mode 100644 (file)
index 0000000..2b65c67
--- /dev/null
@@ -0,0 +1,72 @@
+/* -*- 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 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.
+ */
+
+#ifndef INCLUDED_GR_FILTER_DELAY_FC_H
+#define INCLUDED_GR_FILTER_DELAY_FC_H
+
+#include <gr_sync_block.h>
+#include <gr_io_signature.h>
+#include <gr_types.h>
+
+class gr_filter_delay_fc;
+typedef boost::shared_ptr<gr_filter_delay_fc> gr_filter_delay_fc_sptr;
+
+// public constructor
+gr_filter_delay_fc_sptr gr_make_filter_delay_fc (const std::vector<float> &taps);
+
+class gr_fir_fff;
+
+/*!
+ * \brief Filter-Delay Combination Block.
+ * \ingroup filter
+ *
+ * The block takes one or two float stream and outputs a complex
+ * stream. If only one float stream is input, the real output is
+ * a delayed version of this input and the imaginary output is the
+ * filtered output. If two floats are connected to the input, then
+ * the real output is the delayed version of the first input, and
+ * the imaginary output is the filtered output. The delay in the 
+ * real path accounts for the group delay introduced by the filter
+ * in the imaginary path. The filter taps needs to be calculated
+ * before initializing this block.
+ *
+ */
+class gr_filter_delay_fc : public gr_sync_block
+{
+ public:
+  ~gr_filter_delay_fc ();
+
+  int work (int noutput_items,
+           gr_vector_const_void_star &input_items,
+           gr_vector_void_star &output_items);
+
+ protected:
+  gr_filter_delay_fc (const std::vector<float> &taps);
+
+ private:
+  unsigned int  d_delay;
+  gr_fir_fff   *d_fir;
+
+  friend gr_filter_delay_fc_sptr gr_make_filter_delay_fc (const std::vector<float> &taps);
+};
+
+#endif /* INCLUDED_GR_FILTER_DELAY_FC_H */
diff --git a/gnuradio-core/src/lib/filter/gr_filter_delay_fc.i b/gnuradio-core/src/lib/filter/gr_filter_delay_fc.i
new file mode 100644 (file)
index 0000000..85603ce
--- /dev/null
@@ -0,0 +1,34 @@
+/* -*- 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 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.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,filter_delay_fc);
+
+gr_filter_delay_fc_sptr gr_make_filter_delay_fc (const std::vector<float> &taps);
+
+class gr_filter_delay_fc : public gr_sync_block
+{
+private:
+  gr_filter_delay_fc ();
+};
+
+// ----------------------------------------------------------------
+
diff --git a/gnuradio-core/src/lib/filter/gr_fir_XXX.cc.t b/gnuradio-core/src/lib/filter/gr_fir_XXX.cc.t
new file mode 100644 (file)
index 0000000..1f78662
--- /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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <@FIR_TYPE@.h>
+
+@FIR_TYPE@::~@FIR_TYPE@ ()
+{
+}
diff --git a/gnuradio-core/src/lib/filter/gr_fir_XXX.h.t b/gnuradio-core/src/lib/filter/gr_fir_XXX.h.t
new file mode 100644 (file)
index 0000000..a5bf3ed
--- /dev/null
@@ -0,0 +1,123 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002,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 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.
+ */
+
+/*
+ * WARNING: This file is automatically generated by generate_gr_fir_XXX.py
+ * Any changes made to this file will be overwritten.
+ */
+
+
+#ifndef @GUARD_NAME@
+#define @GUARD_NAME@
+
+#include <vector>
+@VRCOMPLEX_INCLUDE@
+#include <gr_reverse.h>
+
+/*!
+ * \brief Abstract class for FIR with @I_TYPE@ input, @O_TYPE@ output and @TAP_TYPE@ taps
+ * \ingroup filter_primitive
+ * 
+ * This is the abstract class for a Finite Impulse Response filter.
+ *
+ * The trailing suffix has the form _IOT where I codes the input type,
+ * O codes the output type, and T codes the tap type.
+ * I,O,T are elements of the set 's' (short), 'f' (float), 'c' (gr_complex), 'i' (int)
+ */
+
+class @FIR_TYPE@ {
+
+protected:
+  std::vector<@TAP_TYPE@>      d_taps;         // reversed taps
+
+public:
+
+  // CONSTRUCTORS
+
+  /*!
+   * \brief construct new FIR with given taps.
+   *
+   * Note that taps must be in forward order, e.g., coefficient 0 is
+   * stored in new_taps[0], coefficient 1 is stored in
+   * new_taps[1], etc.
+   */
+  @FIR_TYPE@ () {}
+  @FIR_TYPE@ (const std::vector<@TAP_TYPE@> &taps) : d_taps (gr_reverse(taps)) {}
+
+  virtual ~@FIR_TYPE@ ();
+
+  // MANIPULATORS
+
+  /*!
+   * \brief compute a single output value.
+   *
+   * \p input must have ntaps() valid entries.
+   * input[0] .. input[ntaps() - 1] are referenced to compute the output value.
+   *
+   * \returns the filtered input value.
+   */
+  virtual @O_TYPE@ filter (const @I_TYPE@ input[]) = 0;
+
+  /*!
+   * \brief compute an array of N output values.
+   *
+   * \p input must have (n - 1 + ntaps()) valid entries.
+   * input[0] .. input[n - 1 + ntaps() - 1] are referenced to compute the output values.
+   */
+  virtual void filterN (@O_TYPE@ output[], const @I_TYPE@ input[],
+                       unsigned long n) = 0;
+
+  /*!
+   * \brief compute an array of N output values, decimating the input
+   *
+   * \p input must have (decimate * (n - 1) + ntaps()) valid entries.
+   * input[0] .. input[decimate * (n - 1) + ntaps() - 1] are referenced to 
+   * compute the output values.
+   */
+  virtual void filterNdec (@O_TYPE@ output[], const @I_TYPE@ input[],
+                          unsigned long n, unsigned decimate) = 0;
+
+  /*!
+   * \brief install \p new_taps as the current taps.
+   */
+  virtual void set_taps (const std::vector<@TAP_TYPE@> &taps)
+  {
+    d_taps = gr_reverse(taps);
+  }
+
+  // ACCESSORS
+
+  /*!
+   * \return number of taps in filter.
+   */
+  unsigned ntaps () const { return d_taps.size (); }
+
+  /*!
+   * \return current taps
+   */
+  virtual const std::vector<@TAP_TYPE@> get_taps () const
+  {
+    return gr_reverse(d_taps);
+  }
+};
+
+#endif /* @GUARD_NAME@ */
diff --git a/gnuradio-core/src/lib/filter/gr_fir_XXX_generic.cc.t b/gnuradio-core/src/lib/filter/gr_fir_XXX_generic.cc.t
new file mode 100644 (file)
index 0000000..7bc7a5e
--- /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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <@FIR_TYPE@_generic.h>
+
+#if (@N_UNROLL@ == 4)
+
+@O_TYPE@
+@FIR_TYPE@_generic::filter (const @I_TYPE@ input[])
+{
+  static const int N_UNROLL = 4;
+
+  @ACC_TYPE@   acc0 = 0;
+  @ACC_TYPE@   acc1 = 0;
+  @ACC_TYPE@   acc2 = 0;
+  @ACC_TYPE@   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_CAST@ input[i + 0];
+    acc1 += d_taps[i + 1] * @INPUT_CAST@ input[i + 1];
+    acc2 += d_taps[i + 2] * @INPUT_CAST@ input[i + 2];
+    acc3 += d_taps[i + 3] * @INPUT_CAST@ input[i + 3];
+  }
+
+  for (; i < ntaps (); i++)
+    acc0 += d_taps[i] * @INPUT_CAST@ input[i];
+
+  return (@O_TYPE@) (acc0 + acc1 + acc2 + acc3);
+}
+
+#else 
+
+@O_TYPE@
+@FIR_TYPE@_generic::filter (const @I_TYPE@ input[])
+{
+  static const int N_UNROLL = 2;
+
+  @ACC_TYPE@   acc0 = 0;
+  @ACC_TYPE@   acc1 = 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_CAST@ input[i + 0];
+    acc1 += d_taps[i + 1] * @INPUT_CAST@ input[i + 1];
+  }
+
+  for (; i < ntaps (); i++)
+    acc0 += d_taps[i] * @INPUT_CAST@ input[i];
+
+  return (@O_TYPE@) (acc0 + acc1);
+}
+
+#endif // N_UNROLL
+
+void 
+@FIR_TYPE@_generic::filterN (@O_TYPE@ output[],
+                            const @I_TYPE@ input[],
+                            unsigned long n)
+{
+  for (unsigned i = 0; i < n; i++)
+    output[i] = filter (&input[i]);
+}
+
+void 
+@FIR_TYPE@_generic::filterNdec (@O_TYPE@ output[],
+                               const @I_TYPE@ input[],
+                               unsigned long n,
+                               unsigned decimate)
+{
+  unsigned j = 0;
+  for (unsigned i = 0; i < n; i++){
+    output[i] = filter (&input[j]);
+    j += decimate;
+  }
+}
diff --git a/gnuradio-core/src/lib/filter/gr_fir_XXX_generic.h.t b/gnuradio-core/src/lib/filter/gr_fir_XXX_generic.h.t
new file mode 100644 (file)
index 0000000..b1b2f40
--- /dev/null
@@ -0,0 +1,77 @@
+/* -*- 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 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.
+ */
+#ifndef @GUARD_NAME@
+#define @GUARD_NAME@
+
+#include <@FIR_TYPE@.h>
+
+/*!
+ * \brief Concrete class for generic implementation of FIR with @I_TYPE@ input, @O_TYPE@ output and @TAP_TYPE@ taps
+ *
+ * The trailing suffix has the form _IOT where I codes the input type,
+ * O codes the output type, and T codes the tap type.
+ * I,O,T are elements of the set 's' (short), 'f' (float), 'c' (gr_complex), 'i' (int)
+ */
+
+class @FIR_TYPE@_generic : public @FIR_TYPE@ {
+
+public:
+
+  // CREATORS
+  
+  @FIR_TYPE@_generic () {}
+  @FIR_TYPE@_generic (const std::vector<@TAP_TYPE@> &taps) : @FIR_TYPE@ (taps) {}
+
+  // MANIPULATORS
+
+  /*!
+   * \brief compute a single output value.
+   *
+   * \p input must have ntaps() valid entries.
+   * input[0] .. input[ntaps() - 1] are referenced to compute the output value.
+   *
+   * \returns the filtered input value.
+   */
+  virtual @O_TYPE@ filter (const @I_TYPE@ input[]);
+
+  /*!
+   * \brief compute an array of N output values.
+   *
+   * \p input must have (n - 1 + ntaps()) valid entries.
+   * input[0] .. input[n - 1 + ntaps() - 1] are referenced to compute the output values.
+   */
+  virtual void filterN (@O_TYPE@ output[], const @I_TYPE@ input[],
+                       unsigned long n);
+
+  /*!
+   * \brief compute an array of N output values, decimating the input
+   *
+   * \p input must have (decimate * (n - 1) + ntaps()) valid entries.
+   * input[0] .. input[decimate * (n - 1) + ntaps() - 1] are referenced to 
+   * compute the output values.
+   */
+  virtual void filterNdec (@O_TYPE@ output[], const @I_TYPE@ input[],
+                          unsigned long n, unsigned decimate);
+
+};
+
+#endif /* @GUARD_NAME@ */
diff --git a/gnuradio-core/src/lib/filter/gr_fir_ccc_simd.cc b/gnuradio-core/src/lib/filter/gr_fir_ccc_simd.cc
new file mode 100644 (file)
index 0000000..6d5cba3
--- /dev/null
@@ -0,0 +1,139 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <gr_fir_ccc_simd.h>
+
+#include <assert.h>
+#include <malloc16.h>
+#include <iostream>
+
+using std::cerr;
+using std::endl;
+
+gr_fir_ccc_simd::gr_fir_ccc_simd ()
+  : gr_fir_ccc_generic ()
+{
+  // cerr << "@@@ gr_fir_ccc_simd\n";
+
+  d_ccomplex_dotprod = 0;
+  
+  d_aligned_taps[0] = 0;
+  d_aligned_taps[1] = 0;
+  d_aligned_taps[2] = 0;
+  d_aligned_taps[3] = 0;
+}
+
+gr_fir_ccc_simd::gr_fir_ccc_simd (const std::vector<gr_complex> &new_taps)
+  : gr_fir_ccc_generic (new_taps)
+{
+  // cerr << "@@@ gr_fir_ccc_simd\n";
+
+  d_ccomplex_dotprod = 0;
+  
+  d_aligned_taps[0] = 0;
+  d_aligned_taps[1] = 0;
+  d_aligned_taps[2] = 0;
+  d_aligned_taps[3] = 0;
+  set_taps (new_taps);
+}
+
+gr_fir_ccc_simd::~gr_fir_ccc_simd ()
+{
+  free16Align (d_aligned_taps[0]);
+  free16Align (d_aligned_taps[1]);
+  free16Align (d_aligned_taps[2]);
+  free16Align (d_aligned_taps[3]);
+}
+
+void
+gr_fir_ccc_simd::set_taps (const std::vector<gr_complex> &inew_taps)
+{
+  gr_fir_ccc::set_taps (inew_taps);    // call superclass
+
+  const std::vector<gr_complex> new_taps = gr_reverse(inew_taps);
+  unsigned len = new_taps.size ();
+
+  // Make 4 copies of the coefficients, one for each data alignment
+  // Note use of special 16-byte-aligned version of calloc()
+  
+  for (unsigned i = 0; i < 4; i++){
+    free16Align (d_aligned_taps[i]);   // free old value
+
+    // this works because the bit representation of a IEEE floating point
+    // +zero is all zeros.  If you're using a different representation,
+    // you'll need to explictly set the result to the appropriate 0.0 value.
+    
+    d_aligned_taps[i] = (float *) calloc16Align (1 + (len + i - 1) / 2,
+                                              2 * 4 * sizeof (float));
+    if (d_aligned_taps[i] == 0){
+      // throw something...
+      cerr << "@@@ gr_fir_ccc_simd d_aligned_taps[" << i << "] == 0\n";
+    }
+
+    for (unsigned j = 0; j < len; j++) {
+      d_aligned_taps[i][2*(j+i)] = new_taps[j].real();
+      d_aligned_taps[i][2*(j+i)+1] = new_taps[j].imag();
+    }
+  }
+}
+
+gr_complex 
+gr_fir_ccc_simd::filter (const gr_complex input[])
+{
+  if (ntaps () == 0)
+    return 0.0;
+
+
+  // Round input data address down to 16 byte boundary
+  // NB: depending on the alignment of input[], memory
+  // before input[] will be accessed. The contents don't matter since 
+  // they'll be multiplied by zero coefficients. I can't conceive of any
+  // situation where this could cause a segfault since memory protection
+  // in the x86 machines is done on much larger boundaries.
+  
+  const gr_complex *ar = (gr_complex *)((unsigned long) input & ~15);
+
+  // Choose one of 4 sets of pre-shifted coefficients. al is both the
+  // index into d_aligned_taps[] and the number of 0 words padded onto
+  // that coefficients array for alignment purposes.
+
+  unsigned al = input - ar;
+
+  // call assembler routine to do the work, passing number of 2x4-float blocks.
+
+  // assert (((unsigned long) ar & 15) == 0);
+  // assert (((unsigned long) d_aligned_taps[al] & 15) == 0);
+
+  // cerr << "ar: " << ar << " d_aligned_taps[ar]: " << d_aligned_taps[al]
+  //  << " (ntaps() + al - 1)/2 + 1: " << (ntaps() + al -1) / 2 + 1 << endl;
+
+  float result[2];
+
+  d_ccomplex_dotprod ((float*)ar, d_aligned_taps[al], (ntaps() + al - 1) / 2 + 1, result);
+
+  // cerr << "result = " << result[0] << " " << result[1] << endl;
+
+  return gr_complex(result[0], result[1]);
+}
diff --git a/gnuradio-core/src/lib/filter/gr_fir_ccc_simd.h b/gnuradio-core/src/lib/filter/gr_fir_ccc_simd.h
new file mode 100644 (file)
index 0000000..8988887
--- /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 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.
+ */
+#ifndef INCLUDED_GR_FIR_CCC_SIMD_H
+#define INCLUDED_GR_FIR_CCC_SIMD_H
+
+#include <gr_fir_ccc_generic.h>
+
+/*!
+ * \brief common base class for SIMD versions of gr_fir_ccc
+ *
+ * This base class handles alignment issues common to SSE and 3DNOW
+ * subclasses.
+ */
+
+class gr_fir_ccc_simd : public gr_fir_ccc_generic
+{
+protected:
+  typedef void (*ccomplex_dotprod_t)(const float *input,
+                                    const float *taps,
+                                    unsigned n_2_ccomplex_blocks,
+                                    float *result);
+
+  /*!
+   * \p aligned_taps holds 4 copies of the coefficients preshifted
+   * by 0, 1, 2, or 3 floats to meet all possible input data alignments.
+   * This allows us to always fetch data and taps that are 128-bit aligned.
+   */
+  float                *d_aligned_taps[4];
+
+  ccomplex_dotprod_t   d_ccomplex_dotprod;     // fast dot product primitive
+
+public:
+
+  // CREATORS
+  gr_fir_ccc_simd ();
+  gr_fir_ccc_simd (const std::vector<gr_complex> &taps);
+  ~gr_fir_ccc_simd ();
+
+  // MANIPULATORS
+  virtual void set_taps (const std::vector<gr_complex> &taps);
+  virtual gr_complex filter (const gr_complex input[]);
+};
+
+#endif
diff --git a/gnuradio-core/src/lib/filter/gr_fir_ccc_x86.cc b/gnuradio-core/src/lib/filter/gr_fir_ccc_x86.cc
new file mode 100644 (file)
index 0000000..8b96c23
--- /dev/null
@@ -0,0 +1,77 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <gr_fir_ccc_x86.h>
+#include <ccomplex_dotprod_x86.h>
+
+/*
+ *     --- 3DNow! version ---
+ */
+gr_fir_ccc_3dnow::gr_fir_ccc_3dnow ()
+  : gr_fir_ccc_simd () 
+{
+  d_ccomplex_dotprod = ccomplex_dotprod_3dnow;
+}
+
+gr_fir_ccc_3dnow::gr_fir_ccc_3dnow (const std::vector<gr_complex> &new_taps)
+  : gr_fir_ccc_simd (new_taps)
+{
+  d_ccomplex_dotprod = ccomplex_dotprod_3dnow;
+}
+
+
+/*
+ *     --- 3DNow!Ext version ---
+ */
+gr_fir_ccc_3dnowext::gr_fir_ccc_3dnowext ()
+  : gr_fir_ccc_simd () 
+{
+  d_ccomplex_dotprod = ccomplex_dotprod_3dnowext;
+}
+
+gr_fir_ccc_3dnowext::gr_fir_ccc_3dnowext (const std::vector<gr_complex> &new_taps)
+  : gr_fir_ccc_simd (new_taps)
+{
+  d_ccomplex_dotprod = ccomplex_dotprod_3dnowext;
+}
+
+
+/*
+ *     --- SSE version ---
+ */
+gr_fir_ccc_sse::gr_fir_ccc_sse ()
+  : gr_fir_ccc_simd ()
+{
+  d_ccomplex_dotprod = ccomplex_dotprod_sse;
+}
+
+gr_fir_ccc_sse::gr_fir_ccc_sse (const std::vector<gr_complex> &new_taps)
+  : gr_fir_ccc_simd (new_taps)
+{
+  d_ccomplex_dotprod = ccomplex_dotprod_sse;
+}
diff --git a/gnuradio-core/src/lib/filter/gr_fir_ccc_x86.h b/gnuradio-core/src/lib/filter/gr_fir_ccc_x86.h
new file mode 100644 (file)
index 0000000..ee2fe9b
--- /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 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.
+ */
+
+#ifndef INCLUDED_GR_FIR_CCC_X86_H
+#define INCLUDED_GR_FIR_CCC_X86_H
+
+#include <gr_fir_ccc_simd.h>
+
+/*!
+ * \brief 3DNow! version of gr_fir_ccc
+ */
+class gr_fir_ccc_3dnow : public gr_fir_ccc_simd
+{
+public:
+  gr_fir_ccc_3dnow ();
+  gr_fir_ccc_3dnow (const std::vector<gr_complex> &taps);
+};
+
+class gr_fir_ccc_3dnowext : public gr_fir_ccc_simd
+{
+public:
+  gr_fir_ccc_3dnowext ();
+  gr_fir_ccc_3dnowext (const std::vector<gr_complex> &taps);
+};
+
+/*!
+ * \brief SSE version of gr_fir_ccc
+ */
+class gr_fir_ccc_sse : public gr_fir_ccc_simd
+{
+public:
+  gr_fir_ccc_sse ();
+  gr_fir_ccc_sse (const std::vector<gr_complex> &taps);
+};
+
+#endif
diff --git a/gnuradio-core/src/lib/filter/gr_fir_ccf_simd.cc b/gnuradio-core/src/lib/filter/gr_fir_ccf_simd.cc
new file mode 100644 (file)
index 0000000..d1992d7
--- /dev/null
@@ -0,0 +1,138 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <gr_fir_ccf_simd.h>
+
+#include <assert.h>
+#include <malloc16.h>
+#include <iostream>
+
+using std::cerr;
+using std::endl;
+
+gr_fir_ccf_simd::gr_fir_ccf_simd ()
+  : gr_fir_ccf_generic ()
+{
+  // cerr << "@@@ gr_fir_ccf_simd\n";
+
+  d_fcomplex_dotprod = 0;
+  
+  d_aligned_taps[0] = 0;
+  d_aligned_taps[1] = 0;
+  d_aligned_taps[2] = 0;
+  d_aligned_taps[3] = 0;
+}
+
+gr_fir_ccf_simd::gr_fir_ccf_simd (const std::vector<float> &new_taps)
+  : gr_fir_ccf_generic (new_taps)
+{
+  // cerr << "@@@ gr_fir_ccf_simd\n";
+
+  d_fcomplex_dotprod = 0;
+  
+  d_aligned_taps[0] = 0;
+  d_aligned_taps[1] = 0;
+  d_aligned_taps[2] = 0;
+  d_aligned_taps[3] = 0;
+  set_taps (new_taps);
+}
+
+gr_fir_ccf_simd::~gr_fir_ccf_simd ()
+{
+  free16Align (d_aligned_taps[0]);
+  free16Align (d_aligned_taps[1]);
+  free16Align (d_aligned_taps[2]);
+  free16Align (d_aligned_taps[3]);
+}
+
+void
+gr_fir_ccf_simd::set_taps (const std::vector<float> &inew_taps)
+{
+  gr_fir_ccf::set_taps (inew_taps);    // call superclass
+  const std::vector<float> new_taps = gr_reverse(inew_taps);
+
+  unsigned len = new_taps.size ();
+
+  // Make 4 copies of the coefficients, one for each data alignment
+  // Note use of special 16-byte-aligned version of calloc()
+  
+  for (unsigned i = 0; i < 4; i++){
+    free16Align (d_aligned_taps[i]);   // free old value
+
+    // this works because the bit representation of a IEEE floating point
+    // +zero is all zeros.  If you're using a different representation,
+    // you'll need to explictly set the result to the appropriate 0.0 value.
+    
+    d_aligned_taps[i] = (float *) calloc16Align (1 + (len + i - 1) / 4,
+                                              4 * sizeof (float));
+    if (d_aligned_taps[i] == 0){
+      // throw something...
+      cerr << "@@@ gr_fir_ccf_simd d_aligned_taps[" << i << "] == 0\n";
+    }
+
+    for (unsigned j = 0; j < len; j++)
+      d_aligned_taps[i][j+i] = new_taps[j];
+  }
+}
+gr_complex 
+gr_fir_ccf_simd::filter (const gr_complex input[])
+{
+  if (ntaps () == 0)
+    return 0.0;
+
+
+  // Round input data address down to 16 byte boundary
+  // NB: depending on the alignment of input[], memory
+  // before input[] will be accessed. The contents don't matter since 
+  // they'll be multiplied by zero coefficients. I can't conceive of any
+  // situation where this could cause a segfault since memory protection
+  // in the x86 machines is done on much larger boundaries.
+  
+  const gr_complex *ar = (gr_complex *)((unsigned long) input & ~15);
+
+  // Choose one of 4 sets of pre-shifted coefficients. al is both the
+  // index into d_aligned_taps[] and the number of 0 words padded onto
+  // that coefficients array for alignment purposes.
+
+  unsigned al = input - ar;
+
+  // call assembler routine to do the work, passing number of 2x4-float blocks.
+
+  // assert (((unsigned long) ar & 15) == 0);
+  // assert (((unsigned long) d_aligned_taps[al] & 15) == 0);
+
+  // cerr << "ar: " << ar << " d_aligned_taps[ar]: " << d_aligned_taps[al]
+  //  << " (ntaps() + al - 1)/2 + 1: " << (ntaps() + al -1) / 2 + 1 << endl;
+
+  float result[2];
+
+  // the trick here is to invert input and taps, and reuse FCC speedup
+  d_fcomplex_dotprod (d_aligned_taps[al], (float*)ar, (ntaps() + al - 1) / 2 + 1, result);
+
+  // cerr << "result = " << result[0] << " " << result[1] << endl;
+
+  return gr_complex(result[0], result[1]);
+}
diff --git a/gnuradio-core/src/lib/filter/gr_fir_ccf_simd.h b/gnuradio-core/src/lib/filter/gr_fir_ccf_simd.h
new file mode 100644 (file)
index 0000000..60898b4
--- /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 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.
+ */
+#ifndef INCLUDED_GR_FIR_CCF_SIMD_H
+#define INCLUDED_GR_FIR_CCF_SIMD_H
+
+#include <gr_fir_ccf_generic.h>
+
+
+/*!
+ * \brief common base class for SIMD versions of gr_fir_ccf
+ *
+ * This base class handles alignment issues common to SSE and 3DNOW
+ * subclasses.
+ */
+
+class gr_fir_ccf_simd : public gr_fir_ccf_generic
+{
+protected:
+  typedef void (*fcomplex_dotprod_t)(const float *taps,
+                                    const float *input,
+                                    unsigned n_2_complex_blocks,
+                                    float *result);
+
+  /*!
+   * \p aligned_taps holds 4 copies of the coefficients preshifted
+   * by 0, 1, 2, or 3 float pairs to meet all possible input data alignments.
+   * This allows us to always fetch data and taps that are 128-bit aligned.
+   */
+  float                *d_aligned_taps[4];
+
+  fcomplex_dotprod_t   d_fcomplex_dotprod;     // fast dot product primitive
+
+public:
+
+  // CREATORS
+  gr_fir_ccf_simd ();
+  gr_fir_ccf_simd (const std::vector<float> &taps);
+  ~gr_fir_ccf_simd ();
+
+  // MANIPULATORS
+  virtual void set_taps (const std::vector<float> &taps);
+  virtual gr_complex filter (const gr_complex input[]);
+};
+
+#endif
diff --git a/gnuradio-core/src/lib/filter/gr_fir_ccf_x86.cc b/gnuradio-core/src/lib/filter/gr_fir_ccf_x86.cc
new file mode 100644 (file)
index 0000000..9f288fc
--- /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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <gr_fir_ccf_x86.h>
+#include <fcomplex_dotprod_x86.h>
+
+/*
+ *     --- 3DNow! version ---
+ */
+gr_fir_ccf_3dnow::gr_fir_ccf_3dnow ()
+  : gr_fir_ccf_simd () 
+{
+  d_fcomplex_dotprod = fcomplex_dotprod_3dnow;
+}
+
+gr_fir_ccf_3dnow::gr_fir_ccf_3dnow (const std::vector<float> &new_taps)
+  : gr_fir_ccf_simd (new_taps)
+{
+  d_fcomplex_dotprod = fcomplex_dotprod_3dnow;
+}
+
+
+/*
+ *     --- SSE version ---
+ */
+gr_fir_ccf_sse::gr_fir_ccf_sse ()
+  : gr_fir_ccf_simd ()
+{
+  d_fcomplex_dotprod = fcomplex_dotprod_sse;
+}
+
+gr_fir_ccf_sse::gr_fir_ccf_sse (const std::vector<float> &new_taps)
+  : gr_fir_ccf_simd (new_taps)
+{
+  d_fcomplex_dotprod = fcomplex_dotprod_sse;
+}
diff --git a/gnuradio-core/src/lib/filter/gr_fir_ccf_x86.h b/gnuradio-core/src/lib/filter/gr_fir_ccf_x86.h
new file mode 100644 (file)
index 0000000..5c51a5f
--- /dev/null
@@ -0,0 +1,48 @@
+/* -*- 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 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.
+ */
+
+#ifndef INCLUDED_GR_FIR_CCF_X86_H
+#define INCLUDED_GR_FIR_CCF_X86_H
+
+#include <gr_fir_ccf_simd.h>
+
+/*!
+ * \brief 3DNow! version of gr_fir_ccf
+ */
+class gr_fir_ccf_3dnow : public gr_fir_ccf_simd
+{
+public:
+  gr_fir_ccf_3dnow ();
+  gr_fir_ccf_3dnow (const std::vector<float> &taps);
+};
+
+/*!
+ * \brief SSE version of gr_fir_ccf
+ */
+class gr_fir_ccf_sse : public gr_fir_ccf_simd
+{
+public:
+  gr_fir_ccf_sse ();
+  gr_fir_ccf_sse (const std::vector<float> &taps);
+};
+
+#endif
diff --git a/gnuradio-core/src/lib/filter/gr_fir_fcc_simd.cc b/gnuradio-core/src/lib/filter/gr_fir_fcc_simd.cc
new file mode 100644 (file)
index 0000000..c17d29f
--- /dev/null
@@ -0,0 +1,139 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <gr_fir_fcc_simd.h>
+
+#include <assert.h>
+#include <malloc16.h>
+#include <iostream>
+
+using std::cerr;
+using std::endl;
+
+gr_fir_fcc_simd::gr_fir_fcc_simd ()
+  : gr_fir_fcc_generic ()
+{
+  // cerr << "@@@ gr_fir_fcc_simd\n";
+
+  d_fcomplex_dotprod = 0;
+  
+  d_aligned_taps[0] = 0;
+  d_aligned_taps[1] = 0;
+  d_aligned_taps[2] = 0;
+  d_aligned_taps[3] = 0;
+}
+
+gr_fir_fcc_simd::gr_fir_fcc_simd (const std::vector<gr_complex> &new_taps)
+  : gr_fir_fcc_generic (new_taps)
+{
+  // cerr << "@@@ gr_fir_fcc_simd\n";
+
+  d_fcomplex_dotprod = 0;
+  
+  d_aligned_taps[0] = 0;
+  d_aligned_taps[1] = 0;
+  d_aligned_taps[2] = 0;
+  d_aligned_taps[3] = 0;
+  set_taps (new_taps);
+}
+
+gr_fir_fcc_simd::~gr_fir_fcc_simd ()
+{
+  free16Align (d_aligned_taps[0]);
+  free16Align (d_aligned_taps[1]);
+  free16Align (d_aligned_taps[2]);
+  free16Align (d_aligned_taps[3]);
+}
+
+void
+gr_fir_fcc_simd::set_taps (const std::vector<gr_complex> &inew_taps)
+{
+  gr_fir_fcc::set_taps (inew_taps);    // call superclass
+  const std::vector<gr_complex> new_taps = gr_reverse(inew_taps);
+
+  unsigned len = new_taps.size ();
+
+  // Make 4 copies of the coefficients, one for each data alignment
+  // Note use of special 16-byte-aligned version of calloc()
+  
+  for (unsigned i = 0; i < 4; i++){
+    free16Align (d_aligned_taps[i]);   // free old value
+
+    // this works because the bit representation of a IEEE floating point
+    // +zero is all zeros.  If you're using a different representation,
+    // you'll need to explictly set the result to the appropriate 0.0 value.
+    
+    d_aligned_taps[i] = (float *) calloc16Align (1 + (len + i - 1) / 2,
+                                              2 * 4 * sizeof (float));
+    if (d_aligned_taps[i] == 0){
+      // throw something...
+      cerr << "@@@ gr_fir_fcc_simd d_aligned_taps[" << i << "] == 0\n";
+    }
+
+    for (unsigned j = 0; j < len; j++) {
+      d_aligned_taps[i][2*(j+i)] = new_taps[j].real();
+      d_aligned_taps[i][2*(j+i)+1] = new_taps[j].imag();
+    }
+  }
+}
+
+gr_complex 
+gr_fir_fcc_simd::filter (const float input[])
+{
+  if (ntaps () == 0)
+    return 0.0;
+
+
+  // Round input data address down to 16 byte boundary
+  // NB: depending on the alignment of input[], memory
+  // before input[] will be accessed. The contents don't matter since 
+  // they'll be multiplied by zero coefficients. I can't conceive of any
+  // situation where this could cause a segfault since memory protection
+  // in the x86 machines is done on much larger boundaries.
+  
+  const float *ar = (float *)((unsigned long) input & ~15);
+
+  // Choose one of 4 sets of pre-shifted coefficients. al is both the
+  // index into d_aligned_taps[] and the number of 0 words padded onto
+  // that coefficients array for alignment purposes.
+
+  unsigned al = input - ar;
+
+  // call assembler routine to do the work, passing number of 2x4-float blocks.
+
+  // assert (((unsigned long) ar & 15) == 0);
+  // assert (((unsigned long) d_aligned_taps[al] & 15) == 0);
+
+  // cerr << "ar: " << ar << " d_aligned_taps[ar]: " << d_aligned_taps[al]
+  //  << " (ntaps() + al - 1)/2 + 1: " << (ntaps() + al -1) / 2 + 1 << endl;
+
+  float result[2];
+
+  d_fcomplex_dotprod (ar, d_aligned_taps[al], (ntaps() + al - 1) / 2 + 1, result);
+
+  // cerr << "result = " << result[0] << " " << result[1] << endl;
+
+  return gr_complex(result[0], result[1]);
+}
diff --git a/gnuradio-core/src/lib/filter/gr_fir_fcc_simd.h b/gnuradio-core/src/lib/filter/gr_fir_fcc_simd.h
new file mode 100644 (file)
index 0000000..5624820
--- /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 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.
+ */
+#ifndef INCLUDED_GR_FIR_FCC_SIMD_H
+#define INCLUDED_GR_FIR_FCC_SIMD_H
+
+#include <gr_fir_fcc_generic.h>
+
+
+/*!
+ * \brief common base class for SIMD versions of gr_fir_fcc
+ *
+ * This base class handles alignment issues common to SSE and 3DNOW
+ * subclasses.
+ */
+
+class gr_fir_fcc_simd : public gr_fir_fcc_generic
+{
+protected:
+  typedef void (*fcomplex_dotprod_t)(const float *input,
+                                    const float *taps,
+                                    unsigned n_2_complex_blocks,
+                                    float *result);
+
+  /*!
+   * \p aligned_taps holds 4 copies of the coefficients preshifted
+   * by 0, 1, 2, or 3 float pairs to meet all possible input data alignments.
+   * This allows us to always fetch data and taps that are 128-bit aligned.
+   */
+  float                *d_aligned_taps[4];
+
+  fcomplex_dotprod_t   d_fcomplex_dotprod;     // fast dot product primitive
+
+public:
+
+  // CREATORS
+  gr_fir_fcc_simd ();
+  gr_fir_fcc_simd (const std::vector<gr_complex> &taps);
+  ~gr_fir_fcc_simd ();
+
+  // MANIPULATORS
+  virtual void set_taps (const std::vector<gr_complex> &taps);
+  virtual gr_complex filter (const float input[]);
+};
+
+#endif
diff --git a/gnuradio-core/src/lib/filter/gr_fir_fcc_x86.cc b/gnuradio-core/src/lib/filter/gr_fir_fcc_x86.cc
new file mode 100644 (file)
index 0000000..e80dfe1
--- /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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <gr_fir_fcc_x86.h>
+#include <fcomplex_dotprod_x86.h>
+
+/*
+ *     --- 3DNow! version ---
+ */
+gr_fir_fcc_3dnow::gr_fir_fcc_3dnow ()
+  : gr_fir_fcc_simd () 
+{
+  d_fcomplex_dotprod = fcomplex_dotprod_3dnow;
+}
+
+gr_fir_fcc_3dnow::gr_fir_fcc_3dnow (const std::vector<gr_complex> &new_taps)
+  : gr_fir_fcc_simd (new_taps)
+{
+  d_fcomplex_dotprod = fcomplex_dotprod_3dnow;
+}
+
+
+/*
+ *     --- SSE version ---
+ */
+gr_fir_fcc_sse::gr_fir_fcc_sse ()
+  : gr_fir_fcc_simd ()
+{
+  d_fcomplex_dotprod = fcomplex_dotprod_sse;
+}
+
+gr_fir_fcc_sse::gr_fir_fcc_sse (const std::vector<gr_complex> &new_taps)
+  : gr_fir_fcc_simd (new_taps)
+{
+  d_fcomplex_dotprod = fcomplex_dotprod_sse;
+}
diff --git a/gnuradio-core/src/lib/filter/gr_fir_fcc_x86.h b/gnuradio-core/src/lib/filter/gr_fir_fcc_x86.h
new file mode 100644 (file)
index 0000000..500f4fb
--- /dev/null
@@ -0,0 +1,48 @@
+/* -*- 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 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.
+ */
+
+#ifndef INCLUDED_GR_FIR_FCC_X86_H
+#define INCLUDED_GR_FIR_FCC_X86_H
+
+#include <gr_fir_fcc_simd.h>
+
+/*!
+ * \brief 3DNow! version of gr_fir_fcc
+ */
+class gr_fir_fcc_3dnow : public gr_fir_fcc_simd
+{
+public:
+  gr_fir_fcc_3dnow ();
+  gr_fir_fcc_3dnow (const std::vector<gr_complex> &taps);
+};
+
+/*!
+ * \brief SSE version of gr_fir_fcc
+ */
+class gr_fir_fcc_sse : public gr_fir_fcc_simd
+{
+public:
+  gr_fir_fcc_sse ();
+  gr_fir_fcc_sse (const std::vector<gr_complex> &taps);
+};
+
+#endif
diff --git a/gnuradio-core/src/lib/filter/gr_fir_fff_simd.cc b/gnuradio-core/src/lib/filter/gr_fir_fff_simd.cc
new file mode 100644 (file)
index 0000000..92c4256
--- /dev/null
@@ -0,0 +1,134 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <gr_fir_fff_simd.h>
+
+#include <assert.h>
+#include <malloc16.h>
+#include <iostream>
+
+using std::cerr;
+
+gr_fir_fff_simd::gr_fir_fff_simd ()
+  : gr_fir_fff_generic ()
+{
+  // cerr << "@@@ gr_fir_fff_simd\n";
+
+  d_float_dotprod = 0;
+  
+  d_aligned_taps[0] = 0;
+  d_aligned_taps[1] = 0;
+  d_aligned_taps[2] = 0;
+  d_aligned_taps[3] = 0;
+}
+
+gr_fir_fff_simd::gr_fir_fff_simd (const std::vector<float> &new_taps)
+  : gr_fir_fff_generic (new_taps)
+{
+  // cerr << "@@@ gr_fir_fff_simd\n";
+
+  d_float_dotprod = 0;
+  
+  d_aligned_taps[0] = 0;
+  d_aligned_taps[1] = 0;
+  d_aligned_taps[2] = 0;
+  d_aligned_taps[3] = 0;
+  set_taps (new_taps);
+}
+
+gr_fir_fff_simd::~gr_fir_fff_simd ()
+{
+  free16Align (d_aligned_taps[0]);
+  free16Align (d_aligned_taps[1]);
+  free16Align (d_aligned_taps[2]);
+  free16Align (d_aligned_taps[3]);
+}
+
+void
+gr_fir_fff_simd::set_taps (const std::vector<float> &inew_taps)
+{
+  gr_fir_fff::set_taps (inew_taps);    // call superclass
+  const std::vector<float> new_taps = gr_reverse(inew_taps);
+
+  unsigned len = new_taps.size ();
+
+  // Make 4 copies of the coefficients, one for each data alignment
+  // Note use of special 16-byte-aligned version of calloc()
+  
+  for (unsigned i = 0; i < 4; i++){
+    free16Align (d_aligned_taps[i]);   // free old value
+
+    // this works because the bit representation of a IEEE floating point
+    // +zero is all zeros.  If you're using a different representation,
+    // you'll need to explictly set the result to the appropriate 0.0 value.
+    
+    d_aligned_taps[i] = (float *) calloc16Align (1 + (len + i - 1) / 4,
+                                              4 * sizeof (float));
+    if (d_aligned_taps[i] == 0){
+      // throw something...
+      cerr << "@@@ gr_fir_fff_simd d_aligned_taps[" << i << "] == 0\n";
+    }
+
+    for (unsigned j = 0; j < len; j++)
+      d_aligned_taps[i][j+i] = new_taps[j];
+  }
+}
+
+float 
+gr_fir_fff_simd::filter (const float input[])
+{
+  if (ntaps () == 0)
+    return 0.0;
+
+
+  // Round input data address down to 16 byte boundary
+  // NB: depending on the alignment of input[], memory
+  // before input[] will be accessed. The contents don't matter since 
+  // they'll be multiplied by zero coefficients. I can't conceive of any
+  // situation where this could cause a segfault since memory protection
+  // in the x86 machines is done on much larger boundaries.
+  
+  const float *ar = (float *)((unsigned long) input & ~15);
+
+  // Choose one of 4 sets of pre-shifted coefficients. al is both the
+  // index into d_aligned_taps[] and the number of 0 words padded onto
+  // that coefficients array for alignment purposes.
+
+  unsigned al = input - ar;
+
+  // call assembler routine to do the work, passing number of 4-float blocks.
+
+  // assert (((unsigned long) ar & 15) == 0);
+  // assert (((unsigned long) d_aligned_taps[al] & 15) == 0);
+
+  // cerr << "ar: " << ar << " d_aligned_taps[ar]: " << d_aligned_taps[al]
+  // << " (ntaps() + al - 1)/4 + 1: " << (ntaps() + al -1) / 4 + 1 << endl;
+  
+  float r = d_float_dotprod (ar, d_aligned_taps[al], (ntaps() + al - 1) / 4 + 1);
+
+  // cerr << "result = " << r << endl;
+
+  return r;
+}
diff --git a/gnuradio-core/src/lib/filter/gr_fir_fff_simd.h b/gnuradio-core/src/lib/filter/gr_fir_fff_simd.h
new file mode 100644 (file)
index 0000000..375b119
--- /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 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.
+ */
+#ifndef INCLUDED_GR_FIR_FFF_SIMD_H
+#define INCLUDED_GR_FIR_FFF_SIMD_H
+
+#include <gr_fir_fff_generic.h>
+
+/*!
+ * \brief common base class for SIMD versions of gr_fir_fff
+ *
+ * This base class handles alignment issues common to SSE and 3DNOW
+ * subclasses.
+ */
+
+class gr_fir_fff_simd : public gr_fir_fff_generic
+{
+protected:
+  typedef float (*float_dotprod_t)(const float *input,
+                                  const float *taps,
+                                  unsigned n_4_float_blocks);
+
+  /*!
+   * \p aligned_taps holds 4 copies of the coefficients preshifted
+   * by 0, 1, 2, or 3 floats to meet all possible input data alignments.
+   * This allows us to always fetch data and taps that are 128-bit aligned.
+   */
+  float                *d_aligned_taps[4];
+
+  float_dotprod_t      d_float_dotprod;        // fast dot product primitive
+
+public:
+
+  // CREATORS
+  gr_fir_fff_simd ();
+  gr_fir_fff_simd (const std::vector<float> &taps);
+  ~gr_fir_fff_simd ();
+
+  // MANIPULATORS
+  virtual void set_taps (const std::vector<float> &taps);
+  virtual float filter (const float input[]);
+};
+
+#endif
diff --git a/gnuradio-core/src/lib/filter/gr_fir_fff_x86.cc b/gnuradio-core/src/lib/filter/gr_fir_fff_x86.cc
new file mode 100644 (file)
index 0000000..494a0f7
--- /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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <gr_fir_fff_x86.h>
+#include <float_dotprod_x86.h>
+
+/*
+ *     --- 3DNow! version ---
+ */
+gr_fir_fff_3dnow::gr_fir_fff_3dnow ()
+  : gr_fir_fff_simd () 
+{
+  d_float_dotprod = float_dotprod_3dnow;
+}
+
+gr_fir_fff_3dnow::gr_fir_fff_3dnow (const std::vector<float> &new_taps)
+  : gr_fir_fff_simd (new_taps)
+{
+  d_float_dotprod = float_dotprod_3dnow;
+}
+
+
+/*
+ *     --- SSE version ---
+ */
+gr_fir_fff_sse::gr_fir_fff_sse ()
+  : gr_fir_fff_simd ()
+{
+  d_float_dotprod = float_dotprod_sse;
+}
+
+gr_fir_fff_sse::gr_fir_fff_sse (const std::vector<float> &new_taps)
+  : gr_fir_fff_simd (new_taps)
+{
+  d_float_dotprod = float_dotprod_sse;
+}
diff --git a/gnuradio-core/src/lib/filter/gr_fir_fff_x86.h b/gnuradio-core/src/lib/filter/gr_fir_fff_x86.h
new file mode 100644 (file)
index 0000000..407ae3f
--- /dev/null
@@ -0,0 +1,48 @@
+/* -*- 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 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.
+ */
+
+#ifndef INCLUDED_GR_FIR_FFF_X86_H
+#define INCLUDED_GR_FIR_FFF_X86_H
+
+#include <gr_fir_fff_simd.h>
+
+/*!
+ * \brief 3DNow! version of gr_fir_fff
+ */
+class gr_fir_fff_3dnow : public gr_fir_fff_simd
+{
+public:
+  gr_fir_fff_3dnow ();
+  gr_fir_fff_3dnow (const std::vector<float> &taps);
+};
+
+/*!
+ * \brief SSE version of gr_fir_fff
+ */
+class gr_fir_fff_sse : public gr_fir_fff_simd
+{
+public:
+  gr_fir_fff_sse ();
+  gr_fir_fff_sse (const std::vector<float> &taps);
+};
+
+#endif
diff --git a/gnuradio-core/src/lib/filter/gr_fir_filter_XXX.cc.t b/gnuradio-core/src/lib/filter/gr_fir_filter_XXX.cc.t
new file mode 100644 (file)
index 0000000..91b3111
--- /dev/null
@@ -0,0 +1,88 @@
+/* -*- 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 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.
+ */
+
+/*
+ * WARNING: This file is automatically generated by generate_gr_fir_filter_XXX.py
+ * Any changes made to this file will be overwritten.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <@NAME@.h>
+#include <@FIR_TYPE@.h>
+#include <gr_fir_util.h>
+#include <gr_io_signature.h>
+
+@SPTR_NAME@ gr_make_@BASE_NAME@ (int decimation, const std::vector<@TAP_TYPE@> &taps)
+{
+  return @SPTR_NAME@ (new @NAME@ (decimation, taps));
+}
+
+
+@NAME@::@NAME@ (int decimation, const std::vector<@TAP_TYPE@> &taps)
+  : gr_sync_decimator ("@BASE_NAME@",
+                      gr_make_io_signature (1, 1, sizeof (@I_TYPE@)),
+                      gr_make_io_signature (1, 1, sizeof (@O_TYPE@)),
+                      decimation),
+    d_updated (false)
+{
+  d_fir = gr_fir_util::create_@FIR_TYPE@ (taps);
+  set_history (d_fir->ntaps ());
+}
+
+@NAME@::~@NAME@ ()
+{
+  delete d_fir;
+}
+
+void
+@NAME@::set_taps (const std::vector<@TAP_TYPE@> &taps)
+{
+  d_new_taps = taps;
+  d_updated = true;
+}
+
+int
+@NAME@::work (int noutput_items,
+                  gr_vector_const_void_star &input_items,
+                  gr_vector_void_star &output_items)
+{
+  @I_TYPE@ *in = (@I_TYPE@ *) input_items[0];
+  @O_TYPE@ *out = (@O_TYPE@ *) output_items[0];
+
+  if (d_updated) {
+    d_fir->set_taps (d_new_taps);
+    set_history (d_fir->ntaps ());
+    d_updated = false;
+    return 0;               // history requirements may have changed.
+  }
+
+  if (decimation() == 1)
+    d_fir->filterN (out, in, noutput_items);
+
+  else
+    d_fir->filterNdec (out, in, noutput_items, decimation());
+
+  return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/filter/gr_fir_filter_XXX.h.t b/gnuradio-core/src/lib/filter/gr_fir_filter_XXX.h.t
new file mode 100644 (file)
index 0000000..b6e5d1a
--- /dev/null
@@ -0,0 +1,67 @@
+/* -*- 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 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.
+ */
+
+/*
+ * WARNING: This file is automatically generated by generate_gr_fir_filter_XXX.py
+ * Any changes made to this file will be overwritten.
+ */
+
+#ifndef @GUARD_NAME@
+#define        @GUARD_NAME@
+
+#include <gr_sync_decimator.h>
+
+class @NAME@;
+typedef boost::shared_ptr<@NAME@> @SPTR_NAME@;
+@SPTR_NAME@ gr_make_@BASE_NAME@ (int decimation, const std::vector<@TAP_TYPE@> &taps);
+
+class @FIR_TYPE@;
+
+/*!
+ * \brief FIR filter with @I_TYPE@ input, @O_TYPE@ output and @TAP_TYPE@ taps
+ * \ingroup filter
+ */
+class @NAME@ : public gr_sync_decimator
+{
+ private:
+  friend @SPTR_NAME@ gr_make_@BASE_NAME@ (int decimation, const std::vector<@TAP_TYPE@> &taps);
+
+  @FIR_TYPE@           *d_fir;
+  std::vector<@TAP_TYPE@>      d_new_taps;
+  bool                 d_updated;
+
+  /*!
+   * Construct a FIR filter with the given taps
+   */
+  @NAME@ (int decimation, const std::vector<@TAP_TYPE@> &taps);
+
+ public:
+  ~@NAME@ ();
+
+  void set_taps (const std::vector<@TAP_TYPE@> &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_fir_filter_XXX.i.t b/gnuradio-core/src/lib/filter/gr_fir_filter_XXX.i.t
new file mode 100644 (file)
index 0000000..13c919d
--- /dev/null
@@ -0,0 +1,41 @@
+/* -*- 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 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.
+ */
+
+/*
+ * WARNING: This file is automatically generated by generate_GrFIRfilterXXX.py
+ * Any changes made to this file will be overwritten.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,@BASE_NAME@)
+
+@SPTR_NAME@ gr_make_@BASE_NAME@ (int decimation, const std::vector<@TAP_TYPE@> &taps);
+
+class @NAME@ : public gr_sync_decimator
+{
+ private:
+  @NAME@ (int decimation, const std::vector<@TAP_TYPE@> &taps);
+
+ public:
+  ~@NAME@ ();
+
+  void set_taps (const std::vector<@TAP_TYPE@> &taps);
+};
diff --git a/gnuradio-core/src/lib/filter/gr_fir_fsf_simd.cc b/gnuradio-core/src/lib/filter/gr_fir_fsf_simd.cc
new file mode 100644 (file)
index 0000000..00b4e60
--- /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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <gr_fir_fsf_simd.h>
+
+#include <assert.h>
+#include <malloc16.h>
+#include <iostream>
+
+using std::cerr;
+
+gr_fir_fsf_simd::gr_fir_fsf_simd ()
+  : gr_fir_fsf_generic ()
+{
+  // cerr << "@@@ gr_fir_fsf_simd\n";
+
+  d_float_dotprod = 0;
+  
+  d_aligned_taps[0] = 0;
+  d_aligned_taps[1] = 0;
+  d_aligned_taps[2] = 0;
+  d_aligned_taps[3] = 0;
+}
+
+gr_fir_fsf_simd::gr_fir_fsf_simd (const std::vector<float> &new_taps)
+  : gr_fir_fsf_generic (new_taps)
+{
+  // cerr << "@@@ gr_fir_fsf_simd\n";
+
+  d_float_dotprod = 0;
+  
+  d_aligned_taps[0] = 0;
+  d_aligned_taps[1] = 0;
+  d_aligned_taps[2] = 0;
+  d_aligned_taps[3] = 0;
+  set_taps (new_taps);
+}
+
+gr_fir_fsf_simd::~gr_fir_fsf_simd ()
+{
+  free16Align (d_aligned_taps[0]);
+  free16Align (d_aligned_taps[1]);
+  free16Align (d_aligned_taps[2]);
+  free16Align (d_aligned_taps[3]);
+}
+
+void
+gr_fir_fsf_simd::set_taps (const std::vector<float> &inew_taps)
+{
+  gr_fir_fsf::set_taps (inew_taps);    // call superclass
+  const std::vector<float> new_taps = gr_reverse(inew_taps);
+  unsigned len = new_taps.size ();
+
+  // Make 4 copies of the coefficients, one for each data alignment
+  // Note use of special 16-byte-aligned version of calloc()
+  
+  for (unsigned i = 0; i < 4; i++){
+    free16Align (d_aligned_taps[i]);   // free old value
+
+    // this works because the bit representation of a IEEE floating point
+    // +zero is all zeros.  If you're using a different representation,
+    // you'll need to explictly set the result to the appropriate 0.0 value.
+    
+    d_aligned_taps[i] = (float *) calloc16Align (1 + (len + i - 1) / 4,
+                                              4 * sizeof (float));
+    if (d_aligned_taps[i] == 0){
+      // throw something...
+      cerr << "@@@ gr_fir_fsf_simd d_aligned_taps[" << i << "] == 0\n";
+    }
+
+    for (unsigned j = 0; j < len; j++)
+      d_aligned_taps[i][j+i] = new_taps[j];
+  }
+}
+
+short 
+gr_fir_fsf_simd::filter (const float input[])
+{
+  if (ntaps () == 0)
+    return 0;
+
+
+  // Round input data address down to 16 byte boundary
+  // NB: depending on the alignment of input[], memory
+  // before input[] will be accessed. The contents don't matter since 
+  // they'll be multiplied by zero coefficients. I can't conceive of any
+  // situation where this could cause a segfault since memory protection
+  // in the x86 machines is done on much larger boundaries.
+  
+  const float *ar = (float *)((unsigned long) input & ~15);
+
+  // Choose one of 4 sets of pre-shifted coefficients. al is both the
+  // index into d_aligned_taps[] and the number of 0 words padded onto
+  // that coefficients array for alignment purposes.
+
+  unsigned al = input - ar;
+
+  // call assembler routine to do the work, passing number of 4-float blocks.
+
+  // assert (((unsigned long) ar & 15) == 0);
+  // assert (((unsigned long) d_aligned_taps[al] & 15) == 0);
+
+  // cerr << "ar: " << ar << " d_aligned_taps[ar]: " << d_aligned_taps[al]
+  // << " (ntaps() + al - 1)/4 + 1: " << (ntaps() + al -1) / 4 + 1 << endl;
+  
+  float r = d_float_dotprod (ar, d_aligned_taps[al], (ntaps() + al - 1) / 4 + 1);
+
+  // cerr << "result = " << r << endl;
+
+  return (short) r;    // FIXME? may want to saturate here
+}
diff --git a/gnuradio-core/src/lib/filter/gr_fir_fsf_simd.h b/gnuradio-core/src/lib/filter/gr_fir_fsf_simd.h
new file mode 100644 (file)
index 0000000..77e093c
--- /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 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.
+ */
+#ifndef _GR_FIR_FSF_SIMD_H_
+#define _GR_FIR_FSF_SIMD_H_
+
+#include <gr_fir_fsf_generic.h>
+
+/*!
+ * \brief common base class for SIMD versions of gr_fir_fsf
+ *
+ * This base class handles alignment issues common to SSE and 3DNOW
+ * subclasses.
+ */
+
+class gr_fir_fsf_simd : public gr_fir_fsf_generic
+{
+protected:
+  typedef float (*float_dotprod_t)(const float *input,
+                                  const float *taps,
+                                  unsigned n_4_float_blocks);
+
+  /*!
+   * \p aligned_taps holds 4 copies of the coefficients preshifted
+   * by 0, 1, 2, or 3 floats to meet all possible input data alignments.
+   * This allows us to always fetch data and taps that are 128-bit aligned.
+   */
+  float                *d_aligned_taps[4];
+
+  float_dotprod_t      d_float_dotprod;        // fast dot product primitive
+
+public:
+
+  // CREATORS
+  gr_fir_fsf_simd ();
+  gr_fir_fsf_simd (const std::vector<float> &taps);
+  ~gr_fir_fsf_simd ();
+
+  // MANIPULATORS
+  virtual void set_taps (const std::vector<float> &taps);
+  virtual short filter (const float input[]);
+};
+
+#endif
diff --git a/gnuradio-core/src/lib/filter/gr_fir_fsf_x86.cc b/gnuradio-core/src/lib/filter/gr_fir_fsf_x86.cc
new file mode 100644 (file)
index 0000000..c407789
--- /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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <gr_fir_fsf_x86.h>
+#include <float_dotprod_x86.h>
+
+/*
+ *     --- 3DNow! version ---
+ */
+gr_fir_fsf_3dnow::gr_fir_fsf_3dnow ()
+  : gr_fir_fsf_simd () 
+{
+  d_float_dotprod = float_dotprod_3dnow;
+}
+
+gr_fir_fsf_3dnow::gr_fir_fsf_3dnow (const std::vector<float> &new_taps)
+  : gr_fir_fsf_simd (new_taps)
+{
+  d_float_dotprod = float_dotprod_3dnow;
+}
+
+
+/*
+ *     --- SSE version ---
+ */
+gr_fir_fsf_sse::gr_fir_fsf_sse ()
+  : gr_fir_fsf_simd ()
+{
+  d_float_dotprod = float_dotprod_sse;
+}
+
+gr_fir_fsf_sse::gr_fir_fsf_sse (const std::vector<float> &new_taps)
+  : gr_fir_fsf_simd (new_taps)
+{
+  d_float_dotprod = float_dotprod_sse;
+}
diff --git a/gnuradio-core/src/lib/filter/gr_fir_fsf_x86.h b/gnuradio-core/src/lib/filter/gr_fir_fsf_x86.h
new file mode 100644 (file)
index 0000000..e8ae763
--- /dev/null
@@ -0,0 +1,48 @@
+/* -*- 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 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.
+ */
+
+#ifndef INCLUDED_GR_FIR_FSF_X86_H
+#define INCLUDED_GR_FIR_FSF_X86_H
+
+#include <gr_fir_fsf_simd.h>
+
+/*!
+ * \brief 3DNow! version of gr_fir_fsf
+ */
+class gr_fir_fsf_3dnow : public gr_fir_fsf_simd
+{
+public:
+  gr_fir_fsf_3dnow ();
+  gr_fir_fsf_3dnow (const std::vector<float> &taps);
+};
+
+/*!
+ * \brief SSE version of gr_fir_fsf
+ */
+class gr_fir_fsf_sse : public gr_fir_fsf_simd
+{
+public:
+  gr_fir_fsf_sse ();
+  gr_fir_fsf_sse (const std::vector<float> &taps);
+};
+
+#endif
diff --git a/gnuradio-core/src/lib/filter/gr_fir_scc_simd.cc b/gnuradio-core/src/lib/filter/gr_fir_scc_simd.cc
new file mode 100644 (file)
index 0000000..b6f91a7
--- /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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <gr_fir_scc_simd.h>
+
+#include <assert.h>
+#include <malloc16.h>
+#include <iostream>
+
+using std::cerr;
+using std::endl;
+
+gr_fir_scc_simd::gr_fir_scc_simd ()
+  : gr_fir_scc_generic ()
+{
+  // cerr << "@@@ gr_fir_scc_simd\n";
+
+  d_complex_dotprod = 0;
+  
+  d_aligned_taps[0] = 0;
+  d_aligned_taps[1] = 0;
+  d_aligned_taps[2] = 0;
+  d_aligned_taps[3] = 0;
+}
+
+gr_fir_scc_simd::gr_fir_scc_simd (const std::vector<gr_complex> &new_taps)
+  : gr_fir_scc_generic (new_taps)
+{
+  // cerr << "@@@ gr_fir_scc_simd\n";
+
+  d_complex_dotprod = 0;
+  
+  d_aligned_taps[0] = 0;
+  d_aligned_taps[1] = 0;
+  d_aligned_taps[2] = 0;
+  d_aligned_taps[3] = 0;
+  set_taps (new_taps);
+}
+
+gr_fir_scc_simd::~gr_fir_scc_simd ()
+{
+  free16Align (d_aligned_taps[0]);
+  free16Align (d_aligned_taps[1]);
+  free16Align (d_aligned_taps[2]);
+  free16Align (d_aligned_taps[3]);
+}
+
+void
+gr_fir_scc_simd::set_taps (const std::vector<gr_complex> &inew_taps)
+{
+  gr_fir_scc::set_taps (inew_taps);    // call superclass
+
+  const std::vector<gr_complex> new_taps = gr_reverse(inew_taps);
+
+  unsigned len = new_taps.size ();
+
+  // Make 4 copies of the coefficients, one for each data alignment
+  // Note use of special 16-byte-aligned version of calloc()
+  
+  for (unsigned i = 0; i < 4; i++){
+    free16Align (d_aligned_taps[i]);   // free old value
+
+    // this works because the bit representation of a IEEE floating point
+    // +zero is all zeros.  If you're using a different representation,
+    // you'll need to explictly set the result to the appropriate 0.0 value.
+    
+    d_aligned_taps[i] = (float *) calloc16Align (1 + (len + i - 1) / 2,
+                                              2 * 4 * sizeof (float));
+    if (d_aligned_taps[i] == 0){
+      // throw something...
+      cerr << "@@@ gr_fir_scc_simd d_aligned_taps[" << i << "] == 0\n";
+    }
+
+    for (unsigned j = 0; j < len; j++) {
+      d_aligned_taps[i][2*(j+i)] = new_taps[j].real();
+      d_aligned_taps[i][2*(j+i)+1] = new_taps[j].imag();
+    }
+  }
+}
+
+gr_complex 
+gr_fir_scc_simd::filter (const short input[])
+{
+  if (ntaps () == 0)
+    return 0.0;
+
+
+  // Round input data address down to 8 byte boundary
+  // NB: depending on the alignment of input[], memory
+  // before input[] will be accessed. The contents don't matter since 
+  // they'll be multiplied by zero coefficients. I can't conceive of any
+  // situation where this could cause a segfault since memory protection
+  // in the x86 machines is done on much larger boundaries.
+  
+  const short *ar = (short *)((unsigned long) input & ~7);
+
+  // Choose one of 4 sets of pre-shifted coefficients. al is both the
+  // index into d_aligned_taps[] and the number of 0 words padded onto
+  // that coefficients array for alignment purposes.
+
+  unsigned al = input - ar;
+
+  // call assembler routine to do the work, passing number of 2x4-float blocks.
+
+  // assert (((unsigned long) ar & 7) == 0);
+  // assert (((unsigned long) d_aligned_taps[al] & 15) == 0);
+
+  // cerr << "ar: " << ar << " d_aligned_taps[ar]: " << d_aligned_taps[al]
+  //  << " (ntaps() + al - 1)/2 + 1: " << (ntaps() + al -1) / 2 + 1 << endl;
+
+  float result[2];
+
+  d_complex_dotprod (ar, d_aligned_taps[al], (ntaps() + al - 1) / 2 + 1, result);
+
+  // cerr << "result = " << result[0] << " " << result[1] << endl;
+
+  return gr_complex(result[0], result[1]);
+}
diff --git a/gnuradio-core/src/lib/filter/gr_fir_scc_simd.h b/gnuradio-core/src/lib/filter/gr_fir_scc_simd.h
new file mode 100644 (file)
index 0000000..098b02a
--- /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 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.
+ */
+#ifndef INCLUDED_GR_FIR_SCC_SIMD_H
+#define INCLUDED_GR_FIR_SCC_SIMD_H
+
+#include <gr_fir_scc_generic.h>
+
+
+/*!
+ * \brief common base class for SIMD versions of gr_fir_scc
+ *
+ * This base class handles alignment issues common to SSE and 3DNOW
+ * subclasses.
+ */
+
+class gr_fir_scc_simd : public gr_fir_scc_generic
+{
+protected:
+  typedef void (*complex_dotprod_t)(const short *input,
+                                   const float *taps,
+                                   unsigned n_2_complex_blocks,
+                                   float *result);
+
+  /*!
+   * \p aligned_taps holds 4 copies of the coefficients preshifted
+   * by 0, 1, 2, or 3 float pairs to meet all possible input data alignments.
+   * This allows us to always fetch data and taps that are 128-bit aligned.
+   */
+  float                *d_aligned_taps[4];
+
+  complex_dotprod_t    d_complex_dotprod;      // fast dot product primitive
+
+public:
+
+  // CREATORS
+  gr_fir_scc_simd ();
+  gr_fir_scc_simd (const std::vector<gr_complex> &taps);
+  ~gr_fir_scc_simd ();
+
+  // MANIPULATORS
+  virtual void set_taps (const std::vector<gr_complex> &taps);
+  virtual gr_complex filter (const short input[]);
+};
+
+#endif
diff --git a/gnuradio-core/src/lib/filter/gr_fir_scc_x86.cc b/gnuradio-core/src/lib/filter/gr_fir_scc_x86.cc
new file mode 100644 (file)
index 0000000..c654fce
--- /dev/null
@@ -0,0 +1,77 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <gr_fir_scc_x86.h>
+#include <complex_dotprod_x86.h>
+
+/*
+ *     --- 3DNow! version ---
+ */
+gr_fir_scc_3dnow::gr_fir_scc_3dnow ()
+  : gr_fir_scc_simd () 
+{
+  d_complex_dotprod = complex_dotprod_3dnow;
+}
+
+gr_fir_scc_3dnow::gr_fir_scc_3dnow (const std::vector<gr_complex> &new_taps)
+  : gr_fir_scc_simd (new_taps)
+{
+  d_complex_dotprod = complex_dotprod_3dnow;
+}
+
+
+/*
+ *     --- 3DNow! Ext version ---
+ */
+gr_fir_scc_3dnowext::gr_fir_scc_3dnowext ()
+  : gr_fir_scc_simd () 
+{
+  d_complex_dotprod = complex_dotprod_3dnowext;
+}
+
+gr_fir_scc_3dnowext::gr_fir_scc_3dnowext (const std::vector<gr_complex> &new_taps)
+  : gr_fir_scc_simd (new_taps)
+{
+  d_complex_dotprod = complex_dotprod_3dnowext;
+}
+
+
+/*
+ *     --- SSE version ---
+ */
+gr_fir_scc_sse::gr_fir_scc_sse ()
+  : gr_fir_scc_simd ()
+{
+  d_complex_dotprod = complex_dotprod_sse;
+}
+
+gr_fir_scc_sse::gr_fir_scc_sse (const std::vector<gr_complex> &new_taps)
+  : gr_fir_scc_simd (new_taps)
+{
+  d_complex_dotprod = complex_dotprod_sse;
+}
diff --git a/gnuradio-core/src/lib/filter/gr_fir_scc_x86.h b/gnuradio-core/src/lib/filter/gr_fir_scc_x86.h
new file mode 100644 (file)
index 0000000..bbdf5eb
--- /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 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.
+ */
+
+#ifndef INCLUDED_GR_FIR_SCC_X86_H
+#define INCLUDED_GR_FIR_SCC_X86_H
+
+#include <gr_fir_scc_simd.h>
+
+/*!
+ * \brief 3DNow! version of gr_fir_scc
+ */
+class gr_fir_scc_3dnow : public gr_fir_scc_simd
+{
+public:
+  gr_fir_scc_3dnow ();
+  gr_fir_scc_3dnow (const std::vector<gr_complex> &taps);
+};
+
+/*!
+ * \brief 3DNow! Ext version of gr_fir_scc
+ */
+class gr_fir_scc_3dnowext : public gr_fir_scc_simd
+{
+public:
+  gr_fir_scc_3dnowext ();
+  gr_fir_scc_3dnowext (const std::vector<gr_complex> &taps);
+};
+
+/*!
+ * \brief SSE version of gr_fir_scc
+ */
+class gr_fir_scc_sse : public gr_fir_scc_simd
+{
+public:
+  gr_fir_scc_sse ();
+  gr_fir_scc_sse (const std::vector<gr_complex> &taps);
+};
+
+#endif
diff --git a/gnuradio-core/src/lib/filter/gr_fir_sysconfig_x86.cc b/gnuradio-core/src/lib/filter/gr_fir_sysconfig_x86.cc
new file mode 100644 (file)
index 0000000..7d576e8
--- /dev/null
@@ -0,0 +1,553 @@
+/* -*- 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 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.
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <gr_fir_sysconfig_x86.h>
+#include <gr_cpu.h>
+
+#include <gr_fir_ccf.h>
+#include <gr_fir_ccf_generic.h>
+#include <gr_fir_ccf_x86.h>
+#include <gr_fir_fcc.h>
+#include <gr_fir_fcc_generic.h>
+#include <gr_fir_fcc_x86.h>
+#include <gr_fir_fff.h>
+#include <gr_fir_fff_generic.h>
+#include <gr_fir_fff_x86.h>
+#include <gr_fir_fsf.h>
+#include <gr_fir_fsf_generic.h>
+#include <gr_fir_fsf_x86.h>
+#include <gr_fir_ccc.h>
+#include <gr_fir_ccc_generic.h>
+#include <gr_fir_ccc_x86.h>
+#include <gr_fir_scc.h>
+#include <gr_fir_scc_generic.h>
+#include <gr_fir_scc_x86.h>
+// #include <gr_fir_sss.h>
+// #include <gr_fir_sss_generic.h>
+// #include <gr_fir_sss_mmx.h>
+// #include <gr_fir_sss_sse2.h>
+
+#include <iostream>
+using std::cerr;
+
+/*
+ * ----------------------------------------------------------------
+ * static functions that serve as constructors...
+ * Is it possible to take the address of a normal constructor?
+ * ----------------------------------------------------------------
+ */
+
+static gr_fir_ccf *
+make_gr_fir_ccf_3dnow(const std::vector<float> &taps)
+{
+  return new gr_fir_ccf_3dnow(taps);
+}
+
+static gr_fir_ccf *
+make_gr_fir_ccf_sse(const std::vector<float> &taps)
+{
+  return new gr_fir_ccf_sse(taps);
+}
+
+static gr_fir_fcc *
+make_gr_fir_fcc_3dnow(const std::vector<gr_complex> &taps)
+{
+  return new gr_fir_fcc_3dnow(taps);
+}
+
+static gr_fir_fcc *
+make_gr_fir_fcc_sse(const std::vector<gr_complex> &taps)
+{
+  return new gr_fir_fcc_sse(taps);
+}
+
+static gr_fir_ccc *
+make_gr_fir_ccc_3dnow (const std::vector<gr_complex> &taps)
+{
+  return new gr_fir_ccc_3dnow (taps);
+}
+
+static gr_fir_ccc *
+make_gr_fir_ccc_3dnowext (const std::vector<gr_complex> &taps)
+{
+  return new gr_fir_ccc_3dnowext (taps);
+}
+
+static gr_fir_ccc *
+make_gr_fir_ccc_sse (const std::vector<gr_complex> &taps)
+{
+  return new gr_fir_ccc_sse (taps);
+}
+
+static gr_fir_fff *
+make_gr_fir_fff_3dnow (const std::vector<float> &taps)
+{
+  return new gr_fir_fff_3dnow (taps);
+}
+
+static gr_fir_fff *
+make_gr_fir_fff_sse (const std::vector<float> &taps)
+{
+  return new gr_fir_fff_sse (taps);
+}
+
+static gr_fir_fsf *
+make_gr_fir_fsf_3dnow (const std::vector<float> &taps)
+{
+  return new gr_fir_fsf_3dnow (taps);
+}
+
+static gr_fir_fsf *
+make_gr_fir_fsf_sse (const std::vector<float> &taps)
+{
+  return new gr_fir_fsf_sse (taps);
+}
+
+#if 0
+static gr_fir_sss *
+make_gr_fir_sss_mmx (const std::vector<short> &taps)
+{
+  return new gr_fir_sss_mmx (taps);
+}
+
+static gr_fir_sss *
+make_gr_fir_sss_sse2 (const std::vector<short> &taps)
+{
+  return new gr_fir_sss_sse2 (taps);
+}
+#endif
+
+static gr_fir_scc *
+make_gr_fir_scc_3dnow(const std::vector<gr_complex> &taps)
+{
+  return new gr_fir_scc_3dnow(taps);
+}
+
+static gr_fir_scc *
+make_gr_fir_scc_3dnowext(const std::vector<gr_complex> &taps)
+{
+  return new gr_fir_scc_3dnowext(taps);
+}
+
+static gr_fir_scc *
+make_gr_fir_scc_sse(const std::vector<gr_complex> &taps)
+{
+  return new gr_fir_scc_sse(taps);
+}
+
+/*
+ * ----------------------------------------------------------------
+ * Return instances of the fastest x86 versions of these classes.
+ *
+ * check CPUID, if has 3DNowExt, return 3DNow!Ext version,
+ *              else if 3DNow, return 3DNow! version,
+ *              else if SSE2, return SSE2 version,
+ *             else if SSE, return SSE version,
+ *             else if MMX, return MMX version,
+ *             else return generic version.
+ *
+ * FIXME: benchmark, store result, use stored result to
+ *   select the fastest version.
+ * ----------------------------------------------------------------
+ */
+
+gr_fir_ccf *
+gr_fir_sysconfig_x86::create_gr_fir_ccf (const std::vector<float> &taps)
+{
+  static bool first = true;
+
+  if (gr_cpu::has_3dnow ()){
+    if (first){
+      cerr << ">>> gr_fir_ccf: using 3DNow!\n";
+      first = false;
+    }
+    return make_gr_fir_ccf_3dnow (taps);
+  }
+
+  if (gr_cpu::has_sse ()){
+    if (first){
+      cerr << ">>> gr_fir_ccf: using SSE\n";
+      first = false;
+    }
+    return make_gr_fir_ccf_sse (taps);
+  }
+
+  if (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_x86::create_gr_fir_fcc (const std::vector<gr_complex> &taps)
+{
+  static bool first = true;
+
+  if (gr_cpu::has_3dnow ()){
+    if (first){
+      cerr << ">>> gr_fir_fcc: using 3DNow!\n";
+      first = false;
+    }
+    return make_gr_fir_fcc_3dnow (taps);
+  }
+
+  if (gr_cpu::has_sse ()){
+    if (first){
+      cerr << ">>> gr_fir_fcc: using SSE\n";
+      first = false;
+    }
+    return make_gr_fir_fcc_sse (taps);
+  }
+
+  if (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_x86::create_gr_fir_ccc (const std::vector<gr_complex> &taps)
+{
+  static bool first = true;
+
+  if (gr_cpu::has_3dnowext ()){
+    if (first) {
+      cerr << ">>> gr_fir_ccc: using 3DNow!Ext\n";
+      first = false;
+    }
+    return make_gr_fir_ccc_3dnowext (taps);
+  }
+
+  if (gr_cpu::has_3dnow ()){
+    if (first) {
+      cerr << ">>> gr_fir_ccc: using 3DNow!\n";
+      first = false;
+    }
+    return make_gr_fir_ccc_3dnow (taps);
+  }
+
+  if (gr_cpu::has_sse ()){
+    if (first){
+      cerr << ">>> gr_fir_ccc: using SSE\n";
+      first = false;
+    }
+    return make_gr_fir_ccc_sse (taps);
+  }
+  
+  if (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_x86::create_gr_fir_fff (const std::vector<float> &taps)
+{
+  static bool first = true;
+
+  if (gr_cpu::has_3dnow ()){
+    if (first) {
+      cerr << ">>> gr_fir_fff: using 3DNow!\n";
+      first = false;
+    }
+    return make_gr_fir_fff_3dnow (taps);
+  }
+
+  if (gr_cpu::has_sse ()){
+    if (first){
+      cerr << ">>> gr_fir_fff: using SSE\n";
+      first = false;
+    }
+    return make_gr_fir_fff_sse (taps);
+  }
+  
+  if (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_x86::create_gr_fir_fsf (const std::vector<float> &taps)
+{
+  static bool first = true;
+
+  if (gr_cpu::has_3dnow ()){
+    if (first) {
+      cerr << ">>> gr_fir_fsf: using 3DNow!\n";
+      first = false;
+    }
+    return make_gr_fir_fsf_3dnow (taps);
+  }
+
+  if (gr_cpu::has_sse ()){
+    if (first){
+      cerr << ">>> gr_fir_fsf: using SSE\n";
+      first = false;
+    }
+    return make_gr_fir_fsf_sse (taps);
+  }
+  
+  if (first){
+    cerr << ">>> gr_fir_fsf: handing off to parent class\n";
+    first = false;
+  }
+  return gr_fir_sysconfig_generic::create_gr_fir_fsf (taps);
+}
+
+#if 0
+gr_fir_sss *
+gr_fir_sysconfig_x86::create_gr_fir_sss (const std::vector<short> &taps)
+{
+  // FIXME -- probably want to figure out best answer for Athlon and code
+  // add code to select it here...
+
+  if (gr_cpu::has_sse2 ()){
+    cerr << ">>> gr_fir_sss: using SSE2\n";
+    return make_gr_fir_sss_sse2 (taps);
+  }
+  
+  if (gr_cpu::has_mmx ()){
+    cerr << ">>> gr_fir_sss: using MMX\n";
+    return make_gr_fir_sss_mmx (taps);
+  }
+  
+  cerr << ">>> gr_fir_sss: handing off to parent class\n";
+  return gr_fir_sysconfig_generic::create_gr_fir_sss (taps);
+}
+#endif
+
+gr_fir_scc *
+gr_fir_sysconfig_x86::create_gr_fir_scc (const std::vector<gr_complex> &taps)
+{
+  static bool first = true;
+
+  if (gr_cpu::has_3dnowext ()){
+    if (first){
+      cerr << ">>> gr_fir_scc: using 3DNow!Ext\n";
+      first = false;
+    }
+    return make_gr_fir_scc_3dnowext (taps);
+  }
+
+  if (gr_cpu::has_3dnow ()){
+    if (first){
+      cerr << ">>> gr_fir_scc: using 3DNow!\n";
+      first = false;
+    }
+    return make_gr_fir_scc_3dnow (taps);
+  }
+
+  if (gr_cpu::has_sse ()){
+    if (first){
+      cerr << ">>> gr_fir_scc: using SSE\n";
+      first = false;
+    }
+    return make_gr_fir_scc_sse (taps);
+  }
+
+  if (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_x86::get_gr_fir_ccf_info (std::vector<gr_fir_ccf_info> *info)
+{
+  gr_fir_ccf_info      t;
+
+  // invoke parent..
+  gr_fir_sysconfig_generic::get_gr_fir_ccf_info (info);
+
+  // add our stuff...
+  if (gr_cpu::has_3dnow ()){
+    t.name = "3DNow!";
+    t.create = make_gr_fir_ccf_3dnow;
+    (*info).push_back (t);
+  }
+
+  if (gr_cpu::has_sse ()){
+    t.name = "SSE";
+    t.create = make_gr_fir_ccf_sse;
+    (*info).push_back (t);
+  }
+}
+
+void 
+gr_fir_sysconfig_x86::get_gr_fir_fcc_info (std::vector<gr_fir_fcc_info> *info)
+{
+  gr_fir_fcc_info      t;
+
+  // invoke parent..
+  gr_fir_sysconfig_generic::get_gr_fir_fcc_info (info);
+
+  // add our stuff...
+  if (gr_cpu::has_3dnow ()){
+    t.name = "3DNow!";
+    t.create = make_gr_fir_fcc_3dnow;
+    (*info).push_back (t);
+  }
+
+  if (gr_cpu::has_sse ()){
+    t.name = "SSE";
+    t.create = make_gr_fir_fcc_sse;
+    (*info).push_back (t);
+  }
+}
+
+void 
+gr_fir_sysconfig_x86::get_gr_fir_ccc_info (std::vector<gr_fir_ccc_info> *info)
+{
+  gr_fir_ccc_info      t;
+  
+  // invoke parent..
+  gr_fir_sysconfig_generic::get_gr_fir_ccc_info (info);
+
+  // add our stuff...
+  if (gr_cpu::has_3dnowext ()){
+    t.name = "3DNow!Ext";
+    t.create = make_gr_fir_ccc_3dnowext;
+    (*info).push_back (t);
+  }
+
+  if (gr_cpu::has_3dnow ()){
+    t.name = "3DNow!";
+    t.create = make_gr_fir_ccc_3dnow;
+    (*info).push_back (t);
+  }
+
+  if (gr_cpu::has_sse ()){
+    t.name = "SSE";
+    t.create = make_gr_fir_ccc_sse;
+    (*info).push_back (t);
+  }
+}
+
+void 
+gr_fir_sysconfig_x86::get_gr_fir_fff_info (std::vector<gr_fir_fff_info> *info)
+{
+  gr_fir_fff_info      t;
+  
+  // invoke parent..
+  gr_fir_sysconfig_generic::get_gr_fir_fff_info (info);
+
+  // add our stuff...
+  if (gr_cpu::has_3dnow ()){
+    t.name = "3DNow!";
+    t.create = make_gr_fir_fff_3dnow;
+    (*info).push_back (t);
+  }
+
+  if (gr_cpu::has_sse ()){
+    t.name = "SSE";
+    t.create = make_gr_fir_fff_sse;
+    (*info).push_back (t);
+  }
+}
+
+void 
+gr_fir_sysconfig_x86::get_gr_fir_fsf_info (std::vector<gr_fir_fsf_info> *info)
+{
+  gr_fir_fsf_info      t;
+  
+  // invoke parent..
+  gr_fir_sysconfig_generic::get_gr_fir_fsf_info (info);
+
+  // add our stuff...
+  if (gr_cpu::has_3dnow ()){
+    t.name = "3DNow!";
+    t.create = make_gr_fir_fsf_3dnow;
+    (*info).push_back (t);
+  }
+
+  if (gr_cpu::has_sse ()){
+    t.name = "SSE";
+    t.create = make_gr_fir_fsf_sse;
+    (*info).push_back (t);
+  }
+}
+
+void 
+gr_fir_sysconfig_x86::get_gr_fir_scc_info (std::vector<gr_fir_scc_info> *info)
+{
+  gr_fir_scc_info      t;
+
+  // invoke parent..
+  gr_fir_sysconfig_generic::get_gr_fir_scc_info (info);
+
+  // add our stuff...
+  if (gr_cpu::has_3dnowext ()){
+    t.name = "3DNow!Ext";
+    t.create = make_gr_fir_scc_3dnowext;
+    (*info).push_back (t);
+  }
+
+  if (gr_cpu::has_3dnow ()){
+    t.name = "3DNow!";
+    t.create = make_gr_fir_scc_3dnow;
+    (*info).push_back (t);
+  }
+
+  if (gr_cpu::has_sse ()){
+    t.name = "SSE";
+    t.create = make_gr_fir_scc_sse;
+    (*info).push_back (t);
+  }
+}
+
+#if 0
+void 
+gr_fir_sysconfig_x86::get_gr_fir_sss_info (std::vector<gr_fir_sss_info> *info)
+{
+  gr_fir_sss_info      t;
+  
+  // invoke parent..
+  gr_fir_sysconfig_generic::get_gr_fir_sss_info (info);
+
+  // add our stuff...
+  if (gr_cpu::has_mmx ()){
+    t.name = "MMX";
+    t.create = make_gr_fir_sss_mmx;
+    (*info).push_back (t);
+  }
+
+  if (gr_cpu::has_sse2 ()){
+    t.name = "SSE2";
+    t.create = make_gr_fir_sss_sse2;
+    (*info).push_back (t);
+  }
+}
+#endif
diff --git a/gnuradio-core/src/lib/filter/gr_fir_sysconfig_x86.h b/gnuradio-core/src/lib/filter/gr_fir_sysconfig_x86.h
new file mode 100644 (file)
index 0000000..2f1d48e
--- /dev/null
@@ -0,0 +1,46 @@
+/* -*- 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 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.
+ */
+#ifndef INCLUDED_GR_FIR_SYSCONFIG_X86_H
+#define INCLUDED_GR_FIR_SYSCONFIG_X86_H
+
+#include <gr_fir_sysconfig_generic.h>
+
+class gr_fir_sysconfig_x86 : 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_fractional_interpolator.cc b/gnuradio-core/src/lib/filter/gr_fractional_interpolator.cc
new file mode 100644 (file)
index 0000000..6abb963
--- /dev/null
@@ -0,0 +1,97 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_io_signature.h>
+#include <gr_fractional_interpolator.h>
+#include <gri_mmse_fir_interpolator.h>
+#include <stdexcept>
+
+// Public constructor
+gr_fractional_interpolator_sptr gr_make_fractional_interpolator(float phase_shift, float interp_ratio)
+{
+  return gr_fractional_interpolator_sptr(new gr_fractional_interpolator(phase_shift, interp_ratio));
+}
+
+gr_fractional_interpolator::gr_fractional_interpolator(float phase_shift, float interp_ratio)
+  : gr_block ("fractional_interpolator",
+             gr_make_io_signature (1, 1, sizeof (float)),
+             gr_make_io_signature (1, 1, sizeof (float))),
+    d_mu (phase_shift), d_mu_inc (interp_ratio), d_interp()
+{
+  if (interp_ratio <=  0)
+    throw std::out_of_range ("interpolation ratio must be > 0");
+  if (phase_shift <  0  || phase_shift > 1)
+    throw std::out_of_range ("phase shift ratio must be > 0 and < 1");
+
+  set_relative_rate (1.0 / interp_ratio);
+}
+
+gr_fractional_interpolator::~gr_fractional_interpolator()
+{
+    delete d_interp;
+}
+
+void
+gr_fractional_interpolator::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] =
+      (int) ceil((noutput_items * d_mu_inc) + d_interp->ntaps());
+}
+
+int
+gr_fractional_interpolator::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];
+
+  int  ii = 0;                         // input index
+  int          oo = 0;                         // output index
+
+  while (oo < noutput_items){
+
+    // produce output sample
+
+    out[oo++] = d_interp->interpolate(&in[ii], d_mu);
+
+    //  printf( "%4d %9.6f\n", ii, d_mu);
+
+    double s = d_mu + d_mu_inc;
+    double f = floor (s);
+    int incr = (int) f;
+    d_mu = s - f;
+    ii += incr;
+  }
+
+  consume_each (ii);
+
+  return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/filter/gr_fractional_interpolator.h b/gnuradio-core/src/lib/filter/gr_fractional_interpolator.h
new file mode 100644 (file)
index 0000000..b024c44
--- /dev/null
@@ -0,0 +1,62 @@
+/* -*- 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 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.
+ */
+
+#ifndef INCLUDED_GR_FRACTIONAL_INTERPOLATOR_H
+#define        INCLUDED_GR_FRACTIONAL_INTERPOLATOR_H
+
+#include <gr_block.h>
+
+class gri_mmse_fir_interpolator;
+
+class gr_fractional_interpolator;
+typedef boost::shared_ptr<gr_fractional_interpolator> gr_fractional_interpolator_sptr;
+
+// public constructor
+gr_fractional_interpolator_sptr gr_make_fractional_interpolator (float phase_shift, float interp_ratio);
+
+/*!
+ * \brief Interpolating mmse filter with float input, float output
+ * \ingroup filter
+ */
+class gr_fractional_interpolator : public gr_block
+{
+ public:
+  ~gr_fractional_interpolator ();
+  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);
+
+protected:
+  gr_fractional_interpolator (float phase_shift, float interp_ratio);
+
+ private:
+  float                        d_mu;
+  float                        d_mu_inc;
+  gri_mmse_fir_interpolator    *d_interp;
+
+  friend gr_fractional_interpolator_sptr
+    gr_make_fractional_interpolator (float phase_shift, float interp_ratio);
+};
+
+#endif
diff --git a/gnuradio-core/src/lib/filter/gr_freq_xlating_fir_filter_XXX.cc.t b/gnuradio-core/src/lib/filter/gr_freq_xlating_fir_filter_XXX.cc.t
new file mode 100644 (file)
index 0000000..4592e75
--- /dev/null
@@ -0,0 +1,122 @@
+/* -*- 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 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.
+ */
+
+/*
+ * WARNING: This file is automatically generated by
+ * generate_gr_freq_xlating_fir_filter_XXX.py 
+ * Any changes made to this file will be overwritten.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <@NAME@.h>
+#include <@FIR_TYPE@.h>
+#include <gr_fir_util.h>
+#include <gr_io_signature.h>
+
+@SPTR_NAME@ 
+gr_make_@BASE_NAME@ (int decimation, const std::vector<@TAP_TYPE@> &taps,
+                    double center_freq, double sampling_freq)
+{
+  return @SPTR_NAME@ (new @NAME@ (decimation, taps, center_freq, sampling_freq));
+}
+
+
+@NAME@::@NAME@ (
+
+       int decimation,
+       const std::vector<@TAP_TYPE@> &taps,
+       double center_freq,
+       double sampling_freq)
+
+  : gr_sync_decimator ("@BASE_NAME@",
+                      gr_make_io_signature (1, 1, sizeof (@I_TYPE@)),
+                      gr_make_io_signature (1, 1, sizeof (@O_TYPE@)),
+                      decimation),
+    d_proto_taps (taps), d_center_freq (center_freq), d_sampling_freq (sampling_freq),
+    d_updated (false)
+{
+  std::vector<gr_complex>      dummy_taps;
+  d_composite_fir = gr_fir_util::create_@FIR_TYPE@ (dummy_taps);
+
+  set_history (d_proto_taps.size ());
+  build_composite_fir ();
+}
+
+@NAME@::~@NAME@ ()
+{
+  delete d_composite_fir;
+}
+
+void
+@NAME@::build_composite_fir ()
+{
+  std::vector<gr_complex> ctaps (d_proto_taps.size ());
+
+  float fwT0 = 2 * M_PI * d_center_freq / d_sampling_freq;
+  for (unsigned int i = 0; i < d_proto_taps.size (); i++)
+    ctaps[i] = d_proto_taps[i] * exp (gr_complex (0, i * fwT0));
+
+  d_composite_fir->set_taps (gr_reverse(ctaps));
+  d_r.set_phase_incr (exp (gr_complex (0, fwT0 * decimation ())));
+}
+
+void
+@NAME@::set_center_freq (double center_freq)
+{
+  d_center_freq = center_freq;
+  d_updated = true;
+}
+
+void
+@NAME@::set_taps (const std::vector<@TAP_TYPE@> &taps)
+{
+  d_proto_taps = taps;
+  d_updated = true;
+}
+
+int
+@NAME@::work (int noutput_items,
+                  gr_vector_const_void_star &input_items,
+                  gr_vector_void_star &output_items)
+{
+  @I_TYPE@     *in  = (@I_TYPE@ *) input_items[0];
+  @O_TYPE@     *out = (@O_TYPE@ *) output_items[0];
+
+  // rebuild composite FIR if the center freq has changed
+
+  if (d_updated){
+    set_history (d_proto_taps.size ());
+    build_composite_fir ();
+    d_updated = false;
+  }
+
+  unsigned j = 0;
+  for (int i = 0; i < noutput_items; i++){
+    out[i] = d_r.rotate (d_composite_fir->filter (&in[j]));
+    j += decimation ();
+  }
+  
+  return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/filter/gr_freq_xlating_fir_filter_XXX.h.t b/gnuradio-core/src/lib/filter/gr_freq_xlating_fir_filter_XXX.h.t
new file mode 100644 (file)
index 0000000..d1351e2
--- /dev/null
@@ -0,0 +1,100 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002,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.
+ */
+
+/*
+ * WARNING: This file is automatically generated by
+ * generate_gr_freq_xlating_fir_filter_XXX.py  Any changes made to this file
+ * will be overwritten.
+ */
+
+#ifndef @GUARD_NAME@
+#define        @GUARD_NAME@
+
+#include <gr_sync_decimator.h>
+#include <gr_rotator.h>
+
+class @NAME@;
+typedef boost::shared_ptr<@NAME@> @SPTR_NAME@;
+
+/*!
+ * Construct a FIR filter with the given taps and a composite frequency
+ * translation that shifts center_freq down to zero Hz.  The frequency 
+ * translation logically comes before the filtering operation.
+ */
+@SPTR_NAME@ 
+gr_make_@BASE_NAME@ (int decimation, const std::vector<@TAP_TYPE@> &taps,
+                    double center_freq, double sampling_freq);
+
+
+class @FIR_TYPE@;
+
+/*!
+ * \brief FIR filter combined with frequency translation with @I_TYPE@ input, @O_TYPE@ output and @TAP_TYPE@ taps
+ * \ingroup filter
+ *
+ * This class efficiently combines a frequency translation
+ * (typically "down conversion") with a FIR filter (typically low-pass)
+ * and decimation.  It is ideally suited for a "channel selection filter"
+ * and can be efficiently used to select and decimate a narrow band signal
+ * out of wide bandwidth input.
+ *
+ * Uses a single input array to produce a single output array.
+ * Additional inputs and/or outputs are ignored.
+ */
+class @NAME@ : public gr_sync_decimator
+{
+ public:
+  virtual ~@NAME@ ();
+
+  void set_center_freq (double center_freq);
+  void set_taps (const std::vector<@TAP_TYPE@> &taps);
+
+  int work (int noutput_items,
+           gr_vector_const_void_star &input_items,
+           gr_vector_void_star &output_items);
+
+ private:
+  friend @SPTR_NAME@ 
+  gr_make_@BASE_NAME@ (int decimation, const std::vector<@TAP_TYPE@> &taps,
+                      double center_freq, double sampling_freq);
+
+ protected:
+  std::vector<@TAP_TYPE@>      d_proto_taps;
+  @FIR_TYPE@                  *d_composite_fir;
+  gr_rotator                   d_r;
+  double                       d_center_freq;
+  double                       d_sampling_freq;
+  bool                         d_updated;
+
+  virtual void build_composite_fir ();
+
+  /*!
+   * Construct a FIR filter with the given taps and a composite frequency
+   * translation that shifts center_freq down to zero Hz.  The frequency 
+   * translation logically comes before the filtering operation.
+   */
+  @NAME@ (int decimation,
+                         const std::vector<@TAP_TYPE@> &taps,
+                         double center_freq, double sampling_freq);
+};
+
+#endif /* _@NAME@_H_ */
diff --git a/gnuradio-core/src/lib/filter/gr_freq_xlating_fir_filter_XXX.i.t b/gnuradio-core/src/lib/filter/gr_freq_xlating_fir_filter_XXX.i.t
new file mode 100644 (file)
index 0000000..0a4f8b3
--- /dev/null
@@ -0,0 +1,47 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003,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.
+ */
+
+/*
+ * WARNING: This file is automatically generated by
+ * generate_gr_freq_xlating_fir_filter_XXX.py
+ * Any changes made to this file will be overwritten.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,@BASE_NAME@)
+
+@SPTR_NAME@ 
+gr_make_@BASE_NAME@ (int decimation, const std::vector<@TAP_TYPE@> &taps,
+                    double center_freq, double sampling_freq);
+
+
+class @NAME@ : public gr_sync_decimator
+{
+ protected:
+  @NAME@ (int decimation, const std::vector<@TAP_TYPE@> &taps,
+         double center_freq, double sampling_freq);
+
+ public:
+  ~@NAME@ ();
+
+  void set_center_freq (double center_freq);
+  void set_taps (const std::vector<@TAP_TYPE@> &taps);
+};
diff --git a/gnuradio-core/src/lib/filter/gr_goertzel_fc.cc b/gnuradio-core/src/lib/filter/gr_goertzel_fc.cc
new file mode 100644 (file)
index 0000000..264b96e
--- /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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_goertzel_fc.h>
+#include <gr_io_signature.h>
+
+// public constructor
+gr_goertzel_fc_sptr 
+gr_make_goertzel_fc(int rate, int len, float freq) 
+{
+  return gr_goertzel_fc_sptr (new gr_goertzel_fc(rate, len, freq));
+}
+
+gr_goertzel_fc::gr_goertzel_fc(int rate, int len, float freq)
+  : gr_sync_decimator("goertzel_fc",
+                     gr_make_io_signature (1, 1, sizeof (float)),
+                     gr_make_io_signature (1, 1, sizeof (gr_complex)),
+                     len),
+    d_goertzel(rate, len, freq)
+{
+  d_len = len;
+}
+
+int gr_goertzel_fc::work(int noutput_items,
+                        gr_vector_const_void_star &input_items,
+                        gr_vector_void_star &output_items)
+{
+  float *in = (float *)input_items[0];
+  gr_complex *out = (gr_complex *)output_items[0];
+
+  for (int i = 0; i < noutput_items; i++) {
+    *out++ = d_goertzel.batch(in);
+    in += d_len;
+  }
+
+  return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/filter/gr_goertzel_fc.h b/gnuradio-core/src/lib/filter/gr_goertzel_fc.h
new file mode 100644 (file)
index 0000000..c8363bc
--- /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 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.
+ */
+
+#ifndef INCLUDED_GR_GOERTZEL_FC_H
+#define INCLUDED_GR_GOERTZEL_FC_H
+
+#include <gri_goertzel.h>
+#include <gr_sync_decimator.h>
+
+class gr_goertzel_fc;
+typedef boost::shared_ptr<gr_goertzel_fc> gr_goertzel_fc_sptr;
+
+// public constructor
+gr_goertzel_fc_sptr gr_make_goertzel_fc(int rate, int len, float freq);
+
+/*!
+ * \brief Goertzel single-bin DFT calculation.
+ * \ingroup filter
+ */
+class gr_goertzel_fc : public gr_sync_decimator
+{
+private:
+  friend gr_goertzel_fc_sptr gr_make_goertzel_fc (int rate, int len, float freq);
+
+  gr_goertzel_fc(int rate, int len, float freq);
+  gri_goertzel d_goertzel;
+  int          d_len;
+
+public:
+  int work(int noutput_items,
+          gr_vector_const_void_star &input_items,
+          gr_vector_void_star &output_items);
+};
+
+#endif /* INCLUDED_GR_GOERTZEL_FC_H */
+
diff --git a/gnuradio-core/src/lib/filter/gr_goertzel_fc.i b/gnuradio-core/src/lib/filter/gr_goertzel_fc.i
new file mode 100644 (file)
index 0000000..6d5efd2
--- /dev/null
@@ -0,0 +1,31 @@
+/* -*- 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 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.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,goertzel_fc);
+
+gr_goertzel_fc_sptr gr_make_goertzel_fc(int rate, int len, float freq);
+
+class gr_goertzel_fc : public gr_sync_decimator
+{
+private:
+  gr_goertzel_fc();
+};
diff --git a/gnuradio-core/src/lib/filter/gr_hilbert_fc.cc b/gnuradio-core/src/lib/filter/gr_hilbert_fc.cc
new file mode 100644 (file)
index 0000000..371363c
--- /dev/null
@@ -0,0 +1,67 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_hilbert_fc.h>
+#include <gr_firdes.h>
+#include <gr_fir_fff.h>
+#include <gr_fir_util.h>
+
+// public constructor
+gr_hilbert_fc_sptr 
+gr_make_hilbert_fc (unsigned int ntaps)
+{
+  return gr_hilbert_fc_sptr (new gr_hilbert_fc (ntaps));
+}
+
+gr_hilbert_fc::gr_hilbert_fc (unsigned int ntaps)
+  : gr_sync_block ("hilbert_fc",
+                  gr_make_io_signature (1, 1, sizeof (float)),
+                  gr_make_io_signature (1, 1, sizeof (gr_complex))),
+    d_ntaps (ntaps | 0x1),     // ensure ntaps is odd
+    d_hilb (gr_fir_util::create_gr_fir_fff (gr_firdes::hilbert (d_ntaps)))
+{
+  set_history (d_ntaps);
+}
+
+gr_hilbert_fc::~gr_hilbert_fc ()
+{
+  delete d_hilb;
+}
+
+int
+gr_hilbert_fc::work (int noutput_items,
+                         gr_vector_const_void_star &input_items,
+                         gr_vector_void_star &output_items)
+{
+  float *in = (float *) input_items[0];
+  gr_complex *out = (gr_complex *) output_items[0];
+
+  for (int i = 0; i < noutput_items; i++)
+    out[i] = gr_complex (in[i + d_ntaps/2],
+                        d_hilb->filter (&in[i]));
+
+  return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/filter/gr_hilbert_fc.h b/gnuradio-core/src/lib/filter/gr_hilbert_fc.h
new file mode 100644 (file)
index 0000000..54082a9
--- /dev/null
@@ -0,0 +1,68 @@
+/* -*- 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 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.
+ */
+
+#ifndef INCLUDED_GR_HILBERT_FC_H
+#define INCLUDED_GR_HILBERT_FC_H
+
+#include <gr_sync_block.h>
+#include <gr_io_signature.h>
+#include <gr_types.h>
+
+class gr_hilbert_fc;
+typedef boost::shared_ptr<gr_hilbert_fc> gr_hilbert_fc_sptr;
+
+// public constructor
+gr_hilbert_fc_sptr gr_make_hilbert_fc (unsigned int ntaps);
+
+
+class gr_fir_fff;
+
+/*!
+ * \brief Hilbert transformer.
+ * \ingroup filter
+ *
+ * real output is input appropriately delayed.
+ * imaginary output is hilbert filtered (90 degree phase shift)
+ * version of input.
+ */
+class gr_hilbert_fc : public gr_sync_block
+{
+ public:
+  ~gr_hilbert_fc ();
+
+  int work (int noutput_items,
+           gr_vector_const_void_star &input_items,
+           gr_vector_void_star &output_items);
+
+ protected:
+  gr_hilbert_fc (unsigned int ntaps);
+
+ private:
+  unsigned int  d_ntaps;
+  gr_fir_fff   *d_hilb;
+
+  friend gr_hilbert_fc_sptr gr_make_hilbert_fc (unsigned int ntaps);
+};
+
+
+
+#endif /* INCLUDED_GR_HILBERT_FC_H */
diff --git a/gnuradio-core/src/lib/filter/gr_hilbert_fc.i b/gnuradio-core/src/lib/filter/gr_hilbert_fc.i
new file mode 100644 (file)
index 0000000..f69f624
--- /dev/null
@@ -0,0 +1,34 @@
+/* -*- 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 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.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,hilbert_fc);
+
+gr_hilbert_fc_sptr gr_make_hilbert_fc (unsigned int ntaps);
+
+class gr_hilbert_fc : public gr_sync_block
+{
+protected:
+  gr_hilbert_fc (unsigned int ntaps);
+
+public:
+  ~gr_hilbert_fc ();
+};
diff --git a/gnuradio-core/src/lib/filter/gr_iir_filter_ffd.cc b/gnuradio-core/src/lib/filter/gr_iir_filter_ffd.cc
new file mode 100644 (file)
index 0000000..4e825e7
--- /dev/null
@@ -0,0 +1,88 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_iir_filter_ffd.h>
+#include <gr_io_signature.h>
+#include <stdio.h>
+
+
+gr_iir_filter_ffd_sptr 
+gr_make_iir_filter_ffd (const std::vector<double> &fftaps,
+                       const std::vector<double> &fbtaps) throw (std::invalid_argument)
+{
+  return gr_iir_filter_ffd_sptr (new gr_iir_filter_ffd (fftaps, fbtaps));
+}
+
+gr_iir_filter_ffd::gr_iir_filter_ffd (const std::vector<double> &fftaps,
+                                     const std::vector<double> &fbtaps) throw (std::invalid_argument)
+
+  : gr_sync_block ("iir_filter_ffd",
+                  gr_make_io_signature (1, 1, sizeof (float)),
+                  gr_make_io_signature (1, 1, sizeof (float))),
+    d_iir (fftaps, fbtaps),
+    d_updated (false)
+{
+  // fprintf (stderr, "gr_iir_filter_ffd::ctor\n");
+}
+
+gr_iir_filter_ffd::~gr_iir_filter_ffd ()
+{
+  // nop
+}
+
+void
+gr_iir_filter_ffd::set_taps (const std::vector<double> &fftaps,
+                            const std::vector<double> &fbtaps) throw (std::invalid_argument)
+{
+  if (fftaps.size () != fbtaps.size ()){
+    fprintf (stderr,
+     "gr_iir_filter_ffd::set_taps: fftaps and fbtaps must have the same number of elements.\n");
+    throw std::invalid_argument ("gr_iir_filter_ffd::set_taps");
+  }
+  
+  d_new_fftaps = fftaps;
+  d_new_fbtaps = fbtaps;
+  d_updated = true;
+}
+
+int
+gr_iir_filter_ffd::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];
+
+  // fprintf (stderr, "gr_iir_filter_ffd::work noutput_items = %d\n", noutput_items);
+
+  if (d_updated){
+    d_iir.set_taps (d_new_fftaps, d_new_fbtaps);
+    d_updated = false;
+  }
+
+  d_iir.filter_n (out, in, noutput_items);
+  return noutput_items;
+};
diff --git a/gnuradio-core/src/lib/filter/gr_iir_filter_ffd.h b/gnuradio-core/src/lib/filter/gr_iir_filter_ffd.h
new file mode 100644 (file)
index 0000000..5ef3634
--- /dev/null
@@ -0,0 +1,89 @@
+/* -*- 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 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.
+ */
+
+#ifndef INCLUDED_GR_IIR_FILTER_FFD_H
+#define        INCLUDED_GR_IIR_FILTER_FFD_H
+
+#include <gr_sync_block.h>
+#include <gri_iir.h>
+#include <stdexcept>
+
+class gr_iir_filter_ffd;
+typedef boost::shared_ptr<gr_iir_filter_ffd> gr_iir_filter_ffd_sptr;
+gr_iir_filter_ffd_sptr 
+gr_make_iir_filter_ffd (const std::vector<double> &fftaps,
+                       const std::vector<double> &fbtaps) throw (std::invalid_argument);
+
+/*!
+ * \brief  IIR filter with float input, float output and double taps
+ * \ingroup filter
+ *
+ * This filter uses the Direct Form I implementation, where
+ * \p fftaps contains the feed-forward taps, and \p fbtaps the feedback ones.
+ *
+ * \p fftaps and \p fbtaps must have equal numbers of taps
+ *
+ * The input and output satisfy a difference equation of the form
+
+ \f[
+ y[n] - \sum_{k=1}^{N} a_k y[n-k] = \sum_{k=0}^{M} b_k x[n-k]
+ \f]
+
+ * with the corresponding rational system function
+
+ \f[
+ H(z) = \frac{\sum_{k=0}^{M} b_k z^{-k}}{1 - \sum_{k=1}^{N} a_k z^{-k}}
+ \f]
+
+ * Note that some texts define the system function with a + in the denominator.
+ * If you're using that convention, you'll need to negate the feedback taps.
+ */
+class gr_iir_filter_ffd : public gr_sync_block
+{
+ private:
+  friend gr_iir_filter_ffd_sptr 
+  gr_make_iir_filter_ffd (const std::vector<double> &fftaps,
+                         const std::vector<double> &fbtaps) throw (std::invalid_argument);
+
+  gri_iir<float,float,double>          d_iir;
+  std::vector<double>                  d_new_fftaps;
+  std::vector<double>                  d_new_fbtaps;
+  bool                                 d_updated;
+
+  /*!
+   * Construct an IIR filter with the given taps
+   */
+  gr_iir_filter_ffd (const std::vector<double> &fftaps,
+                    const std::vector<double> &fbtaps) throw (std::invalid_argument);
+
+ public:
+  ~gr_iir_filter_ffd ();
+
+  void set_taps (const std::vector<double> &fftaps,
+                const std::vector<double> &fbtaps) throw (std::invalid_argument);
+
+  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_iir_filter_ffd.i b/gnuradio-core/src/lib/filter/gr_iir_filter_ffd.i
new file mode 100644 (file)
index 0000000..bab8310
--- /dev/null
@@ -0,0 +1,40 @@
+/* -*- 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 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.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,iir_filter_ffd);
+
+gr_iir_filter_ffd_sptr 
+gr_make_iir_filter_ffd (const std::vector<double> &fftaps,
+                       const std::vector<double> &fbtaps) throw (std::invalid_argument);
+
+class gr_iir_filter_ffd : public gr_sync_block
+{
+ private:
+  gr_iir_filter_ffd (const std::vector<double> &fftaps,
+                    const std::vector<double> &fbtaps) throw (std::invalid_argument);
+
+ public:
+  ~gr_iir_filter_ffd ();
+
+  void set_taps (const std::vector<double> &fftaps,
+                const std::vector<double> &fbtaps) throw (std::invalid_argument);
+};
diff --git a/gnuradio-core/src/lib/filter/gr_interp_fir_filter_XXX.cc.t b/gnuradio-core/src/lib/filter/gr_interp_fir_filter_XXX.cc.t
new file mode 100644 (file)
index 0000000..f382a7c
--- /dev/null
@@ -0,0 +1,146 @@
+/* -*- 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 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.
+ */
+
+/*
+ * WARNING: This file is automatically generated by generate_gr_fir_filter_XXX.py
+ * Any changes made to this file will be overwritten.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <@NAME@.h>
+#include <@FIR_TYPE@.h>
+#include <gr_fir_util.h>
+#include <gr_io_signature.h>
+#include <stdexcept>
+#include <iostream>
+
+@SPTR_NAME@ gr_make_@BASE_NAME@ (unsigned interpolation, const std::vector<@TAP_TYPE@> &taps)
+{
+  return @SPTR_NAME@ (new @NAME@ (interpolation, taps));
+}
+
+
+@NAME@::@NAME@ (unsigned interpolation, const std::vector<@TAP_TYPE@> &taps)
+  : gr_sync_interpolator ("@BASE_NAME@",
+                         gr_make_io_signature (1, 1, sizeof (@I_TYPE@)),
+                         gr_make_io_signature (1, 1, sizeof (@O_TYPE@)),
+                         interpolation),
+    d_updated (false), d_firs (interpolation)
+{
+  if (interpolation == 0)
+    throw std::out_of_range ("interpolation must be > 0");
+
+  std::vector<@TAP_TYPE@>      dummy_taps;
+  
+  for (unsigned i = 0; i < interpolation; i++)
+    d_firs[i] = gr_fir_util::create_@FIR_TYPE@ (dummy_taps);
+
+  set_taps (taps);
+  install_taps(d_new_taps);
+}
+
+@NAME@::~@NAME@ ()
+{
+  int interp = interpolation ();
+  for (int i = 0; i < interp; i++)
+    delete d_firs[i];
+}
+
+void
+@NAME@::set_taps (const std::vector<@TAP_TYPE@> &taps)
+{
+  d_new_taps = taps;
+  d_updated = true;
+
+  // round up length to a multiple of the interpolation factor
+  int n = taps.size () % interpolation ();
+  if (n > 0){
+    n = interpolation () - n;
+    while (n-- > 0)
+      d_new_taps.insert(d_new_taps.begin(), 0);
+  }
+
+  assert (d_new_taps.size () % interpolation () == 0);
+}
+
+
+void
+@NAME@::install_taps (const std::vector<@TAP_TYPE@> &taps)
+{
+  int nfilters = interpolation ();
+  int nt = taps.size () / nfilters;
+
+  assert (nt * nfilters == (int) taps.size ());
+
+  std::vector< std::vector <@TAP_TYPE@> > xtaps (nfilters);
+
+  for (int n = 0; n < nfilters; n++)
+    xtaps[n].resize (nt);  
+
+  for (int i = 0; i < (int) taps.size(); i++)
+    xtaps[i % nfilters][i / nfilters] = taps[i];
+
+  for (int n = 0; n < nfilters; n++)
+    d_firs[n]->set_taps (xtaps[n]);
+  
+  set_history (nt);
+  d_updated = false;
+
+#if 0
+  for (int i = 0; i < nfilters; i++){
+    std::cout << "filter[" << i << "] = ";
+    for (int j = 0; j < nt; j++)
+      std::cout << xtaps[i][j] << " ";
+
+    std::cout << "\n";
+  }
+#endif
+
+}
+
+int
+@NAME@::work (int noutput_items,
+                  gr_vector_const_void_star &input_items,
+                  gr_vector_void_star &output_items)
+{
+  const @I_TYPE@ *in = (const @I_TYPE@ *) input_items[0];
+  @O_TYPE@ *out = (@O_TYPE@ *) output_items[0];
+
+  if (d_updated) {
+    install_taps (d_new_taps);
+    return 0;               // history requirements may have changed.
+  }
+
+  int nfilters = interpolation ();
+  int ni = noutput_items / interpolation ();
+  
+  for (int i = 0; i < ni; i++){
+    for (int nf = 0; nf < nfilters; nf++)
+      out[nf] = d_firs[nf]->filter (&in[i]);
+    out += nfilters;
+  }
+
+  return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/filter/gr_interp_fir_filter_XXX.h.t b/gnuradio-core/src/lib/filter/gr_interp_fir_filter_XXX.h.t
new file mode 100644 (file)
index 0000000..866c43a
--- /dev/null
@@ -0,0 +1,69 @@
+/* -*- 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 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.
+ */
+
+/*
+ * WARNING: This file is automatically generated by generate_gr_fir_filter_XXX.py
+ * Any changes made to this file will be overwritten.
+ */
+
+#ifndef @GUARD_NAME@
+#define        @GUARD_NAME@
+
+#include <gr_sync_interpolator.h>
+
+class @NAME@;
+typedef boost::shared_ptr<@NAME@> @SPTR_NAME@;
+@SPTR_NAME@ gr_make_@BASE_NAME@ (unsigned interpolation, const std::vector<@TAP_TYPE@> &taps);
+
+class @FIR_TYPE@;
+
+/*!
+ * \brief Interpolating FIR filter with @I_TYPE@ input, @O_TYPE@ output and @TAP_TYPE@ taps
+ * \ingroup filter
+ */
+class @NAME@ : public gr_sync_interpolator
+{
+ private:
+  friend @SPTR_NAME@ gr_make_@BASE_NAME@ (unsigned interpolation, const std::vector<@TAP_TYPE@> &taps);
+
+  std::vector<@TAP_TYPE@>      d_new_taps;
+  bool                 d_updated;
+  std::vector<@FIR_TYPE@ *> d_firs;
+
+  /*!
+   * Construct a FIR filter with the given taps
+   */
+  @NAME@ (unsigned interpolation, const std::vector<@TAP_TYPE@> &taps);
+
+  void install_taps (const std::vector<@TAP_TYPE@> &taps);
+
+ public:
+  ~@NAME@ ();
+
+  void set_taps (const std::vector<@TAP_TYPE@> &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_interp_fir_filter_XXX.i.t b/gnuradio-core/src/lib/filter/gr_interp_fir_filter_XXX.i.t
new file mode 100644 (file)
index 0000000..d58c823
--- /dev/null
@@ -0,0 +1,41 @@
+/* -*- 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 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.
+ */
+
+/*
+ * WARNING: This file is automatically generated by generate_GrFIRfilterXXX.py
+ * Any changes made to this file will be overwritten.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,@BASE_NAME@)
+
+@SPTR_NAME@ gr_make_@BASE_NAME@ (int interpolation, const std::vector<@TAP_TYPE@> &taps);
+
+class @NAME@ : public gr_sync_interpolator
+{
+ private:
+  @NAME@ (int interpolation, const std::vector<@TAP_TYPE@> &taps);
+
+ public:
+  ~@NAME@ ();
+
+  void set_taps (const std::vector<@TAP_TYPE@> &taps);
+};
diff --git a/gnuradio-core/src/lib/filter/gr_rational_resampler_base_XXX.cc.t b/gnuradio-core/src/lib/filter/gr_rational_resampler_base_XXX.cc.t
new file mode 100644 (file)
index 0000000..a07b739
--- /dev/null
@@ -0,0 +1,172 @@
+/* -*- 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 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.
+ */
+
+/*
+ * WARNING: This file is automatically generated by
+ * generate_gr_rational_resampler_base_XXX.py Any changes made to this
+ * file will be overwritten.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <@NAME@.h>
+#include <@FIR_TYPE@.h>
+#include <gr_fir_util.h>
+#include <gr_io_signature.h>
+#include <stdexcept>
+#include <iostream>
+
+@SPTR_NAME@ 
+gr_make_@BASE_NAME@ (unsigned interpolation,
+                    unsigned decimation, 
+                    const std::vector<@TAP_TYPE@> &taps)
+{
+  return @SPTR_NAME@ (new @NAME@ (interpolation, decimation, taps));
+}
+
+@NAME@::@NAME@ (unsigned interpolation, unsigned decimation,
+               const std::vector<@TAP_TYPE@> &taps)
+  : gr_block ("@BASE_NAME@",
+             gr_make_io_signature (1, 1, sizeof (@I_TYPE@)),
+             gr_make_io_signature (1, 1, sizeof (@O_TYPE@))),
+    d_history(1),
+    d_interpolation(interpolation), d_decimation(decimation),
+    d_ctr(0), d_updated(false),
+    d_firs(interpolation)
+{
+  if (interpolation == 0)
+    throw std::out_of_range ("interpolation must be > 0");
+  if (decimation == 0)
+    throw std::out_of_range ("decimation must be > 0");
+
+  set_relative_rate (1.0 * interpolation / decimation);
+  set_output_multiple (1);
+
+  std::vector<@TAP_TYPE@>      dummy_taps;
+  
+  for (unsigned i = 0; i < interpolation; i++)
+    d_firs[i] = gr_fir_util::create_@FIR_TYPE@ (dummy_taps);
+
+  set_taps (taps);
+  install_taps (d_new_taps);
+}
+
+@NAME@::~@NAME@ ()
+{
+  int interp = interpolation();
+  for (int i = 0; i < interp; i++)
+    delete d_firs[i];
+}
+
+void
+@NAME@::set_taps (const std::vector<@TAP_TYPE@> &taps)
+{
+  d_new_taps = taps;
+  d_updated = true;
+
+  // round up length to a multiple of the interpolation factor
+  int n = taps.size () % interpolation ();
+  if (n > 0){
+    n = interpolation () - n;
+    while (n-- > 0)
+      d_new_taps.insert(d_new_taps.begin(), 0);
+  }
+
+  assert (d_new_taps.size () % interpolation () == 0);
+}
+
+
+void
+@NAME@::install_taps (const std::vector<@TAP_TYPE@> &taps)
+{
+  int nfilters = interpolation ();
+  int nt = taps.size () / nfilters;
+
+  assert (nt * nfilters == (int) taps.size ());
+
+  std::vector< std::vector <@TAP_TYPE@> > xtaps (nfilters);
+
+  for (int n = 0; n < nfilters; n++)
+    xtaps[n].resize (nt);  
+
+  for (int i = 0; i < (int) taps.size(); i++)
+    xtaps[i % nfilters][i / nfilters] = taps[i];
+
+  for (int n = 0; n < nfilters; n++)
+    d_firs[n]->set_taps (xtaps[n]);
+  
+  set_history (nt);
+  d_updated = false;
+
+#if 0
+  for (int i = 0; i < nfilters; i++){
+    std::cout << "filter[" << i << "] = ";
+    for (int j = 0; j < nt; j++)
+      std::cout << xtaps[i][j] << " ";
+
+    std::cout << "\n";
+  }
+#endif
+
+}
+
+void
+@NAME@::forecast (int noutput_items, gr_vector_int &ninput_items_required)
+{
+  int nreqd = std::max((unsigned)1, (int)((double) (noutput_items+1) * decimation() / interpolation()) + history() - 1);
+  unsigned ninputs = ninput_items_required.size ();
+  for (unsigned i = 0; i < ninputs; i++)
+    ninput_items_required[i] = nreqd;
+}
+
+int
+@NAME@::general_work (int noutput_items,
+                     gr_vector_int &ninput_items,
+                     gr_vector_const_void_star &input_items,
+                     gr_vector_void_star &output_items)
+{
+  const @I_TYPE@ *in = (const @I_TYPE@ *) input_items[0];
+  @O_TYPE@ *out = (@O_TYPE@ *) output_items[0];
+
+  if (d_updated) {
+    install_taps (d_new_taps);
+    return 0;          // history requirement may have increased.
+  }
+
+  unsigned int ctr = d_ctr;
+
+  int i = 0;
+  while (i < noutput_items){
+    out[i++] = d_firs[ctr]->filter(in);
+    ctr += decimation();
+    while (ctr >= interpolation()){
+      ctr -= interpolation();
+      in++;
+    }
+  }
+
+  d_ctr = ctr;
+  consume_each(in - (@I_TYPE@ *) input_items[0]);
+  return i;
+}
diff --git a/gnuradio-core/src/lib/filter/gr_rational_resampler_base_XXX.h.t b/gnuradio-core/src/lib/filter/gr_rational_resampler_base_XXX.h.t
new file mode 100644 (file)
index 0000000..0117269
--- /dev/null
@@ -0,0 +1,87 @@
+/* -*- 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 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.
+ */
+
+/*
+ * WARNING: This file is automatically generated by
+ * generate_gr_rational_resampler_base_XXX.py Any changes made to this
+ * file will be overwritten.
+ */
+
+#ifndef @GUARD_NAME@
+#define        @GUARD_NAME@
+
+#include <gr_block.h>
+
+class @NAME@;
+typedef boost::shared_ptr<@NAME@> @SPTR_NAME@;
+@SPTR_NAME@
+gr_make_@BASE_NAME@ (unsigned interpolation,
+                    unsigned decimation,
+                    const std::vector<@TAP_TYPE@> &taps);
+
+class @FIR_TYPE@;
+
+/*!
+ * \brief Rational Resampling Polyphase FIR filter with @I_TYPE@ input, @O_TYPE@ output and @TAP_TYPE@ taps
+ * \ingroup filter
+ */
+class @NAME@ : public gr_block
+{
+ private:
+  unsigned                     d_history;
+  unsigned                     d_interpolation, d_decimation;
+  unsigned                     d_ctr;
+  std::vector<@TAP_TYPE@>      d_new_taps;
+  bool                         d_updated;
+  std::vector<@FIR_TYPE@ *> d_firs;
+
+  friend @SPTR_NAME@ 
+  gr_make_@BASE_NAME@ (unsigned interpolation, unsigned decimation, const std::vector<@TAP_TYPE@> &taps);
+
+
+  /*!
+   * Construct a FIR filter with the given taps
+   */
+  @NAME@ (unsigned interpolation, unsigned decimation,
+         const std::vector<@TAP_TYPE@> &taps);
+
+  void install_taps (const std::vector<@TAP_TYPE@> &taps);
+
+ public:
+  ~@NAME@ ();
+  unsigned history () const { return d_history; }
+  void  set_history (unsigned history) { d_history = history; }
+
+  unsigned interpolation() const { return d_interpolation; }
+  unsigned decimation() const { return d_decimation; }
+
+  void set_taps (const std::vector<@TAP_TYPE@> &taps);
+
+  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);
+};
+
+#endif
diff --git a/gnuradio-core/src/lib/filter/gr_rational_resampler_base_XXX.i.t b/gnuradio-core/src/lib/filter/gr_rational_resampler_base_XXX.i.t
new file mode 100644 (file)
index 0000000..2411d03
--- /dev/null
@@ -0,0 +1,42 @@
+/* -*- 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 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.
+ */
+
+/*
+ * WARNING: This file is automatically generated by
+ * generate_gr_rational_resampler_base_XXX.py Any changes made to this
+ * file will be overwritten.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,@BASE_NAME@);
+
+@SPTR_NAME@ gr_make_@BASE_NAME@ (int interpolation, int decimation, const std::vector<@TAP_TYPE@> &taps);
+
+class @NAME@ : public gr_block
+{
+ private:
+  @NAME@ (int interpolation, int decimation, const std::vector<@TAP_TYPE@> &taps);
+
+ public:
+  ~@NAME@ ();
+
+  void set_taps (const std::vector<@TAP_TYPE@> &taps);
+};
diff --git a/gnuradio-core/src/lib/filter/gr_rotator.h b/gnuradio-core/src/lib/filter/gr_rotator.h
new file mode 100644 (file)
index 0000000..930b1cc
--- /dev/null
@@ -0,0 +1,50 @@
+/* -*- 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 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.
+ */
+
+#ifndef _GR_ROTATOR_H_
+#define _GR_ROTATOR_H_
+
+#include <gr_complex.h>
+
+class gr_rotator {
+  gr_complex   d_phase;
+  gr_complex   d_phase_incr;
+
+ public:
+  gr_rotator () : d_phase (1), d_phase_incr (0) { }
+
+  void set_phase (gr_complex phase)     { d_phase = phase; }
+  void set_phase_incr (gr_complex incr) { d_phase_incr = incr; }
+
+  gr_complex rotate (gr_complex in){
+    d_phase *= d_phase_incr;   // incr our phase (complex mult == add phases)
+
+    d_phase /= abs(d_phase);   // ensure multiplication is rotation
+                               // FIXME.  This is expensive.  Maybe workaround using
+                               // double precision complex???
+
+    return in * d_phase;       // rotate in by phase
+  }
+
+};
+
+#endif /* _GR_ROTATOR_H_ */
diff --git a/gnuradio-core/src/lib/filter/gr_sincos.c b/gnuradio-core/src/lib/filter/gr_sincos.c
new file mode 100644 (file)
index 0000000..44c8574
--- /dev/null
@@ -0,0 +1,81 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#define _GNU_SOURCE            // ask for GNU extensions if available
+
+#include <gr_sincos.h>
+#include <math.h>
+
+// ----------------------------------------------------------------
+
+#if defined (HAVE_SINCOS)
+
+void
+gr_sincos (double x, double *sinx, double *cosx)
+{
+  sincos (x, sinx, cosx);
+}
+
+#else
+
+void
+gr_sincos (double x, double *sinx, double *cosx)
+{
+  *sinx = sin (x);
+  *cosx = cos (x);
+}
+
+#endif
+
+// ----------------------------------------------------------------
+
+#if defined (HAVE_SINCOSF)
+
+void
+gr_sincosf (float x, float *sinx, float *cosx)
+{
+  sincosf (x, sinx, cosx);
+}
+
+#elif defined (HAVE_SINF) && defined (HAVE_COSF)
+
+void
+gr_sincosf (float x, float *sinx, float *cosx)
+{
+  *sinx = sinf (x);
+  *cosx = cosf (x);
+}
+
+#else
+
+void
+gr_sincosf (float x, float *sinx, float *cosx)
+{
+  *sinx = sin (x);
+  *cosx = cos (x);
+}
+
+#endif
diff --git a/gnuradio-core/src/lib/filter/gr_sincos.h b/gnuradio-core/src/lib/filter/gr_sincos.h
new file mode 100644 (file)
index 0000000..2e8f3ff
--- /dev/null
@@ -0,0 +1,39 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002,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.
+ */
+
+#ifndef INCLUDED_GR_SINCOS_H
+#define INCLUDED_GR_SINCOS_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+  
+// compute sine and cosine at the same time
+
+void gr_sincos (double x, double *sin, double *cos);
+void gr_sincosf (float x, float *sin, float *cos);
+
+#ifdef __cplusplus
+};
+#endif
+
+#endif /* INCLUDED_GR_SINCOS_H */
diff --git a/gnuradio-core/src/lib/filter/gr_single_pole_avg.h b/gnuradio-core/src/lib/filter/gr_single_pole_avg.h
new file mode 100644 (file)
index 0000000..adf871a
--- /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 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.
+ */
+#ifndef _GR_SINGLE_POLE_AVG_H_
+#define _GR_SINGLE_POLE_AVG_H_
+
+#include <stdexcept>
+
+/*!
+ * \brief class template for single pole moving average filter
+ */
+template<class o_type, class i_type, class tap_type> 
+class gr_single_pole_avg {
+public:
+  /*!
+   * \brief construct new single pole moving average filter with given alpha
+   *
+   * computes y(i) = alpha * x(i) - (1-alpha) * y(i-1)
+   */
+  gr_single_pole_avg (tap_type alpha = 1.0)
+  {
+    d_prev_input = 0;
+    set_taps (alpha);
+  }
+
+  /*!
+   * \brief compute a single output value.
+   * \returns the filtered input value.
+   */
+  o_type filter (const i_type input);
+
+  /*!
+   * \brief compute an array of N output values.
+   * \p input must have n valid entries.
+   */
+  void filterN (o_type output[], const i_type input[], unsigned long n);
+
+  /*!
+   * \brief install \p alpha as the current taps.
+   */
+  void set_taps (tap_type alpha)
+  { 
+    if (alpha < 0 || alpha > 1)
+      throw std::out_of_range ("Alpha must be in [0, 1]\n");
+
+    d_alpha = alpha;
+    d_one_minus_alpha = 1.0 - alpha;
+  }
+
+  //! reset state to zero
+  void reset ()
+  {
+    d_prev_input = 0;
+  }
+
+  tap_type prev_input () { return d_prev_input; }
+    
+protected:
+  tap_type     d_alpha;
+  tap_type     d_one_minus_alpha;
+  tap_type     d_prev_input;
+};
+
+
+//
+// general case.  We may want to specialize this
+//
+template<class o_type, class i_type, class tap_type> 
+o_type
+gr_single_pole_avg<o_type, i_type, tap_type>::filter (const i_type input)
+{
+  tap_type     output;
+
+  output = d_alpha * input - d_one_minus_alpha * d_prev_input;
+  d_prev_input = input;
+
+  return (o_type) output;
+}
+
+
+template<class o_type, class i_type, class tap_type> 
+void 
+gr_single_pole_avg<o_type, i_type, tap_type>::filterN (o_type output[],
+                                                      const i_type input[],
+                                                      unsigned long n)
+{
+  for (unsigned i = 0; i < n; i++)
+    output[i] = filter (input[i]);
+}
+
+
+#endif /* _GR_SINGLE_POLE_AVG_H_ */
diff --git a/gnuradio-core/src/lib/filter/gr_single_pole_avg_filter_ff.cc b/gnuradio-core/src/lib/filter/gr_single_pole_avg_filter_ff.cc
new file mode 100644 (file)
index 0000000..99f8b11
--- /dev/null
@@ -0,0 +1,81 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_single_pole_avg_filter_ff.h>
+#include <gr_io_signature.h>
+#include <stdio.h>
+
+
+gr_single_pole_avg_filter_ff_sptr 
+gr_make_single_pole_avg_filter_ff (double alpha, unsigned int vlen)
+{
+  return gr_single_pole_avg_filter_ff_sptr(new gr_single_pole_avg_filter_ff(alpha, vlen));
+}
+
+gr_single_pole_avg_filter_ff::gr_single_pole_avg_filter_ff (
+                                   double alpha, unsigned int vlen)
+  : gr_sync_block ("single_pole_avg_filter_ff",
+                  gr_make_io_signature (1, 1, sizeof (float) * vlen),
+                  gr_make_io_signature (1, 1, sizeof (float) * vlen)),
+    d_vlen(vlen), d_rec(vlen)
+{
+  set_taps(alpha);
+}
+
+gr_single_pole_avg_filter_ff::~gr_single_pole_avg_filter_ff ()
+{
+  // nop
+}
+
+void
+gr_single_pole_avg_filter_ff::set_taps (double alpha)
+{
+  for (unsigned int i = 0; i < d_vlen; i++)
+    d_rec[i].set_taps(alpha);
+}
+
+int
+gr_single_pole_avg_filter_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];
+  unsigned int vlen = d_vlen;
+
+  if (d_vlen == 1){
+    for (int i = 0; i < noutput_items; i++)
+      out[i] = d_rec[0].filter (in[i]);
+  }
+  else {
+    for (int i = 0; i < noutput_items; i++){
+      for (unsigned int j = 0; j < vlen; j++){
+       *out++ = d_rec[j].filter (*in++);
+      }
+    }
+  }
+  return noutput_items;
+};
diff --git a/gnuradio-core/src/lib/filter/gr_single_pole_avg_filter_ff.h b/gnuradio-core/src/lib/filter/gr_single_pole_avg_filter_ff.h
new file mode 100644 (file)
index 0000000..cc3640f
--- /dev/null
@@ -0,0 +1,76 @@
+/* -*- c++ -*- */
+/*
+ * 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 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.
+ */
+
+#ifndef INCLUDED_GR_SINGLE_POLE_REC_FILTER_FF_H
+#define        INCLUDED_GR_SINGLE_POLE_REC_FILTER_FF_H
+
+#include <gr_sync_block.h>
+#include <gr_single_pole_avg.h>
+#include <stdexcept>
+
+class gr_single_pole_avg_filter_ff;
+typedef boost::shared_ptr<gr_single_pole_avg_filter_ff> gr_single_pole_avg_filter_ff_sptr;
+
+gr_single_pole_avg_filter_ff_sptr 
+gr_make_single_pole_avg_filter_ff (double alpha, unsigned int vlen=1);
+
+/*!
+ * \brief  single pole moving average filter with float input, float output
+ * \ingroup filter
+ *
+ * The input and output satisfy a difference equation of the form
+
+ \f[
+ y[n] - (1-alpha) y[n-1] = alpha x[n]
+ \f]
+
+ * with the corresponding rational system function
+
+ \f[
+ H(z) = \frac{alpha}{1 - (1-alpha) z^{-1}}
+ \f]
+
+ * Note that some texts define the system function with a + in the denominator.
+ * If you're using that convention, you'll need to negate the feedback tap.
+ */
+class gr_single_pole_avg_filter_ff : public gr_sync_block
+{
+ private:
+  friend gr_single_pole_avg_filter_ff_sptr 
+  gr_make_single_pole_avg_filter_ff (double alpha, unsigned int vlen);
+
+  unsigned int                                         d_vlen;
+  std::vector<gr_single_pole_avg<float,float,double> > d_rec;
+
+  gr_single_pole_avg_filter_ff (double alpha, unsigned int vlen);
+
+ public:
+  ~gr_single_pole_avg_filter_ff ();
+
+  void set_taps (double alpha);
+
+  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_single_pole_avg_filter_ff.i b/gnuradio-core/src/lib/filter/gr_single_pole_avg_filter_ff.i
new file mode 100644 (file)
index 0000000..f0ffe6c
--- /dev/null
@@ -0,0 +1,34 @@
+/* -*- 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 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.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,single_pole_avg_filter_ff);
+
+gr_single_pole_avg_filter_ff_sptr 
+gr_make_single_pole_avg_filter_ff (double alpha, unsigned int vlen=1);
+
+class gr_single_pole_avg_filter_ff : public gr_sync_block
+{
+ public:
+  ~gr_single_pole_avg_filter_ff ();
+
+  void set_taps (double alpha);
+};
diff --git a/gnuradio-core/src/lib/filter/gr_single_pole_iir.h b/gnuradio-core/src/lib/filter/gr_single_pole_iir.h
new file mode 100644 (file)
index 0000000..c1d3f74
--- /dev/null
@@ -0,0 +1,190 @@
+/* -*- 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 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.
+ */
+#ifndef _GR_SINGLE_POLE_IIR_H_
+#define _GR_SINGLE_POLE_IIR_H_
+
+#include <stdexcept>
+#include <gr_complex.h>
+/*!
+ * \brief class template for single pole IIR filter
+ */
+template<class o_type, class i_type, class tap_type> 
+class gr_single_pole_iir {
+public:
+  /*!
+   * \brief construct new single pole IIR with given alpha
+   *
+   * computes y(i) = (1-alpha) * y(i-1) + alpha * x(i)
+   */
+  gr_single_pole_iir (tap_type alpha = 1.0)
+  {
+    d_prev_output = 0;
+    set_taps (alpha);
+  }
+
+  /*!
+   * \brief compute a single output value.
+   * \returns the filtered input value.
+   */
+  o_type filter (const i_type input);
+
+  /*!
+   * \brief compute an array of N output values.
+   * \p input must have n valid entries.
+   */
+  void filterN (o_type output[], const i_type input[], unsigned long n);
+
+  /*!
+   * \brief install \p alpha as the current taps.
+   */
+  void set_taps (tap_type alpha)
+  { 
+    if (alpha < 0 || alpha > 1)
+      throw std::out_of_range ("Alpha must be in [0, 1]\n");
+
+    d_alpha = alpha;
+    d_one_minus_alpha = 1.0 - alpha;
+  }
+
+  //! reset state to zero
+  void reset ()
+  {
+    d_prev_output = 0;
+  }
+
+  tap_type prev_output () { return d_prev_output; }
+    
+protected:
+  tap_type     d_alpha;
+  tap_type     d_one_minus_alpha;
+  tap_type     d_prev_output;
+};
+
+
+//
+// general case.  We may want to specialize this
+//
+template<class o_type, class i_type, class tap_type> 
+o_type
+gr_single_pole_iir<o_type, i_type, tap_type>::filter (const i_type input)
+{
+  tap_type     output;
+
+  output = d_alpha * input + d_one_minus_alpha * d_prev_output;
+  d_prev_output = output;
+
+  return (o_type) output;
+}
+
+
+template<class o_type, class i_type, class tap_type> 
+void 
+gr_single_pole_iir<o_type, i_type, tap_type>::filterN (o_type output[],
+                                                      const i_type input[],
+                                                      unsigned long n)
+{
+  for (unsigned i = 0; i < n; i++)
+    output[i] = filter (input[i]);
+}
+
+
+//
+// Specialized case for gr_complex output and double taps
+// We need to have a gr_complexd type for the calculations and prev_output variable (in stead of double)
+
+template<class i_type> 
+class gr_single_pole_iir<gr_complex, i_type, double>  {
+public:
+  /*!
+   * \brief construct new single pole IIR with given alpha
+   *
+   * computes y(i) = (1-alpha) * y(i-1) + alpha * x(i)
+   */
+  gr_single_pole_iir (double alpha = 1.0)
+  {
+    d_prev_output = 0;
+    set_taps (alpha);
+  }
+
+  /*!
+   * \brief compute a single output value.
+   * \returns the filtered input value.
+   */
+ gr_complex filter (const i_type input);
+
+  /*!
+   * \brief compute an array of N output values.
+   * \p input must have n valid entries.
+   */
+  void filterN (gr_complex output[], const i_type input[], unsigned long n);
+
+  /*!
+   * \brief install \p alpha as the current taps.
+   */
+  void set_taps (double alpha)
+  { 
+    if (alpha < 0 || alpha > 1)
+      throw std::out_of_range ("Alpha must be in [0, 1]\n");
+
+    d_alpha = alpha;
+    d_one_minus_alpha = 1.0 - alpha;
+  }
+
+  //! reset state to zero
+  void reset ()
+  {
+    d_prev_output = 0;
+  }
+
+  gr_complexd prev_output () { return d_prev_output; }
+    
+protected:
+  double       d_alpha;
+  double       d_one_minus_alpha;
+  gr_complexd  d_prev_output;
+};
+
+template< class i_type> 
+gr_complex
+gr_single_pole_iir<gr_complex, i_type, double>::filter (const i_type input)
+{
+  gr_complexd  output;
+
+  output = d_alpha * (gr_complexd)input + d_one_minus_alpha * d_prev_output;
+  d_prev_output = output;
+
+  return (gr_complex) output;
+}
+
+//Do we need to specialize this, although it is the same as the general case?
+
+template<class i_type> 
+void 
+gr_single_pole_iir<gr_complex, i_type, double>::filterN (gr_complex output[],
+                                                      const i_type input[],
+                                                      unsigned long n)
+{
+  for (unsigned i = 0; i < n; i++)
+    output[i] = filter (input[i]);
+}
+
+#endif /* _GR_SINGLE_POLE_IIR_H_ */
diff --git a/gnuradio-core/src/lib/filter/gr_single_pole_iir_filter_cc.cc b/gnuradio-core/src/lib/filter/gr_single_pole_iir_filter_cc.cc
new file mode 100644 (file)
index 0000000..0218452
--- /dev/null
@@ -0,0 +1,81 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_single_pole_iir_filter_cc.h>
+#include <gr_io_signature.h>
+#include <stdio.h>
+
+
+gr_single_pole_iir_filter_cc_sptr 
+gr_make_single_pole_iir_filter_cc (double alpha, unsigned int vlen)
+{
+  return gr_single_pole_iir_filter_cc_sptr(new gr_single_pole_iir_filter_cc(alpha, vlen));
+}
+
+gr_single_pole_iir_filter_cc::gr_single_pole_iir_filter_cc (
+                                   double alpha, unsigned int vlen)
+  : gr_sync_block ("single_pole_iir_filter_cc",
+                  gr_make_io_signature (1, 1, sizeof (gr_complex) * vlen),
+                  gr_make_io_signature (1, 1, sizeof (gr_complex) * vlen)),
+    d_vlen(vlen), d_iir(vlen)
+{
+  set_taps(alpha);
+}
+
+gr_single_pole_iir_filter_cc::~gr_single_pole_iir_filter_cc ()
+{
+  // nop
+}
+
+void
+gr_single_pole_iir_filter_cc::set_taps (double alpha)
+{
+  for (unsigned int i = 0; i < d_vlen; i++)
+    d_iir[i].set_taps(alpha);
+}
+
+int
+gr_single_pole_iir_filter_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];
+  unsigned int vlen = d_vlen;
+
+  if (d_vlen == 1){
+    for (int i = 0; i < noutput_items; i++)
+      out[i] = d_iir[0].filter (in[i]);
+  }
+  else {
+    for (int i = 0; i < noutput_items; i++){
+      for (unsigned int j = 0; j < vlen; j++){
+       *out++ = d_iir[j].filter (*in++);
+      }
+    }
+  }
+  return noutput_items;
+};
diff --git a/gnuradio-core/src/lib/filter/gr_single_pole_iir_filter_cc.h b/gnuradio-core/src/lib/filter/gr_single_pole_iir_filter_cc.h
new file mode 100644 (file)
index 0000000..38caa61
--- /dev/null
@@ -0,0 +1,77 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2005,2006 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 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.
+ */
+
+#ifndef INCLUDED_GR_SINGLE_POLE_IIR_FILTER_CC_H
+#define        INCLUDED_GR_SINGLE_POLE_IIR_FILTER_CC_H
+
+#include <gr_sync_block.h>
+#include <gr_single_pole_iir.h>
+#include <gr_complex.h>
+#include <stdexcept>
+
+class gr_single_pole_iir_filter_cc;
+typedef boost::shared_ptr<gr_single_pole_iir_filter_cc> gr_single_pole_iir_filter_cc_sptr;
+
+gr_single_pole_iir_filter_cc_sptr 
+gr_make_single_pole_iir_filter_cc (double alpha, unsigned int vlen=1);
+
+/*!
+ * \brief  single pole IIR filter with complex input, complex output
+ * \ingroup filter
+ *
+ * The input and output satisfy a difference equation of the form
+
+ \f[
+ y[n] - (1-alpha) y[n-1] = alpha x[n]
+ \f]
+
+ * with the corresponding rational system function
+
+ \f[
+ H(z) = \frac{alpha}{1 - (1-alpha) z^{-1}}
+ \f]
+
+ * Note that some texts define the system function with a + in the denominator.
+ * If you're using that convention, you'll need to negate the feedback tap.
+ */
+class gr_single_pole_iir_filter_cc : public gr_sync_block
+{
+ private:
+  friend gr_single_pole_iir_filter_cc_sptr 
+  gr_make_single_pole_iir_filter_cc (double alpha, unsigned int vlen);
+
+  unsigned int                                         d_vlen;
+  std::vector<gr_single_pole_iir<gr_complex,gr_complex,double> >       d_iir;
+
+  gr_single_pole_iir_filter_cc (double alpha, unsigned int vlen);
+
+ public:
+  ~gr_single_pole_iir_filter_cc ();
+
+  void set_taps (double alpha);
+
+  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_single_pole_iir_filter_cc.i b/gnuradio-core/src/lib/filter/gr_single_pole_iir_filter_cc.i
new file mode 100644 (file)
index 0000000..683bbe9
--- /dev/null
@@ -0,0 +1,34 @@
+/* -*- 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 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.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,single_pole_iir_filter_cc);
+
+gr_single_pole_iir_filter_cc_sptr 
+gr_make_single_pole_iir_filter_cc (double alpha, unsigned int vlen=1);
+
+class gr_single_pole_iir_filter_cc : public gr_sync_block
+{
+ public:
+  ~gr_single_pole_iir_filter_cc ();
+
+  void set_taps (double alpha);
+};
diff --git a/gnuradio-core/src/lib/filter/gr_single_pole_iir_filter_ff.cc b/gnuradio-core/src/lib/filter/gr_single_pole_iir_filter_ff.cc
new file mode 100644 (file)
index 0000000..03e2748
--- /dev/null
@@ -0,0 +1,81 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_single_pole_iir_filter_ff.h>
+#include <gr_io_signature.h>
+#include <stdio.h>
+
+
+gr_single_pole_iir_filter_ff_sptr 
+gr_make_single_pole_iir_filter_ff (double alpha, unsigned int vlen)
+{
+  return gr_single_pole_iir_filter_ff_sptr(new gr_single_pole_iir_filter_ff(alpha, vlen));
+}
+
+gr_single_pole_iir_filter_ff::gr_single_pole_iir_filter_ff (
+                                   double alpha, unsigned int vlen)
+  : gr_sync_block ("single_pole_iir_filter_ff",
+                  gr_make_io_signature (1, 1, sizeof (float) * vlen),
+                  gr_make_io_signature (1, 1, sizeof (float) * vlen)),
+    d_vlen(vlen), d_iir(vlen)
+{
+  set_taps(alpha);
+}
+
+gr_single_pole_iir_filter_ff::~gr_single_pole_iir_filter_ff ()
+{
+  // nop
+}
+
+void
+gr_single_pole_iir_filter_ff::set_taps (double alpha)
+{
+  for (unsigned int i = 0; i < d_vlen; i++)
+    d_iir[i].set_taps(alpha);
+}
+
+int
+gr_single_pole_iir_filter_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];
+  unsigned int vlen = d_vlen;
+
+  if (d_vlen == 1){
+    for (int i = 0; i < noutput_items; i++)
+      out[i] = d_iir[0].filter (in[i]);
+  }
+  else {
+    for (int i = 0; i < noutput_items; i++){
+      for (unsigned int j = 0; j < vlen; j++){
+       *out++ = d_iir[j].filter (*in++);
+      }
+    }
+  }
+  return noutput_items;
+};
diff --git a/gnuradio-core/src/lib/filter/gr_single_pole_iir_filter_ff.h b/gnuradio-core/src/lib/filter/gr_single_pole_iir_filter_ff.h
new file mode 100644 (file)
index 0000000..ff6bae3
--- /dev/null
@@ -0,0 +1,76 @@
+/* -*- c++ -*- */
+/*
+ * 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 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.
+ */
+
+#ifndef INCLUDED_GR_SINGLE_POLE_IIR_FILTER_FF_H
+#define        INCLUDED_GR_SINGLE_POLE_IIR_FILTER_FF_H
+
+#include <gr_sync_block.h>
+#include <gr_single_pole_iir.h>
+#include <stdexcept>
+
+class gr_single_pole_iir_filter_ff;
+typedef boost::shared_ptr<gr_single_pole_iir_filter_ff> gr_single_pole_iir_filter_ff_sptr;
+
+gr_single_pole_iir_filter_ff_sptr 
+gr_make_single_pole_iir_filter_ff (double alpha, unsigned int vlen=1);
+
+/*!
+ * \brief  single pole IIR filter with float input, float output
+ * \ingroup filter
+ *
+ * The input and output satisfy a difference equation of the form
+
+ \f[
+ y[n] - (1-alpha) y[n-1] = alpha x[n]
+ \f]
+
+ * with the corresponding rational system function
+
+ \f[
+ H(z) = \frac{alpha}{1 - (1-alpha) z^{-1}}
+ \f]
+
+ * Note that some texts define the system function with a + in the denominator.
+ * If you're using that convention, you'll need to negate the feedback tap.
+ */
+class gr_single_pole_iir_filter_ff : public gr_sync_block
+{
+ private:
+  friend gr_single_pole_iir_filter_ff_sptr 
+  gr_make_single_pole_iir_filter_ff (double alpha, unsigned int vlen);
+
+  unsigned int                                         d_vlen;
+  std::vector<gr_single_pole_iir<float,float,double> > d_iir;
+
+  gr_single_pole_iir_filter_ff (double alpha, unsigned int vlen);
+
+ public:
+  ~gr_single_pole_iir_filter_ff ();
+
+  void set_taps (double alpha);
+
+  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_single_pole_iir_filter_ff.i b/gnuradio-core/src/lib/filter/gr_single_pole_iir_filter_ff.i
new file mode 100644 (file)
index 0000000..6680c84
--- /dev/null
@@ -0,0 +1,34 @@
+/* -*- 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 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.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,single_pole_iir_filter_ff);
+
+gr_single_pole_iir_filter_ff_sptr 
+gr_make_single_pole_iir_filter_ff (double alpha, unsigned int vlen=1);
+
+class gr_single_pole_iir_filter_ff : public gr_sync_block
+{
+ public:
+  ~gr_single_pole_iir_filter_ff ();
+
+  void set_taps (double alpha);
+};
diff --git a/gnuradio-core/src/lib/filter/gr_single_pole_rec.h b/gnuradio-core/src/lib/filter/gr_single_pole_rec.h
new file mode 100644 (file)
index 0000000..f443678
--- /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 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.
+ */
+#ifndef _GR_SINGLE_POLE_REC_H_
+#define _GR_SINGLE_POLE_REC_H_
+
+#include <stdexcept>
+
+/*!
+ * \brief class template for single pole recursive filter
+ */
+template<class o_type, class i_type, class tap_type> 
+class gr_single_pole_rec {
+public:
+  /*!
+   * \brief construct new single pole IIR with given alpha
+   *
+   * computes y(i) = alpha * x(i) - (1-alpha) * y(i-1)
+   */
+  gr_single_pole_rec (tap_type alpha = 1.0)
+  {
+    d_prev_output = 0;
+    set_taps (alpha);
+  }
+
+  /*!
+   * \brief compute a single output value.
+   * \returns the filtered input value.
+   */
+  o_type filter (const i_type input);
+
+  /*!
+   * \brief compute an array of N output values.
+   * \p input must have n valid entries.
+   */
+  void filterN (o_type output[], const i_type input[], unsigned long n);
+
+  /*!
+   * \brief install \p alpha as the current taps.
+   */
+  void set_taps (tap_type alpha)
+  { 
+    if (alpha < 0 || alpha > 1)
+      throw std::out_of_range ("Alpha must be in [0, 1]\n");
+
+    d_alpha = alpha;
+    d_one_minus_alpha = 1.0 - alpha;
+  }
+
+  //! reset state to pole
+  void reset ()
+  {
+    d_prev_output = 0;
+  }
+
+  tap_type prev_output () { return d_prev_output; }
+    
+protected:
+  tap_type     d_alpha;
+  tap_type     d_one_minus_alpha;
+  tap_type     d_prev_output;
+};
+
+
+//
+// general case.  We may want to specialize this
+//
+template<class o_type, class i_type, class tap_type> 
+o_type
+gr_single_pole_rec<o_type, i_type, tap_type>::filter (const i_type input)
+{
+  tap_type     output;
+
+  output = d_alpha * input + d_one_minus_alpha * d_prev_output;
+  d_prev_output = output;
+
+  return (o_type) output;
+}
+
+
+template<class o_type, class i_type, class tap_type> 
+void 
+gr_single_pole_rec<o_type, i_type, tap_type>::filterN (o_type output[],
+                                                      const i_type input[],
+                                                      unsigned long n)
+{
+  for (unsigned i = 0; i < n; i++)
+    output[i] = filter (input[i]);
+}
+
+
+#endif /* _GR_SINGLE_POLE_REC_H_ */
diff --git a/gnuradio-core/src/lib/filter/gr_single_pole_rec_filter_ff.cc b/gnuradio-core/src/lib/filter/gr_single_pole_rec_filter_ff.cc
new file mode 100644 (file)
index 0000000..7c0a9aa
--- /dev/null
@@ -0,0 +1,81 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_single_pole_rec_filter_ff.h>
+#include <gr_io_signature.h>
+#include <stdio.h>
+
+
+gr_single_pole_rec_filter_ff_sptr 
+gr_make_single_pole_rec_filter_ff (double alpha, unsigned int vlen)
+{
+  return gr_single_pole_rec_filter_ff_sptr(new gr_single_pole_rec_filter_ff(alpha, vlen));
+}
+
+gr_single_pole_rec_filter_ff::gr_single_pole_rec_filter_ff (
+                                   double alpha, unsigned int vlen)
+  : gr_sync_block ("single_pole_rec_filter_ff",
+                  gr_make_io_signature (1, 1, sizeof (float) * vlen),
+                  gr_make_io_signature (1, 1, sizeof (float) * vlen)),
+    d_vlen(vlen), d_rec(vlen)
+{
+  set_taps(alpha);
+}
+
+gr_single_pole_rec_filter_ff::~gr_single_pole_rec_filter_ff ()
+{
+  // nop
+}
+
+void
+gr_single_pole_rec_filter_ff::set_taps (double alpha)
+{
+  for (unsigned int i = 0; i < d_vlen; i++)
+    d_rec[i].set_taps(alpha);
+}
+
+int
+gr_single_pole_rec_filter_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];
+  unsigned int vlen = d_vlen;
+
+  if (d_vlen == 1){
+    for (int i = 0; i < noutput_items; i++)
+      out[i] = d_rec[0].filter (in[i]);
+  }
+  else {
+    for (int i = 0; i < noutput_items; i++){
+      for (unsigned int j = 0; j < vlen; j++){
+       *out++ = d_rec[j].filter (*in++);
+      }
+    }
+  }
+  return noutput_items;
+};
diff --git a/gnuradio-core/src/lib/filter/gr_single_pole_rec_filter_ff.h b/gnuradio-core/src/lib/filter/gr_single_pole_rec_filter_ff.h
new file mode 100644 (file)
index 0000000..d1861e7
--- /dev/null
@@ -0,0 +1,76 @@
+/* -*- c++ -*- */
+/*
+ * 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 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.
+ */
+
+#ifndef INCLUDED_GR_SINGLE_POLE_REC_FILTER_FF_H
+#define        INCLUDED_GR_SINGLE_POLE_REC_FILTER_FF_H
+
+#include <gr_sync_block.h>
+#include <gr_single_pole_rec.h>
+#include <stdexcept>
+
+class gr_single_pole_rec_filter_ff;
+typedef boost::shared_ptr<gr_single_pole_rec_filter_ff> gr_single_pole_rec_filter_ff_sptr;
+
+gr_single_pole_rec_filter_ff_sptr 
+gr_make_single_pole_rec_filter_ff (double alpha, unsigned int vlen=1);
+
+/*!
+ * \brief  single pole recursive filter with float input, float output
+ * \ingroup filter
+ *
+ * The input and output satisfy a difference equation of the form
+
+ \f[
+ y[n] - (1-alpha) y[n-1] = alpha x[n]
+ \f]
+
+ * with the corresponding rational system function
+
+ \f[
+ H(z) = \frac{alpha}{1 - (1-alpha) z^{-1}}
+ \f]
+
+ * Note that some texts define the system function with a + in the denominator.
+ * If you're using that convention, you'll need to negate the feedback tap.
+ */
+class gr_single_pole_rec_filter_ff : public gr_sync_block
+{
+ private:
+  friend gr_single_pole_rec_filter_ff_sptr 
+  gr_make_single_pole_rec_filter_ff (double alpha, unsigned int vlen);
+
+  unsigned int                                         d_vlen;
+  std::vector<gr_single_pole_rec<float,float,double> > d_rec;
+
+  gr_single_pole_rec_filter_ff (double alpha, unsigned int vlen);
+
+ public:
+  ~gr_single_pole_rec_filter_ff ();
+
+  void set_taps (double alpha);
+
+  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_single_pole_rec_filter_ff.i b/gnuradio-core/src/lib/filter/gr_single_pole_rec_filter_ff.i
new file mode 100644 (file)
index 0000000..06da737
--- /dev/null
@@ -0,0 +1,34 @@
+/* -*- 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 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.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,single_pole_rec_filter_ff);
+
+gr_single_pole_rec_filter_ff_sptr 
+gr_make_single_pole_rec_filter_ff (double alpha, unsigned int vlen=1);
+
+class gr_single_pole_rec_filter_ff : public gr_sync_block
+{
+ public:
+  ~gr_single_pole_rec_filter_ff ();
+
+  void set_taps (double alpha);
+};
diff --git a/gnuradio-core/src/lib/filter/gr_single_zero_avg.h b/gnuradio-core/src/lib/filter/gr_single_zero_avg.h
new file mode 100644 (file)
index 0000000..def340a
--- /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 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.
+ */
+#ifndef _GR_SINGLE_ZERO_AVG_H_
+#define _GR_SINGLE_ZERO_AVG_H_
+
+#include <stdexcept>
+
+/*!
+ * \brief class template for single zero moving average filter
+ */
+template<class o_type, class i_type, class tap_type> 
+class gr_single_zero_avg {
+public:
+  /*!
+   * \brief construct new single zero moving average filter with given alpha
+   *
+   * computes y(i) = alpha * x(i) + (1-alpha) * y(i-1)
+   */
+  gr_single_zero_avg (tap_type alpha = 1.0)
+  {
+    d_prev_input = 0;
+    set_taps (alpha);
+  }
+
+  /*!
+   * \brief compute a single output value.
+   * \returns the filtered input value.
+   */
+  o_type filter (const i_type input);
+
+  /*!
+   * \brief compute an array of N output values.
+   * \p input must have n valid entries.
+   */
+  void filterN (o_type output[], const i_type input[], unsigned long n);
+
+  /*!
+   * \brief install \p alpha as the current taps.
+   */
+  void set_taps (tap_type alpha)
+  { 
+    if (alpha < 0 || alpha > 1)
+      throw std::out_of_range ("Alpha must be in [0, 1]\n");
+
+    d_alpha = alpha;
+    d_one_minus_alpha = 1.0 - alpha;
+  }
+
+  //! reset state to zero
+  void reset ()
+  {
+    d_prev_input = 0;
+  }
+
+  tap_type prev_input () { return d_prev_input; }
+    
+protected:
+  tap_type     d_alpha;
+  tap_type     d_one_minus_alpha;
+  tap_type     d_prev_input;
+};
+
+
+//
+// general case.  We may want to specialize this
+//
+template<class o_type, class i_type, class tap_type> 
+o_type
+gr_single_zero_avg<o_type, i_type, tap_type>::filter (const i_type input)
+{
+  tap_type     output;
+
+  output = d_alpha * input + d_one_minus_alpha * d_prev_input;
+  d_prev_input = input;
+
+  return (o_type) output;
+}
+
+
+template<class o_type, class i_type, class tap_type> 
+void 
+gr_single_zero_avg<o_type, i_type, tap_type>::filterN (o_type output[],
+                                                      const i_type input[],
+                                                      unsigned long n)
+{
+  for (unsigned i = 0; i < n; i++)
+    output[i] = filter (input[i]);
+}
+
+
+#endif /* _GR_SINGLE_ZERO_AVG_H_ */
diff --git a/gnuradio-core/src/lib/filter/gr_single_zero_avg_filter_ff.cc b/gnuradio-core/src/lib/filter/gr_single_zero_avg_filter_ff.cc
new file mode 100644 (file)
index 0000000..62feb4c
--- /dev/null
@@ -0,0 +1,81 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_single_zero_avg_filter_ff.h>
+#include <gr_io_signature.h>
+#include <stdio.h>
+
+
+gr_single_zero_avg_filter_ff_sptr 
+gr_make_single_zero_avg_filter_ff (double alpha, unsigned int vlen)
+{
+  return gr_single_zero_avg_filter_ff_sptr(new gr_single_zero_avg_filter_ff(alpha, vlen));
+}
+
+gr_single_zero_avg_filter_ff::gr_single_zero_avg_filter_ff (
+                                   double alpha, unsigned int vlen)
+  : gr_sync_block ("single_zero_avg_filter_ff",
+                  gr_make_io_signature (1, 1, sizeof (float) * vlen),
+                  gr_make_io_signature (1, 1, sizeof (float) * vlen)),
+    d_vlen(vlen), d_rec(vlen)
+{
+  set_taps(alpha);
+}
+
+gr_single_zero_avg_filter_ff::~gr_single_zero_avg_filter_ff ()
+{
+  // nop
+}
+
+void
+gr_single_zero_avg_filter_ff::set_taps (double alpha)
+{
+  for (unsigned int i = 0; i < d_vlen; i++)
+    d_rec[i].set_taps(alpha);
+}
+
+int
+gr_single_zero_avg_filter_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];
+  unsigned int vlen = d_vlen;
+
+  if (d_vlen == 1){
+    for (int i = 0; i < noutput_items; i++)
+      out[i] = d_rec[0].filter (in[i]);
+  }
+  else {
+    for (int i = 0; i < noutput_items; i++){
+      for (unsigned int j = 0; j < vlen; j++){
+       *out++ = d_rec[j].filter (*in++);
+      }
+    }
+  }
+  return noutput_items;
+};
diff --git a/gnuradio-core/src/lib/filter/gr_single_zero_avg_filter_ff.h b/gnuradio-core/src/lib/filter/gr_single_zero_avg_filter_ff.h
new file mode 100644 (file)
index 0000000..4a283d3
--- /dev/null
@@ -0,0 +1,76 @@
+/* -*- c++ -*- */
+/*
+ * 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 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.
+ */
+
+#ifndef INCLUDED_GR_SINGLE_ZERO_REC_FILTER_FF_H
+#define        INCLUDED_GR_SINGLE_ZERO_REC_FILTER_FF_H
+
+#include <gr_sync_block.h>
+#include <gr_single_zero_avg.h>
+#include <stdexcept>
+
+class gr_single_zero_avg_filter_ff;
+typedef boost::shared_ptr<gr_single_zero_avg_filter_ff> gr_single_zero_avg_filter_ff_sptr;
+
+gr_single_zero_avg_filter_ff_sptr 
+gr_make_single_zero_avg_filter_ff (double alpha, unsigned int vlen=1);
+
+/*!
+ * \brief  single zero moving average filter with float input, float output
+ * \ingroup filter
+ *
+ * The input and output satisfy a difference equation of the form
+
+ \f[
+ y[n] - (1-alpha) y[n-1] = alpha x[n]
+ \f]
+
+ * with the corresponding rational system function
+
+ \f[
+ H(z) = \frac{alpha}{1 - (1-alpha) z^{-1}}
+ \f]
+
+ * Note that some texts define the system function with a + in the denominator.
+ * If you're using that convention, you'll need to negate the feedback tap.
+ */
+class gr_single_zero_avg_filter_ff : public gr_sync_block
+{
+ private:
+  friend gr_single_zero_avg_filter_ff_sptr 
+  gr_make_single_zero_avg_filter_ff (double alpha, unsigned int vlen);
+
+  unsigned int                                         d_vlen;
+  std::vector<gr_single_zero_avg<float,float,double> > d_rec;
+
+  gr_single_zero_avg_filter_ff (double alpha, unsigned int vlen);
+
+ public:
+  ~gr_single_zero_avg_filter_ff ();
+
+  void set_taps (double alpha);
+
+  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_single_zero_avg_filter_ff.i b/gnuradio-core/src/lib/filter/gr_single_zero_avg_filter_ff.i
new file mode 100644 (file)
index 0000000..0e6d84f
--- /dev/null
@@ -0,0 +1,34 @@
+/* -*- 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 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.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,single_zero_avg_filter_ff);
+
+gr_single_zero_avg_filter_ff_sptr 
+gr_make_single_zero_avg_filter_ff (double alpha, unsigned int vlen=1);
+
+class gr_single_zero_avg_filter_ff : public gr_sync_block
+{
+ public:
+  ~gr_single_zero_avg_filter_ff ();
+
+  void set_taps (double alpha);
+};
diff --git a/gnuradio-core/src/lib/filter/gr_single_zero_rec.h b/gnuradio-core/src/lib/filter/gr_single_zero_rec.h
new file mode 100644 (file)
index 0000000..f91640c
--- /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 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.
+ */
+#ifndef _GR_SINGLE_ZERO_REC_H_
+#define _GR_SINGLE_ZERO_REC_H_
+
+#include <stdexcept>
+
+/*!
+ * \brief class template for single zero recursive filter
+ */
+template<class o_type, class i_type, class tap_type> 
+class gr_single_zero_rec {
+public:
+  /*!
+   * \brief construct new single zero IIR with given alpha
+   *
+   * computes y(i) = alpha * x(i) - (1-alpha) * y(i-1)
+   */
+  gr_single_zero_rec (tap_type alpha = 1.0)
+  {
+    d_prev_output = 0;
+    set_taps (alpha);
+  }
+
+  /*!
+   * \brief compute a single output value.
+   * \returns the filtered input value.
+   */
+  o_type filter (const i_type input);
+
+  /*!
+   * \brief compute an array of N output values.
+   * \p input must have n valid entries.
+   */
+  void filterN (o_type output[], const i_type input[], unsigned long n);
+
+  /*!
+   * \brief install \p alpha as the current taps.
+   */
+  void set_taps (tap_type alpha)
+  { 
+    if (alpha < 0 || alpha > 1)
+      throw std::out_of_range ("Alpha must be in [0, 1]\n");
+
+    d_alpha = alpha;
+    d_one_minus_alpha = 1.0 - alpha;
+  }
+
+  //! reset state to zero
+  void reset ()
+  {
+    d_prev_output = 0;
+  }
+
+  tap_type prev_output () { return d_prev_output; }
+    
+protected:
+  tap_type     d_alpha;
+  tap_type     d_one_minus_alpha;
+  tap_type     d_prev_output;
+};
+
+
+//
+// general case.  We may want to specialize this
+//
+template<class o_type, class i_type, class tap_type> 
+o_type
+gr_single_zero_rec<o_type, i_type, tap_type>::filter (const i_type input)
+{
+  tap_type     output;
+
+  output = d_alpha * input - d_one_minus_alpha * d_prev_output;
+  d_prev_output = output;
+
+  return (o_type) output;
+}
+
+
+template<class o_type, class i_type, class tap_type> 
+void 
+gr_single_zero_rec<o_type, i_type, tap_type>::filterN (o_type output[],
+                                                      const i_type input[],
+                                                      unsigned long n)
+{
+  for (unsigned i = 0; i < n; i++)
+    output[i] = filter (input[i]);
+}
+
+
+#endif /* _GR_SINGLE_ZERO_REC_H_ */
diff --git a/gnuradio-core/src/lib/filter/gr_single_zero_rec_filter_ff.cc b/gnuradio-core/src/lib/filter/gr_single_zero_rec_filter_ff.cc
new file mode 100644 (file)
index 0000000..fe704f4
--- /dev/null
@@ -0,0 +1,81 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_single_zero_rec_filter_ff.h>
+#include <gr_io_signature.h>
+#include <stdio.h>
+
+
+gr_single_zero_rec_filter_ff_sptr 
+gr_make_single_zero_rec_filter_ff (double alpha, unsigned int vlen)
+{
+  return gr_single_zero_rec_filter_ff_sptr(new gr_single_zero_rec_filter_ff(alpha, vlen));
+}
+
+gr_single_zero_rec_filter_ff::gr_single_zero_rec_filter_ff (
+                                   double alpha, unsigned int vlen)
+  : gr_sync_block ("single_zero_rec_filter_ff",
+                  gr_make_io_signature (1, 1, sizeof (float) * vlen),
+                  gr_make_io_signature (1, 1, sizeof (float) * vlen)),
+    d_vlen(vlen), d_rec(vlen)
+{
+  set_taps(alpha);
+}
+
+gr_single_zero_rec_filter_ff::~gr_single_zero_rec_filter_ff ()
+{
+  // nop
+}
+
+void
+gr_single_zero_rec_filter_ff::set_taps (double alpha)
+{
+  for (unsigned int i = 0; i < d_vlen; i++)
+    d_rec[i].set_taps(alpha);
+}
+
+int
+gr_single_zero_rec_filter_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];
+  unsigned int vlen = d_vlen;
+
+  if (d_vlen == 1){
+    for (int i = 0; i < noutput_items; i++)
+      out[i] = d_rec[0].filter (in[i]);
+  }
+  else {
+    for (int i = 0; i < noutput_items; i++){
+      for (unsigned int j = 0; j < vlen; j++){
+       *out++ = d_rec[j].filter (*in++);
+      }
+    }
+  }
+  return noutput_items;
+};
diff --git a/gnuradio-core/src/lib/filter/gr_single_zero_rec_filter_ff.h b/gnuradio-core/src/lib/filter/gr_single_zero_rec_filter_ff.h
new file mode 100644 (file)
index 0000000..98215e9
--- /dev/null
@@ -0,0 +1,76 @@
+/* -*- c++ -*- */
+/*
+ * 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 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.
+ */
+
+#ifndef INCLUDED_GR_SINGLE_POLE_REC_FILTER_FF_H
+#define        INCLUDED_GR_SINGLE_POLE_REC_FILTER_FF_H
+
+#include <gr_sync_block.h>
+#include <gr_single_zero_rec.h>
+#include <stdexcept>
+
+class gr_single_zero_rec_filter_ff;
+typedef boost::shared_ptr<gr_single_zero_rec_filter_ff> gr_single_zero_rec_filter_ff_sptr;
+
+gr_single_zero_rec_filter_ff_sptr 
+gr_make_single_zero_rec_filter_ff (double alpha, unsigned int vlen=1);
+
+/*!
+ * \brief  single zero recursive filter with float input, float output
+ * \ingroup filter
+ *
+ * The input and output satisfy a difference equation of the form
+
+ \f[
+ y[n] - (1-alpha) y[n-1] = -alpha x[n]
+ \f]
+
+ * with the corresponding system function
+
+ \f[
+ H(z) = {alpha - (1-alpha) z^{-1}}
+ \f]
+
+ * Note that some texts define the system function with a + in the denominator.
+ * If you're using that convention, you'll need to negate the feedback tap.
+ */
+class gr_single_zero_rec_filter_ff : public gr_sync_block
+{
+ private:
+  friend gr_single_zero_rec_filter_ff_sptr 
+  gr_make_single_zero_rec_filter_ff (double alpha, unsigned int vlen);
+
+  unsigned int                                         d_vlen;
+  std::vector<gr_single_zero_rec<float,float,double> > d_rec;
+
+  gr_single_zero_rec_filter_ff (double alpha, unsigned int vlen);
+
+ public:
+  ~gr_single_zero_rec_filter_ff ();
+
+  void set_taps (double alpha);
+
+  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_single_zero_rec_filter_ff.i b/gnuradio-core/src/lib/filter/gr_single_zero_rec_filter_ff.i
new file mode 100644 (file)
index 0000000..e2cbbfc
--- /dev/null
@@ -0,0 +1,34 @@
+/* -*- 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 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.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,single_zero_rec_filter_ff);
+
+gr_single_zero_rec_filter_ff_sptr 
+gr_make_single_zero_rec_filter_ff (double alpha, unsigned int vlen=1);
+
+class gr_single_zero_rec_filter_ff : public gr_sync_block
+{
+ public:
+  ~gr_single_zero_rec_filter_ff ();
+
+  void set_taps (double alpha);
+};
diff --git a/gnuradio-core/src/lib/filter/gri_goertzel.cc b/gnuradio-core/src/lib/filter/gri_goertzel.cc
new file mode 100644 (file)
index 0000000..571de61
--- /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 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.
+ */
+
+#include <cmath>
+
+#include <gri_goertzel.h>
+
+gri_goertzel::gri_goertzel(int rate, int len, float freq)
+{
+  d_d1 = 0.0;
+  d_d2 = 0.0;
+
+  float w = 2.0*M_PI*freq/rate;
+  d_wr = 2.0*std::cos(w);
+  d_wi = std::sin(w);
+
+  d_len = len;
+  d_processed = 0;
+}
+
+gr_complex gri_goertzel::batch(float *in)
+{
+  d_d1 = 0.0;
+  d_d2 = 0.0;
+
+  for(int i = 0; i < d_len; i++)
+    input(in[i]);
+
+  return output();
+}
+
+void gri_goertzel::input(const float &input)
+{
+  float y = input + d_wr*d_d1 - d_d2;
+  d_d2 = d_d1;
+  d_d1 = y;
+  d_processed++;
+}
+
+gr_complex gri_goertzel::output()
+{
+  gr_complex out((0.5*d_wr*d_d1-d_d2)/d_len, (d_wi*d_d1)/d_len);
+  d_d1 = 0.0;
+  d_d2 = 0.0;
+  d_processed = 0;
+  return out;
+}
diff --git a/gnuradio-core/src/lib/filter/gri_goertzel.h b/gnuradio-core/src/lib/filter/gri_goertzel.h
new file mode 100644 (file)
index 0000000..6baf94e
--- /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 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.
+ */
+
+#ifndef INCLUDED_GRI_GOERTZEL_H
+#define INCLUDED_GRI_GOERTZEL_H
+
+#include <gr_types.h>
+
+/*!
+ * \brief implements Goertzel single-bin DFT calculation
+ */
+
+class gri_goertzel
+{
+public:
+  gri_goertzel() {}
+  gri_goertzel(int rate, int len, float freq);
+
+  // Process a input array
+  gr_complex batch(float *in);
+
+  // Process sample by sample
+  void input(const float &in);
+  gr_complex output();
+  bool ready() const { return d_processed == d_len; }
+    
+private:
+  float d_d1;
+  float d_d2;
+  float d_wr;
+  float d_wi;
+  int   d_len;
+  int   d_processed;
+};
+
+#endif /* INCLUDED_GRI_GOERTZEL_H */
diff --git a/gnuradio-core/src/lib/filter/gri_iir.h b/gnuradio-core/src/lib/filter/gri_iir.h
new file mode 100644 (file)
index 0000000..7de8c69
--- /dev/null
@@ -0,0 +1,164 @@
+/* -*- 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 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.
+ */
+
+#ifndef INCLUDED_GRI_IIR_H
+#define INCLUDED_GRI_IIR_H
+
+#include <vector>
+#include <stdexcept>
+
+/*!
+ * \brief base class template for Infinite Impulse Response filter (IIR)
+ */
+template<class i_type, class o_type, class tap_type> 
+class gri_iir {
+public:
+  /*!
+   * \brief Construct an IIR with the given taps.
+   *
+   * This filter uses the Direct Form I implementation, where
+   * \p fftaps contains the feed-forward taps, and \p fbtaps the feedback ones.
+   *
+   * \p fftaps and \p fbtaps must have equal numbers of taps
+   *
+   * The input and output satisfy a difference equation of the form
+
+   \f[
+   y[n] - \sum_{k=1}^{N} a_k y[n-k] = \sum_{k=0}^{M} b_k x[n-k]
+   \f]
+
+   * with the corresponding rational system function
+
+   \f[
+   H(z) = \frac{\sum_{k=0}^{M} b_k z^{-k}}{1 - \sum_{k=1}^{N} a_k z^{-k}}
+   \f]
+
+   * Note that some texts define the system function with a + in the denominator.
+   * If you're using that convention, you'll need to negate the feedback taps.
+   */
+  gri_iir (const std::vector<tap_type>& fftaps,
+         const std::vector<tap_type>& fbtaps) throw (std::invalid_argument)
+  {
+    set_taps (fftaps, fbtaps);
+  }
+
+  gri_iir () : d_latest(0) { }
+
+  ~gri_iir () {}
+
+  /*!
+   * \brief compute a single output value.
+   * \returns the filtered input value.
+   */
+  o_type filter (const i_type input);
+
+  /*!
+   * \brief compute an array of N output values.
+   * \p input must have N valid entries.
+   */
+  void filter_n (o_type output[], const i_type input[], long n);
+
+  /*!
+   * \return number of taps in filter.
+   */
+  unsigned ntaps () const { return d_fftaps.size (); }
+
+  /*!
+   * \brief install new taps.
+   */
+  void set_taps (const std::vector<tap_type> &fftaps, 
+                const std::vector<tap_type> &fbtaps) throw (std::invalid_argument)
+  { 
+    if (fftaps.size () != fbtaps.size ())
+      throw std::invalid_argument ("gri_iir::set_taps");
+
+    d_latest = 0;
+    d_fftaps = fftaps; 
+    d_fbtaps = fbtaps; 
+
+    int n = fftaps.size ();
+    d_prev_input.resize (2 * n);
+    d_prev_output.resize (2 * n);
+
+    for (int i = 0; i < 2 * n; i++){
+      d_prev_input[i] = 0;
+      d_prev_output[i] = 0;
+    }
+  }
+
+protected:
+  std::vector<tap_type>        d_fftaps;
+  std::vector<tap_type>        d_fbtaps;
+  int                  d_latest;
+  std::vector<tap_type>        d_prev_output;
+  std::vector<i_type>  d_prev_input;
+};
+
+
+//
+// general case.  We may want to specialize this
+//
+template<class i_type, class o_type, class tap_type> 
+o_type
+gri_iir<i_type, o_type, tap_type>::filter (const i_type input)
+{
+  tap_type     acc;
+  unsigned     i = 0;
+  unsigned     n = ntaps ();
+
+  if (n == 0)
+    return (o_type) 0;
+
+  int latest = d_latest;
+  
+  acc = d_fftaps[0] * input;
+  for (i = 1; i < n; i ++)
+    acc += (d_fftaps[i] * d_prev_input[latest + i]
+           + d_fbtaps[i] * d_prev_output[latest + i]);
+
+  // store the values twice to avoid having to handle wrap-around in the loop
+  d_prev_output[latest] = acc;
+  d_prev_output[latest+n] = acc;
+  d_prev_input[latest] = input;
+  d_prev_input[latest+n] = input;
+
+  latest--;
+  if (latest < 0)
+    latest += n;
+
+  d_latest = latest;
+  return (o_type) acc;
+}
+
+
+template<class i_type, class o_type, class tap_type> 
+void 
+gri_iir<i_type, o_type, tap_type>::filter_n (o_type output[],
+                                            const i_type input[],
+                                            long n)
+{
+  for (int i = 0; i < n; i++)
+    output[i] = filter (input[i]);
+}
+
+#endif /* INCLUDED_GRI_IIR_H */
+
diff --git a/gnuradio-core/src/lib/filter/gri_mmse_fir_interpolator.cc b/gnuradio-core/src/lib/filter/gri_mmse_fir_interpolator.cc
new file mode 100644 (file)
index 0000000..ff7eca8
--- /dev/null
@@ -0,0 +1,71 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <gri_mmse_fir_interpolator.h>
+#include <gr_fir_util.h>
+#include <gr_fir_fff.h>
+#include <assert.h>
+#include <cmath>
+#include "interpolator_taps.h"
+
+gri_mmse_fir_interpolator::gri_mmse_fir_interpolator ()
+{
+  filters.resize (NSTEPS + 1);
+  
+  for (int i = 0; i < NSTEPS + 1; i++){
+    std::vector<float> t (&taps[i][0], &taps[i][NTAPS]);
+    filters[i] = gr_fir_util::create_gr_fir_fff (t);
+  }
+}
+
+gri_mmse_fir_interpolator::~gri_mmse_fir_interpolator ()
+{
+  for (int i = 0; i < NSTEPS + 1; i++)
+    delete filters[i];
+}
+
+unsigned
+gri_mmse_fir_interpolator::ntaps () const
+{
+  return NTAPS;
+}
+
+unsigned
+gri_mmse_fir_interpolator::nsteps () const
+{
+  return NSTEPS;
+}
+
+float
+gri_mmse_fir_interpolator::interpolate (const float input[], float mu) const
+{
+  int  imu = (int) rint (mu * NSTEPS);
+
+  assert (imu >= 0);
+  assert (imu <= NSTEPS);
+
+  float r = filters[imu]->filter (input);
+  return r;
+}
diff --git a/gnuradio-core/src/lib/filter/gri_mmse_fir_interpolator.h b/gnuradio-core/src/lib/filter/gri_mmse_fir_interpolator.h
new file mode 100644 (file)
index 0000000..e2fb8f7
--- /dev/null
@@ -0,0 +1,65 @@
+/* -*- 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 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.
+ */
+#ifndef _GRI_MMSE_FIR_INTERPOLATOR_H_
+#define _GRI_MMSE_FIR_INTERPOLATOR_H_
+
+#include <vector>
+
+class gr_fir_fff;
+
+/*!
+ * \brief Compute intermediate samples between signal samples x(k*Ts)
+ *
+ * This implements a Mininum Mean Squared Error interpolator with 8 taps.
+ * It is suitable for signals where the bandwidth of interest B = 1/(4*Ts)
+ * Where Ts is the time between samples.
+ *
+ * Although mu, the fractional delay, is specified as a float, it is actually
+ * quantized.  0.0 <= mu <= 1.0.  That is, mu is quantized in the interpolate 
+ * method to 32nd's of a sample.
+ */
+
+class gri_mmse_fir_interpolator {
+public:
+  gri_mmse_fir_interpolator ();
+  ~gri_mmse_fir_interpolator ();
+
+  unsigned ntaps () const;
+  unsigned nsteps () const;
+
+  /*!
+   * \brief compute a single interpolated output value.
+   * \p input must have ntaps() valid entries.
+   * input[0] .. input[ntaps() - 1] are referenced to compute the output value.
+   *
+   * \p mu must be in the range [0, 1] and specifies the fractional delay.
+   *
+   * \returns the interpolated input value.
+   */
+  float interpolate (const float input[], float mu) const;
+
+protected:
+  std::vector<gr_fir_fff *>    filters;
+};
+
+
+#endif /* _GRI_MMSE_FIR_INTERPOLATOR_H_ */
diff --git a/gnuradio-core/src/lib/filter/gri_mmse_fir_interpolator_cc.cc b/gnuradio-core/src/lib/filter/gri_mmse_fir_interpolator_cc.cc
new file mode 100644 (file)
index 0000000..3f75aed
--- /dev/null
@@ -0,0 +1,71 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <gri_mmse_fir_interpolator_cc.h>
+#include <gr_fir_util.h>
+#include <gr_fir_ccf.h>
+#include <assert.h>
+#include <cmath>
+#include "interpolator_taps.h"
+
+gri_mmse_fir_interpolator_cc::gri_mmse_fir_interpolator_cc ()
+{
+  filters.resize (NSTEPS + 1);
+  
+  for (int i = 0; i < NSTEPS + 1; i++){
+    std::vector<float> t (&taps[i][0], &taps[i][NTAPS]);
+    filters[i] = gr_fir_util::create_gr_fir_ccf (t);
+  }
+}
+
+gri_mmse_fir_interpolator_cc::~gri_mmse_fir_interpolator_cc ()
+{
+  for (int i = 0; i < NSTEPS + 1; i++)
+    delete filters[i];
+}
+
+unsigned
+gri_mmse_fir_interpolator_cc::ntaps () const
+{
+  return NTAPS;
+}
+
+unsigned
+gri_mmse_fir_interpolator_cc::nsteps () const
+{
+  return NSTEPS;
+}
+
+gr_complex
+gri_mmse_fir_interpolator_cc::interpolate (const gr_complex input[], float mu)
+{
+  int  imu = (int) rint (mu * NSTEPS);
+
+  assert (imu >= 0);
+  assert (imu <= NSTEPS);
+
+  gr_complex r = filters[imu]->filter (input);
+  return r;
+}
diff --git a/gnuradio-core/src/lib/filter/gri_mmse_fir_interpolator_cc.h b/gnuradio-core/src/lib/filter/gri_mmse_fir_interpolator_cc.h
new file mode 100644 (file)
index 0000000..d0c1411
--- /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 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.
+ */
+#ifndef _GRI_MMSE_FIR_INTERPOLATOR_CC_H_
+#define _GRI_MMSE_FIR_INTERPOLATOR_CC_H_
+
+#include <gr_complex.h>
+#include <vector>
+
+class gr_fir_ccf;
+
+/*!
+ * \brief Compute intermediate samples between signal samples x(k*Ts)
+ *
+ * This implements a Mininum Mean Squared Error interpolator with 8 taps.
+ * It is suitable for signals where the bandwidth of interest B = 1/(4*Ts)
+ * Where Ts is the time between samples.
+ *
+ * Although mu, the fractional delay, is specified as a float, it is actually
+ * quantized.  0.0 <= mu <= 1.0.  That is, mu is quantized in the interpolate 
+ * method to 32nd's of a sample.
+ */
+
+class gri_mmse_fir_interpolator_cc {
+public:
+  gri_mmse_fir_interpolator_cc ();
+  ~gri_mmse_fir_interpolator_cc ();
+
+  unsigned ntaps () const;
+  unsigned nsteps () const;
+
+  /*!
+   * \brief compute a single interpolated output value.
+   * \p input must have ntaps() valid entries.
+   * input[0] .. input[ntaps() - 1] are referenced to compute the output value.
+   *
+   * \p mu must be in the range [0, 1] and specifies the fractional delay.
+   *
+   * \returns the interpolated input value.
+   */
+  gr_complex interpolate (const gr_complex input[], float mu);
+
+protected:
+  std::vector<gr_fir_ccf *>    filters;
+};
+
+
+#endif /* _GRI_MMSE_FIR_INTERPOLATOR_CC_H_ */
diff --git a/gnuradio-core/src/lib/filter/interpolator_taps.h b/gnuradio-core/src/lib/filter/interpolator_taps.h
new file mode 100644 (file)
index 0000000..76702b6
--- /dev/null
@@ -0,0 +1,141 @@
+/*
+ * This file was machine generated by gen_interpolator_taps.
+ * DO NOT EDIT BY HAND.
+ */
+
+static const int       NTAPS  =   8;
+static const int       NSTEPS = 128;
+
+static const float taps[NSTEPS+1][NTAPS] = {
+  //    -4            -3            -2            -1             0             1             2             3                mu
+  {  0.00000e+00,  0.00000e+00,  0.00000e+00,  0.00000e+00,  1.00000e+00,  0.00000e+00,  0.00000e+00,  0.00000e+00 }, //   0/128
+  { -1.54700e-04,  8.53777e-04, -2.76968e-03,  7.89295e-03,  9.98534e-01, -5.41054e-03,  1.24642e-03, -1.98993e-04 }, //   1/128
+  { -3.09412e-04,  1.70888e-03, -5.55134e-03,  1.58840e-02,  9.96891e-01, -1.07209e-02,  2.47942e-03, -3.96391e-04 }, //   2/128
+  { -4.64053e-04,  2.56486e-03, -8.34364e-03,  2.39714e-02,  9.95074e-01, -1.59305e-02,  3.69852e-03, -5.92100e-04 }, //   3/128
+  { -6.18544e-04,  3.42130e-03, -1.11453e-02,  3.21531e-02,  9.93082e-01, -2.10389e-02,  4.90322e-03, -7.86031e-04 }, //   4/128
+  { -7.72802e-04,  4.27773e-03, -1.39548e-02,  4.04274e-02,  9.90917e-01, -2.60456e-02,  6.09305e-03, -9.78093e-04 }, //   5/128
+  { -9.26747e-04,  5.13372e-03, -1.67710e-02,  4.87921e-02,  9.88580e-01, -3.09503e-02,  7.26755e-03, -1.16820e-03 }, //   6/128
+  { -1.08030e-03,  5.98883e-03, -1.95925e-02,  5.72454e-02,  9.86071e-01, -3.57525e-02,  8.42626e-03, -1.35627e-03 }, //   7/128
+  { -1.23337e-03,  6.84261e-03, -2.24178e-02,  6.57852e-02,  9.83392e-01, -4.04519e-02,  9.56876e-03, -1.54221e-03 }, //   8/128
+  { -1.38589e-03,  7.69462e-03, -2.52457e-02,  7.44095e-02,  9.80543e-01, -4.50483e-02,  1.06946e-02, -1.72594e-03 }, //   9/128
+  { -1.53777e-03,  8.54441e-03, -2.80746e-02,  8.31162e-02,  9.77526e-01, -4.95412e-02,  1.18034e-02, -1.90738e-03 }, //  10/128
+  { -1.68894e-03,  9.39154e-03, -3.09033e-02,  9.19033e-02,  9.74342e-01, -5.39305e-02,  1.28947e-02, -2.08645e-03 }, //  11/128
+  { -1.83931e-03,  1.02356e-02, -3.37303e-02,  1.00769e-01,  9.70992e-01, -5.82159e-02,  1.39681e-02, -2.26307e-03 }, //  12/128
+  { -1.98880e-03,  1.10760e-02, -3.65541e-02,  1.09710e-01,  9.67477e-01, -6.23972e-02,  1.50233e-02, -2.43718e-03 }, //  13/128
+  { -2.13733e-03,  1.19125e-02, -3.93735e-02,  1.18725e-01,  9.63798e-01, -6.64743e-02,  1.60599e-02, -2.60868e-03 }, //  14/128
+  { -2.28483e-03,  1.27445e-02, -4.21869e-02,  1.27812e-01,  9.59958e-01, -7.04471e-02,  1.70776e-02, -2.77751e-03 }, //  15/128
+  { -2.43121e-03,  1.35716e-02, -4.49929e-02,  1.36968e-01,  9.55956e-01, -7.43154e-02,  1.80759e-02, -2.94361e-03 }, //  16/128
+  { -2.57640e-03,  1.43934e-02, -4.77900e-02,  1.46192e-01,  9.51795e-01, -7.80792e-02,  1.90545e-02, -3.10689e-03 }, //  17/128
+  { -2.72032e-03,  1.52095e-02, -5.05770e-02,  1.55480e-01,  9.47477e-01, -8.17385e-02,  2.00132e-02, -3.26730e-03 }, //  18/128
+  { -2.86289e-03,  1.60193e-02, -5.33522e-02,  1.64831e-01,  9.43001e-01, -8.52933e-02,  2.09516e-02, -3.42477e-03 }, //  19/128
+  { -3.00403e-03,  1.68225e-02, -5.61142e-02,  1.74242e-01,  9.38371e-01, -8.87435e-02,  2.18695e-02, -3.57923e-03 }, //  20/128
+  { -3.14367e-03,  1.76185e-02, -5.88617e-02,  1.83711e-01,  9.33586e-01, -9.20893e-02,  2.27664e-02, -3.73062e-03 }, //  21/128
+  { -3.28174e-03,  1.84071e-02, -6.15931e-02,  1.93236e-01,  9.28650e-01, -9.53307e-02,  2.36423e-02, -3.87888e-03 }, //  22/128
+  { -3.41815e-03,  1.91877e-02, -6.43069e-02,  2.02814e-01,  9.23564e-01, -9.84679e-02,  2.44967e-02, -4.02397e-03 }, //  23/128
+  { -3.55283e-03,  1.99599e-02, -6.70018e-02,  2.12443e-01,  9.18329e-01, -1.01501e-01,  2.53295e-02, -4.16581e-03 }, //  24/128
+  { -3.68570e-03,  2.07233e-02, -6.96762e-02,  2.22120e-01,  9.12947e-01, -1.04430e-01,  2.61404e-02, -4.30435e-03 }, //  25/128
+  { -3.81671e-03,  2.14774e-02, -7.23286e-02,  2.31843e-01,  9.07420e-01, -1.07256e-01,  2.69293e-02, -4.43955e-03 }, //  26/128
+  { -3.94576e-03,  2.22218e-02, -7.49577e-02,  2.41609e-01,  9.01749e-01, -1.09978e-01,  2.76957e-02, -4.57135e-03 }, //  27/128
+  { -4.07279e-03,  2.29562e-02, -7.75620e-02,  2.51417e-01,  8.95936e-01, -1.12597e-01,  2.84397e-02, -4.69970e-03 }, //  28/128
+  { -4.19774e-03,  2.36801e-02, -8.01399e-02,  2.61263e-01,  8.89984e-01, -1.15113e-01,  2.91609e-02, -4.82456e-03 }, //  29/128
+  { -4.32052e-03,  2.43930e-02, -8.26900e-02,  2.71144e-01,  8.83893e-01, -1.17526e-01,  2.98593e-02, -4.94589e-03 }, //  30/128
+  { -4.44107e-03,  2.50946e-02, -8.52109e-02,  2.81060e-01,  8.77666e-01, -1.19837e-01,  3.05345e-02, -5.06363e-03 }, //  31/128
+  { -4.55932e-03,  2.57844e-02, -8.77011e-02,  2.91006e-01,  8.71305e-01, -1.22047e-01,  3.11866e-02, -5.17776e-03 }, //  32/128
+  { -4.67520e-03,  2.64621e-02, -9.01591e-02,  3.00980e-01,  8.64812e-01, -1.24154e-01,  3.18153e-02, -5.28823e-03 }, //  33/128
+  { -4.78866e-03,  2.71272e-02, -9.25834e-02,  3.10980e-01,  8.58189e-01, -1.26161e-01,  3.24205e-02, -5.39500e-03 }, //  34/128
+  { -4.89961e-03,  2.77794e-02, -9.49727e-02,  3.21004e-01,  8.51437e-01, -1.28068e-01,  3.30021e-02, -5.49804e-03 }, //  35/128
+  { -5.00800e-03,  2.84182e-02, -9.73254e-02,  3.31048e-01,  8.44559e-01, -1.29874e-01,  3.35600e-02, -5.59731e-03 }, //  36/128
+  { -5.11376e-03,  2.90433e-02, -9.96402e-02,  3.41109e-01,  8.37557e-01, -1.31581e-01,  3.40940e-02, -5.69280e-03 }, //  37/128
+  { -5.21683e-03,  2.96543e-02, -1.01915e-01,  3.51186e-01,  8.30432e-01, -1.33189e-01,  3.46042e-02, -5.78446e-03 }, //  38/128
+  { -5.31716e-03,  3.02507e-02, -1.04150e-01,  3.61276e-01,  8.23188e-01, -1.34699e-01,  3.50903e-02, -5.87227e-03 }, //  39/128
+  { -5.41467e-03,  3.08323e-02, -1.06342e-01,  3.71376e-01,  8.15826e-01, -1.36111e-01,  3.55525e-02, -5.95620e-03 }, //  40/128
+  { -5.50931e-03,  3.13987e-02, -1.08490e-01,  3.81484e-01,  8.08348e-01, -1.37426e-01,  3.59905e-02, -6.03624e-03 }, //  41/128
+  { -5.60103e-03,  3.19495e-02, -1.10593e-01,  3.91596e-01,  8.00757e-01, -1.38644e-01,  3.64044e-02, -6.11236e-03 }, //  42/128
+  { -5.68976e-03,  3.24843e-02, -1.12650e-01,  4.01710e-01,  7.93055e-01, -1.39767e-01,  3.67941e-02, -6.18454e-03 }, //  43/128
+  { -5.77544e-03,  3.30027e-02, -1.14659e-01,  4.11823e-01,  7.85244e-01, -1.40794e-01,  3.71596e-02, -6.25277e-03 }, //  44/128
+  { -5.85804e-03,  3.35046e-02, -1.16618e-01,  4.21934e-01,  7.77327e-01, -1.41727e-01,  3.75010e-02, -6.31703e-03 }, //  45/128
+  { -5.93749e-03,  3.39894e-02, -1.18526e-01,  4.32038e-01,  7.69305e-01, -1.42566e-01,  3.78182e-02, -6.37730e-03 }, //  46/128
+  { -6.01374e-03,  3.44568e-02, -1.20382e-01,  4.42134e-01,  7.61181e-01, -1.43313e-01,  3.81111e-02, -6.43358e-03 }, //  47/128
+  { -6.08674e-03,  3.49066e-02, -1.22185e-01,  4.52218e-01,  7.52958e-01, -1.43968e-01,  3.83800e-02, -6.48585e-03 }, //  48/128
+  { -6.15644e-03,  3.53384e-02, -1.23933e-01,  4.62289e-01,  7.44637e-01, -1.44531e-01,  3.86247e-02, -6.53412e-03 }, //  49/128
+  { -6.22280e-03,  3.57519e-02, -1.25624e-01,  4.72342e-01,  7.36222e-01, -1.45004e-01,  3.88454e-02, -6.57836e-03 }, //  50/128
+  { -6.28577e-03,  3.61468e-02, -1.27258e-01,  4.82377e-01,  7.27714e-01, -1.45387e-01,  3.90420e-02, -6.61859e-03 }, //  51/128
+  { -6.34530e-03,  3.65227e-02, -1.28832e-01,  4.92389e-01,  7.19116e-01, -1.45682e-01,  3.92147e-02, -6.65479e-03 }, //  52/128
+  { -6.40135e-03,  3.68795e-02, -1.30347e-01,  5.02377e-01,  7.10431e-01, -1.45889e-01,  3.93636e-02, -6.68698e-03 }, //  53/128
+  { -6.45388e-03,  3.72167e-02, -1.31800e-01,  5.12337e-01,  7.01661e-01, -1.46009e-01,  3.94886e-02, -6.71514e-03 }, //  54/128
+  { -6.50285e-03,  3.75341e-02, -1.33190e-01,  5.22267e-01,  6.92808e-01, -1.46043e-01,  3.95900e-02, -6.73929e-03 }, //  55/128
+  { -6.54823e-03,  3.78315e-02, -1.34515e-01,  5.32164e-01,  6.83875e-01, -1.45993e-01,  3.96678e-02, -6.75943e-03 }, //  56/128
+  { -6.58996e-03,  3.81085e-02, -1.35775e-01,  5.42025e-01,  6.74865e-01, -1.45859e-01,  3.97222e-02, -6.77557e-03 }, //  57/128
+  { -6.62802e-03,  3.83650e-02, -1.36969e-01,  5.51849e-01,  6.65779e-01, -1.45641e-01,  3.97532e-02, -6.78771e-03 }, //  58/128
+  { -6.66238e-03,  3.86006e-02, -1.38094e-01,  5.61631e-01,  6.56621e-01, -1.45343e-01,  3.97610e-02, -6.79588e-03 }, //  59/128
+  { -6.69300e-03,  3.88151e-02, -1.39150e-01,  5.71370e-01,  6.47394e-01, -1.44963e-01,  3.97458e-02, -6.80007e-03 }, //  60/128
+  { -6.71985e-03,  3.90083e-02, -1.40136e-01,  5.81063e-01,  6.38099e-01, -1.44503e-01,  3.97077e-02, -6.80032e-03 }, //  61/128
+  { -6.74291e-03,  3.91800e-02, -1.41050e-01,  5.90706e-01,  6.28739e-01, -1.43965e-01,  3.96469e-02, -6.79662e-03 }, //  62/128
+  { -6.76214e-03,  3.93299e-02, -1.41891e-01,  6.00298e-01,  6.19318e-01, -1.43350e-01,  3.95635e-02, -6.78902e-03 }, //  63/128
+  { -6.77751e-03,  3.94578e-02, -1.42658e-01,  6.09836e-01,  6.09836e-01, -1.42658e-01,  3.94578e-02, -6.77751e-03 }, //  64/128
+  { -6.78902e-03,  3.95635e-02, -1.43350e-01,  6.19318e-01,  6.00298e-01, -1.41891e-01,  3.93299e-02, -6.76214e-03 }, //  65/128
+  { -6.79662e-03,  3.96469e-02, -1.43965e-01,  6.28739e-01,  5.90706e-01, -1.41050e-01,  3.91800e-02, -6.74291e-03 }, //  66/128
+  { -6.80032e-03,  3.97077e-02, -1.44503e-01,  6.38099e-01,  5.81063e-01, -1.40136e-01,  3.90083e-02, -6.71985e-03 }, //  67/128
+  { -6.80007e-03,  3.97458e-02, -1.44963e-01,  6.47394e-01,  5.71370e-01, -1.39150e-01,  3.88151e-02, -6.69300e-03 }, //  68/128
+  { -6.79588e-03,  3.97610e-02, -1.45343e-01,  6.56621e-01,  5.61631e-01, -1.38094e-01,  3.86006e-02, -6.66238e-03 }, //  69/128
+  { -6.78771e-03,  3.97532e-02, -1.45641e-01,  6.65779e-01,  5.51849e-01, -1.36969e-01,  3.83650e-02, -6.62802e-03 }, //  70/128
+  { -6.77557e-03,  3.97222e-02, -1.45859e-01,  6.74865e-01,  5.42025e-01, -1.35775e-01,  3.81085e-02, -6.58996e-03 }, //  71/128
+  { -6.75943e-03,  3.96678e-02, -1.45993e-01,  6.83875e-01,  5.32164e-01, -1.34515e-01,  3.78315e-02, -6.54823e-03 }, //  72/128
+  { -6.73929e-03,  3.95900e-02, -1.46043e-01,  6.92808e-01,  5.22267e-01, -1.33190e-01,  3.75341e-02, -6.50285e-03 }, //  73/128
+  { -6.71514e-03,  3.94886e-02, -1.46009e-01,  7.01661e-01,  5.12337e-01, -1.31800e-01,  3.72167e-02, -6.45388e-03 }, //  74/128
+  { -6.68698e-03,  3.93636e-02, -1.45889e-01,  7.10431e-01,  5.02377e-01, -1.30347e-01,  3.68795e-02, -6.40135e-03 }, //  75/128
+  { -6.65479e-03,  3.92147e-02, -1.45682e-01,  7.19116e-01,  4.92389e-01, -1.28832e-01,  3.65227e-02, -6.34530e-03 }, //  76/128
+  { -6.61859e-03,  3.90420e-02, -1.45387e-01,  7.27714e-01,  4.82377e-01, -1.27258e-01,  3.61468e-02, -6.28577e-03 }, //  77/128
+  { -6.57836e-03,  3.88454e-02, -1.45004e-01,  7.36222e-01,  4.72342e-01, -1.25624e-01,  3.57519e-02, -6.22280e-03 }, //  78/128
+  { -6.53412e-03,  3.86247e-02, -1.44531e-01,  7.44637e-01,  4.62289e-01, -1.23933e-01,  3.53384e-02, -6.15644e-03 }, //  79/128
+  { -6.48585e-03,  3.83800e-02, -1.43968e-01,  7.52958e-01,  4.52218e-01, -1.22185e-01,  3.49066e-02, -6.08674e-03 }, //  80/128
+  { -6.43358e-03,  3.81111e-02, -1.43313e-01,  7.61181e-01,  4.42134e-01, -1.20382e-01,  3.44568e-02, -6.01374e-03 }, //  81/128
+  { -6.37730e-03,  3.78182e-02, -1.42566e-01,  7.69305e-01,  4.32038e-01, -1.18526e-01,  3.39894e-02, -5.93749e-03 }, //  82/128
+  { -6.31703e-03,  3.75010e-02, -1.41727e-01,  7.77327e-01,  4.21934e-01, -1.16618e-01,  3.35046e-02, -5.85804e-03 }, //  83/128
+  { -6.25277e-03,  3.71596e-02, -1.40794e-01,  7.85244e-01,  4.11823e-01, -1.14659e-01,  3.30027e-02, -5.77544e-03 }, //  84/128
+  { -6.18454e-03,  3.67941e-02, -1.39767e-01,  7.93055e-01,  4.01710e-01, -1.12650e-01,  3.24843e-02, -5.68976e-03 }, //  85/128
+  { -6.11236e-03,  3.64044e-02, -1.38644e-01,  8.00757e-01,  3.91596e-01, -1.10593e-01,  3.19495e-02, -5.60103e-03 }, //  86/128
+  { -6.03624e-03,  3.59905e-02, -1.37426e-01,  8.08348e-01,  3.81484e-01, -1.08490e-01,  3.13987e-02, -5.50931e-03 }, //  87/128
+  { -5.95620e-03,  3.55525e-02, -1.36111e-01,  8.15826e-01,  3.71376e-01, -1.06342e-01,  3.08323e-02, -5.41467e-03 }, //  88/128
+  { -5.87227e-03,  3.50903e-02, -1.34699e-01,  8.23188e-01,  3.61276e-01, -1.04150e-01,  3.02507e-02, -5.31716e-03 }, //  89/128
+  { -5.78446e-03,  3.46042e-02, -1.33189e-01,  8.30432e-01,  3.51186e-01, -1.01915e-01,  2.96543e-02, -5.21683e-03 }, //  90/128
+  { -5.69280e-03,  3.40940e-02, -1.31581e-01,  8.37557e-01,  3.41109e-01, -9.96402e-02,  2.90433e-02, -5.11376e-03 }, //  91/128
+  { -5.59731e-03,  3.35600e-02, -1.29874e-01,  8.44559e-01,  3.31048e-01, -9.73254e-02,  2.84182e-02, -5.00800e-03 }, //  92/128
+  { -5.49804e-03,  3.30021e-02, -1.28068e-01,  8.51437e-01,  3.21004e-01, -9.49727e-02,  2.77794e-02, -4.89961e-03 }, //  93/128
+  { -5.39500e-03,  3.24205e-02, -1.26161e-01,  8.58189e-01,  3.10980e-01, -9.25834e-02,  2.71272e-02, -4.78866e-03 }, //  94/128
+  { -5.28823e-03,  3.18153e-02, -1.24154e-01,  8.64812e-01,  3.00980e-01, -9.01591e-02,  2.64621e-02, -4.67520e-03 }, //  95/128
+  { -5.17776e-03,  3.11866e-02, -1.22047e-01,  8.71305e-01,  2.91006e-01, -8.77011e-02,  2.57844e-02, -4.55932e-03 }, //  96/128
+  { -5.06363e-03,  3.05345e-02, -1.19837e-01,  8.77666e-01,  2.81060e-01, -8.52109e-02,  2.50946e-02, -4.44107e-03 }, //  97/128
+  { -4.94589e-03,  2.98593e-02, -1.17526e-01,  8.83893e-01,  2.71144e-01, -8.26900e-02,  2.43930e-02, -4.32052e-03 }, //  98/128
+  { -4.82456e-03,  2.91609e-02, -1.15113e-01,  8.89984e-01,  2.61263e-01, -8.01399e-02,  2.36801e-02, -4.19774e-03 }, //  99/128
+  { -4.69970e-03,  2.84397e-02, -1.12597e-01,  8.95936e-01,  2.51417e-01, -7.75620e-02,  2.29562e-02, -4.07279e-03 }, // 100/128
+  { -4.57135e-03,  2.76957e-02, -1.09978e-01,  9.01749e-01,  2.41609e-01, -7.49577e-02,  2.22218e-02, -3.94576e-03 }, // 101/128
+  { -4.43955e-03,  2.69293e-02, -1.07256e-01,  9.07420e-01,  2.31843e-01, -7.23286e-02,  2.14774e-02, -3.81671e-03 }, // 102/128
+  { -4.30435e-03,  2.61404e-02, -1.04430e-01,  9.12947e-01,  2.22120e-01, -6.96762e-02,  2.07233e-02, -3.68570e-03 }, // 103/128
+  { -4.16581e-03,  2.53295e-02, -1.01501e-01,  9.18329e-01,  2.12443e-01, -6.70018e-02,  1.99599e-02, -3.55283e-03 }, // 104/128
+  { -4.02397e-03,  2.44967e-02, -9.84679e-02,  9.23564e-01,  2.02814e-01, -6.43069e-02,  1.91877e-02, -3.41815e-03 }, // 105/128
+  { -3.87888e-03,  2.36423e-02, -9.53307e-02,  9.28650e-01,  1.93236e-01, -6.15931e-02,  1.84071e-02, -3.28174e-03 }, // 106/128
+  { -3.73062e-03,  2.27664e-02, -9.20893e-02,  9.33586e-01,  1.83711e-01, -5.88617e-02,  1.76185e-02, -3.14367e-03 }, // 107/128
+  { -3.57923e-03,  2.18695e-02, -8.87435e-02,  9.38371e-01,  1.74242e-01, -5.61142e-02,  1.68225e-02, -3.00403e-03 }, // 108/128
+  { -3.42477e-03,  2.09516e-02, -8.52933e-02,  9.43001e-01,  1.64831e-01, -5.33522e-02,  1.60193e-02, -2.86289e-03 }, // 109/128
+  { -3.26730e-03,  2.00132e-02, -8.17385e-02,  9.47477e-01,  1.55480e-01, -5.05770e-02,  1.52095e-02, -2.72032e-03 }, // 110/128
+  { -3.10689e-03,  1.90545e-02, -7.80792e-02,  9.51795e-01,  1.46192e-01, -4.77900e-02,  1.43934e-02, -2.57640e-03 }, // 111/128
+  { -2.94361e-03,  1.80759e-02, -7.43154e-02,  9.55956e-01,  1.36968e-01, -4.49929e-02,  1.35716e-02, -2.43121e-03 }, // 112/128
+  { -2.77751e-03,  1.70776e-02, -7.04471e-02,  9.59958e-01,  1.27812e-01, -4.21869e-02,  1.27445e-02, -2.28483e-03 }, // 113/128
+  { -2.60868e-03,  1.60599e-02, -6.64743e-02,  9.63798e-01,  1.18725e-01, -3.93735e-02,  1.19125e-02, -2.13733e-03 }, // 114/128
+  { -2.43718e-03,  1.50233e-02, -6.23972e-02,  9.67477e-01,  1.09710e-01, -3.65541e-02,  1.10760e-02, -1.98880e-03 }, // 115/128
+  { -2.26307e-03,  1.39681e-02, -5.82159e-02,  9.70992e-01,  1.00769e-01, -3.37303e-02,  1.02356e-02, -1.83931e-03 }, // 116/128
+  { -2.08645e-03,  1.28947e-02, -5.39305e-02,  9.74342e-01,  9.19033e-02, -3.09033e-02,  9.39154e-03, -1.68894e-03 }, // 117/128
+  { -1.90738e-03,  1.18034e-02, -4.95412e-02,  9.77526e-01,  8.31162e-02, -2.80746e-02,  8.54441e-03, -1.53777e-03 }, // 118/128
+  { -1.72594e-03,  1.06946e-02, -4.50483e-02,  9.80543e-01,  7.44095e-02, -2.52457e-02,  7.69462e-03, -1.38589e-03 }, // 119/128
+  { -1.54221e-03,  9.56876e-03, -4.04519e-02,  9.83392e-01,  6.57852e-02, -2.24178e-02,  6.84261e-03, -1.23337e-03 }, // 120/128
+  { -1.35627e-03,  8.42626e-03, -3.57525e-02,  9.86071e-01,  5.72454e-02, -1.95925e-02,  5.98883e-03, -1.08030e-03 }, // 121/128
+  { -1.16820e-03,  7.26755e-03, -3.09503e-02,  9.88580e-01,  4.87921e-02, -1.67710e-02,  5.13372e-03, -9.26747e-04 }, // 122/128
+  { -9.78093e-04,  6.09305e-03, -2.60456e-02,  9.90917e-01,  4.04274e-02, -1.39548e-02,  4.27773e-03, -7.72802e-04 }, // 123/128
+  { -7.86031e-04,  4.90322e-03, -2.10389e-02,  9.93082e-01,  3.21531e-02, -1.11453e-02,  3.42130e-03, -6.18544e-04 }, // 124/128
+  { -5.92100e-04,  3.69852e-03, -1.59305e-02,  9.95074e-01,  2.39714e-02, -8.34364e-03,  2.56486e-03, -4.64053e-04 }, // 125/128
+  { -3.96391e-04,  2.47942e-03, -1.07209e-02,  9.96891e-01,  1.58840e-02, -5.55134e-03,  1.70888e-03, -3.09412e-04 }, // 126/128
+  { -1.98993e-04,  1.24642e-03, -5.41054e-03,  9.98534e-01,  7.89295e-03, -2.76968e-03,  8.53777e-04, -1.54700e-04 }, // 127/128
+  {  0.00000e+00,  0.00000e+00,  0.00000e+00,  1.00000e+00,  0.00000e+00,  0.00000e+00,  0.00000e+00,  0.00000e+00 }, // 128/128
+};
+
diff --git a/gnuradio-core/src/lib/filter/qa_ccomplex_dotprod_x86.cc b/gnuradio-core/src/lib/filter/qa_ccomplex_dotprod_x86.cc
new file mode 100644 (file)
index 0000000..ad6f6c6
--- /dev/null
@@ -0,0 +1,341 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <cppunit/TestAssert.h>
+#include <qa_ccomplex_dotprod_x86.h>
+#include <ccomplex_dotprod_x86.h>
+#include <string.h>
+#include <iostream>
+#include <malloc16.h>
+#include <sse_debug.h>
+#include <cmath>
+#include <gr_cpu.h>
+#include <random.h>
+
+using std::cerr;
+
+/// Macro for primitive value comparisons
+#define assertcomplexEqual(expected0,expected1,actual,delta)   \
+  CPPUNIT_ASSERT_DOUBLES_EQUAL (expected0, actual[0], delta);  \
+  CPPUNIT_ASSERT_DOUBLES_EQUAL (expected1, actual[1], delta);  
+
+
+#define        MAX_BLKS        10
+#define        FLOATS_PER_BLK   4
+
+#define        ERR_DELTA       (1e-6)
+
+static float
+uniform ()
+{
+  return 2.0 * ((float) random () / RANDOM_MAX - 0.5); // uniformly (-1, 1)
+}
+
+static void
+random_floats (float *buf, unsigned n)
+{
+  for (unsigned i = 0; i < n; i++)
+    buf[i] = rint (uniform () * 32767);
+}
+
+static void
+zero_floats (float *buf, unsigned n)
+{
+  for (unsigned i = 0; i < n; i++)
+    buf[i] = 0.0;
+}
+
+void
+ref_ccomplex_dotprod (const float *input,
+                     const float *taps, unsigned n_2_ccomplex_blocks,
+                     float *result)
+{
+  float sum0[2] = {0,0};
+  float sum1[2] = {0,0};
+
+  do {
+
+    sum0[0] += input[0] * taps[0] - input[1] * taps[1];
+    sum0[1] += input[0] * taps[1] + input[1] * taps[0];
+    sum1[0] += input[2] * taps[2] - input[3] * taps[3];
+    sum1[1] += input[2] * taps[3] + input[3] * taps[2];
+
+    input += 4;
+    taps += 4;
+
+  } while (--n_2_ccomplex_blocks != 0);
+
+
+  result[0] = sum0[0] + sum1[0];
+  result[1] = sum0[1] + sum1[1];
+}
+
+void 
+qa_ccomplex_dotprod_x86::setUp ()
+{
+  taps = (float *) calloc16Align (MAX_BLKS, 
+                                 sizeof (float) * FLOATS_PER_BLK);
+
+  input = (float *) calloc16Align (MAX_BLKS,
+                                  sizeof (float) * FLOATS_PER_BLK);
+
+  if (taps == 0 || input == 0)
+    abort ();
+}
+
+void
+qa_ccomplex_dotprod_x86::tearDown ()
+{
+  free16Align (taps);
+  free16Align (input);
+  taps = 0;
+  input = 0;
+}
+
+
+void 
+qa_ccomplex_dotprod_x86::zb () // "zero both"
+{
+  zero_floats (taps, MAX_BLKS * FLOATS_PER_BLK);
+  zero_floats (input, MAX_BLKS * FLOATS_PER_BLK);
+}
+
+// 
+// t1 
+//
+
+void
+qa_ccomplex_dotprod_x86::t1_base (ccomplex_dotprod_t ccomplex_dotprod)
+{
+  float result[2];
+
+  // cerr << "Testing dump_xmm_regs\n";
+  // dump_xmm_regs ();
+
+  // test basic cases, 1 block
+
+  zb ();
+  ccomplex_dotprod (input, taps, 1, result);
+  assertcomplexEqual (0.0, 0.0, result, ERR_DELTA);
+
+  // vary each input
+
+  zb ();
+  input[0] = 1.0;      taps[0] = 1.0; taps[1] = -1.0;
+  ccomplex_dotprod (input, taps, 1, result);
+  //cerr << result[0] << " " << result[1] << "\n";
+  assertcomplexEqual (1.0, -1.0, result, ERR_DELTA);
+  
+  zb ();
+  input[1] = 2.0;      taps[0] = 1.0; taps[1] = -1.0;
+  ccomplex_dotprod (input, taps, 1, result);
+  assertcomplexEqual (2.0, 2.0, result, ERR_DELTA);
+
+  zb ();
+  input[2] = 3.0;      taps[2] = 1.0; taps[3] = -1.0;
+  ccomplex_dotprod (input, taps, 1, result);
+  assertcomplexEqual (3.0, -3.0, result, ERR_DELTA);
+  
+  zb ();
+  input[3] = 4.0;      taps[2] = 1.0; taps[3] = -1.0;
+  ccomplex_dotprod (input, taps, 1, result);
+  assertcomplexEqual (4.0, 4.0, result, ERR_DELTA);
+
+  // vary each tap
+
+  zb ();
+  input[0] = 1.0;      taps[0] = 0.5; taps[1] = -0.5;
+  ccomplex_dotprod (input, taps, 1, result);
+  assertcomplexEqual (0.5, -0.5, result, ERR_DELTA);
+  
+  zb ();
+  input[0] = 1.0;      taps[0] = 2.0; taps[1] = -2.0;
+  ccomplex_dotprod (input, taps, 1, result);
+  assertcomplexEqual (2.0, -2.0, result, ERR_DELTA);
+  
+  zb ();
+  input[0] = 1.0;      taps[0] = 3.0; taps[1] = -3.0;
+  ccomplex_dotprod (input, taps, 1, result);
+  assertcomplexEqual (3.0, -3.0, result, ERR_DELTA);
+  
+  zb ();
+  input[0] = 1.0;      taps[0] = 4.0; taps[1] = -4.0;
+  ccomplex_dotprod (input, taps, 1, result);
+  assertcomplexEqual (4.0, -4.0, result, ERR_DELTA);
+}
+
+// 
+// t2 
+//
+void
+qa_ccomplex_dotprod_x86::t2_base (ccomplex_dotprod_t ccomplex_dotprod)
+{
+  float result[2];
+
+  zb ();
+  input[0] =  1.0; input[1] =  3.0;    taps[0] =  5.0; taps[1] =  -2.0;
+
+  //1*5-3*-2 =11, 1*-2+3*5=13
+  ccomplex_dotprod (input, taps, 1, result);
+  assertcomplexEqual (11.0, 13.0, result, ERR_DELTA);
+
+  //7*5-13*-5 =100, 7*-5+13*5=30
+
+  input[2] =  7.0; input[3] = 13.0;    taps[2] =  5.0; taps[3] =  -5.0;
+
+  ccomplex_dotprod (input, taps, 1, result);
+  assertcomplexEqual (111.0, 43.0, result, ERR_DELTA);
+
+  input[4] = 19; input[5] = -19;       taps[4] = 23.0; taps[5] = -23.0;
+
+  //19*23--19*-23 =0, 19*-23+-19*23=-874
+
+  ccomplex_dotprod (input, taps, 2, result);
+  assertcomplexEqual (111.0, -831.0, result, ERR_DELTA);
+  
+}
+
+//
+// t3
+//
+void
+qa_ccomplex_dotprod_x86::t3_base (ccomplex_dotprod_t ccomplex_dotprod)
+{
+  srandom (0); // we want reproducibility
+
+  for (unsigned int i = 0; i < 10; i++){
+    random_floats (input, MAX_BLKS * FLOATS_PER_BLK);
+    random_floats (taps, MAX_BLKS * FLOATS_PER_BLK);
+
+    // we use a sloppy error margin because on the x86 architecture,
+    // our reference implementation is using 80 bit floating point
+    // arithmetic, while the SSE version is using 32 bit float point
+    // arithmetic.
+
+    float ref[2];
+    ref_ccomplex_dotprod (input, taps, MAX_BLKS, ref);
+    float calc[2];
+    ccomplex_dotprod (input, taps, MAX_BLKS, calc);
+    CPPUNIT_ASSERT_DOUBLES_EQUAL (ref[0],
+                       calc[0],
+                       fabs (ref[0]) * 1e-4);
+    CPPUNIT_ASSERT_DOUBLES_EQUAL (ref[1],
+                       calc[1],
+                       fabs (ref[1]) * 1e-4);
+  }
+}
+
+void
+qa_ccomplex_dotprod_x86::t1_3dnowext ()
+{
+  if (!gr_cpu::has_3dnowext ()){
+    cerr << "No 3DNow!Ext support; not tested\n";
+  }
+  else
+    t1_base (ccomplex_dotprod_3dnowext);
+}
+
+void 
+qa_ccomplex_dotprod_x86::t2_3dnowext ()
+{
+  if (!gr_cpu::has_3dnowext ()){
+    cerr << "No 3DNow!Ext support; not tested\n";
+  }
+  else
+    t2_base (ccomplex_dotprod_3dnowext);
+}
+
+void 
+qa_ccomplex_dotprod_x86::t3_3dnowext ()
+{
+  if (!gr_cpu::has_3dnowext ()){
+    cerr << "No 3DNow!Ext support; not tested\n";
+  }
+  else
+    t3_base (ccomplex_dotprod_3dnowext);
+}
+
+void
+qa_ccomplex_dotprod_x86::t1_3dnow ()
+{
+  if (!gr_cpu::has_3dnow ()){
+    cerr << "No 3DNow! support; not tested\n";
+  }
+  else
+    t1_base (ccomplex_dotprod_3dnow);
+}
+
+void 
+qa_ccomplex_dotprod_x86::t2_3dnow ()
+{
+  if (!gr_cpu::has_3dnow ()){
+    cerr << "No 3DNow! support; not tested\n";
+  }
+  else
+    t2_base (ccomplex_dotprod_3dnow);
+}
+
+void 
+qa_ccomplex_dotprod_x86::t3_3dnow ()
+{
+  if (!gr_cpu::has_3dnow ()){
+    cerr << "No 3DNow! support; not tested\n";
+  }
+  else
+    t3_base (ccomplex_dotprod_3dnow);
+}
+
+void 
+qa_ccomplex_dotprod_x86::t1_sse ()
+{
+  if (!gr_cpu::has_sse ()){
+    cerr << "No SSE support; not tested\n";
+  }
+  else
+    t1_base (ccomplex_dotprod_sse);
+}
+
+void 
+qa_ccomplex_dotprod_x86::t2_sse ()
+{
+  if (!gr_cpu::has_sse ()){
+    cerr << "No SSE support; not tested\n";
+  }
+  else
+    t2_base (ccomplex_dotprod_sse);
+}
+
+void 
+qa_ccomplex_dotprod_x86::t3_sse ()
+{
+  if (!gr_cpu::has_sse ()){
+    cerr << "No SSE support; not tested\n";
+  }
+  else
+    t3_base (ccomplex_dotprod_sse);
+}
+
diff --git a/gnuradio-core/src/lib/filter/qa_ccomplex_dotprod_x86.h b/gnuradio-core/src/lib/filter/qa_ccomplex_dotprod_x86.h
new file mode 100644 (file)
index 0000000..f10f006
--- /dev/null
@@ -0,0 +1,74 @@
+/* -*- 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 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.
+ */
+#ifndef _QA_CCOMPLEX_DOTPROD_X86_H_
+#define _QA_CCOMPLEX_DOTPROD_X86_H_
+
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/TestCase.h>
+
+class qa_ccomplex_dotprod_x86 : public CppUnit::TestCase {
+ public:
+  void setUp            ();
+  void tearDown         ();
+
+  CPPUNIT_TEST_SUITE (qa_ccomplex_dotprod_x86);
+  CPPUNIT_TEST (t1_3dnowext);
+  CPPUNIT_TEST (t2_3dnowext);
+  CPPUNIT_TEST (t3_3dnowext);
+  CPPUNIT_TEST (t1_3dnow);
+  CPPUNIT_TEST (t2_3dnow);
+  CPPUNIT_TEST (t3_3dnow);
+  CPPUNIT_TEST (t1_sse);
+  CPPUNIT_TEST (t2_sse);
+  CPPUNIT_TEST (t3_sse);
+  CPPUNIT_TEST_SUITE_END ();
+
+ private:
+
+  void t1_3dnowext ();
+  void t2_3dnowext ();
+  void t3_3dnowext ();
+  void t1_3dnow ();
+  void t2_3dnow ();
+  void t3_3dnow ();
+  void t1_sse ();
+  void t2_sse ();
+  void t3_sse ();
+
+
+  typedef void (*ccomplex_dotprod_t)(const float *input,
+                                  const float *taps,
+                                  unsigned n_2_ccomplex_blocks,
+                                  float *result);
+
+  void t1_base (ccomplex_dotprod_t);
+  void t2_base (ccomplex_dotprod_t);
+  void t3_base (ccomplex_dotprod_t);
+
+  void zb ();
+
+  float        *taps;          // 16-byte aligned
+  float *input;                // 16-byte aligned
+};
+
+
+#endif /* _QA_CCOMPLEX_DOTPROD_X86_H_ */
diff --git a/gnuradio-core/src/lib/filter/qa_complex_dotprod_x86.cc b/gnuradio-core/src/lib/filter/qa_complex_dotprod_x86.cc
new file mode 100644 (file)
index 0000000..91c8e9e
--- /dev/null
@@ -0,0 +1,347 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <cppunit/TestAssert.h>
+#include <qa_complex_dotprod_x86.h>
+#include <complex_dotprod_x86.h>
+#include <string.h>
+#include <iostream>
+#include <malloc16.h>
+#include <sse_debug.h>
+#include <cmath>
+#include <gr_cpu.h>
+#include <random.h>
+
+using std::cerr;
+
+/// Macro for primitive value comparisons
+#define assertcomplexEqual(expected0,expected1,actual,delta)   \
+  CPPUNIT_ASSERT_DOUBLES_EQUAL (expected0, actual[0], delta);  \
+  CPPUNIT_ASSERT_DOUBLES_EQUAL (expected1, actual[1], delta);  
+
+
+#define        MAX_BLKS        10
+#define        FLOATS_PER_BLK   4
+#define        SHORTS_PER_BLK   2
+
+#define        ERR_DELTA       (1e-6)
+
+static float
+uniform ()
+{
+  return 2.0 * ((float) random () / RANDOM_MAX - 0.5); // uniformly (-1, 1)
+}
+
+static void
+random_floats (float *buf, unsigned n)
+{
+  for (unsigned i = 0; i < n; i++)
+    buf[i] = rint (uniform () * 32767);
+}
+
+static void
+zero_floats (float *buf, unsigned n)
+{
+  for (unsigned i = 0; i < n; i++)
+    buf[i] = 0.0;
+}
+
+static void
+random_shorts (short *buf, unsigned n)
+{
+  for (unsigned i = 0; i < n; i++)
+    buf[i] = (short) rint (uniform () * 32767);
+}
+
+static void
+zero_shorts (short *buf, unsigned n)
+{
+  for (unsigned i = 0; i < n; i++)
+    buf[i] = 0;
+}
+
+void
+ref_complex_dotprod (const short *input,
+                  const float *taps, unsigned n_2_complex_blocks,
+                  float *result)
+{
+  float sum0[2] = {0,0};
+  float sum1[2] = {0,0};
+
+  do {
+
+    sum0[0] += input[0] * taps[0];
+    sum0[1] += input[0] * taps[1];
+    sum1[0] += input[1] * taps[2];
+    sum1[1] += input[1] * taps[3];
+
+    input += 2;
+    taps += 4;
+
+  } while (--n_2_complex_blocks != 0);
+
+
+  result[0] = sum0[0] + sum1[0];
+  result[1] = sum0[1] + sum1[1];
+}
+
+void 
+qa_complex_dotprod_x86::setUp ()
+{
+  taps = (float *) calloc16Align (MAX_BLKS, 
+                                 sizeof (float) * FLOATS_PER_BLK);
+
+  input = (short *) calloc16Align (MAX_BLKS,
+                                  sizeof (short) * SHORTS_PER_BLK);
+
+  if (taps == 0 || input == 0)
+    abort ();
+}
+
+void
+qa_complex_dotprod_x86::tearDown ()
+{
+  free16Align (taps);
+  free16Align (input);
+  taps = 0;
+  input = 0;
+}
+
+
+void 
+qa_complex_dotprod_x86::zb ()  // "zero both"
+{
+  zero_floats (taps, MAX_BLKS * FLOATS_PER_BLK);
+  zero_shorts (input, MAX_BLKS * SHORTS_PER_BLK);
+}
+
+// 
+// t1 
+//
+
+void
+qa_complex_dotprod_x86::t1_base (complex_dotprod_t complex_dotprod)
+{
+  float result[2];
+
+  // cerr << "Testing dump_xmm_regs\n";
+  // dump_xmm_regs ();
+
+  // test basic cases, 1 block
+
+  zb ();
+  complex_dotprod (input, taps, 1, result);
+  assertcomplexEqual (0.0, 0.0, result, ERR_DELTA);
+
+  // vary each input
+
+  zb ();
+  input[0] = 1;        taps[0] = 1.0; taps[1] = -1.0;
+  complex_dotprod (input, taps, 1, result);
+  //cerr << result[0] << " " << result[1] << "\n";
+  assertcomplexEqual (1.0, -1.0, result, ERR_DELTA);
+  
+  zb ();
+  input[1] = 2;        taps[2] = 1.0; taps[3] = -1.0;
+  complex_dotprod (input, taps, 1, result);
+  assertcomplexEqual (2.0, -2.0, result, ERR_DELTA);
+
+  zb ();
+  input[2] = 3;        taps[4] = 1.0; taps[5] = -1.0;
+  complex_dotprod (input, taps, 2, result);
+  assertcomplexEqual (3.0, -3.0, result, ERR_DELTA);
+  
+  zb ();
+  input[3] = 4;        taps[6] = 1.0; taps[7] = -1.0;
+  complex_dotprod (input, taps, 2, result);
+  assertcomplexEqual (4.0, -4.0, result, ERR_DELTA);
+
+  // vary each tap
+
+  zb ();
+  input[0] = 1;        taps[0] = 0.5; taps[1] = -0.5;
+  complex_dotprod (input, taps, 1, result);
+  assertcomplexEqual (0.5, -0.5, result, ERR_DELTA);
+  
+  zb ();
+  input[0] = 1;        taps[0] = 2.0; taps[1] = -2.0;
+  complex_dotprod (input, taps, 1, result);
+  assertcomplexEqual (2.0, -2.0, result, ERR_DELTA);
+  
+  zb ();
+  input[0] = 1;        taps[0] = 3.0; taps[1] = -3.0;
+  complex_dotprod (input, taps, 1, result);
+  assertcomplexEqual (3.0, -3.0, result, ERR_DELTA);
+  
+  zb ();
+  input[0] = 1;        taps[0] = 4.0; taps[1] = -4.0;
+  complex_dotprod (input, taps, 1, result);
+  assertcomplexEqual (4.0, -4.0, result, ERR_DELTA);
+}
+
+// 
+// t2 
+//
+void
+qa_complex_dotprod_x86::t2_base (complex_dotprod_t complex_dotprod)
+{
+  float result[2];
+
+  zb ();
+  input[0] =  1;       taps[0] =  2.0; taps[1] =  -2.0;
+  input[1] =  3;       taps[2] =  5.0; taps[3] =  -5.0;
+  input[2] =  7;       taps[4] = 11.0; taps[5] =  -11.0;
+  input[3] = 13;       taps[6] = 17.0; taps[7] =  -17.0;
+
+  complex_dotprod (input, taps, 2, result);
+  assertcomplexEqual (315.0, -315.0, result, ERR_DELTA);
+
+  input[4] = 19;       taps[8] = 23.0; taps[9] = -23.0;
+  complex_dotprod (input, taps, 3, result);
+  assertcomplexEqual (752.0, -752.0, result, ERR_DELTA);
+  
+}
+
+//
+// t3
+//
+void
+qa_complex_dotprod_x86::t3_base (complex_dotprod_t complex_dotprod)
+{
+  srandom (0); // we want reproducibility
+
+  for (unsigned int i = 0; i < 10; i++){
+    random_shorts (input, MAX_BLKS * SHORTS_PER_BLK);
+    random_floats (taps, MAX_BLKS * FLOATS_PER_BLK);
+
+    // we use a sloppy error margin because on the x86 architecture,
+    // our reference implementation is using 80 bit floating point
+    // arithmetic, while the SSE version is using 32 bit float point
+    // arithmetic.
+
+    float ref[2];
+    ref_complex_dotprod (input, taps, MAX_BLKS, ref);
+    float calc[2];
+    complex_dotprod (input, taps, MAX_BLKS, calc);
+    CPPUNIT_ASSERT_DOUBLES_EQUAL (ref[0],
+                       calc[0],
+                       fabs (ref[0]) * 1e-4);
+    CPPUNIT_ASSERT_DOUBLES_EQUAL (ref[1],
+                       calc[1],
+                       fabs (ref[1]) * 1e-4);
+  }
+}
+
+void
+qa_complex_dotprod_x86::t1_3dnowext ()
+{
+  if (!gr_cpu::has_3dnowext ()){
+    cerr << "No 3DNow!Ext support; not tested\n";
+  }
+  else
+    t1_base (complex_dotprod_3dnowext);
+}
+
+void 
+qa_complex_dotprod_x86::t2_3dnowext ()
+{
+  if (!gr_cpu::has_3dnowext ()){
+    cerr << "No 3DNow!Ext support; not tested\n";
+  }
+  else
+    t2_base (complex_dotprod_3dnowext);
+}
+
+void 
+qa_complex_dotprod_x86::t3_3dnowext ()
+{
+  if (!gr_cpu::has_3dnowext ()){
+    cerr << "No 3DNow!Ext support; not tested\n";
+  }
+  else
+    t3_base (complex_dotprod_3dnowext);
+}
+
+void
+qa_complex_dotprod_x86::t1_3dnow ()
+{
+  if (!gr_cpu::has_3dnow ()){
+    cerr << "No 3DNow! support; not tested\n";
+  }
+  else
+    t1_base (complex_dotprod_3dnow);
+}
+
+void 
+qa_complex_dotprod_x86::t2_3dnow ()
+{
+  if (!gr_cpu::has_3dnow ()){
+    cerr << "No 3DNow! support; not tested\n";
+  }
+  else
+    t2_base (complex_dotprod_3dnow);
+}
+
+void 
+qa_complex_dotprod_x86::t3_3dnow ()
+{
+  if (!gr_cpu::has_3dnow ()){
+    cerr << "No 3DNow! support; not tested\n";
+  }
+  else
+    t3_base (complex_dotprod_3dnow);
+}
+
+void 
+qa_complex_dotprod_x86::t1_sse ()
+{
+  if (!gr_cpu::has_sse ()){
+    cerr << "No SSE support; not tested\n";
+  }
+  else
+    t1_base (complex_dotprod_sse);
+}
+
+void 
+qa_complex_dotprod_x86::t2_sse ()
+{
+  if (!gr_cpu::has_sse ()){
+    cerr << "No SSE support; not tested\n";
+  }
+  else
+    t2_base (complex_dotprod_sse);
+}
+
+void 
+qa_complex_dotprod_x86::t3_sse ()
+{
+  if (!gr_cpu::has_sse ()){
+    cerr << "No SSE support; not tested\n";
+  }
+  else
+    t3_base (complex_dotprod_sse);
+}
+
diff --git a/gnuradio-core/src/lib/filter/qa_complex_dotprod_x86.h b/gnuradio-core/src/lib/filter/qa_complex_dotprod_x86.h
new file mode 100644 (file)
index 0000000..53509ea
--- /dev/null
@@ -0,0 +1,74 @@
+/* -*- 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 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.
+ */
+#ifndef _QA_COMPLEX_DOTPROD_X86_H_
+#define _QA_COMPLEX_DOTPROD_X86_H_
+
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/TestCase.h>
+
+class qa_complex_dotprod_x86 : public CppUnit::TestCase {
+ public:
+  void setUp            ();
+  void tearDown         ();
+
+  CPPUNIT_TEST_SUITE (qa_complex_dotprod_x86);
+  CPPUNIT_TEST (t1_3dnowext);
+  CPPUNIT_TEST (t2_3dnowext);
+  CPPUNIT_TEST (t3_3dnowext);
+  CPPUNIT_TEST (t1_3dnow);
+  CPPUNIT_TEST (t2_3dnow);
+  CPPUNIT_TEST (t3_3dnow);
+  CPPUNIT_TEST (t1_sse);
+  CPPUNIT_TEST (t2_sse);
+  CPPUNIT_TEST (t3_sse);
+  CPPUNIT_TEST_SUITE_END ();
+
+ private:
+
+  void t1_3dnowext ();
+  void t2_3dnowext ();
+  void t3_3dnowext ();
+  void t1_3dnow ();
+  void t2_3dnow ();
+  void t3_3dnow ();
+  void t1_sse ();
+  void t2_sse ();
+  void t3_sse ();
+
+
+  typedef void (*complex_dotprod_t)(const short *input,
+                                  const float *taps,
+                                  unsigned n_2_complex_blocks,
+                                  float *result);
+
+  void t1_base (complex_dotprod_t);
+  void t2_base (complex_dotprod_t);
+  void t3_base (complex_dotprod_t);
+
+  void zb ();
+
+  float        *taps;          // 16-byte aligned
+  short *input;                // 16-byte aligned
+};
+
+
+#endif /* _QA_COMPLEX_DOTPROD_X86_H_ */
diff --git a/gnuradio-core/src/lib/filter/qa_dotprod.h b/gnuradio-core/src/lib/filter/qa_dotprod.h
new file mode 100644 (file)
index 0000000..3fbbdc3
--- /dev/null
@@ -0,0 +1,30 @@
+/* -*- 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 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.
+ */
+#ifndef _QA_DOTPROD_H_
+#define        _QA_DOTPROD_H_
+
+#include <cppunit/TestSuite.h>
+
+CppUnit::TestSuite *qa_dotprod_suite ();
+
+#endif // _QA_DOTPROD_H_
+
diff --git a/gnuradio-core/src/lib/filter/qa_dotprod_generic.cc b/gnuradio-core/src/lib/filter/qa_dotprod_generic.cc
new file mode 100644 (file)
index 0000000..d0f66cc
--- /dev/null
@@ -0,0 +1,32 @@
+/* -*- 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 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.
+ */
+#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/qa_dotprod_x86.cc b/gnuradio-core/src/lib/filter/qa_dotprod_x86.cc
new file mode 100644 (file)
index 0000000..6aeb493
--- /dev/null
@@ -0,0 +1,37 @@
+/* -*- 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 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.
+ */
+#include "qa_dotprod.h"
+#include "qa_float_dotprod_x86.h"
+#include "qa_complex_dotprod_x86.h"
+#include "qa_ccomplex_dotprod_x86.h"
+
+CppUnit::TestSuite *
+qa_dotprod_suite ()
+{
+  CppUnit::TestSuite *s = new CppUnit::TestSuite ("dotprod");
+
+  s->addTest (qa_float_dotprod_x86::suite ());
+  s->addTest (qa_complex_dotprod_x86::suite ());
+  s->addTest (qa_ccomplex_dotprod_x86::suite ());
+
+  return s;
+}
diff --git a/gnuradio-core/src/lib/filter/qa_filter.cc b/gnuradio-core/src/lib/filter/qa_filter.cc
new file mode 100644 (file)
index 0000000..75415a7
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * 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 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 class gathers together all the test cases for the gr
+ * directory into a single test suite.  As you create new test cases,
+ * add them here.
+ */
+
+#include <qa_filter.h>
+#include <qa_gr_fir_ccf.h>
+#include <qa_gr_fir_fff.h>
+#include <qa_gr_fir_ccc.h>
+#include <qa_gr_fir_fcc.h>
+#include <qa_gr_fir_scc.h>
+#include <qa_gr_firdes.h>
+#include <qa_dotprod.h>
+#include <qa_gri_mmse_fir_interpolator.h>
+
+CppUnit::TestSuite *
+qa_filter::suite ()
+{
+  CppUnit::TestSuite   *s = new CppUnit::TestSuite ("filter");
+
+  s->addTest (qa_dotprod_suite ());
+  s->addTest (qa_gri_mmse_fir_interpolator::suite ());
+  s->addTest (qa_gr_fir_fff::suite ());
+  s->addTest (qa_gr_fir_ccc::suite ());
+  s->addTest (qa_gr_fir_fcc::suite ());
+  s->addTest (qa_gr_fir_scc::suite ());
+  s->addTest (qa_gr_fir_ccf::suite ());
+
+  return s;
+}
diff --git a/gnuradio-core/src/lib/filter/qa_filter.h b/gnuradio-core/src/lib/filter/qa_filter.h
new file mode 100644 (file)
index 0000000..71371ae
--- /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 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.
+ */
+
+#ifndef _QA_FILTER_H_
+#define _QA_FILTER_H_
+
+#include <cppunit/TestSuite.h>
+
+//! collect all the tests for the gr directory
+
+class qa_filter {
+ public:
+  //! return suite of tests for all of gr directory
+  static CppUnit::TestSuite *suite ();
+};
+
+
+#endif /* _QA_FILTER_H_ */
diff --git a/gnuradio-core/src/lib/filter/qa_float_dotprod_x86.cc b/gnuradio-core/src/lib/filter/qa_float_dotprod_x86.cc
new file mode 100644 (file)
index 0000000..a169779
--- /dev/null
@@ -0,0 +1,270 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <cppunit/TestAssert.h>
+#include <qa_float_dotprod_x86.h>
+#include <float_dotprod_x86.h>
+#include <string.h>
+#include <iostream>
+#include <malloc16.h>
+#include <sse_debug.h>
+#include <cmath>
+#include <gr_cpu.h>
+#include <random.h>
+
+using std::cerr;
+
+
+#define        MAX_BLKS        10
+#define        FLOATS_PER_BLK   4
+
+#define        ERR_DELTA       (1e-6)
+
+
+static void
+random_floats (float *buf, unsigned n)
+{
+  for (unsigned i = 0; i < n; i++)
+    buf[i] = random () - RANDOM_MAX/2;
+}
+
+static void
+zero_floats (float *buf, unsigned n)
+{
+  for (unsigned i = 0; i < n; i++)
+    buf[i] = 0.0;
+}
+
+float 
+ref_float_dotprod (const float *input,
+                  const float *taps, unsigned n_4_float_blocks)
+{
+  float sum0 = 0;
+  float sum1 = 0;
+  float sum2 = 0;
+  float sum3 = 0;
+
+  do {
+
+    sum0 += input[0] * taps[0];
+    sum1 += input[1] * taps[1];
+    sum2 += input[2] * taps[2];
+    sum3 += input[3] * taps[3];
+
+    input += 4;
+    taps += 4;
+
+  } while (--n_4_float_blocks != 0);
+
+
+  return sum0 + sum1 + sum2 + sum3;
+}
+
+void 
+qa_float_dotprod_x86::setUp ()
+{
+  taps = (float *) calloc16Align (MAX_BLKS, 
+                                 sizeof (float) * FLOATS_PER_BLK);
+
+  input = (float *) calloc16Align (MAX_BLKS,
+                                  sizeof (float) * FLOATS_PER_BLK);
+
+  if (taps == 0 || input == 0)
+    abort ();
+}
+
+void
+qa_float_dotprod_x86::tearDown ()
+{
+  free16Align (taps);
+  free16Align (input);
+  taps = 0;
+  input = 0;
+}
+
+
+void 
+qa_float_dotprod_x86::zb ()    // "zero both"
+{
+  zero_floats (taps, MAX_BLKS * FLOATS_PER_BLK);
+  zero_floats (input, MAX_BLKS * FLOATS_PER_BLK);
+}
+
+// 
+// t1 
+//
+
+void
+qa_float_dotprod_x86::t1_base (float_dotprod_t float_dotprod)
+{
+  
+  // cerr << "Testing dump_xmm_regs\n";
+  // dump_xmm_regs ();
+
+  // test basic cases, 1 block
+
+  zb ();
+  CPPUNIT_ASSERT_DOUBLES_EQUAL (0.0, float_dotprod (input, taps, 1), ERR_DELTA);
+
+  // vary each input
+
+  zb ();
+  input[0] = 0.5;      taps[0] = 1.0;
+  CPPUNIT_ASSERT_DOUBLES_EQUAL (0.5, float_dotprod (input, taps, 1), ERR_DELTA);
+  
+  zb ();
+  input[1] = 2.0;      taps[1] = 1.0;
+  CPPUNIT_ASSERT_DOUBLES_EQUAL (2.0, float_dotprod (input, taps, 1), ERR_DELTA);
+  
+  zb ();
+  input[2] = 3.0;      taps[2] = 1.0;
+  CPPUNIT_ASSERT_DOUBLES_EQUAL (3.0, float_dotprod (input, taps, 1), ERR_DELTA);
+  
+  zb ();
+  input[3] = 4.0;      taps[3] = 1.0;
+  CPPUNIT_ASSERT_DOUBLES_EQUAL (4.0, float_dotprod (input, taps, 1), ERR_DELTA);
+  
+  // vary each tap
+
+  zb ();
+  input[0] = 1.0;      taps[0] = 0.5;
+  CPPUNIT_ASSERT_DOUBLES_EQUAL (0.5, float_dotprod (input, taps, 1), ERR_DELTA);
+  
+  zb ();
+  input[0] = 1.0;      taps[0] = 2.0;
+  CPPUNIT_ASSERT_DOUBLES_EQUAL (2.0, float_dotprod (input, taps, 1), ERR_DELTA);
+  
+  zb ();
+  input[0] = 1.0;      taps[0] = 3.0;
+  CPPUNIT_ASSERT_DOUBLES_EQUAL (3.0, float_dotprod (input, taps, 1), ERR_DELTA);
+  
+  zb ();
+  input[0] = 1.0;      taps[0] = 4.0;
+  CPPUNIT_ASSERT_DOUBLES_EQUAL (4.0, float_dotprod (input, taps, 1), ERR_DELTA);
+}
+
+// 
+// t2 
+//
+void
+qa_float_dotprod_x86::t2_base (float_dotprod_t float_dotprod)
+{
+  zb ();
+  input[0] =  1.0;     taps[0] =  2.0;
+  input[1] =  3.0;     taps[1] =  5.0;
+  input[2] =  7.0;     taps[2] = 11.0;
+  input[3] = 13.0;     taps[3] = 17.0;
+
+  CPPUNIT_ASSERT_DOUBLES_EQUAL (315.0, float_dotprod (input, taps, 1), ERR_DELTA);
+
+  input[4] = 19.0;     taps[4] = 23.0;
+  CPPUNIT_ASSERT_DOUBLES_EQUAL (752.0, float_dotprod (input, taps, 2), ERR_DELTA);
+  
+}
+
+//
+// t3
+//
+void
+qa_float_dotprod_x86::t3_base (float_dotprod_t float_dotprod)
+{
+  srandom (0); // we want reproducibility
+
+  for (unsigned int i = 0; i < 10; i++){
+    random_floats (input, MAX_BLKS * FLOATS_PER_BLK);
+    random_floats (taps, MAX_BLKS * FLOATS_PER_BLK);
+
+    // we use a sloppy error margin because on the x86 architecture,
+    // our reference implementation is using 80 bit floating point
+    // arithmetic, while the SSE version is using 32 bit float point
+    // arithmetic.
+
+    float ref = ref_float_dotprod (input, taps, MAX_BLKS);
+    CPPUNIT_ASSERT_DOUBLES_EQUAL (ref,
+                       float_dotprod (input, taps, MAX_BLKS),
+                       fabs (ref) * 1e-4);
+  }
+}
+
+void
+qa_float_dotprod_x86::t1_3dnow ()
+{
+  if (!gr_cpu::has_3dnow ()){
+    cerr << "No 3DNow! support; not tested\n";
+  }
+  else
+    t1_base (float_dotprod_3dnow);
+}
+
+void 
+qa_float_dotprod_x86::t2_3dnow ()
+{
+  if (!gr_cpu::has_3dnow ()){
+    cerr << "No 3DNow! support; not tested\n";
+  }
+  else
+    t2_base (float_dotprod_3dnow);
+}
+
+void 
+qa_float_dotprod_x86::t3_3dnow ()
+{
+  if (!gr_cpu::has_3dnow ()){
+    cerr << "No 3DNow! support; not tested\n";
+  }
+  else
+    t3_base (float_dotprod_3dnow);
+}
+
+void 
+qa_float_dotprod_x86::t1_sse ()
+{
+  if (!gr_cpu::has_sse ()){
+    cerr << "No SSE support; not tested\n";
+  }
+  else
+    t1_base (float_dotprod_sse);
+}
+
+void 
+qa_float_dotprod_x86::t2_sse ()
+{
+  if (!gr_cpu::has_sse ()){
+    cerr << "No SSE support; not tested\n";
+  }
+  else
+    t2_base (float_dotprod_sse);
+}
+
+void 
+qa_float_dotprod_x86::t3_sse ()
+{
+  if (!gr_cpu::has_sse ()){
+    cerr << "No SSE support; not tested\n";
+  }
+  else
+    t3_base (float_dotprod_sse);
+}
diff --git a/gnuradio-core/src/lib/filter/qa_float_dotprod_x86.h b/gnuradio-core/src/lib/filter/qa_float_dotprod_x86.h
new file mode 100644 (file)
index 0000000..0056812
--- /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 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.
+ */
+#ifndef _QA_FLOAT_DOTPROD_X86_H_
+#define _QA_FLOAT_DOTPROD_X86_H_
+
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/TestCase.h>
+
+class qa_float_dotprod_x86 : public CppUnit::TestCase {
+ public:
+  void setUp            ();
+  void tearDown         ();
+
+  CPPUNIT_TEST_SUITE (qa_float_dotprod_x86);
+  CPPUNIT_TEST (t1_3dnow);
+  CPPUNIT_TEST (t2_3dnow);
+  CPPUNIT_TEST (t3_3dnow);
+  CPPUNIT_TEST (t1_sse);
+  CPPUNIT_TEST (t2_sse);
+  CPPUNIT_TEST (t3_sse);
+  CPPUNIT_TEST_SUITE_END ();
+
+ private:
+
+  void t1_3dnow ();
+  void t2_3dnow ();
+  void t3_3dnow ();
+  void t1_sse ();
+  void t2_sse ();
+  void t3_sse ();
+
+
+  typedef float (*float_dotprod_t)(const float *input,
+                                  const float *taps,
+                                  unsigned n_4_float_blocks);
+
+  void t1_base (float_dotprod_t);
+  void t2_base (float_dotprod_t);
+  void t3_base (float_dotprod_t);
+
+  
+  void zb ();
+
+  float        *taps;          // 16-byte aligned
+  float *input;                // 16-byte aligned
+
+};
+
+
+#endif /* _QA_FLOAT_DOTPROD_X86_H_ */
diff --git a/gnuradio-core/src/lib/filter/qa_gr_fir_ccc.cc b/gnuradio-core/src/lib/filter/qa_gr_fir_ccc.cc
new file mode 100644 (file)
index 0000000..9c70a16
--- /dev/null
@@ -0,0 +1,183 @@
+/* -*- 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 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.
+ */
+
+/*
+ * FIXME.  This code is virtually identical to qa_gr_fir_?CC.cc
+ *   Kludge up some kind of macro to handle the minor differences.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <gr_types.h>
+
+typedef gr_complex     i_type;
+typedef gr_complex     o_type;
+typedef gr_complex     tap_type;
+typedef        gr_complex      acc_type;
+
+
+#include <qa_gr_fir_ccc.h>
+#include <gr_fir_ccc.h>
+#include <gr_fir_util.h>
+#include <string.h>
+#include <iostream>
+#include <cmath>
+#include <gr_types.h>
+#include <cppunit/TestAssert.h>
+#include <random.h>
+#include <malloc16.h>
+
+using std::vector;
+
+#define        ERR_DELTA       (1e-5)
+
+#define        NELEM(x) (sizeof (x) / sizeof (x[0]))
+
+//
+// typedef for something logically "pointer to constructor".
+// there may be a better way, please let me know...
+//
+typedef gr_fir_ccc* (*fir_maker_t)(const std::vector<tap_type> &taps);
+
+
+static float
+uniform ()
+{
+  return 2.0 * ((float) random () / RANDOM_MAX - 0.5); // uniformly (-1, 1)
+}
+
+static void
+random_input (i_type *buf, unsigned n)
+{
+  for (unsigned i = 0; i < n; i++)
+    buf[i] = (i_type) rint (uniform () * 32767);
+}
+
+static void
+random_complex (gr_complex *buf, unsigned n)
+{
+  for (unsigned i = 0; i < n; i++){
+    float re = rint (uniform () * 32767);
+    float im = rint (uniform () * 32767);
+    buf[i] = gr_complex (re, im);
+  }
+}
+
+static o_type
+ref_dotprod (const i_type input[], const tap_type taps[], int ntaps)
+{
+  acc_type     sum = 0;
+  for (int i = 0; i < ntaps; i++)
+    sum += input[i] * taps[ntaps - i - 1];
+
+  return sum;
+}
+
+//
+// Test for ntaps in [0,9], and input lengths in [0,17].
+// This ensures that we are building the shifted taps correctly,
+// and exercises all corner cases on input alignment and length.
+//
+
+static void
+test_random_io (fir_maker_t maker)  
+{
+  const int    MAX_TAPS        = 9;
+  const int    OUTPUT_LEN      = 17;
+  const int    INPUT_LEN       = MAX_TAPS + OUTPUT_LEN;
+
+  // Our SIMD ccc kernel requires that the complex input be 64-bit (8-byte) aligned.
+  // i_type    input[INPUT_LEN];
+  i_type       *input = (i_type *)malloc16Align(INPUT_LEN * sizeof(i_type));
+  o_type       expected_output[OUTPUT_LEN];
+  o_type       actual_output[OUTPUT_LEN];
+  tap_type     taps[MAX_TAPS];
+
+
+  srandom (0); // we want reproducibility
+
+  for (int n = 0; n <= MAX_TAPS; n++){
+    for (int ol = 0; ol <= OUTPUT_LEN; ol++){
+
+      // cerr << "@@@ n:ol " << n << ":" << ol << endl;
+
+      // build random test case
+      random_input (input, INPUT_LEN);
+      random_complex (taps, MAX_TAPS);
+
+      // compute expected output values
+      for (int o = 0; o < ol; o++){
+       expected_output[o] = ref_dotprod (&input[o], taps, n);
+      }
+
+      // build filter
+
+      vector<tap_type> f1_taps (&taps[0], &taps[n]);
+      gr_fir_ccc *f1 = maker (f1_taps);
+
+      // zero the output, then do the filtering
+      memset (actual_output, 0, sizeof (actual_output));
+      f1->filterN (actual_output, input, ol);
+
+      // check results
+      //
+      // we use a sloppy error margin because on the x86 architecture,
+      // our reference implementation is using 80 bit floating point
+      // arithmetic, while the SSE version is using 32 bit float point
+      // arithmetic.
+      
+      for (int o = 0; o < ol; o++){
+       ASSERT_COMPLEXES_EQUAL (expected_output[o],
+                               actual_output[o],
+                               abs (expected_output[o]) * ERR_DELTA);
+      }
+
+      delete f1;
+    }
+  }
+  free16Align(input);
+}
+
+static void
+for_each (void (*f)(fir_maker_t))
+{
+  std::vector<gr_fir_ccc_info>         info;
+  gr_fir_util::get_gr_fir_ccc_info (&info);    // get all known ccc implementations 
+
+  for (std::vector<gr_fir_ccc_info>::iterator p = info.begin ();
+       p != info.end ();
+       ++p){
+
+    std::cerr << " [" << p->name << "]";
+    f (p->create);
+  }
+
+  std::cerr << std::endl;
+}
+
+void
+qa_gr_fir_ccc::t1 ()
+{
+  for_each (test_random_io);
+}
diff --git a/gnuradio-core/src/lib/filter/qa_gr_fir_ccc.h b/gnuradio-core/src/lib/filter/qa_gr_fir_ccc.h
new file mode 100644 (file)
index 0000000..46fa9b0
--- /dev/null
@@ -0,0 +1,40 @@
+/* -*- 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 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.
+ */
+#ifndef _QA_GR_FIR_CCC_H_
+#define _QA_GR_FIR_CCC_H_
+
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/TestCase.h>
+
+class qa_gr_fir_ccc : public CppUnit::TestCase {
+
+  CPPUNIT_TEST_SUITE (qa_gr_fir_ccc);
+  CPPUNIT_TEST (t1);
+  CPPUNIT_TEST_SUITE_END ();
+
+ private:
+  void t1 ();
+
+};
+
+
+#endif /* _QA_GR_FIR_CCC_H_ */
diff --git a/gnuradio-core/src/lib/filter/qa_gr_fir_ccf.cc b/gnuradio-core/src/lib/filter/qa_gr_fir_ccf.cc
new file mode 100644 (file)
index 0000000..c45e085
--- /dev/null
@@ -0,0 +1,183 @@
+/* -*- 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 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.
+ */
+
+/*
+ * FIXME.  This code is virtually identical to qa_gr_fir_?CC.cc
+ *   Kludge up some kind of macro to handle the minor differences.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <gr_types.h>
+
+typedef gr_complex     i_type;
+typedef gr_complex     o_type;
+typedef float          tap_type;
+typedef        gr_complex      acc_type;
+
+
+#include <qa_gr_fir_ccf.h>
+#include <gr_fir_ccf.h>
+#include <gr_fir_util.h>
+#include <string.h>
+#include <iostream>
+#include <cmath>
+#include <gr_types.h>
+#include <cppunit/TestAssert.h>
+#include <random.h>
+#include <malloc16.h>
+
+using std::vector;
+
+#define        ERR_DELTA       (1e-5)
+
+#define        NELEM(x) (sizeof (x) / sizeof (x[0]))
+
+//
+// typedef for something logically "pointer to constructor".
+// there may be a better way, please let me know...
+//
+typedef gr_fir_ccf* (*fir_maker_t)(const std::vector<tap_type> &taps);
+
+static float
+uniform ()
+{
+  return 2.0 * ((float) random () / RANDOM_MAX - 0.5); // uniformly (-1, 1)
+}
+
+static void
+random_floats (float *buf, unsigned n)
+{
+  for (unsigned i = 0; i < n; i++)
+    buf[i] = (float) rint (uniform () * 32767);
+}
+
+static void
+random_complex (gr_complex *buf, unsigned n)
+{
+  for (unsigned i = 0; i < n; i++){
+    float re = rint (uniform () * 32767);
+    float im = rint (uniform () * 32767);
+    buf[i] = gr_complex (re, im);
+  }
+}
+
+static o_type
+ref_dotprod (const i_type input[], const tap_type taps[], int ntaps)
+{
+  acc_type     sum = 0;
+  for (int i = 0; i < ntaps; i++)
+    sum += input[i] * taps[ntaps - i - 1];
+
+  return sum;
+}
+
+//
+// Test for ntaps in [0,9], and input lengths in [0,17].
+// This ensures that we are building the shifted taps correctly,
+// and exercises all corner cases on input alignment and length.
+//
+
+static void
+test_random_io (fir_maker_t maker)  
+{
+  const int    MAX_TAPS        = 9;
+  const int    OUTPUT_LEN      = 17;
+  const int    INPUT_LEN       = MAX_TAPS + OUTPUT_LEN;
+
+  // Our SIMD ccc kernel requires that the complex input be 64-bit (8-byte) aligned.
+  //i_type     input[INPUT_LEN];
+  i_type       *input = (i_type *)malloc16Align(INPUT_LEN * sizeof(i_type));
+  o_type       expected_output[OUTPUT_LEN];
+  o_type       actual_output[OUTPUT_LEN];
+  tap_type     taps[MAX_TAPS];
+
+
+  srandom (0); // we want reproducibility
+
+  for (int n = 0; n <= MAX_TAPS; n++){
+    for (int ol = 0; ol <= OUTPUT_LEN; ol++){
+
+      // cerr << "@@@ n:ol " << n << ":" << ol << endl;
+
+      // build random test case
+      random_complex (input, INPUT_LEN);
+      random_floats (taps, MAX_TAPS);
+
+      // compute expected output values
+      for (int o = 0; o < ol; o++){
+       expected_output[o] = ref_dotprod (&input[o], taps, n);
+      }
+
+      // build filter
+
+      vector<tap_type> f1_taps (&taps[0], &taps[n]);
+      gr_fir_ccf *f1 = maker (f1_taps);
+
+      // zero the output, then do the filtering
+      memset (actual_output, 0, sizeof (actual_output));
+      f1->filterN (actual_output, input, ol);
+
+      // check results
+      //
+      // we use a sloppy error margin because on the x86 architecture,
+      // our reference implementation is using 80 bit floating point
+      // arithmetic, while the SSE version is using 32 bit float point
+      // arithmetic.
+      
+      for (int o = 0; o < ol; o++){
+       ASSERT_COMPLEXES_EQUAL (expected_output[o], actual_output[o],
+                               abs (expected_output[o]) * ERR_DELTA);
+      }
+
+      delete f1;
+    }
+  }
+  free16Align(input);
+}
+
+
+static void
+for_each (void (*f)(fir_maker_t))
+{
+  std::vector<gr_fir_ccf_info>         info;
+  gr_fir_util::get_gr_fir_ccf_info (&info);    // get all known ccf implementations 
+
+  for (std::vector<gr_fir_ccf_info>::iterator p = info.begin ();
+       p != info.end ();
+       ++p){
+
+    std::cerr << " [" << p->name << "]";
+    f (p->create);
+  }
+
+  std::cerr << std::endl;
+}
+
+
+void
+qa_gr_fir_ccf::t1 ()
+{
+  for_each (test_random_io);
+}
diff --git a/gnuradio-core/src/lib/filter/qa_gr_fir_ccf.h b/gnuradio-core/src/lib/filter/qa_gr_fir_ccf.h
new file mode 100644 (file)
index 0000000..bf87136
--- /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 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.
+ */
+#ifndef _QA_GR_FIR_CCF_H_
+#define _QA_GR_FIR_CCF_H_
+
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/TestCase.h>
+
+class qa_gr_fir_ccf : public CppUnit::TestCase {
+
+  CPPUNIT_TEST_SUITE (qa_gr_fir_ccf);
+  CPPUNIT_TEST (t1);
+  CPPUNIT_TEST_SUITE_END ();
+
+ private:
+
+  void t1 ();
+  // void t2 ();
+  // void t3 ();
+
+};
+
+
+#endif /* _QA_GR_FIR_CCF_H_ */
diff --git a/gnuradio-core/src/lib/filter/qa_gr_fir_fcc.cc b/gnuradio-core/src/lib/filter/qa_gr_fir_fcc.cc
new file mode 100644 (file)
index 0000000..0706b58
--- /dev/null
@@ -0,0 +1,180 @@
+/* -*- 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 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.
+ */
+
+/*
+ * FIXME.  This code is virtually identical to qa_gr_fir_?CC.cc
+ *   Kludge up some kind of macro to handle the minor differences.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <gr_types.h>
+
+typedef float          i_type;
+typedef gr_complex     o_type;
+typedef gr_complex     tap_type;
+typedef        gr_complex      acc_type;
+
+
+#include <qa_gr_fir_fcc.h>
+#include <gr_fir_fcc.h>
+#include <gr_fir_util.h>
+#include <string.h>
+#include <iostream>
+#include <cmath>
+#include <gr_types.h>
+#include <cppunit/TestAssert.h>
+#include <random.h>
+
+using std::vector;
+
+#define        ERR_DELTA       (1e-5)
+
+#define        NELEM(x) (sizeof (x) / sizeof (x[0]))
+
+
+//
+// typedef for something logically "pointer to constructor".
+// there may be a better way, please let me know...
+//
+typedef gr_fir_fcc* (*fir_maker_t)(const std::vector<tap_type> &taps);
+
+
+static float
+uniform ()
+{
+  return 2.0 * ((float) random () / RANDOM_MAX - 0.5); // uniformly (-1, 1)
+}
+
+static void
+random_input (i_type *buf, unsigned n)
+{
+  for (unsigned i = 0; i < n; i++)
+    buf[i] = (i_type) rint (uniform () * 32767);
+}
+
+static void
+random_complex (gr_complex *buf, unsigned n)
+{
+  for (unsigned i = 0; i < n; i++){
+    float re = rint (uniform () * 32767);
+    float im = rint (uniform () * 32767);
+    buf[i] = gr_complex (re, im);
+  }
+}
+
+static o_type
+ref_dotprod (const i_type input[], const tap_type taps[], int ntaps)
+{
+  acc_type     sum = 0;
+  for (int i = 0; i < ntaps; i++)
+    sum += input[i] * taps[ntaps - i - 1];
+
+  return sum;
+}
+
+//
+// Test for ntaps in [0,9], and input lengths in [0,17].
+// This ensures that we are building the shifted taps correctly,
+// and exercises all corner cases on input alignment and length.
+//
+
+static void
+test_random_io (fir_maker_t maker)  
+{
+  const int    MAX_TAPS        = 9;
+  const int    OUTPUT_LEN      = 17;
+  const int    INPUT_LEN       = MAX_TAPS + OUTPUT_LEN;
+
+  i_type       input[INPUT_LEN];
+  o_type       expected_output[OUTPUT_LEN];
+  o_type       actual_output[OUTPUT_LEN];
+  tap_type     taps[MAX_TAPS];
+
+
+  srandom (0); // we want reproducibility
+
+  for (int n = 0; n <= MAX_TAPS; n++){
+    for (int ol = 0; ol <= OUTPUT_LEN; ol++){
+
+      // cerr << "@@@ n:ol " << n << ":" << ol << endl;
+
+      // build random test case
+      random_input (input, INPUT_LEN);
+      random_complex (taps, MAX_TAPS);
+
+      // compute expected output values
+      for (int o = 0; o < ol; o++){
+       expected_output[o] = ref_dotprod (&input[o], taps, n);
+      }
+
+      // build filter
+
+      vector<tap_type> f1_taps (&taps[0], &taps[n]);
+      gr_fir_fcc *f1 = maker (f1_taps);
+
+      // zero the output, then do the filtering
+      memset (actual_output, 0, sizeof (actual_output));
+      f1->filterN (actual_output, input, ol);
+
+      // check results
+      //
+      // we use a sloppy error margin because on the x86 architecture,
+      // our reference implementation is using 80 bit floating point
+      // arithmetic, while the SSE version is using 32 bit float point
+      // arithmetic.
+      
+      for (int o = 0; o < ol; o++){
+       ASSERT_COMPLEXES_EQUAL (expected_output[o],
+                               actual_output[o],
+                               abs (expected_output[o]) * ERR_DELTA);
+      }
+
+      delete f1;
+    }
+  }
+}
+
+static void
+for_each (void (*f)(fir_maker_t))
+{
+  std::vector<gr_fir_fcc_info>         info;
+  gr_fir_util::get_gr_fir_fcc_info (&info);    // get all known fcc implementations 
+
+  for (std::vector<gr_fir_fcc_info>::iterator p = info.begin ();
+       p != info.end ();
+       ++p){
+
+    std::cerr << " [" << p->name << "]";
+    f (p->create);
+  }
+
+  std::cerr << std::endl;
+}
+
+void
+qa_gr_fir_fcc::t1 ()
+{
+  for_each (test_random_io);
+}
diff --git a/gnuradio-core/src/lib/filter/qa_gr_fir_fcc.h b/gnuradio-core/src/lib/filter/qa_gr_fir_fcc.h
new file mode 100644 (file)
index 0000000..145f72f
--- /dev/null
@@ -0,0 +1,40 @@
+/* -*- 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 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.
+ */
+#ifndef _QA_GR_FIR_FCC_H_
+#define _QA_GR_FIR_FCC_H_
+
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/TestCase.h>
+
+class qa_gr_fir_fcc : public CppUnit::TestCase {
+
+  CPPUNIT_TEST_SUITE (qa_gr_fir_fcc);
+  CPPUNIT_TEST (t1);
+  CPPUNIT_TEST_SUITE_END ();
+
+ private:
+
+  void t1 ();
+};
+
+
+#endif /* _QA_GR_FIR_FCC_H_ */
diff --git a/gnuradio-core/src/lib/filter/qa_gr_fir_fff.cc b/gnuradio-core/src/lib/filter/qa_gr_fir_fff.cc
new file mode 100644 (file)
index 0000000..1ba3bee
--- /dev/null
@@ -0,0 +1,225 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <qa_gr_fir_fff.h>
+#include <gr_fir_fff.h>
+#include <gr_fir_util.h>
+#include <string.h>
+#include <iostream>
+#include <cmath>
+#include <cppunit/TestAssert.h>
+#include <random.h>
+
+using std::vector;
+
+typedef float  i_type;
+typedef float  o_type;
+typedef float  tap_type;
+typedef        float   acc_type;
+
+#define        ERR_DELTA       (1e-6)
+
+#define        NELEM(x) (sizeof (x) / sizeof (x[0]))
+
+
+//
+// typedef for something logically "pointer to constructor".
+// there may be a better way, please let me know...
+//
+typedef gr_fir_fff* (*fir_maker_t)(const std::vector<tap_type> &taps);
+
+
+// ----------------------------------------------------------------
+
+const static i_type input_1[] = {
+  234,  -4,  23,  -56,  45,    98,  -23,  -7
+};
+
+const static tap_type taps_1a[] = {
+  -3
+};
+
+const static o_type expected_1a[] = {
+  -702, 12, -69,   168, -135, -294,  69,  21
+};
+
+const static tap_type taps_1b[] = {
+  -4, 5
+};
+
+const static o_type expected_1b[] = {
+  1186, -112, 339, -460, -167, 582, -87
+};
+
+// ----------------------------------------------------------------
+
+static void
+test_known_io (fir_maker_t maker)
+{
+  vector<tap_type> t1a (&taps_1a[0], &taps_1a[NELEM (taps_1a)]);
+  vector<tap_type> t1b (&taps_1b[0], &taps_1b[NELEM (taps_1b)]);
+  
+  gr_fir_fff *f1 = maker (t1a);                // create filter
+  CPPUNIT_ASSERT_EQUAL ((unsigned) 1, f1->ntaps ());   // check ntaps
+
+  // check filter output
+  int n = NELEM (input_1) - f1->ntaps () + 1;
+  for (int i = 0; i < n; i++)
+    CPPUNIT_ASSERT_DOUBLES_EQUAL (expected_1a[i], f1->filter (&input_1[i]), ERR_DELTA);
+
+  f1->set_taps (t1b);                  // set new taps
+  CPPUNIT_ASSERT_EQUAL ((unsigned) 2, f1->ntaps ());   // check ntaps
+  
+  // check filter output
+  n = NELEM (input_1) - f1->ntaps () + 1;
+  for (int i = 0; i < n; i++)
+    CPPUNIT_ASSERT_DOUBLES_EQUAL (expected_1b[i], f1->filter (&input_1[i]), ERR_DELTA);
+
+  // test filterN interface
+
+  o_type output[NELEM (expected_1b)];
+  memset (output, 0, sizeof (output));
+
+  f1->filterN (output, input_1, n);
+  for (int i = 0; i < n; i++)
+    CPPUNIT_ASSERT_DOUBLES_EQUAL (expected_1b[i], output[i], ERR_DELTA);
+
+  delete f1;
+}
+
+//
+// Test for ntaps in [0,9], and input lengths in [0,17].
+// This ensures that we are building the shifted taps correctly,
+// and exercises all corner cases on input alignment and length.
+//
+
+static float
+uniform ()
+{
+  return 2.0 * ((float) random () / RANDOM_MAX - 0.5); // uniformly (-1, 1)
+}
+
+static void
+random_floats (float *buf, unsigned n)
+{
+  for (unsigned i = 0; i < n; i++)
+    buf[i] = rint (uniform () * 32768);
+}
+
+static o_type
+ref_dotprod (const i_type input[], const tap_type taps[], int ntaps)
+{
+  acc_type     sum = 0;
+  for (int i = 0; i < ntaps; i++)
+    sum += input[i] * taps[ntaps - i - 1];
+
+  return sum;
+}
+
+static void
+test_random_io (fir_maker_t maker)  
+{
+  const int    MAX_TAPS        = 9;
+  const int    OUTPUT_LEN      = 17;
+  const int    INPUT_LEN       = MAX_TAPS + OUTPUT_LEN;
+
+  i_type       input[INPUT_LEN];
+  o_type       expected_output[OUTPUT_LEN];
+  o_type       actual_output[OUTPUT_LEN];
+  tap_type     taps[MAX_TAPS];
+
+
+  srandom (0); // we want reproducibility
+
+  for (int n = 0; n <= MAX_TAPS; n++){
+    for (int ol = 0; ol <= OUTPUT_LEN; ol++){
+
+      // cerr << "@@@ n:ol " << n << ":" << ol << endl;
+
+      // build random test case
+      random_floats (input, INPUT_LEN);
+      random_floats (taps, MAX_TAPS);
+
+      // compute expected output values
+      for (int o = 0; o < ol; o++){
+       expected_output[o] = ref_dotprod (&input[o], taps, n);
+      }
+
+      // build filter
+
+      vector<tap_type> f1_taps (&taps[0], &taps[n]);
+      gr_fir_fff *f1 = maker (f1_taps);
+
+      // zero the output, then do the filtering
+      memset (actual_output, 0, sizeof (actual_output));
+      f1->filterN (actual_output, input, ol);
+
+      // check results
+      //
+      // we use a sloppy error margin because on the x86 architecture,
+      // our reference implementation is using 80 bit floating point
+      // arithmetic, while the SSE version is using 32 bit float point
+      // arithmetic.
+      
+      for (int o = 0; o < ol; o++){
+       CPPUNIT_ASSERT_DOUBLES_EQUAL (expected_output[o], actual_output[o],
+                           fabs (expected_output[o]) * 1e-4);
+      }
+
+      delete f1;
+    }
+  }
+}
+
+
+static void
+for_each (void (*f)(fir_maker_t))
+{
+  std::vector<gr_fir_fff_info>         info;
+  gr_fir_util::get_gr_fir_fff_info (&info);    // get all known fff implementations 
+
+  for (std::vector<gr_fir_fff_info>::iterator p = info.begin ();
+       p != info.end ();
+       ++p){
+
+    std::cerr << " [" << p->name << "]";
+    f (p->create);
+  }
+
+  std::cerr << std::endl;
+}
+
+void
+qa_gr_fir_fff::t1 ()
+{
+  for_each (test_known_io);
+}
+
+void
+qa_gr_fir_fff::t2 ()
+{
+  for_each (test_random_io);
+}
diff --git a/gnuradio-core/src/lib/filter/qa_gr_fir_fff.h b/gnuradio-core/src/lib/filter/qa_gr_fir_fff.h
new file mode 100644 (file)
index 0000000..34d86f9
--- /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 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.
+ */
+#ifndef _QA_GR_FIR_FFF_H_
+#define _QA_GR_FIR_FFF_H_
+
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/TestCase.h>
+
+class qa_gr_fir_fff : public CppUnit::TestCase {
+
+  CPPUNIT_TEST_SUITE (qa_gr_fir_fff);
+  CPPUNIT_TEST (t1);
+  CPPUNIT_TEST (t2);
+  CPPUNIT_TEST_SUITE_END ();
+
+ private:
+
+  void t1 ();
+  void t2 ();
+
+};
+
+
+#endif /* _QA_GR_FIR_FFF_H_ */
diff --git a/gnuradio-core/src/lib/filter/qa_gr_fir_scc.cc b/gnuradio-core/src/lib/filter/qa_gr_fir_scc.cc
new file mode 100644 (file)
index 0000000..38a7692
--- /dev/null
@@ -0,0 +1,179 @@
+/* -*- 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 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.
+ */
+
+/*
+ * FIXME.  This code is virtually identical to qa_gr_fir_?CC.cc
+ *   Kludge up some kind of macro to handle the minor differences.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <gr_types.h>
+
+typedef short          i_type;
+typedef gr_complex     o_type;
+typedef gr_complex     tap_type;
+typedef        gr_complex      acc_type;
+
+
+#include <qa_gr_fir_scc.h>
+#include <gr_fir_scc.h>
+#include <gr_fir_util.h>
+#include <string.h>
+#include <iostream>
+#include <cmath>
+#include <gr_types.h>
+#include <cppunit/TestAssert.h>
+#include <random.h>
+
+using std::vector;
+
+#define        ERR_DELTA       (1e-5)
+
+#define        NELEM(x) (sizeof (x) / sizeof (x[0]))
+
+//
+// typedef for something logically "pointer to constructor".
+// there may be a better way, please let me know...
+//
+typedef gr_fir_scc* (*fir_maker_t)(const std::vector<tap_type> &taps);
+
+
+static float
+uniform ()
+{
+  return 2.0 * ((float) random () / RANDOM_MAX - 0.5); // uniformly (-1, 1)
+}
+
+static void
+random_input (i_type *buf, unsigned n)
+{
+  for (unsigned i = 0; i < n; i++)
+    buf[i] = (i_type) rint (uniform () * 32767);
+}
+
+static void
+random_complex (gr_complex *buf, unsigned n)
+{
+  for (unsigned i = 0; i < n; i++){
+    float re = rint (uniform () * 32767);
+    float im = rint (uniform () * 32767);
+    buf[i] = gr_complex (re, im);
+  }
+}
+
+static o_type
+ref_dotprod (const i_type input[], const tap_type taps[], int ntaps)
+{
+  acc_type     sum = 0;
+  for (int i = 0; i < ntaps; i++)
+    sum += (float) input[i] * taps[ntaps - i - 1];
+
+  return sum;
+}
+
+//
+// Test for ntaps in [0,9], and input lengths in [0,17].
+// This ensures that we are building the shifted taps correctly,
+// and exercises all corner cases on input alignment and length.
+//
+
+static void
+test_random_io (fir_maker_t maker)  
+{
+  const int    MAX_TAPS        = 9;
+  const int    OUTPUT_LEN      = 17;
+  const int    INPUT_LEN       = MAX_TAPS + OUTPUT_LEN;
+
+  i_type       input[INPUT_LEN];
+  o_type       expected_output[OUTPUT_LEN];
+  o_type       actual_output[OUTPUT_LEN];
+  tap_type     taps[MAX_TAPS];
+
+
+  srandom (0); // we want reproducibility
+
+  for (int n = 0; n <= MAX_TAPS; n++){
+    for (int ol = 0; ol <= OUTPUT_LEN; ol++){
+
+      // cerr << "@@@ n:ol " << n << ":" << ol << endl;
+
+      // build random test case
+      random_input (input, INPUT_LEN);
+      random_complex (taps, MAX_TAPS);
+
+      // compute expected output values
+      for (int o = 0; o < ol; o++){
+       expected_output[o] = ref_dotprod (&input[o], taps, n);
+      }
+
+      // build filter
+
+      vector<tap_type> f1_taps (&taps[0], &taps[n]);
+      gr_fir_scc *f1 = maker (f1_taps);
+
+      // zero the output, then do the filtering
+      memset (actual_output, 0, sizeof (actual_output));
+      f1->filterN (actual_output, input, ol);
+
+      // check results
+      //
+      // we use a sloppy error margin because on the x86 architecture,
+      // our reference implementation is using 80 bit floating point
+      // arithmetic, while the SSE version is using 32 bit float point
+      // arithmetic.
+      
+      for (int o = 0; o < ol; o++){
+       ASSERT_COMPLEXES_EQUAL (expected_output[o],
+                               actual_output[o],
+                               abs (expected_output[o]) * ERR_DELTA);
+      }
+
+      delete f1;
+    }
+  }
+}
+
+static void
+for_each (void (*f)(fir_maker_t))
+{
+  std::vector<gr_fir_scc_info>         info;
+  gr_fir_util::get_gr_fir_scc_info (&info);    // get all known scc implementations 
+
+  for (std::vector<gr_fir_scc_info>::iterator p = info.begin ();
+       p != info.end ();
+       ++p){
+
+    std::cerr << " [" << p->name << "]";
+    f (p->create);
+  }
+
+  std::cerr << std::endl;
+}
+
+void
+qa_gr_fir_scc::t1 ()
+{
+  for_each (test_random_io);
+}
diff --git a/gnuradio-core/src/lib/filter/qa_gr_fir_scc.h b/gnuradio-core/src/lib/filter/qa_gr_fir_scc.h
new file mode 100644 (file)
index 0000000..2662d02
--- /dev/null
@@ -0,0 +1,40 @@
+/* -*- 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 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.
+ */
+#ifndef _QA_GR_FIR_SCC_H_
+#define _QA_GR_FIR_SCC_H_
+
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/TestCase.h>
+
+class qa_gr_fir_scc : public CppUnit::TestCase {
+
+  CPPUNIT_TEST_SUITE (qa_gr_fir_scc);
+  CPPUNIT_TEST (t1);
+  CPPUNIT_TEST_SUITE_END ();
+
+ private:
+  void t1 ();
+
+};
+
+
+#endif /* _QA_GR_FIR_SCC_H_ */
diff --git a/gnuradio-core/src/lib/filter/qa_gri_mmse_fir_interpolator.cc b/gnuradio-core/src/lib/filter/qa_gri_mmse_fir_interpolator.cc
new file mode 100644 (file)
index 0000000..a756bbc
--- /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 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.
+ */
+
+#include <cppunit/TestAssert.h>
+#include <qa_gri_mmse_fir_interpolator.h>
+#include <gri_mmse_fir_interpolator.h>
+#include <stdio.h>
+#include <cmath>
+
+#define        NELEM(x) (sizeof (x) / sizeof (x[0]))
+
+
+static float
+test_fcn (double index)
+{
+  return (2 * sin (index * 0.25 * 2 * M_PI + 0.125 * M_PI)
+         + 3 * sin (index * 0.077 * 2 * M_PI + 0.3 * M_PI));
+}
+
+
+void
+qa_gri_mmse_fir_interpolator::t1 ()
+{
+  static const unsigned        N = 100;
+  float input[N + 10];
+
+  for (unsigned i = 0; i < NELEM(input); i++)
+    input[i] = test_fcn ((double) i);
+
+  gri_mmse_fir_interpolator    intr;
+  float inv_nsteps = 1.0 / intr.nsteps ();
+
+  for (unsigned i = 0; i < N; i++){
+    for (unsigned imu = 0; imu <= intr.nsteps (); imu += 1){
+      float expected = test_fcn ((i + 3) + imu * inv_nsteps);
+      float actual = intr.interpolate (&input[i], imu * inv_nsteps);
+
+      CPPUNIT_ASSERT_DOUBLES_EQUAL (expected, actual, 0.004);
+      // printf ("%9.6f  %9.6f  %9.6f\n", expected, actual, expected - actual);
+    }
+  }
+}
+
diff --git a/gnuradio-core/src/lib/filter/qa_gri_mmse_fir_interpolator.h b/gnuradio-core/src/lib/filter/qa_gri_mmse_fir_interpolator.h
new file mode 100644 (file)
index 0000000..85be45e
--- /dev/null
@@ -0,0 +1,40 @@
+/* -*- 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 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.
+ */
+#ifndef _QA_GRI_MMSE_FIR_INTERPOLATOR_H_
+#define _QA_GRI_MMSE_FIR_INTERPOLATOR_H_
+
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/TestCase.h>
+
+class qa_gri_mmse_fir_interpolator : public CppUnit::TestCase {
+
+  CPPUNIT_TEST_SUITE (qa_gri_mmse_fir_interpolator);
+  CPPUNIT_TEST (t1);
+  CPPUNIT_TEST_SUITE_END ();
+
+ private:
+  void t1 ();
+
+};
+
+
+#endif /* _QA_GRI_MMSE_FIR_INTERPOLATOR_H_ */
diff --git a/gnuradio-core/src/lib/filter/short_dotprod_generic.c b/gnuradio-core/src/lib/filter/short_dotprod_generic.c
new file mode 100644 (file)
index 0000000..4fca2e5
--- /dev/null
@@ -0,0 +1,49 @@
+/* -*- 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 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.
+ */
+
+#include "short_dotprod_generic.h"
+
+
+int
+short_dotprod_generic (const short *input,
+                      const short *taps, unsigned n_4_short_blocks)
+{
+  int sum0 = 0;
+  int sum1 = 0;
+  int sum2 = 0;
+  int sum3 = 0;
+
+  do {
+
+    sum0 += input[0] * taps[0];
+    sum1 += input[1] * taps[1];
+    sum2 += input[2] * taps[2];
+    sum3 += input[3] * taps[3];
+
+    input += 4;
+    taps += 4;
+
+  } while (--n_4_short_blocks != 0);
+
+
+  return (sum0 + sum1 + sum2 + sum3);
+}
diff --git a/gnuradio-core/src/lib/filter/short_dotprod_generic.h b/gnuradio-core/src/lib/filter/short_dotprod_generic.h
new file mode 100644 (file)
index 0000000..6e3709f
--- /dev/null
@@ -0,0 +1,41 @@
+/* -*- 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 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.
+ */
+
+#ifndef _SHORT_DOTPROD_GENERIC_H_
+#define _SHORT_DOTPROD_GENERIC_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int
+short_dotprod_generic (const short *input,
+                      const short *taps, unsigned n_4_short_blocks);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+#endif /* _SHORT_DOTPROD_GENERIC_H_ */
diff --git a/gnuradio-core/src/lib/filter/short_dotprod_mmx.S b/gnuradio-core/src/lib/filter/short_dotprod_mmx.S
new file mode 100644 (file)
index 0000000..7c9ae07
--- /dev/null
@@ -0,0 +1,113 @@
+#
+# 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 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.
+# 
+
+# SIMD MMX dot product
+# Equivalent to the following C code:
+# long dotprod(signed short *a,signed short *b,int cnt)
+# {
+#      long sum = 0; 
+#      cnt *= 4; 
+#      while(cnt--)
+#              sum += *a++ + *b++;
+#      return sum;
+# }
+# a and b should also be 64-bit aligned, or speed will suffer greatly
+# Copyright 1999, Phil Karn KA9Q
+# May be used under the terms of the GNU public license
+       
+#include "assembly.h"
+
+
+       .file   "short_dotprod_mmx.S"
+       .version        "01.01"
+.text
+       .p2align 3
+.globl GLOB_SYMB(short_dotprod_mmx)
+       DEF_FUNC_HEAD(short_dotprod_mmx)
+GLOB_SYMB(short_dotprod_mmx):
+       pushl %ebp
+       movl %esp,%ebp
+       pushl %esi
+       pushl %edi
+       pushl %ecx
+       pushl %ebx
+       movl 8(%ebp),%esi       # a
+       movl 12(%ebp),%edi      # b
+       movl 16(%ebp),%ecx      # cnt
+       pxor %mm0,%mm0          # clear running sum (in two 32-bit halves)
+       
+# MMX dot product loop unrolled 4 times, crunching 16 terms per loop
+       .p2align 4
+.Loop1mmx:     subl $4,%ecx
+       jl   .Loop1Done
+       
+       movq (%esi),%mm1        # mm1 = a[3],a[2],a[1],a[0]
+       pmaddwd (%edi),%mm1     # mm1 = b[3]*a[3]+b[2]*a[2],b[1]*a[1]+b[0]*a[0]
+       paddd %mm1,%mm0
+       
+       movq 8(%esi),%mm1
+       pmaddwd 8(%edi),%mm1
+       paddd %mm1,%mm0
+
+       movq 16(%esi),%mm1
+       pmaddwd 16(%edi),%mm1
+       paddd %mm1,%mm0
+
+       movq 24(%esi),%mm1
+       addl $32,%esi   
+       pmaddwd 24(%edi),%mm1
+       addl $32,%edi   
+       paddd %mm1,%mm0
+
+       jmp .Loop1mmx
+.Loop1Done:
+       
+       addl $4,%ecx    
+       
+# MMX dot product loop, not unrolled, crunching 4 terms per loop
+# This could be redone as Duff's Device on the unrolled loop above
+.Loop2:        subl $1,%ecx
+       jl   .Loop2Done
+       
+       movq (%esi),%mm1
+       addl $8,%esi
+       pmaddwd (%edi),%mm1
+       addl $8,%edi
+       paddd %mm1,%mm0
+       jmp .Loop2
+.Loop2Done:
+       
+       movd %mm0,%ebx          # right-hand word to ebx
+       punpckhdq %mm0,%mm0     # left-hand word to right side of %mm0
+       movd %mm0,%eax
+       addl %ebx,%eax          # running sum now in %eax
+       emms                    # done with MMX
+       
+       popl %ebx
+       popl %ecx
+       popl %edi
+       popl %esi
+       movl %ebp,%esp
+       popl    %ebp
+       ret
+
+FUNC_TAIL(short_dotprod_mmx)
+       .ident  "Hand coded x86 MMX assembly"
diff --git a/gnuradio-core/src/lib/filter/short_dotprod_mmx64.S b/gnuradio-core/src/lib/filter/short_dotprod_mmx64.S
new file mode 100644 (file)
index 0000000..4c46e0e
--- /dev/null
@@ -0,0 +1,101 @@
+#
+# Copyright 2002,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 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.
+# 
+
+# SIMD MMX dot product
+# Equivalent to the following C code:
+# long dotprod(signed short *a,signed short *b,int cnt)
+# {
+#      long sum = 0; 
+#      cnt *= 4; 
+#      while(cnt--)
+#              sum += *a++ + *b++;
+#      return sum;
+# }
+# a and b should also be 64-bit aligned, or speed will suffer greatly
+# Copyright 1999, Phil Karn KA9Q
+# May be used under the terms of the GNU public license
+       
+#include "assembly.h"
+
+
+       .file   "short_dotprod_mmx64.S"
+       .version        "01.01"
+.text
+       .p2align 3
+.globl GLOB_SYMB(short_dotprod_mmx)
+       DEF_FUNC_HEAD(short_dotprod_mmx)
+GLOB_SYMB(short_dotprod_mmx):
+
+       # a: rdi, b: rsi, cnt: rdx
+
+       pxor %mm0,%mm0          # clear running sum (in two 32-bit halves)
+       
+# MMX dot product loop unrolled 4 times, crunching 16 terms per loop
+       .p2align 4
+.Loop1mmx:     sub $4,%rdx
+       jl   .Loop1Done
+       
+       movq (%rdi),%mm1        # mm1 = a[3],a[2],a[1],a[0]
+       pmaddwd (%rsi),%mm1     # mm1 = b[3]*a[3]+b[2]*a[2],b[1]*a[1]+b[0]*a[0]
+       paddd %mm1,%mm0
+       
+       movq 8(%rdi),%mm1
+       pmaddwd 8(%rsi),%mm1
+       paddd %mm1,%mm0
+
+       movq 16(%rdi),%mm1
+       pmaddwd 16(%rsi),%mm1
+       paddd %mm1,%mm0
+
+       movq 24(%rdi),%mm1
+       add $32,%rdi    
+       pmaddwd 24(%rsi),%mm1
+       add $32,%rsi    
+       paddd %mm1,%mm0
+
+       jmp .Loop1mmx
+.Loop1Done:
+       
+       add $4,%rdx     
+       
+# MMX dot product loop, not unrolled, crunching 4 terms per loop
+# This could be redone as Duff's Device on the unrolled loop above
+.Loop2:        sub $1,%rdx
+       jl   .Loop2Done
+       
+       movq (%rdi),%mm1
+       add $8,%rdi
+       pmaddwd (%rsi),%mm1
+       add $8,%rsi
+       paddd %mm1,%mm0
+       jmp .Loop2
+.Loop2Done:
+       
+       movd %mm0,%edx          # right-hand word to edx
+       punpckhdq %mm0,%mm0     # left-hand word to right side of %mm0
+       movd %mm0,%eax
+       addl %edx,%eax          # running sum now in %eax
+       emms                    # done with MMX
+       
+       retq
+
+FUNC_TAIL(short_dotprod_mmx)
+       .ident  "Hand coded x86_64 MMX assembly"
diff --git a/gnuradio-core/src/lib/filter/short_dotprod_x86.h b/gnuradio-core/src/lib/filter/short_dotprod_x86.h
new file mode 100644 (file)
index 0000000..03b4748
--- /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 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.
+ */
+
+#ifndef _SHORT_DOTPROD_X86_H_
+#define _SHORT_DOTPROD_X86_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int
+short_dotprod_mmx (const short *input,
+                  const short *taps, unsigned n_4_short_blocks);
+
+int
+short_dotprod_sse2 (const short *input,
+                   const short *taps, unsigned n_4_short_blocks);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+#endif /* _SHORT_DOTPROD_X86_H_ */
diff --git a/gnuradio-core/src/lib/filter/sse_debug.c b/gnuradio-core/src/lib/filter/sse_debug.c
new file mode 100644 (file)
index 0000000..f27d393
--- /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 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.
+ */
+#include <stdio.h>
+#include <sse_debug.h>
+#include <string.h>
+
+void
+format_xmm_regs (FILE *f, struct xmm_regs *r)
+{
+  int  i;
+
+  for (i = 0; i < 8; i++){
+    union xmm_register *x = &r->xmm[i];
+    fprintf (f, "xmm%d: %08lx %08lx %08lx %08lx", i,
+            x->ul[0], x->ul[1], x->ul[2], x->ul[3]);
+    fprintf (f, "  %12g %12g %12g %12g\n",
+            x->f[0],  x->f[1],  x->f[2],  x->f[3]);
+  }
+}
+
+
+void
+get_xmm_regs (struct xmm_regs *x)
+{
+  asm ("movups %%xmm0,0x00(%0);        \n"
+       "movups %%xmm1,0x10(%0);        \n"
+       "movups %%xmm2,0x20(%0);        \n"
+       "movups %%xmm3,0x30(%0);        \n"
+       "movups %%xmm4,0x40(%0);        \n"
+       "movups %%xmm5,0x50(%0);        \n"
+       "movups %%xmm6,0x60(%0);        \n"
+       "movups %%xmm7,0x70(%0);        \n" : : "r" (x));
+}
+
+void 
+dump_xmm_regs (void)
+{
+  struct xmm_regs      r;
+
+  get_xmm_regs (&r);
+  format_xmm_regs (stderr, &r);
+}
+
diff --git a/gnuradio-core/src/lib/filter/sse_debug.h b/gnuradio-core/src/lib/filter/sse_debug.h
new file mode 100644 (file)
index 0000000..f356a0e
--- /dev/null
@@ -0,0 +1,48 @@
+/* -*- 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 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.
+ */
+
+#ifndef _SSE_DEBUG_H_
+#define        _SSE_DEBUG_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+  union xmm_register {
+    unsigned long      ul[4];
+    float              f[4];
+  };
+  
+  struct xmm_regs {
+    union xmm_register xmm[8];
+  };
+
+  // callable from asm, dumps all xmm regs
+  void dump_xmm_regs (void);
+
+  void get_xmm_regs (struct xmm_regs *x);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _SSE_DEBUG_H_
diff --git a/gnuradio-core/src/lib/filter/sysconfig_generic.cc b/gnuradio-core/src/lib/filter/sysconfig_generic.cc
new file mode 100644 (file)
index 0000000..1cecf49
--- /dev/null
@@ -0,0 +1,35 @@
+/* -*- 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 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.
+ */
+
+#include <gr_fir_sysconfig_generic.h>
+
+gr_fir_sysconfig *
+gr_fir_sysconfig_singleton ()
+{
+  static gr_fir_sysconfig *singleton = 0;
+
+  if (singleton)
+    return singleton;
+
+  singleton = new gr_fir_sysconfig_generic ();
+  return singleton;
+}
diff --git a/gnuradio-core/src/lib/filter/sysconfig_x86.cc b/gnuradio-core/src/lib/filter/sysconfig_x86.cc
new file mode 100644 (file)
index 0000000..d2c3161
--- /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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <gr_fir_sysconfig_x86.h>
+
+gr_fir_sysconfig *
+gr_fir_sysconfig_singleton ()
+{
+  static gr_fir_sysconfig *singleton = 0;
+
+  if (singleton)
+    return singleton;
+
+  singleton = new gr_fir_sysconfig_x86 ();
+  return singleton;
+}
diff --git a/gnuradio-core/src/lib/g72x/Makefile.am b/gnuradio-core/src/lib/g72x/Makefile.am
new file mode 100644 (file)
index 0000000..c8ba3e8
--- /dev/null
@@ -0,0 +1,27 @@
+#
+# 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 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.
+# 
+
+include $(top_srcdir)/Makefile.common
+
+noinst_LTLIBRARIES = libccitt.la
+libccitt_la_SOURCES = g711.c g72x.c g721.c g723_24.c g723_40.c g72x.h
+
+EXTRA_DIST = encode.c decode.c
diff --git a/gnuradio-core/src/lib/g72x/README b/gnuradio-core/src/lib/g72x/README
new file mode 100644 (file)
index 0000000..23b0e7d
--- /dev/null
@@ -0,0 +1,94 @@
+The files in this directory comprise ANSI-C language reference implementations
+of the CCITT (International Telegraph and Telephone Consultative Committee)
+G.711, G.721 and G.723 voice compressions.  They have been tested on Sun
+SPARCstations and passed 82 out of 84 test vectors published by CCITT
+(Dec. 20, 1988) for G.721 and G.723.  [The two remaining test vectors,
+which the G.721 decoder implementation for u-law samples did not pass,
+may be in error because they are identical to two other vectors for G.723_40.]
+
+This source code is released by Sun Microsystems, Inc. to the public domain.
+Please give your acknowledgement in product literature if this code is used
+in your product implementation.
+
+Sun Microsystems supports some CCITT audio formats in Solaris 2.0 system
+software.  However, Sun's implementations have been optimized for higher
+performance on SPARCstations.
+
+
+The source files for CCITT conversion routines in this directory are:
+
+       g72x.h          header file for g721.c, g723_24.c and g723_40.c
+       g711.c          CCITT G.711 u-law and A-law compression
+       g72x.c          common denominator of G.721 and G.723 ADPCM codes
+       g721.c          CCITT G.721 32Kbps ADPCM coder (with g72x.c)
+       g723_24.c       CCITT G.723 24Kbps ADPCM coder (with g72x.c)
+       g723_40.c       CCITT G.723 40Kbps ADPCM coder (with g72x.c)
+
+
+Simple conversions between u-law, A-law, and 16-bit linear PCM are invoked
+as follows:
+
+       unsigned char           ucode, acode;
+       short                   pcm_val;
+
+       ucode = linear2ulaw(pcm_val);
+       ucode = alaw2ulaw(acode);
+
+       acode = linear2alaw(pcm_val);
+       acode = ulaw2alaw(ucode);
+
+       pcm_val = ulaw2linear(ucode);
+       pcm_val = alaw2linear(acode);
+
+
+The other CCITT compression routines are invoked as follows:
+
+       #include "g72x.h"
+
+       struct g72x_state       state;
+       int                     sample, code;
+
+       g72x_init_state(&state);
+       code = {g721,g723_24,g723_40}_encoder(sample, coding, &state);
+       sample = {g721,g723_24,g723_40}_decoder(code, coding, &state);
+
+where
+       coding = AUDIO_ENCODING_ULAW    for 8-bit u-law samples
+                AUDIO_ENCODING_ALAW    for 8-bit A-law samples
+                AUDIO_ENCODING_LINEAR  for 16-bit linear PCM samples
+
+
+
+This directory also includes the following sample programs:
+
+       encode.c        CCITT ADPCM encoder
+       decode.c        CCITT ADPCM decoder
+       Makefile        makefile for the sample programs
+
+
+The sample programs contain examples of how to call the various compression
+routines and pack/unpack the bits.  The sample programs read byte streams from
+stdin and write to stdout.  The input/output data is raw data (no file header
+or other identifying information is embedded).  The sample programs are
+invoked as follows:
+
+       encode [-3|4|5] [-a|u|l] <infile >outfile
+       decode [-3|4|5] [-a|u|l] <infile >outfile
+where:
+       -3      encode to (decode from) G.723 24kbps (3-bit) data
+       -4      encode to (decode from) G.721 32kbps (4-bit) data [the default]
+       -5      encode to (decode from) G.723 40kbps (5-bit) data
+       -a      encode from (decode to) A-law data
+       -u      encode from (decode to) u-law data [the default]
+       -l      encode from (decode to) 16-bit linear data
+
+Examples:
+       # Read 16-bit linear and output G.721
+       encode -4 -l <pcmfile >g721file
+
+       # Read 40Kbps G.723 and output A-law
+       decode -5 -a <g723file >alawfile
+
+       # Compress and then decompress u-law data using 24Kbps G.723
+       encode -3 <ulawin | deoced -3 >ulawout
+
diff --git a/gnuradio-core/src/lib/g72x/decode.c b/gnuradio-core/src/lib/g72x/decode.c
new file mode 100644 (file)
index 0000000..cf8c739
--- /dev/null
@@ -0,0 +1,113 @@
+/*
+ * decode.c
+ *
+ * CCITT ADPCM decoder
+ *
+ * Usage : decode [-3|4|5] [-a|u|l] < infile > outfile
+ */
+#include <stdio.h>
+#include "g72x.h"
+
+
+/*
+ * Unpack input codes and pass them back as bytes.
+ * Returns 1 if there is residual input, returns -1 if eof, else returns 0.
+ */
+int
+unpack_input(
+       unsigned char           *code,
+       int                     bits)
+{
+       static unsigned int     in_buffer = 0;
+       static int              in_bits = 0;
+       unsigned char           in_byte;
+
+       if (in_bits < bits) {
+               if (fread(&in_byte, sizeof (char), 1, stdin) != 1) {
+                       *code = 0;
+                       return (-1);
+               }
+               in_buffer |= (in_byte << in_bits);
+               in_bits += 8;
+       }
+       *code = in_buffer & ((1 << bits) - 1);
+       in_buffer >>= bits;
+       in_bits -= bits;
+       return (in_bits > 0);
+}
+
+
+main(
+       int                     argc,
+       char                    **argv)
+{
+       short                   sample;
+       unsigned char           code;
+       int                     n;
+       struct g72x_state       state;
+       int                     out_coding;
+       int                     out_size;
+       int                     (*dec_routine)();
+       int                     dec_bits;
+
+       g72x_init_state(&state);
+       out_coding = AUDIO_ENCODING_ULAW;
+       out_size = sizeof (char);
+       dec_routine = g721_decoder;
+       dec_bits = 4;
+
+       /* Process encoding argument, if any */
+       while ((argc > 1) && (argv[1][0] == '-')) {
+               switch (argv[1][1]) {
+               case '3':
+                       dec_routine = g723_24_decoder;
+                       dec_bits = 3;
+                       break;
+               case '4':
+                       dec_routine = g721_decoder;
+                       dec_bits = 4;
+                       break;
+               case '5':
+                       dec_routine = g723_40_decoder;
+                       dec_bits = 5;
+                       break;
+               case 'u':
+                       out_coding = AUDIO_ENCODING_ULAW;
+                       out_size = sizeof (char);
+                       break;
+               case 'a':
+                       out_coding = AUDIO_ENCODING_ALAW;
+                       out_size = sizeof (char);
+                       break;
+               case 'l':
+                       out_coding = AUDIO_ENCODING_LINEAR;
+                       out_size = sizeof (short);
+                       break;
+               default:
+fprintf(stderr, "CCITT ADPCM Decoder -- usage:\n");
+fprintf(stderr, "\tdecode [-3|4|5] [-a|u|l] < infile > outfile\n");
+fprintf(stderr, "where:\n");
+fprintf(stderr, "\t-3\tProcess G.723 24kbps (3-bit) input data\n");
+fprintf(stderr, "\t-4\tProcess G.721 32kbps (4-bit) input data [default]\n");
+fprintf(stderr, "\t-5\tProcess G.723 40kbps (5-bit) input data\n");
+fprintf(stderr, "\t-a\tGenerate 8-bit A-law data\n");
+fprintf(stderr, "\t-u\tGenerate 8-bit u-law data [default]\n");
+fprintf(stderr, "\t-l\tGenerate 16-bit linear PCM data\n");
+                       exit(1);
+               }
+               argc--;
+               argv++;
+       }
+
+       /* Read and unpack input codes and process them */
+       while (unpack_input(&code, dec_bits) >= 0) {
+               sample = (*dec_routine)(code, out_coding, &state);
+               if (out_size == 2) {
+                       fwrite(&sample, out_size, 1, stdout);
+               } else {
+                       code = (unsigned char)sample;
+                       fwrite(&code, out_size, 1, stdout);
+               }
+       }
+       fclose(stdout);
+}
diff --git a/gnuradio-core/src/lib/g72x/encode.c b/gnuradio-core/src/lib/g72x/encode.c
new file mode 100644 (file)
index 0000000..e744828
--- /dev/null
@@ -0,0 +1,119 @@
+/*
+ * encode.c
+ *
+ * CCITT ADPCM encoder
+ *
+ * Usage : encode [-3|4|5] [-a|u|l] < infile > outfile
+ */
+#include <stdio.h>
+#include "g72x.h"
+
+
+/*
+ * Pack output codes into bytes and write them to stdout.
+ * Returns 1 if there is residual output, else returns 0.
+ */
+int
+pack_output(
+       unsigned                code,
+       int                     bits)
+{
+       static unsigned int     out_buffer = 0;
+       static int              out_bits = 0;
+       unsigned char           out_byte;
+
+       out_buffer |= (code << out_bits);
+       out_bits += bits;
+       if (out_bits >= 8) {
+               out_byte = out_buffer & 0xff;
+               out_bits -= 8;
+               out_buffer >>= 8;
+               fwrite(&out_byte, sizeof (char), 1, stdout);
+       }
+       return (out_bits > 0);
+}
+
+
+main(
+       int                     argc,
+       char                    **argv)
+{
+       struct g72x_state       state;
+       unsigned char           sample_char;
+       short                   sample_short;
+       unsigned char           code;
+       int                     resid;
+       int                     in_coding;
+       int                     in_size;
+       unsigned                *in_buf;
+       int                     (*enc_routine)();
+       int                     enc_bits;
+
+       g72x_init_state(&state);
+
+       /* Set defaults to u-law input, G.721 output */
+       in_coding = AUDIO_ENCODING_ULAW;
+       in_size = sizeof (char);
+       in_buf = (unsigned *)&sample_char;
+       enc_routine = g721_encoder;
+       enc_bits = 4;
+
+       /* Process encoding argument, if any */
+       while ((argc > 1) && (argv[1][0] == '-')) {
+               switch (argv[1][1]) {
+               case '3':
+                       enc_routine = g723_24_encoder;
+                       enc_bits = 3;
+                       break;
+               case '4':
+                       enc_routine = g721_encoder;
+                       enc_bits = 4;
+                       break;
+               case '5':
+                       enc_routine = g723_40_encoder;
+                       enc_bits = 5;
+                       break;
+               case 'u':
+                       in_coding = AUDIO_ENCODING_ULAW;
+                       in_size = sizeof (char);
+                       in_buf = (unsigned *)&sample_char;
+                       break;
+               case 'a':
+                       in_coding = AUDIO_ENCODING_ALAW;
+                       in_size = sizeof (char);
+                       in_buf = (unsigned *)&sample_char;
+                       break;
+               case 'l':
+                       in_coding = AUDIO_ENCODING_LINEAR;
+                       in_size = sizeof (short);
+                       in_buf = (unsigned *)&sample_short;
+                       break;
+               default:
+fprintf(stderr, "CCITT ADPCM Encoder -- usage:\n");
+fprintf(stderr, "\tencode [-3|4|5] [-a|u|l] < infile > outfile\n");
+fprintf(stderr, "where:\n");
+fprintf(stderr, "\t-3\tGenerate G.723 24kbps (3-bit) data\n");
+fprintf(stderr, "\t-4\tGenerate G.721 32kbps (4-bit) data [default]\n");
+fprintf(stderr, "\t-5\tGenerate G.723 40kbps (5-bit) data\n");
+fprintf(stderr, "\t-a\tProcess 8-bit A-law input data\n");
+fprintf(stderr, "\t-u\tProcess 8-bit u-law input data [default]\n");
+fprintf(stderr, "\t-l\tProcess 16-bit linear PCM input data\n");
+                       exit(1);
+               }
+               argc--;
+               argv++;
+       }
+
+       /* Read input file and process */
+       while (fread(in_buf, in_size, 1, stdin) == 1) {
+         code = (*enc_routine)(in_size == 2 ? sample_short : sample_char,
+                   in_coding, &state);
+               resid = pack_output(code, enc_bits);
+       }
+
+       /* Write zero codes until all residual codes are written out */
+       while (resid) {
+               resid = pack_output(0, enc_bits);
+       }
+       fclose(stdout);
+}
diff --git a/gnuradio-core/src/lib/g72x/g711.c b/gnuradio-core/src/lib/g72x/g711.c
new file mode 100644 (file)
index 0000000..d4d60a5
--- /dev/null
@@ -0,0 +1,283 @@
+/*
+ * This source code is a product of Sun Microsystems, Inc. and is provided
+ * for unrestricted use.  Users may copy or modify this source code without
+ * charge.
+ *
+ * SUN SOURCE CODE IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING
+ * THE WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun source code is provided with no support and without any obligation on
+ * the part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY THIS SOFTWARE
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+
+/*
+ * g711.c
+ *
+ * u-law, A-law and linear PCM conversions.
+ */
+#define        SIGN_BIT        (0x80)          /* Sign bit for a A-law byte. */
+#define        QUANT_MASK      (0xf)           /* Quantization field mask. */
+#define        NSEGS           (8)             /* Number of A-law segments. */
+#define        SEG_SHIFT       (4)             /* Left shift for segment number. */
+#define        SEG_MASK        (0x70)          /* Segment field mask. */
+
+static short seg_end[8] = {0xFF, 0x1FF, 0x3FF, 0x7FF,
+                           0xFFF, 0x1FFF, 0x3FFF, 0x7FFF};
+
+/* copy from CCITT G.711 specifications */
+unsigned char _u2a[128] = {                    /* u- to A-law conversions */
+       1,      1,      2,      2,      3,      3,      4,      4,
+       5,      5,      6,      6,      7,      7,      8,      8,
+       9,      10,     11,     12,     13,     14,     15,     16,
+       17,     18,     19,     20,     21,     22,     23,     24,
+       25,     27,     29,     31,     33,     34,     35,     36,
+       37,     38,     39,     40,     41,     42,     43,     44,
+       46,     48,     49,     50,     51,     52,     53,     54,
+       55,     56,     57,     58,     59,     60,     61,     62,
+       64,     65,     66,     67,     68,     69,     70,     71,
+       72,     73,     74,     75,     76,     77,     78,     79,
+       81,     82,     83,     84,     85,     86,     87,     88,
+       89,     90,     91,     92,     93,     94,     95,     96,
+       97,     98,     99,     100,    101,    102,    103,    104,
+       105,    106,    107,    108,    109,    110,    111,    112,
+       113,    114,    115,    116,    117,    118,    119,    120,
+       121,    122,    123,    124,    125,    126,    127,    128};
+
+unsigned char _a2u[128] = {                    /* A- to u-law conversions */
+       1,      3,      5,      7,      9,      11,     13,     15,
+       16,     17,     18,     19,     20,     21,     22,     23,
+       24,     25,     26,     27,     28,     29,     30,     31,
+       32,     32,     33,     33,     34,     34,     35,     35,
+       36,     37,     38,     39,     40,     41,     42,     43,
+       44,     45,     46,     47,     48,     48,     49,     49,
+       50,     51,     52,     53,     54,     55,     56,     57,
+       58,     59,     60,     61,     62,     63,     64,     64,
+       65,     66,     67,     68,     69,     70,     71,     72,
+       73,     74,     75,     76,     77,     78,     79,     79,
+       80,     81,     82,     83,     84,     85,     86,     87,
+       88,     89,     90,     91,     92,     93,     94,     95,
+       96,     97,     98,     99,     100,    101,    102,    103,
+       104,    105,    106,    107,    108,    109,    110,    111,
+       112,    113,    114,    115,    116,    117,    118,    119,
+       120,    121,    122,    123,    124,    125,    126,    127};
+
+static int
+search(
+       int             val,
+       short           *table,
+       int             size)
+{
+       int             i;
+
+       for (i = 0; i < size; i++) {
+               if (val <= *table++)
+                       return (i);
+       }
+       return (size);
+}
+
+/*
+ * linear2alaw() - Convert a 16-bit linear PCM value to 8-bit A-law
+ *
+ * linear2alaw() accepts an 16-bit integer and encodes it as A-law data.
+ *
+ *             Linear Input Code       Compressed Code
+ *     ------------------------        ---------------
+ *     0000000wxyza                    000wxyz
+ *     0000001wxyza                    001wxyz
+ *     000001wxyzab                    010wxyz
+ *     00001wxyzabc                    011wxyz
+ *     0001wxyzabcd                    100wxyz
+ *     001wxyzabcde                    101wxyz
+ *     01wxyzabcdef                    110wxyz
+ *     1wxyzabcdefg                    111wxyz
+ *
+ * For further information see John C. Bellamy's Digital Telephony, 1982,
+ * John Wiley & Sons, pps 98-111 and 472-476.
+ */
+unsigned char
+linear2alaw(
+       int             pcm_val)        /* 2's complement (16-bit range) */
+{
+       int             mask;
+       int             seg;
+       unsigned char   aval;
+
+       if (pcm_val >= 0) {
+               mask = 0xD5;            /* sign (7th) bit = 1 */
+       } else {
+               mask = 0x55;            /* sign bit = 0 */
+               pcm_val = -pcm_val - 8;
+       }
+
+       /* Convert the scaled magnitude to segment number. */
+       seg = search(pcm_val, seg_end, 8);
+
+       /* Combine the sign, segment, and quantization bits. */
+
+       if (seg >= 8)           /* out of range, return maximum value. */
+               return (0x7F ^ mask);
+       else {
+               aval = seg << SEG_SHIFT;
+               if (seg < 2)
+                       aval |= (pcm_val >> 4) & QUANT_MASK;
+               else
+                       aval |= (pcm_val >> (seg + 3)) & QUANT_MASK;
+               return (aval ^ mask);
+       }
+}
+
+/*
+ * alaw2linear() - Convert an A-law value to 16-bit linear PCM
+ *
+ */
+int
+alaw2linear(
+       unsigned char   a_val)
+{
+       int             t;
+       int             seg;
+
+       a_val ^= 0x55;
+
+       t = (a_val & QUANT_MASK) << 4;
+       seg = ((unsigned)a_val & SEG_MASK) >> SEG_SHIFT;
+       switch (seg) {
+       case 0:
+               t += 8;
+               break;
+       case 1:
+               t += 0x108;
+               break;
+       default:
+               t += 0x108;
+               t <<= seg - 1;
+       }
+       return ((a_val & SIGN_BIT) ? t : -t);
+}
+
+#define        BIAS            (0x84)          /* Bias for linear code. */
+
+/*
+ * linear2ulaw() - Convert a linear PCM value to u-law
+ *
+ * In order to simplify the encoding process, the original linear magnitude
+ * is biased by adding 33 which shifts the encoding range from (0 - 8158) to
+ * (33 - 8191). The result can be seen in the following encoding table:
+ *
+ *     Biased Linear Input Code        Compressed Code
+ *     ------------------------        ---------------
+ *     00000001wxyza                   000wxyz
+ *     0000001wxyzab                   001wxyz
+ *     000001wxyzabc                   010wxyz
+ *     00001wxyzabcd                   011wxyz
+ *     0001wxyzabcde                   100wxyz
+ *     001wxyzabcdef                   101wxyz
+ *     01wxyzabcdefg                   110wxyz
+ *     1wxyzabcdefgh                   111wxyz
+ *
+ * Each biased linear code has a leading 1 which identifies the segment
+ * number. The value of the segment number is equal to 7 minus the number
+ * of leading 0's. The quantization interval is directly available as the
+ * four bits wxyz.  * The trailing bits (a - h) are ignored.
+ *
+ * Ordinarily the complement of the resulting code word is used for
+ * transmission, and so the code word is complemented before it is returned.
+ *
+ * For further information see John C. Bellamy's Digital Telephony, 1982,
+ * John Wiley & Sons, pps 98-111 and 472-476.
+ */
+unsigned char
+linear2ulaw(
+       int             pcm_val)        /* 2's complement (16-bit range) */
+{
+       int             mask;
+       int             seg;
+       unsigned char   uval;
+
+       /* Get the sign and the magnitude of the value. */
+       if (pcm_val < 0) {
+               pcm_val = BIAS - pcm_val;
+               mask = 0x7F;
+       } else {
+               pcm_val += BIAS;
+               mask = 0xFF;
+       }
+
+       /* Convert the scaled magnitude to segment number. */
+       seg = search(pcm_val, seg_end, 8);
+
+       /*
+        * Combine the sign, segment, quantization bits;
+        * and complement the code word.
+        */
+       if (seg >= 8)           /* out of range, return maximum value. */
+               return (0x7F ^ mask);
+       else {
+               uval = (seg << 4) | ((pcm_val >> (seg + 3)) & 0xF);
+               return (uval ^ mask);
+       }
+
+}
+
+/*
+ * ulaw2linear() - Convert a u-law value to 16-bit linear PCM
+ *
+ * First, a biased linear code is derived from the code word. An unbiased
+ * output can then be obtained by subtracting 33 from the biased code.
+ *
+ * Note that this function expects to be passed the complement of the
+ * original code word. This is in keeping with ISDN conventions.
+ */
+int
+ulaw2linear(
+       unsigned char   u_val)
+{
+       int             t;
+
+       /* Complement to obtain normal u-law value. */
+       u_val = ~u_val;
+
+       /*
+        * Extract and bias the quantization bits. Then
+        * shift up by the segment number and subtract out the bias.
+        */
+       t = ((u_val & QUANT_MASK) << 3) + BIAS;
+       t <<= ((unsigned)u_val & SEG_MASK) >> SEG_SHIFT;
+
+       return ((u_val & SIGN_BIT) ? (BIAS - t) : (t - BIAS));
+}
+
+/* A-law to u-law conversion */
+unsigned char
+alaw2ulaw(
+       unsigned char   aval)
+{
+       aval &= 0xff;
+       return ((aval & 0x80) ? (0xFF ^ _a2u[aval ^ 0xD5]) :
+           (0x7F ^ _a2u[aval ^ 0x55]));
+}
+
+/* u-law to A-law conversion */
+unsigned char
+ulaw2alaw(
+       unsigned char   uval)
+{
+       uval &= 0xff;
+       return ((uval & 0x80) ? (0xD5 ^ (_u2a[0xFF ^ uval] - 1)) :
+           (0x55 ^ (_u2a[0x7F ^ uval] - 1)));
+}
diff --git a/gnuradio-core/src/lib/g72x/g721.c b/gnuradio-core/src/lib/g72x/g721.c
new file mode 100644 (file)
index 0000000..445f177
--- /dev/null
@@ -0,0 +1,173 @@
+/*
+ * This source code is a product of Sun Microsystems, Inc. and is provided
+ * for unrestricted use.  Users may copy or modify this source code without
+ * charge.
+ *
+ * SUN SOURCE CODE IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING
+ * THE WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun source code is provided with no support and without any obligation on
+ * the part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY THIS SOFTWARE
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+
+/*
+ * g721.c
+ *
+ * Description:
+ *
+ * g721_encoder(), g721_decoder()
+ *
+ * These routines comprise an implementation of the CCITT G.721 ADPCM
+ * coding algorithm.  Essentially, this implementation is identical to
+ * the bit level description except for a few deviations which
+ * take advantage of work station attributes, such as hardware 2's
+ * complement arithmetic and large memory.  Specifically, certain time
+ * consuming operations such as multiplications are replaced
+ * with lookup tables and software 2's complement operations are
+ * replaced with hardware 2's complement.
+ *
+ * The deviation from the bit level specification (lookup tables)
+ * preserves the bit level performance specifications.
+ *
+ * As outlined in the G.721 Recommendation, the algorithm is broken
+ * down into modules.  Each section of code below is preceded by
+ * the name of the module which it is implementing.
+ *
+ */
+#include "g72x.h"
+
+static short qtab_721[7] = {-124, 80, 178, 246, 300, 349, 400};
+/*
+ * Maps G.721 code word to reconstructed scale factor normalized log
+ * magnitude values.
+ */
+static short   _dqlntab[16] = {-2048, 4, 135, 213, 273, 323, 373, 425,
+                               425, 373, 323, 273, 213, 135, 4, -2048};
+
+/* Maps G.721 code word to log of scale factor multiplier. */
+static short   _witab[16] = {-12, 18, 41, 64, 112, 198, 355, 1122,
+                               1122, 355, 198, 112, 64, 41, 18, -12};
+/*
+ * Maps G.721 code words to a set of values whose long and short
+ * term averages are computed and then compared to give an indication
+ * how stationary (steady state) the signal is.
+ */
+static short   _fitab[16] = {0, 0, 0, 0x200, 0x200, 0x200, 0x600, 0xE00,
+                               0xE00, 0x600, 0x200, 0x200, 0x200, 0, 0, 0};
+
+/*
+ * g721_encoder()
+ *
+ * Encodes the input vale of linear PCM, A-law or u-law data sl and returns
+ * the resulting code. -1 is returned for unknown input coding value.
+ */
+int
+g721_encoder(
+       int             sl,
+       int             in_coding,
+       struct g72x_state *state_ptr)
+{
+       short           sezi, se, sez;          /* ACCUM */
+       short           d;                      /* SUBTA */
+       short           sr;                     /* ADDB */
+       short           y;                      /* MIX */
+       short           dqsez;                  /* ADDC */
+       short           dq, i;
+
+       switch (in_coding) {    /* linearize input sample to 14-bit PCM */
+       case AUDIO_ENCODING_ALAW:
+               sl = alaw2linear(sl) >> 2;
+               break;
+       case AUDIO_ENCODING_ULAW:
+               sl = ulaw2linear(sl) >> 2;
+               break;
+       case AUDIO_ENCODING_LINEAR:
+               sl >>= 2;                       /* 14-bit dynamic range */
+               break;
+       default:
+               return (-1);
+       }
+
+       sezi = predictor_zero(state_ptr);
+       sez = sezi >> 1;
+       se = (sezi + predictor_pole(state_ptr)) >> 1;   /* estimated signal */
+
+       d = sl - se;                            /* estimation difference */
+
+       /* quantize the prediction difference */
+       y = step_size(state_ptr);               /* quantizer step size */
+       i = quantize(d, y, qtab_721, 7);        /* i = ADPCM code */
+
+       dq = reconstruct(i & 8, _dqlntab[i], y);        /* quantized est diff */
+
+       sr = (dq < 0) ? se - (dq & 0x3FFF) : se + dq;   /* reconst. signal */
+
+       dqsez = sr + sez - se;                  /* pole prediction diff. */
+
+       update(4, y, _witab[i] << 5, _fitab[i], dq, sr, dqsez, state_ptr);
+
+       return (i);
+}
+
+/*
+ * g721_decoder()
+ *
+ * Description:
+ *
+ * Decodes a 4-bit code of G.721 encoded data of i and
+ * returns the resulting linear PCM, A-law or u-law value.
+ * return -1 for unknown out_coding value.
+ */
+int
+g721_decoder(
+       int             i,
+       int             out_coding,
+       struct g72x_state *state_ptr)
+{
+       short           sezi, sei, sez, se;     /* ACCUM */
+       short           y;                      /* MIX */
+       short           sr;                     /* ADDB */
+       short           dq;
+       short           dqsez;
+
+       i &= 0x0f;                      /* mask to get proper bits */
+       sezi = predictor_zero(state_ptr);
+       sez = sezi >> 1;
+       sei = sezi + predictor_pole(state_ptr);
+       se = sei >> 1;                  /* se = estimated signal */
+
+       y = step_size(state_ptr);       /* dynamic quantizer step size */
+
+       dq = reconstruct(i & 0x08, _dqlntab[i], y); /* quantized diff. */
+
+       sr = (dq < 0) ? (se - (dq & 0x3FFF)) : se + dq; /* reconst. signal */
+
+       dqsez = sr - se + sez;                  /* pole prediction diff. */
+
+       update(4, y, _witab[i] << 5, _fitab[i], dq, sr, dqsez, state_ptr);
+
+       switch (out_coding) {
+       case AUDIO_ENCODING_ALAW:
+               return (tandem_adjust_alaw(sr, se, y, i, 8, qtab_721));
+       case AUDIO_ENCODING_ULAW:
+               return (tandem_adjust_ulaw(sr, se, y, i, 8, qtab_721));
+       case AUDIO_ENCODING_LINEAR:
+               return (sr << 2);       /* sr was 14-bit dynamic range */
+       default:
+               return (-1);
+       }
+}
diff --git a/gnuradio-core/src/lib/g72x/g723_24.c b/gnuradio-core/src/lib/g72x/g723_24.c
new file mode 100644 (file)
index 0000000..452f4da
--- /dev/null
@@ -0,0 +1,158 @@
+/*
+ * This source code is a product of Sun Microsystems, Inc. and is provided
+ * for unrestricted use.  Users may copy or modify this source code without
+ * charge.
+ *
+ * SUN SOURCE CODE IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING
+ * THE WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun source code is provided with no support and without any obligation on
+ * the part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY THIS SOFTWARE
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+
+/*
+ * g723_24.c
+ *
+ * Description:
+ *
+ * g723_24_encoder(), g723_24_decoder()
+ *
+ * These routines comprise an implementation of the CCITT G.723 24 Kbps
+ * ADPCM coding algorithm.  Essentially, this implementation is identical to
+ * the bit level description except for a few deviations which take advantage
+ * of workstation attributes, such as hardware 2's complement arithmetic.
+ *
+ */
+#include "g72x.h"
+
+/*
+ * Maps G.723_24 code word to reconstructed scale factor normalized log
+ * magnitude values.
+ */
+static short   _dqlntab[8] = {-2048, 135, 273, 373, 373, 273, 135, -2048};
+
+/* Maps G.723_24 code word to log of scale factor multiplier. */
+static short   _witab[8] = {-128, 960, 4384, 18624, 18624, 4384, 960, -128};
+
+/*
+ * Maps G.723_24 code words to a set of values whose long and short
+ * term averages are computed and then compared to give an indication
+ * how stationary (steady state) the signal is.
+ */
+static short   _fitab[8] = {0, 0x200, 0x400, 0xE00, 0xE00, 0x400, 0x200, 0};
+
+static short qtab_723_24[3] = {8, 218, 331};
+
+/*
+ * g723_24_encoder()
+ *
+ * Encodes a linear PCM, A-law or u-law input sample and returns its 3-bit code.
+ * Returns -1 if invalid input coding value.
+ */
+int
+g723_24_encoder(
+       int             sl,
+       int             in_coding,
+       struct g72x_state *state_ptr)
+{
+       short           sei, sezi, se, sez;     /* ACCUM */
+       short           d;                      /* SUBTA */
+       short           y;                      /* MIX */
+       short           sr;                     /* ADDB */
+       short           dqsez;                  /* ADDC */
+       short           dq, i;
+
+       switch (in_coding) {    /* linearize input sample to 14-bit PCM */
+       case AUDIO_ENCODING_ALAW:
+               sl = alaw2linear(sl) >> 2;
+               break;
+       case AUDIO_ENCODING_ULAW:
+               sl = ulaw2linear(sl) >> 2;
+               break;
+       case AUDIO_ENCODING_LINEAR:
+               sl >>= 2;               /* sl of 14-bit dynamic range */
+               break;
+       default:
+               return (-1);
+       }
+
+       sezi = predictor_zero(state_ptr);
+       sez = sezi >> 1;
+       sei = sezi + predictor_pole(state_ptr);
+       se = sei >> 1;                  /* se = estimated signal */
+
+       d = sl - se;                    /* d = estimation diff. */
+
+       /* quantize prediction difference d */
+       y = step_size(state_ptr);       /* quantizer step size */
+       i = quantize(d, y, qtab_723_24, 3);     /* i = ADPCM code */
+       dq = reconstruct(i & 4, _dqlntab[i], y); /* quantized diff. */
+
+       sr = (dq < 0) ? se - (dq & 0x3FFF) : se + dq; /* reconstructed signal */
+
+       dqsez = sr + sez - se;          /* pole prediction diff. */
+
+       update(3, y, _witab[i], _fitab[i], dq, sr, dqsez, state_ptr);
+
+       return (i);
+}
+
+/*
+ * g723_24_decoder()
+ *
+ * Decodes a 3-bit CCITT G.723_24 ADPCM code and returns
+ * the resulting 16-bit linear PCM, A-law or u-law sample value.
+ * -1 is returned if the output coding is unknown.
+ */
+int
+g723_24_decoder(
+       int             i,
+       int             out_coding,
+       struct g72x_state *state_ptr)
+{
+       short           sezi, sei, sez, se;     /* ACCUM */
+       short           y;                      /* MIX */
+       short           sr;                     /* ADDB */
+       short           dq;
+       short           dqsez;
+
+       i &= 0x07;                      /* mask to get proper bits */
+       sezi = predictor_zero(state_ptr);
+       sez = sezi >> 1;
+       sei = sezi + predictor_pole(state_ptr);
+       se = sei >> 1;                  /* se = estimated signal */
+
+       y = step_size(state_ptr);       /* adaptive quantizer step size */
+       dq = reconstruct(i & 0x04, _dqlntab[i], y); /* unquantize pred diff */
+
+       sr = (dq < 0) ? (se - (dq & 0x3FFF)) : (se + dq); /* reconst. signal */
+
+       dqsez = sr - se + sez;                  /* pole prediction diff. */
+
+       update(3, y, _witab[i], _fitab[i], dq, sr, dqsez, state_ptr);
+
+       switch (out_coding) {
+       case AUDIO_ENCODING_ALAW:
+               return (tandem_adjust_alaw(sr, se, y, i, 4, qtab_723_24));
+       case AUDIO_ENCODING_ULAW:
+               return (tandem_adjust_ulaw(sr, se, y, i, 4, qtab_723_24));
+       case AUDIO_ENCODING_LINEAR:
+               return (sr << 2);       /* sr was of 14-bit dynamic range */
+       default:
+               return (-1);
+       }
+}
diff --git a/gnuradio-core/src/lib/g72x/g723_40.c b/gnuradio-core/src/lib/g72x/g723_40.c
new file mode 100644 (file)
index 0000000..4858baf
--- /dev/null
@@ -0,0 +1,178 @@
+/*
+ * This source code is a product of Sun Microsystems, Inc. and is provided
+ * for unrestricted use.  Users may copy or modify this source code without
+ * charge.
+ *
+ * SUN SOURCE CODE IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING
+ * THE WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun source code is provided with no support and without any obligation on
+ * the part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY THIS SOFTWARE
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+
+/*
+ * g723_40.c
+ *
+ * Description:
+ *
+ * g723_40_encoder(), g723_40_decoder()
+ *
+ * These routines comprise an implementation of the CCITT G.723 40Kbps
+ * ADPCM coding algorithm.  Essentially, this implementation is identical to
+ * the bit level description except for a few deviations which
+ * take advantage of workstation attributes, such as hardware 2's
+ * complement arithmetic.
+ *
+ * The deviation from the bit level specification (lookup tables),
+ * preserves the bit level performance specifications.
+ *
+ * As outlined in the G.723 Recommendation, the algorithm is broken
+ * down into modules.  Each section of code below is preceded by
+ * the name of the module which it is implementing.
+ *
+ */
+#include "g72x.h"
+
+/*
+ * Maps G.723_40 code word to ructeconstructed scale factor normalized log
+ * magnitude values.
+ */
+static short   _dqlntab[32] = {-2048, -66, 28, 104, 169, 224, 274, 318,
+                               358, 395, 429, 459, 488, 514, 539, 566,
+                               566, 539, 514, 488, 459, 429, 395, 358,
+                               318, 274, 224, 169, 104, 28, -66, -2048};
+
+/* Maps G.723_40 code word to log of scale factor multiplier. */
+static short   _witab[32] = {448, 448, 768, 1248, 1280, 1312, 1856, 3200,
+                       4512, 5728, 7008, 8960, 11456, 14080, 16928, 22272,
+                       22272, 16928, 14080, 11456, 8960, 7008, 5728, 4512,
+                       3200, 1856, 1312, 1280, 1248, 768, 448, 448};
+
+/*
+ * Maps G.723_40 code words to a set of values whose long and short
+ * term averages are computed and then compared to give an indication
+ * how stationary (steady state) the signal is.
+ */
+static short   _fitab[32] = {0, 0, 0, 0, 0, 0x200, 0x200, 0x200,
+                       0x200, 0x200, 0x400, 0x600, 0x800, 0xA00, 0xC00, 0xC00,
+                       0xC00, 0xC00, 0xA00, 0x800, 0x600, 0x400, 0x200, 0x200,
+                       0x200, 0x200, 0x200, 0, 0, 0, 0, 0};
+
+static short qtab_723_40[15] = {-122, -16, 68, 139, 198, 250, 298, 339,
+                               378, 413, 445, 475, 502, 528, 553};
+
+/*
+ * g723_40_encoder()
+ *
+ * Encodes a 16-bit linear PCM, A-law or u-law input sample and retuens
+ * the resulting 5-bit CCITT G.723 40Kbps code.
+ * Returns -1 if the input coding value is invalid.
+ */
+int
+g723_40_encoder(
+       int             sl,
+       int             in_coding,
+       struct g72x_state *state_ptr)
+{
+       short           sei, sezi, se, sez;     /* ACCUM */
+       short           d;                      /* SUBTA */
+       short           y;                      /* MIX */
+       short           sr;                     /* ADDB */
+       short           dqsez;                  /* ADDC */
+       short           dq, i;
+
+       switch (in_coding) {    /* linearize input sample to 14-bit PCM */
+       case AUDIO_ENCODING_ALAW:
+               sl = alaw2linear(sl) >> 2;
+               break;
+       case AUDIO_ENCODING_ULAW:
+               sl = ulaw2linear(sl) >> 2;
+               break;
+       case AUDIO_ENCODING_LINEAR:
+               sl >>= 2;               /* sl of 14-bit dynamic range */
+               break;
+       default:
+               return (-1);
+       }
+
+       sezi = predictor_zero(state_ptr);
+       sez = sezi >> 1;
+       sei = sezi + predictor_pole(state_ptr);
+       se = sei >> 1;                  /* se = estimated signal */
+
+       d = sl - se;                    /* d = estimation difference */
+
+       /* quantize prediction difference */
+       y = step_size(state_ptr);       /* adaptive quantizer step size */
+       i = quantize(d, y, qtab_723_40, 15);    /* i = ADPCM code */
+
+       dq = reconstruct(i & 0x10, _dqlntab[i], y);     /* quantized diff */
+
+       sr = (dq < 0) ? se - (dq & 0x7FFF) : se + dq; /* reconstructed signal */
+
+       dqsez = sr + sez - se;          /* dqsez = pole prediction diff. */
+
+       update(5, y, _witab[i], _fitab[i], dq, sr, dqsez, state_ptr);
+
+       return (i);
+}
+
+/*
+ * g723_40_decoder()
+ *
+ * Decodes a 5-bit CCITT G.723 40Kbps code and returns
+ * the resulting 16-bit linear PCM, A-law or u-law sample value.
+ * -1 is returned if the output coding is unknown.
+ */
+int
+g723_40_decoder(
+       int             i,
+       int             out_coding,
+       struct g72x_state *state_ptr)
+{
+       short           sezi, sei, sez, se;     /* ACCUM */
+       short           y;                      /* MIX */
+       short           sr;                     /* ADDB */
+       short           dq;
+       short           dqsez;
+
+       i &= 0x1f;                      /* mask to get proper bits */
+       sezi = predictor_zero(state_ptr);
+       sez = sezi >> 1;
+       sei = sezi + predictor_pole(state_ptr);
+       se = sei >> 1;                  /* se = estimated signal */
+
+       y = step_size(state_ptr);       /* adaptive quantizer step size */
+       dq = reconstruct(i & 0x10, _dqlntab[i], y);     /* estimation diff. */
+
+       sr = (dq < 0) ? (se - (dq & 0x7FFF)) : (se + dq); /* reconst. signal */
+
+       dqsez = sr - se + sez;          /* pole prediction diff. */
+
+       update(5, y, _witab[i], _fitab[i], dq, sr, dqsez, state_ptr);
+
+       switch (out_coding) {
+       case AUDIO_ENCODING_ALAW:
+               return (tandem_adjust_alaw(sr, se, y, i, 0x10, qtab_723_40));
+       case AUDIO_ENCODING_ULAW:
+               return (tandem_adjust_ulaw(sr, se, y, i, 0x10, qtab_723_40));
+       case AUDIO_ENCODING_LINEAR:
+               return (sr << 2);       /* sr was of 14-bit dynamic range */
+       default:
+               return (-1);
+       }
+}
diff --git a/gnuradio-core/src/lib/g72x/g72x.c b/gnuradio-core/src/lib/g72x/g72x.c
new file mode 100644 (file)
index 0000000..9a823c7
--- /dev/null
@@ -0,0 +1,576 @@
+/*
+ * This source code is a product of Sun Microsystems, Inc. and is provided
+ * for unrestricted use.  Users may copy or modify this source code without
+ * charge.
+ *
+ * SUN SOURCE CODE IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING
+ * THE WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun source code is provided with no support and without any obligation on
+ * the part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY THIS SOFTWARE
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+#include <stdlib.h>
+/*
+ * g72x.c
+ *
+ * Common routines for G.721 and G.723 conversions.
+ */
+
+#include "g72x.h"
+
+static short power2[15] = {1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80,
+                       0x100, 0x200, 0x400, 0x800, 0x1000, 0x2000, 0x4000};
+
+/*
+ * quan()
+ *
+ * quantizes the input val against the table of size short integers.
+ * It returns i if table[i - 1] <= val < table[i].
+ *
+ * Using linear search for simple coding.
+ */
+static int
+quan(
+       int             val,
+       short           *table,
+       int             size)
+{
+       int             i;
+
+       for (i = 0; i < size; i++)
+               if (val < *table++)
+                       break;
+       return (i);
+}
+
+/*
+ * fmult()
+ *
+ * returns the integer product of the 14-bit integer "an" and
+ * "floating point" representation (4-bit exponent, 6-bit mantessa) "srn".
+ */
+static int
+fmult(
+       int             an,
+       int             srn)
+{
+       short           anmag, anexp, anmant;
+       short           wanexp, wanmant;
+       short           retval;
+
+       anmag = (an > 0) ? an : ((-an) & 0x1FFF);
+       anexp = quan(anmag, power2, 15) - 6;
+       anmant = (anmag == 0) ? 32 :
+           (anexp >= 0) ? anmag >> anexp : anmag << -anexp;
+       wanexp = anexp + ((srn >> 6) & 0xF) - 13;
+
+       wanmant = (anmant * (srn & 077) + 0x30) >> 4;
+       retval = (wanexp >= 0) ? ((wanmant << wanexp) & 0x7FFF) :
+           (wanmant >> -wanexp);
+
+       return (((an ^ srn) < 0) ? -retval : retval);
+}
+
+/*
+ * g72x_init_state()
+ *
+ * This routine initializes and/or resets the g72x_state structure
+ * pointed to by 'state_ptr'.
+ * All the initial state values are specified in the CCITT G.721 document.
+ */
+void
+g72x_init_state(
+       struct g72x_state *state_ptr)
+{
+       int             cnta;
+
+       state_ptr->yl = 34816;
+       state_ptr->yu = 544;
+       state_ptr->dms = 0;
+       state_ptr->dml = 0;
+       state_ptr->ap = 0;
+       for (cnta = 0; cnta < 2; cnta++) {
+               state_ptr->a[cnta] = 0;
+               state_ptr->pk[cnta] = 0;
+               state_ptr->sr[cnta] = 32;
+       }
+       for (cnta = 0; cnta < 6; cnta++) {
+               state_ptr->b[cnta] = 0;
+               state_ptr->dq[cnta] = 32;
+       }
+       state_ptr->td = 0;
+}
+
+/*
+ * predictor_zero()
+ *
+ * computes the estimated signal from 6-zero predictor.
+ *
+ */
+int
+predictor_zero(
+       struct g72x_state *state_ptr)
+{
+       int             i;
+       int             sezi;
+
+       sezi = fmult(state_ptr->b[0] >> 2, state_ptr->dq[0]);
+       for (i = 1; i < 6; i++)                 /* ACCUM */
+               sezi += fmult(state_ptr->b[i] >> 2, state_ptr->dq[i]);
+       return (sezi);
+}
+/*
+ * predictor_pole()
+ *
+ * computes the estimated signal from 2-pole predictor.
+ *
+ */
+int
+predictor_pole(
+       struct g72x_state *state_ptr)
+{
+       return (fmult(state_ptr->a[1] >> 2, state_ptr->sr[1]) +
+           fmult(state_ptr->a[0] >> 2, state_ptr->sr[0]));
+}
+/*
+ * step_size()
+ *
+ * computes the quantization step size of the adaptive quantizer.
+ *
+ */
+int
+step_size(
+       struct g72x_state *state_ptr)
+{
+       int             y;
+       int             dif;
+       int             al;
+
+       if (state_ptr->ap >= 256)
+               return (state_ptr->yu);
+       else {
+               y = state_ptr->yl >> 6;
+               dif = state_ptr->yu - y;
+               al = state_ptr->ap >> 2;
+               if (dif > 0)
+                       y += (dif * al) >> 6;
+               else if (dif < 0)
+                       y += (dif * al + 0x3F) >> 6;
+               return (y);
+       }
+}
+
+/*
+ * quantize()
+ *
+ * Given a raw sample, 'd', of the difference signal and a
+ * quantization step size scale factor, 'y', this routine returns the
+ * ADPCM codeword to which that sample gets quantized.  The step
+ * size scale factor division operation is done in the log base 2 domain
+ * as a subtraction.
+ */
+int
+quantize(
+       int             d,      /* Raw difference signal sample */
+       int             y,      /* Step size multiplier */
+       short           *table, /* quantization table */
+       int             size)   /* table size of short integers */
+{
+       short           dqm;    /* Magnitude of 'd' */
+       short           exp;    /* Integer part of base 2 log of 'd' */
+       short           mant;   /* Fractional part of base 2 log */
+       short           dl;     /* Log of magnitude of 'd' */
+       short           dln;    /* Step size scale factor normalized log */
+       int             i;
+
+       /*
+        * LOG
+        *
+        * Compute base 2 log of 'd', and store in 'dl'.
+        */
+       dqm = abs(d);
+       exp = quan(dqm >> 1, power2, 15);
+       mant = ((dqm << 7) >> exp) & 0x7F;      /* Fractional portion. */
+       dl = (exp << 7) + mant;
+
+       /*
+        * SUBTB
+        *
+        * "Divide" by step size multiplier.
+        */
+       dln = dl - (y >> 2);
+
+       /*
+        * QUAN
+        *
+        * Obtain codword i for 'd'.
+        */
+       i = quan(dln, table, size);
+       if (d < 0)                      /* take 1's complement of i */
+               return ((size << 1) + 1 - i);
+       else if (i == 0)                /* take 1's complement of 0 */
+               return ((size << 1) + 1); /* new in 1988 */
+       else
+               return (i);
+}
+/*
+ * reconstruct()
+ *
+ * Returns reconstructed difference signal 'dq' obtained from
+ * codeword 'i' and quantization step size scale factor 'y'.
+ * Multiplication is performed in log base 2 domain as addition.
+ */
+int
+reconstruct(
+       int             sign,   /* 0 for non-negative value */
+       int             dqln,   /* G.72x codeword */
+       int             y)      /* Step size multiplier */
+{
+       short           dql;    /* Log of 'dq' magnitude */
+       short           dex;    /* Integer part of log */
+       short           dqt;
+       short           dq;     /* Reconstructed difference signal sample */
+
+       dql = dqln + (y >> 2);  /* ADDA */
+
+       if (dql < 0) {
+               return ((sign) ? -0x8000 : 0);
+       } else {                /* ANTILOG */
+               dex = (dql >> 7) & 15;
+               dqt = 128 + (dql & 127);
+               dq = (dqt << 7) >> (14 - dex);
+               return ((sign) ? (dq - 0x8000) : dq);
+       }
+}
+
+
+/*
+ * update()
+ *
+ * updates the state variables for each output code
+ */
+void
+update(
+       int             code_size,      /* distinguish 723_40 with others */
+       int             y,              /* quantizer step size */
+       int             wi,             /* scale factor multiplier */
+       int             fi,             /* for long/short term energies */
+       int             dq,             /* quantized prediction difference */
+       int             sr,             /* reconstructed signal */
+       int             dqsez,          /* difference from 2-pole predictor */
+       struct g72x_state *state_ptr)   /* coder state pointer */
+{
+       int             cnt;
+       short           mag, exp;       /* Adaptive predictor, FLOAT A */
+       short           a2p = 0;        /* LIMC */
+       short           a1ul;           /* UPA1 */
+       short           pks1;           /* UPA2 */
+       short           fa1;
+       char            tr;             /* tone/transition detector */
+       short           ylint, thr2, dqthr;
+       short           ylfrac, thr1;
+       short           pk0;
+
+       pk0 = (dqsez < 0) ? 1 : 0;      /* needed in updating predictor poles */
+
+       mag = dq & 0x7FFF;              /* prediction difference magnitude */
+       /* TRANS */
+       ylint = state_ptr->yl >> 15;    /* exponent part of yl */
+       ylfrac = (state_ptr->yl >> 10) & 0x1F;  /* fractional part of yl */
+       thr1 = (32 + ylfrac) << ylint;          /* threshold */
+       thr2 = (ylint > 9) ? 31 << 10 : thr1;   /* limit thr2 to 31 << 10 */
+       dqthr = (thr2 + (thr2 >> 1)) >> 1;      /* dqthr = 0.75 * thr2 */
+       if (state_ptr->td == 0)         /* signal supposed voice */
+               tr = 0;
+       else if (mag <= dqthr)          /* supposed data, but small mag */
+               tr = 0;                 /* treated as voice */
+       else                            /* signal is data (modem) */
+               tr = 1;
+
+       /*
+        * Quantizer scale factor adaptation.
+        */
+
+       /* FUNCTW & FILTD & DELAY */
+       /* update non-steady state step size multiplier */
+       state_ptr->yu = y + ((wi - y) >> 5);
+
+       /* LIMB */
+       if (state_ptr->yu < 544)        /* 544 <= yu <= 5120 */
+               state_ptr->yu = 544;
+       else if (state_ptr->yu > 5120)
+               state_ptr->yu = 5120;
+
+       /* FILTE & DELAY */
+       /* update steady state step size multiplier */
+       state_ptr->yl += state_ptr->yu + ((-state_ptr->yl) >> 6);
+
+       /*
+        * Adaptive predictor coefficients.
+        */
+       if (tr == 1) {                  /* reset a's and b's for modem signal */
+               state_ptr->a[0] = 0;
+               state_ptr->a[1] = 0;
+               state_ptr->b[0] = 0;
+               state_ptr->b[1] = 0;
+               state_ptr->b[2] = 0;
+               state_ptr->b[3] = 0;
+               state_ptr->b[4] = 0;
+               state_ptr->b[5] = 0;
+       } else {                        /* update a's and b's */
+               pks1 = pk0 ^ state_ptr->pk[0];          /* UPA2 */
+
+               /* update predictor pole a[1] */
+               a2p = state_ptr->a[1] - (state_ptr->a[1] >> 7);
+               if (dqsez != 0) {
+                       fa1 = (pks1) ? state_ptr->a[0] : -state_ptr->a[0];
+                       if (fa1 < -8191)        /* a2p = function of fa1 */
+                               a2p -= 0x100;
+                       else if (fa1 > 8191)
+                               a2p += 0xFF;
+                       else
+                               a2p += fa1 >> 5;
+
+                       if (pk0 ^ state_ptr->pk[1])
+                               /* LIMC */
+                               if (a2p <= -12160)
+                                       a2p = -12288;
+                               else if (a2p >= 12416)
+                                       a2p = 12288;
+                               else
+                                       a2p -= 0x80;
+                       else if (a2p <= -12416)
+                               a2p = -12288;
+                       else if (a2p >= 12160)
+                               a2p = 12288;
+                       else
+                               a2p += 0x80;
+               }
+
+               /* TRIGB & DELAY */
+               state_ptr->a[1] = a2p;
+
+               /* UPA1 */
+               /* update predictor pole a[0] */
+               state_ptr->a[0] -= state_ptr->a[0] >> 8;
+               if (dqsez != 0){
+                       if (pks1 == 0)
+                               state_ptr->a[0] += 192;
+                       else
+                               state_ptr->a[0] -= 192;
+               }
+
+               /* LIMD */
+               a1ul = 15360 - a2p;
+               if (state_ptr->a[0] < -a1ul)
+                       state_ptr->a[0] = -a1ul;
+               else if (state_ptr->a[0] > a1ul)
+                       state_ptr->a[0] = a1ul;
+
+               /* UPB : update predictor zeros b[6] */
+               for (cnt = 0; cnt < 6; cnt++) {
+                       if (code_size == 5)             /* for 40Kbps G.723 */
+                               state_ptr->b[cnt] -= state_ptr->b[cnt] >> 9;
+                       else                    /* for G.721 and 24Kbps G.723 */
+                               state_ptr->b[cnt] -= state_ptr->b[cnt] >> 8;
+                       if (dq & 0x7FFF) {                      /* XOR */
+                               if ((dq ^ state_ptr->dq[cnt]) >= 0)
+                                       state_ptr->b[cnt] += 128;
+                               else
+                                       state_ptr->b[cnt] -= 128;
+                       }
+               }
+       }
+
+       for (cnt = 5; cnt > 0; cnt--)
+               state_ptr->dq[cnt] = state_ptr->dq[cnt-1];
+       /* FLOAT A : convert dq[0] to 4-bit exp, 6-bit mantissa f.p. */
+       if (mag == 0) {
+               state_ptr->dq[0] = (dq >= 0) ? 0x20 : 0xFC20;
+       } else {
+               exp = quan(mag, power2, 15);
+               state_ptr->dq[0] = (dq >= 0) ?
+                   (exp << 6) + ((mag << 6) >> exp) :
+                   (exp << 6) + ((mag << 6) >> exp) - 0x400;
+       }
+
+       state_ptr->sr[1] = state_ptr->sr[0];
+       /* FLOAT B : convert sr to 4-bit exp., 6-bit mantissa f.p. */
+       if (sr == 0) {
+               state_ptr->sr[0] = 0x20;
+       } else if (sr > 0) {
+               exp = quan(sr, power2, 15);
+               state_ptr->sr[0] = (exp << 6) + ((sr << 6) >> exp);
+       } else if (sr > -32768) {
+               mag = -sr;
+               exp = quan(mag, power2, 15);
+               state_ptr->sr[0] =  (exp << 6) + ((mag << 6) >> exp) - 0x400;
+       } else
+               state_ptr->sr[0] = 0xFC20;
+
+       /* DELAY A */
+       state_ptr->pk[1] = state_ptr->pk[0];
+       state_ptr->pk[0] = pk0;
+
+       /* TONE */
+       if (tr == 1)            /* this sample has been treated as data */
+               state_ptr->td = 0;      /* next one will be treated as voice */
+       else if (a2p < -11776)  /* small sample-to-sample correlation */
+               state_ptr->td = 1;      /* signal may be data */
+       else                            /* signal is voice */
+               state_ptr->td = 0;
+
+       /*
+        * Adaptation speed control.
+        */
+       state_ptr->dms += (fi - state_ptr->dms) >> 5;           /* FILTA */
+       state_ptr->dml += (((fi << 2) - state_ptr->dml) >> 7);  /* FILTB */
+
+       if (tr == 1)
+               state_ptr->ap = 256;
+       else if (y < 1536)                                      /* SUBTC */
+               state_ptr->ap += (0x200 - state_ptr->ap) >> 4;
+       else if (state_ptr->td == 1)
+               state_ptr->ap += (0x200 - state_ptr->ap) >> 4;
+       else if (abs((state_ptr->dms << 2) - state_ptr->dml) >=
+           (state_ptr->dml >> 3))
+               state_ptr->ap += (0x200 - state_ptr->ap) >> 4;
+       else
+               state_ptr->ap += (-state_ptr->ap) >> 4;
+}
+
+/*
+ * tandem_adjust(sr, se, y, i, sign)
+ *
+ * At the end of ADPCM decoding, it simulates an encoder which may be receiving
+ * the output of this decoder as a tandem process. If the output of the
+ * simulated encoder differs from the input to this decoder, the decoder output
+ * is adjusted by one level of A-law or u-law codes.
+ *
+ * Input:
+ *     sr      decoder output linear PCM sample,
+ *     se      predictor estimate sample,
+ *     y       quantizer step size,
+ *     i       decoder input code,
+ *     sign    sign bit of code i
+ *
+ * Return:
+ *     adjusted A-law or u-law compressed sample.
+ */
+int
+tandem_adjust_alaw(
+       int             sr,     /* decoder output linear PCM sample */
+       int             se,     /* predictor estimate sample */
+       int             y,      /* quantizer step size */
+       int             i,      /* decoder input code */
+       int             sign,
+       short           *qtab)
+{
+       unsigned char   sp;     /* A-law compressed 8-bit code */
+       short           dx;     /* prediction error */
+       char            id;     /* quantized prediction error */
+       int             sd;     /* adjusted A-law decoded sample value */
+       int             im;     /* biased magnitude of i */
+       int             imx;    /* biased magnitude of id */
+
+       if (sr <= -32768)
+               sr = -1;
+       sp = linear2alaw((sr >> 1) << 3);       /* short to A-law compression */
+       dx = (alaw2linear(sp) >> 2) - se;       /* 16-bit prediction error */
+       id = quantize(dx, y, qtab, sign - 1);
+
+       if (id == i) {                  /* no adjustment on sp */
+               return (sp);
+       } else {                        /* sp adjustment needed */
+               /* ADPCM codes : 8, 9, ... F, 0, 1, ... , 6, 7 */
+               im = i ^ sign;          /* 2's complement to biased unsigned */
+               imx = id ^ sign;
+
+               if (imx > im) {         /* sp adjusted to next lower value */
+                       if (sp & 0x80) {
+                               sd = (sp == 0xD5) ? 0x55 :
+                                   ((sp ^ 0x55) - 1) ^ 0x55;
+                       } else {
+                               sd = (sp == 0x2A) ? 0x2A :
+                                   ((sp ^ 0x55) + 1) ^ 0x55;
+                       }
+               } else {                /* sp adjusted to next higher value */
+                       if (sp & 0x80)
+                               sd = (sp == 0xAA) ? 0xAA :
+                                   ((sp ^ 0x55) + 1) ^ 0x55;
+                       else
+                               sd = (sp == 0x55) ? 0xD5 :
+                                   ((sp ^ 0x55) - 1) ^ 0x55;
+               }
+               return (sd);
+       }
+}
+
+int
+tandem_adjust_ulaw(
+       int             sr,     /* decoder output linear PCM sample */
+       int             se,     /* predictor estimate sample */
+       int             y,      /* quantizer step size */
+       int             i,      /* decoder input code */
+       int             sign,
+       short           *qtab)
+{
+       unsigned char   sp;     /* u-law compressed 8-bit code */
+       short           dx;     /* prediction error */
+       char            id;     /* quantized prediction error */
+       int             sd;     /* adjusted u-law decoded sample value */
+       int             im;     /* biased magnitude of i */
+       int             imx;    /* biased magnitude of id */
+
+       if (sr <= -32768)
+               sr = 0;
+       sp = linear2ulaw(sr << 2);      /* short to u-law compression */
+       dx = (ulaw2linear(sp) >> 2) - se;       /* 16-bit prediction error */
+       id = quantize(dx, y, qtab, sign - 1);
+       if (id == i) {
+               return (sp);
+       } else {
+               /* ADPCM codes : 8, 9, ... F, 0, 1, ... , 6, 7 */
+               im = i ^ sign;          /* 2's complement to biased unsigned */
+               imx = id ^ sign;
+               if (imx > im) {         /* sp adjusted to next lower value */
+                       if (sp & 0x80)
+                               sd = (sp == 0xFF) ? 0x7E : sp + 1;
+                       else
+                               sd = (sp == 0) ? 0 : sp - 1;
+
+               } else {                /* sp adjusted to next higher value */
+                       if (sp & 0x80)
+                               sd = (sp == 0x80) ? 0x80 : sp - 1;
+                       else
+                               sd = (sp == 0x7F) ? 0xFE : sp + 1;
+               }
+               return (sd);
+       }
+}
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/gnuradio-core/src/lib/g72x/g72x.h b/gnuradio-core/src/lib/g72x/g72x.h
new file mode 100644 (file)
index 0000000..3380717
--- /dev/null
@@ -0,0 +1,156 @@
+/*
+ * This source code is a product of Sun Microsystems, Inc. and is provided
+ * for unrestricted use.  Users may copy or modify this source code without
+ * charge.
+ *
+ * SUN SOURCE CODE IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING
+ * THE WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun source code is provided with no support and without any obligation on
+ * the part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY THIS SOFTWARE
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+
+/*
+ * g72x.h
+ *
+ * Header file for CCITT conversion routines.
+ *
+ */
+#ifndef _G72X_H
+#define        _G72X_H
+
+#define        AUDIO_ENCODING_ULAW     (1)     /* ISDN u-law */
+#define        AUDIO_ENCODING_ALAW     (2)     /* ISDN A-law */
+#define        AUDIO_ENCODING_LINEAR   (3)     /* PCM 2's-complement (0-center) */
+
+/*
+ * The following is the definition of the state structure
+ * used by the G.721/G.723 encoder and decoder to preserve their internal
+ * state between successive calls.  The meanings of the majority
+ * of the state structure fields are explained in detail in the
+ * CCITT Recommendation G.721.  The field names are essentially indentical
+ * to variable names in the bit level description of the coding algorithm
+ * included in this Recommendation.
+ */
+struct g72x_state {
+       long yl;        /* Locked or steady state step size multiplier. */
+       short yu;       /* Unlocked or non-steady state step size multiplier. */
+       short dms;      /* Short term energy estimate. */
+       short dml;      /* Long term energy estimate. */
+       short ap;       /* Linear weighting coefficient of 'yl' and 'yu'. */
+
+       short a[2];     /* Coefficients of pole portion of prediction filter. */
+       short b[6];     /* Coefficients of zero portion of prediction filter. */
+       short pk[2];    /*
+                        * Signs of previous two samples of a partially
+                        * reconstructed signal.
+                        */
+       short dq[6];    /*
+                        * Previous 6 samples of the quantized difference
+                        * signal represented in an internal floating point
+                        * format.
+                        */
+       short sr[2];    /*
+                        * Previous 2 samples of the quantized difference
+                        * signal represented in an internal floating point
+                        * format.
+                        */
+       char td;        /* delayed tone detect, new in 1988 version */
+};
+
+/* External function definitions. */
+
+extern void g72x_init_state(struct g72x_state *);
+extern int g721_encoder(
+               int sample,
+               int in_coding,
+               struct g72x_state *state_ptr);
+extern int g721_decoder(
+               int code,
+               int out_coding,
+               struct g72x_state *state_ptr);
+extern int g723_24_encoder(
+               int sample,
+               int in_coding,
+               struct g72x_state *state_ptr);
+extern int g723_24_decoder(
+               int code,
+               int out_coding,
+               struct g72x_state *state_ptr);
+extern int g723_40_encoder(
+               int sample,
+               int in_coding,
+               struct g72x_state *state_ptr);
+extern int g723_40_decoder(
+               int code,
+               int out_coding,
+               struct g72x_state *state_ptr);
+
+
+extern int
+quantize(
+        int            d,      
+        int            y,      
+       short           *table, 
+       int             size);
+extern int reconstruct(int,int,int);void
+
+extern update(
+       int             code_size,      
+       int             y,              
+       int             wi,             
+       int             fi,             
+       int             dq,             
+       int             sr,             
+       int             dqsez,          
+       struct g72x_state *state_ptr);
+extern int
+tandem_adjust_alaw(
+       int             sr,     
+       int             se,     
+       int             y,      
+       int             i,      
+       int             sign,
+       short           *qtab);
+
+extern int
+tandem_adjust_ulaw(
+       int             sr,     
+       int             se,     
+       int             y,      
+       int             i,      
+       int             sign,
+       short           *qtab);
+
+extern unsigned char
+linear2alaw(
+       int             pcm_val);
+
+extern int
+alaw2linear(
+       unsigned char   a_val);
+
+extern unsigned char
+linear2ulaw(int                pcm_val);
+
+extern int ulaw2linear(        unsigned char   u_val);
+
+extern int predictor_zero(struct g72x_state *state_ptr);
+
+extern int predictor_pole(     struct g72x_state *state_ptr);
+extern int step_size(  struct g72x_state *state_ptr);
+#endif /* !_G72X_H */
diff --git a/gnuradio-core/src/lib/general/Makefile.am b/gnuradio-core/src/lib/general/Makefile.am
new file mode 100644 (file)
index 0000000..a240cc9
--- /dev/null
@@ -0,0 +1,440 @@
+#
+# Copyright 2001,2002,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 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.
+# 
+
+include $(top_srcdir)/Makefile.common
+
+INCLUDES = $(STD_DEFINES_AND_INCLUDES) $(CPPUNIT_INCLUDES)
+
+noinst_LTLIBRARIES = libgeneral.la libgeneral-qa.la
+
+# ----------------------------------------------------------------
+# these scripts generate code
+
+CODE_GENERATOR =                       \
+       generate_all.py                 \
+       generate_common.py              \
+       gr_add_XX.cc.t                  \
+       gr_add_XX.h.t                   \
+       gr_add_XX.i.t                   \
+       gr_add_const_XX.cc.t            \
+       gr_add_const_XX.h.t             \
+       gr_add_const_XX.i.t             \
+        gr_chunks_to_symbols_XX.cc.t   \
+        gr_chunks_to_symbols_XX.h.t    \
+        gr_chunks_to_symbols_XX.i.t    \
+       gr_divide_XX.cc.t               \
+       gr_divide_XX.h.t                \
+       gr_divide_XX.i.t                \
+       gr_multiply_XX.cc.t             \
+       gr_multiply_XX.h.t              \
+       gr_multiply_XX.i.t              \
+       gr_multiply_const_XX.cc.t       \
+       gr_multiply_const_XX.h.t        \
+       gr_multiply_const_XX.i.t        \
+       gr_mute_XX.cc.t                 \
+       gr_mute_XX.h.t                  \
+       gr_mute_XX.i.t                  \
+       gr_noise_source_X.cc.t          \
+       gr_noise_source_X.h.t           \
+       gr_noise_source_X.i.t           \
+       gr_packed_to_unpacked_XX.cc.t   \
+       gr_packed_to_unpacked_XX.h.t    \
+       gr_packed_to_unpacked_XX.i.t    \
+       gr_sig_source_X.cc.t            \
+       gr_sig_source_X.h.t             \
+       gr_sig_source_X.i.t             \
+       gr_sub_XX.cc.t                  \
+       gr_sub_XX.h.t                   \
+       gr_sub_XX.i.t                   \
+       gr_unpacked_to_packed_XX.cc.t   \
+       gr_unpacked_to_packed_XX.h.t    \
+       gr_unpacked_to_packed_XX.i.t    \
+       gr_vector_source_X.cc.t         \
+       gr_vector_source_X.h.t          \
+       gr_vector_source_X.i.t          \
+       gr_vector_sink_X.cc.t           \
+       gr_vector_sink_X.h.t            \
+       gr_vector_sink_X.i.t            
+
+# include $(srcdir)/Makefile.gen
+include Makefile.gen
+
+
+$(GENERATED_H) $(GENERATED_I) $(GENERATED_CC): $(CODE_GENERATOR)
+       PYTHONPATH=$(top_srcdir)/gnuradio-core/src/python srcdir=$(srcdir) $(srcdir)/generate_all.py
+
+
+BUILT_SOURCES = $(GENERATED_H) $(GENERATED_I) $(GENERATED_CC)
+
+# ----------------------------------------------------------------
+
+EXTRA_DIST =                           \
+       $(CODE_GENERATOR)               \
+       gen_sine_table.py               \
+       gr_prefix.cc.in                 
+
+libgeneral_la_SOURCES =                \
+       $(GENERATED_CC)                 \
+       gr_agc_cc.cc                    \
+       gr_agc_ff.cc                    \
+       gr_align_on_samplenumbers_ss.cc \
+       gr_binary_slicer_fb.cc          \
+       gr_bytes_to_syms.cc             \
+       gr_char_to_float.cc             \
+       gr_check_counting_s.cc          \
+       gr_check_lfsr_32k_s.cc          \
+       gr_circular_file.cc             \
+       gr_clock_recovery_mm_cc.cc      \
+       gr_clock_recovery_mm_ff.cc      \
+       gr_complex_to_interleaved_short.cc \
+       gr_complex_to_xxx.cc            \
+       gr_conjugate_cc.cc              \
+       gr_constellation_decoder_cb.cc  \
+       gr_correlate_access_code_bb.cc  \
+       gr_costas_loop_cc.cc            \
+       gr_count_bits.cc                \
+       gr_crc32.cc                     \
+       gr_ctcss_squelch_ff.cc          \
+       gr_dd_mpsk_sync_cc.cc           \
+       gr_deinterleave.cc              \
+       gr_diff_decoder_bb.cc           \
+       gr_diff_encoder_bb.cc           \
+       gr_diff_phasor_cc.cc            \
+       gr_fake_channel_coder_pp.cc     \
+       gr_fast_atan2f.cc               \
+       gr_feval.cc                     \
+       gr_fft_vcc.cc                   \
+       gr_fft_vfc.cc                   \
+       gr_firdes.cc                    \
+       gr_float_to_char.cc             \
+       gr_float_to_complex.cc          \
+       gr_float_to_short.cc            \
+       gr_float_to_uchar.cc            \
+       gr_frequency_modulator_fc.cc    \
+       gr_fxpt.cc                      \
+       gr_framer_sink_1.cc             \
+       gr_head.cc                      \
+       gr_interleave.cc                \
+       gr_interleaved_short_to_complex.cc \
+       gr_keep_one_in_n.cc             \
+       gr_kludge_copy.cc               \
+       gr_lfsr_32k_source_s.cc         \
+       gr_lms_dfe_cc.cc                \
+       gr_lms_dfe_ff.cc                \
+       gr_map_bb.cc                    \
+       gr_math.cc                      \
+       gr_misc.cc                      \
+       gr_nlog10_ff.cc                 \
+       gr_nop.cc                       \
+       gr_null_sink.cc                 \
+       gr_null_source.cc               \
+       gr_pa_2x2_phase_combiner.cc     \
+       gr_packet_sink.cc               \
+       gr_phase_modulator_fc.cc        \
+       gr_pll_carriertracking_cc.cc    \
+       gr_pll_freqdet_cf.cc            \
+       gr_pll_refout_cc.cc             \
+       gr_prefix.cc                    \
+       gr_prefs.cc                     \
+       gr_probe_avg_mag_sqrd_c.cc      \
+       gr_probe_avg_mag_sqrd_f.cc      \
+       gr_probe_signal_f.cc            \
+       gr_pwr_squelch_cc.cc            \
+       gr_pwr_squelch_ff.cc            \
+       gr_quadrature_demod_cf.cc       \
+       gr_random.cc                    \
+       gr_remez.cc                     \
+       gr_reverse.cc                   \
+       gr_rms_cf.cc                    \
+       gr_rms_ff.cc                    \
+       gr_short_to_float.cc            \
+       gr_simple_correlator.cc         \
+       gr_simple_framer.cc             \
+       gr_simple_squelch_cc.cc         \
+       gr_skiphead.cc                  \
+       gr_squelch_base_cc.cc           \
+       gr_squelch_base_ff.cc           \
+       gr_stream_to_streams.cc         \
+       gr_stream_to_vector.cc          \
+       gr_streams_to_stream.cc         \
+       gr_streams_to_vector.cc         \
+       gr_sync_block.cc                \
+       gr_sync_decimator.cc            \
+       gr_sync_interpolator.cc         \
+        gr_test.cc                      \
+       gr_threshold_ff.cc              \
+       gr_throttle.cc                  \
+       gr_uchar_to_float.cc            \
+       gr_vco_f.cc                     \
+       gr_vector_to_stream.cc          \
+       gr_vector_to_streams.cc         \
+       gri_add_const_ss_generic.cc     \
+       gri_char_to_float.cc            \
+       gri_debugger_hook.cc            \
+       gri_fft.cc                      \
+       gri_float_to_char.cc            \
+       gri_float_to_short.cc           \
+       gri_float_to_uchar.cc           \
+       gri_interleaved_short_to_complex.cc \
+       gri_short_to_float.cc           \
+       gri_uchar_to_float.cc           \
+       malloc16.c                      \
+       gr_unpack_k_bits_bb.cc
+
+libgeneral_qa_la_SOURCES =             \
+       qa_general.cc                   \
+       qa_gr_circular_file.cc          \
+       qa_gr_firdes.cc                 \
+       qa_gr_fxpt.cc                   \
+       qa_gr_fxpt_nco.cc               \
+       qa_gr_fxpt_vco.cc               
+
+
+
+grinclude_HEADERS =                    \
+       $(GENERATED_H)                  \
+       gr_agc_cc.h                     \
+       gr_agc_ff.h                     \
+       gr_align_on_samplenumbers_ss.h  \
+       gr_binary_slicer_fb.h           \
+       gr_bytes_to_syms.h              \
+       gr_char_to_float.h              \
+       gr_check_counting_s.h           \
+       gr_check_lfsr_32k_s.h           \
+       gr_circular_file.h              \
+       gr_clock_recovery_mm_cc.h       \
+       gr_clock_recovery_mm_ff.h       \
+       gr_complex_to_interleaved_short.h \
+       gr_complex_to_xxx.h             \
+       gr_conjugate_cc.h               \
+       gr_constellation_decoder_cb.h   \
+       gr_correlate_access_code_bb.h   \
+       gr_costas_loop_cc.h             \
+       gr_count_bits.h                 \
+       gr_crc32.h                      \
+       gr_ctcss_squelch_ff.h           \
+       gr_dd_mpsk_sync_cc.h            \
+       gr_diff_decoder_bb.h            \
+       gr_diff_encoder_bb.h            \
+       gr_deinterleave.h               \
+       gr_diff_phasor_cc.h             \
+       gr_endianness.h                 \
+       gr_expj.h                       \
+       gr_fake_channel_coder_pp.h      \
+       gr_feval.h                      \
+       gr_fft_vcc.h                    \
+       gr_fft_vfc.h                    \
+       gr_firdes.h                     \
+       gr_float_to_char.h              \
+       gr_float_to_complex.h           \
+       gr_float_to_short.h             \
+       gr_float_to_uchar.h             \
+       gr_framer_sink_1.h              \
+       gr_frequency_modulator_fc.h     \
+       gr_fxpt.h                       \
+       gr_fxpt_nco.h                   \
+       gr_fxpt_vco.h                   \
+       gr_head.h                       \
+       gr_interleave.h                 \
+       gr_interleaved_short_to_complex.h \
+       gr_keep_one_in_n.h              \
+       gr_kludge_copy.h                \
+       gr_lfsr_32k_source_s.h          \
+       gr_lms_dfe_cc.h                 \
+       gr_lms_dfe_ff.h                 \
+       gr_log2_const.h                 \
+       gr_map_bb.h                     \
+       gr_math.h                       \
+       gr_misc.h                       \
+       gr_nco.h                        \
+       gr_nlog10_ff.h                  \
+       gr_noise_type.h                 \
+       gr_nop.h                        \
+       gr_null_sink.h                  \
+       gr_null_source.h                \
+       gr_pa_2x2_phase_combiner.h      \
+       gr_packet_sink.h                \
+       gr_phase_modulator_fc.h         \
+       gr_pll_carriertracking_cc.h     \
+       gr_pll_freqdet_cf.h             \
+       gr_pll_refout_cc.h              \
+       gr_prefix.h                     \
+       gr_prefs.h                      \
+       gr_probe_avg_mag_sqrd_c.h       \
+       gr_probe_avg_mag_sqrd_f.h       \
+       gr_probe_signal_f.h             \
+       gr_pwr_squelch_cc.h             \
+       gr_pwr_squelch_ff.h             \
+       gr_quadrature_demod_cf.h        \
+       gr_random.h                     \
+       gr_remez.h                      \
+       gr_reverse.h                    \
+       gr_rms_cf.h                     \
+       gr_rms_ff.h                     \
+       gr_short_to_float.h             \
+       gr_sig_source_waveform.h        \
+       gr_simple_correlator.h          \
+       gr_simple_framer.h              \
+       gr_simple_framer_sync.h         \
+       gr_simple_squelch_cc.h          \
+       gr_skiphead.h                   \
+       gr_squelch_base_cc.h            \
+       gr_squelch_base_ff.h            \
+       gr_stream_to_streams.h          \
+       gr_stream_to_vector.h           \
+       gr_streams_to_stream.h          \
+       gr_streams_to_vector.h          \
+       gr_sync_block.h                 \
+       gr_sync_decimator.h             \
+       gr_sync_interpolator.h          \
+        gr_test_types.h                        \
+        gr_test.h                      \
+       gr_threshold_ff.h               \
+       gr_throttle.h                   \
+       gr_uchar_to_float.h             \
+       gr_vco.h                        \
+       gr_vco_f.h                      \
+       gr_vector_to_stream.h           \
+       gr_vector_to_streams.h          \
+       gri_add_const_ss.h              \
+       gri_agc.h                       \
+       gri_agc_cc.h                    \
+       gri_char_to_float.h             \
+       gri_debugger_hook.h             \
+       gri_fft.h                       \
+       gri_float_to_char.h             \
+       gri_float_to_short.h            \
+       gri_float_to_uchar.h            \
+       gri_interleaved_short_to_complex.h \
+       gri_lfsr_15_1_0.h               \
+       gri_lfsr_32k.h                  \
+       gri_short_to_float.h            \
+       gri_uchar_to_float.h            \
+       malloc16.h                      \
+       random.h                        \
+       gr_unpack_k_bits_bb.h
+
+
+noinst_HEADERS =                       \
+       qa_general.h                    \
+       qa_gr_circular_file.h           \
+       qa_gr_firdes.h                  \
+       qa_gr_fxpt.h                    \
+       qa_gr_fxpt_nco.h                \
+       qa_gr_fxpt_vco.h                \
+       sine_table.h                    
+
+swiginclude_HEADERS =                  \
+       $(GENERATED_I)                  \
+       general.i                       \
+       general_generated.i             \
+       gr_agc_cc.i                     \
+       gr_agc_ff.i                     \
+       gr_align_on_samplenumbers_ss.i  \
+       gr_binary_slicer_fb.i           \
+       gr_bytes_to_syms.i              \
+       gr_char_to_float.i              \
+       gr_check_counting_s.i           \
+       gr_check_lfsr_32k_s.i           \
+       gr_clock_recovery_mm_cc.i       \
+       gr_clock_recovery_mm_ff.i       \
+       gr_complex_to_interleaved_short.i \
+       gr_complex_to_xxx.i             \
+       gr_conjugate_cc.i               \
+       gr_constellation_decoder_cb.i   \
+       gr_correlate_access_code_bb.i   \
+       gr_costas_loop_cc.i             \
+       gr_crc32.i                      \
+       gr_ctcss_squelch_ff.i           \
+       gr_dd_mpsk_sync_cc.i            \
+       gr_diff_decoder_bb.i            \
+       gr_diff_encoder_bb.i            \
+       gr_diff_phasor_cc.i             \
+       gr_deinterleave.i               \
+       gr_endianness.i                 \
+       gr_fake_channel_coder_pp.i      \
+       gr_feval.i                      \
+       gr_fft_vcc.i                    \
+       gr_fft_vfc.i                    \
+       gr_firdes.i                     \
+       gr_float_to_char.i              \
+       gr_float_to_complex.i           \
+       gr_float_to_short.i             \
+       gr_float_to_uchar.i             \
+       gr_frequency_modulator_fc.i     \
+       gr_framer_sink_1.i              \
+       gr_head.i                       \
+       gr_interleave.i                 \
+       gr_interleaved_short_to_complex.i \
+       gr_keep_one_in_n.i              \
+       gr_kludge_copy.i                \
+       gr_lfsr_32k_source_s.i          \
+       gr_lms_dfe_cc.i                 \
+       gr_lms_dfe_ff.i                 \
+       gr_map_bb.i                     \
+       gr_nlog10_ff.i                  \
+       gr_nop.i                        \
+       gr_null_sink.i                  \
+       gr_null_source.i                \
+       gr_pa_2x2_phase_combiner.i      \
+       gr_packet_sink.i                \
+       gr_phase_modulator_fc.i         \
+       gr_pll_carriertracking_cc.i     \
+       gr_pll_freqdet_cf.i             \
+       gr_pll_refout_cc.i              \
+       gr_prefix.i                     \
+       gr_prefs.i                      \
+       gr_probe_avg_mag_sqrd_c.i       \
+       gr_probe_avg_mag_sqrd_f.i       \
+       gr_probe_signal_f.i             \
+       gr_pwr_squelch_cc.i             \
+       gr_pwr_squelch_ff.i             \
+       gr_quadrature_demod_cf.i        \
+       gr_remez.i                      \
+       gr_rms_cf.i                     \
+       gr_rms_ff.i                     \
+       gr_short_to_float.i             \
+       gr_simple_correlator.i          \
+       gr_simple_framer.i              \
+       gr_simple_squelch_cc.i          \
+       gr_skiphead.i                   \
+       gr_squelch_base_cc.i            \
+       gr_squelch_base_ff.i            \
+       gr_stream_to_streams.i          \
+       gr_stream_to_vector.i           \
+       gr_streams_to_stream.i          \
+       gr_streams_to_vector.i          \
+       gr_sync_block.i                 \
+       gr_sync_decimator.i             \
+       gr_sync_interpolator.i          \
+        gr_test.i                      \
+       gr_threshold_ff.i               \
+       gr_throttle.i                   \
+       gr_uchar_to_float.i             \
+       gr_vco_f.i                      \
+       gr_vector_to_stream.i           \
+       gr_vector_to_streams.i          \
+       gri_agc.i                       \
+       gri_agc_cc.i                    \
+       gr_unpack_k_bits_bb.i
+
+
+CLEANFILES = $(BUILT_SOURCES) *.pyc
diff --git a/gnuradio-core/src/lib/general/Makefile.gen b/gnuradio-core/src/lib/general/Makefile.gen
new file mode 100644 (file)
index 0000000..f0c477e
--- /dev/null
@@ -0,0 +1,234 @@
+#
+# This file is machine generated.  All edits will be overwritten
+#
+GENERATED_H = \
+       gr_add_cc.h \
+       gr_add_const_cc.h \
+       gr_add_const_ff.h \
+       gr_add_const_ii.h \
+       gr_add_const_sf.h \
+       gr_add_const_ss.h \
+       gr_add_const_vcc.h \
+       gr_add_const_vff.h \
+       gr_add_const_vii.h \
+       gr_add_const_vss.h \
+       gr_add_ff.h \
+       gr_add_ii.h \
+       gr_add_ss.h \
+       gr_add_vcc.h \
+       gr_add_vff.h \
+       gr_add_vii.h \
+       gr_add_vss.h \
+       gr_chunks_to_symbols_bc.h \
+       gr_chunks_to_symbols_bf.h \
+       gr_chunks_to_symbols_ic.h \
+       gr_chunks_to_symbols_if.h \
+       gr_chunks_to_symbols_sc.h \
+       gr_chunks_to_symbols_sf.h \
+       gr_divide_cc.h \
+       gr_divide_ff.h \
+       gr_divide_ii.h \
+       gr_divide_ss.h \
+       gr_multiply_cc.h \
+       gr_multiply_const_cc.h \
+       gr_multiply_const_ff.h \
+       gr_multiply_const_ii.h \
+       gr_multiply_const_ss.h \
+       gr_multiply_const_vcc.h \
+       gr_multiply_const_vff.h \
+       gr_multiply_const_vii.h \
+       gr_multiply_const_vss.h \
+       gr_multiply_ff.h \
+       gr_multiply_ii.h \
+       gr_multiply_ss.h \
+       gr_multiply_vcc.h \
+       gr_multiply_vff.h \
+       gr_multiply_vii.h \
+       gr_multiply_vss.h \
+       gr_mute_cc.h \
+       gr_mute_ff.h \
+       gr_mute_ii.h \
+       gr_mute_ss.h \
+       gr_noise_source_c.h \
+       gr_noise_source_f.h \
+       gr_noise_source_i.h \
+       gr_noise_source_s.h \
+       gr_packed_to_unpacked_bb.h \
+       gr_packed_to_unpacked_ii.h \
+       gr_packed_to_unpacked_ss.h \
+       gr_sig_source_c.h \
+       gr_sig_source_f.h \
+       gr_sig_source_i.h \
+       gr_sig_source_s.h \
+       gr_sub_cc.h \
+       gr_sub_ff.h \
+       gr_sub_ii.h \
+       gr_sub_ss.h \
+       gr_unpacked_to_packed_bb.h \
+       gr_unpacked_to_packed_ii.h \
+       gr_unpacked_to_packed_ss.h \
+       gr_vector_sink_b.h \
+       gr_vector_sink_c.h \
+       gr_vector_sink_f.h \
+       gr_vector_sink_i.h \
+       gr_vector_sink_s.h \
+       gr_vector_source_b.h \
+       gr_vector_source_c.h \
+       gr_vector_source_f.h \
+       gr_vector_source_i.h \
+       gr_vector_source_s.h
+
+GENERATED_I = \
+       gr_add_cc.i \
+       gr_add_const_cc.i \
+       gr_add_const_ff.i \
+       gr_add_const_ii.i \
+       gr_add_const_sf.i \
+       gr_add_const_ss.i \
+       gr_add_const_vcc.i \
+       gr_add_const_vff.i \
+       gr_add_const_vii.i \
+       gr_add_const_vss.i \
+       gr_add_ff.i \
+       gr_add_ii.i \
+       gr_add_ss.i \
+       gr_add_vcc.i \
+       gr_add_vff.i \
+       gr_add_vii.i \
+       gr_add_vss.i \
+       gr_chunks_to_symbols_bc.i \
+       gr_chunks_to_symbols_bf.i \
+       gr_chunks_to_symbols_ic.i \
+       gr_chunks_to_symbols_if.i \
+       gr_chunks_to_symbols_sc.i \
+       gr_chunks_to_symbols_sf.i \
+       gr_divide_cc.i \
+       gr_divide_ff.i \
+       gr_divide_ii.i \
+       gr_divide_ss.i \
+       gr_multiply_cc.i \
+       gr_multiply_const_cc.i \
+       gr_multiply_const_ff.i \
+       gr_multiply_const_ii.i \
+       gr_multiply_const_ss.i \
+       gr_multiply_const_vcc.i \
+       gr_multiply_const_vff.i \
+       gr_multiply_const_vii.i \
+       gr_multiply_const_vss.i \
+       gr_multiply_ff.i \
+       gr_multiply_ii.i \
+       gr_multiply_ss.i \
+       gr_multiply_vcc.i \
+       gr_multiply_vff.i \
+       gr_multiply_vii.i \
+       gr_multiply_vss.i \
+       gr_mute_cc.i \
+       gr_mute_ff.i \
+       gr_mute_ii.i \
+       gr_mute_ss.i \
+       gr_noise_source_c.i \
+       gr_noise_source_f.i \
+       gr_noise_source_i.i \
+       gr_noise_source_s.i \
+       gr_packed_to_unpacked_bb.i \
+       gr_packed_to_unpacked_ii.i \
+       gr_packed_to_unpacked_ss.i \
+       gr_sig_source_c.i \
+       gr_sig_source_f.i \
+       gr_sig_source_i.i \
+       gr_sig_source_s.i \
+       gr_sub_cc.i \
+       gr_sub_ff.i \
+       gr_sub_ii.i \
+       gr_sub_ss.i \
+       gr_unpacked_to_packed_bb.i \
+       gr_unpacked_to_packed_ii.i \
+       gr_unpacked_to_packed_ss.i \
+       gr_vector_sink_b.i \
+       gr_vector_sink_c.i \
+       gr_vector_sink_f.i \
+       gr_vector_sink_i.i \
+       gr_vector_sink_s.i \
+       gr_vector_source_b.i \
+       gr_vector_source_c.i \
+       gr_vector_source_f.i \
+       gr_vector_source_i.i \
+       gr_vector_source_s.i
+
+GENERATED_CC = \
+       gr_add_cc.cc \
+       gr_add_const_cc.cc \
+       gr_add_const_ff.cc \
+       gr_add_const_ii.cc \
+       gr_add_const_sf.cc \
+       gr_add_const_ss.cc \
+       gr_add_const_vcc.cc \
+       gr_add_const_vff.cc \
+       gr_add_const_vii.cc \
+       gr_add_const_vss.cc \
+       gr_add_ff.cc \
+       gr_add_ii.cc \
+       gr_add_ss.cc \
+       gr_add_vcc.cc \
+       gr_add_vff.cc \
+       gr_add_vii.cc \
+       gr_add_vss.cc \
+       gr_chunks_to_symbols_bc.cc \
+       gr_chunks_to_symbols_bf.cc \
+       gr_chunks_to_symbols_ic.cc \
+       gr_chunks_to_symbols_if.cc \
+       gr_chunks_to_symbols_sc.cc \
+       gr_chunks_to_symbols_sf.cc \
+       gr_divide_cc.cc \
+       gr_divide_ff.cc \
+       gr_divide_ii.cc \
+       gr_divide_ss.cc \
+       gr_multiply_cc.cc \
+       gr_multiply_const_cc.cc \
+       gr_multiply_const_ff.cc \
+       gr_multiply_const_ii.cc \
+       gr_multiply_const_ss.cc \
+       gr_multiply_const_vcc.cc \
+       gr_multiply_const_vff.cc \
+       gr_multiply_const_vii.cc \
+       gr_multiply_const_vss.cc \
+       gr_multiply_ff.cc \
+       gr_multiply_ii.cc \
+       gr_multiply_ss.cc \
+       gr_multiply_vcc.cc \
+       gr_multiply_vff.cc \
+       gr_multiply_vii.cc \
+       gr_multiply_vss.cc \
+       gr_mute_cc.cc \
+       gr_mute_ff.cc \
+       gr_mute_ii.cc \
+       gr_mute_ss.cc \
+       gr_noise_source_c.cc \
+       gr_noise_source_f.cc \
+       gr_noise_source_i.cc \
+       gr_noise_source_s.cc \
+       gr_packed_to_unpacked_bb.cc \
+       gr_packed_to_unpacked_ii.cc \
+       gr_packed_to_unpacked_ss.cc \
+       gr_sig_source_c.cc \
+       gr_sig_source_f.cc \
+       gr_sig_source_i.cc \
+       gr_sig_source_s.cc \
+       gr_sub_cc.cc \
+       gr_sub_ff.cc \
+       gr_sub_ii.cc \
+       gr_sub_ss.cc \
+       gr_unpacked_to_packed_bb.cc \
+       gr_unpacked_to_packed_ii.cc \
+       gr_unpacked_to_packed_ss.cc \
+       gr_vector_sink_b.cc \
+       gr_vector_sink_c.cc \
+       gr_vector_sink_f.cc \
+       gr_vector_sink_i.cc \
+       gr_vector_sink_s.cc \
+       gr_vector_source_b.cc \
+       gr_vector_source_c.cc \
+       gr_vector_source_f.cc \
+       gr_vector_source_i.cc \
+       gr_vector_source_s.cc
+
diff --git a/gnuradio-core/src/lib/general/README b/gnuradio-core/src/lib/general/README
new file mode 100644 (file)
index 0000000..26d829f
--- /dev/null
@@ -0,0 +1,98 @@
+Files beginning with Gr* define classes that inherit from VrSigProc.
+These are high level signal processing modules that can be glued
+together in your signal processing chain.
+
+All the others are either lower level routines which implement the
+functionality of the Gr* modules, but are easier to test (fewer
+dependencies), or they are general purpose.
+
+gr_fir_???.{h,cc}, where ??? are in F, S or C are low level Finite
+Impulse Response Filters.  These turn out to be where the bulk of the
+cycles are burned in many applications.  The ??? suffix  specifies the
+input type, output type and tap type of the arguments.  We've
+implemented the most frequently used ones.
+
+[Once upon a time this stuff was done with templates
+(gr_fir<iType,oType,tapType>), but this turned out to be a headache.
+The code appeared to trigger a bug in GCC where we were getting
+multiple definitions of unrelated stuff when we started subclassing
+partially specialized templates.  It was also not obvious as to to
+what combinations of iType, oType and tapType actually worked.  We're
+now explicit, and the world is a safer place to live...]
+
+The top level routines for FIR filtering are:
+
+    GrFIRfilterFFF : Float input, Float output, Float taps
+       -- general purpose
+
+    GrFIRfilterCCF : Complex input, Complex output, Float taps
+       -- applying real filter to a complex signal
+
+    GrFIRfilterFCC : Float input, Complex output, Complex taps
+       -- applying complex filter to float input
+
+    GrFIRfilterSCC : Short input, Complex output, Complex taps
+       -- applying complex filter to short input.  Quantizes complex
+           coefficients to 16 bits and uses MMX or SSE2 as appropriate
+
+
+The combination of down conversion (frequency translation) and channel
+selection (filtering) is performed with:
+
+    GrFreqXlatingFIRfilterSFC : Short input, Float taps, Complex baseband output
+        -- quantizes complex coefficents to 16 bits and uses MMX or
+          SSE2 (128-bit MMX) as appropriate [optimization to be done].
+
+    GrFreqXlatingFIRfilterFFC : Float input, Float taps, Complex baseband output
+       -- 3dnow or SSE as appropriate.
+
+
+[ The stuff described from here down is used to implement the routines
+  above.  This info is only relevant to those who are hacking the internals ]
+
+
+A bit of indirection is involved in selecting the fastest
+implementation for any given platform.  The lower level classes
+gr_fir_FFF.h, gr_fir_CCF, gr_fir_FCC and gr_fir_SCC have i/o
+signatures similar to the high level clases above.   These
+should be considered the abstract base classes that you
+work with.  Note that they are not actually abstract (they've got a
+default implementation; this might be considered a bug), but they
+should not be directly instantiated by user code.
+
+Instead of directly instantiating a gr_fir_FFF, for example, your code
+should actually:
+
+       #include <gr_fir_util.h>
+
+       // let the system pick the best implementation for you
+       gr_fir_FFF *filter = gr_fir_util::create_gr_fir_FFF (my_taps);
+
+Clear?  The same for all the other gr_fir_XXX's.
+
+
+
+Performance hacking can be done by subclassing the appropriate
+base class.  For example, on the x86 platform, there are two
+additional classes derived from gr_fir_FFF, gr_fir_FFF_sse and
+gr_fir_FFF_3dnow.  These classes are then made available to the rest
+of the system by virtue of being added to gr_fir_sysconfig_x86.cc,
+along with any guards (CPUID checks) needed to ensure that only
+compatible code is executed on the current hardware.
+
+
+TO DO
+------
+
+* Move all the machine specific code to a subdirectory, then have
+configure symlink to the right directory.  This will allow us to build on
+any platform without choking.  There is generic code for all routines,
+only the machine dependent speedup will be lacking. 
+
+* Add an interface to gr_fir_util that will return a vector of all
+valid constructors with descriptive names for each i/o signature.
+This will allow the test code and benchmarking code to be blissfully
+ignorant of what platform they're running on.  The actual building of
+the vectors should be done bottom up through the gr_fir_sysconfig
+hierarchy. 
+
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
diff --git a/gnuradio-core/src/lib/general/gen_sine_table.py b/gnuradio-core/src/lib/general/gen_sine_table.py
new file mode 100755 (executable)
index 0000000..06a5e7c
--- /dev/null
@@ -0,0 +1,77 @@
+#!/usr/bin/env 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.
+# 
+
+import math
+import sys
+
+def wrap (x):
+    if x >= 2**31:
+        return x - 2**32
+    return x
+
+def gen_approx_table (f, nentries, min_x, max_x):
+    """return a list of nentries containing tuples of the form:
+    (m, c, abs_error).  min_x and max_x specify the domain
+    of the table.
+    """
+    r = []
+    incx = float (max_x - min_x) / nentries
+    for i in range (nentries):
+        a = (i * incx) + min_x
+        b = ((i + 1) * incx) + min_x
+        m = (f(b)-f(a))/(b-a)
+        c = (3*a+b)*(f(a)-f(b))/(4*(b-a)) + (f((a+b)/2) + f(a))/2
+        abs_error = c+m*a-f(a)
+        r.append ((m, c, abs_error))
+    return r
+
+def scaled_sine (x):
+    return math.sin (x * math.pi / 2**31)
+
+def gen_sine_table ():
+    nbits = 10
+    nentries = 2**nbits
+
+    # min_x = -2**31
+    # max_x =  2**31-1
+    min_x = 0
+    max_x = 2**32-1
+    t = gen_approx_table (scaled_sine, nentries, min_x, max_x)
+
+    max_error = 0
+    for e in t:
+        max_error = max (max_error, abs (e[2]))
+
+    # sys.stdout.write ('static const int WORDBITS = 32;\n')
+    # sys.stdout.write ('static const int NBITS = %d;\n' % (nbits,))
+
+    sys.stdout.write ('  // max_error = %22.15e\n' % (max_error,))
+
+    # sys.stdout.write ('static const double sine_table[%d][2] = {\n'% (nentries,))
+
+    for e in t:
+        sys.stdout.write ('  { %22.15e, %22.15e },\n' % (2 * e[0], e[1]))
+
+    # sys.stdout.write ('};\n')
+                    
+if __name__ == '__main__':
+    gen_sine_table ()
diff --git a/gnuradio-core/src/lib/general/general.i b/gnuradio-core/src/lib/general/general.i
new file mode 100644 (file)
index 0000000..3f410a9
--- /dev/null
@@ -0,0 +1,203 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2005,2006 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 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.
+ */
+
+%{
+
+#include <gr_sync_block.h>
+#include <gr_sync_decimator.h>
+#include <gr_sync_interpolator.h>
+#include <gr_nop.h>
+#include <gr_null_sink.h>
+#include <gr_null_source.h>
+#include <gr_head.h>
+#include <gr_skiphead.h>
+#include <gr_sig_source_waveform.h>
+#include <gr_quadrature_demod_cf.h>
+#include <gr_remez.h>
+#include <gr_float_to_complex.h>
+#include <gr_check_counting_s.h>
+#include <gr_lfsr_32k_source_s.h>
+#include <gr_check_lfsr_32k_s.h>
+#include <gr_stream_to_vector.h>
+#include <gr_vector_to_stream.h>
+#include <gr_keep_one_in_n.h>
+#include <gr_fft_vcc.h>
+#include <gr_fft_vfc.h>
+#include <gr_float_to_short.h>
+#include <gr_float_to_char.h>
+#include <gr_float_to_uchar.h>
+#include <gr_short_to_float.h>
+#include <gr_char_to_float.h>
+#include <gr_uchar_to_float.h>
+#include <gr_frequency_modulator_fc.h>
+#include <gr_phase_modulator_fc.h>
+#include <gr_bytes_to_syms.h>
+#include <gr_simple_correlator.h>
+#include <gr_simple_framer.h>
+#include <gr_align_on_samplenumbers_ss.h>
+#include <gr_complex_to_xxx.h>
+#include <gr_complex_to_interleaved_short.h>
+#include <gr_interleaved_short_to_complex.h>
+#include <gr_endianness.h>
+#include <gr_firdes.h>
+#include <gr_interleave.h>
+#include <gr_deinterleave.h>
+#include <gr_simple_squelch_cc.h>
+#include <gr_agc_ff.h>
+#include <gr_agc_cc.h>
+#include <gr_rms_cf.h>
+#include <gr_rms_ff.h>
+#include <gr_nlog10_ff.h>
+#include <gr_fake_channel_coder_pp.h>
+#include <gr_throttle.h>
+#include <gr_stream_to_streams.h>
+#include <gr_streams_to_stream.h>
+#include <gr_streams_to_vector.h>
+#include <gr_vector_to_streams.h>
+#include <gr_conjugate_cc.h>
+#include <gr_vco_f.h>
+#include <gr_crc32.h>
+#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_pll_freqdet_cf.h>
+#include <gr_pll_refout_cc.h>
+#include <gr_pll_carriertracking_cc.h>
+#include <gr_probe_avg_mag_sqrd_c.h>
+#include <gr_probe_avg_mag_sqrd_f.h>
+#include <gr_probe_signal_f.h>
+#include <gr_costas_loop_cc.h>
+#include <gr_pa_2x2_phase_combiner.h>
+#include <gr_kludge_copy.h>
+#include <gr_prefs.h>
+#include <gr_prefix.h>
+#include <gr_test_types.h>
+#include <gr_test.h>
+#include <gr_unpack_k_bits_bb.h>
+#include <gr_correlate_access_code_bb.h>
+#include <gr_diff_phasor_cc.h>
+#include <gr_constellation_decoder_cb.h>
+#include <gr_binary_slicer_fb.h>
+#include <gr_diff_encoder_bb.h>
+#include <gr_diff_decoder_bb.h>
+#include <gr_framer_sink_1.h>
+#include <gr_map_bb.h>
+#include <gr_feval.h>
+#include <gr_pwr_squelch_cc.h>
+#include <gr_pwr_squelch_ff.h>
+#include <gr_ctcss_squelch_ff.h>
+%}
+
+%include "gr_sync_block.i"
+%include "gr_sync_decimator.i"
+%include "gr_sync_interpolator.i"
+%include "gr_nop.i"
+%include "gr_null_sink.i"
+%include "gr_null_source.i"
+%include "gr_head.i"
+%include "gr_skiphead.i"
+%include "gr_sig_source_waveform.h"
+%include "gr_noise_type.h"
+%include "gr_quadrature_demod_cf.i"
+%include "gr_remez.i"
+%include "gr_float_to_complex.i"
+%include "gr_check_counting_s.i"
+%include "gr_lfsr_32k_source_s.i"
+%include "gr_check_lfsr_32k_s.i"
+%include "gr_stream_to_vector.i"
+%include "gr_vector_to_stream.i"
+%include "gr_keep_one_in_n.i"
+%include "gr_fft_vcc.i"
+%include "gr_fft_vfc.i"
+%include "gr_float_to_short.i"
+%include "gr_float_to_char.i"
+%include "gr_float_to_uchar.i"
+%include "gr_short_to_float.i"
+%include "gr_char_to_float.i"
+%include "gr_uchar_to_float.i"
+%include "gr_frequency_modulator_fc.i"
+%include "gr_phase_modulator_fc.i"
+%include "gr_bytes_to_syms.i"
+%include "gr_simple_correlator.i"
+%include "gr_simple_framer.i"
+%include "gr_align_on_samplenumbers_ss.i"
+%include "gr_complex_to_xxx.i"
+%include "gr_complex_to_interleaved_short.i"
+%include "gr_endianness.i"
+%include "gr_interleaved_short_to_complex.i"
+%include "gr_firdes.i"
+%include "gr_interleave.i"
+%include "gr_deinterleave.i"
+%include "gr_simple_squelch_cc.i"
+%include "gr_agc_ff.i"
+%include "gr_agc_cc.i"
+%include "gr_rms_cf.i"
+%include "gr_rms_ff.i"
+%include "gr_nlog10_ff.i"
+%include "gr_fake_channel_coder_pp.i"
+%include "gr_throttle.i"
+%include "gr_stream_to_streams.i"
+%include "gr_streams_to_stream.i"
+%include "gr_streams_to_vector.i"
+%include "gr_vector_to_streams.i"
+%include "gr_conjugate_cc.i"
+%include "gr_vco_f.i"
+%include "gr_crc32.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_pll_freqdet_cf.i"
+%include "gr_pll_refout_cc.i"
+%include "gr_pll_carriertracking_cc.i"
+%include "gr_probe_avg_mag_sqrd_c.i"
+%include "gr_probe_avg_mag_sqrd_f.i"
+%include "gr_probe_signal_f.i"
+%include "gr_costas_loop_cc.i"
+%include "gr_pa_2x2_phase_combiner.i"
+%include "gr_kludge_copy.i"
+%include "gr_prefs.i"
+%include "gr_prefix.i"
+%include "gr_test_types.h"
+%include "gr_test.i"
+%include "gr_unpack_k_bits_bb.i"
+%include "gr_correlate_access_code_bb.i"
+%include "gr_diff_phasor_cc.i"
+%include "gr_constellation_decoder_cb.i"
+%include "gr_binary_slicer_fb.i"
+%include "gr_diff_encoder_bb.i"
+%include "gr_diff_decoder_bb.i"
+%include "gr_framer_sink_1.i"
+%include "gr_map_bb.i"
+%include "gr_feval.i"
+%include "gr_pwr_squelch_cc.i"
+%include "gr_pwr_squelch_ff.i"
+%include "gr_ctcss_squelch_ff.i"
+
+%include "general_generated.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/generate_all.py b/gnuradio-core/src/lib/general/generate_all.py
new file mode 100755 (executable)
index 0000000..1b33abb
--- /dev/null
@@ -0,0 +1,33 @@
+#!/usr/bin/env 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.
+# 
+
+from build_utils import output_glue
+
+import generate_common
+
+def generate_all ():
+    generate_common.generate ()
+    output_glue ('general')
+
+
+if __name__ == '__main__':
+    generate_all ()
diff --git a/gnuradio-core/src/lib/general/generate_common.py b/gnuradio-core/src/lib/general/generate_common.py
new file mode 100755 (executable)
index 0000000..4616f4a
--- /dev/null
@@ -0,0 +1,93 @@
+#!/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 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.
+# 
+
+from build_utils import expand_template, standard_dict
+from build_utils_codes import *
+
+import re
+
+
+# sources and sinks
+ss_signatures = ['s', 'i', 'f', 'c']
+
+ss_roots = [
+    'gr_vector_source_X',
+    'gr_vector_sink_X',
+    'gr_noise_source_X',
+    'gr_sig_source_X'
+    ]
+
+# regular blocks
+reg_signatures = ['ss', 'ii', 'ff', 'cc']
+
+reg_roots = [
+    'gr_add_const_XX',
+    'gr_multiply_const_XX',
+    'gr_add_XX',
+    'gr_sub_XX',
+    'gr_multiply_XX',
+    'gr_divide_XX',
+    'gr_mute_XX',
+    'gr_add_vXX',
+    'gr_multiply_vXX',
+    'gr_add_const_vXX',
+    'gr_multiply_const_vXX'
+    ]
+
+# other blocks
+others = (
+    ('gr_chunks_to_symbols_XX',     ('bf', 'bc', 'sf', 'sc', 'if', 'ic')),
+    ('gr_unpacked_to_packed_XX',    ('bb','ss','ii')),
+    ('gr_packed_to_unpacked_XX',    ('bb','ss','ii'))
+    )
+
+
+def expand_h_cc_i (root, sig):
+    # root looks like 'gr_vector_sink_X'
+    name = re.sub ('X+', sig, root)
+    d = standard_dict (name, sig)
+    expand_template (d, root + '.h.t')
+    expand_template (d, root + '.cc.t')
+    expand_template (d, root + '.i.t')
+
+
+def generate ():
+    expand_h_cc_i ('gr_add_const_XX', 'sf')     # for MC4020
+    expand_h_cc_i ('gr_vector_sink_X', 'b')
+    expand_h_cc_i ('gr_vector_source_X', 'b')
+    for r in ss_roots:
+        for s in ss_signatures:
+            expand_h_cc_i (r, s)
+    for r in reg_roots :
+        for s in reg_signatures:
+            expand_h_cc_i (r, s)
+            
+    for root, sigs in others:
+        for s in sigs:
+            expand_h_cc_i (root, s)
+
+
+
+if __name__ == '__main__':
+    generate ()
+
+    
diff --git a/gnuradio-core/src/lib/general/gr_add_XX.cc.t b/gnuradio-core/src/lib/general/gr_add_XX.cc.t
new file mode 100644 (file)
index 0000000..f743d87
--- /dev/null
@@ -0,0 +1,62 @@
+/* -*- 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 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.
+ */
+
+// @WARNING@
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <@NAME@.h>
+#include <gr_io_signature.h>
+
+@SPTR_NAME@
+gr_make_@BASE_NAME@ ()
+{
+  return @SPTR_NAME@ (new @NAME@ ());
+}
+
+@NAME@::@NAME@ ()
+  : gr_sync_block ("@BASE_NAME@",
+                  gr_make_io_signature (1, -1, sizeof (@I_TYPE@)),
+                  gr_make_io_signature (1,  1, sizeof (@O_TYPE@)))
+{
+}
+
+int
+@NAME@::work (int noutput_items,
+                  gr_vector_const_void_star &input_items,
+                  gr_vector_void_star &output_items)
+{
+  @O_TYPE@ *optr = (@O_TYPE@ *) output_items[0];
+
+  int ninputs = input_items.size ();
+
+  for (int i = 0; i < noutput_items; i++){
+    @I_TYPE@ acc = ((@I_TYPE@ *) input_items[0])[i];
+    for (int j = 1; j < ninputs; j++)
+      acc += ((@I_TYPE@ *) input_items[j])[i];
+
+    *optr++ = (@O_TYPE@) acc;
+  }
+  return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_add_XX.h.t b/gnuradio-core/src/lib/general/gr_add_XX.h.t
new file mode 100644 (file)
index 0000000..1fa42e3
--- /dev/null
@@ -0,0 +1,54 @@
+/* -*- 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 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.
+ */
+
+// @WARNING@
+
+#ifndef @GUARD_NAME@
+#define @GUARD_NAME@
+
+#include <gr_sync_block.h>
+
+class @NAME@;
+typedef boost::shared_ptr<@NAME@> @SPTR_NAME@;
+
+@SPTR_NAME@ gr_make_@BASE_NAME@ ();
+
+/*!
+ * \brief output = sum (input_0, input_1, ...)
+ * \ingroup block
+ *
+ * Add across all input streams.
+ */
+class @NAME@ : public gr_sync_block
+{
+  friend @SPTR_NAME@ gr_make_@BASE_NAME@ ();
+
+  @NAME@ ();
+
+ public:
+
+  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_add_XX.i.t b/gnuradio-core/src/lib/general/gr_add_XX.i.t
new file mode 100644 (file)
index 0000000..8479aad
--- /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 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.
+ */
+
+// @WARNING@
+
+GR_SWIG_BLOCK_MAGIC(gr,@BASE_NAME@)
+
+@SPTR_NAME@ gr_make_@BASE_NAME@ ();
+
+class @NAME@ : public gr_sync_block
+{
+ private:
+  @NAME@ ();
+};
diff --git a/gnuradio-core/src/lib/general/gr_add_const_XX.cc.t b/gnuradio-core/src/lib/general/gr_add_const_XX.cc.t
new file mode 100644 (file)
index 0000000..1a2cf08
--- /dev/null
@@ -0,0 +1,72 @@
+/* -*- 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 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.
+ */
+
+// @WARNING@
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <@NAME@.h>
+#include <gr_io_signature.h>
+
+@SPTR_NAME@
+gr_make_@BASE_NAME@ (@O_TYPE@ k)
+{
+  return @SPTR_NAME@ (new @NAME@ (k));
+}
+
+@NAME@::@NAME@ (@O_TYPE@ k)
+  : gr_sync_block ("@BASE_NAME@",
+                  gr_make_io_signature (1, 1, sizeof (@I_TYPE@)),
+                  gr_make_io_signature (1, 1, sizeof (@O_TYPE@))),
+    d_k (k)
+{
+}
+
+int
+@NAME@::work (int noutput_items,
+                  gr_vector_const_void_star &input_items,
+                  gr_vector_void_star &output_items)
+{
+  @I_TYPE@ *iptr = (@I_TYPE@ *) input_items[0];
+  @O_TYPE@ *optr = (@O_TYPE@ *) output_items[0];
+
+  int  size = noutput_items;
+
+  while (size >= 8){
+    *optr++ = *iptr++ + d_k;
+    *optr++ = *iptr++ + d_k;
+    *optr++ = *iptr++ + d_k;
+    *optr++ = *iptr++ + d_k;
+    *optr++ = *iptr++ + d_k;
+    *optr++ = *iptr++ + d_k;
+    *optr++ = *iptr++ + d_k;
+    *optr++ = *iptr++ + d_k;
+    size -= 8;
+  }
+
+  while (size-- > 0)
+    *optr++ = *iptr++ + d_k;
+  
+  return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_add_const_XX.h.t b/gnuradio-core/src/lib/general/gr_add_const_XX.h.t
new file mode 100644 (file)
index 0000000..c965df3
--- /dev/null
@@ -0,0 +1,55 @@
+/* -*- 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 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.
+ */
+
+// @WARNING@
+
+#ifndef @GUARD_NAME@
+#define @GUARD_NAME@
+
+#include <gr_sync_block.h>
+
+class @NAME@;
+typedef boost::shared_ptr<@NAME@> @SPTR_NAME@;
+
+@SPTR_NAME@ gr_make_@BASE_NAME@ (@O_TYPE@ k);
+
+/*!
+ * \brief output = input + constant
+ * \ingroup block
+ */
+class @NAME@ : public gr_sync_block
+{
+  friend @SPTR_NAME@ gr_make_@BASE_NAME@ (@O_TYPE@ k);
+
+  @O_TYPE@     d_k;            // the constant
+  @NAME@ (@O_TYPE@ k);
+
+ public:
+  @O_TYPE@ k () const { return d_k; }
+  void set_k (@O_TYPE@ k) { d_k = k; }
+
+  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_add_const_XX.i.t b/gnuradio-core/src/lib/general/gr_add_const_XX.i.t
new file mode 100644 (file)
index 0000000..c2c814b
--- /dev/null
@@ -0,0 +1,37 @@
+/* -*- 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 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.
+ */
+
+// @WARNING@
+
+GR_SWIG_BLOCK_MAGIC(gr,@BASE_NAME@)
+
+@SPTR_NAME@ gr_make_@BASE_NAME@ (@TYPE@ k);
+
+class @NAME@ : public gr_sync_block
+{
+ private:
+  @NAME@ (@TYPE@ k);
+
+ public:
+  @TYPE@ k () const { return d_k; }
+  void set_k (@TYPE@ k) { d_k = k; }
+};
diff --git a/gnuradio-core/src/lib/general/gr_add_const_vXX.cc.t b/gnuradio-core/src/lib/general/gr_add_const_vXX.cc.t
new file mode 100755 (executable)
index 0000000..7966331
--- /dev/null
@@ -0,0 +1,61 @@
+/* -*- 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 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.
+ */
+
+// @WARNING@
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <@NAME@.h>
+#include <gr_io_signature.h>
+
+@SPTR_NAME@
+gr_make_@BASE_NAME@ (const std::vector<@I_TYPE@> k)
+{
+  return @SPTR_NAME@ (new @NAME@ (k));
+}
+
+@NAME@::@NAME@ (const std::vector<@I_TYPE@> k)
+  : gr_sync_block ("@BASE_NAME@",
+                  gr_make_io_signature (1, 1, sizeof(@I_TYPE@)*k.size()),
+                  gr_make_io_signature (1, 1, sizeof(@O_TYPE@)*k.size()))
+{
+  d_k = k;
+}
+
+int
+@NAME@::work (int noutput_items,
+                  gr_vector_const_void_star &input_items,
+                  gr_vector_void_star &output_items)
+{
+  @I_TYPE@ *iptr = (@O_TYPE@ *)input_items[0];
+  @O_TYPE@ *optr = (@O_TYPE@ *)output_items[0];
+  int nitems_per_block = output_signature()->sizeof_stream_item(0)/sizeof(@I_TYPE@);
+
+  for (int i = 0; i < noutput_items; i++)
+    for (int j = 0; j < nitems_per_block; j++)
+      *optr++ = *iptr++ + d_k[j];
+  
+  return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_add_const_vXX.h.t b/gnuradio-core/src/lib/general/gr_add_const_vXX.h.t
new file mode 100755 (executable)
index 0000000..b42bc2d
--- /dev/null
@@ -0,0 +1,55 @@
+/* -*- 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 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.
+ */
+
+// @WARNING@
+
+#ifndef @GUARD_NAME@
+#define @GUARD_NAME@
+
+#include <gr_sync_block.h>
+
+class @NAME@;
+typedef boost::shared_ptr<@NAME@> @SPTR_NAME@;
+
+@SPTR_NAME@ gr_make_@BASE_NAME@ (const std::vector<@I_TYPE@> k);
+
+/*!
+ * \brief output vector = input vector + constant vector
+ * \ingroup block
+ */
+class @NAME@ : public gr_sync_block
+{
+  friend @SPTR_NAME@ gr_make_@BASE_NAME@ (const std::vector<@I_TYPE@> k);
+
+  std::vector<@I_TYPE@> d_k; // the constant
+  @NAME@ (const std::vector<@I_TYPE@> k);
+
+ public:
+  const std::vector<@I_TYPE@> k () const { return d_k; }
+  void set_k (const std::vector<@I_TYPE@> k) { d_k = k; }
+
+  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_add_const_vXX.i.t b/gnuradio-core/src/lib/general/gr_add_const_vXX.i.t
new file mode 100755 (executable)
index 0000000..38c3994
--- /dev/null
@@ -0,0 +1,37 @@
+/* -*- 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 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.
+ */
+
+// @WARNING@
+
+GR_SWIG_BLOCK_MAGIC(gr,@BASE_NAME@)
+
+@SPTR_NAME@ gr_make_@BASE_NAME@ (const std::vector<@I_TYPE@> k);
+
+class @NAME@ : public gr_sync_block
+{
+ private:
+  @NAME@ (const std::vector<@I_TYPE@> k);
+
+ public:
+  std::vector<@I_TYPE@> k () const { return d_k; }
+  void set_k (const std::vector<@I_TYPE@> k) { d_k = k; }
+};
diff --git a/gnuradio-core/src/lib/general/gr_add_vXX.cc.t b/gnuradio-core/src/lib/general/gr_add_vXX.cc.t
new file mode 100755 (executable)
index 0000000..480b4a4
--- /dev/null
@@ -0,0 +1,65 @@
+/* -*- 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 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.
+ */
+
+// @WARNING@
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <@NAME@.h>
+#include <gr_io_signature.h>
+
+@SPTR_NAME@
+gr_make_@BASE_NAME@ (size_t nitems_per_block)
+{
+  return @SPTR_NAME@ (new @NAME@ (nitems_per_block));
+}
+
+@NAME@::@NAME@ (size_t nitems_per_block)
+  : gr_sync_block ("@BASE_NAME@",
+                  gr_make_io_signature (1, -1, sizeof (@I_TYPE@)*nitems_per_block),
+                  gr_make_io_signature (1,  1, sizeof (@O_TYPE@)*nitems_per_block))
+{
+}
+
+int
+@NAME@::work (int noutput_items,
+                  gr_vector_const_void_star &input_items,
+                  gr_vector_void_star &output_items)
+{
+  @O_TYPE@ *optr = (@O_TYPE@ *) output_items[0];
+
+  int ninputs = input_items.size ();
+  int nitems_per_block = output_signature()->sizeof_stream_item(0)/sizeof(@I_TYPE@);
+
+  for (int i = 0; i < noutput_items; i++){
+    for (int j = 0; j < nitems_per_block; j++){
+      @I_TYPE@ acc = ((@I_TYPE@ *) input_items[0])[i*nitems_per_block+j];
+      for (int k = 1; k < ninputs; k++)
+        acc += ((@I_TYPE@ *) input_items[k])[i*nitems_per_block+j];
+
+      *optr++ = (@O_TYPE@) acc;
+    }
+  }
+  return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_add_vXX.h.t b/gnuradio-core/src/lib/general/gr_add_vXX.h.t
new file mode 100755 (executable)
index 0000000..29a0b03
--- /dev/null
@@ -0,0 +1,54 @@
+/* -*- 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 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.
+ */
+
+// @WARNING@
+
+#ifndef @GUARD_NAME@
+#define @GUARD_NAME@
+
+#include <gr_sync_block.h>
+
+class @NAME@;
+typedef boost::shared_ptr<@NAME@> @SPTR_NAME@;
+
+@SPTR_NAME@ gr_make_@BASE_NAME@ (size_t nitems_per_block);
+
+/*!
+ * \brief output = sum (input_0, input_1, ...)
+ * \ingroup block
+ *
+ * Add across all input vectors.
+ */
+class @NAME@ : public gr_sync_block
+{
+  friend @SPTR_NAME@ gr_make_@BASE_NAME@ (size_t nitems_per_block);
+
+  @NAME@ (size_t nitems_per_block);
+
+ public:
+
+  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_add_vXX.i.t b/gnuradio-core/src/lib/general/gr_add_vXX.i.t
new file mode 100755 (executable)
index 0000000..0810961
--- /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 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.
+ */
+
+// @WARNING@
+
+GR_SWIG_BLOCK_MAGIC(gr,@BASE_NAME@)
+
+@SPTR_NAME@ gr_make_@BASE_NAME@ (size_t nitems_per_block);
+
+class @NAME@ : public gr_sync_block
+{
+ private:
+  @NAME@ (size_t nitems_per_block);
+};
diff --git a/gnuradio-core/src/lib/general/gr_agc_cc.cc b/gnuradio-core/src/lib/general/gr_agc_cc.cc
new file mode 100644 (file)
index 0000000..7249ee1
--- /dev/null
@@ -0,0 +1,54 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_agc_cc.h>
+#include <gr_io_signature.h>
+#include <gri_agc_cc.h>
+
+gr_agc_cc_sptr
+gr_make_agc_cc (float rate, float reference, float gain, float max_gain)
+{
+  return gr_agc_cc_sptr (new gr_agc_cc (rate, reference, gain, max_gain));
+}
+
+gr_agc_cc::gr_agc_cc (float rate, float reference, float gain, float max_gain)
+  : gr_sync_block ("gr_agc_cc",
+                  gr_make_io_signature (1, 1, sizeof (gr_complex)),
+                  gr_make_io_signature (1, 1, sizeof (gr_complex)))
+  , gri_agc_cc (rate,  reference, gain, max_gain)
+{
+}
+
+int
+gr_agc_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];
+  scaleN (out, in, noutput_items);
+  return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_agc_cc.h b/gnuradio-core/src/lib/general/gr_agc_cc.h
new file mode 100644 (file)
index 0000000..c7676a5
--- /dev/null
@@ -0,0 +1,50 @@
+/* -*- 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 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.
+ */
+
+#ifndef INCLUDED_GR_AGC_CC_H
+#define INCLUDED_GR_AGC_CC_H
+
+#include <gr_sync_block.h>
+#include <gri_agc_cc.h>
+class gr_agc_cc;
+typedef boost::shared_ptr<gr_agc_cc> gr_agc_cc_sptr;
+
+gr_agc_cc_sptr
+gr_make_agc_cc (float rate = 1e-4, float reference = 1.0, float gain = 1.0, float max_gain = 0.0);
+/*!
+ * \brief high performance Automatic Gain Control class
+ *
+ * For Power the absolute value of the complex number is used.
+ */
+
+class gr_agc_cc : public gr_sync_block, public gri_agc_cc
+{
+  friend gr_agc_cc_sptr gr_make_agc_cc (float rate, float reference, float gain, float max_gain);
+  gr_agc_cc (float rate, float reference, float gain, float max_gain);
+
+ public:
+  virtual int work (int noutput_items,
+                   gr_vector_const_void_star &input_items,
+                   gr_vector_void_star &output_items);
+};
+
+#endif /* INCLUDED_GR_AGC_CC_H */
diff --git a/gnuradio-core/src/lib/general/gr_agc_cc.i b/gnuradio-core/src/lib/general/gr_agc_cc.i
new file mode 100644 (file)
index 0000000..79ebf19
--- /dev/null
@@ -0,0 +1,33 @@
+/* -*- 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 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.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,agc_cc)
+
+%include <gri_agc_cc.i>
+
+gr_agc_cc_sptr
+gr_make_agc_cc (float rate = 1e-4, float reference = 1.0, float gain = 1.0, float max_gain = 0.0);
+
+class gr_agc_cc : public gr_sync_block , public gri_agc_cc
+{
+  gr_agc_cc (float rate, float reference, float gain, float max_gain);
+};
diff --git a/gnuradio-core/src/lib/general/gr_agc_ff.cc b/gnuradio-core/src/lib/general/gr_agc_ff.cc
new file mode 100644 (file)
index 0000000..6b0d01e
--- /dev/null
@@ -0,0 +1,54 @@
+/* -*- c++ -*- */
+/*
+ * 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_agc_ff.h>
+#include <gr_io_signature.h>
+#include <gri_agc.h>
+
+gr_agc_ff_sptr
+gr_make_agc_ff (float rate, float reference, float gain, float max_gain)
+{
+  return gr_agc_ff_sptr (new gr_agc_ff (rate, reference, gain, max_gain));
+}
+
+gr_agc_ff::gr_agc_ff (float rate, float reference, float gain, float max_gain)
+  : gr_sync_block ("gr_agc_ff",
+                  gr_make_io_signature (1, 1, sizeof (float)),
+                  gr_make_io_signature (1, 1, sizeof (float)))
+  , gri_agc (rate,  reference, gain, max_gain)
+{
+}
+
+int
+gr_agc_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];
+  scaleN (out, in, noutput_items);
+  return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_agc_ff.h b/gnuradio-core/src/lib/general/gr_agc_ff.h
new file mode 100644 (file)
index 0000000..da7edb7
--- /dev/null
@@ -0,0 +1,50 @@
+/* -*- c++ -*- */
+/*
+ * 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 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.
+ */
+
+#ifndef INCLUDED_GR_AGC_FF_H
+#define INCLUDED_GR_AGC_FF_H
+
+#include <gr_sync_block.h>
+#include <gri_agc.h>
+class gr_agc_ff;
+typedef boost::shared_ptr<gr_agc_ff> gr_agc_ff_sptr;
+
+gr_agc_ff_sptr
+gr_make_agc_ff (float rate = 1e-4, float reference = 1.0, float gain = 1.0, float max_gain = 0.0);
+/*!
+ * \brief high performance Automatic Gain Control class
+ *
+ * Power is approximated by absolute value
+ */
+
+class gr_agc_ff : public gr_sync_block, public gri_agc
+{
+  friend gr_agc_ff_sptr gr_make_agc_ff (float rate, float reference, float gain, float max_gain);
+  gr_agc_ff (float rate, float reference, float gain, float max_gain);
+
+ public:
+  virtual int work (int noutput_items,
+                   gr_vector_const_void_star &input_items,
+                   gr_vector_void_star &output_items);
+};
+
+#endif /* INCLUDED_GR_FLOAT_AGC_FF_H */
diff --git a/gnuradio-core/src/lib/general/gr_agc_ff.i b/gnuradio-core/src/lib/general/gr_agc_ff.i
new file mode 100644 (file)
index 0000000..9b63127
--- /dev/null
@@ -0,0 +1,33 @@
+/* -*- c++ -*- */
+/*
+ * 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 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.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,agc_ff)
+
+%include <gri_agc.i>
+
+gr_agc_ff_sptr
+gr_make_agc_ff (float rate = 1e-4, float reference = 1.0, float gain = 1.0, float max_gain = 0.0);
+
+class gr_agc_ff : public gr_sync_block , public gri_agc
+{
+  gr_agc_ff (float rate, float reference, float gain, float max_gain);
+};
diff --git a/gnuradio-core/src/lib/general/gr_align_on_samplenumbers_ss.cc b/gnuradio-core/src/lib/general/gr_align_on_samplenumbers_ss.cc
new file mode 100644 (file)
index 0000000..005b575
--- /dev/null
@@ -0,0 +1,461 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_align_on_samplenumbers_ss.h>
+#include <gr_io_signature.h>
+#include <assert.h>
+#include <stdexcept>
+
+//define ALIGN_ADVANCED_IMPLEMENTATION to have an alternative implementation of the align algoritm which exactly follows the align_interval spec.
+//It is more resource intensive, less tested and probably not needed
+//define ALIGN_ADVANCED_IMPLEMENTATION
+
+//define DEBUG_TOCONSUME to see debug messages about the synchronisation part of this block
+//define DEBUG_TOCONSUME
+#ifdef DEBUG_TOCONSUME
+#define tcPrintf if(dprint) printf
+#else
+#define tcPrintf //printf
+#endif
+
+#define ePrintf printf
+
+gr_align_on_samplenumbers_ss_sptr
+gr_make_align_on_samplenumbers_ss (int nchan, int align_interval)
+{
+  return gr_align_on_samplenumbers_ss_sptr (new gr_align_on_samplenumbers_ss (nchan,align_interval));
+}
+
+gr_align_on_samplenumbers_ss::gr_align_on_samplenumbers_ss (int nchan,int align_interval)
+  : gr_block ("align_on_samplenumbers_ss",
+        gr_make_io_signature (2, -1, sizeof (short)), //2, -1
+        gr_make_io_signature (2, -1, sizeof (short))), //2,-1
+  d_align_interval (align_interval),
+  d_nchan(nchan),
+  d_ninputs(0)
+{
+  if (d_align_interval<0)
+    set_output_multiple (d_nchan*2);
+  else
+  {
+    set_output_multiple (d_align_interval*d_nchan*2);
+  }
+    
+}
+
+gr_align_on_samplenumbers_ss::~gr_align_on_samplenumbers_ss()
+{
+  
+}
+void
+gr_align_on_samplenumbers_ss::forecast (int noutput_items, gr_vector_int &ninput_items_required)
+{
+  //assert (0 == noutput_items % d_align_interval);
+  unsigned ninputs = ninput_items_required.size();
+  for (unsigned int i = 0; i < ninputs; i++)
+    ninput_items_required[i] = std::max(noutput_items*d_nchan*2+ history() - 1,1024*d_nchan*2+ history() - 1);//TODO include the diffs found in determine input_items_required
+}
+
+bool
+gr_align_on_samplenumbers_ss::check_topology (int ninputs, int noutputs)
+{
+  bool result=true;
+  if(noutputs!=ninputs)
+  {
+    result=false;
+    ePrintf("gr_align_on_samplenumbers_ss: ERROR noutputs %i != ninputs %i\n",noutputs,ninputs);
+  }
+  if(d_nchan<2)
+  {
+    result=false;
+    ePrintf("gr_align_on_samplenumbers_ss: ERROR nchan %i<2 \n",d_nchan);
+  }
+  if((int)d_ninputs!=ninputs)
+  {
+    //Only resize and reset the status if there really changed something
+    //Don't reset the status if the user just called stop() and start(), although maybe we should.
+    d_state.resize(ninputs);
+    d_ninputs=ninputs;
+    for(unsigned int i=0;i<d_ninputs;i++)
+    {
+      d_state[i].sync_found=false;
+      d_state[i].sync_end_found=false;
+    }
+    d_in_presync=false;
+  }
+  return result;
+}
+
+#ifdef ALIGN_ADVANCED_IMPLEMENTATION
+int
+gr_align_on_samplenumbers_ss::general_work (int noutput_items,
+        gr_vector_int &ninput_items,
+        gr_vector_const_void_star &input_items,
+        gr_vector_void_star &output_items)
+{
+#ifdef DEBUG_TOCONSUME
+  static int dcount=0;
+  bool dprint=false;
+  dcount++;
+  if(dcount>200)
+  {
+    dcount=0;
+    dprint=true;
+  } 
+#endif
+  const size_t item_size = output_signature()->sizeof_stream_item (0);
+  const unsigned ninputs = input_items.size();
+  const unsigned noutputs = output_items.size();
+
+  int align_interval=d_align_interval*2*d_nchan;
+  if(d_align_interval<0)
+  {
+    //align once per noutput_items
+    align_interval=noutput_items;
+    align_interval=align_interval/(2*d_nchan);
+    align_interval=align_interval*(2*d_nchan);
+  }
+
+  int min_ninput_items=noutput_items;//numeric_limits<int>::max();
+  int noutput_items_produced=0;
+  for(unsigned int i=0;i<ninputs;i++)
+  { 
+    d_state[i].ninput_items=ninput_items[i];
+    d_state[i].ninput_items_used=0;
+    min_ninput_items=std::min(ninput_items[i],min_ninput_items);
+  }
+  for(int j=0;j<noutput_items-align_interval+1;j+=align_interval)
+  {
+    int common_end;
+    if(min_ninput_items>=align_interval)
+      common_end=align_interval;
+    else
+    {
+      common_end=min_ninput_items/(d_nchan*2);
+      common_end=common_end*(d_nchan*2);
+    }
+    if (common_end<=0) break;
+    
+    bool all_diffs_zero=true;
+    //bool sync_found=false;
+    int diff_comp_end_max=0;
+    for(unsigned int i=0;i<ninputs;i++)
+    {
+      unsigned short * uin=&(((unsigned short*)input_items[i])[d_state[i].ninput_items_used]);
+      unsigned int  x_high16bits = uin[0];
+      unsigned int  x_low16bits = uin[1];
+      d_state[i].ucounter_begin = x_high16bits<<16 | x_low16bits;
+      d_state[i].diff=d_state[0].ucounter_begin-d_state[i].ucounter_begin;//Result is a signed value,Will wrap around on 32 bit boundary
+      int common_last=std::max(common_end-d_nchan*2,0);
+      x_high16bits = uin[d_nchan*2];
+      x_low16bits = uin[d_nchan*2+1];
+      unsigned int ucounter_begin2 = x_high16bits<<16 | x_low16bits;
+#ifdef DEBUG_TOCONSUME
+      if((d_state[i].ucounter_begin+1)!=(ucounter_begin2))
+        if(ucounter_begin2==0)
+          ePrintf("SYNC counters are 0\n");
+        else
+           ePrintf("Error: counter not continuous.\n ucounter_begin[%i]=%i +1 !=  ucounter_begin2=%i\n",i,d_state[i].ucounter_begin,ucounter_begin2);
+#endif
+      x_high16bits = uin[common_last];
+      x_low16bits = uin[common_last+1];
+      d_state[i].ucounter_end = x_high16bits<<16 | x_low16bits;
+      d_state[i].diff_end=d_state[0].ucounter_end-d_state[i].ucounter_end;//Result is a signed value,Will wrap around on 32 bit boundary
+      d_state[i].diff_comp_end=d_state[i].ucounter_end-d_state[0].ucounter_end;
+      diff_comp_end_max=std::max(d_state[i].diff_comp_end,diff_comp_end_max);
+#ifdef DEBUG_TOCONSUME
+      if(d_state[i].diff>256000000 || d_state[i].diff_end>256000000 || d_state[i].diff_comp_end>256000000)
+      {
+        tcPrintf("diff[%i]=%i diff_end=%i diff_comp_end=%i\n",i,d_state[i].diff,d_state[i].diff_end,d_state[i].diff_comp_end);
+      }
+#endif
+      all_diffs_zero=all_diffs_zero && (0==d_state[i].diff_end);
+      if(d_state[i].ucounter_end<d_state[i].ucounter_begin+(unsigned)(common_last/(d_nchan*2))) //(unsigned)(common_last/(d_nchan*2)))
+      {
+        //printf("sync 1 ");// found ucounter_end[%i]=%i ucounter_begin[%i]=%i \n",i,d_state[i].ucounter_end,i,d_state[i].ucounter_begin);
+        //sync_found=true;//sync_found or 32 bit counter  wraparound (0xffffffff -> 0x00000000)
+        if(!d_in_presync)
+        {
+#ifdef DEBUG_TOCONSUME
+          printf("presync START with %i\n",i);
+#endif
+         for(unsigned int k=0;k<ninputs;k++)
+         {
+          d_state[k].sync_found=false;
+          d_state[i].sync_end_found=false;
+         }
+         d_in_presync=true;
+         d_state[i].sync_found=true;    
+        } else
+        {
+          //d_in_presync=true;
+#ifdef DEBUG_TOCONSUME
+          if(d_state[i].sync_found)
+            printf("presync CONTINUE with %i\n",i);
+          else
+            printf("presync NEXT with %i\n",i);
+#endif
+          d_state[i].sync_found=true;  
+          d_state[i].sync_end_found=false;  
+        }             
+      } else
+      {
+        if(d_in_presync && d_state[i].sync_found)
+        {
+          d_state[i].sync_end_found=true;
+          bool all_syncs_found=true;
+          for(unsigned int k=0;k<ninputs;k++)
+            all_syncs_found=all_syncs_found && d_state[k].sync_end_found;
+          d_in_presync=!all_syncs_found;
+          if(!d_in_presync)
+          {
+            for(unsigned int k=0;k<ninputs;k++)
+            {
+              d_state[k].sync_found=false;
+              d_state[i].sync_end_found=false;
+            }
+#ifdef DEBUG_TOCONSUME
+            printf("presync END\n");
+#endif
+          }
+        }
+      }
+    }
+    if(d_in_presync || all_diffs_zero)
+    {
+      for(unsigned int i=0;i<ninputs;i++)
+      {
+         memcpy(&(((unsigned short*)output_items[i])[j]),&(((const unsigned short*)input_items[i])[d_state[i].ninput_items_used]),common_end*item_size);
+         //consume(i,common_end);
+         d_state[i].ninput_items-=common_end;
+         d_state[i].ninput_items_used+=common_end;
+         min_ninput_items=std::min(d_state[i].ninput_items,min_ninput_items);
+#ifdef DEBUG_TOCONSUME
+         if(common_end<256)
+           tcPrintf("common_end %i\n",common_end);
+#endif
+      }
+      //min_ninput_items-=common_end;
+      noutput_items_produced+=common_end;
+      //return common_end;
+    } else
+    {
+      //printf("sync 2");
+      for(unsigned int i=0;i<ninputs;i++)
+      {
+        int toconsume=std::min((d_state[i].diff_end+diff_comp_end_max)*d_nchan*2,d_state[i].ninput_items);
+        toconsume=toconsume/(d_nchan*2);
+        toconsume=toconsume*(d_nchan*2);
+        d_state[i].ninput_items-=toconsume;
+        d_state[i].ninput_items_used+=toconsume;
+        min_ninput_items=std::min(d_state[i].ninput_items,min_ninput_items);
+#ifdef DEBUG_TOCONSUME
+      static int toconsume_counter=0;
+      toconsume_counter++;
+      //if(toconsume_counter>10)
+      {
+        tcPrintf("toconsume=%i diff_end[%i]*d_nchan*2=%i diff_comp_end_max*d_nchan*2=%i ninput_items[%i]=%i\n",toconsume,i,d_state[i].diff_end*d_nchan*2,diff_comp_end_max*d_nchan*2,i,ninput_items[i]);
+        toconsume_counter=0;
+      }
+#endif
+        //printf("toconsume[%i]=%i\n",i,toconsume);
+        //consume(i,toconsume);//skip the difference in samplenumber items
+      }
+      //return 0;
+    }
+  }
+  for(unsigned int i=0;i<ninputs;i++)
+    consume(i,d_state[i].ninput_items_used);
+#ifdef DEBUG_TOCONSUME
+  if(noutput_items_produced<256)
+    tcPrintf("noutput_items_produced %i\n",noutput_items_produced);
+#endif
+  return noutput_items_produced;
+}
+
+
+#else /*ALIGN_ADVANCED_IMPLEMENTATION*/
+int
+gr_align_on_samplenumbers_ss::general_work (int noutput_items,
+        gr_vector_int &ninput_items,
+        gr_vector_const_void_star &input_items,
+        gr_vector_void_star &output_items)
+{
+#ifdef DEBUG_TOCONSUME
+  static int dcount=0;
+  bool dprint=false;
+  dcount++;
+  if(dcount>2000)
+  {
+    dcount=0;
+    dprint=true;
+  } 
+#endif
+  const size_t item_size = output_signature()->sizeof_stream_item (0);
+  const unsigned ninputs = input_items.size();
+  
+  int common_end=noutput_items;
+  //int diff_min=INT_MAX;
+  //int diff_max=INT_MIN;
+  for(unsigned int i=0;i<ninputs;i++)
+  {
+    unsigned short * uin=(unsigned short*)input_items[i];
+    unsigned int  x_high16bits = uin[0];
+    unsigned int  x_low16bits = uin[1];
+    d_state[i].ucounter_begin = x_high16bits<<16 | x_low16bits;
+    d_state[i].diff=d_state[0].ucounter_end-d_state[i].ucounter_end;//Result is a signed value,Will wrap around on 32 bit boundary
+    x_high16bits = uin[d_nchan*2];
+    x_low16bits = uin[d_nchan*2+1];
+    unsigned int ucounter_begin2 = x_high16bits<<16 | x_low16bits;
+    if((d_state[i].ucounter_begin+1)!=(ucounter_begin2))
+      if(ucounter_begin2==0)
+      {
+#ifdef DEBUG_TOCONSUME
+        ePrintf("SYNC counters are 0\n");
+#endif
+      }
+      else
+      {
+        ePrintf("Error: counter not continuous.\n ucounter_begin[%i]=%i +1 !=  ucounter_begin2=%i\n",i,d_state[i].ucounter_begin,ucounter_begin2);
+      }
+      
+    //diff_comp[i]=ucounter[i]-ucounter[0];
+    //diff_min=std::min(diff[i],diff_min);
+    //diff_max=std::max(diff[i],diff_max);
+    common_end=std::max(std::min(ninput_items[i],common_end),0);
+  }
+  common_end=common_end/(d_nchan*2);
+  common_end=common_end*(d_nchan*2);
+#ifdef DEBUG_TOCONSUME
+  if(common_end<d_nchan*2)
+  {
+    printf(" common_end %i\n",common_end);
+    for(int j=0;j<ninputs;j++)
+      printf("ninput_items[%i]=%i\n",j,ninput_items[j]);
+  }
+#endif
+  bool all_diffs_zero=true;
+  bool sync_found=false;
+  int diff_comp_end_max=0;
+  for(unsigned int i=0;i<ninputs;i++)
+  {
+    unsigned short * uin=(unsigned short*)input_items[i];
+    int common_last=common_end-(d_nchan*2);
+    unsigned int  x_high16bits = uin[common_last];
+    unsigned int  x_low16bits = uin[common_last+1];
+    d_state[i].ucounter_end = x_high16bits<<16 | x_low16bits;
+    d_state[i].diff_end=d_state[0].ucounter_end-d_state[i].ucounter_end;//Result is a signed value,Will wrap around on 32 bit boundary
+    d_state[i].diff_comp_end=d_state[i].ucounter_end-d_state[0].ucounter_end;
+    //diff_end_min=std::min(diff_end[i],diff_end_min);
+    //diff_end_max=std::max(diff_end[i],diff_end_max);
+    diff_comp_end_max=std::max(d_state[i].diff_comp_end,diff_comp_end_max);
+#ifdef DEBUG_TOCONSUME
+    if(d_state[i].diff_end!=d_state[i].diff)
+    {
+      //samples_lost_or_syncstart=true;
+      printf("Us%i %i %i ",i,d_state[i].diff_end,d_state[i].diff);
+    }
+#endif
+    all_diffs_zero=all_diffs_zero && (0==d_state[i].diff_end);
+    if((d_state[i].ucounter_end<d_state[i].ucounter_begin+(unsigned)(common_last/(d_nchan*2))) || (0==d_state[i].ucounter_end) || (0==d_state[i].ucounter_begin)) //(unsigned)(common_last/(d_nchan*2)))
+    {
+      sync_found=true;//sync_found or 32 bit counter  wraparound (0xffffffff -> 0x00000000)
+#ifdef DEBUG_TOCONSUME
+      tcPrintf("SYNC diff_end[%i]=%i ucounter_end[%i]=%i ucounter_begin[%i]=%i \n",i,d_state[i].diff_end,i,d_state[i].ucounter_end,i,d_state[i].ucounter_begin);
+      tcPrintf("ucounter_end=%i < %i = ucounter_begin+(unsigned)(common_last/(d_nchan*2) \n",d_state[i].ucounter_end,d_state[i].ucounter_begin+(unsigned)(common_last/(d_nchan*2)));
+
+      printf("ucounter_end[%i]=%i ucounter_begin[%i]=%i\n",i,d_state[i].ucounter_end,i,d_state[i].ucounter_begin);      
+      int expected_sync_position=common_last - d_state[i].ucounter_end*(d_nchan*2);
+      if(0==uin[expected_sync_position] && 0==uin[expected_sync_position+1])
+      {
+        printf("sync found on input %i at position %i \n",i,expected_sync_position);
+        //sync_start[i]=expected_sync_position;
+      } else
+      {
+        printf("sync found on input %i position unclear, expected at %i value there %i\n",i,expected_sync_position,uin[expected_sync_position]<<16 | uin[expected_sync_position+1]);
+        //sync_start[i]=-1;
+      }
+    } else
+    {
+      tcPrintf("NOsync diff_end[%i]=%i ucounter_end[%i]=%i ucounter_begin[%i]=%i \n",i,d_state[i].diff_end,i,d_state[i].ucounter_end,i,d_state[i].ucounter_begin);
+#endif    
+    }
+  }
+  bool problem=false;
+  for(unsigned int i=0;i<ninputs;i++)
+    if((d_state[i].diff_end+diff_comp_end_max) >0x4000000)
+      {
+        problem=true;
+        ePrintf("Warning: counter diff greater as 64 Million\n");
+        ePrintf("         You might want to swap master and slave.\n");
+        ePrintf("          i=%i,d_state[i].diff_end+diff_comp_end_max=%i,d_state[i].diff_end=%i,diff_comp_end_max=%i,ucounter[i]=%i,ucounter[0]=%i\n",
+                          i,d_state[i].diff_end+diff_comp_end_max,d_state[i].diff_end,diff_comp_end_max,d_state[i].ucounter_end,d_state[0].ucounter_end);
+        //ePrintf("        toconsume=%i\n",toconsume); 
+      }
+  if(sync_found || all_diffs_zero || problem)
+  {
+#ifdef DEBUG_TOCONSUME
+    if(all_diffs_zero) tcPrintf("ZERO\n");
+    if(sync_found) tcPrintf("SYNC\n");
+#endif
+    for(unsigned int i=0;i<ninputs;i++)
+    {
+       memcpy(output_items[i],input_items[i],common_end*item_size);
+       consume(i,common_end);
+#ifdef DEBUG_TOCONSUME
+      if(common_end<256)
+        tcPrintf("common_end %i\n",common_end);
+#endif
+    }
+    return common_end;
+  } else
+  {
+    //int minconsume=0;//common_end/(2*d_nchan*2);
+    //min_consume=min_consume*d_nchan*2;  
+    for(unsigned int i=0;i<ninputs;i++)
+    {
+      int toconsume=std::min((d_state[i].diff_end+diff_comp_end_max)*d_nchan*2,ninput_items[i]);
+      toconsume=toconsume/(d_nchan*2);
+      toconsume=toconsume*(d_nchan*2);
+#ifdef DEBUG_TOCONSUME
+      //printf("dcount %i\n",dcount);
+      static int toconsume_counter=0;
+      toconsume_counter++;
+      //if(toconsume_counter>10)
+      {
+        tcPrintf("toconsume=%i diff_end[[%i]*d_nchan*2=%i diff_comp_end_max)*d_nchan*2=%i ninput_items[%i]=%i\n",
+                  toconsume,i,d_state[i].diff_end*d_nchan*2,diff_comp_end_max*d_nchan*2,i,ninput_items[i]);
+        toconsume_counter=0;
+      }
+#endif
+      consume(i,toconsume);//skip the difference in samplenumber items
+      //printf("toconsume%i %i diff_comp_end_max %i diff_end[[%i] %i\n",i,toconsume,diff_comp_end_max,i,d_state[i].diff_end);
+    }
+    return 0;
+  }
+  return -1;//Should never come here
+}
+#endif /*ALIGN_ADVANCED_IMPLEMENTATION*/
diff --git a/gnuradio-core/src/lib/general/gr_align_on_samplenumbers_ss.h b/gnuradio-core/src/lib/general/gr_align_on_samplenumbers_ss.h
new file mode 100644 (file)
index 0000000..69d68b2
--- /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 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.
+ */
+
+#ifndef INCLUDED_GR_ALIGN_ON_SAMPLE_NUMBERS_SS_H
+#define INCLUDED_GR_ALIGN_ON_SAMPLE_NUMBERS_SS_H
+
+#include <gr_block.h>
+
+class gr_align_on_samplenumbers_ss;
+typedef boost::shared_ptr<gr_align_on_samplenumbers_ss> gr_align_on_samplenumbers_ss_sptr;
+
+gr_align_on_samplenumbers_ss_sptr gr_make_align_on_samplenumbers_ss (int nchan=2, int align_interval=128);
+
+/*!
+ * \brief align several complex short (interleaved short) input channels with corresponding unsigned 32 bit sample_counters (provided as interleaved 16 bit values)
+ * \param number of complex_short input channels (including the 32 bit counting channel)
+ * \param align_interval is after how much samples (minimally) the sample-alignement is refreshed. Default is 128.
+ * A bigger value means less processing power but also requests more buffer space, which has a maximum.
+ * Decrease the align_interval if you get an error like:
+ * "sched: <gr_block align_on_samplenumbers_ss (0)> is requesting more input data  than we can provide.
+ *  ninput_items_required = 32768
+ *  max_possible_items_available = 16383
+ *  If this is a filter, consider reducing the number of taps."
+ * \ingroup block
+ * Pay attention on how you connect this block.
+ * It expects a minimum of 2 usrp_source_s with nchan number of channels and FPGA_MODE_COUNTING_32BIT enabled.
+ * This means that the first complex_short channel on every input is an interleaved 32 bit counter. 
+ * The samples are aligned by dropping samples untill the samplenumbers match.
+ */
+
+
+class gr_align_on_samplenumbers_ss : public gr_block
+{
+  int  d_align_interval;
+  int  d_sample_counter;
+  int  d_nchan;
+  bool d_in_presync;
+  unsigned int d_ninputs;
+  class align_state {
+      public:
+        unsigned int ucounter_end;
+        unsigned int ucounter_begin;
+        int diff;
+        int diff_comp;
+        int diff_end;
+        int diff_comp_end;
+        bool sync_found;
+        bool sync_end_found;
+        int ninput_items;
+        int ninput_items_used;
+      };
+  std::vector<align_state>   d_state;
+    
+  friend gr_align_on_samplenumbers_ss_sptr gr_make_align_on_samplenumbers_ss (int nchan,int align_interval);
+  gr_align_on_samplenumbers_ss (int nchan,int align_interval);
+
+ public:
+   ~gr_align_on_samplenumbers_ss();
+  bool check_topology (int ninputs, int noutputs);
+  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);
+};
+
+
+#endif /* INCLUDED_GR_ALIGN_ON_SAMPLE_NUMBERS_SS_H */
diff --git a/gnuradio-core/src/lib/general/gr_align_on_samplenumbers_ss.i b/gnuradio-core/src/lib/general/gr_align_on_samplenumbers_ss.i
new file mode 100644 (file)
index 0000000..00d3174
--- /dev/null
@@ -0,0 +1,33 @@
+/* -*- 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 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.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,align_on_samplenumbers_ss);
+
+gr_align_on_samplenumbers_ss_sptr gr_make_align_on_samplenumbers_ss(int nchan=2, int align_interval=128);
+
+class gr_align_on_samplenumbers_ss : public gr_block
+{
+ public:
+  ~gr_align_on_samplenumbers_ss ();
+ private:
+  gr_align_on_samplenumbers_ss (int nchan,int align_interval);
+};
diff --git a/gnuradio-core/src/lib/general/gr_binary_slicer_fb.cc b/gnuradio-core/src/lib/general/gr_binary_slicer_fb.cc
new file mode 100644 (file)
index 0000000..a74746d
--- /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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_binary_slicer_fb.h>
+#include <gr_io_signature.h>
+#include <stdexcept>
+
+gr_binary_slicer_fb_sptr
+gr_make_binary_slicer_fb ()
+{
+  return gr_binary_slicer_fb_sptr (new gr_binary_slicer_fb ());
+}
+
+gr_binary_slicer_fb::gr_binary_slicer_fb ()
+  : gr_sync_block ("binary_slicer_fb",
+                  gr_make_io_signature (1, 1, sizeof (float)),
+                  gr_make_io_signature (1, 1, sizeof (unsigned char)))
+{
+}
+
+static inline int
+slice(float x)
+{
+  return x < 0 ? 0 : 1;
+}
+
+int
+gr_binary_slicer_fb::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];
+  unsigned char *out = (unsigned char *) output_items[0];
+
+
+  for (int i = 0; i < noutput_items; i++){
+    out[i] = slice(in[i]);
+  }
+  
+  return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_binary_slicer_fb.h b/gnuradio-core/src/lib/general/gr_binary_slicer_fb.h
new file mode 100644 (file)
index 0000000..ce75571
--- /dev/null
@@ -0,0 +1,51 @@
+/* -*- 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 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.
+ */
+
+#ifndef INCLUDED_GR_BINARY_SLICER_FB_H
+#define INCLUDED_GR_BINARY_SLICER_FB_H
+
+#include <gr_sync_block.h>
+
+class gr_binary_slicer_fb;
+typedef boost::shared_ptr<gr_binary_slicer_fb> gr_binary_slicer_fb_sptr;
+
+gr_binary_slicer_fb_sptr gr_make_binary_slicer_fb ();
+
+/*!
+ * \brief slice float binary symbol outputting 1 bit output
+ * \ingroup block
+ *
+ * x <  0 --> 0
+ * x >= 0 --> 1
+ */
+class gr_binary_slicer_fb : public gr_sync_block
+{
+  friend gr_binary_slicer_fb_sptr gr_make_binary_slicer_fb ();
+  gr_binary_slicer_fb ();
+
+ public:
+  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_binary_slicer_fb.i b/gnuradio-core/src/lib/general/gr_binary_slicer_fb.i
new file mode 100644 (file)
index 0000000..0d66429
--- /dev/null
@@ -0,0 +1,33 @@
+/* -*- 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 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.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,binary_slicer_fb);
+
+gr_binary_slicer_fb_sptr gr_make_binary_slicer_fb ();
+
+class gr_binary_slicer_fb : public gr_sync_block
+{
+ private:
+  gr_binary_slicer_fb ();
+
+ public:
+};
diff --git a/gnuradio-core/src/lib/general/gr_bytes_to_syms.cc b/gnuradio-core/src/lib/general/gr_bytes_to_syms.cc
new file mode 100644 (file)
index 0000000..3b492cd
--- /dev/null
@@ -0,0 +1,74 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_bytes_to_syms.h>
+#include <gr_io_signature.h>
+#include <assert.h>
+
+static const int BITS_PER_BYTE = 8;
+
+gr_bytes_to_syms_sptr 
+gr_make_bytes_to_syms ()
+{
+  return gr_bytes_to_syms_sptr (new gr_bytes_to_syms ());
+}
+
+gr_bytes_to_syms::gr_bytes_to_syms ()
+  : gr_sync_interpolator ("bytes_to_syms",
+                         gr_make_io_signature (1, 1, sizeof (unsigned char)),
+                         gr_make_io_signature (1, 1, sizeof (float)),
+                         BITS_PER_BYTE)
+{
+}
+
+int
+gr_bytes_to_syms::work (int noutput_items,
+                       gr_vector_const_void_star &input_items,
+                       gr_vector_void_star &output_items)
+{
+  const unsigned char *in = (unsigned char *) input_items[0];
+  float *out = (float *) output_items[0];
+
+  assert (noutput_items % BITS_PER_BYTE == 0);
+
+  for (int i = 0; i < noutput_items / BITS_PER_BYTE; i++){
+    int x = in[i];
+
+    *out++ = (((x >> 7) & 0x1) << 1) - 1;
+    *out++ = (((x >> 6) & 0x1) << 1) - 1;
+    *out++ = (((x >> 5) & 0x1) << 1) - 1;
+    *out++ = (((x >> 4) & 0x1) << 1) - 1;
+    *out++ = (((x >> 3) & 0x1) << 1) - 1;
+    *out++ = (((x >> 2) & 0x1) << 1) - 1;
+    *out++ = (((x >> 1) & 0x1) << 1) - 1;
+    *out++ = (((x >> 0) & 0x1) << 1) - 1;
+  }
+
+  return noutput_items;
+}
+
+
+  
diff --git a/gnuradio-core/src/lib/general/gr_bytes_to_syms.h b/gnuradio-core/src/lib/general/gr_bytes_to_syms.h
new file mode 100644 (file)
index 0000000..72f844d
--- /dev/null
@@ -0,0 +1,60 @@
+/* -*- 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 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.
+ */
+#ifndef INCLUDED_GR_BYTES_TO_SYMS_H
+#define INCLUDED_GR_BYTES_TO_SYMS_H
+
+#include <gr_sync_interpolator.h>
+
+class gr_bytes_to_syms;
+typedef boost::shared_ptr<gr_bytes_to_syms> gr_bytes_to_syms_sptr;
+
+gr_bytes_to_syms_sptr gr_make_bytes_to_syms ();
+
+/*!
+ * \brief Convert stream of bytes to stream of +/- 1 symbols
+ * \ingroup block
+ *
+ * input: stream of bytes; output: stream of float
+ *
+ * This block is deprecated.
+ *
+ * The combination of gr_packed_to_unpacked_bb followed by
+ * gr_chunks_to_symbols_bf or gr_chunks_to_symbols_bc handles the
+ * general case of mapping from a stream of bytes into arbitrary float
+ * or complex symbols.
+ *
+ * \sa gr_packed_to_unpacked_bb, gr_unpacked_to_packed_bb,
+ * \sa gr_chunks_to_symbols_bf, gr_chunks_to_symbols_bc.
+ */
+class gr_bytes_to_syms : public gr_sync_interpolator
+{
+  friend gr_bytes_to_syms_sptr gr_make_bytes_to_syms ();
+
+  gr_bytes_to_syms ();
+
+ public:
+  int work (int noutput_items,
+           gr_vector_const_void_star &input_items,
+           gr_vector_void_star &output_items);
+};
+
+#endif /* INCLUDED_GR_BYTES_TO_SYMS_H */
diff --git a/gnuradio-core/src/lib/general/gr_bytes_to_syms.i b/gnuradio-core/src/lib/general/gr_bytes_to_syms.i
new file mode 100644 (file)
index 0000000..33ef089
--- /dev/null
@@ -0,0 +1,30 @@
+/* -*- 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 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.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,bytes_to_syms);
+
+gr_bytes_to_syms_sptr gr_make_bytes_to_syms ();
+
+class gr_bytes_to_syms : public gr_sync_interpolator
+{
+  gr_bytes_to_syms ();
+};
diff --git a/gnuradio-core/src/lib/general/gr_char_to_float.cc b/gnuradio-core/src/lib/general/gr_char_to_float.cc
new file mode 100644 (file)
index 0000000..c4151ee
--- /dev/null
@@ -0,0 +1,55 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_char_to_float.h>
+#include <gr_io_signature.h>
+#include <gri_char_to_float.h>
+
+gr_char_to_float_sptr
+gr_make_char_to_float ()
+{
+  return gr_char_to_float_sptr (new gr_char_to_float ());
+}
+
+gr_char_to_float::gr_char_to_float ()
+  : gr_sync_block ("gr_char_to_float",
+                  gr_make_io_signature (1, 1, sizeof (char)),
+                  gr_make_io_signature (1, 1, sizeof (float)))
+{
+}
+
+int
+gr_char_to_float::work (int noutput_items,
+                        gr_vector_const_void_star &input_items,
+                        gr_vector_void_star &output_items)
+{
+  const char *in = (const char *) input_items[0];
+  float *out = (float *) output_items[0];
+
+  gri_char_to_float (in, out, noutput_items);
+  
+  return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_char_to_float.h b/gnuradio-core/src/lib/general/gr_char_to_float.h
new file mode 100644 (file)
index 0000000..d2b287f
--- /dev/null
@@ -0,0 +1,51 @@
+/* -*- 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 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.
+ */
+
+#ifndef INCLUDED_GR_CHAR_TO_FLOAT_H
+#define INCLUDED_GR_CHAR_TO_FLOAT_H
+
+#include <gr_sync_block.h>
+
+class gr_char_to_float;
+typedef boost::shared_ptr<gr_char_to_float> gr_char_to_float_sptr;
+
+gr_char_to_float_sptr
+gr_make_char_to_float ();
+
+/*!
+ * \brief Convert stream of chars to a stream of float
+ * \ingroup converter
+ */
+
+class gr_char_to_float : public gr_sync_block
+{
+  friend gr_char_to_float_sptr gr_make_char_to_float ();
+  gr_char_to_float ();
+
+ public:
+  virtual int work (int noutput_items,
+                   gr_vector_const_void_star &input_items,
+                   gr_vector_void_star &output_items);
+};
+
+
+#endif /* INCLUDED_GR_CHAR_TO_FLOAT_H */
diff --git a/gnuradio-core/src/lib/general/gr_char_to_float.i b/gnuradio-core/src/lib/general/gr_char_to_float.i
new file mode 100644 (file)
index 0000000..3f1c7e1
--- /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 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.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,char_to_float)
+
+gr_char_to_float_sptr gr_make_char_to_float ();
+
+class gr_char_to_float : public gr_sync_block
+{
+  gr_char_to_float ();
+};
diff --git a/gnuradio-core/src/lib/general/gr_check_counting_s.cc b/gnuradio-core/src/lib/general/gr_check_counting_s.cc
new file mode 100644 (file)
index 0000000..59e740c
--- /dev/null
@@ -0,0 +1,190 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_check_counting_s.h>
+#include <gr_io_signature.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+gr_check_counting_s_sptr
+gr_make_check_counting_s (bool do_32bit)
+{
+  return gr_check_counting_s_sptr (new gr_check_counting_s (do_32bit));
+}
+
+gr_check_counting_s::gr_check_counting_s (bool do_32bit)
+  : gr_sync_block ("gr_check_counting",
+    gr_make_io_signature (1, 1, sizeof (short)),
+    gr_make_io_signature (0, 0, 0)),
+    d_state(SEARCHING), d_history (0), d_current_count (0), d_current_count_32bit(0),
+    d_total_errors (0), d_total_shorts (0),
+    d_do_32bit(do_32bit)
+{
+  enter_SEARCHING ();
+}
+
+int
+gr_check_counting_s::work (int noutput_items,
+        gr_vector_const_void_star &input_items,
+        gr_vector_void_star &output_items)
+{
+  unsigned short *in = (unsigned short *) input_items[0];
+  if(d_do_32bit)
+    return check_32bit(noutput_items,in);
+  else
+    return check_16bit(noutput_items,in);
+}
+
+int
+gr_check_counting_s::check_16bit (int noutput_items,
+        unsigned short * in)
+{
+  for (int i = 0; i < noutput_items; i++){
+    unsigned short  x = in[i];
+    
+    switch (d_state){
+
+    case SEARCHING:
+      if (x == d_current_count){
+       right ();
+       log_error (d_current_count, x);
+       d_current_count = d_current_count + 1;
+       if (right_three_times ())
+         enter_LOCKED ();
+      }
+      else {
+        wrong ();
+        log_error (d_current_count, x);
+        d_current_count = x + 1;
+      }
+      break;
+
+    case LOCKED:
+      if (x == d_current_count){
+        right ();
+        d_current_count = d_current_count + 1;
+      }
+      else {
+        wrong ();
+        log_error (d_current_count, x);
+        d_current_count = d_current_count + 1;
+        if (wrong_three_times ())
+          enter_SEARCHING ();
+      }
+      break;
+
+    default:
+      abort ();
+    }
+
+    d_total_shorts++;
+  }
+
+  return noutput_items;
+}
+
+int
+gr_check_counting_s::check_32bit (int noutput_items,
+        unsigned short * in)
+{
+
+  for (int i = 0; i < noutput_items-1; i+=2){
+    unsigned int  x_high16bits = in[i];
+    unsigned int  x_low16bits = in[i+1];
+    unsigned int  x = x_high16bits<<16 | x_low16bits;
+    
+    switch (d_state){
+
+    case SEARCHING:
+      if (x == d_current_count_32bit){
+        right ();
+        log_error_32bit (d_current_count_32bit, x);
+        d_current_count_32bit = d_current_count_32bit + 1;
+        if (right_three_times ())
+          enter_LOCKED ();
+      }
+      else {
+        wrong ();
+        log_error_32bit (d_current_count_32bit, x);
+        d_current_count_32bit = x + 1;
+      }
+      break;
+
+    case LOCKED:
+      if (x == d_current_count_32bit){
+        right ();
+        d_current_count_32bit = d_current_count_32bit + 1;
+      }
+      else {
+        wrong ();
+        log_error_32bit (d_current_count_32bit, x);
+        d_current_count_32bit = d_current_count_32bit + 1;
+        if (wrong_three_times ())
+          enter_SEARCHING ();
+      }
+      break;
+
+    default:
+      abort ();
+    }
+
+    d_total_shorts++;
+  }
+
+  return noutput_items;
+}
+
+void
+gr_check_counting_s::enter_SEARCHING ()
+{
+  d_state = SEARCHING;
+  fprintf (stdout, "gr_check_counting: enter_SEARCHING at offset %8ld (0x%08lx)\n",
+     d_total_shorts, d_total_shorts);
+}
+
+void
+gr_check_counting_s::enter_LOCKED ()
+{
+  d_state = LOCKED;
+  fprintf (stdout, "gr_check_counting: enter_LOCKED at offset %8ld (0x%08lx)\n",
+     d_total_shorts, d_total_shorts);
+}
+
+void
+gr_check_counting_s::log_error (unsigned short expected, unsigned short actual)
+{
+  fprintf (stdout, 
+"gr_check_counting: expected %5d (0x%04x) got %5d (0x%04x) offset %8ld (0x%08lx)\n",
+     expected, expected, actual, actual, d_total_shorts, d_total_shorts);
+}
+
+void
+gr_check_counting_s::log_error_32bit (unsigned int expected, unsigned int actual)
+{
+  fprintf (stdout, 
+"gr_check_counting: expected %10d (0x%08x) got %10d (0x%08x) offset %8ld (0x%08lx)\n",
+     expected, expected, actual, actual, d_total_shorts, d_total_shorts);
+}
diff --git a/gnuradio-core/src/lib/general/gr_check_counting_s.h b/gnuradio-core/src/lib/general/gr_check_counting_s.h
new file mode 100644 (file)
index 0000000..3037e9f
--- /dev/null
@@ -0,0 +1,88 @@
+/* -*- 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 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.
+ */
+#ifndef INCLUDED_GR_CHECK_COUNTING_S_H
+#define INCLUDED_GR_CHECK_COUNTING_S_H
+
+#include <gr_sync_block.h>
+
+class gr_check_counting_s;
+typedef boost::shared_ptr<gr_check_counting_s> gr_check_counting_s_sptr;
+
+gr_check_counting_s_sptr gr_make_check_counting_s (bool do_32bit=false);
+
+/*!
+ * \brief sink that checks if its input stream consists of a counting sequence.
+ * \param do_32bit  expect an interleaved 32 bit counter in stead of 16 bit counter (default false)
+ * \ingroup sink
+ *
+ * This sink is typically used to test the USRP "Counting Mode" or "Counting mode 32 bit".
+ */
+class gr_check_counting_s : public gr_sync_block
+{
+  friend gr_check_counting_s_sptr gr_make_check_counting_s (bool do_32bit);
+
+  enum state {
+    SEARCHING,    // searching for synchronization
+    LOCKED    // is locked
+  };
+
+  state      d_state;
+  unsigned int    d_history;    // bitmask of decisions
+  unsigned short  d_current_count;
+  unsigned int    d_current_count_32bit;
+  
+  long      d_total_errors;
+  long      d_total_shorts;
+  bool      d_do_32bit;
+
+  gr_check_counting_s (bool do_32bit);
+  
+  void enter_SEARCHING ();
+  void enter_LOCKED ();
+
+  void right (){
+    d_history = (d_history << 1) | 0x1;
+  }
+  
+  void wrong (){
+    d_history = (d_history << 1) | 0x0;
+    d_total_errors++;
+  }
+
+  bool right_three_times () { return (d_history & 0x7) == 0x7; }
+  bool wrong_three_times () { return (d_history & 0x7) == 0x0; }
+
+  void log_error (unsigned short expected, unsigned short actual);
+  void log_error_32bit (unsigned int expected, unsigned int actual);
+  
+  int check_32bit (int noutput_items, unsigned short * in);
+  int check_16bit (int noutput_items, unsigned short * in);
+
+ public:
+
+  int work (int noutput_items,
+      gr_vector_const_void_star &input_items,
+      gr_vector_void_star &output_items);
+};
+
+
+#endif /* INCLUDED_GR_CHECK_COUNTING_S_H */
diff --git a/gnuradio-core/src/lib/general/gr_check_counting_s.i b/gnuradio-core/src/lib/general/gr_check_counting_s.i
new file mode 100644 (file)
index 0000000..f52f872
--- /dev/null
@@ -0,0 +1,31 @@
+/* -*- 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 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.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,check_counting_s)
+
+gr_check_counting_s_sptr gr_make_check_counting_s (bool do_32bit=false);
+
+class gr_check_counting_s : public gr_sync_block
+{
+ private:
+  gr_check_counting_s (bool do_32bit);
+};
diff --git a/gnuradio-core/src/lib/general/gr_check_lfsr_32k_s.cc b/gnuradio-core/src/lib/general/gr_check_lfsr_32k_s.cc
new file mode 100644 (file)
index 0000000..72051cf
--- /dev/null
@@ -0,0 +1,169 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_check_lfsr_32k_s.h>
+#include <gr_io_signature.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+gr_check_lfsr_32k_s_sptr
+gr_make_check_lfsr_32k_s ()
+{
+  return gr_check_lfsr_32k_s_sptr (new gr_check_lfsr_32k_s ());
+}
+
+gr_check_lfsr_32k_s::gr_check_lfsr_32k_s ()
+  : gr_sync_block ("gr_check_lfsr_32k",
+                  gr_make_io_signature (1, 1, sizeof (short)),
+                  gr_make_io_signature (0, 0, 0)),
+    d_state(SEARCHING), d_history (0), d_ntotal (0), d_nright (0),
+    d_runlength (0), d_index(0)
+{
+  gri_lfsr_32k lfsr;
+  
+  for (int i = 0; i < BUFSIZE; i++)
+    d_buffer[i] = lfsr.next_short ();
+
+  enter_SEARCHING ();
+}
+
+int
+gr_check_lfsr_32k_s::work (int noutput_items,
+                          gr_vector_const_void_star &input_items,
+                          gr_vector_void_star &output_items)
+{
+  unsigned short *in = (unsigned short *) input_items[0];
+
+  for (int i = 0; i < noutput_items; i++){
+    unsigned short     x = in[i];
+    unsigned short     expected;
+    
+    switch (d_state){
+
+    case MATCH0:
+      if (x == d_buffer[0])
+       enter_MATCH1 ();
+      break;
+      
+    case MATCH1:
+      if (x == d_buffer[1])
+       enter_MATCH2 ();
+      else
+       enter_MATCH0 ();
+      break;
+      
+    case MATCH2:
+      if (x == d_buffer[2])
+       enter_LOCKED ();
+      else
+       enter_MATCH0 ();
+      break;
+
+    case LOCKED:
+      expected = d_buffer[d_index];
+      d_index = d_index + 1;
+      if (d_index >= BUFSIZE)
+       d_index = 0;
+
+      if (x == expected)
+       right ();
+      else {
+       wrong ();
+       log_error (expected, x);
+       if (wrong_three_times ())
+         enter_SEARCHING ();
+      }
+      break;
+
+    default:
+      abort ();
+    }
+
+    d_ntotal++;
+  }
+
+  return noutput_items;
+}
+
+void
+gr_check_lfsr_32k_s::enter_SEARCHING ()
+{
+  d_state = SEARCHING;
+  wrong ();                    // reset history
+  wrong ();
+  wrong ();
+
+  d_runlength = 0;
+  d_index = 0;                 // reset LFSR to beginning
+
+  if (0)
+    fprintf (stdout, "gr_check_lfsr_32k: enter_SEARCHING at offset %8ld (0x%08lx)\n",
+            d_ntotal, d_ntotal);
+
+  enter_MATCH0 ();
+}
+
+void
+gr_check_lfsr_32k_s::enter_MATCH0 ()
+{
+  d_state = MATCH0;
+}
+
+void
+gr_check_lfsr_32k_s::enter_MATCH1 ()
+{
+  d_state = MATCH1;
+}
+
+void
+gr_check_lfsr_32k_s::enter_MATCH2 ()
+{
+  d_state = MATCH2;
+}
+
+void
+gr_check_lfsr_32k_s::enter_LOCKED ()
+{
+  d_state = LOCKED;
+  right ();                    // setup history
+  right ();
+  right ();
+
+  d_index = 3;                 // already matched first 3 items
+
+  if (0)
+    fprintf (stdout, "gr_check_lfsr_32k: enter_LOCKED at offset %8ld (0x%08lx)\n",
+            d_ntotal, d_ntotal);
+}
+
+void
+gr_check_lfsr_32k_s::log_error (unsigned short expected, unsigned short actual)
+{
+  if (0)
+    fprintf (stdout, 
+     "gr_check_lfsr_32k: expected %5d (0x%04x) got %5d (0x%04x) offset %8ld (0x%08lx)\n",
+            expected, expected, actual, actual, d_ntotal, d_ntotal);
+}
diff --git a/gnuradio-core/src/lib/general/gr_check_lfsr_32k_s.h b/gnuradio-core/src/lib/general/gr_check_lfsr_32k_s.h
new file mode 100644 (file)
index 0000000..4b7eb8a
--- /dev/null
@@ -0,0 +1,102 @@
+/* -*- 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 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.
+ */
+#ifndef INCLUDED_GR_CHECK_LFSR_32K_S_H
+#define INCLUDED_GR_CHECK_LFSR_32K_S_H
+
+#include <gr_sync_block.h>
+#include <gri_lfsr_32k.h>
+
+
+class gr_check_lfsr_32k_s;
+typedef boost::shared_ptr<gr_check_lfsr_32k_s> gr_check_lfsr_32k_s_sptr;
+
+gr_check_lfsr_32k_s_sptr gr_make_check_lfsr_32k_s ();
+
+/*!
+ * \brief sink that checks if its input stream consists of a lfsr_32k sequence.
+ * \ingroup sink
+ *
+ * This sink is typically used along with gr_lfsr_32k_source_s to test
+ * the USRP using its digital loopback mode.
+ */
+class gr_check_lfsr_32k_s : public gr_sync_block
+{
+  friend gr_check_lfsr_32k_s_sptr gr_make_check_lfsr_32k_s ();
+
+  enum state {
+    SEARCHING,         // searching for synchronization
+    MATCH0,
+    MATCH1,
+    MATCH2,
+    LOCKED             // is locked
+  };
+
+  state                        d_state;
+  unsigned int         d_history;              // bitmask of decisions
+  
+  long                 d_ntotal;               // total number of shorts
+  long                 d_nright;               // # of correct shorts
+  long                 d_runlength;            // # of correct shorts in a row
+
+  static const int BUFSIZE = 2048 - 1;         // ensure pattern isn't packet aligned
+  int                  d_index;
+  unsigned short       d_buffer[BUFSIZE];
+
+
+  gr_check_lfsr_32k_s ();
+  
+  void enter_SEARCHING ();
+  void enter_MATCH0 ();
+  void enter_MATCH1 ();
+  void enter_MATCH2 ();
+  void enter_LOCKED ();
+
+  void right (){
+    d_history = (d_history << 1) | 0x1;
+    d_nright++;
+    d_runlength++;
+  }
+  
+  void wrong (){
+    d_history = (d_history << 1) | 0x0;
+    d_runlength = 0;
+  }
+
+  bool right_three_times () { return (d_history & 0x7) == 0x7; }
+  bool wrong_three_times () { return (d_history & 0x7) == 0x0; }
+
+  void log_error (unsigned short expected, unsigned short actual);
+
+ public:
+
+  int work (int noutput_items,
+           gr_vector_const_void_star &input_items,
+           gr_vector_void_star &output_items);
+
+  long ntotal () const { return d_ntotal; }
+  long nright () const { return d_nright; }
+  long runlength () const { return d_runlength; }
+
+};
+
+
+#endif /* INCLUDED_GR_CHECK_LFSR_32K_S_H */
diff --git a/gnuradio-core/src/lib/general/gr_check_lfsr_32k_s.i b/gnuradio-core/src/lib/general/gr_check_lfsr_32k_s.i
new file mode 100644 (file)
index 0000000..422b7cd
--- /dev/null
@@ -0,0 +1,36 @@
+/* -*- 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 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.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,check_lfsr_32k_s)
+
+gr_check_lfsr_32k_s_sptr gr_make_check_lfsr_32k_s ();
+
+class gr_check_lfsr_32k_s : public gr_sync_block
+{
+ private:
+  gr_check_lfsr_32k_s ();
+
+public:
+  long ntotal () const;
+  long nright () const;
+  long runlength () const;
+};
diff --git a/gnuradio-core/src/lib/general/gr_chunks_to_symbols_XX.cc.t b/gnuradio-core/src/lib/general/gr_chunks_to_symbols_XX.cc.t
new file mode 100644 (file)
index 0000000..a488733
--- /dev/null
@@ -0,0 +1,73 @@
+/* -*- 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 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.
+ */
+
+// @WARNING@
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <@NAME@.h>
+#include <gr_io_signature.h>
+#include <assert.h>
+#include <iostream>
+
+@SPTR_NAME@
+gr_make_@BASE_NAME@ (const std::vector<@O_TYPE@> &symbol_table, const int D)
+{
+  return @SPTR_NAME@ (new @NAME@ (symbol_table,D));
+}
+
+@NAME@::@NAME@ (const std::vector<@O_TYPE@> &symbol_table, const int D)
+  : gr_sync_interpolator ("@BASE_NAME@",
+                         gr_make_io_signature (1, -1, sizeof (@I_TYPE@)),
+                         gr_make_io_signature (1, -1, sizeof (@O_TYPE@)),
+                         D),
+  d_D (D),
+  d_symbol_table (symbol_table)
+{
+}
+
+int
+@NAME@::work (int noutput_items,
+                       gr_vector_const_void_star &input_items,
+                       gr_vector_void_star &output_items)
+{
+  assert (noutput_items % d_D == 0);
+  assert (input_items.size() == output_items.size());
+  int nstreams = input_items.size();
+
+  for (int m=0;m<nstreams;m++) {
+    const @I_TYPE@ *in = (@I_TYPE@ *) input_items[m];
+    @O_TYPE@ *out = (@O_TYPE@ *) output_items[m];
+
+    // per stream processing
+    for (int i = 0; i < noutput_items / d_D; i++){
+      assert (((unsigned int)in[i]*d_D) < d_symbol_table.size());
+      memcpy(out, &d_symbol_table[(unsigned int)in[i]*d_D], d_D*sizeof(@O_TYPE@));
+      out+=d_D;
+    }
+    // end of per stream processing
+
+  }
+  return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_chunks_to_symbols_XX.h.t b/gnuradio-core/src/lib/general/gr_chunks_to_symbols_XX.h.t
new file mode 100644 (file)
index 0000000..16763c9
--- /dev/null
@@ -0,0 +1,72 @@
+/* -*- 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 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.
+ */
+
+// @WARNING@
+
+#ifndef @GUARD_NAME@
+#define @GUARD_NAME@
+
+#include <gr_sync_interpolator.h>
+
+class @NAME@;
+typedef boost::shared_ptr<@NAME@> @SPTR_NAME@;
+
+@SPTR_NAME@ gr_make_@BASE_NAME@ (const std::vector<@O_TYPE@> &symbol_table, const int D = 1);
+
+/*!
+ * \brief Map a stream of symbol indexes (unpacked bytes or shorts) to stream of float or complex onstellation points.in \p D dimensions (\p D = 1 by default)
+ * \ingroup block
+ *
+ * input: stream of @I_TYPE@; output: stream of @O_TYPE@
+ *
+ * out[n D + k] = symbol_table[in[n] D + k], k=0,1,...,D-1
+ *
+ * The combination of gr_packed_to_unpacked_XX followed by
+ * gr_chunks_to_symbols_XY handles the general case of mapping 
+ * from a stream of bytes or shorts into arbitrary float
+ * or complex symbols.
+ *
+ * \sa gr_packed_to_unpacked_bb, gr_unpacked_to_packed_bb,
+ * \sa gr_packed_to_unpacked_ss, gr_unpacked_to_packed_ss,
+ * \sa gr_chunks_to_symbols_bf, gr_chunks_to_symbols_bc.
+ * \sa gr_chunks_to_symbols_sf, gr_chunks_to_symbols_sc.
+ */
+
+class @NAME@ : public gr_sync_interpolator
+{
+  friend @SPTR_NAME@ gr_make_@BASE_NAME@ (const std::vector<@O_TYPE@> &symbol_table, const int D);
+
+  int d_D;
+  std::vector<@O_TYPE@> d_symbol_table;
+  @NAME@ (const std::vector<@O_TYPE@> &symbol_table, const int D = 1);
+
+ public:
+  int D () const { return d_D; }
+  std::vector<@O_TYPE@> symbol_table () const { return d_symbol_table; }
+  int work (int noutput_items,
+           gr_vector_const_void_star &input_items,
+           gr_vector_void_star &output_items);
+
+  bool check_topology(int ninputs, int noutputs) { return ninputs == noutputs; }
+};
+
+#endif
diff --git a/gnuradio-core/src/lib/general/gr_chunks_to_symbols_XX.i.t b/gnuradio-core/src/lib/general/gr_chunks_to_symbols_XX.i.t
new file mode 100644 (file)
index 0000000..e67e480
--- /dev/null
@@ -0,0 +1,37 @@
+/* -*- 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 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.
+ */
+
+// @WARNING@
+
+GR_SWIG_BLOCK_MAGIC(gr,@BASE_NAME@);
+
+@SPTR_NAME@ gr_make_@BASE_NAME@ (const std::vector<@O_TYPE@> &symbol_table, const int D = 1);
+
+class @NAME@ : public gr_sync_interpolator
+{
+private:
+  @NAME@ (const std::vector<@O_TYPE@> &symbol_table, const int D = 1);
+
+public:
+  int D () const { return d_D; }
+  std::vector<@O_TYPE@> symbol_table () const { return d_symbol_table; }
+};
diff --git a/gnuradio-core/src/lib/general/gr_circular_file.cc b/gnuradio-core/src/lib/general/gr_circular_file.cc
new file mode 100644 (file)
index 0000000..8aa8af0
--- /dev/null
@@ -0,0 +1,194 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <gr_circular_file.h>
+
+#include <unistd.h>
+#ifdef HAVE_SYS_MMAN_H
+#include <sys/mman.h>
+#endif
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <assert.h>
+#include <stdlib.h>
+
+#include <algorithm>
+
+static const int HEADER_SIZE = 4096;
+static const int HEADER_MAGIC = 0xEB021026;
+
+static const int HD_MAGIC = 0;
+static const int HD_HEADER_SIZE = 1;   // integer offsets into header
+static const int HD_BUFFER_SIZE = 2;
+static const int HD_BUFFER_BASE = 3;
+static const int HD_BUFFER_CURRENT = 4;
+
+gr_circular_file::gr_circular_file (const char *filename,
+                                   bool writable, int size)
+  : d_fd (-1), d_header (0), d_buffer (0), d_mapped_size (0), d_bytes_read (0)
+{
+  int  mm_prot;
+  if (writable){
+#ifdef HAVE_MMAP
+    mm_prot = PROT_READ | PROT_WRITE;
+#endif
+    d_fd = open (filename, O_CREAT | O_RDWR | O_TRUNC, 0664);
+    if (d_fd < 0){
+      perror (filename);
+      exit (1);
+    }
+#ifdef HAVE_MMAP       /* FIXME */
+    ftruncate (d_fd, size + HEADER_SIZE);
+#endif
+  }
+  else {
+#ifdef HAVE_MMAP
+    mm_prot = PROT_READ;
+#endif
+    d_fd = open (filename, O_RDONLY);
+    if (d_fd < 0){
+      perror (filename);
+      exit (1);
+    }
+  }
+
+  struct stat statbuf;
+  if (fstat (d_fd, &statbuf) < 0){
+    perror (filename);
+    exit (1);
+  }
+
+  if (statbuf.st_size < HEADER_SIZE){
+    fprintf (stderr, "%s: file too small to be circular buffer\n", filename);
+    exit (1);
+  }
+
+  d_mapped_size = statbuf.st_size;
+#ifdef HAVE_MMAP
+  void *p = mmap (0, d_mapped_size, mm_prot, MAP_SHARED, d_fd, 0);
+  if (p == MAP_FAILED){
+    perror ("gr_circular_file: mmap failed");
+    exit (1);
+  }
+
+  d_header = (int *) p;
+#else
+    perror ("gr_circular_file: mmap unsupported by this system");
+    exit (1);
+#endif
+
+  if (writable){               // init header
+
+    if (size < 0){
+      fprintf (stderr, "gr_circular_buffer: size must be > 0 when writable\n");
+      exit (1);
+    }
+
+    d_header[HD_MAGIC] = HEADER_MAGIC;
+    d_header[HD_HEADER_SIZE] = HEADER_SIZE;
+    d_header[HD_BUFFER_SIZE] = size;
+    d_header[HD_BUFFER_BASE] = HEADER_SIZE;    // right after header
+    d_header[HD_BUFFER_CURRENT] = 0;
+  }
+
+  // sanity check (the asserts are a bit unforgiving...)
+
+  assert (d_header[HD_MAGIC] == HEADER_MAGIC);
+  assert (d_header[HD_HEADER_SIZE] == HEADER_SIZE);
+  assert (d_header[HD_BUFFER_SIZE] > 0);
+  assert (d_header[HD_BUFFER_BASE] >= d_header[HD_HEADER_SIZE]);
+  assert (d_header[HD_BUFFER_BASE] + d_header[HD_BUFFER_SIZE] <= d_mapped_size);
+  assert (d_header[HD_BUFFER_CURRENT] >= 0 &&
+         d_header[HD_BUFFER_CURRENT] < d_header[HD_BUFFER_SIZE]);
+
+  d_bytes_read = 0;
+  d_buffer = (unsigned char *) d_header + d_header[HD_BUFFER_BASE];
+}
+
+gr_circular_file::~gr_circular_file ()
+{
+#ifdef HAVE_MMAP
+  if (munmap ((char *) d_header, d_mapped_size) < 0){
+    perror ("gr_circular_file: munmap");
+    exit (1);
+  }
+#endif
+  close (d_fd);
+}
+
+bool
+gr_circular_file::write (void *vdata, int nbytes)
+{
+  unsigned char *data = (unsigned char *) vdata;
+  int  buffer_size = d_header[HD_BUFFER_SIZE];
+  int  buffer_current = d_header[HD_BUFFER_CURRENT];
+  
+  while (nbytes > 0){
+    int n = std::min (nbytes, buffer_size - buffer_current);
+    memcpy (d_buffer + buffer_current, data, n);
+    
+    buffer_current += n;
+    if (buffer_current >= buffer_size)
+      buffer_current = 0;
+    
+    data += n;
+    nbytes -= n;
+  }
+
+  d_header[HD_BUFFER_CURRENT] = buffer_current;
+  return true;
+}
+
+int
+gr_circular_file::read (void *vdata, int nbytes)
+{
+  unsigned char *data = (unsigned char *) vdata;
+  int  buffer_current = d_header[HD_BUFFER_CURRENT];
+  int  buffer_size = d_header[HD_BUFFER_SIZE];
+  int  total = 0;
+  
+  nbytes = std::min (nbytes, buffer_size - d_bytes_read);
+
+  while (nbytes > 0){
+    int offset = (buffer_current + d_bytes_read) % buffer_size;
+    int n = std::min (nbytes, buffer_size - offset);
+    memcpy (data, d_buffer + offset, n);
+    data += n;
+    d_bytes_read += n;
+    total += n;
+    nbytes -= n;
+  }
+  return total;
+}
+
+void
+gr_circular_file::reset_read_pointer ()
+{
+  d_bytes_read = 0;
+}
diff --git a/gnuradio-core/src/lib/general/gr_circular_file.h b/gnuradio-core/src/lib/general/gr_circular_file.h
new file mode 100644 (file)
index 0000000..3340745
--- /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 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.
+ */
+
+#ifndef _GR_CIRCULAR_FILE_H_
+#define _GR_CIRCULAR_FILE_H_
+
+/*
+ * writes input data into a circular buffer on disk.
+ *
+ * the file contains a fixed header:
+ *   0x0000:    int32 magic (0xEB021026)
+ *   0x0004:   int32 size in bytes of header (constant 4096)
+ *   0x0008:   int32 size in bytes of circular buffer (not including header)
+ *   0x000C:    int32 file offset to beginning of circular buffer
+ *   0x0010:    int32 byte offset from beginning of circular buffer to 
+ *                   current start of data
+ *
+ */
+class gr_circular_file {
+  int           d_fd;
+  int          *d_header;
+  unsigned char        *d_buffer;
+  int           d_mapped_size;
+  int           d_bytes_read;
+
+public:
+  gr_circular_file (const char *filename, bool writable = false, int size = 0);
+  ~gr_circular_file ();
+
+  bool write (void *data, int nbytes);
+
+  // returns # of bytes actually read or 0 if end of buffer, or -1 on error.
+  int read (void *data, int nbytes);
+
+  // reset read pointer to beginning of buffer.
+  void reset_read_pointer ();
+};
+
+#endif /* _GR_CIRCULAR_FILE_H_ */
diff --git a/gnuradio-core/src/lib/general/gr_clock_recovery_mm_cc.cc b/gnuradio-core/src/lib/general/gr_clock_recovery_mm_cc.cc
new file mode 100644 (file)
index 0000000..0d8c7f3
--- /dev/null
@@ -0,0 +1,182 @@
+/* -*- c++ -*- */
+/*
+ * 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_io_signature.h>
+#include <gr_prefs.h>
+#include <gr_clock_recovery_mm_cc.h>
+#include <gri_mmse_fir_interpolator_cc.h>
+#include <stdexcept>
+
+// Public constructor
+
+
+gr_clock_recovery_mm_cc_sptr 
+gr_make_clock_recovery_mm_cc(float omega, float gain_omega, float mu, float gain_mu,
+                            float omega_relative_limit)
+{
+  return gr_clock_recovery_mm_cc_sptr (new gr_clock_recovery_mm_cc (omega, 
+                                                                   gain_omega, 
+                                                                   mu,
+                                                                   gain_mu,
+                                                                   omega_relative_limit));
+}
+
+gr_clock_recovery_mm_cc::gr_clock_recovery_mm_cc (float omega, float gain_omega, float mu, 
+                                                 float gain_mu, float omega_relative_limit)
+  : gr_block ("clock_recovery_mm_cc",
+             gr_make_io_signature (1, 1, sizeof (gr_complex)),
+             gr_make_io_signature (1, 1, sizeof (gr_complex))),
+    d_mu (mu), d_omega(omega), d_gain_omega(gain_omega), 
+    d_omega_relative_limit(omega_relative_limit), 
+    d_gain_mu(gain_mu), d_last_sample(0), d_interp(new gri_mmse_fir_interpolator_cc()),
+    d_verbose(gr_prefs::singleton()->get_bool("clock_recovery_mm_cc", "verbose", false)),
+    d_p_2T(0), d_p_1T(0), d_p_0T(0), d_c_2T(0), d_c_1T(0), d_c_0T(0)
+{
+  if (omega <= 0.0)
+    throw std::out_of_range ("clock rate must be > 0");
+  if (gain_mu <  0  || gain_omega < 0)
+    throw std::out_of_range ("Gains must be non-negative");
+
+  set_omega(omega);                    // also sets min and max omega
+  set_relative_rate (1.0 / omega);
+  set_history(3);                      // ensure 2 extra input sample is available
+}
+
+gr_clock_recovery_mm_cc::~gr_clock_recovery_mm_cc ()
+{
+  delete d_interp;
+}
+
+void
+gr_clock_recovery_mm_cc::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] =
+      (int) ceil((noutput_items * d_omega) + d_interp->ntaps());
+}
+
+gr_complex
+gr_clock_recovery_mm_cc::slicer_0deg (gr_complex sample)
+{
+  float real=0, imag=0;
+
+  if(sample.real() > 0)
+    real = 1;
+  if(sample.imag() > 0)
+    imag = 1;
+  return gr_complex(real,imag);
+}
+
+gr_complex
+gr_clock_recovery_mm_cc::slicer_45deg (gr_complex sample)
+{
+  float real= -1, imag = -1;
+  if(sample.real() > 0)
+    real=1;
+  if(sample.imag() > 0)
+    imag = 1;
+  return gr_complex(real,imag);
+}
+
+/*
+  Modified Mueller and Muller clock recovery circuit
+  Based:
+     G. R. Danesfahani, T.G. Jeans, "Optimisation of modified Mueller and Muller 
+     algorithm,"  Electronics Letters, Vol. 31, no. 13,  22 June 1995, pp. 1032 - 1033.
+*/
+
+static const int FUDGE = 16;
+
+int
+gr_clock_recovery_mm_cc::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];
+  gr_complex *out = (gr_complex *) output_items[0];
+  
+  int  ii = 0;                         // input index
+  int  oo = 0;                         // output index
+  int  ni = ninput_items[0] - d_interp->ntaps() - FUDGE;  // don't use more input than this
+
+  assert(d_mu >= 0.0);
+  assert(d_mu <= 1.0);
+
+  float mm_val=0;
+  gr_complex u, x, y;
+
+  while(oo < noutput_items && ii < ni) {
+    d_p_2T = d_p_1T;
+    d_p_1T = d_p_0T;
+    d_p_0T = d_interp->interpolate (&in[ii], d_mu);
+
+    d_c_2T = d_c_1T;
+    d_c_1T = d_c_0T;
+    d_c_0T = slicer_0deg(d_p_0T);
+
+    x = (d_c_0T - d_c_2T) * conj(d_p_1T);
+    y = (d_p_0T - d_p_2T) * conj(d_c_1T);
+    u = y - x;
+    mm_val = u.real();
+    out[oo++] = d_p_0T;
+
+    // limit mm_val
+    if (mm_val > 1.0)
+      mm_val = 1.0;
+    else if (mm_val < -1.0)
+      mm_val = -1.0;
+
+    d_omega = d_omega + d_gain_omega * mm_val;
+    if (d_omega > d_max_omega)
+      d_omega = d_max_omega;
+    else if (d_omega < d_min_omega)
+      d_omega = d_min_omega;
+
+    d_mu = d_mu + d_omega + d_gain_mu * mm_val;
+    ii += (int)floor(d_mu);
+    d_mu -= floor(d_mu);
+
+    if(d_verbose) {
+      printf("%f\t%f\n", d_omega, d_mu);
+    }
+
+    if (ii < 0)        // clamp it.  This should only happen with bogus input
+      ii = 0;
+  }
+
+  if (ii > 0){
+    if (ii > ninput_items[0]){
+      fprintf(stderr, "gr_clock_recovery_mm_cc: ii > ninput_items[0] (%d > %d)\n",
+             ii, ninput_items[0]);
+      assert(0);
+    }
+    consume_each (ii);
+  }
+
+  return oo;
+}
diff --git a/gnuradio-core/src/lib/general/gr_clock_recovery_mm_cc.h b/gnuradio-core/src/lib/general/gr_clock_recovery_mm_cc.h
new file mode 100644 (file)
index 0000000..8a65ae4
--- /dev/null
@@ -0,0 +1,105 @@
+/* -*- 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 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.
+ */
+
+#ifndef INCLUDED_GR_CLOCK_RECOVERY_MM_CC_H
+#define        INCLUDED_GR_CLOCK_RECOVERY_MM_CC_H
+
+#include <gr_block.h>
+#include <gr_complex.h>
+
+class gri_mmse_fir_interpolator_cc;
+
+class gr_clock_recovery_mm_cc;
+typedef boost::shared_ptr<gr_clock_recovery_mm_cc> gr_clock_recovery_mm_cc_sptr;
+
+// public constructor
+gr_clock_recovery_mm_cc_sptr 
+gr_make_clock_recovery_mm_cc (float omega, float gain_omega, float mu, float gain_mu,
+                             float omega_relative_limit=0.001);
+
+/*!
+ * \brief Mueller and Müller (M&M) based clock recovery block with complex input, complex output.
+ * \ingroup block
+ *
+ * This implements the Mueller and Müller (M&M) discrete-time error-tracking synchronizer.
+ *
+ * See "Digital Communication Receivers: Synchronization, Channel
+ * Estimation and Signal Processing" by Heinrich Meyr, Marc Moeneclaey, & Stefan Fechtel.
+ * ISBN 0-471-50275-8.
+ */
+class gr_clock_recovery_mm_cc : public gr_block
+{
+ public:
+  ~gr_clock_recovery_mm_cc ();
+  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);
+  float mu() const { return d_mu;}
+  float omega() const { return d_omega;}
+  float gain_mu() const { return d_gain_mu;}
+  float gain_omega() const { return d_gain_omega;}
+  void set_verbose (bool verbose) { d_verbose = verbose; }
+
+  void set_gain_mu (float gain_mu) { d_gain_mu = gain_mu; }
+  void set_gain_omega (float gain_omega) { d_gain_omega = gain_omega; }
+  void set_mu (float mu) { d_mu = mu; }
+  void set_omega (float omega) { 
+    d_omega = omega;
+    d_min_omega = omega*(1.0 - d_omega_relative_limit);
+    d_max_omega = omega*(1.0 + d_omega_relative_limit);
+  }
+
+protected:
+  gr_clock_recovery_mm_cc (float omega, float gain_omega, float mu, float gain_mu,
+                          float omega_relative_limi);
+
+ private:
+  float                        d_mu;
+  float                        d_omega;
+  float                         d_gain_omega;
+  float                                d_min_omega;            // minimum allowed omega
+  float                                d_max_omega;            // maximum allowed omeg
+  float                                d_omega_relative_limit; // used to compute min and max omega
+  float                         d_gain_mu;
+  gr_complex                    d_last_sample;
+  gri_mmse_fir_interpolator_cc         *d_interp;
+  bool                         d_verbose;
+
+  gr_complex                    d_p_2T;
+  gr_complex                    d_p_1T;
+  gr_complex                    d_p_0T;
+
+  gr_complex                    d_c_2T;
+  gr_complex                    d_c_1T;
+  gr_complex                    d_c_0T;
+
+  gr_complex slicer_0deg (gr_complex sample);
+  gr_complex slicer_45deg (gr_complex sample);
+
+  friend gr_clock_recovery_mm_cc_sptr
+  gr_make_clock_recovery_mm_cc (float omega, float gain_omega, float mu, float gain_mu, 
+                               float omega_relative_limit);
+};
+
+#endif
diff --git a/gnuradio-core/src/lib/general/gr_clock_recovery_mm_cc.i b/gnuradio-core/src/lib/general/gr_clock_recovery_mm_cc.i
new file mode 100644 (file)
index 0000000..4db01af
--- /dev/null
@@ -0,0 +1,49 @@
+/* -*- 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 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.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,clock_recovery_mm_cc);
+
+gr_clock_recovery_mm_cc_sptr gr_make_clock_recovery_mm_cc (float omega, float gain_omega, 
+                                                          float mu, float gain_mu,
+                                                          float omega_relative_limit);
+
+class gr_clock_recovery_mm_cc : public gr_sync_block
+{
+ private:
+  gr_clock_recovery_mm_cc (float omega, float gain_omega, float mu, 
+                          float gain_mu, float omega_relative_limit);
+
+public:
+  float mu() const { return d_mu;}
+  float omega() const { return d_omega;}
+  float gain_mu() const { return d_gain_mu;}
+  float gain_omega() const { return d_gain_omega;}
+
+  void set_gain_mu (float gain_mu) { d_gain_mu = gain_mu; }
+  void set_gain_omega (float gain_omega) { d_gain_omega = gain_omega; }
+  void set_mu (float omega) { d_mu = mu; }
+  void set_omega (float omega) { d_omega = omega; 
+                                 d_min_omega = omega*(1.0 - d_omega_relative_limit);
+                                d_max_omega = omega*(1.0 + d_omega_relative_limit);
+                               }
+  void set_verbose (bool verbose) { d_verbose = verbose; }
+};
diff --git a/gnuradio-core/src/lib/general/gr_clock_recovery_mm_ff.cc b/gnuradio-core/src/lib/general/gr_clock_recovery_mm_ff.cc
new file mode 100644 (file)
index 0000000..1219df7
--- /dev/null
@@ -0,0 +1,140 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_io_signature.h>
+#include <gr_clock_recovery_mm_ff.h>
+#include <gri_mmse_fir_interpolator.h>
+#include <stdexcept>
+
+#define DEBUG_CR_MM_FF 0               // must be defined as 0 or 1
+
+// Public constructor
+
+gr_clock_recovery_mm_ff_sptr 
+gr_make_clock_recovery_mm_ff(float omega, float gain_omega, float mu, float gain_mu,
+                            float omega_relative_limit)
+{
+  return gr_clock_recovery_mm_ff_sptr (new gr_clock_recovery_mm_ff (omega,
+                                                                   gain_omega, 
+                                                                   mu,
+                                                                   gain_mu,
+                                                                   omega_relative_limit));
+}
+
+gr_clock_recovery_mm_ff::gr_clock_recovery_mm_ff (float omega, float gain_omega, float mu, float gain_mu,
+                                                 float omega_relative_limit)
+  : gr_block ("clock_recovery_mm_ff",
+             gr_make_io_signature (1, 1, sizeof (float)),
+             gr_make_io_signature (1, 1, sizeof (float))),
+    d_mu (mu), d_gain_omega(gain_omega), d_gain_mu(gain_mu),
+    d_last_sample(0), d_interp(new gri_mmse_fir_interpolator()),
+    d_logfile(0), d_omega_relative_limit(omega_relative_limit)
+{
+  if (omega <  1)
+    throw std::out_of_range ("clock rate must be > 0");
+  if (gain_mu <  0  || gain_omega < 0)
+    throw std::out_of_range ("Gains must be non-negative");
+
+  set_omega(omega);                    // also sets min and max omega
+  set_relative_rate (1.0 / omega);
+
+  if (DEBUG_CR_MM_FF)
+    d_logfile = fopen("cr_mm_ff.dat", "wb");
+}
+
+gr_clock_recovery_mm_ff::~gr_clock_recovery_mm_ff ()
+{
+  delete d_interp;
+
+  if (DEBUG_CR_MM_FF && d_logfile){
+    fclose(d_logfile);
+    d_logfile = 0;
+  }
+}
+
+void
+gr_clock_recovery_mm_ff::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] =
+      (int) ceil((noutput_items * d_omega) + d_interp->ntaps());
+}
+
+static inline float
+slice(float x)
+{
+  return x < 0 ? -1.0F : 1.0F;
+}
+
+/*
+ * This implements the Mueller and Müller (M&M) discrete-time error-tracking synchronizer.
+ *
+ * See "Digital Communication Receivers: Synchronization, Channel
+ * Estimation and Signal Processing" by Heinrich Meyr, Marc Moeneclaey, & Stefan Fechtel.
+ * ISBN 0-471-50275-8.
+ */
+int
+gr_clock_recovery_mm_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];
+
+  int  ii = 0;                         // input index
+  int          oo = 0;                         // output index
+  float mm_val;
+
+  while (oo < noutput_items){
+
+    // produce output sample
+    out[oo] = d_interp->interpolate (&in[ii], d_mu);
+    mm_val = slice(d_last_sample) * out[oo] - slice(out[oo]) * d_last_sample;
+    d_last_sample = out[oo];
+
+    d_omega = d_omega + d_gain_omega * mm_val;
+    if (d_omega > d_max_omega)
+      d_omega = d_max_omega;
+    else if (d_omega < d_min_omega)
+      d_omega = d_min_omega;
+
+    d_mu = d_mu + d_omega + d_gain_mu * mm_val;
+
+    ii += (int) floor(d_mu);
+    d_mu = d_mu - floor(d_mu);
+    oo++;
+
+    if (DEBUG_CR_MM_FF && d_logfile){
+      fwrite(&d_omega, sizeof(d_omega), 1, d_logfile);
+    }
+  }
+
+  consume_each (ii);
+
+  return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_clock_recovery_mm_ff.h b/gnuradio-core/src/lib/general/gr_clock_recovery_mm_ff.h
new file mode 100644 (file)
index 0000000..e970bcc
--- /dev/null
@@ -0,0 +1,93 @@
+/* -*- 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 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.
+ */
+
+#ifndef INCLUDED_GR_CLOCK_RECOVERY_MM_FF_H
+#define        INCLUDED_GR_CLOCK_RECOVERY_MM_FF_H
+
+#include <gr_block.h>
+#include <stdio.h>
+
+class gri_mmse_fir_interpolator;
+
+class gr_clock_recovery_mm_ff;
+typedef boost::shared_ptr<gr_clock_recovery_mm_ff> gr_clock_recovery_mm_ff_sptr;
+
+// public constructor
+gr_clock_recovery_mm_ff_sptr 
+gr_make_clock_recovery_mm_ff (float omega, float gain_omega, float mu, float gain_mu,
+                             float omega_relative_limit=0.001);
+
+/*!
+ * \brief Mueller and Müller (M&M) based clock recovery block with float input, float output.
+ * \ingroup block
+ *
+ * This implements the Mueller and Müller (M&M) discrete-time error-tracking synchronizer.
+ *
+ * See "Digital Communication Receivers: Synchronization, Channel
+ * Estimation and Signal Processing" by Heinrich Meyr, Marc Moeneclaey, & Stefan Fechtel.
+ * ISBN 0-471-50275-8.
+ */
+class gr_clock_recovery_mm_ff : public gr_block
+{
+ public:
+  ~gr_clock_recovery_mm_ff ();
+  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);
+  float mu() const { return d_mu;}
+  float omega() const { return d_omega;}
+  float gain_mu() const { return d_gain_mu;}
+  float gain_omega() const { return d_gain_omega;}
+
+  void set_gain_mu (float gain_mu) { d_gain_mu = gain_mu; }
+  void set_gain_omega (float gain_omega) { d_gain_omega = gain_omega; }
+  void set_mu (float mu) { d_mu = mu; }
+  void set_omega (float omega){
+    d_omega = omega;
+    d_min_omega = omega*(1.0 - d_omega_relative_limit);
+    d_max_omega = omega*(1.0 + d_omega_relative_limit);
+  }
+
+protected:
+  gr_clock_recovery_mm_ff (float omega, float gain_omega, float mu, float gain_mu,
+                          float omega_relative_limit);
+
+ private:
+  float                        d_mu;           // fractional sample position [0.0, 1.0]
+  float                        d_omega;        // nominal frequency
+  float                                d_min_omega;    // minimum allowed omega
+  float                                d_max_omega;    // maximum allowed omega
+  float                         d_gain_omega;  // gain for adjusting omega
+  float                         d_gain_mu;     // gain for adjusting mu
+  float                         d_last_sample;
+  gri_mmse_fir_interpolator    *d_interp;
+  FILE                         *d_logfile;
+  float                                d_omega_relative_limit; // used to compute min and max omega
+
+  friend gr_clock_recovery_mm_ff_sptr
+  gr_make_clock_recovery_mm_ff (float omega, float gain_omega, float mu, float gain_mu,
+                               float omega_relative_limit);
+};
+
+#endif
diff --git a/gnuradio-core/src/lib/general/gr_clock_recovery_mm_ff.i b/gnuradio-core/src/lib/general/gr_clock_recovery_mm_ff.i
new file mode 100644 (file)
index 0000000..5b7bd45
--- /dev/null
@@ -0,0 +1,45 @@
+/* -*- 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 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.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,clock_recovery_mm_ff);
+
+gr_clock_recovery_mm_ff_sptr gr_make_clock_recovery_mm_ff (float omega, float gain_omega, 
+                                                          float mu, float gain_mu,
+                                                          float omega_relative_limit=0.001);
+
+class gr_clock_recovery_mm_ff : public gr_sync_block
+{
+ private:
+  gr_clock_recovery_mm_ff (float omega, float gain_omega, float mu, float gain_mu,
+                          float omega_relative_limit);
+
+public:
+  float mu() const;
+  float omega() const;
+  float gain_mu() const;
+  float gain_omega() const;
+
+  void set_gain_mu (float gain_mu);
+  void set_gain_omega (float gain_omega);
+  void set_mu (float omega);
+  void set_omega (float omega);
+};
diff --git a/gnuradio-core/src/lib/general/gr_complex_to_interleaved_short.cc b/gnuradio-core/src/lib/general/gr_complex_to_interleaved_short.cc
new file mode 100644 (file)
index 0000000..65fbbe9
--- /dev/null
@@ -0,0 +1,62 @@
+/* -*- c++ -*- */
+/*
+ * 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_complex_to_interleaved_short.h>
+#include <gr_io_signature.h>
+#include <math.h>
+
+gr_complex_to_interleaved_short_sptr
+gr_make_complex_to_interleaved_short ()
+{
+  return gr_complex_to_interleaved_short_sptr (new gr_complex_to_interleaved_short ());
+}
+
+gr_complex_to_interleaved_short::gr_complex_to_interleaved_short ()
+  : gr_sync_interpolator ("gr_complex_to_interleaved_short",
+                         gr_make_io_signature (1, 1, sizeof (gr_complex)),
+                         gr_make_io_signature (1, 1, sizeof (short)),
+                         2)
+{
+}
+
+int
+gr_complex_to_interleaved_short::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];
+  short *out = (short *) output_items[0];
+
+  for (int i = 0; i < noutput_items/2; i++){
+    *out++ = (short) lrintf(in[i].real());     // FIXME saturate?
+    *out++ = (short) lrintf(in[i].imag());
+  }
+  
+  return noutput_items;
+}
+
+
+
diff --git a/gnuradio-core/src/lib/general/gr_complex_to_interleaved_short.h b/gnuradio-core/src/lib/general/gr_complex_to_interleaved_short.h
new file mode 100644 (file)
index 0000000..1afca56
--- /dev/null
@@ -0,0 +1,51 @@
+/* -*- 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 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.
+ */
+
+#ifndef INCLUDED_GR_COMPLEX_TO_INTERLEAVED_SHORT_H
+#define INCLUDED_GR_COMPLEX_TO_INTERLEAVED_SHORT_H
+
+#include <gr_sync_interpolator.h>
+
+class gr_complex_to_interleaved_short;
+typedef boost::shared_ptr<gr_complex_to_interleaved_short>
+  gr_complex_to_interleaved_short_sptr;
+
+gr_complex_to_interleaved_short_sptr
+gr_make_complex_to_interleaved_short ();
+
+/*!
+ * \brief Convert stream of complex to a stream of interleaved shorts
+ * \ingroup converter
+ */
+
+class gr_complex_to_interleaved_short : public gr_sync_interpolator
+{
+  friend gr_complex_to_interleaved_short_sptr gr_make_complex_to_interleaved_short ();
+  gr_complex_to_interleaved_short ();
+
+ public:
+  virtual int work (int noutput_items,
+                   gr_vector_const_void_star &input_items,
+                   gr_vector_void_star &output_items);
+};
+
+#endif /* INCLUDED_GR_COMPLEX_TO_INTERLEAVED_SHORT_H */
diff --git a/gnuradio-core/src/lib/general/gr_complex_to_interleaved_short.i b/gnuradio-core/src/lib/general/gr_complex_to_interleaved_short.i
new file mode 100644 (file)
index 0000000..1b4b6ba
--- /dev/null
@@ -0,0 +1,30 @@
+/* -*- 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 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.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,complex_to_interleaved_short)
+
+gr_complex_to_interleaved_short_sptr gr_make_complex_to_interleaved_short ();
+
+class gr_complex_to_interleaved_short : public gr_sync_interpolator
+{
+  gr_complex_to_interleaved_short ();
+};
diff --git a/gnuradio-core/src/lib/general/gr_complex_to_xxx.cc b/gnuradio-core/src/lib/general/gr_complex_to_xxx.cc
new file mode 100644 (file)
index 0000000..727f44f
--- /dev/null
@@ -0,0 +1,199 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_complex_to_xxx.h>
+#include <gr_io_signature.h>
+
+// ----------------------------------------------------------------
+
+gr_complex_to_float_sptr
+gr_make_complex_to_float (unsigned int vlen)
+{
+  return gr_complex_to_float_sptr (new gr_complex_to_float (vlen));
+}
+
+gr_complex_to_float::gr_complex_to_float (unsigned int vlen)
+  : gr_sync_block ("complex_to_float",
+                  gr_make_io_signature (1, 1, sizeof (gr_complex) * vlen),
+                  gr_make_io_signature (1, 2, sizeof (float) * vlen)),
+    d_vlen(vlen)
+{
+}
+
+int
+gr_complex_to_float::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 *out0 = (float *) output_items[0];
+  float *out1 = (float *) output_items[1];
+  int noi = noutput_items * d_vlen;
+
+  switch (output_items.size ()){
+  case 1:
+    for (int i = 0; i < noi; i++){
+      out0[i] = in[i].real ();
+    }
+    break;
+
+  case 2:
+    for (int i = 0; i < noi; i++){
+      out0[i] = in[i].real ();
+      out1[i] = in[i].imag ();
+    }
+    break;
+
+  default:
+    abort ();
+  }
+
+  return noutput_items;
+}
+
+// ----------------------------------------------------------------
+
+gr_complex_to_real_sptr
+gr_make_complex_to_real (unsigned int vlen)
+{
+  return gr_complex_to_real_sptr (new gr_complex_to_real (vlen));
+}
+
+gr_complex_to_real::gr_complex_to_real (unsigned int vlen)
+  : gr_sync_block ("complex_to_real",
+                  gr_make_io_signature (1, 1, sizeof (gr_complex) * vlen),
+                  gr_make_io_signature (1, 1, sizeof (float) * vlen)),
+    d_vlen(vlen)
+{
+}
+
+int
+gr_complex_to_real::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];
+  int noi = noutput_items * d_vlen;
+
+  for (int i = 0; i < noi; i++){
+    out[i] = in[i].real ();
+  }
+  return noutput_items;
+}
+
+// ----------------------------------------------------------------
+
+gr_complex_to_imag_sptr
+gr_make_complex_to_imag (unsigned int vlen)
+{
+  return gr_complex_to_imag_sptr (new gr_complex_to_imag (vlen));
+}
+
+gr_complex_to_imag::gr_complex_to_imag (unsigned int vlen)
+  : gr_sync_block ("complex_to_imag",
+                  gr_make_io_signature (1, 1, sizeof (gr_complex) * vlen),
+                  gr_make_io_signature (1, 1, sizeof (float) * vlen)),
+    d_vlen(vlen)
+{
+}
+
+int
+gr_complex_to_imag::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];
+  int noi = noutput_items * d_vlen;
+
+  for (int i = 0; i < noi; i++){
+    out[i] = in[i].imag ();
+  }
+  return noutput_items;
+}
+
+// ----------------------------------------------------------------
+
+gr_complex_to_mag_sptr
+gr_make_complex_to_mag (unsigned int vlen)
+{
+  return gr_complex_to_mag_sptr (new gr_complex_to_mag (vlen));
+}
+
+gr_complex_to_mag::gr_complex_to_mag (unsigned int vlen)
+  : gr_sync_block ("complex_to_mag",
+                  gr_make_io_signature (1, 1, sizeof (gr_complex) * vlen),
+                  gr_make_io_signature (1, 1, sizeof (float) * vlen)),
+    d_vlen(vlen)
+{
+}
+
+int
+gr_complex_to_mag::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];
+  int noi = noutput_items * d_vlen;
+
+  for (int i = 0; i < noi; i++){
+    out[i] = std::abs (in[i]);
+  }
+  return noutput_items;
+}
+
+// ----------------------------------------------------------------
+
+gr_complex_to_arg_sptr
+gr_make_complex_to_arg (unsigned int vlen)
+{
+  return gr_complex_to_arg_sptr (new gr_complex_to_arg (vlen));
+}
+
+gr_complex_to_arg::gr_complex_to_arg (unsigned int vlen)
+  : gr_sync_block ("complex_to_arg",
+                  gr_make_io_signature (1, 1, sizeof (gr_complex) * vlen),
+                  gr_make_io_signature (1, 1, sizeof (float) * vlen)),
+    d_vlen(vlen)
+{
+}
+
+int
+gr_complex_to_arg::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];
+  int noi = noutput_items * d_vlen;
+
+  for (int i = 0; i < noi; i++){
+    out[i] = std::arg (in[i]);
+  }
+  return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_complex_to_xxx.h b/gnuradio-core/src/lib/general/gr_complex_to_xxx.h
new file mode 100644 (file)
index 0000000..02a9fc8
--- /dev/null
@@ -0,0 +1,137 @@
+/* -*- 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 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.
+ */
+
+#ifndef INCLUDED_GR_COMPLEX_TO_XXX_H
+#define INCLUDED_GR_COMPLEX_TO_XXX_H
+
+#include <gr_sync_block.h>
+#include <gr_complex.h>
+
+class gr_complex_to_float;
+class gr_complex_to_real;
+class gr_complex_to_imag;
+class gr_complex_to_mag;
+class gr_complex_to_arg;
+
+typedef boost::shared_ptr<gr_complex_to_float> gr_complex_to_float_sptr;
+typedef boost::shared_ptr<gr_complex_to_real> gr_complex_to_real_sptr;
+typedef boost::shared_ptr<gr_complex_to_imag> gr_complex_to_imag_sptr;
+typedef boost::shared_ptr<gr_complex_to_mag> gr_complex_to_mag_sptr;
+typedef boost::shared_ptr<gr_complex_to_arg> gr_complex_to_arg_sptr;
+
+gr_complex_to_float_sptr gr_make_complex_to_float (unsigned int vlen=1);
+gr_complex_to_real_sptr gr_make_complex_to_real (unsigned int vlen=1);
+gr_complex_to_imag_sptr gr_make_complex_to_imag (unsigned int vlen=1);
+gr_complex_to_mag_sptr gr_make_complex_to_mag (unsigned int vlen=1);
+gr_complex_to_arg_sptr gr_make_complex_to_arg (unsigned int vlen=1);
+
+/*!
+ * \brief convert a stream of gr_complex to 1 or 2 streams of float
+ * \ingroup converter
+ * \param vlen vector len (default 1)
+ */
+class gr_complex_to_float : public gr_sync_block
+{
+  friend gr_complex_to_float_sptr gr_make_complex_to_float (unsigned int vlen);
+  gr_complex_to_float (unsigned int vlen);
+
+  unsigned int d_vlen;
+
+ public:
+  virtual int work (int noutput_items,
+                   gr_vector_const_void_star &input_items,
+                   gr_vector_void_star &output_items);
+};
+
+/*!
+ * \brief complex in, real out (float)
+ * \ingroup converter
+ * \param vlen vector len (default 1)
+ */
+class gr_complex_to_real : public gr_sync_block
+{
+  friend gr_complex_to_real_sptr gr_make_complex_to_real (unsigned int vlen);
+  gr_complex_to_real (unsigned int vlen);
+
+  unsigned int d_vlen;
+
+ public:
+  virtual int work (int noutput_items,
+                   gr_vector_const_void_star &input_items,
+                   gr_vector_void_star &output_items);
+};
+
+/*!
+ * \brief complex in, imaginary out (float)
+ * \ingroup converter
+ * \param vlen vector len (default 1)
+ */
+class gr_complex_to_imag : public gr_sync_block
+{
+  friend gr_complex_to_imag_sptr gr_make_complex_to_imag (unsigned int vlen);
+  gr_complex_to_imag (unsigned int vlen);
+
+  unsigned int d_vlen;
+
+ public:
+  virtual int work (int noutput_items,
+                   gr_vector_const_void_star &input_items,
+                   gr_vector_void_star &output_items);
+};
+
+/*!
+ * \brief complex in, magnitude out (float)
+ * \ingroup converter
+ * \param vlen vector len (default 1)
+ */
+class gr_complex_to_mag : public gr_sync_block
+{
+  friend gr_complex_to_mag_sptr gr_make_complex_to_mag (unsigned int vlen);
+  gr_complex_to_mag (unsigned int vlen);
+
+  unsigned int d_vlen;
+
+ public:
+  virtual int work (int noutput_items,
+                   gr_vector_const_void_star &input_items,
+                   gr_vector_void_star &output_items);
+};
+
+/*!
+ * \brief complex in, angle out (float) 
+ * \ingroup converter
+ * \param vlen vector len (default 1)
+ */
+class gr_complex_to_arg : public gr_sync_block
+{
+  friend gr_complex_to_arg_sptr gr_make_complex_to_arg (unsigned int vlen);
+  gr_complex_to_arg (unsigned int vlen);
+
+  unsigned int d_vlen;
+
+ public:
+  virtual int work (int noutput_items,
+                   gr_vector_const_void_star &input_items,
+                   gr_vector_void_star &output_items);
+};
+
+#endif /* INCLUDED_GR_COMPLEX_TO_XXX_H */
diff --git a/gnuradio-core/src/lib/general/gr_complex_to_xxx.i b/gnuradio-core/src/lib/general/gr_complex_to_xxx.i
new file mode 100644 (file)
index 0000000..06f1020
--- /dev/null
@@ -0,0 +1,57 @@
+/* -*- 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 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.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,complex_to_float);
+gr_complex_to_float_sptr gr_make_complex_to_float (unsigned int vlen=1);
+class gr_complex_to_float : public gr_sync_block
+{
+  gr_complex_to_float (unsigned int vlen);
+};
+
+GR_SWIG_BLOCK_MAGIC(gr,complex_to_real);
+gr_complex_to_real_sptr gr_make_complex_to_real (unsigned int vlen=1);
+class gr_complex_to_real : public gr_sync_block
+{
+  gr_complex_to_real (unsigned int vlen);
+};
+
+GR_SWIG_BLOCK_MAGIC(gr,complex_to_imag);
+gr_complex_to_imag_sptr gr_make_complex_to_imag (unsigned int vlen=1);
+class gr_complex_to_imag : public gr_sync_block
+{
+  gr_complex_to_imag (unsigned int vlen);
+}
+  ;
+GR_SWIG_BLOCK_MAGIC(gr,complex_to_mag);
+gr_complex_to_mag_sptr gr_make_complex_to_mag (unsigned int vlen=1);
+class gr_complex_to_mag : public gr_sync_block
+{
+  gr_complex_to_mag (unsigned int vlen);
+};
+
+GR_SWIG_BLOCK_MAGIC(gr,complex_to_arg);
+gr_complex_to_arg_sptr gr_make_complex_to_arg (unsigned int vlen=1);
+class gr_complex_to_arg : public gr_sync_block
+{
+  gr_complex_to_arg (unsigned int vlen);
+};
+
diff --git a/gnuradio-core/src/lib/general/gr_conjugate_cc.cc b/gnuradio-core/src/lib/general/gr_conjugate_cc.cc
new file mode 100644 (file)
index 0000000..50e25ef
--- /dev/null
@@ -0,0 +1,71 @@
+/* -*- 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 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.
+ */
+
+// WARNING: this file is machine generated.  Edits will be over written
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_conjugate_cc.h>
+#include <gr_io_signature.h>
+
+gr_conjugate_cc_sptr
+gr_make_conjugate_cc ()
+{
+  return gr_conjugate_cc_sptr (new gr_conjugate_cc ());
+}
+
+gr_conjugate_cc::gr_conjugate_cc ()
+  : gr_sync_block ("conjugate_cc",
+                  gr_make_io_signature (1, 1, sizeof (gr_complex)),
+                  gr_make_io_signature (1, 1, sizeof (gr_complex)))
+{
+}
+
+int
+gr_conjugate_cc::work (int noutput_items,
+                  gr_vector_const_void_star &input_items,
+                  gr_vector_void_star &output_items)
+{
+  gr_complex *iptr = (gr_complex *) input_items[0];
+  gr_complex *optr = (gr_complex *) output_items[0];
+
+  int  size = noutput_items;
+
+  while (size >= 8){
+    *optr++ = gr_complex(real(*iptr),-imag(*iptr));iptr++;
+    *optr++ = gr_complex(real(*iptr),-imag(*iptr));iptr++;
+    *optr++ = gr_complex(real(*iptr),-imag(*iptr));iptr++;
+    *optr++ = gr_complex(real(*iptr),-imag(*iptr));iptr++;
+    *optr++ = gr_complex(real(*iptr),-imag(*iptr));iptr++;
+    *optr++ = gr_complex(real(*iptr),-imag(*iptr));iptr++;
+    *optr++ = gr_complex(real(*iptr),-imag(*iptr));iptr++;
+    *optr++ = gr_complex(real(*iptr),-imag(*iptr));iptr++;
+    size -= 8;
+  }
+
+  while (size-- > 0)
+    *optr++ = gr_complex(real(*iptr),-imag(*iptr));iptr++;
+  
+  return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_conjugate_cc.h b/gnuradio-core/src/lib/general/gr_conjugate_cc.h
new file mode 100644 (file)
index 0000000..f1551b8
--- /dev/null
@@ -0,0 +1,51 @@
+/* -*- 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 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.
+ */
+
+// WARNING: this file is machine generated.  Edits will be over written
+
+#ifndef INCLUDED_GR_CONJUGATE_CC_H
+#define INCLUDED_GR_CONJUGATE_CC_H
+
+#include <gr_sync_block.h>
+
+class gr_conjugate_cc;
+typedef boost::shared_ptr<gr_conjugate_cc> gr_conjugate_cc_sptr;
+
+gr_conjugate_cc_sptr gr_make_conjugate_cc ();
+
+/*!
+ * \brief output = complex conjugate of input
+ * \ingroup block
+ */
+class gr_conjugate_cc : public gr_sync_block
+{
+  friend gr_conjugate_cc_sptr gr_make_conjugate_cc ();
+
+  gr_conjugate_cc ();
+
+ public:
+  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_conjugate_cc.i b/gnuradio-core/src/lib/general/gr_conjugate_cc.i
new file mode 100644 (file)
index 0000000..efafa84
--- /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 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.
+ */
+
+// WARNING: this file is machine generated.  Edits will be over written
+
+GR_SWIG_BLOCK_MAGIC(gr,conjugate_cc)
+
+gr_conjugate_cc_sptr gr_make_conjugate_cc ();
+
+class gr_conjugate_cc : public gr_sync_block
+{
+ private:
+  gr_conjugate_cc ();
+};
diff --git a/gnuradio-core/src/lib/general/gr_constellation_decoder_cb.cc b/gnuradio-core/src/lib/general/gr_constellation_decoder_cb.cc
new file mode 100644 (file)
index 0000000..5b4f719
--- /dev/null
@@ -0,0 +1,113 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_constellation_decoder_cb.h>
+#include <gr_io_signature.h>
+#include <stdexcept>
+
+#include <iostream>
+using std::cout;
+using std::endl;
+
+static const bool compute_EVM = false;
+
+gr_constellation_decoder_cb_sptr
+gr_make_constellation_decoder_cb (const std::vector<gr_complex> &sym_position, 
+                                 const std::vector<unsigned char> &sym_value_out)
+{
+  return gr_constellation_decoder_cb_sptr 
+               (new gr_constellation_decoder_cb(sym_position, sym_value_out));
+}
+
+gr_constellation_decoder_cb::
+gr_constellation_decoder_cb (const std::vector<gr_complex> &sym_position, 
+                            const std::vector<unsigned char> &sym_value_out)
+  : gr_sync_block ("constellation_decoder_cb",
+                  gr_make_io_signature (1, 1, sizeof (gr_complex)),
+                  gr_make_io_signature (1, 1, sizeof (unsigned char))) 
+{
+  if (!set_constellation(sym_position,sym_value_out))
+    throw std::invalid_argument("constellation_decoder_cb");
+}
+
+
+gr_constellation_decoder_cb::~gr_constellation_decoder_cb(){}
+
+
+bool
+gr_constellation_decoder_cb::set_constellation(const std::vector<gr_complex> &sym_position, 
+                                              const std::vector<unsigned char> &sym_value_out)
+{
+  if (sym_position.size() != sym_value_out.size())
+    return false;
+
+  if (sym_position.size()<1)
+    return false;
+
+  d_sym_position  = sym_position;
+  d_sym_value_out = sym_value_out;     
+  return true;
+}
+
+
+int
+gr_constellation_decoder_cb::work(int noutput_items,
+                                 gr_vector_const_void_star &input_items,
+                                 gr_vector_void_star &output_items)
+{
+  gr_complex const *in = (const gr_complex *) input_items[0];
+  unsigned char *out = (unsigned char *) output_items[0];
+  unsigned int table_size = d_sym_value_out.size();
+  unsigned int min_index = 0;
+  float min_euclid_dist = 0;
+  float euclid_dist = 0;
+  double total_error = 0;
+    
+  for(int i = 0; i < noutput_items; i++){
+    min_euclid_dist = norm(in[i] - d_sym_position[0]); 
+    min_index = 0; 
+    for (unsigned int j = 1; j < table_size; j++){
+      euclid_dist = norm(in[i] - d_sym_position[j]);
+      if (euclid_dist < min_euclid_dist){
+       min_euclid_dist = euclid_dist;
+       min_index = j;
+      }
+    }
+
+    out[i] = d_sym_value_out[min_index];
+
+    if (compute_EVM)
+      total_error += sqrtf(min_euclid_dist);
+  }
+
+  if (compute_EVM){
+    double mean = total_error / noutput_items;
+    double rms = sqrt(mean * mean);
+    fprintf(stderr, "EVM = %8.4f\n", rms);
+  }
+
+  return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_constellation_decoder_cb.h b/gnuradio-core/src/lib/general/gr_constellation_decoder_cb.h
new file mode 100644 (file)
index 0000000..2cc16c5
--- /dev/null
@@ -0,0 +1,61 @@
+/* -*- 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 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.
+ */
+
+#ifndef INCLUDED_GR_CONSTELLATION_DECODER_CB_H
+#define INCLUDED_GR_CONSTELLATION_DECODER_CB_H
+
+#include <gr_sync_block.h>
+#include <vector>
+
+class gr_constellation_decoder_cb;
+typedef boost::shared_ptr<gr_constellation_decoder_cb> gr_constellation_decoder_cb_sptr;
+
+gr_constellation_decoder_cb_sptr 
+       gr_make_constellation_decoder_cb (const std::vector<gr_complex> &sym_position,
+                                         const std::vector<unsigned char> &sym_value_out);
+
+
+class gr_constellation_decoder_cb : public gr_sync_block
+{
+
+ private:
+  std::vector<gr_complex> d_sym_position;
+  std::vector<unsigned char> d_sym_value_out;
+
+  friend gr_constellation_decoder_cb_sptr 
+               gr_make_constellation_decoder_cb (const std::vector<gr_complex> &sym_position,                                                    const std::vector<unsigned char> &sym_value_out);
+  
+  gr_constellation_decoder_cb (const std::vector<gr_complex> &sym_position, 
+                               const std::vector<unsigned char> &sym_value_out);  //constructor
+
+ public:
+  bool set_constellation(const std::vector<gr_complex> &sym_position, 
+                        const std::vector<unsigned char> &sym_value_out);
+
+  ~gr_constellation_decoder_cb();      //destructor
+
+  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_constellation_decoder_cb.i b/gnuradio-core/src/lib/general/gr_constellation_decoder_cb.i
new file mode 100644 (file)
index 0000000..ba1e38f
--- /dev/null
@@ -0,0 +1,43 @@
+/* -*- 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 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.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,constellation_decoder_cb)
+
+gr_constellation_decoder_cb_sptr 
+       gr_make_constellation_decoder_cb (const std::vector<gr_complex> &sym_position, 
+                                          const std::vector<unsigned char> &sym_value_out);
+
+class gr_constellation_decoder_cb : public gr_sync_block
+{
+ private:
+  gr_constellation_decoder_cb (const std::vector<gr_complex> &sym_position, 
+                               const std::vector<unsigned char> &sym_value_out);
+
+  friend gr_constellation_decoder_cb_sptr 
+       gr_make_constellation_decoder_cb (const std::vector<gr_complex> &sym_position,  
+                                          const std::vector<unsigned char> &sym_value_out);
+
+ public:
+  int set_constellation(const std::vector<gr_complex> &sym_position, 
+                        const std::vector<unsigned char> &sym_value_out);
+  ~gr_constellation_decoder_cb();
+};
diff --git a/gnuradio-core/src/lib/general/gr_correlate_access_code_bb.cc b/gnuradio-core/src/lib/general/gr_correlate_access_code_bb.cc
new file mode 100644 (file)
index 0000000..0f25986
--- /dev/null
@@ -0,0 +1,129 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_correlate_access_code_bb.h>
+#include <gr_io_signature.h>
+#include <stdexcept>
+#include <gr_count_bits.h>
+
+#define VERBOSE 0
+
+
+gr_correlate_access_code_bb_sptr
+gr_make_correlate_access_code_bb (const std::string &access_code, int threshold)
+{
+  return gr_correlate_access_code_bb_sptr (new gr_correlate_access_code_bb (access_code, threshold));
+}
+
+
+gr_correlate_access_code_bb::gr_correlate_access_code_bb (
+  const std::string &access_code, int threshold)
+  : gr_sync_block ("correlate_access_code_bb",
+                  gr_make_io_signature (1, 1, sizeof(char)),
+                  gr_make_io_signature (1, 1, sizeof(char))),
+    d_data_reg(0), d_flag_reg(0), d_flag_bit(0), d_mask(0),
+    d_threshold(threshold), d_flip(0)
+
+{
+  if (!set_access_code(access_code)){
+    fprintf(stderr, "gr_correlate_access_code_bb: access_code is > 64 bits\n");
+    throw std::out_of_range ("access_code is > 64 bits");
+  }
+}
+
+gr_correlate_access_code_bb::~gr_correlate_access_code_bb ()
+{
+}
+
+bool
+gr_correlate_access_code_bb::set_access_code(
+  const std::string &access_code)
+{
+  unsigned len = access_code.length(); // # of bytes in string
+  if (len > 64)
+    return false;
+
+  // set len top bits to 1.
+  d_mask = ((~0ULL) >> (64 - len)) << (64 - len);
+
+  d_flag_bit = 1LL << (64 - len);      // Where we or-in new flag values.
+                                        // new data always goes in 0x0000000000000001
+  d_access_code = 0;
+  for (unsigned i=0; i < 64; i++){
+    d_access_code <<= 1;
+    if (i < len)
+      d_access_code |= access_code[i] & 1;     // look at LSB only
+  }
+
+  return true;
+}
+
+int
+gr_correlate_access_code_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++){
+
+    // compute output value
+    unsigned int t = 0;
+
+    t |= d_flip ^ (((d_data_reg >> 63) & 0x1) << 0);
+    t |= ((d_flag_reg >> 63) & 0x1) << 1;      // flag bit
+    out[i] = t;
+    
+    // compute hamming distance between desired access code and current data
+    unsigned long long wrong_bits = 0;
+    unsigned int nwrong = d_threshold+1;
+    int new_flag = 0;
+
+    wrong_bits  = (d_data_reg ^ d_access_code) & d_mask;
+    nwrong = gr_count_bits64(wrong_bits);
+
+    // test for access code with up to threshold errors or its compelement
+    new_flag = (nwrong <= d_threshold) || (nwrong >= (64-d_threshold));
+
+#if 0   
+    if(new_flag) {
+      printf("%llx  ==>  %llx  :  d_flip=%u\n", d_access_code, d_data_reg, d_flip);
+    }
+#endif
+
+    // shift in new data and new flag
+    d_data_reg = (d_data_reg << 1) | (in[i] & 0x1);
+    d_flag_reg = (d_flag_reg << 1);
+    if (new_flag) {
+      d_flag_reg |= d_flag_bit;
+      d_flip = nwrong >= (64-d_threshold);   // flip bits if this is true
+    }
+  }
+
+  return noutput_items;
+}
+  
diff --git a/gnuradio-core/src/lib/general/gr_correlate_access_code_bb.h b/gnuradio-core/src/lib/general/gr_correlate_access_code_bb.h
new file mode 100644 (file)
index 0000000..519258c
--- /dev/null
@@ -0,0 +1,85 @@
+/* -*- c++ -*- */
+/*
+ * 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 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.
+ */
+
+#ifndef INCLUDED_GR_CORRELATE_ACCESS_CODE_BB_H
+#define INCLUDED_GR_CORRELATE_ACCESS_CODE_BB_H
+
+#include <gr_sync_block.h>
+#include <string>
+
+class gr_correlate_access_code_bb;
+typedef boost::shared_ptr<gr_correlate_access_code_bb> gr_correlate_access_code_bb_sptr;
+
+/*!
+ * \param access_code is represented with 1 byte per bit, e.g., "010101010111000100"
+ * \param threshold maximum number of bits that may be wrong
+ */
+gr_correlate_access_code_bb_sptr 
+gr_make_correlate_access_code_bb (const std::string &access_code, int threshold);
+
+/*!
+ * \brief Examine input for specified access code, one bit at a time.
+ * \ingroup block
+ *
+ * input:  stream of bits, 1 bit per input byte (data in LSB)
+ * output: stream of bits, 2 bits per output byte (data in LSB, flag in next higher bit)
+ *
+ * Each output byte contains two valid bits, the data bit, and the
+ * flag bit.  The LSB (bit 0) is the data bit, and is the original
+ * input data, delayed 64 bits.  Bit 1 is the
+ * flag bit and is 1 if the corresponding data bit is the first data
+ * bit following the access code. Otherwise the flag bit is 0.
+ */
+class gr_correlate_access_code_bb : public gr_sync_block
+{
+  friend gr_correlate_access_code_bb_sptr 
+  gr_make_correlate_access_code_bb (const std::string &access_code, int threshold);
+ private:
+  unsigned long long d_access_code;    // access code to locate start of packet
+                                        //   access code is left justified in the word
+  unsigned long long d_data_reg;       // used to look for access_code
+  unsigned long long d_flag_reg;       // keep track of decisions
+  unsigned long long d_flag_bit;       // mask containing 1 bit which is location of new flag
+  unsigned long long d_mask;           // masks access_code bits (top N bits are set where
+                                        //   N is the number of bits in the access code)
+  unsigned int      d_threshold;       // how many bits may be wrong in sync vector
+  unsigned int       d_flip;            // flip bits if 180 degress out of sync
+
+
+ protected:
+  gr_correlate_access_code_bb(const std::string &access_code, int threshold);
+
+ public:
+  ~gr_correlate_access_code_bb();
+
+  int work(int noutput_items,
+          gr_vector_const_void_star &input_items,
+          gr_vector_void_star &output_items);
+
+  
+  /*!
+   * \param access_code is represented with 1 byte per bit, e.g., "010101010111000100"
+   */
+  bool set_access_code (const std::string &access_code);
+};
+
+#endif /* INCLUDED_GR_CORRELATE_ACCESS_CODE_BB_H */
diff --git a/gnuradio-core/src/lib/general/gr_correlate_access_code_bb.i b/gnuradio-core/src/lib/general/gr_correlate_access_code_bb.i
new file mode 100644 (file)
index 0000000..688f3f6
--- /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 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.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,correlate_access_code_bb);
+
+/*!
+ * \param access_code is represented with 1 byte per bit, e.g., "010101010111000100"
+ * \param threshold maximum number of bits that may be wrong
+ */
+gr_correlate_access_code_bb_sptr 
+gr_make_correlate_access_code_bb (const std::string &access_code, int threshold) 
+  throw(std::out_of_range);
+
+/*!
+ * \brief Examine input for specified access code, one bit at a time.
+ * \ingroup block
+ *
+ * input:  stream of bits, 1 bit per input byte (data in LSB)
+ * output: stream of bits, 2 bits per output byte (data in LSB, flag in next higher bit)
+ *
+ * Each output byte contains two valid bits, the data bit, and the
+ * flag bit.  The LSB (bit 0) is the data bit, and is the original
+ * input data, delayed 64 bits.  Bit 1 is the
+ * flag bit and is 1 if the corresponding data bit is the first data
+ * bit following the access code. Otherwise the flag bit is 0.
+ */
+class gr_correlate_access_code_bb : public gr_sync_block
+{
+  friend gr_correlate_access_code_bb_sptr 
+  gr_make_correlate_access_code_bb (const std::string &access_code, int threshold);
+ protected:
+  gr_correlate_access_code_bb(const std::string &access_code, int threshold);
+
+ public:
+  ~gr_correlate_access_code_bb();
+
+  /*!
+   * \param access_code is represented with 1 byte per bit, e.g., "010101010111000100"
+   */
+  bool set_access_code (const std::string &access_code);
+};
diff --git a/gnuradio-core/src/lib/general/gr_costas_loop_cc.cc b/gnuradio-core/src/lib/general/gr_costas_loop_cc.cc
new file mode 100644 (file)
index 0000000..4ad627f
--- /dev/null
@@ -0,0 +1,118 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_costas_loop_cc.h>
+#include <gr_io_signature.h>
+#include <gr_expj.h>
+#include <gr_sincos.h>
+#include <math.h>
+
+#define M_TWOPI (2*M_PI)
+
+gr_costas_loop_cc_sptr
+gr_make_costas_loop_cc (float alpha, float beta,
+                       float max_freq, float min_freq,
+                       int order
+                       ) throw (std::invalid_argument)
+{
+  return gr_costas_loop_cc_sptr (new gr_costas_loop_cc (alpha, beta,
+                                                       max_freq, min_freq,
+                                                       order));
+}
+
+gr_costas_loop_cc::gr_costas_loop_cc (float alpha, float beta,
+                                     float max_freq, float min_freq,
+                                     int order
+                                     ) throw (std::invalid_argument)
+  : gr_sync_block ("costas_loop_cc",
+                  gr_make_io_signature (1, 1, sizeof (gr_complex)),
+                  gr_make_io_signature (1, 1, sizeof (gr_complex))),
+    d_alpha(alpha), d_beta(beta), 
+    d_max_freq(max_freq), d_min_freq(min_freq),
+    d_phase(0), d_freq((max_freq+min_freq)/2),
+    d_order(order), d_phase_detector(0)
+{
+  switch(d_order) {
+  case 2:
+    d_phase_detector = &gr_costas_loop_cc::phase_detector_2;
+    break;
+
+  case 4:
+    d_phase_detector = &gr_costas_loop_cc::phase_detector_4;
+    break;
+
+  default: 
+    throw std::invalid_argument("order must be 2 or 4");
+    break;
+  }
+}
+
+
+float
+gr_costas_loop_cc::phase_detector_4(gr_complex sample) const
+{
+
+  return ((sample.real()>0 ? 1.0 : -1.0) * sample.imag() -
+         (sample.imag()>0 ? 1.0 : -1.0) * sample.real());
+}
+
+float
+gr_costas_loop_cc::phase_detector_2(gr_complex sample) const
+{
+  return (sample.real()*sample.imag());
+}
+
+int
+gr_costas_loop_cc::work (int noutput_items,
+                        gr_vector_const_void_star &input_items,
+                        gr_vector_void_star &output_items)
+{
+  const gr_complex *iptr = (gr_complex *) input_items[0];
+  gr_complex *optr = (gr_complex *) output_items[0];
+
+  float error;
+  gr_complex nco_out;
+
+  for (int i = 0; i < noutput_items; i++){
+    nco_out = gr_expj(-d_phase);
+    optr[i] = iptr[i] * nco_out;
+    
+    error = (*this.*d_phase_detector)(optr[i]);
+    
+    d_freq = d_freq + d_beta * error;
+    d_phase = d_phase + d_freq + d_alpha * error;
+    while(d_phase>M_TWOPI)
+      d_phase -= M_TWOPI;
+    while(d_phase<-M_TWOPI)
+      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;
+  }
+  return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_costas_loop_cc.h b/gnuradio-core/src/lib/general/gr_costas_loop_cc.h
new file mode 100644 (file)
index 0000000..4672c09
--- /dev/null
@@ -0,0 +1,72 @@
+/* -*- 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 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.
+ */
+
+
+#ifndef INCLUDED_GR_COSTAS_LOOP_CC_H
+#define INCLUDED_GR_COSTAS_LOOP_CC_H
+
+#include <gr_sync_block.h>
+#include <stdexcept>
+
+class gr_costas_loop_cc;
+typedef boost::shared_ptr<gr_costas_loop_cc> gr_costas_loop_cc_sptr;
+
+gr_costas_loop_cc_sptr 
+gr_make_costas_loop_cc (float alpha, float beta,
+                       float max_freq, float min_freq, 
+                       int order
+                       ) throw (std::invalid_argument);
+
+
+/*!
+ * \brief Carrier tracking PLL for QPSK
+ * input: complex; output: complex
+ *
+ * \p order must be 2 or 4.
+ */
+class gr_costas_loop_cc : public gr_sync_block
+{
+  friend gr_costas_loop_cc_sptr gr_make_costas_loop_cc (float alpha, float beta,
+                                                       float max_freq, float min_freq, 
+                                                       int order
+                                                       ) throw (std::invalid_argument);
+
+  float d_alpha, d_beta, d_max_freq, d_min_freq, d_phase, d_freq;
+  int d_order;
+
+  gr_costas_loop_cc (float alpha, float beta,
+                    float max_freq, float min_freq, 
+                    int order
+                    ) throw (std::invalid_argument);
+
+  float phase_detector_4(gr_complex sample) const;    // for QPSK
+  float phase_detector_2(gr_complex sample) const;    // for BPSK
+  float (gr_costas_loop_cc::*d_phase_detector)(gr_complex sample) const;
+
+public:
+
+  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_costas_loop_cc.i b/gnuradio-core/src/lib/general/gr_costas_loop_cc.i
new file mode 100644 (file)
index 0000000..85d2ada
--- /dev/null
@@ -0,0 +1,37 @@
+/* -*- c++ -*- */
+/*
+ * 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 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.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,costas_loop_cc);
+
+gr_costas_loop_cc_sptr
+gr_make_costas_loop_cc (float alpha, float beta, 
+                       float max_freq, float min_freq,
+                       int order
+                       ) throw (std::invalid_argument);
+
+
+class gr_costas_loop_cc : public gr_sync_block
+{
+ private:
+  gr_costas_loop_cc (float alpha, float beta,
+                    float max_freq, float min_freq, int order);
+};
diff --git a/gnuradio-core/src/lib/general/gr_count_bits.cc b/gnuradio-core/src/lib/general/gr_count_bits.cc
new file mode 100644 (file)
index 0000000..cd51ce8
--- /dev/null
@@ -0,0 +1,93 @@
+/* -*- 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 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.
+ */
+
+#include <gr_count_bits.h>
+
+/*
+ * these are slow and obvious.  If you need something faster, fix these
+ */
+
+// return number of set bits in the low  8 bits of x
+unsigned int 
+gr_count_bits8 (unsigned int x)
+{
+  int  count = 0;
+
+  for (int i = 0; i < 8; i++)
+    if (x & (1 << i))
+      count++;
+
+  return count;
+}
+
+// return number of set bits in the low 16 bits of x
+unsigned int 
+gr_count_bits16 (unsigned int x)
+{
+  int  count = 0;
+
+  for (int i = 0; i < 16; i++)
+    if (x & (1 << i))
+      count++;
+
+  return count;
+
+}
+
+
+#if 0  // slow and obvious
+
+// return number of set bits in the low 32 bits of x
+unsigned int 
+gr_count_bits32 (unsigned int x)
+{
+  int  count = 0;
+
+  for (int i = 0; i < 32; i++)
+    if (x & (1 << i))
+      count++;
+
+  return count;
+}
+
+#else  // fast and not so obvious
+
+// return number of set bits in the low 32 bits of x
+unsigned int
+gr_count_bits32 (unsigned int x)
+{
+  unsigned res = (x & 0x55555555) + ((x >> 1) & 0x55555555);
+  res = (res & 0x33333333) + ((res >> 2) & 0x33333333);
+  res = (res & 0x0F0F0F0F) + ((res >> 4) & 0x0F0F0F0F);
+  res = (res & 0x00FF00FF) + ((res >> 8) & 0x00FF00FF);
+  return (res & 0x0000FFFF) + ((res >> 16) & 0x0000FFFF);
+}
+
+#endif
+
+// return number of set bits in the low 64 bits of x
+unsigned int
+gr_count_bits64 (unsigned long long x)
+{
+  return gr_count_bits32((x >> 32) & 0xffffffff) + gr_count_bits32(x & 0xffffffff);
+}
diff --git a/gnuradio-core/src/lib/general/gr_count_bits.h b/gnuradio-core/src/lib/general/gr_count_bits.h
new file mode 100644 (file)
index 0000000..b0e83c8
--- /dev/null
@@ -0,0 +1,31 @@
+/* -*- 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 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.
+ */
+
+#ifndef _GR_COUNT_BITS_H_
+#define _GR_COUNT_BITS_H_
+
+unsigned int gr_count_bits8(unsigned int x);   // return number of set bits in the low  8 bits of x
+unsigned int gr_count_bits16(unsigned int x);  // return number of set bits in the low 16 bits of x
+unsigned int gr_count_bits32(unsigned int x);  // return number of set bits in the low 32 bits of x
+unsigned int gr_count_bits64(unsigned long long int x);
+
+#endif /* _GR_COUNT_BITS_H_ */
diff --git a/gnuradio-core/src/lib/general/gr_crc32.cc b/gnuradio-core/src/lib/general/gr_crc32.cc
new file mode 100644 (file)
index 0000000..3b0ebd4
--- /dev/null
@@ -0,0 +1,130 @@
+/* -*- 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 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.
+ */
+
+/*
+ * See also ISO 3309 [ISO-3309] or ITU-T V.42 [ITU-V42] for a formal specification.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <gr_crc32.h>
+
+   
+// Automatically generated CRC function
+// polynomial: 0x104C11DB7
+unsigned int
+gr_update_crc32(unsigned int crc, const unsigned char *data, size_t len)
+{
+    static const unsigned int table[256] = {
+    0x00000000U,0x04C11DB7U,0x09823B6EU,0x0D4326D9U,
+    0x130476DCU,0x17C56B6BU,0x1A864DB2U,0x1E475005U,
+    0x2608EDB8U,0x22C9F00FU,0x2F8AD6D6U,0x2B4BCB61U,
+    0x350C9B64U,0x31CD86D3U,0x3C8EA00AU,0x384FBDBDU,
+    0x4C11DB70U,0x48D0C6C7U,0x4593E01EU,0x4152FDA9U,
+    0x5F15ADACU,0x5BD4B01BU,0x569796C2U,0x52568B75U,
+    0x6A1936C8U,0x6ED82B7FU,0x639B0DA6U,0x675A1011U,
+    0x791D4014U,0x7DDC5DA3U,0x709F7B7AU,0x745E66CDU,
+    0x9823B6E0U,0x9CE2AB57U,0x91A18D8EU,0x95609039U,
+    0x8B27C03CU,0x8FE6DD8BU,0x82A5FB52U,0x8664E6E5U,
+    0xBE2B5B58U,0xBAEA46EFU,0xB7A96036U,0xB3687D81U,
+    0xAD2F2D84U,0xA9EE3033U,0xA4AD16EAU,0xA06C0B5DU,
+    0xD4326D90U,0xD0F37027U,0xDDB056FEU,0xD9714B49U,
+    0xC7361B4CU,0xC3F706FBU,0xCEB42022U,0xCA753D95U,
+    0xF23A8028U,0xF6FB9D9FU,0xFBB8BB46U,0xFF79A6F1U,
+    0xE13EF6F4U,0xE5FFEB43U,0xE8BCCD9AU,0xEC7DD02DU,
+    0x34867077U,0x30476DC0U,0x3D044B19U,0x39C556AEU,
+    0x278206ABU,0x23431B1CU,0x2E003DC5U,0x2AC12072U,
+    0x128E9DCFU,0x164F8078U,0x1B0CA6A1U,0x1FCDBB16U,
+    0x018AEB13U,0x054BF6A4U,0x0808D07DU,0x0CC9CDCAU,
+    0x7897AB07U,0x7C56B6B0U,0x71159069U,0x75D48DDEU,
+    0x6B93DDDBU,0x6F52C06CU,0x6211E6B5U,0x66D0FB02U,
+    0x5E9F46BFU,0x5A5E5B08U,0x571D7DD1U,0x53DC6066U,
+    0x4D9B3063U,0x495A2DD4U,0x44190B0DU,0x40D816BAU,
+    0xACA5C697U,0xA864DB20U,0xA527FDF9U,0xA1E6E04EU,
+    0xBFA1B04BU,0xBB60ADFCU,0xB6238B25U,0xB2E29692U,
+    0x8AAD2B2FU,0x8E6C3698U,0x832F1041U,0x87EE0DF6U,
+    0x99A95DF3U,0x9D684044U,0x902B669DU,0x94EA7B2AU,
+    0xE0B41DE7U,0xE4750050U,0xE9362689U,0xEDF73B3EU,
+    0xF3B06B3BU,0xF771768CU,0xFA325055U,0xFEF34DE2U,
+    0xC6BCF05FU,0xC27DEDE8U,0xCF3ECB31U,0xCBFFD686U,
+    0xD5B88683U,0xD1799B34U,0xDC3ABDEDU,0xD8FBA05AU,
+    0x690CE0EEU,0x6DCDFD59U,0x608EDB80U,0x644FC637U,
+    0x7A089632U,0x7EC98B85U,0x738AAD5CU,0x774BB0EBU,
+    0x4F040D56U,0x4BC510E1U,0x46863638U,0x42472B8FU,
+    0x5C007B8AU,0x58C1663DU,0x558240E4U,0x51435D53U,
+    0x251D3B9EU,0x21DC2629U,0x2C9F00F0U,0x285E1D47U,
+    0x36194D42U,0x32D850F5U,0x3F9B762CU,0x3B5A6B9BU,
+    0x0315D626U,0x07D4CB91U,0x0A97ED48U,0x0E56F0FFU,
+    0x1011A0FAU,0x14D0BD4DU,0x19939B94U,0x1D528623U,
+    0xF12F560EU,0xF5EE4BB9U,0xF8AD6D60U,0xFC6C70D7U,
+    0xE22B20D2U,0xE6EA3D65U,0xEBA91BBCU,0xEF68060BU,
+    0xD727BBB6U,0xD3E6A601U,0xDEA580D8U,0xDA649D6FU,
+    0xC423CD6AU,0xC0E2D0DDU,0xCDA1F604U,0xC960EBB3U,
+    0xBD3E8D7EU,0xB9FF90C9U,0xB4BCB610U,0xB07DABA7U,
+    0xAE3AFBA2U,0xAAFBE615U,0xA7B8C0CCU,0xA379DD7BU,
+    0x9B3660C6U,0x9FF77D71U,0x92B45BA8U,0x9675461FU,
+    0x8832161AU,0x8CF30BADU,0x81B02D74U,0x857130C3U,
+    0x5D8A9099U,0x594B8D2EU,0x5408ABF7U,0x50C9B640U,
+    0x4E8EE645U,0x4A4FFBF2U,0x470CDD2BU,0x43CDC09CU,
+    0x7B827D21U,0x7F436096U,0x7200464FU,0x76C15BF8U,
+    0x68860BFDU,0x6C47164AU,0x61043093U,0x65C52D24U,
+    0x119B4BE9U,0x155A565EU,0x18197087U,0x1CD86D30U,
+    0x029F3D35U,0x065E2082U,0x0B1D065BU,0x0FDC1BECU,
+    0x3793A651U,0x3352BBE6U,0x3E119D3FU,0x3AD08088U,
+    0x2497D08DU,0x2056CD3AU,0x2D15EBE3U,0x29D4F654U,
+    0xC5A92679U,0xC1683BCEU,0xCC2B1D17U,0xC8EA00A0U,
+    0xD6AD50A5U,0xD26C4D12U,0xDF2F6BCBU,0xDBEE767CU,
+    0xE3A1CBC1U,0xE760D676U,0xEA23F0AFU,0xEEE2ED18U,
+    0xF0A5BD1DU,0xF464A0AAU,0xF9278673U,0xFDE69BC4U,
+    0x89B8FD09U,0x8D79E0BEU,0x803AC667U,0x84FBDBD0U,
+    0x9ABC8BD5U,0x9E7D9662U,0x933EB0BBU,0x97FFAD0CU,
+    0xAFB010B1U,0xAB710D06U,0xA6322BDFU,0xA2F33668U,
+    0xBCB4666DU,0xB8757BDAU,0xB5365D03U,0xB1F740B4U,
+    };
+  
+    while (len > 0)
+    {
+      crc = table[*data ^ ((crc >> 24) & 0xff)] ^ (crc << 8);
+      data++;
+      len--;
+    }
+    return crc;
+}
+
+unsigned int
+gr_update_crc32(unsigned int crc, const std::string s)
+{
+  return gr_update_crc32(crc, (const unsigned char *) s.data(), s.size());
+}
+    
+unsigned int
+gr_crc32(const unsigned char *buf, size_t len)
+{
+  return gr_update_crc32(0xffffffff, buf, len) ^ 0xffffffff;
+}
+
+unsigned int
+gr_crc32(const std::string s)
+{
+  return gr_crc32((const unsigned char *) s.data(), s.size());
+}
diff --git a/gnuradio-core/src/lib/general/gr_crc32.h b/gnuradio-core/src/lib/general/gr_crc32.h
new file mode 100644 (file)
index 0000000..2d6fdc8
--- /dev/null
@@ -0,0 +1,43 @@
+/* -*- 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 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.
+ */
+
+#ifndef INCLUDED_GR_CRC32_H
+#define INCLUDED_GR_CRC32_H
+
+#include <string>
+#include <gr_types.h>
+
+/*!
+ * \brief update running CRC-32
+ *
+ * Update a running CRC with the bytes buf[0..len-1] The CRC should be
+ * initialized to all 1's, and the transmitted value is the 1's
+ * complement of the final running CRC.  The resulting CRC should be
+ * transmitted in big endian order.
+ */
+unsigned int gr_update_crc32(unsigned int crc, const unsigned char *buf, int len);
+unsigned int gr_update_crc32(unsigned int crc, const std::string buf);
+
+unsigned int gr_crc32(const unsigned char *buf, int len);
+unsigned int gr_crc32(const std::string buf);
+
+#endif /* INCLUDED_CRC32_H */
diff --git a/gnuradio-core/src/lib/general/gr_crc32.i b/gnuradio-core/src/lib/general/gr_crc32.i
new file mode 100644 (file)
index 0000000..79e1d08
--- /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 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.
+ */
+
+%rename(update_crc32) gr_update_crc32;
+%rename(crc32) gr_crc32;
+
+unsigned int gr_update_crc32(unsigned int crc, const std::string buf);
+unsigned int gr_crc32(const std::string buf);
diff --git a/gnuradio-core/src/lib/general/gr_ctcss_squelch_ff.cc b/gnuradio-core/src/lib/general/gr_ctcss_squelch_ff.cc
new file mode 100644 (file)
index 0000000..7ad31cb
--- /dev/null
@@ -0,0 +1,112 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_ctcss_squelch_ff.h>
+
+static float ctcss_tones[] = {
+   67.0,  71.9,  74.4,  77.0,  79.7,  82.5,  85.4,  88.5,  91.5,  94.8, 
+   97.4, 100.0, 103.5, 107.2, 110.9, 114.8, 118.8, 123.0, 127.3, 131.8,
+  136.5, 141.3, 146.2, 151.4, 156.7, 162.2, 167.9, 173.8, 179.9, 186.2, 
+  192.8, 203.5, 210.7, 218.1, 225.7, 233.6, 241.8, 250.3
+};
+
+static int max_tone_index = 37;
+
+gr_ctcss_squelch_ff_sptr
+gr_make_ctcss_squelch_ff(int rate, float freq, float level, int len, int ramp, bool gate)
+{
+  return gr_ctcss_squelch_ff_sptr(new gr_ctcss_squelch_ff(rate, freq, level, len, ramp, gate));
+}
+
+int gr_ctcss_squelch_ff::find_tone(float freq)
+{
+  for (int i = 0; i <= max_tone_index; i++)
+    if (ctcss_tones[i] == freq) // FIXME: make almost equal
+      return i;
+
+  return -1;
+}
+
+gr_ctcss_squelch_ff::gr_ctcss_squelch_ff(int rate, float freq, float level, int len, int ramp, bool gate) : 
+    gr_squelch_base_ff("ctcss_squelch_ff", ramp, gate)
+{
+  d_freq = freq;
+  d_level = level;
+
+  // Default is 100 ms detection time
+  if (len == 0)
+    d_len = (int)(rate/10.0);
+  else
+    d_len = len;
+
+  int i = find_tone(freq);
+
+  // Non-standard tones or edge tones get 2% guard band, otherwise
+  // guards are set at adjacent ctcss tone frequencies
+  float f_l, f_r;
+  if (i == -1 || i == 0)
+    f_l = freq*0.98;
+  else
+    f_l = ctcss_tones[i-1];
+    
+  if (i == -1 || i == max_tone_index)
+    f_r = freq*1.02;
+  else
+    f_r = ctcss_tones[i+1];
+
+  d_goertzel_l = gri_goertzel(rate, d_len, f_l);
+  d_goertzel_c = gri_goertzel(rate, d_len, freq);
+  d_goertzel_r = gri_goertzel(rate, d_len, f_r);
+
+  d_mute = true;
+}
+
+std::vector<float> gr_ctcss_squelch_ff::squelch_range() const
+{
+  std::vector<float> r(3);
+  r[0] = 0.0;
+  r[1] = 1.0;
+  r[2] = (r[1]-r[0])/100; // step size
+
+  return r;
+}
+
+void gr_ctcss_squelch_ff::update_state(const float &in)
+{
+  d_goertzel_l.input(in);
+  d_goertzel_c.input(in);
+  d_goertzel_r.input(in);
+
+  float d_out_l, d_out_c, d_out_r;
+  if (d_goertzel_c.ready()) {
+      d_out_l = abs(d_goertzel_l.output());
+      d_out_c = abs(d_goertzel_c.output());
+      d_out_r = abs(d_goertzel_r.output());
+  
+      //printf("d_out_l=%f d_out_c=%f d_out_r=%f\n", d_out_l, d_out_c, d_out_r);
+      d_mute = (d_out_c < d_level || d_out_c < d_out_l || d_out_c < d_out_r);
+  }
+}
diff --git a/gnuradio-core/src/lib/general/gr_ctcss_squelch_ff.h b/gnuradio-core/src/lib/general/gr_ctcss_squelch_ff.h
new file mode 100644 (file)
index 0000000..337e5ca
--- /dev/null
@@ -0,0 +1,67 @@
+/* -*- 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 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.
+ */
+
+#ifndef INCLUDED_GR_CTCSS_SQUELCH_FF_H
+#define INCLUDED_GR_CTCSS_SQUELCH_FF_H
+
+#include <gr_squelch_base_ff.h>
+#include <gri_goertzel.h>
+
+class gr_ctcss_squelch_ff;
+typedef boost::shared_ptr<gr_ctcss_squelch_ff> gr_ctcss_squelch_ff_sptr;
+
+gr_ctcss_squelch_ff_sptr 
+gr_make_ctcss_squelch_ff(int rate, float freq, float level=0.01, int len=0, int ramp=0, bool gate=false);
+
+/*!
+ * \brief gate or zero output if ctcss tone not present
+ * \ingroup block
+ */
+class gr_ctcss_squelch_ff : public gr_squelch_base_ff
+{
+private:
+  float d_freq;
+  float d_level;
+  int   d_len;
+  bool  d_mute;
+     
+  gri_goertzel d_goertzel_l;
+  gri_goertzel d_goertzel_c;
+  gri_goertzel d_goertzel_r;
+
+  friend gr_ctcss_squelch_ff_sptr gr_make_ctcss_squelch_ff(int rate, float freq, float level, int len, int ramp, bool gate);
+  gr_ctcss_squelch_ff(int rate, float freq, float level, int len, int ramp, bool gate);
+
+  int find_tone(float freq);
+
+protected:
+  virtual void update_state(const float &in);
+  virtual bool mute() const { return d_mute; }
+  
+public:
+  std::vector<float> squelch_range() const;
+  float level() const { return d_level; }
+  void set_level(float level) { d_level = level; }
+  int len() const { return d_len; }
+};
+
+#endif /* INCLUDED_GR_CTCSS_SQUELCH_FF_H */
diff --git a/gnuradio-core/src/lib/general/gr_ctcss_squelch_ff.i b/gnuradio-core/src/lib/general/gr_ctcss_squelch_ff.i
new file mode 100644 (file)
index 0000000..6d32c7d
--- /dev/null
@@ -0,0 +1,39 @@
+/* -*- 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 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.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,ctcss_squelch_ff);
+
+%include gr_squelch_base_ff.i
+
+gr_ctcss_squelch_ff_sptr 
+gr_make_ctcss_squelch_ff(int rate, float freq, float level=0.01, int len=0, int ramp=0, bool gate=false);
+
+class gr_ctcss_squelch_ff : public gr_squelch_base_ff
+{
+  gr_ctcss_squelch_ff(int rate, float freq, float level, int len, int ramp, bool gate);
+
+public:
+  std::vector<float> squelch_range() const;
+  float level() const { return d_level; }
+  void set_level(float level) { d_level = level; }
+  int len() const { return d_len; }
+};
diff --git a/gnuradio-core/src/lib/general/gr_dd_mpsk_sync_cc.cc b/gnuradio-core/src/lib/general/gr_dd_mpsk_sync_cc.cc
new file mode 100644 (file)
index 0000000..1f0bc01
--- /dev/null
@@ -0,0 +1,195 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_dd_mpsk_sync_cc.h>
+#include <gr_io_signature.h>
+#include <gr_sincos.h>
+#include <gri_mmse_fir_interpolator_cc.h>
+#include <math.h>
+#include <stdexcept>
+
+#include <gr_complex.h>
+
+#define M_TWOPI (2*M_PI)
+
+gr_dd_mpsk_sync_cc_sptr
+gr_make_dd_mpsk_sync_cc (float alpha, float beta, float max_freq, float min_freq, float ref_phase,
+                        float omega, float gain_omega, float mu, float gain_mu)
+{
+    return gr_dd_mpsk_sync_cc_sptr (new gr_dd_mpsk_sync_cc (alpha, beta, max_freq, min_freq,ref_phase,
+                                                           omega,gain_omega,mu,gain_mu));
+}
+
+gr_dd_mpsk_sync_cc::gr_dd_mpsk_sync_cc (float alpha, float beta, float max_freq, float min_freq,
+                                       float ref_phase,
+                                       float omega, float gain_omega, float mu, float gain_mu)
+    : gr_block ("dd_mpsk_sync_cc",
+               gr_make_io_signature (1, 1, sizeof (gr_complex)),
+               gr_make_io_signature (1, 1, sizeof (gr_complex))),
+      d_alpha(alpha), d_beta(beta), 
+      d_max_freq(max_freq), d_min_freq(min_freq),
+      d_ref_phase(ref_phase),d_omega(omega), d_gain_omega(gain_omega), 
+      d_mu(mu), d_gain_mu(gain_mu),
+      d_phase(0), d_freq((max_freq+min_freq)/2), d_last_sample(0), 
+      d_interp(new gri_mmse_fir_interpolator_cc()),
+      d_dl_idx(0)
+{
+    if (omega <= 0.0)
+       throw std::out_of_range ("clock rate must be > 0");
+    if (gain_mu <  0  || gain_omega < 0)
+       throw std::out_of_range ("Gains must be non-negative");
+
+    assert(d_interp->ntaps() <= DLLEN);
+
+    // zero double length delay line.
+    for (unsigned int i = 0; i < 2 * DLLEN; i++)
+      d_dl[i] = gr_complex(0.0,0.0);
+}
+
+gr_dd_mpsk_sync_cc::~gr_dd_mpsk_sync_cc()
+{
+    delete d_interp;
+}
+
+float
+gr_dd_mpsk_sync_cc::phase_detector(gr_complex sample,float ref_phase)
+{
+  return ((sample.real()>0 ? 1.0 : -1.0) * sample.imag() -
+         (sample.imag()>0 ? 1.0 : -1.0) * sample.real());
+}
+
+void
+gr_dd_mpsk_sync_cc::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] =
+      (int) ceil((noutput_items * d_omega) + d_interp->ntaps());
+}
+gr_complex
+gr_dd_mpsk_sync_cc::slicer_45deg (gr_complex sample)
+{
+  float real,imag;
+  if(sample.real() > 0)
+    real=1;
+  else
+    real=-1;
+  if(sample.imag() > 0)
+    imag = 1;
+  else
+    imag = -1;
+  return gr_complex(real,imag);
+}
+
+gr_complex
+gr_dd_mpsk_sync_cc::slicer_0deg (gr_complex sample)
+{
+  gr_complex out;
+  if( fabs(sample.real()) > fabs(sample.imag()) ) {
+    if(sample.real() > 0)
+      return gr_complex(1.0,0.0);
+    else
+      return gr_complex(-1.0,0.0);
+  }
+  else {
+    if(sample.imag() > 0)
+      return gr_complex(0.0, 1.0);
+    else
+      return gr_complex(0.0, -1.0);
+  }
+}
+
+int
+gr_dd_mpsk_sync_cc::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 = (gr_complex *) input_items[0];
+  gr_complex *out = (gr_complex *) output_items[0];
+  
+  int ii, oo;
+  ii = 0; oo = 0;
+  
+  float error;
+  float t_imag, t_real;
+  gr_complex nco_out;
+  float mm_val;
+
+  while (oo < noutput_items) {
+    // 
+    // generate an output sample by interpolating between the carrier
+    // tracked samples in the delay line.  d_mu, the fractional
+    // interpolation amount (in [0.0, 1.0]) is controlled by the
+    // symbol timing loop below.
+    //
+    out[oo] = d_interp->interpolate (&d_dl[d_dl_idx], d_mu);
+
+    error = phase_detector(out[oo], d_ref_phase);
+    
+    d_freq = d_freq + d_beta * error;
+    d_phase = d_phase + d_alpha * error;
+    while(d_phase>M_TWOPI)
+      d_phase -= M_TWOPI;
+    while(d_phase<-M_TWOPI)
+      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;
+      
+    mm_val = real(d_last_sample * slicer_0deg(out[oo]) - out[oo] * slicer_0deg(d_last_sample));
+    d_last_sample = out[oo];
+
+    d_omega = d_omega + d_gain_omega * mm_val;
+    d_mu = d_mu + d_omega + d_gain_mu * mm_val;
+    
+    while(d_mu >= 1.0) {
+      //
+      // Generate more carrier tracked samples for the delay line
+      //
+      d_mu -= 1.0;
+      gr_sincosf(d_phase, &t_imag, &t_real);
+      nco_out = gr_complex(t_real, -t_imag);
+      gr_complex new_sample = in[ii] * nco_out;
+
+      d_dl[d_dl_idx] = new_sample;             // overwrite oldest sample
+      d_dl[(d_dl_idx + DLLEN)] = new_sample;   // and second copy
+      d_dl_idx = (d_dl_idx+1) % DLLEN;         // point to the new oldest sample
+      d_phase = d_phase + d_freq;
+      ii++;
+    }
+    oo++;
+    printf("%f\t%f\t%f\t%f\t%f\n",d_mu,d_omega,mm_val,d_freq,d_phase);
+    //printf("%f\t%f\t%f\t%f\t%f\t%f\t%f\n",mple).real(),slicer_0deg(d_last_sample).imag(),mm_val,d_omega,d_mu);
+  }
+
+  assert(ii <= ninput_items[0]);
+
+  consume_each (ii);
+  return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_dd_mpsk_sync_cc.h b/gnuradio-core/src/lib/general/gr_dd_mpsk_sync_cc.h
new file mode 100644 (file)
index 0000000..fdc2561
--- /dev/null
@@ -0,0 +1,92 @@
+/* -*- 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 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.
+ */
+
+#ifndef INCLUDED_GR_DD_MPSK_SYNC_CC_H
+#define INCLUDED_GR_DD_MPSK_SYNC_CC_H
+
+#include <gr_sync_block.h>
+
+class gri_mmse_fir_interpolator_cc;
+
+class gr_dd_mpsk_sync_cc;
+typedef boost::shared_ptr<gr_dd_mpsk_sync_cc> gr_dd_mpsk_sync_cc_sptr;
+
+gr_dd_mpsk_sync_cc_sptr 
+gr_make_dd_mpsk_sync_cc (float alpha, float beta,
+                        float max_freq, float min_freq, float ref_phase,
+                        float omega, float gain_omega, float mu, float gain_mu);
+
+/*!
+ * \brief Decision directed M-PSK synchronous demod 
+ * This block performs joint carrier tracking and symbol timing recovery.
+ *
+ * input: complex baseband; output: properly timed complex samples ready for slicing.
+ *
+ * N.B, at this point, it handles only QPSK.
+ */
+
+class gr_dd_mpsk_sync_cc : public gr_block
+{
+  friend gr_dd_mpsk_sync_cc_sptr gr_make_dd_mpsk_sync_cc (float alpha, float beta,
+                                                         float max_freq, float min_freq, float ref_phase,
+                                                         float omega, float gain_omega, float mu, float gain_mu);
+public:
+  ~gr_dd_mpsk_sync_cc ();
+  void forecast(int noutput_items, gr_vector_int &ninput_items_required);
+  float mu() const { return d_mu;}
+  float omega() const { return d_omega;}
+  float gain_mu() const { return d_gain_mu;}
+  float gain_omega() const { return d_gain_omega;}
+  
+  void set_gain_mu (float gain_mu) { d_gain_mu = gain_mu; }
+  void set_gain_omega (float gain_omega) { d_gain_omega = gain_omega; }
+  void set_mu (float mu) { d_mu = mu; }
+  void set_omega (float omega) { d_omega = omega; }
+
+protected:
+  gr_dd_mpsk_sync_cc (float alpha, float beta, float max_freq, float min_freq, float ref_phase,
+                     float omega, float gain_omega, float mu, float gain_mu);
+  
+  int general_work (int noutput_items,
+                   gr_vector_int &ninput_items,
+                   gr_vector_const_void_star &input_items,
+                   gr_vector_void_star &output_items);
+  
+private:
+  static const unsigned int DLLEN = 8; // delay line length.
+
+  float d_alpha,d_beta,d_max_freq,d_min_freq,d_ref_phase;
+  float d_omega, d_gain_omega, d_mu, d_gain_mu;
+  float d_phase, d_freq;
+  gr_complex slicer_45deg (gr_complex sample);
+  gr_complex slicer_0deg (gr_complex sample);
+  gr_complex d_last_sample;
+  gri_mmse_fir_interpolator_cc         *d_interp;
+  
+  gr_complex d_dl[2 * DLLEN];  // Holds post carrier tracking samples.
+                                // double length delay line to avoid wraps.
+  unsigned int d_dl_idx;       // indexes oldest sample in delay line.
+
+  float phase_detector(gr_complex sample,float ref_phase);
+};
+
+#endif
diff --git a/gnuradio-core/src/lib/general/gr_dd_mpsk_sync_cc.i b/gnuradio-core/src/lib/general/gr_dd_mpsk_sync_cc.i
new file mode 100644 (file)
index 0000000..3bab9e2
--- /dev/null
@@ -0,0 +1,34 @@
+/* -*- 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 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.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,dd_mpsk_sync_cc)
+
+  gr_dd_mpsk_sync_cc_sptr gr_make_dd_mpsk_sync_cc (float alpha, float beta, 
+                                                  float max_freq, float min_freq, float ref_phase,
+                                                  float omega, float gain_omega, float mu, float gain_mu);
+
+class gr_dd_mpsk_sync_cc : public gr_block
+{
+ private:
+  gr_dd_mpsk_sync_cc (float alpha, float beta, float max_freq, float min_freq, float ref_phase,
+                     float omega, float gain_omega, float mu, float gain_mu);
+};
diff --git a/gnuradio-core/src/lib/general/gr_deinterleave.cc b/gnuradio-core/src/lib/general/gr_deinterleave.cc
new file mode 100644 (file)
index 0000000..375a40d
--- /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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_deinterleave.h>
+#include <gr_io_signature.h>
+#include <string.h>
+
+
+gr_deinterleave_sptr
+gr_make_deinterleave (size_t itemsize)
+{
+  return gr_deinterleave_sptr (new gr_deinterleave (itemsize));
+}
+
+gr_deinterleave::gr_deinterleave (size_t itemsize)
+  : gr_sync_decimator ("deinterleave",
+                      gr_make_io_signature (1, 1, itemsize),
+                      gr_make_io_signature (1, gr_io_signature::IO_INFINITE, itemsize),
+                      1),
+    d_itemsize (itemsize)
+{
+}
+
+gr_deinterleave::~gr_deinterleave ()
+{
+  // NOP
+}
+
+bool
+gr_deinterleave::check_topology (int ninputs, int noutputs)
+{
+  set_decimation (noutputs);
+  return true;
+}
+
+int
+gr_deinterleave::work (int noutput_items,
+                      gr_vector_const_void_star &input_items,
+                      gr_vector_void_star &output_items)
+{
+  size_t nchan = output_items.size ();
+  size_t itemsize = d_itemsize;
+  const char *in = (const char *) input_items[0];
+  char **out = (char **) &output_items[0];
+
+  for (int i = 0; i < noutput_items; i++){
+    for (unsigned int n = 0; n < nchan; n++){
+      memcpy (out[n], in, itemsize);
+      out[n] += itemsize;
+      in += itemsize;
+    }
+  }
+
+  return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_deinterleave.h b/gnuradio-core/src/lib/general/gr_deinterleave.h
new file mode 100644 (file)
index 0000000..0eb9874
--- /dev/null
@@ -0,0 +1,56 @@
+/* -*- 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 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.
+ */
+
+#ifndef INCLUDED_GR_DEINTERLEAVE_H
+#define INCLUDED_GR_DEINTERLEAVE_H
+
+#include <gr_sync_decimator.h>
+
+class gr_deinterleave;
+typedef boost::shared_ptr<gr_deinterleave> gr_deinterleave_sptr;
+
+gr_deinterleave_sptr gr_make_deinterleave (size_t itemsize);
+
+/*!
+ * \brief deinterleave a single input into N outputs
+ * \ingroup block
+ */
+class gr_deinterleave : public gr_sync_decimator
+{
+  friend gr_deinterleave_sptr gr_make_deinterleave (size_t itemsize);
+
+  size_t       d_itemsize;
+
+  gr_deinterleave (size_t itemsize);
+
+public:
+  ~gr_deinterleave ();
+
+  int work (int noutput_items,
+           gr_vector_const_void_star &input_items,
+           gr_vector_void_star &output_items);
+
+  bool check_topology (int ninputs, int noutputs);
+
+};
+
+#endif /* INCLUDED_GR_DEINTERLEAVE_H */
diff --git a/gnuradio-core/src/lib/general/gr_deinterleave.i b/gnuradio-core/src/lib/general/gr_deinterleave.i
new file mode 100644 (file)
index 0000000..f1eac5c
--- /dev/null
@@ -0,0 +1,30 @@
+/* -*- 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 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.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,deinterleave)
+
+gr_deinterleave_sptr gr_make_deinterleave (size_t itemsize);
+
+class gr_deinterleave : public gr_sync_decimator
+{
+  gr_deinterleave (size_t itemsize);
+};
diff --git a/gnuradio-core/src/lib/general/gr_diff_decoder_bb.cc b/gnuradio-core/src/lib/general/gr_diff_decoder_bb.cc
new file mode 100644 (file)
index 0000000..5ab88a9
--- /dev/null
@@ -0,0 +1,61 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_diff_decoder_bb.h>
+#include <gr_io_signature.h>
+
+gr_diff_decoder_bb_sptr
+gr_make_diff_decoder_bb (unsigned int modulus)
+{
+  return gr_diff_decoder_bb_sptr (new gr_diff_decoder_bb(modulus));
+}
+
+gr_diff_decoder_bb::gr_diff_decoder_bb (unsigned int modulus)
+  : gr_sync_block ("diff_decoder_bb",
+                  gr_make_io_signature (1, 1, sizeof (unsigned char)),
+                  gr_make_io_signature (1, 1, sizeof (unsigned char))),
+    d_modulus(modulus)
+{
+  set_history(2);      // need to look at two inputs
+}
+
+int
+gr_diff_decoder_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];
+  in += 1;     // ensure that in[-1] is valid
+
+  unsigned modulus = d_modulus;
+
+  for (int i = 0; i < noutput_items; i++){
+    out[i] = (in[i] - in[i-1]) % modulus;
+  }
+
+  return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_diff_decoder_bb.h b/gnuradio-core/src/lib/general/gr_diff_decoder_bb.h
new file mode 100644 (file)
index 0000000..c88e0e2
--- /dev/null
@@ -0,0 +1,52 @@
+/* -*- 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 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.
+ */
+
+#ifndef INCLUDED_GR_DIFF_DECODER_BB_H
+#define INCLUDED_GR_DIFF_DECODER_BB_H
+
+#include <gr_sync_block.h>
+
+class gr_diff_decoder_bb;
+typedef boost::shared_ptr<gr_diff_decoder_bb> gr_diff_decoder_bb_sptr;
+
+gr_diff_decoder_bb_sptr gr_make_diff_decoder_bb (unsigned int modulus);
+
+/*!
+ * \brief y[0] = (x[0] - x[-1]) % M
+ * \ingroup block
+ *
+ * Differential decoder
+ */
+class gr_diff_decoder_bb : public gr_sync_block
+{
+  friend gr_diff_decoder_bb_sptr gr_make_diff_decoder_bb (unsigned int modulus);
+  gr_diff_decoder_bb(unsigned int modulus);
+
+  unsigned int d_modulus;
+
+ public:
+  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_diff_decoder_bb.i b/gnuradio-core/src/lib/general/gr_diff_decoder_bb.i
new file mode 100644 (file)
index 0000000..b4ad5f6
--- /dev/null
@@ -0,0 +1,31 @@
+/* -*- 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 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.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,diff_decoder_bb)
+
+gr_diff_decoder_bb_sptr gr_make_diff_decoder_bb (unsigned int  modulus);
+
+class gr_diff_decoder_bb : public gr_sync_block
+{
+ private:
+  gr_diff_decoder_bb (unsigned int modulus);
+};
diff --git a/gnuradio-core/src/lib/general/gr_diff_encoder_bb.cc b/gnuradio-core/src/lib/general/gr_diff_encoder_bb.cc
new file mode 100644 (file)
index 0000000..bd4135c
--- /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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_diff_encoder_bb.h>
+#include <gr_io_signature.h>
+
+gr_diff_encoder_bb_sptr
+gr_make_diff_encoder_bb (unsigned int modulus)
+{
+  return gr_diff_encoder_bb_sptr (new gr_diff_encoder_bb(modulus));
+}
+
+gr_diff_encoder_bb::gr_diff_encoder_bb (unsigned int modulus)
+  : gr_sync_block ("diff_encoder_bb",
+                  gr_make_io_signature (1, 1, sizeof (unsigned char)),
+                  gr_make_io_signature (1, 1, sizeof (unsigned char))),
+    d_last_out(0), d_modulus(modulus)
+{
+}
+
+int
+gr_diff_encoder_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];
+
+  unsigned last_out = d_last_out;
+  unsigned modulus = d_modulus;
+
+  for (int i = 0; i < noutput_items; i++){
+    out[i] = (in[i] + last_out) % modulus;
+    last_out = out[i];
+  }
+
+  d_last_out = last_out;
+  return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_diff_encoder_bb.h b/gnuradio-core/src/lib/general/gr_diff_encoder_bb.h
new file mode 100644 (file)
index 0000000..c839d39
--- /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 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.
+ */
+
+#ifndef INCLUDED_GR_DIFF_ENCODER_BB_H
+#define INCLUDED_GR_DIFF_ENCODER_BB_H
+
+#include <gr_sync_block.h>
+
+class gr_diff_encoder_bb;
+typedef boost::shared_ptr<gr_diff_encoder_bb> gr_diff_encoder_bb_sptr;
+
+gr_diff_encoder_bb_sptr gr_make_diff_encoder_bb (unsigned int modulus);
+
+/*!
+ * \brief y[0] = (x[0] + y[-1]) % M
+ * \ingroup block
+ *
+ * Differential encoder
+ */
+class gr_diff_encoder_bb : public gr_sync_block
+{
+  friend gr_diff_encoder_bb_sptr gr_make_diff_encoder_bb (unsigned int modulus);
+  gr_diff_encoder_bb(unsigned int modulus);
+
+  unsigned int d_last_out;
+  unsigned int d_modulus;
+
+ public:
+  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_diff_encoder_bb.i b/gnuradio-core/src/lib/general/gr_diff_encoder_bb.i
new file mode 100644 (file)
index 0000000..890779c
--- /dev/null
@@ -0,0 +1,31 @@
+/* -*- 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 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.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,diff_encoder_bb)
+
+gr_diff_encoder_bb_sptr gr_make_diff_encoder_bb (unsigned int  modulus);
+
+class gr_diff_encoder_bb : public gr_sync_block
+{
+ private:
+  gr_diff_encoder_bb (unsigned int modulus);
+};
diff --git a/gnuradio-core/src/lib/general/gr_diff_phasor_cc.cc b/gnuradio-core/src/lib/general/gr_diff_phasor_cc.cc
new file mode 100644 (file)
index 0000000..c5eae5f
--- /dev/null
@@ -0,0 +1,61 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_diff_phasor_cc.h>
+#include <gr_io_signature.h>
+
+gr_diff_phasor_cc_sptr
+gr_make_diff_phasor_cc ()
+{
+  return gr_diff_phasor_cc_sptr (new gr_diff_phasor_cc());
+}
+
+gr_diff_phasor_cc::gr_diff_phasor_cc ()
+  : gr_sync_block ("diff_phasor_cc",
+                  gr_make_io_signature (1, 1, sizeof (gr_complex)),
+                  gr_make_io_signature (1, 1, sizeof (gr_complex)))    
+{
+  set_history(2);
+}
+
+
+gr_diff_phasor_cc::~gr_diff_phasor_cc(){}
+
+int
+gr_diff_phasor_cc::work (int noutput_items,
+                        gr_vector_const_void_star &input_items,
+                        gr_vector_void_star &output_items)
+{
+  gr_complex const *in = (const gr_complex *) input_items[0];
+  gr_complex *out = (gr_complex *) output_items[0];
+  in += 1; // ensure that i - 1 is valid.
+
+  for(int i = 0; i < noutput_items; i++){
+    out[i] = in[i] * conj(in[i-1]);
+  }
+    
+  return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_diff_phasor_cc.h b/gnuradio-core/src/lib/general/gr_diff_phasor_cc.h
new file mode 100644 (file)
index 0000000..64a3f29
--- /dev/null
@@ -0,0 +1,48 @@
+/* -*- 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 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.
+ */
+
+#ifndef INCLUDED_GR_DIFF_PHASOR_CC_H
+#define INCLUDED_GR_DIFF_PHASOR_CC_H
+
+#include <gr_sync_block.h>
+
+class gr_diff_phasor_cc;
+typedef boost::shared_ptr<gr_diff_phasor_cc> gr_diff_phasor_cc_sptr;
+
+gr_diff_phasor_cc_sptr gr_make_diff_phasor_cc ();
+
+
+class gr_diff_phasor_cc : public gr_sync_block
+{
+  friend gr_diff_phasor_cc_sptr gr_make_diff_phasor_cc ();
+
+  gr_diff_phasor_cc ();  //constructor
+
+ public:
+  ~gr_diff_phasor_cc();        //destructor
+
+  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_diff_phasor_cc.i b/gnuradio-core/src/lib/general/gr_diff_phasor_cc.i
new file mode 100644 (file)
index 0000000..773d276
--- /dev/null
@@ -0,0 +1,34 @@
+/* -*- 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 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.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,diff_phasor_cc)
+
+gr_diff_phasor_cc_sptr gr_make_diff_phasor_cc ();
+
+class gr_diff_phasor_cc : public gr_sync_block
+{
+ private:
+  gr_diff_phasor_cc ();
+
+ public:
+  ~gr_diff_phasor_cc();
+};
diff --git a/gnuradio-core/src/lib/general/gr_divide_XX.cc.t b/gnuradio-core/src/lib/general/gr_divide_XX.cc.t
new file mode 100644 (file)
index 0000000..e85f7b0
--- /dev/null
@@ -0,0 +1,71 @@
+/* -*- 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 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.
+ */
+
+// @WARNING@
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <@NAME@.h>
+#include <gr_io_signature.h>
+
+@SPTR_NAME@
+gr_make_@BASE_NAME@ ()
+{
+  return @SPTR_NAME@ (new @NAME@ ());
+}
+
+@NAME@::@NAME@ ()
+  : gr_sync_block ("@BASE_NAME@",
+                  gr_make_io_signature (1, -1, sizeof (@I_TYPE@)),
+                  gr_make_io_signature (1,  1, sizeof (@O_TYPE@)))
+{
+}
+
+int
+@NAME@::work (int noutput_items,
+                  gr_vector_const_void_star &input_items,
+                  gr_vector_void_star &output_items)
+{
+  @O_TYPE@ *optr = (@O_TYPE@ *) output_items[0];
+
+  int ninputs = input_items.size ();
+
+  if (ninputs == 1){           // compute reciprocal
+    for (int i = 0; i < noutput_items; i++)
+      *optr++ = (@O_TYPE@) ((@O_TYPE@) 1 /
+                           ((@I_TYPE@ *) input_items[0])[i]);
+  }
+
+  else {
+    for (int i = 0; i < noutput_items; i++){
+      @I_TYPE@ acc = ((@I_TYPE@ *) input_items[0])[i];
+      for (int j = 1; j < ninputs; j++)
+       acc /= ((@I_TYPE@ *) input_items[j])[i];
+
+      *optr++ = (@O_TYPE@) acc;
+    }
+  }
+
+  return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_divide_XX.h.t b/gnuradio-core/src/lib/general/gr_divide_XX.h.t
new file mode 100644 (file)
index 0000000..193d6f8
--- /dev/null
@@ -0,0 +1,54 @@
+/* -*- 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 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.
+ */
+
+// @WARNING@
+
+#ifndef @GUARD_NAME@
+#define @GUARD_NAME@
+
+#include <gr_sync_block.h>
+
+class @NAME@;
+typedef boost::shared_ptr<@NAME@> @SPTR_NAME@;
+
+@SPTR_NAME@ gr_make_@BASE_NAME@ ();
+
+/*!
+ * \brief output = input_0 / input_1 / input_x ...)
+ * \ingroup block
+ *
+ * Divide across all input streams.
+ */
+class @NAME@ : public gr_sync_block
+{
+  friend @SPTR_NAME@ gr_make_@BASE_NAME@ ();
+
+  @NAME@ ();
+
+ public:
+
+  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_divide_XX.i.t b/gnuradio-core/src/lib/general/gr_divide_XX.i.t
new file mode 100644 (file)
index 0000000..8479aad
--- /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 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.
+ */
+
+// @WARNING@
+
+GR_SWIG_BLOCK_MAGIC(gr,@BASE_NAME@)
+
+@SPTR_NAME@ gr_make_@BASE_NAME@ ();
+
+class @NAME@ : public gr_sync_block
+{
+ private:
+  @NAME@ ();
+};
diff --git a/gnuradio-core/src/lib/general/gr_endianness.h b/gnuradio-core/src/lib/general/gr_endianness.h
new file mode 100644 (file)
index 0000000..e33af16
--- /dev/null
@@ -0,0 +1,27 @@
+/* -*- 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 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.
+ */
+#ifndef INCLUDED_GR_ENDIANNESS_H
+#define INCLUDED_GR_ENDIANNESS_H
+
+typedef enum {GR_MSB_FIRST, GR_LSB_FIRST} gr_endianness_t;
+
+#endif /* INCLUDED_GR_ENDIANNESS_H */
diff --git a/gnuradio-core/src/lib/general/gr_endianness.i b/gnuradio-core/src/lib/general/gr_endianness.i
new file mode 100644 (file)
index 0000000..d05b06a
--- /dev/null
@@ -0,0 +1,23 @@
+/* -*- 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 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.
+ */
+
+%include <gr_endianness.h>
diff --git a/gnuradio-core/src/lib/general/gr_expj.h b/gnuradio-core/src/lib/general/gr_expj.h
new file mode 100644 (file)
index 0000000..502bfe9
--- /dev/null
@@ -0,0 +1,37 @@
+/* -*- 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 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.
+ */
+#ifndef INCLUDED_GR_EXPJ_H
+#define INCLUDED_GR_EXPJ_H
+
+#include <gr_sincos.h>
+#include <gr_types.h>
+
+static inline gr_complex
+gr_expj(float phase)
+{
+  float        t_imag, t_real;
+  gr_sincosf(phase, &t_imag, &t_real);
+  return gr_complex(t_real, t_imag);
+}
+
+
+#endif /* INCLUDED_GR_EXPJ_H */
diff --git a/gnuradio-core/src/lib/general/gr_fake_channel_coder_pp.cc b/gnuradio-core/src/lib/general/gr_fake_channel_coder_pp.cc
new file mode 100644 (file)
index 0000000..0ef4c46
--- /dev/null
@@ -0,0 +1,112 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_fake_channel_coder_pp.h>
+#include <gr_io_signature.h>
+#include <string.h>
+#include <stdexcept>
+
+static const int PAD_VAL = 0xAA;
+
+gr_fake_channel_encoder_pp_sptr
+gr_make_fake_channel_encoder_pp(int input_vlen, int output_vlen)
+{
+  return gr_fake_channel_encoder_pp_sptr(new gr_fake_channel_encoder_pp(input_vlen,
+                                                                       output_vlen));
+}
+
+gr_fake_channel_encoder_pp::gr_fake_channel_encoder_pp(int input_vlen, int output_vlen)
+  : gr_sync_block("fake_channel_encoder_pp",
+                 gr_make_io_signature(1, 1, input_vlen * sizeof(unsigned char)),
+                 gr_make_io_signature(1, 1, output_vlen * sizeof(unsigned char))),
+    d_input_vlen(input_vlen), d_output_vlen(output_vlen)
+{
+  if (input_vlen <= 0 || output_vlen <= 0 || input_vlen > output_vlen)
+    throw std::invalid_argument("gr_fake_channel_encoder_pp");
+}
+
+gr_fake_channel_encoder_pp::~gr_fake_channel_encoder_pp()
+{
+}
+
+int
+gr_fake_channel_encoder_pp::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];
+  int  npad = d_output_vlen - d_input_vlen;
+  
+  for (int i = 0; i < noutput_items; i++){
+    memcpy(out, in, d_input_vlen);
+    memset(out + d_input_vlen, PAD_VAL, npad);
+    in += d_input_vlen;
+    out += d_output_vlen;
+  }
+
+  return noutput_items;
+}
+
+// ------------------------------------------------------------------------
+
+gr_fake_channel_decoder_pp_sptr
+gr_make_fake_channel_decoder_pp(int input_vlen, int output_vlen)
+{
+  return gr_fake_channel_decoder_pp_sptr(new gr_fake_channel_decoder_pp(input_vlen,
+                                                                       output_vlen));
+}
+
+gr_fake_channel_decoder_pp::gr_fake_channel_decoder_pp(int input_vlen, int output_vlen)
+  : gr_sync_block("fake_channel_decoder_pp",
+                 gr_make_io_signature(1, 1, input_vlen * sizeof(unsigned char)),
+                 gr_make_io_signature(1, 1, output_vlen * sizeof(unsigned char))),
+    d_input_vlen(input_vlen), d_output_vlen(output_vlen)
+{
+  if (input_vlen <= 0 || output_vlen <= 0 || output_vlen > input_vlen)
+    throw std::invalid_argument("gr_fake_channel_decoder_pp");
+}
+
+gr_fake_channel_decoder_pp::~gr_fake_channel_decoder_pp()
+{
+}
+
+int
+gr_fake_channel_decoder_pp::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++){
+    memcpy(out, in, d_output_vlen);
+    in += d_input_vlen;
+    out += d_output_vlen;
+  }
+
+  return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_fake_channel_coder_pp.h b/gnuradio-core/src/lib/general/gr_fake_channel_coder_pp.h
new file mode 100644 (file)
index 0000000..03b651e
--- /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 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.
+ */
+
+#ifndef INCLUDED_GR_FAKE_CHANNEL_CODER_PP_H
+#define INCLUDED_GR_FAKE_CHANNEL_CODER_PP_H
+
+#include <gr_sync_block.h>
+
+class gr_fake_channel_encoder_pp;
+typedef boost::shared_ptr<gr_fake_channel_encoder_pp> gr_fake_channel_encoder_pp_sptr;
+
+gr_fake_channel_encoder_pp_sptr
+gr_make_fake_channel_encoder_pp(int input_vlen, int output_vlen);
+
+/*!
+ * \brief pad packet with alternating 1,0 pattern.
+ * \ingroup block
+ *
+ * input: stream of byte vectors; output: stream of byte vectors
+ */
+class gr_fake_channel_encoder_pp : public gr_sync_block
+{
+  int  d_input_vlen;
+  int  d_output_vlen;
+  
+  gr_fake_channel_encoder_pp(int input_vlen, int output_vlen);
+
+  friend gr_fake_channel_encoder_pp_sptr
+         gr_make_fake_channel_encoder_pp(int input_vlen, int output_vlen);
+  
+public:
+  ~gr_fake_channel_encoder_pp();
+
+  int work (int noutput_items,
+           gr_vector_const_void_star &input_items,
+           gr_vector_void_star &output_items);
+};
+
+// ------------------------------------------------------------------------
+
+class gr_fake_channel_decoder_pp;
+typedef boost::shared_ptr<gr_fake_channel_decoder_pp> gr_fake_channel_decoder_pp_sptr;
+
+gr_fake_channel_decoder_pp_sptr
+gr_make_fake_channel_decoder_pp(int input_vlen, int output_vlen);
+
+/*!
+ * \brief remove fake padding from packet
+ * \ingroup block
+ *
+ * input: stream of byte vectors; output: stream of byte vectors
+ */
+class gr_fake_channel_decoder_pp : public gr_sync_block
+{
+  int  d_input_vlen;
+  int  d_output_vlen;
+  
+  gr_fake_channel_decoder_pp(int input_vlen, int output_vlen);
+
+  friend gr_fake_channel_decoder_pp_sptr
+         gr_make_fake_channel_decoder_pp(int input_vlen, int output_vlen);
+  
+public:
+  ~gr_fake_channel_decoder_pp();
+
+  int work (int noutput_items,
+           gr_vector_const_void_star &input_items,
+           gr_vector_void_star &output_items);
+};
+
+#endif /* INCLUDED_GR_FAKE_CHANNEL_CODER_PP_H */
diff --git a/gnuradio-core/src/lib/general/gr_fake_channel_coder_pp.i b/gnuradio-core/src/lib/general/gr_fake_channel_coder_pp.i
new file mode 100644 (file)
index 0000000..3bf394e
--- /dev/null
@@ -0,0 +1,53 @@
+/* -*- 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 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.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,fake_channel_encoder_pp)
+
+gr_fake_channel_encoder_pp_sptr 
+gr_make_fake_channel_encoder_pp(int input_vlen,
+                               int output_vlen
+                               ) throw(std::invalid_argument);
+
+class gr_fake_channel_encoder_pp : public gr_sync_block
+{
+  gr_fake_channel_encoder_pp(int input_vlen, int output_vlen);
+
+public:
+  ~gr_fake_channel_encoder_pp();
+};
+
+// ------------------------------------------------------------------------
+
+GR_SWIG_BLOCK_MAGIC(gr,fake_channel_decoder_pp)
+
+gr_fake_channel_decoder_pp_sptr 
+gr_make_fake_channel_decoder_pp(int input_vlen,
+                               int output_vlen
+                               ) throw(std::invalid_argument);
+
+class gr_fake_channel_decoder_pp : public gr_sync_block
+{
+  gr_fake_channel_decoder_pp(int input_vlen, int output_vlen);
+
+public:
+  ~gr_fake_channel_decoder_pp();
+};
diff --git a/gnuradio-core/src/lib/general/gr_fast_atan2f.cc b/gnuradio-core/src/lib/general/gr_fast_atan2f.cc
new file mode 100644 (file)
index 0000000..ebbece5
--- /dev/null
@@ -0,0 +1,198 @@
+/* -*- 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 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.
+ */
+
+#include <gr_math.h>         // declaration is in here
+#include <cmath>
+
+#define REAL float
+
+/***************************************************************************/
+/* Constant definitions */
+/***************************************************************************/
+
+#define TAN_MAP_RES 0.003921569 /* (smallest non-zero value in table) */
+#define RAD_PER_DEG 0.017453293
+#define TAN_MAP_SIZE 256
+
+/* arctangents from 0 to pi/4 radians */
+static REAL 
+fast_atan_table[257] = {
+   0.000000e+00, 3.921549e-03, 7.842976e-03, 1.176416e-02,
+   1.568499e-02, 1.960533e-02, 2.352507e-02, 2.744409e-02,
+   3.136226e-02, 3.527947e-02, 3.919560e-02, 4.311053e-02,
+   4.702413e-02, 5.093629e-02, 5.484690e-02, 5.875582e-02,
+   6.266295e-02, 6.656816e-02, 7.047134e-02, 7.437238e-02,
+   7.827114e-02, 8.216752e-02, 8.606141e-02, 8.995267e-02,
+   9.384121e-02, 9.772691e-02, 1.016096e-01, 1.054893e-01,
+   1.093658e-01, 1.132390e-01, 1.171087e-01, 1.209750e-01,
+   1.248376e-01, 1.286965e-01, 1.325515e-01, 1.364026e-01,
+   1.402496e-01, 1.440924e-01, 1.479310e-01, 1.517652e-01,
+   1.555948e-01, 1.594199e-01, 1.632403e-01, 1.670559e-01,
+   1.708665e-01, 1.746722e-01, 1.784728e-01, 1.822681e-01,
+   1.860582e-01, 1.898428e-01, 1.936220e-01, 1.973956e-01,
+   2.011634e-01, 2.049255e-01, 2.086818e-01, 2.124320e-01,
+   2.161762e-01, 2.199143e-01, 2.236461e-01, 2.273716e-01,
+   2.310907e-01, 2.348033e-01, 2.385093e-01, 2.422086e-01,
+   2.459012e-01, 2.495869e-01, 2.532658e-01, 2.569376e-01,
+   2.606024e-01, 2.642600e-01, 2.679104e-01, 2.715535e-01,
+   2.751892e-01, 2.788175e-01, 2.824383e-01, 2.860514e-01,
+   2.896569e-01, 2.932547e-01, 2.968447e-01, 3.004268e-01,
+   3.040009e-01, 3.075671e-01, 3.111252e-01, 3.146752e-01,
+   3.182170e-01, 3.217506e-01, 3.252758e-01, 3.287927e-01,
+   3.323012e-01, 3.358012e-01, 3.392926e-01, 3.427755e-01,
+   3.462497e-01, 3.497153e-01, 3.531721e-01, 3.566201e-01,
+   3.600593e-01, 3.634896e-01, 3.669110e-01, 3.703234e-01,
+   3.737268e-01, 3.771211e-01, 3.805064e-01, 3.838825e-01,
+   3.872494e-01, 3.906070e-01, 3.939555e-01, 3.972946e-01,
+   4.006244e-01, 4.039448e-01, 4.072558e-01, 4.105574e-01,
+   4.138496e-01, 4.171322e-01, 4.204054e-01, 4.236689e-01,
+   4.269229e-01, 4.301673e-01, 4.334021e-01, 4.366272e-01,
+   4.398426e-01, 4.430483e-01, 4.462443e-01, 4.494306e-01,
+   4.526070e-01, 4.557738e-01, 4.589307e-01, 4.620778e-01,
+   4.652150e-01, 4.683424e-01, 4.714600e-01, 4.745676e-01,
+   4.776654e-01, 4.807532e-01, 4.838312e-01, 4.868992e-01,
+   4.899573e-01, 4.930055e-01, 4.960437e-01, 4.990719e-01,
+   5.020902e-01, 5.050985e-01, 5.080968e-01, 5.110852e-01,
+   5.140636e-01, 5.170320e-01, 5.199904e-01, 5.229388e-01,
+   5.258772e-01, 5.288056e-01, 5.317241e-01, 5.346325e-01,
+   5.375310e-01, 5.404195e-01, 5.432980e-01, 5.461666e-01,
+   5.490251e-01, 5.518738e-01, 5.547124e-01, 5.575411e-01,
+   5.603599e-01, 5.631687e-01, 5.659676e-01, 5.687566e-01,
+   5.715357e-01, 5.743048e-01, 5.770641e-01, 5.798135e-01,
+   5.825531e-01, 5.852828e-01, 5.880026e-01, 5.907126e-01,
+   5.934128e-01, 5.961032e-01, 5.987839e-01, 6.014547e-01,
+   6.041158e-01, 6.067672e-01, 6.094088e-01, 6.120407e-01,
+   6.146630e-01, 6.172755e-01, 6.198784e-01, 6.224717e-01,
+   6.250554e-01, 6.276294e-01, 6.301939e-01, 6.327488e-01,
+   6.352942e-01, 6.378301e-01, 6.403565e-01, 6.428734e-01,
+   6.453808e-01, 6.478788e-01, 6.503674e-01, 6.528466e-01,
+   6.553165e-01, 6.577770e-01, 6.602282e-01, 6.626701e-01,
+   6.651027e-01, 6.675261e-01, 6.699402e-01, 6.723452e-01,
+   6.747409e-01, 6.771276e-01, 6.795051e-01, 6.818735e-01,
+   6.842328e-01, 6.865831e-01, 6.889244e-01, 6.912567e-01,
+   6.935800e-01, 6.958943e-01, 6.981998e-01, 7.004964e-01,
+   7.027841e-01, 7.050630e-01, 7.073330e-01, 7.095943e-01,
+   7.118469e-01, 7.140907e-01, 7.163258e-01, 7.185523e-01,
+   7.207701e-01, 7.229794e-01, 7.251800e-01, 7.273721e-01,
+   7.295557e-01, 7.317307e-01, 7.338974e-01, 7.360555e-01,
+   7.382053e-01, 7.403467e-01, 7.424797e-01, 7.446045e-01,
+   7.467209e-01, 7.488291e-01, 7.509291e-01, 7.530208e-01,
+   7.551044e-01, 7.571798e-01, 7.592472e-01, 7.613064e-01,
+   7.633576e-01, 7.654008e-01, 7.674360e-01, 7.694633e-01,
+   7.714826e-01, 7.734940e-01, 7.754975e-01, 7.774932e-01,
+   7.794811e-01, 7.814612e-01, 7.834335e-01, 7.853983e-01,
+   7.853983e-01
+ };
+
+
+/*****************************************************************************
+Function: Arc tangent
+
+Syntax: angle = fast_atan2(y, x);
+REAL y y component of input vector
+REAL x x component of input vector
+REAL angle angle of vector (x, y) in radians
+
+Description: This function calculates the angle of the vector (x,y) based
+on a table lookup and linear interpolation. The table uses
+a 256 point table covering -45 to +45 degrees and uses
+symetry to determine the final angle value in the range of
+-180 to 180 degrees. Note that this function uses the small
+angle approximation for values close to zero. This routine
+calculates the arc tangent with an average error of
++/- 0.045 degrees.
+*****************************************************************************/
+
+REAL
+gr_fast_atan2f(REAL y, REAL x)
+{
+  REAL x_abs, y_abs, z;
+  REAL alpha, angle, base_angle;
+  int index;
+
+  /* don't divide by zero! */          // FIXME could get hosed with -0.0
+  if ((y == 0.0) && (x == 0.0))
+    return 0.0;
+
+  /* normalize to +/- 45 degree range */
+  y_abs = fabs(y);
+  x_abs = fabs(x);
+  //z = (y_abs < x_abs ? y_abs / x_abs : x_abs / y_abs);
+  if (y_abs < x_abs)
+    z = y_abs / x_abs;
+  else
+    z = x_abs / y_abs;
+
+  /* when ratio approaches the table resolution, the angle is */
+  /* best approximated with the argument itself... */
+  if (z < TAN_MAP_RES)
+    base_angle = z;
+  else {
+    /* find index and interpolation value */
+    alpha = z * (REAL) TAN_MAP_SIZE - .5;
+    index = (int) alpha;
+    alpha -= (REAL) index;
+    /* determine base angle based on quadrant and */
+    /* add or subtract table value from base angle based on quadrant */
+    base_angle = fast_atan_table[index];
+    base_angle +=
+      (fast_atan_table[index + 1] - fast_atan_table[index]) * alpha;
+  }
+
+  if (x_abs > y_abs) { /* -45 -> 45 or 135 -> 225 */
+    if (x >= 0.0) { /* -45 -> 45 */
+      if (y >= 0.0)
+       angle = base_angle; /* 0 -> 45, angle OK */
+      else
+       angle = -base_angle; /* -45 -> 0, angle = -angle */
+    } else { /* 135 -> 180 or 180 -> -135 */
+      angle = 3.14159265358979323846;
+      if (y >= 0.0)
+       angle -= base_angle; /* 135 -> 180, angle = 180 - angle */
+      else
+       angle = base_angle - angle; /* 180 -> -135, angle = angle - 180 */
+    }
+  } else { /* 45 -> 135 or -135 -> -45 */
+    if (y >= 0.0) { /* 45 -> 135 */
+      angle = 1.57079632679489661923;
+      if (x >= 0.0)
+       angle -= base_angle; /* 45 -> 90, angle = 90 - angle */
+      else
+       angle += base_angle; /* 90 -> 135, angle = 90 + angle */
+    } else { /* -135 -> -45 */
+      angle = -1.57079632679489661923;
+      if (x >= 0.0)
+       angle += base_angle; /* -90 -> -45, angle = -90 + angle */
+      else
+       angle -= base_angle; /* -135 -> -90, angle = -90 - angle */
+    }
+  }
+
+#ifdef ZERO_TO_TWOPI
+  if (angle < 0)
+    return (angle + TWOPI);
+  else
+    return (angle);
+#else
+  return (angle);
+#endif
+}
diff --git a/gnuradio-core/src/lib/general/gr_feval.cc b/gnuradio-core/src/lib/general/gr_feval.cc
new file mode 100644 (file)
index 0000000..b30930e
--- /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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <gr_feval.h>
+
+gr_feval_dd::~gr_feval_dd(){}
+
+double 
+gr_feval_dd::eval(double x)
+{
+  return 0;
+}
+
+gr_feval_ff::~gr_feval_ff(){}
+
+float 
+gr_feval_ff::eval(float x)
+{
+  return 0;
+}
+
+gr_feval_cc::~gr_feval_cc(){}
+
+gr_complex
+gr_feval_cc::eval(gr_complex x)
+{
+  return 0;
+}
+
+gr_feval_ll::~gr_feval_ll(){}
+
+long
+gr_feval_ll::eval(long x)
+{
+  return 0;
+}
+
+/*
+ * Trivial examples showing C++ (transparently) calling Python
+ */
+double
+gr_feval_dd_example(gr_feval_dd *f, double x)
+{
+  return f->eval(x);
+}
+
+float
+gr_feval_ff_example(gr_feval_ff *f, float x)
+{
+  return f->eval(x);
+}
+
+gr_complex
+gr_feval_cc_example(gr_feval_cc *f, gr_complex x)
+{
+  return f->eval(x);
+}
+
+long
+gr_feval_ll_example(gr_feval_ll *f, long x)
+{
+  return f->eval(x);
+}
diff --git a/gnuradio-core/src/lib/general/gr_feval.h b/gnuradio-core/src/lib/general/gr_feval.h
new file mode 100644 (file)
index 0000000..e9f3ae3
--- /dev/null
@@ -0,0 +1,116 @@
+/* -*- 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 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.
+ */
+#ifndef INCLUDED_GR_FEVAL_H
+#define INCLUDED_GR_FEVAL_H
+
+#include <gr_complex.h>
+
+/*!
+ * \brief base class for evaluating a function: double -> double
+ *
+ * This class is designed to be subclassed in Python or C++
+ * and is callable from both places.  It uses SWIG's
+ * "director" feature to implement the magic.
+ * It's slow. Don't use it in a performance critical path.
+ */
+class gr_feval_dd
+{
+public:
+  gr_feval_dd() {}
+  virtual ~gr_feval_dd();
+
+  /*!
+   * \brief override this to define the function
+   */
+  virtual double eval(double x);
+};
+
+/*!
+ * \brief base class for evaluating a function: float -> float
+ *
+ * This class is designed to be subclassed in Python or C++
+ * and is callable from both places.  It uses SWIG's
+ * "director" feature to implement the magic.
+ * It's slow. Don't use it in a performance critical path.
+ */
+class gr_feval_ff
+{
+public:
+  gr_feval_ff() {}
+  virtual ~gr_feval_ff();
+
+  /*!
+   * \brief override this to define the function
+   */
+  virtual float eval(float x);
+};
+
+/*!
+ * \brief base class for evaluating a function: complex -> complex
+ *
+ * This class is designed to be subclassed in Python or C++
+ * and is callable from both places.  It uses SWIG's
+ * "director" feature to implement the magic.
+ * It's slow. Don't use it in a performance critical path.
+ */
+class gr_feval_cc
+{
+public:
+  gr_feval_cc() {}
+  virtual ~gr_feval_cc();
+
+  /*!
+   * \brief override this to define the function
+   */
+  virtual gr_complex eval(gr_complex x);
+};
+
+/*!
+ * \brief base class for evaluating a function: long -> long
+ *
+ * This class is designed to be subclassed in Python or C++
+ * and is callable from both places.  It uses SWIG's
+ * "director" feature to implement the magic.
+ * It's slow. Don't use it in a performance critical path.
+ */
+class gr_feval_ll
+{
+public:
+  gr_feval_ll() {}
+  virtual ~gr_feval_ll();
+
+  /*!
+   * \brief override this to define the function
+   */
+  virtual long eval(long x);
+};
+
+/*!
+ * \brief trivial examples / test cases showing C++ calling Python code
+ */
+double     gr_feval_dd_example(gr_feval_dd *f, double x);
+float      gr_feval_ff_example(gr_feval_ff *f, float x);
+gr_complex gr_feval_cc_example(gr_feval_cc *f, gr_complex x);
+long       gr_feval_ll_example(gr_feval_ll *f, long x);
+
+
+#endif /* INCLUDED_GR_FEVAL_H */
diff --git a/gnuradio-core/src/lib/general/gr_feval.i b/gnuradio-core/src/lib/general/gr_feval.i
new file mode 100644 (file)
index 0000000..f7d8c22
--- /dev/null
@@ -0,0 +1,69 @@
+/* -*- 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 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.
+ */
+
+// Enable SWIG directors for these classes
+%feature("director") gr_feval_dd;
+%feature("director") gr_feval_cc;
+%feature("director") gr_feval_ll;
+
+
+%rename(feval_dd) gr_feval_dd;
+class gr_feval_dd
+{
+public:
+  gr_feval_dd() {}
+  virtual ~gr_feval_dd();
+
+  virtual double eval(double x);
+};
+
+%rename(feval_cc) gr_feval_cc;
+class gr_feval_cc
+{
+public:
+  gr_feval_cc() {}
+  virtual ~gr_feval_cc();
+
+  virtual gr_complex eval(gr_complex x);
+};
+
+%rename(feval_ll) gr_feval_ll;
+class gr_feval_ll
+{
+public:
+  gr_feval_ll() {}
+  virtual ~gr_feval_ll();
+
+  virtual long eval(long x);
+};
+
+
+// examples / test cases
+
+%rename(feval_dd_example) gr_feval_dd_example;
+double gr_feval_dd_example(gr_feval_dd *f, double x);
+
+%rename(feval_cc_example) gr_feval_cc_example;
+gr_complex gr_feval_cc_example(gr_feval_cc *f, gr_complex x);
+
+%rename(feval_ll_example) gr_feval_ll_example;
+long gr_feval_ll_example(gr_feval_ll *f, long x);
diff --git a/gnuradio-core/src/lib/general/gr_fft_vcc.cc b/gnuradio-core/src/lib/general/gr_fft_vcc.cc
new file mode 100644 (file)
index 0000000..e529159
--- /dev/null
@@ -0,0 +1,102 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_fft_vcc.h>
+#include <gr_io_signature.h>
+#include <gri_fft.h>
+#include <math.h>
+
+gr_fft_vcc_sptr
+gr_make_fft_vcc (int fft_size, bool forward,const std::vector<float> window)
+{
+  return gr_fft_vcc_sptr (new gr_fft_vcc (fft_size, forward, window));
+}
+
+gr_fft_vcc::gr_fft_vcc (int fft_size, bool forward, const std::vector<float> window)
+  : gr_sync_block ("fft_vcc",
+                  gr_make_io_signature (1, 1, fft_size * sizeof (gr_complex)),
+                  gr_make_io_signature (1, 1, fft_size * sizeof (gr_complex))),
+    d_fft_size(fft_size)
+{
+  d_fft = new gri_fft_complex (d_fft_size, forward);
+
+  set_window(window);
+
+}
+
+gr_fft_vcc::~gr_fft_vcc ()
+{
+  delete d_fft;
+}
+
+int
+gr_fft_vcc::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];
+
+  unsigned int input_data_size = input_signature()->sizeof_stream_item (0);
+  unsigned int output_data_size = output_signature()->sizeof_stream_item (0);
+
+  int count = 0;
+
+  while (count++ < noutput_items){
+
+    // copy input into optimally aligned buffer
+
+    if (d_window.size()){
+      gr_complex *dst = d_fft->get_inbuf();
+      for (unsigned int i = 0; i < d_fft_size; i++)            // apply window
+       dst[i] = in[i] * d_window[i];
+    }
+    else
+      memcpy (d_fft->get_inbuf(), in, input_data_size);
+
+    // compute the fft
+    d_fft->execute ();
+
+    // cpoy result to our output
+    memcpy (out, d_fft->get_outbuf (), output_data_size);
+
+    in  += d_fft_size;
+    out += d_fft_size;
+  }
+
+  return noutput_items;
+}
+
+bool 
+gr_fft_vcc::set_window(const std::vector<float> window)
+{
+  if(window.size()==0 || window.size()==d_fft_size) {
+    d_window=window;
+    return true;
+  }
+  else 
+    return false;
+}
diff --git a/gnuradio-core/src/lib/general/gr_fft_vcc.h b/gnuradio-core/src/lib/general/gr_fft_vcc.h
new file mode 100644 (file)
index 0000000..784471a
--- /dev/null
@@ -0,0 +1,62 @@
+/* -*- 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 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.
+ */
+
+#ifndef INCLUDED_GR_FFT_VCC_H
+#define INCLUDED_GR_FFT_VCC_H
+
+#include <gr_sync_block.h>
+
+class gri_fft_complex;
+
+class gr_fft_vcc;
+typedef boost::shared_ptr<gr_fft_vcc> gr_fft_vcc_sptr;
+
+gr_fft_vcc_sptr
+gr_make_fft_vcc (int fft_size, bool forward, const std::vector<float> window);
+
+/*!
+ * \brief Compute forward or reverse FFT.  complex vector in / complex vector out.
+ * \ingroup block
+ */
+
+class gr_fft_vcc : public gr_sync_block
+{
+  friend gr_fft_vcc_sptr
+  gr_make_fft_vcc (int fft_size, bool forward, const std::vector<float> window);
+
+  unsigned int    d_fft_size;
+  std::vector<float>   d_window;
+  gri_fft_complex *d_fft;
+
+  gr_fft_vcc (int fft_size, bool forward, const std::vector<float> window);
+
+ public:
+  ~gr_fft_vcc ();
+
+  int work (int noutput_items,
+           gr_vector_const_void_star &input_items,
+           gr_vector_void_star &output_items);
+  bool set_window(const std::vector<float> window);
+};
+
+
+#endif /* INCLUDED_GR_FFT_VCC_H */
diff --git a/gnuradio-core/src/lib/general/gr_fft_vcc.i b/gnuradio-core/src/lib/general/gr_fft_vcc.i
new file mode 100644 (file)
index 0000000..a171d12
--- /dev/null
@@ -0,0 +1,35 @@
+/* -*- 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 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.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr, fft_vcc)
+
+gr_fft_vcc_sptr 
+gr_make_fft_vcc (int fft_size, bool forward, const std::vector<float> window);
+
+class gr_fft_vcc : public gr_sync_block
+{
+ protected:
+  gr_fft_vcc (int fft_size, bool forward, const std::vector<float> window);
+
+ public:
+  bool set_window(const std::vector<float> window);
+};
diff --git a/gnuradio-core/src/lib/general/gr_fft_vfc.cc b/gnuradio-core/src/lib/general/gr_fft_vfc.cc
new file mode 100644 (file)
index 0000000..d6d2479
--- /dev/null
@@ -0,0 +1,116 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_fft_vfc.h>
+#include <gr_io_signature.h>
+#include <gri_fft.h>
+#include <math.h>
+#include <stdexcept>
+
+
+// FIXME after this is working, change to use native real to complex fft.
+// It should run twice as fast.
+
+
+
+
+gr_fft_vfc_sptr
+gr_make_fft_vfc (int fft_size, bool forward, const std::vector<float> window)
+{
+  return gr_fft_vfc_sptr (new gr_fft_vfc (fft_size, forward, window));
+}
+
+gr_fft_vfc::gr_fft_vfc (int fft_size, bool forward, const std::vector<float> window)
+  : gr_sync_block ("fft_vfc",
+                  gr_make_io_signature (1, 1, fft_size * sizeof (float)),
+                  gr_make_io_signature (1, 1, fft_size * sizeof (gr_complex))),
+    d_fft_size(fft_size), d_window()
+{
+  if (!forward){
+    fprintf (stderr, "fft_vfc: forward must == true\n");
+    throw std::invalid_argument ("fft_vfc: forward must == true");
+  }
+
+  d_fft = new gri_fft_complex (d_fft_size, forward);
+
+  set_window(window);
+}
+
+gr_fft_vfc::~gr_fft_vfc ()
+{
+  delete d_fft;
+}
+
+int
+gr_fft_vfc::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];
+  gr_complex *out = (gr_complex *) output_items[0];
+
+  unsigned int output_data_size = output_signature()->sizeof_stream_item (0);
+
+  int count = 0;
+
+  while (count++ < noutput_items){
+
+    // copy input into optimally aligned buffer
+
+    if (d_window.size()){
+      gr_complex *dst = d_fft->get_inbuf();
+      for (unsigned int i = 0; i < d_fft_size; i++)            // apply window
+       dst[i] = in[i] * d_window[i];
+    }
+    else {
+      gr_complex *dst = d_fft->get_inbuf();
+      for (unsigned int i = 0; i < d_fft_size; i++)            // float to complex conversion
+       dst[i] = in[i];                                
+    }
+
+    // compute the fft
+    d_fft->execute ();
+
+    // cpoy result to our output
+    memcpy (out, d_fft->get_outbuf (), output_data_size);
+
+    in  += d_fft_size;
+    out += d_fft_size;
+  }
+
+  return noutput_items;
+}
+
+bool 
+gr_fft_vfc::set_window(const std::vector<float> window)
+{
+  if(window.size()==0 || window.size()==d_fft_size) {
+    d_window=window;
+    return true;
+  }
+  else 
+    return false;
+}
diff --git a/gnuradio-core/src/lib/general/gr_fft_vfc.h b/gnuradio-core/src/lib/general/gr_fft_vfc.h
new file mode 100644 (file)
index 0000000..a30495d
--- /dev/null
@@ -0,0 +1,62 @@
+/* -*- 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 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.
+ */
+
+#ifndef INCLUDED_GR_FFT_VFC_H
+#define INCLUDED_GR_FFT_VFC_H
+
+#include <gr_sync_block.h>
+
+class gri_fft_complex;
+
+class gr_fft_vfc;
+typedef boost::shared_ptr<gr_fft_vfc> gr_fft_vfc_sptr;
+
+gr_fft_vfc_sptr
+gr_make_fft_vfc (int fft_size, bool forward, const std::vector<float>);
+
+/*!
+ * \brief Compute forward FFT.  float vector in / complex vector out.
+ * \ingroup block
+ */
+
+class gr_fft_vfc : public gr_sync_block
+{
+  friend gr_fft_vfc_sptr
+  gr_make_fft_vfc (int fft_size, bool forward, const std::vector<float>  window);
+
+  unsigned int  d_fft_size;
+  std::vector<float> d_window;
+  gri_fft_complex *d_fft;
+
+  gr_fft_vfc (int fft_size, bool forward, const std::vector<float>  window);
+
+ public:
+  ~gr_fft_vfc ();
+
+  int work (int noutput_items,
+           gr_vector_const_void_star &input_items,
+           gr_vector_void_star &output_items);
+  bool set_window(const std::vector<float> window);
+};
+
+
+#endif /* INCLUDED_GR_FFT_VFC_H */
diff --git a/gnuradio-core/src/lib/general/gr_fft_vfc.i b/gnuradio-core/src/lib/general/gr_fft_vfc.i
new file mode 100644 (file)
index 0000000..f30606d
--- /dev/null
@@ -0,0 +1,35 @@
+/* -*- 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 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.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr, fft_vfc)
+
+gr_fft_vfc_sptr 
+gr_make_fft_vfc (int fft_size, bool forward, const std::vector<float> window);
+
+class gr_fft_vfc : public gr_sync_block
+{
+ protected:
+  gr_fft_vfc (int fft_size, bool forward, const std::vector<float> window);
+  
+ public:
+  bool set_window(const std::vector<float> window);
+};
diff --git a/gnuradio-core/src/lib/general/gr_firdes.cc b/gnuradio-core/src/lib/general/gr_firdes.cc
new file mode 100644 (file)
index 0000000..d09d68d
--- /dev/null
@@ -0,0 +1,584 @@
+/* -*- 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 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.
+ */
+
+#include <gr_firdes.h>
+#include <stdexcept>
+
+
+using std::vector;
+
+#define IzeroEPSILON 1E-21               /* Max error acceptable in Izero */
+
+static double Izero(double x)
+{
+   double sum, u, halfx, temp;
+   int n;
+
+   sum = u = n = 1;
+   halfx = x/2.0;
+   do {
+      temp = halfx/(double)n;
+      n += 1;
+      temp *= temp;
+      u *= temp;
+      sum += u;
+      } while (u >= IzeroEPSILON*sum);
+   return(sum);
+}
+
+
+//
+//     === Low Pass ===
+//
+
+vector<float>
+gr_firdes::low_pass (double gain,
+                    double sampling_freq,
+                    double cutoff_freq,        // Hz center of transition band
+                    double transition_width,   // Hz width of transition band
+                    win_type window_type,
+                    double beta)               // used only with Kaiser
+{
+  sanity_check_1f (sampling_freq, cutoff_freq, transition_width);
+
+  int ntaps = compute_ntaps (sampling_freq, transition_width,
+                            window_type, beta);
+
+  // construct the truncated ideal impulse response
+  // [sin(x)/x for the low pass case]
+
+  vector<float> taps(ntaps);
+  vector<float> w = window (window_type, ntaps, beta);
+
+  int M = (ntaps - 1) / 2;
+  double fwT0 = 2 * M_PI * cutoff_freq / sampling_freq;
+
+  for (int n = -M; n <= M; n++){
+    if (n == 0)
+ taps[n + M] = fwT0 / M_PI * w[n + M];
+    else {
+      // a little algebra gets this into the more familiar sin(x)/x form
+      taps[n + M] =  sin (n * fwT0) / (n * M_PI) * w[n + M];
+    }
+  }
+  
+  // find the factor to normalize the gain, fmax.
+  // For low-pass, gain @ zero freq = 1.0
+  
+  double fmax = taps[0 + M];
+  for (int n = 1; n <= M; n++)
+    fmax += 2 * taps[n + M];
+
+  gain /= fmax;        // normalize
+
+  for (int i = 0; i < ntaps; i++)
+    taps[i] *= gain;
+
+  return taps;
+}
+
+//
+//     === High Pass ===
+//
+
+vector<float>
+gr_firdes::high_pass (double gain,
+                     double sampling_freq,
+                     double cutoff_freq,       // Hz center of transition band
+                     double transition_width,  // Hz width of transition band
+                     win_type window_type,
+                     double beta)              // used only with Kaiser
+{
+  sanity_check_1f (sampling_freq, cutoff_freq, transition_width);
+
+  int ntaps = compute_ntaps (sampling_freq, transition_width,
+                            window_type, beta);
+
+  // construct the truncated ideal impulse response times the window function
+
+  vector<float> taps(ntaps);
+  vector<float> w = window (window_type, ntaps, beta);
+
+  int M = (ntaps - 1) / 2;
+  double fwT0 = 2 * M_PI * cutoff_freq / sampling_freq;
+
+  for (int n = -M; n <= M; n++){
+    if (n == 0)
+      taps[n + M] = (1 - (fwT0 / M_PI)) * w[n + M];
+    else {
+      // a little algebra gets this into the more familiar sin(x)/x form
+      taps[n + M] =  -sin (n * fwT0) / (n * M_PI) * w[n + M];
+    }
+  }
+  
+  // find the factor to normalize the gain, fmax.
+  // For high-pass, gain @ fs/2 freq = 1.0
+  
+  double fmax = taps[0 + M];
+  for (int n = 1; n <= M; n++)
+    fmax += 2 * taps[n + M] * cos (n * M_PI);
+
+  gain /= fmax;        // normalize
+
+  for (int i = 0; i < ntaps; i++)
+    taps[i] *= gain;
+
+  return taps;
+}
+
+//
+//     === Band Pass ===
+//
+
+vector<float>
+gr_firdes::band_pass (double gain,
+                     double sampling_freq,
+                     double low_cutoff_freq,   // Hz center of transition band
+                     double high_cutoff_freq,  // Hz center of transition band
+                     double transition_width,  // Hz width of transition band
+                     win_type window_type,
+                     double beta)              // used only with Kaiser
+{
+  sanity_check_2f (sampling_freq,
+                  low_cutoff_freq,
+                  high_cutoff_freq, transition_width);
+
+  int ntaps = compute_ntaps (sampling_freq, transition_width,
+                            window_type, beta);
+
+  // construct the truncated ideal impulse response times the window function
+
+  vector<float> taps(ntaps);
+  vector<float> w = window (window_type, ntaps, beta);
+
+  int M = (ntaps - 1) / 2;
+  double fwT0 = 2 * M_PI * low_cutoff_freq / sampling_freq;
+  double fwT1 = 2 * M_PI * high_cutoff_freq / sampling_freq;
+
+  for (int n = -M; n <= M; n++){
+    if (n == 0)
+      taps[n + M] = (fwT1 - fwT0) / M_PI * w[n + M];
+    else {
+      taps[n + M] =  (sin (n * fwT1) - sin (n * fwT0)) / (n * M_PI) * w[n + M];
+    }
+  }
+  
+  // find the factor to normalize the gain, fmax.
+  // For band-pass, gain @ center freq = 1.0
+  
+  double fmax = taps[0 + M];
+  for (int n = 1; n <= M; n++)
+    fmax += 2 * taps[n + M] * cos (n * (fwT0 + fwT1) * 0.5);
+
+  gain /= fmax;        // normalize
+
+  for (int i = 0; i < ntaps; i++)
+    taps[i] *= gain;
+
+  return taps;
+}
+
+//
+//     === Complex Band Pass ===
+//
+
+vector<gr_complex>
+gr_firdes::complex_band_pass (double gain,
+                     double sampling_freq,
+                     double low_cutoff_freq,   // Hz center of transition band
+                     double high_cutoff_freq,  // Hz center of transition band
+                     double transition_width,  // Hz width of transition band
+                     win_type window_type,
+                     double beta)              // used only with Kaiser
+{
+  sanity_check_2f_c (sampling_freq,
+                  low_cutoff_freq,
+                  high_cutoff_freq, transition_width);
+
+  int ntaps = compute_ntaps (sampling_freq, transition_width,
+                            window_type, beta);
+
+  // construct the truncated ideal impulse response times the window function
+
+  vector<gr_complex> taps(ntaps);
+  vector<float> lptaps(ntaps);
+  vector<float> w = window (window_type, ntaps, beta);
+
+  lptaps = low_pass(gain,sampling_freq,(high_cutoff_freq - low_cutoff_freq)/2,transition_width,window_type,beta);
+
+  gr_complex *optr = &taps[0];
+  float *iptr = &lptaps[0];
+  float freq = M_PI * (high_cutoff_freq + low_cutoff_freq)/sampling_freq;
+  float phase=0;
+  if (lptaps.size() & 01) {
+      phase = - freq * ( lptaps.size() >> 1 );
+  } else phase = - freq/2.0 * ((1 + 2*lptaps.size()) >> 1);
+  for(unsigned int i=0;i<lptaps.size();i++) {
+      *optr++ = gr_complex(*iptr * cos(phase),*iptr * sin(phase));
+      iptr++, phase += freq;
+  }
+  
+  return taps;
+}
+
+
+//
+//     === Band Reject ===
+//
+
+vector<float>
+gr_firdes::band_reject (double gain,
+                       double sampling_freq,
+                       double low_cutoff_freq,  // Hz center of transition band
+                       double high_cutoff_freq, // Hz center of transition band
+                       double transition_width, // Hz width of transition band
+                       win_type window_type,
+                       double beta)             // used only with Kaiser
+{
+  sanity_check_2f (sampling_freq,
+                  low_cutoff_freq,
+                  high_cutoff_freq, transition_width);
+
+  int ntaps = compute_ntaps (sampling_freq, transition_width,
+                            window_type, beta);
+
+  // construct the truncated ideal impulse response times the window function
+
+  vector<float> taps(ntaps);
+  vector<float> w = window (window_type, ntaps, beta);
+
+  int M = (ntaps - 1) / 2;
+  double fwT0 = 2 * M_PI * low_cutoff_freq / sampling_freq;
+  double fwT1 = 2 * M_PI * high_cutoff_freq / sampling_freq;
+
+  for (int n = -M; n <= M; n++){
+    if (n == 0)
+      taps[n + M] = (1.0 + (fwT0 - fwT1)) / M_PI * w[n + M];
+    else {
+      taps[n + M] =  (sin (n * fwT0) - sin (n * fwT1)) / (n * M_PI) * w[n + M];
+    }
+  }
+  
+  // find the factor to normalize the gain, fmax.
+  // For band-reject, gain @ zero freq = 1.0
+  
+  double fmax = taps[0 + M];
+  for (int n = 1; n <= M; n++)
+    fmax += 2 * taps[n + M];
+
+  gain /= fmax;        // normalize
+
+  for (int i = 0; i < ntaps; i++)
+    taps[i] *= gain;
+
+  return taps;
+}
+
+//
+// Hilbert Transform
+//
+
+vector<float>
+gr_firdes::hilbert (unsigned int ntaps,
+                   win_type windowtype, 
+                   double beta)
+{
+  if(!(ntaps & 1))
+    throw std::out_of_range("Hilbert:  Must have odd number of taps");
+
+  vector<float> taps(ntaps);
+  vector<float> w = window (windowtype, ntaps, beta);
+  unsigned int h = (ntaps-1)/2;
+  float gain=0;
+  for (unsigned int i = 1; i <= h; i++)
+    {
+      if(i&1)
+       {
+         float x = 1/(float)i;
+         taps[h+i] = x * w[h+i];
+         taps[h-i] = -x * w[h-i];
+         gain = taps[h+i] - gain;
+       }
+      else
+       taps[h+i] = taps[h-i] = 0;
+    }
+  gain = 2 * fabs(gain);
+  for ( unsigned int i = 0; i < ntaps; i++)
+      taps[i] /= gain;
+  return taps;
+}
+
+//
+// Gaussian
+//
+
+vector<float>
+gr_firdes::gaussian (double gain,
+                    double spb,
+                    double bt,
+                    int ntaps)
+{
+
+  vector<float> taps(ntaps);
+  double scale = 0;
+  double dt = 1.0/spb;
+  double s = 1.0/(sqrt(log(2)) / (2*M_PI*bt));
+  double t0 = -0.5 * ntaps;
+  double ts;
+  for(int i=0;i<ntaps;i++)
+    {
+      t0++;
+      ts = s*dt*t0;
+      taps[i] = exp(-0.5*ts*ts);
+      scale += taps[i];
+    }
+  for(int i=0;i<ntaps;i++)
+    taps[i] = taps[i] / scale * gain;
+  return taps;
+}
+
+
+//
+// Root Raised Cosine
+//
+
+vector<float>
+gr_firdes::root_raised_cosine (double gain,
+                              double sampling_freq,
+                              double symbol_rate,
+                              double alpha,
+                              int ntaps)
+{
+  ntaps |= 1;  // ensure that ntaps is odd
+
+  double spb = sampling_freq/symbol_rate; // samples per bit/symbol
+  vector<float> taps(ntaps);
+  double scale = 0;
+  for(int i=0;i<ntaps;i++)
+    {
+      double x1,x2,x3,num,den;
+      double xindx = i - ntaps/2;
+      x1 = M_PI * xindx/spb;
+      x2 = 4 * alpha * xindx / spb;
+      x3 = x2*x2 - 1;
+      if( fabs(x3) >= 0.000001 )  // Avoid Rounding errors...
+       {
+         if( i != ntaps/2 )
+           num = cos((1+alpha)*x1) + sin((1-alpha)*x1)/(4*alpha*xindx/spb);
+         else
+           num = cos((1+alpha)*x1) + (1-alpha) * M_PI / (4*alpha);
+         den = x3 * M_PI;
+       }
+      else
+       {
+         if(alpha==1)
+           {
+             taps[i] = -1;
+             continue;
+           }
+         x3 = (1-alpha)*x1;
+         x2 = (1+alpha)*x1;
+         num = (sin(x2)*(1+alpha)*M_PI
+                - cos(x3)*((1-alpha)*M_PI*spb)/(4*alpha*xindx)
+                + sin(x3)*spb*spb/(4*alpha*xindx*xindx));
+         den = -32 * M_PI * alpha * alpha * xindx/spb;
+       }
+      taps[i] = 4 * alpha * num / den;
+      scale += taps[i];
+    }
+
+  for(int i=0;i<ntaps;i++)
+    taps[i] = taps[i] * gain / scale;
+
+  return taps;
+}
+
+//
+//     === Utilities ===
+//
+
+// delta_f / width_factor gives number of taps required.
+static const float width_factor[5] = {   // indexed by win_type
+  3.3,                 // WIN_HAMMING
+  3.1,                 // WIN_HANN
+  5.5,                 // WIN_BLACKMAN
+  2.0,                  // WIN_RECTANGULAR
+  //5.0                   // WIN_KAISER  (guesstimate compromise)
+  //2.0                   // WIN_KAISER  (guesstimate compromise)
+  10.0                 // WIN_KAISER
+};
+
+int
+gr_firdes::compute_ntaps (double sampling_freq,
+                         double transition_width,
+                         win_type window_type,
+                         double beta)
+{
+  // normalized transition width
+  double delta_f = transition_width / sampling_freq;
+
+  // compute number of taps required for given transition width
+  int ntaps = (int) (width_factor[window_type] / delta_f + 0.5);
+  if ((ntaps & 1) == 0)        // if even...
+    ntaps++;           // ...make odd
+
+  return ntaps;
+}
+
+double gr_firdes::bessi0(double x)
+{
+       double ax,ans;
+       double y;
+
+       ax=fabs(x);
+       if (ax < 3.75)
+       {
+               y=x/3.75;
+               y*=y;
+               ans=1.0+y*(3.5156229+y*(3.0899424+y*(1.2067492
+                       +y*(0.2659732+y*(0.360768e-1+y*0.45813e-2)))));
+       }
+       else
+       {
+               y=3.75/ax;
+               ans=(exp(ax)/sqrt(ax))*(0.39894228+y*(0.1328592e-1
+                       +y*(0.225319e-2+y*(-0.157565e-2+y*(0.916281e-2
+                       +y*(-0.2057706e-1+y*(0.2635537e-1+y*(-0.1647633e-1
+                       +y*0.392377e-2))))))));
+       }
+       return ans;
+}
+vector<float>
+gr_firdes::window (win_type type, int ntaps, double beta)
+{
+  vector<float> taps(ntaps);
+  int  M = ntaps - 1;          // filter order
+
+  switch (type){
+  case WIN_RECTANGULAR:
+    for (int n = 0; n < ntaps; n++)
+      taps[n] = 1;
+
+  case WIN_HAMMING:
+    for (int n = 0; n < ntaps; n++)
+      taps[n] = 0.54 - 0.46 * cos ((2 * M_PI * n) / M);
+    break;
+
+  case WIN_HANN:
+    for (int n = 0; n < ntaps; n++)
+      taps[n] = 0.5 - 0.5 * cos ((2 * M_PI * n) / M);
+    break;
+
+  case WIN_BLACKMAN:
+    for (int n = 0; n < ntaps; n++)
+      taps[n] = 0.42 - 0.50 * cos ((2*M_PI * n) / (M-1)) - 0.08 * cos ((4*M_PI * n) / (M-1));
+    break;
+
+#if 0
+  case WIN_KAISER:
+    for (int n = 0; n < ntaps; n++)
+       taps[n] = bessi0(beta*sqrt(1.0 - (4.0*n/(M*M))))/bessi0(beta);
+    break;
+#else
+
+  case WIN_KAISER:
+    {
+      double IBeta = 1.0/Izero(beta);
+      double inm1 = 1.0/((double)(ntaps));
+      double temp;
+      //fprintf(stderr, "IBeta = %g; inm1 = %g\n", IBeta, inm1);
+
+      for (int i=0; i<ntaps; i++) {
+       temp = i * inm1;
+       //fprintf(stderr, "temp = %g\n", temp);
+       taps[i] = Izero(beta*sqrt(1.0-temp*temp)) * IBeta;
+       //fprintf(stderr, "taps[%d] = %g\n", i, taps[i]);
+      }
+    }
+    break;
+
+#endif
+  default:
+    throw std::runtime_error ("not_implemented");
+  }
+
+  return taps;
+}
+
+void
+gr_firdes::sanity_check_1f (double sampling_freq,
+                           double fa,                  // cutoff freq
+                           double transition_width)
+{
+  if (sampling_freq <= 0.0)
+    throw std::out_of_range ("gr_firdes check failed: sampling_freq > 0");
+
+  if (fa <= 0.0 || fa > sampling_freq / 2)
+    throw std::out_of_range ("gr_firdes check failed: 0 < fa <= sampling_freq / 2");
+  
+  if (transition_width <= 0)
+    throw std::out_of_range ("gr_dirdes check failed: transition_width > 0");
+}
+
+void
+gr_firdes::sanity_check_2f (double sampling_freq,
+                           double fa,                  // first cutoff freq
+                           double fb,                  // second cutoff freq
+                           double transition_width)
+{
+  if (sampling_freq <= 0.0)
+    throw std::out_of_range ("gr_firdes check failed: sampling_freq > 0");
+
+  if (fa <= 0.0 || fa > sampling_freq / 2)
+    throw std::out_of_range ("gr_firdes check failed: 0 < fa <= sampling_freq / 2");
+  
+  if (fb <= 0.0 || fb > sampling_freq / 2)
+    throw std::out_of_range ("gr_firdes check failed: 0 < fb <= sampling_freq / 2");
+  
+  if (fa > fb)
+    throw std::out_of_range ("gr_firdes check failed: fa <= fb");
+  
+  if (transition_width <= 0)
+    throw std::out_of_range ("gr_firdes check failed: transition_width > 0");
+}
+
+void
+gr_firdes::sanity_check_2f_c (double sampling_freq,
+                           double fa,                  // first cutoff freq
+                           double fb,                  // second cutoff freq
+                           double transition_width)
+{
+  if (sampling_freq <= 0.0)
+    throw std::out_of_range ("gr_firdes check failed: sampling_freq > 0");
+
+  if (fa < -sampling_freq / 2 || fa > sampling_freq / 2)
+    throw std::out_of_range ("gr_firdes check failed: 0 < fa <= sampling_freq / 2");
+  
+  if (fb < -sampling_freq / 2  || fb > sampling_freq / 2)
+    throw std::out_of_range ("gr_firdes check failed: 0 < fb <= sampling_freq / 2");
+  
+  if (fa > fb)
+    throw std::out_of_range ("gr_firdes check failed: fa <= fb");
+  
+  if (transition_width <= 0)
+    throw std::out_of_range ("gr_firdes check failed: transition_width > 0");
+}
diff --git a/gnuradio-core/src/lib/general/gr_firdes.h b/gnuradio-core/src/lib/general/gr_firdes.h
new file mode 100644 (file)
index 0000000..734f8ee
--- /dev/null
@@ -0,0 +1,225 @@
+/* -*- 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 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.
+ */
+
+#ifndef _GR_FIRDES_H_
+#define _GR_FIRDES_H_
+
+#include <vector>
+#include <cmath>
+#include <gr_complex.h>
+
+/*!
+ * \brief Finite Impulse Response (FIR) filter design functions.
+ */
+
+class gr_firdes {
+ public:
+
+  enum win_type {
+    WIN_HAMMING = 0,   // max attenuation 53 dB
+    WIN_HANN = 1,      // max attenuation 44 dB
+    WIN_BLACKMAN = 2,  // max attenuation 74 dB
+    WIN_RECTANGULAR = 3,
+    WIN_KAISER = 4      // max attenuation a function of beta, google it
+  };
+
+
+  // ... class methods ...
+
+  /*!
+   * \brief use "window method" to design a low-pass FIR filter
+   *
+   * \p gain:                  overall gain of filter (typically 1.0)
+   * \p sampling_freq:         sampling freq (Hz)
+   * \p cutoff_freq:           center of transition band (Hz)
+   * \p transition_width:      width of transition band (Hz).
+   *                           The normalized width of the transition
+   *                           band is what sets the number of taps
+   *                           required.  Narrow --> more taps
+   * \p window_type:           What kind of window to use. Determines
+   *                           maximum attenuation and passband ripple.
+   * \p beta:                  parameter for Kaiser window
+   */
+  static std::vector<float>
+  low_pass (double gain,
+           double sampling_freq,
+           double cutoff_freq,         // Hz center of transition band
+           double transition_width,    // Hz width of transition band
+           win_type window = WIN_HAMMING,
+           double beta = 6.76);                // used only with Kaiser
+
+  /*!
+   * \brief use "window method" to design a high-pass FIR filter
+   *
+   * \p gain:                  overall gain of filter (typically 1.0)
+   * \p sampling_freq:         sampling freq (Hz)
+   * \p cutoff_freq:           center of transition band (Hz)
+   * \p transition_width:      width of transition band (Hz).
+   *                           The normalized width of the transition
+   *                           band is what sets the number of taps
+   *                           required.  Narrow --> more taps
+   * \p window_type:           What kind of window to use. Determines
+   *                           maximum attenuation and passband ripple.
+   * \p beta:                  parameter for Kaiser window
+   */
+  static std::vector<float>
+  high_pass (double gain,
+            double sampling_freq,
+            double cutoff_freq,                // Hz center of transition band
+            double transition_width,           // Hz width of transition band
+            win_type window = WIN_HAMMING,
+            double beta = 6.76);               // used only with Kaiser
+
+  /*!
+   * \brief use "window method" to design a band-pass FIR filter
+   *
+   * \p gain:                  overall gain of filter (typically 1.0)
+   * \p sampling_freq:         sampling freq (Hz)
+   * \p low_cutoff_freq:       center of transition band (Hz)
+   * \p high_cutoff_freq:      center of transition band (Hz)
+   * \p transition_width:      width of transition band (Hz).
+   *                           The normalized width of the transition
+   *                           band is what sets the number of taps
+   *                           required.  Narrow --> more taps
+   * \p window_type:           What kind of window to use. Determines
+   *                           maximum attenuation and passband ripple.
+   * \p beta:                  parameter for Kaiser window
+   */
+  static std::vector<float>
+  band_pass (double gain,
+            double sampling_freq,
+            double low_cutoff_freq,            // Hz center of transition band
+            double high_cutoff_freq,           // Hz center of transition band
+            double transition_width,           // Hz width of transition band
+            win_type window = WIN_HAMMING,
+            double beta = 6.76);               // used only with Kaiser
+
+
+  /*!
+   * \brief use "window method" to design a complex band-pass FIR filter
+   *
+   * \p gain:                  overall gain of filter (typically 1.0)
+   * \p sampling_freq:         sampling freq (Hz)
+   * \p low_cutoff_freq:       center of transition band (Hz)
+   * \p high_cutoff_freq:      center of transition band (Hz)
+   * \p transition_width:      width of transition band (Hz).
+   *                           The normalized width of the transition
+   *                           band is what sets the number of taps
+   *                           required.  Narrow --> more taps
+   * \p window_type:           What kind of window to use. Determines
+   *                           maximum attenuation and passband ripple.
+   * \p beta:                  parameter for Kaiser window
+   */
+
+  static std::vector<gr_complex>
+  complex_band_pass (double gain,
+            double sampling_freq,
+            double low_cutoff_freq,            // Hz center of transition band
+            double high_cutoff_freq,           // Hz center of transition band
+            double transition_width,           // Hz width of transition band
+            win_type window = WIN_HAMMING,
+            double beta = 6.76);               // used only with Kaiser
+
+
+  /*!
+   * \brief use "window method" to design a band-reject FIR filter
+   *
+   * \p gain:                  overall gain of filter (typically 1.0)
+   * \p sampling_freq:         sampling freq (Hz)
+   * \p low_cutoff_freq:       center of transition band (Hz)
+   * \p high_cutoff_freq:      center of transition band (Hz)
+   * \p transition_width:      width of transition band (Hz).
+   *                           The normalized width of the transition
+   *                           band is what sets the number of taps
+   *                           required.  Narrow --> more taps
+   * \p window_type:           What kind of window to use. Determines
+   *                           maximum attenuation and passband ripple.
+   * \p beta:                  parameter for Kaiser window
+   */
+
+  static std::vector<float>
+  band_reject (double gain,
+              double sampling_freq,
+              double low_cutoff_freq,          // Hz center of transition band
+              double high_cutoff_freq,         // Hz center of transition band
+              double transition_width,         // Hz width of transition band
+              win_type window = WIN_HAMMING,
+              double beta = 6.76);             // used only with Kaiser
+
+  /*!\brief design a Hilbert Transform Filter
+   *
+   * \p ntaps:                  Number of taps, must be odd
+   * \p window_type:            What kind of window to use
+   * \p beta:                   Only used for Kaiser
+   */
+  static std::vector<float>
+  hilbert (unsigned int ntaps,
+          win_type windowtype = WIN_RECTANGULAR,
+          double beta = 6.76);
+   
+  /*!
+   * \brief design a Root Cosine FIR Filter (do we need a window?)
+   *
+   * \p gain:                  overall gain of filter (typically 1.0)
+   * \p sampling_freq:         sampling freq (Hz)
+   * \p symbol rate:           symbol rate, must be a factor of sample rate
+   * \p alpha:                 excess bandwidth factor
+   * \p ntaps:                 number of taps
+   */
+  static std::vector<float>
+  root_raised_cosine (double gain,
+                     double sampling_freq,
+                     double symbol_rate,       // Symbol rate, NOT bitrate (unless BPSK)
+                     double alpha,             // Excess Bandwidth Factor
+                     int ntaps);
+
+  /*!
+   * \brief design a Gaussian filter
+   *
+   * \p gain:                  overall gain of filter (typically 1.0)
+   * \p symbols per bit:       symbol rate, must be a factor of sample rate
+   * \p ntaps:                 number of taps
+   */
+  static std::vector<float>
+  gaussian (double gain,
+           double spb,       
+           double bt,              // Bandwidth to bitrate ratio
+           int ntaps);
+
+  // window functions ...
+  static std::vector<float> window (win_type type, int ntaps, double beta);
+
+private:
+  static double bessi0(double x);
+  static void sanity_check_1f (double sampling_freq, double f1,
+                              double transition_width);
+  static void sanity_check_2f (double sampling_freq, double f1, double f2,
+                              double transition_width);
+  static void sanity_check_2f_c (double sampling_freq, double f1, double f2,
+                              double transition_width);
+
+  static int compute_ntaps (double sampling_freq,
+                           double transition_width,
+                           win_type window_type, double beta);
+};
+
+#endif
diff --git a/gnuradio-core/src/lib/general/gr_firdes.i b/gnuradio-core/src/lib/general/gr_firdes.i
new file mode 100644 (file)
index 0000000..a0ea2f4
--- /dev/null
@@ -0,0 +1,187 @@
+/* -*- C++ -*- */
+
+/*!
+ * \brief Finite Impulse Response (FIR) filter design functions.
+ */
+
+%rename(firdes) gr_firdes;
+
+class gr_firdes {
+ public:
+
+  enum win_type {
+    WIN_HAMMING = 0,   // max attenuation 53 dB
+    WIN_HANN = 1,      // max attenuation 44 dB
+    WIN_BLACKMAN = 2,  // max attenuation 74 dB
+    WIN_RECTANGULAR = 3,
+    WIN_KAISER = 4      // max attenuation variable with beta, google it
+  };
+
+  // ... class methods ...
+
+  /*!
+   * \brief use "window method" to design a low-pass FIR filter
+   *
+   * \p gain:                  overall gain of filter (typically 1.0)
+   * \p sampling_freq:         sampling freq (Hz)
+   * \p cutoff_freq:           center of transition band (Hz)
+   * \p transition_width:      width of transition band (Hz).
+   *                           The normalized width of the transition
+   *                           band is what sets the number of taps
+   *                           required.  Narrow --> more taps
+   * \p window_type:           What kind of window to use. Determines
+   *                           maximum attenuation and passband ripple.
+   * \p beta:                  parameter for Kaiser window
+   */
+  static std::vector<float>
+  low_pass (double gain,
+           double sampling_freq,
+           double cutoff_freq,         // Hz center of transition band
+           double transition_width,    // Hz width of transition band
+           win_type window = WIN_HAMMING,
+           double beta = 6.76);                // used only with Kaiser
+
+  /*!
+   * \brief use "window method" to design a high-pass FIR filter
+   *
+   * \p gain:                  overall gain of filter (typically 1.0)
+   * \p sampling_freq:         sampling freq (Hz)
+   * \p cutoff_freq:           center of transition band (Hz)
+   * \p transition_width:      width of transition band (Hz).
+   *                           The normalized width of the transition
+   *                           band is what sets the number of taps
+   *                           required.  Narrow --> more taps
+   * \p window_type:           What kind of window to use. Determines
+   *                           maximum attenuation and passband ripple.
+   * \p beta:                  parameter for Kaiser window
+   */
+  static std::vector<float>
+  high_pass (double gain,
+            double sampling_freq,
+            double cutoff_freq,                // Hz center of transition band
+            double transition_width,           // Hz width of transition band
+            win_type window = WIN_HAMMING,
+            double beta = 6.76);               // used only with Kaiser
+
+  /*!
+   * \brief use "window method" to design a band-pass FIR filter
+   *
+   * \p gain:                  overall gain of filter (typically 1.0)
+   * \p sampling_freq:         sampling freq (Hz)
+   * \p low_cutoff_freq:       center of transition band (Hz)
+   * \p high_cutoff_freq:      center of transition band (Hz)
+   * \p transition_width:      width of transition band (Hz).
+   *                           The normalized width of the transition
+   *                           band is what sets the number of taps
+   *                           required.  Narrow --> more taps
+   * \p window_type:           What kind of window to use. Determines
+   *                           maximum attenuation and passband ripple.
+   * \p beta:                  parameter for Kaiser window
+   */
+  static std::vector<float>
+  band_pass (double gain,
+            double sampling_freq,
+            double low_cutoff_freq,            // Hz center of transition band
+            double high_cutoff_freq,           // Hz center of transition band
+            double transition_width,           // Hz width of transition band
+            win_type window = WIN_HAMMING,
+            double beta = 6.76);               // used only with Kaiser
+
+
+  /*!
+   * \brief use "window method" to design a band-reject FIR filter
+   *
+   * \p gain:                  overall gain of filter (typically 1.0)
+   * \p sampling_freq:         sampling freq (Hz)
+   * \p low_cutoff_freq:       center of transition band (Hz)
+   * \p high_cutoff_freq:      center of transition band (Hz)
+   * \p transition_width:      width of transition band (Hz).
+   *                           The normalized width of the transition
+   *                           band is what sets the number of taps
+   *                           required.  Narrow --> more taps
+   * \p window_type:           What kind of window to use. Determines
+   *                           maximum attenuation and passband ripple.
+   * \p beta:                  parameter for Kaiser window
+   */
+
+  static std::vector<gr_complex>
+  complex_band_pass (double gain,
+            double sampling_freq,
+            double low_cutoff_freq,            // Hz center of transition band
+            double high_cutoff_freq,           // Hz center of transition band
+            double transition_width,           // Hz width of transition band
+            win_type window = WIN_HAMMING,
+            double beta = 6.76);               // used only with Kaiser
+
+
+  /*!
+   * \brief use "window method" to design a band-reject FIR filter
+   *
+   * \p gain:                  overall gain of filter (typically 1.0)
+   * \p sampling_freq:         sampling freq (Hz)
+   * \p low_cutoff_freq:       center of transition band (Hz)
+   * \p high_cutoff_freq:      center of transition band (Hz)
+   * \p transition_width:      width of transition band (Hz).
+   *                           The normalized width of the transition
+   *                           band is what sets the number of taps
+   *                           required.  Narrow --> more taps
+   * \p window_type:           What kind of window to use. Determines
+   *                           maximum attenuation and passband ripple.
+   * \p beta:                  parameter for Kaiser window
+   */
+
+  static std::vector<float>
+  band_reject (double gain,
+              double sampling_freq,
+              double low_cutoff_freq,          // Hz center of transition band
+              double high_cutoff_freq,         // Hz center of transition band
+              double transition_width,         // Hz width of transition band
+              win_type window = WIN_HAMMING,
+              double beta = 6.76);             // used only with Kaiser
+
+  /*!\brief design a Hilbert Transform Filter
+   *
+   * \p ntaps:                  Number of taps, must be odd
+   * \p window_type:            What kind of window to use
+   * \p beta:                   Only used for Kaiser
+   */
+  static std::vector<float>
+  hilbert (unsigned int ntaps,
+          win_type windowtype = WIN_RECTANGULAR,
+          double beta = 6.76);
+   
+  /*!
+   * \brief design a Root Cosine FIR Filter (do we need a window?)
+   *
+   * \p gain:                  overall gain of filter (typically 1.0)
+   * \p sampling_freq:         sampling freq (Hz)
+   * \p symbol rate:           symbol rate, must be a factor of sample rate
+   * \p alpha:                 excess bandwidth factor
+   * \p ntaps:                 number of taps
+   */
+  static std::vector<float>
+  root_raised_cosine (double gain,
+                     double sampling_freq,
+                     double symbol_rate,       // Symbol rate, NOT bitrate (unless BPSK)
+                     double alpha,             // Excess Bandwidth Factor
+                     int ntaps);
+
+  /*!
+   * \brief design a Gaussian filter
+   *
+   * \p gain:                  overall gain of filter (typically 1.0)
+   * \p symbols per bit:       symbol rate, must be a factor of sample rate
+   * \p bt:                     BT bandwidth time product
+   * \p ntaps:                 number of taps
+   */
+  static std::vector<float>
+  gaussian (double gain,
+           double spb,       
+           double bt,              // Bandwidth to bitrate ratio
+           int ntaps);
+
+  /*!
+   * Return window given type, ntaps and optional beta.
+   */
+  static std::vector<float> gr_firdes::window (win_type type, int ntaps, double beta);
+};
diff --git a/gnuradio-core/src/lib/general/gr_float_to_char.cc b/gnuradio-core/src/lib/general/gr_float_to_char.cc
new file mode 100644 (file)
index 0000000..ed9538f
--- /dev/null
@@ -0,0 +1,58 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_float_to_char.h>
+#include <gr_io_signature.h>
+#include <gri_float_to_char.h>
+
+gr_float_to_char_sptr
+gr_make_float_to_char ()
+{
+  return gr_float_to_char_sptr (new gr_float_to_char ());
+}
+
+gr_float_to_char::gr_float_to_char ()
+  : gr_sync_block ("gr_float_to_char",
+                  gr_make_io_signature (1, 1, sizeof (float)),
+                  gr_make_io_signature (1, 1, sizeof (char)))
+{
+}
+
+int
+gr_float_to_char::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];
+  char *out = (char *) output_items[0];
+
+  gri_float_to_char (in, out, noutput_items);
+  
+  return noutput_items;
+}
+
+
+
diff --git a/gnuradio-core/src/lib/general/gr_float_to_char.h b/gnuradio-core/src/lib/general/gr_float_to_char.h
new file mode 100644 (file)
index 0000000..e1d0f9f
--- /dev/null
@@ -0,0 +1,51 @@
+/* -*- 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 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.
+ */
+
+#ifndef INCLUDED_GR_FLOAT_TO_CHAR_H
+#define INCLUDED_GR_FLOAT_TO_CHAR_H
+
+#include <gr_sync_block.h>
+
+class gr_float_to_char;
+typedef boost::shared_ptr<gr_float_to_char> gr_float_to_char_sptr;
+
+gr_float_to_char_sptr
+gr_make_float_to_char ();
+
+/*!
+ * \brief Convert stream of float to a stream of char
+ * \ingroup converter
+ */
+
+class gr_float_to_char : public gr_sync_block
+{
+  friend gr_float_to_char_sptr gr_make_float_to_char ();
+  gr_float_to_char ();
+
+ public:
+  virtual int work (int noutput_items,
+                   gr_vector_const_void_star &input_items,
+                   gr_vector_void_star &output_items);
+};
+
+
+#endif /* INCLUDED_GR_FLOAT_TO_CHAR_H */
diff --git a/gnuradio-core/src/lib/general/gr_float_to_char.i b/gnuradio-core/src/lib/general/gr_float_to_char.i
new file mode 100644 (file)
index 0000000..139439c
--- /dev/null
@@ -0,0 +1,30 @@
+/* -*- 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 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.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,float_to_char)
+
+gr_float_to_char_sptr gr_make_float_to_char ();
+
+class gr_float_to_char : public gr_sync_block
+{
+  gr_float_to_char ();
+};
diff --git a/gnuradio-core/src/lib/general/gr_float_to_complex.cc b/gnuradio-core/src/lib/general/gr_float_to_complex.cc
new file mode 100644 (file)
index 0000000..547d917
--- /dev/null
@@ -0,0 +1,71 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_float_to_complex.h>
+#include <gr_io_signature.h>
+
+gr_float_to_complex_sptr
+gr_make_float_to_complex ()
+{
+  return gr_float_to_complex_sptr (new gr_float_to_complex ());
+}
+
+gr_float_to_complex::gr_float_to_complex ()
+  : gr_sync_block ("gr_float_to_complex",
+                  gr_make_io_signature (1, 2, sizeof (float)),
+                  gr_make_io_signature (1, 1, sizeof (gr_complex)))
+{
+}
+
+int
+gr_float_to_complex::work (int noutput_items,
+                          gr_vector_const_void_star &input_items,
+                          gr_vector_void_star &output_items)
+{
+  float        *r = (float *)input_items[0];
+  float *i = (float *)input_items[1];
+  gr_complex *out = (gr_complex *) output_items[0];
+
+  switch (input_items.size ()){
+  case 1:
+    for (int j = 0; j < noutput_items; j++)
+      out[j] = gr_complex (r[j], 0);
+    break;
+
+  case 2:
+    for (int j = 0; j < noutput_items; j++)
+      out[j] = gr_complex (r[j], i[j]);
+    break;
+
+  default:
+    assert (0);
+  }
+
+  return noutput_items;
+}
+
+
+
diff --git a/gnuradio-core/src/lib/general/gr_float_to_complex.h b/gnuradio-core/src/lib/general/gr_float_to_complex.h
new file mode 100644 (file)
index 0000000..8c28521
--- /dev/null
@@ -0,0 +1,52 @@
+/* -*- 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 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.
+ */
+
+#ifndef INCLUDED_GR_FLOAT_TO_COMPLEX_H
+#define INCLUDED_GR_FLOAT_TO_COMPLEX_H
+
+#include <gr_sync_block.h>
+#include <gr_complex.h>
+
+class gr_float_to_complex;
+typedef boost::shared_ptr<gr_float_to_complex> gr_float_to_complex_sptr;
+
+gr_float_to_complex_sptr
+gr_make_float_to_complex ();
+
+/*!
+ * \brief Convert 1 or 2 streams of float to a stream of gr_complex
+ * \ingroup converter
+ */
+
+class gr_float_to_complex : public gr_sync_block
+{
+  friend gr_float_to_complex_sptr gr_make_float_to_complex ();
+  gr_float_to_complex ();
+
+ public:
+  virtual int work (int noutput_items,
+                   gr_vector_const_void_star &input_items,
+                   gr_vector_void_star &output_items);
+};
+
+
+#endif /* INCLUDED_GR_FLOAT_TO_COMPLEX_H */
diff --git a/gnuradio-core/src/lib/general/gr_float_to_complex.i b/gnuradio-core/src/lib/general/gr_float_to_complex.i
new file mode 100644 (file)
index 0000000..4a6ea32
--- /dev/null
@@ -0,0 +1,30 @@
+/* -*- 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 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.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,float_to_complex)
+
+gr_float_to_complex_sptr gr_make_float_to_complex ();
+
+class gr_float_to_complex : public gr_sync_block
+{
+  gr_float_to_complex ();
+};
diff --git a/gnuradio-core/src/lib/general/gr_float_to_short.cc b/gnuradio-core/src/lib/general/gr_float_to_short.cc
new file mode 100644 (file)
index 0000000..171726b
--- /dev/null
@@ -0,0 +1,58 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_float_to_short.h>
+#include <gr_io_signature.h>
+#include <gri_float_to_short.h>
+
+gr_float_to_short_sptr
+gr_make_float_to_short ()
+{
+  return gr_float_to_short_sptr (new gr_float_to_short ());
+}
+
+gr_float_to_short::gr_float_to_short ()
+  : gr_sync_block ("gr_float_to_short",
+                  gr_make_io_signature (1, 1, sizeof (float)),
+                  gr_make_io_signature (1, 1, sizeof (short)))
+{
+}
+
+int
+gr_float_to_short::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];
+  short *out = (short *) output_items[0];
+
+  gri_float_to_short (in, out, noutput_items);
+  
+  return noutput_items;
+}
+
+
+
diff --git a/gnuradio-core/src/lib/general/gr_float_to_short.h b/gnuradio-core/src/lib/general/gr_float_to_short.h
new file mode 100644 (file)
index 0000000..75fdd94
--- /dev/null
@@ -0,0 +1,51 @@
+/* -*- 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 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.
+ */
+
+#ifndef INCLUDED_GR_FLOAT_TO_SHORT_H
+#define INCLUDED_GR_FLOAT_TO_SHORT_H
+
+#include <gr_sync_block.h>
+
+class gr_float_to_short;
+typedef boost::shared_ptr<gr_float_to_short> gr_float_to_short_sptr;
+
+gr_float_to_short_sptr
+gr_make_float_to_short ();
+
+/*!
+ * \brief Convert stream of float to a stream of short
+ * \ingroup converter
+ */
+
+class gr_float_to_short : public gr_sync_block
+{
+  friend gr_float_to_short_sptr gr_make_float_to_short ();
+  gr_float_to_short ();
+
+ public:
+  virtual int work (int noutput_items,
+                   gr_vector_const_void_star &input_items,
+                   gr_vector_void_star &output_items);
+};
+
+
+#endif /* INCLUDED_GR_FLOAT_TO_SHORT_H */
diff --git a/gnuradio-core/src/lib/general/gr_float_to_short.i b/gnuradio-core/src/lib/general/gr_float_to_short.i
new file mode 100644 (file)
index 0000000..10726bc
--- /dev/null
@@ -0,0 +1,30 @@
+/* -*- 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 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.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,float_to_short)
+
+gr_float_to_short_sptr gr_make_float_to_short ();
+
+class gr_float_to_short : public gr_sync_block
+{
+  gr_float_to_short ();
+};
diff --git a/gnuradio-core/src/lib/general/gr_float_to_uchar.cc b/gnuradio-core/src/lib/general/gr_float_to_uchar.cc
new file mode 100644 (file)
index 0000000..d940242
--- /dev/null
@@ -0,0 +1,58 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_float_to_uchar.h>
+#include <gr_io_signature.h>
+#include <gri_float_to_uchar.h>
+
+gr_float_to_uchar_sptr
+gr_make_float_to_uchar ()
+{
+  return gr_float_to_uchar_sptr (new gr_float_to_uchar ());
+}
+
+gr_float_to_uchar::gr_float_to_uchar ()
+  : gr_sync_block ("gr_float_to_uchar",
+                  gr_make_io_signature (1, 1, sizeof (float)),
+                  gr_make_io_signature (1, 1, sizeof (unsigned char)))
+{
+}
+
+int
+gr_float_to_uchar::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];
+  unsigned char *out = (unsigned char *) output_items[0];
+
+  gri_float_to_uchar (in, out, noutput_items);
+  
+  return noutput_items;
+}
+
+
+
diff --git a/gnuradio-core/src/lib/general/gr_float_to_uchar.h b/gnuradio-core/src/lib/general/gr_float_to_uchar.h
new file mode 100644 (file)
index 0000000..bab00c4
--- /dev/null
@@ -0,0 +1,51 @@
+/* -*- 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 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.
+ */
+
+#ifndef INCLUDED_GR_FLOAT_TO_UCHAR_H
+#define INCLUDED_GR_FLOAT_TO_UCHAR_H
+
+#include <gr_sync_block.h>
+
+class gr_float_to_uchar;
+typedef boost::shared_ptr<gr_float_to_uchar> gr_float_to_uchar_sptr;
+
+gr_float_to_uchar_sptr
+gr_make_float_to_uchar ();
+
+/*!
+ * \brief Convert stream of float to a stream of unsigned char
+ * \ingroup converter
+ */
+
+class gr_float_to_uchar : public gr_sync_block
+{
+  friend gr_float_to_uchar_sptr gr_make_float_to_uchar ();
+  gr_float_to_uchar ();
+
+ public:
+  virtual int work (int noutput_items,
+                   gr_vector_const_void_star &input_items,
+                   gr_vector_void_star &output_items);
+};
+
+
+#endif /* INCLUDED_GR_FLOAT_TO_UCHAR_H */
diff --git a/gnuradio-core/src/lib/general/gr_float_to_uchar.i b/gnuradio-core/src/lib/general/gr_float_to_uchar.i
new file mode 100644 (file)
index 0000000..8c0ee58
--- /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 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.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,float_to_uchar)
+
+gr_float_to_uchar_sptr gr_make_float_to_uchar ();
+
+class gr_float_to_uchar : public gr_sync_block
+{
+  gr_float_to_uchar ();
+};
diff --git a/gnuradio-core/src/lib/general/gr_framer_sink_1.cc b/gnuradio-core/src/lib/general/gr_framer_sink_1.cc
new file mode 100644 (file)
index 0000000..c1afc43
--- /dev/null
@@ -0,0 +1,175 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_framer_sink_1.h>
+#include <gr_io_signature.h>
+#include <cstdio>
+#include <stdexcept>
+
+#define VERBOSE 0
+
+inline void
+gr_framer_sink_1::enter_search()
+{
+  if (VERBOSE)
+    fprintf(stderr, "@ enter_search\n");
+
+  d_state = STATE_SYNC_SEARCH;
+}
+    
+inline void
+gr_framer_sink_1::enter_have_sync()
+{
+  if (VERBOSE)
+    fprintf(stderr, "@ enter_have_sync\n");
+
+  d_state = STATE_HAVE_SYNC;
+  d_header = 0;
+  d_headerbitlen_cnt = 0;
+}
+
+inline void
+gr_framer_sink_1::enter_have_header(int payload_len)
+{
+  if (VERBOSE)
+    fprintf(stderr, "@ enter_have_header (payload_len = %d)\n", payload_len);
+
+  d_state = STATE_HAVE_HEADER;
+  d_packetlen = payload_len;
+  d_packetlen_cnt = 0;
+  d_packet_byte = 0;
+  d_packet_byte_index = 0;
+}
+
+gr_framer_sink_1_sptr
+gr_make_framer_sink_1(gr_msg_queue_sptr target_queue)
+{
+  return gr_framer_sink_1_sptr(new gr_framer_sink_1(target_queue));
+}
+
+
+gr_framer_sink_1::gr_framer_sink_1(gr_msg_queue_sptr target_queue)
+  : gr_sync_block ("framer_sink_1",
+                  gr_make_io_signature (1, 1, sizeof(unsigned char)),
+                  gr_make_io_signature (0, 0, 0)),
+    d_target_queue(target_queue)
+{
+  enter_search();
+}
+
+gr_framer_sink_1::~gr_framer_sink_1 ()
+{
+}
+
+int
+gr_framer_sink_1::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];
+  int count=0;
+  
+  if (VERBOSE)
+    fprintf(stderr,">>> Entering state machine\n");
+
+  while (count < noutput_items){
+    switch(d_state) {
+      
+    case STATE_SYNC_SEARCH:    // Look for flag indicating beginning of pkt
+      if (VERBOSE)
+       fprintf(stderr,"SYNC Search, noutput=%d\n", noutput_items);
+
+      while (count < noutput_items) {
+       if (in[count] & 0x2){  // Found it, set up for header decode
+         enter_have_sync();
+         break;
+       }
+       count++;
+      }
+      break;
+
+    case STATE_HAVE_SYNC:
+      if (VERBOSE)
+       fprintf(stderr,"Header Search bitcnt=%d, header=0x%08x\n",
+               d_headerbitlen_cnt, d_header);
+
+      while (count < noutput_items) {  // Shift bits one at a time into header
+       d_header = (d_header << 1) | (in[count++] & 0x1);
+       if (++d_headerbitlen_cnt == HEADERBITLEN) {
+
+         if (VERBOSE)
+           fprintf(stderr, "got header: 0x%08x\n", d_header);
+
+         // we have a full header, check to see if it has been received properly
+         if (header_ok()){
+           int payload_len = header_payload_len();
+           if (payload_len <= MAX_PKT_LEN)             // reasonable?
+             enter_have_header(payload_len);           // yes.
+           else
+             enter_search();                           // no.
+         }
+         else
+           enter_search();                             // no.
+         break;                        // we're in a new state
+       }
+      }
+      break;
+      
+    case STATE_HAVE_HEADER:
+      if (VERBOSE)
+       fprintf(stderr,"Packet Build\n");
+
+      while (count < noutput_items) {   // shift bits into bytes of packet one at a time
+       d_packet_byte = (d_packet_byte << 1) | (in[count++] & 0x1);
+       if (d_packet_byte_index++ == 7) {               // byte is full so move to next byte
+         d_packet[d_packetlen_cnt++] = d_packet_byte;
+         d_packet_byte_index = 0;
+
+         if (d_packetlen_cnt == d_packetlen){          // packet is filled
+
+           // build a message
+           gr_message_sptr msg = gr_make_message(0, 0, 0, d_packetlen_cnt);        
+           memcpy(msg->msg(), d_packet, d_packetlen_cnt);
+
+           d_target_queue->insert_tail(msg);           // send it
+           msg.reset();                                // free it up
+
+           enter_search();
+           break;
+         }
+       }
+      }
+      break;
+
+    default:
+      assert(0);
+
+    } // switch
+
+  }   // while
+
+  return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_framer_sink_1.h b/gnuradio-core/src/lib/general/gr_framer_sink_1.h
new file mode 100644 (file)
index 0000000..3e38aee
--- /dev/null
@@ -0,0 +1,103 @@
+/* -*- c++ -*- */
+/*
+ * 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 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.
+ */
+
+#ifndef INCLUDED_GR_FRAMER_SINK_1_H
+#define INCLUDED_GR_FRAMER_SINK_1_H
+
+#include <gr_sync_block.h>
+#include <gr_msg_queue.h>
+
+class gr_framer_sink_1;
+typedef boost::shared_ptr<gr_framer_sink_1> gr_framer_sink_1_sptr;
+
+gr_framer_sink_1_sptr 
+gr_make_framer_sink_1 (gr_msg_queue_sptr target_queue);
+
+/*!
+ * \brief Given a stream of bits and access_code flags, assemble packets.
+ * \ingroup sink
+ *
+ * input: stream of bytes from gr_correlate_access_code_bb
+ * output: none.  Pushes assembled packet into target queue
+ *
+ * The framer expects a fixed length header of 2 16-bit shorts
+ * containing the payload length, followed by the payload.  If the 
+ * 2 16-bit shorts are not identical, this packet is ignored.  Better
+ * algs are welcome.
+ *
+ * The input data consists of bytes that have two bits used.
+ * Bit 0, the LSB, contains the data bit.
+ * Bit 1 if set, indicates that the corresponding bit is the
+ * the first bit of the packet.  That is, this bit is the first
+ * one after the access code.
+ */
+class gr_framer_sink_1 : public gr_sync_block
+{
+  friend gr_framer_sink_1_sptr 
+  gr_make_framer_sink_1 (gr_msg_queue_sptr target_queue);
+
+ private:
+  enum state_t {STATE_SYNC_SEARCH, STATE_HAVE_SYNC, STATE_HAVE_HEADER};
+
+  static const int MAX_PKT_LEN    = 4096;
+  static const int HEADERBITLEN   = 32;
+
+  gr_msg_queue_sptr  d_target_queue;           // where to send the packet when received
+  state_t            d_state;
+  unsigned int       d_header;                 // header bits
+  int               d_headerbitlen_cnt;        // how many so far
+
+  unsigned char      d_packet[MAX_PKT_LEN];    // assembled payload
+  unsigned char             d_packet_byte;             // byte being assembled
+  int               d_packet_byte_index;       // which bit of d_packet_byte we're working on
+  int               d_packetlen;               // length of packet
+  int               d_packetlen_cnt;           // how many so far
+
+ protected:
+  gr_framer_sink_1(gr_msg_queue_sptr target_queue);
+
+  void enter_search();
+  void enter_have_sync();
+  void enter_have_header(int payload_len);
+  
+  bool header_ok()
+  {
+    // confirm that two copies of header info are identical
+    return ((d_header >> 16) ^ (d_header & 0xffff)) == 0;
+  }
+
+  int header_payload_len()
+  {
+    // header consists of two 16-bit shorts in network byte order
+    int t = (d_header >> 16) & 0xffff;
+    return t;
+  }
+
+ public:
+  ~gr_framer_sink_1();
+
+  int work(int noutput_items,
+          gr_vector_const_void_star &input_items,
+          gr_vector_void_star &output_items);
+};
+
+#endif /* INCLUDED_GR_FRAMER_SINK_1_H */
diff --git a/gnuradio-core/src/lib/general/gr_framer_sink_1.i b/gnuradio-core/src/lib/general/gr_framer_sink_1.i
new file mode 100644 (file)
index 0000000..fbc5569
--- /dev/null
@@ -0,0 +1,35 @@
+/* -*- 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 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.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,framer_sink_1);
+
+gr_framer_sink_1_sptr 
+gr_make_framer_sink_1(gr_msg_queue_sptr target_queue);
+
+class gr_framer_sink_1 : public gr_sync_block
+{
+ protected:
+  gr_framer_sink_1(gr_msg_queue_sptr target_queue);
+
+ public:
+  ~gr_framer_sink_1();
+};
diff --git a/gnuradio-core/src/lib/general/gr_frequency_modulator_fc.cc b/gnuradio-core/src/lib/general/gr_frequency_modulator_fc.cc
new file mode 100644 (file)
index 0000000..271b8d3
--- /dev/null
@@ -0,0 +1,70 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_frequency_modulator_fc.h>
+#include <gr_io_signature.h>
+#include <gr_sincos.h>
+#include <math.h>
+
+
+gr_frequency_modulator_fc_sptr gr_make_frequency_modulator_fc (double sensitivity)
+{
+  return gr_frequency_modulator_fc_sptr (new gr_frequency_modulator_fc (sensitivity));
+}
+
+gr_frequency_modulator_fc::gr_frequency_modulator_fc (double sensitivity)
+  : gr_sync_block ("frequency_modulator_fc",
+                  gr_make_io_signature (1, 1, sizeof (float)),
+                  gr_make_io_signature (1, 1, sizeof (gr_complex))),
+    d_sensitivity (sensitivity), d_phase (0)
+{
+}
+
+int
+gr_frequency_modulator_fc::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];
+  gr_complex *out = (gr_complex *) output_items[0];
+
+  for (int i = 0; i < noutput_items; i++){
+    d_phase = d_phase + d_sensitivity * in[i];
+    float oi, oq;
+    gr_sincosf (d_phase, &oq, &oi);
+    out[i] = gr_complex (oi, oq);
+  }
+
+  // Limit the phase accumulator to [-16*pi,16*pi]
+  // to avoid loss of precision in the addition above.
+
+  if (fabs (d_phase) > 16 * M_PI){
+    double ii = trunc (d_phase / (2 * M_PI));
+    d_phase = d_phase - (ii * 2 * M_PI);
+  }
+
+  return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_frequency_modulator_fc.h b/gnuradio-core/src/lib/general/gr_frequency_modulator_fc.h
new file mode 100644 (file)
index 0000000..6080adb
--- /dev/null
@@ -0,0 +1,56 @@
+/* -*- 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 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.
+ */
+
+#ifndef INCLUDED_GR_FREQUENCY_MODULATOR_FC_H
+#define INCLUDED_GR_FREQUENCY_MODULATOR_FC_H
+
+#include <gr_sync_block.h>
+
+class gr_frequency_modulator_fc;
+typedef boost::shared_ptr<gr_frequency_modulator_fc> gr_frequency_modulator_fc_sptr;
+
+gr_frequency_modulator_fc_sptr gr_make_frequency_modulator_fc (double sensitivity);
+
+/*!
+ * \brief Frequency modulator block
+ * \ingroup block
+ *
+ * float input; complex baseband output
+ */
+class gr_frequency_modulator_fc : public gr_sync_block
+{
+  double       d_sensitivity;
+  double       d_phase;
+
+  friend gr_frequency_modulator_fc_sptr
+  gr_make_frequency_modulator_fc (double sensitivity);
+
+  gr_frequency_modulator_fc (double sensitivity);
+
+ public:
+
+  int work (int noutput_items,
+           gr_vector_const_void_star &input_items,
+           gr_vector_void_star &output_items);
+};
+
+#endif /* INCLUDED_GR_FREQUENCY_MODULATOR_FC_H */
diff --git a/gnuradio-core/src/lib/general/gr_frequency_modulator_fc.i b/gnuradio-core/src/lib/general/gr_frequency_modulator_fc.i
new file mode 100644 (file)
index 0000000..04a8b53
--- /dev/null
@@ -0,0 +1,31 @@
+/* -*- 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 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.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,frequency_modulator_fc)
+
+gr_frequency_modulator_fc_sptr gr_make_frequency_modulator_fc (double sensitivity);
+
+class gr_frequency_modulator_fc : public gr_sync_block
+{
+ private:
+  gr_frequency_modulator_fc (double sensitivity);
+};
diff --git a/gnuradio-core/src/lib/general/gr_fxpt.cc b/gnuradio-core/src/lib/general/gr_fxpt.cc
new file mode 100644 (file)
index 0000000..62ed8bd
--- /dev/null
@@ -0,0 +1,57 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_fxpt.h>
+
+const float gr_fxpt::s_sine_table[1 << NBITS][2] = {
+#include "sine_table.h"
+};
+
+// gcc 4.x fix
+const float gr_fxpt::TWO_TO_THE_31;
+const float gr_fxpt::PI;
+
+#if 0
+/*
+ * Compute sine using table lookup with linear interpolation.
+ * Each table entry contains slope and intercept.
+ */
+float
+gr_fxpt::sin (gr_int32 x)
+{
+  gr_uint32 ux = x;
+  int index = ux >> (WORDBITS - NBITS);
+  return s_sine_table[index][0] * (ux >> 1) + s_sine_table[index][1];
+}
+
+float
+gr_fxpt::cos (gr_int32 x)
+{
+  gr_uint32 ux = x + 0x40000000;
+  int index = ux >> (WORDBITS - NBITS);
+  return s_sine_table[index][0] * (ux >> 1) + s_sine_table[index][1];
+}
+#endif
diff --git a/gnuradio-core/src/lib/general/gr_fxpt.h b/gnuradio-core/src/lib/general/gr_fxpt.h
new file mode 100644 (file)
index 0000000..fc8432d
--- /dev/null
@@ -0,0 +1,82 @@
+/* -*- 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 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.
+ */
+#ifndef INCLUDED_GR_FXPT_H
+#define INCLUDED_GR_FXPT_H
+
+#include <gr_types.h>
+
+/*!
+ * \brief fixed point sine and cosine and friends.
+ *
+ *   fixed pt  radians
+ *  ---------  --------
+ *   -2**31       -pi
+ *        0         0
+ *  2**31-1        pi - epsilon
+ *
+ */
+class gr_fxpt
+{
+  static const int WORDBITS = 32;
+  static const int NBITS = 10;
+  static const float s_sine_table[1 << NBITS][2];
+  static const float PI = 3.14159265358979323846;
+  static const float TWO_TO_THE_31 = 2147483648.0;
+public:
+
+  static gr_int32
+  float_to_fixed (float x)
+  {
+    return (gr_int32) ((float) x * TWO_TO_THE_31 / PI);
+  }
+
+  static float
+  fixed_to_float (gr_int32 x)
+  {
+    return x * (PI / TWO_TO_THE_31);
+  }
+
+  /*!
+   * \brief Given a fixed point angle x, return float sine (x)
+   */
+  static float
+  sin (gr_int32 x)
+  {
+    gr_uint32 ux = x;
+    int index = ux >> (WORDBITS - NBITS);
+    return s_sine_table[index][0] * (ux >> 1) + s_sine_table[index][1];
+  }
+
+  /*
+   * \brief Given a fixed point angle x, return float cosine (x)
+   */
+  static float
+  cos (gr_int32 x)
+  {
+    gr_uint32 ux = x + 0x40000000;
+    int index = ux >> (WORDBITS - NBITS);
+    return s_sine_table[index][0] * (ux >> 1) + s_sine_table[index][1];
+  }
+
+};
+
+#endif /* INCLUDED_GR_FXPT_H */
diff --git a/gnuradio-core/src/lib/general/gr_fxpt_nco.h b/gnuradio-core/src/lib/general/gr_fxpt_nco.h
new file mode 100644 (file)
index 0000000..c779bdf
--- /dev/null
@@ -0,0 +1,151 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002,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.
+ */
+#ifndef INCLUDED_GR_FXPT_NCO_H
+#define INCLUDED_GR_FXPT_NCO_H
+
+#include <gr_fxpt.h>
+#include <gr_complex.h>
+
+/*!
+ * \brief Numerically Controlled Oscillator (NCO)
+ */
+class gr_fxpt_nco {
+  gr_int32     d_phase;
+  gr_int32     d_phase_inc;
+
+public:
+  gr_fxpt_nco () : d_phase (0), d_phase_inc (0) {}
+
+  ~gr_fxpt_nco () {}
+
+  // radians
+  void set_phase (float angle) {
+    d_phase = gr_fxpt::float_to_fixed (angle);
+  }
+
+  void adjust_phase (float delta_phase) {
+    d_phase += gr_fxpt::float_to_fixed (delta_phase);
+  }
+
+  // angle_rate is in radians / step
+  void set_freq (float angle_rate){
+    d_phase_inc = gr_fxpt::float_to_fixed (angle_rate);
+  }
+
+  // angle_rate is a delta in radians / step
+  void adjust_freq (float delta_angle_rate)
+  {
+    d_phase_inc += gr_fxpt::float_to_fixed (delta_angle_rate);
+  }
+
+  // increment current phase angle
+
+  void step () 
+  { 
+    d_phase += d_phase_inc;
+  }
+
+  void step (int n)
+  {
+    d_phase += d_phase_inc * n;
+  }
+
+  // units are radians / step
+  float get_phase () const { return gr_fxpt::fixed_to_float (d_phase); }
+  float get_freq () const { return gr_fxpt::fixed_to_float (d_phase_inc); }
+
+  // compute sin and cos for current phase angle
+  void sincos (float *sinx, float *cosx) const
+  {
+    *sinx = gr_fxpt::sin (d_phase);
+    *cosx = gr_fxpt::cos (d_phase);
+  }
+
+  // compute cos and sin for a block of phase angles
+  void sincos (gr_complex *output, int noutput_items, double ampl=1.0)
+  {
+    for (int i = 0; i < noutput_items; i++){
+      output[i]   = gr_complex(gr_fxpt::cos (d_phase) * ampl, gr_fxpt::sin (d_phase) * ampl);
+      step ();
+    }
+  }
+
+  // compute sin for a block of phase angles
+  void sin (float *output, int noutput_items, double ampl=1.0)
+  {
+    for (int i = 0; i < noutput_items; i++){
+      output[i] = (float)(gr_fxpt::sin (d_phase) * ampl);
+      step ();
+    }
+  }
+
+  // compute cos for a block of phase angles
+  void cos (float *output, int noutput_items, double ampl=1.0)
+  {
+    for (int i = 0; i < noutput_items; i++){
+      output[i] = (float)(gr_fxpt::cos (d_phase) * ampl);
+      step ();
+    }
+  }
+
+  // compute sin for a block of phase angles
+  void sin (short *output, int noutput_items, double ampl=1.0)
+  {
+    for (int i = 0; i < noutput_items; i++){
+      output[i] = (short)(gr_fxpt::sin (d_phase) * ampl);
+      step ();
+    }
+  }
+
+  // compute cos for a block of phase angles
+  void cos (short *output, int noutput_items, double ampl=1.0)
+  {
+    for (int i = 0; i < noutput_items; i++){
+      output[i] = (short)(gr_fxpt::cos (d_phase) * ampl);
+      step ();
+    }
+  }
+
+  // compute sin for a block of phase angles
+  void sin (int *output, int noutput_items, double ampl=1.0)
+  {
+    for (int i = 0; i < noutput_items; i++){
+      output[i] = (int)(gr_fxpt::sin (d_phase) * ampl);
+      step ();
+    }
+  }
+
+  // compute cos for a block of phase angles
+  void cos (int *output, int noutput_items, double ampl=1.0)
+  {
+    for (int i = 0; i < noutput_items; i++){
+      output[i] = (int)(gr_fxpt::cos (d_phase) * ampl);
+      step ();
+    }
+  }
+
+  // compute cos or sin for current phase angle
+  float cos () const { return gr_fxpt::cos (d_phase); }
+  float sin () const { return gr_fxpt::sin (d_phase); }
+};
+
+#endif /* INCLUDED_GR_FXPT_NCO_H */
diff --git a/gnuradio-core/src/lib/general/gr_fxpt_vco.h b/gnuradio-core/src/lib/general/gr_fxpt_vco.h
new file mode 100644 (file)
index 0000000..c57a577
--- /dev/null
@@ -0,0 +1,71 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002,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 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.
+ */
+#ifndef INCLUDED_GR_FXPT_VCO_H
+#define INCLUDED_GR_FXPT_VCO_H
+
+#include <gr_fxpt.h>
+#include <gr_complex.h>
+
+/*!
+ * \brief Voltage Controlled Oscillator (VCO)
+ */
+class gr_fxpt_vco {
+  gr_int32     d_phase;
+
+public:
+  gr_fxpt_vco () : d_phase (0) {}
+
+  ~gr_fxpt_vco () {}
+
+  // radians
+  void set_phase (float angle) {
+    d_phase = gr_fxpt::float_to_fixed (angle);
+  }
+
+  void adjust_phase (float delta_phase) {
+    d_phase += gr_fxpt::float_to_fixed (delta_phase);
+  }
+
+  float get_phase () const { return gr_fxpt::fixed_to_float (d_phase); }
+
+  // compute sin and cos for current phase angle
+  void sincos (float *sinx, float *cosx) const
+  {
+    *sinx = gr_fxpt::sin (d_phase);
+    *cosx = gr_fxpt::cos (d_phase);
+  }
+
+  // compute a block at a time
+  void cos (float *output, const float *input, int noutput_items, float k, float ampl = 1.0)
+  {
+    for (int i = 0; i < noutput_items; i++){
+      output[i] = (float)(gr_fxpt::cos (d_phase) * ampl);
+      adjust_phase(input[i] * k);
+    }
+  }
+
+  // compute cos or sin for current phase angle
+  float cos () const { return gr_fxpt::cos (d_phase); }
+  float sin () const { return gr_fxpt::sin (d_phase); }
+};
+
+#endif /* INCLUDED_GR_FXPT_VCO_H */
diff --git a/gnuradio-core/src/lib/general/gr_head.cc b/gnuradio-core/src/lib/general/gr_head.cc
new file mode 100644 (file)
index 0000000..7771ed5
--- /dev/null
@@ -0,0 +1,60 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <gr_head.h>
+#include <gr_io_signature.h>
+
+gr_head::gr_head (size_t sizeof_stream_item, int nitems)
+  : gr_sync_block ("head",
+                  gr_make_io_signature (1, 1, sizeof_stream_item),
+                  gr_make_io_signature (1, 1, sizeof_stream_item)),
+    d_nitems (nitems), d_ncopied_items (0)
+{
+}
+
+gr_block_sptr
+gr_make_head (size_t sizeof_stream_item, int nitems)
+{
+  return gr_block_sptr (new gr_head (sizeof_stream_item, nitems));
+}
+
+int
+gr_head::work (int noutput_items,
+                   gr_vector_const_void_star &input_items,
+                   gr_vector_void_star &output_items)
+{
+  if (d_ncopied_items >= d_nitems)
+    return -1;                         // Done!
+
+  unsigned n = std::min (d_nitems - d_ncopied_items, noutput_items);
+  
+  if (n == 0)
+    return 0;
+
+  memcpy (output_items[0], input_items[0], n * input_signature()->sizeof_stream_item (0));
+  d_ncopied_items += n;
+
+  return n;
+}
diff --git a/gnuradio-core/src/lib/general/gr_head.h b/gnuradio-core/src/lib/general/gr_head.h
new file mode 100644 (file)
index 0000000..125ee14
--- /dev/null
@@ -0,0 +1,54 @@
+/* -*- 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 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.
+ */
+
+#ifndef INCLUDED_GR_HEAD_H
+#define INCLUDED_GR_HEAD_H
+
+#include <gr_sync_block.h>
+#include <stddef.h>                    // size_t
+
+/*!
+ * \brief copies the first N items to the output then signals done
+ * \ingroup block
+ *
+ * Useful for building test cases
+ */
+
+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);
+
+  int  d_nitems;
+  int  d_ncopied_items;
+
+ public:
+  int work (int noutput_items,
+                gr_vector_const_void_star &input_items,
+                gr_vector_void_star &output_items);
+};
+
+gr_block_sptr
+gr_make_head (size_t sizeof_stream_item, int nitems);
+
+
+#endif /* INCLUDED_GR_HEAD_H */
diff --git a/gnuradio-core/src/lib/general/gr_head.i b/gnuradio-core/src/lib/general/gr_head.i
new file mode 100644 (file)
index 0000000..0a34214
--- /dev/null
@@ -0,0 +1,30 @@
+/* -*- 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 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.
+ */
+
+%ignore gr_head;
+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);
+};
+
+%rename(head) gr_make_head;
+gr_block_sptr gr_make_head (size_t sizeof_stream_item, int nitems);
diff --git a/gnuradio-core/src/lib/general/gr_interleave.cc b/gnuradio-core/src/lib/general/gr_interleave.cc
new file mode 100644 (file)
index 0000000..cae0cd9
--- /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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_interleave.h>
+#include <gr_io_signature.h>
+#include <string.h>
+
+
+gr_interleave_sptr
+gr_make_interleave (size_t itemsize)
+{
+  return gr_interleave_sptr (new gr_interleave (itemsize));
+}
+
+gr_interleave::gr_interleave (size_t itemsize)
+  : gr_sync_interpolator ("interleave",
+                         gr_make_io_signature (1, gr_io_signature::IO_INFINITE, itemsize),
+                         gr_make_io_signature (1, 1, itemsize),
+                         1),
+    d_itemsize (itemsize)
+{
+}
+
+gr_interleave::~gr_interleave ()
+{
+  // NOP
+}
+
+bool
+gr_interleave::check_topology (int ninputs, int noutputs)
+{
+  set_interpolation (ninputs);
+  return true;
+}
+
+int
+gr_interleave::work (int noutput_items,
+                    gr_vector_const_void_star &input_items,
+                    gr_vector_void_star &output_items)
+{
+  size_t nchan = input_items.size ();
+  size_t itemsize = d_itemsize;
+  const char **in = (const char **) &input_items[0];
+  char *out = (char *) output_items[0];
+
+  for (int i = 0; i < noutput_items; i += nchan){
+    for (unsigned int n = 0; n < nchan; n++){
+      memcpy (out, in[n], itemsize);
+      out += itemsize;
+      in[n] += itemsize;
+    }
+  }
+  return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_interleave.h b/gnuradio-core/src/lib/general/gr_interleave.h
new file mode 100644 (file)
index 0000000..128ed7c
--- /dev/null
@@ -0,0 +1,56 @@
+/* -*- 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 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.
+ */
+
+#ifndef INCLUDED_GR_INTERLEAVE_H
+#define INCLUDED_GR_INTERLEAVE_H
+
+#include <gr_sync_interpolator.h>
+
+class gr_interleave;
+typedef boost::shared_ptr<gr_interleave> gr_interleave_sptr;
+
+gr_interleave_sptr gr_make_interleave (size_t itemsize);
+
+/*!
+ * \brief interleave N inputs to a single output
+ * \ingroup block
+ */
+class gr_interleave : public gr_sync_interpolator
+{
+  friend gr_interleave_sptr gr_make_interleave (size_t itemsize);
+
+  size_t       d_itemsize;
+
+  gr_interleave (size_t itemsize);
+
+public:
+  ~gr_interleave ();
+
+  int work (int noutput_items,
+           gr_vector_const_void_star &input_items,
+           gr_vector_void_star &output_items);
+
+  bool check_topology (int ninputs, int noutputs);
+
+};
+
+#endif /* INCLUDED_GR_INTERLEAVE_H */
diff --git a/gnuradio-core/src/lib/general/gr_interleave.i b/gnuradio-core/src/lib/general/gr_interleave.i
new file mode 100644 (file)
index 0000000..f082531
--- /dev/null
@@ -0,0 +1,30 @@
+/* -*- 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 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.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,interleave)
+
+gr_interleave_sptr gr_make_interleave (size_t itemsize);
+
+class gr_interleave : public gr_sync_interpolator
+{
+  gr_interleave (size_t itemsize);
+};
diff --git a/gnuradio-core/src/lib/general/gr_interleaved_short_to_complex.cc b/gnuradio-core/src/lib/general/gr_interleaved_short_to_complex.cc
new file mode 100644 (file)
index 0000000..c43e725
--- /dev/null
@@ -0,0 +1,59 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_interleaved_short_to_complex.h>
+#include <gr_io_signature.h>
+#include <gri_interleaved_short_to_complex.h>
+
+gr_interleaved_short_to_complex_sptr
+gr_make_interleaved_short_to_complex ()
+{
+  return gr_interleaved_short_to_complex_sptr (new gr_interleaved_short_to_complex ());
+}
+
+gr_interleaved_short_to_complex::gr_interleaved_short_to_complex ()
+  : gr_sync_decimator ("gr_interleaved_short_to_complex",
+                      gr_make_io_signature (1, 1, sizeof (short)),
+                      gr_make_io_signature (1, 1, sizeof (gr_complex)),
+                      2)
+{
+}
+
+int
+gr_interleaved_short_to_complex::work (int noutput_items,
+                                      gr_vector_const_void_star &input_items,
+                                      gr_vector_void_star &output_items)
+{
+  const short *in = (const short *) input_items[0];
+  gr_complex *out = (gr_complex *) output_items[0];
+
+  gri_interleaved_short_to_complex (in, out, 2 * noutput_items);
+  
+  return noutput_items;
+}
+
+
+
diff --git a/gnuradio-core/src/lib/general/gr_interleaved_short_to_complex.h b/gnuradio-core/src/lib/general/gr_interleaved_short_to_complex.h
new file mode 100644 (file)
index 0000000..0eb1a32
--- /dev/null
@@ -0,0 +1,51 @@
+/* -*- 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 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.
+ */
+
+#ifndef INCLUDED_GR_INTERLEAVED_SHORT_TO_COMPLEX_H
+#define INCLUDED_GR_INTERLEAVED_SHORT_TO_COMPLEX_H
+
+#include <gr_sync_decimator.h>
+
+class gr_interleaved_short_to_complex;
+typedef boost::shared_ptr<gr_interleaved_short_to_complex>
+  gr_interleaved_short_to_complex_sptr;
+
+gr_interleaved_short_to_complex_sptr
+gr_make_interleaved_short_to_complex ();
+
+/*!
+ * \brief Convert stream of interleaved shorts to a stream of complex
+ * \ingroup converter
+ */
+
+class gr_interleaved_short_to_complex : public gr_sync_decimator
+{
+  friend gr_interleaved_short_to_complex_sptr gr_make_interleaved_short_to_complex ();
+  gr_interleaved_short_to_complex ();
+
+ public:
+  virtual int work (int noutput_items,
+                   gr_vector_const_void_star &input_items,
+                   gr_vector_void_star &output_items);
+};
+
+#endif /* INCLUDED_GR_INTERLEAVED_SHORT_TO_COMPLEX_H */
diff --git a/gnuradio-core/src/lib/general/gr_interleaved_short_to_complex.i b/gnuradio-core/src/lib/general/gr_interleaved_short_to_complex.i
new file mode 100644 (file)
index 0000000..02d1ec0
--- /dev/null
@@ -0,0 +1,30 @@
+/* -*- 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 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.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,interleaved_short_to_complex)
+
+gr_interleaved_short_to_complex_sptr gr_make_interleaved_short_to_complex ();
+
+class gr_interleaved_short_to_complex : public gr_sync_decimator
+{
+  gr_interleaved_short_to_complex ();
+};
diff --git a/gnuradio-core/src/lib/general/gr_keep_one_in_n.cc b/gnuradio-core/src/lib/general/gr_keep_one_in_n.cc
new file mode 100644 (file)
index 0000000..e302070
--- /dev/null
@@ -0,0 +1,81 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_keep_one_in_n.h>
+#include <gr_io_signature.h>
+
+gr_keep_one_in_n_sptr
+gr_make_keep_one_in_n (size_t item_size, int n)
+{
+  return gr_keep_one_in_n_sptr (new gr_keep_one_in_n (item_size, n));
+}
+
+gr_keep_one_in_n::gr_keep_one_in_n (size_t item_size, int n)
+  : gr_block ("keep_one_in_n",
+             gr_make_io_signature (1, 1, item_size),
+             gr_make_io_signature (1, 1, item_size)),
+    d_n (n), d_count(n)
+{
+}
+
+void
+gr_keep_one_in_n::set_n(int n)
+{
+  if (n < 1)
+    n = 1;
+
+  d_n = n;
+  d_count = n;
+}
+
+int
+gr_keep_one_in_n::general_work (int noutput_items,
+                               gr_vector_int &ninput_items,
+                               gr_vector_const_void_star &input_items,
+                               gr_vector_void_star &output_items)
+{
+  const char *in = (const char *) input_items[0];
+  char *out = (char *) output_items[0];
+  
+  size_t item_size = input_signature ()->sizeof_stream_item (0);
+  int   ni = 0;
+  int   no = 0;
+
+  while (ni < ninput_items[0] && no < noutput_items){
+    d_count--;
+    if (d_count <= 0){
+      memcpy (out, in, item_size);             // copy 1 item
+      out += item_size;
+      no++;
+      d_count = d_n;
+    }
+    in += item_size;
+    ni++;
+  }
+
+  consume_each (ni);
+  return no;
+}
diff --git a/gnuradio-core/src/lib/general/gr_keep_one_in_n.h b/gnuradio-core/src/lib/general/gr_keep_one_in_n.h
new file mode 100644 (file)
index 0000000..44a8474
--- /dev/null
@@ -0,0 +1,60 @@
+/* -*- 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 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.
+ */
+
+#ifndef INCLUDED_GR_KEEP_ONE_IN_N_H
+#define INCLUDED_GR_KEEP_ONE_IN_N_H
+
+#include <gr_sync_decimator.h>
+
+class gr_keep_one_in_n;
+typedef boost::shared_ptr<gr_keep_one_in_n> gr_keep_one_in_n_sptr;
+
+gr_keep_one_in_n_sptr 
+gr_make_keep_one_in_n (size_t item_size, int n);
+
+
+/*!
+ * \brief decimate a stream, keeping one item out of every n.
+ * \ingroup block
+ */
+class gr_keep_one_in_n : public gr_block
+{
+  friend gr_keep_one_in_n_sptr
+  gr_make_keep_one_in_n (size_t item_size, int n);
+
+  int  d_n;
+  int  d_count;
+
+ protected:
+  gr_keep_one_in_n (size_t item_size, int n);
+
+ 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);
+
+  void set_n(int n);
+
+};
+
+#endif /* INCLUDED_GR_KEEP_ONE_IN_N_H */
diff --git a/gnuradio-core/src/lib/general/gr_keep_one_in_n.i b/gnuradio-core/src/lib/general/gr_keep_one_in_n.i
new file mode 100644 (file)
index 0000000..13ed9a3
--- /dev/null
@@ -0,0 +1,35 @@
+/* -*- 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 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.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,keep_one_in_n)
+
+gr_keep_one_in_n_sptr 
+gr_make_keep_one_in_n (size_t itemsize, int n);
+
+class gr_keep_one_in_n : public gr_block
+{
+ protected:
+  gr_keep_one_in_n (size_t itemsize, int n);
+
+ public:
+  void set_n(int n);
+};
diff --git a/gnuradio-core/src/lib/general/gr_kludge_copy.cc b/gnuradio-core/src/lib/general/gr_kludge_copy.cc
new file mode 100644 (file)
index 0000000..bf980d2
--- /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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_kludge_copy.h>
+#include <gr_io_signature.h>
+#include <string.h>
+
+gr_kludge_copy_sptr
+gr_make_kludge_copy(size_t itemsize)
+{
+  return gr_kludge_copy_sptr(new gr_kludge_copy(itemsize));
+}
+
+gr_kludge_copy::gr_kludge_copy(size_t itemsize)
+  : gr_sync_block ("kludge_copy",
+                  gr_make_io_signature (1, -1, sizeof (float)),
+                  gr_make_io_signature (1, -1, sizeof (float))),
+    d_itemsize(itemsize)
+{
+}
+
+bool
+gr_kludge_copy::check_topology(int ninputs, int noutputs)
+{
+  return ninputs == noutputs;
+}
+
+int
+gr_kludge_copy::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];
+
+  int ninputs = input_items.size();
+  for (int i = 0; i < ninputs; i++){
+    memcpy(out[i], in[i], noutput_items * d_itemsize);
+  }
+  return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_kludge_copy.h b/gnuradio-core/src/lib/general/gr_kludge_copy.h
new file mode 100644 (file)
index 0000000..d1cf54e
--- /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 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.
+ */
+
+#ifndef INCLUDED_GR_KLUDGE_COPY_H
+#define INCLUDED_GR_KLUDGE_COPY_H
+
+#include <gr_sync_block.h>
+
+class gr_kludge_copy;
+typedef boost::shared_ptr<gr_kludge_copy> gr_kludge_copy_sptr;
+
+gr_kludge_copy_sptr gr_make_kludge_copy(size_t itemsize);
+
+/*!
+ * \brief output[i] = input[i]
+ * \ingroup block
+ *
+ * This is a short term kludge to work around a problem with the hierarchical block impl.
+ */
+class gr_kludge_copy : public gr_sync_block
+{
+  size_t               d_itemsize;
+
+  friend gr_kludge_copy_sptr gr_make_kludge_copy(size_t itemsize);
+  gr_kludge_copy(size_t itemsize);
+
+ public:
+
+  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
diff --git a/gnuradio-core/src/lib/general/gr_kludge_copy.i b/gnuradio-core/src/lib/general/gr_kludge_copy.i
new file mode 100644 (file)
index 0000000..828ec21
--- /dev/null
@@ -0,0 +1,31 @@
+/* -*- 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 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.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,kludge_copy)
+
+gr_kludge_copy_sptr gr_make_kludge_copy(size_t itemsize);
+
+class gr_kludge_copy : public gr_sync_block
+{
+ private:
+  gr_kludge_copy(size_t itemsize);
+};
diff --git a/gnuradio-core/src/lib/general/gr_lfsr_32k_source_s.cc b/gnuradio-core/src/lib/general/gr_lfsr_32k_source_s.cc
new file mode 100644 (file)
index 0000000..8a0b876
--- /dev/null
@@ -0,0 +1,70 @@
+/* -*- 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 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.
+ */
+
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <gr_lfsr_32k_source_s.h>
+#include <gr_io_signature.h>
+#include <stdexcept>
+
+
+gr_lfsr_32k_source_s_sptr 
+gr_make_lfsr_32k_source_s ()
+{
+  return gr_lfsr_32k_source_s_sptr (new gr_lfsr_32k_source_s ());
+}
+
+
+gr_lfsr_32k_source_s::gr_lfsr_32k_source_s ()
+  : gr_sync_block ("lfsr_32k_source_s",
+                  gr_make_io_signature (0, 0, 0),
+                  gr_make_io_signature (1, 1, sizeof (short))),
+    d_index (0)
+{
+  gri_lfsr_32k lfsr;
+  
+  for (int i = 0; i < BUFSIZE; i++)
+    d_buffer[i] = lfsr.next_short ();
+}
+
+int
+gr_lfsr_32k_source_s::work (int noutput_items,
+                           gr_vector_const_void_star &input_items,
+                           gr_vector_void_star &output_items)
+{
+  short *out = (short *) output_items[0];
+  short *buf = d_buffer;
+  int  index = d_index;
+  
+  for (int i = 0; i < noutput_items; i++){
+    out[i] = buf[index];
+    // index = (index + 1) & (BUFSIZE - 1);
+    index = index + 1;
+    if (index >= BUFSIZE)
+      index = 0;
+  }
+
+  d_index = index;
+  return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_lfsr_32k_source_s.h b/gnuradio-core/src/lib/general/gr_lfsr_32k_source_s.h
new file mode 100644 (file)
index 0000000..d3d72a9
--- /dev/null
@@ -0,0 +1,60 @@
+/* -*- 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 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.
+ */
+
+#ifndef INCLUDED_GR_LFSR_32K_SOURCE_S_H
+#define INCLUDED_GR_LFSR_32K_SOURCE_S_H
+
+#include <gr_sync_block.h>
+#include <gri_lfsr_32k.h>
+
+class gr_lfsr_32k_source_s;
+typedef boost::shared_ptr<gr_lfsr_32k_source_s> gr_lfsr_32k_source_s_sptr;
+
+gr_lfsr_32k_source_s_sptr gr_make_lfsr_32k_source_s ();
+
+/*!
+ * \brief LFSR pseudo-random source with period of 2^15 bits (2^11 shorts)
+ * \ingroup source
+ *
+ * This source is typically used along with gr_check_lfsr_32k_s to test
+ * the USRP using its digital loopback mode.
+ */
+class gr_lfsr_32k_source_s : public gr_sync_block 
+{
+  friend gr_lfsr_32k_source_s_sptr gr_make_lfsr_32k_source_s ();
+
+  
+  static const int BUFSIZE = 2048 - 1; // ensure pattern isn't packet aligned
+  int          d_index;
+  short                d_buffer[BUFSIZE];
+
+  gr_lfsr_32k_source_s ();
+
+ public:
+
+  virtual 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_lfsr_32k_source_s.i b/gnuradio-core/src/lib/general/gr_lfsr_32k_source_s.i
new file mode 100644 (file)
index 0000000..60b6267
--- /dev/null
@@ -0,0 +1,31 @@
+/* -*- 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 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.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,lfsr_32k_source_s);
+
+gr_lfsr_32k_source_s_sptr gr_make_lfsr_32k_source_s ();
+
+class gr_lfsr_32k_source_s : public gr_sync_block 
+{
+ private:
+  gr_lfsr_32k_source_s ();
+};
diff --git a/gnuradio-core/src/lib/general/gr_lms_dfe_cc.cc b/gnuradio-core/src/lib/general/gr_lms_dfe_cc.cc
new file mode 100644 (file)
index 0000000..874ad84
--- /dev/null
@@ -0,0 +1,148 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_lms_dfe_cc.h>
+#include <gr_io_signature.h>
+#include <gr_misc.h>
+#include <iostream>
+
+gr_complex
+gr_lms_dfe_cc::slicer_0deg (gr_complex sample)
+{
+  gr_complex out;
+  if(fabs(real(sample))>fabs(imag(sample))) {
+    if(real(sample) > 0)
+      out = gr_complex(1,0);
+    else
+      out = gr_complex(-1,0);
+  }
+  else {
+    if(imag(sample) > 0)
+      out = gr_complex(0,1);
+    else
+      out = gr_complex(0,-1);
+  }
+  return out;
+}
+
+gr_complex
+gr_lms_dfe_cc::slicer_45deg (gr_complex sample)
+{
+  gr_complex out;
+  if(real(sample) > 0)
+    out = gr_complex(1,0);
+  else
+    out = gr_complex(-1,0);
+  if(imag(sample) > 0)
+    out += gr_complex(0,1);
+  else
+    out += gr_complex(0,-1);
+  return out;
+}
+
+gr_lms_dfe_cc_sptr
+gr_make_lms_dfe_cc (float lambda_ff, float lambda_fb, 
+                   unsigned int num_fftaps, unsigned int num_fbtaps)
+{
+  return gr_lms_dfe_cc_sptr (new gr_lms_dfe_cc (lambda_ff, lambda_fb,
+                                               num_fftaps, num_fbtaps));
+}
+
+gr_lms_dfe_cc::gr_lms_dfe_cc (float lambda_ff, float lambda_fb , 
+                             unsigned int num_fftaps, unsigned int num_fbtaps)
+  : gr_sync_block ("lms_dfe_cc",
+                  gr_make_io_signature (1, 1, sizeof (gr_complex)),
+                  gr_make_io_signature (1, 1, sizeof (gr_complex))),
+    d_lambda_ff (lambda_ff), d_lambda_fb (lambda_fb), 
+    d_ff_delayline(gr_rounduppow2(num_fftaps)),
+    d_fb_delayline(gr_rounduppow2(num_fbtaps)),
+    d_ff_taps(num_fftaps),d_fb_taps(num_fbtaps),
+    d_ff_index(0), d_fb_index(0)
+{
+  gr_zero_vector(d_ff_taps);
+  d_ff_taps [d_ff_taps.size()/2] = 1;
+
+  gr_zero_vector(d_fb_taps);
+  gr_zero_vector(d_ff_delayline);
+  gr_zero_vector(d_fb_delayline);
+}
+
+int
+gr_lms_dfe_cc::work (int noutput_items,
+                  gr_vector_const_void_star &input_items,
+                  gr_vector_void_star &output_items)
+{
+  const gr_complex *iptr = (const gr_complex *) input_items[0];
+  gr_complex *optr = (gr_complex *) output_items[0];
+  
+  gr_complex acc, decision, error;
+  unsigned int i;
+
+  unsigned int ff_mask = d_ff_delayline.size() - 1;    // size is power of 2
+  unsigned int fb_mask = d_fb_delayline.size() - 1;
+
+  int  size = noutput_items;
+  while (size-- > 0){
+    acc = 0; 
+    d_ff_delayline[d_ff_index] = *iptr++;
+
+    // Compute output
+    for (i=0; i < d_ff_taps.size(); i++) 
+      acc += conj(d_ff_delayline[(i+d_ff_index) & ff_mask]) * d_ff_taps[i];
+    
+    for (i=0; i < d_fb_taps.size(); i++)
+      acc -= conj(d_fb_delayline[(i+d_fb_index) & fb_mask]) * d_fb_taps[i];
+
+    decision = slicer_45deg(acc);
+    error = decision - acc;
+    
+    //  Update taps
+    for (i=0; i < d_ff_taps.size(); i++)
+      d_ff_taps[i] += d_lambda_ff * conj(error) * d_ff_delayline[(i+d_ff_index) & ff_mask];
+    
+    for (i=0; i < d_fb_taps.size(); i++)
+      d_fb_taps[i] -= d_lambda_fb * conj(error) * d_fb_delayline[(i+d_fb_index) & fb_mask];
+    
+    d_fb_index = (d_fb_index - 1) & fb_mask;   // Decrement index
+    d_ff_index = (d_ff_index - 1) & ff_mask;   // Decrement index
+
+    d_fb_delayline[d_fb_index] = decision;     // Save decision in feedback
+
+    *optr++ = acc;   // Output decision
+  }
+
+  if (0){
+    std::cout << "FF Taps\t";
+    for(i=0;i<d_ff_taps.size();i++)
+      std::cout << d_ff_taps[i] << "\t";
+    std::cout << std::endl << "FB Taps\t";
+    for(i=0;i<d_fb_taps.size();i++)
+      std::cout << d_fb_taps[i] << "\t";
+    std::cout << std::endl;
+  }
+
+  return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_lms_dfe_cc.h b/gnuradio-core/src/lib/general/gr_lms_dfe_cc.h
new file mode 100644 (file)
index 0000000..034c26d
--- /dev/null
@@ -0,0 +1,64 @@
+/* -*- 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 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.
+ */
+
+#ifndef INCLUDED_GR_LMS_DFE_CC_H
+#define INCLUDED_GR_LMS_DFE_CC_H
+
+#include <gr_sync_block.h>
+
+class gr_lms_dfe_cc;
+typedef boost::shared_ptr<gr_lms_dfe_cc> gr_lms_dfe_cc_sptr;
+
+gr_lms_dfe_cc_sptr gr_make_lms_dfe_cc (float lambda_ff, float lambda_fb,
+                                      unsigned int num_fftaps, unsigned int num_fbtaps);
+
+/*!
+ * \brief Least-Mean-Square Decision Feedback Equalizer (complex in/out)
+ * \ingroup block
+ */
+class gr_lms_dfe_cc : public gr_sync_block
+{
+  friend gr_lms_dfe_cc_sptr gr_make_lms_dfe_cc (float lambda_ff, float lambda_fb,
+                                               unsigned int num_fftaps, unsigned int num_fbtaps);
+  
+  float        d_lambda_ff;
+  float        d_lambda_fb;
+  std::vector<gr_complex>  d_ff_delayline;
+  std::vector<gr_complex>  d_fb_delayline;
+  std::vector<gr_complex>  d_ff_taps;
+  std::vector<gr_complex>  d_fb_taps;
+  unsigned int d_ff_index;
+  unsigned int d_fb_index;
+
+  gr_lms_dfe_cc (float lambda_ff, float lambda_fb, 
+                unsigned int num_fftaps, unsigned int num_fbtaps);
+  gr_complex slicer_0deg(gr_complex baud);
+  gr_complex slicer_45deg(gr_complex baud);
+
+  public:
+  
+  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_lms_dfe_cc.i b/gnuradio-core/src/lib/general/gr_lms_dfe_cc.i
new file mode 100644 (file)
index 0000000..4ea4a6a
--- /dev/null
@@ -0,0 +1,37 @@
+/* -*- 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 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.
+ */
+
+
+GR_SWIG_BLOCK_MAGIC(gr,lms_dfe_cc)
+
+gr_lms_dfe_cc_sptr gr_make_lms_dfe_cc (float lambda_ff, float lambda_fb, 
+                                      unsigned int num_fftaps, unsigned int num_fbtaps);
+
+class gr_lms_dfe_cc : public gr_sync_block
+{
+ private:
+  gr_lms_dfe_cc (float lambda_ff, float lambda_fb, 
+                unsigned int num_fftaps, unsigned int num_fbtaps);
+  gr_complex slicer_0deg(gr_complex baud);
+  gr_complex slicer_45deg(gr_complex baud);
+  gr_complex conjg(gr_complex val);
+};
diff --git a/gnuradio-core/src/lib/general/gr_lms_dfe_ff.cc b/gnuradio-core/src/lib/general/gr_lms_dfe_ff.cc
new file mode 100644 (file)
index 0000000..017c90a
--- /dev/null
@@ -0,0 +1,122 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_lms_dfe_ff.h>
+#include <gr_io_signature.h>
+#include <gr_misc.h>
+#include <iostream>
+
+float
+slice(float val)
+{
+  if (val>0)
+    return 1;
+  else
+    return -1;
+}
+
+gr_lms_dfe_ff_sptr
+gr_make_lms_dfe_ff (float lambda_ff, float lambda_fb, 
+                   unsigned int num_fftaps, unsigned int num_fbtaps)
+{
+  return gr_lms_dfe_ff_sptr (new gr_lms_dfe_ff (lambda_ff,lambda_fb,num_fftaps,num_fbtaps));
+}
+
+gr_lms_dfe_ff::gr_lms_dfe_ff (float lambda_ff, float lambda_fb , 
+                             unsigned int num_fftaps, unsigned int num_fbtaps)
+  : gr_sync_block ("lms_dfe_ff",
+                  gr_make_io_signature (1, 1, sizeof (float)),
+                  gr_make_io_signature (1, 1, sizeof (float))),
+    d_lambda_ff (lambda_ff), d_lambda_fb (lambda_fb), 
+    d_ff_delayline(gr_rounduppow2(num_fftaps)),
+    d_fb_delayline(gr_rounduppow2(num_fbtaps)),
+    d_ff_taps(num_fftaps), d_fb_taps(num_fbtaps),
+    d_ff_index(0), d_fb_index(0)
+{
+  gr_zero_vector(d_ff_taps);
+  d_ff_taps [d_ff_taps.size()/2] = 1;
+
+  gr_zero_vector(d_fb_taps);
+  gr_zero_vector(d_ff_delayline);
+  gr_zero_vector(d_fb_delayline);
+}
+
+int
+gr_lms_dfe_ff::work (int noutput_items,
+                  gr_vector_const_void_star &input_items,
+                  gr_vector_void_star &output_items)
+{
+  const float *iptr = (const float *) input_items[0];
+  float *optr = (float *) output_items[0];
+  
+  float acc, decision, error;
+  unsigned int i;
+
+  unsigned int ff_mask = d_ff_delayline.size() - 1;    // size is power of 2
+  unsigned int fb_mask = d_fb_delayline.size() - 1;
+
+  int  size = noutput_items;
+  while(size-- > 0) {
+    acc = 0; 
+    d_ff_delayline[d_ff_index] = *iptr++;
+
+    // Compute output
+    for (i=0; i < d_ff_taps.size(); i++) 
+      acc += d_ff_delayline[(i+d_ff_index) & ff_mask] * d_ff_taps[i];
+    
+    for (i=0; i < d_fb_taps.size(); i++)
+      acc -= d_fb_delayline[(i+d_fb_index) & fb_mask] * d_fb_taps[i];
+
+    decision = slice(acc);
+    error = decision - acc;
+    
+    // Update taps
+    for (i=0; i < d_ff_taps.size(); i++)
+      d_ff_taps[i] += d_lambda_ff * error * d_ff_delayline[(i+d_ff_index) & ff_mask];
+    
+    for (i=0; i < d_fb_taps.size(); i++)
+      d_fb_taps[i] -= d_lambda_fb * error * d_fb_delayline[(i+d_fb_index) & fb_mask];
+    
+    d_fb_index = (d_fb_index - 1) & fb_mask;           // Decrement index
+    d_ff_index = (d_ff_index - 1) & ff_mask;           // Decrement index
+
+    d_fb_delayline[d_fb_index] = decision;     // Save decision in feedback
+
+    *optr++ = acc;   // Output decision
+  }
+
+  if (0){
+    std::cout << "FF Taps\t";
+    for(i=0;i<d_ff_taps.size();i++)
+      std::cout << d_ff_taps[i] << "\t";
+    std::cout << std::endl << "FB Taps\t";
+    for(i=0;i<d_fb_taps.size();i++)
+      std::cout << d_fb_taps[i] << "\t";
+    std::cout << std::endl;
+  }
+
+  return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_lms_dfe_ff.h b/gnuradio-core/src/lib/general/gr_lms_dfe_ff.h
new file mode 100644 (file)
index 0000000..338b0a1
--- /dev/null
@@ -0,0 +1,62 @@
+/* -*- 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 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.
+ */
+
+#ifndef INCLUDED_GR_LMS_DFE_FF_H
+#define INCLUDED_GR_LMS_DFE_FF_H
+
+#include <gr_sync_block.h>
+
+class gr_lms_dfe_ff;
+typedef boost::shared_ptr<gr_lms_dfe_ff> gr_lms_dfe_ff_sptr;
+
+gr_lms_dfe_ff_sptr gr_make_lms_dfe_ff (float lambda_ff, float lambda_fb,
+                                      unsigned int num_fftaps, unsigned int num_fbtaps);
+
+/*!
+ * \brief Least-Mean-Square Decision Feedback Equalizer (float in/out)
+ * \ingroup block
+ */
+class gr_lms_dfe_ff : public gr_sync_block
+{
+  friend gr_lms_dfe_ff_sptr gr_make_lms_dfe_ff (float lambda_ff, float lambda_fb,
+                                               unsigned int num_fftaps, unsigned int num_fbtaps);
+  
+  float        d_lambda_ff;
+  float        d_lambda_fb;
+  std::vector<float>  d_ff_delayline;
+  std::vector<float>  d_fb_delayline;
+  std::vector<float>  d_ff_taps;
+  std::vector<float>  d_fb_taps;
+  unsigned int d_ff_index;
+  unsigned int d_fb_index;
+
+  gr_lms_dfe_ff (float lambda_ff, float lambda_fb, 
+                unsigned int num_fftaps, unsigned int num_fbtaps);
+  
+  public:
+  
+  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_lms_dfe_ff.i b/gnuradio-core/src/lib/general/gr_lms_dfe_ff.i
new file mode 100644 (file)
index 0000000..6b9e439
--- /dev/null
@@ -0,0 +1,34 @@
+/* -*- 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 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.
+ */
+
+
+GR_SWIG_BLOCK_MAGIC(gr,lms_dfe_ff)
+
+gr_lms_dfe_ff_sptr gr_make_lms_dfe_ff (float lambda_ff, float lambda_fb, 
+                                      unsigned int num_fftaps, unsigned int num_fbtaps);
+
+class gr_lms_dfe_ff : public gr_sync_block
+{
+ private:
+  gr_lms_dfe_ff (float lambda_ff, float lambda_fb, 
+                unsigned int num_fftaps, unsigned int num_fbtaps);
+};
diff --git a/gnuradio-core/src/lib/general/gr_log2_const.h b/gnuradio-core/src/lib/general/gr_log2_const.h
new file mode 100644 (file)
index 0000000..fe25504
--- /dev/null
@@ -0,0 +1,46 @@
+/* -*- 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 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.
+ */
+
+
+/*
+ * a bit of template hackery...
+ */
+#ifndef INCLUDED_GR_LOG2_CONST_H
+#define INCLUDED_GR_LOG2_CONST_H
+
+#include <assert.h>
+
+template<unsigned int k> static inline int gr_log2_const() { assert(0); }
+
+template<> static inline int gr_log2_const<1>()   { return 0; }
+template<> static inline int gr_log2_const<2>()   { return 1; }
+template<> static inline int gr_log2_const<4>()   { return 2; }
+template<> static inline int gr_log2_const<8>()   { return 3; }
+template<> static inline int gr_log2_const<16>()  { return 4; }
+template<> static inline int gr_log2_const<32>()  { return 5; }
+template<> static inline int gr_log2_const<64>()  { return 6; }
+template<> static inline int gr_log2_const<128>() { return 7; }
+template<> static inline int gr_log2_const<256>() { return 8; }
+template<> static inline int gr_log2_const<512>() { return 9; }
+template<> static inline int gr_log2_const<1024>(){ return 10; }
+
+#endif /* INCLUDED_GR_LOG2_CONST_H */
diff --git a/gnuradio-core/src/lib/general/gr_map_bb.cc b/gnuradio-core/src/lib/general/gr_map_bb.cc
new file mode 100644 (file)
index 0000000..891ff02
--- /dev/null
@@ -0,0 +1,61 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_map_bb.h>
+#include <gr_io_signature.h>
+
+gr_map_bb_sptr
+gr_make_map_bb (const std::vector<int> &map)
+{
+  return gr_map_bb_sptr (new gr_map_bb (map));
+}
+
+gr_map_bb::gr_map_bb (const std::vector<int> &map)
+  : gr_sync_block ("map_bb",
+                  gr_make_io_signature (1, 1, sizeof (unsigned char)),
+                  gr_make_io_signature (1, 1, sizeof (unsigned char)))
+{
+  for (int i = 0; i < 0x100; i++)
+    d_map[i] = i;
+
+  unsigned int size = std::max((size_t) 0x100, map.size());
+  for (unsigned int i = 0; i < size; i++)
+    d_map[i] = map[i];
+}
+
+int
+gr_map_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] = d_map[in[i]];
+  
+  return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_map_bb.h b/gnuradio-core/src/lib/general/gr_map_bb.h
new file mode 100644 (file)
index 0000000..f5f7fa8
--- /dev/null
@@ -0,0 +1,51 @@
+/* -*- 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 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.
+ */
+#ifndef INCLUDED_GR_MAP_BB_H
+#define INCLUDED_GR_MAP_BB_H
+
+#include <gr_sync_block.h>
+
+class gr_map_bb;
+typedef boost::shared_ptr<gr_map_bb> gr_map_bb_sptr;
+
+gr_map_bb_sptr gr_make_map_bb(const std::vector<int> &map);
+
+/*!
+ * \brief output[i] = map[input[i]]
+ * \ingroup block
+ */
+
+class gr_map_bb : public gr_sync_block
+{
+  friend gr_map_bb_sptr gr_make_map_bb(const std::vector<int> &map);
+
+  unsigned char d_map[0x100];
+
+  gr_map_bb(const std::vector<int> &map);
+
+public:
+  int work (int noutput_items,
+           gr_vector_const_void_star &input_items,
+           gr_vector_void_star &output_items);
+};
+
+#endif /* INCLUDED_GR_MAP_BB_H */
diff --git a/gnuradio-core/src/lib/general/gr_map_bb.i b/gnuradio-core/src/lib/general/gr_map_bb.i
new file mode 100644 (file)
index 0000000..a4282a3
--- /dev/null
@@ -0,0 +1,32 @@
+/* -*- 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 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.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,map_bb);
+
+gr_map_bb_sptr gr_make_map_bb (const std::vector<int> &map);
+
+class gr_map_bb : public gr_sync_block
+{
+ private:
+  gr_map_bb (const std::vector<int> &map);
+};
+
diff --git a/gnuradio-core/src/lib/general/gr_math.cc b/gnuradio-core/src/lib/general/gr_math.cc
new file mode 100644 (file)
index 0000000..e2e7249
--- /dev/null
@@ -0,0 +1,102 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <gr_math.h>
+#include <math.h>
+
+/*
+ * Greatest Common Divisor, using Euclid's algorithm.
+ * [There are faster algorithms.  See Knuth 4.5.2 if you care]
+ */
+
+long
+gr_gcd (long m, long n)
+{
+  if (m < 0)
+    m = -m;
+  
+  if (n < 0)
+    n = -n;
+
+  while (n != 0){
+    long       t = m % n;
+    m = n;
+    n = t;
+  }
+
+  return m;
+}
+
+
+/*
+ * These really need some configure hacking to figure out the right answer.
+ * As a stop gap, try for a macro, and if not that, then try std::
+ */
+
+// returns a non-zero value if value is "not-a-number" (NaN), and 0 otherwise
+
+#if defined(isnan) || !defined(CXX_HAS_STD_ISNAN)
+
+int 
+gr_isnan (double value)
+{
+  return isnan (value);
+}
+
+#else
+
+int 
+gr_isnan (double value)
+{
+  return std::isnan (value);
+}
+
+#endif
+
+// returns a non-zero value if the value of x has its sign bit set.
+//
+// This  is  not  the  same  as `x < 0.0', because IEEE 754 floating point
+// allows zero to be signed.  The comparison `-0.0 < 0.0'  is  false,  but
+// `gr_signbit (-0.0)' will return a nonzero value.
+
+#ifdef signbit
+
+int 
+gr_signbit (double x)
+{
+  return signbit (x);
+}
+
+#else
+
+int 
+gr_signbit (double x)
+{
+  return std::signbit (x);
+}
+
+
+#endif
diff --git a/gnuradio-core/src/lib/general/gr_math.h b/gnuradio-core/src/lib/general/gr_math.h
new file mode 100644 (file)
index 0000000..5ce8fb7
--- /dev/null
@@ -0,0 +1,60 @@
+/* -*- 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 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.
+ */
+
+/*
+ * mathematical odds and ends.
+ */
+
+#ifndef _GR_MATH_H_
+#define _GR_MATH_H_
+
+long gr_gcd (long m, long n);
+
+// returns a non-zero value if value is "not-a-number" (NaN), and 0 otherwise
+int gr_isnan (double value);
+
+// returns a non-zero value if the value of x has its sign bit set.
+//
+// This  is  not  the  same  as `x < 0.0', because IEEE 754 floating point
+// allows zero to be signed.  The comparison `-0.0 < 0.0'  is  false,  but
+// `gr_signbit (-0.0)' will return a nonzero value.
+
+int gr_signbit (double x);
+  
+/*!
+ * \brief Fast arc tangent using table lookup and linear interpolation
+ *
+ * \param y component of input vector
+ * \param x component of input vector
+ * \returns float angle angle of vector (x, y) in radians
+ *
+ * This function calculates the angle of the vector (x,y) based on a
+ * table lookup and linear interpolation. The table uses a 256 point
+ * table covering -45 to +45 degrees and uses symetry to determine the
+ * final angle value in the range of -180 to 180 degrees. Note that
+ * this function uses the small angle approximation for values close
+ * to zero. This routine calculates the arc tangent with an average
+ * error of +/- 0.045 degrees.
+ */
+float gr_fast_atan2f(float y, float x);
+
+#endif /* _GR_MATH_H_ */
diff --git a/gnuradio-core/src/lib/general/gr_misc.cc b/gnuradio-core/src/lib/general/gr_misc.cc
new file mode 100644 (file)
index 0000000..d152022
--- /dev/null
@@ -0,0 +1,65 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include <gr_misc.h>
+
+unsigned int 
+gr_rounduppow2(unsigned int n)
+{
+  int i;
+  for (i=0;((n-1)>>i) != 0;i++)
+    ;
+  return 1<<i;
+}
+
+// ----------------------------------------------------------------
+
+void
+gr_zero_vector(std::vector<float> &v)
+{
+  for(unsigned int i=0; i < v.size(); i++)
+    v[i] = 0;
+}
+
+void
+gr_zero_vector(std::vector<double> &v)
+{
+  for(unsigned int i=0; i < v.size(); i++)
+    v[i] = 0;
+}
+
+void
+gr_zero_vector(std::vector<int> &v)
+{
+  for(unsigned int i=0; i < v.size(); i++)
+    v[i] = 0;
+}
+
+void
+gr_zero_vector(std::vector<gr_complex> &v)
+{
+  for(unsigned int i=0; i < v.size(); i++)
+    v[i] = 0;
+}
diff --git a/gnuradio-core/src/lib/general/gr_misc.h b/gnuradio-core/src/lib/general/gr_misc.h
new file mode 100644 (file)
index 0000000..177df96
--- /dev/null
@@ -0,0 +1,38 @@
+/* -*- 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 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.
+ */
+
+#ifndef INCLUDED_GR_MISC_H
+#define INCLUDED_GR_MISC_H
+
+#include <gr_types.h>
+
+unsigned int 
+gr_rounduppow2(unsigned int n);
+
+// FIXME should be template
+void gr_zero_vector(std::vector<float> &v);
+void gr_zero_vector(std::vector<double> &v);
+void gr_zero_vector(std::vector<int> &v);
+void gr_zero_vector(std::vector<gr_complex> &v);
+
+
+#endif /* INCLUDED_GR_MISC_H */
diff --git a/gnuradio-core/src/lib/general/gr_multiply_XX.cc.t b/gnuradio-core/src/lib/general/gr_multiply_XX.cc.t
new file mode 100644 (file)
index 0000000..a9c4322
--- /dev/null
@@ -0,0 +1,62 @@
+/* -*- 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 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.
+ */
+
+// @WARNING@
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <@NAME@.h>
+#include <gr_io_signature.h>
+
+@SPTR_NAME@
+gr_make_@BASE_NAME@ ()
+{
+  return @SPTR_NAME@ (new @NAME@ ());
+}
+
+@NAME@::@NAME@ ()
+  : gr_sync_block ("@BASE_NAME@",
+                  gr_make_io_signature (1, -1, sizeof (@I_TYPE@)),
+                  gr_make_io_signature (1,  1, sizeof (@O_TYPE@)))
+{
+}
+
+int
+@NAME@::work (int noutput_items,
+                  gr_vector_const_void_star &input_items,
+                  gr_vector_void_star &output_items)
+{
+  @O_TYPE@ *optr = (@O_TYPE@ *) output_items[0];
+
+  int ninputs = input_items.size ();
+
+  for (int i = 0; i < noutput_items; i++){
+    @I_TYPE@ acc = ((@I_TYPE@ *) input_items[0])[i];
+    for (int j = 1; j < ninputs; j++)
+      acc *= ((@I_TYPE@ *) input_items[j])[i];
+
+    *optr++ = (@O_TYPE@) acc;
+  }
+  return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_multiply_XX.h.t b/gnuradio-core/src/lib/general/gr_multiply_XX.h.t
new file mode 100644 (file)
index 0000000..cfa416f
--- /dev/null
@@ -0,0 +1,54 @@
+/* -*- 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 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.
+ */
+
+// @WARNING@
+
+#ifndef @GUARD_NAME@
+#define @GUARD_NAME@
+
+#include <gr_sync_block.h>
+
+class @NAME@;
+typedef boost::shared_ptr<@NAME@> @SPTR_NAME@;
+
+@SPTR_NAME@ gr_make_@BASE_NAME@ ();
+
+/*!
+ * \brief output = prod (input_0, input_1, ...)
+ * \ingroup block
+ *
+ * Multiply across all input streams.
+ */
+class @NAME@ : public gr_sync_block
+{
+  friend @SPTR_NAME@ gr_make_@BASE_NAME@ ();
+
+  @NAME@ ();
+
+ public:
+
+  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_multiply_XX.i.t b/gnuradio-core/src/lib/general/gr_multiply_XX.i.t
new file mode 100644 (file)
index 0000000..8479aad
--- /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 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.
+ */
+
+// @WARNING@
+
+GR_SWIG_BLOCK_MAGIC(gr,@BASE_NAME@)
+
+@SPTR_NAME@ gr_make_@BASE_NAME@ ();
+
+class @NAME@ : public gr_sync_block
+{
+ private:
+  @NAME@ ();
+};
diff --git a/gnuradio-core/src/lib/general/gr_multiply_const_XX.cc.t b/gnuradio-core/src/lib/general/gr_multiply_const_XX.cc.t
new file mode 100644 (file)
index 0000000..b312b9c
--- /dev/null
@@ -0,0 +1,72 @@
+/* -*- 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 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.
+ */
+
+// @WARNING@
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <@NAME@.h>
+#include <gr_io_signature.h>
+
+@SPTR_NAME@
+gr_make_@BASE_NAME@ (@O_TYPE@ k)
+{
+  return @SPTR_NAME@ (new @NAME@ (k));
+}
+
+@NAME@::@NAME@ (@O_TYPE@ k)
+  : gr_sync_block ("@BASE_NAME@",
+                  gr_make_io_signature (1, 1, sizeof (@I_TYPE@)),
+                  gr_make_io_signature (1, 1, sizeof (@O_TYPE@))),
+    d_k (k)
+{
+}
+
+int
+@NAME@::work (int noutput_items,
+                  gr_vector_const_void_star &input_items,
+                  gr_vector_void_star &output_items)
+{
+  @I_TYPE@ *iptr = (@I_TYPE@ *) input_items[0];
+  @O_TYPE@ *optr = (@O_TYPE@ *) output_items[0];
+
+  int  size = noutput_items;
+
+  while (size >= 8){
+    *optr++ = *iptr++ * d_k;
+    *optr++ = *iptr++ * d_k;
+    *optr++ = *iptr++ * d_k;
+    *optr++ = *iptr++ * d_k;
+    *optr++ = *iptr++ * d_k;
+    *optr++ = *iptr++ * d_k;
+    *optr++ = *iptr++ * d_k;
+    *optr++ = *iptr++ * d_k;
+    size -= 8;
+  }
+
+  while (size-- > 0)
+    *optr++ = *iptr++ * d_k;
+  
+  return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_multiply_const_XX.h.t b/gnuradio-core/src/lib/general/gr_multiply_const_XX.h.t
new file mode 100644 (file)
index 0000000..6e771e0
--- /dev/null
@@ -0,0 +1,55 @@
+/* -*- 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 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.
+ */
+
+// @WARNING@
+
+#ifndef @GUARD_NAME@
+#define @GUARD_NAME@
+
+#include <gr_sync_block.h>
+
+class @NAME@;
+typedef boost::shared_ptr<@NAME@> @SPTR_NAME@;
+
+@SPTR_NAME@ gr_make_@BASE_NAME@ (@O_TYPE@ k);
+
+/*!
+ * \brief output = input * constant
+ * \ingroup block
+ */
+class @NAME@ : public gr_sync_block
+{
+  friend @SPTR_NAME@ gr_make_@BASE_NAME@ (@O_TYPE@ k);
+
+  @O_TYPE@     d_k;            // the constant
+  @NAME@ (@O_TYPE@ k);
+
+ public:
+  @O_TYPE@ k () const { return d_k; }
+  void set_k (@O_TYPE@ k) { d_k = k; }
+
+  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_multiply_const_XX.i.t b/gnuradio-core/src/lib/general/gr_multiply_const_XX.i.t
new file mode 100644 (file)
index 0000000..c2c814b
--- /dev/null
@@ -0,0 +1,37 @@
+/* -*- 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 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.
+ */
+
+// @WARNING@
+
+GR_SWIG_BLOCK_MAGIC(gr,@BASE_NAME@)
+
+@SPTR_NAME@ gr_make_@BASE_NAME@ (@TYPE@ k);
+
+class @NAME@ : public gr_sync_block
+{
+ private:
+  @NAME@ (@TYPE@ k);
+
+ public:
+  @TYPE@ k () const { return d_k; }
+  void set_k (@TYPE@ k) { d_k = k; }
+};
diff --git a/gnuradio-core/src/lib/general/gr_multiply_const_vXX.cc.t b/gnuradio-core/src/lib/general/gr_multiply_const_vXX.cc.t
new file mode 100755 (executable)
index 0000000..9b723a3
--- /dev/null
@@ -0,0 +1,61 @@
+/* -*- 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 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.
+ */
+
+// @WARNING@
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <@NAME@.h>
+#include <gr_io_signature.h>
+
+@SPTR_NAME@
+gr_make_@BASE_NAME@ (const std::vector<@I_TYPE@> k)
+{
+  return @SPTR_NAME@ (new @NAME@ (k));
+}
+
+@NAME@::@NAME@ (const std::vector<@I_TYPE@> k)
+  : gr_sync_block ("@BASE_NAME@",
+                  gr_make_io_signature (1, 1, sizeof(@I_TYPE@)*k.size()),
+                  gr_make_io_signature (1, 1, sizeof(@O_TYPE@)*k.size()))
+{
+  d_k = k;
+}
+
+int
+@NAME@::work (int noutput_items,
+                  gr_vector_const_void_star &input_items,
+                  gr_vector_void_star &output_items)
+{
+  @I_TYPE@ *iptr = (@O_TYPE@ *)input_items[0];
+  @O_TYPE@ *optr = (@O_TYPE@ *)output_items[0];
+  int nitems_per_block = output_signature()->sizeof_stream_item(0)/sizeof(@I_TYPE@);
+
+  for (int i = 0; i < noutput_items; i++)
+    for (int j = 0; j < nitems_per_block; j++)
+      *optr++ = *iptr++ * d_k[j];
+  
+  return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_multiply_const_vXX.h.t b/gnuradio-core/src/lib/general/gr_multiply_const_vXX.h.t
new file mode 100755 (executable)
index 0000000..dba875c
--- /dev/null
@@ -0,0 +1,55 @@
+/* -*- 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 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.
+ */
+
+// @WARNING@
+
+#ifndef @GUARD_NAME@
+#define @GUARD_NAME@
+
+#include <gr_sync_block.h>
+
+class @NAME@;
+typedef boost::shared_ptr<@NAME@> @SPTR_NAME@;
+
+@SPTR_NAME@ gr_make_@BASE_NAME@ (const std::vector<@I_TYPE@> k);
+
+/*!
+ * \brief output vector = input vector * constant vector (element-wise)
+ * \ingroup block
+ */
+class @NAME@ : public gr_sync_block
+{
+  friend @SPTR_NAME@ gr_make_@BASE_NAME@ (const std::vector<@I_TYPE@> k);
+
+  std::vector<@I_TYPE@> d_k; // the constant
+  @NAME@ (const std::vector<@I_TYPE@> k);
+
+ public:
+  const std::vector<@I_TYPE@> k () const { return d_k; }
+  void set_k (const std::vector<@I_TYPE@> k) { d_k = k; }
+
+  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_multiply_const_vXX.i.t b/gnuradio-core/src/lib/general/gr_multiply_const_vXX.i.t
new file mode 100755 (executable)
index 0000000..38c3994
--- /dev/null
@@ -0,0 +1,37 @@
+/* -*- 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 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.
+ */
+
+// @WARNING@
+
+GR_SWIG_BLOCK_MAGIC(gr,@BASE_NAME@)
+
+@SPTR_NAME@ gr_make_@BASE_NAME@ (const std::vector<@I_TYPE@> k);
+
+class @NAME@ : public gr_sync_block
+{
+ private:
+  @NAME@ (const std::vector<@I_TYPE@> k);
+
+ public:
+  std::vector<@I_TYPE@> k () const { return d_k; }
+  void set_k (const std::vector<@I_TYPE@> k) { d_k = k; }
+};
diff --git a/gnuradio-core/src/lib/general/gr_multiply_vXX.cc.t b/gnuradio-core/src/lib/general/gr_multiply_vXX.cc.t
new file mode 100755 (executable)
index 0000000..cc242dd
--- /dev/null
@@ -0,0 +1,65 @@
+/* -*- 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 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.
+ */
+
+// @WARNING@
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <@NAME@.h>
+#include <gr_io_signature.h>
+
+@SPTR_NAME@
+gr_make_@BASE_NAME@ (size_t nitems_per_block)
+{
+  return @SPTR_NAME@ (new @NAME@ (nitems_per_block));
+}
+
+@NAME@::@NAME@ (size_t nitems_per_block)
+  : gr_sync_block ("@BASE_NAME@",
+                  gr_make_io_signature (1, -1, sizeof (@I_TYPE@)*nitems_per_block),
+                  gr_make_io_signature (1,  1, sizeof (@O_TYPE@)*nitems_per_block))
+{
+}
+
+int
+@NAME@::work (int noutput_items,
+                  gr_vector_const_void_star &input_items,
+                  gr_vector_void_star &output_items)
+{
+  @O_TYPE@ *optr = (@O_TYPE@ *) output_items[0];
+
+  int ninputs = input_items.size ();
+  int nitems_per_block = output_signature()->sizeof_stream_item(0)/sizeof(@I_TYPE@);
+
+  for (int i = 0; i < noutput_items; i++){
+    for (int j = 0; j < nitems_per_block; j++){
+      @I_TYPE@ acc = ((@I_TYPE@ *) input_items[0])[i*nitems_per_block+j];
+      for (int k = 1; k < ninputs; k++)
+        acc *= ((@I_TYPE@ *) input_items[k])[i*nitems_per_block+j];
+
+      *optr++ = (@O_TYPE@) acc;
+    }
+  }
+  return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_multiply_vXX.h.t b/gnuradio-core/src/lib/general/gr_multiply_vXX.h.t
new file mode 100755 (executable)
index 0000000..c6388d9
--- /dev/null
@@ -0,0 +1,54 @@
+/* -*- 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 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.
+ */
+
+// @WARNING@
+
+#ifndef @GUARD_NAME@
+#define @GUARD_NAME@
+
+#include <gr_sync_block.h>
+
+class @NAME@;
+typedef boost::shared_ptr<@NAME@> @SPTR_NAME@;
+
+@SPTR_NAME@ gr_make_@BASE_NAME@ (size_t nitems_per_block);
+
+/*!
+ * \brief output = prod (input_0, input_1, ...)
+ * \ingroup block
+ *
+ * Element-wise multiply across all input vectors.
+ */
+class @NAME@ : public gr_sync_block
+{
+  friend @SPTR_NAME@ gr_make_@BASE_NAME@ (size_t nitems_per_block);
+
+  @NAME@ (size_t nitems_per_block);
+
+ public:
+
+  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_multiply_vXX.i.t b/gnuradio-core/src/lib/general/gr_multiply_vXX.i.t
new file mode 100755 (executable)
index 0000000..0810961
--- /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 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.
+ */
+
+// @WARNING@
+
+GR_SWIG_BLOCK_MAGIC(gr,@BASE_NAME@)
+
+@SPTR_NAME@ gr_make_@BASE_NAME@ (size_t nitems_per_block);
+
+class @NAME@ : public gr_sync_block
+{
+ private:
+  @NAME@ (size_t nitems_per_block);
+};
diff --git a/gnuradio-core/src/lib/general/gr_mute_XX.cc.t b/gnuradio-core/src/lib/general/gr_mute_XX.cc.t
new file mode 100644 (file)
index 0000000..740821e
--- /dev/null
@@ -0,0 +1,79 @@
+/* -*- 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 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.
+ */
+
+// @WARNING@
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <@NAME@.h>
+#include <gr_io_signature.h>
+#include <string.h>
+
+
+@SPTR_NAME@
+gr_make_@BASE_NAME@ (bool mute)
+{
+  return @SPTR_NAME@ (new @NAME@ (mute));
+}
+
+@NAME@::@NAME@ (bool mute)
+  : gr_sync_block ("@BASE_NAME@",
+                  gr_make_io_signature (1, 1, sizeof (@I_TYPE@)),
+                  gr_make_io_signature (1, 1, sizeof (@O_TYPE@))),
+    d_mute (mute)
+{
+}
+
+int
+@NAME@::work (int noutput_items,
+                  gr_vector_const_void_star &input_items,
+                  gr_vector_void_star &output_items)
+{
+  @I_TYPE@ *iptr = (@I_TYPE@ *) input_items[0];
+  @O_TYPE@ *optr = (@O_TYPE@ *) output_items[0];
+
+  int  size = noutput_items;
+
+  if (d_mute){
+    memset (optr, 0, noutput_items * sizeof(@O_TYPE@));
+  }
+  else {
+    while (size >= 8){
+      *optr++ = *iptr++;
+      *optr++ = *iptr++;
+      *optr++ = *iptr++;
+      *optr++ = *iptr++;
+      *optr++ = *iptr++;
+      *optr++ = *iptr++;
+      *optr++ = *iptr++;
+      *optr++ = *iptr++;
+      size -= 8;
+    }
+
+    while (size-- > 0)
+      *optr++ = *iptr++;
+  }
+  
+  return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_mute_XX.h.t b/gnuradio-core/src/lib/general/gr_mute_XX.h.t
new file mode 100644 (file)
index 0000000..8891532
--- /dev/null
@@ -0,0 +1,55 @@
+/* -*- 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 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.
+ */
+
+// @WARNING@
+
+#ifndef @GUARD_NAME@
+#define @GUARD_NAME@
+
+#include <gr_sync_block.h>
+
+class @NAME@;
+typedef boost::shared_ptr<@NAME@> @SPTR_NAME@;
+
+@SPTR_NAME@ gr_make_@BASE_NAME@ (bool mute=false);
+
+/*!
+ * \brief output = input or zero if muted.
+ * \ingroup block
+ */
+class @NAME@ : public gr_sync_block
+{
+  friend @SPTR_NAME@ gr_make_@BASE_NAME@ (bool mute);
+
+  bool         d_mute;
+  @NAME@ (bool mute);
+
+ public:
+  bool mute () const { return d_mute; }
+  void set_mute (bool mute) { d_mute = mute; }
+
+  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_mute_XX.i.t b/gnuradio-core/src/lib/general/gr_mute_XX.i.t
new file mode 100644 (file)
index 0000000..413e529
--- /dev/null
@@ -0,0 +1,37 @@
+/* -*- 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 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.
+ */
+
+// @WARNING@
+
+GR_SWIG_BLOCK_MAGIC(gr,@BASE_NAME@)
+
+@SPTR_NAME@ gr_make_@BASE_NAME@(bool mute=false);
+
+class @NAME@ : public gr_sync_block
+{
+ private:
+  @NAME@ (bool mute);
+
+ public:
+  bool mute () const { return d_mute; }
+  void set_mute (bool mute) { d_mute = mute; }
+};
diff --git a/gnuradio-core/src/lib/general/gr_nco.h b/gnuradio-core/src/lib/general/gr_nco.h
new file mode 100644 (file)
index 0000000..2cf41fd
--- /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 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.
+ */
+#ifndef _GR_NCO_H_
+#define _GR_NCO_H_
+
+
+#include <vector>
+#include <gr_sincos.h>
+#include <cmath>
+#include <gr_complex.h>
+
+/*!
+ * \brief base class template for Numerically Controlled Oscillator (NCO)
+ */
+
+
+//FIXME  Eventually generalize this to fixed point
+
+template<class o_type, class i_type> 
+class gr_nco {
+public:
+  gr_nco () : phase (0), phase_inc(0) {}
+
+  virtual ~gr_nco () {}
+
+  // radians
+  void set_phase (double angle) {
+    phase = angle;
+  }
+
+  void adjust_phase (double delta_phase) {
+    phase += delta_phase;
+  }
+
+
+  // angle_rate is in radians / step
+  void set_freq (double angle_rate){
+    phase_inc = angle_rate;
+  }
+
+  // angle_rate is a delta in radians / step
+  void adjust_freq (double delta_angle_rate)
+  {
+    phase_inc += delta_angle_rate;
+  }
+
+  // increment current phase angle
+
+  void step () 
+  { 
+    phase += phase_inc; 
+    if (fabs (phase) > M_PI){
+      
+      while (phase > M_PI)
+       phase -= 2*M_PI;
+
+      while (phase < -M_PI)
+       phase += 2*M_PI;
+    }
+  }
+
+  void step (int n)
+  {
+    phase += phase_inc * n;
+    if (fabs (phase) > M_PI){
+      
+      while (phase > M_PI)
+       phase -= 2*M_PI;
+
+      while (phase < -M_PI)
+       phase += 2*M_PI;
+    }
+  }
+
+  // units are radians / step
+  double get_phase () const { return phase; }
+  double get_freq () const { return phase_inc; }
+
+  // compute sin and cos for current phase angle
+  void sincos (float *sinx, float *cosx) const;
+
+  // compute cos or sin for current phase angle
+  float cos () const { return std::cos (phase); }
+  float sin () const { return std::sin (phase); }
+
+  // compute a block at a time
+  void sin (float *output, int noutput_items, double ampl = 1.0);
+  void cos (float *output, int noutput_items, double ampl = 1.0);
+  void sincos (gr_complex *output, int noutput_items, double ampl = 1.0);
+  void sin (short *output, int noutput_items, double ampl = 1.0);
+  void cos (short *output, int noutput_items, double ampl = 1.0);
+  void sin (int *output, int noutput_items, double ampl = 1.0);
+  void cos (int *output, int noutput_items, double ampl = 1.0);
+
+protected:
+  double phase;
+  double phase_inc;
+};
+
+template<class o_type, class i_type> 
+void
+gr_nco<o_type,i_type>::sincos (float *sinx, float *cosx) const
+{
+  gr_sincosf (phase, sinx, cosx);
+}
+
+template<class o_type, class i_type> 
+void
+gr_nco<o_type,i_type>::sin (float *output, int noutput_items, double ampl)
+{
+  for (int i = 0; i < noutput_items; i++){
+    output[i] = (float)(sin () * ampl);
+    step ();
+  }
+}
+
+template<class o_type, class i_type> 
+void
+gr_nco<o_type,i_type>::cos (float *output, int noutput_items, double ampl)
+{
+  for (int i = 0; i < noutput_items; i++){
+    output[i] = (float)(cos () * ampl);
+    step ();
+  }
+}
+
+template<class o_type, class i_type> 
+void
+gr_nco<o_type,i_type>::sin (short *output, int noutput_items, double ampl)
+{
+  for (int i = 0; i < noutput_items; i++){
+    output[i] = (short)(sin() * ampl);
+    step ();
+  }
+}
+
+template<class o_type, class i_type> 
+void
+gr_nco<o_type,i_type>::cos (short *output, int noutput_items, double ampl)
+{
+  for (int i = 0; i < noutput_items; i++){
+    output[i] = (short)(cos () * ampl);
+    step ();
+  }
+}
+
+template<class o_type, class i_type> 
+void
+gr_nco<o_type,i_type>::sin (int *output, int noutput_items, double ampl)
+{
+  for (int i = 0; i < noutput_items; i++){
+    output[i] = (int)(sin () * ampl);
+    step ();
+  }
+}
+
+template<class o_type, class i_type> 
+void
+gr_nco<o_type,i_type>::cos (int *output, int noutput_items, double ampl)
+{
+  for (int i = 0; i < noutput_items; i++){
+    output[i] = (int)(cos () * ampl);
+    step ();
+  }
+}
+
+template<class o_type, class i_type> 
+void
+gr_nco<o_type,i_type>::sincos (gr_complex *output, int noutput_items, double ampl)
+{
+  for (int i = 0; i < noutput_items; i++){
+    float cosx, sinx;
+    sincos (&sinx, &cosx);
+    output[i] = gr_complex(cosx * ampl, sinx * ampl);
+    step ();
+  }
+}
+#endif /* _NCO_H_ */
diff --git a/gnuradio-core/src/lib/general/gr_nlog10_ff.cc b/gnuradio-core/src/lib/general/gr_nlog10_ff.cc
new file mode 100644 (file)
index 0000000..71e8279
--- /dev/null
@@ -0,0 +1,64 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_nlog10_ff.h>
+#include <gr_io_signature.h>
+#include <algorithm>
+
+gr_nlog10_ff_sptr
+gr_make_nlog10_ff (float n, unsigned vlen, float k)
+{
+  return gr_nlog10_ff_sptr(new gr_nlog10_ff(n, vlen, k));
+}
+
+gr_nlog10_ff::gr_nlog10_ff(float n, unsigned vlen, float k)
+  : gr_sync_block("nlog10_ff",
+                 gr_make_io_signature(1, 1, sizeof(float) * vlen),
+                 gr_make_io_signature(1, 1, sizeof(float) * vlen)),
+    d_vlen(vlen), d_n(n), d_k(k)
+{
+}
+
+gr_nlog10_ff::~gr_nlog10_ff()
+{
+}
+
+int
+gr_nlog10_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];
+  int noi = noutput_items * d_vlen;
+  float n = d_n;
+  float k = d_k;
+
+  for (int i = 0; i < noi; i++)
+    out[i] = n * log10(std::max(in[i], (float) 1e-18)) + k;
+
+  return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_nlog10_ff.h b/gnuradio-core/src/lib/general/gr_nlog10_ff.h
new file mode 100644 (file)
index 0000000..04a6f80
--- /dev/null
@@ -0,0 +1,55 @@
+/* -*- 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 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.
+ */
+#ifndef INCLUDED_GR_NLOG10_FF_H
+#define INCLUDED_GR_NLOG10_FF_H
+
+#include <gr_sync_block.h>
+
+class gr_nlog10_ff;
+typedef boost::shared_ptr<gr_nlog10_ff> gr_nlog10_ff_sptr;
+
+gr_nlog10_ff_sptr gr_make_nlog10_ff (float n=1.0, unsigned vlen=1, float k=0);
+
+/*!
+ * \brief output = n*log10(input) + k
+ * \ingroup block
+ */
+class gr_nlog10_ff : public gr_sync_block
+{
+  friend gr_nlog10_ff_sptr gr_make_nlog10_ff (float n, unsigned vlen, float k);
+
+  unsigned int         d_vlen;
+  float                        d_n;
+  float                        d_k;
+
+  gr_nlog10_ff (float n, unsigned vlen, float k);
+
+public:
+  ~gr_nlog10_ff();
+
+  int work (int noutput_items,
+           gr_vector_const_void_star &input_items,
+           gr_vector_void_star &output_items);
+};
+
+
+#endif /* INCLUDED_GR_NLOG10_FF_H */
diff --git a/gnuradio-core/src/lib/general/gr_nlog10_ff.i b/gnuradio-core/src/lib/general/gr_nlog10_ff.i
new file mode 100644 (file)
index 0000000..3dbd12d
--- /dev/null
@@ -0,0 +1,33 @@
+/* -*- 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 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.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,nlog10_ff);
+
+gr_nlog10_ff_sptr gr_make_nlog10_ff (float n=1.0, unsigned vlen=1, float k=0);
+
+class gr_nlog10_ff : public gr_sync_block
+{
+  gr_nlog10_ff (float n, unsigned vlen, float k);
+
+public:
+  ~gr_nlog10_ff();
+};
diff --git a/gnuradio-core/src/lib/general/gr_noise_source_X.cc.t b/gnuradio-core/src/lib/general/gr_noise_source_X.cc.t
new file mode 100644 (file)
index 0000000..401bed1
--- /dev/null
@@ -0,0 +1,99 @@
+/* -*- 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 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.
+ */
+
+// @WARNING@
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <@NAME@.h>
+#include <gr_io_signature.h>
+#include <stdexcept>
+
+
+@NAME@_sptr 
+gr_make_@BASE_NAME@ (gr_noise_type_t type, float ampl, long seed)
+{
+  return @NAME@_sptr (new @NAME@ (type, ampl, seed));
+}
+
+
+@NAME@::@NAME@ (gr_noise_type_t type, float ampl, long seed)
+  : gr_sync_block ("@BASE_NAME@",
+                  gr_make_io_signature (0, 0, 0),
+                  gr_make_io_signature (1, 1, sizeof (@TYPE@))),
+    d_type (type),
+    d_ampl (ampl),
+    d_rng (seed)
+{
+}
+
+int
+@NAME@::work (int noutput_items,
+                  gr_vector_const_void_star &input_items,
+                  gr_vector_void_star &output_items)
+{
+  @TYPE@ *out = (@TYPE@ *) output_items[0];
+  
+  switch (d_type){
+#if @IS_COMPLEX@       // complex?
+
+  case GR_UNIFORM:
+    for (int i = 0; i < noutput_items; i++)
+      out[i] = gr_complex (d_ampl * ((d_rng.ran1 () * 2.0) - 1.0),
+                          d_ampl * ((d_rng.ran1 () * 2.0) - 1.0));
+    break;
+
+  case GR_GAUSSIAN:
+    for (int i = 0; i < noutput_items; i++)
+      out[i] = d_ampl * d_rng.rayleigh_complex ();
+    break;
+
+#else                  // nope...
+
+  case GR_UNIFORM:
+    for (int i = 0; i < noutput_items; i++)
+      out[i] = (@TYPE@)(d_ampl * ((d_rng.ran1 () * 2.0) - 1.0));
+    break;
+
+  case GR_GAUSSIAN:
+    for (int i = 0; i < noutput_items; i++)
+      out[i] = (@TYPE@)(d_ampl * d_rng.gasdev ());
+    break;
+    
+  case GR_LAPLACIAN:
+    for (int i = 0; i < noutput_items; i++)
+      out[i] = (@TYPE@)(d_ampl * d_rng.laplacian ());
+    break;
+    
+  case GR_IMPULSE:     // FIXME changeable impulse settings
+    for (int i = 0; i < noutput_items; i++)
+      out[i] = (@TYPE@)(d_ampl * d_rng.impulse (9));
+    break;
+#endif
+    
+  default:
+    throw std::runtime_error ("invalid type");
+  }
+
+  return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_noise_source_X.h.t b/gnuradio-core/src/lib/general/gr_noise_source_X.h.t
new file mode 100644 (file)
index 0000000..bc016af
--- /dev/null
@@ -0,0 +1,63 @@
+/* -*- 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 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.
+ */
+
+// @WARNING@
+
+#ifndef @GUARD_NAME@
+#define @GUARD_NAME@
+
+#include <gr_sync_block.h>
+#include <gr_noise_type.h>
+#include <gr_random.h>
+
+
+class @NAME@;
+typedef boost::shared_ptr<@NAME@> @NAME@_sptr;
+
+@NAME@_sptr 
+gr_make_@BASE_NAME@ (gr_noise_type_t type, float ampl, long seed = 3021);
+
+/*!
+ * \brief random number source
+ * \ingroup source
+ */
+class @NAME@ : public gr_sync_block {
+  friend @NAME@_sptr 
+  gr_make_@BASE_NAME@ (gr_noise_type_t type, float ampl, long seed);
+
+  gr_noise_type_t      d_type;
+  float                        d_ampl;
+  gr_random            d_rng;
+
+  @NAME@ (gr_noise_type_t type, float ampl, long seed = 3021);
+
+ public:
+  void set_type (gr_noise_type_t type) { d_type = type; }
+  void set_amplitude (float ampl) { d_ampl = ampl; }
+
+  virtual 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_noise_source_X.i.t b/gnuradio-core/src/lib/general/gr_noise_source_X.i.t
new file mode 100644 (file)
index 0000000..0a3ad96
--- /dev/null
@@ -0,0 +1,37 @@
+/* -*- 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 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.
+ */
+
+// @WARNING@
+
+GR_SWIG_BLOCK_MAGIC(gr,@BASE_NAME@);
+
+@NAME@_sptr 
+gr_make_@BASE_NAME@ (gr_noise_type_t type, float ampl, long seed = 3021);
+
+class @NAME@ : public gr_block {
+ private:
+  @NAME@ (gr_noise_type_t type, float ampl, long seed = 3021);
+
+ public:
+  void set_type (gr_noise_type_t type) { d_type = type; }
+  void set_amplitude (float ampl) { d_ampl = ampl; }
+};
diff --git a/gnuradio-core/src/lib/general/gr_noise_type.h b/gnuradio-core/src/lib/general/gr_noise_type.h
new file mode 100644 (file)
index 0000000..886d5f4
--- /dev/null
@@ -0,0 +1,30 @@
+/* -*- 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 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.
+ */
+
+#ifndef INCLUDED_GR_NOISE_TYPE_H
+#define INCLUDED_GR_NOISE_TYPE_H
+
+typedef enum {
+  GR_UNIFORM = 200, GR_GAUSSIAN, GR_LAPLACIAN, GR_IMPULSE
+} gr_noise_type_t;
+
+#endif /* INCLUDED_GR_NOISE_TYPE_H */
diff --git a/gnuradio-core/src/lib/general/gr_nop.cc b/gnuradio-core/src/lib/general/gr_nop.cc
new file mode 100644 (file)
index 0000000..0a3f4f3
--- /dev/null
@@ -0,0 +1,55 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <gr_nop.h>
+#include <gr_io_signature.h>
+
+gr_nop::gr_nop (size_t sizeof_stream_item)
+  : gr_block ("nop",
+              gr_make_io_signature (0, -1, sizeof_stream_item),
+              gr_make_io_signature (0, -1, sizeof_stream_item))
+{
+}
+
+gr_block_sptr
+gr_make_nop (size_t sizeof_stream_item)
+{
+  return gr_block_sptr (new gr_nop (sizeof_stream_item));
+}
+
+int
+gr_nop::general_work (int noutput_items,
+                     gr_vector_int &ninput_items,
+                     gr_vector_const_void_star &input_items,
+                     gr_vector_void_star &output_items)
+{
+  // eat any input that's available
+  for (unsigned i = 0; i < ninput_items.size (); i++)
+    consume (i, ninput_items[i]);
+  
+  return noutput_items;
+}
+
+
diff --git a/gnuradio-core/src/lib/general/gr_nop.h b/gnuradio-core/src/lib/general/gr_nop.h
new file mode 100644 (file)
index 0000000..faf9386
--- /dev/null
@@ -0,0 +1,49 @@
+/* -*- 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 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.
+ */
+
+#ifndef INCLUDED_GR_NOP_H
+#define INCLUDED_GR_NOP_H
+
+#include <gr_block.h>
+#include <stddef.h>                    // size_t
+
+/*!
+ * \brief Does nothing.  Used for testing only.
+ * \ingroup block
+ */
+class gr_nop : public gr_block
+{
+  friend gr_block_sptr gr_make_nop (size_t sizeof_stream_item);
+
+  gr_nop (size_t sizeof_stream_item);
+
+ public:
+  virtual int general_work (int noutput_items,
+                           gr_vector_int &ninput_items,
+                           gr_vector_const_void_star &input_items,
+                           gr_vector_void_star &output_items);
+};
+
+gr_block_sptr
+gr_make_nop (size_t sizeof_stream_item);
+
+#endif /* INCLUDED_GR_NOP_H */
diff --git a/gnuradio-core/src/lib/general/gr_nop.i b/gnuradio-core/src/lib/general/gr_nop.i
new file mode 100644 (file)
index 0000000..556ad57
--- /dev/null
@@ -0,0 +1,30 @@
+/* -*- 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 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.
+ */
+
+%ignore gr_nop;
+class gr_nop : public gr_block {
+  friend gr_block_sptr gr_make_nop (size_t sizeof_stream_item);
+  gr_nop (size_t sizeof_stream_item);
+};
+
+%rename(nop) gr_make_nop;
+gr_block_sptr gr_make_nop (size_t sizeof_stream_item);
diff --git a/gnuradio-core/src/lib/general/gr_null_sink.cc b/gnuradio-core/src/lib/general/gr_null_sink.cc
new file mode 100644 (file)
index 0000000..7e9c7a7
--- /dev/null
@@ -0,0 +1,49 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_null_sink.h>
+#include <gr_io_signature.h>
+
+gr_null_sink::gr_null_sink (size_t sizeof_stream_item)
+  : gr_sync_block ("null_sink",
+                  gr_make_io_signature (1, 1, sizeof_stream_item),
+                  gr_make_io_signature (0, 0, 0))
+{
+}
+
+gr_block_sptr
+gr_make_null_sink (size_t sizeof_stream_item)
+{
+  return gr_block_sptr (new gr_null_sink (sizeof_stream_item));
+}
+
+int
+gr_null_sink::work (int noutput_items,
+                   gr_vector_const_void_star &input_items,
+                   gr_vector_void_star &output_items)
+{
+  return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_null_sink.h b/gnuradio-core/src/lib/general/gr_null_sink.h
new file mode 100644 (file)
index 0000000..55b61aa
--- /dev/null
@@ -0,0 +1,51 @@
+/* -*- 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 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.
+ */
+
+#ifndef INCLUDED_GR_NULL_SINK_H
+#define INCLUDED_GR_NULL_SINK_H
+
+#include <gr_sync_block.h>
+#include <stddef.h>                    // size_t
+
+/*!
+ * \brief Bit bucket
+ * \ingroup sink
+ */
+class gr_null_sink : public gr_sync_block
+{
+  friend gr_block_sptr gr_make_null_sink (size_t sizeof_stream_item);
+
+  gr_null_sink (size_t sizeof_stream_item);
+
+ public:
+
+  virtual int work (int noutput_items,
+                   gr_vector_const_void_star &input_items,
+                   gr_vector_void_star &output_items);
+
+};
+
+gr_block_sptr
+gr_make_null_sink (size_t sizeof_stream_item);
+
+#endif /* INCLUDED_GR_NULL_SINK_H */
diff --git a/gnuradio-core/src/lib/general/gr_null_sink.i b/gnuradio-core/src/lib/general/gr_null_sink.i
new file mode 100644 (file)
index 0000000..145be90
--- /dev/null
@@ -0,0 +1,30 @@
+/* -*- 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 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.
+ */
+
+%ignore gr_null_sink;
+class gr_null_sink : public gr_sync_block {
+  friend gr_block_sptr gr_make_null_sink (size_t sizeof_stream_item);
+  gr_null_sink (size_t sizeof_stream_item);
+};
+
+%rename(null_sink) gr_make_null_sink;
+gr_block_sptr gr_make_null_sink (size_t sizeof_stream_item);
diff --git a/gnuradio-core/src/lib/general/gr_null_source.cc b/gnuradio-core/src/lib/general/gr_null_source.cc
new file mode 100644 (file)
index 0000000..65923cf
--- /dev/null
@@ -0,0 +1,51 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_null_source.h>
+#include <gr_io_signature.h>
+
+gr_null_source::gr_null_source (size_t sizeof_stream_item)
+  : gr_sync_block ("null_source",
+                  gr_make_io_signature (0, 0, 0),
+                  gr_make_io_signature (1, 1, sizeof_stream_item))
+{
+}
+
+gr_block_sptr
+gr_make_null_source (size_t sizeof_stream_item)
+{
+  return gr_block_sptr (new gr_null_source (sizeof_stream_item));
+}
+
+int
+gr_null_source::work (int noutput_items,
+                     gr_vector_const_void_star &input_items,
+                     gr_vector_void_star &output_items)
+{
+  void *optr = (void *) output_items[0];
+  memset (optr, 0, noutput_items * output_signature()->sizeof_stream_item (0));
+  return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_null_source.h b/gnuradio-core/src/lib/general/gr_null_source.h
new file mode 100644 (file)
index 0000000..9fc43a0
--- /dev/null
@@ -0,0 +1,49 @@
+/* -*- 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 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.
+ */
+
+#ifndef INCLUDED_GR_NULL_SOURCE_H
+#define INCLUDED_GR_NULL_SOURCE_H
+
+#include <gr_sync_block.h>
+
+/*!
+ * \brief A source of zeros.
+ * \ingroup source
+ */
+
+class gr_null_source : public gr_sync_block
+{
+  friend gr_block_sptr gr_make_null_source (size_t sizeof_stream_item);
+
+  gr_null_source (size_t sizeof_stream_item);
+
+ public:
+  virtual int work (int noutput_items,
+                   gr_vector_const_void_star &input_items,
+                   gr_vector_void_star &output_items);
+  
+};
+
+gr_block_sptr
+gr_make_null_source (size_t sizeof_stream_item);
+
+#endif /* INCLUDED_GR_NULL_SOURCE_H */
diff --git a/gnuradio-core/src/lib/general/gr_null_source.i b/gnuradio-core/src/lib/general/gr_null_source.i
new file mode 100644 (file)
index 0000000..8a88f35
--- /dev/null
@@ -0,0 +1,30 @@
+/* -*- 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 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.
+ */
+
+%ignore gr_null_source;
+class gr_null_source : public gr_sync_block {
+  friend gr_block_sptr gr_make_null_source (size_t sizeof_stream_item);
+  gr_null_source (size_t sizeof_stream_item);
+};
+
+%rename(null_source) gr_make_null_source;
+gr_block_sptr gr_make_null_source (size_t sizeof_stream_item);
diff --git a/gnuradio-core/src/lib/general/gr_pa_2x2_phase_combiner.cc b/gnuradio-core/src/lib/general/gr_pa_2x2_phase_combiner.cc
new file mode 100644 (file)
index 0000000..7f470af
--- /dev/null
@@ -0,0 +1,74 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_pa_2x2_phase_combiner.h>
+#include <gr_io_signature.h>
+
+gr_pa_2x2_phase_combiner_sptr
+gr_make_pa_2x2_phase_combiner()
+{
+  return gr_pa_2x2_phase_combiner_sptr(new gr_pa_2x2_phase_combiner());
+}
+
+gr_pa_2x2_phase_combiner::gr_pa_2x2_phase_combiner ()
+  : gr_sync_block ("pa_2x2_phase_combiner",
+                  gr_make_io_signature (1, 1, NM * sizeof (gr_complex)),
+                  gr_make_io_signature (1, 1, sizeof (float)))
+{
+  set_theta(0);
+}
+
+void
+gr_pa_2x2_phase_combiner::set_theta(float theta)
+{
+  d_theta = theta;
+  gr_complex j = gr_complex(0,1);
+  d_phase[0] = exp(j * (float) (M_PI * (sin(theta) + cos(theta))));
+  d_phase[1] = exp(j * (float) (M_PI * cos(theta)));
+  d_phase[2] = exp(j * (float) (M_PI * sin(theta)));
+  d_phase[3] = exp(j * (float) 0.0);
+}
+
+int
+gr_pa_2x2_phase_combiner::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];
+
+  for (int i = 0; i < noutput_items; i++){
+    gr_complex acc = 0;
+    acc += in[0] * d_phase[0];
+    acc += in[1] * d_phase[1];
+    acc += in[2] * d_phase[2];
+    acc += in[3] * d_phase[3];
+    out[i] = acc;
+    in += 4;
+  }
+
+  return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_pa_2x2_phase_combiner.h b/gnuradio-core/src/lib/general/gr_pa_2x2_phase_combiner.h
new file mode 100644 (file)
index 0000000..e863496
--- /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 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.
+ */
+#ifndef INCLUDED_GR_PA_2X2_PHASE_COMBINER_H
+#define INCLUDED_GR_PA_2X2_PHASE_COMBINER_H
+
+#include <gr_sync_block.h>
+
+class gr_pa_2x2_phase_combiner;
+typedef boost::shared_ptr<gr_pa_2x2_phase_combiner> gr_pa_2x2_phase_combiner_sptr;
+
+gr_pa_2x2_phase_combiner_sptr gr_make_pa_2x2_phase_combiner ();
+
+/*!
+ * \brief pa_2x2 phase combiner
+ * \ingroup block
+ *
+ * Anntenas are arranged like this:
+ *
+ *     2  3
+ *     0  1
+ *
+ * dx and dy are lambda/2.
+ */
+class gr_pa_2x2_phase_combiner : public gr_sync_block
+{
+  static const int     NM = 4;
+
+  float                d_theta;
+  gr_complex   d_phase[NM];
+
+  gr_pa_2x2_phase_combiner ();
+  friend gr_pa_2x2_phase_combiner_sptr gr_make_pa_2x2_phase_combiner();
+
+ public:
+  float theta() const { return d_theta; }
+  void set_theta(float theta);
+
+  int work(int noutput_items,
+          gr_vector_const_void_star &input_items,
+          gr_vector_void_star &output_items);
+};
+
+#endif /* INCLUDED_GR_PA_2X2_PHASE_COMBINER_H */
diff --git a/gnuradio-core/src/lib/general/gr_pa_2x2_phase_combiner.i b/gnuradio-core/src/lib/general/gr_pa_2x2_phase_combiner.i
new file mode 100644 (file)
index 0000000..a19413a
--- /dev/null
@@ -0,0 +1,34 @@
+/* -*- 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 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.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,pa_2x2_phase_combiner)
+
+gr_pa_2x2_phase_combiner_sptr gr_make_pa_2x2_phase_combiner();
+
+class gr_pa_2x2_phase_combiner : public gr_sync_block
+{
+  gr_pa_2x2_phase_combiner();
+
+ public:
+  float theta() const;
+  void set_theta(float theta);
+};
diff --git a/gnuradio-core/src/lib/general/gr_packed_to_unpacked_XX.cc.t b/gnuradio-core/src/lib/general/gr_packed_to_unpacked_XX.cc.t
new file mode 100644 (file)
index 0000000..f585c4a
--- /dev/null
@@ -0,0 +1,133 @@
+/* -*- 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 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.
+ */
+
+// @WARNING@
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <@NAME@.h>
+#include <gr_io_signature.h>
+#include <assert.h>
+#include <gr_log2_const.h>
+
+static const unsigned int BITS_PER_TYPE = sizeof(@I_TYPE@) * 8;
+static const unsigned int LOG2_L_TYPE = gr_log2_const<sizeof(@I_TYPE@) * 8>();
+
+
+@SPTR_NAME@ 
+gr_make_@BASE_NAME@ (unsigned int bits_per_chunk, gr_endianness_t endianness)
+{
+  return @SPTR_NAME@ 
+    (new @NAME@ (bits_per_chunk,endianness));
+}
+
+@NAME@::@NAME@ (unsigned int bits_per_chunk, 
+                                                   gr_endianness_t endianness)
+  : gr_block ("@BASE_NAME@",
+             gr_make_io_signature (1, -1, sizeof (@I_TYPE@)),
+             gr_make_io_signature (1, -1, sizeof (@O_TYPE@))),
+    d_bits_per_chunk(bits_per_chunk),d_endianness(endianness),d_index(0)
+{
+  assert (bits_per_chunk <= BITS_PER_TYPE);
+  assert (bits_per_chunk > 0);
+
+  set_relative_rate ((1.0 * BITS_PER_TYPE) / bits_per_chunk);
+}
+
+void
+@NAME@::forecast(int noutput_items, gr_vector_int &ninput_items_required)
+{
+
+  int input_required = (int) ceil((d_index + noutput_items * d_bits_per_chunk) / (1.0 * BITS_PER_TYPE));
+  unsigned ninputs = ninput_items_required.size();
+  for (unsigned int i = 0; i < ninputs; i++) {
+    ninput_items_required[i] = input_required;
+    //printf("Forecast wants %d needs %d\n",noutput_items,ninput_items_required[i]);
+  }
+}
+
+unsigned int
+get_bit_le (const @I_TYPE@ *in_vector,unsigned int bit_addr)
+{
+  @I_TYPE@ x = in_vector[bit_addr>>LOG2_L_TYPE];
+  return (x>>(bit_addr&(BITS_PER_TYPE-1)))&1;
+}
+
+unsigned int
+get_bit_be (const @I_TYPE@ *in_vector,unsigned int bit_addr)
+{
+  @I_TYPE@ x = in_vector[bit_addr>>LOG2_L_TYPE];
+  return (x>>((BITS_PER_TYPE-1)-(bit_addr&(BITS_PER_TYPE-1))))&1;
+}
+
+int
+@NAME@::general_work (int noutput_items,
+                                       gr_vector_int &ninput_items,
+                                       gr_vector_const_void_star &input_items,
+                                       gr_vector_void_star &output_items)
+{
+  assert (input_items.size() == output_items.size());
+  int nstreams = input_items.size();
+
+  for (int m=0; m < nstreams; m++){
+    const @I_TYPE@ *in = (@I_TYPE@ *) input_items[m];
+    @O_TYPE@ *out = (@O_TYPE@ *) output_items[m];
+
+    // per stream processing
+
+    switch (d_endianness){
+
+    case GR_MSB_FIRST:
+      for (int i = 0; i < noutput_items; i++){
+       //printf("here msb %d\n",i);
+       @O_TYPE@ x = 0;
+       for(unsigned int j=0; j<d_bits_per_chunk; j++, d_index++)
+         x = (x<<1) | get_bit_be(in, d_index);
+       out[i] = x;
+      }
+      break;
+
+    case GR_LSB_FIRST:
+      for (int i = 0; i < noutput_items; i++){
+       //printf("here lsb %d\n",i);
+       @O_TYPE@ x = 0;
+       for(unsigned int j=0; j<d_bits_per_chunk; j++, d_index++)
+         x = (x<<1) | get_bit_le(in, d_index);
+       out[i] = x;
+      }
+      break;
+
+    default:
+      assert(0);
+    }
+
+    //printf("almost got to end\n");
+    assert(ninput_items[m] >= (int) ((d_index+(BITS_PER_TYPE-1))>>LOG2_L_TYPE));
+  }
+
+  consume_each (d_index >> LOG2_L_TYPE);
+  d_index = d_index & (BITS_PER_TYPE-1);
+  //printf("got to end\n");
+  return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_packed_to_unpacked_XX.h.t b/gnuradio-core/src/lib/general/gr_packed_to_unpacked_XX.h.t
new file mode 100644 (file)
index 0000000..1c9d2a0
--- /dev/null
@@ -0,0 +1,84 @@
+/* -*- 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 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.
+ */
+
+// @WARNING@
+
+#ifndef @GUARD_NAME@
+#define @GUARD_NAME@
+
+#include <gr_block.h>
+#include <gr_endianness.h>
+
+class @NAME@;
+typedef boost::shared_ptr<@NAME@> @SPTR_NAME@;
+
+@SPTR_NAME@ 
+gr_make_@BASE_NAME@ (unsigned int bits_per_chunk, gr_endianness_t endianness);
+
+/*!
+ * \brief Convert a stream of packed bytes or shorts to stream of unpacked bytes or shorts.
+ * \ingroup block
+ *
+ * input: stream of @I_TYPE@; output: stream of @O_TYPE@
+ *
+ * This is the inverse of gr_unpacked_to_packed_XX.
+ *
+ * The bits in the bytes or shorts input stream are grouped into chunks of 
+ * \p bits_per_chunk bits and each resulting chunk is written right-
+ * justified to the output stream of bytes or shorts.  
+ * All b or 16 bits of the each input bytes or short are processed.  
+ * The right thing is done if bits_per_chunk is not a power of two.
+ *
+ * The combination of gr_packed_to_unpacked_XX_ followed by
+ * gr_chunks_to_symbols_Xf or gr_chunks_to_symbols_Xc handles the
+ * general case of mapping from a stream of bytes or shorts into 
+ * arbitrary float or complex symbols.
+ *
+ * \sa gr_packed_to_unpacked_bb, gr_unpacked_to_packed_bb,
+ * \sa gr_packed_to_unpacked_ss, gr_unpacked_to_packed_ss,
+ * \sa gr_chunks_to_symbols_bf, gr_chunks_to_symbols_bc.
+ * \sa gr_chunks_to_symbols_sf, gr_chunks_to_symbols_sc.
+ */
+
+class @NAME@ : public gr_block
+{
+  friend @SPTR_NAME@ 
+  gr_make_@BASE_NAME@ (unsigned int bits_per_chunk, gr_endianness_t endianness);
+
+  @NAME@ (unsigned int bits_per_chunk, gr_endianness_t endianness);
+
+  unsigned int    d_bits_per_chunk;
+  gr_endianness_t d_endianness;
+  unsigned int    d_index;
+
+ 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);
+
+  bool check_topology(int ninputs, int noutputs) { return ninputs == noutputs; }
+
+};
+
+#endif
diff --git a/gnuradio-core/src/lib/general/gr_packed_to_unpacked_XX.i.t b/gnuradio-core/src/lib/general/gr_packed_to_unpacked_XX.i.t
new file mode 100644 (file)
index 0000000..9517a8a
--- /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 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.
+ */
+
+// @WARNING@
+
+GR_SWIG_BLOCK_MAGIC(gr,@BASE_NAME@);
+
+@SPTR_NAME@ 
+gr_make_@BASE_NAME@ (unsigned int bits_per_chunk, gr_endianness_t endianness);
+
+class @NAME@ : public gr_block
+{
+  @NAME@ (unsigned int bits_per_chunk, gr_endianness_t endianness);
+};
diff --git a/gnuradio-core/src/lib/general/gr_packet_sink.cc b/gnuradio-core/src/lib/general/gr_packet_sink.cc
new file mode 100644 (file)
index 0000000..f88758b
--- /dev/null
@@ -0,0 +1,206 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_packet_sink.h>
+#include <gr_io_signature.h>
+#include <cstdio>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdexcept>
+#include <gr_count_bits.h>
+
+#define VERBOSE 0
+
+static const int DEFAULT_THRESHOLD = 12;  // detect access code with up to DEFAULT_THRESHOLD bits wrong
+
+inline void
+gr_packet_sink::enter_search()
+{
+  if (VERBOSE)
+    fprintf(stderr, "@ enter_search\n");
+
+  d_state = STATE_SYNC_SEARCH;
+  d_shift_reg = 0;
+}
+    
+inline void
+gr_packet_sink::enter_have_sync()
+{
+  if (VERBOSE)
+    fprintf(stderr, "@ enter_have_sync\n");
+
+  d_state = STATE_HAVE_SYNC;
+  d_header = 0;
+  d_headerbitlen_cnt = 0;
+}
+
+inline void
+gr_packet_sink::enter_have_header(int payload_len)
+{
+  if (VERBOSE)
+    fprintf(stderr, "@ enter_have_header (payload_len = %d)\n", payload_len);
+
+  d_state = STATE_HAVE_HEADER;
+  d_packetlen  = payload_len;
+  d_packetlen_cnt = 0;
+  d_packet_byte = 0;
+  d_packet_byte_index = 0;
+}
+
+gr_packet_sink_sptr
+gr_make_packet_sink (const std::vector<unsigned char>& sync_vector,
+                    gr_msg_queue_sptr target_queue, int threshold)
+{
+  return gr_packet_sink_sptr (new gr_packet_sink (sync_vector, target_queue, threshold));
+}
+
+
+gr_packet_sink::gr_packet_sink (const std::vector<unsigned char>& sync_vector,
+                               gr_msg_queue_sptr target_queue, int threshold)
+  : gr_sync_block ("packet_sink",
+                  gr_make_io_signature (1, 1, sizeof(float)),
+                  gr_make_io_signature (0, 0, 0)),
+    d_target_queue(target_queue), d_threshold(threshold == -1 ? DEFAULT_THRESHOLD : threshold)
+{
+  d_sync_vector = 0;
+  for(int i=0;i<8;i++){
+    d_sync_vector <<= 8;
+    d_sync_vector |= sync_vector[i];
+  }
+
+  enter_search();
+}
+
+gr_packet_sink::~gr_packet_sink ()
+{
+}
+
+int
+gr_packet_sink::work (int noutput_items,
+                     gr_vector_const_void_star &input_items,
+                     gr_vector_void_star &output_items)
+{
+  float *inbuf = (float *) input_items[0];
+  int count=0;
+  
+  if (VERBOSE)
+    fprintf(stderr,">>> Entering state machine\n"),fflush(stderr);
+
+  while (count<noutput_items) {
+    switch(d_state) {
+      
+    case STATE_SYNC_SEARCH:    // Look for sync vector
+      if (VERBOSE)
+       fprintf(stderr,"SYNC Search, noutput=%d\n",noutput_items),fflush(stderr);
+
+      while (count < noutput_items) {
+       if(slice(inbuf[count++]))
+         d_shift_reg = (d_shift_reg << 1) | 1;
+       else
+         d_shift_reg = d_shift_reg << 1;
+
+       // Compute popcnt of putative sync vector
+       if(gr_count_bits64 (d_shift_reg ^ d_sync_vector) <= d_threshold) {
+         // Found it, set up for header decode
+         enter_have_sync();
+         break;
+       }
+      }
+      break;
+
+    case STATE_HAVE_SYNC:
+      if (VERBOSE)
+       fprintf(stderr,"Header Search bitcnt=%d, header=0x%08x\n", d_headerbitlen_cnt, d_header),
+         fflush(stderr);
+
+      while (count < noutput_items) {          // Shift bits one at a time into header
+       if(slice(inbuf[count++]))
+         d_header = (d_header << 1) | 1;
+       else
+         d_header = d_header << 1;
+
+       if (++d_headerbitlen_cnt == HEADERBITLEN) {
+
+         if (VERBOSE)
+           fprintf(stderr, "got header: 0x%08x\n", d_header);
+
+         // we have a full header, check to see if it has been received properly
+         if (header_ok()){
+           int payload_len = header_payload_len();
+           if (payload_len <= MAX_PKT_LEN)             // reasonable?
+             enter_have_header(payload_len);           // yes.
+           else
+             enter_search();                           // no.
+         }
+         else
+           enter_search();                             // no.
+         break;                        // we're in a new state
+       }
+      }
+      break;
+      
+    case STATE_HAVE_HEADER:
+      if (VERBOSE)
+       fprintf(stderr,"Packet Build\n"),fflush(stderr);
+
+      while (count < noutput_items) {   // shift bits into bytes of packet one at a time
+       if(slice(inbuf[count++]))
+         d_packet_byte = (d_packet_byte << 1) | 1;
+       else
+         d_packet_byte = d_packet_byte << 1;
+       
+       if (d_packet_byte_index++ == 7) {               // byte is full so move to next byte
+         d_packet[d_packetlen_cnt++] = d_packet_byte;
+         d_packet_byte_index = 0;
+
+         if (d_packetlen_cnt == d_packetlen){          // packet is filled
+
+           // build a message
+           gr_message_sptr msg = gr_make_message(0, 0, 0, d_packetlen_cnt);        
+           memcpy(msg->msg(), d_packet, d_packetlen_cnt);
+
+           d_target_queue->insert_tail(msg);           // send it
+           msg.reset();                                // free it up
+
+           enter_search();
+           break;
+         }
+       }
+      }
+      break;
+
+    default:
+      assert(0);
+
+    } // switch
+
+  }   // while
+
+  return noutput_items;
+}
+  
diff --git a/gnuradio-core/src/lib/general/gr_packet_sink.h b/gnuradio-core/src/lib/general/gr_packet_sink.h
new file mode 100644 (file)
index 0000000..3c468af
--- /dev/null
@@ -0,0 +1,111 @@
+/* -*- 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 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.
+ */
+
+#ifndef INCLUDED_GR_PACKET_SINK_H
+#define INCLUDED_GR_PACKET_SINK_H
+
+#include <gr_sync_block.h>
+#include <gr_msg_queue.h>
+
+class gr_packet_sink;
+typedef boost::shared_ptr<gr_packet_sink> gr_packet_sink_sptr;
+
+gr_packet_sink_sptr 
+gr_make_packet_sink (const std::vector<unsigned char>& sync_vector,
+                    gr_msg_queue_sptr target_queue,
+                    int threshold = -1                 // -1 -> use default
+                    );
+/*!
+ * \brief process received  bits looking for packet sync, header, and process bits into packet
+ * \ingroup sink
+ */
+class gr_packet_sink : public gr_sync_block
+{
+  friend gr_packet_sink_sptr 
+  gr_make_packet_sink (const std::vector<unsigned char>& sync_vector,
+                      gr_msg_queue_sptr target_queue,
+                      int threshold);
+
+ private:
+  enum state_t {STATE_SYNC_SEARCH, STATE_HAVE_SYNC, STATE_HAVE_HEADER};
+
+  static const int MAX_PKT_LEN    = 4096;
+  static const int HEADERBITLEN   = 32;
+
+  gr_msg_queue_sptr  d_target_queue;           // where to send the packet when received
+  unsigned long long d_sync_vector;            // access code to locate start of packet
+  unsigned int      d_threshold;               // how many bits may be wrong in sync vector
+
+  state_t            d_state;
+
+  unsigned long long d_shift_reg;              // used to look for sync_vector
+
+  unsigned int       d_header;                 // header bits
+  int               d_headerbitlen_cnt;        // how many so far
+
+  unsigned char      d_packet[MAX_PKT_LEN];    // assembled payload
+  unsigned char             d_packet_byte;             // byte being assembled
+  int               d_packet_byte_index;       // which bit of d_packet_byte we're working on
+  int               d_packetlen;               // length of packet
+  int               d_packetlen_cnt;           // how many so far
+
+ protected:
+  gr_packet_sink(const std::vector<unsigned char>& sync_vector, 
+                gr_msg_queue_sptr target_queue,
+                int threshold);
+
+  void enter_search();
+  void enter_have_sync();
+  void enter_have_header(int payload_len);
+  
+  int slice(float x) { return x > 0 ? 1 : 0; }
+
+  bool header_ok()
+  {
+    // confirm that two copies of header info are identical
+    return ((d_header >> 16) ^ (d_header & 0xffff)) == 0;
+  }
+
+  int header_payload_len()
+  {
+    // header consists of two 16-bit shorts in network byte order
+    int t = (d_header >> 16) & 0xffff;
+    return t;
+  }
+
+ public:
+  ~gr_packet_sink();
+
+  int work(int noutput_items,
+          gr_vector_const_void_star &input_items,
+          gr_vector_void_star &output_items);
+
+
+  //! return true if we detect carrier
+  bool carrier_sensed() const
+  {
+    return d_state != STATE_SYNC_SEARCH;
+  }
+
+};
+
+#endif /* INCLUDED_GR_PACKET_SINK_H */
diff --git a/gnuradio-core/src/lib/general/gr_packet_sink.i b/gnuradio-core/src/lib/general/gr_packet_sink.i
new file mode 100644 (file)
index 0000000..fb96072
--- /dev/null
@@ -0,0 +1,41 @@
+/* -*- 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 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.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,packet_sink)
+
+gr_packet_sink_sptr 
+gr_make_packet_sink (const std::vector<unsigned char>& sync_vector,
+                    gr_msg_queue_sptr target_queue,
+                    int threshold = -1        // -1 -> use default
+                    );
+
+class gr_packet_sink : public gr_sync_block
+{
+ protected:
+  gr_packet_sink (const std::vector<unsigned char>& sync_vector,
+                 gr_msg_queue_sptr target_queue,
+                 int threshold);
+ public:
+  ~gr_packet_sink ();
+
+  bool carrier_sensed() const;
+};
diff --git a/gnuradio-core/src/lib/general/gr_phase_modulator_fc.cc b/gnuradio-core/src/lib/general/gr_phase_modulator_fc.cc
new file mode 100644 (file)
index 0000000..95631f0
--- /dev/null
@@ -0,0 +1,62 @@
+/* -*- c++ -*- */
+/*
+ * 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_phase_modulator_fc.h>
+#include <gr_io_signature.h>
+#include <gr_sincos.h>
+#include <math.h>
+
+
+gr_phase_modulator_fc_sptr gr_make_phase_modulator_fc (double sensitivity)
+{
+  return gr_phase_modulator_fc_sptr (new gr_phase_modulator_fc (sensitivity));
+}
+
+gr_phase_modulator_fc::gr_phase_modulator_fc (double sensitivity)
+  : gr_sync_block ("phase_modulator_fc",
+                  gr_make_io_signature (1, 1, sizeof (float)),
+                  gr_make_io_signature (1, 1, sizeof (gr_complex))),
+    d_sensitivity (sensitivity), d_phase (0)
+{
+}
+
+int
+gr_phase_modulator_fc::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];
+  gr_complex *out = (gr_complex *) output_items[0];
+
+  for (int i = 0; i < noutput_items; i++){
+    d_phase = d_sensitivity * in[i];
+    float oi, oq;
+    gr_sincosf (d_phase, &oq, &oi);
+    out[i] = gr_complex (oi, oq);
+  }
+  return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_phase_modulator_fc.h b/gnuradio-core/src/lib/general/gr_phase_modulator_fc.h
new file mode 100644 (file)
index 0000000..ea27427
--- /dev/null
@@ -0,0 +1,55 @@
+/* -*- c++ -*- */
+/*
+ * 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 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.
+ */
+
+#ifndef INCLUDED_GR_PHASE_MODULATOR_FC_H
+#define INCLUDED_GR_PHASE_MODULATOR_FC_H
+
+#include <gr_sync_block.h>
+
+class gr_phase_modulator_fc;
+typedef boost::shared_ptr<gr_phase_modulator_fc> gr_phase_modulator_fc_sptr;
+
+gr_phase_modulator_fc_sptr gr_make_phase_modulator_fc (double sensitivity);
+
+/*!
+ * \brief Phase modulator block
+ * \ingroup block 
+ * output=complex(cos(in*sensitivity),sin(in*sensitivity))
+ */
+class gr_phase_modulator_fc : public gr_sync_block
+{
+  double       d_sensitivity;
+  double       d_phase;
+
+  friend gr_phase_modulator_fc_sptr
+  gr_make_phase_modulator_fc (double sensitivity);
+
+  gr_phase_modulator_fc (double sensitivity);
+
+ public:
+
+  int work (int noutput_items,
+           gr_vector_const_void_star &input_items,
+           gr_vector_void_star &output_items);
+};
+
+#endif /* INCLUDED_GR_PHASE_MODULATOR_FC_H */
diff --git a/gnuradio-core/src/lib/general/gr_phase_modulator_fc.i b/gnuradio-core/src/lib/general/gr_phase_modulator_fc.i
new file mode 100644 (file)
index 0000000..0ce25fd
--- /dev/null
@@ -0,0 +1,31 @@
+/* -*- c++ -*- */
+/*
+ * 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 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.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,phase_modulator_fc)
+
+gr_phase_modulator_fc_sptr gr_make_phase_modulator_fc (double sensitivity);
+
+class gr_phase_modulator_fc : public gr_sync_block
+{
+ private: 
+  gr_phase_modulator_fc (double sensitivity);
+};
diff --git a/gnuradio-core/src/lib/general/gr_pll_carriertracking_cc.cc b/gnuradio-core/src/lib/general/gr_pll_carriertracking_cc.cc
new file mode 100644 (file)
index 0000000..4736e77
--- /dev/null
@@ -0,0 +1,117 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_pll_carriertracking_cc.h>
+#include <gr_io_signature.h>
+#include <gr_sincos.h>
+#include <math.h>
+
+#define M_TWOPI (2*M_PI)
+
+gr_pll_carriertracking_cc_sptr
+gr_make_pll_carriertracking_cc (float alpha, float beta, float max_freq, float min_freq)
+{
+  return gr_pll_carriertracking_cc_sptr (new gr_pll_carriertracking_cc (alpha, beta, max_freq, min_freq));
+}
+
+gr_pll_carriertracking_cc::gr_pll_carriertracking_cc (float alpha, float beta, float max_freq, float min_freq)
+  : gr_sync_block ("pll_carriertracking_cc",
+                  gr_make_io_signature (1, 1, sizeof (gr_complex)),
+                  gr_make_io_signature (1, 1, sizeof (gr_complex))),
+    d_alpha(alpha), d_beta(beta), 
+    d_max_freq(max_freq), d_min_freq(min_freq),
+    d_phase(0), d_freq((max_freq+min_freq)/2),
+    d_locksig(0),d_lock_threshold(0),d_squelch_enable(false)
+{
+}
+
+float
+gr_pll_carriertracking_cc::mod_2pi (float in)
+{
+  if(in>M_PI)
+    return in-M_TWOPI;
+  else if(in<-M_PI)
+    return in+M_TWOPI;
+  else
+    return in;
+}
+
+float
+gr_pll_carriertracking_cc::phase_detector(gr_complex sample,float ref_phase)
+{
+  float sample_phase;
+  sample_phase = atan2(sample.imag(),sample.real());
+  return mod_2pi(sample_phase-ref_phase);
+}
+
+bool
+gr_pll_carriertracking_cc::lock_detector(void)
+{
+    return (fabs(d_locksig) > d_lock_threshold);
+}
+
+bool
+gr_pll_carriertracking_cc::squelch_enable(bool set_squelch)
+{
+    return d_squelch_enable = set_squelch;
+}
+
+float
+gr_pll_carriertracking_cc::set_lock_threshold(float threshold)
+{
+    return d_lock_threshold = threshold;
+}
+
+int
+gr_pll_carriertracking_cc::work (int noutput_items,
+                                gr_vector_const_void_star &input_items,
+                                gr_vector_void_star &output_items)
+{
+  const gr_complex *iptr = (gr_complex *) input_items[0];
+  gr_complex *optr = (gr_complex *) output_items[0];
+
+  float error;
+  float t_imag, t_real;
+  
+  for (int i = 0; i < noutput_items; i++){
+    error = phase_detector(iptr[i],d_phase);
+    
+    d_freq = d_freq + d_beta * error;
+    d_phase = mod_2pi(d_phase + d_freq + d_alpha * error);
+    
+    if (d_freq > d_max_freq)
+      d_freq = d_max_freq;
+    else if (d_freq < d_min_freq)
+      d_freq = d_min_freq;
+    gr_sincosf(d_phase,&t_imag,&t_real);
+    optr[i] = gr_complex(t_real,t_imag);
+    d_locksig = d_locksig * (1.0 - d_alpha) + d_alpha*(iptr[i].real() * t_real + iptr[i].imag() * t_imag);
+    
+    if ((d_squelch_enable) && !lock_detector())
+      optr[i] = 0;
+  }
+  return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_pll_carriertracking_cc.h b/gnuradio-core/src/lib/general/gr_pll_carriertracking_cc.h
new file mode 100644 (file)
index 0000000..679eb24
--- /dev/null
@@ -0,0 +1,70 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,206 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio is free software; you can 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.
+ */
+
+#ifndef INCLUDED_GR_PLL_CARRIERTRACKING_CC_H
+#define INCLUDED_GR_PLL_CARRIERTRACKING_CC_H
+
+#include <gr_sync_block.h>
+
+class gr_pll_carriertracking_cc;
+typedef boost::shared_ptr<gr_pll_carriertracking_cc> gr_pll_carriertracking_cc_sptr;
+
+gr_pll_carriertracking_cc_sptr gr_make_pll_carriertracking_cc (float alpha, float beta,
+                                              float max_freq, float min_freq);
+/*!
+ * \brief Implements a PLL which locks to the input frequency and outputs the 
+ * input signal mixed with that carrier.
+ * \ingroup block
+ *
+ * input: stream of complex; output: stream of complex
+ *
+ * This PLL locks onto a [possibly noisy] reference carrier on
+ * the input and outputs that signal, downconverted to DC
+ * 
+ * All settings max_freq and min_freq are in terms of radians per sample, 
+ * NOT HERTZ.  Alpha is the phase gain (first order, units of radians per radian) 
+ * and beta is the frequency gain (second order, units of radians per sample per radian)
+ * \sa gr_pll_freqdet_cf, gr_pll_carriertracking_cc
+ */
+
+class gr_pll_carriertracking_cc : public gr_sync_block
+{
+  friend gr_pll_carriertracking_cc_sptr gr_make_pll_carriertracking_cc (float alpha, float beta,
+                                                       float max_freq, float min_freq);
+
+  float d_alpha,d_beta,d_max_freq,d_min_freq,d_phase,d_freq,d_locksig,d_lock_threshold;
+  bool d_squelch_enable;
+  gr_pll_carriertracking_cc (float alpha, float beta, float max_freq, float min_freq);
+
+  int work (int noutput_items,
+           gr_vector_const_void_star &input_items,
+           gr_vector_void_star &output_items);
+private:
+  float mod_2pi (float in);
+  float phase_detector(gr_complex sample,float ref_phase);
+public:
+  bool lock_detector(void);
+  bool  squelch_enable(bool);
+  float set_lock_threshold(float);
+};
+
+#endif
diff --git a/gnuradio-core/src/lib/general/gr_pll_carriertracking_cc.i b/gnuradio-core/src/lib/general/gr_pll_carriertracking_cc.i
new file mode 100644 (file)
index 0000000..2653f8e
--- /dev/null
@@ -0,0 +1,38 @@
+/* -*- 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 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.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,pll_carriertracking_cc);
+
+gr_pll_carriertracking_cc_sptr
+gr_make_pll_carriertracking_cc (float alpha, float beta, 
+                               float max_freq, float min_freq);
+
+class gr_pll_carriertracking_cc : public gr_sync_block
+{
+ private:
+  gr_pll_carriertracking_cc (float alpha, float beta, float max_freq, float min_freq);
+ public:
+  bool lock_detector(void);
+  bool  squelch_enable(bool);
+  float set_lock_threshold(float);
+
+};
diff --git a/gnuradio-core/src/lib/general/gr_pll_freqdet_cf.cc b/gnuradio-core/src/lib/general/gr_pll_freqdet_cf.cc
new file mode 100644 (file)
index 0000000..f15f160
--- /dev/null
@@ -0,0 +1,94 @@
+/* -*- 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 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.
+ */
+
+// WARNING: this file is machine generated.  Edits will be over written
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_pll_freqdet_cf.h>
+#include <gr_io_signature.h>
+#include <math.h>
+
+#define M_TWOPI (2*M_PI)
+
+gr_pll_freqdet_cf_sptr
+gr_make_pll_freqdet_cf (float alpha, float beta, float max_freq, float min_freq)
+{
+  return gr_pll_freqdet_cf_sptr (new gr_pll_freqdet_cf (alpha, beta, max_freq, min_freq));
+}
+
+gr_pll_freqdet_cf::gr_pll_freqdet_cf (float alpha, float beta, float max_freq, float min_freq)
+  : gr_sync_block ("pll_freqdet_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_freq(max_freq), d_min_freq(min_freq),
+    d_phase(0), d_freq((max_freq+min_freq)/2)
+{
+}
+
+float
+gr_pll_freqdet_cf::mod_2pi (float in)
+{
+  if(in>M_PI)
+    return in-M_TWOPI;
+  else if(in<-M_PI)
+    return in+M_TWOPI;
+  else
+    return in;
+}
+
+float
+gr_pll_freqdet_cf::phase_detector(gr_complex sample,float ref_phase)
+{
+  float sample_phase;
+  sample_phase = atan2(sample.imag(),sample.real());
+  return mod_2pi(sample_phase-ref_phase);
+}
+
+int
+gr_pll_freqdet_cf::work (int noutput_items,
+                  gr_vector_const_void_star &input_items,
+                  gr_vector_void_star &output_items)
+{
+  const gr_complex *iptr = (gr_complex *) input_items[0];
+  float *optr = (float *) output_items[0];
+
+  float error;
+  int  size = noutput_items;
+  
+  while (size-- > 0) {
+    error = phase_detector(*iptr++,d_phase);
+    
+    d_freq = d_freq + d_beta * error;
+    d_phase = mod_2pi(d_phase + d_freq + d_alpha * error);
+    
+    if (d_freq > d_max_freq)
+      d_freq = d_max_freq;
+    else if (d_freq < d_min_freq)
+      d_freq = d_min_freq;
+    *optr++ = d_freq;
+  }
+  return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_pll_freqdet_cf.h b/gnuradio-core/src/lib/general/gr_pll_freqdet_cf.h
new file mode 100644 (file)
index 0000000..3d05a1c
--- /dev/null
@@ -0,0 +1,64 @@
+/* -*- 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 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.
+ */
+
+#ifndef INCLUDED_GR_PLL_FREQDET_CF_H
+#define INCLUDED_GR_PLL_FREQDET_CF_H
+
+#include <gr_sync_block.h>
+
+class gr_pll_freqdet_cf;
+typedef boost::shared_ptr<gr_pll_freqdet_cf> gr_pll_freqdet_cf_sptr;
+
+gr_pll_freqdet_cf_sptr gr_make_pll_freqdet_cf (float alpha, float beta,
+                                              float max_freq, float min_freq);
+/*!
+ * \brief Implements a PLL which locks to the input frequency and outputs 
+ * an estimate of that frequency.  Useful for FM Demod.
+ * \ingroup block
+ *
+ * input: stream of complex; output: stream of floats
+ *
+ * This PLL locks onto a [possibly noisy] reference carrier on
+ * the input and outputs an estimate of that frequency in radians per sample.
+ * All settings max_freq and min_freq are in terms of radians per sample, 
+ * NOT HERTZ.  Alpha is the phase gain (first order, units of radians per radian) 
+ * and beta is the frequency gain (second order, units of radians per sample per radian)
+ * \sa gr_pll_refout_cc, gr_pll_carriertracking_cc
+ */
+
+class gr_pll_freqdet_cf : public gr_sync_block
+{
+  friend gr_pll_freqdet_cf_sptr gr_make_pll_freqdet_cf (float alpha, float beta,
+                                                       float max_freq, float min_freq);
+
+  float d_alpha,d_beta,d_max_freq,d_min_freq,d_phase,d_freq;
+  gr_pll_freqdet_cf (float alpha, float beta, float max_freq, float min_freq);
+
+  int work (int noutput_items,
+           gr_vector_const_void_star &input_items,
+           gr_vector_void_star &output_items);
+private:
+  float mod_2pi (float in);
+  float phase_detector(gr_complex sample,float ref_phase);
+};
+
+#endif
diff --git a/gnuradio-core/src/lib/general/gr_pll_freqdet_cf.i b/gnuradio-core/src/lib/general/gr_pll_freqdet_cf.i
new file mode 100644 (file)
index 0000000..8a27c4f
--- /dev/null
@@ -0,0 +1,32 @@
+/* -*- 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 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.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,pll_freqdet_cf)
+
+  gr_pll_freqdet_cf_sptr gr_make_pll_freqdet_cf (float alpha, float beta, 
+                                                float max_freq, float min_freq);
+
+class gr_pll_freqdet_cf : public gr_sync_block
+{
+ private:
+  gr_pll_freqdet_cf (float alpha, float beta, float max_freq, float min_freq);
+};
diff --git a/gnuradio-core/src/lib/general/gr_pll_refout_cc.cc b/gnuradio-core/src/lib/general/gr_pll_refout_cc.cc
new file mode 100644 (file)
index 0000000..e535611
--- /dev/null
@@ -0,0 +1,97 @@
+/* -*- 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 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.
+ */
+
+// WARNING: this file is machine generated.  Edits will be over written
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_pll_refout_cc.h>
+#include <gr_io_signature.h>
+#include <gr_sincos.h>
+#include <math.h>
+
+#define M_TWOPI (2*M_PI)
+
+gr_pll_refout_cc_sptr
+gr_make_pll_refout_cc (float alpha, float beta, float max_freq, float min_freq)
+{
+  return gr_pll_refout_cc_sptr (new gr_pll_refout_cc (alpha, beta, max_freq, min_freq));
+}
+
+gr_pll_refout_cc::gr_pll_refout_cc (float alpha, float beta, float max_freq, float min_freq)
+  : gr_sync_block ("pll_refout_cc",
+                  gr_make_io_signature (1, 1, sizeof (gr_complex)),
+                  gr_make_io_signature (1, 1, sizeof (gr_complex))),
+    d_alpha(alpha), d_beta(beta), 
+    d_max_freq(max_freq), d_min_freq(min_freq),
+    d_phase(0), d_freq((max_freq+min_freq)/2)
+{
+}
+
+float
+gr_pll_refout_cc::mod_2pi (float in)
+{
+  if(in>M_PI)
+    return in-M_TWOPI;
+  else if(in<-M_PI)
+    return in+M_TWOPI;
+  else
+    return in;
+}
+
+float
+gr_pll_refout_cc::phase_detector(gr_complex sample,float ref_phase)
+{
+  float sample_phase;
+  sample_phase = atan2(sample.imag(),sample.real());
+  return mod_2pi(sample_phase-ref_phase);
+}
+
+int
+gr_pll_refout_cc::work (int noutput_items,
+                  gr_vector_const_void_star &input_items,
+                  gr_vector_void_star &output_items)
+{
+  const gr_complex *iptr = (gr_complex *) input_items[0];
+  gr_complex *optr = (gr_complex *) output_items[0];
+
+  float error;
+  float t_imag, t_real;
+  int  size = noutput_items;
+  
+  while (size-- > 0) {
+    error = phase_detector(*iptr++,d_phase);
+    
+    d_freq = d_freq + d_beta * error;
+    d_phase = mod_2pi(d_phase + d_freq + d_alpha * error);
+    
+    if (d_freq > d_max_freq)
+      d_freq = d_max_freq;
+    else if (d_freq < d_min_freq)
+      d_freq = d_min_freq;
+    gr_sincosf(d_phase,&t_imag,&t_real);
+    *optr++ = gr_complex(t_real,t_imag);
+  }
+  return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_pll_refout_cc.h b/gnuradio-core/src/lib/general/gr_pll_refout_cc.h
new file mode 100644 (file)
index 0000000..c46a65e
--- /dev/null
@@ -0,0 +1,66 @@
+/* -*- 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 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.
+ */
+
+
+
+#ifndef INCLUDED_GR_PLL_REFOUT_CC_H
+#define INCLUDED_GR_PLL_REFOUT_CC_H
+
+#include <gr_sync_block.h>
+
+class gr_pll_refout_cc;
+typedef boost::shared_ptr<gr_pll_refout_cc> gr_pll_refout_cc_sptr;
+
+gr_pll_refout_cc_sptr gr_make_pll_refout_cc (float alpha, float beta,
+                                              float max_freq, float min_freq);
+/*!
+ * \brief Implements a PLL which locks to the input frequency and outputs a carrier
+ * \ingroup block
+ *
+ * input: stream of complex; output: stream of complex
+ *
+ * This PLL locks onto a [possibly noisy] reference carrier on
+ * the input and outputs a clean version which is phase and frequency
+ * aligned to it.
+ * 
+ * All settings max_freq and min_freq are in terms of radians per sample, 
+ * NOT HERTZ.  Alpha is the phase gain (first order, units of radians per radian) 
+ * and beta is the frequency gain (second order, units of radians per sample per radian)
+ * \sa gr_pll_freqdet_cf, gr_pll_carriertracking_cc
+ */
+class gr_pll_refout_cc : public gr_sync_block
+{
+  friend gr_pll_refout_cc_sptr gr_make_pll_refout_cc (float alpha, float beta,
+                                                       float max_freq, float min_freq);
+
+  float d_alpha,d_beta,d_max_freq,d_min_freq,d_phase,d_freq;
+  gr_pll_refout_cc (float alpha, float beta, float max_freq, float min_freq);
+
+  int work (int noutput_items,
+           gr_vector_const_void_star &input_items,
+           gr_vector_void_star &output_items);
+private:
+  float mod_2pi (float in);
+  float phase_detector(gr_complex sample,float ref_phase);
+};
+
+#endif
diff --git a/gnuradio-core/src/lib/general/gr_pll_refout_cc.i b/gnuradio-core/src/lib/general/gr_pll_refout_cc.i
new file mode 100644 (file)
index 0000000..8cb4fde
--- /dev/null
@@ -0,0 +1,32 @@
+/* -*- 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 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.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,pll_refout_cc)
+
+  gr_pll_refout_cc_sptr gr_make_pll_refout_cc (float alpha, float beta, 
+                                                float max_freq, float min_freq);
+
+class gr_pll_refout_cc : public gr_sync_block
+{
+ private:
+  gr_pll_refout_cc (float alpha, float beta, float max_freq, float min_freq);
+};
diff --git a/gnuradio-core/src/lib/general/gr_prefix.cc.in b/gnuradio-core/src/lib/general/gr_prefix.cc.in
new file mode 100644 (file)
index 0000000..25c6960
--- /dev/null
@@ -0,0 +1,29 @@
+/* -*- 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 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.
+ */
+
+#include <gr_prefix.h>
+
+const std::string
+gr_prefix()
+{
+  return "@prefix@";
+}
diff --git a/gnuradio-core/src/lib/general/gr_prefix.h b/gnuradio-core/src/lib/general/gr_prefix.h
new file mode 100644 (file)
index 0000000..a521b61
--- /dev/null
@@ -0,0 +1,33 @@
+/* -*- 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 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.
+ */
+#ifndef INCLUDED_GR_PREFIX_H
+#define INCLUDED_GR_PREFIX_H
+
+#include <string>
+
+/*!
+ * \brief return ./configure --prefix argument.  Typically /usr/local
+ */
+const std::string gr_prefix();
+
+
+#endif /* INCLUDED_GR_PREFIX_H */
diff --git a/gnuradio-core/src/lib/general/gr_prefix.i b/gnuradio-core/src/lib/general/gr_prefix.i
new file mode 100644 (file)
index 0000000..04e1899
--- /dev/null
@@ -0,0 +1,5 @@
+/* -*- c++ -*- */
+
+%rename(prefix) gr_prefix;
+
+const std::string gr_prefix();
diff --git a/gnuradio-core/src/lib/general/gr_prefs.cc b/gnuradio-core/src/lib/general/gr_prefs.cc
new file mode 100644 (file)
index 0000000..c9721f0
--- /dev/null
@@ -0,0 +1,88 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <gr_prefs.h>
+
+/*
+ * Stub implementations
+ */
+
+static gr_prefs         s_default_singleton;
+static gr_prefs  *s_singleton = &s_default_singleton;
+
+gr_prefs *
+gr_prefs::singleton()
+{
+  return s_singleton;
+}
+
+void
+gr_prefs::set_singleton(gr_prefs *p)
+{
+  s_singleton = p;
+}
+
+gr_prefs::~gr_prefs()
+{
+  // nop
+}
+
+bool
+gr_prefs::has_section(const std::string section)
+{
+  return false;
+}
+
+bool
+gr_prefs::has_option(const std::string section, const std::string option)
+{
+  return false;
+}
+
+const std::string
+gr_prefs::get_string(const std::string section, const std::string option, const std::string default_val)
+{
+  return default_val;
+}
+
+bool
+gr_prefs::get_bool(const std::string section, const std::string option, bool default_val)
+{
+  return default_val;
+}
+
+long
+gr_prefs::get_long(const std::string section, const std::string option, long default_val)
+{
+  return default_val;
+}
+
+double
+gr_prefs::get_double(const std::string section, const std::string option, double default_val)
+{
+  return default_val;
+}
+
diff --git a/gnuradio-core/src/lib/general/gr_prefs.h b/gnuradio-core/src/lib/general/gr_prefs.h
new file mode 100644 (file)
index 0000000..eaf7487
--- /dev/null
@@ -0,0 +1,82 @@
+/* -*- 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 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.
+ */
+#ifndef INCLUDED_GR_PREFS_H
+#define INCLUDED_GR_PREFS_H
+
+#include <string>
+
+/*!
+ * \brief Base class for representing user preferences a la windows INI files.
+ *
+ * The real implementation is in Python, and is accessable from C++
+ * via the magic of SWIG directors.
+ */
+
+class gr_prefs
+{
+public:
+  static gr_prefs *singleton();
+  static void set_singleton(gr_prefs *p);
+
+  virtual ~gr_prefs();
+
+  /*!
+   * \brief Does \p section exist?
+   */
+  virtual bool has_section(const std::string section);
+
+  /*!
+   * \brief Does \p option exist?
+   */
+  virtual bool has_option(const std::string section, const std::string option);
+
+  /*!
+   * \brief If option exists return associated value; else default_val.
+   */
+  virtual const std::string get_string(const std::string section,
+                                      const std::string option,
+                                      const std::string default_val);
+
+  /*!
+   * \brief If option exists and value can be converted to bool, return it; else default_val.
+   */
+  virtual bool get_bool(const std::string section,
+                       const std::string option,
+                       bool default_val);
+
+  /*!
+   * \brief If option exists and value can be converted to long, return it; else default_val.
+   */
+  virtual long get_long(const std::string section,
+                       const std::string option,
+                       long default_val);
+
+  /*!
+   * \brief If option exists and value can be converted to double, return it; else default_val.
+   */
+  virtual double get_double(const std::string section,
+                           const std::string option,
+                           double default_val);
+};
+
+
+#endif /* INCLUDED_GR_PREFS_H */
diff --git a/gnuradio-core/src/lib/general/gr_prefs.i b/gnuradio-core/src/lib/general/gr_prefs.i
new file mode 100644 (file)
index 0000000..d11da17
--- /dev/null
@@ -0,0 +1,72 @@
+/* -*- 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 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.
+ */
+
+// Generate SWIG directors for gr_prefs.
+%feature("director") gr_prefs;
+
+class gr_prefs
+{
+public:
+  static gr_prefs *singleton();
+  static void set_singleton(gr_prefs *p);
+
+  virtual ~gr_prefs();
+
+  /*!
+   * \brief Does \p section exist?
+   */
+  virtual bool has_section(const std::string section);
+
+  /*!
+   * \brief Does \p option exist?
+   */
+  virtual bool has_option(const std::string section, const std::string option);
+
+  /*!
+   * \brief If option exists return associated value; else default_val.
+   */
+  virtual const std::string get_string(const std::string section,
+                                      const std::string option,
+                                      const std::string default_val);
+
+  /*!
+   * \brief If option exists and value can be converted to bool, return it; else default_val.
+   */
+  virtual bool get_bool(const std::string section,
+                       const std::string option,
+                       bool default_val);
+
+  /*!
+   * \brief If option exists and value can be converted to long, return it; else default_val.
+   */
+  virtual long get_long(const std::string section,
+                       const std::string option,
+                       long default_val);
+
+  /*!
+   * \brief If option exists and value can be converted to double, return it; else default_val.
+   */
+  virtual double get_double(const std::string section,
+                           const std::string option,
+                           double default_val);
+};
+
diff --git a/gnuradio-core/src/lib/general/gr_probe_avg_mag_sqrd_c.cc b/gnuradio-core/src/lib/general/gr_probe_avg_mag_sqrd_c.cc
new file mode 100644 (file)
index 0000000..73c7343
--- /dev/null
@@ -0,0 +1,84 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include <gr_probe_avg_mag_sqrd_c.h>
+#include <gr_io_signature.h>
+#include <cmath>
+
+gr_probe_avg_mag_sqrd_c_sptr
+gr_make_probe_avg_mag_sqrd_c(double threshold_db, double alpha)
+{
+  return gr_probe_avg_mag_sqrd_c_sptr(new gr_probe_avg_mag_sqrd_c(threshold_db, alpha));
+}
+
+gr_probe_avg_mag_sqrd_c::gr_probe_avg_mag_sqrd_c (double threshold_db, double alpha)
+  : gr_sync_block ("probe_avg_mag_sqrd_c",
+                  gr_make_io_signature(1, 1, sizeof(gr_complex)),
+                  gr_make_io_signature(0, 0, 0)),
+    d_iir(alpha), d_unmuted(false), d_level(0)
+{
+  set_threshold (threshold_db);
+}
+
+gr_probe_avg_mag_sqrd_c::~gr_probe_avg_mag_sqrd_c()
+{
+}
+
+
+int
+gr_probe_avg_mag_sqrd_c::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];
+
+  for (int i = 0; i < noutput_items; i++){
+    double mag_sqrd = in[i].real()*in[i].real() + in[i].imag()*in[i].imag();
+    d_iir.filter(mag_sqrd);    // computed for side effect: prev_output()
+  }
+
+  d_unmuted = d_iir.prev_output() >= d_threshold;
+  d_level = d_iir.prev_output();
+  return noutput_items;
+}
+
+double
+gr_probe_avg_mag_sqrd_c::threshold() const
+{
+  return 10 * std::log10(d_threshold);
+}
+
+void
+gr_probe_avg_mag_sqrd_c::set_threshold(double decibels)
+{
+  // convert to absolute threshold (mag squared)
+  d_threshold = std::pow(10.0, decibels/10);
+}
+
+void
+gr_probe_avg_mag_sqrd_c::set_alpha(double alpha)
+{
+  d_iir.set_taps(alpha);
+}
diff --git a/gnuradio-core/src/lib/general/gr_probe_avg_mag_sqrd_c.h b/gnuradio-core/src/lib/general/gr_probe_avg_mag_sqrd_c.h
new file mode 100644 (file)
index 0000000..85e2244
--- /dev/null
@@ -0,0 +1,74 @@
+/* -*- c++ -*- */
+/*
+ * 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 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.
+ */
+#ifndef INCLUDED_GR_PROBE_AVG_MAG_SQRD_C_H
+#define INCLUDED_GR_PROBE_AVG_MAG_SQRD_C_H
+
+#include <gr_sync_block.h>
+#include <gr_single_pole_iir.h>
+
+class gr_probe_avg_mag_sqrd_c;
+typedef boost::shared_ptr<gr_probe_avg_mag_sqrd_c> gr_probe_avg_mag_sqrd_c_sptr;
+
+gr_probe_avg_mag_sqrd_c_sptr
+gr_make_probe_avg_mag_sqrd_c (double threshold_db, double alpha = 0.0001);
+
+/*!
+ * \brief compute avg magnitude squared.
+ * \ingroup sink
+ *
+ * input: gr_complex
+ *
+ * Compute a running average of the magnitude squared of the the input.
+ * The level and indication as to whether the level exceeds threshold
+ * can be retrieved with the level and unmuted accessors.
+ */
+class gr_probe_avg_mag_sqrd_c : public gr_sync_block
+{
+  double                                       d_threshold;
+  gr_single_pole_iir<double,double,double>     d_iir;
+  bool                                         d_unmuted;
+  double                                       d_level;
+
+  friend gr_probe_avg_mag_sqrd_c_sptr
+  gr_make_probe_avg_mag_sqrd_c (double threshold_db, double alpha);
+
+  gr_probe_avg_mag_sqrd_c (double threshold_db, double alpha);
+
+public:
+  ~gr_probe_avg_mag_sqrd_c ();
+
+  int work (int noutput_items,
+           gr_vector_const_void_star &input_items,
+           gr_vector_void_star &output_items);
+
+  // ACCESSORS
+  bool unmuted () const { return d_unmuted; }
+  double level () const { return d_level; }
+
+  double threshold() const;
+
+  // SETTERS
+  void set_alpha (double alpha);
+  void set_threshold (double decibels);
+};
+
+#endif /* INCLUDED_GR_PROBE_AVG_MAG_SQRD_C_H */
diff --git a/gnuradio-core/src/lib/general/gr_probe_avg_mag_sqrd_c.i b/gnuradio-core/src/lib/general/gr_probe_avg_mag_sqrd_c.i
new file mode 100644 (file)
index 0000000..0b8000c
--- /dev/null
@@ -0,0 +1,36 @@
+/* -*- 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 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.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,probe_avg_mag_sqrd_c);
+
+gr_probe_avg_mag_sqrd_c_sptr
+gr_make_probe_avg_mag_sqrd_c (double threshold_db, double alpha = 0.0001);
+
+class gr_probe_avg_mag_sqrd_c : public gr_sync_block
+{
+public:
+  bool unmuted () const { return d_unmuted; }
+  double level () const { return d_level; }
+  void set_alpha (double alpha);
+  void set_threshold (double decibels);
+  double threshold();
+};
diff --git a/gnuradio-core/src/lib/general/gr_probe_avg_mag_sqrd_f.cc b/gnuradio-core/src/lib/general/gr_probe_avg_mag_sqrd_f.cc
new file mode 100644 (file)
index 0000000..439138f
--- /dev/null
@@ -0,0 +1,84 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include <gr_probe_avg_mag_sqrd_f.h>
+#include <gr_io_signature.h>
+#include <cmath>
+
+gr_probe_avg_mag_sqrd_f_sptr
+gr_make_probe_avg_mag_sqrd_f(double threshold_db, double alpha)
+{
+  return gr_probe_avg_mag_sqrd_f_sptr(new gr_probe_avg_mag_sqrd_f(threshold_db, alpha));
+}
+
+gr_probe_avg_mag_sqrd_f::gr_probe_avg_mag_sqrd_f (double threshold_db, double alpha)
+  : gr_sync_block ("probe_avg_mag_sqrd_f",
+                  gr_make_io_signature(1, 1, sizeof(float)),
+                  gr_make_io_signature(0, 0, 0)),
+    d_iir(alpha), d_unmuted(false), d_level(0)
+{
+  set_threshold (threshold_db);
+}
+
+gr_probe_avg_mag_sqrd_f::~gr_probe_avg_mag_sqrd_f()
+{
+}
+
+
+int
+gr_probe_avg_mag_sqrd_f::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];
+
+  for (int i = 0; i < noutput_items; i++){
+    double mag_sqrd = in[i]*in[i];
+    d_iir.filter(mag_sqrd);            // computed for side effect: prev_output()
+  }
+
+  d_unmuted = d_iir.prev_output() >= d_threshold;
+  d_level = d_iir.prev_output();
+  return noutput_items;
+}
+
+double
+gr_probe_avg_mag_sqrd_f::threshold() const
+{
+  return 10 * std::log10(d_threshold);
+}
+
+void
+gr_probe_avg_mag_sqrd_f::set_threshold(double decibels)
+{
+  // convert to absolute threshold (mag sqrd)
+  d_threshold = std::pow(10.0, decibels/10);
+}
+
+void
+gr_probe_avg_mag_sqrd_f::set_alpha(double alpha)
+{
+  d_iir.set_taps(alpha);
+}
diff --git a/gnuradio-core/src/lib/general/gr_probe_avg_mag_sqrd_f.h b/gnuradio-core/src/lib/general/gr_probe_avg_mag_sqrd_f.h
new file mode 100644 (file)
index 0000000..5f20a5c
--- /dev/null
@@ -0,0 +1,74 @@
+/* -*- 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 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.
+ */
+#ifndef INCLUDED_GR_PROBE_AVG_MAG_SQRD_F_H
+#define INCLUDED_GR_PROBE_AVG_MAG_SQRD_F_H
+
+#include <gr_sync_block.h>
+#include <gr_single_pole_iir.h>
+
+class gr_probe_avg_mag_sqrd_f;
+typedef boost::shared_ptr<gr_probe_avg_mag_sqrd_f> gr_probe_avg_mag_sqrd_f_sptr;
+
+gr_probe_avg_mag_sqrd_f_sptr
+gr_make_probe_avg_mag_sqrd_f (double threshold_db, double alpha = 0.0001);
+
+/*!
+ * \brief compute avg magnitude squared.
+ * \ingroup sink
+ *
+ * input: float
+ *
+ * Compute a running average of the magnitude squared of the the input.
+ * The level and indication as to whether the level exceeds threshold
+ * can be retrieved with the level and unmuted accessors.
+ */
+class gr_probe_avg_mag_sqrd_f : public gr_sync_block
+{
+  double                                       d_threshold;
+  gr_single_pole_iir<double,double,double>     d_iir;
+  bool                                         d_unmuted;
+  double                                       d_level;
+
+  friend gr_probe_avg_mag_sqrd_f_sptr
+  gr_make_probe_avg_mag_sqrd_f (double threshold_db, double alpha);
+
+  gr_probe_avg_mag_sqrd_f (double threshold_db, double alpha);
+
+public:
+  ~gr_probe_avg_mag_sqrd_f ();
+
+  int work (int noutput_items,
+           gr_vector_const_void_star &input_items,
+           gr_vector_void_star &output_items);
+
+  // ACCESSORS
+  bool unmuted () const { return d_unmuted; }
+  double level () const { return d_level; }
+
+  double threshold() const;
+
+  // SETTERS
+  void set_alpha (double alpha);
+  void set_threshold (double decibels);
+};
+
+#endif /* INCLUDED_GR_PROBE_AVG_MAG_SQRD_F_H */
diff --git a/gnuradio-core/src/lib/general/gr_probe_avg_mag_sqrd_f.i b/gnuradio-core/src/lib/general/gr_probe_avg_mag_sqrd_f.i
new file mode 100644 (file)
index 0000000..f58caa2
--- /dev/null
@@ -0,0 +1,36 @@
+/* -*- 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 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.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,probe_avg_mag_sqrd_f);
+
+gr_probe_avg_mag_sqrd_f_sptr
+gr_make_probe_avg_mag_sqrd_f (double threshold_db, double alpha = 0.0001);
+
+class gr_probe_avg_mag_sqrd_f : public gr_sync_block
+{
+public:
+  bool unmuted () const { return d_unmuted; }
+  double level () const { return d_level; }
+  double threshold() const;
+  void set_alpha (double alpha);
+  void set_threshold (double decibels);
+};
diff --git a/gnuradio-core/src/lib/general/gr_probe_signal_f.cc b/gnuradio-core/src/lib/general/gr_probe_signal_f.cc
new file mode 100644 (file)
index 0000000..8c94b03
--- /dev/null
@@ -0,0 +1,60 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include <gr_probe_signal_f.h>
+#include <gr_io_signature.h>
+
+gr_probe_signal_f_sptr
+gr_make_probe_signal_f()
+{
+  return gr_probe_signal_f_sptr(new gr_probe_signal_f());
+}
+
+gr_probe_signal_f::gr_probe_signal_f ()
+  : gr_sync_block ("probe_signal_f",
+                  gr_make_io_signature(1, 1, sizeof(float)),
+                  gr_make_io_signature(0, 0, 0)),
+    d_level(0)
+{
+}
+
+gr_probe_signal_f::~gr_probe_signal_f()
+{
+}
+
+
+int
+gr_probe_signal_f::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];
+
+  if (noutput_items > 0)
+    d_level = in[noutput_items-1];
+
+  return noutput_items;
+}
+
diff --git a/gnuradio-core/src/lib/general/gr_probe_signal_f.h b/gnuradio-core/src/lib/general/gr_probe_signal_f.h
new file mode 100644 (file)
index 0000000..72811b2
--- /dev/null
@@ -0,0 +1,57 @@
+/* -*- 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 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.
+ */
+#ifndef INCLUDED_GR_PROBE_SIGNAL_F_H
+#define INCLUDED_GR_PROBE_SIGNAL_F_H
+
+#include <gr_sync_block.h>
+
+class gr_probe_signal_f;
+typedef boost::shared_ptr<gr_probe_signal_f> gr_probe_signal_f_sptr;
+
+gr_probe_signal_f_sptr
+gr_make_probe_signal_f ();
+
+/*!
+ * \brief Sink that allows a sample to be grabbed from Python.
+ * \ingroup sink
+ */
+class gr_probe_signal_f : public gr_sync_block
+{
+  float        d_level;
+
+  friend gr_probe_signal_f_sptr
+  gr_make_probe_signal_f();
+
+  gr_probe_signal_f();
+
+public:
+  ~gr_probe_signal_f();
+
+  int work(int noutput_items,
+          gr_vector_const_void_star &input_items,
+          gr_vector_void_star &output_items);
+
+  float level() const { return d_level; }
+
+};
+
+#endif /* INCLUDED_GR_PROBE_SIGNAL_F_H */
diff --git a/gnuradio-core/src/lib/general/gr_probe_signal_f.i b/gnuradio-core/src/lib/general/gr_probe_signal_f.i
new file mode 100644 (file)
index 0000000..14fc6f1
--- /dev/null
@@ -0,0 +1,32 @@
+/* -*- 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 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.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,probe_signal_f);
+
+gr_probe_signal_f_sptr
+gr_make_probe_signal_f ();
+
+class gr_probe_signal_f : public gr_sync_block
+{
+public:
+  float level () const { return d_level; }
+};
diff --git a/gnuradio-core/src/lib/general/gr_pwr_squelch_cc.cc b/gnuradio-core/src/lib/general/gr_pwr_squelch_cc.cc
new file mode 100644 (file)
index 0000000..33c1287
--- /dev/null
@@ -0,0 +1,55 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_pwr_squelch_cc.h>
+
+gr_pwr_squelch_cc_sptr
+gr_make_pwr_squelch_cc(double threshold, double alpha, int ramp, bool gate)
+{
+  return gr_pwr_squelch_cc_sptr(new gr_pwr_squelch_cc(threshold, alpha, ramp, gate));
+}
+
+gr_pwr_squelch_cc::gr_pwr_squelch_cc(double threshold, double alpha, int ramp, bool gate) : 
+       gr_squelch_base_cc("pwr_squelch_cc", ramp, gate),
+       d_iir(alpha)
+{
+  set_threshold(threshold);
+}
+
+std::vector<float> gr_pwr_squelch_cc::squelch_range() const
+{
+  std::vector<float> r(3);
+  r[0] = -50.0;                                // min  FIXME
+  r[1] = +50.0;                                // max  FIXME
+  r[2] = (r[1] - r[0]) / 100;          // step size
+
+  return r;
+}
+
+void gr_pwr_squelch_cc::update_state(const gr_complex &in)
+{
+  d_pwr = d_iir.filter(in.real()*in.real()+in.imag()*in.imag());
+}
diff --git a/gnuradio-core/src/lib/general/gr_pwr_squelch_cc.h b/gnuradio-core/src/lib/general/gr_pwr_squelch_cc.h
new file mode 100644 (file)
index 0000000..2822ee5
--- /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 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.
+ */
+
+#ifndef INCLUDED_GR_PWR_SQUELCH_CC_H
+#define INCLUDED_GR_PWR_SQUELCH_CC_H
+
+#include <cmath>
+#include <gr_squelch_base_cc.h>
+#include <gr_single_pole_iir.h>
+
+class gr_pwr_squelch_cc;
+typedef boost::shared_ptr<gr_pwr_squelch_cc> gr_pwr_squelch_cc_sptr;
+
+gr_pwr_squelch_cc_sptr 
+gr_make_pwr_squelch_cc(double db, double alpha = 0.0001, int ramp=0, bool gate=false);
+
+/*!
+ * \brief gate or zero output when input power below threshold
+ * \ingroup block
+ */
+class gr_pwr_squelch_cc : public gr_squelch_base_cc
+{
+private:
+  double d_threshold;
+  double d_pwr;
+  gr_single_pole_iir<double,double,double> d_iir;
+
+  friend gr_pwr_squelch_cc_sptr gr_make_pwr_squelch_cc(double db, double alpha, int ramp, bool gate);
+  gr_pwr_squelch_cc(double db, double alpha, int ramp, bool gate);
+
+protected:
+  virtual void update_state(const gr_complex &in);
+  virtual bool mute() const { return d_pwr < d_threshold; }
+  
+public:
+  std::vector<float> squelch_range() const;
+
+  double threshold() const { return 10*log10(d_threshold); }
+  void set_threshold(double db) { d_threshold = std::pow(10.0, db/10); }
+  void set_alpha(double alpha) { d_iir.set_taps(alpha); }
+};
+
+#endif /* INCLUDED_GR_PWR_SQUELCH_CC_H */
diff --git a/gnuradio-core/src/lib/general/gr_pwr_squelch_cc.i b/gnuradio-core/src/lib/general/gr_pwr_squelch_cc.i
new file mode 100644 (file)
index 0000000..41832ab
--- /dev/null
@@ -0,0 +1,40 @@
+/* -*- 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 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.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,pwr_squelch_cc);
+
+%include gr_squelch_base_cc.i
+
+gr_pwr_squelch_cc_sptr 
+gr_make_pwr_squelch_cc(double db, double alpha=0.0001, int ramp=0, bool gate=false);
+
+class gr_pwr_squelch_cc : public gr_squelch_base_cc
+{
+private:
+  gr_pwr_squelch_cc(double db, double alpha, int ramp, bool gate);
+
+public:
+  double threshold() const { return 10*log10(d_threshold); }
+  void set_threshold(double db) { d_threshold = std::pow(10.0, db/10); }
+  void set_alpha(double alpha) { d_iir.set_taps(alpha); }
+  std::vector<float> squelch_range() const;
+};
diff --git a/gnuradio-core/src/lib/general/gr_pwr_squelch_ff.cc b/gnuradio-core/src/lib/general/gr_pwr_squelch_ff.cc
new file mode 100644 (file)
index 0000000..8bc3aad
--- /dev/null
@@ -0,0 +1,55 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_pwr_squelch_ff.h>
+
+gr_pwr_squelch_ff_sptr
+gr_make_pwr_squelch_ff(double threshold, double alpha, int ramp, bool gate)
+{
+  return gr_pwr_squelch_ff_sptr(new gr_pwr_squelch_ff(threshold, alpha, ramp, gate));
+}
+
+gr_pwr_squelch_ff::gr_pwr_squelch_ff(double threshold, double alpha, int ramp, bool gate) : 
+       gr_squelch_base_ff("pwr_squelch_ff", ramp, gate),
+       d_iir(alpha)
+{
+  set_threshold(threshold);
+}
+
+std::vector<float> gr_pwr_squelch_ff::squelch_range() const
+{
+  std::vector<float> r(3);
+  r[0] = -50.0;                                // min  FIXME
+  r[1] = +50.0;                                // max  FIXME
+  r[2] = (r[1] - r[0]) / 100;          // step size
+
+  return r;
+}
+
+void gr_pwr_squelch_ff::update_state(const float &in)
+{
+  d_pwr = d_iir.filter(in*in);
+}
diff --git a/gnuradio-core/src/lib/general/gr_pwr_squelch_ff.h b/gnuradio-core/src/lib/general/gr_pwr_squelch_ff.h
new file mode 100644 (file)
index 0000000..1eb61b1
--- /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 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.
+ */
+
+#ifndef INCLUDED_GR_PWR_SQUELCH_FF_H
+#define INCLUDED_GR_PWR_SQUELCH_FF_H
+
+#include <cmath>
+#include <gr_squelch_base_ff.h>
+#include <gr_single_pole_iir.h>
+
+class gr_pwr_squelch_ff;
+typedef boost::shared_ptr<gr_pwr_squelch_ff> gr_pwr_squelch_ff_sptr;
+
+gr_pwr_squelch_ff_sptr 
+gr_make_pwr_squelch_ff(double db, double alpha = 0.0001, int ramp=0, bool gate=false);
+
+/*!
+ * \brief gate or zero output when input power below threshold
+ * \ingroup block
+ */
+class gr_pwr_squelch_ff : public gr_squelch_base_ff
+{
+private:
+  double d_threshold;
+  double d_pwr;
+  gr_single_pole_iir<double,double,double> d_iir;
+
+  friend gr_pwr_squelch_ff_sptr gr_make_pwr_squelch_ff(double db, double alpha, int ramp, bool gate);
+  gr_pwr_squelch_ff(double db, double alpha, int ramp, bool gate);
+
+protected:
+  virtual void update_state(const float &in);
+  virtual bool mute() const { return d_pwr < d_threshold; }
+  
+public:
+  std::vector<float> squelch_range() const;
+
+  double threshold() const { return 10*log10(d_threshold); }
+  void set_threshold(double db) { d_threshold = std::pow(10.0, db/10); }
+  void set_alpha(double alpha) { d_iir.set_taps(alpha); }
+};
+
+#endif /* INCLUDED_GR_PWR_SQUELCH_FF_H */
diff --git a/gnuradio-core/src/lib/general/gr_pwr_squelch_ff.i b/gnuradio-core/src/lib/general/gr_pwr_squelch_ff.i
new file mode 100644 (file)
index 0000000..4bc16b1
--- /dev/null
@@ -0,0 +1,40 @@
+/* -*- 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 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.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,pwr_squelch_ff);
+
+%include gr_squelch_base_ff.i
+
+gr_pwr_squelch_ff_sptr 
+gr_make_pwr_squelch_ff(double db, double alpha=0.0001, int ramp=0, bool gate=false);
+
+class gr_pwr_squelch_ff : public gr_squelch_base_ff
+{
+private:
+  gr_pwr_squelch_ff(double db, double alpha, int ramp, bool gate);
+
+public:
+  double threshold() const { return 10*log10(d_threshold); }
+  void set_threshold(double db) { d_threshold = std::pow(10.0, db/10); }
+  void set_alpha(double alpha) { d_iir.set_taps(alpha); }
+  std::vector<float> squelch_range() const;
+};
diff --git a/gnuradio-core/src/lib/general/gr_quadrature_demod_cf.cc b/gnuradio-core/src/lib/general/gr_quadrature_demod_cf.cc
new file mode 100644 (file)
index 0000000..eb1fae8
--- /dev/null
@@ -0,0 +1,62 @@
+/* -*- c++ -*- */
+/*
+ * 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_quadrature_demod_cf.h>
+#include <gr_io_signature.h>
+#include <gr_math.h>
+
+gr_quadrature_demod_cf::gr_quadrature_demod_cf (float gain)
+  : gr_sync_block ("quadrature_demod_cf",
+                  gr_make_io_signature (1, 1, sizeof (gr_complex)),
+                  gr_make_io_signature (1, 1, sizeof (float))),
+    d_gain (gain)
+{
+  set_history (2);     // we need to look at the previous value
+}
+
+gr_quadrature_demod_cf_sptr
+gr_make_quadrature_demod_cf (float gain)
+{
+  return gr_quadrature_demod_cf_sptr (new gr_quadrature_demod_cf (gain));
+}
+
+int
+gr_quadrature_demod_cf::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];
+  float *out = (float *) output_items[0];
+  in++;                                // ensure that in[-1] is valid
+  
+  for (int i = 0; i < noutput_items; i++){
+    gr_complex product = in[i] * conj (in[i-1]);
+    // out[i] = d_gain * arg (product);
+    out[i] = d_gain * gr_fast_atan2f(imag(product), real(product));
+  }
+
+  return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_quadrature_demod_cf.h b/gnuradio-core/src/lib/general/gr_quadrature_demod_cf.h
new file mode 100644 (file)
index 0000000..7e625e7
--- /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 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.
+ */
+
+#ifndef INCLUDED_GR_QUADRATURE_DEMOD_CF_H
+#define INCLUDED_GR_QUADRATURE_DEMOD_CF_H
+
+#include <gr_sync_block.h>
+
+class gr_quadrature_demod_cf;
+typedef boost::shared_ptr<gr_quadrature_demod_cf> gr_quadrature_demod_cf_sptr;
+gr_quadrature_demod_cf_sptr gr_make_quadrature_demod_cf (float gain);
+
+/*!
+ * \brief quadrature demodulator: complex in, float out
+ * \ingroup block
+ *
+ * This can be used to demod FM, FSK, GMSK, etc.
+ * The input is complex baseband.
+ */
+class gr_quadrature_demod_cf : public gr_sync_block
+{
+  friend gr_quadrature_demod_cf_sptr gr_make_quadrature_demod_cf (float gain);
+  gr_quadrature_demod_cf (float gain);
+
+  float                d_gain;
+
+ public:
+
+  int work (int noutput_items,
+                gr_vector_const_void_star &input_items,
+                gr_vector_void_star &output_items);
+};
+
+#endif /* INCLUDED_GR_QUADRATURE_DEMOD_CF_H */
diff --git a/gnuradio-core/src/lib/general/gr_quadrature_demod_cf.i b/gnuradio-core/src/lib/general/gr_quadrature_demod_cf.i
new file mode 100644 (file)
index 0000000..685b278
--- /dev/null
@@ -0,0 +1,30 @@
+/* -*- 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 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.
+ */
+
+GR_SWIG_BLOCK_MAGIC (gr, quadrature_demod_cf)
+
+gr_quadrature_demod_cf_sptr gr_make_quadrature_demod_cf (float gain);
+
+class gr_quadrature_demod_cf : public gr_sync_block
+{
+  gr_quadrature_demod_cf (float gain);
+};
diff --git a/gnuradio-core/src/lib/general/gr_random.cc b/gnuradio-core/src/lib/general/gr_random.cc
new file mode 100644 (file)
index 0000000..a56f287
--- /dev/null
@@ -0,0 +1,180 @@
+/* -*- 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 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.
+ */
+
+/*
+ *  Copyright 1997 Massachusetts Institute of Technology
+ * 
+ *  Permission to use, copy, modify, distribute, and sell this software and its
+ *  documentation for any purpose is hereby granted without fee, provided that
+ *  the above copyright notice appear in all copies and that both that
+ *  copyright notice and this permission notice appear in supporting
+ *  documentation, and that the name of M.I.T. not be used in advertising or
+ *  publicity pertaining to distribution of the software without specific,
+ *  written prior permission.  M.I.T. makes no representations about the
+ *  suitability of this software for any purpose.  It is provided "as is"
+ *  without express or implied warranty.
+ * 
+ */
+
+#include <math.h>
+#include <gr_random.h>
+
+#define IA 16807
+#define IM 2147483647
+#define AM (1.0/IM)
+#define IQ 127773
+#define IR 2836
+#define NDIV (1+(IM-1)/NTAB)
+#define EPS 1.2e-7
+#define RNMX (1.0-EPS)
+
+
+gr_random::gr_random (long seed)
+{
+  reseed (seed);
+}
+
+void
+gr_random::reseed (long seed)
+{
+  d_seed = seed;
+  d_iy = 0;
+  for (int i = 0; i < NTAB; i++)
+    d_iv[i] = 0;
+  d_iset = 0;
+  d_gset = 0;
+}
+
+/*
+ * This looks like it returns a uniform random deviate between 0.0 and 1.0
+ * It looks similar to code from "Numerical Recipes in C".
+ */
+float gr_random::ran1()
+{
+  int j;
+  long k;
+  float temp;
+  
+  if (d_seed <= 0 || !d_iy)  {
+    if (-d_seed < 1) 
+      d_seed=1;
+    else 
+      d_seed = -d_seed;
+    for (j=NTAB+7;j>=0;j--) {
+      k=d_seed/IQ;
+      d_seed=IA*(d_seed-k*IQ)-IR*k;
+      if (d_seed < 0) 
+       d_seed += IM;
+      if (j < NTAB) 
+       d_iv[j] = d_seed;
+    }
+    d_iy=d_iv[0];
+  }
+  k=(d_seed)/IQ;
+  d_seed=IA*(d_seed-k*IQ)-IR*k;
+  if (d_seed < 0)
+    d_seed += IM;
+  j=d_iy/NDIV;
+  d_iy=d_iv[j];
+  d_iv[j] = d_seed;
+  temp=AM * d_iy;
+  if (temp > RNMX)
+    temp = RNMX;
+  return temp;
+}
+
+/*
+ * Returns a normally distributed deviate with zero mean and variance 1.
+ * Also looks like it's from "Numerical Recipes in C".
+ */
+float gr_random::gasdev()
+{
+  float fac,rsq,v1,v2;
+  d_iset = 1 - d_iset;
+  if  (d_iset) {
+    do {
+      v1=2.0*ran1()-1.0;
+      v2=2.0*ran1()-1.0;
+      rsq=v1*v1+v2*v2;
+    } while (rsq >= 1.0 || rsq == 0.0);
+    fac= sqrt(-2.0*log(rsq)/rsq);
+    d_gset=v1*fac;
+    return v2*fac;
+  }
+  return d_gset;
+}
+
+/*
+ * Copied from The KC7WW / OH2BNS Channel Simulator
+ * FIXME Need to check how good this is at some point
+ */
+
+float gr_random::laplacian()
+{
+  float z = ran1();
+  if (z < 0.5)
+    return log(2.0 * z) / M_SQRT2;
+  else
+    return -log(2.0 * (1.0 - z)) / M_SQRT2;
+}
+
+/*
+ * Copied from The KC7WW / OH2BNS Channel Simulator
+ * FIXME Need to check how good this is at some point
+ */
+
+  // 5 => scratchy, 8 => Geiger
+
+float gr_random::impulse(float factor = 5)
+{
+  float z = -M_SQRT2 * log(ran1());
+  if (fabsf(z) <= factor)              
+    return 0.0;
+  else 
+    return z;
+}
+
+/*
+ * Complex rayleigh is really gaussian I and gaussian Q
+ * It can also be generated by real rayleigh magnitude and
+ * uniform random angle 
+ * Adapted from The KC7WW / OH2BNS Channel Simulator
+ * FIXME Need to check how good this is at some point
+ */
+
+gr_complex gr_random::rayleigh_complex()
+{
+  return gr_complex(gasdev(),gasdev());
+}
+
+/*   Other option
+     mag = rayleigh();
+     ang = 2.0 * M_PI * RNG();
+     *Rx = rxx * cos(z);
+     *Iy = rxx * sin(z);
+*/
+
+
+float gr_random::rayleigh()
+{
+  return sqrt(-2.0 * log(ran1()));
+}
diff --git a/gnuradio-core/src/lib/general/gr_random.h b/gnuradio-core/src/lib/general/gr_random.h
new file mode 100644 (file)
index 0000000..9726ee9
--- /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 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.
+ */
+
+#ifndef INCLUDED_GR_RANDOM_H
+#define INCLUDED_GR_RANDOM_H
+
+#include <gr_complex.h>
+
+/*!
+ * \brief pseudo random number generator
+ */
+class gr_random {
+protected:
+  static const int NTAB  = 32;
+  long  d_seed;
+  long  d_iy;
+  long  d_iv[NTAB];
+  int  d_iset;
+  float        d_gset;
+
+  
+public: 
+  gr_random (long seed=3021);
+
+  void reseed (long seed);
+
+  /*!
+   * \brief uniform random deviate in the range [0.0, 1.0)
+   */
+  float ran1 ();
+
+  /*!
+   * \brief normally distributed deviate with zero mean and variance 1
+   */
+  float gasdev ();
+
+  float laplacian ();
+  float impulse (float factor);
+  float rayleigh ();
+  gr_complex rayleigh_complex ();
+};
+
+#endif /* INCLUDED_GR_RANDOM_H */
+
diff --git a/gnuradio-core/src/lib/general/gr_remez.cc b/gnuradio-core/src/lib/general/gr_remez.cc
new file mode 100644 (file)
index 0000000..1003900
--- /dev/null
@@ -0,0 +1,1031 @@
+/**************************************************************************
+ * Parks-McClellan algorithm for FIR filter design (C version)
+ *-------------------------------------------------
+ *  Copyright (c) 1995,1998  Jake Janovetz (janovetz@uiuc.edu)
+ *  Copyright (c) 2004  Free Software Foundation, Inc.
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Library General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Library General Public
+ *  License along with this library; if not, write to the Free
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ *
+ *  Sep 1999 - Paul Kienzle (pkienzle@cs.indiana.edu)
+ *      Modified for use in octave as a replacement for the matlab function
+ *      remez.mex.  In particular, magnitude responses are required for all
+ *      band edges rather than one per band, griddensity is a parameter,
+ *      and errors are returned rather than printed directly.
+ *  Mar 2000 - Kai Habel (kahacjde@linux.zrz.tu-berlin.de)
+ *      Change: ColumnVector x=arg(i).vector_value();
+ *      to: ColumnVector x(arg(i).vector_value());
+ *  There appear to be some problems with the routine Search. See comments
+ *  therein [search for PAK:].  I haven't looked closely at the rest
+ *  of the code---it may also have some problems.
+ *************************************************************************/
+
+/*
+ * This code was extracted from octave.sf.net, and wrapped with
+ * GNU Radio glue.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include <gr_remez.h>
+#include <cmath>
+#include <assert.h>
+#include <iostream>
+
+
+#ifndef LOCAL_BUFFER
+#include <vector>
+#define LOCAL_BUFFER(T, buf, size) \
+  std::vector<T> buf ## _vector (size); \
+  T *buf = &(buf ## _vector[0])
+#endif
+
+
+#define CONST const
+#define BANDPASS       1
+#define DIFFERENTIATOR 2
+#define HILBERT        3
+
+#define NEGATIVE       0
+#define POSITIVE       1
+
+#define Pi             3.14159265358979323846
+#define Pi2            (2*Pi)
+
+#define GRIDDENSITY    16
+#define MAXITERATIONS  40
+
+/*******************
+ * CreateDenseGrid
+ *=================
+ * Creates the dense grid of frequencies from the specified bands.
+ * Also creates the Desired Frequency Response function (D[]) and
+ * the Weight function (W[]) on that dense grid
+ *
+ *
+ * INPUT:
+ * ------
+ * int      r        - 1/2 the number of filter coefficients
+ * int      numtaps  - Number of taps in the resulting filter
+ * int      numband  - Number of bands in user specification
+ * double   bands[]  - User-specified band edges [2*numband]
+ * double   des[]    - Desired response per band [2*numband]
+ * double   weight[] - Weight per band [numband]
+ * int      symmetry - Symmetry of filter - used for grid check
+ * int      griddensity
+ *
+ * OUTPUT:
+ * -------
+ * int    gridsize   - Number of elements in the dense frequency grid
+ * double Grid[]     - Frequencies (0 to 0.5) on the dense grid [gridsize]
+ * double D[]        - Desired response on the dense grid [gridsize]
+ * double W[]        - Weight function on the dense grid [gridsize]
+ *******************/
+
+static void 
+CreateDenseGrid (int r, int numtaps, int numband, const double bands[],
+                const double des[], const double weight[], int gridsize,
+                double Grid[], double D[], double W[],
+                int symmetry, int griddensity)
+{
+   int i, j, k, band;
+   double delf, lowf, highf, grid0;
+
+   delf = 0.5/(griddensity*r);
+
+/*
+ * For differentiator, hilbert,
+ *   symmetry is odd and Grid[0] = max(delf, bands[0])
+ */
+   grid0 = (symmetry == NEGATIVE) && (delf > bands[0]) ? delf : bands[0];
+
+   j=0;
+   for (band=0; band < numband; band++)
+   {
+      lowf = (band==0 ? grid0 : bands[2*band]);
+      highf = bands[2*band + 1];
+      k = (int)((highf - lowf)/delf + 0.5);   /* .5 for rounding */
+      for (i=0; i<k; i++)
+      {
+         D[j] = des[2*band] + i*(des[2*band+1]-des[2*band])/(k-1);
+         W[j] = weight[band];
+         Grid[j] = lowf;
+         lowf += delf;
+         j++;
+      }
+      Grid[j-1] = highf;
+   }
+
+/*
+ * Similar to above, if odd symmetry, last grid point can't be .5
+ *  - but, if there are even taps, leave the last grid point at .5
+ */
+   if ((symmetry == NEGATIVE) &&
+       (Grid[gridsize-1] > (0.5 - delf)) &&
+       (numtaps % 2))
+   {
+      Grid[gridsize-1] = 0.5-delf;
+   }
+}
+
+
+/********************
+ * InitialGuess
+ *==============
+ * Places Extremal Frequencies evenly throughout the dense grid.
+ *
+ *
+ * INPUT: 
+ * ------
+ * int r        - 1/2 the number of filter coefficients
+ * int gridsize - Number of elements in the dense frequency grid
+ *
+ * OUTPUT:
+ * -------
+ * int Ext[]    - Extremal indexes to dense frequency grid [r+1]
+ ********************/
+
+static void
+InitialGuess (int r, int Ext[], int gridsize)
+{
+   int i;
+
+   for (i=0; i<=r; i++)
+      Ext[i] = i * (gridsize-1) / r;
+}
+
+
+/***********************
+ * CalcParms
+ *===========
+ *
+ *
+ * INPUT:
+ * ------
+ * int    r      - 1/2 the number of filter coefficients
+ * int    Ext[]  - Extremal indexes to dense frequency grid [r+1]
+ * double Grid[] - Frequencies (0 to 0.5) on the dense grid [gridsize]
+ * double D[]    - Desired response on the dense grid [gridsize]
+ * double W[]    - Weight function on the dense grid [gridsize]
+ *
+ * OUTPUT:
+ * -------
+ * double ad[]   - 'b' in Oppenheim & Schafer [r+1]
+ * double x[]    - [r+1]
+ * double y[]    - 'C' in Oppenheim & Schafer [r+1]
+ ***********************/
+
+static void
+CalcParms (int r, int Ext[], double Grid[], double D[], double W[],
+          double ad[], double x[], double y[])
+{
+   int i, j, k, ld;
+   double sign, xi, delta, denom, numer;
+
+/*
+ * Find x[]
+ */
+   for (i=0; i<=r; i++)
+      x[i] = cos(Pi2 * Grid[Ext[i]]);
+
+/*
+ * Calculate ad[]  - Oppenheim & Schafer eq 7.132
+ */
+   ld = (r-1)/15 + 1;         /* Skips around to avoid round errors */
+   for (i=0; i<=r; i++)
+   {
+       denom = 1.0;
+       xi = x[i];
+       for (j=0; j<ld; j++)
+       {
+          for (k=j; k<=r; k+=ld)
+             if (k != i)
+                denom *= 2.0*(xi - x[k]);
+       }
+       if (fabs(denom)<0.00001)
+          denom = 0.00001;
+       ad[i] = 1.0/denom;
+   }
+
+/*
+ * Calculate delta  - Oppenheim & Schafer eq 7.131
+ */
+   numer = denom = 0;
+   sign = 1;
+   for (i=0; i<=r; i++)
+   {
+      numer += ad[i] * D[Ext[i]];
+      denom += sign * ad[i]/W[Ext[i]];
+      sign = -sign;
+   }
+   delta = numer/denom;
+   sign = 1;
+
+/*
+ * Calculate y[]  - Oppenheim & Schafer eq 7.133b
+ */
+   for (i=0; i<=r; i++)
+   {
+      y[i] = D[Ext[i]] - sign * delta/W[Ext[i]];
+      sign = -sign;
+   }
+}
+
+
+/*********************
+ * ComputeA
+ *==========
+ * Using values calculated in CalcParms, ComputeA calculates the
+ * actual filter response at a given frequency (freq).  Uses
+ * eq 7.133a from Oppenheim & Schafer.
+ *
+ *
+ * INPUT:
+ * ------
+ * double freq - Frequency (0 to 0.5) at which to calculate A
+ * int    r    - 1/2 the number of filter coefficients
+ * double ad[] - 'b' in Oppenheim & Schafer [r+1]
+ * double x[]  - [r+1]
+ * double y[]  - 'C' in Oppenheim & Schafer [r+1]
+ *
+ * OUTPUT:
+ * -------
+ * Returns double value of A[freq]
+ *********************/
+
+static double
+ComputeA (double freq, int r, double ad[], double x[], double y[])
+{
+   int i;
+   double xc, c, denom, numer;
+
+   denom = numer = 0;
+   xc = cos(Pi2 * freq);
+   for (i=0; i<=r; i++)
+   {
+      c = xc - x[i];
+      if (fabs(c) < 1.0e-7)
+      {
+         numer = y[i];
+         denom = 1;
+         break;
+      }
+      c = ad[i]/c;
+      denom += c;
+      numer += c*y[i];
+   }
+   return numer/denom;
+}
+
+
+/************************
+ * CalcError
+ *===========
+ * Calculates the Error function from the desired frequency response
+ * on the dense grid (D[]), the weight function on the dense grid (W[]),
+ * and the present response calculation (A[])
+ *
+ *
+ * INPUT:
+ * ------
+ * int    r      - 1/2 the number of filter coefficients
+ * double ad[]   - [r+1]
+ * double x[]    - [r+1]
+ * double y[]    - [r+1]
+ * int gridsize  - Number of elements in the dense frequency grid
+ * double Grid[] - Frequencies on the dense grid [gridsize]
+ * double D[]    - Desired response on the dense grid [gridsize]
+ * double W[]    - Weight function on the desnse grid [gridsize]
+ *
+ * OUTPUT:
+ * -------
+ * double E[]    - Error function on dense grid [gridsize]
+ ************************/
+
+static void
+CalcError (int r, double ad[], double x[], double y[],
+          int gridsize, double Grid[],
+          double D[], double W[], double E[])
+{
+   int i;
+   double A;
+
+   for (i=0; i<gridsize; i++)
+   {
+      A = ComputeA(Grid[i], r, ad, x, y);
+      E[i] = W[i] * (D[i] - A);
+   }
+}
+
+/************************
+ * Search
+ *========
+ * Searches for the maxima/minima of the error curve.  If more than
+ * r+1 extrema are found, it uses the following heuristic (thanks
+ * Chris Hanson):
+ * 1) Adjacent non-alternating extrema deleted first.
+ * 2) If there are more than one excess extrema, delete the
+ *    one with the smallest error.  This will create a non-alternation
+ *    condition that is fixed by 1).
+ * 3) If there is exactly one excess extremum, delete the smaller
+ *    of the first/last extremum
+ *
+ *
+ * INPUT:
+ * ------
+ * int    r        - 1/2 the number of filter coefficients
+ * int    Ext[]    - Indexes to Grid[] of extremal frequencies [r+1]
+ * int    gridsize - Number of elements in the dense frequency grid
+ * double E[]      - Array of error values.  [gridsize]
+ * OUTPUT:
+ * -------
+ * int    Ext[]    - New indexes to extremal frequencies [r+1]
+ ************************/
+static int
+Search (int r, int Ext[],
+       int gridsize, double E[])
+{
+   int i, j, k, l, extra;     /* Counters */
+   int up, alt;
+   int *foundExt;             /* Array of found extremals */
+
+/*
+ * Allocate enough space for found extremals.
+ */
+   foundExt = (int *)malloc((2*r) * sizeof(int));
+   k = 0;
+
+/*
+ * Check for extremum at 0.
+ */
+   if (((E[0]>0.0) && (E[0]>E[1])) ||
+       ((E[0]<0.0) && (E[0]<E[1])))
+      foundExt[k++] = 0;
+
+/*
+ * Check for extrema inside dense grid
+ */
+   for (i=1; i<gridsize-1; i++)
+   {
+      if (((E[i]>=E[i-1]) && (E[i]>E[i+1]) && (E[i]>0.0)) ||
+          ((E[i]<=E[i-1]) && (E[i]<E[i+1]) && (E[i]<0.0))) {
+       // PAK: we sometimes get too many extremal frequencies
+       if (k >= 2*r) return -3;
+       foundExt[k++] = i;
+      }
+   }
+
+/*
+ * Check for extremum at 0.5
+ */
+   j = gridsize-1;
+   if (((E[j]>0.0) && (E[j]>E[j-1])) ||
+       ((E[j]<0.0) && (E[j]<E[j-1]))) {
+     if (k >= 2*r) return -3;
+     foundExt[k++] = j;
+   }
+
+   // PAK: we sometimes get not enough extremal frequencies
+   if (k < r+1) return -2;
+
+
+/*
+ * Remove extra extremals
+ */
+   extra = k - (r+1);
+   assert(extra >= 0);
+
+   while (extra > 0)
+   {
+      if (E[foundExt[0]] > 0.0)
+         up = 1;                /* first one is a maxima */
+      else
+         up = 0;                /* first one is a minima */
+
+      l=0;
+      alt = 1;
+      for (j=1; j<k; j++)
+      {
+         if (fabs(E[foundExt[j]]) < fabs(E[foundExt[l]]))
+            l = j;               /* new smallest error. */
+         if ((up) && (E[foundExt[j]] < 0.0))
+            up = 0;             /* switch to a minima */
+         else if ((!up) && (E[foundExt[j]] > 0.0))
+            up = 1;             /* switch to a maxima */
+         else
+        { 
+            alt = 0;
+           // PAK: break now and you will delete the smallest overall
+           // extremal.  If you want to delete the smallest of the
+           // pair of non-alternating extremals, then you must do:
+            //
+           // if (fabs(E[foundExt[j]]) < fabs(E[foundExt[j-1]])) l=j;
+           // else l=j-1;
+            break;              /* Ooops, found two non-alternating */
+         }                      /* extrema.  Delete smallest of them */
+      }  /* if the loop finishes, all extrema are alternating */
+
+/*
+ * If there's only one extremal and all are alternating,
+ * delete the smallest of the first/last extremals.
+ */
+      if ((alt) && (extra == 1))
+      {
+         if (fabs(E[foundExt[k-1]]) < fabs(E[foundExt[0]]))
+          /* Delete last extremal */
+          l = k-1;
+          // PAK: changed from l = foundExt[k-1]; 
+         else
+          /* Delete first extremal */
+          l = 0;
+          // PAK: changed from l = foundExt[0];     
+      }
+
+      for (j=l; j<k-1; j++)        /* Loop that does the deletion */
+      {
+         foundExt[j] = foundExt[j+1];
+        assert(foundExt[j]<gridsize);
+      }
+      k--;
+      extra--;
+   }
+
+   for (i=0; i<=r; i++)
+   {
+      assert(foundExt[i]<gridsize);
+      Ext[i] = foundExt[i];       /* Copy found extremals to Ext[] */
+   }
+
+   free(foundExt);
+   return 0;
+}
+
+
+/*********************
+ * FreqSample
+ *============
+ * Simple frequency sampling algorithm to determine the impulse
+ * response h[] from A's found in ComputeA
+ *
+ *
+ * INPUT:
+ * ------
+ * int      N        - Number of filter coefficients
+ * double   A[]      - Sample points of desired response [N/2]
+ * int      symmetry - Symmetry of desired filter
+ *
+ * OUTPUT:
+ * -------
+ * double h[] - Impulse Response of final filter [N]
+ *********************/
+static void
+FreqSample (int N, double A[], double h[], int symm)
+{
+   int n, k;
+   double x, val, M;
+
+   M = (N-1.0)/2.0;
+   if (symm == POSITIVE)
+   {
+      if (N%2)
+      {
+         for (n=0; n<N; n++)
+         {
+            val = A[0];
+            x = Pi2 * (n - M)/N;
+            for (k=1; k<=M; k++)
+               val += 2.0 * A[k] * cos(x*k);
+            h[n] = val/N;
+         }
+      }
+      else
+      {
+         for (n=0; n<N; n++)
+         {
+            val = A[0];
+            x = Pi2 * (n - M)/N;
+            for (k=1; k<=(N/2-1); k++)
+               val += 2.0 * A[k] * cos(x*k);
+            h[n] = val/N;
+         }
+      }
+   }
+   else
+   {
+      if (N%2)
+      {
+         for (n=0; n<N; n++)
+         {
+            val = 0;
+            x = Pi2 * (n - M)/N;
+            for (k=1; k<=M; k++)
+               val += 2.0 * A[k] * sin(x*k);
+            h[n] = val/N;
+         }
+      }
+      else
+      {
+          for (n=0; n<N; n++)
+          {
+             val = A[N/2] * sin(Pi * (n - M));
+             x = Pi2 * (n - M)/N;
+             for (k=1; k<=(N/2-1); k++)
+                val += 2.0 * A[k] * sin(x*k);
+             h[n] = val/N;
+          }
+      }
+   }
+}
+
+/*******************
+ * isDone
+ *========
+ * Checks to see if the error function is small enough to consider
+ * the result to have converged.
+ *
+ * INPUT:
+ * ------
+ * int    r     - 1/2 the number of filter coeffiecients
+ * int    Ext[] - Indexes to extremal frequencies [r+1]
+ * double E[]   - Error function on the dense grid [gridsize]
+ *
+ * OUTPUT:
+ * -------
+ * Returns 1 if the result converged
+ * Returns 0 if the result has not converged
+ ********************/
+
+static bool
+isDone (int r, int Ext[], double E[])
+{
+   int i;
+   double min, max, current;
+
+   min = max = fabs(E[Ext[0]]);
+   for (i=1; i<=r; i++)
+   {
+      current = fabs(E[Ext[i]]);
+      if (current < min)
+         min = current;
+      if (current > max)
+         max = current;
+   }
+   return (((max-min)/max) < 0.0001);
+}
+
+/********************
+ * remez
+ *=======
+ * Calculates the optimal (in the Chebyshev/minimax sense)
+ * FIR filter impulse response given a set of band edges,
+ * the desired reponse on those bands, and the weight given to
+ * the error in those bands.
+ *
+ * INPUT:
+ * ------
+ * int     numtaps     - Number of filter coefficients
+ * int     numband     - Number of bands in filter specification
+ * double  bands[]     - User-specified band edges [2 * numband]
+ * double  des[]       - User-specified band responses [2 * numband]
+ * double  weight[]    - User-specified error weights [numband]
+ * int     type        - Type of filter
+ *
+ * OUTPUT:
+ * -------
+ * double h[]      - Impulse response of final filter [numtaps]
+ * returns         - true on success, false on failure to converge
+ ********************/
+
+static int
+remez (double h[], int numtaps,
+       int numband, const double bands[], 
+       const double des[], const double weight[],
+       int type, int griddensity)
+{
+   double *Grid, *W, *D, *E;
+   int    i, iter, gridsize, r, *Ext;
+   double *taps, c;
+   double *x, *y, *ad;
+   int    symmetry;
+
+   if (type == BANDPASS)
+      symmetry = POSITIVE;
+   else
+      symmetry = NEGATIVE;
+
+   r = numtaps/2;                  /* number of extrema */
+   if ((numtaps%2) && (symmetry == POSITIVE))
+      r++;
+
+/*
+ * Predict dense grid size in advance for memory allocation
+ *   .5 is so we round up, not truncate
+ */
+   gridsize = 0;
+   for (i=0; i<numband; i++)
+   {
+      gridsize += (int)(2*r*griddensity*(bands[2*i+1] - bands[2*i]) + .5);
+   }
+   if (symmetry == NEGATIVE)
+   {
+      gridsize--;
+   }
+
+/*
+ * Dynamically allocate memory for arrays with proper sizes
+ */
+   Grid = (double *)malloc(gridsize * sizeof(double));
+   D = (double *)malloc(gridsize * sizeof(double));
+   W = (double *)malloc(gridsize * sizeof(double));
+   E = (double *)malloc(gridsize * sizeof(double));
+   Ext = (int *)malloc((r+1) * sizeof(int));
+   taps = (double *)malloc((r+1) * sizeof(double));
+   x = (double *)malloc((r+1) * sizeof(double));
+   y = (double *)malloc((r+1) * sizeof(double));
+   ad = (double *)malloc((r+1) * sizeof(double));
+
+/*
+ * Create dense frequency grid
+ */
+   CreateDenseGrid(r, numtaps, numband, bands, des, weight,
+                   gridsize, Grid, D, W, symmetry, griddensity);
+   InitialGuess(r, Ext, gridsize);
+
+/*
+ * For Differentiator: (fix grid)
+ */
+   if (type == DIFFERENTIATOR)
+   {
+      for (i=0; i<gridsize; i++)
+      {
+/* D[i] = D[i]*Grid[i]; */
+         if (D[i] > 0.0001)
+            W[i] = W[i]/Grid[i];
+      }
+   }
+
+/*
+ * For odd or Negative symmetry filters, alter the
+ * D[] and W[] according to Parks McClellan
+ */
+   if (symmetry == POSITIVE)
+   {
+      if (numtaps % 2 == 0)
+      {
+         for (i=0; i<gridsize; i++)
+         {
+            c = cos(Pi * Grid[i]);
+            D[i] /= c;
+            W[i] *= c; 
+         }
+      }
+   }
+   else
+   {
+      if (numtaps % 2)
+      {
+         for (i=0; i<gridsize; i++)
+         {
+            c = sin(Pi2 * Grid[i]);
+            D[i] /= c;
+            W[i] *= c;
+         }
+      }
+      else
+      {
+         for (i=0; i<gridsize; i++)
+         {
+            c = sin(Pi * Grid[i]);
+            D[i] /= c;
+            W[i] *= c;
+         }
+      }
+   }
+
+/*
+ * Perform the Remez Exchange algorithm
+ */
+   for (iter=0; iter<MAXITERATIONS; iter++)
+   {
+      CalcParms(r, Ext, Grid, D, W, ad, x, y);
+      CalcError(r, ad, x, y, gridsize, Grid, D, W, E);
+      int err = Search(r, Ext, gridsize, E);
+      if (err) return err;
+      for(int i=0; i <= r; i++) assert(Ext[i]<gridsize);
+      if (isDone(r, Ext, E))
+         break;
+   }
+
+   CalcParms(r, Ext, Grid, D, W, ad, x, y);
+
+/*
+ * Find the 'taps' of the filter for use with Frequency
+ * Sampling.  If odd or Negative symmetry, fix the taps
+ * according to Parks McClellan
+ */
+   for (i=0; i<=numtaps/2; i++)
+   {
+      if (symmetry == POSITIVE)
+      {
+         if (numtaps%2)
+            c = 1;
+         else
+            c = cos(Pi * (double)i/numtaps);
+      }
+      else
+      {
+         if (numtaps%2)
+            c = sin(Pi2 * (double)i/numtaps);
+         else
+            c = sin(Pi * (double)i/numtaps);
+      }
+      taps[i] = ComputeA((double)i/numtaps, r, ad, x, y)*c;
+   }
+
+/*
+ * Frequency sampling design with calculated taps
+ */
+   FreqSample(numtaps, taps, h, symmetry);
+
+/*
+ * Delete allocated memory
+ */
+   free(Grid);
+   free(W);
+   free(D);
+   free(E);
+   free(Ext);
+   free(x);
+   free(y);
+   free(ad);
+   return iter<MAXITERATIONS?0:-1;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+//
+//                         GNU Radio interface
+//
+//////////////////////////////////////////////////////////////////////////////
+
+
+static void
+punt (const std::string msg) 
+{
+  std::cerr << msg << '\n';
+  throw std::runtime_error (msg);
+}
+
+std::vector<double>
+gr_remez (int order,
+         const std::vector<double> &arg_bands,
+         const std::vector<double> &arg_response,
+         const std::vector<double> &arg_weight,
+         const std::string filter_type,
+         int grid_density
+         ) throw (std::runtime_error)
+{
+  int numtaps = order + 1;
+  if (numtaps < 4)
+    punt ("gr_remez: number of taps must be >= 3");
+
+  int numbands = arg_bands.size () / 2;
+  LOCAL_BUFFER (double, bands, numbands * 2);
+  if (numbands < 1 || arg_bands.size () % 2 == 1)
+    punt ("gr_remez: must have an even number of band edges");
+
+  for (unsigned int i = 1; i < arg_bands.size (); i++){
+    if (arg_bands[i] < arg_bands[i-1])
+      punt ("gr_remez: band edges must be nondecreasing");
+  }
+
+  if (arg_bands[0] < 0 || arg_bands[arg_bands.size () - 1] > 1)
+    punt ("gr_remez: band edges must be in the range [0,1]");
+
+  for (int i = 0; i < 2 * numbands; i++)
+    bands[i] = arg_bands[i] / 2;               // FIXME why / 2?
+
+  LOCAL_BUFFER (double, response, numbands * 2);
+  if (arg_response.size () != arg_bands.size ())
+    punt ("gr_remez: must have one response magnitude for each band edge");
+
+  for (int i = 0; i < 2 * numbands; i++)
+    response[i] = arg_response[i];
+
+  LOCAL_BUFFER (double, weight, numbands);
+  for (int i = 0; i < numbands; i++)
+    weight[i] = 1.0;
+
+  if (arg_weight.size () != 0){
+    if ((int) arg_weight.size () != numbands)
+      punt ("gr_remez: need one weight for each band [=length(band)/2]");
+    for (int i = 0; i < numbands; i++)
+      weight[i] = arg_weight [i];
+  }
+  
+  int itype = 0;
+  if (filter_type == "bandpass") 
+    itype = BANDPASS;
+  else if (filter_type == "differentiator") 
+    itype = DIFFERENTIATOR;
+  else if (filter_type == "hilbert") 
+    itype = HILBERT;
+  else
+    punt ("gr_remez: unknown ftype '" + filter_type + "'");
+
+  if (grid_density < 16)
+    punt ("gr_remez: grid_density is too low; must be >= 16");
+
+  LOCAL_BUFFER (double, coeff, numtaps + 5);           // FIXME why + 5?
+  int err = remez (coeff, numtaps, numbands,
+                  bands, response, weight, itype, grid_density);
+
+  if (err == -1)
+    punt ("gr_remez: failed to converge");
+
+  if (err == -2)
+    punt ("gr_remez: insufficient extremals -- cannot continue");
+
+  if (err == -3)
+    punt ("gr_remez: too many extremals -- cannot continue");
+
+  return std::vector<double> (&coeff[0], &coeff[numtaps]);
+}
+
+
+
+#if 0
+/* == Octave interface starts here ====================================== */
+
+DEFUN_DLD (remez, args, ,
+  "b = remez(n, f, a [, w] [, ftype] [, griddensity])\n\
+Parks-McClellan optimal FIR filter design.\n\
+n gives the number of taps in the returned filter\n\
+f gives frequency at the band edges [ b1 e1 b2 e2 b3 e3 ...]\n\
+a gives amplitude at the band edges [ a(b1) a(e1) a(b2) a(e2) ...]\n\
+w gives weighting applied to each band\n\
+ftype is 'bandpass', 'hilbert' or 'differentiator'\n\
+griddensity determines how accurately the filter will be\n\
+    constructed. The minimum value is 16, but higher numbers are\n\
+    slower to compute.\n\
+\n\
+Frequency is in the range (0, 1), with 1 being the nyquist frequency")
+{
+  octave_value_list retval;
+  int i;
+
+  int nargin = args.length();
+  if (nargin < 3 || nargin > 6) {
+    print_usage("remez");
+    return retval;
+  }
+
+  int numtaps = NINT (args(0).double_value()) + 1; // #coeff = filter order+1
+  if (numtaps < 4) {
+    error("remez: number of taps must be an integer greater than 3");
+    return retval;
+  }
+
+  ColumnVector o_bands(args(1).vector_value());
+  int numbands = o_bands.length()/2;
+  OCTAVE_LOCAL_BUFFER(double, bands, numbands*2);
+  if (numbands < 1 || o_bands.length()%2 == 1) {
+    error("remez: must have an even number of band edges");
+    return retval;
+  }
+  for (i=1; i < o_bands.length(); i++) {
+    if (o_bands(i)<o_bands(i-1)) {
+      error("band edges must be nondecreasing");
+      return retval;
+    }
+  }
+  if (o_bands(0) < 0 || o_bands(1) > 1) {
+    error("band edges must be in the range [0,1]");
+    return retval;
+  }
+  for(i=0; i < 2*numbands; i++) bands[i] = o_bands(i)/2.0;
+
+  ColumnVector o_response(args(2).vector_value());
+  OCTAVE_LOCAL_BUFFER (double, response, numbands*2);
+  if (o_response.length() != o_bands.length()) {
+    error("remez: must have one response magnitude for each band edge");
+    return retval;
+  }
+  for(i=0; i < 2*numbands; i++) response[i] = o_response(i);
+
+  std::string stype = std::string("bandpass");
+  int density = 16;
+  OCTAVE_LOCAL_BUFFER (double, weight, numbands);
+  for (i=0; i < numbands; i++) weight[i] = 1.0;
+  if (nargin > 3) {
+    if (args(3).is_real_matrix()) {
+      ColumnVector o_weight(args(3).vector_value());
+      if (o_weight.length() != numbands) {
+       error("remez: need one weight for each band [=length(band)/2]");
+       return retval;
+      }
+      for (i=0; i < numbands; i++) weight[i] = o_weight(i);
+    }
+    else if (args(3).is_string())
+      stype = args(3).string_value();
+    else if (args(3).is_real_scalar())
+      density = NINT(args(3).double_value());
+    else {
+      error("remez: incorrect argument list");
+      return retval;
+    }
+  }
+  if (nargin > 4) {
+    if (args(4).is_string() && !args(3).is_string())
+      stype = args(4).string_value();
+    else if (args(4).is_real_scalar() && !args(3).is_real_scalar())
+      density = NINT(args(4).double_value());
+    else {
+      error("remez: incorrect argument list");
+      return retval;
+    }
+  }
+  if (nargin > 5) {
+    if (args(5).is_real_scalar() 
+       && !args(4).is_real_scalar() 
+       && !args(3).is_real_scalar())
+      density = NINT(args(4).double_value());
+    else {
+      error("remez: incorrect argument list");
+      return retval;
+    }
+  }
+
+  int itype;
+  if (stype == "bandpass") 
+    itype = BANDPASS;
+  else if (stype == "differentiator") 
+    itype = DIFFERENTIATOR;
+  else if (stype == "hilbert") 
+    itype = HILBERT;
+  else {
+    error("remez: unknown ftype '%s'", stype.data());
+    return retval;
+  }
+
+  if (density < 16) {
+    error("remez: griddensity is too low; must be greater than 16");
+    return retval;
+  }
+
+  OCTAVE_LOCAL_BUFFER (double, coeff, numtaps+5);
+  int err = remez(coeff,numtaps,numbands,bands,response,weight,itype,density);
+
+  if (err == -1)
+    warning("remez: -- failed to converge -- returned filter may be bad.");
+  else if (err == -2) {
+    error("remez: insufficient extremals--cannot continue");
+    return retval;
+  }
+  else if (err == -3) {
+    error("remez: too many extremals--cannot continue");
+    return retval;
+  }
+
+  ColumnVector h(numtaps);
+  while(numtaps--) h(numtaps) = coeff[numtaps];
+
+  return octave_value(h);
+}
+
+/*
+%!test
+%! b = [
+%!    0.0415131831103279
+%!    0.0581639884202646
+%!   -0.0281579212691008
+%!   -0.0535575358002337
+%!   -0.0617245915143180
+%!    0.0507753178978075
+%!    0.2079018331396460
+%!    0.3327160895375440
+%!    0.3327160895375440
+%!    0.2079018331396460
+%!    0.0507753178978075
+%!   -0.0617245915143180
+%!   -0.0535575358002337
+%!   -0.0281579212691008
+%!    0.0581639884202646
+%!    0.0415131831103279];
+%! assert(remez(15,[0,0.3,0.4,1],[1,1,0,0]),b,1e-14);
+
+ */
+
+#endif
diff --git a/gnuradio-core/src/lib/general/gr_remez.h b/gnuradio-core/src/lib/general/gr_remez.h
new file mode 100644 (file)
index 0000000..c910803
--- /dev/null
@@ -0,0 +1,63 @@
+/* -*- 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 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.
+ */
+
+#ifndef INCLUDED_GR_REMEZ_H
+#define INCLUDED_GR_REMEZ_H
+
+#include <gr_types.h>
+#include <string>
+#include <stdexcept>
+
+/*!
+ * \brief Parks-McClellan FIR filter design.
+ *
+ *
+ * Calculates the optimal (in the Chebyshev/minimax sense) FIR filter
+ * inpulse reponse given a set of band edges, the desired reponse on
+ * those bands, and the weight given to the error in those bands.
+ *
+ * \param order             filter order (number of taps in the returned filter - 1)
+ * \param bands             frequency at the band edges [ b1 e1 b2 e2 b3 e3 ...]
+ * \param ampl             desired amplitude at the band edges [ a(b1) a(e1) a(b2) a(e2) ...]
+ * \param error_weight     weighting applied to each band (usually 1)
+ * \param filter_type      one of "bandpass", "hilbert" or "differentiator"
+ * \param grid_density     determines how accurately the filter will be constructed. \
+ *                             The minimum value is 16; higher values are slower to compute.
+ *
+ * Frequency is in the range [0, 1], with 1 being the Nyquist frequency (Fs/2)
+ *
+ * \returns vector of computed taps
+ *
+ * \throws std::runtime_error if args are invalid or calculation fails to converge.
+ */
+
+std::vector<double>
+gr_remez (int order,
+         const std::vector<double> &bands,
+         const std::vector<double> &ampl,
+         const std::vector<double> &error_weight,
+         const std::string filter_type = "bandpass",
+         int grid_density = 16
+         ) throw (std::runtime_error);
+
+
+#endif /* INCLUDED_GR_REMEZ_H */
diff --git a/gnuradio-core/src/lib/general/gr_remez.i b/gnuradio-core/src/lib/general/gr_remez.i
new file mode 100644 (file)
index 0000000..2e2471e
--- /dev/null
@@ -0,0 +1,32 @@
+/* -*- 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 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.
+ */
+
+%rename(remez) gr_remez;
+
+std::vector<double>
+gr_remez (int order,
+         const std::vector<double> &bands,
+         const std::vector<double> &ampl,
+         const std::vector<double> &error_weight,
+         const std::string filter_type = "bandpass",
+         int grid_density = 16
+         ) throw (std::runtime_error);
diff --git a/gnuradio-core/src/lib/general/gr_reverse.cc b/gnuradio-core/src/lib/general/gr_reverse.cc
new file mode 100644 (file)
index 0000000..099deb6
--- /dev/null
@@ -0,0 +1,60 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_reverse.h>
+
+
+std::vector<float> 
+gr_reverse (const std::vector<float> &taps)
+{
+  int size = taps.size ();
+  std::vector<float> new_taps(size);
+
+  if (size == 0)
+    return new_taps;
+
+  for (int i = 0; i < size; i++)
+    new_taps[i] = taps[size - i - 1];
+
+  return new_taps;
+}
+
+
+std::vector<gr_complex> 
+gr_reverse (const std::vector<gr_complex> &taps)
+{
+  int size = taps.size ();
+  std::vector<gr_complex> new_taps(size);
+
+  if (size == 0)
+    return new_taps;
+
+  for (int i = 0; i < size; i++)
+    new_taps[i] = taps[size - i - 1];
+
+  return new_taps;
+}
+
diff --git a/gnuradio-core/src/lib/general/gr_reverse.h b/gnuradio-core/src/lib/general/gr_reverse.h
new file mode 100644 (file)
index 0000000..cff5325
--- /dev/null
@@ -0,0 +1,33 @@
+/* -*- 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 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.
+ */
+#ifndef INCLUDED_GR_REVERSE_H
+#define INCLUDED_GR_REVERSE_H
+
+#include <vector>
+#include <gr_complex.h>
+
+// reverse the order of taps
+std::vector<float> gr_reverse (const std::vector<float> &taps);
+std::vector<gr_complex> gr_reverse (const std::vector<gr_complex> &taps);
+
+
+#endif /* INCLUDED_GR_REVERSE_H */
diff --git a/gnuradio-core/src/lib/general/gr_rms_cf.cc b/gnuradio-core/src/lib/general/gr_rms_cf.cc
new file mode 100644 (file)
index 0000000..7abfefd
--- /dev/null
@@ -0,0 +1,71 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include <gr_rms_cf.h>
+#include <gr_io_signature.h>
+#include <cmath>
+
+gr_rms_cf_sptr
+gr_make_rms_cf(double alpha)
+{
+  return gr_rms_cf_sptr(new gr_rms_cf(alpha));
+}
+
+gr_rms_cf::gr_rms_cf (double alpha)
+  : gr_sync_block ("rms_cf",
+                  gr_make_io_signature(1, 1, sizeof(gr_complex)),
+                  gr_make_io_signature(1, 1, sizeof(float))),
+    d_iir(alpha)
+{
+
+}
+
+gr_rms_cf::~gr_rms_cf()
+{
+}
+
+
+int
+gr_rms_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++){
+    double mag_sqrd = in[i].real()*in[i].real() + in[i].imag()*in[i].imag();
+    double f = d_iir.filter(mag_sqrd);
+    out[i] = sqrt(f);
+  }
+
+  return noutput_items;
+}
+
+void
+gr_rms_cf::set_alpha(double alpha)
+{
+  d_iir.set_taps(alpha);
+}
diff --git a/gnuradio-core/src/lib/general/gr_rms_cf.h b/gnuradio-core/src/lib/general/gr_rms_cf.h
new file mode 100644 (file)
index 0000000..bc16c23
--- /dev/null
@@ -0,0 +1,59 @@
+/* -*- 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 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.
+ */
+#ifndef INCLUDED_GR_RMS_CF_H
+#define INCLUDED_GR_RMS_CF_H
+
+#include <gr_sync_block.h>
+#include <gr_single_pole_iir.h>
+
+class gr_rms_cf;
+typedef boost::shared_ptr<gr_rms_cf> gr_rms_cf_sptr;
+
+gr_rms_cf_sptr
+gr_make_rms_cf (double alpha = 0.0001);
+
+/*!
+ * \brief RMS average power
+ */
+class gr_rms_cf : public gr_sync_block
+{
+  gr_single_pole_iir<double,double,double>     d_iir;
+  bool                                         d_unmuted;
+
+  friend gr_rms_cf_sptr
+  gr_make_rms_cf (double alpha);
+
+  gr_rms_cf (double alpha);
+
+public:
+  ~gr_rms_cf ();
+
+  int work (int noutput_items,
+           gr_vector_const_void_star &input_items,
+           gr_vector_void_star &output_items);
+
+  bool unmuted () const { return d_unmuted; }
+
+  void set_alpha (double alpha);
+};
+
+#endif /* INCLUDED_GR_RMS_CF_H */
diff --git a/gnuradio-core/src/lib/general/gr_rms_cf.i b/gnuradio-core/src/lib/general/gr_rms_cf.i
new file mode 100644 (file)
index 0000000..0d7b05c
--- /dev/null
@@ -0,0 +1,33 @@
+/* -*- 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 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.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,rms_cf);
+
+gr_rms_cf_sptr
+gr_make_rms_cf (double alpha = 0.0001);
+
+class gr_rms_cf : public gr_sync_block
+{
+public:
+  bool unmuted () const { return d_unmuted; }
+  void set_alpha (double alpha);
+};
diff --git a/gnuradio-core/src/lib/general/gr_rms_ff.cc b/gnuradio-core/src/lib/general/gr_rms_ff.cc
new file mode 100644 (file)
index 0000000..187be63
--- /dev/null
@@ -0,0 +1,71 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include <gr_rms_ff.h>
+#include <gr_io_signature.h>
+#include <cmath>
+
+gr_rms_ff_sptr
+gr_make_rms_ff(double alpha)
+{
+  return gr_rms_ff_sptr(new gr_rms_ff(alpha));
+}
+
+gr_rms_ff::gr_rms_ff (double alpha)
+  : gr_sync_block ("rms_ff",
+                  gr_make_io_signature(1, 1, sizeof(float)),
+                  gr_make_io_signature(1, 1, sizeof(float))),
+    d_iir(alpha)
+{
+
+}
+
+gr_rms_ff::~gr_rms_ff()
+{
+}
+
+
+int
+gr_rms_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++){
+    double mag_sqrd = in[i]*in[i];
+    double f = d_iir.filter(mag_sqrd);
+    out[i] = sqrt(f);
+  }
+
+  return noutput_items;
+}
+
+void
+gr_rms_ff::set_alpha(double alpha)
+{
+  d_iir.set_taps(alpha);
+}
diff --git a/gnuradio-core/src/lib/general/gr_rms_ff.h b/gnuradio-core/src/lib/general/gr_rms_ff.h
new file mode 100644 (file)
index 0000000..3f276eb
--- /dev/null
@@ -0,0 +1,59 @@
+/* -*- 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 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.
+ */
+#ifndef INCLUDED_GR_RMS_FF_H
+#define INCLUDED_GR_RMS_FF_H
+
+#include <gr_sync_block.h>
+#include <gr_single_pole_iir.h>
+
+class gr_rms_ff;
+typedef boost::shared_ptr<gr_rms_ff> gr_rms_ff_sptr;
+
+gr_rms_ff_sptr
+gr_make_rms_ff (double alpha = 0.0001);
+
+/*!
+ * \brief RMS average power
+ */
+class gr_rms_ff : public gr_sync_block
+{
+  gr_single_pole_iir<double,double,double>     d_iir;
+  bool                                         d_unmuted;
+
+  friend gr_rms_ff_sptr
+  gr_make_rms_ff (double alpha);
+
+  gr_rms_ff (double alpha);
+
+public:
+  ~gr_rms_ff ();
+
+  int work (int noutput_items,
+           gr_vector_const_void_star &input_items,
+           gr_vector_void_star &output_items);
+
+  bool unmuted () const { return d_unmuted; }
+
+  void set_alpha (double alpha);
+};
+
+#endif /* INCLUDED_GR_RMS_FF_H */
diff --git a/gnuradio-core/src/lib/general/gr_rms_ff.i b/gnuradio-core/src/lib/general/gr_rms_ff.i
new file mode 100644 (file)
index 0000000..bf9dbe2
--- /dev/null
@@ -0,0 +1,33 @@
+/* -*- 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 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.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,rms_ff);
+
+gr_rms_ff_sptr
+gr_make_rms_ff (double alpha = 0.0001);
+
+class gr_rms_ff : public gr_sync_block
+{
+public:
+  bool unmuted () const { return d_unmuted; }
+  void set_alpha (double alpha);
+};
diff --git a/gnuradio-core/src/lib/general/gr_short_to_float.cc b/gnuradio-core/src/lib/general/gr_short_to_float.cc
new file mode 100644 (file)
index 0000000..3ca7937
--- /dev/null
@@ -0,0 +1,58 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_short_to_float.h>
+#include <gr_io_signature.h>
+#include <gri_short_to_float.h>
+
+gr_short_to_float_sptr
+gr_make_short_to_float ()
+{
+  return gr_short_to_float_sptr (new gr_short_to_float ());
+}
+
+gr_short_to_float::gr_short_to_float ()
+  : gr_sync_block ("gr_short_to_float",
+                  gr_make_io_signature (1, 1, sizeof (short)),
+                  gr_make_io_signature (1, 1, sizeof (float)))
+{
+}
+
+int
+gr_short_to_float::work (int noutput_items,
+                        gr_vector_const_void_star &input_items,
+                        gr_vector_void_star &output_items)
+{
+  const short *in = (const short *) input_items[0];
+  float *out = (float *) output_items[0];
+
+  gri_short_to_float (in, out, noutput_items);
+  
+  return noutput_items;
+}
+
+
+
diff --git a/gnuradio-core/src/lib/general/gr_short_to_float.h b/gnuradio-core/src/lib/general/gr_short_to_float.h
new file mode 100644 (file)
index 0000000..ee5a4ee
--- /dev/null
@@ -0,0 +1,51 @@
+/* -*- 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 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.
+ */
+
+#ifndef INCLUDED_GR_SHORT_TO_FLOAT_H
+#define INCLUDED_GR_SHORT_TO_FLOAT_H
+
+#include <gr_sync_block.h>
+
+class gr_short_to_float;
+typedef boost::shared_ptr<gr_short_to_float> gr_short_to_float_sptr;
+
+gr_short_to_float_sptr
+gr_make_short_to_float ();
+
+/*!
+ * \brief Convert stream of short to a stream of float
+ * \ingroup converter
+ */
+
+class gr_short_to_float : public gr_sync_block
+{
+  friend gr_short_to_float_sptr gr_make_short_to_float ();
+  gr_short_to_float ();
+
+ public:
+  virtual int work (int noutput_items,
+                   gr_vector_const_void_star &input_items,
+                   gr_vector_void_star &output_items);
+};
+
+
+#endif /* INCLUDED_GR_SHORT_TO_FLOAT_H */
diff --git a/gnuradio-core/src/lib/general/gr_short_to_float.i b/gnuradio-core/src/lib/general/gr_short_to_float.i
new file mode 100644 (file)
index 0000000..724165d
--- /dev/null
@@ -0,0 +1,30 @@
+/* -*- 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 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.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,short_to_float)
+
+gr_short_to_float_sptr gr_make_short_to_float ();
+
+class gr_short_to_float : public gr_sync_block
+{
+  gr_short_to_float ();
+};
diff --git a/gnuradio-core/src/lib/general/gr_sig_source_X.cc.t b/gnuradio-core/src/lib/general/gr_sig_source_X.cc.t
new file mode 100644 (file)
index 0000000..079864b
--- /dev/null
@@ -0,0 +1,149 @@
+/* -*- 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 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.
+ */
+
+// @WARNING@
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <@NAME@.h>
+#include <algorithm>
+#include <gr_io_signature.h>
+#include <stdexcept>
+#include <gr_complex.h>
+
+
+@NAME@::@NAME@ (double sampling_freq, gr_waveform_t waveform,
+               double frequency, double ampl, @TYPE@ offset)
+  : gr_sync_block ("@BASE_NAME@",
+                  gr_make_io_signature (0, 0, 0),
+                  gr_make_io_signature (1, 1, sizeof (@TYPE@))),
+    d_sampling_freq (sampling_freq), d_waveform (waveform), d_frequency (frequency),
+    d_ampl (ampl), d_offset (offset)
+{
+  d_nco.set_freq (2 * M_PI * d_frequency / d_sampling_freq);
+}
+
+@NAME@_sptr
+gr_make_@BASE_NAME@ (double sampling_freq, gr_waveform_t waveform,
+                    double frequency, double ampl, @TYPE@ offset)
+{
+  return @NAME@_sptr (new @NAME@ (sampling_freq, waveform, frequency, ampl, offset));
+}
+
+int
+@NAME@::work (int noutput_items,
+                   gr_vector_const_void_star &input_items,
+                   gr_vector_void_star &output_items)
+{
+  @TYPE@ *optr = (@TYPE@ *) output_items[0];
+  @TYPE@ t;
+
+  switch (d_waveform){
+
+#if @IS_COMPLEX@       // complex?
+
+  case GR_CONST_WAVE:
+    t = (gr_complex) d_ampl + d_offset;
+    for (int i = 0; i < noutput_items; i++)    // FIXME unroll
+      optr[i] = t;
+    break;
+    
+  case GR_SIN_WAVE:
+  case GR_COS_WAVE:
+    d_nco.sincos (optr, noutput_items, d_ampl);
+    if (d_offset == gr_complex(0,0))
+      break;
+
+    for (int i = 0; i < noutput_items; i++){
+      optr[i] += d_offset;
+    }
+    break;
+
+#else                  // nope...
+
+  case GR_CONST_WAVE:
+    t = (@TYPE@) d_ampl + d_offset;
+    for (int i = 0; i < noutput_items; i++)    // FIXME unroll
+      optr[i] = t;
+    break;
+    
+  case GR_SIN_WAVE:
+    d_nco.sin (optr, noutput_items, d_ampl);
+    if (d_offset == 0)
+      break;
+
+    for (int i = 0; i < noutput_items; i++){
+      optr[i] += d_offset;
+    }
+    break;
+
+  case GR_COS_WAVE:
+    d_nco.cos (optr, noutput_items, d_ampl);
+    if (d_offset == 0)
+      break;
+
+    for (int i = 0; i < noutput_items; i++){
+      optr[i] += d_offset;
+    }
+    break;
+#endif
+
+  default:
+    throw std::runtime_error ("gr_sig_source: invalid waveform");
+  }
+
+  return noutput_items;
+}
+
+void
+@NAME@::set_sampling_freq (double sampling_freq)
+{
+  d_sampling_freq = sampling_freq;
+  d_nco.set_freq (2 * M_PI * d_frequency / d_sampling_freq);
+}
+
+void
+@NAME@::set_waveform (gr_waveform_t waveform)
+{
+  d_waveform = waveform;
+}
+
+void
+@NAME@::set_frequency (double frequency)
+{
+  d_frequency = frequency;
+  d_nco.set_freq (2 * M_PI * d_frequency / d_sampling_freq);
+}
+
+void
+@NAME@::set_amplitude (double ampl)
+{
+  d_ampl = ampl;
+}
+
+void
+@NAME@::set_offset (@TYPE@ offset)
+{
+  d_offset = offset;
+}
+
diff --git a/gnuradio-core/src/lib/general/gr_sig_source_X.h.t b/gnuradio-core/src/lib/general/gr_sig_source_X.h.t
new file mode 100644 (file)
index 0000000..2cdeb32
--- /dev/null
@@ -0,0 +1,81 @@
+/* -*- 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 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.
+ */
+
+// @WARNING@
+
+#ifndef @GUARD_NAME@
+#define @GUARD_NAME@
+
+#include <gr_sync_block.h>
+#include <gr_sig_source_waveform.h>
+#include <gr_fxpt_nco.h>
+
+class @NAME@;
+typedef boost::shared_ptr<@NAME@> @NAME@_sptr;
+
+/*!
+ * \brief signal generator with @TYPE@ output.
+ * \ingroup source
+ */
+
+class @NAME@ : public gr_sync_block {
+  friend @NAME@_sptr 
+  gr_make_@BASE_NAME@ (double sampling_freq, gr_waveform_t waveform,
+                      double frequency, double ampl, @TYPE@ offset);
+
+  double               d_sampling_freq;
+  gr_waveform_t                d_waveform;
+  double               d_frequency;
+  double               d_ampl;
+  @TYPE@               d_offset;
+  gr_fxpt_nco          d_nco;
+
+
+  @NAME@ (double sampling_freq, gr_waveform_t waveform,
+         double wave_freq, double ampl, @TYPE@ offset);
+
+ public:
+  virtual int work (int noutput_items,
+                   gr_vector_const_void_star &input_items,
+                   gr_vector_void_star &output_items);
+
+  // ACCESSORS
+  double sampling_freq () const { return d_sampling_freq; }
+  gr_waveform_t waveform () const { return d_waveform; }
+  double frequency () const { return d_frequency; }
+  double amplitude () const { return d_ampl; }
+  @TYPE@ offset () const { return d_offset; }
+
+  // MANIPULATORS
+  void set_sampling_freq (double sampling_freq);
+  void set_waveform (gr_waveform_t waveform);
+  void set_frequency (double frequency);
+  void set_amplitude (double ampl);
+  void set_offset (@TYPE@ offset);
+};
+
+@NAME@_sptr
+gr_make_@BASE_NAME@ (double sampling_freq, gr_waveform_t waveform,
+                    double wave_freq, double ampl, @TYPE@ offset = 0);
+
+
+#endif
diff --git a/gnuradio-core/src/lib/general/gr_sig_source_X.i.t b/gnuradio-core/src/lib/general/gr_sig_source_X.i.t
new file mode 100644 (file)
index 0000000..3e769d4
--- /dev/null
@@ -0,0 +1,52 @@
+/* -*- 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 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.
+ */
+
+// @WARNING@
+
+GR_SWIG_BLOCK_MAGIC(gr,@BASE_NAME@);
+
+@NAME@_sptr
+gr_make_@BASE_NAME@ (double sampling_freq, gr_waveform_t waveform,
+                    double wave_freq, double ampl, @TYPE@ offset = 0);
+
+
+class @NAME@ : public gr_sync_block {
+ private:
+  @NAME@ (double sampling_freq, gr_waveform_t waveform,
+         double wave_freq, double ampl, @TYPE@ offset);
+
+ public:
+
+  // ACCESSORS
+  double sampling_freq () const { return d_sampling_freq; }
+  gr_waveform_t waveform () const { return d_waveform; }
+  double frequency () const { return d_frequency; }
+  double amplitude () const { return d_ampl; }
+  @TYPE@ offset () const { return d_offset; }
+
+  // MANIPULATORS
+  void set_sampling_freq (double sampling_freq);
+  void set_waveform (gr_waveform_t waveform);
+  void set_frequency (double frequency);
+  void set_amplitude (double ampl);
+  void set_offset (@TYPE@ offset);
+};
diff --git a/gnuradio-core/src/lib/general/gr_sig_source_waveform.h b/gnuradio-core/src/lib/general/gr_sig_source_waveform.h
new file mode 100644 (file)
index 0000000..2d0dc56
--- /dev/null
@@ -0,0 +1,29 @@
+/* -*- 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 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.
+ */
+#ifndef INCLUDED_GR_SIG_SOURCE_WAVEFORM_H
+#define INCLUDED_GR_SIG_SOURCE_WAVEFORM_H
+
+typedef enum {
+  GR_CONST_WAVE = 100, GR_SIN_WAVE, GR_COS_WAVE
+} gr_waveform_t;
+
+#endif /* INCLUDED_GR_SIG_SOURCE_WAVEFORM_H */
diff --git a/gnuradio-core/src/lib/general/gr_simple_correlator.cc b/gnuradio-core/src/lib/general/gr_simple_correlator.cc
new file mode 100644 (file)
index 0000000..09c8123
--- /dev/null
@@ -0,0 +1,230 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_simple_correlator.h>
+#include <gr_simple_framer_sync.h>
+#include <gr_io_signature.h>
+#include <assert.h>
+#include <stdexcept>
+#include <gr_count_bits.h>
+
+
+static const int THRESHOLD = 3;
+
+gr_simple_correlator_sptr
+gr_make_simple_correlator (int payload_bytesize)
+{
+  return gr_simple_correlator_sptr (new gr_simple_correlator (payload_bytesize));
+}
+
+gr_simple_correlator::gr_simple_correlator (int payload_bytesize)
+  : gr_block ("simple_correlator",
+             gr_make_io_signature (1, 1, sizeof (float)),
+             gr_make_io_signature (1, 1, sizeof (unsigned char))),
+    d_payload_bytesize (payload_bytesize),
+    d_state (ST_LOOKING), d_osi (0),
+    d_bblen ((payload_bytesize + GRSF_PAYLOAD_OVERHEAD) * GRSF_BITS_PER_BYTE),
+    d_bitbuf (new unsigned char [d_bblen]),
+    d_bbi (0)
+{
+  d_avbi = 0;
+  d_accum = 0.0;
+  d_avg = 0.0;
+  for (int i = 0; i < AVG_PERIOD; i++)
+    d_avgbuf[i] = 0.0;
+
+#ifdef DEBUG_SIMPLE_CORRELATOR
+  d_debug_fp = fopen("corr.log", "w");
+#endif
+  enter_looking ();
+
+}
+
+gr_simple_correlator::~gr_simple_correlator ()
+{
+#ifdef DEBUG_SIMPLE_CORRELATOR
+  fclose(d_debug_fp);
+#endif  
+  delete [] d_bitbuf;
+}
+   
+
+void
+gr_simple_correlator::enter_looking ()
+{
+  fflush (stdout);
+  // fprintf (stderr, ">>> enter_looking\n");
+  d_state = ST_LOOKING;
+  for (int i = 0; i < OVERSAMPLE; i++)
+    d_shift_reg[i] = 0;
+  d_osi = 0;
+
+  d_avbi = 0;
+  d_avg = d_avg * 0.5;
+  d_accum = 0;
+  for (int i = 0; i < AVG_PERIOD; i++)
+    d_avgbuf[i] = 0.0;
+}
+
+void
+gr_simple_correlator::enter_under_threshold ()
+{
+  fflush (stdout);
+  // fprintf (stderr, ">>> enter_under_threshold\n");
+  d_state = ST_UNDER_THRESHOLD;
+  d_transition_osi = d_osi;
+}
+
+void
+gr_simple_correlator::enter_locked ()
+{
+  d_state = ST_LOCKED;
+  int delta = sub_index (d_osi, d_transition_osi);
+  d_center_osi = add_index (d_transition_osi, delta/2);
+  d_center_osi = add_index (d_center_osi, 3);   // FIXME
+  d_bbi = 0;
+  fflush (stdout);
+  // fprintf (stderr, ">>> enter_locked  d_center_osi = %d\n", d_center_osi);
+
+  d_avg = std::max(-1.0, std::min(1.0, d_accum * (1.0/AVG_PERIOD)));
+  // fprintf(stderr, ">>> enter_locked  d_avg = %g\n", d_avg);
+}
+
+static void
+packit (unsigned char *pktbuf, const unsigned char *bitbuf, int bitcount)
+{
+  for (int i = 0; i < bitcount; i += 8){
+    int t = bitbuf[i+0] & 0x1;
+    t = (t << 1) | (bitbuf[i+1] & 0x1);
+    t = (t << 1) | (bitbuf[i+2] & 0x1);
+    t = (t << 1) | (bitbuf[i+3] & 0x1);
+    t = (t << 1) | (bitbuf[i+4] & 0x1);
+    t = (t << 1) | (bitbuf[i+5] & 0x1);
+    t = (t << 1) | (bitbuf[i+6] & 0x1);
+    t = (t << 1) | (bitbuf[i+7] & 0x1);
+    *pktbuf++ = t;
+  }
+}
+
+void
+gr_simple_correlator::update_avg(float x)
+{
+  d_accum -= d_avgbuf[d_avbi];
+  d_avgbuf[d_avbi] = x;
+  d_accum += x;
+  d_avbi = (d_avbi + 1) & (AVG_PERIOD-1);
+}
+  
+
+int
+gr_simple_correlator::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];
+  unsigned char *out = (unsigned char *) output_items[0];
+
+  
+  int n = 0;
+  int nin = ninput_items[0];
+  int decision;
+  int hamming_dist;
+
+  struct debug_data {
+    float      raw_data;
+    float      sampled;
+    float      enter_locked;
+  } debug_data;
+
+  while (n < nin){
+
+#ifdef DEBUG_SIMPLE_CORRELATOR
+    debug_data.raw_data = in[n];
+    debug_data.sampled = 0.0;
+    debug_data.enter_locked = 0.0;
+#endif
+
+    switch (d_state){
+
+    case ST_LOCKED:
+      if (d_osi == d_center_osi){
+
+#ifdef DEBUG_SIMPLE_CORRELATOR
+       debug_data.sampled = 1.0;
+#endif
+       decision = slice (in[n]);
+       
+       d_bitbuf[d_bbi] = decision;
+       d_bbi++;
+       if (d_bbi >= d_bblen){
+         // printf ("got whole packet\n");
+         unsigned char pktbuf[d_bblen/GRSF_BITS_PER_BYTE];
+         packit (pktbuf, d_bitbuf, d_bbi);
+         printf ("seqno %3d\n", pktbuf[0]);
+         memcpy (out, &pktbuf[GRSF_PAYLOAD_OVERHEAD], d_payload_bytesize);
+         enter_looking ();
+         consume_each (n + 1);
+         return d_payload_bytesize;
+       }
+      }
+      break;
+
+    case ST_LOOKING:
+    case ST_UNDER_THRESHOLD:
+      update_avg(in[n]);
+      decision = slice (in[n]);
+      d_shift_reg[d_osi] = (d_shift_reg[d_osi] << 1) | decision;
+
+      hamming_dist = gr_count_bits64 (d_shift_reg[d_osi] ^ GRSF_SYNC);
+      // printf ("%2d  %d\n", hamming_dist, d_osi);
+
+      if (d_state == ST_LOOKING && hamming_dist <= THRESHOLD){
+       // We're seeing a good PN code, remember location
+       enter_under_threshold ();
+      }
+      else if (d_state == ST_UNDER_THRESHOLD && hamming_dist > THRESHOLD){
+       // no longer seeing good PN code, compute center of goodness
+       enter_locked ();
+       debug_data.enter_locked = 1.0;
+      }
+      break;
+
+    default:
+      assert (0);
+    }
+      
+#ifdef DEBUG_SIMPLE_CORRELATOR
+    fwrite(&debug_data, sizeof (debug_data), 1, d_debug_fp);
+#endif
+
+    d_osi = add_index (d_osi, 1);
+    n++;
+  }
+
+  consume_each (n);
+  return 0;
+}
diff --git a/gnuradio-core/src/lib/general/gr_simple_correlator.h b/gnuradio-core/src/lib/general/gr_simple_correlator.h
new file mode 100644 (file)
index 0000000..5697e17
--- /dev/null
@@ -0,0 +1,109 @@
+/* -*- 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 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.
+ */
+
+#ifndef INCLUDED_GR_SIMPLE_CORRELATOR_H
+#define INCLUDED_GR_SIMPLE_CORRELATOR_H
+
+#include <gr_block.h>
+#include <assert.h>
+
+//#define      DEBUG_SIMPLE_CORRELATOR
+
+class gr_simple_correlator;
+typedef boost::shared_ptr<gr_simple_correlator> gr_simple_correlator_sptr;
+
+gr_simple_correlator_sptr gr_make_simple_correlator (int payload_bytesize);
+
+/*!
+ * \brief inverse of gr_simple_framer (more or less)
+ * \ingroup block
+ */
+class gr_simple_correlator : public gr_block
+{
+  static const int OVERSAMPLE = 8;
+  enum state_t { ST_LOOKING, ST_UNDER_THRESHOLD, ST_LOCKED };
+  
+  int           d_payload_bytesize;
+  state_t       d_state;
+  unsigned int  d_osi;                         // over sample index [0,OVERSAMPLE-1]
+  unsigned int  d_transition_osi;              // first index where Hamming dist < thresh
+  unsigned int  d_center_osi;                  // center of bit
+  unsigned long long int d_shift_reg[OVERSAMPLE];
+  int           d_bblen;                       // length of bitbuf
+  unsigned char        *d_bitbuf;                      // demodulated bits
+  int           d_bbi;                         // bitbuf index
+
+  static const int AVG_PERIOD = 512;           // must be power of 2 (for freq offset correction)
+  int  d_avbi;
+  float        d_avgbuf[AVG_PERIOD];
+  float d_avg;
+  float d_accum;
+
+#ifdef DEBUG_SIMPLE_CORRELATOR
+  FILE         *d_debug_fp;                    // binary log file
+#endif
+
+  friend gr_simple_correlator_sptr gr_make_simple_correlator (int payload_bytesize);
+  gr_simple_correlator (int payload_bytesize);
+
+
+  inline int slice (float x)
+  {
+    return x >= d_avg ? 1 : 0;
+  }
+
+  void update_avg(float x);
+
+  void enter_locked ();
+  void enter_under_threshold ();
+  void enter_looking ();
+  
+  static int add_index (int a, int b)
+  {
+    int t = a + b;
+    if (t >= OVERSAMPLE)
+      t -= OVERSAMPLE;
+    assert (t >= 0 && t < OVERSAMPLE);
+    return t;
+  }
+
+  static int sub_index (int a, int b)
+  {
+    int t = a - b;
+    if (t < 0)
+      t += OVERSAMPLE;
+    assert (t >= 0 && t < OVERSAMPLE);
+    return t;
+  }
+
+  
+ public:
+  ~gr_simple_correlator ();
+
+  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_GR_SIMPLE_CORRELATOR_H */
diff --git a/gnuradio-core/src/lib/general/gr_simple_correlator.i b/gnuradio-core/src/lib/general/gr_simple_correlator.i
new file mode 100644 (file)
index 0000000..d143648
--- /dev/null
@@ -0,0 +1,31 @@
+/* -*- 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 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.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,simple_correlator);
+
+gr_simple_correlator_sptr gr_make_simple_correlator (int payload_bytesize);
+
+class gr_simple_correlator : public gr_block
+{
+ private:
+  gr_simple_correlator (int payload_bytesize);
+};
diff --git a/gnuradio-core/src/lib/general/gr_simple_framer.cc b/gnuradio-core/src/lib/general/gr_simple_framer.cc
new file mode 100644 (file)
index 0000000..797b1f3
--- /dev/null
@@ -0,0 +1,100 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_simple_framer.h>
+#include <gr_simple_framer_sync.h>
+#include <gr_io_signature.h>
+#include <assert.h>
+#include <stdexcept>
+
+
+gr_simple_framer_sptr
+gr_make_simple_framer (int payload_bytesize)
+{
+  return gr_simple_framer_sptr (new gr_simple_framer (payload_bytesize));
+}
+
+gr_simple_framer::gr_simple_framer (int payload_bytesize)
+  : gr_block ("simple_framer",
+             gr_make_io_signature (1, 1, sizeof (unsigned char)),
+             gr_make_io_signature (1, 1, sizeof (unsigned char))),
+    d_seqno (0), d_payload_bytesize (payload_bytesize),
+    d_input_block_size (payload_bytesize),
+    d_output_block_size (payload_bytesize + GRSF_OVERHEAD)
+{
+  set_output_multiple (d_output_block_size);
+}
+
+void
+gr_simple_framer::forecast (int noutput_items, gr_vector_int &ninput_items_required)
+{
+  assert (noutput_items % d_output_block_size == 0);
+
+  int  nblocks = noutput_items / d_output_block_size;
+  int  input_required = nblocks * d_input_block_size;
+
+  unsigned ninputs = ninput_items_required.size();
+  for (unsigned int i = 0; i < ninputs; i++)
+    ninput_items_required[i] = input_required;
+}
+
+int
+gr_simple_framer::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];
+  unsigned char *out = (unsigned char *) output_items[0];
+
+  int n = 0;
+  int nblocks = 0;
+
+  memset (out, 0x55, noutput_items);
+
+  while (n < noutput_items){
+    out[0] = (GRSF_SYNC >> 56) & 0xff;
+    out[1] = (GRSF_SYNC >> 48) & 0xff;
+    out[2] = (GRSF_SYNC >> 40) & 0xff;
+    out[3] = (GRSF_SYNC >> 32) & 0xff;
+    out[4] = (GRSF_SYNC >> 24) & 0xff;
+    out[5] = (GRSF_SYNC >> 16) & 0xff;
+    out[6] = (GRSF_SYNC >>  8) & 0xff;
+    out[7] = (GRSF_SYNC >>  0) & 0xff;
+    out[8] = d_seqno++;
+
+    memcpy (&out[9], in, d_input_block_size);
+    in += d_input_block_size;
+    out += d_output_block_size;
+    n += d_output_block_size;
+    nblocks++;
+  }
+
+  assert (n == noutput_items);
+
+  consume_each (nblocks * d_input_block_size);
+  return n;
+}
diff --git a/gnuradio-core/src/lib/general/gr_simple_framer.h b/gnuradio-core/src/lib/general/gr_simple_framer.h
new file mode 100644 (file)
index 0000000..3381374
--- /dev/null
@@ -0,0 +1,58 @@
+/* -*- 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 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.
+ */
+
+#ifndef INCLUDED_GR_SIMPLE_FRAMER_H
+#define INCLUDED_GR_SIMPLE_FRAMER_H
+
+#include <gr_block.h>
+
+class gr_simple_framer;
+typedef boost::shared_ptr<gr_simple_framer> gr_simple_framer_sptr;
+
+gr_simple_framer_sptr gr_make_simple_framer (int payload_bytesize);
+
+/*!
+ * \brief add sync field, seq number and command field to payload
+ * \ingroup block
+ */
+class gr_simple_framer : public gr_block
+{
+  int  d_seqno;
+  int  d_payload_bytesize;
+  int  d_input_block_size;     // bytes
+  int  d_output_block_size;    // bytes
+
+  friend gr_simple_framer_sptr gr_make_simple_framer (int payload_bytesize);
+  gr_simple_framer (int payload_bytesize);
+
+ 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);
+};
+
+
+#endif /* INCLUDED_GR_SIMPLE_FRAMER_H */
diff --git a/gnuradio-core/src/lib/general/gr_simple_framer.i b/gnuradio-core/src/lib/general/gr_simple_framer.i
new file mode 100644 (file)
index 0000000..4083ce1
--- /dev/null
@@ -0,0 +1,31 @@
+/* -*- 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 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.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,simple_framer);
+
+gr_simple_framer_sptr gr_make_simple_framer (int payload_bytesize);
+
+class gr_simple_framer : public gr_block
+{
+ private:
+  gr_simple_framer (int payload_bytesize);
+};
diff --git a/gnuradio-core/src/lib/general/gr_simple_framer_sync.h b/gnuradio-core/src/lib/general/gr_simple_framer_sync.h
new file mode 100644 (file)
index 0000000..c7f6552
--- /dev/null
@@ -0,0 +1,49 @@
+/* -*- c++ -*- */
+/*
+ * 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 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.
+ */
+
+#ifndef INCLUDED_GR_SIMPLE_FRAMER_SYNC_H
+#define INCLUDED_GR_SIMPLE_FRAMER_SYNC_H
+
+/*
+ * Here are a couple of maximum length sequences (m-sequences) that were generated by the
+ * the "mseq" matlab/octave code downloaded from:
+ * http://www.mathworks.com/matlabcentral/fileexchange/loadFile.do?objectId=990&objectType=file
+ *
+ * 31-bit m-sequence:
+ *     0110100100001010111011000111110
+ *     0x690AEC76 (padded on right with a zero)
+ *
+ * 63-bit m-sequence:
+ *     101011001101110110100100111000101111001010001100001000001111110
+ *      0xACDDA4E2F28C20FC (padded on right with a zero)
+ */
+
+static const unsigned long long GRSF_SYNC = 0xacdda4e2f28c20fcULL;
+
+static const int GRSF_BITS_PER_BYTE = 8;
+static const int GRSF_SYNC_OVERHEAD = sizeof(GRSF_SYNC);
+static const int GRSF_PAYLOAD_OVERHEAD = 1;                    // 1 byte seqno
+static const int GRSF_TAIL_PAD = 1;                            // one byte trailing padding
+static const int GRSF_OVERHEAD = GRSF_SYNC_OVERHEAD + GRSF_PAYLOAD_OVERHEAD + GRSF_TAIL_PAD; 
+
+
+#endif /* INCLUDED_GR_SIMPLE_FRAMER_SYNC_H */
diff --git a/gnuradio-core/src/lib/general/gr_simple_squelch_cc.cc b/gnuradio-core/src/lib/general/gr_simple_squelch_cc.cc
new file mode 100644 (file)
index 0000000..e34f9a1
--- /dev/null
@@ -0,0 +1,99 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include <gr_simple_squelch_cc.h>
+#include <gr_io_signature.h>
+#include <cmath>
+
+gr_simple_squelch_cc_sptr
+gr_make_simple_squelch_cc(double threshold_db, double alpha)
+{
+  return gr_simple_squelch_cc_sptr(new gr_simple_squelch_cc(threshold_db, alpha));
+}
+
+gr_simple_squelch_cc::gr_simple_squelch_cc (double threshold_db, double alpha)
+  : gr_sync_block ("simple_squelch_cc",
+                  gr_make_io_signature(1, 1, sizeof(gr_complex)),
+                  gr_make_io_signature(1, 1, sizeof(gr_complex))),
+    d_iir(alpha), d_unmuted(false)
+{
+  set_threshold (threshold_db);
+}
+
+gr_simple_squelch_cc::~gr_simple_squelch_cc()
+{
+}
+
+
+int
+gr_simple_squelch_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];
+
+  for (int i = 0; i < noutput_items; i++){
+    double mag_sqrd = in[i].real()*in[i].real() + in[i].imag()*in[i].imag();
+    double f = d_iir.filter(mag_sqrd);
+    if (f >= d_threshold)
+      out[i] = in[i];
+    else
+      out[i] = 0;
+  }
+
+  d_unmuted = d_iir.prev_output() >= d_threshold;
+  return noutput_items;
+}
+
+void
+gr_simple_squelch_cc::set_threshold(double decibels)
+{
+  // convert to absolute threshold (mag squared)
+  d_threshold = std::pow(10.0, decibels/10);
+}
+
+double
+gr_simple_squelch_cc::threshold() const
+{
+  return 10 * log10(d_threshold);
+}
+
+void
+gr_simple_squelch_cc::set_alpha(double alpha)
+{
+  d_iir.set_taps(alpha);
+}
+
+std::vector<float>
+gr_simple_squelch_cc::squelch_range() const
+{
+  std::vector<float> r(3);
+  r[0] = -50.0;                                // min  FIXME
+  r[1] = +50.0;                                // max  FIXME
+  r[2] = (r[1] - r[0]) / 100;          // step size
+
+  return r;
+}
diff --git a/gnuradio-core/src/lib/general/gr_simple_squelch_cc.h b/gnuradio-core/src/lib/general/gr_simple_squelch_cc.h
new file mode 100644 (file)
index 0000000..31fde12
--- /dev/null
@@ -0,0 +1,65 @@
+/* -*- 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 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.
+ */
+#ifndef INCLUDED_GR_SIMPLE_SQUELCH_CC_H
+#define INCLUDED_GR_SIMPLE_SQUELCH_CC_H
+
+#include <gr_sync_block.h>
+#include <gr_single_pole_iir.h>
+
+class gr_simple_squelch_cc;
+typedef boost::shared_ptr<gr_simple_squelch_cc> gr_simple_squelch_cc_sptr;
+
+gr_simple_squelch_cc_sptr
+gr_make_simple_squelch_cc (double threshold_db, double alpha = 0.0001);
+
+/*!
+ * \brief simple squelch block based on average signal power and threshold in dB.
+ */
+class gr_simple_squelch_cc : public gr_sync_block
+{
+  double                                       d_threshold;
+  gr_single_pole_iir<double,double,double>     d_iir;
+  bool                                         d_unmuted;
+
+  friend gr_simple_squelch_cc_sptr
+  gr_make_simple_squelch_cc (double threshold_db, double alpha);
+
+  gr_simple_squelch_cc (double threshold_db, double alpha);
+
+public:
+  ~gr_simple_squelch_cc ();
+
+  int work (int noutput_items,
+           gr_vector_const_void_star &input_items,
+           gr_vector_void_star &output_items);
+
+  bool unmuted () const { return d_unmuted; }
+
+  void set_alpha (double alpha);
+  void set_threshold (double decibels);
+
+  double threshold() const;
+  std::vector<float> squelch_range() const;
+
+};
+
+#endif /* INCLUDED_GR_SIMPLE_SQUELCH_CC_H */
diff --git a/gnuradio-core/src/lib/general/gr_simple_squelch_cc.i b/gnuradio-core/src/lib/general/gr_simple_squelch_cc.i
new file mode 100644 (file)
index 0000000..5e3339a
--- /dev/null
@@ -0,0 +1,37 @@
+/* -*- 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 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.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,simple_squelch_cc);
+
+gr_simple_squelch_cc_sptr
+gr_make_simple_squelch_cc (double threshold_db, double alpha = 0.0001);
+
+class gr_simple_squelch_cc : public gr_sync_block
+{
+public:
+  bool unmuted () const { return d_unmuted; }
+  void set_alpha (double alpha);
+  void set_threshold (double decibels);
+
+  double threshold() const;
+  std::vector<float> squelch_range() const;
+};
diff --git a/gnuradio-core/src/lib/general/gr_skiphead.cc b/gnuradio-core/src/lib/general/gr_skiphead.cc
new file mode 100644 (file)
index 0000000..599d00b
--- /dev/null
@@ -0,0 +1,70 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <gr_skiphead.h>
+#include <gr_io_signature.h>
+
+gr_skiphead::gr_skiphead (size_t sizeof_stream_item, int nitems)
+  : gr_sync_block ("skiphead",
+       gr_make_io_signature (1, 1, sizeof_stream_item),
+       gr_make_io_signature (1, 1, sizeof_stream_item)),
+    d_nitems (nitems), d_nskipped_items (0)
+{
+}
+
+gr_block_sptr
+gr_make_skiphead (size_t sizeof_stream_item, int nitems)
+{
+  return gr_block_sptr (new gr_skiphead (sizeof_stream_item, nitems));
+}
+
+int
+gr_skiphead::work (int noutput_items,
+        gr_vector_const_void_star &input_items,
+        gr_vector_void_star &output_items)
+{
+  int items_to_skip = d_nitems - d_nskipped_items;
+  if (items_to_skip <=0)
+  {
+     //Done with skipping, copy all input to the output;
+     memcpy (output_items[0], input_items[0], noutput_items * input_signature()->sizeof_stream_item (0));
+     return noutput_items;
+  } else if (items_to_skip < noutput_items)
+  {
+     memcpy (output_items[0], &(((char *)input_items[0])[items_to_skip*input_signature()->sizeof_stream_item (0)]), (noutput_items -items_to_skip) * input_signature()->sizeof_stream_item (0));
+    //memcpy (output_items[0], &((input_items[0])[items_to_skip]), (noutput_items -items_to_skip) * input_signature()->sizeof_stream_item (0));
+     //memcpy (output_items[0], input_items[0]+items_to_skip*input_signature()->sizeof_stream_item (0), (noutput_items -items_to_skip) * input_signature()->sizeof_stream_item (0));
+     d_nskipped_items += items_to_skip;
+     consume_each (items_to_skip);
+     return (noutput_items -items_to_skip);
+  } else
+  {
+     d_nskipped_items += noutput_items;
+     consume_each (items_to_skip);
+     return 0;
+  }
+
+  return -1;//Should never get here
+}
diff --git a/gnuradio-core/src/lib/general/gr_skiphead.h b/gnuradio-core/src/lib/general/gr_skiphead.h
new file mode 100644 (file)
index 0000000..e87f8a4
--- /dev/null
@@ -0,0 +1,54 @@
+/* -*- 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 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.
+ */
+
+#ifndef INCLUDED_GR_SKIPHEAD_H
+#define INCLUDED_GR_SKIPHEAD_H
+
+#include <gr_sync_block.h>
+#include <stddef.h>      // size_t
+
+/*!
+ * \brief skips the first N items, from then on copies items to the output
+ * \ingroup block
+ *
+ * Useful for building test cases and sources which have metadata or junk at the start
+ */
+
+class gr_skiphead : public gr_sync_block
+{
+  friend gr_block_sptr gr_make_skiphead (size_t sizeof_stream_item, int nitems);
+  gr_skiphead (size_t sizeof_stream_item, int nitems);
+
+  int  d_nitems;
+  int  d_nskipped_items;
+
+ public:
+  int work (int noutput_items,
+     gr_vector_const_void_star &input_items,
+     gr_vector_void_star &output_items);
+};
+
+gr_block_sptr
+gr_make_skiphead (size_t sizeof_stream_item, int nitems);
+
+
+#endif /* INCLUDED_GR_SKIPHEAD_H */
diff --git a/gnuradio-core/src/lib/general/gr_skiphead.i b/gnuradio-core/src/lib/general/gr_skiphead.i
new file mode 100644 (file)
index 0000000..deedeb3
--- /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 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.
+ */
+
+%ignore gr_skiphead;
+class gr_skiphead : public gr_block {
+  friend gr_block_sptr gr_make_skiphead (size_t sizeof_stream_item, int nitems);
+  gr_skiphead (size_t sizeof_stream_item, int nitems);
+};
+
+%rename(skiphead) gr_make_skiphead;
+gr_block_sptr gr_make_skiphead (size_t sizeof_stream_item, int nitems);
diff --git a/gnuradio-core/src/lib/general/gr_squelch_base_cc.cc b/gnuradio-core/src/lib/general/gr_squelch_base_cc.cc
new file mode 100644 (file)
index 0000000..b3e61fc
--- /dev/null
@@ -0,0 +1,93 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_squelch_base_cc.h>
+#include <gr_io_signature.h>
+
+gr_squelch_base_cc::gr_squelch_base_cc(const char *name, int ramp, bool gate) : 
+       gr_block(name,
+                gr_make_io_signature(1, 1, sizeof(gr_complex)),
+                gr_make_io_signature(1, 1, sizeof(gr_complex)))
+{
+  set_ramp(ramp);
+  set_gate(gate);
+  d_state = ST_MUTED;
+  d_envelope = d_ramp ? 0.0 : 1.0;
+  d_ramped = 0;
+}
+
+int gr_squelch_base_cc::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];
+  gr_complex *out = (gr_complex *) output_items[0];
+
+  int j = 0;
+
+  for (int i = 0; i < noutput_items; i++) {
+    update_state(in[i]);
+
+    // Adjust envelope based on current state
+    switch(d_state) {
+      case ST_MUTED:
+        if (!mute()) 
+          d_state = d_ramp ? ST_ATTACK : ST_UNMUTED; // If not ramping, go straight to unmuted
+        break;
+
+      case ST_UNMUTED:
+        if (mute())
+          d_state = d_ramp ? ST_DECAY : ST_MUTED;    // If not ramping, go straight to muted
+        break;
+
+      case ST_ATTACK:
+        d_envelope = 0.5-std::cos(M_PI*(++d_ramped)/d_ramp)/2.0; // FIXME: precalculate window for speed
+        if (d_ramped >= d_ramp) { // use >= in case d_ramp is set to lower value elsewhere
+         d_state = ST_UNMUTED;
+         d_envelope = 1.0;
+        }
+        break;
+
+      case ST_DECAY:
+        d_envelope = 0.5-std::cos(M_PI*(--d_ramped)/d_ramp)/2.0; // FIXME: precalculate window for speed
+        if (d_ramped == 0.0)
+         d_state = ST_MUTED;
+        break;
+    };
+       
+    // If unmuted, copy input times envelope to output
+    // Otherwise, if not gating, copy zero to output
+    if (d_state != ST_MUTED)
+      out[j++] = in[i]*gr_complex(d_envelope, 0.0);
+    else
+      if (!d_gate)
+          out[j++] = 0.0;
+  }
+
+  consume_each(noutput_items);  // Use all the inputs
+  return j;                    // But only report outputs copied
+}
diff --git a/gnuradio-core/src/lib/general/gr_squelch_base_cc.h b/gnuradio-core/src/lib/general/gr_squelch_base_cc.h
new file mode 100644 (file)
index 0000000..4e33128
--- /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 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.
+ */
+
+#ifndef INCLUDED_GR_SQUELCH_BASE_CC_H
+#define INCLUDED_GR_SQUELCH_BASE_CC_H
+
+#include <gr_block.h>
+
+class gr_squelch_base_cc : public gr_block
+{
+private:
+  int   d_ramp;
+  int   d_ramped;
+  bool   d_gate;
+  double d_envelope;
+  enum { ST_MUTED, ST_ATTACK, ST_UNMUTED, ST_DECAY } d_state;
+
+protected:
+  virtual void update_state(const gr_complex &sample) {};
+  virtual bool mute() const { return false; };
+
+public:
+  gr_squelch_base_cc(const char *name, int ramp, bool gate);
+
+  int ramp() const { return d_ramp; }
+  void set_ramp(int ramp) { d_ramp = ramp; }
+  bool gate() const { return d_gate; }
+  void set_gate(bool gate) { d_gate = gate; }
+  bool unmuted() const { return (d_state == ST_UNMUTED || d_state == ST_ATTACK); }
+
+  virtual std::vector<float> squelch_range() const = 0;
+
+  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_GR_SQUELCH_BASE_CC_H */
diff --git a/gnuradio-core/src/lib/general/gr_squelch_base_cc.i b/gnuradio-core/src/lib/general/gr_squelch_base_cc.i
new file mode 100644 (file)
index 0000000..0ef674c
--- /dev/null
@@ -0,0 +1,40 @@
+/* -*- 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 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.
+ */
+
+#include <gr_block.h>
+
+class gr_squelch_base_cc : public gr_block
+{
+private:
+  enum { ST_MUTED, ST_ATTACK, ST_UNMUTED, ST_DECAY } d_state;
+
+public:
+  gr_squelch_base_cc(const char *name, int ramp, bool gate);
+
+  int ramp() const { return d_ramp; }
+  void set_ramp(int ramp) { d_ramp = ramp; }
+  bool gate() const { return d_gate; }
+  void set_gate(bool gate) { d_gate = gate; }
+  bool unmuted() const { return (d_state == ST_UNMUTED || d_state == ST_ATTACK); }
+
+  virtual std::vector<float> squelch_range() const = 0;
+};
diff --git a/gnuradio-core/src/lib/general/gr_squelch_base_ff.cc b/gnuradio-core/src/lib/general/gr_squelch_base_ff.cc
new file mode 100644 (file)
index 0000000..a457c5f
--- /dev/null
@@ -0,0 +1,93 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_squelch_base_ff.h>
+#include <gr_io_signature.h>
+
+gr_squelch_base_ff::gr_squelch_base_ff(const char *name, int ramp, bool gate) : 
+       gr_block(name,
+                gr_make_io_signature(1, 1, sizeof(float)),
+                gr_make_io_signature(1, 1, sizeof(float)))
+{
+  set_ramp(ramp);
+  set_gate(gate);
+  d_state = ST_MUTED;
+  d_envelope = d_ramp ? 0.0 : 1.0;
+  d_ramped = 0;
+}
+
+int gr_squelch_base_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];
+
+  int j = 0;
+
+  for (int i = 0; i < noutput_items; i++) {
+    update_state(in[i]);
+
+    // Adjust envelope based on current state
+    switch(d_state) {
+      case ST_MUTED:
+        if (!mute()) 
+          d_state = d_ramp ? ST_ATTACK : ST_UNMUTED; // If not ramping, go straight to unmuted
+        break;
+
+      case ST_UNMUTED:
+        if (mute())
+          d_state = d_ramp ? ST_DECAY : ST_MUTED;    // If not ramping, go straight to muted
+        break;
+
+      case ST_ATTACK:
+        d_envelope = 0.5-std::cos(M_PI*(++d_ramped)/d_ramp)/2.0; // FIXME: precalculate window for speed
+        if (d_ramped >= d_ramp) { // use >= in case d_ramp is set to lower value elsewhere
+         d_state = ST_UNMUTED;
+         d_envelope = 1.0;
+        }
+        break;
+
+      case ST_DECAY:
+        d_envelope = 0.5-std::cos(M_PI*(--d_ramped)/d_ramp)/2.0; // FIXME: precalculate window for speed
+        if (d_ramped == 0.0)
+         d_state = ST_MUTED;
+        break;
+    };
+       
+    // If unmuted, copy input times envelope to output
+    // Otherwise, if not gating, copy zero to output
+    if (d_state != ST_MUTED)
+      out[j++] = in[i]*d_envelope;
+    else
+      if (!d_gate)
+          out[j++] = 0.0;
+  }
+
+  consume_each(noutput_items);  // Use all the inputs
+  return j;                    // But only report outputs copied
+}
diff --git a/gnuradio-core/src/lib/general/gr_squelch_base_ff.h b/gnuradio-core/src/lib/general/gr_squelch_base_ff.h
new file mode 100644 (file)
index 0000000..4128735
--- /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 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.
+ */
+
+#ifndef INCLUDED_GR_SQUELCH_BASE_FF_H
+#define INCLUDED_GR_SQUELCH_BASE_FF_H
+
+#include <gr_block.h>
+
+class gr_squelch_base_ff : public gr_block
+{
+private:
+  int   d_ramp;
+  int   d_ramped;
+  bool   d_gate;
+  double d_envelope;
+  enum { ST_MUTED, ST_ATTACK, ST_UNMUTED, ST_DECAY } d_state;
+
+protected:
+  virtual void update_state(const float &sample) {};
+  virtual bool mute() const { return false; };
+
+public:
+  gr_squelch_base_ff(const char *name, int ramp, bool gate);
+
+  int ramp() const { return d_ramp; }
+  void set_ramp(int ramp) { d_ramp = ramp; }
+  bool gate() const { return d_gate; }
+  void set_gate(bool gate) { d_gate = gate; }
+  bool unmuted() const { return (d_state == ST_UNMUTED || d_state == ST_ATTACK); }
+
+  virtual std::vector<float> squelch_range() const = 0;
+
+  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_GR_SQUELCH_BASE_FF_H */
diff --git a/gnuradio-core/src/lib/general/gr_squelch_base_ff.i b/gnuradio-core/src/lib/general/gr_squelch_base_ff.i
new file mode 100644 (file)
index 0000000..d749d49
--- /dev/null
@@ -0,0 +1,40 @@
+/* -*- 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 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.
+ */
+
+#include <gr_block.h>
+
+class gr_squelch_base_ff : public gr_block
+{
+private:
+  enum { ST_MUTED, ST_ATTACK, ST_UNMUTED, ST_DECAY } d_state;
+
+public:
+  gr_squelch_base_ff(const char *name, int ramp, bool gate);
+
+  int ramp() const { return d_ramp; }
+  void set_ramp(int ramp) { d_ramp = ramp; }
+  bool gate() const { return d_gate; }
+  void set_gate(bool gate) { d_gate = gate; }
+  bool unmuted() const { return (d_state == ST_UNMUTED || d_state == ST_ATTACK); }
+
+  virtual std::vector<float> squelch_range() const = 0;
+};
diff --git a/gnuradio-core/src/lib/general/gr_stream_to_streams.cc b/gnuradio-core/src/lib/general/gr_stream_to_streams.cc
new file mode 100644 (file)
index 0000000..d462796
--- /dev/null
@@ -0,0 +1,65 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_stream_to_streams.h>
+#include <gr_io_signature.h>
+
+gr_stream_to_streams_sptr
+gr_make_stream_to_streams (size_t item_size, size_t nstreams)
+{
+  return gr_stream_to_streams_sptr (new gr_stream_to_streams (item_size, nstreams));
+}
+
+gr_stream_to_streams::gr_stream_to_streams (size_t item_size, size_t nstreams)
+  : gr_sync_decimator ("stream_to_streams",
+                      gr_make_io_signature (1, 1, item_size),
+                      gr_make_io_signature (nstreams,
+                                            nstreams, item_size),
+                      nstreams)
+{
+}
+
+int
+gr_stream_to_streams::work (int noutput_items,
+                           gr_vector_const_void_star &input_items,
+                           gr_vector_void_star &output_items)
+{
+  size_t item_size = output_signature()->sizeof_stream_item (0);
+
+  const char *in = (const char *) input_items[0];
+  char **outv = (char **) &output_items[0];
+  int nstreams = output_items.size();
+
+  for (int i = 0; i < noutput_items; i++){
+    for (int j = 0; j < nstreams; j++){
+      memcpy(outv[j], in, item_size);
+      outv[j] += item_size;
+      in += item_size;
+    }
+  }
+
+  return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_stream_to_streams.h b/gnuradio-core/src/lib/general/gr_stream_to_streams.h
new file mode 100644 (file)
index 0000000..3775e79
--- /dev/null
@@ -0,0 +1,55 @@
+/* -*- 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 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.
+ */
+#ifndef INCLUDED_GR_STREAM_TO_STREAMS_H
+#define INCLUDED_GR_STREAM_TO_STREAMS_H
+
+#include <gr_sync_decimator.h>
+
+class gr_stream_to_streams;
+typedef boost::shared_ptr<gr_stream_to_streams> gr_stream_to_streams_sptr;
+
+gr_stream_to_streams_sptr 
+gr_make_stream_to_streams (size_t item_size, size_t nstreams);
+
+
+/*!
+ * \brief convert a stream of items into a N streams of items
+ * \ingroup block
+ *
+ * Converts a stream of N items into N streams of 1 item.
+ * Repeat ad infinitum.
+ */
+class gr_stream_to_streams : public gr_sync_decimator
+{
+  friend gr_stream_to_streams_sptr
+    gr_make_stream_to_streams (size_t item_size, size_t nstreams);
+
+ protected:
+  gr_stream_to_streams (size_t item_size, size_t nstreams);
+
+ public:
+  int work (int noutput_items,
+           gr_vector_const_void_star &input_items,
+           gr_vector_void_star &output_items);
+};
+
+#endif /* INCLUDED_GR_STREAM_TO_STREAMS_H */
diff --git a/gnuradio-core/src/lib/general/gr_stream_to_streams.i b/gnuradio-core/src/lib/general/gr_stream_to_streams.i
new file mode 100644 (file)
index 0000000..59b93da
--- /dev/null
@@ -0,0 +1,34 @@
+/* -*- c++ -*- */
+/*
+ * 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 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.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,stream_to_streams)
+
+gr_stream_to_streams_sptr 
+gr_make_stream_to_streams (size_t itemsize, size_t nstreams);
+
+class gr_stream_to_streams : public gr_sync_decimator
+{
+ protected:
+  gr_stream_to_streams (size_t itemsize, size_t nstreams);
+
+ public:
+};
diff --git a/gnuradio-core/src/lib/general/gr_stream_to_vector.cc b/gnuradio-core/src/lib/general/gr_stream_to_vector.cc
new file mode 100644 (file)
index 0000000..3d815cf
--- /dev/null
@@ -0,0 +1,57 @@
+/* -*- c++ -*- */
+/*
+ * 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_stream_to_vector.h>
+#include <gr_io_signature.h>
+
+gr_stream_to_vector_sptr
+gr_make_stream_to_vector (size_t item_size, size_t nitems_per_block)
+{
+  return gr_stream_to_vector_sptr (new gr_stream_to_vector (item_size, nitems_per_block));
+}
+
+gr_stream_to_vector::gr_stream_to_vector (size_t item_size, size_t nitems_per_block)
+  : gr_sync_decimator ("stream_to_vector",
+                      gr_make_io_signature (1, 1, item_size),
+                      gr_make_io_signature (1, 1, item_size * nitems_per_block),
+                      nitems_per_block)
+{
+}
+
+int
+gr_stream_to_vector::work (int noutput_items,
+                            gr_vector_const_void_star &input_items,
+                            gr_vector_void_star &output_items)
+{
+  size_t block_size = output_signature()->sizeof_stream_item (0);
+
+  const char *in = (const char *) input_items[0];
+  char *out = (char *) output_items[0];
+
+  memcpy (out, in, noutput_items * block_size);
+
+  return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_stream_to_vector.h b/gnuradio-core/src/lib/general/gr_stream_to_vector.h
new file mode 100644 (file)
index 0000000..a0a318b
--- /dev/null
@@ -0,0 +1,54 @@
+/* -*- 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 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.
+ */
+
+#ifndef INCLUDED_GR_STREAM_TO_VECTOR_H
+#define INCLUDED_GR_STREAM_TO_VECTOR_H
+
+#include <gr_sync_decimator.h>
+
+class gr_stream_to_vector;
+typedef boost::shared_ptr<gr_stream_to_vector> gr_stream_to_vector_sptr;
+
+gr_stream_to_vector_sptr 
+gr_make_stream_to_vector (size_t item_size, size_t nitems_per_block);
+
+
+/*!
+ * \brief convert a stream of items into a stream of blocks containing nitems_per_block
+ * \ingroup block
+ */
+class gr_stream_to_vector : public gr_sync_decimator
+{
+  friend gr_stream_to_vector_sptr
+    gr_make_stream_to_vector (size_t item_size, size_t nitems_per_block);
+
+ protected:
+  gr_stream_to_vector (size_t item_size, size_t nitems_per_block);
+
+ public:
+  int work (int noutput_items,
+           gr_vector_const_void_star &input_items,
+           gr_vector_void_star &output_items);
+};
+
+
+#endif /* INCLUDED_GR_STREAM_TO_VECTOR_H */
diff --git a/gnuradio-core/src/lib/general/gr_stream_to_vector.i b/gnuradio-core/src/lib/general/gr_stream_to_vector.i
new file mode 100644 (file)
index 0000000..16550ac
--- /dev/null
@@ -0,0 +1,34 @@
+/* -*- 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 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.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,stream_to_vector)
+
+gr_stream_to_vector_sptr 
+gr_make_stream_to_vector (size_t itemsize, size_t nitems_per_block);
+
+class gr_stream_to_vector : public gr_sync_decimator
+{
+ protected:
+  gr_stream_to_vector (size_t itemsize, size_t nitems_per_block);
+
+ public:
+};
diff --git a/gnuradio-core/src/lib/general/gr_streams_to_stream.cc b/gnuradio-core/src/lib/general/gr_streams_to_stream.cc
new file mode 100644 (file)
index 0000000..9d05fbf
--- /dev/null
@@ -0,0 +1,67 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_streams_to_stream.h>
+#include <gr_io_signature.h>
+
+gr_streams_to_stream_sptr
+gr_make_streams_to_stream (size_t item_size, size_t nstreams)
+{
+  return gr_streams_to_stream_sptr (new gr_streams_to_stream (item_size, nstreams));
+}
+
+gr_streams_to_stream::gr_streams_to_stream (size_t item_size, size_t nstreams)
+  : gr_sync_interpolator ("streams_to_stream",
+                         gr_make_io_signature (nstreams, nstreams, item_size),
+                         gr_make_io_signature (1, 1, item_size),
+                         nstreams)
+{
+}
+
+int
+gr_streams_to_stream::work (int noutput_items,
+                           gr_vector_const_void_star &input_items,
+                           gr_vector_void_star &output_items)
+{
+  size_t item_size = output_signature()->sizeof_stream_item (0);
+
+  const char **inv = (const char **) &input_items[0];
+  char *out = (char *) output_items[0];
+  int nstreams = input_items.size();
+
+  assert (noutput_items % nstreams == 0);
+  int ni = noutput_items / nstreams;
+
+  for (int i = 0; i < ni; i++){
+    for (int j = 0; j < nstreams; j++){
+      memcpy(out, inv[j], item_size);
+      out += item_size;
+      inv[j] += item_size;
+    }
+  }
+
+  return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_streams_to_stream.h b/gnuradio-core/src/lib/general/gr_streams_to_stream.h
new file mode 100644 (file)
index 0000000..86d3909
--- /dev/null
@@ -0,0 +1,55 @@
+/* -*- 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 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.
+ */
+#ifndef INCLUDED_GR_STREAMS_TO_STREAM_H
+#define INCLUDED_GR_STREAMS_TO_STREAM_H
+
+#include <gr_sync_interpolator.h>
+
+class gr_streams_to_stream;
+typedef boost::shared_ptr<gr_streams_to_stream> gr_streams_to_stream_sptr;
+
+gr_streams_to_stream_sptr 
+gr_make_streams_to_stream (size_t item_size, size_t nstreams);
+
+
+/*!
+ * \brief Convert N streams of 1 item into a 1 stream of N items
+ * \ingroup block
+ *
+ * Convert N streams of 1 item into 1 stream of N items.
+ * Repeat ad infinitum.
+ */
+class gr_streams_to_stream : public gr_sync_interpolator
+{
+  friend gr_streams_to_stream_sptr
+    gr_make_streams_to_stream (size_t item_size, size_t nstreams);
+
+ protected:
+  gr_streams_to_stream (size_t item_size, size_t nstreams);
+
+ public:
+  int work (int noutput_items,
+           gr_vector_const_void_star &input_items,
+           gr_vector_void_star &output_items);
+};
+
+#endif /* INCLUDED_GR_STREAMS_TO_STREAM_H */
diff --git a/gnuradio-core/src/lib/general/gr_streams_to_stream.i b/gnuradio-core/src/lib/general/gr_streams_to_stream.i
new file mode 100644 (file)
index 0000000..0f9e46f
--- /dev/null
@@ -0,0 +1,34 @@
+/* -*- c++ -*- */
+/*
+ * 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 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.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,streams_to_stream)
+
+gr_streams_to_stream_sptr 
+gr_make_streams_to_stream (size_t itemsize, size_t nstreams);
+
+class gr_streams_to_stream : public gr_sync_interpolator
+{
+ protected:
+  gr_streams_to_stream (size_t itemsize, size_t nstreams);
+
+ public:
+};
diff --git a/gnuradio-core/src/lib/general/gr_streams_to_vector.cc b/gnuradio-core/src/lib/general/gr_streams_to_vector.cc
new file mode 100644 (file)
index 0000000..794254d
--- /dev/null
@@ -0,0 +1,63 @@
+/* -*- c++ -*- */
+/*
+ * 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_streams_to_vector.h>
+#include <gr_io_signature.h>
+
+gr_streams_to_vector_sptr
+gr_make_streams_to_vector (size_t item_size, size_t nstreams)
+{
+  return gr_streams_to_vector_sptr (new gr_streams_to_vector (item_size, nstreams));
+}
+
+gr_streams_to_vector::gr_streams_to_vector (size_t item_size, size_t nstreams)
+  : gr_sync_block ("streams_to_vector",
+                  gr_make_io_signature (nstreams, nstreams, item_size),
+                  gr_make_io_signature (1, 1, nstreams * item_size))
+{
+}
+
+int
+gr_streams_to_vector::work (int noutput_items,
+                           gr_vector_const_void_star &input_items,
+                           gr_vector_void_star &output_items)
+{
+  size_t item_size = input_signature()->sizeof_stream_item(0);
+  int nstreams = input_items.size();
+
+  const char **inv = (const char **) &input_items[0];
+  char *out = (char *) output_items[0];
+
+  for (int i = 0; i < noutput_items; i++){
+    for (int j = 0; j < nstreams; j++){
+      memcpy(out, inv[j], item_size);
+      inv[j] += item_size;
+      out += item_size;
+    }
+  }
+
+  return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_streams_to_vector.h b/gnuradio-core/src/lib/general/gr_streams_to_vector.h
new file mode 100644 (file)
index 0000000..d3a8903
--- /dev/null
@@ -0,0 +1,53 @@
+/* -*- c++ -*- */
+/*
+ * 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 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.
+ */
+
+#ifndef INCLUDED_GR_STREAMS_TO_VECTOR_H
+#define INCLUDED_GR_STREAMS_TO_VECTOR_H
+
+#include <gr_sync_interpolator.h>
+
+class gr_streams_to_vector;
+typedef boost::shared_ptr<gr_streams_to_vector> gr_streams_to_vector_sptr;
+
+gr_streams_to_vector_sptr 
+gr_make_streams_to_vector (size_t item_size, size_t nstreams);
+
+
+/*!
+ * \brief convert N streams of items to 1 stream of vector length N
+ * \ingroup block
+ */
+class gr_streams_to_vector : public gr_sync_block
+{
+  friend gr_streams_to_vector_sptr
+    gr_make_streams_to_vector (size_t item_size, size_t nstreams);
+
+ protected:
+  gr_streams_to_vector (size_t item_size, size_t nstreams);
+
+ public:
+  int work (int noutput_items,
+           gr_vector_const_void_star &input_items,
+           gr_vector_void_star &output_items);
+};
+
+#endif /* INCLUDED_GR_STREAMS_TO_VECTOR_H */
diff --git a/gnuradio-core/src/lib/general/gr_streams_to_vector.i b/gnuradio-core/src/lib/general/gr_streams_to_vector.i
new file mode 100644 (file)
index 0000000..a69c2e5
--- /dev/null
@@ -0,0 +1,34 @@
+/* -*- c++ -*- */
+/*
+ * 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 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.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,streams_to_vector)
+
+gr_streams_to_vector_sptr 
+gr_make_streams_to_vector (size_t itemsize, size_t nstreams);
+
+class gr_streams_to_vector : public gr_sync_block
+{
+ protected:
+  gr_streams_to_vector (size_t itemsize, size_t nstreams);
+
+ public:
+};
diff --git a/gnuradio-core/src/lib/general/gr_sub_XX.cc.t b/gnuradio-core/src/lib/general/gr_sub_XX.cc.t
new file mode 100644 (file)
index 0000000..2cfdc6e
--- /dev/null
@@ -0,0 +1,70 @@
+/* -*- 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 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.
+ */
+
+// @WARNING@
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <@NAME@.h>
+#include <gr_io_signature.h>
+
+@SPTR_NAME@
+gr_make_@BASE_NAME@ ()
+{
+  return @SPTR_NAME@ (new @NAME@ ());
+}
+
+@NAME@::@NAME@ ()
+  : gr_sync_block ("@BASE_NAME@",
+                  gr_make_io_signature (1, -1, sizeof (@I_TYPE@)),
+                  gr_make_io_signature (1,  1, sizeof (@O_TYPE@)))
+{
+}
+
+int
+@NAME@::work (int noutput_items,
+                  gr_vector_const_void_star &input_items,
+                  gr_vector_void_star &output_items)
+{
+  @O_TYPE@ *optr = (@O_TYPE@ *) output_items[0];
+
+  int ninputs = input_items.size ();
+
+  if (ninputs == 1){           // negate
+    for (int i = 0; i < noutput_items; i++)
+      *optr++ = (@O_TYPE@) -((@I_TYPE@ *) input_items[0])[i];
+  }
+
+  else {
+    for (int i = 0; i < noutput_items; i++){
+      @I_TYPE@ acc = ((@I_TYPE@ *) input_items[0])[i];
+      for (int j = 1; j < ninputs; j++)
+       acc -= ((@I_TYPE@ *) input_items[j])[i];
+
+      *optr++ = (@O_TYPE@) acc;
+    }
+  }
+
+  return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_sub_XX.h.t b/gnuradio-core/src/lib/general/gr_sub_XX.h.t
new file mode 100644 (file)
index 0000000..025c077
--- /dev/null
@@ -0,0 +1,54 @@
+/* -*- 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 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.
+ */
+
+// @WARNING@
+
+#ifndef @GUARD_NAME@
+#define @GUARD_NAME@
+
+#include <gr_sync_block.h>
+
+class @NAME@;
+typedef boost::shared_ptr<@NAME@> @SPTR_NAME@;
+
+@SPTR_NAME@ gr_make_@BASE_NAME@ ();
+
+/*!
+ * \brief output = input_0 -  input_1 - ...)
+ * \ingroup block
+ *
+ * Subtract across all input streams.
+ */
+class @NAME@ : public gr_sync_block
+{
+  friend @SPTR_NAME@ gr_make_@BASE_NAME@ ();
+
+  @NAME@ ();
+
+ public:
+
+  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_sub_XX.i.t b/gnuradio-core/src/lib/general/gr_sub_XX.i.t
new file mode 100644 (file)
index 0000000..8479aad
--- /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 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.
+ */
+
+// @WARNING@
+
+GR_SWIG_BLOCK_MAGIC(gr,@BASE_NAME@)
+
+@SPTR_NAME@ gr_make_@BASE_NAME@ ();
+
+class @NAME@ : public gr_sync_block
+{
+ private:
+  @NAME@ ();
+};
diff --git a/gnuradio-core/src/lib/general/gr_sync_block.cc b/gnuradio-core/src/lib/general/gr_sync_block.cc
new file mode 100644 (file)
index 0000000..57b6c55
--- /dev/null
@@ -0,0 +1,68 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_sync_block.h>
+
+gr_sync_block::gr_sync_block (const std::string &name,
+                             gr_io_signature_sptr input_signature,
+                             gr_io_signature_sptr output_signature)
+  : gr_block(name, input_signature, output_signature)
+{
+  set_fixed_rate(true);
+}
+
+
+void
+gr_sync_block::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
+gr_sync_block::fixed_rate_noutput_to_ninput(int noutput_items)
+{
+  return noutput_items + history() - 1;
+}
+
+int
+gr_sync_block::fixed_rate_ninput_to_noutput(int ninput_items)
+{
+  return std::max(0, ninput_items - (int)history() + 1);
+}
+
+int
+gr_sync_block::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 (r);
+  return r;
+}
diff --git a/gnuradio-core/src/lib/general/gr_sync_block.h b/gnuradio-core/src/lib/general/gr_sync_block.h
new file mode 100644 (file)
index 0000000..b4a2d00
--- /dev/null
@@ -0,0 +1,65 @@
+/* -*- 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 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.
+ */
+
+#ifndef INCLUDED_GR_SYNC_BLOCK_H
+#define INCLUDED_GR_SYNC_BLOCK_H
+
+#include <gr_block.h>
+
+/*!
+ * \brief synchronous 1:1 input to output with history
+ * \ingroup block
+ *
+ * Override work to provide the signal processing implementation.
+ */
+class gr_sync_block : public gr_block
+{
+ protected:
+
+  gr_sync_block (const std::string &name,
+                gr_io_signature_sptr input_signature,
+                gr_io_signature_sptr output_signature);
+
+ public:
+
+  /*!
+   * \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 &input_items,
+                   gr_vector_void_star &output_items) = 0;
+  
+
+  // gr_sync_block overrides these to assist work
+  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 fixed_rate_ninput_to_noutput(int ninput);
+  int fixed_rate_noutput_to_ninput(int noutput);
+};
+#endif /* INCLUDED_GR_SYNC_BLOCK_H */
diff --git a/gnuradio-core/src/lib/general/gr_sync_block.i b/gnuradio-core/src/lib/general/gr_sync_block.i
new file mode 100644 (file)
index 0000000..c078a8b
--- /dev/null
@@ -0,0 +1,29 @@
+/* -*- 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 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.
+ */
+class gr_sync_block : public gr_block
+{
+ protected:
+
+  gr_sync_block (const std::string &name,
+                gr_io_signature_sptr input_signature,
+                gr_io_signature_sptr output_signature);
+};
diff --git a/gnuradio-core/src/lib/general/gr_sync_decimator.cc b/gnuradio-core/src/lib/general/gr_sync_decimator.cc
new file mode 100644 (file)
index 0000000..4b168a5
--- /dev/null
@@ -0,0 +1,69 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_sync_decimator.h>
+
+gr_sync_decimator::gr_sync_decimator (const std::string &name,
+                                     gr_io_signature_sptr input_signature,
+                                     gr_io_signature_sptr output_signature,
+                                     unsigned decimation)
+  : gr_sync_block (name, input_signature, output_signature)
+{
+  set_decimation (decimation);
+}
+
+void
+gr_sync_decimator::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
+gr_sync_decimator::fixed_rate_noutput_to_ninput(int noutput_items)
+{
+  return noutput_items * decimation() + history() - 1;
+}
+
+int
+gr_sync_decimator::fixed_rate_ninput_to_noutput(int ninput_items)
+{
+  return std::max(0, ninput_items - (int)history() + 1) / decimation();
+}
+
+int
+gr_sync_decimator::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 (r * decimation ());
+  return r;
+}
+
diff --git a/gnuradio-core/src/lib/general/gr_sync_decimator.h b/gnuradio-core/src/lib/general/gr_sync_decimator.h
new file mode 100644 (file)
index 0000000..6cdd35a
--- /dev/null
@@ -0,0 +1,68 @@
+/* -*- 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 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.
+ */
+
+#ifndef INCLUDED_GR_SYNC_DECIMATOR_H
+#define INCLUDED_GR_SYNC_DECIMATOR_H
+
+#include <gr_sync_block.h>
+
+/*!
+ * \brief synchronous N:1 input to output with history
+ * \ingroup block
+ *
+ * Override work to provide the signal processing implementation.
+ */
+class gr_sync_decimator : public gr_sync_block
+{
+ private:
+  unsigned     d_decimation;
+
+ protected:
+
+  gr_sync_decimator (const std::string &name,
+                    gr_io_signature_sptr input_signature,
+                    gr_io_signature_sptr output_signature,
+                    unsigned decimation);
+ public:
+
+  unsigned decimation () const { return d_decimation; }
+  void set_decimation (unsigned decimation)
+  {
+    d_decimation = decimation;
+    set_relative_rate (1.0 / decimation);
+  }
+
+  // gr_sync_decimator overrides these to assist work
+  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);
+
+  // derived classes should override work
+
+  int fixed_rate_ninput_to_noutput(int ninput);
+  int fixed_rate_noutput_to_ninput(int noutput);
+};
+
+
+#endif /* INCLUDED_GR_SYNC_DECIMATOR_H */
diff --git a/gnuradio-core/src/lib/general/gr_sync_decimator.i b/gnuradio-core/src/lib/general/gr_sync_decimator.i
new file mode 100644 (file)
index 0000000..d9f6483
--- /dev/null
@@ -0,0 +1,31 @@
+/* -*- 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 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.
+ */
+
+class gr_sync_decimator : public gr_sync_block
+{
+ protected:
+
+  gr_sync_decimator (const std::string &name,
+                    gr_io_signature_sptr input_signature,
+                    gr_io_signature_sptr output_signature,
+                    unsigned decimation);
+};
diff --git a/gnuradio-core/src/lib/general/gr_sync_interpolator.cc b/gnuradio-core/src/lib/general/gr_sync_interpolator.cc
new file mode 100644 (file)
index 0000000..024d7e7
--- /dev/null
@@ -0,0 +1,70 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_sync_interpolator.h>
+
+gr_sync_interpolator::gr_sync_interpolator (const std::string &name,
+                                           gr_io_signature_sptr input_signature,
+                                           gr_io_signature_sptr output_signature,
+                                           unsigned interpolation)
+  : gr_sync_block (name, input_signature, output_signature)
+{
+  set_interpolation (interpolation);
+}
+
+void
+gr_sync_interpolator::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
+gr_sync_interpolator::fixed_rate_noutput_to_ninput(int noutput_items)
+{
+  return noutput_items / interpolation() + history() - 1;
+}
+
+int
+gr_sync_interpolator::fixed_rate_ninput_to_noutout(int ninput_items)
+{
+  return std::max(0, ninput_items - (int)history() + 1) * interpolation();
+}
+
+int
+gr_sync_interpolator::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 (r / interpolation ());
+  return r;
+}
+
+
diff --git a/gnuradio-core/src/lib/general/gr_sync_interpolator.h b/gnuradio-core/src/lib/general/gr_sync_interpolator.h
new file mode 100644 (file)
index 0000000..914ea8e
--- /dev/null
@@ -0,0 +1,68 @@
+/* -*- 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 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.
+ */
+
+#ifndef INCLUDED_GR_SYNC_INTERPOLATOR_H
+#define INCLUDED_GR_SYNC_INTERPOLATOR_H
+
+#include <gr_sync_block.h>
+
+/*!
+ * \brief synchronous 1:N input to output with history
+ * \ingroup block
+ *
+ * Override work to provide the signal processing implementation.
+ */
+class gr_sync_interpolator : public gr_sync_block
+{
+ private:
+  unsigned     d_interpolation;
+
+ protected:
+  gr_sync_interpolator (const std::string &name,
+                       gr_io_signature_sptr input_signature,
+                       gr_io_signature_sptr output_signature,
+                       unsigned interpolation);
+ public:
+
+  unsigned interpolation () const { return d_interpolation; }
+  void set_interpolation (unsigned interpolation)
+  {
+    d_interpolation = interpolation;
+    set_relative_rate (1.0 * interpolation);
+    set_output_multiple (interpolation);
+  }
+
+  // gr_sync_interpolator overrides these to assist work
+  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);
+
+  // derived classes should override work
+
+  int fixed_rate_ninput_to_noutout(int ninput);
+  int fixed_rate_noutput_to_ninput(int noutput);
+};
+
+
+#endif /* INCLUDED_GR_SYNC_INTERPOLATOR_H */
diff --git a/gnuradio-core/src/lib/general/gr_sync_interpolator.i b/gnuradio-core/src/lib/general/gr_sync_interpolator.i
new file mode 100644 (file)
index 0000000..9b69d33
--- /dev/null
@@ -0,0 +1,31 @@
+/* -*- 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 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.
+ */
+
+class gr_sync_interpolator : public gr_sync_block
+{
+ protected:
+
+  gr_sync_interpolator (const std::string &name,
+                       gr_io_signature_sptr input_signature,
+                       gr_io_signature_sptr output_signature,
+                       unsigned interpolation);
+};
diff --git a/gnuradio-core/src/lib/general/gr_test.cc b/gnuradio-core/src/lib/general/gr_test.cc
new file mode 100644 (file)
index 0000000..17263f4
--- /dev/null
@@ -0,0 +1,176 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_test.h>
+#include <gr_io_signature.h>
+#include <stdexcept>
+#include <iostream>
+
+gr_test_sptr gr_make_test (const std::string &name,
+        int min_inputs, int max_inputs, unsigned int sizeof_input_item,
+        int min_outputs, int max_outputs, unsigned int sizeof_output_item,
+        unsigned int history,unsigned int output_multiple,double relative_rate,
+        bool fixed_rate,gr_consume_type_t cons_type, gr_produce_type_t prod_type)
+{
+  return gr_test_sptr (new gr_test (name, min_inputs,max_inputs,sizeof_input_item,
+             min_outputs,max_outputs,sizeof_output_item,
+             history,output_multiple,relative_rate,fixed_rate,cons_type, prod_type));
+}
+
+  gr_test::gr_test (const std::string &name,int min_inputs, int max_inputs, unsigned int sizeof_input_item,
+                                   int min_outputs, int max_outputs, unsigned int sizeof_output_item,
+                                   unsigned int history,unsigned int output_multiple,double relative_rate,
+                                   bool fixed_rate,gr_consume_type_t cons_type, gr_produce_type_t prod_type): gr_block (name,
+                  gr_make_io_signature (min_inputs, max_inputs, sizeof_input_item),
+                  gr_make_io_signature (min_outputs, max_outputs, sizeof_output_item)),
+                   d_sizeof_input_item(sizeof_input_item),
+                   d_sizeof_output_item(sizeof_output_item),
+                   d_check_topology(true),
+                   d_consume_type(cons_type),
+                   d_min_consume(0),
+                   d_max_consume(0),
+                   d_produce_type(prod_type),
+                   d_min_produce(0),
+                   d_max_produce(0)
+  {
+    set_history(history);
+    set_output_multiple(output_multiple);
+    set_relative_rate(relative_rate);
+    set_fixed_rate(fixed_rate);
+  }
+
+int 
+gr_test::general_work (int noutput_items,
+                           gr_vector_int &ninput_items,
+                           gr_vector_const_void_star &input_items,
+                           gr_vector_void_star &output_items)
+   {
+     //touch all inputs and outputs to detect segfaults
+     unsigned ninputs = input_items.size ();
+     unsigned noutputs= output_items.size();
+     for (unsigned i = 0; i < ninputs; i++)
+     {
+       char * in=(char *)input_items[i];
+       if (ninput_items[i]< (int)(noutput_items+history()))
+       {
+         std::cerr << "ERROR: ninput_items[" << i << "] < noutput_items+history()" << std::endl;
+         std::cerr << "ninput_items[" << i << "] = " << ninput_items[i] <<  std::endl;
+         std::cerr << "noutput_items+history() = " << noutput_items+history() <<  std::endl;
+         std::cerr << "noutput_items = " << noutput_items <<  std::endl;
+         std::cerr << "history() = " << history() <<  std::endl;
+         throw std::runtime_error ("gr_test");
+       } else
+       {
+         for (int j=0;j<ninput_items[i];j++)
+         {
+           //Touch every available input_item
+           //We use a class variable to avoid the compiler to optimize this away
+           for(unsigned int k=0;k<d_sizeof_input_item;k++)
+             d_temp= in[j*d_sizeof_input_item+k];
+         }
+         switch (d_consume_type)
+         {
+           case CONSUME_NOUTPUT_ITEMS:
+             consume(i,noutput_items);
+             break;
+           case CONSUME_NOUTPUT_ITEMS_LIMIT_MAX:
+             consume(i,std::min(noutput_items,d_max_consume));
+             break;
+           case CONSUME_NOUTPUT_ITEMS_LIMIT_MIN:
+             consume(i,std::min(std::max(noutput_items,d_min_consume),ninput_items[i]));
+             break;
+           case CONSUME_ALL_AVAILABLE:
+             consume(i,ninput_items[i]);
+             break;
+           case CONSUME_ALL_AVAILABLE_LIMIT_MAX:
+             consume(i,std::min(ninput_items[i],d_max_consume));
+             break;
+/*         //This could result in segfault, uncomment if you want to test this     
+           case CONSUME_ALL_AVAILABLE_LIMIT_MIN:
+             consume(i,std::max(ninput_items[i],d_max_consume));
+             break;*/
+           case CONSUME_ZERO:
+             consume(i,0);
+             break;
+           case CONSUME_ONE:
+             consume(i,1);
+             break;
+           case CONSUME_MINUS_ONE:
+             consume(i,-1);
+             break;
+           default:
+             consume(i,noutput_items);
+         }
+       }
+     }
+     for (unsigned i = 0; i < noutputs; i++)
+     {
+       char * out=(char *)output_items[i];
+       {
+         for (int j=0;j<noutput_items;j++)
+         {
+           //Touch every available output_item
+           for(unsigned int k=0;k<d_sizeof_output_item;k++)
+             out[j*d_sizeof_input_item+k]=0;
+         }       
+       }
+     } 
+     //Now copy input to output untill max ninputs or max noutputs is reached
+     int common_nports=std::min(ninputs,noutputs); 
+     if(d_sizeof_output_item==d_sizeof_input_item);    
+       for (int i = 0; i < common_nports; i++)
+       {
+         memcpy(output_items[i],input_items[i],noutput_items*d_sizeof_input_item);
+       }
+     int noutput_items_produced=0;
+     switch (d_produce_type){
+           case PRODUCE_NOUTPUT_ITEMS:
+             noutput_items_produced=noutput_items;
+             break;
+           case PRODUCE_NOUTPUT_ITEMS_LIMIT_MAX:
+             noutput_items_produced=std::min(noutput_items,d_max_produce);
+             break;
+/*         //This could result in segfault, uncomment if you want to test this         
+             case PRODUCE_NOUTPUT_ITEMS_LIMIT_MIN:
+             noutput_items_produced=std::max(noutput_items,d_min_produce);
+             break;*/
+           case PRODUCE_ZERO:
+             noutput_items_produced=0;
+             break;
+           case PRODUCE_ONE:
+             noutput_items_produced=1;
+             break;
+           case PRODUCE_MINUS_ONE:
+             noutput_items_produced=-1;
+             break;
+           default:
+             noutput_items_produced=noutput_items;
+       }
+     return noutput_items_produced;
+   }
+
+
+
diff --git a/gnuradio-core/src/lib/general/gr_test.h b/gnuradio-core/src/lib/general/gr_test.h
new file mode 100644 (file)
index 0000000..7bda9ae
--- /dev/null
@@ -0,0 +1,199 @@
+/* -*- 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 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.
+ */
+
+#ifndef INCLUDED_GR_TEST_H
+#define INCLUDED_GR_TEST_H
+
+#include <gr_block.h>
+#include <string>
+#include "gr_test_types.h"
+
+class gr_test;
+typedef boost::shared_ptr<gr_test> gr_test_sptr;
+
+// public constructor
+gr_test_sptr gr_make_test (const std::string &name=std::string("gr_test"),
+        int min_inputs=1, int max_inputs=1, unsigned int sizeof_input_item=1,
+        int min_outputs=1, int max_outputs=1, unsigned int sizeof_output_item=1,
+        unsigned int history=1,unsigned int output_multiple=1,double relative_rate=1.0,
+        bool fixed_rate=true,gr_consume_type_t cons_type=CONSUME_NOUTPUT_ITEMS, gr_produce_type_t prod_type=PRODUCE_NOUTPUT_ITEMS);
+
+/*!
+ * \brief Test class for testing runtime system (setting up buffers and such.)
+ * \ingroup block
+ *
+ * This block does not do any usefull actual data processing.
+ * It just exposes setting all standard block parameters using the contructor or public methods.
+ *
+ * This block can be usefull when testing the runtime system.
+ * You can force this block to have a large history, decimation 
+ * factor and/or large output_multiple.
+ * The runtime system should detect this and create large enough buffers
+ * all through the signal chain.
+ *
+ */
+
+
+
+
+class gr_test : public gr_block {
+
+ public:
+  
+  ~gr_test (){}
+  
+int general_work (int noutput_items,
+                           gr_vector_int &ninput_items,
+                           gr_vector_const_void_star &input_items,
+                           gr_vector_void_star &output_items);
+  // ----------------------------------------------------------------
+  //           override these to define your behavior
+  // ----------------------------------------------------------------
+
+  /*!
+   * \brief  Estimate input requirements given output request
+   *
+   * \param noutput_items           number of output items to produce
+   * \param ninput_items_required   number of input items required on each input stream
+   *
+   * Given a request to product \p noutput_items, estimate the number of
+   * data items required on each input stream.  The estimate doesn't have
+   * to be exact, but should be close.
+   */
+   void 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] = (int)((double)noutput_items / relative_rate()) + (int)history();
+   }
+
+
+  /*!
+   * \brief Force check topology to return true or false.
+   *
+   * \param check_topology     value to return when check_topology is called (true or false)
+   * default check_topology returns true
+   *
+   */
+   void set_check_topology (bool check_topology){ d_check_topology=check_topology;}
+
+  /*!
+   * \brief Confirm that ninputs and noutputs is an acceptable combination.
+   *
+   * \param ninputs    number of input streams connected
+   * \param noutputs   number of output streams connected
+   *
+   * \returns true if this is a valid configuration for this block.
+   *
+   * This function is called by the runtime system whenever the
+   * topology changes.  Most classes do not need to override this.
+   * This check is in addition to the constraints specified by the input
+   * and output gr_io_signatures.
+   */
+  bool check_topology (int ninputs, int noutputs) { return d_check_topology;}
+
+  // ----------------------------------------------------------------
+  /*
+   * The following two methods provide special case info to the
+   * scheduler in the event that a block has a fixed input to output
+   * ratio.  gr_sync_block, gr_sync_decimator and gr_sync_interpolator
+   * override these.  If you're fixed rate, subclass one of those.
+   */
+  /*!
+   * \brief Given ninput samples, return number of output samples that will be produced.
+   * N.B. this is only defined if fixed_rate returns true.
+   * Generally speaking, you don't need to override this.
+   */
+  int fixed_rate_ninput_to_noutput(int ninput) { return (int)((double)ninput/relative_rate()); }
+
+  /*!
+   * \brief Given noutput samples, return number of input samples required to produce noutput.
+   * N.B. this is only defined if fixed_rate returns true.
+   */
+  int fixed_rate_noutput_to_ninput(int noutput)  { return (int)((double)noutput*relative_rate()); }
+
+  /*!
+   * \brief Set if fixed rate should return true.
+   * N.B. This is normally a private method but we make it available here as public.
+   */
+  void set_fixed_rate_public(bool fixed_rate){ set_fixed_rate(fixed_rate);}
+
+  /*!
+   * \brief Set the consume pattern.
+   *
+   * \param cons_type  which consume pattern to use
+   */
+  void set_consume_type (gr_consume_type_t cons_type) { d_consume_type=cons_type;}
+
+  /*!
+   * \brief Set the consume limit.
+   *
+   * \param limit      min or maximum items to consume (depending on consume_type)
+   */
+  void set_consume_limit (unsigned int limit) { d_min_consume=limit; d_max_consume=limit;}
+
+  /*!
+   * \brief Set the produce pattern.
+   *
+   * \param prod_type  which produce pattern to use
+   */
+  void set_produce_type (gr_produce_type_t prod_type) { d_produce_type=prod_type;}
+
+  /*!
+   * \brief Set the produce limit.
+   *
+   * \param limit      min or maximum items to produce (depending on produce_type)
+   */
+  void set_produce_limit (unsigned int limit) { d_min_produce=limit; d_max_produce=limit;}
+
+  // ----------------------------------------------------------------------------
+
+
+  
+ protected:
+  unsigned int d_sizeof_input_item;
+  unsigned int d_sizeof_output_item;
+  bool d_check_topology;
+  char d_temp;
+  gr_consume_type_t d_consume_type;
+  int d_min_consume;
+  int d_max_consume;
+  gr_produce_type_t d_produce_type;
+  int d_min_produce;
+  int d_max_produce;
+  gr_test (const std::string &name,int min_inputs, int max_inputs, unsigned int sizeof_input_item,
+                                   int min_outputs, int max_outputs, unsigned int sizeof_output_item,
+                                   unsigned int history,unsigned int output_multiple,double relative_rate,
+                                   bool fixed_rate,gr_consume_type_t cons_type, gr_produce_type_t prod_type);
+
+
+
+  friend gr_test_sptr gr_make_test (const std::string &name,int min_inputs, int max_inputs, unsigned int sizeof_input_item,
+                                   int min_outputs, int max_outputs, unsigned int sizeof_output_item,
+                                   unsigned int history,unsigned int output_multiple,double relative_rate,
+                                   bool fixed_rate,gr_consume_type_t cons_type, gr_produce_type_t prod_type);
+};
+
+
+
+#endif /* INCLUDED_GR_TEST_H */
diff --git a/gnuradio-core/src/lib/general/gr_test.i b/gnuradio-core/src/lib/general/gr_test.i
new file mode 100644 (file)
index 0000000..e6f922c
--- /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 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.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,test);
+
+
+class gr_test;
+typedef boost::shared_ptr<gr_test> gr_test_sptr;
+
+
+// public constructor
+gr_test_sptr gr_make_test (const std::string &name=std::string("gr_test"),
+        int min_inputs=1, int max_inputs=1, unsigned int sizeof_input_item=1,
+        int min_outputs=1, int max_outputs=1, unsigned int sizeof_output_item=1,
+        unsigned int history=1,unsigned int output_multiple=1,double relative_rate=1.0,
+        bool fixed_rate=true,gr_consume_type_t cons_type=CONSUME_NOUTPUT_ITEMS, gr_produce_type_t prod_type=PRODUCE_NOUTPUT_ITEMS);
+
+
+class gr_test : public gr_block {
+
+ public:
+  
+  ~gr_test ();
+  void forecast (int noutput_items,
+                        gr_vector_int &ninput_items_required);
+  void set_check_topology (bool check_topology);
+  bool check_topology (int ninputs, int noutputs);
+  int fixed_rate_ninput_to_noutput(int ninput);
+  int fixed_rate_noutput_to_ninput(int noutput);
+  void set_fixed_rate_public(bool fixed_rate);
+  void set_consume_type (gr_consume_type_t cons_type);
+  void set_consume_limit (unsigned int limit);
+  void set_produce_type (gr_produce_type_t prod_type);
+  void set_produce_limit (unsigned int limit);
+
+ protected:
+  gr_test (const std::string &name,int min_inputs, int max_inputs, unsigned int sizeof_input_item,
+                                   int min_outputs, int max_outputs, unsigned int sizeof_output_item,
+                                   unsigned int history,unsigned int output_multiple,double relative_rate,
+                                   bool fixed_rate,gr_consume_type_t cons_type, gr_produce_type_t prod_type);
+
+};
+
+
+
diff --git a/gnuradio-core/src/lib/general/gr_test_types.h b/gnuradio-core/src/lib/general/gr_test_types.h
new file mode 100644 (file)
index 0000000..92fe3f7
--- /dev/null
@@ -0,0 +1,46 @@
+/* -*- 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 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.
+ */
+#ifndef INCLUDED_GR_TEST_TYPES_H
+#define INCLUDED_GR_TEST_TYPES_H
+
+typedef enum {
+      CONSUME_NOUTPUT_ITEMS=0,
+      CONSUME_NOUTPUT_ITEMS_LIMIT_MAX=1,
+      CONSUME_NOUTPUT_ITEMS_LIMIT_MIN=2,
+      CONSUME_ALL_AVAILABLE=3,
+      CONSUME_ALL_AVAILABLE_LIMIT_MAX=4,
+      /*CONSUME_ALL_AVAILABLE_LIMIT_MIN=5,*/
+      CONSUME_ZERO=6,
+      CONSUME_ONE=7,
+      CONSUME_MINUS_ONE=8
+  } gr_consume_type_t;
+
+typedef enum {
+      PRODUCE_NOUTPUT_ITEMS=0,
+      PRODUCE_NOUTPUT_ITEMS_LIMIT_MAX=1,
+      /*PRODUCE_NOUTPUT_ITEMS_LIMIT_MIN=2,*/
+      PRODUCE_ZERO=6,
+      PRODUCE_ONE=7,
+      PRODUCE_MINUS_ONE=8
+  } gr_produce_type_t;
+
+#endif /* INCLUDED_GR_TEST_TYPES_H */
diff --git a/gnuradio-core/src/lib/general/gr_threshold_ff.cc b/gnuradio-core/src/lib/general/gr_threshold_ff.cc
new file mode 100644 (file)
index 0000000..4041f46
--- /dev/null
@@ -0,0 +1,67 @@
+/* -*- 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 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.
+ */
+
+// WARNING: this file is machine generated.  Edits will be over written
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_threshold_ff.h>
+#include <gr_io_signature.h>
+
+gr_threshold_ff_sptr
+gr_make_threshold_ff (float lo, float hi, float initial_state)
+{
+  return gr_threshold_ff_sptr (new gr_threshold_ff (lo, hi, initial_state));
+}
+
+gr_threshold_ff::gr_threshold_ff (float lo, float hi, float initial_state)
+  : gr_sync_block ("threshold_ff",
+                  gr_make_io_signature (1, 1, sizeof (float)),
+                  gr_make_io_signature (1, 1, sizeof (float))),
+    d_lo (lo), d_hi (hi), d_last_state (initial_state)
+{
+}
+
+int
+gr_threshold_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++) {
+    if (in[i] > d_hi) {
+      out[i] = 1.0;
+      d_last_state = 1.0;
+    } else if (in[i] < d_lo) {
+      out[i] = 0.0;
+      d_last_state = 0.0;
+    } else
+      out[i] = d_last_state;
+  }
+
+  return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_threshold_ff.h b/gnuradio-core/src/lib/general/gr_threshold_ff.h
new file mode 100644 (file)
index 0000000..30ca67f
--- /dev/null
@@ -0,0 +1,58 @@
+/* -*- 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 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.
+ */
+
+#ifndef INCLUDED_GR_THRESHOLD_FF_H
+#define INCLUDED_GR_THRESHOLD_FF_H
+
+#include <gr_sync_block.h>
+
+class gr_threshold_ff;
+typedef boost::shared_ptr<gr_threshold_ff> gr_threshold_ff_sptr;
+
+gr_threshold_ff_sptr gr_make_threshold_ff (float lo, float hi, float initial_state=0);
+
+/*!
+ * \brief 
+ * \ingroup block
+ */
+class gr_threshold_ff : public gr_sync_block
+{
+  friend gr_threshold_ff_sptr gr_make_threshold_ff (float lo, float hi, float initial_state);
+
+  float        d_lo,d_hi;              // the constant
+  float d_last_state;
+  gr_threshold_ff (float lo, float hi, float initial_state);
+
+ public:
+  float lo () const { return d_lo; }
+  void set_lo (float lo) { d_lo = lo; }
+  float hi () const { return d_hi; }
+  void set_hi (float hi) { d_hi = hi; }
+  float last_state () const { return d_last_state; }
+  void set_last_state (float last_state) { d_last_state = last_state; }
+
+  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_threshold_ff.i b/gnuradio-core/src/lib/general/gr_threshold_ff.i
new file mode 100644 (file)
index 0000000..2fcf1de
--- /dev/null
@@ -0,0 +1,39 @@
+/* -*- 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 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.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,threshold_ff);
+
+gr_threshold_ff_sptr gr_make_threshold_ff (float lo, float hi, float initial_state=0);
+
+class gr_threshold_ff : public gr_sync_block
+{
+ private:
+  gr_threshold_ff (float lo, float hi, float initial_state);
+
+ public:
+  float lo () const { return d_lo; }
+  void set_lo (float lo) { d_lo = lo; }
+  float hi () const { return d_hi; }
+  void set_hi (float hi) { d_hi = hi; }
+  float last_state () const { return d_last_state; }
+  void set_last_state (float last_state) { d_last_state = last_state; }
+};
diff --git a/gnuradio-core/src/lib/general/gr_throttle.cc b/gnuradio-core/src/lib/general/gr_throttle.cc
new file mode 100644 (file)
index 0000000..9fbf23e
--- /dev/null
@@ -0,0 +1,109 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_throttle.h>
+#include <gr_io_signature.h>
+#include <errno.h>
+#include <stdio.h>
+#include <math.h>
+#ifdef HAVE_TIME_H
+#include <time.h>
+#endif
+
+
+#ifdef HAVE_NANOSLEEP
+void
+gr_nanosleep(struct timespec *ts)
+{
+  struct timespec      *req = ts;
+  struct timespec      rem;
+  int r = nanosleep(req, &rem);
+  while (r < 0 && errno == EINTR){
+    req = &rem;
+    r = nanosleep(req, &rem);
+  }
+  if (r < 0)
+    perror ("gr_nanosleep");
+}
+#endif
+
+gr_throttle_sptr
+gr_make_throttle(size_t itemsize, double samples_per_sec)
+{
+  return gr_throttle_sptr(new gr_throttle(itemsize, samples_per_sec));
+}
+
+gr_throttle::gr_throttle(size_t itemsize, double samples_per_sec)
+  : gr_sync_block("throttle",
+                 gr_make_io_signature(1, 1, itemsize),
+                 gr_make_io_signature(1, 1, itemsize)),
+    d_itemsize(itemsize), d_samples_per_sec(samples_per_sec),
+    d_total_samples(0)
+{
+#ifdef HAVE_GETTIMEOFDAY
+  gettimeofday(&d_start, 0);
+#endif  
+}
+
+gr_throttle::~gr_throttle()
+{
+}
+
+int
+gr_throttle::work (int noutput_items,
+                  gr_vector_const_void_star &input_items,
+                  gr_vector_void_star &output_items)
+{
+  const char *in = (const char *) input_items[0];
+  char *out = (char *) output_items[0];
+
+#if defined(HAVE_GETTIMEOFDAY) && defined(HAVE_NANOSLEEP)
+  //
+  // If our average sample rate exceeds our target sample rate,
+  // delay long enough to reduce to our target rate.
+  //
+  struct timeval now;
+  gettimeofday(&now, 0);
+  long t_usec = now.tv_usec - d_start.tv_usec;
+  long t_sec  = now.tv_sec - d_start.tv_sec;
+  double t = (double)t_sec + (double)t_usec * 1e-6;
+  if (t < 1e-6)                // avoid unlikely divide by zero
+    t = 1e-6;
+
+  double actual_samples_per_sec = d_total_samples / t;
+  if (actual_samples_per_sec > d_samples_per_sec){     // need to delay
+    double delay = d_total_samples / d_samples_per_sec - t;
+    struct timespec ts;
+    ts.tv_sec = (time_t)floor(delay);
+    ts.tv_nsec = (long)((delay - floor(delay)) * 1e9);
+    gr_nanosleep(&ts);
+  }
+#endif  
+
+  memcpy(out, in, noutput_items * d_itemsize);
+  d_total_samples += noutput_items;
+  return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_throttle.h b/gnuradio-core/src/lib/general/gr_throttle.h
new file mode 100644 (file)
index 0000000..c926a40
--- /dev/null
@@ -0,0 +1,63 @@
+/* -*- 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 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.
+ */
+#ifndef INCLUDED_GR_THROTTLE_H
+#define INCLUDED_GR_THROTTLE_H
+
+#include <gr_sync_block.h>
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#endif
+
+class gr_throttle;
+typedef boost::shared_ptr<gr_throttle> gr_throttle_sptr;
+
+
+gr_throttle_sptr gr_make_throttle(size_t itemsize, double samples_per_sec);
+
+/*!
+ * \brief throttle flow of samples such that the average rate does not exceed samples_per_sec.
+ * \ingroup block
+ *
+ * input: one stream of itemsize; output: one stream of itemsize
+ */
+class gr_throttle : public gr_sync_block
+{
+  friend gr_throttle_sptr gr_make_throttle(size_t itemsize, double samples_per_sec);
+  size_t               d_itemsize;
+  double               d_samples_per_sec;
+  double               d_total_samples;
+#ifdef HAVE_SYS_TIME_H
+  struct timeval       d_start;
+#endif
+
+  gr_throttle(size_t itemsize, double samples_per_sec);
+
+public:
+  ~gr_throttle();
+
+  int work (int noutput_items,
+           gr_vector_const_void_star &input_items,
+           gr_vector_void_star &output_items);
+};
+
+#endif /* INCLUDED_GR_THROTTLE_H */
diff --git a/gnuradio-core/src/lib/general/gr_throttle.i b/gnuradio-core/src/lib/general/gr_throttle.i
new file mode 100644 (file)
index 0000000..eb237b3
--- /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 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.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,throttle);
+
+gr_throttle_sptr gr_make_throttle (size_t itemsize, double samples_per_sec);
+
+class gr_throttle : public gr_sync_block
+{
+  gr_throttle (size_t itemsize, double samples_per_sec);
+};
diff --git a/gnuradio-core/src/lib/general/gr_uchar_to_float.cc b/gnuradio-core/src/lib/general/gr_uchar_to_float.cc
new file mode 100644 (file)
index 0000000..e162d77
--- /dev/null
@@ -0,0 +1,55 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_uchar_to_float.h>
+#include <gr_io_signature.h>
+#include <gri_uchar_to_float.h>
+
+gr_uchar_to_float_sptr
+gr_make_uchar_to_float ()
+{
+  return gr_uchar_to_float_sptr (new gr_uchar_to_float ());
+}
+
+gr_uchar_to_float::gr_uchar_to_float ()
+  : gr_sync_block ("gr_uchar_to_float",
+                  gr_make_io_signature (1, 1, sizeof (unsigned char)),
+                  gr_make_io_signature (1, 1, sizeof (float)))
+{
+}
+
+int
+gr_uchar_to_float::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];
+  float *out = (float *) output_items[0];
+
+  gri_uchar_to_float (in, out, noutput_items);
+  
+  return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_uchar_to_float.h b/gnuradio-core/src/lib/general/gr_uchar_to_float.h
new file mode 100644 (file)
index 0000000..7de5572
--- /dev/null
@@ -0,0 +1,51 @@
+/* -*- 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 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.
+ */
+
+#ifndef INCLUDED_GR_UCHAR_TO_FLOAT_H
+#define INCLUDED_GR_UCHAR_TO_FLOAT_H
+
+#include <gr_sync_block.h>
+
+class gr_uchar_to_float;
+typedef boost::shared_ptr<gr_uchar_to_float> gr_uchar_to_float_sptr;
+
+gr_uchar_to_float_sptr
+gr_make_uchar_to_float ();
+
+/*!
+ * \brief Convert stream of unsigned chars to a stream of float
+ * \ingroup converter
+ */
+
+class gr_uchar_to_float : public gr_sync_block
+{
+  friend gr_uchar_to_float_sptr gr_make_uchar_to_float ();
+  gr_uchar_to_float ();
+
+ public:
+  virtual int work (int noutput_items,
+                   gr_vector_const_void_star &input_items,
+                   gr_vector_void_star &output_items);
+};
+
+
+#endif /* INCLUDED_GR_UCHAR_TO_FLOAT_H */
diff --git a/gnuradio-core/src/lib/general/gr_uchar_to_float.i b/gnuradio-core/src/lib/general/gr_uchar_to_float.i
new file mode 100644 (file)
index 0000000..4b7e8bc
--- /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 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.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,uchar_to_float)
+
+gr_uchar_to_float_sptr gr_make_uchar_to_float ();
+
+class gr_uchar_to_float : public gr_sync_block
+{
+  gr_uchar_to_float ();
+};
diff --git a/gnuradio-core/src/lib/general/gr_unpack_k_bits_bb.cc b/gnuradio-core/src/lib/general/gr_unpack_k_bits_bb.cc
new file mode 100644 (file)
index 0000000..399bc11
--- /dev/null
@@ -0,0 +1,70 @@
+/* -*- 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 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.
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_unpack_k_bits_bb.h>
+#include <gr_io_signature.h>
+#include <stdexcept>
+#include <iostream>
+
+gr_unpack_k_bits_bb_sptr gr_make_unpack_k_bits_bb (unsigned k)
+{
+  return gr_unpack_k_bits_bb_sptr (new gr_unpack_k_bits_bb (k));
+}
+
+
+gr_unpack_k_bits_bb::gr_unpack_k_bits_bb (unsigned k)
+  : gr_sync_interpolator ("unpack_k_bits_bb",
+                         gr_make_io_signature (1, 1, sizeof (unsigned char)),
+                         gr_make_io_signature (1, 1, sizeof (unsigned char)),
+                         k),
+    d_k (k)
+{
+  if (d_k == 0)
+    throw std::out_of_range ("interpolation must be > 0");
+}
+
+gr_unpack_k_bits_bb::~gr_unpack_k_bits_bb ()
+{
+}
+
+int
+gr_unpack_k_bits_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];
+
+  int n = 0;
+  for (unsigned int i = 0; i < noutput_items/d_k; i++){
+    unsigned int t = in[i];
+    for (int j = d_k - 1; j >= 0; j--)
+      out[n++] = (t >> j) & 0x01;
+  }
+
+  assert(n == noutput_items);
+  return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_unpack_k_bits_bb.h b/gnuradio-core/src/lib/general/gr_unpack_k_bits_bb.h
new file mode 100644 (file)
index 0000000..38a8bc1
--- /dev/null
@@ -0,0 +1,54 @@
+/* -*- 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 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.
+ */
+
+#ifndef INCLUDED_GR_UNPACK_K_BITS_BB_H
+#define        INCLUDED_GR_UNPACK_K_BITS_BB_H
+
+#include <gr_sync_interpolator.h>
+
+class gr_unpack_k_bits_bb;
+typedef boost::shared_ptr<gr_unpack_k_bits_bb> gr_unpack_k_bits_bb_sptr;
+gr_unpack_k_bits_bb_sptr gr_make_unpack_k_bits_bb (unsigned k);
+
+class gr_unpack_k_bits_bb;
+
+/*!
+ * \brief Converts a byte with k relevent bits to k output bytes with 1 bit in the LSB
+ */
+class gr_unpack_k_bits_bb : public gr_sync_interpolator
+{
+ private:
+  friend gr_unpack_k_bits_bb_sptr gr_make_unpack_k_bits_bb (unsigned k);
+
+  gr_unpack_k_bits_bb (unsigned k);
+
+  unsigned d_k;    // number of relevent bits to unpack into k output bytes
+  
+ public:
+  ~gr_unpack_k_bits_bb ();
+
+  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_unpack_k_bits_bb.i b/gnuradio-core/src/lib/general/gr_unpack_k_bits_bb.i
new file mode 100644 (file)
index 0000000..eb6bda9
--- /dev/null
@@ -0,0 +1,34 @@
+/* -*- 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 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.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,unpack_k_bits_bb)
+
+gr_unpack_k_bits_bb_sptr gr_make_unpack_k_bits_bb (int k);
+
+class gr_unpack_k_bits_bb : public gr_sync_interpolator
+{
+ private:
+  gr_unpack_k_bits_bb (int k);
+
+ public:
+  ~gr_unpack_k_bits_bb ();
+};
diff --git a/gnuradio-core/src/lib/general/gr_unpacked_to_packed_XX.cc.t b/gnuradio-core/src/lib/general/gr_unpacked_to_packed_XX.cc.t
new file mode 100644 (file)
index 0000000..7d5d72e
--- /dev/null
@@ -0,0 +1,125 @@
+/* -*- 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 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.
+ */
+
+// @WARNING@
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <@NAME@.h>
+#include <gr_io_signature.h>
+#include <assert.h>
+
+static const unsigned int BITS_PER_TYPE = sizeof(@O_TYPE@) * 8;
+
+
+@SPTR_NAME@ 
+gr_make_@BASE_NAME@ (unsigned int bits_per_chunk, gr_endianness_t endianness)
+{
+  return @SPTR_NAME@ 
+    (new @NAME@ (bits_per_chunk,endianness));
+}
+
+@NAME@::@NAME@ (unsigned int bits_per_chunk, 
+                                                   gr_endianness_t endianness)
+  : gr_block ("@BASE_NAME@",
+             gr_make_io_signature (1, -1, sizeof (@I_TYPE@)),
+             gr_make_io_signature (1, -1, sizeof (@O_TYPE@))),
+    d_bits_per_chunk(bits_per_chunk),d_endianness(endianness),d_index(0)
+{
+  assert (bits_per_chunk <= BITS_PER_TYPE);
+  assert (bits_per_chunk > 0);
+
+  set_relative_rate (bits_per_chunk/(1.0 * BITS_PER_TYPE));
+}
+
+void
+@NAME@::forecast(int noutput_items, gr_vector_int &ninput_items_required)
+{
+  int input_required = (int) ceil( (d_index+noutput_items * 1.0 * BITS_PER_TYPE)/d_bits_per_chunk);
+  unsigned ninputs = ninput_items_required.size();
+  for (unsigned int i = 0; i < ninputs; i++) {
+    ninput_items_required[i] = input_required;
+  }
+}
+
+unsigned int
+get_bit_be1 (const @I_TYPE@ *in_vector,unsigned int bit_addr, unsigned int bits_per_chunk) {
+  unsigned int byte_addr = (int)bit_addr/bits_per_chunk;
+  @I_TYPE@ x = in_vector[byte_addr];
+  unsigned int residue = bit_addr - byte_addr * bits_per_chunk;
+  //printf("Bit addr %d  byte addr %d  residue %d  val  %d\n",bit_addr,byte_addr,residue,(x>>(bits_per_chunk-1-residue))&1);
+  return (x >> (bits_per_chunk-1-residue))&1;
+}
+
+int
+@NAME@::general_work (int noutput_items,
+                                       gr_vector_int &ninput_items,
+                                       gr_vector_const_void_star &input_items,
+                                       gr_vector_void_star &output_items)
+{
+  assert (input_items.size() == output_items.size());
+  int nstreams = input_items.size();
+
+  for (int m=0; m< nstreams; m++) {
+    const @I_TYPE@ *in = (@I_TYPE@ *) input_items[m];
+    @O_TYPE@ *out = (@O_TYPE@ *) output_items[m];
+
+    // per stream processing
+
+    //assert((ninput_items[m]-d_index)*d_bits_per_chunk >= noutput_items*BITS_PER_TYPE);
+  
+    switch(d_endianness){
+
+    case GR_MSB_FIRST:
+      for(int i=0;i<noutput_items;i++) {
+       @O_TYPE@ tmp=0;
+       for(unsigned int j=0; j<BITS_PER_TYPE; j++) {
+         tmp = (tmp<<1) | get_bit_be1(in,d_index,d_bits_per_chunk);
+         d_index++;
+       }
+       out[i] = tmp;
+      }
+      break;
+
+    case GR_LSB_FIRST:
+      for(int i=0;i<noutput_items;i++) {
+       unsigned long tmp=0;
+       for(unsigned int j=0; j<BITS_PER_TYPE; j++) {
+         tmp = (tmp>>1)| (get_bit_be1(in,d_index,d_bits_per_chunk)<<(BITS_PER_TYPE-1));
+         d_index++;
+       }
+       out[i] = tmp;
+      }
+      break;
+      
+    default:
+      assert(0);
+    }
+  }
+
+  consume_each ((int)(d_index/d_bits_per_chunk));
+  d_index = d_index%d_bits_per_chunk;
+
+  return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_unpacked_to_packed_XX.h.t b/gnuradio-core/src/lib/general/gr_unpacked_to_packed_XX.h.t
new file mode 100644 (file)
index 0000000..8d8c14d
--- /dev/null
@@ -0,0 +1,81 @@
+/* -*- 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 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.
+ */
+
+// @WARNING@
+
+#ifndef @GUARD_NAME@
+#define @GUARD_NAME@
+
+#include <gr_block.h>
+#include <gr_endianness.h>
+
+class @NAME@;
+typedef boost::shared_ptr<@NAME@> @NAME@_sptr;
+
+@SPTR_NAME@ 
+gr_make_@BASE_NAME@ (unsigned int bits_per_chunk, gr_endianness_t endianness);
+
+/*!
+ * \brief Convert a stream of unpacked bytes or shorts into a stream of packed bytes or shorts.
+ * \ingroup block
+ *
+ * input: stream of @I_TYPE@; output: stream of @O_TYPE@
+ *
+ * This is the inverse of gr_packed_to_unpacked_XX.
+ *
+ * The low \p bits_per_chunk bits are extracted from each input byte or short.
+ * These bits are then packed densely into the output bytes or shorts, such that
+ * all 8 or 16 bits of the output bytes or shorts are filled with valid input bits.
+ * The right thing is done if bits_per_chunk is not a power of two.
+ *
+ * The combination of gr_packed_to_unpacked_XX followed by
+ * gr_chunks_to_symbols_Xf or gr_chunks_to_symbols_Xc handles the
+ * general case of mapping from a stream of bytes or shorts into arbitrary float
+ * or complex symbols.
+ *
+ * \sa gr_packed_to_unpacked_bb, gr_unpacked_to_packed_bb,
+ * \sa gr_packed_to_unpacked_ss, gr_unpacked_to_packed_ss,
+ * \sa gr_chunks_to_symbols_bf, gr_chunks_to_symbols_bc.
+ * \sa gr_chunks_to_symbols_sf, gr_chunks_to_symbols_sc.
+ */
+class @NAME@ : public gr_block
+{
+  friend @SPTR_NAME@
+  gr_make_@BASE_NAME@ (unsigned int bits_per_chunk, gr_endianness_t endianness);
+
+  @NAME@ (unsigned int bits_per_chunk, gr_endianness_t endianness);
+
+  unsigned int    d_bits_per_chunk;
+  gr_endianness_t d_endianness;
+  unsigned int    d_index;
+
+ 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);
+
+  bool check_topology(int ninputs, int noutputs) { return ninputs == noutputs; }
+};
+
+#endif
diff --git a/gnuradio-core/src/lib/general/gr_unpacked_to_packed_XX.i.t b/gnuradio-core/src/lib/general/gr_unpacked_to_packed_XX.i.t
new file mode 100644 (file)
index 0000000..7fdcb5d
--- /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 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.
+ */
+
+// @WARNING@
+
+GR_SWIG_BLOCK_MAGIC(gr,@BASE_NAME@);
+
+@SPTR_NAME@
+gr_make_@BASE_NAME@ (unsigned int bits_per_chunk, gr_endianness_t endianness);
+
+class @NAME@ : public gr_block
+{
+  @NAME@ (unsigned int bits_per_chunk, gr_endianness_t endianness);
+};
diff --git a/gnuradio-core/src/lib/general/gr_vco.h b/gnuradio-core/src/lib/general/gr_vco.h
new file mode 100644 (file)
index 0000000..3c35bdf
--- /dev/null
@@ -0,0 +1,93 @@
+/* -*- 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 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.
+ */
+#ifndef _GR_VCO_H_
+#define _GR_VCO_H_
+
+
+#include <vector>
+#include <gr_sincos.h>
+#include <cmath>
+#include <gr_complex.h>
+
+/*!
+ * \brief base class template for Voltage Controlled Oscillator (VCO)
+ */
+
+//FIXME  Eventually generalize this to fixed point
+
+template<class o_type, class i_type> 
+class gr_vco {
+public:
+  gr_vco () : d_phase (0) {}
+
+  virtual ~gr_vco () {}
+
+  // radians
+  void set_phase (double angle) {
+    d_phase = angle;
+  }
+
+  void adjust_phase (double delta_phase) {
+    d_phase += delta_phase;
+    if (fabs (d_phase) > M_PI){
+      
+      while (d_phase > M_PI)
+       d_phase -= 2*M_PI;
+
+      while (d_phase < -M_PI)
+       d_phase += 2*M_PI;
+    }
+  }
+
+  double get_phase () const { return d_phase; }
+
+  // compute sin and cos for current phase angle
+  void sincos (float *sinx, float *cosx) const;
+
+  // compute cos or sin for current phase angle
+  float cos () const { return std::cos (d_phase); }
+  float sin () const { return std::sin (d_phase); }
+
+  // compute a block at a time
+  void cos (float *output, const float *input, int noutput_items, double k, double ampl = 1.0);
+
+protected:
+  double d_phase;
+};
+
+template<class o_type, class i_type> 
+void
+gr_vco<o_type,i_type>::sincos (float *sinx, float *cosx) const
+{
+  gr_sincosf (d_phase, sinx, cosx);
+}
+
+template<class o_type, class i_type> 
+void
+gr_vco<o_type,i_type>::cos (float *output, const float *input, int noutput_items, double k, double ampl)
+{
+  for (int i = 0; i < noutput_items; i++){
+    output[i] = cos() * ampl;
+    adjust_phase(input[i] * k);
+  }
+}
+#endif /* _GR_VCO_H_ */
diff --git a/gnuradio-core/src/lib/general/gr_vco_f.cc b/gnuradio-core/src/lib/general/gr_vco_f.cc
new file mode 100644 (file)
index 0000000..7421e4e
--- /dev/null
@@ -0,0 +1,58 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_vco_f.h>
+#include <gr_io_signature.h>
+#include <math.h>
+
+gr_vco_f_sptr
+gr_make_vco_f(double sampling_rate, double sensitivity, double amplitude)
+{
+  return gr_vco_f_sptr(new gr_vco_f(sampling_rate, sensitivity, amplitude));
+}
+
+
+gr_vco_f::gr_vco_f(double sampling_rate, double sensitivity, double amplitude)
+  : gr_sync_block("vco_f",
+                 gr_make_io_signature(1, 1, sizeof(float)),
+                 gr_make_io_signature(1, 1, sizeof(float))),
+    d_sampling_rate(sampling_rate), d_sensitivity(sensitivity), d_amplitude(amplitude),
+    d_k(d_sensitivity/d_sampling_rate)
+{
+}
+
+int
+gr_vco_f::work (int noutput_items,
+               gr_vector_const_void_star &input_items,
+               gr_vector_void_star &output_items)
+{
+  const float *input = (const float *)input_items[0];
+  float *output = (float *)output_items[0];
+
+  d_vco.cos(output, input, noutput_items, d_k, d_amplitude);
+  
+  return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_vco_f.h b/gnuradio-core/src/lib/general/gr_vco_f.h
new file mode 100644 (file)
index 0000000..2872d38
--- /dev/null
@@ -0,0 +1,72 @@
+/* -*- 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 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.
+ */
+#ifndef INCLUDED_GR_VCO_F_H
+#define INCLUDED_GR_VCO_F_H
+
+#include <gr_sync_block.h>
+#include <gr_fxpt_vco.h>
+
+class gr_vco_f;
+typedef boost::shared_ptr<gr_vco_f> gr_vco_f_sptr;
+
+/*!
+ * \brief VCO - Voltage controlled oscillator
+ *
+ * \param sampling_rate                sampling rate (Hz)
+ * \param sensitivity          units are radians/sec/volt
+ * \param amplitude            output amplitude
+ */
+gr_vco_f_sptr gr_make_vco_f(double sampling_rate, double sensitivity, double amplitude);
+
+/*!
+ * \brief VCO - Voltage controlled oscillator
+ * \ingroup block
+ *
+ * input: float stream of control voltages; output: float oscillator output
+ */
+class gr_vco_f : public gr_sync_block
+{
+  friend gr_vco_f_sptr gr_make_vco_f(double sampling_rate, double sensitivity, double amplitude);
+
+  /*!
+   * \brief VCO - Voltage controlled oscillator
+   *
+   * \param sampling_rate      sampling rate (Hz)
+   * \param sensitivity                units are radians/sec/volt
+   * \param amplitude          output amplitude
+   */
+  gr_vco_f(double sampling_rate, double sensitivity, double amplitude);
+
+  double       d_sampling_rate;
+  double       d_sensitivity;
+  double       d_amplitude;
+  double       d_k;
+  gr_fxpt_vco  d_vco;
+
+public:
+
+  int work (int noutput_items,
+           gr_vector_const_void_star &input_items,
+           gr_vector_void_star &output_items);
+};
+
+#endif /* INCLUDED_GR_VCO_F_H */
diff --git a/gnuradio-core/src/lib/general/gr_vco_f.i b/gnuradio-core/src/lib/general/gr_vco_f.i
new file mode 100644 (file)
index 0000000..d344745
--- /dev/null
@@ -0,0 +1,38 @@
+/* -*- 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 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.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,vco_f);
+
+/*!
+ * \brief VCO - Voltage controlled oscillator
+ *
+ * \param sampling_rate                sampling rate (Hz)
+ * \param sensitivity          units are radians/sec/volt
+ * \param amplitude            output amplitude
+ */
+gr_vco_f_sptr gr_make_vco_f(double sampling_rate, double sensitivity, double amplitude);
+
+
+class gr_vco_f : public gr_sync_block {
+ private:
+  gr_vco_f(double sampling_rate, double sensitivity, double amplitude);
+};
diff --git a/gnuradio-core/src/lib/general/gr_vector_sink_X.cc.t b/gnuradio-core/src/lib/general/gr_vector_sink_X.cc.t
new file mode 100644 (file)
index 0000000..5e99a92
--- /dev/null
@@ -0,0 +1,63 @@
+/* -*- 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 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.
+ */
+
+// @WARNING@
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <@NAME@.h>
+#include <algorithm>
+#include <gr_io_signature.h>
+
+
+@NAME@::@NAME@ ()
+  : gr_sync_block ("@BASE_NAME@",
+              gr_make_io_signature (1, 1, sizeof (@TYPE@)),
+              gr_make_io_signature (0, 0, 0))
+{
+}
+
+int
+@NAME@::work (int noutput_items,
+                   gr_vector_const_void_star &input_items,
+                   gr_vector_void_star &output_items)
+{
+  @TYPE@ *iptr = (@TYPE@ *) input_items[0];
+  for (int i = 0; i < noutput_items; i++)
+    d_data.push_back (iptr[i]);
+
+  return noutput_items;
+}
+
+
+@NAME@_sptr
+gr_make_@BASE_NAME@ ()
+{
+  return @NAME@_sptr (new @NAME@ ());
+}
+
+std::vector<@TYPE@>
+@NAME@::data () const
+{
+  return d_data;
+}
diff --git a/gnuradio-core/src/lib/general/gr_vector_sink_X.h.t b/gnuradio-core/src/lib/general/gr_vector_sink_X.h.t
new file mode 100644 (file)
index 0000000..e549f1f
--- /dev/null
@@ -0,0 +1,55 @@
+/* -*- 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 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.
+ */
+
+// @WARNING@
+
+#ifndef @GUARD_NAME@
+#define @GUARD_NAME@
+
+#include <gr_sync_block.h>
+
+class @NAME@;
+typedef boost::shared_ptr<@NAME@> @NAME@_sptr;
+
+@NAME@_sptr
+gr_make_@BASE_NAME@ ();
+
+
+/*!
+ * \brief @TYPE@ sink that writes to a vector
+ * \ingroup sink
+ */
+
+class @NAME@ : public gr_sync_block {
+  friend @NAME@_sptr gr_make_@BASE_NAME@ ();
+  std::vector<@TYPE@>  d_data;
+  @NAME@ ();
+
+ public:
+  virtual int work (int noutput_items,
+                   gr_vector_const_void_star &input_items,
+                   gr_vector_void_star &output_items);
+
+  std::vector<@TYPE@> data () const;
+};
+
+#endif
diff --git a/gnuradio-core/src/lib/general/gr_vector_sink_X.i.t b/gnuradio-core/src/lib/general/gr_vector_sink_X.i.t
new file mode 100644 (file)
index 0000000..d10636c
--- /dev/null
@@ -0,0 +1,37 @@
+/* -*- 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 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.
+ */
+
+// @WARNING@
+
+
+GR_SWIG_BLOCK_MAGIC(gr,@BASE_NAME@);
+
+@SPTR_NAME@ gr_make_@BASE_NAME@ ();
+
+class @NAME@ : public gr_sync_block {
+ private:
+  @NAME@ ();
+
+ public:
+  std::vector<@TYPE@> data () const;
+};
+
diff --git a/gnuradio-core/src/lib/general/gr_vector_source_X.cc.t b/gnuradio-core/src/lib/general/gr_vector_source_X.cc.t
new file mode 100644 (file)
index 0000000..4ec2dd8
--- /dev/null
@@ -0,0 +1,85 @@
+/* -*- 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 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.
+ */
+
+// @WARNING@
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <@NAME@.h>
+#include <algorithm>
+#include <gr_io_signature.h>
+
+
+@NAME@::@NAME@ (const std::vector<@TYPE@> &data, bool repeat)
+  : gr_sync_block ("@BASE_NAME@",
+              gr_make_io_signature (0, 0, 0),
+              gr_make_io_signature (1, 1, sizeof (@TYPE@))),
+    d_data (data),
+    d_repeat (repeat),
+    d_offset (0)
+{
+}
+
+int
+@NAME@::work (int noutput_items,
+                   gr_vector_const_void_star &input_items,
+                   gr_vector_void_star &output_items)
+{
+  @TYPE@ *optr = (@TYPE@ *) output_items[0];
+
+  if (d_repeat){
+    unsigned int size = d_data.size ();
+    unsigned int offset = d_offset;
+    
+    if (size == 0)
+      return -1;
+    
+    for (int i = 0; i < noutput_items; i++){
+      optr[i] = d_data[offset++];
+      if (offset >= size)
+       offset = 0;
+    }
+    d_offset = offset;
+    return noutput_items;
+  }
+
+  else {
+    if (d_offset >= d_data.size ())
+      return -1;                       // Done!
+
+    unsigned n = std::min ((unsigned) d_data.size () - d_offset,
+                          (unsigned) noutput_items);
+    for (unsigned i = 0; i < n; i++)
+      optr[i] = d_data[d_offset + i];
+
+    d_offset += n;
+    return n;
+  }
+}
+
+@NAME@_sptr
+gr_make_@BASE_NAME@ (const std::vector<@TYPE@> &data, bool repeat)
+{
+  return @NAME@_sptr (new @NAME@ (data, repeat));
+}
+
diff --git a/gnuradio-core/src/lib/general/gr_vector_source_X.h.t b/gnuradio-core/src/lib/general/gr_vector_source_X.h.t
new file mode 100644 (file)
index 0000000..631ab86
--- /dev/null
@@ -0,0 +1,57 @@
+/* -*- 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 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.
+ */
+
+// @WARNING@
+
+#ifndef @GUARD_NAME@
+#define @GUARD_NAME@
+
+#include <gr_sync_block.h>
+
+class @NAME@;
+typedef boost::shared_ptr<@NAME@> @NAME@_sptr;
+
+/*!
+ * \brief source of @TYPE@'s that gets its data from a vector
+ * \ingroup source
+ */
+
+class @NAME@ : public gr_sync_block {
+  friend @NAME@_sptr 
+  gr_make_@BASE_NAME@ (const std::vector<@TYPE@> &data, bool repeat = false);
+
+  std::vector<@TYPE@>  d_data;
+  bool                 d_repeat;
+  unsigned int         d_offset;
+
+  @NAME@ (const std::vector<@TYPE@> &data, bool repeat);
+
+ public:
+  virtual int work (int noutput_items,
+                   gr_vector_const_void_star &input_items,
+                   gr_vector_void_star &output_items);
+};
+
+@NAME@_sptr
+gr_make_@BASE_NAME@ (const std::vector<@TYPE@> &data, bool repeat);
+
+#endif
diff --git a/gnuradio-core/src/lib/general/gr_vector_source_X.i.t b/gnuradio-core/src/lib/general/gr_vector_source_X.i.t
new file mode 100644 (file)
index 0000000..f3b98c6
--- /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 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.
+ */
+
+// @WARNING@
+
+GR_SWIG_BLOCK_MAGIC(gr,@BASE_NAME@);
+
+@NAME@_sptr
+gr_make_@BASE_NAME@ (const std::vector<@TYPE@> &data, bool repeat = false);
+
+class @NAME@ : public gr_sync_block {
+ private:
+  @NAME@ (const std::vector<@TYPE@> &data);
+};
diff --git a/gnuradio-core/src/lib/general/gr_vector_to_stream.cc b/gnuradio-core/src/lib/general/gr_vector_to_stream.cc
new file mode 100644 (file)
index 0000000..130f961
--- /dev/null
@@ -0,0 +1,57 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_vector_to_stream.h>
+#include <gr_io_signature.h>
+
+gr_vector_to_stream_sptr
+gr_make_vector_to_stream (size_t item_size, size_t nitems_per_block)
+{
+  return gr_vector_to_stream_sptr (new gr_vector_to_stream (item_size, nitems_per_block));
+}
+
+gr_vector_to_stream::gr_vector_to_stream (size_t item_size, size_t nitems_per_block)
+  : gr_sync_interpolator ("vector_to_stream",
+                         gr_make_io_signature (1, 1, item_size * nitems_per_block),
+                         gr_make_io_signature (1, 1, item_size),
+                         nitems_per_block)
+{
+}
+
+int
+gr_vector_to_stream::work (int noutput_items,
+                            gr_vector_const_void_star &input_items,
+                            gr_vector_void_star &output_items)
+{
+  size_t block_size = output_signature()->sizeof_stream_item (0);
+
+  const char *in = (const char *) input_items[0];
+  char *out = (char *) output_items[0];
+
+  memcpy (out, in, noutput_items * block_size);
+
+  return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_vector_to_stream.h b/gnuradio-core/src/lib/general/gr_vector_to_stream.h
new file mode 100644 (file)
index 0000000..5efff73
--- /dev/null
@@ -0,0 +1,53 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2005,2006 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 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.
+ */
+
+#ifndef INCLUDED_GR_VECTOR_TO_STREAM_H
+#define INCLUDED_GR_VECTOR_TO_STREAM_H
+
+#include <gr_sync_interpolator.h>
+
+class gr_vector_to_stream;
+typedef boost::shared_ptr<gr_vector_to_stream> gr_vector_to_stream_sptr;
+
+gr_vector_to_stream_sptr 
+gr_make_vector_to_stream (size_t item_size, size_t nitems_per_block);
+
+
+/*!
+ * \brief convert a stream of blocks of nitems_per_block items into a stream of items
+ * \ingroup block
+ */
+class gr_vector_to_stream : public gr_sync_interpolator
+{
+  friend gr_vector_to_stream_sptr
+    gr_make_vector_to_stream (size_t item_size, size_t nitems_per_block);
+
+ protected:
+  gr_vector_to_stream (size_t item_size, size_t nitems_per_block);
+
+ public:
+  int work (int noutput_items,
+           gr_vector_const_void_star &input_items,
+           gr_vector_void_star &output_items);
+};
+
+#endif /* INCLUDED_GR_VECTOR_TO_STREAM_H */
diff --git a/gnuradio-core/src/lib/general/gr_vector_to_stream.i b/gnuradio-core/src/lib/general/gr_vector_to_stream.i
new file mode 100644 (file)
index 0000000..66ae173
--- /dev/null
@@ -0,0 +1,34 @@
+/* -*- 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 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.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,vector_to_stream)
+
+gr_vector_to_stream_sptr 
+gr_make_vector_to_stream (size_t itemsize, size_t nitems_per_block);
+
+class gr_vector_to_stream : public gr_sync_decimator
+{
+ protected:
+  gr_vector_to_stream (size_t itemsize, size_t nitems_per_block);
+
+ public:
+};
diff --git a/gnuradio-core/src/lib/general/gr_vector_to_streams.cc b/gnuradio-core/src/lib/general/gr_vector_to_streams.cc
new file mode 100644 (file)
index 0000000..4a3f110
--- /dev/null
@@ -0,0 +1,63 @@
+/* -*- c++ -*- */
+/*
+ * 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_vector_to_streams.h>
+#include <gr_io_signature.h>
+
+gr_vector_to_streams_sptr
+gr_make_vector_to_streams (size_t item_size, size_t nstreams)
+{
+  return gr_vector_to_streams_sptr (new gr_vector_to_streams (item_size, nstreams));
+}
+
+gr_vector_to_streams::gr_vector_to_streams (size_t item_size, size_t nstreams)
+  : gr_sync_block ("vector_to_streams",
+                  gr_make_io_signature (1, 1, nstreams * item_size),
+                  gr_make_io_signature (nstreams, nstreams, item_size))
+{
+}
+
+int
+gr_vector_to_streams::work (int noutput_items,
+                           gr_vector_const_void_star &input_items,
+                           gr_vector_void_star &output_items)
+{
+  size_t item_size = output_signature()->sizeof_stream_item(0);
+  int nstreams = output_items.size();
+
+  const char *in = (const char *) input_items[0];
+  char **outv = (char **) &output_items[0];
+
+  for (int i = 0; i < noutput_items; i++){
+    for (int j = 0; j < nstreams; j++){
+      memcpy(outv[j], in, item_size);
+      outv[j] += item_size;
+      in += item_size;
+    }
+  }
+
+  return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_vector_to_streams.h b/gnuradio-core/src/lib/general/gr_vector_to_streams.h
new file mode 100644 (file)
index 0000000..ae13fae
--- /dev/null
@@ -0,0 +1,53 @@
+/* -*- c++ -*- */
+/*
+ * 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 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.
+ */
+
+#ifndef INCLUDED_GR_VECTOR_TO_STREAMS_H
+#define INCLUDED_GR_VECTOR_TO_STREAMS_H
+
+#include <gr_sync_interpolator.h>
+
+class gr_vector_to_streams;
+typedef boost::shared_ptr<gr_vector_to_streams> gr_vector_to_streams_sptr;
+
+gr_vector_to_streams_sptr 
+gr_make_vector_to_streams (size_t item_size, size_t nstreams);
+
+
+/*!
+ * \brief Convert 1 stream of vectors of length N to N streams of items
+ * \ingroup block
+ */
+class gr_vector_to_streams : public gr_sync_block
+{
+  friend gr_vector_to_streams_sptr
+    gr_make_vector_to_streams (size_t item_size, size_t nstreams);
+
+ protected:
+  gr_vector_to_streams (size_t item_size, size_t nstreams);
+
+ public:
+  int work (int noutput_items,
+           gr_vector_const_void_star &input_items,
+           gr_vector_void_star &output_items);
+};
+
+#endif /* INCLUDED_GR_VECTOR_TO_STREAMS_H */
diff --git a/gnuradio-core/src/lib/general/gr_vector_to_streams.i b/gnuradio-core/src/lib/general/gr_vector_to_streams.i
new file mode 100644 (file)
index 0000000..7444d0d
--- /dev/null
@@ -0,0 +1,34 @@
+/* -*- c++ -*- */
+/*
+ * 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 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.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,vector_to_streams)
+
+gr_vector_to_streams_sptr 
+gr_make_vector_to_streams (size_t itemsize, size_t nstreams);
+
+class gr_vector_to_streams : public gr_sync_block
+{
+ protected:
+  gr_vector_to_streams (size_t itemsize, size_t nstreams);
+
+ public:
+};
diff --git a/gnuradio-core/src/lib/general/gri_add_const_ss.h b/gnuradio-core/src/lib/general/gri_add_const_ss.h
new file mode 100644 (file)
index 0000000..49fddb6
--- /dev/null
@@ -0,0 +1,36 @@
+/* -*- 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 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.
+ */
+
+#ifndef INCLUDED_GRI_ADD_CONST_SS_H
+#define INCLUDED_GRI_ADD_CONST_SS_H
+
+/*!
+ * \brief Low-level, high-speed add_const_ss primitive
+ *
+ * copy src to dst adding konst
+ */
+
+void
+gri_add_const_ss (short *dst, const short *src, int nshorts, short konst);
+
+
+#endif /* _INCLUDED_GRI_ADD_CONST_SS_H_ */
diff --git a/gnuradio-core/src/lib/general/gri_add_const_ss_generic.cc b/gnuradio-core/src/lib/general/gri_add_const_ss_generic.cc
new file mode 100644 (file)
index 0000000..f94db30
--- /dev/null
@@ -0,0 +1,49 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gri_add_const_ss.h>
+
+void
+gri_add_const_ss (short *dst, const short *src, int nshorts, short konst)
+{
+  static const int STRIDE = 8;
+
+  int i;
+
+  for (i = 0; i < nshorts - (STRIDE - 1); i += STRIDE){
+    dst[i + 0] = src[i + 0] + konst;
+    dst[i + 1] = src[i + 1] + konst;
+    dst[i + 2] = src[i + 2] + konst;
+    dst[i + 3] = src[i + 3] + konst;
+    dst[i + 4] = src[i + 4] + konst;
+    dst[i + 5] = src[i + 5] + konst;
+    dst[i + 6] = src[i + 6] + konst;
+    dst[i + 7] = src[i + 7] + konst;
+  }
+
+  for (; i < nshorts; i++)
+    dst[i] = src[i] + konst;
+}
diff --git a/gnuradio-core/src/lib/general/gri_agc.h b/gnuradio-core/src/lib/general/gri_agc.h
new file mode 100644 (file)
index 0000000..eaaed8c
--- /dev/null
@@ -0,0 +1,70 @@
+/* -*- 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 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.
+ */
+
+#ifndef _GRI_AGC_H_
+#define _GRI_AGC_H_
+
+#include <math.h>
+
+/*!
+ * \brief high performance Automatic Gain Control class
+ *
+ * Power is approximated by absolute value
+ */
+
+class gri_agc {
+
+ public:
+  gri_agc (float rate = 1e-4, float reference = 1.0, float gain = 1.0, float max_gain = 0.0)
+    : _rate(rate), _reference(reference), _gain(gain), _max_gain(max_gain) {};
+
+  float rate () const      { return _rate; }
+  float reference () const { return _reference; }
+  float gain () const     { return _gain;  }
+  float max_gain () const  { return _max_gain; }
+  
+  void set_rate (float rate) { _rate = rate; }
+  void set_reference (float reference) { _reference = reference; }
+  void set_gain (float gain) { _gain = gain; }
+  void set_max_gain (float max_gain) { _max_gain = max_gain; }
+  
+  float scale (float input){
+    float output = input * _gain;
+    _gain += (_reference - fabsf (output)) * _rate;
+    if (_max_gain > 0.0 && _gain > _max_gain)
+      _gain = _max_gain;
+    return output;
+  }
+
+  void scaleN (float output[], const float input[], unsigned n){
+    for (unsigned i = 0; i < n; i++)
+      output[i] = scale (input[i]);
+  }
+  
+ protected:
+  float _rate;                 // adjustment rate
+  float        _reference;             // reference value
+  float        _gain;                  // current gain
+  float _max_gain;             // maximum gain
+};
+
+#endif /* _GRI_AGC_H_ */
diff --git a/gnuradio-core/src/lib/general/gri_agc.i b/gnuradio-core/src/lib/general/gri_agc.i
new file mode 100644 (file)
index 0000000..0bdbd40
--- /dev/null
@@ -0,0 +1,36 @@
+/* -*- c++ -*- */
+/*
+ * 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 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.
+ */
+
+#include <math.h>
+
+/*!
+ * \brief high performance Automatic Gain Control class
+ *
+ * Power is approximated by absolute value
+ */
+
+
+class gri_agc {
+
+ public:
+  gri_agc (float rate = 1e-4, float reference = 1.0, float gain = 1.0, float max_gain = 0.0);
+  };
diff --git a/gnuradio-core/src/lib/general/gri_agc_cc.h b/gnuradio-core/src/lib/general/gri_agc_cc.h
new file mode 100644 (file)
index 0000000..5cdd4e4
--- /dev/null
@@ -0,0 +1,71 @@
+/* -*- 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 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.
+ */
+
+#ifndef _GRI_AGC_CC_H_
+#define _GRI_AGC_CC_H_
+
+#include <math.h>
+
+/*!
+ * \brief high performance Automatic Gain Control class
+ *
+ * For Power the absolute value of the complex number is used.
+ */
+
+class gri_agc_cc {
+
+ public:
+  gri_agc_cc (float rate = 1e-4, float reference = 1.0, float gain = 1.0, float max_gain = 0.0)
+    : _rate(rate), _reference(reference), _gain(gain), _max_gain(max_gain) {};
+
+  float rate () const      { return _rate; }
+  float reference () const { return _reference; }
+  float gain () const     { return _gain;  }
+  float max_gain() const   { return _max_gain; }
+
+  void set_rate (float rate) { _rate = rate; }
+  void set_reference (float reference) { _reference = reference; }
+  void set_gain (float gain) { _gain = gain; }
+  void set_max_gain(float max_gain) { _max_gain = max_gain; }
+  
+  gr_complex scale (gr_complex input){
+    gr_complex output = input * _gain;
+    _gain += (_reference - sqrt(output.real()*output.real()+output.imag()*output.imag())) * _rate; //use abs or cabs to get approximation by absolute value, 
+                                                     //note that abs is computationally more intensive then norm for a complex number
+    if (_max_gain > 0.0 && _gain > _max_gain)
+       _gain = _max_gain;                                                   
+    return output;
+  }
+
+  void scaleN (gr_complex output[], const gr_complex input[], unsigned n){
+    for (unsigned i = 0; i < n; i++)
+      output[i] = scale (input[i]);
+  }
+  
+ protected:
+  float _rate;                 // adjustment rate
+  float        _reference;             // reference value
+  float        _gain;                  // current gain
+  float _max_gain;             // max allowable gain
+};
+
+#endif /* _GRI_AGC_CC_H_ */
diff --git a/gnuradio-core/src/lib/general/gri_agc_cc.i b/gnuradio-core/src/lib/general/gri_agc_cc.i
new file mode 100644 (file)
index 0000000..70c1baa
--- /dev/null
@@ -0,0 +1,40 @@
+/* -*- 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 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.
+ */
+
+#include <math.h>
+
+/*!
+ * \brief high performance Automatic Gain Control class
+ *
+ * For Power the absolute value of the complex number is used.
+ */
+
+
+class gri_agc_cc {
+
+ public:
+  gri_agc_cc (float rate = 1e-4, float reference = 1.0, float gain = 1.0, float max_gain = 0.0);
+  float rate ();
+  float reference ();
+  float gain ();
+  float max_gain ();
+  };
diff --git a/gnuradio-core/src/lib/general/gri_char_to_float.cc b/gnuradio-core/src/lib/general/gri_char_to_float.cc
new file mode 100644 (file)
index 0000000..ca02ca2
--- /dev/null
@@ -0,0 +1,40 @@
+/* -*- 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 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.
+ */
+
+#include <gri_char_to_float.h>
+
+void 
+gri_char_to_float (const char *in, float *out, int nsamples)
+{
+  while (nsamples >= 4){
+    out[0] = in[0];
+    out[1] = in[1];
+    out[2] = in[2];
+    out[3] = in[3];
+    out += 4;
+    in += 4;
+    nsamples -= 4;
+  }
+
+  while (nsamples-- > 0)
+    *out++ = *in++;
+}
diff --git a/gnuradio-core/src/lib/general/gri_char_to_float.h b/gnuradio-core/src/lib/general/gri_char_to_float.h
new file mode 100644 (file)
index 0000000..7aa38d0
--- /dev/null
@@ -0,0 +1,32 @@
+/* -*- 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 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.
+ */
+
+#ifndef INCLUDED_GRI_CHAR_TO_FLOAT_H
+#define INCLUDED_GRI_CHAR_TO_FLOAT_H
+
+/*
+ * convert array of chars to floats
+ */
+void gri_char_to_float (const char *in, float *out, int nsamples);
+
+
+#endif /* INCLUDED_GRI_CHAR_TO_FLOAT_H */
diff --git a/gnuradio-core/src/lib/general/gri_debugger_hook.cc b/gnuradio-core/src/lib/general/gri_debugger_hook.cc
new file mode 100644 (file)
index 0000000..35e138a
--- /dev/null
@@ -0,0 +1,29 @@
+/* -*- 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 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.
+ */
+
+#include <gri_debugger_hook.h>
+
+void
+gri_debugger_hook ()
+{
+  // nop.  set a breakpoint here
+}
diff --git a/gnuradio-core/src/lib/general/gri_debugger_hook.h b/gnuradio-core/src/lib/general/gri_debugger_hook.h
new file mode 100644 (file)
index 0000000..612b7c5
--- /dev/null
@@ -0,0 +1,28 @@
+/* -*- 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 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.
+ */
+
+#ifndef INCLUDED_GRI_DEBUGGER_HOOK_H
+#define INCLUDED_GRI_DEBUGGER_HOOK_H
+
+void gri_debugger_hook ();
+
+#endif /* INCLUDED_GRI_DEBUGGER_HOOK_H */
diff --git a/gnuradio-core/src/lib/general/gri_fft.cc b/gnuradio-core/src/lib/general/gri_fft.cc
new file mode 100644 (file)
index 0000000..30b0127
--- /dev/null
@@ -0,0 +1,229 @@
+/* -*- 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 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.
+ */
+
+#include <gri_fft.h>
+#include <fftw3.h>
+#include <gr_complex.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <cassert>
+#include <stdexcept>
+
+static char *
+wisdom_filename ()
+{
+  static char *filename = ".gr_fftw_wisdom";
+
+  char *home = getenv ("HOME");
+  if (home){
+    char *p = new char[strlen (home) + strlen (filename) + 2];
+    strcpy (p, home);
+    strcat (p, "/");
+    strcat (p, filename);
+    return p;
+  }
+  return 0;
+}
+
+static void 
+gri_fftw_import_wisdom ()
+{
+  char *filename = wisdom_filename ();
+  FILE *fp = fopen (filename, "r");
+  if (fp != 0){
+    int r = fftwf_import_wisdom_from_file (fp);
+    fclose (fp);
+    if (!r){
+      fprintf (stderr, "gri_fftw: can't import wisdom from %s\n", filename);
+    }
+  }
+  delete [] filename;
+}
+
+static void
+gri_fftw_export_wisdom ()
+{
+  char *filename = wisdom_filename ();
+  FILE *fp = fopen (filename, "w");
+  if (fp != 0){
+    fftwf_export_wisdom_to_file (fp);
+    fclose (fp);
+  }
+  else {
+    fprintf (stderr, "gri_fftw: ");
+    perror (filename);
+  }
+  delete [] filename;
+}
+
+// ----------------------------------------------------------------
+
+gri_fft_complex::gri_fft_complex (int fft_size, bool forward)
+{
+  assert (sizeof (fftwf_complex) == sizeof (gr_complex));
+  
+  if (fft_size <= 0)
+    throw std::out_of_range ("gri_fftw: invalid fft_size");
+  
+  d_fft_size = fft_size;
+  d_inbuf = (gr_complex *) fftwf_malloc (sizeof (gr_complex) * inbuf_length ());
+  if (d_inbuf == 0)
+    throw std::runtime_error ("fftwf_malloc");
+  
+  d_outbuf = (gr_complex *) fftwf_malloc (sizeof (gr_complex) * outbuf_length ());
+  if (d_outbuf == 0){
+    fftwf_free (d_inbuf);
+    throw std::runtime_error ("fftwf_malloc");
+  }
+
+  // FIXME If there's ever a chance that the planning functions
+  // will be called in multiple threads, we've got to ensure single
+  // threaded access.  They are not thread-safe.
+  
+  gri_fftw_import_wisdom ();   // load prior wisdom from disk
+  d_plan = fftwf_plan_dft_1d (fft_size,
+                             reinterpret_cast<fftwf_complex *>(d_inbuf), 
+                             reinterpret_cast<fftwf_complex *>(d_outbuf),
+                             forward ? FFTW_FORWARD : FFTW_BACKWARD,
+                             FFTW_MEASURE);
+
+  if (d_plan == NULL) {
+    fprintf(stderr, "gri_fft_complex: error creating plan\n");
+    throw std::runtime_error ("fftwf_plan_dft_1d failed");
+  }
+  gri_fftw_export_wisdom ();   // store new wisdom to disk
+}
+
+gri_fft_complex::~gri_fft_complex ()
+{
+  fftwf_destroy_plan ((fftwf_plan) d_plan);
+  fftwf_free (d_inbuf);
+  fftwf_free (d_outbuf);
+}
+
+void
+gri_fft_complex::execute ()
+{
+  fftwf_execute ((fftwf_plan) d_plan);
+}
+
+// ----------------------------------------------------------------
+
+gri_fft_real_fwd::gri_fft_real_fwd (int fft_size)
+{
+  assert (sizeof (fftwf_complex) == sizeof (gr_complex));
+  
+  if (fft_size <= 0)
+    throw std::out_of_range ("gri_fftw: invalid fft_size");
+  
+  d_fft_size = fft_size;
+  d_inbuf = (float *) fftwf_malloc (sizeof (float) * inbuf_length ());
+  if (d_inbuf == 0)
+    throw std::runtime_error ("fftwf_malloc");
+  
+  d_outbuf = (gr_complex *) fftwf_malloc (sizeof (gr_complex) * outbuf_length ());
+  if (d_outbuf == 0){
+    fftwf_free (d_inbuf);
+    throw std::runtime_error ("fftwf_malloc");
+  }
+
+  // FIXME If there's ever a chance that the planning functions
+  // will be called in multiple threads, we've got to ensure single
+  // threaded access.  They are not thread-safe.
+  
+  gri_fftw_import_wisdom ();   // load prior wisdom from disk
+  d_plan = fftwf_plan_dft_r2c_1d (fft_size,
+                                 d_inbuf,
+                                 reinterpret_cast<fftwf_complex *>(d_outbuf),
+                                 FFTW_MEASURE);
+
+  if (d_plan == NULL) {
+    fprintf(stderr, "gri_fft_real_fwd: error creating plan\n");
+    throw std::runtime_error ("fftwf_plan_dft_r2c_1d failed");
+  }
+  gri_fftw_export_wisdom ();   // store new wisdom to disk
+}
+
+gri_fft_real_fwd::~gri_fft_real_fwd ()
+{
+  fftwf_destroy_plan ((fftwf_plan) d_plan);
+  fftwf_free (d_inbuf);
+  fftwf_free (d_outbuf);
+}
+
+void
+gri_fft_real_fwd::execute ()
+{
+  fftwf_execute ((fftwf_plan) d_plan);
+}
+
+// ----------------------------------------------------------------
+
+gri_fft_real_rev::gri_fft_real_rev (int fft_size)
+{
+  assert (sizeof (fftwf_complex) == sizeof (gr_complex));
+  
+  if (fft_size <= 0)
+    throw std::out_of_range ("gri_fftw: invalid fft_size");
+  
+  d_fft_size = fft_size;
+  d_inbuf = (gr_complex *) fftwf_malloc (sizeof (gr_complex) * inbuf_length ());
+  if (d_inbuf == 0)
+    throw std::runtime_error ("fftwf_malloc");
+  
+  d_outbuf = (float *) fftwf_malloc (sizeof (float) * outbuf_length ());
+  if (d_outbuf == 0){
+    fftwf_free (d_inbuf);
+    throw std::runtime_error ("fftwf_malloc");
+  }
+
+  // FIXME If there's ever a chance that the planning functions
+  // will be called in multiple threads, we've got to ensure single
+  // threaded access.  They are not thread-safe.
+  
+  gri_fftw_import_wisdom ();   // load prior wisdom from disk
+  d_plan = fftwf_plan_dft_c2r_1d (fft_size,
+                                 reinterpret_cast<fftwf_complex *>(d_inbuf),
+                                 d_outbuf,
+                                 FFTW_MEASURE);
+
+  if (d_plan == NULL) {
+    fprintf(stderr, "gri_fft_real_rev: error creating plan\n");
+    throw std::runtime_error ("fftwf_plan_dft_c2r_1d failed");
+  }
+  gri_fftw_export_wisdom ();   // store new wisdom to disk
+}
+
+gri_fft_real_rev::~gri_fft_real_rev ()
+{
+  fftwf_destroy_plan ((fftwf_plan) d_plan);
+  fftwf_free (d_inbuf);
+  fftwf_free (d_outbuf);
+}
+
+void
+gri_fft_real_rev::execute ()
+{
+  fftwf_execute ((fftwf_plan) d_plan);
+}
+
diff --git a/gnuradio-core/src/lib/general/gri_fft.h b/gnuradio-core/src/lib/general/gri_fft.h
new file mode 100644 (file)
index 0000000..5034774
--- /dev/null
@@ -0,0 +1,122 @@
+/* -*- 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 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.
+ */
+#ifndef _GRI_FFT_H_
+#define _GRI_FFT_H_
+
+/*
+ * Wrappers for FFTW single precision 1d dft
+ */
+
+#include <gr_complex.h>
+
+/*!
+ * \brief FFT: complex in, complex out
+ */
+
+class gri_fft_complex {
+  int        d_fft_size;
+  gr_complex *d_inbuf;
+  gr_complex *d_outbuf;
+  void      *d_plan;
+  
+public:
+  gri_fft_complex (int fft_size, bool forward = true);
+  virtual ~gri_fft_complex ();
+
+  /*
+   * These return pointers to buffers owned by gri_fft_complex into which
+   * input and output take place.  It's done this way in order to
+   * ensure optimal alignment for SIMD instructions.
+   */
+  gr_complex *get_inbuf ()  const { return d_inbuf; }
+  gr_complex *get_outbuf () const { return d_outbuf; }
+
+  int inbuf_length ()  const { return d_fft_size; }
+  int outbuf_length () const { return d_fft_size; }
+
+  /*!
+   * compute FFT.  The input comes from inbuf, the output is placed in outbuf.
+   */
+  void execute ();
+};
+
+/*!
+ * \brief FFT: real in, complex out
+ */
+class gri_fft_real_fwd {
+  int        d_fft_size;
+  float             *d_inbuf;
+  gr_complex *d_outbuf;
+  void      *d_plan;
+  
+public:
+  gri_fft_real_fwd (int fft_size);
+  virtual ~gri_fft_real_fwd ();
+
+  /*
+   * These return pointers to buffers owned by gri_fft_real_fwd into
+   * which input and output take place.  It's done this way in order
+   * to ensure optimal alignment for SIMD instructions.
+   */
+  float *get_inbuf ()      const { return d_inbuf; }
+  gr_complex *get_outbuf () const { return d_outbuf; }
+
+  int inbuf_length ()  const { return d_fft_size; }
+  int outbuf_length () const { return d_fft_size / 2 + 1; }
+
+  /*!
+   * compute FFT.  The input comes from inbuf, the output is placed in outbuf.
+   */
+  void execute ();
+};
+
+/*!
+ * \brief FFT: complex in, float out
+ */
+class gri_fft_real_rev {
+  int        d_fft_size;
+  gr_complex *d_inbuf;
+  float             *d_outbuf;
+  void      *d_plan;
+  
+public:
+  gri_fft_real_rev (int fft_size);
+  virtual ~gri_fft_real_rev ();
+
+  /*
+   * These return pointers to buffers owned by gri_fft_real_rev into
+   * which input and output take place.  It's done this way in order
+   * to ensure optimal alignment for SIMD instructions.
+   */
+  gr_complex *get_inbuf () const { return d_inbuf; }
+  float *get_outbuf () const { return d_outbuf; }
+
+  int inbuf_length ()  const { return d_fft_size / 2 + 1; }
+  int outbuf_length () const { return d_fft_size; }
+
+  /*!
+   * compute FFT.  The input comes from inbuf, the output is placed in outbuf.
+   */
+  void execute ();
+};
+
+#endif
diff --git a/gnuradio-core/src/lib/general/gri_float_to_char.cc b/gnuradio-core/src/lib/general/gri_float_to_char.cc
new file mode 100644 (file)
index 0000000..b94c534
--- /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 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.
+ */
+
+#define _ISOC9X_SOURCE
+#include <gri_float_to_char.h>
+#include <math.h>
+
+static const int MIN_CHAR = -128;
+static const int MAX_CHAR =  127;
+
+
+void 
+gri_float_to_char (const float *in, char *out, int nsamples)
+{
+  for (int i = 0; i < nsamples; i++){
+    long int r = (long int) rint (in[i]);
+    if (r < MIN_CHAR)
+      r = MIN_CHAR;
+    else if (r > MAX_CHAR)
+      r = MAX_CHAR;
+    out[i] = r;
+  }
+}
diff --git a/gnuradio-core/src/lib/general/gri_float_to_char.h b/gnuradio-core/src/lib/general/gri_float_to_char.h
new file mode 100644 (file)
index 0000000..8891ac1
--- /dev/null
@@ -0,0 +1,32 @@
+/* -*- 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 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.
+ */
+
+#ifndef INCLUDED_GRI_FLOAT_TO_CHAR_H
+#define INCLUDED_GRI_FLOAT_TO_CHAR_H
+
+/*!
+ * convert array of floats to chars with rounding and saturation.
+ */
+void gri_float_to_char (const float *in, char *out, int nsamples);
+
+#endif /* INCLUDED_GRI_FLOAT_TO_CHAR_H */
+
diff --git a/gnuradio-core/src/lib/general/gri_float_to_short.cc b/gnuradio-core/src/lib/general/gri_float_to_short.cc
new file mode 100644 (file)
index 0000000..b291061
--- /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 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.
+ */
+
+#define _ISOC9X_SOURCE
+#include <gri_float_to_short.h>
+#include <math.h>
+
+static const int MIN_SHORT = -32768;
+static const int MAX_SHORT =  32767;
+
+
+void 
+gri_float_to_short (const float *in, short *out, int nsamples)
+{
+  for (int i = 0; i < nsamples; i++){
+    long int r = (long int) rint (in[i]);
+    if (r < MIN_SHORT)
+      r = MIN_SHORT;
+    else if (r > MAX_SHORT)
+      r = MAX_SHORT;
+    out[i] = r;
+  }
+}
diff --git a/gnuradio-core/src/lib/general/gri_float_to_short.h b/gnuradio-core/src/lib/general/gri_float_to_short.h
new file mode 100644 (file)
index 0000000..e13b61d
--- /dev/null
@@ -0,0 +1,32 @@
+/* -*- 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 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.
+ */
+
+#ifndef INCLUDED_GRI_FLOAT_TO_SHORT_H
+#define INCLUDED_GRI_FLOAT_TO_SHORT_H
+
+/*!
+ * convert array of floats to shorts with rounding and saturation.
+ */
+void gri_float_to_short (const float *in, short *out, int nsamples);
+
+#endif /* INCLUDED_GRI_FLOAT_TO_SHORT_H */
+
diff --git a/gnuradio-core/src/lib/general/gri_float_to_uchar.cc b/gnuradio-core/src/lib/general/gri_float_to_uchar.cc
new file mode 100644 (file)
index 0000000..8281a96
--- /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 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.
+ */
+
+#define _ISOC9X_SOURCE
+#include <gri_float_to_uchar.h>
+#include <math.h>
+
+static const int MIN_UCHAR = 0;
+static const int MAX_UCHAR =  255;
+
+
+void 
+gri_float_to_uchar (const float *in, unsigned char *out, int nsamples)
+{
+  for (int i = 0; i < nsamples; i++){
+    long int r = (long int) rint (in[i]);
+    if (r < MIN_UCHAR)
+      r = MIN_UCHAR;
+    else if (r > MAX_UCHAR)
+      r = MAX_UCHAR;
+    out[i] = r;
+  }
+}
diff --git a/gnuradio-core/src/lib/general/gri_float_to_uchar.h b/gnuradio-core/src/lib/general/gri_float_to_uchar.h
new file mode 100644 (file)
index 0000000..fbde8c5
--- /dev/null
@@ -0,0 +1,32 @@
+/* -*- 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 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.
+ */
+
+#ifndef INCLUDED_GRI_FLOAT_TO_UCHAR_H
+#define INCLUDED_GRI_FLOAT_TO_UCHAR_H
+
+/*!
+ * convert array of floats to unsigned chars with rounding and saturation.
+ */
+void gri_float_to_uchar (const float *in, unsigned char *out, int nsamples);
+
+#endif /* INCLUDED_GRI_FLOAT_TO_UCHAR_H */
+
diff --git a/gnuradio-core/src/lib/general/gri_interleaved_short_to_complex.cc b/gnuradio-core/src/lib/general/gri_interleaved_short_to_complex.cc
new file mode 100644 (file)
index 0000000..56e3c39
--- /dev/null
@@ -0,0 +1,39 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gri_interleaved_short_to_complex.h>
+#include <assert.h>
+
+void 
+gri_interleaved_short_to_complex (const short *in,
+                                 gr_complex *out, int nsamples)
+{
+  assert (nsamples % 2 == 0);
+  
+  for (int i = 0; i < nsamples/2; i++){
+    out[i] = gr_complex (in[i*2 + 0], in[i*2 + 1]);
+  }
+}
diff --git a/gnuradio-core/src/lib/general/gri_interleaved_short_to_complex.h b/gnuradio-core/src/lib/general/gri_interleaved_short_to_complex.h
new file mode 100644 (file)
index 0000000..3a0fc3d
--- /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 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.
+ */
+
+#ifndef INCLUDED_GRI_INTERLEAVED_SHORT_TO_COMPLEX_H
+#define INCLUDED_GRI_INTERLEAVED_SHORT_TO_COMPLEX_H
+
+#include <gr_complex.h>
+
+/*
+ * convert array of interleaved shorts to complex.
+ * the shorts contains real, imaginary, real, imaginary...
+ * nsamples is the number of shorts; it must be even.
+ */
+void gri_interleaved_short_to_complex (const short *in, gr_complex *out, int nsamples);
+
+#endif /* INCLUDED_GRI_INTERLEAVED_SHORT_TO_COMPLEX_H */
+
+
diff --git a/gnuradio-core/src/lib/general/gri_lfsr_15_1_0.h b/gnuradio-core/src/lib/general/gri_lfsr_15_1_0.h
new file mode 100644 (file)
index 0000000..561ba6c
--- /dev/null
@@ -0,0 +1,57 @@
+/* -*- 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 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.
+ */
+
+#ifndef INCLUDED_GRI_LFSR_15_1_0_H
+#define INCLUDED_GRI_LFSR_15_1_0_H
+
+/*!
+ * \brief Linear Feedback Shift Register using primitive polynomial x^15 + x + 1
+ *
+ * Generates a maximal length pseudo-random sequence of length 2^15 - 1 bits.
+ */
+
+class gri_lfsr_15_1_0 {
+  unsigned long        d_sr;           // shift register
+
+ public:
+
+  gri_lfsr_15_1_0 () { reset (); }
+
+  void reset () { d_sr = 0x7fff; }
+  
+  int next_bit (){
+    d_sr = ((((d_sr >> 1) ^ d_sr) & 0x1) << 14) | (d_sr >> 1);
+    return d_sr & 0x1;
+  }
+
+  int next_byte (){
+    int        v = 0;
+    for (int i = 0; i < 8; i++){
+      v >>= 1;
+      if (next_bit ())
+       v |= 0x80;
+    }
+    return v;
+  }
+};
+
+#endif /* INCLUDED_GRI_LFSR_15_1_0_H */
diff --git a/gnuradio-core/src/lib/general/gri_lfsr_32k.h b/gnuradio-core/src/lib/general/gri_lfsr_32k.h
new file mode 100644 (file)
index 0000000..653223e
--- /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 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.
+ */
+
+#ifndef INCLUDED_GRI_LFSR_32k_H
+#define INCLUDED_GRI_LFSR_32k_H
+
+#include <gri_lfsr_15_1_0.h>
+
+/*!
+ * \brief generate pseudo-random sequence of length 32768 bits.
+ *
+ * This is based on gri_lfsr_15_1_0 with an extra 0 added at the end
+ * of the sequence.
+ */
+
+class gri_lfsr_32k {
+  gri_lfsr_15_1_0      d_lfsr;
+  unsigned int         d_count;
+
+ public:
+  gri_lfsr_32k () { reset (); }
+
+  void reset (){
+    d_lfsr.reset ();
+    d_count = 0;
+  }
+    
+  int next_bit (){
+    if (d_count == 32767){
+      d_count = 0;
+      return 0;
+    }
+    d_count++;
+    return d_lfsr.next_bit ();
+  }
+
+  int next_byte (){
+    int        v = 0;
+    for (int i = 0; i < 8; i++){
+      v >>= 1;
+      if (next_bit ())
+       v |= 0x80;
+    }
+    return v;
+  }
+
+  int next_short (){
+    int        v = 0;
+    for (int i = 0; i < 16; i++){
+      v >>= 1;
+      if (next_bit ())
+       v |= 0x8000;
+    }
+    return v;
+  }
+
+};
+
+#endif /* INCLUDED_GRI_LFSR_32k_H */
diff --git a/gnuradio-core/src/lib/general/gri_short_to_float.cc b/gnuradio-core/src/lib/general/gri_short_to_float.cc
new file mode 100644 (file)
index 0000000..f6beb45
--- /dev/null
@@ -0,0 +1,40 @@
+/* -*- 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 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.
+ */
+
+#include <gri_short_to_float.h>
+
+void 
+gri_short_to_float (const short *in, float *out, int nsamples)
+{
+  while (nsamples >= 4){
+    out[0] = in[0];
+    out[1] = in[1];
+    out[2] = in[2];
+    out[3] = in[3];
+    out += 4;
+    in += 4;
+    nsamples -= 4;
+  }
+
+  while (nsamples-- > 0)
+    *out++ = *in++;
+}
diff --git a/gnuradio-core/src/lib/general/gri_short_to_float.h b/gnuradio-core/src/lib/general/gri_short_to_float.h
new file mode 100644 (file)
index 0000000..1abd0dd
--- /dev/null
@@ -0,0 +1,32 @@
+/* -*- 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 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.
+ */
+
+#ifndef INCLUDED_GRI_SHORT_TO_FLOAT_H
+#define INCLUDED_GRI_SHORT_TO_FLOAT_H
+
+/*
+ * convert array of shorts to floats
+ */
+void gri_short_to_float (const short *in, float *out, int nsamples);
+
+
+#endif /* INCLUDED_GRI_SHORT_TO_FLOAT_H */
diff --git a/gnuradio-core/src/lib/general/gri_uchar_to_float.cc b/gnuradio-core/src/lib/general/gri_uchar_to_float.cc
new file mode 100644 (file)
index 0000000..8a5f87a
--- /dev/null
@@ -0,0 +1,40 @@
+/* -*- 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 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.
+ */
+
+#include <gri_uchar_to_float.h>
+
+void 
+gri_uchar_to_float (const unsigned char *in, float *out, int nsamples)
+{
+  while (nsamples >= 4){
+    out[0] = in[0];
+    out[1] = in[1];
+    out[2] = in[2];
+    out[3] = in[3];
+    out += 4;
+    in += 4;
+    nsamples -= 4;
+  }
+
+  while (nsamples-- > 0)
+    *out++ = *in++;
+}
diff --git a/gnuradio-core/src/lib/general/gri_uchar_to_float.h b/gnuradio-core/src/lib/general/gri_uchar_to_float.h
new file mode 100644 (file)
index 0000000..50646e4
--- /dev/null
@@ -0,0 +1,32 @@
+/* -*- 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 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.
+ */
+
+#ifndef INCLUDED_GRI_UCHAR_TO_FLOAT_H
+#define INCLUDED_GRI_UCHAR_TO_FLOAT_H
+
+/*
+ * convert array of unsigned chars to floats
+ */
+void gri_uchar_to_float (const unsigned char *in, float *out, int nsamples);
+
+
+#endif /* INCLUDED_GRI_UCHAR_TO_FLOAT_H */
diff --git a/gnuradio-core/src/lib/general/malloc16.c b/gnuradio-core/src/lib/general/malloc16.c
new file mode 100644 (file)
index 0000000..2cc6135
--- /dev/null
@@ -0,0 +1,46 @@
+/* Wrapper functions for malloc/free that force 16-byte alignment
+ * See http://perso.club-internet.fr/matmac/sourcesc.htm
+
+ * Copyright 2001 Phil Karn, KA9Q
+ * May be used under the terms of the GNU Public License (GPL)
+ */
+
+#include "malloc16.h"
+#include <string.h>
+
+void *malloc16Align(int size){
+  void *p;
+  void **p1;
+
+  if((p = malloc(size+31)) == NULL)
+    return NULL;
+
+  /* Round up to next 16-byte boundary */
+  p1 = (void **)(((long)p + 31) & (~15));
+
+  /* Stash actual start of block just before ptr we return */
+  p1[-1] = p;
+
+  /* Return 16-byte aligned address */
+  return (void *)p1;
+}
+
+void *calloc16Align(size_t nmemb,size_t size){
+  int nbytes;
+  void *p;
+
+  nbytes = nmemb*size;
+  if((p = malloc16Align(nbytes)) == NULL)
+    return NULL;
+
+  memset(p,0,nbytes);
+  return p;
+}
+
+void free16Align(void *p){
+
+  if(p != NULL){
+    /* Retrieve pointer to actual start of block and free it */
+    free(((void **)p)[-1]);
+  }
+}
diff --git a/gnuradio-core/src/lib/general/malloc16.h b/gnuradio-core/src/lib/general/malloc16.h
new file mode 100644 (file)
index 0000000..0376ec5
--- /dev/null
@@ -0,0 +1,35 @@
+/* -*- 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 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.
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdlib.h>
+
+void *malloc16Align(int size);
+void *calloc16Align(size_t nmemb,size_t size);
+void free16Align(void *p);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/gnuradio-core/src/lib/general/qa_general.cc b/gnuradio-core/src/lib/general/qa_general.cc
new file mode 100644 (file)
index 0000000..1fa2b93
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * 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 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 class gathers together all the test cases for the gr
+ * directory into a single test suite.  As you create new test cases,
+ * add them here.
+ */
+
+#include <qa_general.h>
+#include <qa_gr_firdes.h>
+#include <qa_gr_circular_file.h>
+#include <qa_gr_fxpt.h>
+#include <qa_gr_fxpt_nco.h>
+#include <qa_gr_fxpt_vco.h>
+
+CppUnit::TestSuite *
+qa_general::suite ()
+{
+  CppUnit::TestSuite   *s = new CppUnit::TestSuite ("general");
+
+  s->addTest (qa_gr_firdes::suite ());
+  s->addTest (qa_gr_circular_file::suite ());
+  s->addTest (qa_gr_fxpt::suite ());
+  s->addTest (qa_gr_fxpt_nco::suite ());
+  s->addTest (qa_gr_fxpt_vco::suite ());
+  
+  return s;
+}
diff --git a/gnuradio-core/src/lib/general/qa_general.h b/gnuradio-core/src/lib/general/qa_general.h
new file mode 100644 (file)
index 0000000..6bf57df
--- /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 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.
+ */
+
+#ifndef _QA_GENERAL_H_
+#define _QA_GENERAL_H_
+
+#include <cppunit/TestSuite.h>
+
+//! collect all the tests for the gr directory
+
+class qa_general {
+ public:
+  //! return suite of tests for all of gr directory
+  static CppUnit::TestSuite *suite ();
+};
+
+
+#endif /* _QA_GENERAL_H_ */
diff --git a/gnuradio-core/src/lib/general/qa_gr_circular_file.cc b/gnuradio-core/src/lib/general/qa_gr_circular_file.cc
new file mode 100644 (file)
index 0000000..adfa33c
--- /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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include <qa_gr_circular_file.h>
+#include <gr_circular_file.h>
+#include <cppunit/TestAssert.h>
+#include <iostream>
+#include <stdio.h>
+#include <unistd.h>
+
+static const char *test_file = "qa_gr_circular_file.data";
+static const int BUFFER_SIZE = 8192;
+static const int NWRITE = 8192 * 9 / 8;
+
+void
+qa_gr_circular_file::t1 ()
+{
+#ifdef HAVE_MMAP
+  gr_circular_file     *cf_writer;
+  gr_circular_file     *cf_reader;
+  
+  // write the data...
+
+  cf_writer = new gr_circular_file (test_file, true, BUFFER_SIZE * sizeof (short));
+
+  short sd;
+  for (int i = 0; i < NWRITE; i++){
+    sd = i;
+    cf_writer->write (&sd, sizeof (sd));
+  }
+
+  delete cf_writer;
+
+  // now read it back...
+
+  cf_reader = new gr_circular_file (test_file);
+  for (int i = 0; i < BUFFER_SIZE; i++){
+    int n = cf_reader->read (&sd, sizeof (sd));
+    CPPUNIT_ASSERT_EQUAL ((int) sizeof (sd), n);
+    CPPUNIT_ASSERT_EQUAL (NWRITE - BUFFER_SIZE + i, (int) sd);
+  }
+
+  int n = cf_reader->read (&sd, sizeof (sd));
+  CPPUNIT_ASSERT_EQUAL (0, n);
+
+  delete cf_reader;
+  unlink (test_file);
+#endif // HAVE_MMAP
+}
+
diff --git a/gnuradio-core/src/lib/general/qa_gr_circular_file.h b/gnuradio-core/src/lib/general/qa_gr_circular_file.h
new file mode 100644 (file)
index 0000000..45ebfd8
--- /dev/null
@@ -0,0 +1,40 @@
+/* -*- 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 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.
+ */
+#ifndef _QA_GR_CIRCULAR_FILE_H_
+#define _QA_GR_CIRCULAR_FILE_H_
+
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/TestCase.h>
+
+class qa_gr_circular_file : public CppUnit::TestCase {
+
+  CPPUNIT_TEST_SUITE (qa_gr_circular_file);
+  CPPUNIT_TEST (t1);
+  CPPUNIT_TEST_SUITE_END ();
+
+ private:
+  void t1 ();
+
+};
+
+
+#endif /* _QA_GR_CIRCULAR_FILE_H_ */
diff --git a/gnuradio-core/src/lib/general/qa_gr_firdes.cc b/gnuradio-core/src/lib/general/qa_gr_firdes.cc
new file mode 100644 (file)
index 0000000..072bcb6
--- /dev/null
@@ -0,0 +1,344 @@
+/* -*- 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 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.
+ */
+
+#include <qa_gr_firdes.h>
+#include <gr_firdes.h>
+#include <cppunit/TestAssert.h>
+#include <gr_complex.h>
+#include <string.h>
+#include <iostream>
+#include <iomanip>
+#include <stdio.h>
+
+#define        NELEM(x) (sizeof (x) / sizeof (x[0]))
+
+using std::vector;
+
+static void
+print_taps (std::ostream &s, vector<float> &v)
+{
+  
+  for (unsigned int i = 0; i < v.size (); i++){
+    printf ("tap[%2d] = %16.7e\n", i, v[i]);
+  }
+}
+
+static void
+check_symmetry (vector<float> &v)
+{
+  int  n = v.size ();
+  int  m = n / 2;
+
+  for (int i = 0; i < m; i++)
+    CPPUNIT_ASSERT_DOUBLES_EQUAL (v[i], v[n - i - 1], 1e-9);
+}
+
+const static float t1_exp[53] = {
+ -9.0525491e-04,
+  2.0713841e-04,
+  1.2388536e-03,
+  2.9683491e-04,
+ -1.7744775e-03,
+ -1.3599906e-03,
+  2.2031884e-03,
+  3.2744040e-03,
+ -1.8868084e-03,
+ -5.9935520e-03,
+  6.4301129e-18,
+  8.9516686e-03,
+  4.2178580e-03,
+ -1.0998557e-02,
+ -1.1173409e-02,
+  1.0455756e-02,
+  2.0686293e-02,
+ -5.2032238e-03,
+ -3.1896964e-02,
+ -7.4998410e-03,
+  4.3362070e-02,
+  3.2502845e-02,
+ -5.3328082e-02,
+ -8.5621715e-02,
+  6.0117975e-02,
+  3.1128189e-01,
+  4.3769023e-01,
+  3.1128189e-01,
+  6.0117975e-02,
+ -8.5621715e-02,
+ -5.3328082e-02,
+  3.2502845e-02,
+  4.3362070e-02,
+ -7.4998410e-03,
+ -3.1896964e-02,
+ -5.2032238e-03,
+  2.0686293e-02,
+  1.0455756e-02,
+ -1.1173409e-02,
+ -1.0998557e-02,
+  4.2178580e-03,
+  8.9516686e-03,
+  6.4301129e-18,
+ -5.9935520e-03,
+ -1.8868084e-03,
+  3.2744040e-03,
+  2.2031884e-03,
+ -1.3599906e-03,
+ -1.7744775e-03,
+  2.9683491e-04,
+  1.2388536e-03,
+  2.0713841e-04,
+ -9.0525491e-04
+};
+
+const static float t2_exp[53] = {
+  9.0380036e-04,
+ -2.0680559e-04,
+ -1.2368630e-03,
+ -2.9635796e-04,
+  1.7716263e-03,
+  1.3578053e-03,
+ -2.1996482e-03,
+ -3.2691427e-03,
+  1.8837767e-03,
+  5.9839217e-03,
+ -6.4197810e-18,
+ -8.9372853e-03,
+ -4.2110807e-03,
+  1.0980885e-02,
+  1.1155456e-02,
+ -1.0438956e-02,
+ -2.0653054e-02,
+  5.1948633e-03,
+  3.1845711e-02,
+  7.4877902e-03,
+ -4.3292396e-02,
+ -3.2450620e-02,
+  5.3242393e-02,
+  8.5484132e-02,
+ -6.0021374e-02,
+ -3.1078172e-01,
+  5.6184036e-01,
+ -3.1078172e-01,
+ -6.0021374e-02,
+  8.5484132e-02,
+  5.3242393e-02,
+ -3.2450620e-02,
+ -4.3292396e-02,
+  7.4877902e-03,
+  3.1845711e-02,
+  5.1948633e-03,
+ -2.0653054e-02,
+ -1.0438956e-02,
+  1.1155456e-02,
+  1.0980885e-02,
+ -4.2110807e-03,
+ -8.9372853e-03,
+ -6.4197810e-18,
+  5.9839217e-03,
+  1.8837767e-03,
+ -3.2691427e-03,
+ -2.1996482e-03,
+  1.3578053e-03,
+  1.7716263e-03,
+ -2.9635796e-04,
+ -1.2368630e-03,
+ -2.0680559e-04,
+  9.0380036e-04
+};
+
+const static float t3_exp[107] = {
+  -1.8970841e-06,
+  -7.1057165e-04,
+   5.4005696e-04,
+   4.6233178e-04,
+   2.0572044e-04,
+   3.5209916e-04,
+  -1.4098573e-03,
+   1.1279077e-04,
+  -6.2994129e-04,
+   1.1450432e-03,
+   1.3637283e-03,
+  -6.4360141e-04,
+   3.6509900e-04,
+  -3.2864159e-03,
+   7.0192874e-04,
+   3.7524730e-04,
+   2.0256115e-03,
+   3.0641893e-03,
+  -3.6618244e-03,
+   7.5592739e-05,
+  -5.5586505e-03,
+   2.3849572e-03,
+   4.0114378e-03,
+   1.6636450e-03,
+   4.7835698e-03,
+  -1.0191196e-02,
+  -3.8158931e-04,
+  -5.5551580e-03,
+   5.3901658e-03,
+   1.1366769e-02,
+  -3.0000482e-03,
+   4.9341680e-03,
+  -2.0093076e-02,
+   5.5752542e-17,
+   1.2093617e-03,
+   8.6089745e-03,
+   2.2382140e-02,
+  -1.6854567e-02,
+   1.6913920e-03,
+  -3.1222520e-02,
+   3.2711059e-03,
+   2.2604836e-02,
+   8.1451107e-03,
+   3.7583180e-02,
+  -5.2293688e-02,
+  -8.0551542e-03,
+  -4.0092729e-02,
+   1.5582236e-02,
+   9.7452506e-02,
+  -1.6183170e-02,
+   8.3281815e-02,
+  -2.8196752e-01,
+  -1.0965768e-01,
+   5.2867508e-01,
+  -1.0965768e-01,
+  -2.8196752e-01,
+   8.3281815e-02,
+  -1.6183170e-02,
+   9.7452506e-02,
+   1.5582236e-02,
+  -4.0092729e-02,
+  -8.0551542e-03,
+  -5.2293688e-02,
+   3.7583180e-02,
+   8.1451107e-03,
+   2.2604836e-02,
+   3.2711059e-03,
+  -3.1222520e-02,
+   1.6913920e-03,
+  -1.6854567e-02,
+   2.2382140e-02,
+   8.6089745e-03,
+   1.2093617e-03,
+   5.5752542e-17,
+  -2.0093076e-02,
+   4.9341680e-03,
+  -3.0000482e-03,
+   1.1366769e-02,
+   5.3901658e-03,
+  -5.5551580e-03,
+  -3.8158931e-04,
+  -1.0191196e-02,
+   4.7835698e-03,
+   1.6636450e-03,
+   4.0114378e-03,
+   2.3849572e-03,
+  -5.5586505e-03,
+   7.5592739e-05,
+  -3.6618244e-03,
+   3.0641893e-03,
+   2.0256115e-03,
+   3.7524730e-04,
+   7.0192874e-04,
+  -3.2864159e-03,
+   3.6509900e-04,
+  -6.4360141e-04,
+   1.3637283e-03,
+   1.1450432e-03,
+  -6.2994129e-04,
+   1.1279077e-04,
+  -1.4098573e-03,
+   3.5209916e-04,
+   2.0572044e-04,
+   4.6233178e-04,
+   5.4005696e-04,
+  -7.1057165e-04,
+  -1.8970841e-06
+};
+
+
+void
+qa_gr_firdes::t1 ()
+{
+  vector<float> taps =
+    gr_firdes::low_pass ( 1.0,
+                         8000,
+                         1750,
+                         500,
+                         gr_firdes::WIN_HAMMING);
+
+  // cout << "ntaps: " << taps.size () << endl;
+  // print_taps (cout, taps);
+
+  CPPUNIT_ASSERT_EQUAL (NELEM (t1_exp), taps.size ());
+  for (unsigned int i = 0; i < taps.size (); i++)
+    CPPUNIT_ASSERT_DOUBLES_EQUAL (t1_exp[i], taps[i], 1e-9);
+
+  check_symmetry (taps);
+}
+
+void
+qa_gr_firdes::t2 ()
+{
+  vector<float> taps =
+    gr_firdes::high_pass ( 1.0,
+                          8000,
+                          1750,
+                          500,
+                          gr_firdes::WIN_HAMMING);
+
+  // cout << "ntaps: " << taps.size () << endl;
+  // print_taps (cout, taps);
+
+  CPPUNIT_ASSERT_EQUAL (NELEM (t2_exp), taps.size ());
+
+  for (unsigned int i = 0; i < taps.size (); i++)
+    CPPUNIT_ASSERT_DOUBLES_EQUAL (t2_exp[i], taps[i], 1e-9);
+
+  check_symmetry (taps);
+}
+
+void
+qa_gr_firdes::t3 ()
+{
+  vector<float> taps =
+    gr_firdes::band_pass ( 1.0,
+                          20e6,
+                          5.75e6 - (5.28e6/2),
+                          5.75e6 + (5.28e6/2),
+                          0.62e6,
+                          gr_firdes::WIN_HAMMING);
+
+  // cout << "ntaps: " << taps.size () << endl;
+  // print_taps (cout, taps);
+
+  CPPUNIT_ASSERT_EQUAL (NELEM (t3_exp), taps.size ());
+
+  for (unsigned int i = 0; i < taps.size (); i++)
+    CPPUNIT_ASSERT_DOUBLES_EQUAL (t3_exp[i], taps[i], 1e-7);
+
+  check_symmetry (taps);
+}
+
+void
+qa_gr_firdes::t4 ()
+{
+}
diff --git a/gnuradio-core/src/lib/general/qa_gr_firdes.h b/gnuradio-core/src/lib/general/qa_gr_firdes.h
new file mode 100644 (file)
index 0000000..8fb4d5a
--- /dev/null
@@ -0,0 +1,46 @@
+/* -*- 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 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.
+ */
+#ifndef _QA_GR_FIRDES_H_
+#define _QA_GR_FIRDES_H_
+
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/TestCase.h>
+
+class qa_gr_firdes : public CppUnit::TestCase {
+
+  CPPUNIT_TEST_SUITE (qa_gr_firdes);
+  CPPUNIT_TEST (t1);
+  CPPUNIT_TEST (t2);
+  CPPUNIT_TEST (t3);
+  CPPUNIT_TEST (t4);
+  CPPUNIT_TEST_SUITE_END ();
+
+ private:
+  void t1 ();
+  void t2 ();
+  void t3 ();
+  void t4 ();
+
+};
+
+
+#endif /* _QA_GR_FIRDES_H_ */
diff --git a/gnuradio-core/src/lib/general/qa_gr_fxpt.cc b/gnuradio-core/src/lib/general/qa_gr_fxpt.cc
new file mode 100644 (file)
index 0000000..6cd582a
--- /dev/null
@@ -0,0 +1,94 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <qa_gr_fxpt.h>
+#include <gr_fxpt.h>
+#include <cppunit/TestAssert.h>
+#include <iostream>
+#include <stdio.h>
+#include <unistd.h>
+#include <math.h>
+
+static const float SIN_COS_TOLERANCE = 1e-5;
+
+void
+qa_gr_fxpt::t0 ()
+{
+  CPPUNIT_ASSERT_DOUBLES_EQUAL (M_PI/2, gr_fxpt::fixed_to_float (0x40000000), SIN_COS_TOLERANCE);
+  CPPUNIT_ASSERT_DOUBLES_EQUAL (0.0,    gr_fxpt::fixed_to_float (0x00000000), SIN_COS_TOLERANCE);
+  CPPUNIT_ASSERT_DOUBLES_EQUAL (-M_PI,  gr_fxpt::fixed_to_float (0x80000000), SIN_COS_TOLERANCE);
+
+  if (0){
+    /*
+     * These are disabled because of some precision issues.
+     *
+     * Different compilers seem to have different opinions on whether
+     * the calulations are done single or double (or extended)
+     * precision.  Any of the answers are fine for our real purpose, but
+     * sometimes the answer is off by a few bits at the bottom.
+     * Hence, the disabled check.
+     */
+    CPPUNIT_ASSERT_EQUAL ((gr_int32) 0x40000000, gr_fxpt::float_to_fixed (M_PI/2));
+    CPPUNIT_ASSERT_EQUAL ((gr_int32) 0,          gr_fxpt::float_to_fixed (0));
+    CPPUNIT_ASSERT_EQUAL ((gr_int32) 0x80000000, gr_fxpt::float_to_fixed (-M_PI));
+  }
+}
+
+void
+qa_gr_fxpt::t1 ()
+{
+
+  CPPUNIT_ASSERT_DOUBLES_EQUAL ( 0,           gr_fxpt::sin (0x00000000), SIN_COS_TOLERANCE);
+  CPPUNIT_ASSERT_DOUBLES_EQUAL ( 0.707106781, gr_fxpt::sin (0x20000000), SIN_COS_TOLERANCE);
+  CPPUNIT_ASSERT_DOUBLES_EQUAL ( 1,           gr_fxpt::sin (0x40000000), SIN_COS_TOLERANCE);
+  CPPUNIT_ASSERT_DOUBLES_EQUAL ( 0.707106781, gr_fxpt::sin (0x60000000), SIN_COS_TOLERANCE);
+  CPPUNIT_ASSERT_DOUBLES_EQUAL ( 0,           gr_fxpt::sin (0x7fffffff), SIN_COS_TOLERANCE);
+  CPPUNIT_ASSERT_DOUBLES_EQUAL ( 0,           gr_fxpt::sin (0x80000000), SIN_COS_TOLERANCE);
+  CPPUNIT_ASSERT_DOUBLES_EQUAL ( 0,           gr_fxpt::sin (0x80000001), SIN_COS_TOLERANCE);
+  CPPUNIT_ASSERT_DOUBLES_EQUAL (-1,           gr_fxpt::sin (-0x40000000), SIN_COS_TOLERANCE);
+  CPPUNIT_ASSERT_DOUBLES_EQUAL (-0.707106781, gr_fxpt::sin (-0x20000000), SIN_COS_TOLERANCE);
+
+
+  for (float p = -M_PI; p < M_PI; p += 2 * M_PI / 3600){
+    float expected = sin (p);
+    float actual = gr_fxpt::sin (gr_fxpt::float_to_fixed (p));
+    CPPUNIT_ASSERT_DOUBLES_EQUAL (expected, actual, SIN_COS_TOLERANCE);
+  }
+}
+
+void
+qa_gr_fxpt::t2 ()
+{
+  for (float p = -M_PI; p < M_PI; p += 2 * M_PI / 3600){
+    float expected = cos (p);
+    float actual = gr_fxpt::cos (gr_fxpt::float_to_fixed (p));
+    CPPUNIT_ASSERT_DOUBLES_EQUAL (expected, actual, SIN_COS_TOLERANCE);
+  }
+}
+
+void
+qa_gr_fxpt::t3 ()
+{
+}
diff --git a/gnuradio-core/src/lib/general/qa_gr_fxpt.h b/gnuradio-core/src/lib/general/qa_gr_fxpt.h
new file mode 100644 (file)
index 0000000..a21be5c
--- /dev/null
@@ -0,0 +1,48 @@
+/* -*- 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 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.
+ */
+#ifndef INCLUDED_QA_GR_FXPT_H
+#define INCLUDED_QA_GR_FXPT_H
+
+
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/TestCase.h>
+
+class qa_gr_fxpt : public CppUnit::TestCase {
+
+  CPPUNIT_TEST_SUITE (qa_gr_fxpt);
+  CPPUNIT_TEST (t0);
+  CPPUNIT_TEST (t1);
+  CPPUNIT_TEST (t2);
+  CPPUNIT_TEST (t3);
+  CPPUNIT_TEST_SUITE_END ();
+
+ private:
+  void t0 ();
+  void t1 ();
+  void t2 ();
+  void t3 ();
+
+};
+
+#endif /* INCLUDED_QA_GR_FXPT_H */
+
+
diff --git a/gnuradio-core/src/lib/general/qa_gr_fxpt_nco.cc b/gnuradio-core/src/lib/general/qa_gr_fxpt_nco.cc
new file mode 100644 (file)
index 0000000..5b774fb
--- /dev/null
@@ -0,0 +1,119 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <qa_gr_fxpt_nco.h>
+#include <gr_fxpt_nco.h>
+#include <gr_nco.h>
+#include <cppunit/TestAssert.h>
+#include <iostream>
+#include <stdio.h>
+#include <unistd.h>
+#include <math.h>
+
+static const float SIN_COS_TOLERANCE = 1e-5;
+
+//static const float SIN_COS_FREQ = 5003;
+static const float SIN_COS_FREQ = 4096;
+
+static const int SIN_COS_BLOCK_SIZE = 100000;
+
+static double max_d(double a, double b)
+{
+  return fabs(a) > fabs(b) ? a : b;
+}
+
+void
+qa_gr_fxpt_nco::t0 ()
+{
+  gr_nco<float,float>  ref_nco;
+  gr_fxpt_nco          new_nco;
+  double max_error = 0, max_phase_error = 0;
+
+  ref_nco.set_freq ((float)(2 * M_PI / SIN_COS_FREQ));
+  new_nco.set_freq ((float)(2 * M_PI / SIN_COS_FREQ));
+
+  CPPUNIT_ASSERT_DOUBLES_EQUAL (ref_nco.get_freq(), new_nco.get_freq(), SIN_COS_TOLERANCE);
+
+  for (int i = 0; i < SIN_COS_BLOCK_SIZE; i++){
+    float ref_sin = ref_nco.sin ();
+    float new_sin = new_nco.sin ();
+    //printf ("i = %6d\n", i);
+    CPPUNIT_ASSERT_DOUBLES_EQUAL (ref_sin, new_sin, SIN_COS_TOLERANCE);
+
+    max_error = max_d (max_error, ref_sin-new_sin);
+
+    float ref_cos = ref_nco.cos ();
+    float new_cos = new_nco.cos ();
+    CPPUNIT_ASSERT_DOUBLES_EQUAL (ref_cos, new_cos, SIN_COS_TOLERANCE);
+
+    max_error = max_d (max_error, ref_cos-new_cos);
+
+    ref_nco.step ();
+    new_nco.step ();
+
+    CPPUNIT_ASSERT_DOUBLES_EQUAL (ref_nco.get_phase(), new_nco.get_phase(), SIN_COS_TOLERANCE);
+
+    max_phase_error = max_d (max_phase_error, ref_nco.get_phase()-new_nco.get_phase());
+  }
+  // printf ("Fxpt  max error %.9f, max phase error %.9f\n", max_error, max_phase_error);
+}
+
+void
+qa_gr_fxpt_nco::t1 ()
+{
+  gr_nco<float,float>  ref_nco;
+  gr_fxpt_nco          new_nco;
+  gr_complex           ref_block[SIN_COS_BLOCK_SIZE];
+  gr_complex           new_block[SIN_COS_BLOCK_SIZE];
+  double max_error = 0;
+
+  ref_nco.set_freq ((float)(2 * M_PI / SIN_COS_FREQ));
+  new_nco.set_freq ((float)(2 * M_PI / SIN_COS_FREQ));
+
+  CPPUNIT_ASSERT_DOUBLES_EQUAL (ref_nco.get_freq(), new_nco.get_freq(), SIN_COS_TOLERANCE);
+
+  ref_nco.sincos ((gr_complex*)ref_block, SIN_COS_BLOCK_SIZE);
+  new_nco.sincos ((gr_complex*)new_block, SIN_COS_BLOCK_SIZE);
+
+  for (int i = 0; i < SIN_COS_BLOCK_SIZE; i++){
+    CPPUNIT_ASSERT_DOUBLES_EQUAL (ref_block[i].real(), new_block[i].real(), SIN_COS_TOLERANCE);
+    max_error = max_d (max_error, ref_block[i].real()-new_block[i].real());
+
+    CPPUNIT_ASSERT_DOUBLES_EQUAL (ref_block[i].imag(), new_block[i].imag(), SIN_COS_TOLERANCE);
+    max_error = max_d (max_error, ref_block[i].imag()-new_block[i].imag());
+  }
+  CPPUNIT_ASSERT_DOUBLES_EQUAL (ref_nco.get_phase(), new_nco.get_phase(), SIN_COS_TOLERANCE);
+  // printf ("Fxpt  max error %.9f, max phase error %.9f\n", max_error, max_phase_error);
+}
+
+void
+qa_gr_fxpt_nco::t2 ()
+{
+}
+
+void
+qa_gr_fxpt_nco::t3 ()
+{
+}
diff --git a/gnuradio-core/src/lib/general/qa_gr_fxpt_nco.h b/gnuradio-core/src/lib/general/qa_gr_fxpt_nco.h
new file mode 100644 (file)
index 0000000..3d0c84a
--- /dev/null
@@ -0,0 +1,48 @@
+/* -*- 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 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.
+ */
+#ifndef INCLUDED_QA_GR_FXPT_NCO_H
+#define INCLUDED_QA_GR_FXPT_NCO_H
+
+
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/TestCase.h>
+
+class qa_gr_fxpt_nco : public CppUnit::TestCase {
+
+  CPPUNIT_TEST_SUITE (qa_gr_fxpt_nco);
+  CPPUNIT_TEST (t0);
+  CPPUNIT_TEST (t1);
+  CPPUNIT_TEST (t2);
+  CPPUNIT_TEST (t3);
+  CPPUNIT_TEST_SUITE_END ();
+
+ private:
+  void t0 ();
+  void t1 ();
+  void t2 ();
+  void t3 ();
+
+};
+
+#endif /* INCLUDED_QA_GR_FXPT_NCO_H */
+
+
diff --git a/gnuradio-core/src/lib/general/qa_gr_fxpt_vco.cc b/gnuradio-core/src/lib/general/qa_gr_fxpt_vco.cc
new file mode 100644 (file)
index 0000000..70c2da3
--- /dev/null
@@ -0,0 +1,110 @@
+/* -*- c++ -*- */
+/*
+ * 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <qa_gr_fxpt_vco.h>
+#include <gr_fxpt_vco.h>
+#include <gr_vco.h>
+#include <cppunit/TestAssert.h>
+#include <iostream>
+#include <stdio.h>
+#include <unistd.h>
+#include <math.h>
+
+static const float SIN_COS_TOLERANCE = 1e-5;
+
+static const float SIN_COS_K = 0.42;
+static const float SIN_COS_AMPL = 0.8;
+
+static const int SIN_COS_BLOCK_SIZE = 100000;
+
+static double max_d(double a, double b)
+{
+  return fabs(a) > fabs(b) ? a : b;
+}
+
+void
+qa_gr_fxpt_vco::t0 ()
+{
+  gr_vco<float,float>  ref_vco;
+  gr_fxpt_vco          new_vco;
+  double max_error = 0, max_phase_error = 0;
+  float                        input[SIN_COS_BLOCK_SIZE];
+
+  for (int i = 0; i < SIN_COS_BLOCK_SIZE; i++){
+         input[i] = sin(i);
+  }
+
+  for (int i = 0; i < SIN_COS_BLOCK_SIZE; i++){
+    float ref_cos = ref_vco.cos ();
+    float new_cos = new_vco.cos ();
+    CPPUNIT_ASSERT_DOUBLES_EQUAL (ref_cos, new_cos, SIN_COS_TOLERANCE);
+
+    max_error = max_d (max_error, ref_cos-new_cos);
+
+    ref_vco.adjust_phase (input[i]);
+    new_vco.adjust_phase (input[i]);
+
+    CPPUNIT_ASSERT_DOUBLES_EQUAL (ref_vco.get_phase(), new_vco.get_phase(), SIN_COS_TOLERANCE);
+
+    max_phase_error = max_d (max_phase_error, ref_vco.get_phase()-new_vco.get_phase());
+  }
+  // printf ("Fxpt  max error %.9f, max phase error %.9f\n", max_error, max_phase_error);
+}
+
+
+void
+qa_gr_fxpt_vco::t1 ()
+{
+  gr_vco<float,float>  ref_vco;
+  gr_fxpt_vco          new_vco;
+  float                        ref_block[SIN_COS_BLOCK_SIZE];
+  float                        new_block[SIN_COS_BLOCK_SIZE];
+  float                        input[SIN_COS_BLOCK_SIZE];
+  double max_error = 0;
+
+  for (int i = 0; i < SIN_COS_BLOCK_SIZE; i++){
+         input[i] = sin(i);
+  }
+
+  ref_vco.cos (ref_block, input, SIN_COS_BLOCK_SIZE, SIN_COS_K, SIN_COS_AMPL);
+  new_vco.cos (new_block, input, SIN_COS_BLOCK_SIZE, SIN_COS_K, SIN_COS_AMPL);
+
+  for (int i = 0; i < SIN_COS_BLOCK_SIZE; i++){
+    CPPUNIT_ASSERT_DOUBLES_EQUAL (ref_block[i], new_block[i], SIN_COS_TOLERANCE);
+    max_error = max_d (max_error, ref_block[i]-new_block[i]);
+  }
+  CPPUNIT_ASSERT_DOUBLES_EQUAL (ref_vco.get_phase(), new_vco.get_phase(), SIN_COS_TOLERANCE);
+  // printf ("Fxpt  max error %.9f, max phase error %.9f\n", max_error, ref_vco.get_phase()-new_vco.get_phase());
+}
+
+void
+qa_gr_fxpt_vco::t2 ()
+{
+}
+
+void
+qa_gr_fxpt_vco::t3 ()
+{
+}
diff --git a/gnuradio-core/src/lib/general/qa_gr_fxpt_vco.h b/gnuradio-core/src/lib/general/qa_gr_fxpt_vco.h
new file mode 100644 (file)
index 0000000..80ea025
--- /dev/null
@@ -0,0 +1,48 @@
+/* -*- c++ -*- */
+/*
+ * 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 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.
+ */
+#ifndef INCLUDED_QA_GR_FXPT_VCO_H
+#define INCLUDED_QA_GR_FXPT_VCO_H
+
+
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/TestCase.h>
+
+class qa_gr_fxpt_vco : public CppUnit::TestCase {
+
+  CPPUNIT_TEST_SUITE (qa_gr_fxpt_vco);
+  CPPUNIT_TEST (t0);
+  CPPUNIT_TEST (t1);
+  CPPUNIT_TEST (t2);
+  CPPUNIT_TEST (t3);
+  CPPUNIT_TEST_SUITE_END ();
+
+ private:
+  void t0 ();
+  void t1 ();
+  void t2 ();
+  void t3 ();
+
+};
+
+#endif /* INCLUDED_QA_GR_FXPT_VCO_H */
+
+
diff --git a/gnuradio-core/src/lib/general/random.h b/gnuradio-core/src/lib/general/random.h
new file mode 100644 (file)
index 0000000..816aca3
--- /dev/null
@@ -0,0 +1,32 @@
+/* -*- 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 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.
+ */
+
+#ifndef _RANDOM_H_
+#define _RANDOM_H_
+
+// we use this because some systems (solaris) define RAND_MAX as 32767
+
+static const int RANDOM_MAX = 2147483647;
+
+#include <stdlib.h>
+
+#endif // _RANDOM_H_
diff --git a/gnuradio-core/src/lib/general/sine_table.h b/gnuradio-core/src/lib/general/sine_table.h
new file mode 100644 (file)
index 0000000..6983494
--- /dev/null
@@ -0,0 +1,1025 @@
+  // max_error =  2.353084136763606e-06
+  {  2.925817799165007e-09,  7.219194364267018e-09 },
+  {  2.925707643778599e-09,  2.526699001579799e-07 },
+  {  2.925487337153070e-09,  1.191140162167675e-06 },
+  {  2.925156887582842e-09,  3.284585035595589e-06 },
+  {  2.924716307509151e-09,  6.994872605695784e-06 },
+  {  2.924165613519592e-09,  1.278374920658798e-05 },
+  {  2.923504826347475e-09,  2.111280464718590e-05 },
+  {  2.922733970871080e-09,  3.244343744537165e-05 },
+  {  2.921853076112655e-09,  4.723682007436170e-05 },
+  {  2.920862175237416e-09,  6.595386421935634e-05 },
+  {  2.919761305552202e-09,  8.905518605213658e-05 },
+  {  2.918550508504146e-09,  1.170010715193098e-04 },
+  {  2.917229829679050e-09,  1.502514416517192e-04 },
+  {  2.915799318799769e-09,  1.892658178912071e-04 },
+  {  2.914259029724184e-09,  2.345032874456615e-04 },
+  {  2.912609020443340e-09,  2.864224686607020e-04 },
+  {  2.910849353079123e-09,  3.454814764261432e-04 },
+  {  2.908980093882049e-09,  4.121378876027343e-04 },
+  {  2.907001313228646e-09,  4.868487064877691e-04 },
+  {  2.904913085618902e-09,  5.700703303049837e-04 },
+  {  2.902715489673383e-09,  6.622585147355725e-04 },
+  {  2.900408608130373e-09,  7.638683394782519e-04 },
+  {  2.897992527842612e-09,  8.753541738578119e-04 },
+  {  2.895467339774186e-09,  9.971696424604937e-04 },
+  {  2.892833138996999e-09,  1.129767590823255e-03 },
+  {  2.890090024687216e-09,  1.273600051161478e-03 },
+  {  2.887238100121550e-09,  1.429118208142094e-03 },
+  {  2.884277472673313e-09,  1.596772364709564e-03 },
+  {  2.881208253808507e-09,  1.777011907950626e-03 },
+  {  2.878030559081432e-09,  1.970285275029487e-03 },
+  {  2.874744508130554e-09,  2.177039919152579e-03 },
+  {  2.871350224673798e-09,  2.397722275614272e-03 },
+  {  2.867847836504030e-09,  2.632777727878843e-03 },
+  {  2.864237475484149e-09,  2.882650573737405e-03 },
+  {  2.860519277542297e-09,  3.147783991507308e-03 },
+  {  2.856693382666432e-09,  3.428620006328931e-03 },
+  {  2.852759934899389e-09,  3.725599456482154e-03 },
+  {  2.848719082333207e-09,  4.039161959812243e-03 },
+  {  2.844570977103752e-09,  4.369745880190706e-03 },
+  {  2.840315775384800e-09,  4.717788294077374e-03 },
+  {  2.835953637382310e-09,  5.083724957128360e-03 },
+  {  2.831484727328322e-09,  5.467990270896617e-03 },
+  {  2.826909213474759e-09,  5.871017249604038e-03 },
+  {  2.822227268087134e-09,  6.293237486988512e-03 },
+  {  2.817439067438018e-09,  6.735081123237729e-03 },
+  {  2.812544791800534e-09,  7.196976811989608e-03 },
+  {  2.807544625441273e-09,  7.679351687456759e-03 },
+  {  2.802438756613836e-09,  8.182631331563162e-03 },
+  {  2.797227377551135e-09,  8.707239741274575e-03 },
+  {  2.791910684458716e-09,  9.253599295902304e-03 },
+  {  2.786488877507140e-09,  9.822130724578715e-03 },
+  {  2.780962160824228e-09,  1.041325307382490e-02 },
+  {  2.775330742487884e-09,  1.102738367513773e-02 },
+  {  2.769594834517682e-09,  1.166493811278924e-02 },
+  {  2.763754652867477e-09,  1.232633019159818e-02 },
+  {  2.757810417416620e-09,  1.301197190494069e-02 },
+  {  2.751762351962413e-09,  1.372227340270610e-02 },
+  {  2.745610684210923e-09,  1.445764295952962e-02 },
+  {  2.739355645769094e-09,  1.521848694296229e-02 },
+  {  2.732997472135539e-09,  1.600520978188769e-02 },
+  {  2.726536402691907e-09,  1.681821393496225e-02 },
+  {  2.719972680693777e-09,  1.765789985920713e-02 },
+  {  2.713306553261610e-09,  1.852466597868779e-02 },
+  {  2.706538271371373e-09,  1.941890865333146e-02 },
+  {  2.699668089844909e-09,  2.034102214787814e-02 },
+  {  2.692696267340880e-09,  2.129139860085272e-02 },
+  {  2.685623066344263e-09,  2.227042799383416e-02 },
+  {  2.678448753157212e-09,  2.327849812064098e-02 },
+  {  2.671173597888530e-09,  2.431599455681316e-02 },
+  {  2.663797874443630e-09,  2.538330062913108e-02 },
+  {  2.656321860514457e-09,  2.648079738524795e-02 },
+  {  2.648745837568575e-09,  2.760886356354952e-02 },
+  {  2.641070090839117e-09,  2.876787556300114e-02 },
+  {  2.633294909313421e-09,  2.995820741329835e-02 },
+  {  2.625420585722845e-09,  3.118023074495535e-02 },
+  {  2.617447416531143e-09,  3.243431475972608e-02 },
+  {  2.609375701923643e-09,  3.372082620101990e-02 },
+  {  2.601205745795833e-09,  3.504012932452527e-02 },
+  {  2.592937855741933e-09,  3.639258586895711e-02 },
+  {  2.584572343043400e-09,  3.777855502693250e-02 },
+  {  2.576109522656942e-09,  3.919839341605197e-02 },
+  {  2.567549713203028e-09,  4.065245505002102e-02 },
+  {  2.558893236953688e-09,  4.214109131001403e-02 },
+  {  2.550140419820252e-09,  4.366465091617666e-02 },
+  {  2.541291591341445e-09,  4.522347989919473e-02 },
+  {  2.532347084670572e-09,  4.681792157215026e-02 },
+  {  2.523307236563343e-09,  4.844831650239501e-02 },
+  {  2.514172387364900e-09,  5.011500248369893e-02 },
+  {  2.504942880997064e-09,  5.181831450849345e-02 },
+  {  2.495619064945627e-09,  5.355858474024022e-02 },
+  {  2.486201290246928e-09,  5.533614248606705e-02 },
+  {  2.476689911475047e-09,  5.715131416942842e-02 },
+  {  2.467085286727668e-09,  5.900442330315692e-02 },
+  {  2.457387777613798e-09,  6.089579046229943e-02 },
+  {  2.447597749239101e-09,  6.282573325755320e-02 },
+  {  2.437715570192557e-09,  6.479456630859221e-02 },
+  {  2.427741612532542e-09,  6.680260121764925e-02 },
+  {  2.417676251773166e-09,  6.885014654319160e-02 },
+  {  2.407519866869294e-09,  7.093750777401114e-02 },
+  {  2.397272840203310e-09,  7.306498730310884e-02 },
+  {  2.386935557569868e-09,  7.523288440214027e-02 },
+  {  2.376508408161815e-09,  7.744149519577415e-02 },
+  {  2.365991784555363e-09,  7.969111263635709e-02 },
+  {  2.355386082695641e-09,  8.198202647865405e-02 },
+  {  2.344691701881232e-09,  8.431452325495814e-02 },
+  {  2.333909044749407e-09,  8.668888625021409e-02 },
+  {  2.323038517261246e-09,  8.910539547731611e-02 },
+  {  2.312080528685971e-09,  9.156432765274414e-02 },
+  {  2.301035491585642e-09,  9.406595617227698e-02 },
+  {  2.289903821799651e-09,  9.661055108691619e-02 },
+  {  2.278685938428940e-09,  9.919837907903295e-02 },
+  {  2.267382263820762e-09,  1.018297034385580e-01 },
+  {  2.255993223551837e-09,  1.045047840397028e-01 },
+  {  2.244519246413220e-09,  1.072238773174577e-01 },
+  {  2.232960764393620e-09,  1.099872362446146e-01 },
+  {  2.221318212663309e-09,  1.127951103088245e-01 },
+  {  2.209592029557811e-09,  1.156477454898748e-01 },
+  {  2.197782656561395e-09,  1.185453842371912e-01 },
+  {  2.185890538290176e-09,  1.214882654476019e-01 },
+  {  2.173916122475606e-09,  1.244766244431883e-01 },
+  {  2.161859859947797e-09,  1.275106929493488e-01 },
+  {  2.149722204618256e-09,  1.305906990731841e-01 },
+  {  2.137503613462743e-09,  1.337168672820376e-01 },
+  {  2.125204546504321e-09,  1.368894183821595e-01 },
+  {  2.112825466795944e-09,  1.401085694976751e-01 },
+  {  2.100366840402933e-09,  1.433745340497602e-01 },
+  {  2.087829136385612e-09,  1.466875217359607e-01 },
+  {  2.075212826781308e-09,  1.500477385098620e-01 },
+  {  2.062518386587093e-09,  1.534553865607503e-01 },
+  {  2.049746293741359e-09,  1.569106642937665e-01 },
+  {  2.036897029106193e-09,  1.604137663100403e-01 },
+  {  2.023971076449323e-09,  1.639648833871233e-01 },
+  {  2.010968922425217e-09,  1.675642024598467e-01 },
+  {  1.997891056557933e-09,  1.712119066008896e-01 },
+  {  1.984737971221581e-09,  1.749081750021970e-01 },
+  {  1.971510161622434e-09,  1.786531829561379e-01 },
+  {  1.958208125780130e-09,  1.824471018371070e-01 },
+  {  1.944832364508511e-09,  1.862900990834311e-01 },
+  {  1.931383381397782e-09,  1.901823381790926e-01 },
+  {  1.917861682794392e-09,  1.941239786363039e-01 },
+  {  1.904267777782611e-09,  1.981151759777950e-01 },
+  {  1.890602178165317e-09,  2.021560817195309e-01 },
+  {  1.876865398444616e-09,  2.062468433536743e-01 },
+  {  1.863057955802572e-09,  2.103876043317229e-01 },
+  {  1.849180370081465e-09,  2.145785040479915e-01 },
+  {  1.835233163764673e-09,  2.188196778231083e-01 },
+  {  1.821216861956509e-09,  2.231112568880342e-01 },
+  {  1.807131992362945e-09,  2.274533683680190e-01 },
+  {  1.792979085271234e-09,  2.318461352671018e-01 },
+  {  1.778758673530482e-09,  2.362896764525300e-01 },
+  {  1.764471292530943e-09,  2.407841066397789e-01 },
+  {  1.750117480184598e-09,  2.453295363773890e-01 },
+  {  1.735697776904342e-09,  2.499260720324433e-01 },
+  {  1.721212725583874e-09,  2.545738157760434e-01 },
+  {  1.706662871577097e-09,  2.592728655691494e-01 },
+  {  1.692048762677849e-09,  2.640233151485341e-01 },
+  {  1.677370949099090e-09,  2.688252540131204e-01 },
+  {  1.662629983452104e-09,  2.736787674105404e-01 },
+  {  1.647826420726167e-09,  2.785839363237506e-01 },
+  {  1.632960818266680e-09,  2.835408374583758e-01 },
+  {  1.618033735755429e-09,  2.885495432295704e-01 },
+  {  1.603045735188609e-09,  2.936101217498361e-01 },
+  {  1.587997380855918e-09,  2.987226368167127e-01 },
+  {  1.572889239319430e-09,  3.038871479007593e-01 },
+  {  1.557721879392051e-09,  3.091037101339017e-01 },
+  {  1.542495872116447e-09,  3.143723742978435e-01 },
+  {  1.527211790743024e-09,  3.196931868130269e-01 },
+  {  1.511870210708909e-09,  3.250661897274744e-01 },
+  {  1.496471709615926e-09,  3.304914207062036e-01 },
+  {  1.481016867208896e-09,  3.359689130207621e-01 },
+  {  1.465506265353924e-09,  3.414986955389885e-01 },
+  {  1.449940488016384e-09,  3.470807927151147e-01 },
+  {  1.434320121238994e-09,  3.527152245800635e-01 },
+  {  1.418645753119802e-09,  3.584020067320109e-01 },
+  {  1.402917973789838e-09,  3.641411503272979e-01 },
+  {  1.387137375391042e-09,  3.699326620714776e-01 },
+  {  1.371304552054134e-09,  3.757765442106153e-01 },
+  {  1.355420099875958e-09,  3.816727945230153e-01 },
+  {  1.339484616897137e-09,  3.876214063110671e-01 },
+  {  1.323498703079580e-09,  3.936223683933865e-01 },
+  {  1.307462960283922e-09,  3.996756650972121e-01 },
+  {  1.291377992246768e-09,  4.057812762511174e-01 },
+  {  1.275244404558188e-09,  4.119391771778626e-01 },
+  {  1.259062804638585e-09,  4.181493386877248e-01 },
+  {  1.242833801715929e-09,  4.244117270719281e-01 },
+  {  1.226558006803155e-09,  4.307263040962509e-01 },
+  {  1.210236032674760e-09,  4.370930269951803e-01 },
+  {  1.193868493843725e-09,  4.435118484661861e-01 },
+  {  1.177456006538695e-09,  4.499827166641340e-01 },
+  {  1.160999188680582e-09,  4.565055751961679e-01 },
+  {  1.144498659859216e-09,  4.630803631168164e-01 },
+  {  1.127955041310214e-09,  4.697070149232604e-01 },
+  {  1.111368955891417e-09,  4.763854605510119e-01 },
+  {  1.094741028059551e-09,  4.831156253697562e-01 },
+  {  1.078071883846871e-09,  4.898974301794375e-01 },
+  {  1.061362150836978e-09,  4.967307912069362e-01 },
+  {  1.044612458142151e-09,  5.036156201023686e-01 },
+  {  1.027823436378632e-09,  5.105518239364775e-01 },
+  {  1.010995717643647e-09,  5.175393051975563e-01 },
+  {  9.941299354913699e-10,  5.245779617890562e-01 },
+  {  9.772267249089968e-10,  5.316676870274011e-01 },
+  {  9.602867222926046e-10,  5.388083696401416e-01 },
+  {  9.433105654240147e-10,  5.459998937639375e-01 },
+  {  9.262988934458084e-10,  5.532421389435711e-01 },
+  {  9.092523468378193e-10,  5.605349801305876e-01 },
+  {  8.921715673928355e-10,  5.678782876825250e-01 },
+  {  8.750571981926701e-10,  5.752719273622372e-01 },
+  {  8.579098835836508e-10,  5.827157603377209e-01 },
+  {  8.407302691522673e-10,  5.902096431821322e-01 },
+  {  8.235190017016133e-10,  5.977534278737073e-01 },
+  {  8.062767292259225e-10,  6.053469617967722e-01 },
+  {  7.890041008871165e-10,  6.129900877421282e-01 },
+  {  7.717017669898175e-10,  6.206826439083659e-01 },
+  {  7.543703789572603e-10,  6.284244639030392e-01 },
+  {  7.370105893063053e-10,  6.362153767444958e-01 },
+  {  7.196230516231919e-10,  6.440552068636356e-01 },
+  {  7.022084205389746e-10,  6.519437741060674e-01 },
+  {  6.847673517046416e-10,  6.598808937346672e-01 },
+  {  6.673005017664976e-10,  6.678663764322770e-01 },
+  {  6.498085283416530e-10,  6.759000283046127e-01 },
+  {  6.322920899929834e-10,  6.839816508836737e-01 },
+  {  6.147518462045659e-10,  6.921110411311926e-01 },
+  {  5.971884573565851e-10,  7.002879914425926e-01 },
+  {  5.796025847007168e-10,  7.085122896509806e-01 },
+  {  5.619948903351406e-10,  7.167837190315758e-01 },
+  {  5.443660371796048e-10,  7.251020583063744e-01 },
+  {  5.267166889504394e-10,  7.334670816491009e-01 },
+  {  5.090475101356742e-10,  7.418785586903696e-01 },
+  {  4.913591659698399e-10,  7.503362545232619e-01 },
+  {  4.736523224091392e-10,  7.588399297089872e-01 },
+  {  4.559276461062478e-10,  7.673893402829834e-01 },
+  {  4.381858043851147e-10,  7.759842377612828e-01 },
+  {  4.204274652161870e-10,  7.846243691469355e-01 },
+  {  4.026532971908398e-10,  7.933094769370790e-01 },
+  {  3.848639694963359e-10,  8.020392991300200e-01 },
+  {  3.670601518910503e-10,  8.108135692324444e-01 },
+  {  3.492425146784233e-10,  8.196320162675177e-01 },
+  {  3.314117286825031e-10,  8.284943647824689e-01 },
+  {  3.135684652223755e-10,  8.374003348569865e-01 },
+  {  2.957133960867535e-10,  8.463496421118015e-01 },
+  {  2.778471935089361e-10,  8.553419977173513e-01 },
+  {  2.599705301412391e-10,  8.643771084029740e-01 },
+  {  2.420840790301135e-10,  8.734546764660205e-01 },
+  {  2.241885135902046e-10,  8.825743997817682e-01 },
+  {  2.062845075795238e-10,  8.917359718130367e-01 },
+  {  1.883727350736140e-10,  9.009390816205823e-01 },
+  {  1.704538704408269e-10,  9.101834138731877e-01 },
+  {  1.525285883160648e-10,  9.194686488588080e-01 },
+  {  1.345975635762696e-10,  9.287944624950824e-01 },
+  {  1.166614713141648e-10,  9.381605263410157e-01 },
+  {  9.872098681369190e-11,  9.475665076080466e-01 },
+  {  8.077678552380464e-11,  9.570120691722380e-01 },
+  {  6.282954303364090e-11,  9.664968695860140e-01 },
+  {  4.487993504668797e-11,  9.760205630906909e-01 },
+  {  2.692863735553042e-11,  9.855827996289697e-01 },
+  {  8.976325816439114e-12,  9.951832248577780e-01 },
+  { -8.976323676304494e-12,  1.004821480161519e+00 },
+  { -2.692863521550168e-11,  1.014497202665280e+00 },
+  { -4.487993290681805e-11,  1.024210025248670e+00 },
+  { -6.282954089398273e-11,  1.033959576559617e+00 },
+  { -8.077678338451706e-11,  1.043745481028715e+00 },
+  { -9.872098467477489e-11,  1.053567358883467e+00 },
+  { -1.166614691757772e-10,  1.063424826163223e+00 },
+  { -1.345975614383584e-10,  1.073317494734013e+00 },
+  { -1.525285861788948e-10,  1.083244972303963e+00 },
+  { -1.704538683042922e-10,  1.093206862438572e+00 },
+  { -1.883727329379793e-10,  1.103202764576806e+00 },
+  { -2.062845054446831e-10,  1.113232274046796e+00 },
+  { -2.241885114563697e-10,  1.123294982082432e+00 },
+  { -2.420840768973375e-10,  1.133390475839767e+00 },
+  { -2.599705280096278e-10,  1.143518338413855e+00 },
+  { -2.778471913784365e-10,  1.153678148855860e+00 },
+  { -2.957133939575774e-10,  1.163869482190458e+00 },
+  { -3.135684630945758e-10,  1.174091909433296e+00 },
+  { -3.314117265561857e-10,  1.184344997608959e+00 },
+  { -3.492425125535882e-10,  1.194628309769018e+00 },
+  { -3.670601497678034e-10,  1.204941405010466e+00 },
+  { -3.848639673748360e-10,  1.215283838494269e+00 },
+  { -4.026532950710339e-10,  1.225655161464298e+00 },
+  { -4.204274630982869e-10,  1.236054921266445e+00 },
+  { -4.381858022691734e-10,  1.246482661367958e+00 },
+  { -4.559276439922654e-10,  1.256937921377146e+00 },
+  { -4.736523202972214e-10,  1.267420237063216e+00 },
+  { -4.913591638600925e-10,  1.277929140376502e+00 },
+  { -5.090475080282032e-10,  1.288464159468706e+00 },
+  { -5.267166868452449e-10,  1.299024818713528e+00 },
+  { -5.443660350768455e-10,  1.309610638727845e+00 },
+  { -5.619948882348695e-10,  1.320221136392390e+00 },
+  { -5.796025826029868e-10,  1.330855824873457e+00 },
+  { -5.971884552615020e-10,  1.341514213644420e+00 },
+  { -6.147518441122357e-10,  1.352195808507556e+00 },
+  { -6.322920879034590e-10,  1.362900111616144e+00 },
+  { -6.498085262549874e-10,  1.373626621496939e+00 },
+  { -6.673004996827436e-10,  1.384374833072571e+00 },
+  { -6.847673496239581e-10,  1.395144237684605e+00 },
+  { -7.022084184613616e-10,  1.405934323116231e+00 },
+  { -7.196230495488082e-10,  1.416744573616104e+00 },
+  { -7.370105872352039e-10,  1.427574469921397e+00 },
+  { -7.543703768894941e-10,  1.438423489281758e+00 },
+  { -7.717017649255453e-10,  1.449291105483472e+00 },
+  { -7.890040988262324e-10,  1.460176788873383e+00 },
+  { -8.062767271686383e-10,  1.471080006383765e+00 },
+  { -8.235189996479819e-10,  1.482000221556656e+00 },
+  { -8.407302671024475e-10,  1.492936894569018e+00 },
+  { -8.579098815375368e-10,  1.503889482257845e+00 },
+  { -8.750571961505266e-10,  1.514857438145604e+00 },
+  { -8.921715653546624e-10,  1.525840212465756e+00 },
+  { -9.092523448036167e-10,  1.536837252188703e+00 },
+  { -9.262988914157881e-10,  1.547848001047890e+00 },
+  { -9.433105633981766e-10,  1.558871899565883e+00 },
+  { -9.602867202711075e-10,  1.569908385081254e+00 },
+  { -9.772267228916820e-10,  1.580956891774897e+00 },
+  { -9.941299334786078e-10,  1.592016850697478e+00 },
+  { -1.010995715635332e-09,  1.603087689796053e+00 },
+  { -1.027823434374870e-09,  1.614168833942028e+00 },
+  { -1.044612456143047e-09,  1.625259704958335e+00 },
+  { -1.061362148842745e-09,  1.636359721647526e+00 },
+  { -1.078071881857297e-09,  1.647468299819543e+00 },
+  { -1.094741026074900e-09,  1.658584852320419e+00 },
+  { -1.111368953911690e-09,  1.669708789060341e+00 },
+  { -1.127955039335462e-09,  1.680839517042381e+00 },
+  { -1.144498657889600e-09,  1.691976440391624e+00 },
+  { -1.160999186716154e-09,  1.703118960383971e+00 },
+  { -1.177456004579561e-09,  1.714266475475616e+00 },
+  { -1.193868491889832e-09,  1.725418381332405e+00 },
+  { -1.210236030726319e-09,  1.736574070859850e+00 },
+  { -1.226558004860220e-09,  1.747732934232508e+00 },
+  { -1.242833799778447e-09,  1.758894358924547e+00 },
+  { -1.259062802706714e-09,  1.770057729740021e+00 },
+  { -1.275244402631982e-09,  1.781222428842935e+00 },
+  { -1.291377990326492e-09,  1.792387835788660e+00 },
+  { -1.307462958369363e-09,  1.803553327553897e+00 },
+  { -1.323498701170897e-09,  1.814718278568759e+00 },
+  { -1.339484614994490e-09,  1.825882060747428e+00 },
+  { -1.355420097979292e-09,  1.837044043519582e+00 },
+  { -1.371304550163662e-09,  1.848203593862598e+00 },
+  { -1.387137373506711e-09,  1.859360076332671e+00 },
+  { -1.402917971911754e-09,  1.870512853097495e+00 },
+  { -1.418645751248018e-09,  1.881661283967967e+00 },
+  { -1.434320119373722e-09,  1.892804726431080e+00 },
+  { -1.449940486157623e-09,  1.903942535681972e+00 },
+  { -1.465506263501516e-09,  1.915074064656886e+00 },
+  { -1.481016865363264e-09,  1.926198664066737e+00 },
+  { -1.496471707776859e-09,  1.937315682428795e+00 },
+  { -1.511870208876724e-09,  1.948424466101625e+00 },
+  { -1.527211788917509e-09,  1.959524359317042e+00 },
+  { -1.542495870297867e-09,  1.970614704215133e+00 },
+  { -1.557721877580406e-09,  1.981694840876775e+00 },
+  { -1.572889237514880e-09,  1.992764107358707e+00 },
+  { -1.587997379058514e-09,  2.003821839726753e+00 },
+  { -1.603045733398246e-09,  2.014867372090665e+00 },
+  { -1.618033733972424e-09,  2.025900036638798e+00 },
+  { -1.632960816490822e-09,  2.036919163671778e+00 },
+  { -1.647826418957721e-09,  2.047924081638631e+00 },
+  { -1.662629981691070e-09,  2.058914117170269e+00 },
+  { -1.677370947345626e-09,  2.069888595116115e+00 },
+  { -1.692048760931849e-09,  2.080846838577820e+00 },
+  { -1.706662869838827e-09,  2.091788168946183e+00 },
+  { -1.721212723853279e-09,  2.102711905935372e+00 },
+  { -1.735697775181424e-09,  2.113617367619504e+00 },
+  { -1.750117478469621e-09,  2.124503870468520e+00 },
+  { -1.764471290823748e-09,  2.135370729383332e+00 },
+  { -1.778758671831281e-09,  2.146217257733207e+00 },
+  { -1.792979083579974e-09,  2.157042767390815e+00 },
+  { -1.807131990679890e-09,  2.167846568770014e+00 },
+  { -1.821216860281448e-09,  2.178627970860822e+00 },
+  { -1.835233162097977e-09,  2.189386281268046e+00 },
+  { -1.849180368423027e-09,  2.200120806246095e+00 },
+  { -1.863057954152340e-09,  2.210830850737588e+00 },
+  { -1.876865396802907e-09,  2.221515718409926e+00 },
+  { -1.890602176531920e-09,  2.232174711691990e+00 },
+  { -1.904267776157843e-09,  2.242807131812679e+00 },
+  { -1.917861681178094e-09,  2.253412278837029e+00 },
+  { -1.931383379790273e-09,  2.263989451705295e+00 },
+  { -1.944832362909578e-09,  2.274537948269257e+00 },
+  { -1.958208124189984e-09,  2.285057065331676e+00 },
+  { -1.971510160041235e-09,  2.295546098682665e+00 },
+  { -1.984737969649064e-09,  2.306004343138794e+00 },
+  { -1.997891054994522e-09,  2.316431092581699e+00 },
+  { -2.010968920870647e-09,  2.326825639994779e+00 },
+  { -2.023971074903858e-09,  2.337187277503834e+00 },
+  { -2.036897027569834e-09,  2.347515296413520e+00 },
+  { -2.049746292214264e-09,  2.357808987247877e+00 },
+  { -2.062518385069210e-09,  2.368067639787542e+00 },
+  { -2.075212825272584e-09,  2.378290543109652e+00 },
+  { -2.087829134886364e-09,  2.388476985626922e+00 },
+  { -2.100366838912949e-09,  2.398626255125417e+00 },
+  { -2.112825465315542e-09,  2.408737638805759e+00 },
+  { -2.125204545033289e-09,  2.418810423320288e+00 },
+  { -2.137503612001452e-09,  2.428843894814472e+00 },
+  { -2.149722203166389e-09,  2.438837338964302e+00 },
+  { -2.161859858505829e-09,  2.448790041018174e+00 },
+  { -2.173916121043380e-09,  2.458701285834241e+00 },
+  { -2.185890536867478e-09,  2.468570357921585e+00 },
+  { -2.197782655148702e-09,  2.478396541480230e+00 },
+  { -2.209592028154913e-09,  2.488179120439544e+00 },
+  { -2.221318211270522e-09,  2.497917378500214e+00 },
+  { -2.232960763010574e-09,  2.507610599172123e+00 },
+  { -2.244519245040444e-09,  2.517258065817044e+00 },
+  { -2.255993222189014e-09,  2.526859061686102e+00 },
+  { -2.267382262468209e-09,  2.536412869962689e+00 },
+  { -2.278685937086658e-09,  2.545918773800664e+00 },
+  { -2.289903820467374e-09,  2.555376056366064e+00 },
+  { -2.301035490263848e-09,  2.564784000877677e+00 },
+  { -2.312080527374447e-09,  2.574141890646339e+00 },
+  { -2.323038515960257e-09,  2.583449009117307e+00 },
+  { -2.333909043458635e-09,  2.592704639909166e+00 },
+  { -2.344691700601153e-09,  2.601908066856634e+00 },
+  { -2.355386081425938e-09,  2.611058574048749e+00 },
+  { -2.365991783296513e-09,  2.620155445872768e+00 },
+  { -2.376508406913500e-09,  2.629197967052127e+00 },
+  { -2.386935556332088e-09,  2.638185422689490e+00 },
+  { -2.397272838976436e-09,  2.647117098307332e+00 },
+  { -2.407519865653114e-09,  2.655992279887846e+00 },
+  { -2.417676250567891e-09,  2.664810253915885e+00 },
+  { -2.427741611338014e-09,  2.673570307418169e+00 },
+  { -2.437715569009093e-09,  2.682271728006635e+00 },
+  { -2.447597748066437e-09,  2.690913803917100e+00 },
+  { -2.457387776452357e-09,  2.699495824053297e+00 },
+  { -2.467085285577292e-09,  2.708017078025636e+00 },
+  { -2.476689910335470e-09,  2.716476856194105e+00 },
+  { -2.486201289118733e-09,  2.724874449709689e+00 },
+  { -2.495619063828443e-09,  2.733209150554255e+00 },
+  { -2.504942879891263e-09,  2.741480251583985e+00 },
+  { -2.514172386270163e-09,  2.749687046568741e+00 },
+  { -2.523307235480146e-09,  2.757828830235740e+00 },
+  { -2.532347083598520e-09,  2.765904898308531e+00 },
+  { -2.541291590280960e-09,  2.773914547551261e+00 },
+  { -2.550140418771202e-09,  2.781857075807392e+00 },
+  { -2.558893235915887e-09,  2.789731782043156e+00 },
+  { -2.567549712176927e-09,  2.797537966388929e+00 },
+  { -2.576109521642196e-09,  2.805274930179221e+00 },
+  { -2.584572342040407e-09,  2.812941975996573e+00 },
+  { -2.592937854750428e-09,  2.820538407710556e+00 },
+  { -2.601205744816134e-09,  2.828063530521908e+00 },
+  { -2.609375700955458e-09,  2.835516651001539e+00 },
+  { -2.617447415574869e-09,  2.842897077134583e+00 },
+  { -2.625420584778350e-09,  2.850204118359573e+00 },
+  { -2.633294908380520e-09,  2.857437085611509e+00 },
+  { -2.641070089918234e-09,  2.864595291363663e+00 },
+  { -2.648745836659391e-09,  2.871678049666939e+00 },
+  { -2.656321859617343e-09,  2.878684676194483e+00 },
+  { -2.663797873558322e-09,  2.885614488280000e+00 },
+  { -2.671173597015318e-09,  2.892466804962122e+00 },
+  { -2.678448752295859e-09,  2.899240947023252e+00 },
+  { -2.685623065495139e-09,  2.905936237033475e+00 },
+  { -2.692696266503800e-09,  2.912551999389617e+00 },
+  { -2.699668089019767e-09,  2.919087560358171e+00 },
+  { -2.706538270558513e-09,  2.925542248116882e+00 },
+  { -2.713306552460767e-09,  2.931915392794031e+00 },
+  { -2.719972679905295e-09,  2.938206326512581e+00 },
+  { -2.726536401915442e-09,  2.944414383428562e+00 },
+  { -2.732997471371516e-09,  2.950538899775061e+00 },
+  { -2.739355645017194e-09,  2.956579213900666e+00 },
+  { -2.745610683471516e-09,  2.962534666313284e+00 },
+  { -2.751762351235315e-09,  2.968404599718795e+00 },
+  { -2.757810416701751e-09,  2.974188359063684e+00 },
+  { -2.763754652165128e-09,  2.979885291576143e+00 },
+  { -2.769594833827588e-09,  2.985494746805227e+00 },
+  { -2.775330741810390e-09,  2.991016076664491e+00 },
+  { -2.780962160159068e-09,  2.996448635469842e+00 },
+  { -2.786488876854607e-09,  3.001791779983262e+00 },
+  { -2.791910683818570e-09,  3.007044869450794e+00 },
+  { -2.797227376923695e-09,  3.012207265645876e+00 },
+  { -2.802438755998943e-09,  3.017278332907412e+00 },
+  { -2.807544624838820e-09,  3.022257438182037e+00 },
+  { -2.812544791210840e-09,  3.027143951064684e+00 },
+  { -2.817439066860792e-09,  3.031937243837070e+00 },
+  { -2.822227267522746e-09,  3.036636691510884e+00 },
+  { -2.826909212922864e-09,  3.041241671864994e+00 },
+  { -2.831484726789317e-09,  3.045751565488710e+00 },
+  { -2.835953636855826e-09,  3.050165755818853e+00 },
+  { -2.840315774871260e-09,  3.054483629182857e+00 },
+  { -2.844570976602957e-09,  3.058704574835744e+00 },
+  { -2.848719081844986e-09,  3.062827985002047e+00 },
+  { -2.852759934424164e-09,  3.066853254915581e+00 },
+  { -2.856693382203833e-09,  3.070779782857041e+00 },
+  { -2.860519277092708e-09,  3.074606970196721e+00 },
+  { -2.864237475047239e-09,  3.078334221430809e+00 },
+  { -2.867847836080156e-09,  3.081960944223928e+00 },
+  { -2.871350224262603e-09,  3.085486549445314e+00 },
+  { -2.874744507732462e-09,  3.088910451211251e+00 },
+  { -2.878030558696270e-09,  3.092232066921130e+00 },
+  { -2.881208253436038e-09,  3.095450817298478e+00 },
+  { -2.884277472313999e-09,  3.098566126429974e+00 },
+  { -2.887238099774968e-09,  3.101577421802070e+00 },
+  { -2.890090024353816e-09,  3.104484134342861e+00 },
+  { -2.892833138676371e-09,  3.107285698457308e+00 },
+  { -2.895467339466766e-09,  3.109981552069083e+00 },
+  { -2.897992527547963e-09,  3.112571136655481e+00 },
+  { -2.900408607848946e-09,  3.115053897289195e+00 },
+  { -2.902715489404992e-09,  3.117429282673042e+00 },
+  { -2.904913085363323e-09,  3.119696745180238e+00 },
+  { -2.907001312986328e-09,  3.121855740892224e+00 },
+  { -2.908980093652563e-09,  3.123905729634218e+00 },
+  { -2.910849352862924e-09,  3.125846175016163e+00 },
+  { -2.912609020239985e-09,  3.127676544466606e+00 },
+  { -2.914259029534118e-09,  3.129396309273659e+00 },
+  { -2.915799318622574e-09,  3.131004944618667e+00 },
+  { -2.917229829515169e-09,  3.132501929616775e+00 },
+  { -2.918550508353347e-09,  3.133886747350606e+00 },
+  { -2.919761305414294e-09,  3.135158884909254e+00 },
+  { -2.920862175112829e-09,  3.136317833424958e+00 },
+  { -2.921853076000972e-09,  3.137363088107359e+00 },
+  { -2.922733970772719e-09,  3.138294148283254e+00 },
+  { -2.923504826262027e-09,  3.139110517429204e+00 },
+  { -2.924165613447473e-09,  3.139811703211207e+00 },
+  { -2.924716307449950e-09,  3.140397217517018e+00 },
+  { -2.925156887536978e-09,  3.140866576495489e+00 },
+  { -2.925487337120335e-09,  3.141219300588825e+00 },
+  { -2.925707643758784e-09,  3.141454914570261e+00 },
+  { -2.925817799158535e-09,  3.141572947579352e+00 },
+  { -2.925817799171455e-09,  3.141572933154836e+00 },
+  { -2.925707643798390e-09,  3.141454409272987e+00 },
+  { -2.925487337185779e-09,  3.141216918378770e+00 },
+  { -2.925156887628892e-09,  3.140860007424112e+00 },
+  { -2.924716307568119e-09,  3.140383227898687e+00 },
+  { -2.924165613591896e-09,  3.139786135867868e+00 },
+  { -2.923504826432903e-09,  3.139068292003385e+00 },
+  { -2.922733970969412e-09,  3.138229261619561e+00 },
+  { -2.921853076224321e-09,  3.137268614707029e+00 },
+  { -2.920862175361976e-09,  3.136185925964038e+00 },
+  { -2.919761305690083e-09,  3.134980774833275e+00 },
+  { -2.918550508654911e-09,  3.133652745531368e+00 },
+  { -2.917229829843137e-09,  3.132201427085629e+00 },
+  { -2.915799318976726e-09,  3.130626413363146e+00 },
+  { -2.914259029914435e-09,  3.128927303107136e+00 },
+  { -2.912609020646661e-09,  3.127103699965947e+00 },
+  { -2.910849353295315e-09,  3.125155212527586e+00 },
+  { -2.908980094111509e-09,  3.123081454351802e+00 },
+  { -2.907001313470937e-09,  3.120882043999591e+00 },
+  { -2.904913085874448e-09,  3.118556605068443e+00 },
+  { -2.902715489941767e-09,  3.116104766219928e+00 },
+  { -2.900408608411958e-09,  3.113526161214776e+00 },
+  { -2.897992528137022e-09,  3.110820428940251e+00 },
+  { -2.895467340081818e-09,  3.107987213444579e+00 },
+  { -2.892833139317615e-09,  3.105026163964191e+00 },
+  { -2.890090025020589e-09,  3.101936934956479e+00 },
+  { -2.887238100468092e-09,  3.098719186130021e+00 },
+  { -2.884277473032614e-09,  3.095372582472161e+00 },
+  { -2.881208254180937e-09,  3.091896794282404e+00 },
+  { -2.878030559466594e-09,  3.088291497198199e+00 },
+  { -2.874744508528832e-09,  3.084556372228054e+00 },
+  { -2.871350225084755e-09,  3.080691105776848e+00 },
+  { -2.867847836928063e-09,  3.076695389678615e+00 },
+  { -2.864237475921086e-09,  3.072568921221621e+00 },
+  { -2.860519277991847e-09,  3.068311403179147e+00 },
+  { -2.856693383129018e-09,  3.063922543837792e+00 },
+  { -2.852759935374575e-09,  3.059402057023109e+00 },
+  { -2.848719082821403e-09,  3.054749662130841e+00 },
+  { -2.844570977604520e-09,  3.049965084150782e+00 },
+  { -2.840315775898525e-09,  3.045048053697736e+00 },
+  { -2.835953637908582e-09,  3.039998307034967e+00 },
+  { -2.831484727867511e-09,  3.034815586104635e+00 },
+  { -2.826909214026628e-09,  3.029499638550941e+00 },
+  { -2.822227268651470e-09,  3.024050217748861e+00 },
+  { -2.817439068015245e-09,  3.018467082830179e+00 },
+  { -2.812544792390175e-09,  3.012749998707001e+00 },
+  { -2.807544626043751e-09,  3.006898736100911e+00 },
+  { -2.802438757228650e-09,  3.000913071564665e+00 },
+  { -2.797227378178760e-09,  2.994792787510961e+00 },
+  { -2.791910685098702e-09,  2.988537672233504e+00 },
+  { -2.786488878159805e-09,  2.982147519935565e+00 },
+  { -2.780962161489413e-09,  2.975622130750641e+00 },
+  { -2.775330743165298e-09,  2.968961310769028e+00 },
+  { -2.769594835207775e-09,  2.962164872061613e+00 },
+  { -2.763754653569747e-09,  2.955232632701135e+00 },
+  { -2.757810418131543e-09,  2.948164416789036e+00 },
+  { -2.751762352689432e-09,  2.940960054474719e+00 },
+  { -2.745610684950541e-09,  2.933619381982341e+00 },
+  { -2.739355646520809e-09,  2.926142241629213e+00 },
+  { -2.732997472899722e-09,  2.918528481852205e+00 },
+  { -2.726536403468318e-09,  2.910777957226018e+00 },
+  { -2.719972681482232e-09,  2.902890528487386e+00 },
+  { -2.713306554062453e-09,  2.894866062556452e+00 },
+  { -2.706538272184154e-09,  2.886704432555728e+00 },
+  { -2.699668090670078e-09,  2.878405517834426e+00 },
+  { -2.692696268177908e-09,  2.869969203985464e+00 },
+  { -2.685623067193599e-09,  2.861395382869544e+00 },
+  { -2.678448754018380e-09,  2.852683952631486e+00 },
+  { -2.671173598761847e-09,  2.843834817723832e+00 },
+  { -2.663797875328991e-09,  2.834847888922988e+00 },
+  { -2.656321861411517e-09,  2.825723083350459e+00 },
+  { -2.648745838477759e-09,  2.816460324492298e+00 },
+  { -2.641070091759922e-09,  2.807059542215146e+00 },
+  { -2.633294910246296e-09,  2.797520672788269e+00 },
+  { -2.625420586667340e-09,  2.787843658897949e+00 },
+  { -2.617447417487602e-09,  2.778028449668942e+00 },
+  { -2.609375702891616e-09,  2.768075000678399e+00 },
+  { -2.601205746775692e-09,  2.757983273976943e+00 },
+  { -2.592937856733464e-09,  2.747753238101915e+00 },
+  { -2.584572344046340e-09,  2.737384868096553e+00 },
+  { -2.576109523671634e-09,  2.726878145526201e+00 },
+  { -2.567549714229129e-09,  2.716233058492422e+00 },
+  { -2.558893237991435e-09,  2.705449601651722e+00 },
+  { -2.550140420869302e-09,  2.694527776227857e+00 },
+  { -2.541291592402089e-09,  2.683467590030445e+00 },
+  { -2.532347085742440e-09,  2.672269057466213e+00 },
+  { -2.523307237646751e-09,  2.660932199557362e+00 },
+  { -2.514172388459584e-09,  2.649457043952206e+00 },
+  { -2.504942882102813e-09,  2.637843624941622e+00 },
+  { -2.495619066062810e-09,  2.626091983472908e+00 },
+  { -2.486201291375123e-09,  2.614202167160335e+00 },
+  { -2.476689912614465e-09,  2.602174230302269e+00 },
+  { -2.467085287878098e-09,  2.590008233889805e+00 },
+  { -2.457387778775451e-09,  2.577704245623143e+00 },
+  { -2.447597750411553e-09,  2.565262339920002e+00 },
+  { -2.437715571376127e-09,  2.552682597931055e+00 },
+  { -2.427741613727123e-09,  2.539965107548168e+00 },
+  { -2.417676252978335e-09,  2.527109963417675e+00 },
+  { -2.407519868085581e-09,  2.514117266951687e+00 },
+  { -2.397272841430131e-09,  2.500987126335739e+00 },
+  { -2.386935558807595e-09,  2.487719656543254e+00 },
+  { -2.376508409410024e-09,  2.474314979341178e+00 },
+  { -2.365991785814531e-09,  2.460773223303822e+00 },
+  { -2.355386083965131e-09,  2.447094523817833e+00 },
+  { -2.344691703161363e-09,  2.433279023095734e+00 },
+  { -2.333909046040126e-09,  2.419326870180582e+00 },
+  { -2.323038518562289e-09,  2.405238220956597e+00 },
+  { -2.312080529997549e-09,  2.391013238157397e+00 },
+  { -2.301035492907384e-09,  2.376652091371587e+00 },
+  { -2.289903823131822e-09,  2.362154957053137e+00 },
+  { -2.278685939771276e-09,  2.347522018525197e+00 },
+  { -2.267382265173420e-09,  2.332753465990296e+00 },
+  { -2.255993224914501e-09,  2.317849496533128e+00 },
+  { -2.244519247786155e-09,  2.302810314130351e+00 },
+  { -2.232960765776561e-09,  2.287636129652823e+00 },
+  { -2.221318214056095e-09,  2.272327160873552e+00 },
+  { -2.209592030960763e-09,  2.256883632472565e+00 },
+  { -2.197782657974034e-09,  2.241305776039511e+00 },
+  { -2.185890539712767e-09,  2.225593830081461e+00 },
+  { -2.173916123907886e-09,  2.209748040023618e+00 },
+  { -2.161859861389976e-09,  2.193768658216360e+00 },
+  { -2.149722206070124e-09,  2.177655943935795e+00 },
+  { -2.137503614923981e-09,  2.161410163388424e+00 },
+  { -2.125204547975352e-09,  2.145031589714984e+00 },
+  { -2.112825468276292e-09,  2.128520502989477e+00 },
+  { -2.100366841892917e-09,  2.111877190225612e+00 },
+  { -2.087829137884807e-09,  2.095101945374541e+00 },
+  { -2.075212828290086e-09,  2.078195069329960e+00 },
+  { -2.062518388104923e-09,  2.061156869925600e+00 },
+  { -2.049746295268559e-09,  2.043987661939897e+00 },
+  { -2.036897030642658e-09,  2.026687767092888e+00 },
+  { -2.023971077994576e-09,  2.009257514048162e+00 },
+  { -2.010968923979840e-09,  1.991697238413571e+00 },
+  { -1.997891058121344e-09,  1.974007282737320e+00 },
+  { -1.984737972794098e-09,  1.956187996511354e+00 },
+  { -1.971510163203686e-09,  1.938239736166060e+00 },
+  { -1.958208127370276e-09,  1.920162865072273e+00 },
+  { -1.944832366107339e-09,  1.901957753535934e+00 },
+  { -1.931383383005451e-09,  1.883624778799427e+00 },
+  { -1.917861684410531e-09,  1.865164325035177e+00 },
+  { -1.904267779407432e-09,  1.846576783346324e+00 },
+  { -1.890602179798714e-09,  1.827862551760622e+00 },
+  { -1.876865400086483e-09,  1.809022035228338e+00 },
+  { -1.863057957452539e-09,  1.790055645617624e+00 },
+  { -1.849180371740008e-09,  1.770963801711725e+00 },
+  { -1.835233165431475e-09,  1.751746929201178e+00 },
+  { -1.821216863631569e-09,  1.732405460681919e+00 },
+  { -1.807131994045840e-09,  1.712939835648088e+00 },
+  { -1.792979086962494e-09,  1.693350500488565e+00 },
+  { -1.778758675229683e-09,  1.673637908477153e+00 },
+  { -1.764471294238191e-09,  1.653802519770021e+00 },
+  { -1.750117481899733e-09,  1.633844801396848e+00 },
+  { -1.735697778626995e-09,  1.613765227254186e+00 },
+  { -1.721212727314574e-09,  1.593564278099856e+00 },
+  { -1.706662873315474e-09,  1.573242441540939e+00 },
+  { -1.692048764423848e-09,  1.552800212030258e+00 },
+  { -1.677370950852395e-09,  1.532238090855187e+00 },
+  { -1.662629985213192e-09,  1.511556586131055e+00 },
+  { -1.647826422494560e-09,  1.490756212788764e+00 },
+  { -1.632960820042537e-09,  1.469837492568651e+00 },
+  { -1.618033737538645e-09,  1.448800954008929e+00 },
+  { -1.603045736978760e-09,  1.427647132435469e+00 },
+  { -1.587997382653428e-09,  1.406376569953373e+00 },
+  { -1.572889241124034e-09,  1.384989815432507e+00 },
+  { -1.557721881203696e-09,  1.363487424499449e+00 },
+  { -1.542495873934815e-09,  1.341869959524515e+00 },
+  { -1.527211792568486e-09,  1.320137989611176e+00 },
+  { -1.511870212541253e-09,  1.298292090581491e+00 },
+  { -1.496471711454994e-09,  1.276332844965754e+00 },
+  { -1.481016869054634e-09,  1.254260841988828e+00 },
+  { -1.465506267206068e-09,  1.232076677556547e+00 },
+  { -1.449940489875303e-09,  1.209780954243628e+00 },
+  { -1.434320123104372e-09,  1.187374281276747e+00 },
+  { -1.418645754991533e-09,  1.164857274523495e+00 },
+  { -1.402917975667710e-09,  1.142230556475749e+00 },
+  { -1.387137377275425e-09,  1.119494756236361e+00 },
+  { -1.371304553944712e-09,  1.096650509501278e+00 },
+  { -1.355420101772623e-09,  1.073698458546610e+00 },
+  { -1.339484618799891e-09,  1.050639252211352e+00 },
+  { -1.323498704988051e-09,  1.027473545880543e+00 },
+  { -1.307462962198534e-09,  1.004202001471034e+00 },
+  { -1.291377994167204e-09,  9.808252874104182e-01 },
+  { -1.275244406484394e-09,  9.573440786237052e-01 },
+  { -1.259062806570190e-09,  9.337590565128454e-01 },
+  { -1.242833803653464e-09,  9.100709089414796e-01 },
+  { -1.226558008746195e-09,  8.862803302125812e-01 },
+  { -1.210236034623253e-09,  8.623880210538113e-01 },
+  { -1.193868495797618e-09,  8.383946885959868e-01 },
+  { -1.177456008497777e-09,  8.143010463544786e-01 },
+  { -1.160999190645010e-09,  7.901078142102129e-01 },
+  { -1.144498661828833e-09,  7.658157183877095e-01 },
+  { -1.127955043284965e-09,  7.414254914366063e-01 },
+  { -1.111368957870986e-09,  7.169378722095157e-01 },
+  { -1.094741030044308e-09,  6.923536058430697e-01 },
+  { -1.078071885836393e-09,  6.676734437331688e-01 },
+  { -1.061362152831423e-09,  6.428981435165511e-01 },
+  { -1.044612460141255e-09,  6.180284690466404e-01 },
+  { -1.027823438382183e-09,  5.930651903718045e-01 },
+  { -1.010995719652015e-09,  5.680090837138436e-01 },
+  { -9.941299375042378e-10,  5.428609314418970e-01 },
+  { -9.772267269262058e-10,  5.176215220520872e-01 },
+  { -9.602867243141016e-10,  4.922916501421032e-01 },
+  { -9.433105674499058e-10,  4.668721163885412e-01 },
+  { -9.262988954758817e-10,  4.413637275202624e-01 },
+  { -9.092523488719689e-10,  4.157672962958654e-01 },
+  { -8.921715694311144e-10,  3.900836414778084e-01 },
+  { -8.750572002347607e-10,  3.643135878065193e-01 },
+  { -8.579098856296589e-10,  3.384579659762392e-01 },
+  { -8.407302712022458e-10,  3.125176126069478e-01 },
+  { -8.235190037551917e-10,  2.864933702193017e-01 },
+  { -8.062767312831008e-10,  2.603860872080448e-01 },
+  { -7.890041029479477e-10,  2.341966178147619e-01 },
+  { -7.717017690542486e-10,  2.079258220999725e-01 },
+  { -7.543703810250266e-10,  1.815745659161734e-01 },
+  { -7.370105913774597e-10,  1.551437208801425e-01 },
+  { -7.196230536974697e-10,  1.286341643433767e-01 },
+  { -7.022084226165876e-10,  1.020467793657360e-01 },
+  { -6.847673537853251e-10,  7.538245468350446e-02 },
+  { -6.673005038502516e-10,  4.864208468284503e-02 },
+  { -6.498085304282128e-10,  2.182656936863137e-02 },
+  { -6.322920920826137e-10, -5.063185663820913e-03 },
+  { -6.147518482969490e-10, -3.202626926150343e-02 },
+  { -5.971884594516681e-10, -5.906176474160862e-02 },
+  { -5.796025867984469e-10, -8.616874992366363e-02 },
+  { -5.619948924353588e-10, -1.133462971605448e-01 },
+  { -5.443660392823640e-10, -1.405934733692621e-01 },
+  { -5.267166910556339e-10, -1.679093400638023e-01 },
+  { -5.090475122431451e-10, -1.952929533862739e-01 },
+  { -4.913591680795342e-10, -2.227433641394564e-01 },
+  { -4.736523245210571e-10, -2.502596178194491e-01 },
+  { -4.559276482202303e-10, -2.778407546490776e-01 },
+  { -4.381858065011618e-10, -3.054858096104932e-01 },
+  { -4.204274673340870e-10, -3.331938124792702e-01 },
+  { -4.026532993105397e-10, -3.609637878577768e-01 },
+  { -3.848639716178888e-10, -3.887947552098022e-01 },
+  { -3.670601540142443e-10, -4.166857288948674e-01 },
+  { -3.492425168032583e-10, -4.446357182029681e-01 },
+  { -3.314117308088734e-10, -4.726437273896633e-01 },
+  { -3.135684673501752e-10, -5.007087557112619e-01 },
+  { -2.957133982159296e-10, -5.288297974607742e-01 },
+  { -2.778471956393828e-10, -5.570058420037128e-01 },
+  { -2.599705322729564e-10, -5.852358738143247e-01 },
+  { -2.420840811628366e-10, -6.135188725122560e-01 },
+  { -2.241885157240923e-10, -6.418538128986450e-01 },
+  { -2.062845097142585e-10, -6.702396649949099e-01 },
+  { -1.883727372093546e-10, -6.986753940779493e-01 },
+  { -1.704538725773087e-10, -7.271599607197149e-01 },
+  { -1.525285904532877e-10, -7.556923208240308e-01 },
+  { -1.345975657140748e-10, -7.842714256651911e-01 },
+  { -1.166614734526054e-10, -8.128962219265712e-01 },
+  { -9.872098895260891e-11, -8.415656517393372e-01 },
+  { -8.077678766314517e-11, -8.702786527215916e-01 },
+  { -6.282954517324612e-11, -8.990341580176152e-01 },
+  { -4.487993718655790e-11, -9.278310963373758e-01 },
+  { -2.692863949561210e-11, -9.566683919968972e-01 },
+  { -8.976327956520795e-12, -9.855449649582175e-01 },
+  {  8.976321536169872e-12, -1.014459730869357e+00 },
+  {  2.692863307547294e-11, -1.043411601105914e+00 },
+  {  4.487993076694813e-11, -1.072399482811314e+00 },
+  {  6.282953875437751e-11, -1.101422278938424e+00 },
+  {  8.077678124517653e-11, -1.130478888291020e+00 },
+  {  9.872098253591082e-11, -1.159568205565684e+00 },
+  {  1.166614670373367e-10, -1.188689121393192e+00 },
+  {  1.345975593005002e-10, -1.217840522381901e+00 },
+  {  1.525285840416718e-10, -1.247021291159495e+00 },
+  {  1.704538661678104e-10, -1.276230306415868e+00 },
+  {  1.883727308022916e-10, -1.305466442946703e+00 },
+  {  2.062845033098954e-10, -1.334728571696106e+00 },
+  {  2.241885093225349e-10, -1.364015559800721e+00 },
+  {  2.420840747645085e-10, -1.393326270633325e+00 },
+  {  2.599705258779635e-10, -1.422659563847049e+00 },
+  {  2.778471892479898e-10, -1.452014295419243e+00 },
+  {  2.957133918284542e-10, -1.481389317696831e+00 },
+  {  3.135684609667761e-10, -1.510783479440191e+00 },
+  {  3.314117244297624e-10, -1.540195625869043e+00 },
+  {  3.492425104288060e-10, -1.569624598707558e+00 },
+  {  3.670601476445565e-10, -1.599069236228850e+00 },
+  {  3.848639652533361e-10, -1.628528373302631e+00 },
+  {  4.026532929512281e-10, -1.658000841439269e+00 },
+  {  4.204274609803869e-10, -1.687485468837799e+00 },
+  {  4.381858001531792e-10, -1.716981080430596e+00 },
+  {  4.559276418782829e-10, -1.746486497931567e+00 },
+  {  4.736523181853565e-10, -1.776000539882225e+00 },
+  {  4.913591617503452e-10, -1.805522021699094e+00 },
+  {  5.090475059206794e-10, -1.835049755721194e+00 },
+  {  5.267166847401562e-10, -1.864582551257262e+00 },
+  {  5.443660329740862e-10, -1.894119214633676e+00 },
+  {  5.619948861345454e-10, -1.923658549242818e+00 },
+  {  5.796025805053097e-10, -1.953199355591180e+00 },
+  {  5.971884531664190e-10, -1.982740431347091e+00 },
+  {  6.147518420199055e-10, -2.012280571390674e+00 },
+  {  6.322920858139346e-10, -2.041818567861395e+00 },
+  {  6.498085241682158e-10, -2.071353210208005e+00 },
+  {  6.673004975990425e-10, -2.100883285238127e+00 },
+  {  6.847673475432746e-10, -2.130407577166309e+00 },
+  {  7.022084163838545e-10, -2.159924867664933e+00 },
+  {  7.196230474743716e-10, -2.189433935913779e+00 },
+  {  7.370105851640495e-10, -2.218933558650552e+00 },
+  {  7.543703748217808e-10, -2.248422510220072e+00 },
+  {  7.717017628611672e-10, -2.277899562625407e+00 },
+  {  7.890040967654542e-10, -2.307363485579104e+00 },
+  {  8.062767251113011e-10, -2.336813046552684e+00 },
+  {  8.235189975944034e-10, -2.366247010829556e+00 },
+  {  8.407302650525749e-10, -2.395664141553858e+00 },
+  {  8.579098794915287e-10, -2.425063199784153e+00 },
+  {  8.750571941082773e-10, -2.454442944543319e+00 },
+  {  8.921715633164894e-10, -2.483802132872044e+00 },
+  {  9.092523427695200e-10, -2.513139519878584e+00 },
+  {  9.262988893857148e-10, -2.542453858792682e+00 },
+  {  9.433105613723914e-10, -2.571743901017465e+00 },
+  {  9.602867182493987e-10, -2.601008396180870e+00 },
+  {  9.772267208744730e-10, -2.630246092190425e+00 },
+  {  9.941299314658458e-10, -2.659455735283526e+00 },
+  {  1.010995713627070e-09, -2.688636070081818e+00 },
+  {  1.027823432371055e-09, -2.717785839644439e+00 },
+  {  1.044612454143997e-09, -2.746903785521352e+00 },
+  {  1.061362146848353e-09, -2.775988647805256e+00 },
+  {  1.078071879867828e-09, -2.805039165187255e+00 },
+  {  1.094741024090249e-09, -2.834054075009077e+00 },
+  {  1.111368951931856e-09, -2.863032113318052e+00 },
+  {  1.127955037360817e-09, -2.891972014920939e+00 },
+  {  1.144498655920037e-09, -2.920872513436805e+00 },
+  {  1.160999184751779e-09, -2.949732341353290e+00 },
+  {  1.177456002620215e-09, -2.978550230079517e+00 },
+  {  1.193868489936097e-09, -3.007324910002949e+00 },
+  {  1.210236028777826e-09, -3.036055110540183e+00 },
+  {  1.226558002917232e-09, -3.064739560196251e+00 },
+  {  1.242833797841123e-09, -3.093376986616735e+00 },
+  {  1.259062800774685e-09, -3.121966116643377e+00 },
+  {  1.275244400705935e-09, -3.150505676371791e+00 },
+  {  1.291377988406056e-09, -3.178994391202159e+00 },
+  {  1.307462956454857e-09, -3.207430985899192e+00 },
+  {  1.323498699262108e-09, -3.235814184645077e+00 },
+  {  1.339484613091842e-09, -3.264142711097884e+00 },
+  {  1.355420096082785e-09, -3.292415288443373e+00 },
+  {  1.371304548273191e-09, -3.320630639454825e+00 },
+  {  1.387137371622433e-09, -3.348787486547389e+00 },
+  {  1.402917970033511e-09, -3.376884551834256e+00 },
+  {  1.418645749376393e-09, -3.404920557184582e+00 },
+  {  1.434320117508396e-09, -3.432894224276359e+00 },
+  {  1.449940484298756e-09, -3.460804274656981e+00 },
+  {  1.465506261649108e-09, -3.488649429796768e+00 },
+  {  1.481016863517580e-09, -3.516428411149154e+00 },
+  {  1.496471705937951e-09, -3.544139940202303e+00 },
+  {  1.511870207044433e-09, -3.571782738540999e+00 },
+  {  1.527211787092206e-09, -3.599355527901174e+00 },
+  {  1.542495868479076e-09, -3.626857030226671e+00 },
+  {  1.557721875768920e-09, -3.654285967729458e+00 },
+  {  1.572889235710329e-09, -3.681641062941412e+00 },
+  {  1.587997377261005e-09, -3.708921038776707e+00 },
+  {  1.603045731607830e-09, -3.736124618586623e+00 },
+  {  1.618033732189314e-09, -3.763250526218862e+00 },
+  {  1.632960814715177e-09, -3.790297486071938e+00 },
+  {  1.647826417189275e-09, -3.817264223155802e+00 },
+  {  1.662629979930247e-09, -3.844149463148589e+00 },
+  {  1.677370945591844e-09, -3.870951932452996e+00 },
+  {  1.692048759186008e-09, -3.897670358257890e+00 },
+  {  1.706662868100504e-09, -3.924303468590212e+00 },
+  {  1.721212722122685e-09, -3.950849992378278e+00 },
+  {  1.735697773458400e-09, -3.977308659506432e+00 },
+  {  1.750117476754591e-09, -4.003678200876669e+00 },
+  {  1.764471289116712e-09, -4.029957348461003e+00 },
+  {  1.778758670132079e-09, -4.056144835364877e+00 },
+  {  1.792979081888926e-09, -4.082239395882965e+00 },
+  {  1.807131988996465e-09, -4.108239765556996e+00 },
+  {  1.821216858606652e-09, -4.134144681236933e+00 },
+  {  1.835233160431175e-09, -4.159952881133585e+00 },
+  {  1.849180366764537e-09, -4.185663104882633e+00 },
+  {  1.863057952502055e-09, -4.211274093599509e+00 },
+  {  1.876865395161145e-09, -4.236784589940537e+00 },
+  {  1.890602174898734e-09, -4.262193338157148e+00 },
+  {  1.904267774533022e-09, -4.287499084158302e+00 },
+  {  1.917861679562008e-09, -4.312700575567174e+00 },
+  {  1.931383378182392e-09, -4.337796561778708e+00 },
+  {  1.944832361310856e-09, -4.362785794021793e+00 },
+  {  1.958208122599839e-09, -4.387667025411434e+00 },
+  {  1.971510158459931e-09, -4.412439011013396e+00 },
+  {  1.984737968076495e-09, -4.437100507898339e+00 },
+  {  1.997891053431005e-09, -4.461650275204912e+00 },
+  {  2.010968919316289e-09, -4.486087074191693e+00 },
+  {  2.023971073358447e-09, -4.510409668301784e+00 },
+  {  2.036897026033634e-09, -4.534616823217992e+00 },
+  {  2.049746290686799e-09, -4.558707306921882e+00 },
+  {  2.062518383551274e-09, -4.582679889754607e+00 },
+  {  2.075212823764071e-09, -4.606533344469879e+00 },
+  {  2.087829133387063e-09, -4.630266446298172e+00 },
+  {  2.100366837422912e-09, -4.653877973001258e+00 },
+  {  2.112825463835087e-09, -4.677366704934605e+00 },
+  {  2.125204543562522e-09, -4.700731425099899e+00 },
+  {  2.137503610540056e-09, -4.723970919208608e+00 },
+  {  2.149722201714786e-09, -4.747083975738060e+00 },
+  {  2.161859857063438e-09, -4.770069385989595e+00 },
+  {  2.173916119610994e-09, -4.792925944149308e+00 },
+  {  2.185890535445098e-09, -4.815652447340950e+00 },
+  {  2.197782653735957e-09, -4.838247695689436e+00 },
+  {  2.209592026751962e-09, -4.860710492376411e+00 },
+  {  2.221318209877576e-09, -4.883039643700314e+00 },
+  {  2.232960761627846e-09, -4.905233959130168e+00 },
+  {  2.244519243667616e-09, -4.927292251368517e+00 },
+  {  2.255993220826402e-09, -4.949213336406265e+00 },
+  {  2.267382261115285e-09, -4.970996033581527e+00 },
+  {  2.278685935744269e-09, -4.992639165639563e+00 },
+  {  2.289903819135414e-09, -5.014141558784778e+00 },
+  {  2.301035488942000e-09, -5.035502042744443e+00 },
+  {  2.312080526062763e-09, -5.056719450823151e+00 },
+  {  2.323038514659161e-09, -5.077792619963239e+00 },
+  {  2.333909042168180e-09, -5.098720390796817e+00 },
+  {  2.344691699320969e-09, -5.119501607709159e+00 },
+  {  2.355386080156553e-09, -5.140135118892792e+00 },
+  {  2.365991782037187e-09, -5.160619776404897e+00 },
+  {  2.376508405665132e-09, -5.180954436227641e+00 },
+  {  2.386935555094626e-09, -5.201137958319343e+00 },
+  {  2.397272837749508e-09, -5.221169206676762e+00 },
+  {  2.407519864436774e-09, -5.241047049389645e+00 },
+  {  2.417676249362563e-09, -5.260770358700167e+00 },
+  {  2.427741610143750e-09, -5.280338011053974e+00 },
+  {  2.437715567825576e-09, -5.299748887163106e+00 },
+  {  2.447597746894037e-09, -5.319001872058887e+00 },
+  {  2.457387775290440e-09, -5.338095855149190e+00 },
+  {  2.467085284426756e-09, -5.357029730277389e+00 },
+  {  2.476689909196263e-09, -5.375802395772283e+00 },
+  {  2.486201287990485e-09, -5.394412754510426e+00 },
+  {  2.495619062711154e-09, -5.412859713968929e+00 },
+  {  2.504942878785408e-09, -5.431142186284682e+00 },
+  {  2.514172385175743e-09, -5.449259088303476e+00 },
+  {  2.523307234396791e-09, -5.467209341642627e+00 },
+  {  2.532347082526785e-09, -5.484991872743321e+00 },
+  {  2.541291589219998e-09, -5.502605612925014e+00 },
+  {  2.550140417722072e-09, -5.520049498445633e+00 },
+  {  2.558893234878378e-09, -5.537322470548212e+00 },
+  {  2.567549711150773e-09, -5.554423475524196e+00 },
+  {  2.576109520627371e-09, -5.571351464763084e+00 },
+  {  2.584572341037361e-09, -5.588105394812198e+00 },
+  {  2.592937853759161e-09, -5.604684227423386e+00 },
+  {  2.601205743836355e-09, -5.621086929615246e+00 },
+  {  2.609375699987564e-09, -5.637312473723475e+00 },
+  {  2.617447414618146e-09, -5.653359837454964e+00 },
+  {  2.625420583833750e-09, -5.669228003945694e+00 },
+  {  2.633294907447937e-09, -5.684915961806963e+00 },
+  {  2.641070088997271e-09, -5.700422705186584e+00 },
+  {  2.648745835750128e-09, -5.715747233817712e+00 },
+  {  2.656321858720176e-09, -5.730888553077074e+00 },
+  {  2.663797872673252e-09, -5.745845674030161e+00 },
+  {  2.671173596142054e-09, -5.760617613492118e+00 },
+  {  2.678448751434797e-09, -5.775203394076705e+00 },
+  {  2.685623064645538e-09, -5.789602044248679e+00 },
+  {  2.692696265666640e-09, -5.803812598380606e+00 },
+  {  2.699668088194915e-09, -5.817834096797069e+00 },
+  {  2.706538269745573e-09, -5.831665585834668e+00 },
+  {  2.713306551659817e-09, -5.845306117889361e+00 },
+  {  2.719972679116734e-09, -5.858754751472542e+00 },
+  {  2.726536401139295e-09, -5.872010551255358e+00 },
+  {  2.732997470607439e-09, -5.885072588127400e+00 },
+  {  2.739355644265558e-09, -5.897939939244211e+00 },
+  {  2.745610682731633e-09, -5.910611688078208e+00 },
+  {  2.751762350508137e-09, -5.923086924473290e+00 },
+  {  2.757810415987146e-09, -5.935364744687794e+00 },
+  {  2.763754651462700e-09, -5.947444251452243e+00 },
+  {  2.769594833137415e-09, -5.959324554015538e+00 },
+  {  2.775330741132843e-09, -5.971004768198829e+00 },
+  {  2.780962159494174e-09, -5.982484016437981e+00 },
+  {  2.786488876202047e-09, -5.993761427840588e+00 },
+  {  2.791910683178690e-09, -6.004836138231525e+00 },
+  {  2.797227376295779e-09, -6.015707290202086e+00 },
+  {  2.802438755383971e-09, -6.026374033162623e+00 },
+  {  2.807544624236659e-09, -6.036835523383457e+00 },
+  {  2.812544790621093e-09, -6.047090924050914e+00 },
+  {  2.817439066283459e-09, -6.057139405311101e+00 },
+  {  2.822227266958278e-09, -6.066980144322601e+00 },
+  {  2.826909212371261e-09, -6.076612325295799e+00 },
+  {  2.831484726250221e-09, -6.086035139548830e+00 },
+  {  2.835953636329660e-09, -6.095247785550617e+00 },
+  {  2.840315774357203e-09, -6.104249468967751e+00 },
+  {  2.844570976102082e-09, -6.113039402715685e+00 },
+  {  2.848719081357095e-09, -6.121616806996519e+00 },
+  {  2.852759933948860e-09, -6.129980909353977e+00 },
+  {  2.856693381741114e-09, -6.138130944714082e+00 },
+  {  2.860519276643053e-09, -6.146066155436312e+00 },
+  {  2.864237474610633e-09, -6.153785791350256e+00 },
+  {  2.867847835656203e-09, -6.161289109809551e+00 },
+  {  2.871350223851726e-09, -6.168575375732642e+00 },
+  {  2.874744507333867e-09, -6.175643861647406e+00 },
+  {  2.878030558310989e-09, -6.182493847739853e+00 },
+  {  2.881208253063899e-09, -6.189124621889823e+00 },
+  {  2.884277471954592e-09, -6.195535479723423e+00 },
+  {  2.887238099428306e-09, -6.201725724651554e+00 },
+  {  2.890090024020323e-09, -6.207694667918394e+00 },
+  {  2.892833138356060e-09, -6.213441628635915e+00 },
+  {  2.895467339159240e-09, -6.218965933835304e+00 },
+  {  2.897992527253659e-09, -6.224266918505075e+00 },
+  {  2.900408607567016e-09, -6.229343925633495e+00 },
+  {  2.902715489136496e-09, -6.234196306254763e+00 },
+  {  2.904913085108075e-09, -6.238823419482017e+00 },
+  {  2.907001312743911e-09, -6.243224632557377e+00 },
+  {  2.908980093422997e-09, -6.247399320887848e+00 },
+  {  2.910849352646620e-09, -6.251346868091392e+00 },
+  {  2.912609020036956e-09, -6.255066666028537e+00 },
+  {  2.914259029343965e-09, -6.258558114851525e+00 },
+  {  2.915799318445710e-09, -6.261820623039620e+00 },
+  {  2.917229829350759e-09, -6.264853607438842e+00 },
+  {  2.918550508202463e-09, -6.267656493305673e+00 },
+  {  2.919761305276718e-09, -6.270228714337005e+00 },
+  {  2.920862174988150e-09, -6.272569712717951e+00 },
+  {  2.921853075889193e-09, -6.274678939154603e+00 },
+  {  2.922733970674264e-09, -6.276555852917634e+00 },
+  {  2.923504826176907e-09, -6.278199921870962e+00 },
+  {  2.924165613375264e-09, -6.279610622518139e+00 },
+  {  2.924716307391075e-09, -6.280787440034993e+00 },
+  {  2.925156887490598e-09, -6.281729868306345e+00 },
+  {  2.925487337087508e-09, -6.282437409966992e+00 },
+  {  2.925707643739298e-09, -6.282909576428774e+00 },
+  {  2.925817799151970e-09, -6.283145887925411e+00 },
diff --git a/gnuradio-core/src/lib/io/Makefile.am b/gnuradio-core/src/lib/io/Makefile.am
new file mode 100644 (file)
index 0000000..e390e13
--- /dev/null
@@ -0,0 +1,96 @@
+#
+# Copyright 2001,2003,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.
+# 
+
+include $(top_srcdir)/Makefile.common
+
+
+INCLUDES = $(STD_DEFINES_AND_INCLUDES)
+
+noinst_LTLIBRARIES = libio.la
+
+
+libio_la_SOURCES =                     \
+       gr_file_sink.cc                 \
+       gr_file_source.cc               \
+       gr_file_descriptor_sink.cc      \
+       gr_file_descriptor_source.cc    \
+       gr_message_sink.cc              \
+       gr_message_source.cc            \
+       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                     \
+       i2c_bbio_pp.cc                  \
+       microtune_4702.cc               \
+       microtune_4937.cc               \
+       microtune_4702_eval_board.cc    \
+       microtune_4937_eval_board.cc    \
+       microtune_xxxx.cc               \
+       microtune_xxxx_eval_board.cc    \
+       ppio.cc                         \
+       ppio_ppdev.cc                   \
+       sdr_1000.cc                     
+
+grinclude_HEADERS =                    \
+       gr_file_sink.h                  \
+       gr_file_source.h                \
+       gr_file_descriptor_sink.h       \
+       gr_file_descriptor_source.h     \
+       gr_message_sink.h               \
+       gr_message_source.h             \
+       gr_oscope_guts.h                \
+       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                      \
+       i2c_bbio_pp.h                   \
+       microtune_4702.h                \
+       microtune_4937.h                \
+       microtune_4702_eval_board.h     \
+       microtune_4937_eval_board.h     \
+       microtune_eval_board_defs.h     \
+       microtune_xxxx.h                \
+       microtune_xxxx_eval_board.h     \
+       ppio.h                          \
+       ppio_ppdev.h                    \
+       sdr_1000.h                      
+
+
+swiginclude_HEADERS =                  \
+       io.i                            \
+       gr_file_sink.i                  \
+       gr_file_source.i                \
+       gr_file_descriptor_sink.i       \
+       gr_file_descriptor_source.i     \
+       gr_message_sink.i               \
+       gr_message_source.i             \
+       gr_oscope_sink.i                \
+       microtune_xxxx_eval_board.i     \
+       microtune_4702_eval_board.i     \
+       microtune_4937_eval_board.i     \
+       ppio.i                          \
+       sdr_1000.i                      
diff --git a/gnuradio-core/src/lib/io/gr_file_descriptor_sink.cc b/gnuradio-core/src/lib/io/gr_file_descriptor_sink.cc
new file mode 100644 (file)
index 0000000..6a0b1ca
--- /dev/null
@@ -0,0 +1,83 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_file_descriptor_sink.h>
+#include <gr_io_signature.h>
+#include <cstdio>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdexcept>
+
+
+gr_file_descriptor_sink::gr_file_descriptor_sink (size_t itemsize, int fd)
+  : gr_sync_block ("file_descriptor_sink",
+                  gr_make_io_signature (1, 1, itemsize),
+                  gr_make_io_signature (0, 0, 0)),
+    d_itemsize (itemsize), d_fd (fd)
+{
+}
+
+gr_file_descriptor_sink_sptr
+gr_make_file_descriptor_sink (size_t itemsize, int fd)
+{
+  return gr_file_descriptor_sink_sptr (new gr_file_descriptor_sink (itemsize, fd));
+}
+
+gr_file_descriptor_sink::~gr_file_descriptor_sink ()
+{
+  close (d_fd);
+}
+
+int 
+gr_file_descriptor_sink::work (int noutput_items,
+                              gr_vector_const_void_star &input_items,
+                              gr_vector_void_star &output_items)
+{
+  char *inbuf = (char *) input_items[0];
+  unsigned long byte_size = noutput_items * d_itemsize;
+
+  while (byte_size > 0){
+    ssize_t    r;
+
+    r = write (d_fd, inbuf, byte_size);
+    if (r == -1){
+      if (errno == EINTR)
+       continue;
+      else {
+       perror ("gr_file_descriptor_sink");
+       return -1;              // indicate we're done
+      }
+    }
+    else {
+      byte_size -= r;
+      inbuf += r;
+    }
+  }
+
+  return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/io/gr_file_descriptor_sink.h b/gnuradio-core/src/lib/io/gr_file_descriptor_sink.h
new file mode 100644 (file)
index 0000000..a811ce7
--- /dev/null
@@ -0,0 +1,58 @@
+/* -*- 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 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.
+ */
+
+#ifndef INCLUDED_GR_FILE_DESCRIPTOR_SINK_H
+#define INCLUDED_GR_FILE_DESCRIPTOR_SINK_H
+
+#include <gr_sync_block.h>
+
+class gr_file_descriptor_sink;
+typedef boost::shared_ptr<gr_file_descriptor_sink> gr_file_descriptor_sink_sptr;
+
+gr_file_descriptor_sink_sptr gr_make_file_descriptor_sink (size_t itemsize, int fd);
+
+/*!
+ * \brief Write stream to file descriptor.
+ * \ingroup sink
+ */
+
+class gr_file_descriptor_sink : public gr_sync_block
+{
+  friend gr_file_descriptor_sink_sptr gr_make_file_descriptor_sink (size_t itemsize, int fd);
+
+ private:
+  size_t       d_itemsize;
+  int          d_fd;
+
+ protected:
+  gr_file_descriptor_sink (size_t itemsize, int fd);
+
+ public:
+  ~gr_file_descriptor_sink ();
+
+  int work (int noutput_items,
+           gr_vector_const_void_star &input_items,
+           gr_vector_void_star &output_items);
+};
+
+
+#endif /* INCLUDED_GR_FILE_DESCRIPTOR_SINK_H */
diff --git a/gnuradio-core/src/lib/io/gr_file_descriptor_sink.i b/gnuradio-core/src/lib/io/gr_file_descriptor_sink.i
new file mode 100644 (file)
index 0000000..e058186
--- /dev/null
@@ -0,0 +1,35 @@
+/* -*- 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 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.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,file_descriptor_sink)
+
+gr_file_descriptor_sink_sptr 
+gr_make_file_descriptor_sink (size_t itemsize, int fd);
+
+class gr_file_descriptor_sink : public gr_sync_block
+{
+ protected:
+  gr_file_descriptor_sink (size_t itemsize, int fd);
+
+ public:
+  ~gr_file_descriptor_sink ();
+};
diff --git a/gnuradio-core/src/lib/io/gr_file_descriptor_source.cc b/gnuradio-core/src/lib/io/gr_file_descriptor_source.cc
new file mode 100644 (file)
index 0000000..38b9da0
--- /dev/null
@@ -0,0 +1,146 @@
+/* -*- c++ -*- */
+/*
+ * 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_file_descriptor_source.h>
+#include <gr_io_signature.h>
+#include <cstdio>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdexcept>
+
+
+gr_file_descriptor_source::gr_file_descriptor_source (size_t itemsize,
+                                                     int fd,
+                                                     bool repeat)
+  : gr_sync_block ("file_descriptor_source",
+                  gr_make_io_signature (0, 0, 0),
+                  gr_make_io_signature (1, 1, itemsize)),
+    d_itemsize (itemsize), d_fd (fd), d_repeat (repeat),
+    d_residue (new unsigned char[itemsize]), d_residue_len (0)
+{
+}
+
+// public constructor that returns a shared_ptr
+
+gr_file_descriptor_source_sptr
+gr_make_file_descriptor_source (size_t itemsize, int fd, bool repeat)
+{
+  return gr_file_descriptor_source_sptr (
+              new gr_file_descriptor_source (itemsize, fd, repeat));
+}
+
+gr_file_descriptor_source::~gr_file_descriptor_source ()
+{
+  close (d_fd);
+  delete [] d_residue;
+}
+
+int
+gr_file_descriptor_source::work (int noutput_items,
+                                gr_vector_const_void_star &input_items,
+                                gr_vector_void_star &output_items)
+{
+  assert (noutput_items > 0);
+
+  char *o = (char *) output_items[0];
+  int nread = 0;
+
+  while (1){
+    int r = read_items (o, noutput_items - nread);
+    if (r == -1){
+      if (errno == EINTR)
+       continue;
+      else {
+       perror ("file_descriptor_source[read]");
+       return -1;
+      }
+    }
+    else if (r == 0){    // end of file
+      if (!d_repeat)
+       break;
+      else {
+       flush_residue ();
+       if (lseek (d_fd, 0, SEEK_SET) == -1){
+         perror ("file_descriptor_source[lseek]");
+         return -1;
+       }
+      }
+    }
+    else {
+      o += r * d_itemsize;
+      nread += r;
+      break;
+    }
+  }
+
+  if (nread == 0)      // EOF
+    return -1;
+
+  return nread;
+}
+
+int
+gr_file_descriptor_source::read_items (char *buf, int nitems)
+{
+  assert (nitems > 0);
+  assert (d_residue_len < d_itemsize);
+
+  int nbytes_read = 0;
+
+  if (d_residue_len > 0){
+    memcpy (buf, d_residue, d_residue_len);
+    nbytes_read = d_residue_len;
+    d_residue_len = 0;
+  }
+
+  int r = read (d_fd, buf + nbytes_read, nitems * d_itemsize - nbytes_read);
+  if (r <= 0){
+    handle_residue (buf, nbytes_read);
+    return r;
+  }
+
+  r = handle_residue (buf, r + nbytes_read);
+
+  if (r == 0)                  // block until we get something
+    return read_items (buf, nitems);
+  
+  return r;
+}  
+
+int
+gr_file_descriptor_source::handle_residue (char *buf, int nbytes_read)
+{
+  assert (nbytes_read >= 0);
+  int nitems_read = nbytes_read / d_itemsize;
+  d_residue_len = nbytes_read % d_itemsize;
+  if (d_residue_len > 0){
+    // fprintf (stderr, "handle_residue: %d\n", d_residue_len);
+    memcpy (d_residue, buf + nbytes_read - d_residue_len, d_residue_len);
+  }
+  return nitems_read;
+}
diff --git a/gnuradio-core/src/lib/io/gr_file_descriptor_source.h b/gnuradio-core/src/lib/io/gr_file_descriptor_source.h
new file mode 100644 (file)
index 0000000..9f678dc
--- /dev/null
@@ -0,0 +1,67 @@
+/* -*- 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 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.
+ */
+
+#ifndef INCLUDED_GR_FILE_DESCRIPTOR_SOURCE_H
+#define INCLUDED_GR_FILE_DESCRIPTOR_SOURCE_H
+
+#include <gr_sync_block.h>
+
+class gr_file_descriptor_source;
+typedef boost::shared_ptr<gr_file_descriptor_source> gr_file_descriptor_source_sptr;
+
+gr_file_descriptor_source_sptr
+gr_make_file_descriptor_source (size_t itemsize, int fd, bool repeat = false);
+
+/*!
+ * \brief Read stream from file descriptor.
+ * \ingroup source
+ */
+
+class gr_file_descriptor_source : public gr_sync_block
+{
+  friend gr_file_descriptor_source_sptr
+  gr_make_file_descriptor_source (size_t itemsize, int fd, bool repeat);
+ private:
+  size_t        d_itemsize;
+  int           d_fd;
+  bool          d_repeat;
+
+  unsigned char        *d_residue;
+  unsigned long         d_residue_len;
+
+ protected:
+  gr_file_descriptor_source (size_t itemsize, int fd, bool repeat);
+
+  int read_items (char *buf, int nitems);
+  int handle_residue (char *buf, int nbytes_read);
+  void flush_residue () { d_residue_len = 0; }
+
+
+ public:
+  ~gr_file_descriptor_source ();
+
+  int work (int noutput_items,
+           gr_vector_const_void_star &input_items,
+           gr_vector_void_star &output_items);
+};
+
+#endif /* INCLUDED_GR_FILE_DESCRIPTOR_SOURCE_H */
diff --git a/gnuradio-core/src/lib/io/gr_file_descriptor_source.i b/gnuradio-core/src/lib/io/gr_file_descriptor_source.i
new file mode 100644 (file)
index 0000000..ba9b389
--- /dev/null
@@ -0,0 +1,35 @@
+/* -*- 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 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.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,file_descriptor_source)
+
+gr_file_descriptor_source_sptr 
+gr_make_file_descriptor_source (size_t itemsize, int fd, bool repeat=false);
+
+class gr_file_descriptor_source : public gr_sync_block
+{
+ protected:
+  gr_file_descriptor_source (size_t itemsize, int fd, bool repeat);
+
+ public:
+  ~gr_file_descriptor_source ();
+};
diff --git a/gnuradio-core/src/lib/io/gr_file_sink.cc b/gnuradio-core/src/lib/io/gr_file_sink.cc
new file mode 100644 (file)
index 0000000..d22488b
--- /dev/null
@@ -0,0 +1,144 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_file_sink.h>
+#include <gr_io_signature.h>
+#include <cstdio>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdexcept>
+
+// win32 (mingw/msvc) specific
+#ifdef HAVE_IO_H
+#include <io.h>
+#endif
+#ifdef O_BINARY
+#define        OUR_O_BINARY O_BINARY
+#else
+#define        OUR_O_BINARY 0
+#endif
+
+// should be handled via configure
+#ifdef O_LARGEFILE
+#define        OUR_O_LARGEFILE O_LARGEFILE
+#else
+#define        OUR_O_LARGEFILE 0
+#endif
+
+gr_file_sink::gr_file_sink(size_t itemsize, const char *filename)
+  : gr_sync_block ("file_sink",
+                  gr_make_io_signature(1, 1, itemsize),
+                  gr_make_io_signature(0, 0, 0)),
+    d_itemsize(itemsize), d_fp(0), d_new_fp(0), d_updated(false)
+{
+  if (!open(filename))
+    throw std::runtime_error ("can't open file");
+}
+
+gr_file_sink_sptr
+gr_make_file_sink (size_t itemsize, const char *filename)
+{
+  return gr_file_sink_sptr (new gr_file_sink (itemsize, filename));
+}
+
+gr_file_sink::~gr_file_sink ()
+{
+  close();
+  if (d_fp){
+    fclose((FILE *) d_fp);
+    d_fp = 0;
+  }
+}
+
+bool
+gr_file_sink::open(const char *filename)
+{
+  omni_mutex_lock      l(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;
+  if ((fd = ::open (filename,
+                   O_WRONLY|O_CREAT|O_TRUNC|OUR_O_LARGEFILE|OUR_O_BINARY, 0664)) < 0){
+    perror (filename);
+    return false;
+  }
+
+  if (d_new_fp){               // if we've already got a new one open, close it
+    fclose((FILE *) d_new_fp);
+    d_new_fp = 0;
+  }
+
+  if ((d_new_fp = fdopen (fd, "wb")) == NULL){
+    perror (filename);
+    ::close(fd);               // don't leak file descriptor if fdopen fails.
+  }
+
+  d_updated = true;
+  return d_new_fp != 0;
+}
+
+void
+gr_file_sink::close()
+{
+  omni_mutex_lock      l(d_mutex);     // hold mutex for duration of this function
+
+  if (d_new_fp){
+    fclose((FILE *) d_new_fp);
+    d_new_fp = 0;
+  }
+  d_updated = true;
+}
+
+int 
+gr_file_sink::work (int noutput_items,
+                   gr_vector_const_void_star &input_items,
+                   gr_vector_void_star &output_items)
+{
+  char *inbuf = (char *) input_items[0];
+  int  nwritten = 0;
+
+  if (d_updated){
+    omni_mutex_lock    l(d_mutex);     // hold mutex for duration of this block
+    if (d_fp)
+      fclose((FILE *)d_fp);
+    d_fp = d_new_fp;                   // install new file pointer
+    d_new_fp = 0;
+    d_updated = false;
+  }
+  
+  if (!d_fp)
+    return noutput_items;              // drop output on the floor
+
+  while (nwritten < noutput_items){
+    int count = fwrite (inbuf, d_itemsize, noutput_items - nwritten, (FILE *) d_fp);
+    if (count == 0)    // FIXME add error handling
+      break;
+    nwritten += count;
+    inbuf += count * d_itemsize;
+  }
+  return nwritten;
+}
diff --git a/gnuradio-core/src/lib/io/gr_file_sink.h b/gnuradio-core/src/lib/io/gr_file_sink.h
new file mode 100644 (file)
index 0000000..9c11bf7
--- /dev/null
@@ -0,0 +1,75 @@
+/* -*- 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 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.
+ */
+
+#ifndef INCLUDED_GR_FILE_SINK_H
+#define INCLUDED_GR_FILE_SINK_H
+
+#include <gr_sync_block.h>
+#include <omnithread.h>
+
+class gr_file_sink;
+typedef boost::shared_ptr<gr_file_sink> gr_file_sink_sptr;
+
+gr_file_sink_sptr gr_make_file_sink(size_t itemsize, const char *filename);
+
+/*!
+ * \brief Write stream to file.
+ * \ingroup sink
+ */
+
+class gr_file_sink : public gr_sync_block
+{
+  friend gr_file_sink_sptr gr_make_file_sink(size_t itemsize, const char *filename);
+
+ private:
+  size_t       d_itemsize;
+  void        *d_fp;           // current FILE pointer
+  void        *d_new_fp;       // new FILE pointer
+  bool         d_updated;      // is there a new FILE pointer?
+  omni_mutex   d_mutex;
+
+ protected:
+  gr_file_sink(size_t itemsize, const char *filename);
+
+ public:
+  ~gr_file_sink();
+
+  /*! 
+   * \brief Open filename and begin output to it.
+   */
+  bool open(const char *filename);
+
+  /*!
+   * \brief Close current output file.
+   *
+   * Closes current output file and ignores any output until
+   * open is called to connect to another file.
+   */
+  void close();
+
+  int work(int noutput_items,
+          gr_vector_const_void_star &input_items,
+          gr_vector_void_star &output_items);
+};
+
+
+#endif /* INCLUDED_GR_FILE_SINK_H */
diff --git a/gnuradio-core/src/lib/io/gr_file_sink.i b/gnuradio-core/src/lib/io/gr_file_sink.i
new file mode 100644 (file)
index 0000000..ffcf02a
--- /dev/null
@@ -0,0 +1,45 @@
+/* -*- 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 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.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,file_sink)
+
+gr_file_sink_sptr 
+gr_make_file_sink (size_t itemsize, const char *filename);
+
+class gr_file_sink : public gr_sync_block
+{
+ protected:
+  gr_file_sink (size_t itemsize, const char *filename);
+
+ public:
+  ~gr_file_sink ();
+
+  /*! 
+   * \brief open filename and begin output to it.
+   */
+  bool open(const char *filename);
+
+  /*!
+   * \brief close current output file.
+   */
+  void close();
+};
diff --git a/gnuradio-core/src/lib/io/gr_file_source.cc b/gnuradio-core/src/lib/io/gr_file_source.cc
new file mode 100644 (file)
index 0000000..2573a37
--- /dev/null
@@ -0,0 +1,131 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_file_source.h>
+#include <gr_io_signature.h>
+#include <cstdio>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdexcept>
+
+// win32 (mingw/msvc) specific
+#ifdef HAVE_IO_H
+#include <io.h>
+#endif
+#ifdef O_BINARY
+#define        OUR_O_BINARY O_BINARY
+#else
+#define        OUR_O_BINARY 0
+#endif
+// should be handled via configure
+#ifdef O_LARGEFILE
+#define        OUR_O_LARGEFILE O_LARGEFILE
+#else
+#define        OUR_O_LARGEFILE 0
+#endif
+
+gr_file_source::gr_file_source (size_t itemsize, const char *filename, bool repeat)
+  : gr_sync_block ("file_source",
+                  gr_make_io_signature (0, 0, 0),
+                  gr_make_io_signature (1, 1, itemsize)),
+    d_itemsize (itemsize), d_fp (0), d_repeat (repeat)
+{
+  // we use "open" to use to the O_LARGEFILE flag
+  
+  int fd;
+  if ((fd = open (filename, O_RDONLY | OUR_O_LARGEFILE | OUR_O_BINARY)) < 0){
+    perror (filename);
+    throw std::runtime_error ("can't open file");
+  }
+
+  if ((d_fp = fdopen (fd, "rb")) == NULL){
+    perror (filename);
+    throw std::runtime_error ("can't open file");
+  }
+}
+
+// public constructor that returns a shared_ptr
+
+gr_file_source_sptr
+gr_make_file_source (size_t itemsize, const char *filename, bool repeat)
+{
+  return gr_file_source_sptr (new gr_file_source (itemsize, filename, repeat));
+}
+
+gr_file_source::~gr_file_source ()
+{
+  fclose ((FILE *) d_fp);
+}
+
+int 
+gr_file_source::work (int noutput_items,
+                     gr_vector_const_void_star &input_items,
+                     gr_vector_void_star &output_items)
+{
+  char *o = (char *) output_items[0];
+  int i;
+  int size = noutput_items;
+
+  while (size) {
+    i = fread(o, d_itemsize, size, (FILE *) d_fp);
+    
+    size -= i;
+    o += i * d_itemsize;
+
+    if (size == 0)             // done
+      break;
+
+    if (i > 0)                 // short read, try again
+      continue;
+
+    // We got a zero from fread.  This is either EOF or error.  In
+    // any event, if we're in repeat mode, seek back to the beginning
+    // of the file and try again, else break
+
+    if (!d_repeat)
+      break;
+
+    if (fseek ((FILE *) d_fp, 0, SEEK_SET) == -1) {
+      fprintf(stderr, "[%s] fseek failed\n", __FILE__);
+      exit(-1);
+    }
+  }
+
+  if (size > 0){                       // EOF or error
+    if (size == noutput_items)         // we didn't read anything; say we're done
+      return -1;
+    return noutput_items - size;       // else return partial result
+  }
+
+  return noutput_items;
+}
+
+bool
+gr_file_source::seek (long seek_point, int whence)
+{
+   return fseek ((FILE *) d_fp, seek_point * d_itemsize, whence) == 0;
+}
diff --git a/gnuradio-core/src/lib/io/gr_file_source.h b/gnuradio-core/src/lib/io/gr_file_source.h
new file mode 100644 (file)
index 0000000..6b635c5
--- /dev/null
@@ -0,0 +1,68 @@
+/* -*- 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 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.
+ */
+
+#ifndef INCLUDED_GR_FILE_SOURCE_H
+#define INCLUDED_GR_FILE_SOURCE_H
+
+#include <gr_sync_block.h>
+
+class gr_file_source;
+typedef boost::shared_ptr<gr_file_source> gr_file_source_sptr;
+
+gr_file_source_sptr
+gr_make_file_source (size_t itemsize, const char *filename, bool repeat = false);
+
+/*!
+ * \brief Read stream from file
+ * \ingroup source
+ */
+
+class gr_file_source : public gr_sync_block
+{
+  friend gr_file_source_sptr gr_make_file_source (size_t itemsize,
+                                                 const char *filename,
+                                                 bool repeat);
+ private:
+  size_t       d_itemsize;
+  void        *d_fp;
+  bool         d_repeat;
+
+ protected:
+  gr_file_source (size_t itemsize, const char *filename, bool repeat);
+
+ public:
+  ~gr_file_source ();
+
+  int work (int noutput_items,
+           gr_vector_const_void_star &input_items,
+           gr_vector_void_star &output_items);
+
+  /*!
+   * \brief seek file to \p seek_point relative to \p whence
+   *
+   * \param seek_point sample offset in file
+   * \param whence     one of SEEK_SET, SEEK_CUR, SEEK_END (man fseek)
+   */
+  bool seek (long seek_point, int whence);
+};
+
+#endif /* INCLUDED_GR_FILE_SOURCE_H */
diff --git a/gnuradio-core/src/lib/io/gr_file_source.i b/gnuradio-core/src/lib/io/gr_file_source.i
new file mode 100644 (file)
index 0000000..08fdfaf
--- /dev/null
@@ -0,0 +1,43 @@
+/* -*- 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 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.
+ */
+
+
+%constant int SEEK_SET = 0;     /* Seek from beginning of file. */
+%constant int SEEK_CUR = 1;     /* Seek from current position.  */
+%constant int SEEK_END = 2;     /* Seek from end of file.       */
+
+
+GR_SWIG_BLOCK_MAGIC(gr,file_source)
+
+gr_file_source_sptr 
+gr_make_file_source (size_t itemsize, const char *filename, bool repeat=false);
+
+class gr_file_source : public gr_sync_block
+{
+ protected:
+  gr_file_source (size_t itemsize, const char *filename, bool repeat);
+
+ public:
+  ~gr_file_source ();
+
+  bool seek (long seek_point, int whence);
+};
diff --git a/gnuradio-core/src/lib/io/gr_message_sink.cc b/gnuradio-core/src/lib/io/gr_message_sink.cc
new file mode 100644 (file)
index 0000000..8a0784e
--- /dev/null
@@ -0,0 +1,78 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_message_sink.h>
+#include <gr_io_signature.h>
+#include <cstdio>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdexcept>
+
+
+// public constructor that returns a shared_ptr
+
+gr_message_sink_sptr 
+gr_make_message_sink (size_t itemsize, gr_msg_queue_sptr msgq, bool dont_block)
+{
+  return gr_message_sink_sptr(new gr_message_sink(itemsize, msgq, dont_block));
+}
+
+gr_message_sink::gr_message_sink (size_t itemsize, gr_msg_queue_sptr msgq, bool dont_block)
+  : gr_sync_block("message_sink",
+                 gr_make_io_signature(1, 1, itemsize),
+                 gr_make_io_signature(0, 0, 0)),
+    d_itemsize(itemsize), d_msgq(msgq), d_dont_block(dont_block)
+{
+}
+
+gr_message_sink::~gr_message_sink()
+{
+}
+
+int
+gr_message_sink::work(int noutput_items,
+                     gr_vector_const_void_star &input_items,
+                     gr_vector_void_star &output_items)
+{
+  const char *in = (const char *) input_items[0];
+
+  // if we'd block, drop the data on the floor and say everything is OK
+  if (d_dont_block && d_msgq->full_p())
+    return noutput_items;
+
+  // build a message to hold whatever we've got
+  gr_message_sptr msg = gr_make_message(0,             // msg type
+                                       d_itemsize,     // arg1 for other end
+                                       noutput_items,  // arg2 for other end (redundant)
+                                       noutput_items * d_itemsize);   // len of msg
+  memcpy(msg->msg(), in, noutput_items * d_itemsize);
+
+  d_msgq->handle(msg);         // send it
+
+  return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/io/gr_message_sink.h b/gnuradio-core/src/lib/io/gr_message_sink.h
new file mode 100644 (file)
index 0000000..8011ab2
--- /dev/null
@@ -0,0 +1,62 @@
+/* -*- 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 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.
+ */
+
+#ifndef INCLUDED_GR_MESSAGE_SINK_H
+#define INCLUDED_GR_MESSAGE_SINK_H
+
+#include <gr_sync_block.h>
+#include <gr_message.h>
+#include <gr_msg_queue.h>
+
+class gr_message_sink;
+typedef boost::shared_ptr<gr_message_sink> gr_message_sink_sptr;
+
+gr_message_sink_sptr gr_make_message_sink (size_t itemsize,
+                                          gr_msg_queue_sptr msgq,
+                                          bool dont_block);
+
+/*!
+ * \brief Gather received items into messages and insert into msgq
+ * \ingroup sink
+ */
+class gr_message_sink : public gr_sync_block
+{
+ private:
+  size_t               d_itemsize;
+  gr_msg_queue_sptr    d_msgq;
+  bool                 d_dont_block;
+
+  friend gr_message_sink_sptr
+  gr_make_message_sink(size_t itemsize, gr_msg_queue_sptr msgq, bool dont_block);
+
+ protected:
+  gr_message_sink (size_t itemsize, gr_msg_queue_sptr msgq, bool dont_block);
+
+ public:
+  ~gr_message_sink ();
+
+  int work (int noutput_items,
+           gr_vector_const_void_star &input_items,
+           gr_vector_void_star &output_items);
+};
+
+#endif /* INCLUDED_GR_MESSAGE_SINK_H */
diff --git a/gnuradio-core/src/lib/io/gr_message_sink.i b/gnuradio-core/src/lib/io/gr_message_sink.i
new file mode 100644 (file)
index 0000000..ca73479
--- /dev/null
@@ -0,0 +1,36 @@
+/* -*- 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 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.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,message_sink);
+
+gr_message_sink_sptr gr_make_message_sink (size_t itemsize,
+                                          gr_msg_queue_sptr msgq,
+                                          bool dont_block);
+
+class gr_message_sink : public gr_sync_block
+{
+ protected:
+  gr_message_sink (size_t itemsize, gr_msg_queue_sptr msgq, bool dont_block);
+
+ public:
+  ~gr_message_sink ();
+};
diff --git a/gnuradio-core/src/lib/io/gr_message_source.cc b/gnuradio-core/src/lib/io/gr_message_source.cc
new file mode 100644 (file)
index 0000000..797433b
--- /dev/null
@@ -0,0 +1,104 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_message_source.h>
+#include <gr_io_signature.h>
+#include <cstdio>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdexcept>
+
+
+// public constructor that returns a shared_ptr
+
+gr_message_source_sptr
+gr_make_message_source(size_t itemsize, int msgq_limit)
+{
+  return gr_message_source_sptr(new gr_message_source(itemsize, msgq_limit));
+}
+
+gr_message_source::gr_message_source (size_t itemsize, int msgq_limit)
+  : gr_sync_block("message_source",
+                 gr_make_io_signature(0, 0, 0),
+                 gr_make_io_signature(1, 1, itemsize)),
+    d_itemsize(itemsize), d_msgq(gr_make_msg_queue(msgq_limit)), d_msg_offset(0), d_eof(false)
+{
+}
+
+gr_message_source::~gr_message_source()
+{
+}
+
+int
+gr_message_source::work(int noutput_items,
+                       gr_vector_const_void_star &input_items,
+                       gr_vector_void_star &output_items)
+{
+  char *out = (char *) output_items[0];
+  int nn = 0;
+
+  while (nn < noutput_items){
+    if (d_msg){
+      //
+      // Consume whatever we can from the current message
+      //
+      int mm = std::min(noutput_items - nn, (int)((d_msg->length() - d_msg_offset) / d_itemsize));
+      memcpy (out, &(d_msg->msg()[d_msg_offset]), mm * d_itemsize);
+
+      nn += mm;
+      out += mm * d_itemsize;
+      d_msg_offset += mm * d_itemsize;
+      assert(d_msg_offset <= d_msg->length());
+
+      if (d_msg_offset == d_msg->length()){
+       if (d_msg->type() == 1)            // type == 1 sets EOF
+         d_eof = true;
+       d_msg.reset();
+      }
+    }
+    else {
+      //
+      // No current message
+      //
+      if (d_msgq->empty_p() && nn > 0){    // no more messages in the queue, return what we've got
+       break;
+      }
+
+      if (d_eof)
+       return -1;
+
+      d_msg = d_msgq->delete_head();      // block, waiting for a message
+      d_msg_offset = 0;
+
+      if ((d_msg->length() % d_itemsize) != 0)
+       throw std::runtime_error("msg length is not a multiple of d_itemsize");
+    }
+  }
+
+  return nn;
+}
diff --git a/gnuradio-core/src/lib/io/gr_message_source.h b/gnuradio-core/src/lib/io/gr_message_source.h
new file mode 100644 (file)
index 0000000..0206012
--- /dev/null
@@ -0,0 +1,64 @@
+/* -*- 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 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.
+ */
+
+#ifndef INCLUDED_GR_MESSAGE_SOURCE_H
+#define INCLUDED_GR_MESSAGE_SOURCE_H
+
+#include <gr_sync_block.h>
+#include <gr_message.h>
+#include <gr_msg_queue.h>
+
+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);
+
+/*!
+ * \brief Turn received messages into a stream
+ * \ingroup source
+ */
+class gr_message_source : public gr_sync_block
+{
+ private:
+  size_t               d_itemsize;
+  gr_msg_queue_sptr    d_msgq;
+  gr_message_sptr      d_msg;
+  unsigned             d_msg_offset;
+  bool                 d_eof;
+
+  friend gr_message_source_sptr
+  gr_make_message_source(size_t itemsize, int msgq_limit);
+
+ protected:
+  gr_message_source (size_t itemsize, int msgq_limit);
+
+ public:
+  ~gr_message_source ();
+
+  gr_msg_queue_sptr    msgq() const { return d_msgq; }
+
+  int work (int noutput_items,
+           gr_vector_const_void_star &input_items,
+           gr_vector_void_star &output_items);
+};
+
+#endif /* INCLUDED_GR_MESSAGE_SOURCE_H */
diff --git a/gnuradio-core/src/lib/io/gr_message_source.i b/gnuradio-core/src/lib/io/gr_message_source.i
new file mode 100644 (file)
index 0000000..369112e
--- /dev/null
@@ -0,0 +1,36 @@
+/* -*- 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 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.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,message_source);
+
+gr_message_source_sptr gr_make_message_source (size_t itemsize, int msgq_limit=0);
+
+class gr_message_source : public gr_sync_block
+{
+ protected:
+  gr_message_source (size_t itemsize, int msgq_limit);
+
+ public:
+  ~gr_message_source ();
+
+  gr_msg_queue_sptr msgq() const;
+};
diff --git a/gnuradio-core/src/lib/io/gr_oscope_guts.cc b/gnuradio-core/src/lib/io/gr_oscope_guts.cc
new file mode 100644 (file)
index 0000000..6636fff
--- /dev/null
@@ -0,0 +1,382 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <gr_oscope_guts.h>
+#include <stdexcept>
+#include <stdio.h>
+#include <algorithm>
+#include <unistd.h>
+#include <math.h>
+#include <assert.h>
+
+static const int OUTPUT_RECORD_SIZE = 2048;    // must be power of 2
+
+static inline int
+wrap_bi (int buffer_index)             // wrap buffer index
+{
+  return buffer_index & (OUTPUT_RECORD_SIZE - 1);
+}
+
+static inline int
+incr_bi (int buffer_index)             // increment buffer index
+{
+  return wrap_bi (buffer_index + 1);
+}
+
+static inline int
+decr_bi (int buffer_index)             // decrement buffer index
+{
+  return wrap_bi (buffer_index - 1);
+}
+
+gr_oscope_guts::gr_oscope_guts (int nchannels, double sample_rate, gr_msg_queue_sptr msgq)
+  : d_nchannels (nchannels),
+    d_msgq (msgq), 
+    d_trigger_mode (gr_TRIG_POS_SLOPE),
+    d_trigger_channel (0),
+    d_sample_rate (sample_rate),
+    d_update_rate (20),
+    d_trigger_level (0),
+    d_obi (0),
+    d_state (LOOK_FOR_TRIGGER),
+    d_decimator_count (0),
+    d_decimator_count_init (1),
+    d_hold_off_count (0),
+    d_hold_off_count_init (0),
+    d_post_trigger_count (0),
+    d_post_trigger_count_init (OUTPUT_RECORD_SIZE/2),
+    d_prev_sample (0)
+{
+  if (d_nchannels > MAX_CHANNELS){
+    fprintf (stderr, "gr_oscope_guts: too many channels.  MAX_CHANNELS = %d\n", MAX_CHANNELS);
+    throw std::runtime_error ("too many channels");
+  }
+
+  for (int i = 0; i < MAX_CHANNELS; i++)
+    d_buffer[i] = 0;
+
+  for (int i = 0; i < d_nchannels; i++)
+    d_buffer[i] = new float [OUTPUT_RECORD_SIZE];
+
+  update_rate_or_decimation_changed ();
+  enter_look_for_trigger ();
+}
+
+gr_oscope_guts::~gr_oscope_guts ()
+{
+  for (int i = 0; i < MAX_CHANNELS; i++)
+    delete [] d_buffer[i];
+}
+
+// MANIPULATORS
+
+// \p channel_data points to nchannels float values.  These are the values
+// for each channel at this sample time.
+
+void
+gr_oscope_guts::process_sample (const float *channel_data)
+{
+  d_decimator_count--;
+  if (d_decimator_count > 0)
+    return;
+
+  d_decimator_count = d_decimator_count_init;
+  
+  for (int i = 0; i < d_nchannels; i++)
+    d_buffer[i][d_obi] = channel_data[i];              // copy data into buffer
+
+  int trigger = 0;
+  
+  switch (d_state){
+  case HOLD_OFF:
+    d_hold_off_count--;
+    if (d_hold_off_count <= 0)
+      enter_look_for_trigger ();
+    break;
+
+  case LOOK_FOR_TRIGGER:
+    trigger = found_trigger (d_buffer[d_trigger_channel][d_obi]);
+    if (trigger != 0){
+      enter_post_trigger ();
+      if (trigger < 0)                 // previous sample was closer
+       d_post_trigger_count--;
+    }
+    break;
+
+  case POST_TRIGGER:
+    d_post_trigger_count--;
+    if (d_post_trigger_count <= 0){
+      write_output_records ();
+      enter_hold_off ();
+    }
+    break;
+
+  default:
+    assert (0);
+  }
+
+  d_obi = incr_bi (d_obi);
+}
+
+/*
+ * Functions called on state entry
+ */
+
+void
+gr_oscope_guts::enter_hold_off ()
+{
+  d_state = HOLD_OFF;
+  d_hold_off_count = d_hold_off_count_init;
+}
+
+void
+gr_oscope_guts::enter_look_for_trigger ()
+{
+  d_state = LOOK_FOR_TRIGGER;
+  d_prev_sample = d_buffer[d_trigger_channel][d_obi];
+}
+
+void
+gr_oscope_guts::enter_post_trigger ()
+{
+  d_state = POST_TRIGGER;
+  d_post_trigger_count = d_post_trigger_count_init;
+}
+
+// ----------------------------------------------------------------
+// returns 0 if no trigger found. 
+// returns +1 if this sample is the trigger point
+// returns -1 if the previous sample is the trigger point
+
+int
+gr_oscope_guts::found_trigger (float new_sample)
+{
+  float prev_sample = d_prev_sample;
+  d_prev_sample = new_sample;
+  bool trig;
+
+  switch (d_trigger_mode){
+
+  case gr_TRIG_AUTO:           // always trigger
+    return +1;
+    
+  case gr_TRIG_POS_SLOPE:
+    trig = prev_sample < d_trigger_level && new_sample >= d_trigger_level;
+    if (trig){
+      if (fabs (prev_sample - d_trigger_level) < fabs (new_sample - d_trigger_level))
+       return -1;
+      else
+       return +1;
+    }
+    return 0;
+
+  case gr_TRIG_NEG_SLOPE:
+    trig = prev_sample > d_trigger_level && new_sample <= d_trigger_level;
+    if (trig){
+      if (fabs (prev_sample - d_trigger_level) < fabs (new_sample - d_trigger_level))
+       return -1;
+      else
+       return +1;
+    }
+    return 0;
+
+  default:
+    assert (0);
+    return 0;
+  }
+}
+
+// ----------------------------------------------------------------
+// write output records (duh!)
+
+void
+gr_oscope_guts::write_output_records ()
+{
+  // if the output queue if full, drop the data on the ground.
+  if (d_msgq->full_p())
+    return;
+
+  // Build a message to hold the output records
+  gr_message_sptr msg = 
+    gr_make_message(0,                                                // msg type
+                   d_nchannels,                                       // arg1 for other side
+                   OUTPUT_RECORD_SIZE,                                // arg2 for other side
+                   d_nchannels * OUTPUT_RECORD_SIZE * sizeof(float)); // sizeof payload
+
+  float *out = (float *)msg->msg();    // get pointer to raw message buffer
+
+  for (int ch = 0; ch < d_nchannels; ch++){
+    // note that d_obi points at the oldest sample in the buffer
+    for (int i = 0; i < OUTPUT_RECORD_SIZE; i++)
+      out[i] = d_buffer[ch][wrap_bi(d_obi + i)];
+
+    out += OUTPUT_RECORD_SIZE;
+  }
+
+  d_msgq->handle(msg);         // send the msg
+}
+
+// ----------------------------------------------------------------
+
+bool
+gr_oscope_guts::set_update_rate (double update_rate)
+{
+  d_update_rate = std::min (std::max (1./10., update_rate), d_sample_rate);
+  update_rate_or_decimation_changed ();
+  return true;
+}
+
+bool
+gr_oscope_guts::set_decimation_count (int decimator_count)
+{
+  decimator_count = std::max (1, decimator_count);
+  d_decimator_count_init = decimator_count;
+  update_rate_or_decimation_changed ();
+  return true;
+}
+
+bool
+gr_oscope_guts::set_sample_rate(double sample_rate)
+{
+  d_sample_rate = sample_rate;
+  return set_update_rate(update_rate());
+}
+
+
+void
+gr_oscope_guts::update_rate_or_decimation_changed ()
+{
+  d_hold_off_count_init =
+    (int) rint (d_sample_rate / d_update_rate / d_decimator_count_init);
+}
+
+bool
+gr_oscope_guts::set_trigger_channel (int channel)
+{
+  if (channel >= 0 && channel < d_nchannels){
+    d_trigger_channel = channel;
+    trigger_changed ();
+    return true;
+  }
+
+  return false;
+}
+
+bool
+gr_oscope_guts::set_trigger_mode (gr_trigger_mode mode)
+{
+  switch (mode){
+  case gr_TRIG_POS_SLOPE:
+  case gr_TRIG_NEG_SLOPE:
+  case gr_TRIG_AUTO:
+    d_trigger_mode = mode;
+    trigger_changed ();
+    return true;
+  }
+  return false;
+}
+
+bool
+gr_oscope_guts::set_trigger_level (double trigger_level)
+{
+  d_trigger_level = trigger_level;
+  trigger_changed ();
+  return true;
+}
+
+bool
+gr_oscope_guts::set_trigger_level_auto ()
+{
+  // find the level 1/2 way between the min and the max
+
+  float        min_v = d_buffer[d_trigger_channel][0];
+  float        max_v = d_buffer[d_trigger_channel][0];
+
+  for (int i = 1; i < OUTPUT_RECORD_SIZE; i++){
+    min_v = std::min (min_v, d_buffer[d_trigger_channel][i]);
+    max_v = std::max (max_v, d_buffer[d_trigger_channel][i]);
+  }
+
+  d_trigger_level = (min_v + max_v) * 0.5;
+  trigger_changed ();
+  return true;
+}
+
+void
+gr_oscope_guts::trigger_changed ()
+{
+  // d_prev_sample = d_buffer[d_trigger_channel][decr_bi(d_obi)];
+  enter_look_for_trigger ();
+}
+
+// ACCESSORS
+
+int
+gr_oscope_guts::num_channels () const
+{
+  return d_nchannels;
+}
+
+double
+gr_oscope_guts::sample_rate () const
+{
+  return d_sample_rate;
+}
+
+double
+gr_oscope_guts::update_rate () const
+{
+  return d_update_rate;
+}
+
+int
+gr_oscope_guts::get_decimation_count () const
+{
+  return d_decimator_count_init;
+}
+
+int
+gr_oscope_guts::get_trigger_channel () const
+{
+  return d_trigger_channel;
+}
+
+gr_trigger_mode
+gr_oscope_guts::get_trigger_mode () const
+{
+  return d_trigger_mode;
+}
+
+double
+gr_oscope_guts::get_trigger_level () const
+{
+  return d_trigger_level;
+}
+
+int
+gr_oscope_guts::get_samples_per_output_record () const
+{
+  return OUTPUT_RECORD_SIZE;
+}
diff --git a/gnuradio-core/src/lib/io/gr_oscope_guts.h b/gnuradio-core/src/lib/io/gr_oscope_guts.h
new file mode 100644 (file)
index 0000000..4094a65
--- /dev/null
@@ -0,0 +1,116 @@
+/* -*- 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 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.
+ */
+
+
+#ifndef INCLUDED_GR_OSCOPE_GUTS_H
+#define INCLUDED_GR_OSCOPE_GUTS_H
+
+#include <gr_trigger_mode.h>
+#include <gr_msg_queue.h>
+
+/*!
+ * \brief guts of oscilloscope trigger and buffer module
+ *
+ * This module processes sets of samples provided the \p process_sample
+ * method.  When appropriate given the updateRate, sampleRate and
+ * trigger conditions, process_sample will periodically write output
+ * records of captured data to output_fd.  For each trigger event,
+ * nchannels records will be written.  Each record consists of
+ * get_samples_per_output_record binary floats.  The trigger instant
+ * occurs at the 1/2 way point in the buffer.  Thus, output records
+ * consist of 50% pre-trigger data and 50% post-trigger data.
+ */
+
+class gr_oscope_guts {
+private:
+  static const int     MAX_CHANNELS = 16;
+  enum scope_state     { HOLD_OFF, LOOK_FOR_TRIGGER, POST_TRIGGER };
+
+  int                  d_nchannels;            // how many channels
+  gr_msg_queue_sptr    d_msgq;                 // message queue we stuff output records into
+  gr_trigger_mode      d_trigger_mode;         
+  int                  d_trigger_channel;      // which channel to watch for trigger condition
+  double               d_sample_rate;          // input sample rate in Hz
+  double               d_update_rate;          // approx freq to produce an output record (Hz)
+  double               d_trigger_level;
+
+  int                  d_obi;                  // output buffer index 
+  float                       *d_buffer[MAX_CHANNELS];
+
+  scope_state          d_state;
+  int                  d_decimator_count;
+  int                  d_decimator_count_init;
+  int                  d_hold_off_count;
+  int                  d_hold_off_count_init;
+  int                  d_post_trigger_count;
+  int                  d_post_trigger_count_init;
+  float                        d_prev_sample;                  // used for trigger checking
+
+  // NOT IMPLEMENTED
+  gr_oscope_guts (const gr_oscope_guts &rhs);                  // no copy constructor
+  gr_oscope_guts &operator= (const gr_oscope_guts &rhs);       // no assignment operator
+
+  void trigger_changed ();
+  void update_rate_or_decimation_changed ();
+  int  found_trigger (float sample);   // returns -1, 0, +1
+  void write_output_records ();
+
+  void enter_hold_off ();                      // called on state entry
+  void enter_look_for_trigger ();
+  void enter_post_trigger ();
+
+public:
+  // CREATORS
+  gr_oscope_guts (int nchannels, double sample_rate, gr_msg_queue_sptr msgq);
+  ~gr_oscope_guts ();
+
+  // MANIPULATORS
+
+  /*!
+   * \p channel_data points to nchannels float values.  These are the values
+   * for each channel at this sample time.
+   */
+  void process_sample (const float *channel_data);
+
+  bool set_update_rate (double update_rate);
+  bool set_decimation_count (int decimation_count);
+  bool set_trigger_channel (int channel);
+  bool set_trigger_mode (gr_trigger_mode mode);
+  bool set_trigger_level (double trigger_level);
+  bool set_trigger_level_auto ();                              // set to 50% level
+  bool set_sample_rate(double sample_rate);
+
+
+  // ACCESSORS
+  int num_channels () const;
+  double sample_rate () const;
+  double update_rate () const;
+  int get_decimation_count () const;
+  int get_trigger_channel () const;
+  gr_trigger_mode get_trigger_mode () const;
+  double get_trigger_level () const;
+
+  // # of samples written to each output record.
+  int get_samples_per_output_record () const;
+};
+
+#endif /* INCLUDED_GR_OSCOPE_GUTS_H */
diff --git a/gnuradio-core/src/lib/io/gr_oscope_sink.i b/gnuradio-core/src/lib/io/gr_oscope_sink.i
new file mode 100644 (file)
index 0000000..ea84199
--- /dev/null
@@ -0,0 +1,79 @@
+/* -*- 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 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.
+ */
+
+enum gr_trigger_mode {
+  gr_TRIG_AUTO,                        // auto trigger (on anything)
+  gr_TRIG_POS_SLOPE,           // trigger on positive slope across trigger level
+  gr_TRIG_NEG_SLOPE            // trigger on negative slope across trigger level
+};
+
+// GR_SWIG_BLOCK_MAGIC(gr,oscope_sink_x)
+
+%ignore gr_oscope_sink_x;
+class gr_oscope_sink_x : public gr_sync_block
+{
+ protected:
+  gr_oscope_sink_x (const std::string name,
+                   gr_io_signature_sptr input_sig,
+                   double sample_rate);
+
+ public:
+  ~gr_oscope_sink_x ();
+
+  bool set_update_rate (double update_rate);
+  bool set_decimation_count (int decimation_count);
+  bool set_trigger_channel (int channel);
+  bool set_trigger_mode (gr_trigger_mode mode);
+  bool set_trigger_level (double trigger_level);
+  bool set_trigger_level_auto ();                              // set to 50% level
+  bool set_sample_rate(double sample_rate);
+
+  // ACCESSORS
+  int num_channels () const;
+  double sample_rate () const;
+  double update_rate () const;
+  int get_decimation_count () const;
+  int get_trigger_channel () const;
+  gr_trigger_mode get_trigger_mode () const;
+  double get_trigger_level () const;
+
+  // # of samples written to each output record.
+  int get_samples_per_output_record () const;
+};
+
+// ----------------------------------------------------------------
+
+GR_SWIG_BLOCK_MAGIC(gr,oscope_sink_f)
+
+gr_oscope_sink_f_sptr
+gr_make_oscope_sink_f (double sample_rate, gr_msg_queue_sptr msgq);
+
+class gr_oscope_sink_f : public gr_oscope_sink_x
+{
+private:
+  gr_oscope_sink_f (double sample_rate, gr_msg_queue_sptr msgq);
+
+public:
+  ~gr_oscope_sink_f ();
+};
+
+// ----------------------------------------------------------------
diff --git a/gnuradio-core/src/lib/io/gr_oscope_sink_f.cc b/gnuradio-core/src/lib/io/gr_oscope_sink_f.cc
new file mode 100644 (file)
index 0000000..b505381
--- /dev/null
@@ -0,0 +1,80 @@
+/* -*- c++ -*- */
+/*
+ * 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_oscope_sink_f.h>
+#include <gr_io_signature.h>
+#include <gr_oscope_guts.h>
+
+
+gr_oscope_sink_f_sptr
+gr_make_oscope_sink_f (double sampling_rate, gr_msg_queue_sptr msgq)
+{
+  return gr_oscope_sink_f_sptr (new gr_oscope_sink_f (sampling_rate, msgq));
+}
+
+
+gr_oscope_sink_f::gr_oscope_sink_f (double sampling_rate, gr_msg_queue_sptr msgq)
+  : gr_oscope_sink_x ("oscope_sink_f",
+                     gr_make_io_signature (1, MAX_CHANNELS, sizeof (float)),
+                     sampling_rate),
+    d_msgq(msgq)
+{
+}
+
+
+bool
+gr_oscope_sink_f::check_topology (int ninputs, int noutputs)
+{
+  delete d_guts;
+  d_guts = 0;
+  d_guts = new gr_oscope_guts (ninputs, d_sampling_rate, d_msgq);
+  return true;
+}
+
+
+gr_oscope_sink_f::~gr_oscope_sink_f ()
+{
+}
+
+int
+gr_oscope_sink_f::work (int noutput_items,
+                       gr_vector_const_void_star &input_items,
+                       gr_vector_void_star &output_items)
+{
+  int    ni = input_items.size ();
+  float          tmp[MAX_CHANNELS];
+
+  for (int i = 0; i < noutput_items; i++){
+
+    // FIXME for now, copy the data.  Fix later if reqd
+    for (int ch = 0; ch < ni; ch++)    
+      tmp[ch] = ((const float *) input_items[ch])[i];
+
+    d_guts->process_sample (tmp);
+  }
+
+  return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/io/gr_oscope_sink_f.h b/gnuradio-core/src/lib/io/gr_oscope_sink_f.h
new file mode 100644 (file)
index 0000000..7b92a78
--- /dev/null
@@ -0,0 +1,65 @@
+/* -*- c++ -*- */
+/*
+ * 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 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.
+ */
+
+#ifndef INCLUDED_GR_OSCOPE_SINK_F_H
+#define INCLUDED_GR_OSCOPE_SINK_F_H
+
+#include <gr_oscope_sink_x.h>
+#include <gr_msg_queue.h>
+
+class gr_oscope_sink_f;
+typedef boost::shared_ptr<gr_oscope_sink_x> gr_oscope_sink_f_sptr;
+
+gr_oscope_sink_f_sptr gr_make_oscope_sink_f (double sampling_rate, gr_msg_queue_sptr msgq);
+
+
+/*!
+ * \brief Building block for python oscilloscope module.
+ * \ingroup sink
+ *
+ * Accepts 1 to 16 float streams.
+ */
+class gr_oscope_sink_f : public gr_oscope_sink_x
+{
+public:
+  static const int MAX_CHANNELS = 16;
+
+private:
+  friend gr_oscope_sink_f_sptr
+  gr_make_oscope_sink_f (double sampling_rate, gr_msg_queue_sptr msgq);
+
+  gr_oscope_sink_f (double sampling_rate, gr_msg_queue_sptr msgq);
+
+  gr_msg_queue_sptr    d_msgq;
+
+ public:
+  ~gr_oscope_sink_f ();
+
+  int work (int noutput_items,
+           gr_vector_const_void_star &input_items,
+           gr_vector_void_star &output_items);
+
+  bool check_topology (int ninputs, int noutputs);
+};
+
+#endif /* INCLUDED_GR_OSCOPE_SINK_F_H */
+
diff --git a/gnuradio-core/src/lib/io/gr_oscope_sink_x.cc b/gnuradio-core/src/lib/io/gr_oscope_sink_x.cc
new file mode 100644 (file)
index 0000000..51c2867
--- /dev/null
@@ -0,0 +1,138 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003,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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_oscope_sink_x.h>
+#include <gr_io_signature.h>
+#include <gr_oscope_guts.h>
+
+
+gr_oscope_sink_x::gr_oscope_sink_x (const std::string name,
+                                   gr_io_signature_sptr input_sig,
+                                   double sampling_rate)
+  : gr_sync_block (name, input_sig, gr_make_io_signature (0, 0, 0)),
+    d_sampling_rate (sampling_rate), d_guts (0)
+{
+}
+
+gr_oscope_sink_x::~gr_oscope_sink_x ()
+{
+  delete d_guts;
+}
+
+// ----------------------------------------------------------------
+
+bool
+gr_oscope_sink_x::set_update_rate (double update_rate)
+{
+  return d_guts->set_update_rate (update_rate);
+}
+
+bool
+gr_oscope_sink_x::set_decimation_count (int decimation_count)
+{
+  return d_guts->set_decimation_count (decimation_count);
+}
+
+bool
+gr_oscope_sink_x::set_trigger_channel (int channel)
+{
+  return d_guts->set_trigger_channel (channel);
+}
+
+bool
+gr_oscope_sink_x::set_trigger_mode (gr_trigger_mode mode)
+{
+  return d_guts->set_trigger_mode (mode);
+}
+
+bool
+gr_oscope_sink_x::set_trigger_level (double trigger_level)
+{
+  return d_guts->set_trigger_level (trigger_level);
+}
+
+
+bool
+gr_oscope_sink_x::set_trigger_level_auto ()
+{
+  return d_guts->set_trigger_level_auto ();
+}
+
+bool
+gr_oscope_sink_x::set_sample_rate (double sample_rate)
+{
+  return d_guts->set_sample_rate (sample_rate);
+}
+
+// ACCESSORS
+
+int
+gr_oscope_sink_x::num_channels () const
+{
+  return d_guts->num_channels ();
+}
+
+double
+gr_oscope_sink_x::sample_rate () const
+{
+  return d_guts->sample_rate ();
+}
+
+double
+gr_oscope_sink_x::update_rate () const
+{
+  return d_guts->update_rate ();
+}
+
+int
+gr_oscope_sink_x::get_decimation_count () const
+{
+  return d_guts->get_decimation_count ();
+}
+
+int
+gr_oscope_sink_x::get_trigger_channel () const
+{
+  return d_guts->get_trigger_channel ();
+}
+
+gr_trigger_mode
+gr_oscope_sink_x::get_trigger_mode () const
+{
+  return d_guts->get_trigger_mode ();
+}
+
+double
+gr_oscope_sink_x::get_trigger_level () const
+{
+  return d_guts->get_trigger_level ();
+}
+
+int
+gr_oscope_sink_x::get_samples_per_output_record () const
+{
+  return d_guts->get_samples_per_output_record ();
+}
diff --git a/gnuradio-core/src/lib/io/gr_oscope_sink_x.h b/gnuradio-core/src/lib/io/gr_oscope_sink_x.h
new file mode 100644 (file)
index 0000000..45cccc0
--- /dev/null
@@ -0,0 +1,73 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003,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.
+ */
+
+#ifndef INCLUDED_GR_OSCOPE_SINK_X_H
+#define INCLUDED_GR_OSCOPE_SINK_X_H
+
+#include <gr_sync_block.h>
+#include <gr_trigger_mode.h>
+
+class gr_oscope_guts;
+
+/*!
+ * \brief Abstract class for python oscilloscope module.
+ * \ingroup sink
+ *
+ * Don't instantiate this.  Use gr_oscope_sink_f or gr_oscope_sink_c instead.
+ */
+class gr_oscope_sink_x : public gr_sync_block
+{
+protected:
+  double                        d_sampling_rate;
+  gr_oscope_guts               *d_guts;
+  
+  gr_oscope_sink_x (const std::string name,
+                   gr_io_signature_sptr input_sig,
+                   double sampling_rate);
+
+public:
+  ~gr_oscope_sink_x ();
+
+  bool set_update_rate (double update_rate);
+  bool set_decimation_count (int decimation_count);
+  bool set_trigger_channel (int channel);
+  bool set_trigger_mode (gr_trigger_mode mode);
+  bool set_trigger_level (double trigger_level);
+  bool set_trigger_level_auto ();                              // set to 50% level
+  bool set_sample_rate(double sample_rate);
+
+
+  // ACCESSORS
+  int num_channels () const;
+  double sample_rate () const;
+  double update_rate () const;
+  int get_decimation_count () const;
+  int get_trigger_channel () const;
+  gr_trigger_mode get_trigger_mode () const;
+  double get_trigger_level () const;
+
+  // # of samples written to each output record.
+  int get_samples_per_output_record () const;
+  
+};
+
+#endif /* INCLUDED_GR_OSCOPE_SINK_X_H */
diff --git a/gnuradio-core/src/lib/io/gr_trigger_mode.h b/gnuradio-core/src/lib/io/gr_trigger_mode.h
new file mode 100644 (file)
index 0000000..0928c6a
--- /dev/null
@@ -0,0 +1,32 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003,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.
+ */
+
+#ifndef INCLUDED_GR_TRIGGER_MODE_H
+#define INCLUDED_GR_TRIGGER_MODE_H
+
+enum gr_trigger_mode {
+  gr_TRIG_AUTO,                        // auto trigger (on anything)
+  gr_TRIG_POS_SLOPE,           // trigger on positive slope across trigger level
+  gr_TRIG_NEG_SLOPE            // trigger on negative slope across trigger level
+};
+
+#endif /* INCLUDED_GR_TRIGGER_MODE_H */
diff --git a/gnuradio-core/src/lib/io/gri_logger.cc b/gnuradio-core/src/lib/io/gri_logger.cc
new file mode 100644 (file)
index 0000000..a1bdfb0
--- /dev/null
@@ -0,0 +1,173 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <gri_logger.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <stdexcept>
+#include <boost/weak_ptr.hpp>
+
+
+/*
+ * This class creates the thread that reads from the ringbuffer and
+ * and writes to the file.  This is opaque to the user.
+ */
+class gri_log_poster : public omni_thread
+{
+  FILE                *d_fp;
+  gr_buffer_sptr       d_writer;
+  gr_buffer_reader_sptr        d_reader;
+  omni_semaphore       d_ringbuffer_ready;
+  volatile bool                d_time_to_die;
+  volatile bool                d_writer_overrun;
+
+  virtual void* run_undetached(void * arg);
+
+public:
+  gri_log_poster(const char *filename);
+  ~gri_log_poster();
+
+  void kill() { d_time_to_die = true; post(); }
+  gr_buffer_sptr writer() const { return d_writer; }
+  void post() { d_ringbuffer_ready.post(); }
+  void note_writer_overrun() { d_writer_overrun = true; }
+};
+
+gri_log_poster::gri_log_poster(const char *filename)
+  : omni_thread(),
+    d_ringbuffer_ready(1, 1),          // binary semaphore
+    d_time_to_die(false),
+    d_writer_overrun(false)
+{
+  if ((d_fp = fopen(filename, "w")) == 0){
+    perror (filename);
+    throw std::runtime_error("can't open file");
+  }
+
+  // Create a 1MB buffer.
+  d_writer = gr_make_buffer(1 * 1024 * 1024, sizeof(unsigned char));
+  d_reader = gr_buffer_add_reader(d_writer, 0);
+
+  start_undetached();  // start the thread
+}
+
+gri_log_poster::~gri_log_poster()
+{
+  if (d_fp != 0){
+    fclose(d_fp);
+    d_fp = 0;
+  }
+}
+
+/*
+ * This is the body of the logging thread.
+ */
+void *
+gri_log_poster::run_undetached(void *arg)
+{
+  int nbytes;
+
+  //fprintf(stderr, "Enter: run_undetached!\n");
+
+  while (!d_time_to_die){
+    while ((nbytes = d_reader->items_available()) > 0){
+      fwrite(d_reader->read_pointer(), 1, nbytes, d_fp);
+      d_reader->update_read_pointer(nbytes);
+    }
+    fflush(d_fp);
+    d_ringbuffer_ready.wait();
+
+    if (d_writer_overrun){
+      fputs(">>>>> gri_logger: writer overrun.  Info lost <<<<<\n", d_fp);
+      d_writer_overrun = false;
+    }
+  }
+
+  // fprintf(stderr, "Exit: run_undetached!\n");
+  return 0;
+}
+
+// ------------------------------------------------------------------------
+
+static boost::weak_ptr<gri_logger> s_singleton;  // weak pointer IQ test ;-)
+static omni_mutex s_singleton_mutex;
+
+gri_logger_sptr
+gri_logger::singleton()
+{
+  omni_mutex_lock l(s_singleton_mutex);
+  gri_logger_sptr r;
+
+  if (r = s_singleton.lock())
+    return r;
+
+  r = gri_logger_sptr(new gri_logger("gri_logger.log"));
+  s_singleton = r;
+  return r;
+}
+  
+
+gri_logger::gri_logger(const char *filename)
+{
+  d_poster = new gri_log_poster(filename);
+}
+
+gri_logger::~gri_logger()
+{
+  d_poster->kill();
+  d_poster->join(NULL);
+}
+
+void
+gri_logger::write(const void *buf, size_t count)
+{
+  omni_mutex_lock l(d_write_mutex);
+  gr_buffer_sptr writer = d_poster->writer();
+  
+  // either write it all, or drop it on the ground
+  if (count <= (size_t) writer->space_available()){
+    memcpy(writer->write_pointer(), buf, count);
+    writer->update_write_pointer(count);
+    d_poster->post();
+  }
+  else {
+    d_poster->note_writer_overrun();
+  }
+}
+
+void
+gri_logger::printf(const char *format, ...)
+{
+  va_list      ap;
+  char         buf[4096];
+  int          n;
+  
+  va_start(ap, format);
+  n = vsnprintf(buf, sizeof(buf), format, ap);
+  va_end(ap);
+  if (n > -1 && n < (ssize_t) sizeof(buf))
+    write(buf, n);
+}
diff --git a/gnuradio-core/src/lib/io/gri_logger.h b/gnuradio-core/src/lib/io/gri_logger.h
new file mode 100644 (file)
index 0000000..ecbd314
--- /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 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.
+ */
+#ifndef INCLUDED_GRI_LOGGER_H
+#define INCLUDED_GRI_LOGGER_H
+
+#include <stddef.h>
+#include <omnithread.h>
+#include <gr_buffer.h>
+
+class gri_log_poster;
+class gri_logger;
+typedef boost::shared_ptr<gri_logger> gri_logger_sptr;
+
+
+/*!
+ * \brief non-blocking logging to a file.
+ *
+ * In reality, this may block, but only for a bounded time.
+ * Trust me, it's safe to use from portaudio and JACK callbacks.
+ */
+class gri_logger
+{
+  gri_log_poster       *d_poster;
+  omni_mutex            d_write_mutex;
+
+public:
+  static gri_logger_sptr singleton();
+
+  gri_logger(const char *filename);
+  ~gri_logger();
+
+  void write(const void *buf, size_t count);
+  void printf(const char *format, ...);
+};
+
+#endif /* INCLUDED_GRI_LOGGER_H */
diff --git a/gnuradio-core/src/lib/io/i2c.cc b/gnuradio-core/src/lib/io/i2c.cc
new file mode 100644 (file)
index 0000000..9b9fbcd
--- /dev/null
@@ -0,0 +1,28 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2001,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.
+ */
+
+#include "i2c.h"
+
+i2c::~i2c ()
+{
+  // NOP
+}
diff --git a/gnuradio-core/src/lib/io/i2c.h b/gnuradio-core/src/lib/io/i2c.h
new file mode 100644 (file)
index 0000000..88b3c91
--- /dev/null
@@ -0,0 +1,48 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2001,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.
+ */
+
+#ifndef INCLUDED_I2C_H
+#define INCLUDED_I2C_H
+
+#include <boost/shared_ptr.hpp>
+
+class i2c;
+typedef boost::shared_ptr<i2c> i2c_sptr;
+
+/*!
+ * \brief abstract class for controlling i2c bus
+ */
+class i2c {
+ public:
+  
+  i2c () {}
+  virtual ~i2c ();
+  
+  //! \returns true iff successful
+  virtual bool write (int addr, const unsigned char *buf, int nbytes) = 0;
+
+  //! \returns number of bytes read or -1 if error
+  virtual int read (int addr, unsigned char *buf, int max_bytes) = 0;
+};
+
+#endif /* INCLUDED_I2C_H */
+
diff --git a/gnuradio-core/src/lib/io/i2c_bbio.cc b/gnuradio-core/src/lib/io/i2c_bbio.cc
new file mode 100644 (file)
index 0000000..8f38397
--- /dev/null
@@ -0,0 +1,29 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2001,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.
+ */
+
+#include "i2c_bbio.h"
+
+i2c_bbio::~i2c_bbio ()
+{
+  // NOP
+}
+
diff --git a/gnuradio-core/src/lib/io/i2c_bbio.h b/gnuradio-core/src/lib/io/i2c_bbio.h
new file mode 100644 (file)
index 0000000..f0ea3b6
--- /dev/null
@@ -0,0 +1,49 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2001,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.
+ */
+
+#ifndef INCLUDED_I2C_BBIO_H
+#define INCLUDED_I2C_BBIO_H
+
+#include <boost/shared_ptr.hpp>
+
+class i2c_bbio;
+typedef boost::shared_ptr<i2c_bbio>    i2c_bbio_sptr;
+
+
+/*!
+ * \brief abstract class that implements bit banging i/o for i2c bus.
+ */
+class i2c_bbio {
+ public:
+
+  i2c_bbio () {}
+  virtual ~i2c_bbio ();
+  
+  virtual void set_scl (bool state) = 0;
+  virtual void set_sda (bool state) = 0;
+  virtual bool get_sda () = 0;
+
+  virtual void lock () = 0;
+  virtual void unlock () = 0;
+};
+
+#endif /* INCLUDED_I2C_BBIO_H */
diff --git a/gnuradio-core/src/lib/io/i2c_bbio_pp.cc b/gnuradio-core/src/lib/io/i2c_bbio_pp.cc
new file mode 100644 (file)
index 0000000..125f01c
--- /dev/null
@@ -0,0 +1,87 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2001,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.
+ */
+
+#include "i2c_bbio_pp.h"
+#include "microtune_eval_board_defs.h"
+
+i2c_bbio_pp::i2c_bbio_pp (ppio_sptr pp)
+{
+  d_pp = pp;
+  d_pp->lock ();
+  d_pp->write_control (d_pp->read_control () & ~UT_CP_MUST_BE_ZERO);   // output, no interrupts
+  d_pp->unlock ();
+}
+
+i2c_bbio_sptr
+make_i2c_bbio_pp (ppio_sptr pp)
+{
+  return i2c_bbio_sptr (new i2c_bbio_pp (pp));
+}
+
+void
+i2c_bbio_pp::set_scl (bool state)
+{
+  int  r = d_pp->read_control();
+
+  if (!state){                                 // active low
+    d_pp->write_control (r | UT_CP_TUNER_SCL);
+  }
+  else {
+    d_pp->write_control (r & ~UT_CP_TUNER_SCL);
+  }
+  d_pp->read_control ();       // use for 1us delay
+  d_pp->read_control ();       // use for 1us delay
+}
+
+void
+i2c_bbio_pp::set_sda (bool state)
+{
+  int  r = d_pp->read_data ();
+
+  if (!state){                                 // active low
+    d_pp->write_data (r | UT_DP_TUNER_SDA_OUT);
+  }
+  else {
+    d_pp->write_data (r & ~UT_DP_TUNER_SDA_OUT);
+  }
+  d_pp->read_data ();  // use for 1us delay
+  d_pp->read_data ();  // use for 1us delay
+}
+
+bool
+i2c_bbio_pp::get_sda ()
+{
+  int  r = d_pp->read_status ();
+  return (r & UT_SP_TUNER_SDA_IN) == 0;        // eval board has an inverter on it
+}
+
+void
+i2c_bbio_pp::lock ()
+{
+  d_pp->lock ();
+}
+
+void
+i2c_bbio_pp::unlock ()
+{
+  d_pp->unlock ();
+}
diff --git a/gnuradio-core/src/lib/io/i2c_bbio_pp.h b/gnuradio-core/src/lib/io/i2c_bbio_pp.h
new file mode 100644 (file)
index 0000000..25af0cf
--- /dev/null
@@ -0,0 +1,55 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2001,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.
+ */
+
+#ifndef INCLUDED_I2C_BBIO_PP_H
+#define INCLUDED_I2C_BBIO_PP_H
+
+#include "i2c_bbio.h"
+#include "ppio.h"
+
+/*!
+ * \brief concrete class that bit bangs eval board i2c bus using parallel port
+ *
+ * This class talks to the i2c bus on the microtune eval board using
+ * the parallel port.  This works for both the 4937 and 4702 boards.
+ */
+class i2c_bbio_pp : public i2c_bbio {
+  friend i2c_bbio_sptr make_i2c_bbio_pp (ppio_sptr pp);
+  i2c_bbio_pp (ppio_sptr pp);
+
+ public:
+
+  virtual void set_scl (bool state);
+  virtual void set_sda (bool state);
+  virtual bool get_sda ();
+
+  virtual void lock ();
+  virtual void unlock ();
+
+ private:
+  ppio_sptr    d_pp;
+};
+
+i2c_bbio_sptr make_i2c_bbio_pp (ppio_sptr pp);
+
+
+#endif /* INCLUDED_I2C_BBIO_PP_H */
diff --git a/gnuradio-core/src/lib/io/i2c_bitbang.cc b/gnuradio-core/src/lib/io/i2c_bitbang.cc
new file mode 100644 (file)
index 0000000..6bf37b6
--- /dev/null
@@ -0,0 +1,144 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2001,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.
+ */
+
+#include "i2c_bitbang.h"
+
+i2c_bitbang::i2c_bitbang (i2c_bbio_sptr io)
+{
+  d_io = io;
+  d_io->lock ();
+
+  stop ();     // get bus in known state
+
+  d_io->unlock ();
+}
+
+i2c_sptr 
+make_i2c_bitbang (i2c_bbio_sptr io)
+{
+  return i2c_sptr (new i2c_bitbang (io));
+}
+
+
+// start:
+//     entry: SCL = 1, SDA = 1
+//     exit:  SCL = 0, SDA = 0
+
+void 
+i2c_bitbang::start ()
+{
+  set_sda (1);
+  set_scl (1);
+  set_sda (0);         // SDA high -> low while SCL high
+  set_scl (0);
+}
+
+
+// stop: 
+//     entry: SCL = X, SDA = X
+//     exit:  SCL = 1, SDA = 1
+
+void 
+i2c_bitbang::stop ()
+{
+  set_scl (0);
+  set_sda (0);
+  set_scl (1);
+  set_sda (1);         // SDA low -> high while SCL high
+}
+
+
+// write_bit:
+//     entry: SCL = 0, SDA = X
+//     exit:  SCL = 0, SDA = X
+
+void 
+i2c_bitbang::write_bit (bool bit)
+{
+  set_sda (bit);
+  set_scl (1);
+  set_scl (0);
+}
+
+
+// write_byte:
+//     entry: SCL = 0, SDA = X
+//     exit:  SCL = 0, SDA = 1
+
+bool
+i2c_bitbang::write_byte (char t)
+{
+  int  i;
+  bool ack_bit;
+
+  for (i = 0; i < 8; i++){
+    write_bit (t & 0x80);
+    t <<= 1;
+  }
+
+  // clock #9. This is the ACK bit.
+
+  set_sda (1);         // tristate SDA
+  set_scl (1);
+  ack_bit = get_sda ();        // slave should pull SDA line low
+  set_scl (0);
+
+  return ack_bit == 0;
+}
+
+
+// write: the high level entry point...
+//     entry: SCL = 1, SDA = 1
+//     exit:  SCL = 1, SDA = 1
+
+bool
+i2c_bitbang::write (int addr, const unsigned char *buf, int nbytes)
+{
+  bool ok = true;
+  
+  d_io->lock ();
+  start ();
+  ok = write_byte ((addr << 1) | 0);   // addr plus "read opcode"
+
+  for (int i = 0; i < nbytes; i++)
+    ok &= write_byte (buf[i]);
+
+  stop ();
+  d_io->unlock ();
+  return ok;
+}
+
+
+// read: the high level entry point...
+//     entry: SCL = 1, SDA = 1
+//     exit:  SCL = 1, SDA = 1
+
+int
+i2c_bitbang::read (int addr, unsigned char *buf, int max_bytes)
+{
+  d_io->lock ();
+
+  // FIXME
+
+  d_io->unlock ();
+  return -1;
+}
diff --git a/gnuradio-core/src/lib/io/i2c_bitbang.h b/gnuradio-core/src/lib/io/i2c_bitbang.h
new file mode 100644 (file)
index 0000000..5196cd2
--- /dev/null
@@ -0,0 +1,63 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2001,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.
+ */
+
+#ifndef INCLUDED_I2C_BITBANG_H
+#define INCLUDED_I2C_BITBANG_H
+
+#include <i2c.h>
+#include <i2c_bbio.h>
+
+/*!
+ * \brief class for controlling i2c bus
+ */
+class i2c_bitbang : public i2c {
+  friend i2c_sptr make_i2c_bitbang (i2c_bbio_sptr io);
+  i2c_bitbang (i2c_bbio_sptr io);
+
+ public:
+  ~i2c_bitbang () {}
+  
+  //! \returns true iff successful
+  bool write (int addr, const unsigned char *buf, int nbytes);
+
+  //! \returns number of bytes read or -1 if error
+  int read (int addr, unsigned char *buf, int max_bytes);
+
+
+private:
+  void start ();
+  void stop ();
+  void write_bit (bool bit);
+  bool write_byte (char byte);
+  
+  void set_sda (bool bit) { d_io->set_sda (bit); }
+  void set_scl (bool bit) { d_io->set_scl (bit); }
+  bool get_sda () { return d_io->get_sda (); }
+
+  i2c_bbio_sptr                d_io;
+};
+
+i2c_sptr make_i2c_bitbang (i2c_bbio_sptr io);
+
+#endif /* INCLUDED_I2C_BITBANG_H */
+
+
diff --git a/gnuradio-core/src/lib/io/io.i b/gnuradio-core/src/lib/io/io.i
new file mode 100644 (file)
index 0000000..ae4ca26
--- /dev/null
@@ -0,0 +1,52 @@
+/* -*- 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 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.
+ */
+
+%{
+
+#include <gr_file_sink.h>
+#include <gr_file_source.h>
+#include <gr_file_descriptor_sink.h>
+#include <gr_file_descriptor_source.h>
+#include <microtune_4702_eval_board.h>
+#include <microtune_4937_eval_board.h>
+#include <sdr_1000.h>
+#include <gr_oscope_sink_x.h>
+#include <gr_oscope_sink_f.h>
+#include <ppio.h>
+#include <gr_message_source.h>
+#include <gr_message_sink.h>
+
+%}
+
+%include "gr_file_sink.i"
+%include "gr_file_source.i"
+%include "gr_file_descriptor_sink.i"
+%include "gr_file_descriptor_source.i"
+%include "microtune_xxxx_eval_board.i"
+%include "microtune_4702_eval_board.i"
+%include "microtune_4937_eval_board.i"
+%include "sdr_1000.i"
+%include "gr_oscope_sink.i"
+%include "ppio.i"
+%include "gr_message_source.i"
+%include "gr_message_sink.i"
+
diff --git a/gnuradio-core/src/lib/io/microtune_4702.cc b/gnuradio-core/src/lib/io/microtune_4702.cc
new file mode 100644 (file)
index 0000000..9b180ff
--- /dev/null
@@ -0,0 +1,183 @@
+/* -*- c++-*- */
+/*
+ * Copyright 2001,2003,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.
+ */
+
+#include "microtune_4702.h"
+#include <stdlib.h>
+#include <stdio.h>
+#include "i2c.h"
+
+static const double FIRST_IF = 36.00e6;
+
+// The tuner internally has 3 bands: VHF Low, VHF High & UHF.
+// These are the recommened boundaries
+static const double VHF_High_takeover = 174e6;
+static const double UHF_takeover = 470e6;
+
+static int PLL_I2C_ADDR            =   0x60;
+
+static unsigned char
+control_byte_1 (bool prescaler, int reference_divisor)
+{
+  int c = 0x80;
+  //Note: Last two divider bits (bits 2 and 3 of this byte) determined later
+  if (prescaler)
+    c |= 0x10;
+
+  switch (reference_divisor){
+  case 2:
+    c |= 0x00; break;
+  case 4:
+    c |= 0x01; break;
+  case 8:
+    c |= 0x02; break;
+  case 16:
+    c |= 0x03; break;
+  case 32:
+    c |= 0x04; break;
+  case 64:
+    c |= 0x05; break;
+  case 128:
+    c |= 0x06; break;
+  case 256:
+    c |= 0x07; break;
+  case 24:
+    c |= 0x08; break;
+  case 5:
+    c |= 0x09; break;
+  case 10:
+    c |= 0x0A; break;
+  case 20:
+    c |= 0x0B; break;
+  case 40:
+    c |= 0x0C; break;
+  case 80:
+    c |= 0x0D; break;
+  case 160:
+    c |= 0x0E; break;
+  case 320:
+    c |= 0x0F; break;
+  default:
+    abort ();
+  }
+  return c;
+}
+
+static unsigned char
+control_byte_2 (double target_freq)
+{
+  int  c;
+
+  if (target_freq < VHF_High_takeover) // VHF low
+    c = 0x8E;
+
+  else if (target_freq < UHF_takeover){        // VHF high
+    c = 0x05;
+    if (target_freq < 390e6)
+      c |= 0x40;
+    else
+      c |= 0x80;
+  }
+  else {                               // UHF
+    c = 0x03;
+    if (target_freq < 750e6)
+      c |= 0x80;
+    else
+      c |= 0xC0;
+  }
+
+  return c;
+}
+
+
+microtune_4702::microtune_4702 (i2c_sptr i2c, int i2c_addr)
+{
+  d_i2c = i2c;
+  d_i2c_addr = i2c_addr;
+  d_reference_divider = 320;
+  d_prescaler  = false;
+}
+
+microtune_4702::~microtune_4702 ()
+{
+  // nop
+}
+
+/*!
+ * \brief select RF frequency to be tuned to output frequency.
+ * \p target_freq is the requested frequency in Hz, \p actual_freq
+ * is set to the actual frequency tuned.  It takes about 100 ms
+ * for the PLL to settle.
+ *
+ * \returns true iff sucessful.
+ */
+bool
+microtune_4702::set_RF_freq (double target_freq, double *p_actual_freq)
+{
+  unsigned char buf[4];
+
+  double target_f_osc = target_freq + FIRST_IF;
+
+  double f_ref = 4e6 / d_reference_divider;
+
+  //int divisor = (int) ((target_f_osc + (f_ref * 4)) / (f_ref * 8));
+
+  long int divisor = (long int) (target_f_osc / f_ref);
+  double actual_freq = (f_ref * divisor) - FIRST_IF;
+  if (p_actual_freq != 0)
+    *p_actual_freq = actual_freq;
+
+  if ((divisor & ~0x1ffff) != 0)       // >17 bit divisor
+    return false;
+
+  buf[0] = ((divisor & 0x07f00) >> 8) & 0xff;  // DB1
+  buf[1] = divisor & 0xff;             // DB2
+  buf[2] = control_byte_1 (d_prescaler, d_reference_divider);
+  buf[2] = (buf[2]|(((divisor & 0x18000) >> 10)) & 0xff);
+  buf[3] = control_byte_2 (target_freq);
+
+  printf ("%x\n", PLL_I2C_ADDR);
+//#if 0
+  printf ("set_RF_freq: target: %g MHz actual: %g MHz %02x %02x %02x %02x\n",
+         target_freq/1e6, actual_freq/1e6, buf[0], buf[1], buf[2], buf[3]);
+//#endif
+
+  return d_i2c->write (d_i2c_addr, buf, sizeof (buf));
+}
+
+/*!
+ * \returns true iff PLL is locked
+ */
+bool 
+microtune_4702::pll_locked_p ()
+{
+  // FIXME
+  return true;
+}
+
+/*!
+ * \returns the output frequency of the tuner in Hz.
+ */
+double
+microtune_4702::get_output_freq ()
+{
+  return FIRST_IF;
+}
diff --git a/gnuradio-core/src/lib/io/microtune_4702.h b/gnuradio-core/src/lib/io/microtune_4702.h
new file mode 100644 (file)
index 0000000..b589077
--- /dev/null
@@ -0,0 +1,69 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2001,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 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.
+ */
+
+#ifndef INCLUDED_MICROTUNE_4702_H
+#define INCLUDED_MICROTUNE_4702_H
+
+#include <microtune_xxxx.h>
+
+/*!
+ * \brief class for controlling microtune 4702 tuner module
+ */
+
+class microtune_4702 : public microtune_xxxx   {
+public:
+  microtune_4702 (i2c_sptr i2c, int i2c_addr);
+
+  virtual ~microtune_4702 ();
+
+  /*!
+   * \brief select RF frequency to be tuned to output frequency.
+   * \p freq is the requested frequency in Hz, \p actual_freq
+   * is set to the actual frequency tuned.  It takes about 100 ms
+   * for the PLL to settle.
+   *
+   * \returns true iff sucessful.
+   */
+  bool set_RF_freq (double freq, double *actual_freq);
+
+  /*!
+   * \returns true iff PLL is locked
+   */
+  bool pll_locked_p ();
+  
+  /*!
+   * \returns the output frequency of the tuner in Hz.
+   */
+  double get_output_freq ();
+
+ private:
+
+  i2c_sptr     d_i2c;
+  int          d_i2c_addr;
+  int          d_reference_divider;
+  bool         d_prescaler;    /* if set, higher charge pump current:
+                                  faster tuning, worse phase noise
+                                  for distance < 10kHz to the carrier */
+};
+
+#endif /* INCLUDED_MICROTUNE_4702_H */
+
diff --git a/gnuradio-core/src/lib/io/microtune_4702_eval_board.cc b/gnuradio-core/src/lib/io/microtune_4702_eval_board.cc
new file mode 100644 (file)
index 0000000..88cf2b6
--- /dev/null
@@ -0,0 +1,88 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2001,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.
+ */
+
+#include "microtune_4702_eval_board.h"
+#include "microtune_eval_board_defs.h"
+#include "ppio.h"
+#include "microtune_4702.h"
+
+static const int TUNER_I2C_ADDR = 0x60;
+
+microtune_4702_eval_board::microtune_4702_eval_board (int which_pp)
+  : microtune_xxxx_eval_board (which_pp)
+{
+  d_tuner = new microtune_4702 (d_i2c, TUNER_I2C_ADDR);
+}
+
+microtune_4702_eval_board::~microtune_4702_eval_board ()
+{
+  // default is OK
+}
+
+static const float RF_MIN_V = 1.0;     // RF AGC control voltages
+static const float RF_MAX_V = 4.0;
+static const float IF_MIN_V = 2.0;     // IF AGC control voltages
+static const float IF_MAX_V = 4.0;
+
+static const float MIN_AGC  =    0;    // bottom of synthetic range
+static const float MAX_AGC  = 1000;    // top of synthetic range
+
+static const float CUTOVER_POINT = 667;
+
+
+// linear is in the range MIN_AGC to MAX_AGC
+
+static float
+linear_to_RF_AGC_voltage (float linear)
+{
+  if (linear >= CUTOVER_POINT)
+    return RF_MAX_V;
+
+  float slope = (RF_MAX_V - RF_MIN_V) / CUTOVER_POINT;
+  return RF_MIN_V + linear * slope;
+}
+
+static float
+linear_to_IF_AGC_voltage (float linear)
+{
+  if (linear < CUTOVER_POINT)
+    return IF_MIN_V;
+
+  float slope = (IF_MAX_V - IF_MIN_V) / (MAX_AGC - CUTOVER_POINT);
+  return IF_MIN_V + (linear - CUTOVER_POINT) * slope;
+}
+
+void
+microtune_4702_eval_board::set_AGC (float v)
+{
+  if (v < MIN_AGC)
+    v = MIN_AGC;
+
+  if (v > MAX_AGC)
+    v = MAX_AGC;
+
+  float rf_agc_voltage = linear_to_RF_AGC_voltage (v);
+  float if_agc_voltage = linear_to_IF_AGC_voltage (v);
+
+  set_RF_AGC_voltage (rf_agc_voltage);
+  set_IF_AGC_voltage (if_agc_voltage);
+}
diff --git a/gnuradio-core/src/lib/io/microtune_4702_eval_board.h b/gnuradio-core/src/lib/io/microtune_4702_eval_board.h
new file mode 100644 (file)
index 0000000..9fc2914
--- /dev/null
@@ -0,0 +1,47 @@
+/* -*- C++ -*- */
+/*
+ * Copyright 2001,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.
+ */
+
+#ifndef INCLUDED_MICROTUNE_4702_EVAL_BOARD_H
+#define INCLUDED_MICROTUNE_4702_EVAL_BOARD_H
+
+#include "microtune_xxxx_eval_board.h"
+
+/*!
+ * \brief control microtune 4702 eval board
+ */
+
+class microtune_4702_eval_board : public microtune_xxxx_eval_board {
+public:
+  microtune_4702_eval_board (int which_pp = 0);
+  ~microtune_4702_eval_board ();
+
+  /*!
+   * \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.
+   */
+  virtual void set_AGC (float value_0_1000);
+};
+
+#endif /* INCLUDED_MICROTUNE_4702_EVAL_BOARD_H */
diff --git a/gnuradio-core/src/lib/io/microtune_4702_eval_board.i b/gnuradio-core/src/lib/io/microtune_4702_eval_board.i
new file mode 100644 (file)
index 0000000..6205c93
--- /dev/null
@@ -0,0 +1,36 @@
+/* -*- C++ -*- */
+/*
+ * Copyright 2001,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.
+ */
+
+class microtune_4702_eval_board : public microtune_xxxx_eval_board {
+public:
+  microtune_4702_eval_board (int which_pp = 0);
+  ~microtune_4702_eval_board ();
+
+  /*!
+   * \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.
+   */
+  virtual void set_AGC (float value_0_1000);
+};
diff --git a/gnuradio-core/src/lib/io/microtune_4937.cc b/gnuradio-core/src/lib/io/microtune_4937.cc
new file mode 100644 (file)
index 0000000..c05f63c
--- /dev/null
@@ -0,0 +1,146 @@
+/* -*- c++-*- */
+/*
+ * Copyright 2001,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 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.
+ */
+
+#include "microtune_4937.h"
+#include <stdlib.h>
+#include <stdio.h>
+#include <i2c.h>
+
+static const double first_IF = 43.75e6;
+
+// The tuner internally has 3 bands: VHF Low, VHF High & UHF.
+// These are the recommened boundaries
+static const double VHF_High_takeover = 158e6;
+static const double UHF_takeover = 464e6;
+
+
+static unsigned char
+control_byte_1 (bool fast_tuning_p, int reference_divisor)
+{
+  int c = 0x88;
+
+  if (fast_tuning_p)
+    c |= 0x40;
+
+  switch (reference_divisor){
+  case 512:
+    c |= 0x3 << 1;     break;
+  case 640:
+    c |= 0x0 << 1;     break;
+  case 1024:
+    c |= 0x1 << 1;     break;
+  default:
+    abort ();
+  }
+  return c;
+}
+
+static unsigned char
+control_byte_2 (double target_freq, bool shutdown_tx_PGA)
+{
+  int  c;
+
+  if (target_freq < VHF_High_takeover) // VHF low
+    c = 0xa0;
+  else if (target_freq < UHF_takeover) // VHF high
+    c = 0x90;
+  else                                 // UHF
+    c = 0x30;
+
+  if (shutdown_tx_PGA)
+    c |= 0x08;
+
+  return c;
+}
+
+microtune_4937::microtune_4937 (i2c_sptr i2c, int i2c_addr)
+{
+  d_i2c = i2c;
+  d_i2c_addr = i2c_addr;
+  d_reference_divider = 640;
+  d_fast_tuning_p  = false;
+}
+
+microtune_4937::~microtune_4937 ()
+{
+  // nop
+}
+
+/*!
+ * \brief select RF frequency to be tuned to output frequency.
+ * \p target_freq is the requested frequency in Hz, \p actual_freq
+ * is set to the actual frequency tuned.  It takes about 100 ms
+ * for the PLL to settle.
+ *
+ * \returns true iff sucessful.
+ */
+bool
+microtune_4937::set_RF_freq (double target_freq, double *p_actual_freq)
+{
+  unsigned char buf[4];
+
+  double target_f_osc = target_freq + first_IF;
+  
+  double f_ref = 4e6 / d_reference_divider;
+
+  // f_osc = f_ref * 8 * divisor
+  // divisor = f_osc / (f_ref * 8)
+
+  int divisor = (int) ((target_f_osc + (f_ref * 4)) / (f_ref * 8));
+  double actual_freq = (f_ref * 8 * divisor) - first_IF;
+  if (p_actual_freq != 0)
+    *p_actual_freq = actual_freq;
+
+  if ((divisor & ~0x7fff) != 0)        // 15 bit divisor
+    return false;
+
+  buf[0] = (divisor >> 8) & 0xff;      // DB1
+  buf[1] = divisor & 0xff;             // DB2
+  buf[2] = control_byte_1 (d_fast_tuning_p, d_reference_divider);
+  buf[3] = control_byte_2 (target_freq, true);
+
+#if 0
+  printf ("set_RF_freq: target: %g MHz actual: %g MHz %02x %02x %02x %02x\n",
+         target_freq/1e6, actual_freq/1e6, buf[0], buf[1], buf[2], buf[3]);
+#endif
+
+  return d_i2c->write (d_i2c_addr, buf, 4);
+}
+
+/*!
+ * \returns true iff PLL is locked
+ */
+bool 
+microtune_4937::pll_locked_p ()
+{
+  // FIXME
+  return true;
+}
+
+/*!
+ * \returns the output frequency of the tuner in Hz.
+ */
+double
+microtune_4937::get_output_freq ()
+{
+  return 5.75e6;       // 3x7702
+}
diff --git a/gnuradio-core/src/lib/io/microtune_4937.h b/gnuradio-core/src/lib/io/microtune_4937.h
new file mode 100644 (file)
index 0000000..84c8d61
--- /dev/null
@@ -0,0 +1,66 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2001,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 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.
+ */
+
+#ifndef INCLUDED_MICROTUNE_4937_H
+#define INCLUDED_MICROTUNE_4937_H
+
+#include <microtune_xxxx.h>
+
+/*!
+ * \brief class for controlling microtune 4937 tuner module
+ */
+class microtune_4937 : public microtune_xxxx {
+public:
+  microtune_4937 (i2c_sptr i2c, int i2c_addr = 0x61);
+  virtual ~microtune_4937 ();
+
+  /*!
+   * \brief select RF frequency to be tuned to output frequency.
+   * \p freq is the requested frequency in Hz, \p actual_freq
+   * is set to the actual frequency tuned.  It takes about 100 ms
+   * for the PLL to settle.
+   *
+   * \returns true iff sucessful.
+   */
+  bool set_RF_freq (double freq, double *actual_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:
+
+  i2c_sptr     d_i2c;
+  int          d_i2c_addr;
+  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 */
+};
+
+#endif /* INCLUDED_MICROTUNE_4937_H */
diff --git a/gnuradio-core/src/lib/io/microtune_4937_eval_board.cc b/gnuradio-core/src/lib/io/microtune_4937_eval_board.cc
new file mode 100644 (file)
index 0000000..82a0374
--- /dev/null
@@ -0,0 +1,97 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2001,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.
+ */
+
+#include "microtune_4937_eval_board.h"
+#include "microtune_eval_board_defs.h"
+#include "ppio.h"
+#include "microtune_4937.h"
+
+static const int TUNER_I2C_ADDR = 0x61;
+
+microtune_4937_eval_board::microtune_4937_eval_board (int which_pp)
+  : microtune_xxxx_eval_board (which_pp)
+{
+  d_tuner = new microtune_4937 (d_i2c, TUNER_I2C_ADDR);
+
+  // disable upstream amplifier
+  d_ppio->lock ();
+  int  t = d_ppio->read_data ();
+  t &= ~(UT_DP_TX_ENABLE | UT_DP_TX_SDA | UT_DP_TX_SCL);
+  t |= UT_DP_TX_AS;
+  d_ppio->write_data (t);
+  d_ppio->unlock ();
+}
+
+microtune_4937_eval_board::~microtune_4937_eval_board ()
+{
+  // Default action is OK
+}
+
+
+static const float RF_MIN_V = 1.5;     // RF AGC control voltages
+static const float RF_MAX_V = 4.0;
+static const float IF_MIN_V = 2.0;     // IF AGC control voltages
+static const float IF_MAX_V = 4.0;
+
+static const float MIN_AGC  =    0;    // bottom of synthetic range
+static const float MAX_AGC  = 1000;    // top of synthetic range
+
+static const float CUTOVER_POINT = 667;
+
+
+// linear is in the range MIN_AGC to MAX_AGC
+
+static float
+linear_to_RF_AGC_voltage (float linear)
+{
+  if (linear >= CUTOVER_POINT)
+    return RF_MAX_V;
+
+  float slope = (RF_MAX_V - RF_MIN_V) / CUTOVER_POINT;
+  return RF_MIN_V + linear * slope;
+}
+
+static float
+linear_to_IF_AGC_voltage (float linear)
+{
+  if (linear < CUTOVER_POINT)
+    return IF_MIN_V;
+
+  float slope = (IF_MAX_V - IF_MIN_V) / (MAX_AGC - CUTOVER_POINT);
+  return IF_MIN_V + (linear - CUTOVER_POINT) * slope;
+}
+
+void
+microtune_4937_eval_board::set_AGC (float v)
+{
+  if (v < MIN_AGC)
+    v = MIN_AGC;
+
+  if (v > MAX_AGC)
+    v = MAX_AGC;
+
+  float rf_agc_voltage = linear_to_RF_AGC_voltage (v);
+  float if_agc_voltage = linear_to_IF_AGC_voltage (v);
+
+  set_RF_AGC_voltage (rf_agc_voltage);
+  set_IF_AGC_voltage (if_agc_voltage);
+}
diff --git a/gnuradio-core/src/lib/io/microtune_4937_eval_board.h b/gnuradio-core/src/lib/io/microtune_4937_eval_board.h
new file mode 100644 (file)
index 0000000..8a8f46b
--- /dev/null
@@ -0,0 +1,48 @@
+/* -*- C++ -*- */
+/*
+ * Copyright 2001,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.
+ */
+
+#ifndef INCLUDED_MICROTUNE_4937_EVAL_BOARD_H
+#define INCLUDED_MICROTUNE_4937_EVAL_BOARD_H
+
+#include "microtune_xxxx_eval_board.h"
+
+/*!
+ * \brief control microtune 4937 eval board
+ */
+
+class microtune_4937_eval_board : public microtune_xxxx_eval_board {
+public:
+  microtune_4937_eval_board (int which_pp = 0);
+  ~microtune_4937_eval_board ();
+
+  /*!
+   * \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.
+   */
+  virtual void set_AGC (float value_0_1000);
+};
+
+
+#endif /* INCLUDED_MICROTUNE_4937_EVAL_BOARD_H */
diff --git a/gnuradio-core/src/lib/io/microtune_4937_eval_board.i b/gnuradio-core/src/lib/io/microtune_4937_eval_board.i
new file mode 100644 (file)
index 0000000..106832e
--- /dev/null
@@ -0,0 +1,36 @@
+/* -*- C++ -*- */
+/*
+ * Copyright 2001,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.
+ */
+
+class microtune_4937_eval_board : public microtune_xxxx_eval_board {
+public:
+  microtune_4937_eval_board (int which_pp = 0);
+  ~microtune_4937_eval_board ();
+
+  /*!
+   * \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.
+   */
+  virtual void set_AGC (float value_0_1000);
+};
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..7c673e3
--- /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 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.
+ */
+
+/*
+ * 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/io/microtune_eval_board_defs.h b/gnuradio-core/src/lib/io/microtune_eval_board_defs.h
new file mode 100644 (file)
index 0000000..5245fd5
--- /dev/null
@@ -0,0 +1,71 @@
+/* -*-C-*-
+*******************************************************************************
+*
+* File:         microtune_eval_board_defs.h
+* Description:  defines for parallel port control of eval board
+*
+*******************************************************************************
+*/
+
+/*
+ * 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 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.
+ */
+
+#ifndef _MICROTUNE_EVAL_BOARD_DEFS_H_
+#define _MICROTUNE_EVAL_BOARD_DEFS_H_
+
+/*
+ * The Microtune 4937DI5 cable modem tuner eval board is controlled
+ * by bit banging the PC parallel port.  This file defines the relevant
+ * bits.
+ *
+ * The parallel port has an 8 bit data port (output),
+ * an 8 bit control port (output) and
+ * an 8 bit status port (input).
+ *
+ * Not all bits of the control and status ports may be arbitrarily used.
+ */
+
+
+// parallel port data port constants (output)
+
+static const int UT_DP_TX_SDA          = 0x01; // upstream control bus
+static const int UT_DP_TX_SCL          = 0x02; // upstream control bus
+static const int UT_DP_TX_AS           = 0x04; // upstream control bus
+static const int UT_DP_TX_ENABLE       = 0x08; // upstream h/w enable
+// bits 4,5,6 not used
+static const int UT_DP_TUNER_SDA_OUT   = 0x80; // tuner i2c bus data
+
+// parallel port control port constants (output)
+
+static const int UT_CP_TUNER_SCL       = 0x08; // tuner i2c bus clock
+static const int UT_CP_MUST_BE_ZERO    = 0xf0; // must be zero
+
+// parallel port status port constants (input)
+
+// bits 0,1,2 not used
+static const int UT_SP_TUNER_SCL_LOOP_BACK= 0x08; // inverted SCL loop back
+static const int UT_SP_SHOULD_BE_ZERO  = 0x10; // reads as zero
+static const int UT_SP_SHOULD_BE_ONE   = 0x20; // reads as one
+// bit 6 not used
+static const int UT_SP_TUNER_SDA_IN    = 0x80;
+
+
+#endif /* _MICROTUNE_EVAL_BOARD_DEFS_H_ */
diff --git a/gnuradio-core/src/lib/io/microtune_xxxx.cc b/gnuradio-core/src/lib/io/microtune_xxxx.cc
new file mode 100644 (file)
index 0000000..8633b11
--- /dev/null
@@ -0,0 +1,41 @@
+/* -*- c++-*- */
+/*
+ * Copyright 2001,2003,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.
+ */
+
+#include "microtune_xxxx.h"
+
+microtune_xxxx::~microtune_xxxx ()
+{
+  // nop
+}
+
+double
+microtune_xxxx::set_RF_freq (double target_freq)
+{
+  double actual_freq = 0.0;
+
+  if (set_RF_freq (target_freq, &actual_freq))
+    return actual_freq;
+
+  return 0.0;
+}
+
+  
diff --git a/gnuradio-core/src/lib/io/microtune_xxxx.h b/gnuradio-core/src/lib/io/microtune_xxxx.h
new file mode 100644 (file)
index 0000000..8fac06d
--- /dev/null
@@ -0,0 +1,64 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2001,2003,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.
+ */
+
+#ifndef INCLUDED_MICROTUNE_XXXX_H
+#define INCLUDED_MICROTUNE_XXXX_H
+
+#include <boost/shared_ptr.hpp>
+
+class i2c;
+typedef boost::shared_ptr<i2c> i2c_sptr;
+
+/*!
+ * \brief abstract class for controlling microtune {4937,4702} tuner modules
+ */
+class microtune_xxxx {
+public:
+  microtune_xxxx () {}
+  virtual ~microtune_xxxx ();
+
+  /*!
+   * \brief select RF frequency to be tuned to output frequency.
+   * \p freq is the requested frequency in Hz, \p actual_freq
+   * is set to the actual frequency tuned.  It takes about 100 ms
+   * for the PLL to settle.
+   *
+   * \returns true iff sucessful.
+   */
+  virtual bool set_RF_freq (double freq, double *actual_freq) = 0;
+  
+  // returns actual freq or 0 if error (easier interface for SWIG)
+  double set_RF_freq (double freq);
+
+  /*!
+   * \returns true iff PLL is locked
+   */
+  virtual bool pll_locked_p () = 0;
+  
+  /*!
+   * \returns the output frequency (IF center freq) of the tuner in Hz.
+   */
+  virtual double get_output_freq () = 0;
+
+};
+
+#endif /* INCLUDED_MICROTUNE_XXXX_H */
diff --git a/gnuradio-core/src/lib/io/microtune_xxxx_eval_board.cc b/gnuradio-core/src/lib/io/microtune_xxxx_eval_board.cc
new file mode 100644 (file)
index 0000000..a7ea98d
--- /dev/null
@@ -0,0 +1,140 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2001,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.
+ */
+
+#include "microtune_xxxx_eval_board.h"
+#include "microtune_eval_board_defs.h"
+#include "microtune_xxxx.h"
+#include "ppio.h"
+#include "i2c_bitbang.h"
+#include "i2c_bbio_pp.h"
+#include <cmath>
+
+static int AGC_DAC_I2C_ADDR =  0x2C;
+
+microtune_xxxx_eval_board::microtune_xxxx_eval_board (int which_pp)
+{
+  d_ppio = make_ppio (which_pp);
+  d_i2c = make_i2c_bitbang (make_i2c_bbio_pp (d_ppio));
+  d_tuner = 0;
+}
+
+microtune_xxxx_eval_board::~microtune_xxxx_eval_board ()
+{
+  delete d_tuner;
+  d_tuner = 0;
+}
+
+
+//! is the eval board present?
+bool 
+microtune_xxxx_eval_board::board_present_p ()
+{
+  bool result = true;
+  d_ppio->lock ();
+
+  int t = d_ppio->read_status ();
+  if ((t & UT_SP_SHOULD_BE_ZERO) != 0
+      || (t & UT_SP_SHOULD_BE_ONE) != UT_SP_SHOULD_BE_ONE)
+    result = false;
+
+  // could also see if SCL is looped back or not, but that seems like overkill
+
+  d_ppio->unlock ();
+  return result;
+}
+
+/*
+ * ----------------------------------------------------------------
+ *                         AGC stuff
+ *
+ * We're using a MAX518 8-bit 5V dual dac for setting the AGC's
+ * ----------------------------------------------------------------
+ */
+void 
+microtune_xxxx_eval_board::write_dac (int which, int value)
+{
+  unsigned char        cmd[2];
+  cmd[0] = which & 1;
+  cmd[1] = value;
+  d_i2c->write (AGC_DAC_I2C_ADDR, cmd, sizeof (cmd));
+}
+
+void 
+microtune_xxxx_eval_board::write_both_dacs (int value0, int value1)
+{
+  unsigned char        cmd[4];
+  cmd[0] = 0;
+  cmd[1] = value0;
+  cmd[2] = 1;
+  cmd[3] = value1;
+  d_i2c->write (AGC_DAC_I2C_ADDR, cmd, sizeof (cmd));
+}
+
+static int scale_volts (float volts)
+{
+  int  n;
+  n = (int) rint (volts * (256 / 5.0));
+  if (n < 0)
+    n = 0;
+  if (n > 255)
+    n = 255;
+
+  return n;
+}
+
+void
+microtune_xxxx_eval_board::set_RF_AGC_voltage (float volts)
+{
+  write_dac (0, scale_volts (volts));
+}
+
+void 
+microtune_xxxx_eval_board::set_IF_AGC_voltage (float volts)
+{
+  write_dac (1, scale_volts (volts));
+}
+
+// delegate to tuner
+
+bool
+microtune_xxxx_eval_board::set_RF_freq (double freq, double *actual_freq)
+{
+  return d_tuner->set_RF_freq (freq, actual_freq);
+}
+  
+double
+microtune_xxxx_eval_board::set_RF_freq (double freq)
+{
+  return d_tuner->set_RF_freq (freq);
+}
+
+bool
+microtune_xxxx_eval_board::pll_locked_p ()
+{
+  return d_tuner->pll_locked_p ();
+}
+
+double
+microtune_xxxx_eval_board::get_output_freq ()
+{
+  return d_tuner->get_output_freq ();
+}
diff --git a/gnuradio-core/src/lib/io/microtune_xxxx_eval_board.h b/gnuradio-core/src/lib/io/microtune_xxxx_eval_board.h
new file mode 100644 (file)
index 0000000..3a817b6
--- /dev/null
@@ -0,0 +1,96 @@
+/* -*- C++ -*- */
+/*
+ * Copyright 2001,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.
+ */
+
+#ifndef INCLUDED_MICROTUNE_XXXX_EVAL_BOARD_H
+#define INCLUDED_MICROTUNE_XXXX_EVAL_BOARD_H
+
+#include <boost/shared_ptr.hpp>
+
+class microtune_xxxx;
+
+class ppio;
+typedef boost::shared_ptr<ppio> ppio_sptr;
+
+class i2c;
+typedef boost::shared_ptr<i2c> i2c_sptr;
+
+/*!
+ * \brief abstract class for controlling microtune xxxx eval board
+ */
+class microtune_xxxx_eval_board {
+public:
+  microtune_xxxx_eval_board (int which_pp = 0);
+  virtual ~microtune_xxxx_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.
+   */
+  virtual void set_AGC (float value_0_1000) = 0;
+
+  /*!
+   * \brief select RF frequency to be tuned to output frequency.
+   * \p freq is the requested frequency in Hz, \p actual_freq
+   * is set to the actual frequency tuned.  It takes about 100 ms
+   * for the PLL to settle.
+   *
+   * \returns true iff sucessful.
+   */
+  bool set_RF_freq (double freq, double *actual_freq);
+  
+  // 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:
+  void write_dac (int which, int value);
+  void write_both_dacs (int val0, int val1);
+  
+protected:
+  ppio_sptr            d_ppio;
+  i2c_sptr             d_i2c;
+  microtune_xxxx       *d_tuner;
+};
+
+#endif /* INCLUDED_MICROTUNE_XXXX_EVAL_BOARD_H */
diff --git a/gnuradio-core/src/lib/io/microtune_xxxx_eval_board.i b/gnuradio-core/src/lib/io/microtune_xxxx_eval_board.i
new file mode 100644 (file)
index 0000000..2e43f27
--- /dev/null
@@ -0,0 +1,58 @@
+/* -*- 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 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.
+ */
+
+class microtune_xxxx_eval_board {
+public:
+  microtune_xxxx_eval_board (int which_pp = 0);
+  virtual ~microtune_xxxx_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.
+   */
+  virtual void set_AGC (float value_0_1000) = 0;
+
+  // 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 ();
+};
diff --git a/gnuradio-core/src/lib/io/ppio.cc b/gnuradio-core/src/lib/io/ppio.cc
new file mode 100644 (file)
index 0000000..86f402b
--- /dev/null
@@ -0,0 +1,39 @@
+/* -*- 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 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.
+ */
+
+#include <ppio.h>
+#include <ppio_ppdev.h>
+
+ppio::~ppio ()
+{
+}
+
+// Factory method.
+//
+// Right now, we've only got one subclass we like.  If there were more,
+// we'd instantiate the "right one" here.
+
+ppio_sptr
+make_ppio (int which_pp)
+{
+  return make_ppio_ppdev (which_pp);
+}
diff --git a/gnuradio-core/src/lib/io/ppio.h b/gnuradio-core/src/lib/io/ppio.h
new file mode 100644 (file)
index 0000000..4181387
--- /dev/null
@@ -0,0 +1,61 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2001,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 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.
+ */
+
+#ifndef INCLUDED_PPIO_H
+#define INCLUDED_PPIO_H
+
+#include <boost/shared_ptr.hpp>
+
+class ppio;
+typedef boost::shared_ptr<ppio> ppio_sptr;
+
+
+/*!
+ * \brief abstract class that provides low level access to parallel port bits
+ */
+
+class ppio {
+ public:
+  ppio () {}
+  virtual ~ppio ();
+
+  virtual void write_data (unsigned char v) = 0;
+  virtual unsigned char read_data () = 0;
+  virtual void write_control (unsigned char v) = 0;
+  virtual unsigned char read_control () = 0;
+  virtual unsigned char read_status () = 0;
+
+  virtual void lock () = 0;
+  virtual void unlock () = 0;
+};
+
+/*!
+ * \brief Factory method.  
+ *
+ * Split out from class to make life easier for SWIG
+ */
+
+ppio_sptr make_ppio (int which_pp);
+
+
+#endif /* INCLUDED_PPIO_H */
+
diff --git a/gnuradio-core/src/lib/io/ppio.i b/gnuradio-core/src/lib/io/ppio.i
new file mode 100644 (file)
index 0000000..2eaddc2
--- /dev/null
@@ -0,0 +1,48 @@
+/* -*- 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 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.
+ */
+
+class ppio;
+typedef boost::shared_ptr<ppio> ppio_sptr;
+
+%template(ppio_sptr) boost::shared_ptr<ppio>;
+
+/*!
+ * \brief abstract class that provides low level access to parallel port bits
+ */
+
+class ppio {
+ public:
+  ppio () {}
+  virtual ~ppio ();
+
+  virtual void write_data (unsigned char v) = 0;
+  virtual unsigned char read_data () = 0;
+  virtual void write_control (unsigned char v) = 0;
+  virtual unsigned char read_control () = 0;
+  virtual unsigned char read_status () = 0;
+
+  virtual void lock () = 0;
+  virtual void unlock () = 0;
+};
+
+
+ppio_sptr make_ppio (int which_pp);
diff --git a/gnuradio-core/src/lib/io/ppio_ppdev.cc b/gnuradio-core/src/lib/io/ppio_ppdev.cc
new file mode 100644 (file)
index 0000000..bfdaa3d
--- /dev/null
@@ -0,0 +1,221 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2001,2003,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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <ppio_ppdev.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <iostream>
+#include <errno.h>
+#include <stdio.h>
+#include <stdexcept>
+#ifdef HAVE_LINUX_PPDEV_H
+#include <sys/ioctl.h>
+#include <linux/ppdev.h>
+#include <linux/parport.h>
+#include <sstream>
+#else
+// #warn "ppio_ppdev is not functional on this platform"
+#endif
+
+// These control port bits are active low.
+// We toggle them so that this weirdness doesn't get get propagated
+// through our interface.
+
+static int CP_ACTIVE_LOW_BITS  = 0x0B;
+
+// These status port bits are active low.
+// We toggle them so that this weirdness doesn't get get propagated
+// through our interface.
+
+static int SP_ACTIVE_LOW_BITS  = 0x80;
+
+#ifndef HAVE_LINUX_PPDEV_H             // use stubs
+
+ppio_ppdev::ppio_ppdev (int which)
+{
+  std::cerr << "ppio_ppdev: Not implemented on this platform\n";
+  throw std::runtime_error ("not implmeneted");
+}
+
+ppio_ppdev::~ppio_ppdev ()
+{
+}
+
+void 
+ppio_ppdev::write_data (unsigned char v)
+{
+}
+
+unsigned char
+ppio_ppdev::read_data ()
+{
+  return 0;
+}
+
+void 
+ppio_ppdev::write_control (unsigned char v)
+{
+}
+
+unsigned char
+ppio_ppdev::read_control ()
+{
+  return 0;
+}
+
+unsigned char
+ppio_ppdev::read_status ()
+{
+  return 0;
+}
+
+void
+ppio_ppdev::lock ()
+{
+}
+
+void
+ppio_ppdev::unlock ()
+{
+}
+
+#else          
+
+// The real code...
+
+ppio_ppdev::ppio_ppdev (int which)
+{
+  std::ostringstream filename;
+  filename << "/dev/parport" << which;
+  const char *c_filename = filename.str().c_str();
+
+  if ((d_fd = open (c_filename, O_RDWR)) < 0){
+    int my_errno = errno;
+    perror (c_filename);
+    if (my_errno == ENOENT){
+      std::cerr << "Does the device file " << c_filename << " exist?\n";
+      std::cerr << "If not, as root execute: \n";
+      std::cerr << "  # mknod " << c_filename << " c 99 0\n";
+      std::cerr << "  # chmod 666 " << c_filename << std::endl;
+    }
+    throw std::runtime_error ("open");
+  }
+
+  int mode = IEEE1284_MODE_COMPAT;
+  if (ioctl (d_fd, PPSETMODE, &mode) != 0){
+    perror ("ppio_ppdev: PPSETMODE");
+    close (d_fd);
+    throw std::runtime_error ("PPSETMODE");
+  }
+}
+
+ppio_ppdev::~ppio_ppdev ()
+{
+  close (d_fd);
+}
+
+
+void 
+ppio_ppdev::write_data (unsigned char v)
+{
+  if (ioctl (d_fd, PPWDATA, &v) != 0){
+    perror ("ppio_ppdev: PPWDATA");
+    throw std::runtime_error ("PPWDATA");
+  }
+}
+
+unsigned char
+ppio_ppdev::read_data ()
+{
+  unsigned char v;
+
+  if (ioctl (d_fd, PPRDATA, &v) != 0){
+    perror ("ppio_ppdev: PPRDATA");
+    throw std::runtime_error ("PPRDATA");
+  }
+  return v;
+}
+
+void 
+ppio_ppdev::write_control (unsigned char v)
+{
+  unsigned char ctrl = v ^ CP_ACTIVE_LOW_BITS;
+  if (ioctl (d_fd, PPWCONTROL, &ctrl) != 0){
+    perror ("ppio_ppdev: PPWCONTROL");
+    throw std::runtime_error ("PPWCONTROL");
+  }
+}
+
+unsigned char
+ppio_ppdev::read_control ()
+{
+  unsigned char ctrl;
+  if (ioctl (d_fd, PPRCONTROL, &ctrl) != 0){
+    perror ("ppio_ppdev: PPRCONTROL");
+    throw std::runtime_error ("PPRCONTROL");
+  }
+
+  return ctrl ^ CP_ACTIVE_LOW_BITS;
+}
+
+unsigned char
+ppio_ppdev::read_status ()
+{
+  unsigned char status;
+  if (ioctl (d_fd, PPRSTATUS, &status) != 0){
+    perror ("ppio_ppdev: PPRSTATUS");
+    throw std::runtime_error ("PPRSTATUS");
+  }
+
+  return status ^ SP_ACTIVE_LOW_BITS;
+}
+
+void
+ppio_ppdev::lock ()
+{
+  if (ioctl (d_fd, PPCLAIM) != 0){
+    perror ("ppio_ppdev: PPCLAIM");
+    throw std::runtime_error ("PPCLAIM");
+  }
+}
+
+void
+ppio_ppdev::unlock ()
+{
+  if (ioctl (d_fd, PPRELEASE) != 0){
+    perror ("ppio_ppdev: PPRELEASE");
+    throw std::runtime_error ("PPRELEASE");
+  }
+}
+
+#endif
+
+ppio_ppdev_sptr
+make_ppio_ppdev (int which)
+{
+  return ppio_ppdev_sptr (new ppio_ppdev (which));
+}
diff --git a/gnuradio-core/src/lib/io/ppio_ppdev.h b/gnuradio-core/src/lib/io/ppio_ppdev.h
new file mode 100644 (file)
index 0000000..8ac4a35
--- /dev/null
@@ -0,0 +1,60 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2001,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 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.
+ */
+
+#ifndef INCLUDED_PPIO_PPDEV_H
+#define INCLUDED_PPIO_PPDEV_H
+
+#include <ppio.h>
+
+class ppio_ppdev;
+typedef boost::shared_ptr<ppio_ppdev> ppio_ppdev_sptr;
+
+/*!
+ * \brief access to parallel port bits using the linux ppdev interface
+ */
+
+class ppio_ppdev : public ppio {
+  friend ppio_ppdev_sptr make_ppio_ppdev (int which = 0);
+  ppio_ppdev (int which = 0);
+
+ public:
+  virtual ~ppio_ppdev ();
+
+  virtual void write_data (unsigned char v);
+  virtual unsigned char read_data ();
+  virtual void write_control (unsigned char v);
+  virtual unsigned char read_control ();
+  virtual unsigned char read_status ();
+
+  virtual void lock ();
+  virtual void unlock ();
+
+ private:
+  int  d_fd;
+};
+
+ppio_ppdev_sptr
+make_ppio_ppdev (int which);
+
+
+#endif /* INCLUDED_PPIO_PPDEV_H */
+
diff --git a/gnuradio-core/src/lib/io/sdr_1000.cc b/gnuradio-core/src/lib/io/sdr_1000.cc
new file mode 100644 (file)
index 0000000..1cb9b9a
--- /dev/null
@@ -0,0 +1,65 @@
+/* -*- 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 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.
+ */
+
+#include <sdr_1000.h>
+#include <ppio.h>
+
+sdr_1000_base::sdr_1000_base (int which_pp)
+{
+  d_ppio = make_ppio (which_pp);
+  d_shadow[0] = 0;
+  d_shadow[1] = 0;
+  d_shadow[2] = 0;
+  d_shadow[3] = 0;
+  reset ();
+}
+
+sdr_1000_base::~sdr_1000_base ()
+{
+}
+
+void
+sdr_1000_base::reset ()
+{
+  d_ppio->lock ();
+  d_ppio->write_control (0x0F);
+  d_ppio->unlock ();
+  write_latch (L_EXT,  0x00, 0xff);
+  write_latch (L_BAND, 0x00, 0xff);
+  write_latch (L_DDS0, 0x80, 0xff);    // hold DDS in reset
+  write_latch (L_DDS1, 0x00, 0xff);
+}
+
+  
+void
+sdr_1000_base::write_latch (int which, int value, int mask)
+{
+  if (!(0 <= which && which <= 3))
+    return;
+  
+  d_ppio->lock ();
+  d_shadow[which] = (d_shadow[which] & ~mask) | (value & mask);
+  d_ppio->write_data (d_shadow[which]);
+  d_ppio->write_control (0x0F ^ (1 << which));
+  d_ppio->write_control (0x0F);
+  d_ppio->unlock ();
+}
diff --git a/gnuradio-core/src/lib/io/sdr_1000.h b/gnuradio-core/src/lib/io/sdr_1000.h
new file mode 100644 (file)
index 0000000..f9ddb35
--- /dev/null
@@ -0,0 +1,51 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003,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.
+ */
+
+#ifndef INCLUDED_SDR_1000_H
+#define INCLUDED_SDR_1000_H
+
+#include <boost/shared_ptr.hpp>
+
+class ppio;
+typedef boost::shared_ptr<ppio> ppio_sptr;
+
+
+enum { L_EXT = 0, L_BAND = 1, L_DDS0 = 2, L_DDS1 = 3 };
+
+/*!
+ * \brief Very low level interface to SDR 1000 xcvr hardware
+ * \sa sdr_1000.py for a higher level interface.
+ */
+class sdr_1000_base {
+  ppio_sptr    d_ppio;
+  int          d_shadow[4];    // shadow latches
+  
+public:
+
+  sdr_1000_base (int which_pp);
+  ~sdr_1000_base ();
+  
+  void reset ();
+  void write_latch (int which, int value, int mask);
+};
+
+#endif /* INCLUDED_SDR_1000_H */
diff --git a/gnuradio-core/src/lib/io/sdr_1000.i b/gnuradio-core/src/lib/io/sdr_1000.i
new file mode 100644 (file)
index 0000000..46690e0
--- /dev/null
@@ -0,0 +1,36 @@
+/* -*- 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 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.
+ */
+
+const int L_EXT  = 0;
+const int L_BAND = 1;
+const int L_DDS0 = 2;
+const int L_DDS1 = 3;
+
+class sdr_1000_base {
+public:
+
+  sdr_1000_base (int which_pp);
+  ~sdr_1000_base ();
+
+  void reset ();
+  void write_latch (int which, int value, int mask);
+};
diff --git a/gnuradio-core/src/lib/missing/Makefile.am b/gnuradio-core/src/lib/missing/Makefile.am
new file mode 100644 (file)
index 0000000..7985fb3
--- /dev/null
@@ -0,0 +1,33 @@
+#
+# Copyright 2003,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.
+# 
+
+include $(top_srcdir)/Makefile.common
+
+EXTRA_DIST =                   \
+       getopt.h                \
+       getopt.c                \
+       gettimeofday.c          \
+       usleep.c
+
+noinst_LTLIBRARIES = libmissing.la
+
+libmissing_la_SOURCES =        \
+       bug_work_around_8.cc    
diff --git a/gnuradio-core/src/lib/missing/bug_work_around_8.cc b/gnuradio-core/src/lib/missing/bug_work_around_8.cc
new file mode 100644 (file)
index 0000000..b797022
--- /dev/null
@@ -0,0 +1,2 @@
+// if libmisc has no sources, it doesn't get built correctly
+static int gr_bug_work_around_8;
diff --git a/gnuradio-core/src/lib/missing/getopt.c b/gnuradio-core/src/lib/missing/getopt.c
new file mode 100644 (file)
index 0000000..93fb6ea
--- /dev/null
@@ -0,0 +1,733 @@
+/* Getopt for GNU.
+   NOTE: getopt is now part of the C library, so if you don't know what
+   "Keep this file name-space clean" means, talk to roland@gnu.ai.mit.edu
+   before changing it!
+
+   Copyright (C) 1987, 88, 89, 90, 91, 92, 1993
+       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, 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, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+\f
+/* NOTE!!!  AIX requires this to be the first thing in the file.
+   Do not put ANYTHING before it!  */
+#if !defined (__GNUC__) && defined (_AIX)
+ #pragma alloca
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifdef __GNUC__
+#define alloca __builtin_alloca
+#else /* not __GNUC__ */
+#if defined (HAVE_ALLOCA_H) || (defined(sparc) && (defined(sun) || (!defined(USG) && !defined(SVR4) && !defined(__svr4__))))
+#include <alloca.h>
+#else
+#ifndef _AIX
+char *alloca ();
+#endif
+#endif /* alloca.h */
+#endif /* not __GNUC__ */
+
+#if !__STDC__ && !defined(const) && IN_GCC
+#define const
+#endif
+
+/* This tells Alpha OSF/1 not to define a getopt prototype in <stdio.h>.  */
+#ifndef _NO_PROTO
+#define _NO_PROTO
+#endif
+
+#include <stdio.h>
+
+/* Comment out all this code if we are using the GNU C Library, and are not
+   actually compiling the library itself.  This code is part of the GNU C
+   Library, but also included in many other GNU distributions.  Compiling
+   and linking in this code is a waste when using the GNU C library
+   (especially if it is a shared library).  Rather than having every GNU
+   program understand `configure --with-gnu-libc' and omit the object files,
+   it is simpler to just do this in the source for each such file.  */
+
+#if defined (_LIBC) || !defined (__GNU_LIBRARY__)
+
+
+/* This needs to come after some library #include
+   to get __GNU_LIBRARY__ defined.  */
+#ifdef __GNU_LIBRARY__
+#undef alloca
+/* Don't include stdlib.h for non-GNU C libraries because some of them
+   contain conflicting prototypes for getopt.  */
+#include <stdlib.h>
+#else  /* Not GNU C library.  */
+#define        __alloca        alloca
+#endif /* GNU C library.  */
+
+/* If GETOPT_COMPAT is defined, `+' as well as `--' can introduce a
+   long-named option.  Because this is not POSIX.2 compliant, it is
+   being phased out.  */
+/* #define GETOPT_COMPAT */
+
+/* This version of `getopt' appears to the caller like standard Unix `getopt'
+   but it behaves differently for the user, since it allows the user
+   to intersperse the options with the other arguments.
+
+   As `getopt' works, it permutes the elements of ARGV so that,
+   when it is done, all the options precede everything else.  Thus
+   all application programs are extended to handle flexible argument order.
+
+   Setting the environment variable POSIXLY_CORRECT disables permutation.
+   Then the behavior is completely standard.
+
+   GNU application programs can use a third alternative mode in which
+   they can distinguish the relative order of options and other arguments.  */
+
+#include "getopt.h"
+
+/* For communication from `getopt' to the caller.
+   When `getopt' finds an option that takes an argument,
+   the argument value is returned here.
+   Also, when `ordering' is RETURN_IN_ORDER,
+   each non-option ARGV-element is returned here.  */
+
+char *optarg = 0;
+
+/* Index in ARGV of the next element to be scanned.
+   This is used for communication to and from the caller
+   and for communication between successive calls to `getopt'.
+
+   On entry to `getopt', zero means this is the first call; initialize.
+
+   When `getopt' returns EOF, this is the index of the first of the
+   non-option elements that the caller should itself scan.
+
+   Otherwise, `optind' communicates from one call to the next
+   how much of ARGV has been scanned so far.  */
+
+/* XXX 1003.2 says this must be 1 before any call.  */
+int optind = 0;
+
+/* The next char to be scanned in the option-element
+   in which the last option character we returned was found.
+   This allows us to pick up the scan where we left off.
+
+   If this is zero, or a null string, it means resume the scan
+   by advancing to the next ARGV-element.  */
+
+static char *nextchar;
+
+/* Callers store zero here to inhibit the error message
+   for unrecognized options.  */
+
+int opterr = 1;
+
+/* Set to an option character which was unrecognized.
+   This must be initialized on some systems to avoid linking in the
+   system's own getopt implementation.  */
+
+int optopt = '?';
+
+/* Describe how to deal with options that follow non-option ARGV-elements.
+
+   If the caller did not specify anything,
+   the default is REQUIRE_ORDER if the environment variable
+   POSIXLY_CORRECT is defined, PERMUTE otherwise.
+
+   REQUIRE_ORDER means don't recognize them as options;
+   stop option processing when the first non-option is seen.
+   This is what Unix does.
+   This mode of operation is selected by either setting the environment
+   variable POSIXLY_CORRECT, or using `+' as the first character
+   of the list of option characters.
+
+   PERMUTE is the default.  We permute the contents of ARGV as we scan,
+   so that eventually all the non-options are at the end.  This allows options
+   to be given in any order, even with programs that were not written to
+   expect this.
+
+   RETURN_IN_ORDER is an option available to programs that were written
+   to expect options and other ARGV-elements in any order and that care about
+   the ordering of the two.  We describe each non-option ARGV-element
+   as if it were the argument of an option with character code 1.
+   Using `-' as the first character of the list of option characters
+   selects this mode of operation.
+
+   The special argument `--' forces an end of option-scanning regardless
+   of the value of `ordering'.  In the case of RETURN_IN_ORDER, only
+   `--' can cause `getopt' to return EOF with `optind' != ARGC.  */
+
+static enum
+{
+  REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER
+} ordering;
+\f
+#ifdef __GNU_LIBRARY__
+/* We want to avoid inclusion of string.h with non-GNU libraries
+   because there are many ways it can cause trouble.
+   On some systems, it contains special magic macros that don't work
+   in GCC.  */
+#include <string.h>
+#define        my_index        strchr
+#define        my_bcopy(src, dst, n)   memcpy ((dst), (src), (n))
+#else
+
+/* Avoid depending on library functions or files
+   whose names are inconsistent.  */
+
+char *getenv ();
+
+static char *
+my_index (str, chr)
+     const char *str;
+     int chr;
+{
+  while (*str)
+    {
+      if (*str == chr)
+       return (char *) str;
+      str++;
+    }
+  return 0;
+}
+
+static void
+my_bcopy (from, to, size)
+     const char *from;
+     char *to;
+     int size;
+{
+  int i;
+  for (i = 0; i < size; i++)
+    to[i] = from[i];
+}
+#endif                         /* GNU C library.  */
+\f
+/* Handle permutation of arguments.  */
+
+/* Describe the part of ARGV that contains non-options that have
+   been skipped.  `first_nonopt' is the index in ARGV of the first of them;
+   `last_nonopt' is the index after the last of them.  */
+
+static int first_nonopt;
+static int last_nonopt;
+
+/* Exchange two adjacent subsequences of ARGV.
+   One subsequence is elements [first_nonopt,last_nonopt)
+   which contains all the non-options that have been skipped so far.
+   The other is elements [last_nonopt,optind), which contains all
+   the options processed since those non-options were skipped.
+
+   `first_nonopt' and `last_nonopt' are relocated so that they describe
+   the new indices of the non-options in ARGV after they are moved.  */
+
+static void
+exchange (argv)
+     char **argv;
+{
+  int nonopts_size = (last_nonopt - first_nonopt) * sizeof (char *);
+  char **temp = (char **) __alloca (nonopts_size);
+
+  /* Interchange the two blocks of data in ARGV.  */
+
+  my_bcopy ((char *) &argv[first_nonopt], (char *) temp, nonopts_size);
+  my_bcopy ((char *) &argv[last_nonopt], (char *) &argv[first_nonopt],
+           (optind - last_nonopt) * sizeof (char *));
+  my_bcopy ((char *) temp,
+           (char *) &argv[first_nonopt + optind - last_nonopt],
+           nonopts_size);
+
+  /* Update records for the slots the non-options now occupy.  */
+
+  first_nonopt += (optind - last_nonopt);
+  last_nonopt = optind;
+}
+\f
+/* Scan elements of ARGV (whose length is ARGC) for option characters
+   given in OPTSTRING.
+
+   If an element of ARGV starts with '-', and is not exactly "-" or "--",
+   then it is an option element.  The characters of this element
+   (aside from the initial '-') are option characters.  If `getopt'
+   is called repeatedly, it returns successively each of the option characters
+   from each of the option elements.
+
+   If `getopt' finds another option character, it returns that character,
+   updating `optind' and `nextchar' so that the next call to `getopt' can
+   resume the scan with the following option character or ARGV-element.
+
+   If there are no more option characters, `getopt' returns `EOF'.
+   Then `optind' is the index in ARGV of the first ARGV-element
+   that is not an option.  (The ARGV-elements have been permuted
+   so that those that are not options now come last.)
+
+   OPTSTRING is a string containing the legitimate option characters.
+   If an option character is seen that is not listed in OPTSTRING,
+   return '?' after printing an error message.  If you set `opterr' to
+   zero, the error message is suppressed but we still return '?'.
+
+   If a char in OPTSTRING is followed by a colon, that means it wants an arg,
+   so the following text in the same ARGV-element, or the text of the following
+   ARGV-element, is returned in `optarg'.  Two colons mean an option that
+   wants an optional arg; if there is text in the current ARGV-element,
+   it is returned in `optarg', otherwise `optarg' is set to zero.
+
+   If OPTSTRING starts with `-' or `+', it requests different methods of
+   handling the non-option ARGV-elements.
+   See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above.
+
+   Long-named options begin with `--' instead of `-'.
+   Their names may be abbreviated as long as the abbreviation is unique
+   or is an exact match for some defined option.  If they have an
+   argument, it follows the option name in the same ARGV-element, separated
+   from the option name by a `=', or else the in next ARGV-element.
+   When `getopt' finds a long-named option, it returns 0 if that option's
+   `flag' field is nonzero, the value of the option's `val' field
+   if the `flag' field is zero.
+
+   The elements of ARGV aren't really const, because we permute them.
+   But we pretend they're const in the prototype to be compatible
+   with other systems.
+
+   LONGOPTS is a vector of `struct option' terminated by an
+   element containing a name which is zero.
+
+   LONGIND returns the index in LONGOPT of the long-named option found.
+   It is only valid when a long-named option has been found by the most
+   recent call.
+
+   If LONG_ONLY is nonzero, '-' as well as '--' can introduce
+   long-named options.  */
+
+int
+_getopt_internal (argc, argv, optstring, longopts, longind, long_only)
+     int argc;
+     char *const *argv;
+     const char *optstring;
+     const struct option *longopts;
+     int *longind;
+     int long_only;
+{
+  int option_index;
+
+  optarg = 0;
+
+  /* Initialize the internal data when the first call is made.
+     Start processing options with ARGV-element 1 (since ARGV-element 0
+     is the program name); the sequence of previously skipped
+     non-option ARGV-elements is empty.  */
+
+  if (optind == 0)
+    {
+      first_nonopt = last_nonopt = optind = 1;
+
+      nextchar = NULL;
+
+      /* Determine how to handle the ordering of options and nonoptions.  */
+
+      if (optstring[0] == '-')
+       {
+         ordering = RETURN_IN_ORDER;
+         ++optstring;
+       }
+      else if (optstring[0] == '+')
+       {
+         ordering = REQUIRE_ORDER;
+         ++optstring;
+       }
+      else if (getenv ("POSIXLY_CORRECT") != NULL)
+       ordering = REQUIRE_ORDER;
+      else
+       ordering = PERMUTE;
+    }
+
+  if (nextchar == NULL || *nextchar == '\0')
+    {
+      if (ordering == PERMUTE)
+       {
+         /* If we have just processed some options following some non-options,
+            exchange them so that the options come first.  */
+
+         if (first_nonopt != last_nonopt && last_nonopt != optind)
+           exchange ((char **) argv);
+         else if (last_nonopt != optind)
+           first_nonopt = optind;
+
+         /* Now skip any additional non-options
+            and extend the range of non-options previously skipped.  */
+
+         while (optind < argc
+                && (argv[optind][0] != '-' || argv[optind][1] == '\0')
+#ifdef GETOPT_COMPAT
+                && (longopts == NULL
+                    || argv[optind][0] != '+' || argv[optind][1] == '\0')
+#endif                         /* GETOPT_COMPAT */
+                )
+           optind++;
+         last_nonopt = optind;
+       }
+
+      /* Special ARGV-element `--' means premature end of options.
+        Skip it like a null option,
+        then exchange with previous non-options as if it were an option,
+        then skip everything else like a non-option.  */
+
+      if (optind != argc && !strcmp (argv[optind], "--"))
+       {
+         optind++;
+
+         if (first_nonopt != last_nonopt && last_nonopt != optind)
+           exchange ((char **) argv);
+         else if (first_nonopt == last_nonopt)
+           first_nonopt = optind;
+         last_nonopt = argc;
+
+         optind = argc;
+       }
+
+      /* If we have done all the ARGV-elements, stop the scan
+        and back over any non-options that we skipped and permuted.  */
+
+      if (optind == argc)
+       {
+         /* Set the next-arg-index to point at the non-options
+            that we previously skipped, so the caller will digest them.  */
+         if (first_nonopt != last_nonopt)
+           optind = first_nonopt;
+         return EOF;
+       }
+
+      /* If we have come to a non-option and did not permute it,
+        either stop the scan or describe it to the caller and pass it by.  */
+
+      if ((argv[optind][0] != '-' || argv[optind][1] == '\0')
+#ifdef GETOPT_COMPAT
+         && (longopts == NULL
+             || argv[optind][0] != '+' || argv[optind][1] == '\0')
+#endif                         /* GETOPT_COMPAT */
+         )
+       {
+         if (ordering == REQUIRE_ORDER)
+           return EOF;
+         optarg = argv[optind++];
+         return 1;
+       }
+
+      /* We have found another option-ARGV-element.
+        Start decoding its characters.  */
+
+      nextchar = (argv[optind] + 1
+                 + (longopts != NULL && argv[optind][1] == '-'));
+    }
+
+  if (longopts != NULL
+      && ((argv[optind][0] == '-'
+          && (argv[optind][1] == '-' || long_only))
+#ifdef GETOPT_COMPAT
+         || argv[optind][0] == '+'
+#endif                         /* GETOPT_COMPAT */
+         ))
+    {
+      const struct option *p;
+      char *s = nextchar;
+      int exact = 0;
+      int ambig = 0;
+      const struct option *pfound = NULL;
+      int indfound;
+
+      while (*s && *s != '=')
+       s++;
+
+      /* Test all options for either exact match or abbreviated matches.  */
+      for (p = longopts, option_index = 0; p->name;
+          p++, option_index++)
+       if (!strncmp (p->name, nextchar, s - nextchar))
+         {
+           if (s - nextchar == strlen (p->name))
+             {
+               /* Exact match found.  */
+               pfound = p;
+               indfound = option_index;
+               exact = 1;
+               break;
+             }
+           else if (pfound == NULL)
+             {
+               /* First nonexact match found.  */
+               pfound = p;
+               indfound = option_index;
+             }
+           else
+             /* Second nonexact match found.  */
+             ambig = 1;
+         }
+
+      if (ambig && !exact)
+       {
+         if (opterr)
+           fprintf (stderr, "%s: option `%s' is ambiguous\n",
+                    argv[0], argv[optind]);
+         nextchar += strlen (nextchar);
+         optind++;
+         return '?';
+       }
+
+      if (pfound != NULL)
+       {
+         option_index = indfound;
+         optind++;
+         if (*s)
+           {
+             /* Don't test has_arg with >, because some C compilers don't
+                allow it to be used on enums.  */
+             if (pfound->has_arg)
+               optarg = s + 1;
+             else
+               {
+                 if (opterr)
+                   {
+                     if (argv[optind - 1][1] == '-')
+                       /* --option */
+                       fprintf (stderr,
+                                "%s: option `--%s' doesn't allow an argument\n",
+                                argv[0], pfound->name);
+                     else
+                       /* +option or -option */
+                       fprintf (stderr,
+                            "%s: option `%c%s' doesn't allow an argument\n",
+                            argv[0], argv[optind - 1][0], pfound->name);
+                   }
+                 nextchar += strlen (nextchar);
+                 return '?';
+               }
+           }
+         else if (pfound->has_arg == 1)
+           {
+             if (optind < argc)
+               optarg = argv[optind++];
+             else
+               {
+                 if (opterr)
+                   fprintf (stderr, "%s: option `%s' requires an argument\n",
+                            argv[0], argv[optind - 1]);
+                 nextchar += strlen (nextchar);
+                 return optstring[0] == ':' ? ':' : '?';
+               }
+           }
+         nextchar += strlen (nextchar);
+         if (longind != NULL)
+           *longind = option_index;
+         if (pfound->flag)
+           {
+             *(pfound->flag) = pfound->val;
+             return 0;
+           }
+         return pfound->val;
+       }
+      /* Can't find it as a long option.  If this is not getopt_long_only,
+        or the option starts with '--' or is not a valid short
+        option, then it's an error.
+        Otherwise interpret it as a short option.  */
+      if (!long_only || argv[optind][1] == '-'
+#ifdef GETOPT_COMPAT
+         || argv[optind][0] == '+'
+#endif                         /* GETOPT_COMPAT */
+         || my_index (optstring, *nextchar) == NULL)
+       {
+         if (opterr)
+           {
+             if (argv[optind][1] == '-')
+               /* --option */
+               fprintf (stderr, "%s: unrecognized option `--%s'\n",
+                        argv[0], nextchar);
+             else
+               /* +option or -option */
+               fprintf (stderr, "%s: unrecognized option `%c%s'\n",
+                        argv[0], argv[optind][0], nextchar);
+           }
+         nextchar = (char *) "";
+         optind++;
+         return '?';
+       }
+    }
+
+  /* Look at and handle the next option-character.  */
+
+  {
+    char c = *nextchar++;
+    char *temp = my_index (optstring, c);
+
+    /* Increment `optind' when we start to process its last character.  */
+    if (*nextchar == '\0')
+      ++optind;
+
+    if (temp == NULL || c == ':')
+      {
+       if (opterr)
+         {
+#if 0
+           if (c < 040 || c >= 0177)
+             fprintf (stderr, "%s: unrecognized option, character code 0%o\n",
+                      argv[0], c);
+           else
+             fprintf (stderr, "%s: unrecognized option `-%c'\n", argv[0], c);
+#else
+           /* 1003.2 specifies the format of this message.  */
+           fprintf (stderr, "%s: illegal option -- %c\n", argv[0], c);
+#endif
+         }
+       optopt = c;
+       return '?';
+      }
+    if (temp[1] == ':')
+      {
+       if (temp[2] == ':')
+         {
+           /* This is an option that accepts an argument optionally.  */
+           if (*nextchar != '\0')
+             {
+               optarg = nextchar;
+               optind++;
+             }
+           else
+             optarg = 0;
+           nextchar = NULL;
+         }
+       else
+         {
+           /* This is an option that requires an argument.  */
+           if (*nextchar != '\0')
+             {
+               optarg = nextchar;
+               /* If we end this ARGV-element by taking the rest as an arg,
+                  we must advance to the next element now.  */
+               optind++;
+             }
+           else if (optind == argc)
+             {
+               if (opterr)
+                 {
+#if 0
+                   fprintf (stderr, "%s: option `-%c' requires an argument\n",
+                            argv[0], c);
+#else
+                   /* 1003.2 specifies the format of this message.  */
+                   fprintf (stderr, "%s: option requires an argument -- %c\n",
+                            argv[0], c);
+#endif
+                 }
+               optopt = c;
+               if (optstring[0] == ':')
+                 c = ':';
+               else
+                 c = '?';
+             }
+           else
+             /* We already incremented `optind' once;
+                increment it again when taking next ARGV-elt as argument.  */
+             optarg = argv[optind++];
+           nextchar = NULL;
+         }
+      }
+    return c;
+  }
+}
+
+#ifdef GETOPT
+int
+getopt (argc, argv, optstring)
+     int argc;
+     char *const *argv;
+     const char *optstring;
+{
+  return _getopt_internal (argc, argv, optstring,
+                          (const struct option *) 0,
+                          (int *) 0,
+                          0);
+}
+#endif
+
+#endif /* _LIBC or not __GNU_LIBRARY__.  */
+\f
+#ifdef TEST
+
+/* Compile with -DTEST to make an executable for use in testing
+   the above definition of `getopt'.  */
+
+int
+main (argc, argv)
+     int argc;
+     char **argv;
+{
+  int c;
+  int digit_optind = 0;
+
+  while (1)
+    {
+      int this_option_optind = optind ? optind : 1;
+
+      c = getopt (argc, argv, "abc:d:0123456789");
+      if (c == EOF)
+       break;
+
+      switch (c)
+       {
+       case '0':
+       case '1':
+       case '2':
+       case '3':
+       case '4':
+       case '5':
+       case '6':
+       case '7':
+       case '8':
+       case '9':
+         if (digit_optind != 0 && digit_optind != this_option_optind)
+           printf ("digits occur in two different argv-elements.\n");
+         digit_optind = this_option_optind;
+         printf ("option %c\n", c);
+         break;
+
+       case 'a':
+         printf ("option a\n");
+         break;
+
+       case 'b':
+         printf ("option b\n");
+         break;
+
+       case 'c':
+         printf ("option c with value `%s'\n", optarg);
+         break;
+
+       case '?':
+         break;
+
+       default:
+         printf ("?? getopt returned character code 0%o ??\n", c);
+       }
+    }
+
+  if (optind < argc)
+    {
+      printf ("non-option ARGV-elements: ");
+      while (optind < argc)
+       printf ("%s ", argv[optind++]);
+      printf ("\n");
+    }
+
+  exit (0);
+}
+
+#endif /* TEST */
diff --git a/gnuradio-core/src/lib/missing/getopt.h b/gnuradio-core/src/lib/missing/getopt.h
new file mode 100644 (file)
index 0000000..45541f5
--- /dev/null
@@ -0,0 +1,129 @@
+/* Declarations for getopt.
+   Copyright (C) 1989, 1990, 1991, 1992, 1993 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, 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, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+#ifndef _GETOPT_H
+#define _GETOPT_H 1
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* For communication from `getopt' to the caller.
+   When `getopt' finds an option that takes an argument,
+   the argument value is returned here.
+   Also, when `ordering' is RETURN_IN_ORDER,
+   each non-option ARGV-element is returned here.  */
+
+extern char *optarg;
+
+/* Index in ARGV of the next element to be scanned.
+   This is used for communication to and from the caller
+   and for communication between successive calls to `getopt'.
+
+   On entry to `getopt', zero means this is the first call; initialize.
+
+   When `getopt' returns EOF, this is the index of the first of the
+   non-option elements that the caller should itself scan.
+
+   Otherwise, `optind' communicates from one call to the next
+   how much of ARGV has been scanned so far.  */
+
+extern int optind;
+
+/* Callers store zero here to inhibit the error message `getopt' prints
+   for unrecognized options.  */
+
+extern int opterr;
+
+/* Set to an option character which was unrecognized.  */
+
+extern int optopt;
+
+/* Describe the long-named options requested by the application.
+   The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector
+   of `struct option' terminated by an element containing a name which is
+   zero.
+
+   The field `has_arg' is:
+   no_argument         (or 0) if the option does not take an argument,
+   required_argument   (or 1) if the option requires an argument,
+   optional_argument   (or 2) if the option takes an optional argument.
+
+   If the field `flag' is not NULL, it points to a variable that is set
+   to the value given in the field `val' when the option is found, but
+   left unchanged if the option is not found.
+
+   To have a long-named option do something other than set an `int' to
+   a compiled-in constant, such as set a value from `optarg', set the
+   option's `flag' field to zero and its `val' field to a nonzero
+   value (the equivalent single-letter option character, if there is
+   one).  For long options that have a zero `flag' field, `getopt'
+   returns the contents of the `val' field.  */
+
+struct option
+{
+#if    __STDC__
+  const char *name;
+#else
+  char *name;
+#endif
+  /* has_arg can't be an enum because some compilers complain about
+     type mismatches in all the code that assumes it is an int.  */
+  int has_arg;
+  int *flag;
+  int val;
+};
+
+/* Names for the values of the `has_arg' field of `struct option'.  */
+
+#define        no_argument             0
+#define required_argument      1
+#define optional_argument      2
+
+#if __STDC__
+#if defined(__GNU_LIBRARY__)
+/* Many other libraries have conflicting prototypes for getopt, with
+   differences in the consts, in stdlib.h.  To avoid compilation
+   errors, only prototype getopt for the GNU C library.  */
+extern int getopt (int argc, char *const *argv, const char *shortopts);
+#else /* not __GNU_LIBRARY__ */
+extern int getopt ();
+#endif /* not __GNU_LIBRARY__ */
+extern int getopt_long (int argc, char *const *argv, const char *shortopts,
+                       const struct option *longopts, int *longind);
+extern int getopt_long_only (int argc, char *const *argv,
+                            const char *shortopts,
+                            const struct option *longopts, int *longind);
+
+/* Internal only.  Users should not call this directly.  */
+extern int _getopt_internal (int argc, char *const *argv,
+                            const char *shortopts,
+                            const struct option *longopts, int *longind,
+                            int long_only);
+#else /* not __STDC__ */
+extern int getopt ();
+extern int getopt_long ();
+extern int getopt_long_only ();
+
+extern int _getopt_internal ();
+#endif /* not __STDC__ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _GETOPT_H */
diff --git a/gnuradio-core/src/lib/missing/gettimeofday.c b/gnuradio-core/src/lib/missing/gettimeofday.c
new file mode 100644 (file)
index 0000000..4ed15e2
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * 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 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.
+ */
+
+#include <config.h>
+
+#ifdef HAVE_WINDOWS_H
+#include <windows.h>
+#endif
+#ifdef HAVE_WINBASE_H
+# include <winbase.h>
+#endif
+
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#endif
+
+/* 
+ * broken implementation for WIN32. 
+ * FIXME: usec precision
+ */
+int gettimeofday(struct timeval *tv, struct timezone *tz)
+{
+       if (tv) {
+               time_t tm;
+               
+               time(&tm);
+               tv->tv_sec = tm;
+               tv->tv_usec = 0;
+       }
+       return 0;
+}
+
diff --git a/gnuradio-core/src/lib/missing/usleep.c b/gnuradio-core/src/lib/missing/usleep.c
new file mode 100644 (file)
index 0000000..4a0f75e
--- /dev/null
@@ -0,0 +1,67 @@
+/* Copyright (C) 1992 Free Software Foundation, Inc.
+This file is part of the GNU C Library.
+
+The GNU C Library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public License as
+published by the Free Software Foundation; either version 2 of the
+License, or (at your option) any later version.
+
+The GNU C Library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <config.h>
+
+#ifndef HAVE_USLEEP
+
+#include <sys/types.h>
+#include <sys/time.h>
+
+#ifdef HAVE_SYS_SELECT_H
+# include <sys/select.h>
+#endif
+
+#ifdef HAVE_WINDOWS_H
+#include <windows.h>
+#endif
+#ifdef HAVE_WINBASE_H
+# include <winbase.h>
+#endif
+
+#ifdef apollo
+# include <apollo/base.h>
+# include <apollo/time.h>
+  static time_$clock_t DomainTime100mS =
+    {
+       0, 100000/4
+    };
+  static status_$t DomainStatus;
+#endif
+
+/* Sleep USECONDS microseconds, or until a previously set timer goes off.  */
+int
+usleep (unsigned long useconds)
+{
+#ifdef apollo
+  /* The usleep function does not work under the SYS5.3 environment.
+     Use the Domain/OS time_$wait call instead. */
+  time_$wait (time_$relative, DomainTime100mS, &DomainStatus);
+#elif defined(HAVE_SSLEEP)     /* Win32 */
+  Sleep( useconds/1000 );
+#else
+  struct timeval delay;
+
+  delay.tv_sec = 0;
+  delay.tv_usec = useconds;
+  select (0, 0, 0, 0, &delay);
+#endif
+  return 0;
+}
+
+#endif /* !HAVE_USLEEP */
diff --git a/gnuradio-core/src/lib/omnithread/Makefile.am b/gnuradio-core/src/lib/omnithread/Makefile.am
new file mode 100644 (file)
index 0000000..f223446
--- /dev/null
@@ -0,0 +1,67 @@
+#
+# 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 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.
+# 
+
+include $(top_srcdir)/Makefile.common
+
+# This is the omnithread package,
+#   extracted from the omniORB-4.0.1 distribution
+
+# we should do some configure hacking to determine these on the fly
+OMNITHREAD_DEFINES = -DPthreadDraftVersion=10
+
+INCLUDES = $(STD_DEFINES_AND_INCLUDES) $(OMNITHREAD_DEFINES)
+
+noinst_LTLIBRARIES = libomnithread.la
+
+# At this point we only support the posix and nt pthreads i/f...
+
+if OMNITHREAD_POSIX
+libomnithread_la_SOURCES =             \
+       posix.cc
+endif
+
+if OMNITHREAD_NT
+libomnithread_la_SOURCES =             \
+       nt.cc
+endif
+
+libomnithread_la_LIBADD =              \
+       $(PTHREAD_LIBS)
+
+# ... but this code also came with the package
+
+EXTRA_DIST =                           \
+       mach.cc                         \
+       nt.cc                           \
+       posix.cc                        \
+       solaris.cc                      \
+       threaddata.cc                   \
+       vxWorks.cc                      \
+       dir.mk
+
+grinclude_HEADERS =                    \
+       omnithread.h                    \
+       ot_mach.h                       \
+       ot_nt.h                         \
+       ot_posix.h                      \
+       ot_pthread_nt.h                 \
+       ot_solaris.h                    \
+       ot_VxThread.h                   
diff --git a/gnuradio-core/src/lib/omnithread/dir.mk b/gnuradio-core/src/lib/omnithread/dir.mk
new file mode 100644 (file)
index 0000000..d538034
--- /dev/null
@@ -0,0 +1,229 @@
+ifeq ($(ThreadSystem),Solaris)
+CXXSRCS = solaris.cc
+DIR_CPPFLAGS = $(OMNITHREAD_CPPFLAGS)
+endif
+
+ifeq ($(ThreadSystem),Posix)
+CXXSRCS = posix.cc
+DIR_CPPFLAGS = $(OMNITHREAD_CPPFLAGS) $(OMNITHREAD_POSIX_CPPFLAGS)
+endif
+
+ifeq ($(ThreadSystem),NT)
+CXXSRCS = nt.cc
+DIR_CPPFLAGS = $(OMNITHREAD_CPPFLAGS)
+MSVC_STATICLIB_CXXNODEBUGFLAGS += -D_WINSTATIC
+MSVC_STATICLIB_CXXDEBUGFLAGS += -D_WINSTATIC
+MSVC_DLL_CXXNODEBUGFLAGS += -D_OMNITHREAD_DLL
+MSVC_DLL_CXXDEBUGFLAGS += -D_OMNITHREAD_DLL
+endif
+
+ifeq ($(ThreadSystem),NTPosix)
+CXXSRCS = posix.cc
+DIR_CPPFLAGS = $(OMNITHREAD_CPPFLAGS)
+MSVC_STATICLIB_CXXNODEBUGFLAGS += -D_WINSTATIC
+MSVC_STATICLIB_CXXDEBUGFLAGS += -D_WINSTATIC
+MSVC_DLL_CXXNODEBUGFLAGS += -D_OMNITHREAD_DLL
+MSVC_DLL_CXXDEBUGFLAGS += -D_OMNITHREAD_DLL
+endif
+
+ifeq ($(ThreadSystem),Mach)
+CXXSRCS = mach.cc
+DIR_CPPFLAGS = $(OMNITHREAD_CPPFLAGS)
+endif
+
+ifeq ($(ThreadSystem),vxWorks)
+CXXSRCS = vxWorks.cc
+OBJS = vxWorks.o
+DIR_CPPFLAGS = $(OMNITHREAD_CPPFLAGS)
+endif
+
+LIB_NAME     := omnithread
+LIB_VERSION  := $(OMNITHREAD_VERSION)
+LIB_OBJS     := $(CXXSRCS:.cc=.o)
+LIB_IMPORTS  := $(OMNITHREAD_PLATFORM_LIB)
+
+all:: mkstatic mkshared
+
+export:: mkstatic mkshared
+
+ifdef INSTALLTARGET
+install:: mkstatic mkshared
+endif
+
+vers := $(subst ., ,$(LIB_VERSION))
+ifeq ($(words $(vers)), 2)
+  vers  := _ $(vers)
+  major := ""
+else
+  major := $(word 1, $(vers))
+endif
+
+namespec := $(LIB_NAME) $(vers)
+
+##############################################################################
+# Build Static library
+##############################################################################
+
+ifndef NoStaticLibrary
+
+staticlib := static/$(patsubst %,$(LibNoDebugPattern),$(LIB_NAME)$(major))
+
+mkstatic::
+       @(dir=static; $(CreateDir))
+
+mkstatic:: $(staticlib)
+
+$(staticlib): $(patsubst %, static/%, $(LIB_OBJS))
+       @$(StaticLinkLibrary)
+
+export:: $(staticlib)
+       @$(ExportLibrary)
+
+ifdef INSTALLTARGET
+install:: $(staticlib)
+       @$(InstallLibrary)
+endif
+
+clean::
+       $(RM) static/*.o
+       $(RM) $(staticlib)
+
+veryclean::
+       $(RM) static/*.o
+       $(RM) $(staticlib)
+
+else
+
+mkstatic::
+
+endif
+
+
+##############################################################################
+# Build Shared library
+##############################################################################
+ifdef BuildSharedLibrary
+
+shlib := shared/$(shell $(SharedLibraryFullName) $(namespec))
+
+ifdef Win32Platform
+# in case of Win32 lossage:
+  imps := $(patsubst $(DLLDebugSearchPattern),$(DLLNoDebugSearchPattern), \
+          $(LIB_IMPORTS))
+else
+  imps := $(LIB_IMPORTS)
+endif
+
+mkshared::
+       @(dir=shared; $(CreateDir))
+
+mkshared:: $(shlib)
+
+$(shlib): $(patsubst %, shared/%, $(LIB_OBJS))
+       @(namespec="$(namespec)" extralibs="$(imps)" nodeffile=1; \
+         $(MakeCXXSharedLibrary))
+
+export:: $(shlib)
+       @(namespec="$(namespec)"; \
+          $(ExportSharedLibrary))
+
+ifdef INSTALLTARGET
+install:: $(shlib)
+       @(namespec="$(namespec)"; \
+          $(InstallSharedLibrary))
+endif
+
+clean::
+       $(RM) shared/*.o
+       (dir=shared; $(CleanSharedLibrary))
+
+veryclean::
+       $(RM) shared/*.o
+       @(dir=shared; $(CleanSharedLibrary))
+
+else
+
+mkshared::
+
+endif
+
+##############################################################################
+# Build debug libraries for Win32
+##############################################################################
+ifdef Win32Platform
+
+ifdef BuildSharedLibrary
+
+all:: mkstaticdbug mkshareddbug
+
+export:: mkstaticdbug mkshareddbug
+
+else
+
+all:: mkstaticdbug
+
+export:: mkstaticdbug
+
+endif
+
+
+#####################################################
+#      Static debug libraries
+#####################################################
+
+dbuglib := debug/$(patsubst %,$(LibDebugPattern),$(LIB_NAME)$(major))
+
+mkstaticdbug::
+       @(dir=debug; $(CreateDir))
+
+mkstaticdbug:: $(dbuglib)
+
+$(dbuglib): $(patsubst %, debug/%, $(LIB_OBJS))
+       @$(StaticLinkLibrary)
+
+export:: $(dbuglib)
+       @$(ExportLibrary)
+
+clean::
+       $(RM) debug/*.o
+       $(RM) $(dbuglib)
+
+veryclean::
+       $(RM) debug/*.o
+       $(RM) $(dbuglib)
+
+#####################################################
+#      DLL debug libraries
+#####################################################
+
+ifdef BuildSharedLibrary
+
+dbugshlib := shareddebug/$(shell $(SharedLibraryDebugFullName) $(namespec))
+
+dbugimps  := $(patsubst $(DLLNoDebugSearchPattern),$(DLLDebugSearchPattern), \
+               $(LIB_IMPORTS))
+
+mkshareddbug::
+       @(dir=shareddebug; $(CreateDir))
+
+mkshareddbug:: $(dbugshlib)
+
+$(dbugshlib): $(patsubst %, shareddebug/%, $(LIB_OBJS))
+       (namespec="$(namespec)" debug=1 extralibs="$(dbugimps)" nodeffile=1; \
+         $(MakeCXXSharedLibrary))
+
+export:: $(dbugshlib)
+       @(namespec="$(namespec)" debug=1; \
+          $(ExportSharedLibrary))
+
+clean::
+       $(RM) shareddebug/*.o
+       @(dir=shareddebug; $(CleanSharedLibrary))
+
+veryclean::
+       $(RM) shareddebug/*.o
+       @(dir=shareddebug; $(CleanSharedLibrary))
+
+endif
+endif
+
diff --git a/gnuradio-core/src/lib/omnithread/mach.cc b/gnuradio-core/src/lib/omnithread/mach.cc
new file mode 100644 (file)
index 0000000..06f8a11
--- /dev/null
@@ -0,0 +1,714 @@
+//                             Package : omnithread
+// omnithread/mach.cc          Created : 7/97 lars immisch lars@ibp.de
+//
+//    Copyright (C) 1997 Immisch, Becker & Partner
+//
+//    This file is part of the omnithread library
+//
+//    The omnithread library is free software; you can redistribute it and/or
+//    modify it under the terms of the GNU Library General Public
+//    License as published by the Free Software Foundation; either
+//    version 2 of the License, or (at your option) any later version.
+//
+//    This library is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//    Library General Public License for more details.
+//
+//    You should have received a copy of the GNU Library General Public
+//    License along with this library; if not, write to the Free
+//    Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  
+//    02111-1307, USA
+//
+
+//
+// Implementation of OMNI thread abstraction for mach threads
+//
+// to the author's pleasure, mach cthreads are very similar to posix threads
+//
+
+#include <stdlib.h>
+#include <errno.h>
+#include <sys/time.h>
+#include <mach/cthreads.h>
+#include "omnithread.h"
+
+#define DB(x) // x
+// #include <iostream> or #include <iostream.h> if DB is on.
+
+#define ERRNO(x) (x)
+
+//
+// static variables
+//
+
+int omni_thread::init_t::count = 0;
+
+omni_mutex* omni_thread::next_id_mutex;
+int omni_thread::next_id = 0;
+
+static int normal_priority;
+static int highest_priority;
+
+static size_t stack_size = 0;
+
+///////////////////////////////////////////////////////////////////////////
+//
+// Mutex
+//
+///////////////////////////////////////////////////////////////////////////
+
+
+omni_mutex::omni_mutex(void)
+{
+  mutex_init(&mach_mutex);     
+}
+
+
+omni_mutex::~omni_mutex(void)
+{
+  mutex_clear(&mach_mutex);    
+}
+
+
+void omni_mutex::lock(void)
+{
+  mutex_lock(&mach_mutex);
+}
+
+
+void omni_mutex::unlock(void)
+{
+  mutex_unlock(&mach_mutex);
+}
+
+
+
+///////////////////////////////////////////////////////////////////////////
+//
+// Condition variable
+//
+///////////////////////////////////////////////////////////////////////////
+
+
+omni_condition::omni_condition(omni_mutex* m) : mutex(m)
+{
+  condition_init(&mach_cond);
+}
+
+
+omni_condition::~omni_condition(void)
+{
+  condition_clear(&mach_cond);
+}
+
+void
+omni_condition::wait(void)
+{
+  condition_wait(&mach_cond, &mutex->mach_mutex);
+}
+
+typedef struct alarmclock_args {
+  unsigned long secs;
+  unsigned long nsecs;
+  bool wakeup;
+  condition_t condition;
+  mutex_t mutex;
+};
+
+any_t alarmclock(any_t arg)
+{
+  alarmclock_args* alarm = (alarmclock_args*)arg;
+       
+  omni_thread::sleep(alarm->secs, alarm->nsecs);
+
+  mutex_lock(alarm->mutex);
+                       
+  alarm->wakeup = TRUE;
+       
+  condition_signal(alarm->condition);
+               
+  mutex_unlock(alarm->mutex);
+
+  return (any_t)TRUE;
+}
+
+int omni_condition::timedwait(unsigned long abs_secs, unsigned long abs_nsecs)
+{
+  alarmclock_args alarm;
+
+  omni_thread::get_time(&alarm.secs, &alarm.nsecs, 0, 0);
+       
+  if (abs_secs < alarm.secs || (abs_secs == alarm.secs && abs_nsecs <= alarm.nsecs))
+    return ETIMEDOUT;
+
+  alarm.secs = abs_secs - alarm.secs;
+  if (abs_nsecs <= alarm.nsecs) {
+    alarm.nsecs = 1000000 - alarm.nsecs + abs_nsecs;
+    alarm.secs--;
+  }
+  else {
+    alarm.nsecs = abs_nsecs - alarm.nsecs;
+  }
+
+  alarm.mutex = &mutex->mach_mutex;
+  alarm.condition = &mach_cond;
+  alarm.wakeup = FALSE;
+       
+  cthread_t ct = cthread_fork((cthread_fn_t)alarmclock, (any_t)&alarm);
+  cthread_detach(ct);
+       
+  condition_wait(&mach_cond, &mutex->mach_mutex);
+               
+  if (alarm.wakeup) {
+    return 0;
+  }
+       
+  // interrupt the alarmclock thread sleep
+  cthread_abort(ct);
+       
+  // wait until it has signalled the condition
+  condition_wait(&mach_cond, &mutex->mach_mutex);
+
+  return 1;
+}
+
+
+void omni_condition::signal(void)
+{
+  condition_signal(&mach_cond);
+}
+
+
+void omni_condition::broadcast(void)
+{
+  condition_signal(&mach_cond);
+}
+
+
+
+///////////////////////////////////////////////////////////////////////////
+//
+// Counting semaphore
+//
+///////////////////////////////////////////////////////////////////////////
+
+
+omni_semaphore::omni_semaphore(unsigned int initial) : c(&m)
+{
+  value = initial;
+}
+
+
+omni_semaphore::~omni_semaphore(void)
+{
+}
+
+
+void 
+omni_semaphore::wait(void)
+{
+  omni_mutex_lock l(m);
+
+  while (value == 0)
+    c.wait();
+
+  value--;
+}
+
+
+int
+omni_semaphore::trywait(void)
+{
+  omni_mutex_lock l(m);
+
+  if (value == 0)
+    return 0;
+
+  value--;
+  return 1;
+}
+
+
+void
+omni_semaphore::post(void)
+{
+  omni_mutex_lock l(m);
+
+  if (value == 0)
+    c.signal();
+
+  value++;
+}
+
+
+
+///////////////////////////////////////////////////////////////////////////
+//
+// Thread
+//
+///////////////////////////////////////////////////////////////////////////
+
+
+
+//
+// Initialisation function (gets called before any user code).
+//
+
+omni_thread::init_t::init_t(void)
+{
+  if (count++ != 0)    // only do it once however many objects get created.
+    return;
+
+  //
+  // find base and max priority. 
+  // This is the initial thread, so the max priority of this
+  // thread also applies to any newly created thread.
+  //
+
+  kern_return_t                                error;
+  struct thread_sched_info     info;
+  unsigned int                         info_count = THREAD_SCHED_INFO_COUNT;
+
+  error = thread_info(thread_self(), THREAD_SCHED_INFO, (thread_info_t)&info, &info_count);
+  if (error != KERN_SUCCESS) {
+    DB(cerr << "omni_thread::init: error determining thread_info" << endl);
+    ::exit(1);
+  }
+  else {
+    normal_priority = info.base_priority;
+    highest_priority = info.max_priority;
+  }
+
+  next_id_mutex = new omni_mutex;
+
+  //
+  // Create object for this (i.e. initial) thread.
+  //
+
+  omni_thread* t = new omni_thread;
+
+  if (t->_state != STATE_NEW) {
+    DB(cerr << "omni_thread::init: problem creating initial thread object\n");
+    ::exit(1);
+  }
+
+  t->_state = STATE_RUNNING;
+  
+  t->mach_thread = cthread_self();
+
+  DB(cerr << "initial thread " << t->id() << endl);
+
+  cthread_set_data(t->mach_thread, (any_t)t);
+}
+
+
+//
+// Wrapper for thread creation.
+//
+
+extern "C" void*
+omni_thread_wrapper(void* ptr)
+{
+  omni_thread* me = (omni_thread*)ptr;
+  
+  DB(cerr << "omni_thread::wrapper: thread " << me->id()
+     << " started\n");
+
+  cthread_set_data(cthread_self(), (any_t)me);
+
+  //
+  // Now invoke the thread function with the given argument.
+  //
+
+  if (me->fn_void != NULL) {
+    (*me->fn_void)(me->thread_arg);
+    omni_thread::exit();
+  }
+  
+  if (me->fn_ret != NULL) {
+    void* return_value = (*me->fn_ret)(me->thread_arg);
+    omni_thread::exit(return_value);
+  }
+  
+  if (me->detached) {
+    me->run(me->thread_arg);
+    omni_thread::exit();
+  } else {
+    void* return_value = me->run_undetached(me->thread_arg);
+    omni_thread::exit(return_value);
+  }
+
+  // should never get here.
+
+  return NULL;
+}
+
+
+//
+// Constructors for omni_thread - set up the thread object but don't
+// start it running.
+//
+
+// construct a detached thread running a given function.
+
+omni_thread::omni_thread(void (*fn)(void*), void* arg, priority_t pri)
+{
+  common_constructor(arg, pri, 1);
+  fn_void = fn;
+  fn_ret = NULL;
+}
+
+// construct an undetached thread running a given function.
+
+omni_thread::omni_thread(void* (*fn)(void*), void* arg, priority_t pri)
+{
+  common_constructor(arg, pri, 0);
+  fn_void = NULL;
+  fn_ret = fn;
+}
+
+// construct a thread which will run either run() or run_undetached().
+
+omni_thread::omni_thread(void* arg, priority_t pri)
+{
+  common_constructor(arg, pri, 1);
+  fn_void = NULL;
+  fn_ret = NULL;
+}
+
+// common part of all constructors.
+
+void omni_thread::common_constructor(void* arg, priority_t pri, int det)
+{
+  _state = STATE_NEW;
+  _priority = pri;
+  
+  next_id_mutex->lock();
+  _id = next_id++;
+  next_id_mutex->unlock();
+  
+  thread_arg = arg;
+  detached = det;      // may be altered in start_undetached()
+
+  _dummy       = 0;
+  _values      = 0;
+  _value_alloc = 0;
+  // posix_thread is set up in initialisation routine or start().
+}
+
+
+//
+// Destructor for omni_thread.
+//
+
+omni_thread::~omni_thread(void)
+{
+  DB(cerr << "destructor called for thread " << id() << endl);
+  if (_values) {
+    for (key_t i=0; i < _value_alloc; i++) {
+      if (_values[i]) {
+       delete _values[i];
+      }
+    }
+    delete [] _values;
+  }
+}
+
+
+//
+// Start the thread
+//
+
+void 
+omni_thread::start(void)
+{
+  omni_mutex_lock l(mutex);
+
+  int rc;
+
+  if (_state != STATE_NEW)
+    throw omni_thread_invalid();
+
+  mach_thread = cthread_fork(omni_thread_wrapper, (any_t)this);
+       
+  _state = STATE_RUNNING;
+
+  if (detached) {
+    cthread_detach(mach_thread);
+  }
+}
+
+//
+// Start a thread which will run the member function run_undetached().
+//
+
+void
+omni_thread::start_undetached(void)
+{
+  if ((fn_void != NULL) || (fn_ret != NULL))
+    throw omni_thread_invalid();
+
+  detached = 0;
+  start();
+}
+
+
+//
+// join - simply check error conditions & call cthread_join.
+//
+
+void 
+omni_thread::join(void** status)
+{
+  mutex.lock();
+
+  if ((_state != STATE_RUNNING) && (_state != STATE_TERMINATED)) {
+    mutex.unlock();
+    throw omni_thread_invalid();
+  }
+
+  mutex.unlock();
+
+  if (this == self())  
+    throw omni_thread_invalid();
+
+  if (detached)
+    throw omni_thread_invalid();
+
+  DB(cerr << "omni_thread::join: doing cthread_join\n");
+
+ *status = cthread_join(mach_thread);
+
+  delete this;
+}
+
+
+//
+// Change this thread's priority.
+//
+
+void
+omni_thread::set_priority(priority_t pri)
+{
+  omni_mutex_lock l(mutex);
+
+  if (_state != STATE_RUNNING)
+    throw omni_thread_invalid();
+
+  _priority = pri;
+
+  kern_return_t rc = cthread_priority(mach_thread, mach_priority(pri), FALSE);
+       
+  if (rc != KERN_SUCCESS)
+    throw omni_thread_fatal(errno);
+}
+
+//
+// create - construct a new thread object and start it running.  Returns thread
+// object if successful, null pointer if not.
+//
+
+// detached version
+
+omni_thread* 
+omni_thread::create(void (*fn)(void*), void* arg, priority_t pri)
+{
+  omni_thread* t = new omni_thread(fn, arg, pri);
+
+  t->start();
+
+  return t;
+}
+
+// undetached version
+
+omni_thread*
+omni_thread::create(void* (*fn)(void*), void* arg, priority_t pri)
+{
+  omni_thread* t = new omni_thread(fn, arg, pri);
+
+  t->start();
+
+  return t;
+}
+
+//
+// exit() _must_ lock the mutex even in the case of a detached thread.  This is
+// because a thread may run to completion before the thread that created it has
+// had a chance to get out of start().  By locking the mutex we ensure that the
+// creating thread must have reached the end of start() before we delete the
+// thread object.  Of course, once the call to start() returns, the user can
+// still incorrectly refer to the thread object, but that's their problem.
+//
+
+void omni_thread::exit(void* return_value)
+{
+  omni_thread* me = self();
+
+  if (me)
+    {
+      me->mutex.lock();
+
+      if (me->_state != STATE_RUNNING)
+       DB(cerr << "omni_thread::exit: thread not in \"running\" state\n");
+
+      me->_state = STATE_TERMINATED;
+
+      me->mutex.unlock();
+
+      DB(cerr << "omni_thread::exit: thread " << me->id() << " detached "
+        << me->detached << " return value " << return_value << endl);
+
+      if (me->detached)
+       delete me;
+    }
+  else
+    {
+      DB(cerr << "omni_thread::exit: called with a non-omnithread. Exit quietly." << endl);
+    }
+  cthread_exit(return_value);
+}
+
+omni_thread* omni_thread::self(void)
+{
+  omni_thread* me;
+
+  me = (omni_thread*)cthread_data(cthread_self());
+
+  if (!me) {
+    // This thread is not created by omni_thread::start because it
+    // doesn't has a class omni_thread instance attached to its key.
+    DB(cerr << "omni_thread::self: called with a non-ominthread. NULL is returned." << endl);
+  }
+       
+  return me;
+}
+
+void omni_thread::yield(void)
+{
+  cthread_yield();
+}
+
+#define MAX_SLEEP_SECONDS (unsigned)4294966    // (2**32-2)/1000
+
+void
+omni_thread::sleep(unsigned long secs, unsigned long nanosecs)
+{
+  if (secs <= MAX_SLEEP_SECONDS) {
+    thread_switch(THREAD_NULL, SWITCH_OPTION_WAIT, secs * 1000 + nanosecs / 1000000);
+    return;
+  }
+
+  unsigned no_of_max_sleeps = secs / MAX_SLEEP_SECONDS;
+
+  for (unsigned i = 0; i < no_of_max_sleeps; i++)
+    thread_switch(THREAD_NULL, SWITCH_OPTION_WAIT, MAX_SLEEP_SECONDS * 1000);
+
+  thread_switch(THREAD_NULL, SWITCH_OPTION_WAIT, 
+               (secs % MAX_SLEEP_SECONDS) * 1000 + nanosecs / 1000000);
+       
+  return;
+}
+
+void
+omni_thread::get_time(unsigned long* abs_sec, unsigned long* abs_nsec,
+                     unsigned long rel_sec, unsigned long rel_nsec)
+{
+  int rc;
+  unsigned long tv_sec;
+  unsigned long tv_nsec;
+  struct timeval tv;
+       
+  rc = gettimeofday(&tv, NULL); 
+  if (rc)      throw omni_thread_fatal(rc);
+
+  tv_sec = tv.tv_sec;
+  tv_nsec = tv.tv_usec * 1000;
+
+  tv_nsec += rel_nsec;
+  tv_sec += rel_sec + tv_nsec / 1000000000;
+  tv_nsec = tv_nsec % 1000000000;
+
+  *abs_sec = tv_sec;
+  *abs_nsec = tv_nsec;
+}
+
+
+int 
+omni_thread::mach_priority(priority_t pri)
+{
+  switch (pri) {
+
+  case PRIORITY_LOW:
+    return 0;
+
+  case PRIORITY_NORMAL:
+    return normal_priority;
+
+  case PRIORITY_HIGH:
+    return highest_priority;
+
+  default:
+    return -1;
+  }
+}
+
+void
+omni_thread::stacksize(unsigned long sz)
+{
+  stack_size = sz;
+}
+
+unsigned long
+omni_thread::stacksize()
+{
+  return stack_size;
+}
+
+
+//
+// Dummy thread
+//
+
+#error This dummy thread code is not tested. It might work if you're lucky.
+
+class omni_thread_dummy : public omni_thread {
+public:
+  inline omni_thread_dummy() : omni_thread()
+  {
+    _dummy = 1;
+    _state = STATE_RUNNING;
+    mach_thread = cthread_self();
+    cthread_set_data(mach_thread, (any_t)this));
+  }
+  inline ~omni_thread_dummy()
+  {
+    cthread_set_data(mach_thread, (any_t)0));
+  }
+};
+
+omni_thread*
+omni_thread::create_dummy()
+{
+  if (omni_thread::self())
+    throw omni_thread_invalid();
+
+  return new omni_thread_dummy;
+}
+
+void
+omni_thread::release_dummy()
+{
+  omni_thread* self = omni_thread::self();
+  if (!self || !self->_dummy)
+    throw omni_thread_invalid();
+
+  omni_thread_dummy* dummy = (omni_thread_dummy*)self;
+  delete dummy;
+}
+
+
+#define INSIDE_THREAD_IMPL_CC
+#include "threaddata.cc"
+#undef INSIDE_THREAD_IMPL_CC
diff --git a/gnuradio-core/src/lib/omnithread/nt.cc b/gnuradio-core/src/lib/omnithread/nt.cc
new file mode 100644 (file)
index 0000000..09be422
--- /dev/null
@@ -0,0 +1,967 @@
+//                             Package : omnithread
+// omnithread/nt.cc            Created : 6/95 tjr
+//
+//    Copyright (C) 2006 Free Software Foundation, Inc.
+//    Copyright (C) 1995-1999 AT&T Laboratories Cambridge
+//
+//    This file is part of the omnithread library
+//
+//    The omnithread library is free software; you can redistribute it and/or
+//    modify it under the terms of the GNU Library General Public
+//    License as published by the Free Software Foundation; either
+//    version 2 of the License, or (at your option) any later version.
+//
+//    This library is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//    Library General Public License for more details.
+//
+//    You should have received a copy of the GNU Library General Public
+//    License along with this library; if not, write to the Free
+//    Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  
+//    02111-1307, USA
+//
+
+//
+// Implementation of OMNI thread abstraction for NT threads
+//
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdlib.h>
+#include <errno.h>
+#include <omnithread.h>
+#include <process.h>
+
+#define DB(x) // x 
+//#include <iostream.h> or #include <iostream> if DB is on.
+
+static void get_time_now(unsigned long* abs_sec, unsigned long* abs_nsec);
+
+///////////////////////////////////////////////////////////////////////////
+//
+// Mutex
+//
+///////////////////////////////////////////////////////////////////////////
+
+
+omni_mutex::omni_mutex(void)
+{
+    InitializeCriticalSection(&crit);
+}
+
+omni_mutex::~omni_mutex(void)
+{
+    DeleteCriticalSection(&crit);
+}
+
+
+
+///////////////////////////////////////////////////////////////////////////
+//
+// Condition variable
+//
+///////////////////////////////////////////////////////////////////////////
+
+
+//
+// Condition variables are tricky to implement using NT synchronisation
+// primitives, since none of them have the atomic "release mutex and wait to be
+// signalled" which is central to the idea of a condition variable.  To get
+// around this the solution is to record which threads are waiting and
+// explicitly wake up those threads.
+//
+// Here we implement a condition variable using a list of waiting threads
+// (protected by a critical section), and a per-thread semaphore (which
+// actually only needs to be a binary semaphore).
+//
+// To wait on the cv, a thread puts itself on the list of waiting threads for
+// that cv, then releases the mutex and waits on its own personal semaphore.  A
+// signalling thread simply takes a thread from the head of the list and kicks
+// that thread's semaphore.  Broadcast is simply implemented by kicking the
+// semaphore of each waiting thread.
+//
+// The only other tricky part comes when a thread gets a timeout from a timed
+// wait on its semaphore.  Between returning with a timeout from the wait and
+// entering the critical section, a signalling thread could get in, kick the
+// waiting thread's semaphore and remove it from the list.  If this happens,
+// the waiting thread's semaphore is now out of step so it needs resetting, and
+// the thread should indicate that it was signalled rather than that it timed
+// out.
+//
+// It is possible that the thread calling wait or timedwait is not a
+// omni_thread. In this case we have to provide a temporary data structure,
+// i.e. for the duration of the call, for the thread to link itself on the
+// list of waiting threads. _internal_omni_thread_dummy provides such
+// a data structure and _internal_omni_thread_helper is a helper class to
+// deal with this special case for wait() and timedwait(). Once created,
+// the _internal_omni_thread_dummy is cached for use by the next wait() or
+// timedwait() call from a non-omni_thread. This is probably worth doing
+// because creating a Semaphore is quite heavy weight.
+
+class _internal_omni_thread_helper;
+
+class _internal_omni_thread_dummy : public omni_thread {
+public:
+  inline _internal_omni_thread_dummy() : next(0) { }
+  inline ~_internal_omni_thread_dummy() { }
+  friend class _internal_omni_thread_helper;
+private:
+  _internal_omni_thread_dummy* next;
+};
+
+class _internal_omni_thread_helper {
+public:
+  inline _internal_omni_thread_helper()  { 
+    d = 0;
+    t = omni_thread::self();
+    if (!t) {
+      omni_mutex_lock sync(cachelock);
+      if (cache) {
+       d = cache;
+       cache = cache->next;
+      }
+      else {
+       d = new _internal_omni_thread_dummy;
+      }
+      t = d;
+    }
+  }
+  inline ~_internal_omni_thread_helper() { 
+    if (d) {
+      omni_mutex_lock sync(cachelock);
+      d->next = cache;
+      cache = d;
+    }
+  }
+  inline operator omni_thread* () { return t; }
+  inline omni_thread* operator->() { return t; }
+
+  static _internal_omni_thread_dummy* cache;
+  static omni_mutex                   cachelock;
+
+private:
+  _internal_omni_thread_dummy* d;
+  omni_thread*                 t;
+};
+
+_internal_omni_thread_dummy* _internal_omni_thread_helper::cache = 0;
+omni_mutex                   _internal_omni_thread_helper::cachelock;
+
+
+omni_condition::omni_condition(omni_mutex* m) : mutex(m)
+{
+    InitializeCriticalSection(&crit);
+    waiting_head = waiting_tail = NULL;
+}
+
+
+omni_condition::~omni_condition(void)
+{
+    DeleteCriticalSection(&crit);
+    DB( if (waiting_head != NULL) {
+       cerr << "omni_condition::~omni_condition: list of waiting threads "
+            << "is not empty\n";
+    } )
+}
+
+
+void
+omni_condition::wait(void)
+{
+    _internal_omni_thread_helper me;
+
+    EnterCriticalSection(&crit);
+
+    me->cond_next = NULL;
+    me->cond_prev = waiting_tail;
+    if (waiting_head == NULL)
+       waiting_head = me;
+    else
+       waiting_tail->cond_next = me;
+    waiting_tail = me;
+    me->cond_waiting = TRUE;
+
+    LeaveCriticalSection(&crit);
+
+    mutex->unlock();
+
+    DWORD result = WaitForSingleObject(me->cond_semaphore, INFINITE);
+
+    mutex->lock();
+
+    if (result != WAIT_OBJECT_0)
+       throw omni_thread_fatal(GetLastError());
+}
+
+
+int
+omni_condition::timedwait(unsigned long abs_sec, unsigned long abs_nsec)
+{
+    _internal_omni_thread_helper me;
+
+    EnterCriticalSection(&crit);
+
+    me->cond_next = NULL;
+    me->cond_prev = waiting_tail;
+    if (waiting_head == NULL)
+       waiting_head = me;
+    else
+       waiting_tail->cond_next = me;
+    waiting_tail = me;
+    me->cond_waiting = TRUE;
+
+    LeaveCriticalSection(&crit);
+
+    mutex->unlock();
+
+    unsigned long now_sec, now_nsec;
+
+    get_time_now(&now_sec, &now_nsec);
+
+    DWORD timeout;
+    if ((abs_sec <= now_sec) && ((abs_sec < now_sec) || (abs_nsec < now_nsec)))
+      timeout = 0;
+    else {
+      timeout = (abs_sec-now_sec) * 1000;
+
+      if( abs_nsec < now_nsec )  timeout -= (now_nsec-abs_nsec) / 1000000;
+      else                       timeout += (abs_nsec-now_nsec) / 1000000;
+    }
+
+    DWORD result = WaitForSingleObject(me->cond_semaphore, timeout);
+
+    if (result == WAIT_TIMEOUT) {
+       EnterCriticalSection(&crit);
+
+       if (me->cond_waiting) {
+           if (me->cond_prev != NULL)
+               me->cond_prev->cond_next = me->cond_next;
+           else
+               waiting_head = me->cond_next;
+           if (me->cond_next != NULL)
+               me->cond_next->cond_prev = me->cond_prev;
+           else
+               waiting_tail = me->cond_prev;
+           me->cond_waiting = FALSE;
+
+           LeaveCriticalSection(&crit);
+
+           mutex->lock();
+           return 0;
+       }
+
+       //
+       // We timed out but another thread still signalled us.  Wait for
+       // the semaphore (it _must_ have been signalled) to decrement it
+       // again.  Return that we were signalled, not that we timed out.
+       //
+
+       LeaveCriticalSection(&crit);
+
+       result = WaitForSingleObject(me->cond_semaphore, INFINITE);
+    }
+
+    if (result != WAIT_OBJECT_0)
+       throw omni_thread_fatal(GetLastError());
+
+    mutex->lock();
+    return 1;
+}
+
+
+void
+omni_condition::signal(void)
+{
+    EnterCriticalSection(&crit);
+
+    if (waiting_head != NULL) {
+       omni_thread* t = waiting_head;
+       waiting_head = t->cond_next;
+       if (waiting_head == NULL)
+           waiting_tail = NULL;
+       else
+           waiting_head->cond_prev = NULL;
+       t->cond_waiting = FALSE;
+
+       if (!ReleaseSemaphore(t->cond_semaphore, 1, NULL)) {
+           int rc = GetLastError();
+           LeaveCriticalSection(&crit);
+           throw omni_thread_fatal(rc);
+       }
+    }
+
+    LeaveCriticalSection(&crit);
+}
+
+
+void
+omni_condition::broadcast(void)
+{
+    EnterCriticalSection(&crit);
+
+    while (waiting_head != NULL) {
+       omni_thread* t = waiting_head;
+       waiting_head = t->cond_next;
+       if (waiting_head == NULL)
+           waiting_tail = NULL;
+       else
+           waiting_head->cond_prev = NULL;
+       t->cond_waiting = FALSE;
+
+       if (!ReleaseSemaphore(t->cond_semaphore, 1, NULL)) {
+           int rc = GetLastError();
+           LeaveCriticalSection(&crit);
+           throw omni_thread_fatal(rc);
+       }
+    }
+
+    LeaveCriticalSection(&crit);
+}
+
+
+
+///////////////////////////////////////////////////////////////////////////
+//
+// Counting semaphore
+//
+///////////////////////////////////////////////////////////////////////////
+
+
+#define SEMAPHORE_MAX 0x7fffffff
+
+
+omni_semaphore::omni_semaphore(unsigned int initial, unsigned int max_count)
+{
+    if (max_count > SEMAPHORE_MAX)
+      max_count= SEMAPHORE_MAX;
+
+    nt_sem = CreateSemaphore(NULL, initial, max_count, NULL);
+
+    if (nt_sem == NULL) {
+      DB( cerr << "omni_semaphore::omni_semaphore: CreateSemaphore error "
+            << GetLastError() << endl );
+      throw omni_thread_fatal(GetLastError());
+    }
+}
+
+
+omni_semaphore::~omni_semaphore(void)
+{
+  if (!CloseHandle(nt_sem)) {
+    DB( cerr << "omni_semaphore::~omni_semaphore: CloseHandle error "
+            << GetLastError() << endl );
+    throw omni_thread_fatal(GetLastError());
+  }
+}
+
+
+void
+omni_semaphore::wait(void)
+{
+    if (WaitForSingleObject(nt_sem, INFINITE) != WAIT_OBJECT_0)
+       throw omni_thread_fatal(GetLastError());
+}
+
+
+int
+omni_semaphore::trywait(void)
+{
+    switch (WaitForSingleObject(nt_sem, 0)) {
+
+    case WAIT_OBJECT_0:
+       return 1;
+    case WAIT_TIMEOUT:
+       return 0;
+    }
+
+    throw omni_thread_fatal(GetLastError());
+    return 0; /* keep msvc++ happy */
+}
+
+
+void
+omni_semaphore::post(void)
+{
+    if (!ReleaseSemaphore(nt_sem, 1, NULL))
+       throw omni_thread_fatal(GetLastError());
+}
+
+
+
+///////////////////////////////////////////////////////////////////////////
+//
+// Thread
+//
+///////////////////////////////////////////////////////////////////////////
+
+
+//
+// Static variables
+//
+
+omni_mutex* omni_thread::next_id_mutex;
+int omni_thread::next_id = 0;
+static DWORD self_tls_index;
+
+static unsigned int stack_size = 0;
+
+//
+// Initialisation function (gets called before any user code).
+//
+
+static int& count() {
+  static int the_count = 0;
+  return the_count;
+}
+
+omni_thread::init_t::init_t(void)
+{
+    if (count()++ != 0)        // only do it once however many objects get created.
+       return;
+
+    DB(cerr << "omni_thread::init: NT implementation initialising\n");
+
+    self_tls_index = TlsAlloc();
+
+    if (self_tls_index == 0xffffffff)
+       throw omni_thread_fatal(GetLastError());
+
+    next_id_mutex = new omni_mutex;
+
+    //
+    // Create object for this (i.e. initial) thread.
+    //
+
+    omni_thread* t = new omni_thread;
+
+    t->_state = STATE_RUNNING;
+
+    if (!DuplicateHandle(GetCurrentProcess(), GetCurrentThread(),
+                        GetCurrentProcess(), &t->handle,
+                        0, FALSE, DUPLICATE_SAME_ACCESS))
+       throw omni_thread_fatal(GetLastError());
+
+    t->nt_id = GetCurrentThreadId();
+
+    DB(cerr << "initial thread " << t->id() << " NT thread id " << t->nt_id
+       << endl);
+
+    if (!TlsSetValue(self_tls_index, (LPVOID)t))
+       throw omni_thread_fatal(GetLastError());
+
+    if (!SetThreadPriority(t->handle, nt_priority(PRIORITY_NORMAL)))
+       throw omni_thread_fatal(GetLastError());
+}
+
+omni_thread::init_t::~init_t(void)
+{
+    if (--count() != 0) return;
+
+    omni_thread* self = omni_thread::self();
+    if (!self) return;
+
+    TlsSetValue(self_tls_index, (LPVOID)0);
+    delete self;
+
+    delete next_id_mutex;
+
+    TlsFree(self_tls_index);
+}
+
+//
+// Wrapper for thread creation.
+//
+
+extern "C" 
+#ifndef __BCPLUSPLUS__
+unsigned __stdcall
+#else
+void _USERENTRY
+#endif
+omni_thread_wrapper(void* ptr)
+{
+    omni_thread* me = (omni_thread*)ptr;
+
+    DB(cerr << "omni_thread_wrapper: thread " << me->id()
+       << " started\n");
+
+    if (!TlsSetValue(self_tls_index, (LPVOID)me))
+       throw omni_thread_fatal(GetLastError());
+
+    //
+    // Now invoke the thread function with the given argument.
+    //
+
+    if (me->fn_void != NULL) {
+       (*me->fn_void)(me->thread_arg);
+       omni_thread::exit();
+    }
+
+    if (me->fn_ret != NULL) {
+       void* return_value = (*me->fn_ret)(me->thread_arg);
+       omni_thread::exit(return_value);
+    }
+
+    if (me->detached) {
+       me->run(me->thread_arg);
+       omni_thread::exit();
+    } else {
+       void* return_value = me->run_undetached(me->thread_arg);
+       omni_thread::exit(return_value);
+    }
+
+    // should never get here.
+#ifndef __BCPLUSPLUS__
+    return 0;
+#endif
+}
+
+
+//
+// Constructors for omni_thread - set up the thread object but don't
+// start it running.
+//
+
+// construct a detached thread running a given function.
+
+omni_thread::omni_thread(void (*fn)(void*), void* arg, priority_t pri)
+{
+    common_constructor(arg, pri, 1);
+    fn_void = fn;
+    fn_ret = NULL;
+}
+
+// construct an undetached thread running a given function.
+
+omni_thread::omni_thread(void* (*fn)(void*), void* arg, priority_t pri)
+{
+    common_constructor(arg, pri, 0);
+    fn_void = NULL;
+    fn_ret = fn;
+}
+
+// construct a thread which will run either run() or run_undetached().
+
+omni_thread::omni_thread(void* arg, priority_t pri)
+{
+    common_constructor(arg, pri, 1);
+    fn_void = NULL;
+    fn_ret = NULL;
+}
+
+// common part of all constructors.
+
+void
+omni_thread::common_constructor(void* arg, priority_t pri, int det)
+{
+    _state = STATE_NEW;
+    _priority = pri;
+
+    next_id_mutex->lock();
+    _id = next_id++;
+    next_id_mutex->unlock();
+
+    thread_arg = arg;
+    detached = det;    // may be altered in start_undetached()
+
+    cond_semaphore = CreateSemaphore(NULL, 0, SEMAPHORE_MAX, NULL);
+
+    if (cond_semaphore == NULL)
+       throw omni_thread_fatal(GetLastError());
+
+    cond_next = cond_prev = NULL;
+    cond_waiting = FALSE;
+
+    handle = NULL;
+
+    _dummy       = 0;
+    _values      = 0;
+    _value_alloc = 0;
+}
+
+
+//
+// Destructor for omni_thread.
+//
+
+omni_thread::~omni_thread(void)
+{
+    DB(cerr << "destructor called for thread " << id() << endl);
+    if (_values) {
+        for (key_t i=0; i < _value_alloc; i++) {
+           if (_values[i]) {
+               delete _values[i];
+           }
+        }
+       delete [] _values;
+    }
+    if (handle && !CloseHandle(handle))
+       throw omni_thread_fatal(GetLastError());
+    if (cond_semaphore && !CloseHandle(cond_semaphore))
+       throw omni_thread_fatal(GetLastError());
+}
+
+
+//
+// Start the thread
+//
+
+void
+omni_thread::start(void)
+{
+    omni_mutex_lock l(mutex);
+
+    if (_state != STATE_NEW)
+       throw omni_thread_invalid();
+
+#ifndef __BCPLUSPLUS__
+    // MSVC++ or compatiable
+    unsigned int t;
+    handle = (HANDLE)_beginthreadex(
+                        NULL,
+                       stack_size,
+                       omni_thread_wrapper,
+                       (LPVOID)this,
+                       CREATE_SUSPENDED, 
+                       &t);
+    nt_id = t;
+    if (handle == NULL)
+      throw omni_thread_fatal(GetLastError());
+#else
+    // Borland C++
+    handle = (HANDLE)_beginthreadNT(omni_thread_wrapper,
+                                   stack_size,
+                                   (void*)this,
+                                   NULL,
+                                   CREATE_SUSPENDED,
+                                   &nt_id);
+    if (handle == INVALID_HANDLE_VALUE)
+      throw omni_thread_fatal(errno);
+#endif
+
+    if (!SetThreadPriority(handle, nt_priority(_priority)))
+      throw omni_thread_fatal(GetLastError());
+
+    if (ResumeThread(handle) == 0xffffffff)
+       throw omni_thread_fatal(GetLastError());
+
+    _state = STATE_RUNNING;
+}
+
+
+//
+// Start a thread which will run the member function run_undetached().
+//
+
+void
+omni_thread::start_undetached(void)
+{
+    if ((fn_void != NULL) || (fn_ret != NULL))
+       throw omni_thread_invalid();
+
+    detached = 0;
+    start();
+}
+
+
+//
+// join - simply check error conditions & call WaitForSingleObject.
+//
+
+void
+omni_thread::join(void** status)
+{
+    mutex.lock();
+
+    if ((_state != STATE_RUNNING) && (_state != STATE_TERMINATED)) {
+       mutex.unlock();
+       throw omni_thread_invalid();
+    }
+
+    mutex.unlock();
+
+    if (this == self())
+       throw omni_thread_invalid();
+
+    if (detached)
+       throw omni_thread_invalid();
+
+    DB(cerr << "omni_thread::join: doing WaitForSingleObject\n");
+
+    if (WaitForSingleObject(handle, INFINITE) != WAIT_OBJECT_0)
+       throw omni_thread_fatal(GetLastError());
+
+    DB(cerr << "omni_thread::join: WaitForSingleObject succeeded\n");
+
+    if (status)
+      *status = return_val;
+
+    delete this;
+}
+
+
+//
+// Change this thread's priority.
+//
+
+void
+omni_thread::set_priority(priority_t pri)
+{
+    omni_mutex_lock l(mutex);
+
+    if (_state != STATE_RUNNING)
+       throw omni_thread_invalid();
+
+    _priority = pri;
+
+    if (!SetThreadPriority(handle, nt_priority(pri)))
+       throw omni_thread_fatal(GetLastError());
+}
+
+
+//
+// create - construct a new thread object and start it running.  Returns thread
+// object if successful, null pointer if not.
+//
+
+// detached version
+
+omni_thread*
+omni_thread::create(void (*fn)(void*), void* arg, priority_t pri)
+{
+    omni_thread* t = new omni_thread(fn, arg, pri);
+    t->start();
+    return t;
+}
+
+// undetached version
+
+omni_thread*
+omni_thread::create(void* (*fn)(void*), void* arg, priority_t pri)
+{
+    omni_thread* t = new omni_thread(fn, arg, pri);
+    t->start();
+    return t;
+}
+
+
+//
+// exit() _must_ lock the mutex even in the case of a detached thread.  This is
+// because a thread may run to completion before the thread that created it has
+// had a chance to get out of start().  By locking the mutex we ensure that the
+// creating thread must have reached the end of start() before we delete the
+// thread object.  Of course, once the call to start() returns, the user can
+// still incorrectly refer to the thread object, but that's their problem.
+//
+
+void
+omni_thread::exit(void* return_value)
+{
+    omni_thread* me = self();
+
+    if (me)
+      {
+       me->mutex.lock();
+
+       me->_state = STATE_TERMINATED;
+
+       me->mutex.unlock();
+
+       DB(cerr << "omni_thread::exit: thread " << me->id() << " detached "
+          << me->detached << " return value " << return_value << endl);
+
+       if (me->detached) {
+         delete me;
+       } else {
+         me->return_val = return_value;
+       }
+      }
+    else
+      {
+       DB(cerr << "omni_thread::exit: called with a non-omnithread. Exit quietly." << endl);
+      }
+#ifndef __BCPLUSPLUS__
+    // MSVC++ or compatiable
+    //   _endthreadex() does not automatically closes the thread handle.
+    //   The omni_thread dtor closes the thread handle.
+    _endthreadex(0);
+#else
+    // Borland C++
+    //   _endthread() does not automatically closes the thread handle.
+    //   _endthreadex() is only available if __MFC_COMPAT__ is defined and
+    //   all it does is to call _endthread().
+    _endthread();
+#endif
+}
+
+
+omni_thread*
+omni_thread::self(void)
+{
+    LPVOID me;
+
+    me = TlsGetValue(self_tls_index);
+
+    if (me == NULL) {
+      DB(cerr << "omni_thread::self: called with a non-ominthread. NULL is returned." << endl);
+    }
+    return (omni_thread*)me;
+}
+
+
+void
+omni_thread::yield(void)
+{
+    Sleep(0);
+}
+
+
+#define MAX_SLEEP_SECONDS (DWORD)4294966       // (2**32-2)/1000
+
+void
+omni_thread::sleep(unsigned long secs, unsigned long nanosecs)
+{
+    if (secs <= MAX_SLEEP_SECONDS) {
+       Sleep(secs * 1000 + nanosecs / 1000000);
+       return;
+    }
+
+    DWORD no_of_max_sleeps = secs / MAX_SLEEP_SECONDS;
+
+    for (DWORD i = 0; i < no_of_max_sleeps; i++)
+       Sleep(MAX_SLEEP_SECONDS * 1000);
+
+    Sleep((secs % MAX_SLEEP_SECONDS) * 1000 + nanosecs / 1000000);
+}
+
+
+void
+omni_thread::get_time(unsigned long* abs_sec, unsigned long* abs_nsec,
+                     unsigned long rel_sec, unsigned long rel_nsec)
+{
+    get_time_now(abs_sec, abs_nsec);
+    *abs_nsec += rel_nsec;
+    *abs_sec += rel_sec + *abs_nsec / 1000000000;
+    *abs_nsec = *abs_nsec % 1000000000;
+}
+
+
+int
+omni_thread::nt_priority(priority_t pri)
+{
+    switch (pri) {
+
+    case PRIORITY_LOW:
+       return THREAD_PRIORITY_LOWEST;
+
+    case PRIORITY_NORMAL:
+       return THREAD_PRIORITY_NORMAL;
+
+    case PRIORITY_HIGH:
+       return THREAD_PRIORITY_HIGHEST;
+    }
+
+    throw omni_thread_invalid();
+    return 0; /* keep msvc++ happy */
+}
+
+
+static void
+get_time_now(unsigned long* abs_sec, unsigned long* abs_nsec)
+{
+    static int days_in_preceding_months[12]
+       = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 };
+    static int days_in_preceding_months_leap[12]
+       = { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335 };
+
+    SYSTEMTIME st;
+
+    GetSystemTime(&st);
+    *abs_nsec = st.wMilliseconds * 1000000;
+
+    // this formula should work until 1st March 2100
+
+    DWORD days = ((st.wYear - 1970) * 365 + (st.wYear - 1969) / 4
+                 + ((st.wYear % 4)
+                    ? days_in_preceding_months[st.wMonth - 1]
+                    : days_in_preceding_months_leap[st.wMonth - 1])
+                 + st.wDay - 1);
+
+    *abs_sec = st.wSecond + 60 * (st.wMinute + 60 * (st.wHour + 24 * days));
+}
+
+void
+omni_thread::stacksize(unsigned long sz)
+{
+  stack_size = sz;
+}
+
+unsigned long
+omni_thread::stacksize()
+{
+  return stack_size;
+}
+
+//
+// Dummy thread
+//
+
+class omni_thread_dummy : public omni_thread {
+public:
+  inline omni_thread_dummy() : omni_thread()
+  {
+    _dummy = 1;
+    _state = STATE_RUNNING;
+
+    if (!DuplicateHandle(GetCurrentProcess(), GetCurrentThread(),
+                        GetCurrentProcess(), &handle,
+                        0, FALSE, DUPLICATE_SAME_ACCESS))
+      throw omni_thread_fatal(GetLastError());
+
+    nt_id = GetCurrentThreadId();
+
+    if (!TlsSetValue(self_tls_index, (LPVOID)this))
+      throw omni_thread_fatal(GetLastError());
+  }
+  inline ~omni_thread_dummy()
+  {
+    if (!TlsSetValue(self_tls_index, (LPVOID)0))
+      throw omni_thread_fatal(GetLastError());
+  }
+};
+
+omni_thread*
+omni_thread::create_dummy()
+{
+  if (omni_thread::self())
+    throw omni_thread_invalid();
+
+  return new omni_thread_dummy;
+}
+
+void
+omni_thread::release_dummy()
+{
+  omni_thread* self = omni_thread::self();
+  if (!self || !self->_dummy)
+    throw omni_thread_invalid();
+
+  omni_thread_dummy* dummy = (omni_thread_dummy*)self;
+  delete dummy;
+}
+
+
+#if defined(__DMC__) && defined(_WINDLL)
+BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
+{
+  return TRUE;
+}
+#endif
+
+
+#define INSIDE_THREAD_IMPL_CC
+#include "threaddata.cc"
+#undef INSIDE_THREAD_IMPL_CC
diff --git a/gnuradio-core/src/lib/omnithread/omnithread.h b/gnuradio-core/src/lib/omnithread/omnithread.h
new file mode 100644 (file)
index 0000000..f63adc4
--- /dev/null
@@ -0,0 +1,622 @@
+// -*- Mode: C++; -*-
+//                             Package : omnithread
+// omnithread.h                        Created : 7/94 tjr
+//
+//    Copyright (C) 2006 Free Software Foundation, Inc.
+//    Copyright (C) 1994,1995,1996, 1997 Olivetti & Oracle Research Laboratory
+//
+//    This file is part of the omnithread library
+//
+//    The omnithread library is free software; you can redistribute it and/or
+//    modify it under the terms of the GNU Library General Public
+//    License as published by the Free Software Foundation; either
+//    version 2 of the License, or (at your option) any later version.
+//
+//    This library is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//    Library General Public License for more details.
+//
+//    You should have received a copy of the GNU Library General Public
+//    License along with this library; if not, write to the Free
+//    Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  
+//    02111-1307, USA
+//
+
+//
+// Interface to OMNI thread abstraction.
+//
+// This file declares classes for threads and synchronisation objects
+// (mutexes, condition variables and counting semaphores).
+//
+// Wherever a seemingly arbitrary choice has had to be made as to the interface
+// provided, the intention here has been to be as POSIX-like as possible.  This
+// is why there is no semaphore timed wait, for example.
+//
+
+#ifndef __omnithread_h_
+#define __omnithread_h_
+
+#ifndef NULL
+#define NULL 0
+#endif
+
+class omni_mutex;
+class omni_condition;
+class omni_semaphore;
+class omni_thread;
+
+//
+// OMNI_THREAD_EXPOSE can be defined as public or protected to expose the
+// implementation class - this may be useful for debugging.  Hopefully this
+// won't change the underlying structure which the compiler generates so that
+// this can work without recompiling the library.
+//
+
+#ifndef OMNI_THREAD_EXPOSE
+#define OMNI_THREAD_EXPOSE private
+#endif
+
+//
+// Include implementation-specific header file.
+//
+// This must define 4 CPP macros of the form OMNI_x_IMPLEMENTATION for mutex,
+// condition variable, semaphore and thread.  Each should define any
+// implementation-specific members of the corresponding classes.
+//
+
+
+//
+// For now, we assume they've always got a Posix Threads implementation.
+// If not, it'll take some configure hacking to sort it out, along with
+// the relevant libraries to link with, etc.
+//
+
+#if !defined(OMNITHREAD_POSIX) && !defined(OMNITHREAD_NT) && defined HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#if defined(OMNITHREAD_POSIX)
+#include <ot_posix.h>
+
+#elif defined(OMNITHREAD_NT)
+#include <ot_nt.h>
+
+#ifdef _MSC_VER
+
+// Using MSVC++ to compile. If compiling library as a DLL,
+// define _OMNITHREAD_DLL. If compiling as a statuc library, define
+// _WINSTATIC
+// If compiling an application that is to be statically linked to omnithread,
+// define _WINSTATIC (if the application is  to be dynamically linked, 
+// there is no need to define any of these macros).
+
+#if defined (_OMNITHREAD_DLL) && defined(_WINSTATIC)
+#error "Both _OMNITHREAD_DLL and _WINSTATIC are defined."
+#elif defined(_OMNITHREAD_DLL)
+#define _OMNITHREAD_NTDLL_ __declspec(dllexport)
+#elif !defined(_WINSTATIC)
+#define _OMNITHREAD_NTDLL_ __declspec(dllimport)
+#elif defined(_WINSTATIC)
+#define _OMNITHREAD_NTDLL_
+#endif
+ // _OMNITHREAD_DLL && _WINSTATIC
+
+#else
+
+// Not using MSVC++ to compile
+#define _OMNITHREAD_NTDLL_
+
+#endif
+ // _MSC_VER
+#elif defined(__vxWorks__)
+#include <ot_VxThread.h>
+
+#elif defined(__sunos__)
+#if __OSVERSION__ != 5
+// XXX Workaround for SUN C++ compiler (seen on 4.2) Template.DB code
+//     regeneration bug. See omniORB2/CORBA_sysdep.h for details.
+#if !defined(__SUNPRO_CC) || __OSVERSION__ != '5'
+#error "Only SunOS 5.x or later is supported."
+#endif
+#endif
+#ifdef UseSolarisThreads
+#include <ot_solaris.h>
+#else
+#include <ot_posix.h>
+#endif
+
+#elif defined(__rtems__)
+#include <ot_posix.h>
+#include <sched.h>
+
+#elif defined(__macos__)
+#include <ot_posix.h>
+#include <sched.h>
+
+#else
+#error "No implementation header file"
+#endif
+
+
+#if !defined(__WIN32__)
+#define _OMNITHREAD_NTDLL_
+#endif
+
+#if (!defined(OMNI_MUTEX_IMPLEMENTATION)        || \
+     !defined(OMNI_MUTEX_LOCK_IMPLEMENTATION)   || \
+     !defined(OMNI_MUTEX_TRYLOCK_IMPLEMENTATION)|| \
+     !defined(OMNI_MUTEX_UNLOCK_IMPLEMENTATION) || \
+     !defined(OMNI_CONDITION_IMPLEMENTATION)    || \
+     !defined(OMNI_SEMAPHORE_IMPLEMENTATION)    || \
+     !defined(OMNI_THREAD_IMPLEMENTATION))
+#error "Implementation header file incomplete"
+#endif
+
+
+//
+// This exception is thrown in the event of a fatal error.
+//
+
+class _OMNITHREAD_NTDLL_ omni_thread_fatal {
+public:
+    int error;
+    omni_thread_fatal(int e = 0) : error(e) {}
+};
+
+
+//
+// This exception is thrown when an operation is invoked with invalid
+// arguments.
+//
+
+class _OMNITHREAD_NTDLL_ omni_thread_invalid {};
+
+
+///////////////////////////////////////////////////////////////////////////
+//
+// Mutex
+//
+///////////////////////////////////////////////////////////////////////////
+
+class _OMNITHREAD_NTDLL_ omni_mutex {
+
+public:
+    omni_mutex(void);
+    ~omni_mutex(void);
+
+    inline void lock(void)    { OMNI_MUTEX_LOCK_IMPLEMENTATION   }
+    inline void unlock(void)  { OMNI_MUTEX_UNLOCK_IMPLEMENTATION }
+    inline int trylock(void)  { return OMNI_MUTEX_TRYLOCK_IMPLEMENTATION }
+       // if mutex is unlocked, lock it and return 1 (true).
+       // If it's already locked then return 0 (false).
+
+    inline void acquire(void) { lock(); }
+    inline void release(void) { unlock(); }
+       // the names lock and unlock are preferred over acquire and release
+       // since we are attempting to be as POSIX-like as possible.
+
+    friend class omni_condition;
+
+private:
+    // dummy copy constructor and operator= to prevent copying
+    omni_mutex(const omni_mutex&);
+    omni_mutex& operator=(const omni_mutex&);
+
+OMNI_THREAD_EXPOSE:
+    OMNI_MUTEX_IMPLEMENTATION
+};
+
+//
+// As an alternative to:
+// {
+//   mutex.lock();
+//   .....
+//   mutex.unlock();
+// }
+//
+// you can use a single instance of the omni_mutex_lock class:
+//
+// {
+//   omni_mutex_lock l(mutex);
+//   ....
+// }
+//
+// This has the advantage that mutex.unlock() will be called automatically
+// when an exception is thrown.
+//
+
+class _OMNITHREAD_NTDLL_ omni_mutex_lock {
+    omni_mutex& mutex;
+public:
+    omni_mutex_lock(omni_mutex& m) : mutex(m) { mutex.lock(); }
+    ~omni_mutex_lock(void) { mutex.unlock(); }
+private:
+    // dummy copy constructor and operator= to prevent copying
+    omni_mutex_lock(const omni_mutex_lock&);
+    omni_mutex_lock& operator=(const omni_mutex_lock&);
+};
+
+
+///////////////////////////////////////////////////////////////////////////
+//
+// Condition variable
+//
+///////////////////////////////////////////////////////////////////////////
+
+class _OMNITHREAD_NTDLL_ omni_condition {
+
+    omni_mutex* mutex;
+
+public:
+    omni_condition(omni_mutex* m);
+       // constructor must be given a pointer to an existing mutex. The
+       // condition variable is then linked to the mutex, so that there is an
+       // implicit unlock and lock around wait() and timed_wait().
+
+    ~omni_condition(void);
+
+    void wait(void);
+       // wait for the condition variable to be signalled.  The mutex is
+       // implicitly released before waiting and locked again after waking up.
+       // If wait() is called by multiple threads, a signal may wake up more
+       // than one thread.  See POSIX threads documentation for details.
+
+    int timedwait(unsigned long secs, unsigned long nanosecs = 0);
+       // timedwait() is given an absolute time to wait until.  To wait for a
+       // relative time from now, use omni_thread::get_time. See POSIX threads
+       // documentation for why absolute times are better than relative.
+       // Returns 1 (true) if successfully signalled, 0 (false) if time
+       // expired.
+
+    void signal(void);
+       // if one or more threads have called wait(), signal wakes up at least
+       // one of them, possibly more.  See POSIX threads documentation for
+       // details.
+
+    void broadcast(void);
+       // broadcast is like signal but wakes all threads which have called
+       // wait().
+
+private:
+    // dummy copy constructor and operator= to prevent copying
+    omni_condition(const omni_condition&);
+    omni_condition& operator=(const omni_condition&);
+
+OMNI_THREAD_EXPOSE:
+    OMNI_CONDITION_IMPLEMENTATION
+};
+
+
+///////////////////////////////////////////////////////////////////////////
+//
+// Counting (or binary) semaphore
+//
+///////////////////////////////////////////////////////////////////////////
+
+class _OMNITHREAD_NTDLL_ omni_semaphore {
+
+public:
+    // if max_count == 1, you've got a binary semaphore.
+    omni_semaphore(unsigned int initial = 1, unsigned int max_count = 0x7fffffff);
+    ~omni_semaphore(void);
+
+    void wait(void);
+       // if semaphore value is > 0 then decrement it and carry on. If it's
+       // already 0 then block.
+
+    int trywait(void);
+       // if semaphore value is > 0 then decrement it and return 1 (true).
+       // If it's already 0 then return 0 (false).
+
+    void post(void);
+       // if any threads are blocked in wait(), wake one of them up. Otherwise
+       // increment the value of the semaphore.
+
+private:
+    // dummy copy constructor and operator= to prevent copying
+    omni_semaphore(const omni_semaphore&);
+    omni_semaphore& operator=(const omni_semaphore&);
+
+OMNI_THREAD_EXPOSE:
+    OMNI_SEMAPHORE_IMPLEMENTATION
+};
+
+//
+// A helper class for semaphores, similar to omni_mutex_lock above.
+//
+
+class _OMNITHREAD_NTDLL_ omni_semaphore_lock {
+    omni_semaphore& sem;
+public:
+    omni_semaphore_lock(omni_semaphore& s) : sem(s) { sem.wait(); }
+    ~omni_semaphore_lock(void) { sem.post(); }
+private:
+    // dummy copy constructor and operator= to prevent copying
+    omni_semaphore_lock(const omni_semaphore_lock&);
+    omni_semaphore_lock& operator=(const omni_semaphore_lock&);
+};
+
+
+///////////////////////////////////////////////////////////////////////////
+//
+// Thread
+//
+///////////////////////////////////////////////////////////////////////////
+
+class _OMNITHREAD_NTDLL_ omni_thread {
+
+public:
+
+    enum priority_t {
+       PRIORITY_LOW,
+       PRIORITY_NORMAL,
+       PRIORITY_HIGH
+    };
+
+    enum state_t {
+       STATE_NEW,              // thread object exists but thread hasn't
+                               // started yet.
+       STATE_RUNNING,          // thread is running.
+       STATE_TERMINATED        // thread has terminated but storage has not
+                               // been reclaimed (i.e. waiting to be joined).
+    };
+
+    //
+    // Constructors set up the thread object but the thread won't start until
+    // start() is called. The create method can be used to construct and start
+    // a thread in a single call.
+    //
+
+    omni_thread(void (*fn)(void*), void* arg = NULL,
+               priority_t pri = PRIORITY_NORMAL);
+    omni_thread(void* (*fn)(void*), void* arg = NULL,
+               priority_t pri = PRIORITY_NORMAL);
+       // these constructors create a thread which will run the given function
+       // when start() is called.  The thread will be detached if given a
+       // function with void return type, undetached if given a function
+       // returning void*. If a thread is detached, storage for the thread is
+       // reclaimed automatically on termination. Only an undetached thread
+       // can be joined.
+
+    void start(void);
+       // start() causes a thread created with one of the constructors to
+       // start executing the appropriate function.
+
+protected:
+
+    omni_thread(void* arg = NULL, priority_t pri = PRIORITY_NORMAL);
+       // this constructor is used in a derived class.  The thread will
+       // execute the run() or run_undetached() member functions depending on
+       // whether start() or start_undetached() is called respectively.
+
+    void start_undetached(void);
+       // can be used with the above constructor in a derived class to cause
+       // the thread to be undetached.  In this case the thread executes the
+       // run_undetached member function.
+
+    virtual ~omni_thread(void);
+       // destructor cannot be called by user (except via a derived class).
+       // Use exit() or cancel() instead. This also means a thread object must
+       // be allocated with new - it cannot be statically or automatically
+       // allocated. The destructor of a class that inherits from omni_thread
+       // shouldn't be public either (otherwise the thread object can be
+       // destroyed while the underlying thread is still running).
+
+public:
+
+    void join(void**);
+       // join causes the calling thread to wait for another's completion,
+       // putting the return value in the variable of type void* whose address
+       // is given (unless passed a null pointer). Only undetached threads
+       // may be joined. Storage for the thread will be reclaimed.
+
+    void set_priority(priority_t);
+       // set the priority of the thread.
+
+    static omni_thread* create(void (*fn)(void*), void* arg = NULL,
+                              priority_t pri = PRIORITY_NORMAL);
+    static omni_thread* create(void* (*fn)(void*), void* arg = NULL,
+                              priority_t pri = PRIORITY_NORMAL);
+       // create spawns a new thread executing the given function with the
+       // given argument at the given priority. Returns a pointer to the
+       // thread object. It simply constructs a new thread object then calls
+       // start.
+
+    static void exit(void* return_value = NULL);
+       // causes the calling thread to terminate.
+
+    static omni_thread* self(void);
+       // returns the calling thread's omni_thread object.  If the
+       // calling thread is not the main thread and is not created
+       // using this library, returns 0. (But see create_dummy()
+       // below.)
+
+    static void yield(void);
+       // allows another thread to run.
+
+    static void sleep(unsigned long secs, unsigned long nanosecs = 0);
+       // sleeps for the given time.
+
+    static void get_time(unsigned long* abs_sec, unsigned long* abs_nsec,
+                        unsigned long rel_sec = 0, unsigned long rel_nsec=0);
+       // calculates an absolute time in seconds and nanoseconds, suitable for
+       // use in timed_waits on condition variables, which is the current time
+       // plus the given relative offset.
+
+
+    static void stacksize(unsigned long sz);
+    static unsigned long stacksize();
+        // Use this value as the stack size when spawning a new thread.
+        // The default value (0) means that the thread library default is
+        // to be used.
+
+
+    // Per-thread data
+    //
+    // These functions allow you to attach additional data to an
+    // omni_thread. First allocate a key for yourself with
+    // allocate_key(). Then you can store any object whose class is
+    // derived from value_t. Any values still stored in the
+    // omni_thread when the thread exits are deleted.
+    //
+    // These functions are NOT thread safe, so you should be very
+    // careful about setting/getting data in a different thread to the
+    // current thread.
+
+    typedef unsigned int key_t;
+    static key_t allocate_key();
+
+    class value_t {
+    public:
+      virtual ~value_t() {}
+    };
+
+    value_t* set_value(key_t k, value_t* v);
+        // Sets a value associated with the given key. The key must
+        // have been allocated with allocate_key(). If a value has
+        // already been set with the specified key, the old value_t
+        // object is deleted and replaced. Returns the value which was
+        // set, or zero if the key is invalid.
+
+    value_t* get_value(key_t k);
+        // Returns the value associated with the key. If the key is
+        // invalid, or there is no value for the key, returns zero.
+
+    value_t* remove_value(key_t k);
+        // Removes the value associated with the key and returns it.
+        // If the key is invalid, or there is no value for the key,
+        // returns zero.
+
+
+    // Dummy omni_thread
+    //
+    // Sometimes, an application finds itself with threads created
+    // outside of omnithread which must interact with omnithread
+    // features such as the per-thread data. In this situation,
+    // omni_thread::self() would normally return 0. These functions
+    // allow the application to create a suitable dummy omni_thread
+    // object.
+
+    static omni_thread* create_dummy(void);
+        // creates a dummy omni_thread for the calling thread. Future
+        // calls to self() will return the dummy omni_thread. Throws
+        // omni_thread_invalid if this thread already has an
+        // associated omni_thread (real or dummy).
+
+    static void release_dummy();
+        // release the dummy omni_thread for this thread. This
+        // function MUST be called before the thread exits. Throws
+        // omni_thread_invalid if the calling thread does not have a
+        // dummy omni_thread.
+
+    // class ensure_self should be created on the stack. If created in
+    // a thread without an associated omni_thread, it creates a dummy
+    // thread which is released when the ensure_self object is deleted.
+
+    class ensure_self {
+    public:
+      inline ensure_self() : _dummy(0)
+      {
+       _self = omni_thread::self();
+       if (!_self) {
+         _dummy = 1;
+         _self  = omni_thread::create_dummy();
+       }
+      }
+      inline ~ensure_self()
+      {
+       if (_dummy)
+         omni_thread::release_dummy();
+      }
+      inline omni_thread* self() { return _self; }
+    private:
+      omni_thread* _self;
+      int          _dummy;
+    };
+
+
+private:
+
+    virtual void run(void* /*arg*/) {}
+    virtual void* run_undetached(void* /*arg*/) { return NULL; }
+       // can be overridden in a derived class.  When constructed using the
+       // the constructor omni_thread(void*, priority_t), these functions are
+       // called by start() and start_undetached() respectively.
+
+    void common_constructor(void* arg, priority_t pri, int det);
+       // implements the common parts of the constructors.
+
+    omni_mutex mutex;
+       // used to protect any members which can change after construction,
+       // i.e. the following 2 members.
+
+    state_t _state;
+    priority_t _priority;
+
+    static omni_mutex* next_id_mutex;
+    static int next_id;
+    int _id;
+
+    void (*fn_void)(void*);
+    void* (*fn_ret)(void*);
+    void* thread_arg;
+    int detached;
+    int _dummy;
+    value_t**     _values;
+    unsigned long _value_alloc;
+
+    omni_thread(const omni_thread&);
+    omni_thread& operator=(const omni_thread&);
+    // Not implemented
+
+public:
+
+    priority_t priority(void) {
+
+       // return this thread's priority.
+
+       omni_mutex_lock l(mutex);
+       return _priority;
+    }
+
+    state_t state(void) {
+
+       // return thread state (invalid, new, running or terminated).
+
+       omni_mutex_lock l(mutex);
+       return _state;
+    }
+
+    int id(void) { return _id; }
+       // return unique thread id within the current process.
+
+
+    // This class plus the instance of it declared below allows us to execute
+    // some initialisation code before main() is called.
+
+    class _OMNITHREAD_NTDLL_ init_t {
+    public:
+       init_t(void);
+        ~init_t(void);
+    };
+
+    friend class init_t;
+    friend class omni_thread_dummy;
+
+OMNI_THREAD_EXPOSE:
+    OMNI_THREAD_IMPLEMENTATION
+};
+
+#ifndef __rtems__
+static omni_thread::init_t omni_thread_init;
+#else
+// RTEMS calls global Ctor/Dtor in a context that is not
+// a posix thread. Calls to functions to pthread_self() in
+// that context returns NULL. 
+// So, for RTEMS we will make the thread initialization at the
+// beginning of the Init task that has a posix context.
+#endif
+
+#endif
diff --git a/gnuradio-core/src/lib/omnithread/ot_VxThread.h b/gnuradio-core/src/lib/omnithread/ot_VxThread.h
new file mode 100644 (file)
index 0000000..e96c036
--- /dev/null
@@ -0,0 +1,118 @@
+#ifndef __VXTHREAD_H__
+#define __VXTHREAD_H__
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Project:     omniORB
+%% Filename:    $Filename$
+%% Author:      Guillaume/Bill ARRECKX
+%%              Copyright Wavetek Wandel & Goltermann, Plymouth.
+%% Description: OMNI thread implementation classes for VxWorks threads
+%% Notes:
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% $Log$
+%% Revision 1.1  2004/04/10 18:00:52  eb
+%% Initial revision
+%%
+%% Revision 1.1.1.1  2004/03/01 00:20:27  eb
+%% initial checkin
+%%
+%% Revision 1.1  2003/05/25 05:29:04  eb
+%% see ChangeLog
+%%
+%% Revision 1.1.2.1  2003/02/17 02:03:07  dgrisby
+%% vxWorks port. (Thanks Michael Sturm / Acterna Eningen GmbH).
+%%
+%% Revision 1.1.1.1  2002/11/19 14:55:21  sokcevti
+%% OmniOrb4.0.0 VxWorks port
+%%
+%% Revision 1.2  2002/06/14 12:45:50  engeln
+%% unnecessary members in condition removed.
+%% ---
+%%
+%% Revision 1.1.1.1  2002/04/02 10:08:49  sokcevti
+%% omniORB4 initial realease
+%%
+%% Revision 1.1  2001/03/23 16:50:23  hartmut
+%% Initial Version 2.8
+%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+*/
+
+
+///////////////////////////////////////////////////////////////////////////
+// Includes
+///////////////////////////////////////////////////////////////////////////
+#include <vxWorks.h>
+#include <semLib.h>
+#include <taskLib.h>
+
+
+///////////////////////////////////////////////////////////////////////////
+// Externs prototypes
+///////////////////////////////////////////////////////////////////////////
+extern "C" void omni_thread_wrapper(void* ptr);
+
+
+///////////////////////////////////////////////////////////////////////////
+// Exported macros
+// Note: These are added as private members in each class implementation.
+///////////////////////////////////////////////////////////////////////////
+#define OMNI_MUTEX_IMPLEMENTATION \
+   SEM_ID mutexID;     \
+   bool m_bConstructed;
+
+#define OMNI_CONDITION_IMPLEMENTATION \
+   long waiters_; \
+   SEM_ID waiters_lock_; \
+   SEM_ID sema_;
+
+#define OMNI_SEMAPHORE_IMPLEMENTATION \
+   SEM_ID semID;
+
+#define OMNI_MUTEX_LOCK_IMPLEMENTATION                  \
+       if(semTake(mutexID, WAIT_FOREVER) != OK)        \
+       {       \
+               throw omni_thread_fatal(errno); \
+       }
+
+#define OMNI_MUTEX_UNLOCK_IMPLEMENTATION                \
+       if(semGive(mutexID) != OK)      \
+       {       \
+               throw omni_thread_fatal(errno); \
+       }
+
+#define OMNI_THREAD_IMPLEMENTATION \
+   friend void omni_thread_wrapper(void* ptr); \
+   static int vxworks_priority(priority_t); \
+   omni_condition *running_cond; \
+   void* return_val; \
+   int tid; \
+   public: \
+   static void attach(void); \
+   static void detach(void); \
+   static void show(void);
+
+
+///////////////////////////////////////////////////////////////////////////
+// Porting macros
+///////////////////////////////////////////////////////////////////////////
+// This is a wrapper function for the 'main' function which does not exists
+//  as such in VxWorks. The wrapper creates a launch function instead,
+//  which spawns the application wrapped in a omni_thread.
+// Argc will always be null.
+///////////////////////////////////////////////////////////////////////////
+#define main( discarded_argc, discarded_argv ) \
+        omni_discard_retval() \
+          { \
+          throw; \
+          } \
+        int omni_main( int argc, char **argv ); \
+        void launch( ) \
+          { \
+          omni_thread* th = new omni_thread( (void(*)(void*))omni_main );\
+          th->start();\
+          }\
+        int omni_main( int argc, char **argv )
+
+
+#endif // ndef __VXTHREAD_H__
diff --git a/gnuradio-core/src/lib/omnithread/ot_mach.h b/gnuradio-core/src/lib/omnithread/ot_mach.h
new file mode 100644 (file)
index 0000000..483f600
--- /dev/null
@@ -0,0 +1,51 @@
+//                             Package : omnithread
+// omnithread/posix.h          Created : 7/97 lars immisch lars@ibp.de
+//
+//    Copyright (C) 1994,1995,1996, 1997 Immisch, becker & Partner
+//
+//    This file is part of the omnithread library
+//
+//    The omnithread library is free software; you can redistribute it and/or
+//    modify it under the terms of the GNU Library General Public
+//    License as published by the Free Software Foundation; either
+//    version 2 of the License, or (at your option) any later version.
+//
+//    This library is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//    Library General Public License for more details.
+//
+//    You should have received a copy of the GNU Library General Public
+//    License along with this library; if not, write to the Free
+//    Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  
+//    02111-1307, USA
+//
+//
+// OMNI thread implementation classes for posix threads
+//
+
+#ifndef __omnithread_mach_h_
+#define __omnithread_mach_h_
+
+#include <mach/cthreads.h>
+
+extern "C" void* omni_thread_wrapper(void* ptr);
+
+#define OMNI_MUTEX_IMPLEMENTATION                      \
+    struct mutex mach_mutex;
+
+#define OMNI_CONDITION_IMPLEMENTATION                  \
+    struct condition mach_cond;
+
+#define OMNI_SEMAPHORE_IMPLEMENTATION                  \
+    omni_mutex m;                                      \
+    omni_condition c;                                  \
+    int value;
+
+
+#define OMNI_THREAD_IMPLEMENTATION                     \
+    cthread_t mach_thread;                             \
+    static int mach_priority(priority_t);              \
+    friend void* omni_thread_wrapper(void* ptr);
+
+#endif
diff --git a/gnuradio-core/src/lib/omnithread/ot_nt.h b/gnuradio-core/src/lib/omnithread/ot_nt.h
new file mode 100644 (file)
index 0000000..3ed173f
--- /dev/null
@@ -0,0 +1,85 @@
+//                             Package : omnithread
+// omnithread/nt.h             Created : 6/95 tjr
+//
+//    Copyright (C) 1995, 1996, 1997 Olivetti & Oracle Research Laboratory
+//
+//    This file is part of the omnithread library
+//
+//    The omnithread library is free software; you can redistribute it and/or
+//    modify it under the terms of the GNU Library General Public
+//    License as published by the Free Software Foundation; either
+//    version 2 of the License, or (at your option) any later version.
+//
+//    This library is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//    Library General Public License for more details.
+//
+//    You should have received a copy of the GNU Library General Public
+//    License along with this library; if not, write to the Free
+//    Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  
+//    02111-1307, USA
+//
+//
+// OMNI thread implementation classes for NT threads.
+//
+
+#ifndef __omnithread_nt_h_
+#define __omnithread_nt_h_
+
+#ifndef WIN32_LEAN_AND_MEAN
+#  define WIN32_LEAN_AND_MEAN
+#  define OMNI_DEFINED_WIN32_LEAN_AND_MEAN
+#endif
+
+#include <windows.h>
+
+#ifdef OMNI_DEFINED_WIN32_LEAN_AND_MEAN
+#  undef WIN32_LEAN_AND_MEAN
+#  undef OMNI_DEFINED_WIN32_LEAN_AND_MEAN
+#endif
+
+
+#ifndef __BCPLUSPLUS__
+#define OMNI_THREAD_WRAPPER \
+    unsigned __stdcall omni_thread_wrapper(LPVOID ptr);
+#else
+#define OMNI_THREAD_WRAPPER \
+    void _USERENTRY omni_thread_wrapper(void *ptr);
+#endif
+
+extern "C" OMNI_THREAD_WRAPPER;
+
+#define OMNI_MUTEX_IMPLEMENTATION                      \
+    CRITICAL_SECTION crit;
+
+#define OMNI_MUTEX_LOCK_IMPLEMENTATION                  \
+    EnterCriticalSection(&crit);
+
+#define OMNI_MUTEX_TRYLOCK_IMPLEMENTATION               \
+    TryEnterCriticalSection(&crit);
+
+#define OMNI_MUTEX_UNLOCK_IMPLEMENTATION                \
+    LeaveCriticalSection(&crit);
+
+#define OMNI_CONDITION_IMPLEMENTATION                  \
+    CRITICAL_SECTION crit;                             \
+    omni_thread* waiting_head;                         \
+    omni_thread* waiting_tail;
+
+#define OMNI_SEMAPHORE_IMPLEMENTATION                  \
+    HANDLE nt_sem;
+
+#define OMNI_THREAD_IMPLEMENTATION                     \
+    HANDLE handle;                                     \
+    DWORD nt_id;                                       \
+    void* return_val;                                  \
+    HANDLE cond_semaphore;                             \
+    omni_thread* cond_next;                            \
+    omni_thread* cond_prev;                            \
+    BOOL cond_waiting;                                 \
+    static int nt_priority(priority_t);                        \
+    friend class omni_condition;                       \
+    friend OMNI_THREAD_WRAPPER;
+
+#endif
diff --git a/gnuradio-core/src/lib/omnithread/ot_posix.h b/gnuradio-core/src/lib/omnithread/ot_posix.h
new file mode 100644 (file)
index 0000000..1e5bf9d
--- /dev/null
@@ -0,0 +1,81 @@
+//                             Package : omnithread
+// omnithread/posix.h          Created : 7/94 tjr
+//
+//    Copyright (C) 2006 Free Software Foundation, Inc.
+//    Copyright (C) 1994,1995,1996, 1997 Olivetti & Oracle Research Laboratory
+//
+//    This file is part of the omnithread library
+//
+//    The omnithread library is free software; you can redistribute it and/or
+//    modify it under the terms of the GNU Library General Public
+//    License as published by the Free Software Foundation; either
+//    version 2 of the License, or (at your option) any later version.
+//
+//    This library is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//    Library General Public License for more details.
+//
+//    You should have received a copy of the GNU Library General Public
+//    License along with this library; if not, write to the Free
+//    Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  
+//    02111-1307, USA
+//
+//
+// OMNI thread implementation classes for posix threads
+//
+
+#ifndef __omnithread_posix_h_
+#define __omnithread_posix_h_
+
+#if defined(__alpha__) && defined(__osf1__) || defined(__hpux__)
+// stop unnecessary definitions of TRY, etc on OSF
+#ifndef EXC_HANDLING
+#define EXC_HANDLING
+#endif
+#endif
+
+#ifndef __POSIX_NT__
+#  include <pthread.h>
+#else
+#  ifndef WIN32_LEAN_AND_MEAN
+#    define WIN32_LEAN_AND_MEAN
+#    define OMNI_DEFINED_WIN32_LEAN_AND_MEAN
+#  endif
+#  include <windows.h>
+#  include "pthread_nt.h"
+#  ifdef OMNI_DEFINED_WIN32_LEAN_AND_MEAN
+#    undef WIN32_LEAN_AND_MEAN
+#    undef OMNI_DEFINED_WIN32_LEAN_AND_MEAN
+#  endif
+#endif
+
+extern "C" void* omni_thread_wrapper(void* ptr);
+
+#define OMNI_MUTEX_IMPLEMENTATION                      \
+    pthread_mutex_t posix_mutex;
+
+#define OMNI_MUTEX_LOCK_IMPLEMENTATION                  \
+    pthread_mutex_lock(&posix_mutex);
+
+#define OMNI_MUTEX_TRYLOCK_IMPLEMENTATION               \
+    (pthread_mutex_trylock(&posix_mutex)==0);
+
+#define OMNI_MUTEX_UNLOCK_IMPLEMENTATION                \
+    pthread_mutex_unlock(&posix_mutex);
+
+#define OMNI_CONDITION_IMPLEMENTATION                  \
+    pthread_cond_t posix_cond;
+
+#define OMNI_SEMAPHORE_IMPLEMENTATION                  \
+    omni_mutex m;                                      \
+    omni_condition c;                                  \
+    int value;                                         \
+    int max_count;
+
+#define OMNI_THREAD_IMPLEMENTATION                     \
+    pthread_t posix_thread;                            \
+    static int posix_priority(priority_t);             \
+    friend void* omni_thread_wrapper(void* ptr);
+
+#endif
diff --git a/gnuradio-core/src/lib/omnithread/ot_pthread_nt.h b/gnuradio-core/src/lib/omnithread/ot_pthread_nt.h
new file mode 100644 (file)
index 0000000..cf3d879
--- /dev/null
@@ -0,0 +1,186 @@
+/*                             Package : omnithread
+   omnithread/pthread_nt.h     Created : Steven Brenneis <brennes1@rjrt.com>
+  
+      Copyright (C) 1998 Steven Brennes
+  
+      This file is part of the omnithread library
+  
+      The omnithread library is free software; you can redistribute it and/or
+      modify it under the terms of the GNU Library General Public
+      License as published by the Free Software Foundation; either
+      version 2 of the License, or (at your option) any later version.
+  
+      This library is distributed in the hope that it will be useful,
+      but WITHOUT ANY WARRANTY; without even the implied warranty of
+      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+      Library General Public License for more details.
+  
+      You should have received a copy of the GNU Library General Public
+      License along with this library; if not, write to the Free
+      Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  
+      02111-1307, USA
+  
+      Posix Threads implementation for Windows NT, version 4.0
+*/
+
+#ifndef PTHREAD_NT_H_INCLUDED
+#define PTHREAD_NT_H_INCLUDED
+
+#include <errno.h>
+
+#ifndef ETIMEDOUT
+//     May have to be changed if NT starts supporting more errno values
+#define ETIMEDOUT 60
+#endif
+
+#undef PthreadDraftVersion
+#define PthreadDraftVersion 10
+
+#define NoNanoSleep
+
+#define PthreadSupportThreadPriority
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef _TIMERS_T_
+#define _TIMERS_T_
+       typedef struct timespec {
+               unsigned long tv_sec;
+               long tv_nsec;
+       } timespec_t;
+#endif
+
+typedef char* __pthreadLongString_t;
+typedef void* __pthreadLongAddr_t;
+typedef __pthreadLongAddr_t* __pthreadLongAddr_p;
+typedef long __pthreadLongInt_t;
+typedef unsigned long __pthreadLongUint_t;
+typedef __pthreadLongAddr_p __pthreadTsd_t;
+
+typedef struct __pthread_mutex_t {
+       unsigned int lock;           /* LOCK, SLOW, TYPE, RECURSIVE  */
+       unsigned int valid;          /* Validation info */
+       __pthreadLongString_t name;   /* Name of mutex */
+       unsigned int arg;            /* printf argument for  name */
+       unsigned int depth;          /* Recursive lock depth */
+       unsigned long sequence;       /* Mutex sequence number */
+       unsigned long owner;          /* Current owner (if known */
+       __pthreadLongAddr_t block;          /* Pointer to blocking struct */
+} pthread_mutex_t;
+
+typedef struct __pthread_mutexattr_t {
+       long valid;
+       __pthreadLongUint_t reserved[15];
+} pthread_mutexattr_t;
+
+typedef struct __pthread_cond_t {
+       unsigned int state;          /* EVENT, SLOW, REFCNT */
+       unsigned int valid;          /* Validation info */
+       __pthreadLongString_t name;   /* Name of condition variable */
+       unsigned int arg;            /* printf argument for name */
+       unsigned long sequence;       /* Condition variable seq # */
+       __pthreadLongAddr_t block;          /* Pointer to blocking struct */
+} pthread_cond_t ;
+
+typedef struct __pthread_condattr_t {
+       long valid;
+       __pthreadLongUint_t reserved[13];
+} pthread_condattr_t ;
+
+typedef struct __pthread_transp_t {
+       __pthreadLongAddr_t reserved1;      /* Reserved to posix_nt */
+       __pthreadLongAddr_t reserved2;      /* Reserved to posix_nt */
+       unsigned short size;           /* Size of data structure */
+       unsigned char reserved3[2];   /* Reserved to posix_nt */
+       __pthreadLongAddr_t reserved4;   /* Reserved to posix_nt */
+       __pthreadLongUint_t sequence;       /* Thread sequence number */
+       __pthreadLongUint_t reserved5[2];   /* Reserved to posix_nt */
+       __pthreadLongAddr_t per_kt_area;    /* Pointer to kernel context */
+       __pthreadLongAddr_t stack_base;     /* Current stack base */
+       __pthreadLongAddr_t stack_reserve; /* Current stack reserve zone */
+       __pthreadLongAddr_t stack_yellow;   /* Current stack yellow zone */
+       __pthreadLongAddr_t stack_guard;    /* Current stack guard zone */
+       __pthreadLongUint_t stack_size;     /* Size of stack */
+       __pthreadTsd_t tsd_values;     /* TSD array (indexed by key) */
+       unsigned long tsd_count;      /* Number of TSD cells */
+       __pthreadLongAddr_t reserved6;      /* Reserved to posix_nt */
+       __pthreadLongAddr_t reserved7;      /* Reserved to posix_nt */
+       unsigned int thread_flags;   /* Dynamic external state */
+} pthread_transp_t, *pthread_transp_p;
+
+typedef pthread_transp_p pthread_t;
+
+typedef struct __pthread_attr_t {
+       long valid;
+       __pthreadLongString_t name;
+       __pthreadLongUint_t arg;
+       __pthreadLongUint_t reserved[19];
+} pthread_attr_t ;
+
+typedef unsigned int pthread_key_t;
+
+typedef struct sched_param {
+       int sched_priority;
+} sched_param_t;
+        
+/*     Function Prototypes */
+
+int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
+                                                               void *(*start_routine)(void*), void *arg);
+int pthread_detach(pthread_t thread);
+int pthread_join(pthread_t thread, void **value_ptr);
+void pthread_exit(void *value_ptr);
+int pthread_attr_init(pthread_attr_t *attr);
+int pthread_attr_destroy(pthread_attr_t *attr);
+int pthread_attr_setstacksize(pthread_attr_t *attr, size_t stacksize);
+int pthread_attr_getstacksize(const pthread_attr_t *attr, 
+                                                                                       size_t *stacksize);
+int pthread_cond_init(pthread_cond_t *cond,
+                                                               const pthread_condattr_t *attr);
+int pthread_cond_destroy(pthread_cond_t *cond);
+int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex);
+int pthread_cond_timedwait(pthread_cond_t *cond, 
+                                                                                       pthread_mutex_t *mutex,
+                                                                                       const struct timespec *abstime);
+int pthread_cond_signal(pthread_cond_t *cond);
+int pthread_cond_broadcast(pthread_cond_t *cond);
+int pthread_key_create(pthread_key_t *key, void (*destructor)(void*));
+int pthread_key_delete(pthread_key_t key);
+int pthread_mutex_destroy(pthread_mutex_t *mutex);
+int pthread_mutex_init(pthread_mutex_t *mutex, 
+                                                                       const pthread_mutexattr_t *attr);
+int pthread_mutex_lock(pthread_mutex_t *mutex);
+int pthread_mutex_trylock(pthread_mutex_t *mutex);
+int pthread_mutex_unlock(pthread_mutex_t *mutex);
+pthread_t pthread_self();
+int pthread_setspecific(pthread_key_t key, const void *value);
+void *pthread_getspecific(pthread_key_t key);
+int pthread_getschedparam(pthread_t thread, int *policy,
+                                                                                       struct sched_param *param);
+int pthread_setschedparam(pthread_t thread, int policy,
+                                                                               const struct sched_param *param);
+int pthread_attr_setschedparam(pthread_attr_t *attr, 
+                                                                                               const struct sched_param *param);
+int pthread_attr_getschedparam(const pthread_attr_t *attr, 
+                                                                                               struct sched_param *param);
+
+int pthread_delay_np(const struct timespec *interval);
+int pthread_get_expiration_np(const struct timespec *delta,
+                                                                                               struct timespec *abstime);
+
+# define SCHED_FIFO 1
+# define SCHED_RR 2
+# define SCHED_OTHER 3
+
+int sched_yield();
+int sched_get_priority_max(int policy);
+int sched_get_priority_min(int policy);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif //      PTHREAD_NT_H_INCLUDED
diff --git a/gnuradio-core/src/lib/omnithread/ot_solaris.h b/gnuradio-core/src/lib/omnithread/ot_solaris.h
new file mode 100644 (file)
index 0000000..aaef036
--- /dev/null
@@ -0,0 +1,47 @@
+//                             Package : omnithread
+// omnithread/solaris.h                Created : 7/94 tjr
+//
+//    Copyright (C) 1994,1995,1996, 1997 Olivetti & Oracle Research Laboratory
+//
+//    This file is part of the omnithread library
+//
+//    The omnithread library is free software; you can redistribute it and/or
+//    modify it under the terms of the GNU Library General Public
+//    License as published by the Free Software Foundation; either
+//    version 2 of the License, or (at your option) any later version.
+//
+//    This library is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//    Library General Public License for more details.
+//
+//    You should have received a copy of the GNU Library General Public
+//    License along with this library; if not, write to the Free
+//    Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  
+//    02111-1307, USA
+//
+// OMNI thread implementation classes for solaris threads.
+//
+
+#ifndef __omnithread_solaris_h_
+#define __omnithread_solaris_h_
+
+#include <thread.h>
+
+extern "C" void* omni_thread_wrapper(void* ptr);
+
+#define OMNI_MUTEX_IMPLEMENTATION                      \
+    mutex_t sol_mutex;
+
+#define OMNI_CONDITION_IMPLEMENTATION                  \
+    cond_t sol_cond;
+
+#define OMNI_SEMAPHORE_IMPLEMENTATION                  \
+    sema_t sol_sem;
+
+#define OMNI_THREAD_IMPLEMENTATION                     \
+    thread_t sol_thread;                               \
+    static int sol_priority(priority_t);               \
+    friend void* omni_thread_wrapper(void* ptr);
+
+#endif
diff --git a/gnuradio-core/src/lib/omnithread/posix.cc b/gnuradio-core/src/lib/omnithread/posix.cc
new file mode 100644 (file)
index 0000000..5fda14f
--- /dev/null
@@ -0,0 +1,972 @@
+//                             Package : omnithread
+// omnithread/posix.cc         Created : 7/94 tjr
+//
+//    Copyright (C) 2006 Free Software Foundation, Inc.
+//    Copyright (C) 1994-1999 AT&T Laboratories Cambridge
+//
+//    This file is part of the omnithread library
+//
+//    The omnithread library is free software; you can redistribute it and/or
+//    modify it under the terms of the GNU Library General Public
+//    License as published by the Free Software Foundation; either
+//    version 2 of the License, or (at your option) any later version.
+//
+//    This library is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//    Library General Public License for more details.
+//
+//    You should have received a copy of the GNU Library General Public
+//    License along with this library; if not, write to the Free
+//    Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  
+//    02111-1307, USA
+//
+
+//
+// Implementation of OMNI thread abstraction for posix threads
+//
+// The source below tests for the definition of the macros:
+//     PthreadDraftVersion
+//     PthreadSupportThreadPriority
+//     NoNanoSleep
+//     NeedPthreadInit
+//
+// As different draft versions of the pthread standard P1003.4a/P1003.1c
+// define slightly different APIs, the macro 'PthreadDraftVersion'
+// identifies the draft version supported by this particular platform.
+//
+// Some unix variants do not support thread priority unless a real-time
+// kernel option is installed. The macro 'PthreadSupportThreadPriority',
+// if defined, enables the use of thread priority. If it is not defined,
+// setting or changing thread priority will be silently ignored.
+//
+// nanosleep() is defined in Posix P1003.4 since Draft 9 (?).
+// Not all platforms support this standard. The macro 'NoNanoSleep'
+// identifies platform that don't.
+//
+
+#include <config.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <time.h>
+#include <omnithread.h>
+
+#ifdef HAVE_NANOSLEEP
+#undef NoNanoSleep
+#else
+#define NoNanoSleep
+#endif
+
+#ifdef HAVE_SYS_TIME_H
+// typedef of struct timeval and gettimeofday();
+#include <sys/time.h>
+#include <unistd.h>
+#endif
+
+#if defined(__linux__) && defined(_MIT_POSIX_THREADS)
+#include <pthread/mit/sys/timers.h>
+#endif
+
+#if defined(__irix__) && defined(PthreadSupportThreadPriority)
+#if _POSIX_THREAD_PRIORITY_SCHEDULING
+#include <sched.h>
+#endif
+#endif
+
+#define DB(x) // x
+//#include <iostream.h> or #include <iostream> if DB is on.
+
+#if (PthreadDraftVersion <= 6)
+#define ERRNO(x) (((x) != 0) ? (errno) : 0)
+#ifdef __VMS
+// pthread_setprio returns old priority on success (draft version 4:
+// OpenVms version < 7)
+#define THROW_ERRORS(x) { if ((x) == -1) throw omni_thread_fatal(errno); }
+#else
+#define THROW_ERRORS(x) { if ((x) != 0) throw omni_thread_fatal(errno); }
+#endif
+#else
+#define ERRNO(x) (x)
+#define THROW_ERRORS(x) { int rc = (x); \
+                         if (rc != 0) throw omni_thread_fatal(rc); }
+#endif
+
+
+
+///////////////////////////////////////////////////////////////////////////
+//
+// Mutex
+//
+///////////////////////////////////////////////////////////////////////////
+
+
+omni_mutex::omni_mutex(void)
+{
+#if (PthreadDraftVersion == 4)
+    THROW_ERRORS(pthread_mutex_init(&posix_mutex, pthread_mutexattr_default));
+#else
+    THROW_ERRORS(pthread_mutex_init(&posix_mutex, 0));
+#endif
+}
+
+omni_mutex::~omni_mutex(void)
+{
+    THROW_ERRORS(pthread_mutex_destroy(&posix_mutex));
+}
+
+
+///////////////////////////////////////////////////////////////////////////
+//
+// Condition variable
+//
+///////////////////////////////////////////////////////////////////////////
+
+
+omni_condition::omni_condition(omni_mutex* m) : mutex(m)
+{
+#if (PthreadDraftVersion == 4)
+    THROW_ERRORS(pthread_cond_init(&posix_cond, pthread_condattr_default));
+#else
+    THROW_ERRORS(pthread_cond_init(&posix_cond, 0));
+#endif
+}
+
+omni_condition::~omni_condition(void)
+{
+    THROW_ERRORS(pthread_cond_destroy(&posix_cond));
+}
+
+void
+omni_condition::wait(void)
+{
+    THROW_ERRORS(pthread_cond_wait(&posix_cond, &mutex->posix_mutex));
+}
+
+int
+omni_condition::timedwait(unsigned long secs, unsigned long nanosecs)
+{
+    timespec rqts = { secs, nanosecs };
+
+again:
+    int rc = ERRNO(pthread_cond_timedwait(&posix_cond,
+                                         &mutex->posix_mutex, &rqts));
+    if (rc == 0)
+       return 1;
+
+#if (PthreadDraftVersion <= 6)
+    if (rc == EAGAIN)
+       return 0;
+#endif
+
+    // Some versions of unix produces this errno when the wait was
+    // interrupted by a unix signal or fork.
+    // Some versions of the glibc 2.0.x produces this errno when the 
+    // program is debugged under gdb. Straightly speaking this is non-posix
+    // compliant. We catch this here to make debugging possible.
+    if (rc == EINTR)
+      goto again;
+
+    if (rc == ETIMEDOUT)
+       return 0;
+
+    throw omni_thread_fatal(rc);
+#ifdef _MSC_VER
+    return 0;
+#endif
+}
+
+void
+omni_condition::signal(void)
+{
+    THROW_ERRORS(pthread_cond_signal(&posix_cond));
+}
+
+void
+omni_condition::broadcast(void)
+{
+    THROW_ERRORS(pthread_cond_broadcast(&posix_cond));
+}
+
+
+
+///////////////////////////////////////////////////////////////////////////
+//
+// Counting (or binary) semaphore
+//
+///////////////////////////////////////////////////////////////////////////
+
+
+omni_semaphore::omni_semaphore(unsigned int initial, unsigned int _max_count) : c(&m)
+{
+    value = initial;
+    max_count = _max_count;
+    if (value < 0 || max_count < 1)
+      throw omni_thread_fatal(0);
+}
+
+omni_semaphore::~omni_semaphore(void)
+{
+}
+
+void
+omni_semaphore::wait(void)
+{
+    omni_mutex_lock l(m);
+
+    while (value == 0)
+       c.wait();
+
+    value--;
+}
+
+int
+omni_semaphore::trywait(void)
+{
+    omni_mutex_lock l(m);
+
+    if (value == 0)
+       return 0;
+
+    value--;
+    return 1;
+}
+
+void
+omni_semaphore::post(void)
+{
+    {
+        omni_mutex_lock l(m);
+       if (value < max_count)
+         value++;
+    }
+
+    c.signal();
+}
+
+
+
+///////////////////////////////////////////////////////////////////////////
+//
+// Thread
+//
+///////////////////////////////////////////////////////////////////////////
+
+
+//
+// static variables
+//
+
+omni_mutex* omni_thread::next_id_mutex;
+int omni_thread::next_id = 0;
+
+static pthread_key_t self_key;
+
+#ifdef PthreadSupportThreadPriority
+static int lowest_priority;
+static int normal_priority;
+static int highest_priority;
+#endif
+
+#if defined(__osf1__) && defined(__alpha__) || defined(__VMS)
+// omniORB requires a larger stack size than the default (21120) on OSF/1
+static size_t stack_size = 32768;
+#elif defined(__rtems__)
+static size_t stack_size = ThreadStackSize;
+#elif defined(__aix__)
+static size_t stack_size = 262144;
+#else
+static size_t stack_size = 0;
+#endif
+
+//
+// Initialisation function (gets called before any user code).
+//
+
+static int& count() {
+  static int the_count = 0;
+  return the_count;
+}
+
+omni_thread::init_t::init_t(void)
+{
+    if (count()++ != 0)        // only do it once however many objects get created.
+       return;
+
+    DB(cerr << "omni_thread::init: posix 1003.4a/1003.1c (draft "
+       << PthreadDraftVersion << ") implementation initialising\n");
+
+#ifdef NeedPthreadInit
+
+    pthread_init();
+
+#endif
+
+#if (PthreadDraftVersion == 4)
+    THROW_ERRORS(pthread_keycreate(&self_key, NULL));
+#else
+    THROW_ERRORS(pthread_key_create(&self_key, NULL));
+#endif
+
+#ifdef PthreadSupportThreadPriority
+
+#if defined(__osf1__) && defined(__alpha__) || defined(__VMS)
+
+    lowest_priority = PRI_OTHER_MIN;
+    highest_priority = PRI_OTHER_MAX;
+
+#elif defined(__hpux__)
+
+    lowest_priority = PRI_OTHER_MIN;
+    highest_priority = PRI_OTHER_MAX;
+
+#elif defined(__sunos__) && (__OSVERSION__ == 5)
+
+    // a bug in pthread_attr_setschedparam means lowest priority is 1 not 0
+
+    lowest_priority  = 1;
+    highest_priority = 3;
+
+#else
+
+    lowest_priority = sched_get_priority_min(SCHED_FIFO);
+    highest_priority = sched_get_priority_max(SCHED_FIFO);
+
+#endif
+
+    switch (highest_priority - lowest_priority) {
+
+    case 0:
+    case 1:
+       normal_priority = lowest_priority;
+       break;
+
+    default:
+       normal_priority = lowest_priority + 1;
+       break;
+    }
+
+#endif   /* PthreadSupportThreadPriority */
+
+    next_id_mutex = new omni_mutex;
+
+    //
+    // Create object for this (i.e. initial) thread.
+    //
+
+    omni_thread* t = new omni_thread;
+
+    t->_state = STATE_RUNNING;
+
+    t->posix_thread = pthread_self ();
+
+    DB(cerr << "initial thread " << t->id() << endl);
+
+    THROW_ERRORS(pthread_setspecific(self_key, (void*)t));
+
+#ifdef PthreadSupportThreadPriority
+
+#if (PthreadDraftVersion == 4)
+
+    THROW_ERRORS(pthread_setprio(t->posix_thread,
+                                posix_priority(PRIORITY_NORMAL)));
+
+#elif (PthreadDraftVersion == 6)
+
+    pthread_attr_t attr;
+    pthread_attr_init(&attr);
+
+    THROW_ERRORS(pthread_attr_setprio(&attr, posix_priority(PRIORITY_NORMAL)));
+
+    THROW_ERRORS(pthread_setschedattr(t->posix_thread, attr));
+
+#else
+
+    struct sched_param sparam;
+
+    sparam.sched_priority = posix_priority(PRIORITY_NORMAL);
+
+    THROW_ERRORS(pthread_setschedparam(t->posix_thread, SCHED_OTHER, &sparam));
+
+#endif   /* PthreadDraftVersion */
+
+#endif   /* PthreadSupportThreadPriority */
+}
+
+omni_thread::init_t::~init_t(void)
+{
+    if (--count() != 0) return;
+
+    omni_thread* self = omni_thread::self();
+    if (!self) return;
+
+    pthread_setspecific(self_key, 0);
+    delete self;
+
+    delete next_id_mutex;
+}
+
+//
+// Wrapper for thread creation.
+//
+
+extern "C" void* 
+omni_thread_wrapper(void* ptr)
+{
+    omni_thread* me = (omni_thread*)ptr;
+
+    DB(cerr << "omni_thread_wrapper: thread " << me->id()
+       << " started\n");
+
+    THROW_ERRORS(pthread_setspecific(self_key, me));
+
+    //
+    // Now invoke the thread function with the given argument.
+    //
+
+    if (me->fn_void != NULL) {
+       (*me->fn_void)(me->thread_arg);
+       omni_thread::exit();
+    }
+
+    if (me->fn_ret != NULL) {
+       void* return_value = (*me->fn_ret)(me->thread_arg);
+       omni_thread::exit(return_value);
+    }
+
+    if (me->detached) {
+       me->run(me->thread_arg);
+       omni_thread::exit();
+    } else {
+       void* return_value = me->run_undetached(me->thread_arg);
+       omni_thread::exit(return_value);
+    }
+
+    // should never get here.
+
+    return NULL;
+}
+
+
+//
+// Constructors for omni_thread - set up the thread object but don't
+// start it running.
+//
+
+// construct a detached thread running a given function.
+
+omni_thread::omni_thread(void (*fn)(void*), void* arg, priority_t pri)
+{
+    common_constructor(arg, pri, 1);
+    fn_void = fn;
+    fn_ret = NULL;
+}
+
+// construct an undetached thread running a given function.
+
+omni_thread::omni_thread(void* (*fn)(void*), void* arg, priority_t pri)
+{
+    common_constructor(arg, pri, 0);
+    fn_void = NULL;
+    fn_ret = fn;
+}
+
+// construct a thread which will run either run() or run_undetached().
+
+omni_thread::omni_thread(void* arg, priority_t pri)
+{
+    common_constructor(arg, pri, 1);
+    fn_void = NULL;
+    fn_ret = NULL;
+}
+
+// common part of all constructors.
+
+void
+omni_thread::common_constructor(void* arg, priority_t pri, int det)
+{
+    _state = STATE_NEW;
+    _priority = pri;
+
+    next_id_mutex->lock();
+    _id = next_id++;
+    next_id_mutex->unlock();
+
+    thread_arg = arg;
+    detached = det;    // may be altered in start_undetached()
+
+    _dummy       = 0;
+    _values      = 0;
+    _value_alloc = 0;
+    // posix_thread is set up in initialisation routine or start().
+}
+
+
+//
+// Destructor for omni_thread.
+//
+
+omni_thread::~omni_thread(void)
+{
+    DB(cerr << "destructor called for thread " << id() << endl);
+    if (_values) {
+        for (key_t i=0; i < _value_alloc; i++) {
+           if (_values[i]) {
+               delete _values[i];
+           }
+        }
+       delete [] _values;
+    }
+}
+
+
+//
+// Start the thread
+//
+
+void
+omni_thread::start(void)
+{
+    omni_mutex_lock l(mutex);
+
+    if (_state != STATE_NEW)
+       throw omni_thread_invalid();
+
+    pthread_attr_t attr;
+
+#if (PthreadDraftVersion == 4)
+    pthread_attr_create(&attr);
+#else
+    pthread_attr_init(&attr);
+#endif
+
+#if (PthreadDraftVersion == 8)
+    pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_UNDETACHED);
+#endif
+
+#ifdef PthreadSupportThreadPriority
+
+#if (PthreadDraftVersion <= 6)
+
+    THROW_ERRORS(pthread_attr_setprio(&attr, posix_priority(_priority)));
+
+#else
+
+    struct sched_param sparam;
+
+    sparam.sched_priority = posix_priority(_priority);
+
+    THROW_ERRORS(pthread_attr_setschedparam(&attr, &sparam));
+
+#endif /* PthreadDraftVersion */
+
+#endif /* PthreadSupportThreadPriority */
+
+#if !defined(__linux__)
+    if (stack_size) {
+      THROW_ERRORS(pthread_attr_setstacksize(&attr, stack_size));
+    }
+#endif
+
+
+#if (PthreadDraftVersion == 4)
+    THROW_ERRORS(pthread_create(&posix_thread, attr, omni_thread_wrapper,
+                               (void*)this));
+    pthread_attr_delete(&attr);
+#else
+    THROW_ERRORS(pthread_create(&posix_thread, &attr, omni_thread_wrapper,
+                               (void*)this));
+    pthread_attr_destroy(&attr);
+#endif
+
+    _state = STATE_RUNNING;
+
+    if (detached) {
+
+#if (PthreadDraftVersion <= 6)
+       THROW_ERRORS(pthread_detach(&posix_thread));
+#else
+       THROW_ERRORS(pthread_detach(posix_thread));
+#endif
+    }
+}
+
+
+//
+// Start a thread which will run the member function run_undetached().
+//
+
+void
+omni_thread::start_undetached(void)
+{
+    if ((fn_void != NULL) || (fn_ret != NULL))
+       throw omni_thread_invalid();
+
+    detached = 0;
+    start();
+}
+
+
+//
+// join - simply check error conditions & call pthread_join.
+//
+
+void
+omni_thread::join(void** status)
+{
+    mutex.lock();
+
+    if ((_state != STATE_RUNNING) && (_state != STATE_TERMINATED)) {
+       mutex.unlock();
+       throw omni_thread_invalid();
+    }
+
+    mutex.unlock();
+
+    if (this == self())
+       throw omni_thread_invalid();
+
+    if (detached)
+       throw omni_thread_invalid();
+
+    DB(cerr << "omni_thread::join: doing pthread_join\n");
+
+    THROW_ERRORS(pthread_join(posix_thread, status));
+
+    DB(cerr << "omni_thread::join: pthread_join succeeded\n");
+
+#if (PthreadDraftVersion == 4)
+    // With draft 4 pthreads implementations (HPUX 10.x and
+    // Digital Unix 3.2), have to detach the thread after 
+    // join. If not, the storage for the thread will not be
+    // be reclaimed.
+    THROW_ERRORS(pthread_detach(&posix_thread));
+#endif
+
+    delete this;
+}
+
+
+//
+// Change this thread's priority.
+//
+
+void
+omni_thread::set_priority(priority_t pri)
+{
+    omni_mutex_lock l(mutex);
+
+    if (_state != STATE_RUNNING)
+       throw omni_thread_invalid();
+
+    _priority = pri;
+
+#ifdef PthreadSupportThreadPriority
+
+#if (PthreadDraftVersion == 4)
+
+    THROW_ERRORS(pthread_setprio(posix_thread, posix_priority(pri)));
+
+#elif (PthreadDraftVersion == 6)
+
+    pthread_attr_t attr;
+    pthread_attr_init(&attr);
+
+    THROW_ERRORS(pthread_attr_setprio(&attr, posix_priority(pri)));
+
+    THROW_ERRORS(pthread_setschedattr(posix_thread, attr));
+
+#else
+
+    struct sched_param sparam;
+
+    sparam.sched_priority = posix_priority(pri);
+
+    THROW_ERRORS(pthread_setschedparam(posix_thread, SCHED_OTHER, &sparam));
+
+#endif   /* PthreadDraftVersion */
+
+#endif   /* PthreadSupportThreadPriority */
+}
+
+
+//
+// create - construct a new thread object and start it running.  Returns thread
+// object if successful, null pointer if not.
+//
+
+// detached version
+
+omni_thread*
+omni_thread::create(void (*fn)(void*), void* arg, priority_t pri)
+{
+    omni_thread* t = new omni_thread(fn, arg, pri);
+
+    t->start();
+
+    return t;
+}
+
+// undetached version
+
+omni_thread*
+omni_thread::create(void* (*fn)(void*), void* arg, priority_t pri)
+{
+    omni_thread* t = new omni_thread(fn, arg, pri);
+
+    t->start();
+
+    return t;
+}
+
+
+//
+// exit() _must_ lock the mutex even in the case of a detached thread.  This is
+// because a thread may run to completion before the thread that created it has
+// had a chance to get out of start().  By locking the mutex we ensure that the
+// creating thread must have reached the end of start() before we delete the
+// thread object.  Of course, once the call to start() returns, the user can
+// still incorrectly refer to the thread object, but that's their problem.
+//
+
+void
+omni_thread::exit(void* return_value)
+{
+    omni_thread* me = self();
+
+    if (me)
+      {
+       me->mutex.lock();
+
+       me->_state = STATE_TERMINATED;
+
+       me->mutex.unlock();
+
+       DB(cerr << "omni_thread::exit: thread " << me->id() << " detached "
+          << me->detached << " return value " << return_value << endl);
+
+       if (me->detached)
+         delete me;
+      }
+    else
+      {
+       DB(cerr << "omni_thread::exit: called with a non-omnithread. Exit quietly." << endl);
+      }
+
+    pthread_exit(return_value);
+}
+
+
+omni_thread*
+omni_thread::self(void)
+{
+    omni_thread* me;
+
+#if (PthreadDraftVersion <= 6)
+
+    THROW_ERRORS(pthread_getspecific(self_key, (void**)&me));
+
+#else
+
+    me = (omni_thread *)pthread_getspecific(self_key);
+
+#endif
+
+    if (!me) {
+      // This thread is not created by omni_thread::start because it
+      // doesn't has a class omni_thread instance attached to its key.
+      DB(cerr << "omni_thread::self: called with a non-omnithread. NULL is returned." << endl);
+    }
+
+    return me;
+}
+
+
+void
+omni_thread::yield(void)
+{
+#if (PthreadDraftVersion == 6)
+
+    pthread_yield(NULL);
+
+#elif (PthreadDraftVersion < 9)
+
+    pthread_yield();
+
+#else
+
+    THROW_ERRORS(sched_yield());
+
+#endif
+}
+
+
+void
+omni_thread::sleep(unsigned long secs, unsigned long nanosecs)
+{
+    timespec rqts = { secs, nanosecs };
+
+#ifndef NoNanoSleep
+
+    timespec remain;
+    while (nanosleep(&rqts, &remain)) {
+      if (errno == EINTR) {
+       rqts.tv_sec  = remain.tv_sec;
+       rqts.tv_nsec = remain.tv_nsec;
+       continue;
+      }
+      else
+       throw omni_thread_fatal(errno);
+    }
+#else
+
+#if defined(__osf1__) && defined(__alpha__) || defined(__hpux__) && (__OSVERSION__ == 10) || defined(__VMS) || defined(__SINIX__) || defined (__POSIX_NT__)
+
+    if (pthread_delay_np(&rqts) != 0)
+       throw omni_thread_fatal(errno);
+
+#elif defined(__linux__) || defined(__aix__)
+
+    if (secs > 2000) {
+      while ((secs = ::sleep(secs))) ;
+    } else {
+       usleep(secs * 1000000 + (nanosecs / 1000));
+    }
+
+#elif defined(__darwin__) || defined(__macos__)
+
+    // Single UNIX Specification says argument of usleep() must be
+    // less than 1,000,000.
+    secs += nanosecs / 1000000000;
+    nanosecs %= 1000000000;
+    while ((secs = ::sleep(secs))) ;
+    usleep(nanosecs / 1000);
+
+#else
+
+    throw omni_thread_invalid();
+
+#endif
+#endif /* NoNanoSleep */
+}
+
+
+void
+omni_thread::get_time(unsigned long* abs_sec, unsigned long* abs_nsec,
+                     unsigned long rel_sec, unsigned long rel_nsec)
+{
+    timespec abs;
+
+#if defined(__osf1__) && defined(__alpha__) || defined(__hpux__) && (__OSVERSION__ == 10) || defined(__VMS) || defined(__SINIX__) || defined(__POSIX_NT__)
+
+    timespec rel;
+    rel.tv_sec = rel_sec;
+    rel.tv_nsec = rel_nsec;
+    THROW_ERRORS(pthread_get_expiration_np(&rel, &abs));
+
+#else
+
+#ifdef HAVE_CLOCK_GETTIME      /* __linux__ || __aix__ */
+
+    clock_gettime(CLOCK_REALTIME, &abs);
+
+#elif defined(HAVE_GETTIMEOFDAY)       /* defined(__linux__) || defined(__aix__) || defined(__SCO_VERSION__) || defined(__darwin__) || defined(__macos__) */
+
+    struct timeval tv;
+    gettimeofday(&tv, NULL); 
+    abs.tv_sec = tv.tv_sec;
+    abs.tv_nsec = tv.tv_usec * 1000;
+
+#else
+#error no get time support
+#endif /* __linux__ || __aix__ */
+
+    abs.tv_nsec += rel_nsec;
+    abs.tv_sec += rel_sec + abs.tv_nsec / 1000000000;
+    abs.tv_nsec = abs.tv_nsec % 1000000000;
+
+#endif /* __osf1__ && __alpha__ */
+
+    *abs_sec = abs.tv_sec;
+    *abs_nsec = abs.tv_nsec;
+}
+
+
+int
+omni_thread::posix_priority(priority_t pri)
+{
+#ifdef PthreadSupportThreadPriority
+    switch (pri) {
+
+    case PRIORITY_LOW:
+       return lowest_priority;
+
+    case PRIORITY_NORMAL:
+       return normal_priority;
+
+    case PRIORITY_HIGH:
+       return highest_priority;
+
+    }
+#endif
+
+    throw omni_thread_invalid();
+#ifdef _MSC_VER
+    return 0;
+#endif
+}
+
+void
+omni_thread::stacksize(unsigned long sz)
+{
+  stack_size = sz;
+}
+
+unsigned long
+omni_thread::stacksize()
+{
+  return stack_size;
+}
+
+//
+// Dummy thread
+//
+
+class omni_thread_dummy : public omni_thread {
+public:
+  inline omni_thread_dummy() : omni_thread()
+  {
+    _dummy = 1;
+    _state = STATE_RUNNING;
+    posix_thread = pthread_self();
+    THROW_ERRORS(pthread_setspecific(self_key, (void*)this));
+  }
+  inline ~omni_thread_dummy()
+  {
+    THROW_ERRORS(pthread_setspecific(self_key, 0));
+  }
+};
+
+omni_thread*
+omni_thread::create_dummy()
+{
+  if (omni_thread::self())
+    throw omni_thread_invalid();
+
+  return new omni_thread_dummy;
+}
+
+void
+omni_thread::release_dummy()
+{
+  omni_thread* self = omni_thread::self();
+  if (!self || !self->_dummy)
+    throw omni_thread_invalid();
+
+  omni_thread_dummy* dummy = (omni_thread_dummy*)self;
+  delete dummy;
+}
+
+
+#define INSIDE_THREAD_IMPL_CC
+#include "threaddata.cc"
+#undef INSIDE_THREAD_IMPL_CC
diff --git a/gnuradio-core/src/lib/omnithread/solaris.cc b/gnuradio-core/src/lib/omnithread/solaris.cc
new file mode 100644 (file)
index 0000000..827a645
--- /dev/null
@@ -0,0 +1,615 @@
+//                             Package : omnithread
+// omnithread/solaris.cc       Created : 7/94 tjr
+//
+//    Copyright (C) 1994-1999 AT&T Laboratories Cambridge
+//
+//    This file is part of the omnithread library
+//
+//    The omnithread library is free software; you can redistribute it and/or
+//    modify it under the terms of the GNU Library General Public
+//    License as published by the Free Software Foundation; either
+//    version 2 of the License, or (at your option) any later version.
+//
+//    This library is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//    Library General Public License for more details.
+//
+//    You should have received a copy of the GNU Library General Public
+//    License along with this library; if not, write to the Free
+//    Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  
+//    02111-1307, USA
+//
+//
+// Implementation of OMNI thread abstraction for solaris threads.
+//
+
+#include <stdlib.h>
+#include <errno.h>
+#include <omnithread.h>
+
+#define DB(x) // x 
+// #include <iostream> or #include <iostream.h> if DB is on.
+
+#define THROW_ERRORS(x) { int rc = (x); \
+                         if (rc != 0) throw omni_thread_fatal(rc); }
+
+
+
+///////////////////////////////////////////////////////////////////////////
+//
+// Mutex
+//
+///////////////////////////////////////////////////////////////////////////
+
+
+omni_mutex::omni_mutex(void)
+{
+    THROW_ERRORS(mutex_init(&sol_mutex, USYNC_THREAD, 0));
+}
+
+omni_mutex::~omni_mutex(void)
+{
+    THROW_ERRORS(mutex_destroy(&sol_mutex));
+}
+
+void
+omni_mutex::lock(void)
+{
+    THROW_ERRORS(mutex_lock(&sol_mutex));
+}
+
+void
+omni_mutex::unlock(void)
+{
+    THROW_ERRORS(mutex_unlock(&sol_mutex));
+}
+
+
+
+///////////////////////////////////////////////////////////////////////////
+//
+// Condition variable
+//
+///////////////////////////////////////////////////////////////////////////
+
+
+omni_condition::omni_condition(omni_mutex* m) : mutex(m)
+{
+    THROW_ERRORS(cond_init(&sol_cond, USYNC_THREAD, 0));
+}
+
+omni_condition::~omni_condition(void)
+{
+    THROW_ERRORS(cond_destroy(&sol_cond));
+}
+
+void
+omni_condition::wait(void)
+{
+    THROW_ERRORS(cond_wait(&sol_cond, &mutex->sol_mutex));
+}
+
+int
+omni_condition::timedwait(unsigned long secs, unsigned long nanosecs)
+{
+    timespec rqts = { secs, nanosecs };
+
+ again:
+    int rc = cond_timedwait(&sol_cond, &mutex->sol_mutex, &rqts);
+
+    if (rc == 0)
+       return 1;
+
+    if (rc == EINTR)
+        goto again;
+
+    if (rc == ETIME)
+       return 0;
+
+    throw omni_thread_fatal(rc);
+}
+
+void
+omni_condition::signal(void)
+{
+    THROW_ERRORS(cond_signal(&sol_cond));
+}
+
+void
+omni_condition::broadcast(void)
+{
+    THROW_ERRORS(cond_broadcast(&sol_cond));
+}
+
+
+
+///////////////////////////////////////////////////////////////////////////
+//
+// Counting semaphore
+//
+///////////////////////////////////////////////////////////////////////////
+
+
+omni_semaphore::omni_semaphore(unsigned int initial)
+{
+    THROW_ERRORS(sema_init(&sol_sem, initial, USYNC_THREAD, NULL));
+}
+
+omni_semaphore::~omni_semaphore(void)
+{
+    THROW_ERRORS(sema_destroy(&sol_sem));
+}
+
+void
+omni_semaphore::wait(void)
+{
+    THROW_ERRORS(sema_wait(&sol_sem));
+}
+
+void
+omni_semaphore::post(void)
+{
+    THROW_ERRORS(sema_post(&sol_sem));
+}
+
+
+
+///////////////////////////////////////////////////////////////////////////
+//
+// Thread
+//
+///////////////////////////////////////////////////////////////////////////
+
+
+//
+// Static variables
+//
+
+int omni_thread::init_t::count = 0;
+
+omni_mutex* omni_thread::next_id_mutex;
+int omni_thread::next_id = 0;
+
+static thread_key_t self_key;
+
+static size_t stack_size = 0;
+
+//
+// Initialisation function (gets called before any user code).
+//
+
+omni_thread::init_t::init_t(void)
+{
+    if (count++ != 0)  // only do it once however many objects get created.
+       return;
+
+    DB(cerr << "omni_thread::init: solaris implementation initialising\n");
+
+    THROW_ERRORS(thr_keycreate(&self_key, NULL));
+
+    next_id_mutex = new omni_mutex;
+
+    //
+    // Create object for this (i.e. initial) thread.
+    //
+
+    omni_thread* t = new omni_thread;
+
+    t->_state = STATE_RUNNING;
+
+    t->sol_thread = thr_self();
+
+    DB(cerr << "initial thread " << t->id() << " sol_thread " << t->sol_thread
+       << endl);
+
+    THROW_ERRORS(thr_setspecific(self_key, (void*)t));
+
+    THROW_ERRORS(thr_setprio(t->sol_thread, sol_priority(PRIORITY_NORMAL)));
+}
+
+
+//
+// Wrapper for thread creation.
+//
+
+extern "C" void*
+omni_thread_wrapper(void* ptr)
+{
+    omni_thread* me = (omni_thread*)ptr;
+
+    DB(cerr << "omni_thread::wrapper: thread " << me->id()
+       << " started\n");
+
+    THROW_ERRORS(thr_setspecific(self_key, me));
+
+    //
+    // Now invoke the thread function with the given argument.
+    //
+
+    if (me->fn_void != NULL) {
+       (*me->fn_void)(me->thread_arg);
+       omni_thread::exit();
+    }
+
+    if (me->fn_ret != NULL) {
+       void* return_value = (*me->fn_ret)(me->thread_arg);
+       omni_thread::exit(return_value);
+    }
+
+    if (me->detached) {
+       me->run(me->thread_arg);
+       omni_thread::exit();
+    } else {
+       void* return_value = me->run_undetached(me->thread_arg);
+       omni_thread::exit(return_value);
+    }
+
+    // should never get here.
+
+    return NULL;
+}
+
+
+//
+// Constructors for omni_thread - set up the thread object but don't
+// start it running.
+//
+
+// construct a detached thread running a given function.
+
+omni_thread::omni_thread(void (*fn)(void*), void* arg, priority_t pri)
+{
+    common_constructor(arg, pri, 1);
+    fn_void = fn;
+    fn_ret = NULL;
+}
+
+// construct an undetached thread running a given function.
+
+omni_thread::omni_thread(void* (*fn)(void*), void* arg, priority_t pri)
+{
+    common_constructor(arg, pri, 0);
+    fn_void = NULL;
+    fn_ret = fn;
+}
+
+// construct a thread which will run either run() or run_undetached().
+
+omni_thread::omni_thread(void* arg, priority_t pri)
+{
+    common_constructor(arg, pri, 1);
+    fn_void = NULL;
+    fn_ret = NULL;
+}
+
+// common part of all constructors.
+
+void
+omni_thread::common_constructor(void* arg, priority_t pri, int det)
+{
+    _state = STATE_NEW;
+    _priority = pri;
+
+    next_id_mutex->lock();
+    _id = next_id++;
+    next_id_mutex->unlock();
+
+    thread_arg = arg;
+    detached = det;    // may be altered in start_undetached()
+
+    _dummy       = 0;
+    _values      = 0;
+    _value_alloc = 0;
+    // sol_thread is set up in initialisation routine or start().
+}
+
+
+//
+// Destructor for omni_thread.
+//
+
+omni_thread::~omni_thread(void)
+{
+    DB(cerr << "destructor called for thread " << id() << endl);
+    if (_values) {
+        for (key_t i=0; i < _value_alloc; i++) {
+           if (_values[i]) {
+               delete _values[i];
+           }
+        }
+       delete [] _values;
+    }
+}
+
+
+//
+// Start the thread
+//
+
+void
+omni_thread::start(void)
+{
+    long flags = 0;
+
+    if (detached)
+       flags |= THR_DETACHED;
+
+    omni_mutex_lock l(mutex);
+
+    if (_state != STATE_NEW)
+       throw omni_thread_invalid();
+
+    THROW_ERRORS(thr_create(0, stack_size, omni_thread_wrapper, (void*)this, flags,
+                           &sol_thread));
+
+    _state = STATE_RUNNING;
+
+    THROW_ERRORS(thr_setprio(sol_thread, sol_priority(_priority)));
+}
+
+
+//
+// Start a thread which will run the member function run_undetached().
+//
+
+void
+omni_thread::start_undetached(void)
+{
+    if ((fn_void != NULL) || (fn_ret != NULL))
+       throw omni_thread_invalid();
+
+    detached = 0;
+    start();
+}
+
+
+//
+// join - simply check error conditions & call thr_join.
+//
+
+void
+omni_thread::join(void** status)
+{
+    mutex.lock();
+
+    if ((_state != STATE_RUNNING) && (_state != STATE_TERMINATED)) {
+       mutex.unlock();
+       throw omni_thread_invalid();
+    }
+
+    mutex.unlock();
+
+    if (this == self())
+       throw omni_thread_invalid();
+
+    if (detached)
+       throw omni_thread_invalid();
+
+    DB(cerr << "omni_thread::join: doing thr_join\n");
+
+    THROW_ERRORS(thr_join(sol_thread, (thread_t *)NULL, status));
+
+    DB(cerr << "omni_thread::join: thr_join succeeded\n");
+
+    delete this;
+}
+
+
+//
+// Change this thread's priority.
+//
+
+void
+omni_thread::set_priority(priority_t pri)
+{
+    omni_mutex_lock l(mutex);
+
+    if (_state != STATE_RUNNING)
+       throw omni_thread_invalid();
+
+    _priority = pri;
+
+    THROW_ERRORS(thr_setprio(sol_thread, sol_priority(pri)));
+}
+
+
+//
+// create - construct a new thread object and start it running.  Returns thread
+// object if successful, null pointer if not.
+//
+
+// detached version
+
+omni_thread*
+omni_thread::create(void (*fn)(void*), void* arg, priority_t pri)
+{
+    omni_thread* t = new omni_thread(fn, arg, pri);
+
+    t->start();
+
+    return t;
+}
+
+// undetached version
+
+omni_thread*
+omni_thread::create(void* (*fn)(void*), void* arg, priority_t pri)
+{
+    omni_thread* t = new omni_thread(fn, arg, pri);
+
+    t->start();
+
+    return t;
+}
+
+
+//
+// exit() _must_ lock the mutex even in the case of a detached thread.  This is
+// because a thread may run to completion before the thread that created it has
+// had a chance to get out of start().  By locking the mutex we ensure that the
+// creating thread must have reached the end of start() before we delete the
+// thread object.  Of course, once the call to start() returns, the user can
+// still incorrectly refer to the thread object, but that's their problem.
+//
+
+void
+omni_thread::exit(void* return_value)
+{
+    omni_thread* me = self();
+
+    if (me)
+      {
+       me->mutex.lock();
+
+       me->_state = STATE_TERMINATED;
+
+       me->mutex.unlock();
+
+       DB(cerr << "omni_thread::exit: thread " << me->id() << " detached "
+          << me->detached << " return value " << return_value << endl);
+
+       if (me->detached)
+         delete me;
+      }
+    else
+      {
+       DB(cerr << "omni_thread::exit: called with a non-omnithread. Exit quietly." << endl);
+      }
+
+    thr_exit(return_value);
+}
+
+
+omni_thread*
+omni_thread::self(void)
+{
+    omni_thread* me;
+
+    THROW_ERRORS(thr_getspecific(self_key, (void**)&me));
+
+    if (!me) {
+      // This thread is not created by omni_thread::start because it
+      // doesn't has a class omni_thread instance attached to its key.
+      DB(cerr << "omni_thread::self: called with a non-ominthread. NULL is returned." << endl);
+    }
+
+    return me;
+}
+
+
+void
+omni_thread::yield(void)
+{
+    thr_yield();
+}
+
+
+void
+omni_thread::sleep(unsigned long secs, unsigned long nanosecs)
+{
+    timespec rqts = { secs, nanosecs };
+    timespec remain;
+    while (nanosleep(&rqts, &remain)) {
+      if (errno == EINTR) {
+       rqts.tv_sec  = remain.tv_sec;
+       rqts.tv_nsec = remain.tv_nsec;
+       continue;
+      }
+      else
+       throw omni_thread_fatal(errno);
+    }
+}
+
+
+void
+omni_thread::get_time(unsigned long* abs_sec, unsigned long* abs_nsec,
+                     unsigned long rel_sec, unsigned long rel_nsec)
+{
+    timespec abs;
+    clock_gettime(CLOCK_REALTIME, &abs);
+    abs.tv_nsec += rel_nsec;
+    abs.tv_sec += rel_sec + abs.tv_nsec / 1000000000;
+    abs.tv_nsec = abs.tv_nsec % 1000000000;
+    *abs_sec = abs.tv_sec;
+    *abs_nsec = abs.tv_nsec;
+}
+
+
+int
+omni_thread::sol_priority(priority_t pri)
+{
+    switch (pri) {
+
+    case PRIORITY_LOW:
+       return 0;
+
+    case PRIORITY_NORMAL:
+       return 1;
+
+    case PRIORITY_HIGH:
+       return 2;
+    }
+
+    throw omni_thread_invalid();
+}
+
+
+void
+omni_thread::stacksize(unsigned long sz)
+{
+  stack_size = sz;
+}
+
+unsigned long
+omni_thread::stacksize()
+{
+  return stack_size;
+}
+
+
+//
+// Dummy thread
+//
+
+#error This dummy thread code is not tested. It might work if you're lucky.
+
+class omni_thread_dummy : public omni_thread {
+public:
+  inline omni_thread_dummy() : omni_thread()
+  {
+    _dummy = 1;
+    _state = STATE_RUNNING;
+    sol_thread = thr_self();
+    THROW_ERRORS(thr_setspecific(self_key, (void*)this));
+  }
+  inline ~omni_thread_dummy()
+  {
+    THROW_ERRORS(thr_setspecific(self_key, 0));
+  }
+};
+
+omni_thread*
+omni_thread::create_dummy()
+{
+  if (omni_thread::self())
+    throw omni_thread_invalid();
+
+  return new omni_thread_dummy;
+}
+
+void
+omni_thread::release_dummy()
+{
+  omni_thread* self = omni_thread::self();
+  if (!self || !self->_dummy)
+    throw omni_thread_invalid();
+
+  omni_thread_dummy* dummy = (omni_thread_dummy*)self;
+  delete dummy;
+}
+
+
+#define INSIDE_THREAD_IMPL_CC
+#include "threaddata.cc"
+#undef INSIDE_THREAD_IMPL_CC
diff --git a/gnuradio-core/src/lib/omnithread/threaddata.cc b/gnuradio-core/src/lib/omnithread/threaddata.cc
new file mode 100644 (file)
index 0000000..3d00771
--- /dev/null
@@ -0,0 +1,83 @@
+//                             Package : omnithread
+// omnithread/threaddata.cc    Created : 10/2000 dpg1
+//
+//    Copyright (C) 2000 AT&T Laboratories Cambridge
+//
+//    This file is part of the omnithread library
+//
+//    The omnithread library is free software; you can redistribute it and/or
+//    modify it under the terms of the GNU Library General Public
+//    License as published by the Free Software Foundation; either
+//    version 2 of the License, or (at your option) any later version.
+//
+//    This library is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//    Library General Public License for more details.
+//
+//    You should have received a copy of the GNU Library General Public
+//    License along with this library; if not, write to the Free
+//    Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  
+//    02111-1307, USA
+//
+
+// Implementation of per-thread data
+
+#ifndef INSIDE_THREAD_IMPL_CC
+#error "threaddata.cc must be #included by a thread implementation."
+#endif
+
+
+static omni_thread::key_t allocated_keys = 0;
+
+omni_thread::key_t
+omni_thread::allocate_key()
+{
+  omni_mutex_lock l(*next_id_mutex);
+  return ++allocated_keys;
+}
+
+omni_thread::value_t*
+omni_thread::set_value(key_t k, value_t* v)
+{
+  if (k == 0) return 0;
+  if (k > _value_alloc) {
+    next_id_mutex->lock();
+    key_t alloc = allocated_keys;
+    next_id_mutex->unlock();
+
+    if (k > alloc) return 0;
+
+    value_t** nv = new value_t*[alloc];
+    key_t i = 0;
+    if (_values) {
+      for (; i < _value_alloc; i++)
+       nv[i] = _values[i];
+      delete [] _values;
+    }
+    for (; i < alloc; i++)
+      nv[i] = 0;
+
+    _values = nv;
+    _value_alloc = alloc;
+  }
+  if (_values[k-1]) delete _values[k-1];
+  _values[k-1] = v;
+  return v;
+}
+
+omni_thread::value_t*
+omni_thread::get_value(key_t k)
+{
+  if (k > _value_alloc) return 0;
+  return _values[k-1];
+}
+
+omni_thread::value_t*
+omni_thread::remove_value(key_t k)
+{
+  if (k > _value_alloc) return 0;
+  value_t* v = _values[k-1];
+  _values[k-1] = 0;
+  return v;
+}
diff --git a/gnuradio-core/src/lib/omnithread/vxWorks.cc b/gnuradio-core/src/lib/omnithread/vxWorks.cc
new file mode 100644 (file)
index 0000000..25634ce
--- /dev/null
@@ -0,0 +1,1160 @@
+//////////////////////////////////////////////////////////////////////////////
+// Filename:    vxWorks.cc
+// Author:             Tihomir Sokcevic
+//                                     Acterna, Eningen.
+// Description: vxWorks adaptation of the omnithread wrapper classes
+// Notes:               Munching strategy is imperative
+//////////////////////////////////////////////////////////////////////////////
+// $Log$
+// Revision 1.1  2004/04/10 18:00:52  eb
+// Initial revision
+//
+// Revision 1.1.1.1  2004/03/01 00:20:27  eb
+// initial checkin
+//
+// Revision 1.1  2003/05/25 05:29:04  eb
+// see ChangeLog
+//
+// Revision 1.1.2.1  2003/02/17 02:03:11  dgrisby
+// vxWorks port. (Thanks Michael Sturm / Acterna Eningen GmbH).
+//
+// Revision 1.1.1.1  2002/11/19 14:58:04  sokcevti
+// OmniOrb4.0.0 VxWorks port
+//
+// Revision 1.4  2002/10/15 07:54:09  kuttlest
+// change semaphore from SEM_FIFO to SEM_PRIO
+// ---
+//
+// Revision 1.3  2002/07/05 07:38:52  engeln
+// made priority redefinable on load time by defining int variables
+//     omni_thread_prio_low = 220;
+//     omni_thread_prio_normal = 110;
+//     omni_thread_prio_high = 55;
+// the default priority is prio_normal.
+// The normal priority default has been increased from 200 to 110 and the
+//     high priority from 100 to 55.
+// ---
+//
+// Revision 1.2  2002/06/14 12:44:57  engeln
+// replaced possibly unsafe wakeup procedure in broadcast.
+// ---
+//
+// Revision 1.1.1.1  2002/04/02 10:09:34  sokcevti
+// omniORB4 initial realease
+//
+// Revision 1.0        2001/10/23 14:22:45     sokcevti
+// Initial Version 4.00
+// ---
+//
+//////////////////////////////////////////////////////////////////////////////
+
+
+//////////////////////////////////////////////////////////////////////////////
+// Include files
+//////////////////////////////////////////////////////////////////////////////
+#include <stdlib.h>
+#include <stdio.h>
+#include <errno.h>
+#include <time.h>
+#include <omnithread.h>
+#include <sysLib.h>
+
+#include <assert.h>            // assert
+#include <intLib.h>            // intContext
+
+
+//////////////////////////////////////////////////////////////////////////////
+// Local defines
+//////////////////////////////////////////////////////////////////////////////
+#define ERRNO(x) (((x) != 0) ? (errno) : 0)
+#define THROW_ERRORS(x) { if((x) != OK) throw omni_thread_fatal(errno); }
+#define OMNI_THREAD_ID 0x7F7155AAl
+#define OMNI_STACK_SIZE 32768l
+
+#ifdef _DEBUG
+       #include <fstream>
+       #define DBG_TRACE(X) X
+#else // _DEBUG
+       #define DBG_TRACE(X)
+#endif // _DEBUG
+
+#define DBG_ASSERT(X)
+
+#define DBG_THROW(X) X
+
+int omni_thread_prio_low = 220;
+int omni_thread_prio_normal = 110;
+int omni_thread_prio_high = 55;
+///////////////////////////////////////////////////////////////////////////
+//
+// Mutex
+//
+///////////////////////////////////////////////////////////////////////////
+omni_mutex::omni_mutex(void):m_bConstructed(false)
+{
+       mutexID = semMCreate(SEM_Q_PRIORITY | SEM_INVERSION_SAFE);
+
+       DBG_ASSERT(assert(mutexID != NULL));
+
+       if(mutexID==NULL)
+       {
+               DBG_TRACE(cout<<"Exception: omni_mutex::omni_mutex()  tid: "<<(int)taskIdSelf()<<endl);
+               DBG_THROW(throw omni_thread_fatal(-1));
+       }
+
+       m_bConstructed = true;
+}
+
+omni_mutex::~omni_mutex(void)
+{
+       m_bConstructed = false;
+
+       STATUS status = semDelete(mutexID);
+
+       DBG_ASSERT(assert(status == OK));
+
+       if(status != OK)
+       {
+               DBG_TRACE(cout<<"Exception: omni_mutex::~omni_mutex()  mutexID: "<<(int)mutexID<<" tid: "<<(int)taskIdSelf()<<endl);
+               DBG_THROW(throw omni_thread_fatal(errno));
+       }
+}
+
+/*
+void omni_mutex::lock(void)
+{
+       DBG_ASSERT(assert(!intContext()));              // not in ISR context
+       DBG_ASSERT(assert(m_bConstructed));
+
+       STATUS status = semTake(mutexID, WAIT_FOREVER);
+
+       DBG_ASSERT(assert(status == OK));
+
+       if(status != OK)
+       {
+               DBG_TRACE(cout<<"Exception: omni_mutex::lock()  mutexID: "<<(int)mutexID<<" tid: "<<(int)taskIdSelf()<<endl);
+               DBG_THROW(throw omni_thread_fatal(errno));
+       }
+}
+
+void omni_mutex::unlock(void)
+{
+       DBG_ASSERT(assert(m_bConstructed));
+
+       STATUS status = semGive(mutexID);
+
+       DBG_ASSERT(assert(status == OK));
+
+       if(status != OK)
+       {
+               DBG_TRACE(cout<<"Exception: omni_mutex::unlock()  mutexID: "<<(int)mutexID<<" tid: "<<(int)taskIdSelf()<<endl);
+               DBG_THROW(throw omni_thread_fatal(errno));
+       }
+}
+*/
+
+///////////////////////////////////////////////////////////////////////////
+//
+// Condition variable
+//
+///////////////////////////////////////////////////////////////////////////
+omni_condition::omni_condition(omni_mutex* m) : mutex(m)
+{
+       DBG_TRACE(cout<<"omni_condition::omni_condition  mutexID: "<<(int)mutex->mutexID<<" tid:"<<(int)taskIdSelf()<<endl);
+
+       waiters_ = 0;
+
+       sema_ = semCCreate(SEM_Q_PRIORITY, 0);
+       if(sema_ == NULL)
+       {
+               DBG_TRACE(cout<<"Exception: omni_condition::omni_condition()  tid: "<<(int)taskIdSelf()<<endl);
+               DBG_THROW(throw omni_thread_fatal(errno));
+       }
+
+       waiters_lock_ = semMCreate(SEM_Q_PRIORITY | SEM_INVERSION_SAFE);
+       if(waiters_lock_ == NULL)
+       {
+               DBG_TRACE(cout<<"Exception: omni_condition::omni_condition()  tid: "<<(int)taskIdSelf()<<endl);
+               DBG_THROW(throw omni_thread_fatal(errno));
+       }
+
+}
+
+omni_condition::~omni_condition(void)
+{
+       STATUS status = semDelete(waiters_lock_);
+
+       DBG_ASSERT(assert(status == OK));
+
+       if(status != OK)
+       {
+               DBG_TRACE(cout<<"Exception: omni_condition::~omni_condition"<<endl);
+               DBG_THROW(throw omni_thread_fatal(errno));
+       }
+
+       status = semDelete(sema_);
+
+       DBG_ASSERT(assert(status == OK));
+
+       if(status != OK)
+       {
+               DBG_TRACE(cout<<"Exception: omni_condition::~omni_condition"<<endl);
+               DBG_THROW(throw omni_thread_fatal(errno));
+       }
+}
+
+void omni_condition::wait(void)
+{
+       DBG_TRACE(cout<<"omni_condition::wait            mutexID: "<<(int)mutex->mutexID<<" tid:"<<(int)taskIdSelf()<<endl);
+
+       // Prevent race conditions on the <waiters_> count.
+
+       STATUS status = semTake(waiters_lock_,WAIT_FOREVER);
+
+       DBG_ASSERT(assert(status == OK));
+
+       if(status != OK)
+       {
+               DBG_TRACE(cout<<"Exception: omni_condition::wait"<<endl);
+               DBG_THROW(throw omni_thread_fatal(errno));
+       }
+
+       ++waiters_;
+
+       status = semGive(waiters_lock_);
+
+       DBG_ASSERT(assert(status == OK));
+
+       if(status != OK)
+       {
+               DBG_TRACE(cout<<"Exception: omni_condition::wait"<<endl);
+               DBG_THROW(throw omni_thread_fatal(errno));
+       }
+
+       // disable task lock to have an atomic unlock+semTake
+       taskLock();
+
+       // We keep the lock held just long enough to increment the count of
+       // waiters by one.      Note that we can't keep it held across the call
+       // to wait() since that will deadlock other calls to signal().
+       mutex->unlock();
+
+       // Wait to be awakened by a cond_signal() or cond_broadcast().
+       status = semTake(sema_,WAIT_FOREVER);
+
+       // reenable task rescheduling
+       taskUnlock();
+
+       DBG_ASSERT(assert(status == OK));
+
+       if(status != OK)
+       {
+               DBG_TRACE(cout<<"Exception: omni_condition::wait"<<endl);
+               DBG_THROW(throw omni_thread_fatal(errno));
+       }
+
+       // Reacquire lock to avoid race conditions on the <waiters_> count.
+       status = semTake(waiters_lock_,WAIT_FOREVER);
+
+       DBG_ASSERT(assert(status == OK));
+
+       if(status != OK)
+       {
+               DBG_TRACE(cout<<"Exception: omni_condition::wait"<<endl);
+               DBG_THROW(throw omni_thread_fatal(errno));
+       }
+
+       // We're ready to return, so there's one less waiter.
+       --waiters_;
+
+       // Release the lock so that other collaborating threads can make
+       // progress.
+       status = semGive(waiters_lock_);
+
+       DBG_ASSERT(assert(status == OK));
+
+       if(status != OK)
+       {
+               DBG_TRACE(cout<<"Exception: omni_condition::wait"<<endl);
+               DBG_THROW(throw omni_thread_fatal(errno));
+       }
+
+       // Bad things happened, so let's just return below.
+
+       // We must always regain the <external_mutex>, even when errors
+       // occur because that's the guarantee that we give to our callers.
+       mutex->lock();
+}
+
+
+// The time given is absolute. Return 0 is timeout
+int omni_condition::timedwait(unsigned long secs, unsigned long nanosecs)
+{
+       STATUS result = OK;
+       timespec now;
+       unsigned long timeout;
+       int ticks;
+
+       // Prevent race conditions on the <waiters_> count.
+       STATUS status = semTake(waiters_lock_, WAIT_FOREVER);
+
+       DBG_ASSERT(assert(status == OK));
+
+       if(status != OK)
+       {
+               DBG_TRACE(cout<<"Exception: omni_condition::timedwait"<<endl);
+               DBG_THROW(throw omni_thread_fatal(errno));
+       }
+
+       ++waiters_;
+
+       status = semGive(waiters_lock_);
+
+       DBG_ASSERT(assert(status == OK));
+
+       if(status != OK)
+       {
+               DBG_TRACE(cout<<"Exception: omni_condition::timedwait"<<endl);
+               DBG_THROW(throw omni_thread_fatal(errno));
+       }
+
+       clock_gettime(CLOCK_REALTIME, &now);
+
+       if(((unsigned long)secs <= (unsigned long)now.tv_sec) &&
+               (((unsigned long)secs < (unsigned long)now.tv_sec) ||
+               (nanosecs < (unsigned long)now.tv_nsec)))
+               timeout = 0;
+       else
+               timeout = (secs-now.tv_sec) * 1000 + (nanosecs-now.tv_nsec) / 1000000l;
+
+       // disable task lock to have an atomic unlock+semTake
+       taskLock();
+
+       // We keep the lock held just long enough to increment the count
+       // of waiters by one.
+       mutex->unlock();
+
+       // Wait to be awakened by a signal() or broadcast().
+       ticks = (timeout * sysClkRateGet()) / 1000L;
+       result = semTake(sema_, ticks);
+
+       // reenable task rescheduling
+       taskUnlock();
+
+       // Reacquire lock to avoid race conditions.
+       status = semTake(waiters_lock_, WAIT_FOREVER);
+
+       DBG_ASSERT(assert(status == OK));
+
+       if(status != OK)
+       {
+               DBG_TRACE(cout<<"Exception: omni_condition::timedwait"<<endl);
+               DBG_THROW(throw omni_thread_fatal(errno));
+       }
+
+       --waiters_;
+
+       status = semGive(waiters_lock_);
+
+       DBG_ASSERT(assert(status == OK));
+
+       if(status != OK)
+       {
+               DBG_TRACE(cout<<"Exception: omni_condition::timedwait"<<endl);
+               DBG_THROW(throw omni_thread_fatal(errno));
+       }
+
+       // A timeout has occured - fires exception if the origin is other than timeout
+       if(result!=OK && !(errno == S_objLib_OBJ_TIMEOUT || errno == S_objLib_OBJ_UNAVAILABLE))
+       {
+               DBG_TRACE(cout<<"omni_condition::timedwait! - thread:"<<omni_thread::self()->id()<<" SemID:"<<(int)sema_<<" errno:"<<errno<<endl);
+               DBG_THROW(throw omni_thread_fatal(errno));
+       }
+
+       // We must always regain the <external_mutex>, even when errors
+       // occur because that's the guarantee that we give to our callers.
+       mutex->lock();
+
+       if(result!=OK) // timeout
+               return 0;
+
+       return 1;
+}
+
+void omni_condition::signal(void)
+{
+       DBG_TRACE(cout<<"omni_condition::signal          mutexID: "<<(int)mutex->mutexID<<" tid:"<<(int)taskIdSelf()<<endl);
+
+       STATUS status = semTake(waiters_lock_, WAIT_FOREVER);
+
+       DBG_ASSERT(assert(status == OK));
+
+       if(status != OK)
+       {
+               DBG_TRACE(cout<<"Exception: omni_condition::signal"<<endl);
+               DBG_THROW(throw omni_thread_fatal(errno));
+       }
+
+       int have_waiters = waiters_ > 0;
+
+       status = semGive(waiters_lock_);
+
+       DBG_ASSERT(assert(status == OK));
+
+       if(status != OK)
+       {
+               DBG_TRACE(cout<<"Exception: omni_condition::signal"<<endl);
+               DBG_THROW(throw omni_thread_fatal(errno));
+       }
+
+       if(have_waiters != 0)
+       {
+               status = semGive(sema_);
+
+               DBG_ASSERT(assert(status == OK));
+
+               if(status != OK)
+               {
+                       DBG_TRACE(cout<<"Exception: omni_condition::signal"<<endl);
+                       DBG_THROW(throw omni_thread_fatal(errno));
+               }
+       }
+}
+
+void omni_condition::broadcast(void)
+{
+       DBG_TRACE(cout<<"omni_condition::broadcast       mutexID: "<<(int)mutex->mutexID<<" tid:"<<(int)taskIdSelf()<<endl);
+
+       int have_waiters = 0;
+
+       // The <external_mutex> must be locked before this call is made.
+       // This is needed to ensure that <waiters_> and <was_broadcast_> are
+       // consistent relative to each other.
+       STATUS status = semTake(waiters_lock_, WAIT_FOREVER);
+
+       DBG_ASSERT(assert(status == OK));
+
+       if(status != OK)
+       {
+               DBG_TRACE(cout<<"Exception: omni_condition::signal"<<endl);
+               DBG_THROW(throw omni_thread_fatal(errno));
+       }
+
+       if(waiters_ > 0)
+       {
+               // We are broadcasting, even if there is just one waiter...
+               // Record the fact that we are broadcasting.    This helps the
+               // cond_wait() method know how to optimize itself.      Be sure to
+               // set this with the <waiters_lock_> held.
+               have_waiters = 1;
+       }
+
+       status = semGive(waiters_lock_);
+
+       DBG_ASSERT(assert(status == OK));
+
+       if(status != OK)
+       {
+               DBG_TRACE(cout<<"Exception: omni_condition::signal"<<endl);
+               DBG_THROW(throw omni_thread_fatal(errno));
+       }
+
+       if(have_waiters)
+       {
+               // Wake up all the waiters.
+               status = semFlush(sema_);
+
+                       DBG_ASSERT(assert(status == OK));
+
+                       if(status != OK)
+                       {
+                               DBG_TRACE(cout<<"omni_condition::broadcast1! - thread:"<<omni_thread::self()->id()<<" SemID:"<<(int)sema_<<" errno:"<<errno<<endl);
+                               DBG_THROW(throw omni_thread_fatal(errno));
+                       }
+
+       }
+}
+
+
+///////////////////////////////////////////////////////////////////////////
+//
+// Counting semaphore
+//
+///////////////////////////////////////////////////////////////////////////
+omni_semaphore::omni_semaphore(unsigned int initial)
+{
+
+       DBG_ASSERT(assert(0 <= (int)initial));          // POSIX expects only unsigned init values
+
+       semID = semCCreate(SEM_Q_PRIORITY, (int)initial);
+
+       DBG_ASSERT(assert(semID!=NULL));
+
+       if(semID==NULL)
+       {
+               DBG_TRACE(cout<<"Exception: omni_semaphore::omni_semaphore"<<endl);
+               DBG_THROW(throw omni_thread_fatal(-1));
+       }
+}
+
+omni_semaphore::~omni_semaphore(void)
+{
+       STATUS status = semDelete(semID);
+
+       DBG_ASSERT(assert(status == OK));
+
+       if(status != OK)
+       {
+               DBG_TRACE(cout<<"Exception: omni_semaphore::~omni_semaphore"<<endl);
+               DBG_THROW(throw omni_thread_fatal(errno));
+       }
+}
+
+void omni_semaphore::wait(void)
+{
+       DBG_ASSERT(assert(!intContext()));              // no wait in ISR
+
+       STATUS status = semTake(semID, WAIT_FOREVER);
+
+       DBG_ASSERT(assert(status == OK));
+
+       if(status != OK)
+       {
+               DBG_TRACE(cout<<"Exception: omni_semaphore::wait"<<endl);
+               DBG_THROW(throw omni_thread_fatal(errno));
+       }
+}
+
+int omni_semaphore::trywait(void)
+{
+       STATUS status = semTake(semID, NO_WAIT);
+
+       DBG_ASSERT(assert(status == OK));
+
+       if(status != OK)
+       {
+               if(errno == S_objLib_OBJ_UNAVAILABLE)
+               {
+                       return 0;
+               }
+               else
+               {
+                       DBG_ASSERT(assert(false));
+
+                       DBG_TRACE(cout<<"Exception: omni_semaphore::trywait"<<endl);
+                       DBG_THROW(throw omni_thread_fatal(errno));
+               }
+       }
+
+       return 1;
+}
+
+void omni_semaphore::post(void)
+{
+       STATUS status = semGive(semID);
+
+       DBG_ASSERT(assert(status == OK));
+
+       if(status != OK)
+       {
+               DBG_TRACE(cout<<"Exception: omni_semaphore::post"<<endl);
+               DBG_THROW(throw omni_thread_fatal(errno));
+       }
+}
+
+
+
+///////////////////////////////////////////////////////////////////////////
+//
+// Thread
+//
+///////////////////////////////////////////////////////////////////////////
+
+
+//
+// static variables
+//
+omni_mutex* omni_thread::next_id_mutex = 0;
+int omni_thread::next_id = 0;
+
+// omniORB requires a larger stack size than the default (21120) on OSF/1
+static size_t stack_size = OMNI_STACK_SIZE;
+
+
+//
+// Initialisation function (gets called before any user code).
+//
+
+static int& count() {
+  static int the_count = 0;
+  return the_count;
+}
+
+omni_thread::init_t::init_t(void)
+{
+       // Only do it once however many objects get created.
+       if(count()++ != 0)
+               return;
+
+       attach();
+}
+
+omni_thread::init_t::~init_t(void)
+{
+    if (--count() != 0) return;
+
+    omni_thread* self = omni_thread::self();
+    if (!self) return;
+
+    taskTcb(taskIdSelf())->spare1 = 0;
+    delete self;
+
+    delete next_id_mutex;
+}
+
+
+//
+// Wrapper for thread creation.
+//
+extern "C" void omni_thread_wrapper(void* ptr)
+{
+       omni_thread* me = (omni_thread*)ptr;
+
+       DBG_TRACE(cout<<"omni_thread_wrapper: thread "<<me->id()<<" started\n");
+
+       //
+       // We can now tweaked the task info since the tcb exist now
+       //
+       me->mutex.lock();       // To ensure that start has had time to finish
+       taskTcb(me->tid)->spare1 = OMNI_THREAD_ID;
+       taskTcb(me->tid)->spare2 = (int)ptr;
+       me->mutex.unlock();
+
+       //
+       // Now invoke the thread function with the given argument.
+       //
+       if(me->fn_void != NULL)
+       {
+               (*me->fn_void)(me->thread_arg);
+               omni_thread::exit();
+       }
+
+       if(me->fn_ret != NULL)
+       {
+               void* return_value = (*me->fn_ret)(me->thread_arg);
+               omni_thread::exit(return_value);
+       }
+
+       if(me->detached)
+       {
+               me->run(me->thread_arg);
+               omni_thread::exit();
+       }
+       else
+       {
+               void* return_value = me->run_undetached(me->thread_arg);
+               omni_thread::exit(return_value);
+       }
+}
+
+
+//
+// Special functions for VxWorks only
+//
+void omni_thread::attach(void)
+{
+       DBG_TRACE(cout<<"omni_thread_attach: VxWorks mapping thread initialising\n");
+
+       int _tid = taskIdSelf();
+
+       // Check the task is not already attached
+       if(taskTcb(_tid)->spare1 == OMNI_THREAD_ID)
+               return;
+
+       // Create the mutex required to lock the threads debugging id (create before the thread!!!)
+       if(next_id_mutex == 0)
+               next_id_mutex = new omni_mutex;
+
+       // Create a thread object for THIS running process
+       omni_thread* t = new omni_thread;
+
+       // Lock its mutex straigh away!
+       omni_mutex_lock l(t->mutex);
+
+       // Adjust data members of this instance
+       t->_state = STATE_RUNNING;
+       t->tid = taskIdSelf();
+
+       // Set the thread values so it can be recongnised as a omni_thread
+       // Set the id last can possibly prevent race condition
+       taskTcb(t->tid)->spare2 = (int)t;
+       taskTcb(t->tid)->spare1 = OMNI_THREAD_ID;
+
+       // Create the running_mutex at this stage, but leave it empty. We are not running
+       //      in the task context HERE, so taking it would be disastrous.
+       t->running_cond = new omni_condition(&t->mutex);
+}
+
+
+void omni_thread::detach(void)
+{
+       DBG_TRACE(cout<<"omni_thread_detach: VxWorks detaching thread mapping\n");
+
+       int _tid = taskIdSelf();
+
+       // Check the task has a OMNI_THREAD attached
+       if(taskTcb(_tid)->spare1 != OMNI_THREAD_ID)
+               return;
+
+       // Invalidate the id NOW !
+       taskTcb(_tid)->spare1 = 0;
+
+       // Even if NULL, it is safe to delete the thread
+       omni_thread* t = (omni_thread*)taskTcb(_tid)->spare2;
+       // Fininsh cleaning the tcb structure
+       taskTcb(_tid)->spare2 = 0;
+
+       delete t;
+}
+
+
+//
+// Constructors for omni_thread - set up the thread object but don't
+// start it running.
+//
+
+// construct a detached thread running a given function.
+omni_thread::omni_thread(void (*fn)(void*), void* arg, priority_t pri)
+{
+       common_constructor(arg, pri, 1);
+       fn_void = fn;
+       fn_ret = NULL;
+}
+
+// construct an undetached thread running a given function.
+omni_thread::omni_thread(void* (*fn)(void*), void* arg, priority_t pri)
+{
+       common_constructor(arg, pri, 0);
+       fn_void = NULL;
+       fn_ret = fn;
+}
+
+// construct a thread which will run either run() or run_undetached().
+
+omni_thread::omni_thread(void* arg, priority_t pri)
+{
+       common_constructor(arg, pri, 1);
+       fn_void = NULL;
+       fn_ret = NULL;
+}
+
+// common part of all constructors.
+void omni_thread::common_constructor(void* arg, priority_t pri, int det)
+{
+       _state = STATE_NEW;
+       _priority = pri;
+
+       // Set the debugging id
+       next_id_mutex->lock();
+       _id = next_id++;
+       next_id_mutex->unlock();
+
+       // Note : tid can only be setup when the task is up and running
+       tid = 0;
+
+       thread_arg = arg;
+       detached = det;         // may be altered in start_undetached()
+
+    _dummy       = 0;
+    _values      = 0;
+    _value_alloc = 0;
+}
+
+//
+// Destructor for omni_thread.
+//
+omni_thread::~omni_thread(void)
+{
+       DBG_TRACE(cout<<"omni_thread::~omni_thread for thread "<<id()<<endl);
+
+    if (_values) {
+        for (key_t i=0; i < _value_alloc; i++) {
+           if (_values[i]) {
+               delete _values[i];
+           }
+        }
+       delete [] _values;
+    }
+
+       delete running_cond;
+}
+
+
+//
+// Start the thread
+//
+void omni_thread::start(void)
+{
+       omni_mutex_lock l(mutex);
+
+       DBG_ASSERT(assert(_state == STATE_NEW));
+
+       if(_state != STATE_NEW)
+               DBG_THROW(throw omni_thread_invalid());
+
+       // Allocate memory for the task. (The returned id cannot be trusted by the task)
+       tid = taskSpawn(
+               NULL,                                                            // Task name
+               vxworks_priority(_priority),    // Priority
+               0,                                                                       // Option
+               stack_size,                                              // Stack size
+               (FUNCPTR)omni_thread_wrapper, // Priority
+               (int)this,                                                      // First argument is this
+               0,0,0,0,0,0,0,0,0                                // Remaining unused args
+               );
+
+       DBG_ASSERT(assert(tid!=ERROR));
+
+       if(tid==ERROR)
+               DBG_THROW(throw omni_thread_invalid());
+
+       _state = STATE_RUNNING;
+
+       // Create the running_mutex at this stage, but leave it empty. We are not running
+       //      in the task context HERE, so taking it would be disastrous.
+       running_cond = new omni_condition(&mutex);
+}
+
+
+//
+// Start a thread which will run the member function run_undetached().
+//
+void omni_thread::start_undetached(void)
+{
+       DBG_ASSERT(assert(!((fn_void != NULL) || (fn_ret != NULL))));
+
+       if((fn_void != NULL) || (fn_ret != NULL))
+               DBG_THROW(throw omni_thread_invalid());
+
+       detached = 0;
+
+       start();
+}
+
+
+//
+// join - Wait for the task to complete before returning to the calling process
+//
+void omni_thread::join(void** status)
+{
+       mutex.lock();
+
+       if((_state != STATE_RUNNING) && (_state != STATE_TERMINATED))
+       {
+               mutex.unlock();
+
+               DBG_ASSERT(assert(false));
+
+               DBG_THROW(throw omni_thread_invalid());
+       }
+
+       mutex.unlock();
+
+       DBG_ASSERT(assert(this != self()));
+
+       if(this == self())
+               DBG_THROW(throw omni_thread_invalid());
+
+       DBG_ASSERT(assert(!detached));
+
+       if(detached)
+               DBG_THROW(throw omni_thread_invalid());
+
+       mutex.lock();
+       running_cond->wait();
+       mutex.unlock();
+
+       if(status)
+               *status = return_val;
+
+       delete this;
+}
+
+
+//
+// Change this thread's priority.
+//
+void omni_thread::set_priority(priority_t pri)
+{
+       omni_mutex_lock l(mutex);
+
+       DBG_ASSERT(assert(_state == STATE_RUNNING));
+
+       if(_state != STATE_RUNNING)
+       {
+               DBG_THROW(throw omni_thread_invalid());
+       }
+
+       _priority = pri;
+
+       if(taskPrioritySet(tid, vxworks_priority(pri))==ERROR)
+       {
+               DBG_ASSERT(assert(false));
+
+               DBG_THROW(throw omni_thread_fatal(errno));
+       }
+}
+
+
+//
+// create - construct a new thread object and start it running.        Returns thread
+// object if successful, null pointer if not.
+//
+
+// detached version (the entry point is a void)
+omni_thread* omni_thread::create(void (*fn)(void*), void* arg, priority_t pri)
+{
+       omni_thread* t = new omni_thread(fn, arg, pri);
+
+       t->start();
+
+       return t;
+}
+
+// undetached version (the entry point is a void*)
+omni_thread* omni_thread::create(void* (*fn)(void*), void* arg, priority_t pri)
+{
+       omni_thread* t = new omni_thread(fn, arg, pri);
+
+       t->start();
+
+       return t;
+}
+
+
+//
+// exit() _must_ lock the mutex even in the case of a detached thread. This is
+// because a thread may run to completion before the thread that created it has
+// had a chance to get out of start(). By locking the mutex we ensure that the
+// creating thread must have reached the end of start() before we delete the
+// thread object.      Of course, once the call to start() returns, the user can
+// still incorrectly refer to the thread object, but that's their problem.
+//
+void omni_thread::exit(void* return_value)
+{
+       omni_thread* me = self();
+
+       if(me)
+       {
+               me->mutex.lock();
+
+               me->return_val = return_value;
+               me->_state = STATE_TERMINATED;
+               me->running_cond->signal();
+
+               me->mutex.unlock();
+
+               DBG_TRACE(cout<<"omni_thread::exit: thread "<<me->id()<<" detached "<<me->detached<<" return value "<<(int)return_value<<endl);
+
+               if(me->detached)
+                       delete me;
+       }
+       else
+               DBG_TRACE(cout<<"omni_thread::exit: called with a non-omnithread. Exit quietly."<<endl);
+
+       taskDelete(taskIdSelf());
+}
+
+
+omni_thread* omni_thread::self(void)
+{
+       if(taskTcb(taskIdSelf())->spare1 != OMNI_THREAD_ID)
+               return NULL;
+
+       return (omni_thread*)taskTcb(taskIdSelf())->spare2;
+}
+
+
+void omni_thread::yield(void)
+{
+       taskDelay(NO_WAIT);
+}
+
+
+void omni_thread::sleep(unsigned long secs, unsigned long nanosecs)
+{
+       int tps = sysClkRateGet();
+
+       // Convert to us to avoid overflow in the multiplication
+       //      tps should always be less than 1000 !
+       nanosecs /= 1000;
+
+       taskDelay(secs*tps + (nanosecs*tps)/1000000l);
+}
+
+
+void omni_thread::get_time( unsigned long* abs_sec,
+                                                       unsigned long* abs_nsec,
+                                                       unsigned long rel_sec,
+                                                       unsigned long rel_nsec)
+{
+       timespec abs;
+       clock_gettime(CLOCK_REALTIME, &abs);
+       abs.tv_nsec += rel_nsec;
+       abs.tv_sec += rel_sec + abs.tv_nsec / 1000000000;
+       abs.tv_nsec = abs.tv_nsec % 1000000000;
+       *abs_sec = abs.tv_sec;
+       *abs_nsec = abs.tv_nsec;
+}
+
+
+int omni_thread::vxworks_priority(priority_t pri)
+{
+       switch (pri)
+       {
+       case PRIORITY_LOW:
+               return omni_thread_prio_low;
+
+       case PRIORITY_NORMAL:
+               return omni_thread_prio_normal;
+
+       case PRIORITY_HIGH:
+               return omni_thread_prio_high;
+       }
+
+       DBG_ASSERT(assert(false));
+
+       DBG_THROW(throw omni_thread_invalid());
+}
+
+
+void omni_thread::stacksize(unsigned long sz)
+{
+       stack_size = sz;
+}
+
+
+unsigned long omni_thread::stacksize()
+{
+       return stack_size;
+}
+
+
+void omni_thread::show(void)
+{
+       omni_thread *pThread;
+       int s1, s2;
+       int tid = taskIdSelf();
+
+       printf("TaskId is %.8x\n", tid);
+
+       s1 = taskTcb(tid)->spare1;
+
+       if(s1 != OMNI_THREAD_ID)
+       {
+               printf("Spare 1 is %.8x, and not recongnized\n", s1);
+
+               return;
+       }
+       else
+       {
+               printf("Spare 1 indicate an omni_thread.\n");
+       }
+
+       s2 = taskTcb(tid)->spare2;
+
+       if(s2 == 0)
+       {
+               printf("Spare 2 is NULL! - No thread object attached !!\n");
+
+               return;
+       }
+       else
+       {
+               printf("Thread object at %.8x\n", s2);
+       }
+
+       pThread = (omni_thread *)s2;
+
+       state_t status = pThread->_state;
+
+       printf("        | Thread status is ");
+
+       switch (status)
+       {
+       case STATE_NEW:
+               printf("NEW\n");                break;
+       case STATE_RUNNING:
+               printf("STATE_RUNNING\n"); break;
+       case STATE_TERMINATED:
+               printf("TERMINATED\n"); break;
+       default:
+               printf("Illegal (=%.8x)\n", (unsigned int)status);
+
+               return;
+       }
+
+       if(pThread->tid != tid)
+       {
+               printf("        | Task ID in thread object is different!! (=%.8x)\n", pThread->tid);
+
+               return;
+       }
+       else
+       {
+               printf("        | Task ID in thread consistent\n");
+       }
+
+       printf("\n");
+}
+
+
+//
+// Dummy thread
+//
+
+class omni_thread_dummy : public omni_thread {
+public:
+  inline omni_thread_dummy() : omni_thread()
+  {
+    _dummy = 1;
+    _state = STATE_RUNNING;
+
+       // Adjust data members of this instance
+       tid = taskIdSelf();
+
+       // Set the thread values so it can be recongnised as a omni_thread
+       // Set the id last can possibly prevent race condition
+       taskTcb(tid)->spare2 = (int)this;
+       taskTcb(tid)->spare1 = OMNI_THREAD_ID;
+   }
+  inline ~omni_thread_dummy()
+  {
+       taskTcb(taskIdSelf())->spare1 = 0;
+  }
+};
+
+omni_thread*
+omni_thread::create_dummy()
+{
+  if (omni_thread::self())
+    throw omni_thread_invalid();
+
+  return new omni_thread_dummy;
+}
+
+void
+omni_thread::release_dummy()
+{
+  omni_thread* self = omni_thread::self();
+  if (!self || !self->_dummy)
+    throw omni_thread_invalid();
+
+  omni_thread_dummy* dummy = (omni_thread_dummy*)self;
+  delete dummy;
+}
+
+
+#define INSIDE_THREAD_IMPL_CC
+#include "threaddata.cc"
+#undef INSIDE_THREAD_IMPL_CC
diff --git a/gnuradio-core/src/lib/reed-solomon/Makefile.am b/gnuradio-core/src/lib/reed-solomon/Makefile.am
new file mode 100644 (file)
index 0000000..71af766
--- /dev/null
@@ -0,0 +1,55 @@
+#
+# 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 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.
+# 
+
+include $(top_srcdir)/Makefile.common
+
+# Note, this Makefile.am only builds the char versions of the reed soloman routines.
+# If you need the int versions too, please figure out how to add them *cleanly* to 
+# this Makefile.am.
+
+INCLUDES = $(STD_DEFINES_AND_INCLUDES) $(CPPUNIT_INCLUDES)
+
+TESTS = rstest
+
+EXTRA_DIST =                   \
+       README.karn
+
+noinst_LTLIBRARIES = librs.la
+
+noinst_PROGRAMS =              \
+       rstest
+
+librs_la_SOURCES =             \
+       encode_rs.c             \
+       decode_rs.c             \
+       init_rs.c
+
+grinclude_HEADERS =            \
+       rs.h
+
+noinst_HEADERS =               \
+       ccsds.h                 \
+       char.h                  \
+       int.h                   \
+       fixed.h                 
+
+rstest_SOURCES =       rstest.c exercise.c
+rstest_LDADD =         librs.la
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/README b/gnuradio-core/src/lib/reed-solomon/README
new file mode 100644 (file)
index 0000000..341832d
--- /dev/null
@@ -0,0 +1,5 @@
+This code is from http://people.qualcomm.com/karn/code/fec
+It is based on reed-soloman-3.1.1 (1 Jan 2002).
+
+I has been converted to use automake, to better integrate with GNU
+Radio's build strategy.
diff --git a/gnuradio-core/src/lib/reed-solomon/README.karn b/gnuradio-core/src/lib/reed-solomon/README.karn
new file mode 100644 (file)
index 0000000..f30644f
--- /dev/null
@@ -0,0 +1,22 @@
+This package implements a general purpose Reed-Solomon encoding and decoding
+facility. See the rs.3 man page for details.
+
+To install, simply do the following after extracting this tarball into
+an empty directory:
+
+./configure
+make
+make install
+
+The command "make test" runs a battery of encode/decode tests using a
+variety of RS codes using random data and random errors. Each test
+should pass with an "OK"; if any fail, please let me know so I can
+track down the problem.
+
+Phil Karn (karn@ka9q.net) 1 Jan 2002
+
+Copyright 2002, Phil Karn, KA9Q
+This software may be used under the terms of the GNU General Public License (GPL).
+
+
+
diff --git a/gnuradio-core/src/lib/reed-solomon/ccsds.h b/gnuradio-core/src/lib/reed-solomon/ccsds.h
new file mode 100644 (file)
index 0000000..0f2bde6
--- /dev/null
@@ -0,0 +1 @@
+extern unsigned char Taltab[],Tal1tab[];
diff --git a/gnuradio-core/src/lib/reed-solomon/char.h b/gnuradio-core/src/lib/reed-solomon/char.h
new file mode 100644 (file)
index 0000000..2fbcb50
--- /dev/null
@@ -0,0 +1,56 @@
+/* Include file to configure the RS codec for character symbols
+ *
+ * Copyright 2002, Phil Karn, KA9Q
+ * May be used under the terms of the GNU General Public License (GPL)
+ */
+
+#define DTYPE unsigned char
+
+/* Reed-Solomon codec control block */
+struct rs {
+  unsigned int mm;              /* Bits per symbol */
+  unsigned int nn;              /* Symbols per block (= (1<<mm)-1) */
+  unsigned char *alpha_to;      /* log lookup table */
+  unsigned char *index_of;      /* Antilog lookup table */
+  unsigned char *genpoly;       /* Generator polynomial */
+  unsigned int nroots;     /* Number of generator roots = number of parity symbols */
+  unsigned char fcr;        /* First consecutive root, index form */
+  unsigned char prim;       /* Primitive element, index form */
+  unsigned char iprim;      /* prim-th root of 1, index form */
+};
+
+static inline int modnn(struct rs *rs,int x){
+  while (x >= rs->nn) {
+    x -= rs->nn;
+    x = (x >> rs->mm) + (x & rs->nn);
+  }
+  return x;
+}
+#define MODNN(x) modnn(rs,x)
+
+#define MM (rs->mm)
+#define NN (rs->nn)
+#define ALPHA_TO (rs->alpha_to) 
+#define INDEX_OF (rs->index_of)
+#define GENPOLY (rs->genpoly)
+#define NROOTS (rs->nroots)
+#define FCR (rs->fcr)
+#define PRIM (rs->prim)
+#define IPRIM (rs->iprim)
+#define A0 (NN)
+
+#define ENCODE_RS encode_rs_char
+#define DECODE_RS decode_rs_char
+#define INIT_RS init_rs_char
+#define FREE_RS free_rs_char
+
+void ENCODE_RS(void *p,DTYPE *data,DTYPE *parity);
+int DECODE_RS(void *p,DTYPE *data,int *eras_pos,int no_eras);
+void *INIT_RS(unsigned int symsize,unsigned int gfpoly,unsigned int fcr,
+                  unsigned int prim,unsigned int nroots);
+void FREE_RS(void *p);
+
+
+
+
+
diff --git a/gnuradio-core/src/lib/reed-solomon/decode_rs.c b/gnuradio-core/src/lib/reed-solomon/decode_rs.c
new file mode 100644 (file)
index 0000000..ca40978
--- /dev/null
@@ -0,0 +1,262 @@
+/* Reed-Solomon decoder
+ * Copyright 2002 Phil Karn, KA9Q
+ * May be used under the terms of the GNU General Public License (GPL)
+ */
+
+#ifdef DEBUG
+#include <stdio.h>
+#endif
+
+#include <string.h>
+
+#define NULL ((void *)0)
+#define        min(a,b)        ((a) < (b) ? (a) : (b))
+
+#ifdef FIXED
+#include "fixed.h"
+#elif defined(BIGSYM)
+#include "int.h"
+#else
+#include "char.h"
+#endif
+
+int DECODE_RS(
+#ifndef FIXED
+void *p,
+#endif
+DTYPE *data, int *eras_pos, int no_eras){
+
+#ifndef FIXED
+  struct rs *rs = (struct rs *)p;
+#endif
+  int deg_lambda, el, deg_omega;
+  int i, j, r,k;
+  DTYPE u,q,tmp,num1,num2,den,discr_r;
+  DTYPE lambda[NROOTS+1], s[NROOTS];   /* Err+Eras Locator poly
+                                        * and syndrome poly */
+  DTYPE b[NROOTS+1], t[NROOTS+1], omega[NROOTS+1];
+  DTYPE root[NROOTS], reg[NROOTS+1], loc[NROOTS];
+  int syn_error, count;
+
+  /* form the syndromes; i.e., evaluate data(x) at roots of g(x) */
+  for(i=0;i<NROOTS;i++)
+    s[i] = data[0];
+
+  for(j=1;j<NN;j++){
+    for(i=0;i<NROOTS;i++){
+      if(s[i] == 0){
+       s[i] = data[j];
+      } else {
+       s[i] = data[j] ^ ALPHA_TO[MODNN(INDEX_OF[s[i]] + (FCR+i)*PRIM)];
+      }
+    }
+  }
+
+  /* Convert syndromes to index form, checking for nonzero condition */
+  syn_error = 0;
+  for(i=0;i<NROOTS;i++){
+    syn_error |= s[i];
+    s[i] = INDEX_OF[s[i]];
+  }
+
+  if (!syn_error) {
+    /* if syndrome is zero, data[] is a codeword and there are no
+     * errors to correct. So return data[] unmodified
+     */
+    count = 0;
+    goto finish;
+  }
+  memset(&lambda[1],0,NROOTS*sizeof(lambda[0]));
+  lambda[0] = 1;
+
+  if (no_eras > 0) {
+    /* Init lambda to be the erasure locator polynomial */
+    lambda[1] = ALPHA_TO[MODNN(PRIM*(NN-1-eras_pos[0]))];
+    for (i = 1; i < no_eras; i++) {
+      u = MODNN(PRIM*(NN-1-eras_pos[i]));
+      for (j = i+1; j > 0; j--) {
+       tmp = INDEX_OF[lambda[j - 1]];
+       if(tmp != A0)
+         lambda[j] ^= ALPHA_TO[MODNN(u + tmp)];
+      }
+    }
+
+#if DEBUG >= 1
+    /* Test code that verifies the erasure locator polynomial just constructed
+       Needed only for decoder debugging. */
+    
+    /* find roots of the erasure location polynomial */
+    for(i=1;i<=no_eras;i++)
+      reg[i] = INDEX_OF[lambda[i]];
+
+    count = 0;
+    for (i = 1,k=IPRIM-1; i <= NN; i++,k = MODNN(k+IPRIM)) {
+      q = 1;
+      for (j = 1; j <= no_eras; j++)
+       if (reg[j] != A0) {
+         reg[j] = MODNN(reg[j] + j);
+         q ^= ALPHA_TO[reg[j]];
+       }
+      if (q != 0)
+       continue;
+      /* store root and error location number indices */
+      root[count] = i;
+      loc[count] = k;
+      count++;
+    }
+    if (count != no_eras) {
+      printf("count = %d no_eras = %d\n lambda(x) is WRONG\n",count,no_eras);
+      count = -1;
+      goto finish;
+    }
+#if DEBUG >= 2
+    printf("\n Erasure positions as determined by roots of Eras Loc Poly:\n");
+    for (i = 0; i < count; i++)
+      printf("%d ", loc[i]);
+    printf("\n");
+#endif
+#endif
+  }
+  for(i=0;i<NROOTS+1;i++)
+    b[i] = INDEX_OF[lambda[i]];
+  
+  /*
+   * Begin Berlekamp-Massey algorithm to determine error+erasure
+   * locator polynomial
+   */
+  r = no_eras;
+  el = no_eras;
+  while (++r <= NROOTS) {      /* r is the step number */
+    /* Compute discrepancy at the r-th step in poly-form */
+    discr_r = 0;
+    for (i = 0; i < r; i++){
+      if ((lambda[i] != 0) && (s[r-i-1] != A0)) {
+       discr_r ^= ALPHA_TO[MODNN(INDEX_OF[lambda[i]] + s[r-i-1])];
+      }
+    }
+    discr_r = INDEX_OF[discr_r];       /* Index form */
+    if (discr_r == A0) {
+      /* 2 lines below: B(x) <-- x*B(x) */
+      memmove(&b[1],b,NROOTS*sizeof(b[0]));
+      b[0] = A0;
+    } else {
+      /* 7 lines below: T(x) <-- lambda(x) - discr_r*x*b(x) */
+      t[0] = lambda[0];
+      for (i = 0 ; i < NROOTS; i++) {
+       if(b[i] != A0)
+         t[i+1] = lambda[i+1] ^ ALPHA_TO[MODNN(discr_r + b[i])];
+       else
+         t[i+1] = lambda[i+1];
+      }
+      if (2 * el <= r + no_eras - 1) {
+       el = r + no_eras - el;
+       /*
+        * 2 lines below: B(x) <-- inv(discr_r) *
+        * lambda(x)
+        */
+       for (i = 0; i <= NROOTS; i++)
+         b[i] = (lambda[i] == 0) ? A0 : MODNN(INDEX_OF[lambda[i]] - discr_r + NN);
+      } else {
+       /* 2 lines below: B(x) <-- x*B(x) */
+       memmove(&b[1],b,NROOTS*sizeof(b[0]));
+       b[0] = A0;
+      }
+      memcpy(lambda,t,(NROOTS+1)*sizeof(t[0]));
+    }
+  }
+
+  /* Convert lambda to index form and compute deg(lambda(x)) */
+  deg_lambda = 0;
+  for(i=0;i<NROOTS+1;i++){
+    lambda[i] = INDEX_OF[lambda[i]];
+    if(lambda[i] != A0)
+      deg_lambda = i;
+  }
+  /* Find roots of the error+erasure locator polynomial by Chien search */
+  memcpy(&reg[1],&lambda[1],NROOTS*sizeof(reg[0]));
+  count = 0;           /* Number of roots of lambda(x) */
+  for (i = 1,k=IPRIM-1; i <= NN; i++,k = MODNN(k+IPRIM)) {
+    q = 1; /* lambda[0] is always 0 */
+    for (j = deg_lambda; j > 0; j--){
+      if (reg[j] != A0) {
+       reg[j] = MODNN(reg[j] + j);
+       q ^= ALPHA_TO[reg[j]];
+      }
+    }
+    if (q != 0)
+      continue; /* Not a root */
+    /* store root (index-form) and error location number */
+#if DEBUG>=2
+    printf("count %d root %d loc %d\n",count,i,k);
+#endif
+    root[count] = i;
+    loc[count] = k;
+    /* If we've already found max possible roots,
+     * abort the search to save time
+     */
+    if(++count == deg_lambda)
+      break;
+  }
+  if (deg_lambda != count) {
+    /*
+     * deg(lambda) unequal to number of roots => uncorrectable
+     * error detected
+     */
+    count = -1;
+    goto finish;
+  }
+  /*
+   * Compute err+eras evaluator poly omega(x) = s(x)*lambda(x) (modulo
+   * x**NROOTS). in index form. Also find deg(omega).
+   */
+  deg_omega = 0;
+  for (i = 0; i < NROOTS;i++){
+    tmp = 0;
+    j = (deg_lambda < i) ? deg_lambda : i;
+    for(;j >= 0; j--){
+      if ((s[i - j] != A0) && (lambda[j] != A0))
+       tmp ^= ALPHA_TO[MODNN(s[i - j] + lambda[j])];
+    }
+    if(tmp != 0)
+      deg_omega = i;
+    omega[i] = INDEX_OF[tmp];
+  }
+  omega[NROOTS] = A0;
+  
+  /*
+   * Compute error values in poly-form. num1 = omega(inv(X(l))), num2 =
+   * inv(X(l))**(FCR-1) and den = lambda_pr(inv(X(l))) all in poly-form
+   */
+  for (j = count-1; j >=0; j--) {
+    num1 = 0;
+    for (i = deg_omega; i >= 0; i--) {
+      if (omega[i] != A0)
+       num1  ^= ALPHA_TO[MODNN(omega[i] + i * root[j])];
+    }
+    num2 = ALPHA_TO[MODNN(root[j] * (FCR - 1) + NN)];
+    den = 0;
+    
+    /* lambda[i+1] for i even is the formal derivative lambda_pr of lambda[i] */
+    for (i = min(deg_lambda,NROOTS-1) & ~1; i >= 0; i -=2) {
+      if(lambda[i+1] != A0)
+       den ^= ALPHA_TO[MODNN(lambda[i+1] + i * root[j])];
+    }
+    if (den == 0) {
+#if DEBUG >= 1
+      printf("\n ERROR: denominator = 0\n");
+#endif
+      count = -1;
+      goto finish;
+    }
+    /* Apply error to data */
+    if (num1 != 0) {
+      data[loc[j]] ^= ALPHA_TO[MODNN(INDEX_OF[num1] + INDEX_OF[num2] + NN - INDEX_OF[den])];
+    }
+  }
+ finish:
+  if(eras_pos != NULL){
+    for(i=0;i<count;i++)
+      eras_pos[i] = loc[i];
+  }
+  return count;
+}
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.c b/gnuradio-core/src/lib/reed-solomon/encode_rs.c
new file mode 100644 (file)
index 0000000..9d56d0b
--- /dev/null
@@ -0,0 +1,47 @@
+/* Reed-Solomon encoder
+ * Copyright 2002, Phil Karn, KA9Q
+ * May be used under the terms of the GNU General Public License (GPL)
+ */
+#include <string.h>
+
+#ifdef FIXED
+#include "fixed.h"
+#elif defined(BIGSYM)
+#include "int.h"
+#else
+#include "char.h"
+#endif
+
+void ENCODE_RS(
+#ifndef FIXED
+void *p,
+#endif
+DTYPE *data, DTYPE *bb){
+#ifndef FIXED
+  struct rs *rs = (struct rs *)p;
+#endif
+  int i, j;
+  DTYPE feedback;
+
+  memset(bb,0,NROOTS*sizeof(DTYPE));
+
+  for(i=0;i<NN-NROOTS;i++){
+    feedback = INDEX_OF[data[i] ^ bb[0]];
+    if(feedback != A0){      /* feedback term is non-zero */
+#ifdef UNNORMALIZED
+      /* This line is unnecessary when GENPOLY[NROOTS] is unity, as it must
+       * always be for the polynomials constructed by init_rs()
+       */
+      feedback = MODNN(NN - GENPOLY[NROOTS] + feedback);
+#endif
+      for(j=1;j<NROOTS;j++)
+       bb[j] ^= ALPHA_TO[MODNN(feedback + GENPOLY[NROOTS-j])];
+    }
+    /* Shift */
+    memmove(&bb[0],&bb[1],sizeof(DTYPE)*(NROOTS-1));
+    if(feedback != A0)
+      bb[NROOTS-1] = ALPHA_TO[MODNN(feedback + GENPOLY[0])];
+    else
+      bb[NROOTS-1] = 0;
+  }
+}
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/exercise.c b/gnuradio-core/src/lib/reed-solomon/exercise.c
new file mode 100644 (file)
index 0000000..91d43e1
--- /dev/null
@@ -0,0 +1,126 @@
+/* Exercise an RS codec a specified number of times using random
+ * data and error patterns
+ *
+ * Copyright 2002 Phil Karn, KA9Q
+ * May be used under the terms of the GNU General Public License (GPL)
+ */
+#define FLAG_ERASURE 1 /* Randomly flag 50% of errors as erasures */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifdef FIXED
+#include "fixed.h"
+#define EXERCISE exercise_8
+#elif defined(CCSDS)
+#include "fixed.h"
+#include "ccsds.h"
+#define EXERCISE exercise_ccsds
+#elif defined(BIGSYM)
+#include "int.h"
+#define EXERCISE exercise_int
+#else
+#include "char.h"
+#define EXERCISE exercise_char
+#endif
+
+#ifdef FIXED
+#define PRINTPARM printf("(255,223):");
+#elif defined(CCSDS)
+#define PRINTPARM printf("CCSDS (255,223):");
+#else
+#define PRINTPARM printf("(%d,%d):",rs->nn,rs->nn-rs->nroots);
+#endif
+
+/* Exercise the RS codec passed as an argument */
+int EXERCISE(
+#if !defined(CCSDS) && !defined(FIXED)
+void *p,
+#endif
+int trials){
+#if !defined(CCSDS) && !defined(FIXED)
+  struct rs *rs = (struct rs *)p;
+#endif
+  DTYPE block[NN],tblock[NN];
+  int i;
+  int errors;
+  int errlocs[NN];
+  int derrlocs[NROOTS];
+  int derrors;
+  int errval,errloc;
+  int erasures;
+  int decoder_errors = 0;
+
+  while(trials-- != 0){
+    /* Test up to the error correction capacity of the code */
+    for(errors=0;errors <= NROOTS/2;errors++){
+
+      /* Load block with random data and encode */
+      for(i=0;i<NN-NROOTS;i++)
+       block[i] = random() & NN;
+      
+#if defined(CCSDS) || defined(FIXED)
+      ENCODE_RS(&block[0],&block[NN-NROOTS]);
+#else
+      ENCODE_RS(rs,&block[0],&block[NN-NROOTS]);
+#endif
+
+      /* Make temp copy, seed with errors */
+      memcpy(tblock,block,sizeof(tblock));
+      memset(errlocs,0,sizeof(errlocs));
+      memset(derrlocs,0,sizeof(derrlocs));
+      erasures=0;
+      for(i=0;i<errors;i++){
+       do {
+         errval = random() & NN;
+       } while(errval == 0); /* Error value must be nonzero */
+
+       do {
+         errloc = random() % NN;
+       } while(errlocs[errloc] != 0); /* Must not choose the same location twice */
+
+       errlocs[errloc] = 1;
+
+#if FLAG_ERASURE
+       if(random() & 1) /* 50-50 chance */
+         derrlocs[erasures++] = errloc;
+#endif
+       tblock[errloc] ^= errval;
+      }
+
+      /* Decode the errored block */
+#if defined(CCSDS) || defined(FIXED)
+      derrors = DECODE_RS(tblock,derrlocs,erasures);
+#else
+      derrors = DECODE_RS(rs,tblock,derrlocs,erasures);
+#endif
+
+      if(derrors != errors){
+       PRINTPARM
+       printf(" decoder says %d errors, true number is %d\n",derrors,errors);
+       decoder_errors++;
+      }
+      for(i=0;i<derrors;i++){
+       if(errlocs[derrlocs[i]] == 0){
+         PRINTPARM
+         printf(" decoder indicates error in location %d without error\n",i);
+         decoder_errors++;
+       }
+      }
+      if(memcmp(tblock,block,sizeof(tblock)) != 0){
+       PRINTPARM
+       printf(" uncorrected errors! output ^ input:");
+       decoder_errors++;
+       for(i=0;i<NN;i++)
+         printf(" %02x",tblock[i] ^ block[i]);
+       printf("\n");
+      }
+    }
+  }
+  return decoder_errors;
+}
diff --git a/gnuradio-core/src/lib/reed-solomon/fixed.h b/gnuradio-core/src/lib/reed-solomon/fixed.h
new file mode 100644 (file)
index 0000000..9f0ddd9
--- /dev/null
@@ -0,0 +1,38 @@
+/* Configure the RS codec with fixed parameters for CCSDS standard
+ * (255,223) code over GF(256). Note: the conventional basis is still
+ * used; the dual-basis mappings are performed in [en|de]code_rs_ccsds.c
+ *
+ * Copyright 2002 Phil Karn, KA9Q
+ * May be used under the terms of the GNU General Public License (GPL)
+ */
+#define DTYPE unsigned char
+
+static inline int mod255(int x){
+  while (x >= 255) {
+    x -= 255;
+    x = (x >> 8) + (x & 255);
+  }
+  return x;
+}
+#define MODNN(x) mod255(x)
+
+extern unsigned char CCSDS_alpha_to[];
+extern unsigned char CCSDS_index_of[];
+extern unsigned char CCSDS_poly[];
+
+#define MM 8
+#define NN 255
+#define ALPHA_TO CCSDS_alpha_to
+#define INDEX_OF CCSDS_index_of
+#define GENPOLY CCSDS_poly
+#define NROOTS 32
+#define FCR 112
+#define PRIM 11
+#define IPRIM 116
+#define A0 (NN)
+
+#define ENCODE_RS encode_rs_8
+#define DECODE_RS decode_rs_8
+
+void ENCODE_RS(DTYPE *data,DTYPE *parity);
+int DECODE_RS(DTYPE *data, int *eras_pos, int no_eras);
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/init_rs.c b/gnuradio-core/src/lib/reed-solomon/init_rs.c
new file mode 100644 (file)
index 0000000..11d7c81
--- /dev/null
@@ -0,0 +1,128 @@
+/* Initialize a RS codec
+ *
+ * Copyright 2002 Phil Karn, KA9Q
+ * May be used under the terms of the GNU General Public License (GPL)
+ */
+#include <stdlib.h>
+
+#ifdef CCSDS
+#include "ccsds.h"
+#elif defined(BIGSYM)
+#include "int.h"
+#else
+#include "char.h"
+#endif
+
+#define NULL ((void *)0)
+
+void FREE_RS(void *p){
+  struct rs *rs = (struct rs *)p;
+
+  free(rs->alpha_to);
+  free(rs->index_of);
+  free(rs->genpoly);
+  free(rs);
+}
+
+/* Initialize a Reed-Solomon codec
+ * symsize = symbol size, bits (1-8)
+ * gfpoly = Field generator polynomial coefficients
+ * fcr = first root of RS code generator polynomial, index form
+ * prim = primitive element to generate polynomial roots
+ * nroots = RS code generator polynomial degree (number of roots)
+ */
+void *INIT_RS(unsigned int symsize,unsigned int gfpoly,unsigned fcr,unsigned prim,
+               unsigned int nroots){
+  struct rs *rs;
+  int i, j, sr,root,iprim;
+
+  if(symsize > 8*sizeof(DTYPE))
+    return NULL; /* Need version with ints rather than chars */
+
+  if(fcr >= (1<<symsize))
+    return NULL;
+  if(prim == 0 || prim >= (1<<symsize))
+    return NULL;
+  if(nroots >= (1<<symsize))
+    return NULL; /* Can't have more roots than symbol values! */
+
+  rs = (struct rs *)calloc(1,sizeof(struct rs));
+  rs->mm = symsize;
+  rs->nn = (1<<symsize)-1;
+
+  rs->alpha_to = (DTYPE *)malloc(sizeof(DTYPE)*(rs->nn+1));
+  if(rs->alpha_to == NULL){
+    free(rs);
+    return NULL;
+  }
+  rs->index_of = (DTYPE *)malloc(sizeof(DTYPE)*(rs->nn+1));
+  if(rs->index_of == NULL){
+    free(rs->alpha_to);
+    free(rs);
+    return NULL;
+  }
+
+  /* Generate Galois field lookup tables */
+  rs->index_of[0] = A0; /* log(zero) = -inf */
+  rs->alpha_to[A0] = 0; /* alpha**-inf = 0 */
+  sr = 1;
+  for(i=0;i<rs->nn;i++){
+    rs->index_of[sr] = i;
+    rs->alpha_to[i] = sr;
+    sr <<= 1;
+    if(sr & (1<<symsize))
+      sr ^= gfpoly;
+    sr &= rs->nn;
+  }
+  if(sr != 1){
+    /* field generator polynomial is not primitive! */
+    free(rs->alpha_to);
+    free(rs->index_of);
+    free(rs);
+    return NULL;
+  }
+
+  /* Form RS code generator polynomial from its roots */
+  rs->genpoly = (DTYPE *)malloc(sizeof(DTYPE)*(nroots+1));
+  if(rs->genpoly == NULL){
+    free(rs->alpha_to);
+    free(rs->index_of);
+    free(rs);
+    return NULL;
+  }
+  rs->fcr = fcr;
+  rs->prim = prim;
+  rs->nroots = nroots;
+
+  /* Find prim-th root of 1, used in decoding */
+  for(iprim=1;(iprim % prim) != 0;iprim += rs->nn)
+    ;
+  rs->iprim = iprim / prim;
+
+  rs->genpoly[0] = 1;
+  for (i = 0,root=fcr*prim; i < nroots; i++,root += prim) {
+    rs->genpoly[i+1] = 1;
+
+    /* Multiply rs->genpoly[] by  @**(root + x) */
+    for (j = i; j > 0; j--){
+      if (rs->genpoly[j] != 0)
+       rs->genpoly[j] = rs->genpoly[j-1] ^ rs->alpha_to[modnn(rs,rs->index_of[rs->genpoly[j]] + root)];
+      else
+       rs->genpoly[j] = rs->genpoly[j-1];
+    }
+    /* rs->genpoly[0] can never be zero */
+    rs->genpoly[0] = rs->alpha_to[modnn(rs,rs->index_of[rs->genpoly[0]] + root)];
+  }
+  /* convert rs->genpoly[] to index form for quicker encoding */
+  for (i = 0; i <= nroots; i++)
+    rs->genpoly[i] = rs->index_of[rs->genpoly[i]];
+
+#if 0
+  printf ("genpoly:\n");
+  for (i = nroots; i >= 0; i--){
+    printf ("  %3d*X^%d\n", rs->alpha_to[rs->genpoly[i]], i);
+  }
+#endif
+
+  return rs;
+}
diff --git a/gnuradio-core/src/lib/reed-solomon/int.h b/gnuradio-core/src/lib/reed-solomon/int.h
new file mode 100644 (file)
index 0000000..2b0405a
--- /dev/null
@@ -0,0 +1,54 @@
+/* Include file to configure the RS codec for integer symbols
+ *
+ * Copyright 2002, Phil Karn, KA9Q
+ * May be used under the terms of the GNU General Public License (GPL)
+ */
+#define DTYPE int
+
+/* Reed-Solomon codec control block */
+struct rs {
+  unsigned int mm;   /* Bits per symbol */
+  unsigned int nn;   /* Symbols per block (= (1<<mm)-1) */
+  int *alpha_to;      /* log lookup table */
+  int *index_of;      /* Antilog lookup table */
+  int *genpoly;       /* Generator polynomial */
+  unsigned int nroots;     /* Number of generator roots = number of parity symbols */
+  unsigned int fcr;        /* First consecutive root, index form */
+  unsigned int prim;       /* Primitive element, index form */
+  unsigned int iprim;      /* prim-th root of 1, index form */
+};
+
+static inline int modnn(struct rs *rs,int x){
+  while (x >= rs->nn) {
+    x -= rs->nn;
+    x = (x >> rs->mm) + (x & rs->nn);
+  }
+  return x;
+}
+#define MODNN(x) modnn(rs,x)
+
+#define MM (rs->mm)
+#define NN (rs->nn)
+#define ALPHA_TO (rs->alpha_to) 
+#define INDEX_OF (rs->index_of)
+#define GENPOLY (rs->genpoly)
+#define NROOTS (rs->nroots)
+#define FCR (rs->fcr)
+#define PRIM (rs->prim)
+#define IPRIM (rs->iprim)
+#define A0 (NN)
+
+#define ENCODE_RS encode_rs_int
+#define DECODE_RS decode_rs_int
+#define INIT_RS init_rs_int
+#define FREE_RS free_rs_int
+
+void ENCODE_RS(void *p,DTYPE *data,DTYPE *parity);
+int DECODE_RS(void *p,DTYPE *data,int *eras_pos,int no_eras);
+void *INIT_RS(unsigned int symsize,unsigned int gfpoly,unsigned int fcr,
+                  unsigned int prim,unsigned int nroots);
+void FREE_RS(void *p);
+
+
+
+
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/reed-solomon/rs.h b/gnuradio-core/src/lib/reed-solomon/rs.h
new file mode 100644 (file)
index 0000000..9e731d9
--- /dev/null
@@ -0,0 +1,30 @@
+/* User include file for the Reed-Solomon codec
+ * Copyright 2002, Phil Karn KA9Q
+ * May be used under the terms of the GNU General Public License (GPL)
+ */
+
+/* General purpose RS codec, 8-bit symbols */
+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 *init_rs_char(unsigned int symsize,unsigned int gfpoly,
+                  unsigned int fcr,unsigned int prim,unsigned int nroots);
+void free_rs_char(void *rs);
+
+/* General purpose RS codec, integer symbols */
+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 *init_rs_int(unsigned int symsize,unsigned int gfpoly,unsigned int fcr,
+                 unsigned int prim,unsigned int nroots);
+void free_rs_int(void *rs);
+
+/* CCSDS standard (255,223) RS codec with conventional (*not* dual-basis)
+ * symbol representation
+ */
+void encode_rs_8(unsigned char *data,unsigned char *parity);
+int decode_rs_8(unsigned char *data,int *eras_pos,int no_eras);
+
+/* Tables to map from conventional->dual (Taltab) and
+ * dual->conventional (Tal1tab) bases
+ */
+extern unsigned char Taltab[],Tal1tab[];
diff --git a/gnuradio-core/src/lib/reed-solomon/rstest.c b/gnuradio-core/src/lib/reed-solomon/rstest.c
new file mode 100644 (file)
index 0000000..d8fc544
--- /dev/null
@@ -0,0 +1,117 @@
+/* Test the Reed-Solomon codecs
+ * for various block sizes and with random data and random error patterns
+ *
+ * Copyright 2002 Phil Karn, KA9Q
+ * May be used under the terms of the GNU General Public License (GPL)
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include "rs.h"
+
+int exercise_char(void *,int);
+
+#ifdef ALL_VERSIONS
+int exercise_int(void *,int);
+int exercise_8(int);
+int exercise_ccsds(int);
+#endif
+
+struct {
+  int symsize;
+  int genpoly;
+  int fcs;
+  int prim;
+  int nroots;
+  int ntrials;
+} Tab[] = {
+  {2, 0x7,     1,   1, 1, 10 },
+  {3, 0xb,     1,   1, 2, 10 },
+  {4, 0x13,    1,   1, 4, 10 },
+  {5, 0x25,    1,   1, 6, 10 },
+  {6, 0x43,    1,   1, 8, 10 },
+  {7, 0x89,    1,   1, 10, 10 },
+  {8, 0x11d,   1,   1, 32, 10 },
+  {8, 0x187,   112,11, 32, 10 }, /* Duplicates CCSDS codec */
+#ifdef ALL_VESIONS
+  {9, 0x211,   1,   1, 32, 10 },
+  {10,0x409,   1,   1, 32, 10 },
+  {11,0x805,   1,   1, 32, 10 },
+  {12,0x1053,  1,   1, 32, 5 },
+  {13,0x201b,  1,   1, 32, 2 },
+  {14,0x4443,  1,   1, 32, 1 },
+  {15,0x8003,  1,   1, 32, 1 },
+  {16,0x1100b, 1,   1, 32, 1 },
+#endif
+  {0, 0, 0, 0, 0},
+};
+
+int main(){
+  void *handle;
+  int errs,terrs;
+  int i;
+
+  terrs = 0;
+  srandom(time(NULL));
+
+#ifdef ALL_VERSIONS
+  printf("Testing fixed (255,223) RS codec...");
+  fflush(stdout);
+  errs = exercise_8(10);
+  terrs += errs;
+  if(errs == 0){
+    printf("OK\n");
+  }
+  printf("Testing CCSDS standard (255,223) RS codec...");
+  fflush(stdout);
+  errs = exercise_ccsds(10);
+  terrs += errs;
+  if(errs == 0){
+    printf("OK\n");
+  }
+#endif
+
+  for(i=0;Tab[i].symsize != 0;i++){
+    int nn,kk;
+
+    nn = (1<<Tab[i].symsize) - 1;
+    kk = nn - Tab[i].nroots;
+    printf("Testing (%d,%d) RS codec...",nn,kk);
+    fflush(stdout);
+    if(Tab[i].symsize <= 8){
+      if((handle = init_rs_char(Tab[i].symsize,Tab[i].genpoly,Tab[i].fcs,Tab[i].prim,Tab[i].nroots)) == NULL){
+       printf("init_rs_char failed!\n");
+       continue;
+      }
+      errs = exercise_char(handle,Tab[i].ntrials);
+    } else {
+#ifdef ALL_VERSIONS
+      if((handle = init_rs_int(Tab[i].symsize,Tab[i].genpoly,Tab[i].fcs,Tab[i].prim,Tab[i].nroots)) == NULL){
+       printf("init_rs_int failed!\n");
+       continue;
+      }
+      errs = exercise_int(handle,Tab[i].ntrials);
+#else
+      printf ("init_rs_init support is not enabled\n");
+      exit (1);
+#endif
+
+    }
+    terrs += errs;
+    if(errs == 0){
+      printf("OK\n");
+    }
+    free_rs_char(handle);
+  }
+  if(terrs == 0)
+    printf("All codec tests passed!\n");
+
+  exit(0);
+}
+
+
diff --git a/gnuradio-core/src/lib/runtime/Makefile.am b/gnuradio-core/src/lib/runtime/Makefile.am
new file mode 100644 (file)
index 0000000..7ee94ba
--- /dev/null
@@ -0,0 +1,109 @@
+#
+# Copyright 2003,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.
+# 
+
+include $(top_srcdir)/Makefile.common
+
+INCLUDES = $(STD_DEFINES_AND_INCLUDES) $(CPPUNIT_INCLUDES)
+
+noinst_LTLIBRARIES = libruntime.la libruntime-qa.la
+
+libruntime_la_LIBADD =         \
+       $(SHM_OPEN_LIBS)
+
+
+libruntime_la_SOURCES =                        \
+       gr_block.cc                             \
+       gr_block_detail.cc                      \
+       gr_buffer.cc                            \
+       gr_dispatcher.cc                        \
+       gr_error_handler.cc                     \
+       gr_io_signature.cc                      \
+       gr_local_sighandler.cc                  \
+       gr_message.cc                           \
+       gr_msg_handler.cc                       \
+       gr_msg_queue.cc                         \
+       gr_pagesize.cc                          \
+       gr_preferences.cc                       \
+       gr_realtime.cc                          \
+       gr_single_threaded_scheduler.cc         \
+       gr_tmp_path.cc                          \
+       gr_vmcircbuf.cc                         \
+       gr_vmcircbuf_mmap_shm_open.cc           \
+       gr_vmcircbuf_mmap_tmpfile.cc            \
+       gr_vmcircbuf_createfilemapping.cc       \
+       gr_vmcircbuf_sysv_shm.cc                \
+       gr_select_handler.cc                    
+
+libruntime_qa_la_SOURCES =                     \
+       qa_gr_block.cc                          \
+       qa_gr_buffer.cc                         \
+       qa_gr_io_signature.cc                   \
+       qa_gr_vmcircbuf.cc                      \
+       qa_runtime.cc                           
+
+grinclude_HEADERS =                            \
+       gr_block.h                              \
+       gr_block_detail.h                       \
+       gr_buffer.h                             \
+       gr_complex.h                            \
+       gr_dispatcher.h                         \
+       gr_error_handler.h                      \
+       gr_io_signature.h                       \
+       gr_local_sighandler.h                   \
+       gr_message.h                            \
+       gr_msg_handler.h                        \
+       gr_msg_queue.h                          \
+       gr_pagesize.h                           \
+       gr_preferences.h                        \
+       gr_realtime.h                           \
+       gr_runtime.h                            \
+       gr_select_handler.h                     \
+       gr_single_threaded_scheduler.h          \
+       gr_timer.h                              \
+       gr_tmp_path.h                           \
+       gr_types.h                              \
+       gr_vmcircbuf.h                          
+
+noinst_HEADERS =                               \
+       gr_vmcircbuf_mmap_shm_open.h            \
+       gr_vmcircbuf_mmap_tmpfile.h             \
+       gr_vmcircbuf_sysv_shm.h                 \
+       gr_vmcircbuf_createfilemapping.h        \
+       qa_gr_block.h                           \
+       qa_gr_buffer.h                          \
+       qa_gr_io_signature.h                    \
+       qa_gr_vmcircbuf.h                       \
+       qa_runtime.h                            
+
+swiginclude_HEADERS =                  \
+       gr_block.i                      \
+       gr_block_detail.i               \
+       gr_buffer.i                     \
+       gr_dispatcher.i                 \
+       gr_error_handler.i              \
+       gr_io_signature.i               \
+       gr_message.i                    \
+       gr_msg_handler.i                \
+       gr_msg_queue.i                  \
+       gr_realtime.i                   \
+       gr_single_threaded_scheduler.i  \
+       gr_swig_block_magic.i           \
+       runtime.i
diff --git a/gnuradio-core/src/lib/runtime/gr_block.cc b/gnuradio-core/src/lib/runtime/gr_block.cc
new file mode 100644 (file)
index 0000000..8378c8f
--- /dev/null
@@ -0,0 +1,131 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_block.h>
+#include <gr_block_detail.h>
+#include <stdexcept>
+
+static long s_next_id = 0;
+static long s_ncurrently_allocated = 0;
+
+long
+gr_block_ncurrently_allocated ()
+{
+  return s_ncurrently_allocated;
+}
+
+gr_block::gr_block (const std::string &name,
+                   gr_io_signature_sptr input_signature,
+                   gr_io_signature_sptr output_signature)
+  : d_name (name),
+    d_input_signature (input_signature),
+    d_output_signature (output_signature),
+    d_output_multiple (1),
+    d_relative_rate (1.0),
+    d_unique_id (s_next_id++),
+    d_history(1),
+    d_fixed_rate(false)
+{
+  s_ncurrently_allocated++;
+}
+  
+gr_block::~gr_block ()
+{
+  s_ncurrently_allocated--;
+}
+
+// stub implementation:  1:1
+
+void
+gr_block::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;
+}
+
+// default implementation
+
+bool
+gr_block::check_topology (int ninputs, int noutputs)
+{
+  return true;
+}
+
+bool
+gr_block::start()
+{
+  return true;
+}
+
+bool
+gr_block::stop()
+{
+  return true;
+}
+
+void
+gr_block::set_output_multiple (int multiple)
+{
+  if (multiple < 1)
+    throw std::invalid_argument ("gr_block::set_output_multiple");
+
+  d_output_multiple = multiple;
+}
+
+void
+gr_block::set_relative_rate (double relative_rate)
+{
+  if (relative_rate < 0.0)
+    throw std::invalid_argument ("gr_block::set_relative_rate");
+  
+  d_relative_rate = relative_rate;
+}
+
+
+void
+gr_block::consume (int which_input, int how_many_items)
+{
+  d_detail->consume (which_input, how_many_items);
+}
+
+void
+gr_block::consume_each (int how_many_items)
+{
+  d_detail->consume_each (how_many_items);
+}
+
+int
+gr_block::fixed_rate_ninput_to_noutput(int ninput)
+{
+  throw std::runtime_error("Unimplemented");
+}
+
+int
+gr_block::fixed_rate_noutput_to_ninput(int noutput)
+{
+  throw std::runtime_error("Unimplemented");
+}
diff --git a/gnuradio-core/src/lib/runtime/gr_block.h b/gnuradio-core/src/lib/runtime/gr_block.h
new file mode 100644 (file)
index 0000000..df72e1a
--- /dev/null
@@ -0,0 +1,247 @@
+/* -*- 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 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.
+ */
+
+#ifndef INCLUDED_GR_BLOCK_H
+#define INCLUDED_GR_BLOCK_H
+
+#include <gr_runtime.h>
+#include <string>
+
+/*!
+ * \brief The abstract base class for all signal processing blocks.
+ * \ingroup block
+ *
+ * Blocks have a set of input streams and output streams.  The
+ * input_signature and output_signature define the number of input
+ * streams and output streams respectively, and the type of the data
+ * items in each stream.
+ *
+ * Although blocks may consume data on each input stream at a
+ * different rate, all outputs streams must produce data at the same
+ * rate.  That rate may be different from any of the input rates.
+ *
+ * User derived blocks override two methods, forecast and general_work,
+ * to implement their signal processing behavior. forecast is called
+ * by the system scheduler to determine how many items are required on
+ * each input stream in order to produce a given number of output
+ * items.
+ *
+ * general_work is called to perform the signal processing in the block.
+ * It reads the input items and writes the output items.
+ */
+
+class gr_block {
+
+ public:
+  
+  virtual ~gr_block ();
+  
+  std::string name () const { return d_name; }
+  gr_io_signature_sptr input_signature () const  { return d_input_signature; }
+  gr_io_signature_sptr output_signature () const { return d_output_signature; }
+  long unique_id () const { return d_unique_id; }
+
+  /*!
+   * Assume block computes y_i = f(x_i, x_i-1, x_i-2, x_i-3...)
+   * History is the number of x_i's that are examined to produce one y_i.
+   * This comes in handy for FIR filters, where we use history to
+   * ensure that our input contains the appropriate "history" for the
+   * filter.   History should be equal to the number of filter taps.
+   */
+  unsigned history () const { return d_history; }
+  void  set_history (unsigned history) { d_history = history; }
+  
+  /*!
+   * \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.
+   */
+  bool fixed_rate() const { return d_fixed_rate; }
+
+  // ----------------------------------------------------------------
+  //           override these to define your behavior
+  // ----------------------------------------------------------------
+
+  /*!
+   * \brief  Estimate input requirements given output request
+   *
+   * \param noutput_items           number of output items to produce
+   * \param ninput_items_required   number of input items required on each input stream
+   *
+   * Given a request to product \p noutput_items, estimate the number of
+   * data items required on each input stream.  The estimate doesn't have
+   * to be exact, but should be close.
+   */
+  virtual void forecast (int noutput_items,
+                        gr_vector_int &ninput_items_required);
+
+  /*!
+   * \brief compute output items from input items
+   *
+   * \param noutput_items      number of output items to write on each output stream
+   * \param ninput_items       number of input items available on each input stream
+   * \param input_items                vector of pointers to the input items, one entry per input stream
+   * \param output_items       vector of pointers to the output items, one entry per output stream
+   *
+   * \returns number of items actually written to each output stream, or -1 on EOF.
+   * It is OK to return a value less than noutput_items.  -1 <= return value <= noutput_items
+   *
+   * general_work must call consume or consume_each to indicate how many items
+   * were consumed on each input stream.
+   */
+  virtual int general_work (int noutput_items,
+                           gr_vector_int &ninput_items,
+                           gr_vector_const_void_star &input_items,
+                           gr_vector_void_star &output_items) = 0;
+
+  /*!
+   * \brief Confirm that ninputs and noutputs is an acceptable combination.
+   *
+   * \param ninputs    number of input streams connected
+   * \param noutputs   number of output streams connected
+   *
+   * \returns true if this is a valid configuration for this block.
+   *
+   * This function is called by the runtime system whenever the
+   * topology changes.  Most classes do not need to override this.
+   * This check is in addition to the constraints specified by the input
+   * and output gr_io_signatures.
+   */
+  virtual bool check_topology (int ninputs, int noutputs);
+
+  /*!
+   * \brief Called to enable drivers, etc for i/o devices.
+   *
+   * This allows a block to enable an associated driver to begin
+   * transfering data just before we start to execute the scheduler.
+   * The end result is that this reduces latency in the pipeline when
+   * dealing with audio devices, usrps, etc.
+   */
+  virtual bool start();
+
+  /*!
+   * \brief Called to disable drivers, etc for i/o devices.
+   */
+  virtual bool stop();
+
+  // ----------------------------------------------------------------
+
+  /*!
+   * \brief Constrain the noutput_items argument passed to forecast and general_work
+   *
+   * set_output_multiple causes the scheduler to ensure that the noutput_items
+   * argument passed to forecast and general_work will be an integer multiple
+   * of \param multiple  The default value of output multiple is 1.
+   */
+  void set_output_multiple (int multiple);
+  int  output_multiple () const { return d_output_multiple; }
+
+  /*!
+   * \brief Tell the scheduler \p how_many_items of input stream \p which_input were consumed.
+   */
+  void consume (int which_input, int how_many_items);
+
+  /*!
+   * \brief Tell the scheduler \p how_many_items were consumed on each input stream.
+   */
+  void consume_each (int how_many_items);
+
+  /*!
+   * \brief Set the approximate output rate / input rate
+   *
+   * Provide a hint to the buffer allocator and scheduler.
+   * The default relative_rate is 1.0
+   *
+   * decimators have relative_rates < 1.0
+   * interpolators have relative_rates > 1.0
+   */
+  void  set_relative_rate (double relative_rate);
+
+  /*!
+   * \brief return the approximate output rate / input rate
+   */
+  double relative_rate () const        { return d_relative_rate; }
+
+  /*
+   * The following two methods provide special case info to the
+   * scheduler in the event that a block has a fixed input to output
+   * ratio.  gr_sync_block, gr_sync_decimator and gr_sync_interpolator
+   * override these.  If you're fixed rate, subclass one of those.
+   */
+  /*!
+   * \brief Given ninput samples, return number of output samples that will be produced.
+   * N.B. this is only defined if fixed_rate returns true.
+   * Generally speaking, you don't need to override this.
+   */
+  virtual int fixed_rate_ninput_to_noutput(int ninput);
+
+  /*!
+   * \brief Given noutput samples, return number of input samples required to produce noutput.
+   * N.B. this is only defined if fixed_rate returns true.
+   * Generally speaking, you don't need to override this.
+   */
+  virtual int fixed_rate_noutput_to_ninput(int noutput);
+
+  // ----------------------------------------------------------------------------
+
+ private:
+
+  std::string          d_name;
+  gr_io_signature_sptr d_input_signature;
+  gr_io_signature_sptr d_output_signature;
+  int                  d_output_multiple;
+  double               d_relative_rate;        // approx output_rate / input_rate
+  gr_block_detail_sptr d_detail;               // implementation details
+  long                 d_unique_id;            // convenient for debugging
+  unsigned             d_history;
+  bool                 d_fixed_rate;
+
+  
+ protected:
+
+  gr_block (const std::string &name,
+           gr_io_signature_sptr input_signature,
+           gr_io_signature_sptr output_signature);
+
+  //! may only be called during constructor
+  void set_input_signature (gr_io_signature_sptr iosig){
+    d_input_signature = iosig;
+  }
+
+  //! may only be called during constructor
+  void set_output_signature (gr_io_signature_sptr iosig){
+    d_output_signature = iosig;
+  }
+
+  void set_fixed_rate(bool fixed_rate){ d_fixed_rate = fixed_rate; }
+
+  // These are really only for internal use, but leaving them public avoids
+  // having to work up an ever-varying list of friends
+
+ public:
+  gr_block_detail_sptr detail () const { return d_detail; }
+  void set_detail (gr_block_detail_sptr detail) { d_detail = detail; }
+};
+
+long gr_block_ncurrently_allocated ();
+
+#endif /* INCLUDED_GR_BLOCK_H */
diff --git a/gnuradio-core/src/lib/runtime/gr_block.i b/gnuradio-core/src/lib/runtime/gr_block.i
new file mode 100644 (file)
index 0000000..f1f0332
--- /dev/null
@@ -0,0 +1,66 @@
+/* -*- 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 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.
+ */
+
+class gr_block;
+typedef boost::shared_ptr<gr_block> gr_block_sptr;
+%template(gr_block_sptr) boost::shared_ptr<gr_block>;
+
+// support vectors of these...
+namespace std {
+  %template(x_vector_gr_block_sptr)    vector<gr_block_sptr>;
+};
+
+class gr_block {
+ protected:
+  gr_block (const std::string &name,
+            gr_io_signature_sptr input_signature,
+            gr_io_signature_sptr output_signature);
+
+ public:
+  
+  virtual ~gr_block ();
+  
+  std::string name () const;
+  gr_io_signature_sptr input_signature () const;
+  gr_io_signature_sptr output_signature () const;
+  long unique_id () const;
+  unsigned history () const;
+
+  int  output_multiple () const;
+  double relative_rate () const;
+
+  bool check_topology (int ninputs, int noutputs);
+  bool start();
+  bool stop();
+
+  // internal use
+  gr_block_detail_sptr detail () const { return d_detail; }
+  void set_detail (gr_block_detail_sptr detail) { d_detail = detail; }
+};
+
+%rename(block_ncurrently_allocated) gr_block_ncurrently_allocated;
+long gr_block_ncurrently_allocated ();
+
+%pythoncode %{
+gr_block_sptr.__repr__ = lambda self: "<gr_block %s (%d)>" % (self.name(), self.unique_id ())
+gr_block_sptr.block = lambda self: self
+%}
diff --git a/gnuradio-core/src/lib/runtime/gr_block_detail.cc b/gnuradio-core/src/lib/runtime/gr_block_detail.cc
new file mode 100644 (file)
index 0000000..0ad5da4
--- /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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_block_detail.h>
+#include <gr_buffer.h>
+
+static long s_ncurrently_allocated = 0;
+
+long
+gr_block_detail_ncurrently_allocated ()
+{
+  return s_ncurrently_allocated;
+}
+
+gr_block_detail::gr_block_detail (unsigned int ninputs, unsigned int noutputs)
+  : d_ninputs (ninputs), d_noutputs (noutputs),
+    d_input (ninputs), d_output (noutputs),
+    d_done (false)
+{
+  s_ncurrently_allocated++;
+}
+
+gr_block_detail::~gr_block_detail ()
+{
+  // should take care of itself
+  s_ncurrently_allocated--;
+}
+
+void
+gr_block_detail::set_input (unsigned int which, gr_buffer_reader_sptr reader)
+{
+  if (which >= d_ninputs)
+    throw std::invalid_argument ("gr_block_detail::set_input");
+
+  d_input[which] = reader;
+}
+
+void
+gr_block_detail::set_output (unsigned int which, gr_buffer_sptr buffer)
+{
+  if (which >= d_noutputs)
+    throw std::invalid_argument ("gr_block_detail::set_output");
+
+  d_output[which] = buffer;
+}
+
+gr_block_detail_sptr
+gr_make_block_detail (unsigned int ninputs, unsigned int noutputs)
+{
+  return gr_block_detail_sptr (new gr_block_detail (ninputs, noutputs));
+}
+
+void
+gr_block_detail::set_done (bool done)
+{
+  d_done = done;
+  for (unsigned int i = 0; i < d_noutputs; i++)
+    d_output[i]->set_done (done);
+
+  for (unsigned int i = 0; i < d_ninputs; i++)
+    d_input[i]->set_done (done);
+}
+
+void 
+gr_block_detail::consume (int which_input, int how_many_items)
+{
+  if (how_many_items > 0)
+    input (which_input)->update_read_pointer (how_many_items);
+}
+
+void
+gr_block_detail::consume_each (int how_many_items)
+{
+  if (how_many_items > 0)
+    for (int i = 0; i < ninputs (); i++)
+      d_input[i]->update_read_pointer (how_many_items);
+}
+
+void
+gr_block_detail::produce_each (int how_many_items)
+{
+  if (how_many_items > 0)
+    for (int i = 0; i < noutputs (); i++)
+      d_output[i]->update_write_pointer (how_many_items);
+}
diff --git a/gnuradio-core/src/lib/runtime/gr_block_detail.h b/gnuradio-core/src/lib/runtime/gr_block_detail.h
new file mode 100644 (file)
index 0000000..90c912c
--- /dev/null
@@ -0,0 +1,99 @@
+/* -*- 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 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 detail.
+ * 
+ * You should have received a 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.
+ */
+
+#ifndef INCLUDED_GR_BLOCK_DETAIL_H
+#define INCLUDED_GR_BLOCK_DETAIL_H
+
+#include <gr_runtime.h>
+#include <stdexcept>
+
+/*!
+ * \brief Implementation details to support the signal processing abstraction
+ * \ingroup internal
+ *
+ * This class contains implementation detail that should be "out of sight"
+ * of almost all users of GNU Radio.  This decoupling also means that
+ * we can make changes to the guts without having to recompile everything.
+ */
+
+class gr_block_detail {
+ public:
+  ~gr_block_detail ();
+
+  int ninputs () const { return d_ninputs; }
+  int noutputs () const { return d_noutputs; }
+  bool sink_p () const { return d_noutputs == 0; }
+  bool source_p () const { return d_ninputs == 0; }
+
+  void set_done (bool done);
+  bool done () const { return d_done; }
+
+  void set_input (unsigned int which, gr_buffer_reader_sptr reader);
+  gr_buffer_reader_sptr input (unsigned int which)
+  {
+    if (which >= d_ninputs)
+      throw std::invalid_argument ("gr_block_detail::input");
+    return d_input[which];
+  }
+
+  void set_output (unsigned int which, gr_buffer_sptr buffer);
+  gr_buffer_sptr output (unsigned int which)
+  {
+    if (which >= d_noutputs)
+      throw std::invalid_argument ("gr_block_detail::output");
+    return d_output[which];
+  }
+
+  /*!
+   * \brief Tell the scheduler \p how_many_items of input stream \p which_input were consumed.
+   */
+  void consume (int which_input, int how_many_items);
+
+  /*!
+   * \brief Tell the scheduler \p how_many_items were consumed on each input stream.
+   */
+  void consume_each (int how_many_items);
+
+  void produce_each (int how_many_items);
+
+  // ----------------------------------------------------------------------------
+
+ private:
+  unsigned int                     d_ninputs;
+  unsigned int                     d_noutputs;
+  std::vector<gr_buffer_reader_sptr> d_input;
+  std::vector<gr_buffer_sptr>      d_output;
+  bool                             d_done;
+    
+  gr_block_detail (unsigned int ninputs, unsigned int noutputs);
+
+  friend gr_block_detail_sptr 
+  gr_make_block_detail (unsigned int ninputs, unsigned int noutputs);
+};
+
+gr_block_detail_sptr
+gr_make_block_detail (unsigned int ninputs, unsigned int noutputs);
+
+long
+gr_block_detail_ncurrently_allocated ();
+
+#endif /* INCLUDED_GR_BLOCK_DETAIL_H */
diff --git a/gnuradio-core/src/lib/runtime/gr_block_detail.i b/gnuradio-core/src/lib/runtime/gr_block_detail.i
new file mode 100644 (file)
index 0000000..9d3843e
--- /dev/null
@@ -0,0 +1,66 @@
+/* -*- 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 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.
+ */
+
+class gr_block_detail;
+typedef boost::shared_ptr<gr_block_detail> gr_block_detail_sptr;
+%template(gr_block_detail_sptr) boost::shared_ptr<gr_block_detail>;
+%rename(block_detail) gr_make_block_detail;
+%ignore gr_block_detail;
+
+gr_block_detail_sptr gr_make_block_detail (unsigned int ninputs, unsigned int noutputs);
+
+class gr_block_detail {
+ public:
+
+  ~gr_block_detail ();
+
+  int ninputs () const { return d_ninputs; }
+  int noutputs () const { return d_noutputs; }
+  bool sink_p () const { return d_noutputs == 0; }
+  bool source_p () const { return d_ninputs == 0; }
+
+  void set_input (unsigned int which, gr_buffer_reader_sptr reader);
+  gr_buffer_reader_sptr input (unsigned int which)
+  {
+    if (which >= d_ninputs)
+      throw std::invalid_argument ("gr_block_detail::input");
+    return d_input[which];
+  }
+
+  void set_output (unsigned int which, gr_buffer_sptr buffer);
+  gr_buffer_sptr output (unsigned int which)
+  {
+    if (which >= d_noutputs)
+      throw std::invalid_argument ("gr_block_detail::output");
+    return d_output[which];
+  }
+
+  // ----------------------------------------------------------------------------
+
+ private:
+  gr_block_detail (unsigned int ninputs, unsigned int noutputs);
+
+};
+
+
+%rename(block_detail_ncurrently_allocated) gr_block_detail_ncurrently_allocated;
+long gr_block_detail_ncurrently_allocated ();
diff --git a/gnuradio-core/src/lib/runtime/gr_buffer.cc b/gnuradio-core/src/lib/runtime/gr_buffer.cc
new file mode 100644 (file)
index 0000000..d3d1230
--- /dev/null
@@ -0,0 +1,248 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_buffer.h>
+#include <gr_vmcircbuf.h>
+#include <gr_math.h>
+#include <stdexcept>
+#include <iostream>
+#include <assert.h>
+#include <algorithm>
+
+static long s_buffer_count = 0;                // counts for debugging storage mgmt
+static long s_buffer_reader_count = 0;
+
+// ----------------------------------------------------------------------------
+//                     Notes on storage management
+//
+// Pretty much all the fundamental classes are now using the
+// shared_ptr stuff for automatic reference counting.  To ensure that
+// no mistakes are made, we make the constructors for classes private,
+// and then provide a free factory function that returns a smart
+// pointer to the desired class.
+//
+// gr_buffer and gr_buffer_reader are no exceptions.  However, they
+// both want pointers to each other, and unless we do something, we'll
+// never delete any of them because of the circular structure.
+// They'll always have a reference count of at least one.  We could
+// use boost::weak_ptr's from gr_buffer to gr_buffer_reader but that
+// introduces it's own problems.  (gr_buffer_reader's destructor needs
+// to call gr_buffer::drop_reader, but has no easy way to get a
+// shared_ptr to itself.)
+//
+// Instead, we solve this problem by having gr_buffer hold a raw
+// pointer to gr_buffer_reader in its d_reader vector.
+// gr_buffer_reader's destructor calls gr_buffer::drop_reader, so
+// we're never left with an dangling pointer.  gr_buffer_reader still
+// has a shared_ptr to the buffer ensuring that the buffer doesn't go
+// away under it.  However, when the reference count of a
+// gr_buffer_reader goes to zero, we can successfully reclaim it.
+// ----------------------------------------------------------------------------
+
+
+/*
+ * Compute the minimum number of buffer items that work (i.e.,
+ * address space wrap-around works).  To work is to satisfy this
+ * contraint for integer buffer_size and k:
+ *
+ *     type_size * nitems == k * page_size
+ */
+static long
+minimum_buffer_items (long type_size, long page_size)
+{
+  return page_size / gr_gcd (type_size, page_size);
+}
+
+
+gr_buffer::gr_buffer (int nitems, size_t sizeof_item)
+  : d_base (0), d_bufsize (0), d_vmcircbuf (0),
+    d_sizeof_item (sizeof_item), d_write_index (0),
+    d_done (false)
+{
+  if (!allocate_buffer (nitems, sizeof_item))
+    throw std::bad_alloc ();
+
+  s_buffer_count++;
+}
+
+gr_buffer_sptr 
+gr_make_buffer (int nitems, size_t sizeof_item)
+{
+  return gr_buffer_sptr (new gr_buffer (nitems, sizeof_item));
+}
+
+gr_buffer::~gr_buffer ()
+{
+  delete d_vmcircbuf;
+  assert (d_readers.size() == 0);
+  s_buffer_count--;
+}
+
+/*!
+ * sets d_vmcircbuf, d_base, d_bufsize.
+ * returns true iff successful.
+ */
+bool
+gr_buffer::allocate_buffer (int nitems, size_t sizeof_item)
+{
+  int  orig_nitems = nitems;
+  
+  // Any buffersize we come up with must be a multiple of min_nitems.
+
+  int granularity = gr_vmcircbuf_sysconfig::granularity ();
+  int min_nitems =  minimum_buffer_items (sizeof_item, granularity);
+
+  // Round-up nitems to a multiple of min_nitems.
+
+  if (nitems % min_nitems != 0)
+    nitems = ((nitems / min_nitems) + 1) * min_nitems;
+
+  // If we rounded-up a whole bunch, give the user a heads up.
+  // This only happens if sizeof_item is not a power of two.
+
+  if (nitems > 2 * orig_nitems && nitems * (int) sizeof_item > granularity){
+    std::cerr << "gr_buffer::allocate_buffer: warning: tried to allocate\n"
+             << "   " << orig_nitems << " items of size "
+             << sizeof_item << ". Due to alignment requirements\n"
+             << "   " << nitems << " were allocated.  If this isn't OK, consider padding\n"
+             << "   your structure to a power-of-two bytes.\n"
+             << "   On this platform, our allocation granularity is " << granularity << " bytes.\n";
+  }
+
+  d_bufsize = nitems;
+  d_vmcircbuf = gr_vmcircbuf_sysconfig::make (d_bufsize * d_sizeof_item);
+  if (d_vmcircbuf == 0){
+    std::cerr << "gr_buffer::allocate_buffer: failed to allocate buffer of size "
+             << d_bufsize * d_sizeof_item / 1024 << " KB\n";
+    return false;
+  }
+
+  d_base = (char *) d_vmcircbuf->pointer_to_first_copy ();
+  return true;
+}
+
+
+int
+gr_buffer::space_available () const
+{
+  if (d_readers.empty ())
+    return d_bufsize - 1;      // See comment below
+
+  else {
+
+    // Find out the maximum amount of data available to our readers
+
+    int        most_data = d_readers[0]->items_available ();
+    for (unsigned int i = 1; i < d_readers.size (); i++)
+      most_data = std::max (most_data, d_readers[i]->items_available ());
+
+    // The -1 ensures that the case d_write_index == d_read_index is
+    // unambiguous.  It indicates that there is no data for the reader
+
+    return d_bufsize - most_data - 1;
+  }
+}
+
+void *
+gr_buffer::write_pointer ()
+{
+  return &d_base[d_write_index * d_sizeof_item];
+}
+
+void
+gr_buffer::update_write_pointer (int nitems)
+{
+  d_write_index = index_add (d_write_index, nitems);
+}
+
+gr_buffer_reader_sptr
+gr_buffer_add_reader (gr_buffer_sptr buf, int history)
+{
+  gr_buffer_reader_sptr r (new gr_buffer_reader (buf,
+                                                buf->index_sub(buf->d_write_index,
+                                                               history-1)));
+  buf->d_readers.push_back (r.get ());
+
+  return r;
+}
+
+void
+gr_buffer::drop_reader (gr_buffer_reader *reader)
+{
+  // isn't C++ beautiful...    GAG!
+
+  std::vector<gr_buffer_reader *>::iterator result =
+    std::find (d_readers.begin (), d_readers.end (), reader);
+
+  if (result == d_readers.end ())
+    throw std::invalid_argument ("gr_buffer::drop_reader");    // we didn't find it...
+
+  d_readers.erase (result);
+}
+
+long
+gr_buffer_ncurrently_allocated ()
+{
+  return s_buffer_count;
+}
+
+// ----------------------------------------------------------------------------
+
+gr_buffer_reader::gr_buffer_reader (gr_buffer_sptr buffer, unsigned int read_index)
+  : d_buffer (buffer), d_read_index (read_index)
+{
+  s_buffer_reader_count++;
+}
+
+gr_buffer_reader::~gr_buffer_reader ()
+{
+  d_buffer->drop_reader(this);
+  s_buffer_reader_count--;
+}
+   
+int
+gr_buffer_reader::items_available () const
+{
+  return d_buffer->index_sub (d_buffer->d_write_index, d_read_index);
+}
+
+const void *
+gr_buffer_reader::read_pointer ()
+{
+  return &d_buffer->d_base[d_read_index * d_buffer->d_sizeof_item];
+}
+
+void
+gr_buffer_reader::update_read_pointer (int nitems)
+{
+  d_read_index = d_buffer->index_add (d_read_index, nitems);
+}
+
+long
+gr_buffer_reader_ncurrently_allocated ()
+{
+  return s_buffer_reader_count;
+}
diff --git a/gnuradio-core/src/lib/runtime/gr_buffer.h b/gnuradio-core/src/lib/runtime/gr_buffer.h
new file mode 100644 (file)
index 0000000..6f85f27
--- /dev/null
@@ -0,0 +1,196 @@
+/* -*- 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 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.
+ */
+
+#ifndef INCLUDED_GR_BUFFER_H
+#define INCLUDED_GR_BUFFER_H
+
+#include <gr_runtime.h>
+
+class gr_vmcircbuf;
+
+/*!
+ * \brief Allocate a buffer that holds at least \p nitems of size \p sizeof_item.
+ *
+ * The total size of the buffer will be rounded up to a system
+ * dependent boundary.  This is typically the system page size, but
+ * under MS windows is 64KB.
+ */
+gr_buffer_sptr gr_make_buffer (int nitems, size_t sizeof_item);
+
+
+/*!
+ * \brief Single writer, multiple reader fifo.
+ * \ingroup internal
+ */
+class gr_buffer {
+ public:
+  virtual ~gr_buffer ();
+
+  /*!
+   * \brief return number of items worth of space available for writing
+   */
+  int space_available () const;
+
+  /*!
+   * \brief return pointer to write buffer.
+   *
+   * The return value points at space that can hold at least
+   * space_available() items.
+   */
+  void *write_pointer ();
+
+  /*!
+   * \brief tell buffer that we wrote \p nitems into it
+   */
+  void update_write_pointer (int nitems);
+
+
+  void set_done (bool done)   { d_done = done; }
+  bool done () const { return d_done; }
+
+  // -------------------------------------------------------------------------
+
+ private:
+
+  friend class gr_buffer_reader;
+  friend gr_buffer_sptr gr_make_buffer (int nitems, size_t sizeof_item);
+  friend gr_buffer_reader_sptr gr_buffer_add_reader (gr_buffer_sptr buf, int history);
+
+ protected:
+  char                                *d_base;         // base address of buffer
+  unsigned int                         d_bufsize;      // in items
+ private:
+  gr_vmcircbuf                        *d_vmcircbuf;
+  size_t                               d_sizeof_item;  // in bytes
+  unsigned int                         d_write_index;  // in items [0,d_bufsize)
+  std::vector<gr_buffer_reader *>      d_readers;
+  bool                                 d_done;
+  
+  unsigned
+  index_add (unsigned a, unsigned b)
+  {
+    unsigned s = a + b;
+
+    if (s >= d_bufsize)
+      s -= d_bufsize;
+
+    assert (s < d_bufsize);
+    return s;
+  }
+
+  unsigned
+  index_sub (unsigned a, unsigned b)
+  {
+    int s = a - b;
+
+    if (s < 0)
+      s += d_bufsize;
+
+    assert ((unsigned) s < d_bufsize);
+    return s;
+  }
+
+  virtual bool allocate_buffer (int nitems, size_t sizeof_item);
+
+  /*!
+   * \brief constructor is private.  Use gr_make_buffer to create instances.
+   *
+   * Allocate a buffer that holds at least \p nitems of size \p sizeof_item.
+   *
+   * The total size of the buffer will be rounded up to a system
+   * dependent boundary.  This is typically the system page size, but
+   * under MS windows is 64KB.
+   */
+  gr_buffer (int nitems, size_t sizeof_item);
+
+  /*!
+   * \brief disassociate \p reader from this buffer
+   */
+  void drop_reader (gr_buffer_reader *reader);
+
+};
+
+//! create a new gr_buffer_reader and attach it to buffer \p buf
+gr_buffer_reader_sptr gr_buffer_add_reader (gr_buffer_sptr buf, int history);
+
+//! returns # of gr_buffers currently allocated
+long gr_buffer_ncurrently_allocated ();
+
+
+// ---------------------------------------------------------------------------
+
+/*!
+ * \brief How we keep track of the readers of a gr_buffer.
+ * \ingroup internal
+ */
+
+class gr_buffer_reader {
+
+ public:
+  ~gr_buffer_reader ();
+
+  /*!
+   * \brief Return number of items available for reading.
+   */
+  int items_available () const;
+
+  /*!
+   * \brief Return maximum number of items that could ever be available for reading.
+   * This is used as a sanity check in the scheduler to avoid looping forever.
+   */
+  int max_possible_items_available () const { return d_buffer->d_bufsize - 1; }
+
+  /*!
+   * \brief return pointer to read buffer.
+   *
+   * The return value points to items_available() number of items
+   */
+  const void *read_pointer ();
+
+  /*
+   * \brief tell buffer we read \p items from it
+   */
+  void update_read_pointer (int nitems);
+
+  void set_done (bool done)   { d_buffer->set_done (done); }
+  bool done () const { return d_buffer->done (); }
+
+  // -------------------------------------------------------------------------
+
+ private:
+
+  friend class gr_buffer;
+  friend gr_buffer_reader_sptr gr_buffer_add_reader (gr_buffer_sptr buf, int history);
+
+
+  gr_buffer_sptr               d_buffer;
+  unsigned int                 d_read_index;   // in items [0,d->buffer.d_bufsize)
+
+  //! constructor is private.  Use gr_buffer::add_reader to create instances
+  gr_buffer_reader (gr_buffer_sptr buffer, unsigned int read_index);
+};
+
+//! returns # of gr_buffer_readers currently allocated
+long gr_buffer_reader_ncurrently_allocated ();
+
+
+#endif /* INCLUDED_GR_BUFFER_H */
diff --git a/gnuradio-core/src/lib/runtime/gr_buffer.i b/gnuradio-core/src/lib/runtime/gr_buffer.i
new file mode 100644 (file)
index 0000000..80f92ec
--- /dev/null
@@ -0,0 +1,63 @@
+/* -*- 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 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.
+ */
+
+class gr_buffer;
+typedef boost::shared_ptr<gr_buffer> gr_buffer_sptr;
+%template(gr_buffer_sptr) boost::shared_ptr<gr_buffer>;
+%rename(buffer) gr_make_buffer;
+%ignore gr_buffer;
+
+gr_buffer_sptr gr_make_buffer (int nitems, size_t sizeof_item);
+
+class gr_buffer {
+ public:
+  ~gr_buffer ();
+
+ private:
+  gr_buffer (int nitems, size_t sizeof_item);
+};
+  
+
+class gr_buffer_reader;
+typedef boost::shared_ptr<gr_buffer_reader> gr_buffer_reader_sptr;
+%template(gr_buffer_reader_sptr) boost::shared_ptr<gr_buffer_reader>;
+%ignore gr_buffer_reader;
+
+%rename(buffer_add_reader) gr_buffer_add_reader;
+gr_buffer_reader_sptr gr_buffer_add_reader (gr_buffer_sptr buf, int history);
+
+class gr_buffer_reader {
+ public:
+  ~gr_buffer_reader ();
+
+ private:
+  friend class gr_buffer;
+  gr_buffer_reader (gr_buffer_sptr buffer, unsigned int read_index);
+};
+
+
+%rename(buffer_ncurrently_allocated) gr_buffer_ncurrently_allocated;
+long gr_buffer_ncurrently_allocated ();
+
+%rename(buffer_reader_ncurrently_allocated) gr_buffer_reader_ncurrently_allocated;
+long gr_buffer_reader_ncurrently_allocated ();
+
diff --git a/gnuradio-core/src/lib/runtime/gr_complex.h b/gnuradio-core/src/lib/runtime/gr_complex.h
new file mode 100644 (file)
index 0000000..242b2f5
--- /dev/null
@@ -0,0 +1,46 @@
+/* -*- 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 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.
+ */
+#ifndef INCLUDED_GR_COMPLEX_H
+#define INCLUDED_GR_COMPLEX_H
+
+#include <complex>
+typedef std::complex<float>                    gr_complex;
+typedef std::complex<double>                   gr_complexd;
+
+
+inline bool is_complex (gr_complex x) { return true;}
+inline bool is_complex (gr_complexd x) { return true;}
+inline bool is_complex (float x) { return false;}
+inline bool is_complex (double x) { return false;}
+inline bool is_complex (int x) { return false;}
+inline bool is_complex (char x) { return false;}
+inline bool is_complex (short x) { return false;}
+
+
+// this doesn't really belong here, but there are worse places for it...
+
+#define ASSERT_COMPLEXES_EQUAL(expected,actual,delta)                  \
+  CPPUNIT_ASSERT_DOUBLES_EQUAL (expected.real(), actual.real(), delta);        \
+  CPPUNIT_ASSERT_DOUBLES_EQUAL (expected.imag(), actual.imag(), delta);
+
+#endif /* INCLUDED_GR_COMPLEX_H */
+
diff --git a/gnuradio-core/src/lib/runtime/gr_dispatcher.cc b/gnuradio-core/src/lib/runtime/gr_dispatcher.cc
new file mode 100644 (file)
index 0000000..c2a1eb5
--- /dev/null
@@ -0,0 +1,192 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_dispatcher.h>
+#include <math.h>
+#include <errno.h>
+
+#ifdef HAVE_SELECT
+#  ifdef HAVE_SYS_SELECT_H
+#    include <sys/select.h>
+#  else
+#    ifdef HAVE_SYS_TIME_H
+#      include <sys/time.h>
+#    endif
+#    ifdef HAVE_SYS_TYPES_H
+#      include <sys/types.h>
+#    endif
+#    ifdef HAVE_UNISTD_H
+#      include <unistd.h>
+#    endif
+#  endif
+#endif
+
+
+static gr_dispatcher_sptr s_singleton;
+
+gr_dispatcher_sptr
+gr_make_dispatcher()
+{
+  return gr_dispatcher_sptr(new gr_dispatcher());
+}
+
+gr_dispatcher_sptr
+gr_dispatcher_singleton()
+{
+  if (s_singleton)
+    return s_singleton;
+
+  s_singleton = gr_make_dispatcher();
+  return s_singleton;
+}
+
+#if !defined(HAVE_SELECT)              // Stub it out
+
+gr_dispatcher::gr_dispatcher()
+{
+}
+
+gr_dispatcher::~gr_dispatcher()
+{
+}
+
+bool
+gr_dispatcher::add_handler(gr_select_handler_sptr handler)
+{
+  return true;
+}
+
+bool
+gr_dispatcher::del_handler(gr_select_handler_sptr handler)
+{
+  return true;
+}
+
+bool
+gr_dispatcher::del_handler(gr_select_handler *handler)
+{
+  return true;
+}
+
+void
+gr_dispatcher::loop(double timeout)
+{
+}
+
+#else                  // defined(HAVE_SELECT)
+
+gr_dispatcher::gr_dispatcher()
+  : d_handler(FD_SETSIZE), d_max_index(-1)
+{
+}
+
+gr_dispatcher::~gr_dispatcher()
+{
+}
+
+bool
+gr_dispatcher::add_handler(gr_select_handler_sptr handler)
+{
+  int fd = handler->fd();
+  if (fd < 0 || fd >= FD_SETSIZE)
+    return false;
+
+  d_max_index = std::max(d_max_index, fd);
+  d_handler[fd] = handler;
+  return true;
+}
+
+bool
+gr_dispatcher::del_handler(gr_select_handler_sptr handler)
+{
+  return del_handler(handler.get());
+}
+
+bool
+gr_dispatcher::del_handler(gr_select_handler *handler)
+{
+  int fd = handler->fd();
+  if (fd < 0 || fd >= FD_SETSIZE)
+    return false;
+
+  d_handler[fd].reset();
+
+  if (fd == d_max_index){
+    int i;
+    for (i = fd - 1; i >= 0 && !d_handler[i]; i--)
+      ;
+    d_max_index = i;
+  }
+  return true;
+}
+
+
+void
+gr_dispatcher::loop(double timeout)
+{
+  struct timeval master;
+  struct timeval tmp;
+  fd_set        rd_set;
+  fd_set        wr_set;
+
+  double secs = floor (timeout);
+  master.tv_sec = (long) secs;
+  master.tv_usec = (long) ((timeout - secs) * 1e6);
+
+  while (d_max_index >= 0){
+    FD_ZERO(&rd_set);
+    FD_ZERO(&wr_set);
+
+    for (int i = 0; i <= d_max_index; i++){
+      if (d_handler[i] && d_handler[i]->readable())
+       FD_SET(i, &rd_set);
+      if (d_handler[i] && d_handler[i]->writable())
+       FD_SET(i, &wr_set);
+    }
+
+    tmp = master;
+    int retval = select(d_max_index+1, &rd_set, &wr_set, 0, &tmp);
+    if (retval == 0)   // timed out with nothing ready
+      continue;
+    if (retval < 0){
+      if (errno == EINTR)
+       continue;
+      perror ("gr_dispatcher/select");
+      return;
+    }
+
+    for (int i = 0; i <= d_max_index; i++){
+      if (FD_ISSET(i, &rd_set))
+       if (d_handler[i])
+         d_handler[i]->handle_read();
+      if (FD_ISSET(i, &wr_set))
+       if (d_handler[i])
+         d_handler[i]->handle_write();
+    }
+  }
+}
+
+#endif
diff --git a/gnuradio-core/src/lib/runtime/gr_dispatcher.h b/gnuradio-core/src/lib/runtime/gr_dispatcher.h
new file mode 100644 (file)
index 0000000..a3d8579
--- /dev/null
@@ -0,0 +1,67 @@
+/* -*- 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 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.
+ */
+
+#ifndef INCLUDED_GR_DISPATCHER_H
+#define INCLUDED_GR_DISPATCHER_H
+
+#include <gr_select_handler.h>
+#include <vector>
+
+class gr_dispatcher;
+typedef boost::shared_ptr<gr_dispatcher> gr_dispatcher_sptr;
+
+gr_dispatcher_sptr gr_dispatcher_singleton();
+gr_dispatcher_sptr gr_make_dispatcher();
+
+/*!
+ * \brief invoke callbacks based on select.
+ *
+ * \sa gr_select_handler
+ */
+class gr_dispatcher
+{
+  gr_dispatcher();
+  friend gr_dispatcher_sptr gr_make_dispatcher();
+
+  std::vector<gr_select_handler_sptr> d_handler;
+  int                                d_max_index;
+
+public:
+  ~gr_dispatcher();
+
+  bool add_handler(gr_select_handler_sptr handler);
+  bool del_handler(gr_select_handler_sptr handler);
+  bool del_handler(gr_select_handler *handler);
+
+  /*!
+   * \brief Event dispatching loop.
+   *
+   * Enter a polling loop that only terminates after all gr_select_handlers
+   * have been removed.  \p timeout sets the timeout parameter to the select()
+   * call, measured in seconds.
+   *
+   * \param timeout maximum number of seconds to block in select.
+   */
+  void loop(double timeout=10);
+};
+
+#endif /* INCLUDED_GR_DISPATCHER_H */
diff --git a/gnuradio-core/src/lib/runtime/gr_dispatcher.i b/gnuradio-core/src/lib/runtime/gr_dispatcher.i
new file mode 100644 (file)
index 0000000..5feca75
--- /dev/null
@@ -0,0 +1,55 @@
+/* -*- 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 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.
+ */
+
+class gr_dispatcher;
+typedef boost::shared_ptr<gr_dispatcher> gr_dispatcher_sptr;
+%template(gr_dispatcher_sptr) boost::shared_ptr<gr_dispatcher>;
+
+%rename(dispatcher) gr_make_dispatcher;
+gr_dispatcher_sptr gr_make_dispatcher();
+
+%rename(dispatcher_singleton) gr_dispatcher_singleton;
+gr_dispatcher_sptr gr_dispatcher_singleton();
+
+/*!
+ * \brief invoke callbacks based on select.
+ *
+ * \sa gr_select_handler
+ */
+class gr_dispatcher
+{
+  gr_dispatcher();
+
+public:
+  ~gr_dispatcher();
+
+  /*!
+   * \brief Event dispatching loop.
+   *
+   * Enter a polling loop that only terminates after all gr_select_handlers
+   * have been removed.  \p timeout sets the timeout parameter to the select()
+   * call, measured in seconds.
+   *
+   * \param timeout maximum number of seconds to block in select.
+   */
+  void loop(double timeout=10);
+};
diff --git a/gnuradio-core/src/lib/runtime/gr_error_handler.cc b/gnuradio-core/src/lib/runtime/gr_error_handler.cc
new file mode 100644 (file)
index 0000000..a3148cf
--- /dev/null
@@ -0,0 +1,244 @@
+/* -*- 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 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 code is based on error.cc from the "Click Modular Router".
+ * Original copyright follows:
+ */
+/* 
+ * error.{cc,hh} -- flexible classes for error reporting
+ * Eddie Kohler
+ *
+ * Copyright (c) 1999-2000 Massachusetts Institute of Technology
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, subject to the conditions
+ * listed in the Click LICENSE file. These conditions include: you must
+ * preserve this copyright notice, and you cannot mention the copyright
+ * holders in advertising related to the Software without their permission.
+ * The Software is provided WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED. This
+ * notice is a summary of the Click LICENSE file; the license in that file is
+ * legally binding.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_error_handler.h>
+#include <assert.h>
+#include <stdexcept>
+#include <unistd.h>
+
+#ifdef HAVE_IO_H
+#include <io.h>
+#endif
+
+static gr_error_handler        *s_default_handler = 0;
+static gr_error_handler *s_silent_handler = 0;
+
+bool
+gr_error_handler::has_default_handler()
+{
+  return s_default_handler != 0;
+}
+
+void
+gr_error_handler::set_default_handler(gr_error_handler *errh)
+{
+  s_default_handler = errh;
+}
+
+gr_error_handler *
+gr_error_handler::default_handler()
+{
+  assert (s_default_handler != 0);
+  return s_default_handler;
+}
+
+gr_error_handler *
+gr_error_handler::silent_handler()
+{
+  assert (s_silent_handler != 0);
+  return s_silent_handler;
+}
+
+// ----------------------------------------------------------------
+
+gr_error_handler::~gr_error_handler()
+{
+  // nop
+}
+
+void
+gr_error_handler::debug(const char *format, ...)
+{
+  va_list val;
+  va_start(val, format);
+  verror(ERR_DEBUG, format, val);
+  va_end(val);
+}
+
+void
+gr_error_handler::message(const char *format, ...)
+{
+  va_list val;
+  va_start(val, format);
+  verror(ERR_MESSAGE, format, val);
+  va_end(val);
+}
+
+void
+gr_error_handler::warning(const char *format, ...)
+{
+  va_list val;
+  va_start(val, format);
+  verror(ERR_WARNING, format, val);
+  va_end(val);
+}
+
+void
+gr_error_handler::error(const char *format, ...)
+{
+  va_list val;
+  va_start(val, format);
+  verror(ERR_ERROR, format, val);
+  va_end(val);
+}
+
+void
+gr_error_handler::fatal(const char *format, ...)
+{
+  va_list val;
+  va_start(val, format);
+  verror(ERR_FATAL, format, val);
+  va_end(val);
+}
+
+void
+gr_error_handler::verror(seriousness s, const char *format, va_list val)
+{
+  std::string text = make_text(s, format, val);
+  handle_text(s, text);
+  count_error(s);
+}
+
+void
+gr_error_handler::verror_text(seriousness s, const std::string &text)
+{
+  // text is already made
+  handle_text(s, text);
+  count_error(s);
+}
+
+std::string
+gr_error_handler::make_text(seriousness s, const char *format, va_list val)
+{
+  char text_buf[4096];
+  vsnprintf(text_buf, sizeof(text_buf), format, val);
+  text_buf[sizeof(text_buf)-1] = 0;
+  return text_buf;
+}
+
+// ----------------------------------------------------------------
+
+void
+gr_base_error_handler::count_error(seriousness s)
+{
+  if (s < ERR_WARNING)
+    /* do nothing */;
+  else if (s < ERR_ERROR)
+    d_nwarnings++;
+  else
+    d_nerrors++;
+}
+
+// ----------------------------------------------------------------
+
+gr_file_error_handler::gr_file_error_handler(FILE *file)
+  : d_file(file), d_fd(-1)
+{
+}
+
+gr_file_error_handler::gr_file_error_handler(int file_descriptor)
+{
+  d_fd = dup(file_descriptor); // so we can fclose it
+  if (d_fd == -1){
+    perror("gr_file_error_handler:dup");
+    throw std::invalid_argument("gr_file_error_handler:dup");
+  }
+  d_file = fdopen(d_fd, "w");
+  if (d_file == 0){
+    perror("gr_file_error_handler:fdopen");
+    throw std::invalid_argument("gr_file_error_handler:fdopen");
+  }
+}
+
+gr_file_error_handler::~gr_file_error_handler()
+{
+  if (d_fd != -1){
+    fclose(d_file);
+  }
+}
+
+void
+gr_file_error_handler::handle_text(seriousness s, const std::string &text)
+{
+  if (text.length() <= 0)
+    return;
+  
+  fwrite(text.data(), 1, text.length(), d_file);
+  if (text[text.length()-1] != '\n')
+    fwrite("\n", 1, 1, d_file);
+
+  if (d_fd != -1)
+    fflush(d_file);    // keep synced with any other users of fd
+}
+  
+
+// ----------------------------------------------------------------
+// static error handlers
+//
+
+class gr_silent_error_handler : public gr_base_error_handler
+{
+public:
+  gr_silent_error_handler() {}
+  void handle_text(seriousness s, const std::string &str);
+};
+
+void
+gr_silent_error_handler::handle_text(seriousness s, const std::string &str)
+{
+  // nop
+}
+
+class force_init {
+public:
+  force_init()
+  {
+    s_default_handler = new gr_file_error_handler(stdout);
+    s_silent_handler = new gr_silent_error_handler();
+  }
+};
+
+static force_init      kludge;
diff --git a/gnuradio-core/src/lib/runtime/gr_error_handler.h b/gnuradio-core/src/lib/runtime/gr_error_handler.h
new file mode 100644 (file)
index 0000000..275db64
--- /dev/null
@@ -0,0 +1,114 @@
+/* -*- 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 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 code is based on error.hh from the "Click Modular Router".
+ * Original copyright follows:
+ */
+/* 
+ * error.{cc,hh} -- flexible classes for error reporting
+ * Eddie Kohler
+ *
+ * Copyright (c) 1999-2000 Massachusetts Institute of Technology
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, subject to the conditions
+ * listed in the Click LICENSE file. These conditions include: you must
+ * preserve this copyright notice, and you cannot mention the copyright
+ * holders in advertising related to the Software without their permission.
+ * The Software is provided WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED. This
+ * notice is a summary of the Click LICENSE file; the license in that file is
+ * legally binding.
+ */
+
+#ifndef INCLUDED_GR_ERROR_HANDLER_H
+#define INCLUDED_GR_ERROR_HANDLER_H
+
+#include <stdarg.h>
+#include <string>
+
+/*!
+ * \brief abstract error handler
+ */
+class gr_error_handler {
+public:
+  enum seriousness {
+    ERR_DEBUG          = 0x00000000,
+    ERR_MESSAGE                = 0x00010000,
+    ERR_WARNING                = 0x00020000,
+    ERR_ERROR          = 0x00030000,
+    ERR_FATAL          = 0x00040000
+  };
+
+  gr_error_handler() {}
+  virtual ~gr_error_handler();
+
+  static gr_error_handler *default_handler();
+  static gr_error_handler *silent_handler();
+
+  static bool has_default_handler();
+  static void set_default_handler(gr_error_handler *errh);
+
+  void debug(const char *format, ...);
+  void message(const char *format, ...);
+  void warning(const char *format, ...);
+  void error(const char *format, ...);
+  void fatal(const char *format, ...);
+
+  virtual int nwarnings() const = 0;
+  virtual int nerrors() const = 0;
+  virtual void reset_counts() = 0;
+
+  void verror(seriousness s, const char *format, va_list);
+  void verror_text(seriousness s, const std::string &text);
+
+protected:
+  virtual void count_error(seriousness s) = 0;
+  virtual void handle_text(seriousness s, const std::string &str) = 0;
+  std::string make_text(seriousness s, const char *format, va_list);
+};
+
+
+class gr_base_error_handler : public gr_error_handler {
+  int  d_nwarnings;
+  int  d_nerrors;
+
+public:
+  gr_base_error_handler() : d_nwarnings(0), d_nerrors(0) {}
+  int nwarnings() const { return d_nwarnings; }
+  int nerrors() const   { return d_nerrors; }
+  void reset_counts()   { d_nwarnings = d_nerrors = 0; }
+  void count_error(seriousness s);
+};
+
+class gr_file_error_handler : public gr_base_error_handler {
+  FILE         *d_file;
+  int           d_fd;
+public:
+  gr_file_error_handler(FILE *file);
+  gr_file_error_handler(int file_descriptor);
+  ~gr_file_error_handler();
+
+  void handle_text(seriousness s, const std::string &str);
+};
+
+#endif /* INCLUDED_GR_ERROR_HANDLER_H */
diff --git a/gnuradio-core/src/lib/runtime/gr_error_handler.i b/gnuradio-core/src/lib/runtime/gr_error_handler.i
new file mode 100644 (file)
index 0000000..d0e6149
--- /dev/null
@@ -0,0 +1,69 @@
+/* -*- 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 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.
+ */
+
+%rename(error_handler) gr_error_handler;
+%rename(file_error_handler) gr_file_error_handler;
+
+class gr_error_handler {
+public:
+  enum seriousness {
+    ERR_DEBUG          = 0x00000000,
+    ERR_MESSAGE                = 0x00010000,
+    ERR_WARNING                = 0x00020000,
+    ERR_ERROR          = 0x00030000,
+    ERR_FATAL          = 0x00040000
+  };
+
+  gr_error_handler() {}
+  virtual ~gr_error_handler();
+
+  static gr_error_handler *default_handler();
+  static gr_error_handler *silent_handler();
+
+  static bool has_default_handler();
+  static void set_default_handler(gr_error_handler *errh);
+
+  virtual int nwarnings() const = 0;
+  virtual int nerrors() const = 0;
+  virtual void reset_counts() = 0;
+
+  void verror_text(seriousness s, const std::string &text);
+};
+
+%ignore gr_base_error_handler;
+class gr_base_error_handler : public gr_error_handler {
+  int  d_nwarnings;
+  int  d_nerrors;
+
+public:
+  gr_base_error_handler() : d_nwarnings(0), d_nerrors(0) {}
+  int nwarnings() const { return d_nwarnings; }
+  int nerrors() const   { return d_nerrors; }
+  void reset_counts()   { d_nwarnings = d_nerrors = 0; }
+  void count_error(seriousness s);
+};
+
+class gr_file_error_handler : public gr_base_error_handler {
+public:
+  gr_file_error_handler(int file_descriptor);
+  ~gr_file_error_handler();
+};
diff --git a/gnuradio-core/src/lib/runtime/gr_io_signature.cc b/gnuradio-core/src/lib/runtime/gr_io_signature.cc
new file mode 100644 (file)
index 0000000..7277108
--- /dev/null
@@ -0,0 +1,54 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <gr_io_signature.h>
+#include <stdexcept>
+#include <iostream>
+
+gr_io_signature::gr_io_signature (int min_streams, int max_streams, size_t sizeof_stream_item)
+{
+  if (min_streams < 0
+      || (max_streams != IO_INFINITE && max_streams < min_streams))
+    throw std::invalid_argument ("gr_io_signature");
+
+  d_min_streams = min_streams;
+  d_max_streams = max_streams;
+  d_sizeof_stream_item = sizeof_stream_item;
+}
+
+gr_io_signature::~gr_io_signature ()
+{
+  // NOP for now
+  // std::cout << "destroying gr_io_signature: " << this << '\n';
+}
+
+gr_io_signature_sptr
+gr_make_io_signature (int min_streams, int max_streams, size_t sizeof_stream_item)
+{
+  return gr_io_signature_sptr (new gr_io_signature (min_streams, max_streams,
+                                                  sizeof_stream_item));
+}
+
+
diff --git a/gnuradio-core/src/lib/runtime/gr_io_signature.h b/gnuradio-core/src/lib/runtime/gr_io_signature.h
new file mode 100644 (file)
index 0000000..e0d9790
--- /dev/null
@@ -0,0 +1,65 @@
+/* -*- 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 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.
+ */
+
+#ifndef INCLUDED_IO_SIGNATURE_H
+#define INCLUDED_IO_SIGNATURE_H
+
+#include <gr_runtime.h>
+
+/*!
+ * \brief i/o signature for input and output ports.
+ *
+ * For now, we restrict all streams to be the same type.
+ * We can fix this later.
+ */
+  
+class gr_io_signature {
+ public:
+
+  static const int IO_INFINITE = -1;
+    
+  ~gr_io_signature ();
+    
+  int min_streams () const { return d_min_streams; }
+  int max_streams () const { return d_max_streams; }
+  size_t sizeof_stream_item (int index) const { return d_sizeof_stream_item; }
+
+  // ----------------------------------------------------------------------------
+
+ private:
+  
+  int          d_min_streams;
+  int          d_max_streams;
+  size_t       d_sizeof_stream_item;
+
+  gr_io_signature (int min_streams, int max_streams, size_t sizeof_stream_item);
+
+  friend gr_io_signature_sptr gr_make_io_signature (int min_streams,
+                                                  int max_streams,
+                                                  size_t sizeof_stream_item);
+};
+
+gr_io_signature_sptr
+gr_make_io_signature (int min_streams, int max_streams, size_t sizeof_stream_item);
+
+
+#endif /* INCLUDED_IO_SIGNATURE_H */
diff --git a/gnuradio-core/src/lib/runtime/gr_io_signature.i b/gnuradio-core/src/lib/runtime/gr_io_signature.i
new file mode 100644 (file)
index 0000000..601142e
--- /dev/null
@@ -0,0 +1,49 @@
+/* -*- c++ -*- */
+/*
+ * 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 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.
+ */
+
+class gr_io_signature;
+typedef boost::shared_ptr<gr_io_signature>  gr_io_signature_sptr;
+%template(gr_io_signature_sptr) boost::shared_ptr<gr_io_signature>;
+
+%rename(io_signature) gr_make_io_signature;
+
+gr_io_signature_sptr
+gr_make_io_signature (int min_streams,
+                     int max_streams,
+                     size_t sizeof_stream_item);
+
+class gr_io_signature {
+ public:
+
+  // disabled. Suspected bug in SWIG 1.3.24
+  // static const int IO_INFINITE = -1;
+    
+  ~gr_io_signature ();
+    
+  int min_streams () const { return d_min_streams; }
+  int max_streams () const { return d_max_streams; }
+  size_t sizeof_stream_item (int index) const { return d_sizeof_stream_item; }
+
+ private:
+  gr_io_signature (int min_streams, int max_streams, size_t sizeof_stream_item);
+};
+
diff --git a/gnuradio-core/src/lib/runtime/gr_local_sighandler.cc b/gnuradio-core/src/lib/runtime/gr_local_sighandler.cc
new file mode 100644 (file)
index 0000000..c6da097
--- /dev/null
@@ -0,0 +1,186 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_local_sighandler.h>
+#include <stdexcept>
+#include <stdio.h>
+
+
+gr_local_sighandler::gr_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
+}
+
+gr_local_sighandler::~gr_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
+gr_local_sighandler::throw_signal (int signum)
+{
+  throw gr_signal (signum);
+}
+
+/*
+ * Semi-hideous way to may a signal number into a signal name
+ */
+
+#define SIGNAME(x) case x: return #x
+
+std::string
+gr_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/gnuradio-core/src/lib/runtime/gr_local_sighandler.h b/gnuradio-core/src/lib/runtime/gr_local_sighandler.h
new file mode 100644 (file)
index 0000000..69eb65d
--- /dev/null
@@ -0,0 +1,60 @@
+/* -*- 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 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.
+ */
+
+#ifndef INCLUDED_GR_LOCAL_SIGHANDLER_H
+#define INCLUDED_GR_LOCAL_SIGHANDLER_H
+
+#include <signal.h>
+#include <string>
+
+/*!
+ * \brief Get and set signal handler.
+ *
+ * Constructor installs new handler, destructor reinstalls
+ * original value.
+ */
+class gr_local_sighandler {
+  int                  d_signum;
+#ifdef HAVE_SIGACTION
+  struct sigaction     d_old_action;
+#endif
+public:
+  gr_local_sighandler (int signum, void (*new_handler)(int));
+  ~gr_local_sighandler ();
+
+  /* throw gr_signal (signum) */
+  static void throw_signal (int signum);
+};
+
+/*!
+ * \brief Representation of signal.
+ */
+class gr_signal
+{
+  int  d_signum;
+public:
+  gr_signal (int signum) : d_signum (signum) {}
+  int signal () const { return d_signum; }
+  std::string name () const;
+};
+
+#endif /* INCLUDED_GR_LOCAL_SIGHANDLER_H */
diff --git a/gnuradio-core/src/lib/runtime/gr_message.cc b/gnuradio-core/src/lib/runtime/gr_message.cc
new file mode 100644 (file)
index 0000000..e9427e6
--- /dev/null
@@ -0,0 +1,77 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include <gr_message.h>
+#include <assert.h>
+
+static long s_ncurrently_allocated = 0;
+
+gr_message_sptr
+gr_make_message (long type, double arg1, double arg2, size_t length)
+{
+  return gr_message_sptr (new gr_message (type, arg1, arg2, length));
+}
+
+gr_message_sptr
+gr_make_message_from_string(const std::string s, long type, double arg1, double arg2)
+{
+  gr_message_sptr m = gr_make_message(type, arg1, arg2, s.size());
+  memcpy(m->msg(), s.data(), s.size());
+  return m;
+}
+
+
+gr_message::gr_message (long type, double arg1, double arg2, size_t length)
+  : d_type(type), d_arg1(arg1), d_arg2(arg2)
+{
+  if (length == 0)
+    d_buf_start = d_msg_start = d_msg_end = d_buf_end = 0;
+  else {
+    d_buf_start = new unsigned char [length];
+    d_msg_start = d_buf_start;
+    d_msg_end = d_buf_end = d_buf_start + length;
+  }
+  s_ncurrently_allocated++;
+}
+
+gr_message::~gr_message ()
+{
+  assert (d_next == 0);
+  delete [] d_buf_start;
+  d_msg_start = d_msg_end = d_buf_end = 0;
+  s_ncurrently_allocated--;
+}
+
+std::string
+gr_message::to_string() const
+{ 
+  return std::string((char *)d_msg_start, length());
+}
+
+long
+gr_message_ncurrently_allocated ()
+{
+  return s_ncurrently_allocated;
+}
diff --git a/gnuradio-core/src/lib/runtime/gr_message.h b/gnuradio-core/src/lib/runtime/gr_message.h
new file mode 100644 (file)
index 0000000..272a82e
--- /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 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.
+ */
+#ifndef INCLUDED_GR_MESSAGE_H
+#define INCLUDED_GR_MESSAGE_H
+
+#include <gr_types.h>
+#include <string>
+
+class gr_message;
+typedef boost::shared_ptr<gr_message> gr_message_sptr;
+
+/*!
+ * \brief public constructor for gr_message
+ */
+gr_message_sptr 
+gr_make_message(long type = 0, double arg1 = 0, double arg2 = 0, size_t length = 0);
+
+gr_message_sptr
+gr_make_message_from_string(const std::string s, long type = 0, double arg1 = 0, double arg2 = 0);
+
+/*!
+ * \brief Message.
+ *
+ * The ideas and method names for adjustable message length were
+ * lifted from the click modular router "Packet" class.
+ */
+class gr_message {
+  gr_message_sptr d_next;      // link field for msg queue
+  long           d_type;       // type of the message
+  double         d_arg1;       // optional arg1
+  double         d_arg2;       // optional arg2
+
+  unsigned char         *d_buf_start;  // start of allocated buffer
+  unsigned char  *d_msg_start; // where the msg starts
+  unsigned char  *d_msg_end;   // one beyond end of msg
+  unsigned char  *d_buf_end;   // one beyond end of allocated buffer
+  
+  gr_message (long type, double arg1, double arg2, size_t length);
+
+  friend gr_message_sptr
+    gr_make_message (long type, double arg1, double arg2, size_t length);
+
+  friend gr_message_sptr
+    gr_make_message_from_string (const std::string s, long type, double arg1, double arg2);
+
+  friend class gr_msg_queue;
+
+  unsigned char *buf_data() const  { return d_buf_start; }
+  size_t buf_len() const          { return d_buf_end - d_buf_start; }
+
+public:
+  ~gr_message ();
+
+  long type() const   { return d_type; }
+  double arg1() const { return d_arg1; }
+  double arg2() const { return d_arg2; }
+
+  void set_type(long type)   { d_type = type; }
+  void set_arg1(double arg1) { d_arg1 = arg1; }
+  void set_arg2(double arg2) { d_arg2 = arg2; }
+
+  unsigned char *msg() const { return d_msg_start; }
+  size_t length() const      { return d_msg_end - d_msg_start; }
+  std::string to_string() const;
+
+};
+
+long gr_message_ncurrently_allocated ();
+
+#endif /* INCLUDED_GR_MESSAGE_H */
diff --git a/gnuradio-core/src/lib/runtime/gr_message.i b/gnuradio-core/src/lib/runtime/gr_message.i
new file mode 100644 (file)
index 0000000..19d5d1c
--- /dev/null
@@ -0,0 +1,65 @@
+/* -*- 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 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.
+ */
+
+class gr_message;
+typedef boost::shared_ptr<gr_message> gr_message_sptr;
+%template(gr_message_sptr) boost::shared_ptr<gr_message>;
+
+%rename(message_from_string) gr_make_message_from_string;
+gr_message_sptr
+gr_make_message_from_string(const std::string s, long type = 0, double arg1 = 0, double arg2 = 0);
+
+%rename(message) gr_make_message;
+gr_message_sptr
+gr_make_message(long type = 0, double arg1 = 0, double arg2 = 0, size_t length = 0);
+
+/*!
+ * \brief Message.
+ *
+ * The ideas and method names for adjustable message length were
+ * lifted from the click modular router "Packet" class.
+ */
+class gr_message {
+  gr_message (long type, double arg1, double arg2, size_t length);
+
+  unsigned char *buf_data() const  { return d_buf_start; }
+  size_t buf_len() const          { return d_buf_end - d_buf_start; }
+
+public:
+  ~gr_message ();
+
+  long type() const   { return d_type; }
+  double arg1() const { return d_arg1; }
+  double arg2() const { return d_arg2; }
+
+  void set_type(long type)   { d_type = type; }
+  void set_arg1(double arg1) { d_arg1 = arg1; }
+  void set_arg2(double arg2) { d_arg2 = arg2; }
+
+  size_t length() const;
+  std::string to_string() const;
+
+};
+
+%rename(message_ncurrently_allocated) gr_message_ncurrently_allocated;
+long gr_message_ncurrently_allocated();
+
diff --git a/gnuradio-core/src/lib/runtime/gr_msg_handler.cc b/gnuradio-core/src/lib/runtime/gr_msg_handler.cc
new file mode 100644 (file)
index 0000000..98007e2
--- /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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include <gr_msg_handler.h>
+
+gr_msg_handler::~gr_msg_handler ()
+{
+}
diff --git a/gnuradio-core/src/lib/runtime/gr_msg_handler.h b/gnuradio-core/src/lib/runtime/gr_msg_handler.h
new file mode 100644 (file)
index 0000000..15aab33
--- /dev/null
@@ -0,0 +1,41 @@
+/* -*- 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 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.
+ */
+#ifndef INCLUDED_GR_MSG_HANDLER_H
+#define INCLUDED_GR_MSG_HANDLER_H
+
+#include <gr_message.h>
+
+class gr_msg_handler;
+typedef boost::shared_ptr<gr_msg_handler> gr_msg_handler_sptr;
+
+/*!
+ * \brief abstract class of message handlers
+ */
+class gr_msg_handler {
+public:
+  virtual ~gr_msg_handler ();
+  
+  //! handle \p msg
+  virtual void handle (gr_message_sptr msg) = 0;
+};
+
+#endif /* INCLUDED_GR_MSG_HANDLER_H */
diff --git a/gnuradio-core/src/lib/runtime/gr_msg_handler.i b/gnuradio-core/src/lib/runtime/gr_msg_handler.i
new file mode 100644 (file)
index 0000000..5571665
--- /dev/null
@@ -0,0 +1,32 @@
+/* -*- 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 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.
+ */
+
+/*!
+ * \brief abstract class of message handlers
+ */
+class gr_msg_handler {
+public:
+  virtual ~gr_msg_handler () = 0;
+  
+  //! handle \p msg
+  virtual void handle (gr_message_sptr msg) = 0;
+};
diff --git a/gnuradio-core/src/lib/runtime/gr_msg_queue.cc b/gnuradio-core/src/lib/runtime/gr_msg_queue.cc
new file mode 100644 (file)
index 0000000..6b53fc7
--- /dev/null
@@ -0,0 +1,127 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#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_head(0), d_tail(0),*/ d_count(0), d_limit(limit)
+{
+}
+
+gr_msg_queue::~gr_msg_queue()
+{
+  flush ();
+}
+
+void
+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);
+
+  while (full_p())
+    d_not_full.wait();
+
+  if (d_tail == 0){
+    d_tail = d_head = msg;
+    //msg->d_next = 0;
+    msg->d_next.reset();
+  }
+  else {
+    d_tail->d_next = msg;
+    d_tail = msg;
+    //msg->d_next = 0;
+    msg->d_next.reset();
+  }
+  d_count++;
+  d_not_empty.signal();
+}
+
+gr_message_sptr
+gr_msg_queue::delete_head()
+{
+  omni_mutex_lock      l(d_mutex);
+  gr_message_sptr      m;
+
+  while ((m = d_head) == 0)
+    d_not_empty.wait();
+
+  d_head = m->d_next;
+  if (d_head == 0){
+    //d_tail = 0;
+    d_tail.reset();
+  }
+
+  d_count--;
+  // m->d_next = 0;
+  m->d_next.reset();
+  d_not_full.signal();
+  return m;
+}
+
+gr_message_sptr
+gr_msg_queue::delete_head_nowait()
+{
+  omni_mutex_lock      l(d_mutex);
+  gr_message_sptr      m;
+
+  if ((m = d_head) == 0){
+    //return 0;
+    return gr_message_sptr();
+  }
+
+  d_head = m->d_next;
+  if (d_head == 0){
+    //d_tail = 0;
+    d_tail.reset();
+  }
+
+  d_count--;
+  //m->d_next = 0;
+  m->d_next.reset();
+  d_not_full.signal();
+  return m;
+}
+
+void
+gr_msg_queue::flush()
+{
+  gr_message_sptr      m;
+
+  while ((m = delete_head_nowait ()) != 0)
+    ;
+}
diff --git a/gnuradio-core/src/lib/runtime/gr_msg_queue.h b/gnuradio-core/src/lib/runtime/gr_msg_queue.h
new file mode 100644 (file)
index 0000000..6a9147e
--- /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 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.
+ */
+#ifndef INCLUDED_GR_MSG_QUEUE_H
+#define INCLUDED_GR_MSG_QUEUE_H
+
+#include <gr_msg_handler.h>
+#include <omnithread.h>
+
+class gr_msg_queue;
+typedef boost::shared_ptr<gr_msg_queue> gr_msg_queue_sptr;
+
+gr_msg_queue_sptr gr_make_msg_queue(unsigned int limit=0);
+
+/*!
+ * \brief thread-safe message queue
+ */
+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
+
+public:
+  gr_msg_queue(unsigned int limit);
+  ~gr_msg_queue();
+
+  //! Generic msg_handler method: insert the message.
+  void handle(gr_message_sptr msg) { insert_tail (msg); }
+
+  /*!
+   * \brief Insert message at tail of queue.
+   * \param msg message
+   *
+   * Block if queue if full.
+   */
+  void insert_tail(gr_message_sptr msg);
+
+  /*!
+   * \brief Delete message from head of queue and return it.
+   * Block if no message is available.
+   */
+  gr_message_sptr delete_head();
+
+  /*!
+   * \brief If there's a message in the q, delete it and return it.
+   * If no message is available, return 0.
+   */
+  gr_message_sptr delete_head_nowait();
+  
+  //! Delete all messages from the queue
+  void flush();
+
+  //! is the queue empty?
+  bool empty_p() const { return d_count == 0; }
+  
+  //! is the queue full?
+  bool full_p() const { return d_limit != 0 && d_count >= d_limit; }
+  
+  //! return number of messages in queue
+  unsigned int count() const { return d_count; }
+
+  //! return limit on number of message in queue.  0 -> unbounded
+  unsigned int limit() const { return d_limit; }
+
+};
+
+#endif /* INCLUDED_GR_MSG_QUEUE_H */
diff --git a/gnuradio-core/src/lib/runtime/gr_msg_queue.i b/gnuradio-core/src/lib/runtime/gr_msg_queue.i
new file mode 100644 (file)
index 0000000..28292d6
--- /dev/null
@@ -0,0 +1,111 @@
+/* -*- 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 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.
+ */
+
+class gr_msg_queue;
+typedef boost::shared_ptr<gr_msg_queue> gr_msg_queue_sptr;
+%template(gr_msg_queue_sptr) boost::shared_ptr<gr_msg_queue>;
+
+%rename(msg_queue) gr_make_msg_queue;
+gr_msg_queue_sptr gr_make_msg_queue(unsigned limit=0);
+
+/*!
+ * \brief thread-safe message queue
+ */
+%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();
+  ~gr_msg_queue();
+
+  //! Generic msg_handler method: insert the message.
+  //void handle(gr_message_sptr msg) { insert_tail (msg); }
+
+  /*!
+   * \brief Insert message at tail of queue.
+   * \param msg message
+   *
+   * Block if queue if full.
+   */
+  //void insert_tail(gr_message_sptr msg);
+
+  /*!
+   * \brief Delete message from head of queue and return it.
+   * Block if no message is available.
+   */
+  //gr_message_sptr delete_head();
+
+  /*!
+   * \brief If there's a message in the q, delete it and return it.
+   * If no message is available, return 0.
+   */
+  gr_message_sptr delete_head_nowait();
+  
+  //! is the queue empty?
+  bool empty_p() const;
+  
+  //! is the queue full?
+  bool full_p() const;
+  
+  //! return number of messages in queue
+  unsigned int count() const;
+
+  //! Delete all messages from the queue
+  void flush();
+};
+
+/*
+ * The following kludge-o-rama releases the Python global interpreter
+ * lock around these potentially blocking calls.  We don't want
+ * libgnuradio-core to be dependent on Python, thus we create these
+ * functions that serve as replacements for the normal C++ delete_head
+ * and insert_tail methods.  The %pythoncode smashes these new C++
+ * functions into the gr.msg_queue wrapper class, so that everything
+ * appears normal.  (An evil laugh is heard in the distance...)
+ */
+%inline {
+  gr_message_sptr gr_py_msg_queue__delete_head(gr_msg_queue_sptr q) {
+    gr_message_sptr msg;
+    Py_BEGIN_ALLOW_THREADS;            // release global interpreter lock
+    msg = q->delete_head();            // possibly blocking call
+    Py_END_ALLOW_THREADS;              // acquire global interpreter lock
+    return msg;
+  }
+
+  void gr_py_msg_queue__insert_tail(gr_msg_queue_sptr q, gr_message_sptr msg) {
+    Py_BEGIN_ALLOW_THREADS;            // release global interpreter lock
+    q->insert_tail(msg);               // possibly blocking call
+    Py_END_ALLOW_THREADS;              // acquire global interpreter lock
+  }
+}
+
+// smash in new python delete_head and insert_tail methods...
+%pythoncode %{
+gr_msg_queue_sptr.delete_head = gr_py_msg_queue__delete_head
+gr_msg_queue_sptr.insert_tail = gr_py_msg_queue__insert_tail
+gr_msg_queue_sptr.handle = gr_py_msg_queue__insert_tail
+%}
diff --git a/gnuradio-core/src/lib/runtime/gr_pagesize.cc b/gnuradio-core/src/lib/runtime/gr_pagesize.cc
new file mode 100644 (file)
index 0000000..dec4067
--- /dev/null
@@ -0,0 +1,56 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_pagesize.h>
+#include <unistd.h>
+#include <stdio.h>
+
+#if defined(_WIN32) && defined(HAVE_GETPAGESIZE)
+extern "C" size_t getpagesize(void);
+#endif
+
+int
+gr_pagesize ()
+{
+  static int s_pagesize = -1;
+
+  if (s_pagesize == -1){
+#if defined(HAVE_GETPAGESIZE)
+    s_pagesize = getpagesize ();
+#elif defined (HAVE_SYSCONF)
+    s_pagesize = sysconf (_SC_PAGESIZE);
+    if (s_pagesize == -1){
+      perror ("_SC_PAGESIZE");
+      s_pagesize = 4096;
+    }
+#else
+    fprintf (stderr, "gr_pagesize: no info; setting pagesize = 4096\n");
+    s_pagesize = 4096;
+#endif
+  }
+  return s_pagesize;
+}
+
diff --git a/gnuradio-core/src/lib/runtime/gr_pagesize.h b/gnuradio-core/src/lib/runtime/gr_pagesize.h
new file mode 100644 (file)
index 0000000..a5cadb7
--- /dev/null
@@ -0,0 +1,32 @@
+/* -*- 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 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.
+ */
+#ifndef _GR_PAGESIZE_H_
+#define _GR_PAGESIZE_H_
+
+/*!
+ * \brief return the page size in bytes
+ */
+
+int gr_pagesize ();
+
+
+#endif /* _GR_PAGESIZE_H_ */
diff --git a/gnuradio-core/src/lib/runtime/gr_preferences.cc b/gnuradio-core/src/lib/runtime/gr_preferences.cc
new file mode 100644 (file)
index 0000000..8543144
--- /dev/null
@@ -0,0 +1,101 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_preferences.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+
+#ifdef MKDIR_TAKES_ONE_ARG
+#define gr_mkdir(pathname, mode) mkdir(pathname)
+#else
+#define gr_mkdir(pathname, mode) mkdir((pathname), (mode))
+#endif
+
+/*
+ * The simplest thing that could possibly work:
+ *  the key is the filename; the value is the file contents.
+ */
+
+static const char *
+pathname (const char *key)
+{
+  static char buf[200];
+  snprintf (buf, sizeof (buf), "%s/.gnuradio/prefs/%s", getenv ("HOME"), key);
+  return buf;
+}
+
+static void
+ensure_dir_path ()
+{
+  char path[200];
+  struct stat  statbuf;
+
+  snprintf (path, sizeof (path), "%s/.gnuradio/prefs", getenv ("HOME"));
+  if (stat (path, &statbuf) == 0 && S_ISDIR (statbuf.st_mode))
+    return;
+
+  // blindly try to make it    // FIXME make this robust. C++ SUCKS!
+
+  snprintf (path, sizeof (path), "%s/.gnuradio", getenv ("HOME"));
+  gr_mkdir (path, 0750);
+  snprintf (path, sizeof (path), "%s/.gnuradio/prefs", getenv ("HOME"));
+  gr_mkdir (path, 0750);
+}
+
+const char *
+gr_preferences::get (const char *key)
+{
+  static char buf[1024];
+
+  FILE         *fp = fopen (pathname (key), "r");
+  if (fp == 0)
+    return 0;
+
+  memset (buf, 0, sizeof (buf));
+  fread (buf, 1, sizeof (buf) - 1, fp);
+  fclose (fp);
+  return buf;
+}
+
+void 
+gr_preferences::set (const char *key, const char *value)
+{
+  ensure_dir_path ();
+
+  FILE *fp = fopen (pathname (key), "w");
+  if (fp == 0){
+    perror (pathname (key));
+    return;
+  }
+
+  fwrite (value, 1, strlen (value), fp);
+  fclose (fp);
+};
diff --git a/gnuradio-core/src/lib/runtime/gr_preferences.h b/gnuradio-core/src/lib/runtime/gr_preferences.h
new file mode 100644 (file)
index 0000000..5a7cad4
--- /dev/null
@@ -0,0 +1,32 @@
+/* -*- 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 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.
+ */
+
+#ifndef _GR_PREFERENCES_H_
+#define _GR_PREFERENCES_H_
+
+class gr_preferences {
+ public:
+  static const char *get (const char *key);
+  static void set (const char *key, const char *value);
+};
+
+#endif /* _GR_PREFERENCES_H_ */
diff --git a/gnuradio-core/src/lib/runtime/gr_realtime.cc b/gnuradio-core/src/lib/runtime/gr_realtime.cc
new file mode 100644 (file)
index 0000000..4f23ea0
--- /dev/null
@@ -0,0 +1,71 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <gr_realtime.h>
+
+#ifdef HAVE_SCHED_H
+#include <sched.h>
+#endif
+
+#include <string.h>
+#include <errno.h>
+#include <stdio.h>
+
+#if defined(HAVE_SCHED_SETSCHEDULER)
+
+gr_rt_status_t
+gr_enable_realtime_scheduling()
+{
+  int policy = SCHED_FIFO;
+  int pri = (sched_get_priority_max (policy) - sched_get_priority_min (policy)) / 2;
+  int pid = 0;  // this process
+
+  struct sched_param param;
+  memset(&param, 0, sizeof(param));
+  param.sched_priority = pri;
+  int result = sched_setscheduler(pid, policy, &param);
+  if (result != 0){
+    if (errno == EPERM)
+      return RT_NO_PRIVS;
+    else {
+      perror ("sched_setscheduler: failed to set real time priority");
+      return RT_OTHER_ERROR;
+    }
+  }
+  //printf("SCHED_FIFO enabled with priority = %d\n", pri);
+  return RT_OK;
+}
+
+// #elif // could try negative niceness
+
+#else
+
+gr_rt_status_t
+gr_enable_realtime_scheduling()
+{
+  return RT_NOT_IMPLEMENTED;
+}
+
+#endif
diff --git a/gnuradio-core/src/lib/runtime/gr_realtime.h b/gnuradio-core/src/lib/runtime/gr_realtime.h
new file mode 100644 (file)
index 0000000..3aeafa5
--- /dev/null
@@ -0,0 +1,39 @@
+/* -*- 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 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.
+ */
+
+#ifndef INCLUDED_GR_REALTIME_H
+#define INCLUDED_GR_REALTIME_H
+
+typedef enum {
+  RT_OK = 0,
+  RT_NOT_IMPLEMENTED,
+  RT_NO_PRIVS,
+  RT_OTHER_ERROR
+} gr_rt_status_t;
+
+/*!
+ * \brief If possible, enable high-priority "real time" scheduling.
+ */
+gr_rt_status_t
+gr_enable_realtime_scheduling();
+
+#endif /* INCLUDED_GR_REALTIME_H */
diff --git a/gnuradio-core/src/lib/runtime/gr_realtime.i b/gnuradio-core/src/lib/runtime/gr_realtime.i
new file mode 100644 (file)
index 0000000..cb43e05
--- /dev/null
@@ -0,0 +1,4 @@
+%rename(enable_realtime_scheduling) gr_enable_realtime_scheduling;
+
+%include <gr_realtime.h>
+
diff --git a/gnuradio-core/src/lib/runtime/gr_runtime.h b/gnuradio-core/src/lib/runtime/gr_runtime.h
new file mode 100644 (file)
index 0000000..f138e6a
--- /dev/null
@@ -0,0 +1,44 @@
+/* -*- 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 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.
+ */
+
+#ifndef INCLUDED_GR_RUNTIME_H
+#define INCLUDED_GR_RUNTIME_H
+
+#include <gr_types.h>
+
+/*
+ * typedefs for smart pointers we use throughout the runtime system
+ */
+
+class gr_block;
+class gr_block_detail;
+class gr_io_signature;
+class gr_buffer;
+class gr_buffer_reader;
+
+typedef boost::shared_ptr<gr_block>            gr_block_sptr;
+typedef boost::shared_ptr<gr_block_detail>     gr_block_detail_sptr;
+typedef boost::shared_ptr<gr_io_signature>     gr_io_signature_sptr;
+typedef boost::shared_ptr<gr_buffer>           gr_buffer_sptr;
+typedef boost::shared_ptr<gr_buffer_reader>    gr_buffer_reader_sptr;
+
+#endif /* INCLUDED_GR_RUNTIME_H */
diff --git a/gnuradio-core/src/lib/runtime/gr_select_handler.cc b/gnuradio-core/src/lib/runtime/gr_select_handler.cc
new file mode 100644 (file)
index 0000000..d85883a
--- /dev/null
@@ -0,0 +1,36 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_select_handler.h>
+
+gr_select_handler::gr_select_handler(int fd)
+  : d_fd(fd)
+{
+}
+
+gr_select_handler::~gr_select_handler()
+{
+}
diff --git a/gnuradio-core/src/lib/runtime/gr_select_handler.h b/gnuradio-core/src/lib/runtime/gr_select_handler.h
new file mode 100644 (file)
index 0000000..d07ff00
--- /dev/null
@@ -0,0 +1,83 @@
+/* -*- 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 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.
+ */
+
+#ifndef INCLUDED_GR_SELECT_HANDLER_H
+#define INCLUDED_GR_SELECT_HANDLER_H
+
+#include <boost/shared_ptr.hpp>
+
+class gr_select_handler;
+typedef boost::shared_ptr<gr_select_handler> gr_select_handler_sptr;
+
+
+/*!
+ * \brief Abstract handler for select based notification.
+ *
+ * \sa gr_dispatcher
+ */
+class gr_select_handler
+{
+  int  d_fd;
+
+protected:
+  gr_select_handler(int file_descriptor);
+
+public:
+  virtual ~gr_select_handler();
+
+  int fd() const { return d_fd; }
+  int file_descriptor() const { return d_fd; }
+
+  /*!
+   * \brief Called when file_descriptor is readable.
+   *
+   * Called when the dispatcher detects that file_descriptor can
+   * be read without blocking.
+   */
+  virtual void handle_read() = 0;
+
+  /*!
+   * \brief Called when file_descriptor is writable.
+   *
+   * Called when dispatcher detects that file descriptor can be 
+   * written without blocking.
+   */
+  virtual void handle_write() = 0;
+
+  /*!
+   * Called each time around the dispatcher loop to determine whether
+   * this handler's file descriptor should be added to the list on which
+   * read events can occur.  The default method returns true, indicating
+   * that by default, all handlers are interested in read events.
+   */
+  virtual bool readable() { return true; }
+
+  /*!
+   * Called each time around the dispatcher loop to determine whether
+   * this handler's file descriptor should be added to the list on which
+   * write events can occur.  The default method returns true, indicating
+   * that by default, all handlers are interested in write events.
+   */
+  virtual bool writable() { return true; }
+};
+
+#endif /* INCLUDED_GR_SELECT_HANDLER_H */
diff --git a/gnuradio-core/src/lib/runtime/gr_single_threaded_scheduler.cc b/gnuradio-core/src/lib/runtime/gr_single_threaded_scheduler.cc
new file mode 100644 (file)
index 0000000..3d40155
--- /dev/null
@@ -0,0 +1,360 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_single_threaded_scheduler.h>
+#include <gr_block.h>
+#include <gr_block_detail.h>
+#include <gr_buffer.h>
+#include <iostream>
+#include <limits>
+#include <assert.h>
+#include <stdio.h>
+
+// must be defined to either 0 or 1
+#define ENABLE_LOGGING 0
+
+#if (ENABLE_LOGGING)
+#define LOG(x) do { x; } while(0)
+#else
+#define LOG(x) do {;} while(0)
+#endif
+
+static int which_scheduler  = 0;
+
+
+std::ostream&
+operator << (std::ostream& os, const gr_block *m)
+{
+  os << "<gr_block " << m->name() << " (" << m->unique_id() << ")>";
+  return os;
+}
+
+gr_single_threaded_scheduler_sptr
+gr_make_single_threaded_scheduler (const std::vector<gr_block_sptr> &blocks)
+{
+  return
+    gr_single_threaded_scheduler_sptr (new gr_single_threaded_scheduler (blocks));
+}
+
+gr_single_threaded_scheduler::gr_single_threaded_scheduler (
+    const std::vector<gr_block_sptr> &blocks)
+  : d_blocks (blocks), d_enabled (true), d_log(0)
+{
+  if (ENABLE_LOGGING){
+    char name[100];
+    snprintf(name, sizeof(name), "sst-%d.log", which_scheduler++);
+    d_log = new std::ofstream(name);
+    *d_log << "gr_single_threaded_scheduler: "
+          << d_blocks.size ()
+          << " blocks\n";
+  }
+}
+
+gr_single_threaded_scheduler::~gr_single_threaded_scheduler ()
+{
+  if (ENABLE_LOGGING)
+    delete d_log;
+}
+
+void
+gr_single_threaded_scheduler::run ()
+{
+  d_enabled = true;
+  main_loop ();
+}
+
+
+inline static unsigned int
+round_up (unsigned int n, unsigned int multiple)
+{
+  return ((n + multiple - 1) / multiple) * multiple;
+}
+
+inline static unsigned int
+round_down (unsigned int n, unsigned int multiple)
+{
+  return (n / multiple) * multiple;
+}
+
+//
+// Return minimum available write space in all our downstream buffers
+// or -1 if we're output blocked and the output we're blocked
+// on is done.
+//
+static int
+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++){
+    int n = round_down (d->output(i)->space_available (), output_multiple);
+    if (n == 0){                       // We're blocked on output.
+      if (d->output(i)->done()){       // Downstream is done, therefore we're done.
+       return -1;
+      }
+      return 0;
+    }
+    min_space = std::min (min_space, n);
+  }
+  return min_space;
+}
+
+void
+gr_single_threaded_scheduler::main_loop ()
+{
+  static const int DEFAULT_CAPACITY = 16;
+
+  int                          noutput_items;
+  gr_vector_int                        ninput_items_required (DEFAULT_CAPACITY);
+  gr_vector_int                        ninput_items (DEFAULT_CAPACITY);
+  gr_vector_const_void_star    input_items (DEFAULT_CAPACITY);
+  gr_vector_void_star          output_items (DEFAULT_CAPACITY);
+  unsigned int                 bi;
+  unsigned int                 nalive;
+  int                          max_items_avail;
+  bool                         made_progress_last_pass;
+  bool                         making_progress;
+
+  for (unsigned i = 0; i < d_blocks.size (); i++)
+    d_blocks[i]->detail()->set_done (false);           // reset any done flags
+
+  for (unsigned i = 0; i < d_blocks.size (); i++)      // enable any drivers, etc.
+    d_blocks[i]->start();
+
+
+  bi = 0;
+  made_progress_last_pass = true;
+  making_progress = false;
+
+  // Loop while there are still blocks alive
+
+  nalive = d_blocks.size ();
+  while (d_enabled && nalive > 0){
+
+    gr_block           *m = d_blocks[bi].get ();
+    gr_block_detail    *d = m->detail().get ();
+
+    LOG(*d_log << std::endl << m);
+
+    if (d->done ())
+      goto next_block;
+
+    if (d->source_p ()){
+      // Invoke sources as a last resort.  As long as the previous pass
+      // made progress, don't call a source.
+      if (made_progress_last_pass){
+       LOG(*d_log << "  Skipping source\n");
+       goto next_block;
+      }
+
+      ninput_items_required.resize (0);
+      ninput_items.resize (0);
+      input_items.resize (0);
+      output_items.resize (d->noutputs ());
+
+      // determine the minimum available output space
+      noutput_items = min_available_space (d, m->output_multiple ());
+      LOG(*d_log << " source\n  noutput_items = " << noutput_items << std::endl);
+      if (noutput_items == -1)         // we're done
+       goto were_done;
+
+      if (noutput_items == 0){         // we're output blocked
+       LOG(*d_log << "  BLKD_OUT\n");
+       goto next_block;
+      }
+
+      goto setup_call_to_work;         // jump to common code
+    }
+
+    else if (d->sink_p ()){
+      ninput_items_required.resize (d->ninputs ());
+      ninput_items.resize (d->ninputs ());
+      input_items.resize (d->ninputs ());
+      output_items.resize (0);
+      LOG(*d_log << " sink\n");
+
+      max_items_avail = 0;
+      for (int i = 0; i < d->ninputs (); i++){
+       ninput_items[i] = d->input(i)->items_available();
+       //if (ninput_items[i] == 0 && d->input(i)->done())
+       if (ninput_items[i] < m->output_multiple() && d->input(i)->done())
+         goto were_done;
+       
+       max_items_avail = std::max (max_items_avail, ninput_items[i]);
+      }
+
+      // take a swag at how much output we can sink
+      noutput_items = (int) (max_items_avail * m->relative_rate ());
+      noutput_items = round_down (noutput_items, m->output_multiple ());
+      LOG(*d_log << "  max_items_avail = " << max_items_avail << std::endl);
+      LOG(*d_log << "  noutput_items = " << noutput_items << std::endl);
+
+      if (noutput_items == 0){ // we're blocked on input
+       LOG(*d_log << "  BLKD_IN\n");
+       goto next_block;
+      }
+
+      goto try_again;          // Jump to code shared with regular case.
+    }
+
+    else {
+      // do the regular thing
+      ninput_items_required.resize (d->ninputs ());
+      ninput_items.resize (d->ninputs ());
+      input_items.resize (d->ninputs ());
+      output_items.resize (d->noutputs ());
+
+      max_items_avail = 0;
+      for (int i = 0; i < d->ninputs (); i++){
+       ninput_items[i] = d->input(i)->items_available ();
+       max_items_avail = std::max (max_items_avail, ninput_items[i]);
+      }
+
+      // determine the minimum available output space
+      noutput_items = min_available_space (d, m->output_multiple ());
+      if (ENABLE_LOGGING){
+       *d_log << " regular ";
+       if (m->relative_rate() >= 1.0)
+         *d_log << "1:" << m->relative_rate() << std::endl;
+       else
+         *d_log << 1.0/m->relative_rate() << ":1\n";
+       *d_log << "  max_items_avail = " << max_items_avail << std::endl;
+       *d_log << "  noutput_items = " << noutput_items << std::endl;
+      }
+      if (noutput_items == -1)         // we're done
+       goto were_done;
+
+      if (noutput_items == 0){         // we're output blocked
+       LOG(*d_log << "  BLKD_OUT\n");
+       goto next_block;
+      }
+
+#if 0
+      // Compute best estimate of noutput_items that we can really use.
+      noutput_items =
+       std::min ((unsigned) noutput_items,
+                 std::max ((unsigned) m->output_multiple(),
+                           round_up ((unsigned) (max_items_avail * m->relative_rate()),
+                                     m->output_multiple ())));
+
+      LOG(*d_log << "  revised noutput_items = " << noutput_items << std::endl);
+#endif
+
+    try_again:
+      if (m->fixed_rate()){
+       // try to work it forward starting with max_items_avail.
+       // We want to try to consume all the input we've got.
+       int reqd_noutput_items = m->fixed_rate_ninput_to_noutput(max_items_avail);
+       reqd_noutput_items = round_up(reqd_noutput_items, m->output_multiple());
+       if (reqd_noutput_items > 0 && reqd_noutput_items <= noutput_items)
+         noutput_items = reqd_noutput_items;
+      }
+
+      // ask the block how much input they need to produce noutput_items
+      m->forecast (noutput_items, ninput_items_required);
+
+      // See if we've got sufficient input available
+
+      int i;
+      for (i = 0; i < d->ninputs (); i++)
+       if (ninput_items_required[i] > ninput_items[i]) // not enough
+         break;
+
+      if (i < d->ninputs ()){                  // not enough input on input[i]
+       // if we can, try reducing the size of our output request
+       if (noutput_items > m->output_multiple ()){
+         noutput_items /= 2;
+         noutput_items = round_up (noutput_items, m->output_multiple ());
+         goto try_again;
+       }
+
+       // We're blocked on input
+       LOG(*d_log << "  BLKD_IN\n");
+       if (d->input(i)->done())    // If the upstream block is done, we're done
+         goto were_done;
+
+       // Is it possible to ever fulfill this request?
+       if (ninput_items_required[i] > d->input(i)->max_possible_items_available ()){
+         // Nope, never going to happen...
+         std::cerr << "\nsched: <gr_block " << m->name()
+                   << " (" << m->unique_id() << ")>"
+                   << " is requesting more input data\n"
+                   << "  than we can provide.\n"
+                   << "  ninput_items_required = "
+                   << ninput_items_required[i] << "\n"
+                   << "  max_possible_items_available = "
+                   << d->input(i)->max_possible_items_available() << "\n"
+                   << "  If this is a filter, consider reducing the number of taps.\n";
+         goto were_done;
+       }
+
+       goto next_block;
+      }
+
+      // We've got enough data on each input to produce noutput_items.
+      // Finish setting up the call to work.
+
+      for (int i = 0; i < d->ninputs (); i++)
+       input_items[i] = d->input(i)->read_pointer();
+
+    setup_call_to_work:
+
+      for (int i = 0; i < d->noutputs (); i++)
+       output_items[i] = d->output(i)->write_pointer();
+
+      // Do the actual work of the block
+      int n = m->general_work (noutput_items, ninput_items,
+                              input_items, output_items);
+      LOG(*d_log << "  general_work: noutput_items = " << noutput_items
+         << " result = " << n << std::endl);
+
+      if (n == -1)             // block is done
+       goto were_done;
+
+      d->produce_each (n);     // advance write pointers
+      if (n > 0)
+       making_progress = true;
+
+      goto next_block;
+    }
+    assert (0);
+    
+  were_done:
+    LOG(*d_log << "  were_done\n");
+    d->set_done (true);
+    nalive--;
+
+  next_block:
+    if (++bi >= d_blocks.size ()){
+      bi = 0;
+      made_progress_last_pass = making_progress;
+      making_progress = false;
+    }
+  }
+
+  for (unsigned i = 0; i < d_blocks.size (); i++)      // disable any drivers, etc.
+    d_blocks[i]->stop();
+}
diff --git a/gnuradio-core/src/lib/runtime/gr_single_threaded_scheduler.h b/gnuradio-core/src/lib/runtime/gr_single_threaded_scheduler.h
new file mode 100644 (file)
index 0000000..1272831
--- /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 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.
+ */
+
+#ifndef INCLUDED_GR_SINGLE_THREADED_SCHEDULER_H
+#define INCLUDED_GR_SINGLE_THREADED_SCHEDULER_H
+
+#include <gr_runtime.h>
+#include <fstream>
+
+class gr_single_threaded_scheduler;
+typedef boost::shared_ptr<gr_single_threaded_scheduler>        gr_single_threaded_scheduler_sptr;
+
+
+/*!
+ * \brief Simple scheduler for stream computations.
+ * \ingroup internal
+ */
+
+class gr_single_threaded_scheduler {
+ public:
+  ~gr_single_threaded_scheduler ();
+
+  void run ();
+  void stop () { d_enabled = false; }
+
+ private:
+  const std::vector<gr_block_sptr>     d_blocks;
+  volatile bool                                d_enabled;
+  std::ofstream                               *d_log;
+
+  gr_single_threaded_scheduler (const std::vector<gr_block_sptr> &blocks);
+
+  void main_loop ();
+  
+  friend gr_single_threaded_scheduler_sptr
+  gr_make_single_threaded_scheduler (const std::vector<gr_block_sptr> &blocks);
+};
+
+gr_single_threaded_scheduler_sptr
+gr_make_single_threaded_scheduler (const std::vector<gr_block_sptr> &blocks);
+
+#endif /* INCLUDED_GR_SINGLE_THREADED_SCHEDULER_H */
diff --git a/gnuradio-core/src/lib/runtime/gr_single_threaded_scheduler.i b/gnuradio-core/src/lib/runtime/gr_single_threaded_scheduler.i
new file mode 100644 (file)
index 0000000..4005822
--- /dev/null
@@ -0,0 +1,52 @@
+/* -*- 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 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.
+ */
+
+#include <gr_runtime.h>
+
+class gr_single_threaded_scheduler;
+typedef boost::shared_ptr<gr_single_threaded_scheduler>        gr_single_threaded_scheduler_sptr;
+%template(gr_single_threaded_scheduler_sptr) boost::shared_ptr<gr_single_threaded_scheduler>;
+%rename(single_threaded_scheduler) gr_make_single_threaded_scheduler;
+%ignore gr_single_threaded_scheduler;
+
+gr_single_threaded_scheduler_sptr 
+gr_make_single_threaded_scheduler (const std::vector<gr_block_sptr> &modules);
+
+class gr_single_threaded_scheduler {
+ public:
+  ~gr_single_threaded_scheduler ();
+
+  // void run ();
+  void stop ();
+
+ private:
+  gr_single_threaded_scheduler (const std::vector<gr_block_sptr> &modules);
+};
+
+%inline {
+  void sts_pyrun (gr_single_threaded_scheduler_sptr s) {
+    Py_BEGIN_ALLOW_THREADS;            // release global interpreter lock
+    s->run ();
+    Py_END_ALLOW_THREADS;              // acquire global interpreter lock
+  }
+}
+
diff --git a/gnuradio-core/src/lib/runtime/gr_swig_block_magic.i b/gnuradio-core/src/lib/runtime/gr_swig_block_magic.i
new file mode 100644 (file)
index 0000000..ca4f6e6
--- /dev/null
@@ -0,0 +1,45 @@
+/* -*- 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 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.
+ */
+
+%define GR_SWIG_BLOCK_MAGIC(PKG, BASE_NAME)
+_GR_SWIG_BLOCK_MAGIC_HELPER(PKG, PKG ## _ ## BASE_NAME, BASE_NAME)
+%enddef
+
+%define _GR_SWIG_BLOCK_MAGIC_HELPER(PKG, NAME, BASE_NAME)
+class NAME;
+typedef boost::shared_ptr<NAME> NAME ## _sptr;
+%template(NAME ## _sptr) boost::shared_ptr<NAME>;
+%rename(BASE_NAME) PKG ## _make_ ## BASE_NAME;
+%inline {
+  gr_block_sptr NAME ## _block (NAME ## _sptr r)
+  {
+    return gr_block_sptr (r);
+  }
+}
+
+%pythoncode %{
+NAME ## _sptr.block = lambda self: NAME ## _block (self)
+NAME ## _sptr.__repr__ = lambda self: "<gr_block %s (%d)>" % (self.name(), self.unique_id ())
+%}
+
+%ignore NAME;
+%enddef
diff --git a/gnuradio-core/src/lib/runtime/gr_timer.h b/gnuradio-core/src/lib/runtime/gr_timer.h
new file mode 100644 (file)
index 0000000..709b984
--- /dev/null
@@ -0,0 +1,82 @@
+/* -*- 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 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.
+ */
+#ifndef INCLUDED_GR_TIMER_H
+#define INCLUDED_GR_TIMER_H
+
+#include <gr_types.h>
+
+class gr_timer;
+
+typedef boost::shared_ptr<gr_timer> gr_timer_sptr;
+
+typedef void (*gr_timer_hook)(gr_timer *, void *);
+
+/*!
+ * \brief create a timeout.
+ *
+ * gr_timer_hook is called when timer fires.
+ */
+gr_timer_sptr gr_make_timer (gr_timer_hook, void *);
+
+/*!
+ * \brief implement timeouts
+ */
+class gr_timer {
+  double       d_expiry;
+  double       d_period;
+  gr_timer_hook        d_hook;
+  void        *d_hook_arg;
+
+  friend gr_timer_sptr gr_make_timer (gr_timer_hook, void *);
+
+  gr_timer (...);
+
+public:
+  ~gr_timer ();
+
+  //! return absolute current time (seconds since the epoc).
+  static double now ();
+  
+  /*!
+   * \brief schedule timer to fire at abs_when
+   * \param abs_when   absolute time in seconds since the epoc.
+   */
+  void schedule_at (double abs_when);
+
+  /*!
+   * \brief schedule timer to fire rel_when seconds from now.
+   * \param rel_when   relative time in seconds from now.
+   */
+  void schedule_after (double rel_when);       // relative time in seconds
+
+  /*!
+   * \brief schedule a periodic timeout.
+   * \param abs_when   absolute time to fire first time
+   * \param period     time between firings
+   */
+  void schedule_periodic (double abs_when, double period);
+
+  //! cancel timer
+  void unschedule ();
+};
+
+#endif /* INCLUDED_GR_TIMER_H */
diff --git a/gnuradio-core/src/lib/runtime/gr_tmp_path.cc b/gnuradio-core/src/lib/runtime/gr_tmp_path.cc
new file mode 100644 (file)
index 0000000..7eb03b5
--- /dev/null
@@ -0,0 +1,52 @@
+/* -*- 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 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.
+ */
+
+#include <gr_tmp_path.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+const char *
+gr_tmp_path ()
+{
+  static char *pp = 0;
+
+  if (pp)
+    return pp;
+
+  char *s = getenv ("TMP");
+  if (s){
+    pp = strdup (s);
+    return pp;
+  }
+
+#ifdef P_tmpdir
+  if (P_tmpdir){
+    pp = strdup (P_tmpdir);
+    return pp;
+  }
+#endif
+
+  pp = strdup ("/tmp");
+  return pp;
+}
+
diff --git a/gnuradio-core/src/lib/runtime/gr_tmp_path.h b/gnuradio-core/src/lib/runtime/gr_tmp_path.h
new file mode 100644 (file)
index 0000000..742ce05
--- /dev/null
@@ -0,0 +1,31 @@
+/* -*- 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 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.
+ */
+
+#ifndef _GR_TMP_PATH_H_
+#define _GR_TMP_PATH_H_
+
+/*!
+ * \brief return directory portion of pathname used for temporary files.
+ */
+const char *gr_tmp_path ();
+
+#endif /* _GR_TMP_PATH_H_ */
diff --git a/gnuradio-core/src/lib/runtime/gr_types.h b/gnuradio-core/src/lib/runtime/gr_types.h
new file mode 100644 (file)
index 0000000..370ca56
--- /dev/null
@@ -0,0 +1,63 @@
+/* -*- 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 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.
+ */
+
+#ifndef INCLUDED_GR_TYPES_H
+#define INCLUDED_GR_TYPES_H
+
+#include <boost/shared_ptr.hpp>
+#include <vector>
+#include <stddef.h>                            // size_t
+
+#include <gr_complex.h>
+
+typedef std::vector<int>                       gr_vector_int;
+typedef std::vector<float>                     gr_vector_float;
+typedef std::vector<double>                    gr_vector_double;
+typedef std::vector<void *>                    gr_vector_void_star;
+typedef std::vector<const void *>              gr_vector_const_void_star;
+
+/*
+ * #include <config.h> must be placed beforehand 
+ * in the source file including gr_types.h for
+ * the following to work correctly
+ */
+#ifdef HAVE_STDINT_H
+#include <stdint.h>
+typedef int16_t                        gr_int16;
+typedef int32_t                        gr_int32;
+typedef int64_t                        gr_int64;
+typedef uint16_t               gr_uint16;
+typedef uint32_t               gr_uint32;
+typedef uint64_t               gr_uint64;
+#else
+/*
+ * Note: these defaults may be wrong on 64-bit systems
+ */
+typedef short                  gr_int16;
+typedef int                    gr_int32;
+typedef long long              gr_int64;
+typedef unsigned short                 gr_uint16;
+typedef unsigned int                   gr_uint32;
+typedef unsigned long long     gr_uint64;
+#endif /* HAVE_STDINT_H */
+
+#endif /* INCLUDED_GR_TYPES_H */
diff --git a/gnuradio-core/src/lib/runtime/gr_vmcircbuf.cc b/gnuradio-core/src/lib/runtime/gr_vmcircbuf.cc
new file mode 100644 (file)
index 0000000..3586c4c
--- /dev/null
@@ -0,0 +1,291 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include <gr_vmcircbuf.h>
+#include <assert.h>
+#include <stdexcept>
+#include <gr_preferences.h>
+#include <stdio.h>
+#include <gr_local_sighandler.h>
+
+// all the factories we know about
+#include <gr_vmcircbuf_createfilemapping.h>
+#include <gr_vmcircbuf_sysv_shm.h>
+#include <gr_vmcircbuf_mmap_shm_open.h>
+#include <gr_vmcircbuf_mmap_tmpfile.h>
+
+static const char *FACTORY_PREF_KEY = "gr_vmcircbuf_default_factory";
+
+gr_vmcircbuf::~gr_vmcircbuf ()
+{
+}
+
+gr_vmcircbuf_factory::~gr_vmcircbuf_factory ()
+{
+}
+
+// ----------------------------------------------------------------
+
+static gr_vmcircbuf_factory *s_default_factory = 0;
+
+gr_vmcircbuf_factory *
+gr_vmcircbuf_sysconfig::get_default_factory ()
+{
+  if (s_default_factory)
+    return s_default_factory;
+
+  bool verbose = false;
+
+  std::vector<gr_vmcircbuf_factory *> all = all_factories ();
+
+  const char *name = gr_preferences::get (FACTORY_PREF_KEY);
+
+  if (name){
+    for (unsigned int i = 0; i < all.size (); i++){
+      if (strcmp (name, all[i]->name ()) == 0){
+       s_default_factory = all[i];
+       if (verbose)
+         fprintf (stderr, "gr_vmcircbuf_sysconfig: using %s\n",
+                  s_default_factory->name ());
+       return s_default_factory;
+      }
+    }
+  }
+
+  // either we don't have a default, or the default named is not in our
+  // list of factories.  Find the first factory that works.
+
+  if (verbose)
+    fprintf (stderr, "gr_vmcircbuf_sysconfig: finding a working factory...\n");
+
+  for (unsigned int i = 0; i < all.size (); i++){
+    if (test_factory (all[i], verbose)){
+      set_default_factory (all[i]);
+      return s_default_factory;
+    }
+  }
+
+  // We're screwed!
+
+  fprintf (stderr, "gr_vmcircbuf_sysconfig: unable to find a working factory!\n");
+  throw std::runtime_error ("gr_vmcircbuf_sysconfig");
+}
+
+std::vector<gr_vmcircbuf_factory *>
+gr_vmcircbuf_sysconfig::all_factories ()
+{
+  std::vector<gr_vmcircbuf_factory *> result;
+
+  result.push_back (gr_vmcircbuf_createfilemapping_factory::singleton ());
+  result.push_back (gr_vmcircbuf_sysv_shm_factory::singleton ());
+  result.push_back (gr_vmcircbuf_mmap_shm_open_factory::singleton ());
+  result.push_back (gr_vmcircbuf_mmap_tmpfile_factory::singleton ());
+
+  return result;
+}
+
+void
+gr_vmcircbuf_sysconfig::set_default_factory (gr_vmcircbuf_factory *f)
+{
+  gr_preferences::set (FACTORY_PREF_KEY, f->name ());
+  s_default_factory = f;
+}
+
+
+// ------------------------------------------------------------------------
+//                 test code for vmcircbuf factories
+// ------------------------------------------------------------------------
+
+static void
+init_buffer (gr_vmcircbuf *c, int counter, int size)
+{
+  unsigned int *p = (unsigned int *) c->pointer_to_first_copy ();
+  for (unsigned int i = 0; i < size / sizeof (int); i++)
+    p[i] = counter + i;
+}
+
+static bool
+check_mapping (gr_vmcircbuf *c, int counter, int size, char *msg, bool verbose)
+{
+  bool ok = true;
+  
+  if (verbose)
+    fprintf (stderr, "... %s", msg);
+
+  unsigned int *p1 = (unsigned int *) c->pointer_to_first_copy ();
+  unsigned int *p2 = (unsigned int *) c->pointer_to_second_copy ();
+
+  // fprintf (stderr, "p1 = %p, p2 = %p\n", p1, p2);
+
+  for (unsigned int i = 0; i < size / sizeof (int); i++){
+    if (p1[i] != counter + i){
+      ok = false;
+      if (verbose)
+       fprintf (stderr, "  p1[%d] == %u, expected %u\n", i, p1[i], counter + i);
+      break;
+    }
+    if (p2[i] != counter + i){
+      if (verbose)
+       fprintf (stderr, "  p2[%d] == %u, expected %u\n", i, p2[i], counter + i);
+      ok = false;
+      break;
+    }
+  }
+
+  if (ok && verbose){
+    fprintf (stderr, "  OK\n");
+  }
+  return ok;
+}
+
+static char *
+memsize (int size)
+{
+  static char buf[100];
+  if (size >= (1 << 20)){
+    snprintf (buf, sizeof (buf), "%dMB", size / (1 << 20));
+  }
+  else if (size >= (1 << 10)){
+    snprintf (buf, sizeof (buf), "%dKB", size / (1 << 10));
+  }
+  else {
+    snprintf (buf, sizeof (buf), "%d", size);
+  }
+  return buf;
+}
+
+static bool
+test_a_bunch (gr_vmcircbuf_factory *factory, int n, int size, int *start_ptr, bool verbose)
+{
+  bool         ok = true;
+  int          counter[n];
+  gr_vmcircbuf *c[n];
+  int          cum_size = 0;
+
+  for (int i = 0; i < n; i++){
+    counter[i] = *start_ptr;
+    *start_ptr += size;
+    if ((c[i] = factory->make (size)) == 0){
+      if (verbose)
+       fprintf (stderr,
+                "Failed to allocate gr_vmcircbuf number %d of size %d (cum = %s)\n",
+                i + 1, size, memsize (cum_size));
+      return false;
+    }
+    init_buffer (c[i], counter[i], size);
+    cum_size += size;
+  }
+
+  for (int i = 0; i < n; i++){
+    char msg[100];
+    snprintf (msg, sizeof (msg), "test_a_bunch_%dx%s[%d]", n, memsize (size), i);
+    ok &= check_mapping (c[i], counter[i], size, msg, verbose);
+  }
+
+  for (int i = 0; i < n; i++){
+    delete c[i];
+    c[i] = 0;
+  }
+
+  return ok;
+}
+
+static bool
+standard_tests (gr_vmcircbuf_factory *f, int verbose)
+{
+  if (verbose >= 1)
+    fprintf (stderr, "Testing %s...\n", f->name ());
+
+  bool  v = verbose >= 2;
+  int  granularity = f->granularity ();
+  int  start = 0;
+  bool ok = true;
+
+  ok &= test_a_bunch (f,   1,   1 * granularity, &start,  v);   //   1 x   4KB =   4KB
+
+  if (ok){
+    ok &= test_a_bunch (f,  64,   4 * granularity, &start, v);  // 256 x  16KB =   4MB
+    ok &= test_a_bunch (f,  32,   4 * (1L << 20),  &start, v);  //  32 x   4MB =  64MB
+    ok &= test_a_bunch (f, 256, 256 * (1L << 10),  &start, v);  // 256 x 256KB =  64MB
+  }
+
+  if (verbose >= 1)
+    fprintf (stderr, "....... %s: %s", f->name (), ok ? "OK\n" : "Doesn't work\n");
+
+  return ok;
+}
+
+bool
+gr_vmcircbuf_sysconfig::test_factory (gr_vmcircbuf_factory *f, int verbose)
+{
+  // Install local signal handlers for SIGSEGV and SIGBUS.
+  // If something goes wrong, these signals may be invoked.
+  
+#ifdef SIGSEGV
+  gr_local_sighandler sigsegv (SIGSEGV, gr_local_sighandler::throw_signal);
+#endif
+#ifdef SIGBUS
+  gr_local_sighandler sigbus (SIGBUS, gr_local_sighandler::throw_signal);
+#endif
+#ifdef SIGSYS
+  gr_local_sighandler sigsys (SIGSYS, gr_local_sighandler::throw_signal);
+#endif
+
+  try {
+    return standard_tests (f, verbose);
+  }
+  catch (gr_signal &sig){
+    if (verbose){
+      fprintf (stderr, "....... %s: %s", f->name (), "Doesn't work\n");
+      fprintf (stderr,
+              "gr_vmcircbuf_factory::test_factory (%s): caught %s\n",
+              f->name (), sig.name().c_str());
+      return false;
+    }
+  }
+  catch (...){
+    if (verbose){
+      fprintf (stderr, "....... %s: %s", f->name (), "Doesn't work\n");
+      fprintf (stderr,
+              "gr_vmcircbuf_factory::test_factory (%s): some kind of uncaught exception\n",
+              f->name ());
+    }
+    return false;
+  }
+  return false;                        // never gets here.  shut compiler up.
+}
+
+bool
+gr_vmcircbuf_sysconfig::test_all_factories (int verbose)
+{
+  bool ok = false;
+  
+  std::vector<gr_vmcircbuf_factory *> all = all_factories ();
+
+  for (unsigned int i = 0; i < all.size (); i++)
+    ok |= test_factory (all[i], verbose);
+
+  return ok;
+}
diff --git a/gnuradio-core/src/lib/runtime/gr_vmcircbuf.h b/gnuradio-core/src/lib/runtime/gr_vmcircbuf.h
new file mode 100644 (file)
index 0000000..e2af935
--- /dev/null
@@ -0,0 +1,120 @@
+/* -*- 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 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.
+ */
+
+#ifndef _GR_VMCIRCBUF_H_
+#define _GR_VMCIRCBUF_H_
+
+#include <vector>
+
+/*!
+ * \brief abstract class to implement doubly mapped virtual memory circular buffers
+ */
+class gr_vmcircbuf {
+ protected:
+  int   d_size;
+  char *d_base;
+
+  // CREATORS
+  gr_vmcircbuf (int size) : d_size (size), d_base (0) {};
+
+ public:
+  virtual ~gr_vmcircbuf ();
+
+  // ACCESSORS
+  void *pointer_to_first_copy ()  const { return d_base; }
+  void *pointer_to_second_copy () const { return d_base + d_size; }
+};
+
+/*!
+ * \brief abstract factory for creating circular buffers
+ */
+class gr_vmcircbuf_factory {
+ protected:
+  gr_vmcircbuf_factory () {};
+  virtual ~gr_vmcircbuf_factory ();
+
+ public:
+
+  /*!
+   * \brief return name of this factory
+   */
+  virtual const char *name () const = 0;
+
+  /*!
+   * \brief return granularity of mapping, typically equal to page size
+   */
+  virtual int granularity () = 0;
+
+  /*!
+   * \brief return a gr_vmcircbuf, or 0 if unable.
+   *
+   * Call this to create a doubly mapped circular buffer.
+   */
+  virtual gr_vmcircbuf *make (int size) = 0;
+};
+
+/*
+ * \brief pulls together all implementations of gr_vmcircbuf
+ */
+class gr_vmcircbuf_sysconfig {
+ public:
+
+  /*
+   * \brief return the single instance of the default factory.
+   *
+   * returns the default factory to use if it's already defined,
+   * else find the first working factory and use it.
+   */
+  static gr_vmcircbuf_factory *get_default_factory ();
+
+    
+  static int granularity ()           { return get_default_factory()->granularity(); }
+  static gr_vmcircbuf *make (int size) { return get_default_factory()->make(size);    }
+  
+
+  // N.B. not all factories are guaranteed to work.
+  // It's too hard to check everything at config time, so we check at runtime
+  static std::vector<gr_vmcircbuf_factory *> all_factories ();
+
+  // make this factory the default
+  static void set_default_factory (gr_vmcircbuf_factory *f);
+
+  /*!
+   * \brief  Does this factory really work?
+   *
+   * verbose = 0: silent
+   * verbose = 1: names of factories tested and results
+   * verbose = 2: all intermediate results
+   */
+  static bool test_factory (gr_vmcircbuf_factory *f, int verbose);
+
+  /*!
+   * \brief Test all factories, return true if at least one of them works
+   * verbose = 0: silent
+   * verbose = 1: names of factories tested and results
+   * verbose = 2: all intermediate results
+   */
+  static bool test_all_factories (int verbose);
+};
+
+
+#endif /* _GR_VMCIRCBUF_H_ */
diff --git a/gnuradio-core/src/lib/runtime/gr_vmcircbuf_createfilemapping.cc b/gnuradio-core/src/lib/runtime/gr_vmcircbuf_createfilemapping.cc
new file mode 100644 (file)
index 0000000..8f3540b
--- /dev/null
@@ -0,0 +1,191 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include <stdexcept>
+#include <assert.h>
+#include <unistd.h>
+#include <fcntl.h>
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_MMAN_H
+#include <sys/mman.h>
+#endif
+#include <errno.h>
+#include <stdio.h>
+#include <gr_pagesize.h>
+#include <gr_tmp_path.h>
+#include <gr_vmcircbuf_createfilemapping.h>
+
+
+gr_vmcircbuf_createfilemapping::gr_vmcircbuf_createfilemapping (int size)
+  : gr_vmcircbuf (size)
+{
+#if !defined(HAVE_CREATEFILEMAPPING)
+  fprintf (stderr, "%s: createfilemapping is not available\n",__FUNCTION__);
+  throw std::runtime_error ("gr_vmcircbuf_createfilemapping");
+#else
+  static int s_seg_counter = 0;
+
+  if (size <= 0 || (size % gr_pagesize ()) != 0){
+    fprintf (stderr, "gr_vmcircbuf_createfilemapping: invalid size = %d\n", size);
+    throw std::runtime_error ("gr_vmcircbuf_createfilemapping");
+  }
+
+  char    seg_name[1024];
+  snprintf (seg_name, sizeof (seg_name), "/gnuradio-%d-%d", getpid (), s_seg_counter);
+
+  d_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
+
+  s_seg_counter++;
+  if (d_handle == NULL || d_handle == INVALID_HANDLE_VALUE){
+    char msg[1024];
+    snprintf (msg, sizeof (msg), "gr_vmcircbuf_mmap_createfilemapping: CreateFileMapping [%s] :%d", seg_name,(int)GetLastError());
+    perror (msg);
+    throw std::runtime_error ("gr_vmcircbuf_mmap_createfilemapping");
+  }
+
+  int i = 0;
+  d_first_copy = d_second_copy = NULL;
+    
+  while (i++ < 8 && d_second_copy == NULL){
+    // keep the first map allocation to force allocation in a new address
+    // space
+    LPVOID first_tmp = d_first_copy;
+        
+    d_first_copy =  MapViewOfFile((HANDLE)d_handle,   // handle to map object
+                                 FILE_MAP_WRITE,     // read/write permission
+                                 0,
+                                 0,
+                                 size);
+   
+    if (d_first_copy == NULL){
+      if (first_tmp)
+       UnmapViewOfFile(first_tmp);
+
+      CloseHandle(d_handle);         // cleanup
+      char msg[1024];
+      snprintf (msg, sizeof (msg),
+               "gr_vmcircbuf_mmap_createfilemapping: MapViewOfFile (1) :%d", (int)GetLastError());
+      perror (msg);
+      throw std::runtime_error ("gr_vmcircbuf_mmap_createfilemapping");
+    }
+
+    // NOTE: d_second_copy will be NULL if MapViewFileEx() fails to allocate the
+    //       requested address space
+    d_second_copy =  MapViewOfFileEx((HANDLE)d_handle,   // handle to map object
+                                    FILE_MAP_WRITE,     // read/write permission
+                                    0,
+                                    0,
+                                    size,
+                                    (char *)d_first_copy + size);//(LPVOID) ((char *)d_first_copy + size));
+
+    if (first_tmp)
+      UnmapViewOfFile(first_tmp);
+
+#ifdef DEBUG
+    fprintf (stderr,"gr_vmcircbuf_mmap_createfilemapping: contiguous? mmap %p %p %p %p, %d\n",
+            (char *)d_first_copy, (char *)d_second_copy, size, (char *)d_first_copy + size,i);
+#endif
+  }
+
+  if (d_second_copy == NULL){    // cleanup
+    fprintf (stderr,"gr_vmcircbuf_mmap_createfilemapping: non contiguous mmap - %p %p %p %p\n",
+            d_first_copy, d_second_copy, size, (char *)d_first_copy + size);
+    UnmapViewOfFile(d_first_copy);
+    CloseHandle(d_handle);                      // cleanup
+    throw std::runtime_error ("gr_vmcircbuf_mmap_createfilemapping");
+  }
+
+  // Now remember the important stuff
+  d_base = (char *) d_first_copy;
+  d_size = size;
+#endif /*HAVE_CREATEFILEMAPPING*/
+}
+
+gr_vmcircbuf_createfilemapping::~gr_vmcircbuf_createfilemapping ()
+{
+#ifdef HAVE_CREATEFILEMAPPING
+  if (UnmapViewOfFile(d_first_copy) == 0)
+  {
+    perror ("gr_vmcircbuf_createfilemapping: UnmapViewOfFile(d_first_copy)");
+  }
+  d_base=NULL;
+  if (UnmapViewOfFile(d_second_copy) == 0)
+  {
+    perror ("gr_vmcircbuf_createfilemapping: UnmapViewOfFile(d_second_copy)");
+  }
+  //d_second=NULL;
+  CloseHandle(d_handle);
+#endif
+}
+
+// ----------------------------------------------------------------
+//      The factory interface
+// ----------------------------------------------------------------
+
+
+gr_vmcircbuf_factory *gr_vmcircbuf_createfilemapping_factory::s_the_factory = 0;
+
+gr_vmcircbuf_factory *
+gr_vmcircbuf_createfilemapping_factory::singleton ()
+{
+  if (s_the_factory)
+    return s_the_factory;
+  s_the_factory = new gr_vmcircbuf_createfilemapping_factory ();
+  return s_the_factory;
+}
+
+int
+gr_vmcircbuf_createfilemapping_factory::granularity ()
+{
+#ifdef HAVE_CREATEFILEMAPPING
+  //  return 65536;//TODO, check, is this needed or can we just use gr_pagesize()
+  SYSTEM_INFO system_info;
+  GetSystemInfo(&system_info);
+  //fprintf(stderr,"win32 AllocationGranularity %p\n",(int)system_info.dwAllocationGranularity);
+  return (int)system_info.dwAllocationGranularity;
+#else
+  return gr_pagesize ();
+#endif
+}
+
+gr_vmcircbuf *
+gr_vmcircbuf_createfilemapping_factory::make (int size)
+{
+  try
+  {
+    return new gr_vmcircbuf_createfilemapping (size);
+  }
+  catch (...)
+  {
+    return 0;
+  }
+}
diff --git a/gnuradio-core/src/lib/runtime/gr_vmcircbuf_createfilemapping.h b/gnuradio-core/src/lib/runtime/gr_vmcircbuf_createfilemapping.h
new file mode 100644 (file)
index 0000000..f7113cf
--- /dev/null
@@ -0,0 +1,74 @@
+/* -*- 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 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.
+ */
+
+#ifndef _GR_VMCIRCBUF_CREATEFILEMAPPING_H_
+#define _GR_VMCIRCBUF_CREATEFILEMAPPING_H_
+
+#include <gr_vmcircbuf.h>
+
+#ifdef HAVE_CREATEFILEMAPPING
+#include <windows.h>
+#endif
+/*!
+ * \brief concrete class to implement circular buffers with mmap and shm_open
+ */
+class gr_vmcircbuf_createfilemapping : public gr_vmcircbuf
+{
+ public:
+   // CREATORS
+   gr_vmcircbuf_createfilemapping (int size);
+   virtual ~gr_vmcircbuf_createfilemapping ();
+#ifdef HAVE_CREATEFILEMAPPING
+ private:
+   HANDLE d_handle;
+   LPVOID d_first_copy;
+   LPVOID d_second_copy;
+#endif
+};
+
+/*!
+ * \brief concrete factory for circular buffers built using mmap and shm_open
+ */
+class gr_vmcircbuf_createfilemapping_factory : public gr_vmcircbuf_factory
+{
+ private:
+  static gr_vmcircbuf_factory *s_the_factory;
+
+ public:
+  static gr_vmcircbuf_factory *singleton ();
+
+  virtual const char *name () const { return "gr_vmcircbuf_createfilemapping_factory"; }
+
+  /*!
+   * \brief return granularity of mapping, typically equal to page size
+   */
+  virtual int granularity ();
+
+  /*!
+   * \brief return a gr_vmcircbuf, or 0 if unable.
+   *
+   * Call this to create a doubly mapped circular buffer.
+   */
+  virtual gr_vmcircbuf *make (int size);
+};
+
+#endif /* _GR_VMCIRCBUF_CREATEFILEMAPPING_H_ */
diff --git a/gnuradio-core/src/lib/runtime/gr_vmcircbuf_mmap_shm_open.cc b/gnuradio-core/src/lib/runtime/gr_vmcircbuf_mmap_shm_open.cc
new file mode 100644 (file)
index 0000000..65fa118
--- /dev/null
@@ -0,0 +1,205 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include <gr_vmcircbuf_mmap_shm_open.h>
+#include <stdexcept>
+#include <assert.h>
+#include <unistd.h>
+#include <fcntl.h>
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_MMAN_H
+#include <sys/mman.h>
+#endif
+#include <errno.h>
+#include <stdio.h>
+#include <gr_pagesize.h>
+#include <gr_tmp_path.h>
+
+
+gr_vmcircbuf_mmap_shm_open::gr_vmcircbuf_mmap_shm_open (int size)
+  : gr_vmcircbuf (size)
+{
+#if !defined(HAVE_MMAP) || !defined(HAVE_SHM_OPEN)
+  fprintf (stderr, "gr_vmcircbuf_mmap_shm_open: mmap or shm_open is not available\n");
+  throw std::runtime_error ("gr_vmcircbuf_mmap_shm_open");
+#else
+  static int s_seg_counter = 0;
+
+  if (size <= 0 || (size % gr_pagesize ()) != 0){
+    fprintf (stderr, "gr_vmcircbuf_mmap_shm_open: invalid size = %d\n", size);
+    throw std::runtime_error ("gr_vmcircbuf_mmap_shm_open");
+  }
+
+  int          shm_fd = -1;
+  char         seg_name[1024];
+  static bool  portable_format = true;
+  
+  // open a new named shared memory segment
+
+  while (1){
+    if (portable_format){
+
+      // This is the POSIX recommended "portable format".
+      // Of course the "portable format" doesn't work on some systems...
+      
+      snprintf (seg_name, sizeof (seg_name),
+               "/gnuradio-%d-%d", getpid (), s_seg_counter);
+    }
+    else {
+
+      // Where the "portable format" doesn't work, we try building
+      // a full filesystem pathname pointing into a suitable temporary directory.
+      
+      snprintf (seg_name, sizeof (seg_name),
+               "%s/gnuradio-%d-%d", gr_tmp_path (), getpid (), s_seg_counter);
+    }
+
+    shm_fd = shm_open (seg_name, O_RDWR | O_CREAT | O_EXCL, 0600);
+    if (shm_fd == -1 && errno == EACCES && portable_format){
+      portable_format = false;
+      continue;                        // try again using "non-portable format"
+    }
+
+    s_seg_counter++;
+
+    if (shm_fd == -1){
+      if (errno == EEXIST)     // Named segment already exists (shouldn't happen).  Try again
+       continue;
+
+      char msg[1024];
+      snprintf (msg, sizeof (msg), "gr_vmcircbuf_mmap_shm_open: shm_open [%s]", seg_name);
+      perror (msg);
+      throw std::runtime_error ("gr_vmcircbuf_mmap_shm_open");
+    }
+    break;
+  }
+
+  // We've got a new shared memory segment fd open.
+  // Now set it's length to 2x what we really want and mmap it in.
+
+  if (ftruncate (shm_fd, (off_t) 2 * size) == -1){
+    close (shm_fd);                                            // cleanup
+    perror ("gr_vmcircbuf_mmap_shm_open: ftruncate (1)");
+    throw std::runtime_error ("gr_vmcircbuf_mmap_shm_open");
+  }
+
+  void *first_copy = mmap (0, 2 * size,
+                          PROT_READ | PROT_WRITE, MAP_SHARED,
+                          shm_fd, (off_t) 0);
+
+  if (first_copy == MAP_FAILED){
+    close (shm_fd);                                            // cleanup
+    perror ("gr_vmcircbuf_mmap_shm_open: mmap (1)");
+    throw std::runtime_error ("gr_vmcircbuf_mmap_shm_open");
+  }
+
+  // unmap the 2nd half
+  if (munmap ((char *) first_copy + size, size) == -1){
+    close (shm_fd);                                            // cleanup
+    perror ("gr_vmcircbuf_mmap_shm_open: munmap (1)");
+    throw std::runtime_error ("gr_vmcircbuf_mmap_shm_open");
+  }
+
+  // map the first half into the now available hole where the
+  // second half used to be.
+
+  void *second_copy = mmap ((char *) first_copy + size, size,
+                           PROT_READ | PROT_WRITE, MAP_SHARED,
+                           shm_fd, (off_t) 0);
+
+  if (second_copy == MAP_FAILED){
+    close (shm_fd);                                            // cleanup
+    perror ("gr_vmcircbuf_mmap_shm_open: mmap (2)");
+    throw std::runtime_error ("gr_vmcircbuf_mmap_shm_open");
+  }
+
+#if 0  // OS/X doesn't allow you to resize the segment
+
+  // cut the shared memory segment down to size
+  if (ftruncate (shm_fd, (off_t) size) == -1){
+    close (shm_fd);                                            // cleanup
+    perror ("gr_vmcircbuf_mmap_shm_open: ftruncate (2)");
+    throw std::runtime_error ("gr_vmcircbuf_mmap_shm_open");
+  }
+#endif
+
+  close (shm_fd);      // fd no longer needed.  The mapping is retained.
+
+  if (shm_unlink (seg_name) == -1){    // unlink the seg_name.  
+    perror ("gr_vmcircbuf_mmap_shm_open: shm_unlink");
+    throw std::runtime_error ("gr_vmcircbuf_mmap_shm_open");
+  }
+
+  // Now remember the important stuff
+
+  d_base = (char *) first_copy;
+  d_size = size;
+#endif
+}
+
+gr_vmcircbuf_mmap_shm_open::~gr_vmcircbuf_mmap_shm_open ()
+{
+#if defined(HAVE_MMAP)  
+  if (munmap (d_base, 2 * d_size) == -1){
+    perror ("gr_vmcircbuf_mmap_shm_open: munmap (2)");
+  }
+#endif
+}
+
+// ----------------------------------------------------------------
+//                     The factory interface
+// ----------------------------------------------------------------
+
+
+gr_vmcircbuf_factory *gr_vmcircbuf_mmap_shm_open_factory::s_the_factory = 0;
+
+gr_vmcircbuf_factory *
+gr_vmcircbuf_mmap_shm_open_factory::singleton ()
+{
+  if (s_the_factory)
+    return s_the_factory;
+
+  s_the_factory = new gr_vmcircbuf_mmap_shm_open_factory ();
+  return s_the_factory;
+}
+
+int
+gr_vmcircbuf_mmap_shm_open_factory::granularity ()
+{
+  return gr_pagesize ();
+}
+
+gr_vmcircbuf *
+gr_vmcircbuf_mmap_shm_open_factory::make (int size)
+{
+  try {
+    return new gr_vmcircbuf_mmap_shm_open (size);
+  }
+  catch (...){
+    return 0;
+  }
+}
diff --git a/gnuradio-core/src/lib/runtime/gr_vmcircbuf_mmap_shm_open.h b/gnuradio-core/src/lib/runtime/gr_vmcircbuf_mmap_shm_open.h
new file mode 100644 (file)
index 0000000..4b1feaf
--- /dev/null
@@ -0,0 +1,65 @@
+/* -*- 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 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.
+ */
+
+#ifndef _GR_VMCIRCBUF_MMAP_SHM_OPEN_H_
+#define _GR_VMCIRCBUF_MMAP_SHM_OPEN_H_
+
+#include <gr_vmcircbuf.h>
+
+/*!
+ * \brief concrete class to implement circular buffers with mmap and shm_open
+ */
+class gr_vmcircbuf_mmap_shm_open : public gr_vmcircbuf {
+ public:
+
+  // CREATORS
+
+  gr_vmcircbuf_mmap_shm_open (int size);
+  virtual ~gr_vmcircbuf_mmap_shm_open ();
+};
+
+/*!
+ * \brief concrete factory for circular buffers built using mmap and shm_open
+ */
+class gr_vmcircbuf_mmap_shm_open_factory : public gr_vmcircbuf_factory {
+ private:
+  static gr_vmcircbuf_factory  *s_the_factory;
+
+ public:
+  static gr_vmcircbuf_factory *singleton ();
+
+  virtual const char *name () const { return "gr_vmcircbuf_mmap_shm_open_factory"; }
+
+  /*!
+   * \brief return granularity of mapping, typically equal to page size
+   */
+  virtual int granularity ();
+
+  /*!
+   * \brief return a gr_vmcircbuf, or 0 if unable.
+   *
+   * Call this to create a doubly mapped circular buffer.
+   */
+  virtual gr_vmcircbuf *make (int size);
+};
+
+#endif /* _GR_VMCIRCBUF_MMAP_SHM_OPEN_H_ */
diff --git a/gnuradio-core/src/lib/runtime/gr_vmcircbuf_mmap_tmpfile.cc b/gnuradio-core/src/lib/runtime/gr_vmcircbuf_mmap_tmpfile.cc
new file mode 100644 (file)
index 0000000..a07df77
--- /dev/null
@@ -0,0 +1,198 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include <gr_vmcircbuf_mmap_tmpfile.h>
+#include <stdexcept>
+#include <assert.h>
+#include <unistd.h>
+#include <stdlib.h>
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_MMAN_H
+#include <sys/mman.h>
+#endif
+#include <fcntl.h>
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <gr_pagesize.h>
+#include <gr_tmp_path.h>
+
+
+gr_vmcircbuf_mmap_tmpfile::gr_vmcircbuf_mmap_tmpfile (int size)
+  : gr_vmcircbuf (size)
+{
+#if !defined(HAVE_MMAP)
+  fprintf (stderr, "gr_vmcircbuf_mmap_tmpfile: mmap or mkstemp is not available\n");
+  throw std::runtime_error ("gr_vmcircbuf_mmap_tmpfile");
+#else
+
+  if (size <= 0 || (size % gr_pagesize ()) != 0){
+    fprintf (stderr, "gr_vmcircbuf_mmap_tmpfile: invalid size = %d\n", size);
+    throw std::runtime_error ("gr_vmcircbuf_mmap_tmpfile");
+  }
+
+  int  seg_fd = -1;
+  char seg_name[1024];
+  
+  static int s_seg_counter = 0;
+
+
+  // open a temporary file that we'll map in a bit later
+
+  while (1){
+    snprintf (seg_name, sizeof (seg_name),
+             "%s/gnuradio-%d-%d-XXXXXX", gr_tmp_path (), getpid (), s_seg_counter);
+    s_seg_counter++;
+
+    seg_fd = open (seg_name, O_RDWR | O_CREAT | O_EXCL, 0600);
+    if (seg_fd == -1){
+      if (errno == EEXIST)     // File already exists (shouldn't happen).  Try again
+       continue;
+
+      char msg[1024];
+      snprintf (msg, sizeof (msg),
+               "gr_vmcircbuf_mmap_tmpfile: open [%s]", seg_name);
+      perror (msg);
+      throw std::runtime_error ("gr_vmcircbuf_mmap_tmpfile");
+    }
+    break;
+  }
+
+  if (unlink (seg_name) == -1){
+    perror ("gr_vmcircbuf_mmap_tmpfile: unlink");
+    throw std::runtime_error ("gr_vmcircbuf_mmap_tmpfile");
+  }
+
+  // We've got a valid file descriptor to a tmp file.
+  // Now set it's length to 2x what we really want and mmap it in.
+
+  if (ftruncate (seg_fd, (off_t) 2 * size) == -1){
+    close (seg_fd);                                            // cleanup
+    perror ("gr_vmcircbuf_mmap_tmpfile: ftruncate (1)");
+    throw std::runtime_error ("gr_vmcircbuf_mmap_tmpfile");
+  }
+
+  void *first_copy = mmap (0, 2 * size,
+                          PROT_READ | PROT_WRITE, MAP_SHARED,
+                          seg_fd, (off_t) 0);
+
+  if (first_copy == MAP_FAILED){
+    close (seg_fd);                                            // cleanup
+    perror ("gr_vmcircbuf_mmap_tmpfile: mmap (1)");
+    throw std::runtime_error ("gr_vmcircbuf_mmap_tmpfile");
+  }
+
+  // unmap the 2nd half
+  if (munmap ((char *) first_copy + size, size) == -1){
+    close (seg_fd);                                            // cleanup
+    perror ("gr_vmcircbuf_mmap_tmpfile: munmap (1)");
+    throw std::runtime_error ("gr_vmcircbuf_mmap_tmpfile");
+  }
+
+  // map the first half into the now available hole where the
+  // second half used to be.
+
+  void *second_copy = mmap ((char *) first_copy + size, size,
+                           PROT_READ | PROT_WRITE, MAP_SHARED,
+                           seg_fd, (off_t) 0);
+
+  if (second_copy == MAP_FAILED){
+    munmap(first_copy, size);                                  // cleanup
+    close (seg_fd);            
+    perror ("gr_vmcircbuf_mmap_tmpfile: mmap (2)");
+    throw std::runtime_error ("gr_vmcircbuf_mmap_tmpfile");
+  }
+
+  // check for contiguity
+  if ((char *) second_copy != (char *) first_copy + size){
+    munmap(first_copy, size);                                  // cleanup
+    munmap(second_copy, size);
+    close (seg_fd);                                            
+    perror ("gr_vmcircbuf_mmap_tmpfile: non-contiguous second copy");
+    throw std::runtime_error ("gr_vmcircbuf_mmap_tmpfile");
+  }
+
+  // cut the tmp file down to size
+  if (ftruncate (seg_fd, (off_t) size) == -1){
+    munmap(first_copy, size);                                  // cleanup
+    munmap(second_copy, size);
+    close (seg_fd);
+    perror ("gr_vmcircbuf_mmap_tmpfile: ftruncate (2)");
+    throw std::runtime_error ("gr_vmcircbuf_mmap_tmpfile");
+  }
+
+  close (seg_fd);      // fd no longer needed.  The mapping is retained.
+
+  // Now remember the important stuff
+
+  d_base = (char *) first_copy;
+  d_size = size;
+#endif
+}
+
+gr_vmcircbuf_mmap_tmpfile::~gr_vmcircbuf_mmap_tmpfile ()
+{
+#if defined(HAVE_MMAP)
+  if (munmap (d_base, 2 * d_size) == -1){
+    perror ("gr_vmcircbuf_mmap_tmpfile: munmap (2)");
+  }
+#endif
+}
+
+// ----------------------------------------------------------------
+//                     The factory interface
+// ----------------------------------------------------------------
+
+
+gr_vmcircbuf_factory *gr_vmcircbuf_mmap_tmpfile_factory::s_the_factory = 0;
+
+gr_vmcircbuf_factory *
+gr_vmcircbuf_mmap_tmpfile_factory::singleton ()
+{
+  if (s_the_factory)
+    return s_the_factory;
+
+  s_the_factory = new gr_vmcircbuf_mmap_tmpfile_factory ();
+  return s_the_factory;
+}
+
+int
+gr_vmcircbuf_mmap_tmpfile_factory::granularity ()
+{
+  return gr_pagesize ();
+}
+
+gr_vmcircbuf *
+gr_vmcircbuf_mmap_tmpfile_factory::make (int size)
+{
+  try {
+    return new gr_vmcircbuf_mmap_tmpfile (size);
+  }
+  catch (...){
+    return 0;
+  }
+}
diff --git a/gnuradio-core/src/lib/runtime/gr_vmcircbuf_mmap_tmpfile.h b/gnuradio-core/src/lib/runtime/gr_vmcircbuf_mmap_tmpfile.h
new file mode 100644 (file)
index 0000000..3b9f5db
--- /dev/null
@@ -0,0 +1,65 @@
+/* -*- 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 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.
+ */
+
+#ifndef _GR_VMCIRCBUF_MMAP_TMPFILE_H_
+#define _GR_VMCIRCBUF_MMAP_TMPFILE_H_
+
+#include <gr_vmcircbuf.h>
+
+/*!
+ * \brief concrete class to implement circular buffers with mmap and shm_open
+ */
+class gr_vmcircbuf_mmap_tmpfile : public gr_vmcircbuf {
+ public:
+
+  // CREATORS
+
+  gr_vmcircbuf_mmap_tmpfile (int size);
+  virtual ~gr_vmcircbuf_mmap_tmpfile ();
+};
+
+/*!
+ * \brief concrete factory for circular buffers built using mmap and shm_open
+ */
+class gr_vmcircbuf_mmap_tmpfile_factory : public gr_vmcircbuf_factory {
+ private:
+  static gr_vmcircbuf_factory  *s_the_factory;
+
+ public:
+  static gr_vmcircbuf_factory *singleton ();
+
+  virtual const char *name () const { return "gr_vmcircbuf_mmap_tmpfile_factory"; }
+
+  /*!
+   * \brief return granularity of mapping, typically equal to page size
+   */
+  virtual int granularity ();
+
+  /*!
+   * \brief return a gr_vmcircbuf, or 0 if unable.
+   *
+   * Call this to create a doubly mapped circular buffer.
+   */
+  virtual gr_vmcircbuf *make (int size);
+};
+
+#endif /* _GR_VMCIRCBUF_MMAP_TMPFILE_H_ */
diff --git a/gnuradio-core/src/lib/runtime/gr_vmcircbuf_sysv_shm.cc b/gnuradio-core/src/lib/runtime/gr_vmcircbuf_sysv_shm.cc
new file mode 100644 (file)
index 0000000..4b6fcfe
--- /dev/null
@@ -0,0 +1,192 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include <gr_vmcircbuf_sysv_shm.h>
+#include <stdexcept>
+#include <assert.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#ifdef HAVE_SYS_IPC_H
+#include <sys/ipc.h>
+#endif
+#ifdef HAVE_SYS_SHM_H
+#include <sys/shm.h>
+#endif
+#include <errno.h>
+#include <stdio.h>
+#include <gr_pagesize.h>
+
+
+gr_vmcircbuf_sysv_shm::gr_vmcircbuf_sysv_shm (int size)
+  : gr_vmcircbuf (size)
+{
+#if !defined(HAVE_SYS_SHM_H)
+  fprintf (stderr, "gr_vmcircbuf_sysv_shm: sysv shared memory is not available\n");
+  throw std::runtime_error ("gr_vmcircbuf_sysv_shm");
+#else
+
+  int pagesize = gr_pagesize();
+
+  if (size <= 0 || (size % pagesize) != 0){
+    fprintf (stderr, "gr_vmcircbuf_sysv_shm: invalid size = %d\n", size);
+    throw std::runtime_error ("gr_vmcircbuf_sysv_shm");
+  }
+
+  int shmid_guard = -1;
+  int shmid1 = -1;
+  int shmid2 = -1;
+
+  // We use this as a guard page.  We'll map it read-only on both ends of the buffer.
+  // Ideally we'd map it no access, but I don't think that's possible with SysV
+  if ((shmid_guard = shmget (IPC_PRIVATE, pagesize, IPC_CREAT | 0400)) == -1){
+    perror ("gr_vmcircbuf_sysv_shm: shmget (0)");
+    throw std::runtime_error ("gr_vmcircbuf_sysv_shm");
+  }
+
+  if ((shmid2 = shmget (IPC_PRIVATE, 2 * size + 2 * pagesize, IPC_CREAT | 0700)) == -1){
+    perror ("gr_vmcircbuf_sysv_shm: shmget (1)");
+    throw std::runtime_error ("gr_vmcircbuf_sysv_shm");
+  }
+
+  if ((shmid1 = shmget (IPC_PRIVATE, size, IPC_CREAT | 0700)) == -1){
+    perror ("gr_vmcircbuf_sysv_shm: shmget (2)");
+    shmctl (shmid2, IPC_RMID, 0);
+    throw std::runtime_error ("gr_vmcircbuf_sysv_shm");
+  }
+
+  void *first_copy = shmat (shmid2, 0, 0);
+  if (first_copy == (void *) -1){
+    perror ("gr_vmcircbuf_sysv_shm: shmat (1)");
+    shmctl (shmid_guard, IPC_RMID, 0);
+    shmctl (shmid2, IPC_RMID, 0);
+    shmctl (shmid1, IPC_RMID, 0);
+    throw std::runtime_error ("gr_vmcircbuf_sysv_shm");
+  }
+
+  shmctl (shmid2, IPC_RMID, 0);
+
+  // There may be a race between our detach and attach.
+  //
+  // If the system allocates all shared memory segments at the same
+  // virtual addresses in all processes and if the system allocates
+  // some other segment to first_copy or first_copoy + size between
+  // our detach and attach, the attaches below could fail [I've never
+  // seen it fail for this reason].
+  
+  shmdt (first_copy);
+
+  // first read-only guard page
+  if (shmat (shmid_guard, first_copy, SHM_RDONLY) == (void *) -1){
+    perror ("gr_vmcircbuf_sysv_shm: shmat (2)");
+    shmctl (shmid_guard, IPC_RMID, 0);
+    shmctl (shmid1, IPC_RMID, 0);
+    throw std::runtime_error ("gr_vmcircbuf_sysv_shm");
+  }
+
+  // first copy
+  if (shmat (shmid1, (char *) first_copy + pagesize, 0) == (void *) -1){
+    perror ("gr_vmcircbuf_sysv_shm: shmat (3)");
+    shmctl (shmid_guard, IPC_RMID, 0);
+    shmctl (shmid1, IPC_RMID, 0);
+    shmdt (first_copy);
+    throw std::runtime_error ("gr_vmcircbuf_sysv_shm");
+  }
+
+  // second copy
+  if (shmat (shmid1, (char *) first_copy + pagesize + size, 0) == (void *) -1){
+    perror ("gr_vmcircbuf_sysv_shm: shmat (4)");
+    shmctl (shmid_guard, IPC_RMID, 0);
+    shmctl (shmid1, IPC_RMID, 0);
+    shmdt ((char *)first_copy + pagesize);
+    throw std::runtime_error ("gr_vmcircbuf_sysv_shm");
+  }
+
+  // second read-only guard page
+  if (shmat (shmid_guard, (char *) first_copy + pagesize + 2 * size, SHM_RDONLY) == (void *) -1){
+    perror ("gr_vmcircbuf_sysv_shm: shmat (5)");
+    shmctl (shmid_guard, IPC_RMID, 0);
+    shmctl (shmid1, IPC_RMID, 0);
+    shmdt (first_copy);
+    shmdt ((char *)first_copy + pagesize);
+    shmdt ((char *)first_copy + pagesize + size);
+    throw std::runtime_error ("gr_vmcircbuf_sysv_shm");
+  }
+
+  shmctl (shmid1, IPC_RMID, 0);
+  shmctl (shmid_guard, IPC_RMID, 0);
+
+  // Now remember the important stuff
+
+  d_base = (char *) first_copy + pagesize;
+  d_size = size;
+#endif
+}
+
+gr_vmcircbuf_sysv_shm::~gr_vmcircbuf_sysv_shm ()
+{
+#if defined(HAVE_SYS_SHM_H)
+  if (shmdt (d_base - gr_pagesize()) == -1
+      || shmdt (d_base) == -1
+      || shmdt (d_base + d_size) == -1
+      || shmdt (d_base + 2 * d_size) == -1){
+    perror ("gr_vmcircbuf_sysv_shm: shmdt (2)");
+  }
+#endif
+}
+
+// ----------------------------------------------------------------
+//                     The factory interface
+// ----------------------------------------------------------------
+
+
+gr_vmcircbuf_factory *gr_vmcircbuf_sysv_shm_factory::s_the_factory = 0;
+
+gr_vmcircbuf_factory *
+gr_vmcircbuf_sysv_shm_factory::singleton ()
+{
+  if (s_the_factory)
+    return s_the_factory;
+
+  s_the_factory = new gr_vmcircbuf_sysv_shm_factory ();
+  return s_the_factory;
+}
+
+int
+gr_vmcircbuf_sysv_shm_factory::granularity ()
+{
+  return gr_pagesize ();
+}
+
+gr_vmcircbuf *
+gr_vmcircbuf_sysv_shm_factory::make (int size)
+{
+  try {
+    return new gr_vmcircbuf_sysv_shm (size);
+  }
+  catch (...){
+    return 0;
+  }
+}
diff --git a/gnuradio-core/src/lib/runtime/gr_vmcircbuf_sysv_shm.h b/gnuradio-core/src/lib/runtime/gr_vmcircbuf_sysv_shm.h
new file mode 100644 (file)
index 0000000..9a8c128
--- /dev/null
@@ -0,0 +1,65 @@
+/* -*- 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 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.
+ */
+
+#ifndef _GR_VMCIRCBUF_SYSV_SHM_H_
+#define _GR_VMCIRCBUF_SYSV_SHM_H_
+
+#include <gr_vmcircbuf.h>
+
+/*!
+ * \brief concrete class to implement circular buffers with mmap and shm_open
+ */
+class gr_vmcircbuf_sysv_shm : public gr_vmcircbuf {
+ public:
+
+  // CREATORS
+
+  gr_vmcircbuf_sysv_shm (int size);
+  virtual ~gr_vmcircbuf_sysv_shm ();
+};
+
+/*!
+ * \brief concrete factory for circular buffers built using mmap and shm_open
+ */
+class gr_vmcircbuf_sysv_shm_factory : public gr_vmcircbuf_factory {
+ private:
+  static gr_vmcircbuf_factory  *s_the_factory;
+
+ public:
+  static gr_vmcircbuf_factory *singleton ();
+
+  virtual const char *name () const { return "gr_vmcircbuf_sysv_shm_factory"; }
+
+  /*!
+   * \brief return granularity of mapping, typically equal to page size
+   */
+  virtual int granularity ();
+
+  /*!
+   * \brief return a gr_vmcircbuf, or 0 if unable.
+   *
+   * Call this to create a doubly mapped circular buffer.
+   */
+  virtual gr_vmcircbuf *make (int size);
+};
+
+#endif /* _GR_VMCIRCBUF_SYSV_SHM_H_ */
diff --git a/gnuradio-core/src/lib/runtime/qa_gr_block.cc b/gnuradio-core/src/lib/runtime/qa_gr_block.cc
new file mode 100644 (file)
index 0000000..e3a21be
--- /dev/null
@@ -0,0 +1,89 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <qa_gr_block.h>
+#include <gr_block.h>
+#include <gr_runtime.h>
+#include <gr_io_signature.h>
+#include <gr_null_sink.h>
+#include <gr_null_source.h>
+
+
+// ----------------------------------------------------------------
+
+
+void
+qa_gr_block::t0 ()
+{
+  // test creation of sources
+  gr_block_sptr src1 (gr_make_null_source (sizeof (int)));
+  CPPUNIT_ASSERT_EQUAL (std::string ("null_source"), src1->name ());
+  CPPUNIT_ASSERT_EQUAL (0, src1->input_signature()->max_streams ());
+  CPPUNIT_ASSERT_EQUAL (1, src1->output_signature()->min_streams ());
+  CPPUNIT_ASSERT_EQUAL (1, src1->output_signature()->max_streams ());
+  CPPUNIT_ASSERT_EQUAL (sizeof (int),
+                       src1->output_signature()->sizeof_stream_item (0));
+
+  gr_block_sptr src2 (gr_make_null_source (sizeof (short)));
+  CPPUNIT_ASSERT_EQUAL (std::string ("null_source"), src2->name ());
+  CPPUNIT_ASSERT_EQUAL (0, src2->input_signature()->max_streams ());
+  CPPUNIT_ASSERT_EQUAL (1, src2->output_signature()->min_streams ());
+  CPPUNIT_ASSERT_EQUAL (1, src2->output_signature()->max_streams ());
+  CPPUNIT_ASSERT_EQUAL (sizeof (short),
+                       src2->output_signature()->sizeof_stream_item (0));
+}
+
+
+void
+qa_gr_block::t1 ()
+{
+  // test creation of sinks
+  gr_block_sptr dst1 (gr_make_null_sink (sizeof (int)));
+  CPPUNIT_ASSERT_EQUAL (std::string ("null_sink"), dst1->name ());
+  CPPUNIT_ASSERT_EQUAL (1, dst1->input_signature()->min_streams ());
+  CPPUNIT_ASSERT_EQUAL (1, dst1->input_signature()->max_streams ());
+  CPPUNIT_ASSERT_EQUAL (sizeof (int),
+                       dst1->input_signature()->sizeof_stream_item (0));
+
+  CPPUNIT_ASSERT_EQUAL (0, dst1->output_signature()->max_streams ());
+
+  gr_block_sptr dst2 (gr_make_null_sink (sizeof (short)));
+  CPPUNIT_ASSERT_EQUAL (std::string ("null_sink"), dst2->name ());
+  CPPUNIT_ASSERT_EQUAL (1, dst2->input_signature()->min_streams ());
+  CPPUNIT_ASSERT_EQUAL (1, dst2->input_signature()->max_streams ());
+  CPPUNIT_ASSERT_EQUAL (sizeof (short),
+                       dst2->input_signature()->sizeof_stream_item (0));
+  CPPUNIT_ASSERT_EQUAL (0, dst2->output_signature()->max_streams ());
+}
+
+void
+qa_gr_block::t2 ()
+{
+}
+
+void
+qa_gr_block::t3 ()
+{
+}
diff --git a/gnuradio-core/src/lib/runtime/qa_gr_block.h b/gnuradio-core/src/lib/runtime/qa_gr_block.h
new file mode 100644 (file)
index 0000000..6e30825
--- /dev/null
@@ -0,0 +1,48 @@
+/* -*- 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 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.
+ */
+
+#ifndef INCLUDED_QA_GR_BLOCK_H
+#define INCLUDED_QA_GR_BLOCK_H
+
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/TestCase.h>
+#include <stdexcept>
+
+class qa_gr_block : public CppUnit::TestCase {
+
+  CPPUNIT_TEST_SUITE (qa_gr_block);
+  CPPUNIT_TEST (t0);
+  CPPUNIT_TEST (t1);
+  CPPUNIT_TEST (t2);
+  CPPUNIT_TEST (t3);
+  CPPUNIT_TEST_SUITE_END ();
+
+ private:
+  void t0 ();
+  void t1 ();
+  void t2 ();
+  void t3 ();
+
+};
+
+
+#endif /* INCLUDED_QA_GR_BLOCK_H */
diff --git a/gnuradio-core/src/lib/runtime/qa_gr_buffer.cc b/gnuradio-core/src/lib/runtime/qa_gr_buffer.cc
new file mode 100644 (file)
index 0000000..5c549d0
--- /dev/null
@@ -0,0 +1,307 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <qa_gr_buffer.h>
+#include <gr_buffer.h>
+#include <cppunit/TestAssert.h>
+#include <stdlib.h>
+#include <gr_random.h>
+
+static void
+leak_check (void f ())
+{
+  long buffer_count = gr_buffer_ncurrently_allocated ();
+  long buffer_reader_count = gr_buffer_reader_ncurrently_allocated ();
+
+  f ();
+
+  CPPUNIT_ASSERT_EQUAL (buffer_reader_count, gr_buffer_reader_ncurrently_allocated ());
+  CPPUNIT_ASSERT_EQUAL (buffer_count, gr_buffer_ncurrently_allocated ());
+}
+
+
+// ----------------------------------------------------------------------------
+// test single writer, no readers...
+//
+
+static void
+t0_body ()
+{
+  int  nitems = 4000 / sizeof (int);
+  int  counter = 0;
+
+  gr_buffer_sptr buf (gr_make_buffer (nitems, sizeof (int)));
+
+  int last_sa;
+  int sa;
+
+  sa = buf->space_available ();
+  CPPUNIT_ASSERT (sa > 0);
+  last_sa = sa;
+
+  for (int i = 0; i < 5; i++){
+    sa = buf->space_available ();
+    CPPUNIT_ASSERT_EQUAL (last_sa, sa);
+    last_sa = sa;
+    
+    int *p = (int *) buf->write_pointer ();
+    CPPUNIT_ASSERT (p != 0);
+
+    for (int j = 0; j < sa; j++)
+      *p++ = counter++;
+
+    buf->update_write_pointer (sa);
+  }
+}
+
+// ----------------------------------------------------------------------------
+// test single writer, single reader
+//
+
+static void 
+t1_body ()
+ {
+  int  nitems = 4000 / sizeof (int);
+  int  write_counter = 0;
+  int  read_counter = 0;
+
+  gr_buffer_sptr buf (gr_make_buffer (nitems, sizeof (int)));
+  gr_buffer_reader_sptr r1 (gr_buffer_add_reader (buf, 1));
+  
+
+  int sa;
+
+  // write 1/3 of buffer
+
+  sa = buf->space_available ();
+  CPPUNIT_ASSERT (sa > 0);
+
+  int *p = (int *) buf->write_pointer ();
+  CPPUNIT_ASSERT (p != 0);
+
+  for (int j = 0; j < sa/3; j++){
+    *p++ = write_counter++;
+  }
+  buf->update_write_pointer (sa/3);
+
+  
+  // write the next 1/3 (1/2 of what's left)
+
+  sa = buf->space_available ();
+  CPPUNIT_ASSERT (sa > 0);
+
+  p = (int *) buf->write_pointer ();
+  CPPUNIT_ASSERT (p != 0);
+
+  for (int j = 0; j < sa/2; j++){
+    *p++ = write_counter++;
+  }
+  buf->update_write_pointer (sa/2);
+
+
+  // check that we can read it OK
+
+  int ia = r1->items_available ();
+  CPPUNIT_ASSERT_EQUAL (write_counter, ia);
+  
+  int *rp = (int *) r1->read_pointer ();
+  CPPUNIT_ASSERT (rp != 0);
+
+  for (int i = 0; i < ia/2; i++){
+    CPPUNIT_ASSERT_EQUAL (read_counter, *rp);
+    read_counter++;
+    rp++;
+  }
+  r1->update_read_pointer (ia/2);
+
+  // read the rest
+
+  ia = r1->items_available ();
+  rp = (int *) r1->read_pointer ();
+  CPPUNIT_ASSERT (rp != 0);
+
+  for (int i = 0; i < ia; i++){
+    CPPUNIT_ASSERT_EQUAL (read_counter, *rp);
+    read_counter++;
+    rp++;
+  }
+  r1->update_read_pointer (ia);
+}
+
+// ----------------------------------------------------------------------------
+// single writer, single reader: check wrap-around
+//
+
+static void
+t2_body ()
+{
+  // 64K is the largest granularity we've seen so far (MS windows file mapping).
+  // This allows a bit of "white box testing"
+  
+  int  nitems = (64 * (1L << 10)) / sizeof (int);      // 64K worth of ints
+
+  gr_buffer_sptr buf (gr_make_buffer (nitems, sizeof (int)));
+  gr_buffer_reader_sptr r1 (gr_buffer_add_reader (buf, 1));
+
+  int  read_counter = 0;
+  int  write_counter = 0;
+  int  n;
+  int  *wp = 0;
+  int  *rp = 0;
+  
+  // Write 3/4 of buffer
+
+  n = (int) (buf->space_available () * 0.75);
+  wp = (int *) buf->write_pointer ();
+
+  for (int i = 0; i < n; i++)
+    *wp++ = write_counter++;
+  buf->update_write_pointer (n);
+
+  // Now read it all
+
+  int m = r1->items_available ();
+  CPPUNIT_ASSERT_EQUAL (n, m);
+  rp = (int *) r1->read_pointer ();
+
+  for (int i = 0; i < m; i++){
+    CPPUNIT_ASSERT_EQUAL (read_counter, *rp);
+    read_counter++;
+    rp++;
+  }
+  r1->update_read_pointer (m);
+
+  // Now write as much as we can.
+  // This will wrap around the buffer
+
+  n = buf->space_available ();
+  CPPUNIT_ASSERT_EQUAL (nitems - 1, n);                // white box test
+  wp = (int *) buf->write_pointer ();
+
+  for (int i = 0; i < n; i++)
+    *wp++ = write_counter++;
+  buf->update_write_pointer (n);
+  
+  // now read it all
+
+  m = r1->items_available ();
+  CPPUNIT_ASSERT_EQUAL (n, m);
+  rp = (int *) r1->read_pointer ();
+
+  for (int i = 0; i < m; i++){
+    CPPUNIT_ASSERT_EQUAL (read_counter, *rp);
+    read_counter++;
+    rp++;
+  }
+  r1->update_read_pointer (m);
+
+}
+
+// ----------------------------------------------------------------------------
+// single writer, N readers, randomized order and lengths
+// ----------------------------------------------------------------------------
+
+static void
+t3_body ()
+{
+  int  nitems = (64 * (1L << 10)) / sizeof (int);
+
+  static const int N = 5;
+  gr_buffer_sptr buf (gr_make_buffer (nitems, sizeof (int)));
+  gr_buffer_reader_sptr        reader[N];
+  int                  read_counter[N];
+  int                  write_counter = 0;
+  gr_random            random;
+
+  for (int i = 0; i < N; i++){
+    read_counter[i] = 0;
+    reader[i] = gr_buffer_add_reader (buf, 1);
+  }
+
+  for (int lc = 0; lc < 1000; lc++){
+
+    // write some
+
+    int n = (int) (buf->space_available () * random.ran1 ());
+    int *wp = (int *) buf->write_pointer ();
+
+    for (int i = 0; i < n; i++)
+      *wp++ = write_counter++;
+
+    buf->update_write_pointer (n);
+
+    // pick a random reader and read some
+
+    int r = (int) (N * random.ran1 ());
+    CPPUNIT_ASSERT (0 <= r && r < N);
+
+    int m = reader[r]->items_available ();
+    int *rp = (int *) reader[r]->read_pointer ();
+
+    for (int i = 0; i < m; i++){
+      CPPUNIT_ASSERT_EQUAL (read_counter[r], *rp);
+      read_counter[r]++;
+      rp++;
+    }
+    reader[r]->update_read_pointer (m);
+  }
+}
+
+
+// ----------------------------------------------------------------------------
+
+void
+qa_gr_buffer::t0 ()
+{
+  leak_check (t0_body);
+}
+
+void
+qa_gr_buffer::t1 ()
+{
+  leak_check (t1_body);
+}
+
+void
+qa_gr_buffer::t2 ()
+{
+  leak_check (t2_body);
+}
+
+void
+qa_gr_buffer::t3 ()
+{
+  leak_check (t3_body);
+}
+
+void
+qa_gr_buffer::t4 ()
+{
+}
+
+void
+qa_gr_buffer::t5 ()
+{
+}
diff --git a/gnuradio-core/src/lib/runtime/qa_gr_buffer.h b/gnuradio-core/src/lib/runtime/qa_gr_buffer.h
new file mode 100644 (file)
index 0000000..700629c
--- /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 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.
+ */
+
+#ifndef INCLUDED_QA_GR_BUFFER_H
+#define INCLUDED_QA_GR_BUFFER_H
+
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/TestCase.h>
+
+class qa_gr_buffer : public CppUnit::TestCase {
+
+  CPPUNIT_TEST_SUITE (qa_gr_buffer);
+  CPPUNIT_TEST (t0);
+  CPPUNIT_TEST (t1);
+  CPPUNIT_TEST (t2);
+  CPPUNIT_TEST (t3);
+  CPPUNIT_TEST (t4);
+  CPPUNIT_TEST (t5);
+  CPPUNIT_TEST_SUITE_END ();
+
+
+ private:
+
+  void t0 ();
+  void t1 ();
+  void t2 ();
+  void t3 ();
+  void t4 ();
+  void t5 ();
+};
+
+
+
+#endif /* INCLUDED_QA_GR_BUFFER_H */
diff --git a/gnuradio-core/src/lib/runtime/qa_gr_io_signature.cc b/gnuradio-core/src/lib/runtime/qa_gr_io_signature.cc
new file mode 100644 (file)
index 0000000..c180e7b
--- /dev/null
@@ -0,0 +1,55 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <qa_gr_io_signature.h>
+#include <gr_io_signature.h>
+
+void
+qa_gr_io_signature::t0 ()
+{
+  gr_make_io_signature (1, 1, sizeof (int));
+}
+
+void
+qa_gr_io_signature::t1 ()
+{
+  gr_make_io_signature (3, 1, sizeof (int));  // throws std::invalid_argument
+}
+
+void
+qa_gr_io_signature::t2 ()
+{
+  gr_io_signature_sptr p =
+    gr_make_io_signature (3, gr_io_signature::IO_INFINITE, sizeof (int));
+
+  CPPUNIT_ASSERT_EQUAL (p->min_streams (), 3);
+  CPPUNIT_ASSERT_EQUAL (p->sizeof_stream_item (0), sizeof (int));
+}
+
+void
+qa_gr_io_signature::t3 ()
+{
+}
+
diff --git a/gnuradio-core/src/lib/runtime/qa_gr_io_signature.h b/gnuradio-core/src/lib/runtime/qa_gr_io_signature.h
new file mode 100644 (file)
index 0000000..225ce80
--- /dev/null
@@ -0,0 +1,47 @@
+/* -*- 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 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.
+ */
+
+#ifndef INCLUDED_QA_GR_IO_SIGNATURE_H
+#define INCLUDED_QA_GR_IO_SIGNATURE_H
+
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/TestCase.h>
+#include <stdexcept>
+
+class qa_gr_io_signature : public CppUnit::TestCase {
+
+  CPPUNIT_TEST_SUITE (qa_gr_io_signature);
+  CPPUNIT_TEST (t0);
+  CPPUNIT_TEST_EXCEPTION (t1, std::invalid_argument);
+  CPPUNIT_TEST (t2);
+  CPPUNIT_TEST (t3);
+  CPPUNIT_TEST_SUITE_END ();
+
+ private:
+  void t0 ();
+  void t1 ();
+  void t2 ();
+  void t3 ();
+
+};
+
+#endif /* INCLUDED_QA_GR_IO_SIGNATURE_H */
diff --git a/gnuradio-core/src/lib/runtime/qa_gr_vmcircbuf.cc b/gnuradio-core/src/lib/runtime/qa_gr_vmcircbuf.cc
new file mode 100644 (file)
index 0000000..f3c815a
--- /dev/null
@@ -0,0 +1,40 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <qa_gr_vmcircbuf.h>
+#include <cppunit/TestAssert.h>
+#include <gr_vmcircbuf.h>
+#include <stdio.h>
+
+void
+qa_gr_vmcircbuf::test_all ()
+{
+  int  verbose = 1;            // summary
+
+  bool ok = gr_vmcircbuf_sysconfig::test_all_factories (verbose);
+  
+  CPPUNIT_ASSERT_EQUAL (true, ok);
+}
diff --git a/gnuradio-core/src/lib/runtime/qa_gr_vmcircbuf.h b/gnuradio-core/src/lib/runtime/qa_gr_vmcircbuf.h
new file mode 100644 (file)
index 0000000..41f69c3
--- /dev/null
@@ -0,0 +1,39 @@
+/* -*- 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 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.
+ */
+#ifndef _QA_GR_VMCIRCBUF_H_
+#define _QA_GR_VMCIRCBUF_H_
+
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/TestCase.h>
+
+class qa_gr_vmcircbuf : public CppUnit::TestCase {
+
+  CPPUNIT_TEST_SUITE (qa_gr_vmcircbuf);
+  CPPUNIT_TEST (test_all);
+  CPPUNIT_TEST_SUITE_END ();
+
+ private:
+  void test_all ();
+};
+
+
+#endif /* _QA_GR_VMCIRCBUF_H_ */
diff --git a/gnuradio-core/src/lib/runtime/qa_runtime.cc b/gnuradio-core/src/lib/runtime/qa_runtime.cc
new file mode 100644 (file)
index 0000000..668628f
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * 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 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 class gathers together all the test cases for the gr
+ * directory into a single test suite.  As you create new test cases,
+ * add them here.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <qa_runtime.h>
+#include <qa_gr_vmcircbuf.h>
+#include <qa_gr_io_signature.h>
+#include <qa_gr_block.h>
+#include <qa_gr_buffer.h>
+
+CppUnit::TestSuite *
+qa_runtime::suite ()
+{
+  CppUnit::TestSuite   *s = new CppUnit::TestSuite ("runtime");
+
+  s->addTest (qa_gr_vmcircbuf::suite ());
+  s->addTest (qa_gr_io_signature::suite ());
+  s->addTest (qa_gr_block::suite ());
+  s->addTest (qa_gr_buffer::suite ());
+  
+  return s;
+}
diff --git a/gnuradio-core/src/lib/runtime/qa_runtime.h b/gnuradio-core/src/lib/runtime/qa_runtime.h
new file mode 100644 (file)
index 0000000..5862b1e
--- /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 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.
+ */
+
+#ifndef _QA_RUNTIME_H_
+#define _QA_RUNTIME_H_
+
+#include <cppunit/TestSuite.h>
+
+//! collect all the tests for the runtime directory
+
+class qa_runtime {
+ public:
+  //! return suite of tests for all of runtime directory
+  static CppUnit::TestSuite *suite ();
+};
+
+
+#endif /* _QA_RUNTIME_H_ */
diff --git a/gnuradio-core/src/lib/runtime/runtime.i b/gnuradio-core/src/lib/runtime/runtime.i
new file mode 100644 (file)
index 0000000..d8dd34f
--- /dev/null
@@ -0,0 +1,49 @@
+/* -*- 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 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.
+ */
+
+%{
+#include <gr_runtime.h>
+#include <gr_io_signature.h>
+#include <gr_buffer.h>
+#include <gr_block.h>
+#include <gr_block_detail.h>
+#include <gr_single_threaded_scheduler.h>
+#include <gr_message.h>
+#include <gr_msg_handler.h>
+#include <gr_msg_queue.h>
+#include <gr_dispatcher.h>
+#include <gr_error_handler.h>
+#include <gr_realtime.h>
+%}
+
+%include <gr_io_signature.i>
+%include <gr_buffer.i>
+%include <gr_block.i>
+%include <gr_block_detail.i>
+%include <gr_swig_block_magic.i>
+%include <gr_single_threaded_scheduler.i>
+%include <gr_message.i>
+%include <gr_msg_handler.i>
+%include <gr_msg_queue.i>
+%include <gr_dispatcher.i>
+%include <gr_error_handler.i>
+%include <gr_realtime.i>
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..26bfa6d
--- /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 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.
+ */
+
+#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/Makefile.am b/gnuradio-core/src/lib/swig/Makefile.am
new file mode 100644 (file)
index 0000000..77bd030
--- /dev/null
@@ -0,0 +1,111 @@
+#
+# Copyright 2001,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 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.
+# 
+
+include $(top_srcdir)/Makefile.common
+
+# Install this stuff in the gr subdirectory of the python pkg dir.
+# This usually ends up at:
+#   ${prefix}/lib/python${python_version}/site-packages/gnuradio/gr
+
+grgrpythondir = $(grpythondir)/gr
+grgrlibdir    = $(grpyexecdir)/gr
+
+
+INCLUDES = $(STD_DEFINES_AND_INCLUDES) $(PYTHON_CPPFLAGS) -I$(srcdir)
+
+
+EXTRA_DIST = gen-swig-bug-fix
+
+
+LOCAL_IFILES =                         \
+       gnuradio.i                      \
+       shared_ptr.i                                    
+
+ALL_IFILES =                           \
+       $(LOCAL_IFILES)                 
+
+
+BUILT_SOURCES =                                \
+       gnuradio_swig_python.cc         \
+       gnuradio_swig_python.py         \
+       gnuradio_swig_python.h          \
+       gnuradio_swig_bug_workaround.h  
+
+grgrpython_PYTHON =                    \
+       gnuradio_swig_python.py         
+
+
+SWIGPYTHONARGS = $(SWIGPYTHONFLAGS) $(INCLUDES)
+
+
+# ----------------------------------------------------------------
+# _gnuradio_swig_python contains all the glue that implements
+# the gnuradio.gr python package
+
+grgrlib_LTLIBRARIES =                                  \
+       _gnuradio_swig_python.la
+
+_gnuradio_swig_python_la_SOURCES =                     \
+       gnuradio_swig_python.cc         
+
+
+_gnuradio_swig_python_la_LIBADD  =                     \
+       $(top_builddir)/gnuradio-core/src/lib/libgnuradio-core.la       \
+       $(PYTHON_LDFLAGS)                               \
+       -lstdc++
+
+_gnuradio_swig_python_la_LDFLAGS = -module -avoid-version $(NO_UNDEFINED)
+
+
+# KLUDGE: Force runtime include of gnuradio_swig_python.d 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@./gnuradio_swig_python.d@am__quote@
+
+gnuradio_swig_python.cc gnuradio_swig_python.py gnuradio_swig_python.h : gnuradio.i
+       if $(SWIG) $(SWIGPYTHONARGS) -MMD -MF gnuradio_swig_python.Td -module gnuradio_swig_python -o gnuradio_swig_python.cc $< ;\
+       then if test $(host_os) = mingw32; \
+            then sed 's,\\\\,/,g' <gnuradio_swig_python.Td >gnuradio_swig_python.d; rm -f gnuradio_swig_python.Td; \
+            else mv -f gnuradio_swig_python.Td gnuradio_swig_python.d; fi \
+       else rm -f gnuradio_swig_python.Td; exit 1; fi 
+
+gnuradio_swig_bug_workaround.h : gnuradio_swig_python.cc $(srcdir)/gen-swig-bug-fix
+       $(srcdir)/gen-swig-bug-fix $< $@
+
+
+# ----------------------------------------------------------------
+
+# Don't distribute output of swig
+dist-hook:
+       @for file in $(BUILT_SOURCES); do echo $(RM) $(distdir)/$$file; done
+       @for file in $(BUILT_SOURCES); do $(RM) $(distdir)/$$file; done
+
+
+grinclude_HEADERS =                            \
+       gnuradio_swig_bug_workaround.h
+
+swiginclude_HEADERS =                          \
+       $(LOCAL_IFILES)                 
+
+MOSTLYCLEANFILES = \
+       $(BUILT_SOURCES) *~ *.pyc 
+
+DISTCLEANFILES = gnuradio_swig_python.d
diff --git a/gnuradio-core/src/lib/swig/atsc.i b/gnuradio-core/src/lib/swig/atsc.i
new file mode 100644 (file)
index 0000000..4e8bf48
--- /dev/null
@@ -0,0 +1,136 @@
+/* -*- 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 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.
+ */
+
+%{
+#include <atsc_types.h>
+#include <atsc_consts.h>
+#include <GrAtscRandomizer.h>
+#include <GrAtscRSEncoder.h>
+#include <GrAtscInterleaver.h>
+#include <GrAtscTrellisEncoder.h>
+#include <GrAtscFieldSyncMux.h>
+#include <GrAtscSymbolMapper.h>
+#include <GrAtscConvert2xTo20.h>
+#include <GrWeaverModHead.h>
+#include <GrWeaverModTail.h>
+
+%}
+
+// from atsc_types.h
+class plinfo;
+class atsc_mpeg_packet;
+class atsc_mpeg_packet_no_sync;
+class atsc_mpeg_packet_rs_encoded;
+class atsc_data_segment;
+class atsc_soft_data_segment;
+
+%include <atsc_consts.h>
+
+
+// leave out the VrHistoryProc and pretend we're directly derived from VrSigProc
+
+// %template(VrHistoryProc_1) VrHistoryProc<atsc_mpeg_packet,atsc_mpeg_packet_no_sync>;
+
+class GrAtscRandomizer : public VrSigProc
+// class GrAtscRandomizer : public VrHistoryProc<atsc_mpeg_packet, atsc_mpeg_packet_no_sync>
+{
+public:
+  GrAtscRandomizer ();
+  ~GrAtscRandomizer ();
+};
+
+class GrAtscRSEncoder : public VrSigProc
+{
+public:
+  GrAtscRSEncoder ();
+  ~GrAtscRSEncoder ();
+};
+
+class GrAtscInterleaver : public VrSigProc
+{
+public:
+  GrAtscInterleaver ();
+  ~GrAtscInterleaver ();
+};
+
+class GrAtscTrellisEncoder : public VrSigProc
+{
+public:
+  GrAtscTrellisEncoder ();
+  ~GrAtscTrellisEncoder ();
+};
+
+class GrAtscFieldSyncMux : public VrSigProc
+{
+public:
+  GrAtscFieldSyncMux ();
+  ~GrAtscFieldSyncMux ();
+};
+
+template<class oType>
+class GrAtscSymbolMapper : public VrSigProc
+{
+public:
+  GrAtscSymbolMapper ();
+  ~GrAtscSymbolMapper ();
+};
+
+%template(GrAtscSymbolMapperF) GrAtscSymbolMapper<float>;
+
+template<class iType, class oType>
+class GrWeaverModHead : public VrSigProc
+{
+public:
+  GrWeaverModHead (int interp_factor);
+  ~GrWeaverModHead ();
+};
+
+%template(GrWeaverModHeadFF) GrWeaverModHead<float,float>;
+
+template<class iType, class oType>
+class GrWeaverModTail : public VrSigProc {
+public:
+  GrWeaverModTail (float freq, float gain);
+  ~GrWeaverModTail ();
+
+  //! frequency is in Hz
+  void set_freq (float frequency);
+  void set_gain (float g);
+};
+
+%template(GrWeaverModTailFS) GrWeaverModTail<float,short>;
+
+class GrAtscConvert2xTo20 : public VrSigProc
+{
+public:
+  GrAtscConvert2xTo20 ();
+  ~GrAtscConvert2xTo20 ();
+};
+
+
+#if 0  // FIXME
+%template(VrSource_mpeg_packet)     VrSource<atsc_mpeg_packet>;
+%template(VrFileSource_mpeg_packet) VrFileSource<atsc_mpeg_packet>;
+
+%template(VrSink_mpeg_packet)      VrSink<atsc_mpeg_packet>;
+%template(VrFileSink_mpeg_packet)   VrFileSink<atsc_mpeg_packet>;
+#endif
diff --git a/gnuradio-core/src/lib/swig/gen-swig-bug-fix b/gnuradio-core/src/lib/swig/gen-swig-bug-fix
new file mode 100755 (executable)
index 0000000..36332cc
--- /dev/null
@@ -0,0 +1,111 @@
+#!/usr/bin/env 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.
+# 
+
+import sys
+import re
+
+def write_header (f):
+    f.write ('''/* -*- 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 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.
+ */
+
+#ifndef INCLUDED_GNURADIO_SWIG_BUG_WORKAROUND_H
+#define INCLUDED_GNURADIO_SWIG_BUG_WORKAROUND_H
+
+/*
+ * This include files works around a bug in SWIG 1.3.21 and 22
+ * where it fails to emit these declarations when doing
+ * %import "gnuradio.i"
+ */
+
+''')
+    
+def write_trailer (f):
+    f.write ('''
+#endif /* INCLUDED_GNURADIO_SWIG_BUG_WORKAROUND_H */
+''')
+
+def doit (input, output):
+    re_RULES_BEGIN = re.compile ('RULES \(BEGIN\)')
+    re_RULES_END = re.compile ('RULES \(END\)')
+    re_RETURN = re.compile ('^\s*return')
+    re_NOT_ID = re.compile ('[^a-zA-Z0-9_]')
+    words = {}
+    
+    write_header (output)
+    for line in input:
+        if re_RULES_BEGIN.search (line):
+            break
+
+    for line in input:
+        if re_RULES_END.search (line):
+            break
+        if not re_RETURN.match (line):
+            continue
+        line = re_NOT_ID.sub (' ', line)
+        line = re.sub (' +', ' ', line)
+        for w in line.split (' '):
+            words[w] = 1
+
+    for w in ('', 'return', 'void', 'x'):
+        del words[w]
+    
+    wl = words.keys()
+    wl.sort ()
+    for w in wl:
+        output.write ('class ' + w + ';\n')
+
+    write_trailer (output)
+    
+
+def main ():
+    if len (sys.argv) != 3:
+        sys.stderr.write ("usage: %s gnuradio_swig_python.cc gnuradio_swig_bug_workaround.h\n"
+                          % (sys.argv[0],))
+        sys.exit (1)
+    input_filename = sys.argv[1]
+    output_filename = sys.argv[2]
+    input = open (input_filename, "r")
+    output = open (output_filename, "w")
+    doit (input, output)
+
+if __name__ == '__main__':
+    main ()
+
diff --git a/gnuradio-core/src/lib/swig/gnuradio.i b/gnuradio-core/src/lib/swig/gnuradio.i
new file mode 100644 (file)
index 0000000..b8c5853
--- /dev/null
@@ -0,0 +1,84 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003,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.
+ */
+
+////////////////////////////////////////////////////////////////////////
+// gnuradio.i
+// SWIG interface definition
+////////////////////////////////////////////////////////////////////////
+
+
+#ifndef SWIGIMPORTED
+// we set the module name on the command line (not any more)
+%module(directors="1") gnuradio_swig_python
+#endif
+
+////////////////////////////////////////////////////////////////////////
+// Headers
+
+
+%{
+#include <gr_types.h>
+#include <stddef.h>            // size_t
+%}
+
+%feature("autodoc","1");
+
+%include <shared_ptr.i>
+%include <stl.i>
+%include <std_complex.i>
+
+
+typedef std::complex<float>            gr_complex;
+typedef std::complex<double>           gr_complexd;
+
+
+// instantiate the required template specializations
+
+namespace std {
+  %template()    vector<unsigned char>;
+  %template()    vector<char>;
+  %template()    vector<short>;
+  %template()    vector<int>;
+  %template()    vector<float>;
+  %template()    vector<double>;
+  %template()    vector<std::complex<float> >;
+};
+
+////////////////////////////////////////////////////////////////////////
+
+%constant int sizeof_char      = sizeof(char);
+%constant int sizeof_short     = sizeof(short);
+%constant int sizeof_int       = sizeof(int);
+%constant int sizeof_float     = sizeof(float);
+%constant int sizeof_double    = sizeof(double);
+%constant int sizeof_gr_complex        = sizeof(gr_complex);
+
+////////////////////////////////////////////////////////////////////////
+
+%include <runtime.i>
+%include <general.i>
+%include <filter.i>
+%include <io.i>
+
+// %include <atsc.i>
+
+////////////////////////////////////////////////////////////////////////
diff --git a/gnuradio-core/src/lib/swig/shared_ptr.i b/gnuradio-core/src/lib/swig/shared_ptr.i
new file mode 100644 (file)
index 0000000..9663033
--- /dev/null
@@ -0,0 +1,43 @@
+//
+//  shared_ptr
+//
+//  An enhanced relative of scoped_ptr with reference counted copy semantics.
+//  The object pointed to is deleted when the last shared_ptr pointing to it
+//  is destroyed or reset.
+//
+
+//
+// This is highly hacked up version of boost::shared_ptr
+// We just need enough to get SWIG to "do the right thing" and
+// generate "Smart Pointer" code.
+//
+
+namespace boost {
+
+template<class T> class shared_ptr
+{
+public:
+
+    shared_ptr()
+    {
+    }
+
+    shared_ptr (T * p)
+    {
+    }
+
+
+    T * operator-> () // never throws
+    {
+        return px;
+    }
+    
+
+private:
+
+    T * px;                     // contained pointer
+    int pn;
+
+};  // shared_ptr
+
+};
\ No newline at end of file
diff --git a/gnuradio-core/src/python/Makefile.am b/gnuradio-core/src/python/Makefile.am
new file mode 100644 (file)
index 0000000..99f8602
--- /dev/null
@@ -0,0 +1,29 @@
+#
+# 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.
+# 
+
+include $(top_srcdir)/Makefile.common
+
+SUBDIRS = gnuradio bin
+
+noinst_PYTHON =                        \
+       build_utils.py          \
+       build_utils_codes.py    
+
diff --git a/gnuradio-core/src/python/bin/Makefile.am b/gnuradio-core/src/python/bin/Makefile.am
new file mode 100644 (file)
index 0000000..3e9b907
--- /dev/null
@@ -0,0 +1,30 @@
+#
+# 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 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.
+# 
+
+include $(top_srcdir)/Makefile.common
+
+
+EXTRA_DIST = microtune.py
+
+bin_SCRIPTS =                  \
+       microtune.py            
+
+CLEANFILES = *.pyc
diff --git a/gnuradio-core/src/python/bin/microtune.py b/gnuradio-core/src/python/bin/microtune.py
new file mode 100755 (executable)
index 0000000..0e799c9
--- /dev/null
@@ -0,0 +1,42 @@
+#!/usr/bin/env python
+# -*- Python -*-
+
+from gnuradio import gr
+from gnuradio.eng_option import eng_option
+from gnuradio.wxgui import stdgui, fftsink
+from optparse import OptionParser
+from gnuradio import eng_notation
+
+
+def main ():
+    parser = OptionParser (option_class=eng_option)
+    parser.add_option ("-g", "--gain", type="eng_float", default=-1,
+                       help="set front end gain to GAIN [0,1000]")
+    parser.add_option ("-f", "--freq", type="eng_float", default=-1,
+                       help="set front end center frequency to FREQ")
+    parser.add_option ("-t", "--type", type="string", default="4937",
+                       help="select eval board type {4937 or 4702}")
+    parser.add_option ("-p", "--port", type="int", default=0,
+                       help="parallel port eval board is attached to")
+    (options, args) = parser.parse_args ()
+
+    if options.type == "4937":
+        front_end = gr.microtune_4937_eval_board (options.port)
+    elif options.type == "4702":
+        front_end = gr.microtune_4702_eval_board (options.port)
+    else:
+        raise RuntimeError, "Invalid board type.  Must be either -t 4937 or -t 4702"
+
+    if options.gain != -1:
+        front_end.set_AGC (options.gain)
+
+    if options.freq != -1:
+        if options.freq < 1e6:
+            options.freq = options.freq * 1e6
+
+        actual = front_end.set_RF_freq (options.freq)
+        print "microtune: actual freq = %s" %  (eng_notation.num_to_str (actual),)
+        
+
+if __name__ == '__main__':
+    main ()
diff --git a/gnuradio-core/src/python/build_utils.py b/gnuradio-core/src/python/build_utils.py
new file mode 100644 (file)
index 0000000..18cfc2e
--- /dev/null
@@ -0,0 +1,163 @@
+#
+# 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.
+# 
+
+"""Misc utilities used at build time
+"""
+
+import re, os, os.path
+from build_utils_codes import *
+
+
+# set srcdir to the directory that contains Makefile.am
+try:
+    srcdir = os.environ['srcdir']
+except KeyError, e:
+    srcdir = "."
+srcdir = srcdir + '/'
+
+
+name_dict = {}
+
+def log_output_name (name):
+    (base, ext) = os.path.splitext (name)
+    ext = ext[1:]                       # drop the leading '.'
+    
+    entry = name_dict.setdefault (ext, [])
+    entry.append (name)
+    
+def open_and_log_name (name, dir):
+    f = open (name, dir)
+    log_output_name (name)
+    return f
+
+def expand_template (d, template_filename, extra = ""):
+    '''Given a dictionary D and a TEMPLATE_FILENAME, expand template into output file
+    '''
+    output_extension = extract_extension (template_filename)
+    template = open_src (template_filename, 'r')
+    output_name = d['NAME'] + extra + '.' + output_extension
+    log_output_name (output_name)
+    output = open (output_name, 'w')
+    do_substitution (d, template, output)
+    template.close ()
+    output.close ()
+
+def output_glue (dirname):
+    output_makefile_fragment ()
+    output_ifile_include (dirname)
+    
+def output_makefile_fragment ():
+    f = open ('Makefile.gen', 'w')
+    f.write ('#\n# This file is machine generated.  All edits will be overwritten\n#\n')
+    output_subfrag (f, 'h')
+    output_subfrag (f, 'i')
+    output_subfrag (f, 'cc')
+    f.close ()
+
+def output_ifile_include (dirname):
+    f = open ('%s_generated.i' % (dirname,), 'w')
+    f.write ('//\n// This file is machine generated.  All edits will be overwritten\n//\n')
+    files = name_dict.setdefault ('i', [])
+    files.sort ()
+    f.write ('%{\n')
+    for file in files:
+        f.write ('#include <%s>\n' % (file[0:-1] + 'h',))
+    f.write ('%}\n\n')
+    for file in files:
+        f.write ('%%include <%s>\n' % (file,))
+
+def output_subfrag (f, ext):
+    files = name_dict.setdefault (ext, [])
+    files.sort ()
+    f.write ("GENERATED_%s =" % (ext.upper ()))
+    for file in files:
+        f.write (" \\\n\t%s" % (file,))
+    f.write ("\n\n")
+    
+
+def extract_extension (template_name):
+    # template name is something like: GrFIRfilterXXX.h.t
+    # we return everything between the penultimate . and .t
+    mo = re.search (r'\.([a-z]+)\.t$', template_name)
+    if not mo:
+        raise ValueError, "Incorrectly formed template_name '%s'" % (template_name,)
+    return mo.group (1)
+
+def open_src (name, mode):
+    global srcdir
+    return open (os.path.join (srcdir, name), mode)
+
+def do_substitution (d, in_file, out_file):
+    def repl (match_obj):
+        key = match_obj.group (1)
+        # print key
+        return d[key]
+    
+    inp = in_file.read ()
+    out = re.sub (r"@([a-zA-Z0-9_]+)@", repl, inp)
+    out_file.write (out)
+
+    
+
+copyright = '''/* -*- c++ -*- */
+/*
+ * Copyright 2003,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.
+ */
+'''
+
+def is_complex (code3):
+    if i_code (code3) == 'c' or o_code (code3) == 'c':
+        return '1'
+    else:
+        return '0'
+
+
+def standard_dict (name, code3):
+    d = {}
+    d['NAME'] = name
+    d['GUARD_NAME'] = 'INCLUDED_%s_H' % name.upper ()
+    d['BASE_NAME'] = re.sub ('^gr_', '', name)
+    d['SPTR_NAME'] = '%s_sptr' % name
+    d['WARNING'] = 'WARNING: this file is machine generated.  Edits will be over written'
+    d['COPYRIGHT'] = copyright
+    d['TYPE'] = i_type (code3)
+    d['I_TYPE'] = i_type (code3)
+    d['O_TYPE'] = o_type (code3)
+    d['TAP_TYPE'] = tap_type (code3)
+    d['IS_COMPLEX'] = is_complex (code3)
+    return d
diff --git a/gnuradio-core/src/python/build_utils_codes.py b/gnuradio-core/src/python/build_utils_codes.py
new file mode 100644 (file)
index 0000000..f4215f2
--- /dev/null
@@ -0,0 +1,52 @@
+#
+# 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.
+# 
+
+def i_code (code3):
+    return code3[0]
+
+def o_code (code3):
+    if len (code3) >= 2:
+        return code3[1]
+    else:
+        return code3[0]
+
+def tap_code (code3):
+    if len (code3) >= 3:
+        return code3[2]
+    else:
+        return code3[0]
+
+def i_type (code3):
+    return char_to_type[i_code (code3)]
+
+def o_type (code3):
+    return char_to_type[o_code (code3)]
+
+def tap_type (code3):
+    return char_to_type[tap_code (code3)]
+
+
+char_to_type = {}
+char_to_type['s'] = 'short'
+char_to_type['i'] = 'int'
+char_to_type['f'] = 'float'
+char_to_type['c'] = 'gr_complex'
+char_to_type['b'] = 'unsigned char'
diff --git a/gnuradio-core/src/python/gnuradio/Makefile.am b/gnuradio-core/src/python/gnuradio/Makefile.am
new file mode 100644 (file)
index 0000000..3222c5d
--- /dev/null
@@ -0,0 +1,36 @@
+#
+# 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.
+# 
+
+include $(top_srcdir)/Makefile.common
+
+SUBDIRS = gr gru gruimpl blks blksimpl
+
+grpython_PYTHON =                      \
+       __init__.py                     \
+       audio.py                        \
+       eng_notation.py                 \
+       eng_option.py                   \
+       packet_utils.py                 \
+       gr_unittest.py                  \
+       optfir.py                       \
+       window.py
+
+CLEANFILES = *.pyc
diff --git a/gnuradio-core/src/python/gnuradio/__init__.py b/gnuradio-core/src/python/gnuradio/__init__.py
new file mode 100644 (file)
index 0000000..a4917cf
--- /dev/null
@@ -0,0 +1 @@
+# make this a package
diff --git a/gnuradio-core/src/python/gnuradio/audio.py b/gnuradio-core/src/python/gnuradio/audio.py
new file mode 100644 (file)
index 0000000..5a9d09c
--- /dev/null
@@ -0,0 +1,88 @@
+#
+# 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 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 is the 'generic' audio or soundcard interface.
+
+The behavior of this module is controlled by the [audio] audio_module
+configuration parameter.  If it is 'auto' we attempt to import modules
+from the known_modules list, using the first one imported successfully.
+
+If [audio] audio_module is not 'auto', we assume it's the name of
+an audio module and attempt to import it.
+"""
+
+__all__ = ['source', 'sink']
+
+from gnuradio import gr
+import sys
+
+source = None
+sink = None
+
+
+known_modules = (
+    'audio_alsa', 'audio_oss', 'audio_osx', 'audio_jack', 'audio_portaudio')
+
+
+def try_import(name):
+    """
+    Build a blob of code and try to execute it.
+    If it succeeds we will have set the globals source and sink
+    as side effects.
+
+    returns True or False
+    """
+    global source, sink
+    full_name = "gnuradio." + name
+    code = """
+import %s
+source = %s.source
+sink = %s.sink
+""" % (full_name, full_name, full_name)
+    try:
+        exec code in globals()
+        return True
+    except ImportError:
+        return False
+    
+
+def __init__ ():
+    p = gr.prefs()             # get preferences (config file) object
+    verbose = p.get_bool('audio', 'verbose', False)
+    module = p.get_string('audio', 'audio_module', 'auto')
+
+    if module == 'auto':        # search our list for the first one that we can import
+        for m in known_modules:
+            if try_import(m):
+                if verbose: sys.stderr.write('audio: using %s\n' % (m,))
+                return
+        raise ImportError, 'Unable to locate an audio module.'
+
+    else:                       # use the one the user specified
+        if try_import(module):
+            if verbose: sys.stderr.write('audio: using %s\n' % (module,))
+        else:
+            msg = 'Failed to import user-specified audio module %s' % (module,)
+            if verbose: sys.stderr.write('audio: %s\n' % (msg,))
+            raise ImportError, msg
+
+__init__()
diff --git a/gnuradio-core/src/python/gnuradio/blks/Makefile.am b/gnuradio-core/src/python/gnuradio/blks/Makefile.am
new file mode 100644 (file)
index 0000000..17574d7
--- /dev/null
@@ -0,0 +1,35 @@
+#
+# 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 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.
+# 
+
+include $(top_srcdir)/Makefile.common
+
+# EXTRA_DIST = run_tests.in
+# TESTS = run_tests
+
+grblkspythondir = $(grpythondir)/blks
+
+grblkspython_PYTHON =          \
+       __init__.py             
+
+
+noinst_PYTHON =                
+
+CLEANFILES = *.pyc *.pyo
diff --git a/gnuradio-core/src/python/gnuradio/blks/__init__.py b/gnuradio-core/src/python/gnuradio/blks/__init__.py
new file mode 100644 (file)
index 0000000..4cc10eb
--- /dev/null
@@ -0,0 +1,37 @@
+#
+# 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 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.
+# 
+
+import glob
+import os.path
+
+# Semi-hideous kludge to import everything in the blksimpl directory
+# into the gnuradio.blks namespace.  This keeps us from having to remember 
+# to manually update this file.
+
+for p in __path__:
+    filenames = glob.glob (os.path.join (p, "..", "blksimpl", "*.py"))
+    for f in filenames:
+        f = os.path.basename(f).lower()
+        f = f[:-3]
+        if f == '__init__':
+            continue
+        # print f
+        exec "from gnuradio.blksimpl.%s import *" % (f,)
diff --git a/gnuradio-core/src/python/gnuradio/blksimpl/Makefile.am b/gnuradio-core/src/python/gnuradio/blksimpl/Makefile.am
new file mode 100644 (file)
index 0000000..415920b
--- /dev/null
@@ -0,0 +1,49 @@
+#
+# 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 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.
+# 
+
+include $(top_srcdir)/Makefile.common
+
+# EXTRA_DIST = run_tests.in
+# TESTS = run_tests
+
+grblkspythondir = $(grpythondir)/blksimpl
+
+grblkspython_PYTHON =          \
+       __init__.py             \
+       am_demod.py             \
+       filterbank.py           \
+       fm_demod.py             \
+       fm_emph.py              \
+       gmsk2.py                \
+       gmsk2_pkt.py            \
+       nbfm_rx.py              \
+       nbfm_tx.py              \
+       pkt.py                  \
+       rational_resampler.py   \
+       standard_squelch.py     \
+       wfm_rcv.py              \
+       wfm_rcv_pll.py          \
+       wfm_tx.py               
+
+
+noinst_PYTHON =                
+
+CLEANFILES = *.pyc *.pyo
diff --git a/gnuradio-core/src/python/gnuradio/blksimpl/__init__.py b/gnuradio-core/src/python/gnuradio/blksimpl/__init__.py
new file mode 100644 (file)
index 0000000..a4917cf
--- /dev/null
@@ -0,0 +1 @@
+# make this a package
diff --git a/gnuradio-core/src/python/gnuradio/blksimpl/am_demod.py b/gnuradio-core/src/python/gnuradio/blksimpl/am_demod.py
new file mode 100644 (file)
index 0000000..309f5e6
--- /dev/null
@@ -0,0 +1,75 @@
+#
+# 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 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.
+# 
+
+from gnuradio import gr, optfir
+
+class am_demod_cf(gr.hier_block):
+    """
+    Generalized AM demodulation block with audio filtering.
+
+    This block demodulates a band-limited, complex down-converted AM 
+    channel into the the original baseband signal, applying low pass 
+    filtering to the audio output. It produces a float stream in the
+    range [-1.0, +1.0].
+
+    @param fg: flowgraph
+    @param channel_rate:  incoming sample rate of the AM baseband
+    @type sample_rate: integer
+    @param audio_decim: input to output decimation rate
+    @type audio_decim: integer
+    @param audio_pass: audio low pass filter passband frequency 
+    @type audio_pass: float
+    @param audio_stop: audio low pass filter stop frequency
+    @type audio_stop: float
+    """ 
+    def __init__(self, fg, channel_rate, audio_decim, audio_pass, audio_stop):
+       MAG = gr.complex_to_mag()
+       DCR = gr.add_const_ff(-1.0)
+
+       audio_taps = optfir.low_pass(0.5,          # Filter gain
+                                    channel_rate, # Sample rate
+                                    audio_pass,   # Audio passband
+                                    audio_stop,   # Audio stopband
+                                    0.1,          # Passband ripple
+                                    60)           # Stopband attenuation
+       LPF = gr.fir_filter_fff(audio_decim, audio_taps)
+
+       fg.connect(MAG, DCR, LPF)
+       gr.hier_block.__init__(self, fg, MAG, LPF)
+
+class demod_10k0a3e_cf(am_demod_cf):
+    """
+    AM demodulation block, 10 KHz channel.
+    
+    This block demodulates an AM channel conformant to 10K0A3E emission
+    standards, such as broadcast band AM transmissions.
+
+    @param fg: flowgraph
+    @param channel_rate:  incoming sample rate of the AM baseband
+    @type sample_rate: integer
+    @param audio_decim: input to output decimation rate
+    @type audio_decim: integer
+    """
+    def __init__(self, fg, channel_rate, audio_decim):
+       am_demod_cf.__init__(self, fg, channel_rate, audio_decim, 
+                            5000, # Audio passband
+                            5500) # Audio stopband
+       
\ No newline at end of file
diff --git a/gnuradio-core/src/python/gnuradio/blksimpl/digital_voice.py.real b/gnuradio-core/src/python/gnuradio/blksimpl/digital_voice.py.real
new file mode 100644 (file)
index 0000000..1b3a14f
--- /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 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.
+# 
+
+"""
+Digital voice Tx and Rx using GSM 13kbit vocoder and GMSK.
+
+Runs channel at 32kbit/sec.  Currently uses fake channel coding,
+but there's room for a rate 1/2 coder.
+"""
+
+from gnuradio import gr, gru
+from gnuradio.blksimpl.gmsk import gmsk_mod, gmsk_demod
+
+from gnuradio.vocoder import gsm_full_rate
+
+# Size of gsm full rate speech encoder output packet in bytes
+
+GSM_FRAME_SIZE = 33
+
+# Size of packet in bytes that we send to GMSK modulator:
+#
+# Target: 256kS/sec air rate.
+#
+#  256kS  1 sym   1 bit   1 byte   0.020 sec   80 bytes
+#  ---- * ----- * ----- * ------ * --------- = --------
+#  sec    8 S     1 sym   8 bits     frame      frame
+#
+# gr_simple_framer add 10 bytes of overhead.
+
+AIR_FRAME_SIZE = 70
+
+
+class digital_voice_tx(gr.hier_block):
+    """
+    Hierarchical block for digital voice tranmission.
+
+    The input is 8kS/sec floating point audio in the range [-1,+1]
+    The output is 256kS/sec GMSK modulated complex baseband signal in the range [-1,+1].
+    """
+    def __init__(self, fg):
+        samples_per_symbol = 8
+        symbol_rate = 32000
+        bt = 0.3                # Gaussian filter bandwidth * symbol time
+
+        src_scale = gr.multiply_const_ff(32767)
+        f2s = gr.float_to_short()
+        voice_coder = gsm_full_rate.encode_sp()
+
+        channel_coder = gr.fake_channel_encoder_pp(GSM_FRAME_SIZE, AIR_FRAME_SIZE)
+        p2s = gr.parallel_to_serial(gr.sizeof_char, AIR_FRAME_SIZE)
+
+        mod = gmsk_mod(fg, sps=samples_per_symbol,
+                       symbol_rate=symbol_rate, bt=bt,
+                       p_size=AIR_FRAME_SIZE)
+
+        fg.connect(src_scale, f2s, voice_coder, channel_coder, p2s, mod)
+        gr.hier_block.__init__(self, fg, src_scale, mod)
+
+
+class digital_voice_rx(gr.hier_block):
+    """
+    Hierarchical block for digital voice reception.
+
+    The input is 256kS/sec GMSK modulated complex baseband signal.
+    The output is 8kS/sec floating point audio in the range [-1,+1]
+    """
+    def __init__(self, fg):
+        samples_per_symbol = 8
+        symbol_rate = 32000
+
+        demod = gmsk_demod(fg, sps=samples_per_symbol,
+                           symbol_rate=symbol_rate, 
+                           p_size=AIR_FRAME_SIZE)
+
+        s2p = gr.serial_to_parallel(gr.sizeof_char, AIR_FRAME_SIZE)
+        channel_decoder = gr.fake_channel_decoder_pp(AIR_FRAME_SIZE, GSM_FRAME_SIZE)
+
+        voice_decoder = gsm_full_rate.decode_ps()
+        s2f = gr.short_to_float ()
+        sink_scale = gr.multiply_const_ff(1.0/32767.)
+
+        fg.connect(demod, s2p, channel_decoder, voice_decoder, s2f, sink_scale)
+        gr.hier_block.__init__(self, fg, demod, sink_scale)
diff --git a/gnuradio-core/src/python/gnuradio/blksimpl/filterbank.py b/gnuradio-core/src/python/gnuradio/blksimpl/filterbank.py
new file mode 100644 (file)
index 0000000..bd23f79
--- /dev/null
@@ -0,0 +1,160 @@
+#
+# 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 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.
+# 
+
+import sys
+from gnuradio import gr, gru
+
+def _generate_synthesis_taps(mpoints):
+    return []   # FIXME
+
+
+def _split_taps(taps, mpoints):
+    assert (len(taps) % mpoints) == 0
+    result = [list() for x in range(mpoints)]
+    for i in xrange(len(taps)):
+        (result[i % mpoints]).append(taps[i])
+    return [tuple(x) for x in result]
+
+
+class synthesis_filterbank(gr.hier_block):
+    """
+    Uniformly modulated polyphase DFT filter bank: synthesis
+
+    See http://cnx.rice.edu/content/m10424/latest
+    """
+    def __init__(self, fg, mpoints, taps=None):
+        """
+        Takes M complex streams in, produces single complex stream out
+        that runs at M times the input sample rate
+
+        @param fg:      flow_graph
+        @param mpoints: number of freq bins/interpolation factor/subbands
+        @param taps:    filter taps for subband filter
+
+        The channel spacing is equal to the input sample rate.
+        The total bandwidth and output sample rate are equal the input
+        sample rate * nchannels.
+
+        Output stream to frequency mapping:
+        
+          channel zero is at zero frequency.
+
+          if mpoints is odd:
+            
+            Channels with increasing positive frequencies come from
+            channels 1 through (N-1)/2.
+
+            Channel (N+1)/2 is the maximum negative frequency, and
+            frequency increases through N-1 which is one channel lower
+            than the zero frequency.
+
+          if mpoints is even:
+
+            Channels with increasing positive frequencies come from
+            channels 1 through (N/2)-1.
+
+            Channel (N/2) is evenly split between the max positive and
+            negative bins.
+
+            Channel (N/2)+1 is the maximum negative frequency, and
+            frequency increases through N-1 which is one channel lower
+            than the zero frequency.
+
+            Channels near the frequency extremes end up getting cut
+            off by subsequent filters and therefore have diminished
+            utility.
+        """
+        item_size = gr.sizeof_gr_complex
+
+        if taps is None:
+            taps = _generate_synthesis_taps(mpoints)
+
+        # pad taps to multiple of mpoints
+        r = len(taps) % mpoints
+        if r != 0:
+            taps = taps + (mpoints - r) * (0,)
+
+        # split in mpoints separate set of taps
+        sub_taps = _split_taps(taps, mpoints)
+
+        self.ss2v = gr.streams_to_vector(item_size, mpoints)
+        self.ifft = gr.fft_vcc(mpoints, False, [])
+        self.v2ss = gr.vector_to_streams(item_size, mpoints)
+        # mpoints filters go in here...
+        self.ss2s = gr.streams_to_stream(item_size, mpoints)
+
+        fg.connect(self.ss2v, self.ifft, self.v2ss)
+
+        # build mpoints fir filters...
+        for i in range(mpoints):
+            f = gr.fft_filter_ccc(1, sub_taps[i])
+            fg.connect((self.v2ss, i), f)
+            fg.connect(f, (self.ss2s, i))
+
+        gr.hier_block.__init__(self, fg, self.ss2v, self.ss2s)
+
+
+class analysis_filterbank(gr.hier_block):
+    """
+    Uniformly modulated polyphase DFT filter bank: analysis
+
+    See http://cnx.rice.edu/content/m10424/latest
+    """
+    def __init__(self, fg, mpoints, taps=None):
+        """
+        Takes 1 complex stream in, produces M complex streams out
+        that runs at 1/M times the input sample rate
+
+        @param fg:      flow_graph
+        @param mpoints: number of freq bins/interpolation factor/subbands
+        @param taps:    filter taps for subband filter
+
+        Same channel to frequency mapping as described above.
+        """
+        item_size = gr.sizeof_gr_complex
+
+        if taps is None:
+            taps = _generate_synthesis_taps(mpoints)
+
+        # pad taps to multiple of mpoints
+        r = len(taps) % mpoints
+        if r != 0:
+            taps = taps + (mpoints - r) * (0,)
+        
+        # split in mpoints separate set of taps
+        sub_taps = _split_taps(taps, mpoints)
+
+        # print >> sys.stderr, "mpoints =", mpoints, "len(sub_taps) =", len(sub_taps) 
+        
+        self.s2ss = gr.stream_to_streams(item_size, mpoints)
+        # filters here
+        self.ss2v = gr.streams_to_vector(item_size, mpoints)
+        self.fft = gr.fft_vcc(mpoints, True, [])
+        self.v2ss = gr.vector_to_streams(item_size, mpoints)
+
+        # build mpoints fir filters...
+        for i in range(mpoints):
+            f = gr.fft_filter_ccc(1, sub_taps[mpoints-i-1])
+            fg.connect((self.s2ss, i), f)
+            fg.connect(f, (self.ss2v, i))
+
+        fg.connect(self.ss2v, self.fft, self.v2ss)
+        gr.hier_block.__init__(self, fg, self.s2ss, self.v2ss)
diff --git a/gnuradio-core/src/python/gnuradio/blksimpl/fm_demod.py b/gnuradio-core/src/python/gnuradio/blksimpl/fm_demod.py
new file mode 100644 (file)
index 0000000..9487e0f
--- /dev/null
@@ -0,0 +1,122 @@
+#
+# 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 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.
+# 
+
+from gnuradio import gr, optfir
+from gnuradio.blksimpl.fm_emph import fm_deemph
+from math import pi
+
+class fm_demod_cf(gr.hier_block):
+    """
+    Generalized FM demodulation block with deemphasis and audio 
+    filtering.
+
+    This block demodulates a band-limited, complex down-converted FM 
+    channel into the the original baseband signal, optionally applying
+    deemphasis. Low pass filtering is done on the resultant signal. It
+    produces an output float strem in the range of [-1.0, +1.0].
+
+    @param fg: flowgraph
+    @param channel_rate:  incoming sample rate of the FM baseband
+    @type sample_rate: integer
+    @param deviation: maximum FM deviation (default = 5000)
+    @type deviation: float
+    @param audio_decim: input to output decimation rate
+    @type audio_decim: integer
+    @param audio_pass: audio low pass filter passband frequency 
+    @type audio_pass: float
+    @param audio_stop: audio low pass filter stop frequency
+    @type audio_stop: float
+    @param gain: gain applied to audio output (default = 1.0)
+    @type gain: float
+    @param tau: deemphasis time constant (default = 75e-6), specify 'None'
+       to prevent deemphasis
+    """ 
+    def __init__(self, fg, channel_rate, audio_decim, deviation, 
+                 audio_pass, audio_stop, gain=1.0, tau=75e-6):
+
+        """    
+       # Equalizer for ~100 us delay
+       delay = 100e-6
+       num_taps = int(channel_rate*delay)
+
+       mu = 1e-4/num_taps
+       print "CMA: delay =", delay, "n =", num_taps, "mu =", mu
+       CMA = gr.cma_equalizer_cc(num_taps, 1.0, mu)
+        """    
+       k = channel_rate/(2*pi*deviation)
+       QUAD = gr.quadrature_demod_cf(k)
+
+       audio_taps = optfir.low_pass(gain,         # Filter gain
+                                    channel_rate, # Sample rate
+                                    audio_pass,   # Audio passband
+                                    audio_stop,   # Audio stopband
+                                    0.1,          # Passband ripple
+                                    60)           # Stopband attenuation
+       LPF = gr.fir_filter_fff(audio_decim, audio_taps)
+
+       if tau is not None:
+           DEEMPH = fm_deemph(fg, channel_rate, tau)
+           fg.connect(QUAD, DEEMPH, LPF)
+        else:
+            fg.connect(QUAD, LPF)
+
+        gr.hier_block.__init__(self, fg, QUAD, LPF)
+
+class demod_20k0f3e_cf(fm_demod_cf):
+    """
+    NBFM demodulation block, 20 KHz channels
+
+    This block demodulates a complex, downconverted, narrowband FM 
+    channel conforming to 20K0F3E emission standards, outputting
+    floats in the range [-1.0, +1.0].
+    
+    @param fg: flowgraph
+    @param sample_rate:  incoming sample rate of the FM baseband
+    @type sample_rate: integer
+    @param audio_decim: input to output decimation rate
+    @type audio_decim: integer
+    """ 
+    def __init__(self, fg, channel_rate, audio_decim):
+        fm_demod_cf.__init__(self, fg, channel_rate, audio_decim,
+                             5000,     # Deviation
+                             3000,     # Audio passband frequency
+                             4000)     # Audio stopband frequency
+
+class demod_200kf3e_cf(fm_demod_cf):
+    """
+    WFM demodulation block, mono.
+    
+    This block demodulates a complex, downconverted, wideband FM 
+    channel conforming to 200KF3E emission standards, outputting 
+    floats in the range [-1.0, +1.0].
+
+    @param fg: flowgraph
+    @param sample_rate:  incoming sample rate of the FM baseband
+    @type sample_rate: integer
+    @param audio_decim: input to output decimation rate
+    @type audio_decim: integer
+    """
+    def __init__(self, fg, channel_rate, audio_decim): 
+       fm_demod_cf.__init__(self, fg, channel_rate, audio_decim,
+                            75000,     # Deviation
+                            15000,     # Audio passband
+                            16000,     # Audio stopband
+                            20.0)      # Audio gain
diff --git a/gnuradio-core/src/python/gnuradio/blksimpl/fm_emph.py b/gnuradio-core/src/python/gnuradio/blksimpl/fm_emph.py
new file mode 100644 (file)
index 0000000..5c256f5
--- /dev/null
@@ -0,0 +1,145 @@
+#
+# 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 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.
+# 
+
+from gnuradio import gr
+import math
+
+
+#
+#           1
+# H(s) = -------
+#         1 + s
+#
+# tau is the RC time constant.
+# critical frequency: w_p = 1/tau
+#
+# We prewarp and use the bilinear z-transform to get our IIR coefficients.
+# See "Digital Signal Processing: A Practical Approach" by Ifeachor and Jervis
+#
+
+class fm_deemph(gr.hier_block):
+    """
+    FM Deemphasis IIR filter.
+    """
+    def __init__(self, fg, fs, tau=75e-6):
+        """
+        @param fg: flow graph
+        @type fg: gr.flow_graph
+        @param fs: sampling frequency in Hz
+        @type fs: float
+        @param tau: Time constant in seconds (75us in US, 50us in EUR)
+        @type tau: float
+        """
+        w_p = 1/tau
+        w_pp = math.tan (w_p / (fs * 2)) # prewarped analog freq
+
+        a1 = (w_pp - 1)/(w_pp + 1)
+        b0 = w_pp/(1 + w_pp)
+        b1 = b0
+
+        btaps = [b0, b1]
+        ataps = [1, a1]
+
+        if 0:
+            print "btaps =", btaps
+            print "ataps =", ataps
+            global plot1
+            plot1 = gru.gnuplot_freqz (gru.freqz (btaps, ataps), fs, True)
+
+        deemph = gr.iir_filter_ffd(btaps, ataps)
+        gr.hier_block.__init__(self, fg, deemph, deemph)
+
+#
+#         1 + s*t1
+# H(s) = ----------
+#         1 + s*t2
+#
+# I think this is the right transfer function.
+#
+#
+# This fine ASCII rendition is based on Figure 5-15
+# in "Digital and Analog Communication Systems", Leon W. Couch II
+#
+#
+#               R1
+#         +-----||------+
+#         |             |
+#  o------+             +-----+--------o
+#         |      C1     |     |
+#         +----/\/\/\/--+     \
+#                             /
+#                             \ R2
+#                             /
+#                             \
+#                             |
+#  o--------------------------+--------o
+#
+# f1 = 1/(2*pi*t1) = 1/(2*pi*R1*C)
+#
+#         1          R1 + R2
+# f2 = ------- = ------------
+#      2*pi*t2    2*pi*R1*R2*C
+#
+# t1 is 75us in US, 50us in EUR
+# f2 should be higher than our audio bandwidth.
+#
+#
+# The Bode plot looks like this:
+#
+#
+#                    /----------------
+#                   /
+#                  /  <-- slope = 20dB/decade
+#                 /
+#   -------------/
+#               f1    f2
+#
+# We prewarp and use the bilinear z-transform to get our IIR coefficients.
+# See "Digital Signal Processing: A Practical Approach" by Ifeachor and Jervis
+#
+
+class fm_preemph(gr.hier_block):
+    """
+    FM Preemphasis IIR filter.
+    """
+    def __init__(self, fg, fs, tau=75e-6):
+        """
+        @param fg: flow graph
+        @type fg: gr.flow_graph
+        @param fs: sampling frequency in Hz
+        @type fs: float
+        @param tau: Time constant in seconds (75us in US, 50us in EUR)
+        @type tau: float
+        """
+
+        # FIXME make this compute the right answer
+        
+        btaps = [1]
+        ataps = [1]
+
+        if 0:
+            print "btaps =", btaps
+            print "ataps =", ataps
+            global plot2
+            plot2 = gru.gnuplot_freqz (gru.freqz (btaps, ataps), fs, True)
+
+        preemph = gr.iir_filter_ffd(btaps, ataps)
+        gr.hier_block.__init__(self, fg, preemph, preemph)
diff --git a/gnuradio-core/src/python/gnuradio/blksimpl/gmsk2.py b/gnuradio-core/src/python/gnuradio/blksimpl/gmsk2.py
new file mode 100644 (file)
index 0000000..68d1896
--- /dev/null
@@ -0,0 +1,159 @@
+#
+# GMSK modulation and demodulation.  
+#
+#
+# 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 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.
+# 
+
+# See gnuradio-examples/python/gmsk2 for examples
+
+from gnuradio import gr
+from math import pi
+import Numeric
+
+# /////////////////////////////////////////////////////////////////////////////
+#            GMSK mod/demod with steams of bytes as data i/o
+# /////////////////////////////////////////////////////////////////////////////
+
+class gmsk2_mod(gr.hier_block):
+
+    def __init__(self, fg, spb = 2, bt = 0.3):
+        """
+       Hierarchical block for Gaussian Minimum Shift Key (GMSK)
+       modulation.
+
+       The input is a byte stream (unsigned char) and the
+       output is the complex modulated signal at baseband.
+
+       @param fg: flow graph
+       @type fg: flow graph
+       @param spb: samples per baud >= 2
+       @type spb: integer
+       @param bt: Gaussian filter bandwidth * symbol time
+       @type bt: float
+       """
+        if not isinstance(spb, int) or spb < 2:
+            raise TypeError, "sbp must be an integer >= 2"
+        self.spb = spb
+
+       ntaps = 4 * spb                 # up to 3 bits in filter at once
+       sensitivity = (pi / 2) / spb    # phase change per bit = pi / 2
+
+       # Turn it into NRZ data.
+       self.nrz = gr.bytes_to_syms()
+
+       # Form Gaussian filter
+
+        # Generate Gaussian response (Needs to be convolved with window below).
+       self.gaussian_taps = gr.firdes.gaussian(
+               1,              # gain
+               spb,            # symbol_rate
+               bt,             # bandwidth * symbol time
+               ntaps           # number of taps
+               )
+
+       self.sqwave = (1,) * spb       # rectangular window
+       self.taps = Numeric.convolve(Numeric.array(self.gaussian_taps),Numeric.array(self.sqwave))
+       self.gaussian_filter = gr.interp_fir_filter_fff(spb, self.taps)
+
+       # FM modulation
+       self.fmmod = gr.frequency_modulator_fc(sensitivity)
+               
+       # Connect
+       fg.connect(self.nrz, self.gaussian_filter, self.fmmod)
+
+       # Initialize base class
+       gr.hier_block.__init__(self, fg, self.nrz, self.fmmod)
+
+    def samples_per_baud(self):
+        return self.spb
+
+    def bits_per_baud(self=None):   # staticmethod that's also callable on an instance
+        return 1
+    bits_per_baud = staticmethod(bits_per_baud)      # make it a static method.  RTFM
+
+
+class gmsk2_demod(gr.hier_block):
+
+    def __init__(self, fg, spb=2, omega=None, gain_mu=0.03, mu=0.5,
+                 omega_relative_limit=0.000200, freq_error=0.0):
+        """
+       Hierarchical block for Gaussian Minimum Shift Key (GMSK)
+       demodulation.
+
+       The input is the complex modulated signal at baseband.
+       The output is a stream of symbols ready to be sliced at zero.
+
+       @param fg: flow graph
+       @type fg: flow graph
+       @param spb: samples per baud
+       @type spb: integer
+
+        Clock recovery parameters.  These all have reasonble defaults.
+        
+        @param omega: nominal relative freq (defaults to spb)
+        @type omega: float
+        @param gain_mu: controls rate of mu adjustment
+        @type gain_mu: float
+        @param mu: fractional delay [0.0, 1.0]
+        @type mu: float
+        @param omega_relative_limit: sets max variation in omega
+        @type omega_relative_limit: float, typically 0.000200 (200 ppm)
+        @param freq_error: bit rate error as a fraction
+        @param float
+       """
+        if spb < 2:
+            raise TypeError, "sbp >= 2"
+        self.spb = spb
+        
+        if omega is None:
+            omega = spb*(1+freq_error)
+
+       gain_omega = .25*gain_mu*gain_mu        # critically damped
+
+        # Automatic gain control
+        self.preamp = gr.multiply_const_cc(10e-5)
+        self.agc = gr.agc_cc(1e-3, 1, 1, 1000)
+
+       # Demodulate FM
+       sensitivity = (pi / 2) / spb
+       self.fmdemod = gr.quadrature_demod_cf(1.0 / sensitivity)
+
+        alpha = 0.0008
+
+       # the clock recovery block tracks the symbol clock and resamples as needed.
+       # the output of the block is a stream of soft symbols (float)
+       self.clock_recovery = gr.clock_recovery_mm_ff(omega, gain_omega, mu, gain_mu,
+                                                      omega_relative_limit)
+
+        # slice the floats at 0, outputting 1 bit (the LSB of the output byte) per sample
+        self.slicer = gr.binary_slicer_fb()
+
+       fg.connect(self.preamp, self.agc, self.fmdemod, self.clock_recovery, self.slicer)
+        
+       # Initialize base class
+       gr.hier_block.__init__(self, fg, self.preamp, self.slicer)
+
+    def samples_per_baud(self):
+        return self.spb
+
+    def bits_per_baud(self=None):   # staticmethod that's also callable on an instance
+        return 1
+    bits_per_baud = staticmethod(bits_per_baud)      # make it a static method.  RTFM
diff --git a/gnuradio-core/src/python/gnuradio/blksimpl/gmsk2_pkt.py b/gnuradio-core/src/python/gnuradio/blksimpl/gmsk2_pkt.py
new file mode 100644 (file)
index 0000000..af58623
--- /dev/null
@@ -0,0 +1,174 @@
+#
+# 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 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.
+# 
+
+from math import pi
+import Numeric
+
+from gnuradio import gr, packet_utils
+import gnuradio.gr.gr_threading as _threading
+import gmsk2
+
+
+def _deprecation_warning(old_name, new_name):
+    print '#'
+    print '#  Warning: %s is deprecated and will be removed soon.' % (old_name,)
+    print '#           Please use the modulation independent block, %s.' % (new_name,)
+    print "#"
+
+
+# /////////////////////////////////////////////////////////////////////////////
+#                   GMSK mod/demod with packets as i/o
+# /////////////////////////////////////////////////////////////////////////////
+
+class gmsk2_mod_pkts(gr.hier_block):
+    """
+    GSM modulator that is a GNU Radio source.
+
+    Send packets by calling send_pkt
+    """
+    def __init__(self, fg, access_code=None, msgq_limit=2, pad_for_usrp=True, *args, **kwargs):
+        """
+       Hierarchical block for Gaussian Minimum Shift Key (GMSK) modulation.
+
+        Packets to be sent are enqueued by calling send_pkt.
+        The output is the complex modulated signal at baseband.
+
+       @param fg: flow graph
+       @type fg: flow graph
+        @param access_code: AKA sync vector
+        @type access_code: string of 1's and 0's between 1 and 64 long
+        @param msgq_limit: maximum number of messages in message queue
+        @type msgq_limit: int
+        @param pad_for_usrp: If true, packets are padded such that they end up a multiple of 128 samples
+
+        See gmsk_mod for remaining parameters
+        """
+        _deprecation_warning('gmsk2_mod_pkts', 'mod_pkts')
+        
+        self.pad_for_usrp = pad_for_usrp
+        if access_code is None:
+            access_code = packet_utils.default_access_code
+        if not packet_utils.is_1_0_string(access_code):
+            raise ValueError, "Invalid access_code %r. Must be string of 1's and 0's" % (access_code,)
+        self._access_code = access_code
+
+        # accepts messages from the outside world
+        self.pkt_input = gr.message_source(gr.sizeof_char, msgq_limit)
+        self.gmsk_mod = gmsk2.gmsk2_mod(fg, *args, **kwargs)
+        fg.connect(self.pkt_input, self.gmsk_mod)
+        gr.hier_block.__init__(self, fg, None, self.gmsk_mod)
+
+    def send_pkt(self, payload='', eof=False):
+        """
+        Send the payload.
+
+        @param payload: data to send
+        @type payload: string
+        """
+        if eof:
+            msg = gr.message(1) # tell self.pkt_input we're not sending any more packets
+        else:
+            # print "original_payload =", string_to_hex_list(payload)
+            pkt = packet_utils.make_packet(payload,
+                                           self.gmsk_mod.samples_per_baud(),
+                                           self.gmsk_mod.bits_per_baud(),
+                                           self._access_code,
+                                           self.pad_for_usrp)
+            #print "pkt =", string_to_hex_list(pkt)
+            msg = gr.message_from_string(pkt)
+        self.pkt_input.msgq().insert_tail(msg)
+
+
+
+class gmsk2_demod_pkts(gr.hier_block):
+    """
+    GSM demodulator that is a GNU Radio sink.
+
+    The input is complex baseband.  When packets are demodulated, they are passed to the
+    app via the callback.
+    """
+
+    def __init__(self, fg, access_code=None, callback=None, threshold=-1, *args, **kwargs):
+        """
+       Hierarchical block for Gaussian Minimum Shift Key (GMSK)
+       demodulation.
+
+       The input is the complex modulated signal at baseband.
+        Demodulated packets are sent to the handler.
+
+       @param fg: flow graph
+       @type fg: flow graph
+        @param access_code: AKA sync vector
+        @type access_code: string of 1's and 0's
+        @param callback:  function of two args: ok, payload
+        @type callback: ok: bool; payload: string
+        @param threshold: detect access_code with up to threshold bits wrong (-1 -> use default)
+        @type threshold: int
+
+        See gmsk_demod for remaining parameters.
+       """
+
+        _deprecation_warning('gmsk2_demod_pkts', 'demod_pkts')
+
+        if access_code is None:
+            access_code = packet_utils.default_access_code
+        if not packet_utils.is_1_0_string(access_code):
+            raise ValueError, "Invalid access_code %r. Must be string of 1's and 0's" % (access_code,)
+        self._access_code = access_code
+
+        if threshold == -1:
+            threshold = 12              # FIXME raise exception
+
+        self._rcvd_pktq = gr.msg_queue()          # holds packets from the PHY
+        self.gmsk_demod = gmsk2.gmsk2_demod(fg, *args, **kwargs)
+        self.correlator = gr.correlate_access_code_bb(access_code, threshold)
+
+        self.framer_sink = gr.framer_sink_1(self._rcvd_pktq)
+        fg.connect(self.gmsk_demod, self.correlator, self.framer_sink)
+        
+        gr.hier_block.__init__(self, fg, self.gmsk_demod, None)
+        self._watcher = _queue_watcher_thread(self._rcvd_pktq, callback)
+
+    def carrier_sensed(self):
+        """
+        Return True if we detect carrier.
+        """
+        return False        # FIXME
+
+
+class _queue_watcher_thread(_threading.Thread):
+    def __init__(self, rcvd_pktq, callback):
+        _threading.Thread.__init__(self)
+        self.setDaemon(1)
+        self.rcvd_pktq = rcvd_pktq
+        self.callback = callback
+        self.keep_running = True
+        self.start()
+
+    #def stop(self):
+    #    self.keep_running = False
+        
+    def run(self):
+        while self.keep_running:
+            msg = self.rcvd_pktq.delete_head()
+            ok, payload = packet_utils.unmake_packet(msg.to_string())
+            if self.callback:
+                self.callback(ok, payload)
diff --git a/gnuradio-core/src/python/gnuradio/blksimpl/nbfm_rx.py b/gnuradio-core/src/python/gnuradio/blksimpl/nbfm_rx.py
new file mode 100644 (file)
index 0000000..39059ec
--- /dev/null
@@ -0,0 +1,87 @@
+#
+# 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 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.
+# 
+
+import math
+from gnuradio import gr, optfir
+from gnuradio.blksimpl.fm_emph import fm_deemph
+from gnuradio.blksimpl.standard_squelch import standard_squelch
+
+class nbfm_rx(gr.hier_block):
+    def __init__(self, fg, audio_rate, quad_rate, tau=75e-6, max_dev=5e3):
+        """
+        Narrow Band FM Receiver.
+
+        Takes a single complex baseband input stream and produces a single
+        float output stream of audio sample in the range [-1, +1].
+
+        @param fg: flow graph
+        @param audio_rate: sample rate of audio stream, >= 16k
+        @type audio_rate: integer
+        @param quad_rate: sample rate of output stream
+        @type quad_rate: integer
+        @param tau: preemphasis time constant (default 75e-6)
+        @type tau: float
+        @param max_dev: maximum deviation in Hz (default 5e3)
+        @type max_dev: float
+
+        quad_rate must be an integer multiple of audio_rate.
+
+        Exported sub-blocks (attributes):
+          squelch
+          quad_demod
+          deemph
+          audio_filter
+        """
+
+        # FIXME audio_rate and quad_rate ought to be exact rationals
+        audio_rate = int(audio_rate)
+        quad_rate = int(quad_rate)
+
+        if quad_rate % audio_rate != 0:
+            raise ValueError, "quad_rate is not an integer multiple of audio_rate"
+
+        squelch_threshold = 20         # dB
+        #self.squelch = gr.simple_squelch_cc(squelch_threshold, 0.001)
+
+        # FM Demodulator  input: complex; output: float
+        k = quad_rate/(2*math.pi*max_dev)
+        self.quad_demod = gr.quadrature_demod_cf(k)
+
+        # FM Deemphasis IIR filter
+        self.deemph = fm_deemph (fg, quad_rate, tau=tau)
+
+        # compute FIR taps for audio filter
+        audio_decim = quad_rate // audio_rate
+        audio_taps = gr.firdes.low_pass (1.0,            # gain
+                                         quad_rate,      # sampling rate
+                                         4.5e3,          # Audio LPF cutoff
+                                         2.5e3,          # Transition band
+                                         gr.firdes.WIN_HAMMING)  # filter type
+
+        print "len(audio_taps) =", len(audio_taps)
+
+        # Decimating audio filter
+        # input: float; output: float; taps: float
+        self.audio_filter = gr.fir_filter_fff(audio_decim, audio_taps)
+
+        fg.connect(self.quad_demod, self.deemph, self.audio_filter)
+
+        gr.hier_block.__init__(self, fg, self.quad_demod, self.audio_filter)
diff --git a/gnuradio-core/src/python/gnuradio/blksimpl/nbfm_tx.py b/gnuradio-core/src/python/gnuradio/blksimpl/nbfm_tx.py
new file mode 100644 (file)
index 0000000..2f636b6
--- /dev/null
@@ -0,0 +1,95 @@
+#
+# 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 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.
+# 
+
+import math
+from gnuradio import gr, optfir
+from gnuradio.blksimpl.fm_emph import fm_preemph
+
+#from gnuradio import ctcss
+
+class nbfm_tx(gr.hier_block):
+    def __init__(self, fg, audio_rate, quad_rate, tau=75e-6, max_dev=5e3):
+        """
+        Narrow Band FM Transmitter.
+
+        Takes a single float input stream of audio samples in the range [-1,+1]
+        and produces a single FM modulated complex baseband output.
+
+        @param fg: flow graph
+        @param audio_rate: sample rate of audio stream, >= 16k
+        @type audio_rate: integer
+        @param quad_rate: sample rate of output stream
+        @type quad_rate: integer
+        @param tau: preemphasis time constant (default 75e-6)
+        @type tau: float
+        @param max_dev: maximum deviation in Hz (default 5e3)
+        @type max_dev: float
+
+        quad_rate must be an integer multiple of audio_rate.
+        """
+        
+        # FIXME audio_rate and quad_rate ought to be exact rationals
+        audio_rate = int(audio_rate)
+        quad_rate = int(quad_rate)
+
+        if quad_rate % audio_rate != 0:
+            raise ValueError, "quad_rate is not an integer multiple of audio_rate"
+
+        
+        do_interp = audio_rate != quad_rate
+        
+        if do_interp:
+            interp_factor = quad_rate / audio_rate
+            interp_taps = optfir.low_pass (interp_factor,   # gain
+                                           quad_rate,       # Fs
+                                           4500,            # passband cutoff
+                                           7000,            # stopband cutoff
+                                           0.1,            # passband ripple dB
+                                           40)              # stopband atten dB
+
+            #print "len(interp_taps) =", len(interp_taps)
+            self.interpolator = gr.interp_fir_filter_fff (interp_factor, interp_taps)
+
+        self.preemph = fm_preemph (fg, quad_rate, tau=tau)
+        
+        k = 2 * math.pi * max_dev / quad_rate
+        self.modulator = gr.frequency_modulator_fc (k)
+
+        if do_interp:
+            fg.connect (self.interpolator, self.preemph, self.modulator)
+            gr.hier_block.__init__(self, fg, self.interpolator, self.modulator)
+        else:
+            fg.connect(self.preemph, self.modulator)
+            gr.hier_block.__init__(self, fg, self.preemph, self.modulator)
+        
+       
+#class ctcss_gen_f(gr.sig_source_f):
+#    def __init__(self, sample_rate, tone_freq):
+#        gr.sig_source_f.__init__(self, sample_rate, gr.SIN_WAVE, tone_freq, 0.1, 0.0)
+#
+#    def set_tone (self, tone):
+#        gr.sig_source_f.set_frequency(self,tone)
+
+class ctcss_gen_f(gr.hier_block):
+    def __init__(self, fg, sample_rate, tone_freq):
+        self.plgen = gr.sig_source_f(sample_rate, gr.GR_SIN_WAVE, tone_freq, 0.1, 0.0)
+        
+        gr.hier_block.__init__(self, fg, self.plgen, self.plgen)
diff --git a/gnuradio-core/src/python/gnuradio/blksimpl/pkt.py b/gnuradio-core/src/python/gnuradio/blksimpl/pkt.py
new file mode 100644 (file)
index 0000000..3ebb722
--- /dev/null
@@ -0,0 +1,156 @@
+#
+# 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 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.
+# 
+
+from math import pi
+import Numeric
+
+from gnuradio import gr, packet_utils
+import gnuradio.gr.gr_threading as _threading
+
+
+# /////////////////////////////////////////////////////////////////////////////
+#                   mod/demod with packets as i/o
+# /////////////////////////////////////////////////////////////////////////////
+
+class mod_pkts(gr.hier_block):
+    """
+    Wrap an arbitrary digital modulator in our packet handling framework.
+
+    Send packets by calling send_pkt
+    """
+    def __init__(self, fg, modulator, access_code=None, msgq_limit=2, pad_for_usrp=True):
+        """
+       Hierarchical block for sending packets
+
+        Packets to be sent are enqueued by calling send_pkt.
+        The output is the complex modulated signal at baseband.
+
+       @param fg: flow graph
+       @type fg: flow graph
+        @param modulator: instance of modulator class (gr_block or hier_block)
+        @type modulator: complex baseband out
+        @param access_code: AKA sync vector
+        @type access_code: string of 1's and 0's between 1 and 64 long
+        @param msgq_limit: maximum number of messages in message queue
+        @type msgq_limit: int
+        @param pad_for_usrp: If true, packets are padded such that they end up a multiple of 128 samples
+
+        See gmsk_mod for remaining parameters
+        """
+        self._modulator = modulator
+        self._pad_for_usrp = pad_for_usrp
+
+        if access_code is None:
+            access_code = packet_utils.default_access_code
+        if not packet_utils.is_1_0_string(access_code):
+            raise ValueError, "Invalid access_code %r. Must be string of 1's and 0's" % (access_code,)
+        self._access_code = access_code
+
+        # accepts messages from the outside world
+        self._pkt_input = gr.message_source(gr.sizeof_char, msgq_limit)
+        fg.connect(self._pkt_input, self._modulator)
+        gr.hier_block.__init__(self, fg, None, self._modulator)
+
+    def send_pkt(self, payload='', eof=False):
+        """
+        Send the payload.
+
+        @param payload: data to send
+        @type payload: string
+        """
+        if eof:
+            msg = gr.message(1) # tell self._pkt_input we're not sending any more packets
+        else:
+            # print "original_payload =", string_to_hex_list(payload)
+            pkt = packet_utils.make_packet(payload,
+                                           self._modulator.samples_per_baud(),
+                                           self._modulator.bits_per_baud(),
+                                           self._access_code,
+                                           self._pad_for_usrp)
+            #print "pkt =", string_to_hex_list(pkt)
+            msg = gr.message_from_string(pkt)
+        self._pkt_input.msgq().insert_tail(msg)
+
+
+
+class demod_pkts(gr.hier_block):
+    """
+    Wrap an arbitrary digital demodulator in our packet handling framework.
+
+    The input is complex baseband.  When packets are demodulated, they are passed to the
+    app via the callback.
+    """
+
+    def __init__(self, fg, demodulator, access_code=None, callback=None, threshold=-1):
+        """
+       Hierarchical block for demodulating and deframing packets.
+
+       The input is the complex modulated signal at baseband.
+        Demodulated packets are sent to the handler.
+
+       @param fg: flow graph
+       @type fg: flow graph
+        @param demodulator: instance of demodulator class (gr_block or hier_block)
+        @type demodulator: complex baseband in
+        @param access_code: AKA sync vector
+        @type access_code: string of 1's and 0's
+        @param callback:  function of two args: ok, payload
+        @type callback: ok: bool; payload: string
+        @param threshold: detect access_code with up to threshold bits wrong (-1 -> use default)
+        @type threshold: int
+       """
+
+        self._demodulator = demodulator
+        if access_code is None:
+            access_code = packet_utils.default_access_code
+        if not packet_utils.is_1_0_string(access_code):
+            raise ValueError, "Invalid access_code %r. Must be string of 1's and 0's" % (access_code,)
+        self._access_code = access_code
+
+        if threshold == -1:
+            threshold = 12              # FIXME raise exception
+
+        self._rcvd_pktq = gr.msg_queue()          # holds packets from the PHY
+        self.correlator = gr.correlate_access_code_bb(access_code, threshold)
+
+        self.framer_sink = gr.framer_sink_1(self._rcvd_pktq)
+        fg.connect(self._demodulator, self.correlator, self.framer_sink)
+        
+        gr.hier_block.__init__(self, fg, self._demodulator, None)
+        self._watcher = _queue_watcher_thread(self._rcvd_pktq, callback)
+
+
+class _queue_watcher_thread(_threading.Thread):
+    def __init__(self, rcvd_pktq, callback):
+        _threading.Thread.__init__(self)
+        self.setDaemon(1)
+        self.rcvd_pktq = rcvd_pktq
+        self.callback = callback
+        self.keep_running = True
+        self.start()
+
+
+    def run(self):
+        while self.keep_running:
+            msg = self.rcvd_pktq.delete_head()
+            ok, payload = packet_utils.unmake_packet(msg.to_string())
+            if self.callback:
+                self.callback(ok, payload)
diff --git a/gnuradio-core/src/python/gnuradio/blksimpl/rational_resampler.py b/gnuradio-core/src/python/gnuradio/blksimpl/rational_resampler.py
new file mode 100644 (file)
index 0000000..8b928b1
--- /dev/null
@@ -0,0 +1,137 @@
+#
+# 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 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.
+# 
+
+from gnuradio import gr, gru
+
+_plot = None
+
+def design_filter(interpolation, decimation, fractional_bw):
+    """
+    Given the interpolation rate, decimation rate and a fractional bandwidth,
+    design a set of taps.
+
+    @param interpolation: interpolation factor
+    @type  interpolation: integer > 0
+    @param decimation: decimation factor
+    @type  decimation: integer > 0
+    @param fractional_bw: fractional bandwidth in (0, 0.5)  0.4 works well.
+    @type  fractional_bw: float
+    @returns: sequence of numbers
+    """
+
+    global _plot
+    
+    if fractional_bw >= 0.5 or fractional_bw <= 0:
+        raise ValueError, "Invalid fractional_bandwidth, must be in (0, 0.5)"
+
+    beta = 5.0
+    trans_width = 0.5 - fractional_bw
+    mid_transition_band = 0.5 - trans_width/2
+
+    taps = gr.firdes.low_pass(interpolation,                     # gain
+                              1,                                 # Fs
+                              mid_transition_band/interpolation, # trans mid point
+                              trans_width/interpolation,         # transition width
+                              gr.firdes.WIN_KAISER,
+                              beta                               # beta
+                              )
+    # print "len(resampler_taps) =", len(taps)
+    # _plot = gru.gnuplot_freqz(gru.freqz(taps, 1), 1)
+
+    return taps
+
+
+
+class _rational_resampler_base(gr.hier_block):
+    """
+    base class for all rational resampler variants.
+    """
+    def __init__(self, resampler_base, fg,
+                 interpolation, decimation, taps=None, fractional_bw=None):
+        """
+        Rational resampling polyphase FIR filter.
+
+        Either taps or fractional_bw may be specified, but not both.
+        If neither is specified, a reasonable default, 0.4, is used as
+        the fractional_bw.
+
+        @param fg: flow graph
+        @param interpolation: interpolation factor
+        @type  interpolation: integer > 0
+        @param decimation: decimation factor
+        @type  decimation: integer > 0
+        @param taps: optional filter coefficients
+        @type  taps: sequence
+        @param fractional_bw: fractional bandwidth in (0, 0.5), measured at final freq (use 0.4)
+        @type  fractional_bw: float
+        """
+
+        if not isinstance(interpolation, int) or interpolation < 1:
+            raise ValueError, "interpolation must be an integer >= 1"
+
+        if not isinstance(decimation, int) or decimation < 1:
+            raise ValueError, "decimation must be an integer >= 1"
+
+        if taps is None and fractional_bw is None:
+            fractional_bw = 0.4
+
+        d = gru.gcd(interpolation, decimation)
+        interpolation = interpolation // d
+        decimation = decimation // d
+        
+        if taps is None:
+            taps = design_filter(interpolation, decimation, fractional_bw)
+
+        resampler = resampler_base(interpolation, decimation, taps)
+        gr.hier_block.__init__(self, fg, resampler, resampler)
+
+
+
+class rational_resampler_fff(_rational_resampler_base):
+    def __init__(self, fg, interpolation, decimation, taps=None, fractional_bw=None):
+        """
+        Rational resampling polyphase FIR filter with
+        float input, float output and float taps.
+        """
+        _rational_resampler_base.__init__(self, gr.rational_resampler_base_fff, fg,
+                                          interpolation, decimation,
+                                          taps, fractional_bw)
+
+class rational_resampler_ccf(_rational_resampler_base):
+    def __init__(self, fg, interpolation, decimation, taps=None, fractional_bw=None):
+        """
+        Rational resampling polyphase FIR filter with
+        complex input, complex output and float taps.
+        """
+        _rational_resampler_base.__init__(self, gr.rational_resampler_base_ccf, fg,
+                                          interpolation, decimation,
+                                          taps, fractional_bw)
+
+class rational_resampler_ccc(_rational_resampler_base):
+    def __init__(self, fg, interpolation, decimation, taps=None, fractional_bw=None):
+        """
+        Rational resampling polyphase FIR filter with
+        complex input, complex output and complex taps.
+        """
+        _rational_resampler_base.__init__(self, gr.rational_resampler_base_ccc, fg,
+                                          interpolation, decimation,
+                                          taps, fractional_bw)
+
diff --git a/gnuradio-core/src/python/gnuradio/blksimpl/standard_squelch.py b/gnuradio-core/src/python/gnuradio/blksimpl/standard_squelch.py
new file mode 100644 (file)
index 0000000..2c80dd5
--- /dev/null
@@ -0,0 +1,73 @@
+#
+# 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 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.
+# 
+
+import math
+from gnuradio import gr, optfir
+
+class standard_squelch(gr.hier_block):
+    def __init__(self, fg, audio_rate):
+    
+        self.input_node = gr.add_const_ff(0)          # FIXME kludge
+        
+        self.low_iir = gr.iir_filter_ffd((0.0193,0,-0.0193),(1,1.9524,-0.9615))
+        self.low_square = gr.multiply_ff()
+        self.low_smooth = gr.single_pole_iir_filter_ff(1/(0.01*audio_rate))   # 100ms time constant
+
+        self.hi_iir = gr.iir_filter_ffd((0.0193,0,-0.0193),(1,1.3597,-0.9615))
+        self.hi_square = gr.multiply_ff()
+        self.hi_smooth = gr.single_pole_iir_filter_ff(1/(0.01*audio_rate))
+
+        self.sub = gr.sub_ff();
+        self.add = gr.add_ff();
+        self.gate = gr.threshold_ff(0.3,0.43,0)
+        self.squelch_lpf = gr.single_pole_iir_filter_ff(1/(0.01*audio_rate))
+
+        self.div = gr.divide_ff()
+        self.squelch_mult = gr.multiply_ff()
+
+        fg.connect (self.input_node, (self.squelch_mult, 0))
+
+        fg.connect (self.input_node,self.low_iir)
+        fg.connect (self.low_iir,(self.low_square,0))
+        fg.connect (self.low_iir,(self.low_square,1))
+        fg.connect (self.low_square,self.low_smooth,(self.sub,0))
+        fg.connect (self.low_smooth, (self.add,0))
+
+        fg.connect (self.input_node,self.hi_iir)
+        fg.connect (self.hi_iir,(self.hi_square,0))
+        fg.connect (self.hi_iir,(self.hi_square,1))
+        fg.connect (self.hi_square,self.hi_smooth,(self.sub,1))
+        fg.connect (self.hi_smooth, (self.add,1))
+
+        fg.connect (self.sub, (self.div, 0))
+        fg.connect (self.add, (self.div, 1))
+        fg.connect (self.div, self.gate, self.squelch_lpf, (self.squelch_mult,1))
+
+        gr.hier_block.__init__(self, fg, self.input_node, self.squelch_mult)
+
+    def set_threshold(self, threshold):
+        self.gate.set_hi(threshold)
+
+    def threshold(self):
+        return self.gate.hi()
+    
+    def squelch_range(self):
+        return (0.0, 1.0, 1.0/100)
diff --git a/gnuradio-core/src/python/gnuradio/blksimpl/wfm_rcv.py b/gnuradio-core/src/python/gnuradio/blksimpl/wfm_rcv.py
new file mode 100644 (file)
index 0000000..55dbbaa
--- /dev/null
@@ -0,0 +1,72 @@
+#
+# 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 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.
+# 
+
+from gnuradio import gr
+from gnuradio.blksimpl.fm_emph import fm_deemph
+import math
+
+class wfm_rcv(gr.hier_block):
+    def __init__ (self, fg, quad_rate, audio_decimation):
+        """
+        Hierarchical block for demodulating a broadcast FM signal.
+        
+        The input is the downconverted complex baseband signal (gr_complex).
+        The output is the demodulated audio (float).
+        
+        @param fg: flow graph.
+        @type fg: flow graph
+        @param quad_rate: input sample rate of complex baseband input.
+        @type quad_rate: float
+        @param audio_decimation: how much to decimate quad_rate to get to audio.
+        @type audio_decimation: integer
+        """
+        volume = 20.
+
+        max_dev = 75e3
+        fm_demod_gain = quad_rate/(2*math.pi*max_dev)
+        audio_rate = quad_rate / audio_decimation
+        
+
+        # We assign to self so that outsiders can grab the demodulator 
+        # if they need to.  E.g., to plot its output.
+        #
+        # input: complex; output: float
+        self.fm_demod = gr.quadrature_demod_cf (fm_demod_gain)
+
+        # input: float; output: float
+        self.deemph = fm_deemph (fg, audio_rate)
+        
+        # compute FIR filter taps for audio filter
+        width_of_transition_band = audio_rate / 32
+        audio_coeffs = gr.firdes.low_pass (1.0,         # gain
+                                           quad_rate,      # sampling rate
+                                           audio_rate/2 - width_of_transition_band,
+                                           width_of_transition_band,
+                                           gr.firdes.WIN_HAMMING)
+        # input: float; output: float
+        self.audio_filter = gr.fir_filter_fff (audio_decimation, audio_coeffs)
+
+        fg.connect (self.fm_demod, self.audio_filter, self.deemph)
+
+        gr.hier_block.__init__(self,
+                               fg,
+                               self.fm_demod,       # head of the pipeline
+                               self.deemph)   # tail of the pipeline
diff --git a/gnuradio-core/src/python/gnuradio/blksimpl/wfm_rcv_pll.py b/gnuradio-core/src/python/gnuradio/blksimpl/wfm_rcv_pll.py
new file mode 100644 (file)
index 0000000..d116090
--- /dev/null
@@ -0,0 +1,206 @@
+#
+# 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 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.
+# 
+
+from gnuradio import gr
+from gnuradio.blksimpl.fm_emph import fm_deemph
+import math
+
+class wfm_rcv_pll(gr.hier_block):
+    def __init__ (self, fg, demod_rate, audio_decimation):
+        """
+        Hierarchical block for demodulating a broadcast FM signal.
+        
+        The input is the downconverted complex baseband signal (gr_complex).
+        The output is two streams of the demodulated audio (float) 0=Left, 1=Right.
+        
+        @param fg: flow graph.
+        @type fg: flow graph
+        @param demod_rate: input sample rate of complex baseband input.
+        @type demod_rate: float
+        @param audio_decimation: how much to decimate demod_rate to get to audio.
+        @type audio_decimation: integer
+        """
+
+        bandwidth = 200e3
+        audio_rate = demod_rate / audio_decimation
+
+
+        # We assign to self so that outsiders can grab the demodulator 
+        # if they need to.  E.g., to plot its output.
+        #
+        # input: complex; output: float
+        alpha = 0.25*bandwidth * math.pi / demod_rate
+        beta = alpha * alpha / 4.0
+        max_freq = 2.0*math.pi*100e3/demod_rate
+            
+        self.fm_demod = gr.pll_freqdet_cf (alpha,beta,max_freq,-max_freq)
+
+        # input: float; output: float
+        self.deemph_Left  = fm_deemph (fg, audio_rate)
+        self.deemph_Right = fm_deemph (fg, audio_rate)
+        
+        # compute FIR filter taps for audio filter
+        width_of_transition_band = audio_rate / 32
+        audio_coeffs = gr.firdes.low_pass (1.0 ,         # gain
+                                           demod_rate,      # sampling rate
+                                           15000 ,
+                                           width_of_transition_band,
+                                           gr.firdes.WIN_HAMMING)
+        # input: float; output: float
+        self.audio_filter = gr.fir_filter_fff (audio_decimation, audio_coeffs)
+        if 1:
+            # Pick off the stereo carrier/2 with this filter. It attenuated 10 dB so apply 10 dB gain
+            # We pick off the negative frequency half because we want to base band by it!
+            ##  NOTE  THIS WAS HACKED TO OFFSET INSERTION LOSS DUE TO DEEMPHASIS
+
+            stereo_carrier_filter_coeffs = gr.firdes.complex_band_pass(10.0,
+                                                                   demod_rate,
+                                                                   -19020,
+                                                                   -18980,
+                                                                   width_of_transition_band,
+                                                                   gr.firdes.WIN_HAMMING)
+            
+            #print "len stereo carrier filter = ",len(stereo_carrier_filter_coeffs)
+            #print "stereo carrier filter ", stereo_carrier_filter_coeffs
+            #print "width of transition band = ",width_of_transition_band, " audio rate = ", audio_rate
+
+            # Pick off the double side band suppressed carrier Left-Right audio. It is attenuated 10 dB so apply 10 dB gain
+
+            stereo_dsbsc_filter_coeffs = gr.firdes.complex_band_pass(20.0,
+                                                                     demod_rate,
+                                                                     38000-15000/2,
+                                                                     38000+15000/2,
+                                                                     width_of_transition_band,
+                                                                     gr.firdes.WIN_HAMMING)
+            #print "len stereo dsbsc filter = ",len(stereo_dsbsc_filter_coeffs)
+            #print "stereo dsbsc filter ", stereo_dsbsc_filter_coeffs
+            # construct overlap add filter system from coefficients for stereo carrier
+
+            self.stereo_carrier_filter = gr.fir_filter_fcc(audio_decimation, stereo_carrier_filter_coeffs)
+
+            # carrier is twice the picked off carrier so arrange to do a commplex multiply
+
+            self.stereo_carrier_generator = gr.multiply_cc();
+
+            # Pick off the rds signal
+
+            stereo_rds_filter_coeffs = gr.firdes.complex_band_pass(30.0,
+                                                                     demod_rate,
+                                                                     57000 - 1500,
+                                                                     57000 + 1500,
+                                                                     width_of_transition_band,
+                                                                     gr.firdes.WIN_HAMMING)
+            #print "len stereo dsbsc filter = ",len(stereo_dsbsc_filter_coeffs)
+            #print "stereo dsbsc filter ", stereo_dsbsc_filter_coeffs
+            # construct overlap add filter system from coefficients for stereo carrier
+
+            self.stereo_carrier_filter = gr.fir_filter_fcc(audio_decimation, stereo_carrier_filter_coeffs)
+           self.rds_signal_filter = gr.fir_filter_fcc(audio_decimation, stereo_rds_filter_coeffs)
+
+
+
+
+
+
+           self.rds_carrier_generator = gr.multiply_cc();
+           self.rds_signal_generator = gr.multiply_cc();
+           self_rds_signal_processor = gr.null_sink(gr.sizeof_gr_complex);
+
+
+
+            alpha = 5 * 0.25 * math.pi / (audio_rate)
+            beta = alpha * alpha / 4.0
+            max_freq = -2.0*math.pi*18990/audio_rate;
+            min_freq = -2.0*math.pi*19010/audio_rate;
+            
+            self.stereo_carrier_pll_recovery = gr.pll_carriertracking_cc(alpha,beta,max_freq,min_freq);
+            self.stereo_carrier_pll_recovery.squelch_enable(False);
+            
+
+            # set up mixer (multiplier) to get the L-R signal at baseband
+
+            self.stereo_basebander = gr.multiply_cc();
+
+            # pick off the real component of the basebanded L-R signal.  The imaginary SHOULD be zero
+
+            self.LmR_real = gr.complex_to_real();
+            self.Make_Left = gr.add_ff();
+            self.Make_Right = gr.sub_ff();
+            
+            self.stereo_dsbsc_filter = gr.fir_filter_fcc(audio_decimation, stereo_dsbsc_filter_coeffs)
+
+
+        if 1:
+
+            # send the real signal to complex filter to pick off the carrier and then to one side of a multiplier
+            fg.connect (self.fm_demod,self.stereo_carrier_filter,self.stereo_carrier_pll_recovery, (self.stereo_carrier_generator,0))
+            # send the already filtered carrier to the otherside of the carrier
+            fg.connect (self.stereo_carrier_pll_recovery, (self.stereo_carrier_generator,1))
+            # the resulting signal from this multiplier is the carrier with correct phase but at -38000 Hz.
+
+            # send the new carrier to one side of the mixer (multiplier)
+            fg.connect (self.stereo_carrier_generator, (self.stereo_basebander,0))
+            # send the demphasized audio to the DSBSC pick off filter,  the complex
+            # DSBSC signal at +38000 Hz is sent to the other side of the mixer/multiplier
+            fg.connect (self.fm_demod,self.stereo_dsbsc_filter, (self.stereo_basebander,1))
+            # the result is BASEBANDED DSBSC with phase zero!
+
+            # Pick off the real part since the imaginary is theoretically zero and then to one side of a summer
+            fg.connect (self.stereo_basebander, self.LmR_real, (self.Make_Left,0))
+            #take the same real part of the DSBSC baseband signal and send it to negative side of a subtracter
+            fg.connect (self.LmR_real,(self.Make_Right,1))
+
+           # Make rds carrier by taking the squared pilot tone and multiplying by pilot tone
+           fg.connect (self.stereo_basebander,(self.rds_carrier_generator,0))
+            fg.connect (self.stereo_carrier_pll_recovery,(self.rds_carrier_generator,1)) 
+           # take signal, filter off rds,  send into mixer 0 channel
+           fg.connect (self.fm_demod,self.rds_signal_filter,(self.rds_signal_generator,0))
+            # take rds_carrier_generator output and send into mixer 1 channel
+           fg.connect (self.rds_carrier_generator,(self.rds_signal_generator,1))
+           # send basebanded rds signal and send into "processor" which for now is a null sink
+           fg.connect (self.rds_signal_generator,self_rds_signal_processor)
+           
+
+        if 1:
+            # pick off the audio, L+R that is what we used to have and send it to the summer
+            fg.connect(self.fm_demod, self.audio_filter, (self.Make_Left, 1))
+            # take the picked off L+R audio and send it to the PLUS side of the subtractor
+            fg.connect(self.audio_filter,(self.Make_Right, 0))
+            # The result of  Make_Left  gets    (L+R) +  (L-R) and results in 2*L
+            # The result of Make_Right gets  (L+R) - (L-R) and results in 2*R
+
+
+            # kludge the signals into a stereo channel
+            kludge = gr.kludge_copy(gr.sizeof_float)
+            fg.connect(self.Make_Left , self.deemph_Left, (kludge, 0))
+            fg.connect(self.Make_Right, self.deemph_Right, (kludge, 1))
+
+           #send it to the audio system
+            gr.hier_block.__init__(self,
+                                   fg,
+                                   self.fm_demod,       # head of the pipeline
+                                   kludge)              # tail of the pipeline
+        else:
+            fg.connect (self.fm_demod, self.audio_filter)
+            gr.hier_block.__init__(self,
+                                   fg,
+                                   self.fm_demod,       # head of the pipeline
+                                   self.audio_filter)   # tail of the pipeline
diff --git a/gnuradio-core/src/python/gnuradio/blksimpl/wfm_tx.py b/gnuradio-core/src/python/gnuradio/blksimpl/wfm_tx.py
new file mode 100644 (file)
index 0000000..5054555
--- /dev/null
@@ -0,0 +1,79 @@
+#
+# 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 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.
+# 
+
+import math
+from gnuradio import gr, optfir
+from gnuradio.blksimpl.fm_emph import fm_preemph
+
+class wfm_tx(gr.hier_block):
+    def __init__(self, fg, audio_rate, quad_rate, tau=75e-6, max_dev=75e3):
+        """
+        Wide Band FM Transmitter.
+
+        Takes a single float input stream of audio samples in the range [-1,+1]
+        and produces a single FM modulated complex baseband output.
+
+        @param fg: flow graph
+        @param audio_rate: sample rate of audio stream, >= 16k
+        @type audio_rate: integer
+        @param quad_rate: sample rate of output stream
+        @type quad_rate: integer
+        @param tau: preemphasis time constant (default 75e-6)
+        @type tau: float
+        @param max_dev: maximum deviation in Hz (default 75e3)
+        @type max_dev: float
+
+        quad_rate must be an integer multiple of audio_rate.
+        """
+        
+        # FIXME audio_rate and quad_rate ought to be exact rationals
+        audio_rate = int(audio_rate)
+        quad_rate = int(quad_rate)
+
+        if quad_rate % audio_rate != 0:
+            raise ValueError, "quad_rate is not an integer multiple of audio_rate"
+
+        
+        do_interp = audio_rate != quad_rate
+        
+        if do_interp:
+            interp_factor = quad_rate / audio_rate
+            interp_taps = optfir.low_pass (interp_factor,   # gain
+                                           quad_rate,       # Fs
+                                           16000,           # passband cutoff
+                                           18000,           # stopband cutoff
+                                           0.1,            # passband ripple dB
+                                           40)              # stopband atten dB
+
+            print "len(interp_taps) =", len(interp_taps)
+            self.interpolator = gr.interp_fir_filter_fff (interp_factor, interp_taps)
+
+        self.preemph = fm_preemph (fg, quad_rate, tau=tau)
+        
+        k = 2 * math.pi * max_dev / quad_rate
+        self.modulator = gr.frequency_modulator_fc (k)
+
+        if do_interp:
+            fg.connect (self.interpolator, self.preemph, self.modulator)
+            gr.hier_block.__init__(self, fg, self.interpolator, self.modulator)
+        else:
+            fg.connect(self.preemph, self.modulator)
+            gr.hier_block.__init__(self, fg, self.preemph, self.modulator)
diff --git a/gnuradio-core/src/python/gnuradio/eng_notation.py b/gnuradio-core/src/python/gnuradio/eng_notation.py
new file mode 100644 (file)
index 0000000..72cd893
--- /dev/null
@@ -0,0 +1,71 @@
+#
+# 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 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.
+# 
+
+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
+
+def num_to_str (n):
+    '''Convert a number to a string in engineering notation.  E.g., 5e-9 -> 5n'''
+    m = abs(n)
+    if m >= 1e9:
+        return "%gG" % (n * 1e-9)
+    elif m >= 1e6:
+        return "%gM" % (n * 1e-6)
+    elif m >= 1e3:
+        return "%gk" % (n * 1e-3)
+    elif m >= 1:
+        return "%g" % (n)
+    elif m >= 1e-3:
+        return "%gm" % (n * 1e3)
+    elif m >= 1e-6:
+        return "%gu" % (n * 1e6)        # where's that mu when you need it (unicode?)
+    elif m >= 1e-9:
+        return "%gn" % (n * 1e9)
+    elif m >= 1e-12:
+        return "%gp" % (n * 1e12)
+    elif m >= 1e-15:
+        return "%gf" % (n * 1e15)
+    else:
+        return "%g" % (n)
+
+
+def str_to_num (value):
+    '''Convert a string in engineering notation to a number.  E.g., '15m' -> 15e-3'''
+    try:
+        scale = 1.0
+        suffix = value[-1]
+        if scale_factor.has_key (suffix):
+            return float (value[0:-1]) * scale_factor[suffix]
+        return float (value)
+    except:
+        raise RuntimeError (
+            "Invalid engineering notation value: %r" % (value,))
diff --git a/gnuradio-core/src/python/gnuradio/eng_option.py b/gnuradio-core/src/python/gnuradio/eng_option.py
new file mode 100644 (file)
index 0000000..3e25c57
--- /dev/null
@@ -0,0 +1,80 @@
+#
+# 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.
+# 
+
+'''Add support for engineering notation to optparse.OptionParser'''
+
+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
+
+
+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)
+    except:
+        raise OptionValueError (
+            "option %s: invalid engineering notation value: %r" % (opt, value))
+
+def check_intx (option, opt, value):
+    try:
+        return int (value, 0)
+    except:
+        raise OptionValueError (
+            "option %s: invalid integer value: %r" % (opt, value))
+
+def check_subdev (option, opt, value):
+    """
+    Value has the form: (A|B)(:0|1)?
+
+    @returns a 2-tuple (0|1, 0|1)
+    """
+    d = { 'A'   : (0, 0),  'A:0' : (0, 0),  'A:1' : (0, 1),
+          'B'   : (1, 0),  'B:0' : (1, 0),  'B:1' : (1, 1) }
+    try:
+        return d[value.upper()]
+    except:
+        raise OptionValueError(
+            "option %s: invalid subdev: '%r', must be one of A, B, A:0, A:1, B:0, B:1" % (opt, value))
+
+class eng_option (Option):
+    TYPES = Option.TYPES + ("eng_float", "intx", "subdev")
+    TYPE_CHECKER = copy (Option.TYPE_CHECKER)
+    TYPE_CHECKER["eng_float"] = check_eng_float
+    TYPE_CHECKER["intx"] = check_intx
+    TYPE_CHECKER["subdev"] = check_subdev
+
diff --git a/gnuradio-core/src/python/gnuradio/gr/Makefile.am b/gnuradio-core/src/python/gnuradio/gr/Makefile.am
new file mode 100644 (file)
index 0000000..05dee29
--- /dev/null
@@ -0,0 +1,77 @@
+#
+# Copyright 2004,2005,2006 Free Software Foundation, Inc.
+# 
+# This file is part of GNU Radio
+# 
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 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.
+# 
+
+include $(top_srcdir)/Makefile.common
+
+EXTRA_DIST = run_tests.in
+
+
+TESTS =                        \
+       run_tests
+
+
+grgrpythondir = $(grpythondir)/gr
+
+grgrpython_PYTHON =            \
+       __init__.py             \
+       basic_flow_graph.py     \
+       exceptions.py           \
+       flow_graph.py           \
+       gr_threading.py         \
+       gr_threading_23.py      \
+       gr_threading_24.py      \
+       hier_block.py           \
+       prefs.py                \
+       scheduler.py            
+
+noinst_PYTHON =                        \
+       qa_add_and_friends.py           \
+       qa_basic_flow_graph.py          \
+       qa_complex_to_xxx.py            \
+       qa_correlate_access_code.py     \
+       qa_diff_encoder.py              \
+       qa_diff_phasor_cc.py            \
+       qa_feval.py                     \
+       qa_fft_filter.py                \
+       qa_filter_delay_fc.py           \
+       qa_flow_graph.py                \
+       qa_frequency_modulator.py       \
+       qa_fsk_stuff.py                 \
+       qa_head.py                      \
+       qa_hilbert.py                   \
+       qa_iir.py                       \
+       qa_interleave.py                \
+       qa_interp_fir_filter.py         \
+       qa_kludge_copy.py               \
+       qa_kludged_imports.py           \
+       qa_message.py                   \
+       qa_mute.py                      \
+       qa_nlog10.py                    \
+       qa_packed_to_unpacked.py        \
+       qa_pipe_fittings.py             \
+       qa_rational_resampler.py        \
+       qa_sig_source.py                \
+       qa_single_pole_iir.py           \
+       qa_single_pole_iir_cc.py        \
+       qa_unpack_k_bits.py             
+
+
+CLEANFILES = *.pyc
diff --git a/gnuradio-core/src/python/gnuradio/gr/__init__.py b/gnuradio-core/src/python/gnuradio/gr/__init__.py
new file mode 100644 (file)
index 0000000..5583c41
--- /dev/null
@@ -0,0 +1,40 @@
+#
+# Copyright 2003,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 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.
+# 
+
+# The presence of this file turns this directory into a Python package
+
+# This is the main GNU Radio python module.
+# We pull the swig output and the other modules into the gnuradio.gr namespace
+
+from gnuradio_swig_python import *
+from basic_flow_graph import *
+from flow_graph import *
+from exceptions import *
+from hier_block import *
+
+
+# create a couple of aliases
+serial_to_parallel = stream_to_vector
+parallel_to_serial = vector_to_stream
+
+# Force the preference database to be initialized
+from prefs import prefs
+
diff --git a/gnuradio-core/src/python/gnuradio/gr/basic_flow_graph.py b/gnuradio-core/src/python/gnuradio/gr/basic_flow_graph.py
new file mode 100644 (file)
index 0000000..1afc962
--- /dev/null
@@ -0,0 +1,267 @@
+#
+# 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.
+# 
+
+from gnuradio_swig_python import gr_block_sptr
+import types
+import hier_block
+
+def remove_duplicates (seq):
+    new = []
+    for x in seq:
+        if not x in new:
+            new.append (x)
+    return new
+
+
+class endpoint (object):
+    __slots__ = ['block', 'port']
+    def __init__ (self, block, port):
+        self.block = block
+        self.port = port
+
+    def __cmp__ (self, other):
+        if self.block == other.block and self.port == other.port:
+            return 0
+        return 1
+
+    def __str__ (self):
+        return '<endpoint (%s, %s)>' % (self.block, self.port)
+        
+def expand_src_endpoint (src_endpoint):
+    # A src_endpoint is an output of a block
+    src_endpoint = coerce_endpoint (src_endpoint)
+    if isinstance (src_endpoint.block, hier_block.hier_block_base):
+        return expand_src_endpoint (
+            coerce_endpoint (src_endpoint.block.resolve_output_port(src_endpoint.port)))
+    else:
+        return src_endpoint
+
+def expand_dst_endpoint (dst_endpoint):
+    # a dst_endpoint is the input to a block
+    dst_endpoint = coerce_endpoint (dst_endpoint)
+    if isinstance (dst_endpoint.block, hier_block.hier_block_base):
+        exp = [coerce_endpoint(x) for x in
+               dst_endpoint.block.resolve_input_port(dst_endpoint.port)]
+        return expand_dst_endpoints (exp)
+    else:
+        return [dst_endpoint]
+
+def expand_dst_endpoints (endpoint_list):
+    r = []
+    for e in endpoint_list:
+        r.extend (expand_dst_endpoint (e))
+    return r
+           
+
+def coerce_endpoint (x):
+    if isinstance (x, endpoint):
+        return x
+    elif isinstance (x, types.TupleType) and len (x) == 2:
+        return endpoint (x[0], x[1])
+    elif hasattr (x, 'block'):          # assume it's a block
+        return endpoint (x, 0)
+    elif isinstance(x, hier_block.hier_block_base):
+        return endpoint (x, 0)
+    else:
+        raise ValueError, "Not coercible to endpoint: %s" % (x,)
+    
+
+class edge (object):
+    __slots__ = ['src', 'dst']
+    def __init__ (self, src_endpoint, dst_endpoint):
+        self.src = src_endpoint
+        self.dst = dst_endpoint
+
+    def __cmp__ (self, other):
+        if self.src == other.src and self.dst == other.dst:
+            return 0
+        return 1
+
+    def __repr__ (self):
+        return '<edge (%s, %s)>' % (self.src, self.dst)
+
+class basic_flow_graph (object):
+    '''basic_flow_graph -- describe connections between blocks'''
+    # __slots__ is incompatible with weakrefs (for some reason!)
+    # __slots__ = ['edge_list']
+    def __init__ (self):
+        self.edge_list = []
+
+    def connect (self, *points):
+        '''connect requires two or more arguments that can be coerced to endpoints.
+        If more than two arguments are provided, they are connected together successively.
+        '''
+        if len (points) < 2:
+            raise ValueError, ("connect requires at least two endpoints; %d provided." % (len (points),))
+        for i in range (1, len (points)):
+            self._connect (points[i-1], points[i])
+
+    def _connect (self, src_endpoint, dst_endpoint):
+        s = expand_src_endpoint (src_endpoint)
+        for d in expand_dst_endpoint (dst_endpoint):
+            self._connect_prim (s, d)
+
+    def _connect_prim (self, src_endpoint, dst_endpoint):
+        src_endpoint = coerce_endpoint (src_endpoint)
+        dst_endpoint = coerce_endpoint (dst_endpoint)
+        self._check_valid_src_port (src_endpoint)
+        self._check_valid_dst_port (dst_endpoint)
+        self._check_dst_in_use (dst_endpoint)
+        self._check_type_match (src_endpoint, dst_endpoint)
+        self.edge_list.append (edge (src_endpoint, dst_endpoint))
+
+    def disconnect (self, src_endpoint, dst_endpoint):
+        s = expand_src_endpoint (src_endpoint)
+        for d in expand_dst_endpoint (dst_endpoint):
+            self._disconnect_prim (s, d)
+
+    def _disconnect_prim (self, src_endpoint, dst_endpoint):
+        src_endpoint = coerce_endpoint (src_endpoint)
+        dst_endpoint = coerce_endpoint (dst_endpoint)
+        e = edge (src_endpoint, dst_endpoint)
+        self.edge_list.remove (e)
+
+    def disconnect_all (self):
+        self.edge_list = []
+        
+    def validate (self):
+        # check all blocks to ensure:
+        #  (1a) their input ports are contiguously assigned
+        #  (1b) the number of input ports is between min and max
+        #  (2a) their output ports are contiguously assigned
+        #  (2b) the number of output ports is between min and max
+        #  (3)  check_topology returns true
+
+        for m in self.all_blocks ():
+            # print m
+
+            edges = self.in_edges (m)
+            used_ports = [e.dst.port for e in edges]
+            ninputs = self._check_contiguity (m, m.input_signature (), used_ports, "input")
+
+            edges = self.out_edges (m)
+            used_ports = [e.src.port for e in edges]
+            noutputs = self._check_contiguity (m, m.output_signature (), used_ports, "output")
+
+            if not m.check_topology (ninputs, noutputs):
+                raise ValueError, ("%s::check_topology (%d, %d) failed" % (m, ninputs, noutputs))
+            
+        
+    # --- public utilities ---
+                
+    def all_blocks (self):
+        '''return list of all blocks in the graph'''
+        all_blocks = []
+        for edge in self.edge_list:
+            m = edge.src.block
+            if not m in all_blocks:
+                all_blocks.append (m)
+            m = edge.dst.block
+            if not m in all_blocks:
+                all_blocks.append (m)
+        return all_blocks
+        
+    def in_edges (self, m):
+        '''return list of all edges that have M as a destination'''
+        return [e for e in self.edge_list if e.dst.block == m]
+    
+    def out_edges (self, m):
+        '''return list of all edges that have M as a source'''
+        return [e for e in self.edge_list if e.src.block == m]
+    
+    def downstream_verticies (self, m):
+        return [e.dst.block for e in self.out_edges (m)]
+
+    def downstream_verticies_port (self, m, port):
+        return [e.dst.block for e in self.out_edges(m) if e.src.port == port]
+
+    def upstream_verticies (self, m):
+        return [e.src.block for e in self.in_edges (m)]
+
+    def adjacent_verticies (self, m):
+        '''return list of all verticies adjacent to M'''
+        return self.downstream_verticies (m) + self.upstream_verticies (m)
+
+    def sink_p (self, m):
+        '''return True iff this block is a sink'''
+        e = self.out_edges (m)
+        return len (e) == 0
+
+    def source_p (self, m):
+        '''return True iff this block is a source'''
+        e = self.in_edges (m)
+        return len (e) == 0
+        
+    # --- internal methods ---
+    
+    def _check_dst_in_use (self, dst_endpoint):
+        '''Ensure that there is not already an endpoint that terminates at dst_endpoint.'''
+        x = [ep for ep in self.edge_list if ep.dst == dst_endpoint]
+        if x:    # already in use
+            raise ValueError, ("destination endpoint already in use: %s" % (dst_endpoint))
+
+    def _check_valid_src_port (self, src_endpoint):
+        self._check_port (src_endpoint.block.output_signature(), src_endpoint.port)
+        
+    def _check_valid_dst_port (self, dst_endpoint):
+        self._check_port (dst_endpoint.block.input_signature(), dst_endpoint.port)
+        
+    def _check_port (self, signature, port):
+        if port < 0:
+            raise ValueError, 'port number out of range.'
+        if signature.max_streams () == -1: # infinite
+            return                         # OK
+        if port >= signature.max_streams ():
+            raise ValueError, 'port number out of range.'
+
+    def _check_type_match (self, src_endpoint, dst_endpoint):
+        # for now, we just ensure that the stream item sizes match
+        src_sig = src_endpoint.block.output_signature ()
+        dst_sig = dst_endpoint.block.input_signature ()
+        src_size = src_sig.sizeof_stream_item (src_endpoint.port)
+        dst_size = dst_sig.sizeof_stream_item (dst_endpoint.port)
+        if src_size != dst_size:
+            raise ValueError, 'source and destination data sizes are different'
+
+    def _check_contiguity (self, m, sig, used_ports, dir):
+        used_ports.sort ()
+        used_ports = remove_duplicates (used_ports)
+        min_s = sig.min_streams ()
+
+        l = len (used_ports)
+        if l == 0:
+            if min_s == 0:
+                return l
+            raise ValueError, ("%s requires %d %s connections.  It has none." %
+                               (m, min_s, dir))
+        
+        if used_ports[-1] + 1 < min_s:
+            raise ValueError, ("%s requires %d %s connections.  It has %d." %
+                               (m, min_s, dir, used_ports[-1] + 1))
+            
+        if used_ports[-1] + 1 != l:
+            for i in range (l):
+                if used_ports[i] != i:
+                    raise ValueError, ("%s %s port %d is not connected" %
+                                       (m, dir, i))
+        
+        # print "%s ports: %s" % (dir, used_ports)
+        return l
diff --git a/gnuradio-core/src/python/gnuradio/gr/benchmark_filters.py b/gnuradio-core/src/python/gnuradio/gr/benchmark_filters.py
new file mode 100755 (executable)
index 0000000..7b2f44c
--- /dev/null
@@ -0,0 +1,55 @@
+#!/usr/bin/env python
+
+import time
+import random
+from optparse import OptionParser
+from gnuradio import gr
+from gnuradio.eng_option import eng_option
+
+def make_random_complex_tuple(L):
+    result = []
+    for x in range(L):
+        result.append(complex(random.uniform(-1000,1000),
+                              random.uniform(-1000,1000)))
+    return tuple(result)
+    
+def benchmark(name, creator, dec, ntaps, total_test_size, block_size):
+    block_size = 32768
+
+    fg = gr.flow_graph()
+    taps = make_random_complex_tuple(ntaps)
+    src = gr.vector_source_c(make_random_complex_tuple(block_size), True)
+    head = gr.head(gr.sizeof_gr_complex, int(total_test_size))
+    op = creator(dec, taps)
+    dst = gr.null_sink(gr.sizeof_gr_complex)
+    fg.connect(src, head, op, dst)
+    start = time.time()
+    fg.run()
+    stop = time.time()
+    delta = stop - start
+    print "%16s: taps: %4d  input: %4g, time: %6.3f  taps/sec: %10.4g" % (
+        name, ntaps, total_test_size, delta, ntaps*total_test_size/delta)
+
+def main():
+    parser = OptionParser(option_class=eng_option)
+    parser.add_option("-n", "--ntaps", type="int", default=256)
+    parser.add_option("-t", "--total-input-size", type="eng_float", default=40e6)
+    parser.add_option("-b", "--block-size", type="intx", default=50000)
+    parser.add_option("-d", "--decimation", type="int", default=1)
+    (options, args) = parser.parse_args()
+    if len(args) != 0:
+        parser.print_help()
+        sys.exit(1)
+
+    ntaps = options.ntaps
+    total_input_size = options.total_input_size
+    block_size = options.block_size
+    dec = options.decimation
+
+    benchmark("gr.fir_filter_ccc", gr.fir_filter_ccc,
+              dec, ntaps, total_input_size, block_size)
+    benchmark("gr.fft_filter_ccc", gr.fft_filter_ccc,
+              dec, ntaps, total_input_size, block_size)
+
+if __name__ == '__main__':
+    main()
diff --git a/gnuradio-core/src/python/gnuradio/gr/exceptions.py b/gnuradio-core/src/python/gnuradio/gr/exceptions.py
new file mode 100644 (file)
index 0000000..0cbeb14
--- /dev/null
@@ -0,0 +1,27 @@
+#
+# 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.
+
+class NotDAG (Exception):
+    """Not a directed acyclic graph"""
+    pass
+
+class CantHappen (Exception):
+    """Can't happen"""
+    pass
diff --git a/gnuradio-core/src/python/gnuradio/gr/flow_graph.py b/gnuradio-core/src/python/gnuradio/gr/flow_graph.py
new file mode 100644 (file)
index 0000000..db9c587
--- /dev/null
@@ -0,0 +1,234 @@
+#
+# 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 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.
+# 
+
+from gnuradio.gr.basic_flow_graph import remove_duplicates, endpoint, edge, \
+     basic_flow_graph
+
+from gnuradio.gr.exceptions import *
+from gnuradio_swig_python import buffer, buffer_add_reader, block_detail, \
+     single_threaded_scheduler
+
+from gnuradio.gr.scheduler import scheduler
+
+_WHITE = 0                          # graph coloring tags
+_GRAY  = 1
+_BLACK = 2
+
+_flow_graph_debug = False
+
+def set_flow_graph_debug(on):
+    global _flow_graph_debug
+    _flow_graph_debug = on
+    
+
+class buffer_sizes (object):
+    """compute buffer sizes to use"""
+    def __init__ (self, flow_graph):
+        # We could scan the graph here and determine individual sizes
+        # based on relative_rate, number of readers, etc.
+
+        # The simplest thing that could possibly work: all buffers same size
+        self.flow_graph = flow_graph
+        self.fixed_buffer_size = 32*1024
+
+    def allocate (self, m, index):
+        """allocate buffer for output index of block m"""
+        item_size = m.output_signature().sizeof_stream_item (index)
+        nitems = self.fixed_buffer_size / item_size
+        if nitems < 2 * m.output_multiple ():
+            nitems = 2 * m.output_multiple ()
+            
+        # if any downstream blocks is a decimator and/or has a large output_multiple, 
+        # ensure that we have a buffer at least 2 * their decimation_factor*output_multiple
+        for mdown in self.flow_graph.downstream_verticies_port(m, index):
+           decimation = int(1.0 / mdown.relative_rate())
+           nitems = max(nitems, 2 * (decimation * mdown.output_multiple() + mdown.history()))
+
+        return buffer (nitems, item_size)
+    
+
+class flow_graph (basic_flow_graph):
+    """add physical connection info to simple_flow_graph
+    """
+    # __slots__ is incompatible with weakrefs (for some reason!)
+    # __slots__ = ['blocks', 'scheduler']
+
+    def __init__ (self):
+        basic_flow_graph.__init__ (self);
+        self.blocks = None
+        self.scheduler = None
+
+    def __del__(self):
+        # print "\nflow_graph.__del__"
+        # this ensures that i/o devices such as the USRP get shutdown gracefully
+        self.stop()
+        
+    def start (self):
+        '''start graph, forking thread(s), return immediately'''
+        if self.scheduler:
+            raise RuntimeError, "Scheduler already running"
+        self._setup_connections ()
+
+        # cast down to gr_module_sptr
+        # t = [x.block () for x in self.topological_sort (self.blocks)]
+        self.scheduler = scheduler (self)
+        self.scheduler.start ()
+
+    def stop (self):
+        '''tells scheduler to stop and waits for it to happen'''
+        if self.scheduler:
+            self.scheduler.stop ()
+            self.scheduler = None
+        
+    def wait (self):
+        '''waits for scheduler to stop'''
+        if self.scheduler:
+            self.scheduler.wait ()
+            self.scheduler = None
+        
+    def is_running (self):
+        return not not self.scheduler
+    
+    def run (self):
+        '''start graph, wait for completion'''
+        self.start ()
+        self.wait ()
+        
+    def _setup_connections (self):
+        """given the basic flow graph, setup all the physical connections"""
+        self.validate ()
+        self.blocks = self.all_blocks ()
+        self._assign_details ()
+        self._assign_buffers ()
+        self._connect_inputs ()
+
+    def _assign_details (self):
+        for m in self.blocks:
+            edges = self.in_edges (m)
+            used_ports = remove_duplicates ([e.dst.port for e in edges])
+            ninputs = len (used_ports)
+
+            edges = self.out_edges (m)
+            used_ports = remove_duplicates ([e.src.port for e in edges])
+            noutputs = len (used_ports)
+
+            m.set_detail (block_detail (ninputs, noutputs))
+
+    def _assign_buffers (self):
+        """determine the buffer sizes to use, allocate them and attach to detail"""
+        sizes = buffer_sizes (self)
+        for m in self.blocks:
+            d = m.detail ()
+            for index in range (d.noutputs ()):
+                d.set_output (index, sizes.allocate (m, index))
+
+    def _connect_inputs (self):
+        """connect all block inputs to appropriate upstream buffers"""
+        for m in self.blocks:
+            d = m.detail ()
+            # print "%r history = %d" % (m, m.history())
+            for e in self.in_edges(m):
+                # FYI, sources don't have any in_edges
+                our_port = e.dst.port
+                upstream_block = e.src.block
+                upstream_port   = e.src.port
+                upstream_buffer = upstream_block.detail().output(upstream_port)
+                d.set_input(our_port, buffer_add_reader(upstream_buffer, m.history()))
+    
+
+    def topological_sort (self, all_v):
+        '''
+        Return a topologically sorted list of vertices.
+        This is basically a depth-first search with checks
+        for back edges (the non-DAG condition)
+
+        '''
+
+        # it's correct without this sort, but this
+        # should give better ordering for cache utilization
+        all_v = self._sort_sources_first (all_v)
+
+        output = []
+        for v in all_v:
+            v.ts_color = _WHITE
+        for v in all_v:
+            if v.ts_color == _WHITE:
+                self._dfs_visit (v, output)
+        output.reverse ()
+        return output
+
+    def _dfs_visit (self, u, output):
+        # print "dfs_visit (enter): ", u
+        u.ts_color = _GRAY
+        for v in self.downstream_verticies (u):
+            if v.ts_color == _WHITE:    # (u, v) is a tree edge
+                self._dfs_visit (v, output)
+            elif v.ts_color == _GRAY:   # (u, v) is a back edge
+                raise NotDAG, "The graph is not an acyclic graph (It's got a loop)"
+            elif v.ts_color == _BLACK:  # (u, v) is a cross or forward edge
+                pass
+            else:
+                raise CantHappen, "Invalid color on vertex"
+        u.ts_color = _BLACK
+        output.append (u)
+        # print "dfs_visit (exit):  ", u, output
+
+    def _sort_sources_first (self, all_v):
+        # the sort function is not guaranteed to be stable.
+        # We add the unique_id in to the key so we're guaranteed
+        # of reproducible results.  This is important for the test
+        # code.  There is often more than one valid topological sort.
+        # We want to force a reproducible choice.
+        x = [(not self.source_p(v), v.unique_id(), v) for v in all_v]
+        x.sort ()
+        x = [v[2] for v in x]
+        # print "sorted: ", x
+        return x
+        
+    def partition_graph (self, all_v):
+        '''Return a list of lists of nodes that are connected.
+        The result is a list of disjoint graphs.
+        The sublists are topologically sorted.
+        '''
+        result = []
+        working_v = all_v[:]    # make copy
+        while working_v:
+            rv = self._reachable_verticies (working_v[0], working_v)
+            result.append (self.topological_sort (rv))
+            for v in rv:
+                working_v.remove (v)
+        if _flow_graph_debug:
+            print "partition_graph:", result
+        return result
+        
+    def _reachable_verticies (self, start, all_v):
+        for v in all_v:
+            v.ts_color = _WHITE
+
+        self._reachable_dfs_visit (start)
+        return [v for v in all_v if v.ts_color == _BLACK]
+
+    def _reachable_dfs_visit (self, u):
+        u.ts_color = _BLACK
+        for v in self.adjacent_verticies (u):
+            if v.ts_color == _WHITE:
+                self._reachable_dfs_visit (v)
+        return None
diff --git a/gnuradio-core/src/python/gnuradio/gr/gr_threading.py b/gnuradio-core/src/python/gnuradio/gr/gr_threading.py
new file mode 100644 (file)
index 0000000..6a09a32
--- /dev/null
@@ -0,0 +1,35 @@
+#
+# 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 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.
+# 
+
+from sys import version_info as _version_info
+
+# import patched version of standard threading module
+
+if _version_info[0:2] == (2, 3):
+    #print "Importing gr_threading_23"
+    from gr_threading_23 import *
+elif _version_info[0:2] == (2, 4):
+    #print "Importing gr_threading_24"
+    from gr_threading_24 import *
+else:
+    # assume the patch was applied...
+    #print "Importing system provided threading"
+    from threading import *
diff --git a/gnuradio-core/src/python/gnuradio/gr/gr_threading_23.py b/gnuradio-core/src/python/gnuradio/gr/gr_threading_23.py
new file mode 100644 (file)
index 0000000..dee8034
--- /dev/null
@@ -0,0 +1,724 @@
+"""Thread module emulating a subset of Java's threading model."""
+
+# This started life as the threading.py module of Python 2.3
+# It's been patched to fix a problem with join, where a KeyboardInterrupt
+# caused a lock to be left in the acquired state.
+
+import sys as _sys
+
+try:
+    import thread
+except ImportError:
+    del _sys.modules[__name__]
+    raise
+
+from StringIO import StringIO as _StringIO
+from time import time as _time, sleep as _sleep
+from traceback import print_exc as _print_exc
+
+# Rename some stuff so "from threading import *" is safe
+__all__ = ['activeCount', 'Condition', 'currentThread', 'enumerate', 'Event',
+           'Lock', 'RLock', 'Semaphore', 'BoundedSemaphore', 'Thread',
+           'Timer', 'setprofile', 'settrace']
+
+_start_new_thread = thread.start_new_thread
+_allocate_lock = thread.allocate_lock
+_get_ident = thread.get_ident
+ThreadError = thread.error
+del thread
+
+
+# Debug support (adapted from ihooks.py).
+# All the major classes here derive from _Verbose.  We force that to
+# be a new-style class so that all the major classes here are new-style.
+# This helps debugging (type(instance) is more revealing for instances
+# of new-style classes).
+
+_VERBOSE = False
+
+if __debug__:
+
+    class _Verbose(object):
+
+        def __init__(self, verbose=None):
+            if verbose is None:
+                verbose = _VERBOSE
+            self.__verbose = verbose
+
+        def _note(self, format, *args):
+            if self.__verbose:
+                format = format % args
+                format = "%s: %s\n" % (
+                    currentThread().getName(), format)
+                _sys.stderr.write(format)
+
+else:
+    # Disable this when using "python -O"
+    class _Verbose(object):
+        def __init__(self, verbose=None):
+            pass
+        def _note(self, *args):
+            pass
+
+# Support for profile and trace hooks
+
+_profile_hook = None
+_trace_hook = None
+
+def setprofile(func):
+    global _profile_hook
+    _profile_hook = func
+
+def settrace(func):
+    global _trace_hook
+    _trace_hook = func
+
+# Synchronization classes
+
+Lock = _allocate_lock
+
+def RLock(*args, **kwargs):
+    return _RLock(*args, **kwargs)
+
+class _RLock(_Verbose):
+
+    def __init__(self, verbose=None):
+        _Verbose.__init__(self, verbose)
+        self.__block = _allocate_lock()
+        self.__owner = None
+        self.__count = 0
+
+    def __repr__(self):
+        return "<%s(%s, %d)>" % (
+                self.__class__.__name__,
+                self.__owner and self.__owner.getName(),
+                self.__count)
+
+    def acquire(self, blocking=1):
+        me = currentThread()
+        if self.__owner is me:
+            self.__count = self.__count + 1
+            if __debug__:
+                self._note("%s.acquire(%s): recursive success", self, blocking)
+            return 1
+        rc = self.__block.acquire(blocking)
+        if rc:
+            self.__owner = me
+            self.__count = 1
+            if __debug__:
+                self._note("%s.acquire(%s): initial succes", self, blocking)
+        else:
+            if __debug__:
+                self._note("%s.acquire(%s): failure", self, blocking)
+        return rc
+
+    def release(self):
+        me = currentThread()
+        assert self.__owner is me, "release() of un-acquire()d lock"
+        self.__count = count = self.__count - 1
+        if not count:
+            self.__owner = None
+            self.__block.release()
+            if __debug__:
+                self._note("%s.release(): final release", self)
+        else:
+            if __debug__:
+                self._note("%s.release(): non-final release", self)
+
+    # Internal methods used by condition variables
+
+    def _acquire_restore(self, (count, owner)):
+        self.__block.acquire()
+        self.__count = count
+        self.__owner = owner
+        if __debug__:
+            self._note("%s._acquire_restore()", self)
+
+    def _release_save(self):
+        if __debug__:
+            self._note("%s._release_save()", self)
+        count = self.__count
+        self.__count = 0
+        owner = self.__owner
+        self.__owner = None
+        self.__block.release()
+        return (count, owner)
+
+    def _is_owned(self):
+        return self.__owner is currentThread()
+
+
+def Condition(*args, **kwargs):
+    return _Condition(*args, **kwargs)
+
+class _Condition(_Verbose):
+
+    def __init__(self, lock=None, verbose=None):
+        _Verbose.__init__(self, verbose)
+        if lock is None:
+            lock = RLock()
+        self.__lock = lock
+        # Export the lock's acquire() and release() methods
+        self.acquire = lock.acquire
+        self.release = lock.release
+        # If the lock defines _release_save() and/or _acquire_restore(),
+        # these override the default implementations (which just call
+        # release() and acquire() on the lock).  Ditto for _is_owned().
+        try:
+            self._release_save = lock._release_save
+        except AttributeError:
+            pass
+        try:
+            self._acquire_restore = lock._acquire_restore
+        except AttributeError:
+            pass
+        try:
+            self._is_owned = lock._is_owned
+        except AttributeError:
+            pass
+        self.__waiters = []
+
+    def __repr__(self):
+        return "<Condition(%s, %d)>" % (self.__lock, len(self.__waiters))
+
+    def _release_save(self):
+        self.__lock.release()           # No state to save
+
+    def _acquire_restore(self, x):
+        self.__lock.acquire()           # Ignore saved state
+
+    def _is_owned(self):
+        # Return True if lock is owned by currentThread.
+        # This method is called only if __lock doesn't have _is_owned().
+        if self.__lock.acquire(0):
+            self.__lock.release()
+            return False
+        else:
+            return True
+
+    def wait(self, timeout=None):
+        currentThread() # for side-effect
+        assert self._is_owned(), "wait() of un-acquire()d lock"
+        waiter = _allocate_lock()
+        waiter.acquire()
+        self.__waiters.append(waiter)
+        saved_state = self._release_save()
+        try:    # restore state no matter what (e.g., KeyboardInterrupt)
+            if timeout is None:
+                waiter.acquire()
+                if __debug__:
+                    self._note("%s.wait(): got it", self)
+            else:
+                # Balancing act:  We can't afford a pure busy loop, so we
+                # have to sleep; but if we sleep the whole timeout time,
+                # we'll be unresponsive.  The scheme here sleeps very
+                # little at first, longer as time goes on, but never longer
+                # than 20 times per second (or the timeout time remaining).
+                endtime = _time() + timeout
+                delay = 0.0005 # 500 us -> initial delay of 1 ms
+                while True:
+                    gotit = waiter.acquire(0)
+                    if gotit:
+                        break
+                    remaining = endtime - _time()
+                    if remaining <= 0:
+                        break
+                    delay = min(delay * 2, remaining, .05)
+                    _sleep(delay)
+                if not gotit:
+                    if __debug__:
+                        self._note("%s.wait(%s): timed out", self, timeout)
+                    try:
+                        self.__waiters.remove(waiter)
+                    except ValueError:
+                        pass
+                else:
+                    if __debug__:
+                        self._note("%s.wait(%s): got it", self, timeout)
+        finally:
+            self._acquire_restore(saved_state)
+
+    def notify(self, n=1):
+        currentThread() # for side-effect
+        assert self._is_owned(), "notify() of un-acquire()d lock"
+        __waiters = self.__waiters
+        waiters = __waiters[:n]
+        if not waiters:
+            if __debug__:
+                self._note("%s.notify(): no waiters", self)
+            return
+        self._note("%s.notify(): notifying %d waiter%s", self, n,
+                   n!=1 and "s" or "")
+        for waiter in waiters:
+            waiter.release()
+            try:
+                __waiters.remove(waiter)
+            except ValueError:
+                pass
+
+    def notifyAll(self):
+        self.notify(len(self.__waiters))
+
+
+def Semaphore(*args, **kwargs):
+    return _Semaphore(*args, **kwargs)
+
+class _Semaphore(_Verbose):
+
+    # After Tim Peters' semaphore class, but not quite the same (no maximum)
+
+    def __init__(self, value=1, verbose=None):
+        assert value >= 0, "Semaphore initial value must be >= 0"
+        _Verbose.__init__(self, verbose)
+        self.__cond = Condition(Lock())
+        self.__value = value
+
+    def acquire(self, blocking=1):
+        rc = False
+        self.__cond.acquire()
+        while self.__value == 0:
+            if not blocking:
+                break
+            if __debug__:
+                self._note("%s.acquire(%s): blocked waiting, value=%s",
+                           self, blocking, self.__value)
+            self.__cond.wait()
+        else:
+            self.__value = self.__value - 1
+            if __debug__:
+                self._note("%s.acquire: success, value=%s",
+                           self, self.__value)
+            rc = True
+        self.__cond.release()
+        return rc
+
+    def release(self):
+        self.__cond.acquire()
+        self.__value = self.__value + 1
+        if __debug__:
+            self._note("%s.release: success, value=%s",
+                       self, self.__value)
+        self.__cond.notify()
+        self.__cond.release()
+
+
+def BoundedSemaphore(*args, **kwargs):
+    return _BoundedSemaphore(*args, **kwargs)
+
+class _BoundedSemaphore(_Semaphore):
+    """Semaphore that checks that # releases is <= # acquires"""
+    def __init__(self, value=1, verbose=None):
+        _Semaphore.__init__(self, value, verbose)
+        self._initial_value = value
+
+    def release(self):
+        if self._Semaphore__value >= self._initial_value:
+            raise ValueError, "Semaphore released too many times"
+        return _Semaphore.release(self)
+
+
+def Event(*args, **kwargs):
+    return _Event(*args, **kwargs)
+
+class _Event(_Verbose):
+
+    # After Tim Peters' event class (without is_posted())
+
+    def __init__(self, verbose=None):
+        _Verbose.__init__(self, verbose)
+        self.__cond = Condition(Lock())
+        self.__flag = False
+
+    def isSet(self):
+        return self.__flag
+
+    def set(self):
+        self.__cond.acquire()
+        try:
+            self.__flag = True
+            self.__cond.notifyAll()
+        finally:
+            self.__cond.release()
+
+    def clear(self):
+        self.__cond.acquire()
+        try:
+            self.__flag = False
+        finally:
+            self.__cond.release()
+
+    def wait(self, timeout=None):
+        self.__cond.acquire()
+        try:
+            if not self.__flag:
+                self.__cond.wait(timeout)
+        finally:
+            self.__cond.release()
+
+# Helper to generate new thread names
+_counter = 0
+def _newname(template="Thread-%d"):
+    global _counter
+    _counter = _counter + 1
+    return template % _counter
+
+# Active thread administration
+_active_limbo_lock = _allocate_lock()
+_active = {}
+_limbo = {}
+
+
+# Main class for threads
+
+class Thread(_Verbose):
+
+    __initialized = False
+
+    def __init__(self, group=None, target=None, name=None,
+                 args=(), kwargs={}, verbose=None):
+        assert group is None, "group argument must be None for now"
+        _Verbose.__init__(self, verbose)
+        self.__target = target
+        self.__name = str(name or _newname())
+        self.__args = args
+        self.__kwargs = kwargs
+        self.__daemonic = self._set_daemon()
+        self.__started = False
+        self.__stopped = False
+        self.__block = Condition(Lock())
+        self.__initialized = True
+
+    def _set_daemon(self):
+        # Overridden in _MainThread and _DummyThread
+        return currentThread().isDaemon()
+
+    def __repr__(self):
+        assert self.__initialized, "Thread.__init__() was not called"
+        status = "initial"
+        if self.__started:
+            status = "started"
+        if self.__stopped:
+            status = "stopped"
+        if self.__daemonic:
+            status = status + " daemon"
+        return "<%s(%s, %s)>" % (self.__class__.__name__, self.__name, status)
+
+    def start(self):
+        assert self.__initialized, "Thread.__init__() not called"
+        assert not self.__started, "thread already started"
+        if __debug__:
+            self._note("%s.start(): starting thread", self)
+        _active_limbo_lock.acquire()
+        _limbo[self] = self
+        _active_limbo_lock.release()
+        _start_new_thread(self.__bootstrap, ())
+        self.__started = True
+        _sleep(0.000001)    # 1 usec, to let the thread run (Solaris hack)
+
+    def run(self):
+        if self.__target:
+            self.__target(*self.__args, **self.__kwargs)
+
+    def __bootstrap(self):
+        try:
+            self.__started = True
+            _active_limbo_lock.acquire()
+            _active[_get_ident()] = self
+            del _limbo[self]
+            _active_limbo_lock.release()
+            if __debug__:
+                self._note("%s.__bootstrap(): thread started", self)
+
+            if _trace_hook:
+                self._note("%s.__bootstrap(): registering trace hook", self)
+                _sys.settrace(_trace_hook)
+            if _profile_hook:
+                self._note("%s.__bootstrap(): registering profile hook", self)
+                _sys.setprofile(_profile_hook)
+
+            try:
+                self.run()
+            except SystemExit:
+                if __debug__:
+                    self._note("%s.__bootstrap(): raised SystemExit", self)
+            except:
+                if __debug__:
+                    self._note("%s.__bootstrap(): unhandled exception", self)
+                s = _StringIO()
+                _print_exc(file=s)
+                _sys.stderr.write("Exception in thread %s:\n%s\n" %
+                                 (self.getName(), s.getvalue()))
+            else:
+                if __debug__:
+                    self._note("%s.__bootstrap(): normal return", self)
+        finally:
+            self.__stop()
+            try:
+                self.__delete()
+            except:
+                pass
+
+    def __stop(self):
+        self.__block.acquire()
+        self.__stopped = True
+        self.__block.notifyAll()
+        self.__block.release()
+
+    def __delete(self):
+        _active_limbo_lock.acquire()
+        del _active[_get_ident()]
+        _active_limbo_lock.release()
+
+    def join(self, timeout=None):
+        assert self.__initialized, "Thread.__init__() not called"
+        assert self.__started, "cannot join thread before it is started"
+        assert self is not currentThread(), "cannot join current thread"
+        if __debug__:
+            if not self.__stopped:
+                self._note("%s.join(): waiting until thread stops", self)
+        self.__block.acquire()
+        try:
+            if timeout is None:
+                while not self.__stopped:
+                    self.__block.wait()
+                if __debug__:
+                    self._note("%s.join(): thread stopped", self)
+            else:
+                deadline = _time() + timeout
+                while not self.__stopped:
+                    delay = deadline - _time()
+                    if delay <= 0:
+                        if __debug__:
+                            self._note("%s.join(): timed out", self)
+                        break
+                    self.__block.wait(delay)
+                else:
+                    if __debug__:
+                        self._note("%s.join(): thread stopped", self)
+        finally:
+            self.__block.release()
+
+    def getName(self):
+        assert self.__initialized, "Thread.__init__() not called"
+        return self.__name
+
+    def setName(self, name):
+        assert self.__initialized, "Thread.__init__() not called"
+        self.__name = str(name)
+
+    def isAlive(self):
+        assert self.__initialized, "Thread.__init__() not called"
+        return self.__started and not self.__stopped
+
+    def isDaemon(self):
+        assert self.__initialized, "Thread.__init__() not called"
+        return self.__daemonic
+
+    def setDaemon(self, daemonic):
+        assert self.__initialized, "Thread.__init__() not called"
+        assert not self.__started, "cannot set daemon status of active thread"
+        self.__daemonic = daemonic
+
+# The timer class was contributed by Itamar Shtull-Trauring
+
+def Timer(*args, **kwargs):
+    return _Timer(*args, **kwargs)
+
+class _Timer(Thread):
+    """Call a function after a specified number of seconds:
+
+    t = Timer(30.0, f, args=[], kwargs={})
+    t.start()
+    t.cancel() # stop the timer's action if it's still waiting
+    """
+
+    def __init__(self, interval, function, args=[], kwargs={}):
+        Thread.__init__(self)
+        self.interval = interval
+        self.function = function
+        self.args = args
+        self.kwargs = kwargs
+        self.finished = Event()
+
+    def cancel(self):
+        """Stop the timer if it hasn't finished yet"""
+        self.finished.set()
+
+    def run(self):
+        self.finished.wait(self.interval)
+        if not self.finished.isSet():
+            self.function(*self.args, **self.kwargs)
+        self.finished.set()
+
+# Special thread class to represent the main thread
+# This is garbage collected through an exit handler
+
+class _MainThread(Thread):
+
+    def __init__(self):
+        Thread.__init__(self, name="MainThread")
+        self._Thread__started = True
+        _active_limbo_lock.acquire()
+        _active[_get_ident()] = self
+        _active_limbo_lock.release()
+        import atexit
+        atexit.register(self.__exitfunc)
+
+    def _set_daemon(self):
+        return False
+
+    def __exitfunc(self):
+        self._Thread__stop()
+        t = _pickSomeNonDaemonThread()
+        if t:
+            if __debug__:
+                self._note("%s: waiting for other threads", self)
+        while t:
+            t.join()
+            t = _pickSomeNonDaemonThread()
+        if __debug__:
+            self._note("%s: exiting", self)
+        self._Thread__delete()
+
+def _pickSomeNonDaemonThread():
+    for t in enumerate():
+        if not t.isDaemon() and t.isAlive():
+            return t
+    return None
+
+
+# Dummy thread class to represent threads not started here.
+# These aren't garbage collected when they die,
+# nor can they be waited for.
+# Their purpose is to return *something* from currentThread().
+# They are marked as daemon threads so we won't wait for them
+# when we exit (conform previous semantics).
+
+class _DummyThread(Thread):
+
+    def __init__(self):
+        Thread.__init__(self, name=_newname("Dummy-%d"))
+        self._Thread__started = True
+        _active_limbo_lock.acquire()
+        _active[_get_ident()] = self
+        _active_limbo_lock.release()
+
+    def _set_daemon(self):
+        return True
+
+    def join(self, timeout=None):
+        assert False, "cannot join a dummy thread"
+
+
+# Global API functions
+
+def currentThread():
+    try:
+        return _active[_get_ident()]
+    except KeyError:
+        ##print "currentThread(): no current thread for", _get_ident()
+        return _DummyThread()
+
+def activeCount():
+    _active_limbo_lock.acquire()
+    count = len(_active) + len(_limbo)
+    _active_limbo_lock.release()
+    return count
+
+def enumerate():
+    _active_limbo_lock.acquire()
+    active = _active.values() + _limbo.values()
+    _active_limbo_lock.release()
+    return active
+
+# Create the main thread object
+
+_MainThread()
+
+
+# Self-test code
+
+def _test():
+
+    class BoundedQueue(_Verbose):
+
+        def __init__(self, limit):
+            _Verbose.__init__(self)
+            self.mon = RLock()
+            self.rc = Condition(self.mon)
+            self.wc = Condition(self.mon)
+            self.limit = limit
+            self.queue = []
+
+        def put(self, item):
+            self.mon.acquire()
+            while len(self.queue) >= self.limit:
+                self._note("put(%s): queue full", item)
+                self.wc.wait()
+            self.queue.append(item)
+            self._note("put(%s): appended, length now %d",
+                       item, len(self.queue))
+            self.rc.notify()
+            self.mon.release()
+
+        def get(self):
+            self.mon.acquire()
+            while not self.queue:
+                self._note("get(): queue empty")
+                self.rc.wait()
+            item = self.queue.pop(0)
+            self._note("get(): got %s, %d left", item, len(self.queue))
+            self.wc.notify()
+            self.mon.release()
+            return item
+
+    class ProducerThread(Thread):
+
+        def __init__(self, queue, quota):
+            Thread.__init__(self, name="Producer")
+            self.queue = queue
+            self.quota = quota
+
+        def run(self):
+            from random import random
+            counter = 0
+            while counter < self.quota:
+                counter = counter + 1
+                self.queue.put("%s.%d" % (self.getName(), counter))
+                _sleep(random() * 0.00001)
+
+
+    class ConsumerThread(Thread):
+
+        def __init__(self, queue, count):
+            Thread.__init__(self, name="Consumer")
+            self.queue = queue
+            self.count = count
+
+        def run(self):
+            while self.count > 0:
+                item = self.queue.get()
+                print item
+                self.count = self.count - 1
+
+    NP = 3
+    QL = 4
+    NI = 5
+
+    Q = BoundedQueue(QL)
+    P = []
+    for i in range(NP):
+        t = ProducerThread(Q, NI)
+        t.setName("Producer-%d" % (i+1))
+        P.append(t)
+    C = ConsumerThread(Q, NI*NP)
+    for t in P:
+        t.start()
+        _sleep(0.000001)
+    C.start()
+    for t in P:
+        t.join()
+    C.join()
+
+if __name__ == '__main__':
+    _test()
diff --git a/gnuradio-core/src/python/gnuradio/gr/gr_threading_24.py b/gnuradio-core/src/python/gnuradio/gr/gr_threading_24.py
new file mode 100644 (file)
index 0000000..8539bfc
--- /dev/null
@@ -0,0 +1,793 @@
+"""Thread module emulating a subset of Java's threading model."""
+
+# This started life as the threading.py module of Python 2.4
+# It's been patched to fix a problem with join, where a KeyboardInterrupt
+# caused a lock to be left in the acquired state.
+
+import sys as _sys
+
+try:
+    import thread
+except ImportError:
+    del _sys.modules[__name__]
+    raise
+
+from time import time as _time, sleep as _sleep
+from traceback import format_exc as _format_exc
+from collections import deque
+
+# Rename some stuff so "from threading import *" is safe
+__all__ = ['activeCount', 'Condition', 'currentThread', 'enumerate', 'Event',
+           'Lock', 'RLock', 'Semaphore', 'BoundedSemaphore', 'Thread',
+           'Timer', 'setprofile', 'settrace', 'local']
+
+_start_new_thread = thread.start_new_thread
+_allocate_lock = thread.allocate_lock
+_get_ident = thread.get_ident
+ThreadError = thread.error
+del thread
+
+
+# Debug support (adapted from ihooks.py).
+# All the major classes here derive from _Verbose.  We force that to
+# be a new-style class so that all the major classes here are new-style.
+# This helps debugging (type(instance) is more revealing for instances
+# of new-style classes).
+
+_VERBOSE = False
+
+if __debug__:
+
+    class _Verbose(object):
+
+        def __init__(self, verbose=None):
+            if verbose is None:
+                verbose = _VERBOSE
+            self.__verbose = verbose
+
+        def _note(self, format, *args):
+            if self.__verbose:
+                format = format % args
+                format = "%s: %s\n" % (
+                    currentThread().getName(), format)
+                _sys.stderr.write(format)
+
+else:
+    # Disable this when using "python -O"
+    class _Verbose(object):
+        def __init__(self, verbose=None):
+            pass
+        def _note(self, *args):
+            pass
+
+# Support for profile and trace hooks
+
+_profile_hook = None
+_trace_hook = None
+
+def setprofile(func):
+    global _profile_hook
+    _profile_hook = func
+
+def settrace(func):
+    global _trace_hook
+    _trace_hook = func
+
+# Synchronization classes
+
+Lock = _allocate_lock
+
+def RLock(*args, **kwargs):
+    return _RLock(*args, **kwargs)
+
+class _RLock(_Verbose):
+
+    def __init__(self, verbose=None):
+        _Verbose.__init__(self, verbose)
+        self.__block = _allocate_lock()
+        self.__owner = None
+        self.__count = 0
+
+    def __repr__(self):
+        return "<%s(%s, %d)>" % (
+                self.__class__.__name__,
+                self.__owner and self.__owner.getName(),
+                self.__count)
+
+    def acquire(self, blocking=1):
+        me = currentThread()
+        if self.__owner is me:
+            self.__count = self.__count + 1
+            if __debug__:
+                self._note("%s.acquire(%s): recursive success", self, blocking)
+            return 1
+        rc = self.__block.acquire(blocking)
+        if rc:
+            self.__owner = me
+            self.__count = 1
+            if __debug__:
+                self._note("%s.acquire(%s): initial succes", self, blocking)
+        else:
+            if __debug__:
+                self._note("%s.acquire(%s): failure", self, blocking)
+        return rc
+
+    def release(self):
+        me = currentThread()
+        assert self.__owner is me, "release() of un-acquire()d lock"
+        self.__count = count = self.__count - 1
+        if not count:
+            self.__owner = None
+            self.__block.release()
+            if __debug__:
+                self._note("%s.release(): final release", self)
+        else:
+            if __debug__:
+                self._note("%s.release(): non-final release", self)
+
+    # Internal methods used by condition variables
+
+    def _acquire_restore(self, (count, owner)):
+        self.__block.acquire()
+        self.__count = count
+        self.__owner = owner
+        if __debug__:
+            self._note("%s._acquire_restore()", self)
+
+    def _release_save(self):
+        if __debug__:
+            self._note("%s._release_save()", self)
+        count = self.__count
+        self.__count = 0
+        owner = self.__owner
+        self.__owner = None
+        self.__block.release()
+        return (count, owner)
+
+    def _is_owned(self):
+        return self.__owner is currentThread()
+
+
+def Condition(*args, **kwargs):
+    return _Condition(*args, **kwargs)
+
+class _Condition(_Verbose):
+
+    def __init__(self, lock=None, verbose=None):
+        _Verbose.__init__(self, verbose)
+        if lock is None:
+            lock = RLock()
+        self.__lock = lock
+        # Export the lock's acquire() and release() methods
+        self.acquire = lock.acquire
+        self.release = lock.release
+        # If the lock defines _release_save() and/or _acquire_restore(),
+        # these override the default implementations (which just call
+        # release() and acquire() on the lock).  Ditto for _is_owned().
+        try:
+            self._release_save = lock._release_save
+        except AttributeError:
+            pass
+        try:
+            self._acquire_restore = lock._acquire_restore
+        except AttributeError:
+            pass
+        try:
+            self._is_owned = lock._is_owned
+        except AttributeError:
+            pass
+        self.__waiters = []
+
+    def __repr__(self):
+        return "<Condition(%s, %d)>" % (self.__lock, len(self.__waiters))
+
+    def _release_save(self):
+        self.__lock.release()           # No state to save
+
+    def _acquire_restore(self, x):
+        self.__lock.acquire()           # Ignore saved state
+
+    def _is_owned(self):
+        # Return True if lock is owned by currentThread.
+        # This method is called only if __lock doesn't have _is_owned().
+        if self.__lock.acquire(0):
+            self.__lock.release()
+            return False
+        else:
+            return True
+
+    def wait(self, timeout=None):
+        assert self._is_owned(), "wait() of un-acquire()d lock"
+        waiter = _allocate_lock()
+        waiter.acquire()
+        self.__waiters.append(waiter)
+        saved_state = self._release_save()
+        try:    # restore state no matter what (e.g., KeyboardInterrupt)
+            if timeout is None:
+                waiter.acquire()
+                if __debug__:
+                    self._note("%s.wait(): got it", self)
+            else:
+                # Balancing act:  We can't afford a pure busy loop, so we
+                # have to sleep; but if we sleep the whole timeout time,
+                # we'll be unresponsive.  The scheme here sleeps very
+                # little at first, longer as time goes on, but never longer
+                # than 20 times per second (or the timeout time remaining).
+                endtime = _time() + timeout
+                delay = 0.0005 # 500 us -> initial delay of 1 ms
+                while True:
+                    gotit = waiter.acquire(0)
+                    if gotit:
+                        break
+                    remaining = endtime - _time()
+                    if remaining <= 0:
+                        break
+                    delay = min(delay * 2, remaining, .05)
+                    _sleep(delay)
+                if not gotit:
+                    if __debug__:
+                        self._note("%s.wait(%s): timed out", self, timeout)
+                    try:
+                        self.__waiters.remove(waiter)
+                    except ValueError:
+                        pass
+                else:
+                    if __debug__:
+                        self._note("%s.wait(%s): got it", self, timeout)
+        finally:
+            self._acquire_restore(saved_state)
+
+    def notify(self, n=1):
+        assert self._is_owned(), "notify() of un-acquire()d lock"
+        __waiters = self.__waiters
+        waiters = __waiters[:n]
+        if not waiters:
+            if __debug__:
+                self._note("%s.notify(): no waiters", self)
+            return
+        self._note("%s.notify(): notifying %d waiter%s", self, n,
+                   n!=1 and "s" or "")
+        for waiter in waiters:
+            waiter.release()
+            try:
+                __waiters.remove(waiter)
+            except ValueError:
+                pass
+
+    def notifyAll(self):
+        self.notify(len(self.__waiters))
+
+
+def Semaphore(*args, **kwargs):
+    return _Semaphore(*args, **kwargs)
+
+class _Semaphore(_Verbose):
+
+    # After Tim Peters' semaphore class, but not quite the same (no maximum)
+
+    def __init__(self, value=1, verbose=None):
+        assert value >= 0, "Semaphore initial value must be >= 0"
+        _Verbose.__init__(self, verbose)
+        self.__cond = Condition(Lock())
+        self.__value = value
+
+    def acquire(self, blocking=1):
+        rc = False
+        self.__cond.acquire()
+        while self.__value == 0:
+            if not blocking:
+                break
+            if __debug__:
+                self._note("%s.acquire(%s): blocked waiting, value=%s",
+                           self, blocking, self.__value)
+            self.__cond.wait()
+        else:
+            self.__value = self.__value - 1
+            if __debug__:
+                self._note("%s.acquire: success, value=%s",
+                           self, self.__value)
+            rc = True
+        self.__cond.release()
+        return rc
+
+    def release(self):
+        self.__cond.acquire()
+        self.__value = self.__value + 1
+        if __debug__:
+            self._note("%s.release: success, value=%s",
+                       self, self.__value)
+        self.__cond.notify()
+        self.__cond.release()
+
+
+def BoundedSemaphore(*args, **kwargs):
+    return _BoundedSemaphore(*args, **kwargs)
+
+class _BoundedSemaphore(_Semaphore):
+    """Semaphore that checks that # releases is <= # acquires"""
+    def __init__(self, value=1, verbose=None):
+        _Semaphore.__init__(self, value, verbose)
+        self._initial_value = value
+
+    def release(self):
+        if self._Semaphore__value >= self._initial_value:
+            raise ValueError, "Semaphore released too many times"
+        return _Semaphore.release(self)
+
+
+def Event(*args, **kwargs):
+    return _Event(*args, **kwargs)
+
+class _Event(_Verbose):
+
+    # After Tim Peters' event class (without is_posted())
+
+    def __init__(self, verbose=None):
+        _Verbose.__init__(self, verbose)
+        self.__cond = Condition(Lock())
+        self.__flag = False
+
+    def isSet(self):
+        return self.__flag
+
+    def set(self):
+        self.__cond.acquire()
+        try:
+            self.__flag = True
+            self.__cond.notifyAll()
+        finally:
+            self.__cond.release()
+
+    def clear(self):
+        self.__cond.acquire()
+        try:
+            self.__flag = False
+        finally:
+            self.__cond.release()
+
+    def wait(self, timeout=None):
+        self.__cond.acquire()
+        try:
+            if not self.__flag:
+                self.__cond.wait(timeout)
+        finally:
+            self.__cond.release()
+
+# Helper to generate new thread names
+_counter = 0
+def _newname(template="Thread-%d"):
+    global _counter
+    _counter = _counter + 1
+    return template % _counter
+
+# Active thread administration
+_active_limbo_lock = _allocate_lock()
+_active = {}
+_limbo = {}
+
+
+# Main class for threads
+
+class Thread(_Verbose):
+
+    __initialized = False
+    # Need to store a reference to sys.exc_info for printing
+    # out exceptions when a thread tries to use a global var. during interp.
+    # shutdown and thus raises an exception about trying to perform some
+    # operation on/with a NoneType
+    __exc_info = _sys.exc_info
+
+    def __init__(self, group=None, target=None, name=None,
+                 args=(), kwargs={}, verbose=None):
+        assert group is None, "group argument must be None for now"
+        _Verbose.__init__(self, verbose)
+        self.__target = target
+        self.__name = str(name or _newname())
+        self.__args = args
+        self.__kwargs = kwargs
+        self.__daemonic = self._set_daemon()
+        self.__started = False
+        self.__stopped = False
+        self.__block = Condition(Lock())
+        self.__initialized = True
+        # sys.stderr is not stored in the class like
+        # sys.exc_info since it can be changed between instances
+        self.__stderr = _sys.stderr
+
+    def _set_daemon(self):
+        # Overridden in _MainThread and _DummyThread
+        return currentThread().isDaemon()
+
+    def __repr__(self):
+        assert self.__initialized, "Thread.__init__() was not called"
+        status = "initial"
+        if self.__started:
+            status = "started"
+        if self.__stopped:
+            status = "stopped"
+        if self.__daemonic:
+            status = status + " daemon"
+        return "<%s(%s, %s)>" % (self.__class__.__name__, self.__name, status)
+
+    def start(self):
+        assert self.__initialized, "Thread.__init__() not called"
+        assert not self.__started, "thread already started"
+        if __debug__:
+            self._note("%s.start(): starting thread", self)
+        _active_limbo_lock.acquire()
+        _limbo[self] = self
+        _active_limbo_lock.release()
+        _start_new_thread(self.__bootstrap, ())
+        self.__started = True
+        _sleep(0.000001)    # 1 usec, to let the thread run (Solaris hack)
+
+    def run(self):
+        if self.__target:
+            self.__target(*self.__args, **self.__kwargs)
+
+    def __bootstrap(self):
+        try:
+            self.__started = True
+            _active_limbo_lock.acquire()
+            _active[_get_ident()] = self
+            del _limbo[self]
+            _active_limbo_lock.release()
+            if __debug__:
+                self._note("%s.__bootstrap(): thread started", self)
+
+            if _trace_hook:
+                self._note("%s.__bootstrap(): registering trace hook", self)
+                _sys.settrace(_trace_hook)
+            if _profile_hook:
+                self._note("%s.__bootstrap(): registering profile hook", self)
+                _sys.setprofile(_profile_hook)
+
+            try:
+                self.run()
+            except SystemExit:
+                if __debug__:
+                    self._note("%s.__bootstrap(): raised SystemExit", self)
+            except:
+                if __debug__:
+                    self._note("%s.__bootstrap(): unhandled exception", self)
+                # If sys.stderr is no more (most likely from interpreter
+                # shutdown) use self.__stderr.  Otherwise still use sys (as in
+                # _sys) in case sys.stderr was redefined since the creation of
+                # self.
+                if _sys:
+                    _sys.stderr.write("Exception in thread %s:\n%s\n" %
+                                      (self.getName(), _format_exc()))
+                else:
+                    # Do the best job possible w/o a huge amt. of code to
+                    # approximate a traceback (code ideas from
+                    # Lib/traceback.py)
+                    exc_type, exc_value, exc_tb = self.__exc_info()
+                    try:
+                        print>>self.__stderr, (
+                            "Exception in thread " + self.getName() +
+                            " (most likely raised during interpreter shutdown):")
+                        print>>self.__stderr, (
+                            "Traceback (most recent call last):")
+                        while exc_tb:
+                            print>>self.__stderr, (
+                                '  File "%s", line %s, in %s' %
+                                (exc_tb.tb_frame.f_code.co_filename,
+                                    exc_tb.tb_lineno,
+                                    exc_tb.tb_frame.f_code.co_name))
+                            exc_tb = exc_tb.tb_next
+                        print>>self.__stderr, ("%s: %s" % (exc_type, exc_value))
+                    # Make sure that exc_tb gets deleted since it is a memory
+                    # hog; deleting everything else is just for thoroughness
+                    finally:
+                        del exc_type, exc_value, exc_tb
+            else:
+                if __debug__:
+                    self._note("%s.__bootstrap(): normal return", self)
+        finally:
+            self.__stop()
+            try:
+                self.__delete()
+            except:
+                pass
+
+    def __stop(self):
+        self.__block.acquire()
+        self.__stopped = True
+        self.__block.notifyAll()
+        self.__block.release()
+
+    def __delete(self):
+        "Remove current thread from the dict of currently running threads."
+
+        # Notes about running with dummy_thread:
+        #
+        # Must take care to not raise an exception if dummy_thread is being
+        # used (and thus this module is being used as an instance of
+        # dummy_threading).  dummy_thread.get_ident() always returns -1 since
+        # there is only one thread if dummy_thread is being used.  Thus
+        # len(_active) is always <= 1 here, and any Thread instance created
+        # overwrites the (if any) thread currently registered in _active.
+        #
+        # An instance of _MainThread is always created by 'threading'.  This
+        # gets overwritten the instant an instance of Thread is created; both
+        # threads return -1 from dummy_thread.get_ident() and thus have the
+        # same key in the dict.  So when the _MainThread instance created by
+        # 'threading' tries to clean itself up when atexit calls this method
+        # it gets a KeyError if another Thread instance was created.
+        #
+        # This all means that KeyError from trying to delete something from
+        # _active if dummy_threading is being used is a red herring.  But
+        # since it isn't if dummy_threading is *not* being used then don't
+        # hide the exception.
+
+        _active_limbo_lock.acquire()
+        try:
+            try:
+                del _active[_get_ident()]
+            except KeyError:
+                if 'dummy_threading' not in _sys.modules:
+                    raise
+        finally:
+            _active_limbo_lock.release()
+
+    def join(self, timeout=None):
+        assert self.__initialized, "Thread.__init__() not called"
+        assert self.__started, "cannot join thread before it is started"
+        assert self is not currentThread(), "cannot join current thread"
+        if __debug__:
+            if not self.__stopped:
+                self._note("%s.join(): waiting until thread stops", self)
+        self.__block.acquire()
+        try:
+            if timeout is None:
+                while not self.__stopped:
+                    self.__block.wait()
+                if __debug__:
+                    self._note("%s.join(): thread stopped", self)
+            else:
+                deadline = _time() + timeout
+                while not self.__stopped:
+                    delay = deadline - _time()
+                    if delay <= 0:
+                        if __debug__:
+                            self._note("%s.join(): timed out", self)
+                        break
+                    self.__block.wait(delay)
+                else:
+                    if __debug__:
+                        self._note("%s.join(): thread stopped", self)
+        finally:
+            self.__block.release()
+
+    def getName(self):
+        assert self.__initialized, "Thread.__init__() not called"
+        return self.__name
+
+    def setName(self, name):
+        assert self.__initialized, "Thread.__init__() not called"
+        self.__name = str(name)
+
+    def isAlive(self):
+        assert self.__initialized, "Thread.__init__() not called"
+        return self.__started and not self.__stopped
+
+    def isDaemon(self):
+        assert self.__initialized, "Thread.__init__() not called"
+        return self.__daemonic
+
+    def setDaemon(self, daemonic):
+        assert self.__initialized, "Thread.__init__() not called"
+        assert not self.__started, "cannot set daemon status of active thread"
+        self.__daemonic = daemonic
+
+# The timer class was contributed by Itamar Shtull-Trauring
+
+def Timer(*args, **kwargs):
+    return _Timer(*args, **kwargs)
+
+class _Timer(Thread):
+    """Call a function after a specified number of seconds:
+
+    t = Timer(30.0, f, args=[], kwargs={})
+    t.start()
+    t.cancel() # stop the timer's action if it's still waiting
+    """
+
+    def __init__(self, interval, function, args=[], kwargs={}):
+        Thread.__init__(self)
+        self.interval = interval
+        self.function = function
+        self.args = args
+        self.kwargs = kwargs
+        self.finished = Event()
+
+    def cancel(self):
+        """Stop the timer if it hasn't finished yet"""
+        self.finished.set()
+
+    def run(self):
+        self.finished.wait(self.interval)
+        if not self.finished.isSet():
+            self.function(*self.args, **self.kwargs)
+        self.finished.set()
+
+# Special thread class to represent the main thread
+# This is garbage collected through an exit handler
+
+class _MainThread(Thread):
+
+    def __init__(self):
+        Thread.__init__(self, name="MainThread")
+        self._Thread__started = True
+        _active_limbo_lock.acquire()
+        _active[_get_ident()] = self
+        _active_limbo_lock.release()
+        import atexit
+        atexit.register(self.__exitfunc)
+
+    def _set_daemon(self):
+        return False
+
+    def __exitfunc(self):
+        self._Thread__stop()
+        t = _pickSomeNonDaemonThread()
+        if t:
+            if __debug__:
+                self._note("%s: waiting for other threads", self)
+        while t:
+            t.join()
+            t = _pickSomeNonDaemonThread()
+        if __debug__:
+            self._note("%s: exiting", self)
+        self._Thread__delete()
+
+def _pickSomeNonDaemonThread():
+    for t in enumerate():
+        if not t.isDaemon() and t.isAlive():
+            return t
+    return None
+
+
+# Dummy thread class to represent threads not started here.
+# These aren't garbage collected when they die,
+# nor can they be waited for.
+# Their purpose is to return *something* from currentThread().
+# They are marked as daemon threads so we won't wait for them
+# when we exit (conform previous semantics).
+
+class _DummyThread(Thread):
+
+    def __init__(self):
+        Thread.__init__(self, name=_newname("Dummy-%d"))
+        self._Thread__started = True
+        _active_limbo_lock.acquire()
+        _active[_get_ident()] = self
+        _active_limbo_lock.release()
+
+    def _set_daemon(self):
+        return True
+
+    def join(self, timeout=None):
+        assert False, "cannot join a dummy thread"
+
+
+# Global API functions
+
+def currentThread():
+    try:
+        return _active[_get_ident()]
+    except KeyError:
+        ##print "currentThread(): no current thread for", _get_ident()
+        return _DummyThread()
+
+def activeCount():
+    _active_limbo_lock.acquire()
+    count = len(_active) + len(_limbo)
+    _active_limbo_lock.release()
+    return count
+
+def enumerate():
+    _active_limbo_lock.acquire()
+    active = _active.values() + _limbo.values()
+    _active_limbo_lock.release()
+    return active
+
+# Create the main thread object
+
+_MainThread()
+
+# get thread-local implementation, either from the thread
+# module, or from the python fallback
+
+try:
+    from thread import _local as local
+except ImportError:
+    from _threading_local import local
+
+
+# Self-test code
+
+def _test():
+
+    class BoundedQueue(_Verbose):
+
+        def __init__(self, limit):
+            _Verbose.__init__(self)
+            self.mon = RLock()
+            self.rc = Condition(self.mon)
+            self.wc = Condition(self.mon)
+            self.limit = limit
+            self.queue = deque()
+
+        def put(self, item):
+            self.mon.acquire()
+            while len(self.queue) >= self.limit:
+                self._note("put(%s): queue full", item)
+                self.wc.wait()
+            self.queue.append(item)
+            self._note("put(%s): appended, length now %d",
+                       item, len(self.queue))
+            self.rc.notify()
+            self.mon.release()
+
+        def get(self):
+            self.mon.acquire()
+            while not self.queue:
+                self._note("get(): queue empty")
+                self.rc.wait()
+            item = self.queue.popleft()
+            self._note("get(): got %s, %d left", item, len(self.queue))
+            self.wc.notify()
+            self.mon.release()
+            return item
+
+    class ProducerThread(Thread):
+
+        def __init__(self, queue, quota):
+            Thread.__init__(self, name="Producer")
+            self.queue = queue
+            self.quota = quota
+
+        def run(self):
+            from random import random
+            counter = 0
+            while counter < self.quota:
+                counter = counter + 1
+                self.queue.put("%s.%d" % (self.getName(), counter))
+                _sleep(random() * 0.00001)
+
+
+    class ConsumerThread(Thread):
+
+        def __init__(self, queue, count):
+            Thread.__init__(self, name="Consumer")
+            self.queue = queue
+            self.count = count
+
+        def run(self):
+            while self.count > 0:
+                item = self.queue.get()
+                print item
+                self.count = self.count - 1
+
+    NP = 3
+    QL = 4
+    NI = 5
+
+    Q = BoundedQueue(QL)
+    P = []
+    for i in range(NP):
+        t = ProducerThread(Q, NI)
+        t.setName("Producer-%d" % (i+1))
+        P.append(t)
+    C = ConsumerThread(Q, NI*NP)
+    for t in P:
+        t.start()
+        _sleep(0.000001)
+    C.start()
+    for t in P:
+        t.join()
+    C.join()
+
+if __name__ == '__main__':
+    _test()
diff --git a/gnuradio-core/src/python/gnuradio/gr/hier_block.py b/gnuradio-core/src/python/gnuradio/gr/hier_block.py
new file mode 100644 (file)
index 0000000..d669d71
--- /dev/null
@@ -0,0 +1,132 @@
+#
+# 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 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.
+# 
+
+from gnuradio_swig_python import io_signature
+import weakref
+
+class hier_block_base(object):
+    """
+    Abstract base class for hierarchical signal processing blocks.
+    """
+    def __init__(self, fg):
+        """
+        @param fg: The flow graph that contains this hierarchical block.
+        @type fg: gr.flow_graph
+        """
+        self.fg = weakref.proxy(fg)
+
+    def input_signature(self):
+        """
+        @return input signature of hierarchical block.
+        @rtype gr.io_signature
+        """
+        raise NotImplemented
+
+    def output_signature(self):
+        """
+        @return output signature of hierarchical block.
+        @rtype gr.io_signature
+        """
+        raise NotImplemented
+
+    def resolve_input_port(self, port_number):
+        """
+        @param port_number: which input port number to resolve to an endpoint.
+        @type port_number: int
+        @return: sequence of endpoints
+        @rtype: sequence of endpoint
+
+        Note that an input port can resolve to more than one endpoint.
+        """
+        raise NotImplemented
+    
+    def resolve_output_port(self, port_number):
+        """
+        @param port_number: which output port number to resolve to an endpoint.
+        @type port_number: int
+        @return: endpoint
+        @rtype: endpoint
+
+        Output ports resolve to a single endpoint.
+        """
+        raise NotImplemented
+    
+
+class hier_block(hier_block_base):
+    """
+    Simple concrete class for building hierarchical blocks.
+
+    This class assumes that there is at most a single block at the
+    head of the chain and a single block at the end of the chain.
+    Either head or tail may be None indicating a sink or source respectively.
+
+    If you needs something more elaborate than this, derive a new class from
+    hier_block_base.
+    """
+    def __init__(self, fg, head_block, tail_block):
+        """
+        @param fg: The flow graph that contains this hierarchical block.
+        @type fg: flow_graph
+        @param head_block: the first block in the signal processing chain.
+        @type head_block: None or subclass of gr.block or gr.hier_block_base
+        @param tail_block: the last block in the signal processing chain.
+        @type tail_block: None or subclass of gr.block or gr.hier_block_base
+        """
+        hier_block_base.__init__(self, fg)
+        # FIXME add type checks here for easier debugging of misuse
+        self.head = head_block
+        self.tail = tail_block
+
+    def input_signature(self):
+        if self.head:
+            return self.head.input_signature()
+        else:
+            return io_signature(0,0,0)
+    
+    def output_signature(self):
+        if self.tail:
+            return self.tail.output_signature()
+        else:
+            return io_signature(0,0,0)
+    
+    def resolve_input_port(self, port_number):
+        return ((self.head, port_number),)
+
+    def resolve_output_port(self, port_number):
+        return (self.tail, port_number)
+
+
+class compose(hier_block):
+    """
+    Compose one or more blocks (primitive or hierarchical) into a new hierarchical block.
+    """
+    def __init__(self, fg, *blocks):
+        """
+        @param fg: flow graph
+        @type fg: gr.flow_graph
+        @param *blocks: list of blocks
+        @type *blocks: list of blocks
+        """
+        if len(blocks) < 1:
+            raise ValueError, ("compose requires at least one block; none provided.")
+        if len(blocks) > 1:
+            fg.connect(*blocks)
+        hier_block.__init__(self, fg, blocks[0], blocks[-1])
diff --git a/gnuradio-core/src/python/gnuradio/gr/prefs.py b/gnuradio-core/src/python/gnuradio/gr/prefs.py
new file mode 100644 (file)
index 0000000..fa12912
--- /dev/null
@@ -0,0 +1,129 @@
+#
+# 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 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.
+# 
+
+import gnuradio_swig_python as gsp
+_prefs_base = gsp.gr_prefs
+
+
+import ConfigParser
+import os
+import os.path
+import sys
+
+
+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')
+
+def _bool(x):
+    """
+    Try to coerce obj to a True or False
+    """
+    if isinstance(x, bool):
+        return x
+    if isinstance(x, (float, int)):
+        return bool(x)
+    raise TypeError, x
+        
+
+class _prefs(_prefs_base):
+    """
+    Derive our 'real class' from the stubbed out base class that has support
+    for SWIG directors.  This allows C++ code to magically and transparently
+    invoke the methods in this python class.
+    """
+    def __init__(self):
+        _prefs_base.__init__(self)
+        self.cp = ConfigParser.RawConfigParser()
+
+    def _sys_prefs_filenames(self):
+        dir = _sys_prefs_dirname()
+        try:
+            fnames = os.listdir(dir)
+        except (IOError, OSError):
+            return []
+        fnames.sort()
+        return [os.path.join(dir, f) for f in fnames]
+
+        
+    def _read_files(self):
+        filenames = self._sys_prefs_filenames()
+        filenames.append(_user_prefs_filename())
+        #print "filenames: ", filenames
+        self.cp.read(filenames)
+
+    def __getattr__(self, name):
+        return getattr(self.cp, name)
+
+    # ----------------------------------------------------------------
+    # These methods override the C++ virtual methods of the same name
+    # ----------------------------------------------------------------
+    def has_section(self, section):
+        return self.cp.has_section(section)
+
+    def has_option(self, section, option):
+        return self.cp.has_option(section, option)
+
+    def get_string(self, section, option, default_val):
+        try:
+            return self.cp.get(section, option)
+        except:
+            return default_val
+
+    def get_bool(self, section, option, default_val):
+        try:
+            return self.cp.getboolean(section, option)
+        except:
+            return default_val
+
+    def get_long(self, section, option, default_val):
+        try:
+            return self.cp.getint(section, option)
+        except:
+            return default_val
+        
+    def get_double(self, section, option, default_val):
+        try:
+            return self.cp.getfloat(section, option)
+        except:
+            return default_val
+    # ----------------------------------------------------------------
+    #              End override of C++ virtual methods
+    # ----------------------------------------------------------------
+
+
+_prefs_db = _prefs()
+
+# if GR_DONT_LOAD_PREFS is set, don't load them.
+# (make check uses this to avoid interactions.)
+if os.getenv("GR_DONT_LOAD_PREFS", None) is None:
+    _prefs_db._read_files()
+    
+
+_prefs_base.set_singleton(_prefs_db)    # tell C++ what instance to use
+
+def prefs():
+    """
+    Return the global preference data base
+    """
+    return _prefs_db
diff --git a/gnuradio-core/src/python/gnuradio/gr/qa_add_and_friends.py b/gnuradio-core/src/python/gnuradio/gr/qa_add_and_friends.py
new file mode 100755 (executable)
index 0000000..6cb74e9
--- /dev/null
@@ -0,0 +1,129 @@
+#!/usr/bin/env 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.
+# 
+
+from gnuradio import gr, gr_unittest
+
+class test_head (gr_unittest.TestCase):
+
+    def setUp (self):
+        self.fg = gr.flow_graph ()
+
+    def tearDown (self):
+        self.fg = None
+
+    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.fg.connect (src, (op, s[0]))
+        dst = gr.vector_sink_i ()
+        self.fg.connect (op, dst)
+        self.fg.run ()
+        result_data = dst.data ()
+        self.assertEqual (exp_data, result_data)
+
+    def help_ff (self, src_data, exp_data, op):
+        for s in zip (range (len (src_data)), src_data):
+            src = gr.vector_source_f (s[1])
+            self.fg.connect (src, (op, s[0]))
+        dst = gr.vector_sink_f ()
+        self.fg.connect (op, dst)
+        self.fg.run ()
+        result_data = dst.data ()
+        self.assertEqual (exp_data, result_data)
+
+    def help_cc (self, src_data, exp_data, op):
+        for s in zip (range (len (src_data)), src_data):
+            src = gr.vector_source_c (s[1])
+            self.fg.connect (src, (op, s[0]))
+        dst = gr.vector_sink_c ()
+        self.fg.connect (op, dst)
+        self.fg.run ()
+        result_data = dst.data ()
+        self.assertEqual (exp_data, result_data)
+
+    def test_add_const_ii (self):
+        src_data = (1, 2, 3, 4, 5)
+        expected_result = (6, 7, 8, 9, 10)
+        op = gr.add_const_ii (5)
+        self.help_ii ((src_data,), expected_result, op)
+
+    def test_add_const_cc (self):
+        src_data = (1, 2, 3, 4, 5)
+        expected_result = (1+5j, 2+5j, 3+5j, 4+5j, 5+5j)
+        op = gr.add_const_cc (5j)
+        self.help_cc ((src_data,), expected_result, op)
+
+    def test_mult_const_ii (self):
+        src_data = (-1, 0, 1, 2, 3)
+        expected_result = (-5, 0, 5, 10, 15)
+        op = gr.multiply_const_ii (5)
+        self.help_ii ((src_data,), expected_result, op)
+
+    def test_add_ii (self):
+        src1_data = (1,  2, 3, 4, 5)
+        src2_data = (8, -3, 4, 8, 2)
+        expected_result = (9, -1, 7, 12, 7)
+        op = gr.add_ii ()
+        self.help_ii ((src1_data, src2_data),
+                      expected_result, op)
+
+    def test_mult_ii (self):
+        src1_data = (1,  2, 3, 4, 5)
+        src2_data = (8, -3, 4, 8, 2)
+        expected_result = (8, -6, 12, 32, 10)
+        op = gr.multiply_ii ()
+        self.help_ii ((src1_data, src2_data),
+                      expected_result, op)
+
+    def test_sub_ii_1 (self):
+        src1_data = (1,  2, 3, 4, 5)
+        expected_result = (-1, -2, -3, -4, -5)
+        op = gr.sub_ii ()
+        self.help_ii ((src1_data,),
+                      expected_result, op)
+
+    def test_sub_ii_2 (self):
+        src1_data = (1,  2, 3, 4, 5)
+        src2_data = (8, -3, 4, 8, 2)
+        expected_result = (-7, 5, -1, -4, 3)
+        op = gr.sub_ii ()
+        self.help_ii ((src1_data, src2_data),
+                      expected_result, op)
+
+    def test_div_ff_1 (self):
+        src1_data       = (1,  2,  4,    -8)
+        expected_result = (1, 0.5, 0.25, -.125)
+        op = gr.divide_ff ()
+        self.help_ff ((src1_data,),
+                      expected_result, op)
+
+    def test_div_ff_2 (self):
+        src1_data       = ( 5,  9, -15, 1024)
+        src2_data       = (10,  3,  -5,   64)
+        expected_result = (0.5, 3,   3,   16)
+        op = gr.divide_ff ()
+        self.help_ff ((src1_data, src2_data),
+                      expected_result, op)
+
+
+if __name__ == '__main__':
+    gr_unittest.main ()
diff --git a/gnuradio-core/src/python/gnuradio/gr/qa_add_v_and_friends.py b/gnuradio-core/src/python/gnuradio/gr/qa_add_v_and_friends.py
new file mode 100755 (executable)
index 0000000..11e69e3
--- /dev/null
@@ -0,0 +1,353 @@
+#!/usr/bin/env 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.
+# 
+
+from gnuradio import gr, gr_unittest
+
+class test_add_v_and_friends(gr_unittest.TestCase):
+
+    def setUp(self):
+        self.fg = gr.flow_graph()
+
+    def tearDown(self):
+        self.fg = None
+
+    def help_ss(self, size, src_data, exp_data, op):
+        for s in zip(range (len (src_data)), src_data):
+            src = gr.vector_source_s(s[1])
+           srcv = gr.stream_to_vector(gr.sizeof_short, size)
+           self.fg.connect(src, srcv)
+            self.fg.connect(srcv, (op, s[0]))
+       rhs = gr.vector_to_stream(gr.sizeof_short, size)
+        dst = gr.vector_sink_s()
+        self.fg.connect(op, rhs, dst)
+        self.fg.run()
+        result_data = dst.data()
+        self.assertEqual(exp_data, result_data)
+
+    def help_ii(self, size, src_data, exp_data, op):
+        for s in zip(range (len (src_data)), src_data):
+            src = gr.vector_source_i(s[1])
+           srcv = gr.stream_to_vector(gr.sizeof_int, size)
+           self.fg.connect(src, srcv)
+            self.fg.connect(srcv, (op, s[0]))
+       rhs = gr.vector_to_stream(gr.sizeof_int, size)
+        dst = gr.vector_sink_i()
+        self.fg.connect(op, rhs, dst)
+        self.fg.run()
+        result_data = dst.data()
+        self.assertEqual(exp_data, result_data)
+
+    def help_ff(self, size, src_data, exp_data, op):
+        for s in zip(range (len (src_data)), src_data):
+            src = gr.vector_source_f(s[1])
+           srcv = gr.stream_to_vector(gr.sizeof_float, size)
+           self.fg.connect(src, srcv)
+            self.fg.connect(srcv, (op, s[0]))
+       rhs = gr.vector_to_stream(gr.sizeof_float, size)
+        dst = gr.vector_sink_f()
+        self.fg.connect(op, rhs, dst)
+        self.fg.run()
+        result_data = dst.data()
+        self.assertEqual(exp_data, result_data)
+
+    def help_cc(self, size, src_data, exp_data, op):
+        for s in zip(range (len (src_data)), src_data):
+            src = gr.vector_source_c(s[1])
+           srcv = gr.stream_to_vector(gr.sizeof_gr_complex, size)
+           self.fg.connect(src, srcv)
+            self.fg.connect(srcv, (op, s[0]))
+       rhs = gr.vector_to_stream(gr.sizeof_gr_complex, size)
+        dst = gr.vector_sink_c()
+        self.fg.connect(op, rhs, dst)
+        self.fg.run()
+        result_data = dst.data()
+        self.assertEqual(exp_data, result_data)
+
+    def help_const_ss(self, src_data, exp_data, op):
+       src = gr.vector_source_s(src_data)
+       srcv = gr.stream_to_vector(gr.sizeof_short, len(src_data))
+       rhs = gr.vector_to_stream(gr.sizeof_short, len(src_data))
+        dst = gr.vector_sink_s()
+        self.fg.connect(src, srcv, op, rhs, dst)
+        self.fg.run()
+        result_data = dst.data()
+        self.assertEqual(exp_data, result_data)
+       
+    def help_const_ii(self, src_data, exp_data, op):
+       src = gr.vector_source_i(src_data)
+       srcv = gr.stream_to_vector(gr.sizeof_int, len(src_data))
+       rhs = gr.vector_to_stream(gr.sizeof_int, len(src_data))
+        dst = gr.vector_sink_i()
+        self.fg.connect(src, srcv, op, rhs, dst)
+        self.fg.run()
+        result_data = dst.data()
+        self.assertEqual(exp_data, result_data)
+       
+    def help_const_ff(self, src_data, exp_data, op):
+       src = gr.vector_source_f(src_data)
+       srcv = gr.stream_to_vector(gr.sizeof_float, len(src_data))
+       rhs = gr.vector_to_stream(gr.sizeof_float, len(src_data))
+        dst = gr.vector_sink_f()
+        self.fg.connect(src, srcv, op, rhs, dst)
+        self.fg.run()
+        result_data = dst.data()
+        self.assertEqual(exp_data, result_data)
+       
+    def help_const_cc(self, src_data, exp_data, op):
+       src = gr.vector_source_c(src_data)
+       srcv = gr.stream_to_vector(gr.sizeof_gr_complex, len(src_data))
+       rhs = gr.vector_to_stream(gr.sizeof_gr_complex, len(src_data))
+        dst = gr.vector_sink_c()
+        self.fg.connect(src, srcv, op, rhs, dst)
+        self.fg.run()
+        result_data = dst.data()
+        self.assertEqual(exp_data, result_data)
+       
+
+    def test_add_vss_one(self):
+       src1_data = (1,)
+       src2_data = (2,)
+       src3_data = (3,)
+       expected_result = (6,)
+       op = gr.add_vss(1)
+       self.help_ss(1, (src1_data, src2_data, src3_data), expected_result, op)
+       
+    def test_add_vss_five(self):
+       src1_data = (1, 2, 3, 4, 5)
+       src2_data = (6, 7, 8, 9, 10)
+       src3_data = (11, 12, 13, 14, 15)
+       expected_result = (18, 21, 24, 27, 30)
+       op = gr.add_vss(5)
+       self.help_ss(5, (src1_data, src2_data, src3_data), expected_result, op)
+
+    def test_add_vii_one(self):
+       src1_data = (1,)
+       src2_data = (2,)
+       src3_data = (3,)
+       expected_result = (6,)
+       op = gr.add_vii(1)
+       self.help_ii(1, (src1_data, src2_data, src3_data), expected_result, op)
+       
+    def test_add_vii_five(self):
+       src1_data = (1, 2, 3, 4, 5)
+       src2_data = (6, 7, 8, 9, 10)
+       src3_data = (11, 12, 13, 14, 15)
+       expected_result = (18, 21, 24, 27, 30)
+       op = gr.add_vii(5)
+       self.help_ii(5, (src1_data, src2_data, src3_data), expected_result, op)
+
+    def test_add_vff_one(self):
+       src1_data = (1.0,)
+       src2_data = (2.0,)
+       src3_data = (3.0,)
+       expected_result = (6.0,)
+       op = gr.add_vff(1)
+       self.help_ff(1, (src1_data, src2_data, src3_data), expected_result, op)
+       
+    def test_add_vff_five(self):
+       src1_data = (1.0, 2.0, 3.0, 4.0, 5.0)
+       src2_data = (6.0, 7.0, 8.0, 9.0, 10.0)
+       src3_data = (11.0, 12.0, 13.0, 14.0, 15.0)
+       expected_result = (18.0, 21.0, 24.0, 27.0, 30.0)
+       op = gr.add_vff(5)
+       self.help_ff(5, (src1_data, src2_data, src3_data), expected_result, op)
+
+    def test_add_vcc_one(self):
+       src1_data = (1.0+2.0j,)
+       src2_data = (3.0+4.0j,)
+       src3_data = (5.0+6.0j,)
+       expected_result = (9.0+12j,)
+       op = gr.add_vcc(1)
+       self.help_cc(1, (src1_data, src2_data, src3_data), expected_result, op)
+       
+    def test_add_vcc_five(self):
+       src1_data = (1.0+2.0j, 3.0+4.0j, 5.0+6.0j, 7.0+8.0j, 9.0+10.0j)
+       src2_data = (11.0+12.0j, 13.0+14.0j, 15.0+16.0j, 17.0+18.0j, 19.0+20.0j)
+       src3_data = (21.0+22.0j, 23.0+24.0j, 25.0+26.0j, 27.0+28.0j, 29.0+30.0j)
+       expected_result = (33.0+36.0j, 39.0+42.0j, 45.0+48.0j, 51.0+54.0j, 57.0+60.0j)
+       op = gr.add_vcc(5)
+       self.help_cc(5, (src1_data, src2_data, src3_data), expected_result, op)
+
+    def test_add_const_vss_one(self):
+       src_data = (1,)
+       op = gr.add_const_vss((2,))
+       exp_data = (3,)
+       self.help_const_ss(src_data, exp_data, op)
+
+    def test_add_const_vss_five(self):
+       src_data = (1, 2, 3, 4, 5)
+       op = gr.add_const_vss((6, 7, 8, 9, 10))
+       exp_data = (7, 9, 11, 13, 15)
+       self.help_const_ss(src_data, exp_data, op)
+
+    def test_add_const_vii_one(self):
+       src_data = (1,)
+       op = gr.add_const_vii((2,))
+       exp_data = (3,)
+       self.help_const_ii(src_data, exp_data, op)
+
+    def test_add_const_vii_five(self):
+       src_data = (1, 2, 3, 4, 5)
+       op = gr.add_const_vii((6, 7, 8, 9, 10))
+       exp_data = (7, 9, 11, 13, 15)
+       self.help_const_ii(src_data, exp_data, op)
+
+    def test_add_const_vff_one(self):
+       src_data = (1.0,)
+       op = gr.add_const_vff((2.0,))
+       exp_data = (3.0,)
+       self.help_const_ff(src_data, exp_data, op)
+
+    def test_add_const_vff_five(self):
+       src_data = (1.0, 2.0, 3.0, 4.0, 5.0)
+       op = gr.add_const_vff((6.0, 7.0, 8.0, 9.0, 10.0))
+       exp_data = (7.0, 9.0, 11.0, 13.0, 15.0)
+       self.help_const_ff(src_data, exp_data, op)
+
+    def test_add_const_vcc_one(self):
+       src_data = (1.0+2.0j,)
+       op = gr.add_const_vcc((2.0+3.0j,))
+       exp_data = (3.0+5.0j,)
+       self.help_const_cc(src_data, exp_data, op)
+
+    def test_add_const_vcc_five(self):
+       src_data = (1.0+2.0j, 3.0+4.0j, 5.0+6.0j, 7.0+8.0j, 9.0+10.0j)
+       op = gr.add_const_vcc((11.0+12.0j, 13.0+14.0j, 15.0+16.0j, 17.0+18.0j, 19.0+20.0j))
+       exp_data = (12.0+14.0j, 16.0+18.0j, 20.0+22.0j, 24.0+26.0j, 28.0+30.0j)
+       self.help_const_cc(src_data, exp_data, op)
+
+
+    def test_multiply_vss_one(self):
+       src1_data = (1,)
+       src2_data = (2,)
+       src3_data = (3,)
+       expected_result = (6,)
+       op = gr.multiply_vss(1)
+       self.help_ss(1, (src1_data, src2_data, src3_data), expected_result, op)
+       
+    def test_multiply_vss_five(self):
+       src1_data = (1, 2, 3, 4, 5)
+       src2_data = (6, 7, 8, 9, 10)
+       src3_data = (11, 12, 13, 14, 15)
+       expected_result = (66, 168, 312, 504, 750)
+       op = gr.multiply_vss(5)
+       self.help_ss(5, (src1_data, src2_data, src3_data), expected_result, op)
+
+    def test_multiply_vii_one(self):
+       src1_data = (1,)
+       src2_data = (2,)
+       src3_data = (3,)
+       expected_result = (6,)
+       op = gr.multiply_vii(1)
+       self.help_ii(1, (src1_data, src2_data, src3_data), expected_result, op)
+       
+    def test_multiply_vii_five(self):
+       src1_data = (1, 2, 3, 4, 5)
+       src2_data = (6, 7, 8, 9, 10)
+       src3_data = (11, 12, 13, 14, 15)
+       expected_result = (66, 168, 312, 504, 750)
+       op = gr.multiply_vii(5)
+       self.help_ii(5, (src1_data, src2_data, src3_data), expected_result, op)
+
+    def test_multiply_vff_one(self):
+       src1_data = (1.0,)
+       src2_data = (2.0,)
+       src3_data = (3.0,)
+       expected_result = (6.0,)
+       op = gr.multiply_vff(1)
+       self.help_ff(1, (src1_data, src2_data, src3_data), expected_result, op)
+       
+    def test_multiply_vff_five(self):
+       src1_data = (1.0, 2.0, 3.0, 4.0, 5.0)
+       src2_data = (6.0, 7.0, 8.0, 9.0, 10.0)
+       src3_data = (11.0, 12.0, 13.0, 14.0, 15.0)
+       expected_result = (66.0, 168.0, 312.0, 504.0, 750.0)
+       op = gr.multiply_vff(5)
+       self.help_ff(5, (src1_data, src2_data, src3_data), expected_result, op)
+
+    def test_multiply_vcc_one(self):
+       src1_data = (1.0+2.0j,)
+       src2_data = (3.0+4.0j,)
+       src3_data = (5.0+6.0j,)
+       expected_result = (-85+20j,)
+       op = gr.multiply_vcc(1)
+       self.help_cc(1, (src1_data, src2_data, src3_data), expected_result, op)
+       
+    def test_multiply_vcc_five(self):
+       src1_data = (1.0+2.0j, 3.0+4.0j, 5.0+6.0j, 7.0+8.0j, 9.0+10.0j)
+       src2_data = (11.0+12.0j, 13.0+14.0j, 15.0+16.0j, 17.0+18.0j, 19.0+20.0j)
+       src3_data = (21.0+22.0j, 23.0+24.0j, 25.0+26.0j, 27.0+28.0j, 29.0+30.0j)
+       expected_result = (-1021.0+428.0j, -2647.0+1754.0j, -4945.0+3704.0j, -8011.0+6374.0j, -11941.0+9860.0j)
+       op = gr.multiply_vcc(5)
+       self.help_cc(5, (src1_data, src2_data, src3_data), expected_result, op)
+
+    def test_multiply_const_vss_one(self):
+       src_data = (2,)
+       op = gr.multiply_const_vss((3,))
+       exp_data = (6,)
+       self.help_const_ss(src_data, exp_data, op)
+
+    def test_multiply_const_vss_five(self):
+       src_data = (1, 2, 3, 4, 5)
+       op = gr.multiply_const_vss((6, 7, 8, 9, 10))
+       exp_data = (6, 14, 24, 36, 50)
+       self.help_const_ss(src_data, exp_data, op)
+
+    def test_multiply_const_vii_one(self):
+       src_data = (2,)
+       op = gr.multiply_const_vii((3,))
+       exp_data = (6,)
+       self.help_const_ii(src_data, exp_data, op)
+
+    def test_multiply_const_vii_five(self):
+       src_data = (1, 2, 3, 4, 5)
+       op = gr.multiply_const_vii((6, 7, 8, 9, 10))
+       exp_data = (6, 14, 24, 36, 50)
+       self.help_const_ii(src_data, exp_data, op)
+
+    def test_multiply_const_vff_one(self):
+       src_data = (2.0,)
+       op = gr.multiply_const_vff((3.0,))
+       exp_data = (6.0,)
+       self.help_const_ff(src_data, exp_data, op)
+
+    def test_multiply_const_vff_five(self):
+       src_data = (1.0, 2.0, 3.0, 4.0, 5.0)
+       op = gr.multiply_const_vff((6.0, 7.0, 8.0, 9.0, 10.0))
+       exp_data = (6.0, 14.0, 24.0, 36.0, 50.0)
+       self.help_const_ff(src_data, exp_data, op)
+
+    def test_multiply_const_vcc_one(self):
+       src_data = (1.0+2.0j,)
+       op = gr.multiply_const_vcc((2.0+3.0j,))
+       exp_data = (-4.0+7.0j,)
+       self.help_const_cc(src_data, exp_data, op)
+
+    def test_multiply_const_vcc_five(self):
+       src_data = (1.0+2.0j, 3.0+4.0j, 5.0+6.0j, 7.0+8.0j, 9.0+10.0j)
+       op = gr.multiply_const_vcc((11.0+12.0j, 13.0+14.0j, 15.0+16.0j, 17.0+18.0j, 19.0+20.0j))
+       exp_data = (-13.0+34.0j, -17.0+94.0j, -21.0+170.0j, -25.0+262.0j, -29.0+370.0j)
+       self.help_const_cc(src_data, exp_data, op)
+
+
+if __name__ == '__main__':
+    gr_unittest.main ()
diff --git a/gnuradio-core/src/python/gnuradio/gr/qa_basic_flow_graph.py b/gnuradio-core/src/python/gnuradio/gr/qa_basic_flow_graph.py
new file mode 100755 (executable)
index 0000000..0799c72
--- /dev/null
@@ -0,0 +1,190 @@
+#!/usr/bin/env python
+
+from gnuradio import gr, gr_unittest
+
+
+# ----------------------------------------------------------------                         
+
+
+class test_basic_flow_graph (gr_unittest.TestCase):
+
+    def setUp (self):
+        self.fg = gr.basic_flow_graph ()
+        
+    def tearDown (self):
+        self.fg = None
+
+    def test_000_create_delete (self):
+        pass
+
+    def test_001a_insert_1 (self):
+        fg = self.fg
+        src1 = gr.null_source (gr.sizeof_int)
+        dst1 = gr.null_sink (gr.sizeof_int)
+        fg.connect (gr.endpoint (src1, 0), gr.endpoint (dst1, 0))
+
+    def test_001b_insert_1 (self):
+        fg = self.fg
+        src1 = gr.null_source (gr.sizeof_int)
+        dst1 = gr.null_sink (gr.sizeof_int)
+        fg.connect (src1, gr.endpoint (dst1, 0))
+
+    def test_001c_insert_1 (self):
+        fg = self.fg
+        src1 = gr.null_source (gr.sizeof_int)
+        dst1 = gr.null_sink (gr.sizeof_int)
+        fg.connect (gr.endpoint (src1, 0), dst1)
+
+    def test_001d_insert_1 (self):
+        fg = self.fg
+        src1 = gr.null_source (gr.sizeof_int)
+        dst1 = gr.null_sink (gr.sizeof_int)
+        fg.connect (src1, dst1)
+
+    def test_001e_insert_1 (self):
+        fg = self.fg
+        src1 = gr.null_source (gr.sizeof_int)
+        dst1 = gr.null_sink (gr.sizeof_int)
+        fg.connect ((src1, 0), (dst1, 0))
+
+    def test_002_dst_in_use (self):
+        fg = self.fg
+        src1 = gr.null_source (gr.sizeof_int)
+        src2 = gr.null_source (gr.sizeof_int)
+        dst1 = gr.null_sink (gr.sizeof_int)
+        fg.connect ((src1, 0), (dst1, 0))
+        self.assertRaises (ValueError,
+                           lambda : fg.connect ((src2, 0),
+                                                (dst1, 0)))
+
+    def test_003_no_such_src_port (self):
+        fg = self.fg
+        src1 = gr.null_source (gr.sizeof_int)
+        dst1 = gr.null_sink (gr.sizeof_int)
+        self.assertRaises (ValueError,
+                           lambda : fg.connect ((src1, 1),
+                                                (dst1, 0)))
+
+    def test_004_no_such_dst_port (self):
+        fg = self.fg
+        src1 = gr.null_source (gr.sizeof_int)
+        dst1 = gr.null_sink (gr.sizeof_int)
+        self.assertRaises (ValueError,
+                           lambda : fg.connect ((src1, 0),
+                                                (dst1, 1)))
+
+    def test_005_one_src_two_dst (self):
+        fg = self.fg
+        src1 = gr.null_source (gr.sizeof_int)
+        dst1 = gr.null_sink (gr.sizeof_int)
+        dst2 = gr.null_sink (gr.sizeof_int)
+        fg.connect ((src1, 0), (dst1, 0))
+        fg.connect ((src1, 0), (dst2, 0))
+
+    def test_006_check_item_sizes (self):
+        fg = self.fg
+        src1 = gr.null_source (gr.sizeof_int)
+        dst1 = gr.null_sink (gr.sizeof_char)
+        self.assertRaises (ValueError,
+                           lambda : fg.connect ((src1, 0),
+                                                (dst1, 0)))
+        
+    def test_007_validate (self):
+        fg = self.fg
+        src1 = gr.null_source (gr.sizeof_int)
+        dst1 = gr.null_sink (gr.sizeof_int)
+        dst2 = gr.null_sink (gr.sizeof_int)
+        fg.connect ((src1, 0), (dst1, 0))
+        fg.connect ((src1, 0), (dst2, 0))
+        fg.validate ()
+
+    def test_008_validate (self):
+        fg = self.fg
+        src1 = gr.null_source (gr.sizeof_int)
+        nop1 = gr.nop (gr.sizeof_int)
+        dst1 = gr.null_sink (gr.sizeof_int)
+        dst2 = gr.null_sink (gr.sizeof_int)
+        fg.connect ((src1, 0), (nop1, 0))
+        fg.connect ((src1, 0), (nop1, 1))
+        fg.connect ((nop1, 0), (dst1, 0))
+        fg.connect ((nop1, 1), (dst2, 0))
+        fg.validate ()
+
+    def test_009_validate (self):
+        fg = self.fg
+        src1 = gr.null_source (gr.sizeof_int)
+        nop1 = gr.nop (gr.sizeof_int)
+        dst1 = gr.null_sink (gr.sizeof_int)
+        dst2 = gr.null_sink (gr.sizeof_int)
+        fg.connect ((src1, 0), (nop1, 0))
+        fg.connect ((src1, 0), (nop1, 2))
+        fg.connect ((nop1, 0), (dst1, 0))
+        fg.connect ((nop1, 1), (dst2, 0))
+        self.assertRaises (ValueError,
+                           lambda : fg.validate ())
+
+
+    def test_010_validate (self):
+        fg = self.fg
+        src1 = gr.null_source (gr.sizeof_int)
+        nop1 = gr.nop (gr.sizeof_int)
+        dst1 = gr.null_sink (gr.sizeof_int)
+        dst2 = gr.null_sink (gr.sizeof_int)
+        fg.connect ((src1, 0), (nop1, 0))
+        fg.connect ((src1, 0), (nop1, 1))
+        fg.connect ((nop1, 0), (dst1, 0))
+        fg.connect ((nop1, 2), (dst2, 0))
+        self.assertRaises (ValueError,
+                           lambda : fg.validate ())
+
+        
+    def test_011_disconnect (self):
+        fg = self.fg
+        src1 = gr.null_source (gr.sizeof_int)
+        nop1 = gr.nop (gr.sizeof_int)
+        dst1 = gr.null_sink (gr.sizeof_int)
+        dst2 = gr.null_sink (gr.sizeof_int)
+        fg.connect ((src1, 0), (nop1, 0))
+        fg.connect ((src1, 0), (nop1, 1))
+        fg.connect ((nop1, 0), (dst1, 0))
+        fg.connect ((nop1, 1), (dst2, 0))
+        fg.validate ()
+        fg.disconnect ((src1, 0), (nop1, 1))
+        fg.validate ()
+        self.assertRaises (ValueError,
+                           lambda : fg.disconnect ((src1, 0),
+                                                   (nop1, 1)))
+
+    def test_012_connect (self):
+        fg = self.fg
+        src_data = (0, 1, 2, 3)
+        expected_result = (2, 3, 4, 5)
+        src1 = gr.vector_source_i (src_data)
+        op = gr.add_const_ii (2)
+        dst1 = gr.vector_sink_i ()
+        fg.connect (src1, op)
+        fg.connect (op, dst1)
+        # print "edge_list:", fg.edge_list
+        fg.validate ()
+
+    def test_013_connect_varargs (self):
+        fg = self.fg
+        src1 = gr.null_source (gr.sizeof_int)
+        nop1 = gr.nop (gr.sizeof_int)
+        dst1 = gr.null_sink (gr.sizeof_int)
+        self.assertRaises (ValueError,
+                           lambda : fg.connect ())
+        self.assertRaises (ValueError,
+                           lambda : fg.connect (src1))
+
+    def test_014_connect_varargs (self):
+        fg = self.fg
+        src1 = gr.null_source (gr.sizeof_int)
+        nop1 = gr.nop (gr.sizeof_int)
+        dst1 = gr.null_sink (gr.sizeof_int)
+        fg.connect (src1, nop1, dst1)
+        fg.validate ()
+
+if __name__ == '__main__':
+    gr_unittest.main ()
+    
diff --git a/gnuradio-core/src/python/gnuradio/gr/qa_cma_equalizer.py b/gnuradio-core/src/python/gnuradio/gr/qa_cma_equalizer.py
new file mode 100755 (executable)
index 0000000..6b3e9aa
--- /dev/null
@@ -0,0 +1,29 @@
+#!/usr/bin/env python
+
+from gnuradio import gr, gr_unittest
+
+class test_cma_equalizer_fir(gr_unittest.TestCase):
+
+    def setUp(self):
+       self.fg = gr.flow_graph()
+
+    def tearDown(self):
+       self.fg = None
+       
+    def transform(self, src_data):
+       SRC = gr.vector_source_c(src_data, False)
+       EQU = gr.cma_equalizer_cc(4, 1.0, .001)
+       DST = gr.vector_sink_c()
+       self.fg.connect(SRC, EQU, DST)
+       self.fg.run()
+       return DST.data()
+
+    def test_001_identity(self):
+       # Constant modulus signal so no adjustments
+       src_data      = (1+0j, 0+1j, -1+0j, 0-1j)*1000
+       expected_data = src_data
+       result = self.transform(src_data)
+       self.assertComplexTuplesAlmostEqual(expected_data, result)
+
+if __name__ == "__main__":
+    gr_unittest.main()
\ No newline at end of file
diff --git a/gnuradio-core/src/python/gnuradio/gr/qa_complex_to_xxx.py b/gnuradio-core/src/python/gnuradio/gr/qa_complex_to_xxx.py
new file mode 100755 (executable)
index 0000000..4bc1933
--- /dev/null
@@ -0,0 +1,116 @@
+#!/usr/bin/env 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.
+# 
+
+from gnuradio import gr, gr_unittest
+import math
+
+class test_complex_ops (gr_unittest.TestCase):
+
+    def setUp (self):
+        self.fg = gr.flow_graph ()
+
+    def tearDown (self):
+        self.fg = None
+
+    def test_complex_to_float_1 (self):
+        src_data = (0, 1, -1, 3+4j, -3-4j, -3+4j)
+        expected_result = (0, 1, -1, 3, -3, -3)
+        src = gr.vector_source_c (src_data)
+        op = gr.complex_to_float ()
+        dst = gr.vector_sink_f ()
+        self.fg.connect (src, op)
+        self.fg.connect (op, dst)
+        self.fg.run ()               # run the graph and wait for it to finish
+        actual_result = dst.data ()  # fetch the contents of the sink
+        self.assertFloatTuplesAlmostEqual (expected_result, actual_result)
+
+    def test_complex_to_float_2 (self):
+        src_data = (0, 1, -1, 3+4j, -3-4j, -3+4j)
+        expected_result0 = (0, 1, -1, 3, -3, -3)
+        expected_result1 = (0, 0, 0, 4, -4, 4)
+        src = gr.vector_source_c (src_data)
+        op = gr.complex_to_float ()
+        dst0 = gr.vector_sink_f ()
+        dst1 = gr.vector_sink_f ()
+        self.fg.connect (src, op)
+        self.fg.connect ((op, 0), dst0)
+        self.fg.connect ((op, 1), dst1)
+        self.fg.run ()
+        actual_result = dst0.data ()
+        self.assertFloatTuplesAlmostEqual (expected_result0, actual_result)
+        actual_result = dst1.data ()
+        self.assertFloatTuplesAlmostEqual (expected_result1, actual_result)
+
+    def test_complex_to_real (self):
+        src_data = (0, 1, -1, 3+4j, -3-4j, -3+4j)
+        expected_result = (0, 1, -1, 3, -3, -3)
+        src = gr.vector_source_c (src_data)
+        op = gr.complex_to_real ()
+        dst = gr.vector_sink_f ()
+        self.fg.connect (src, op)
+        self.fg.connect (op, dst)
+        self.fg.run ()
+        actual_result = dst.data ()
+        self.assertFloatTuplesAlmostEqual (expected_result, actual_result)
+
+    def test_complex_to_imag (self):
+        src_data = (0, 1, -1, 3+4j, -3-4j, -3+4j)
+        expected_result = (0, 0, 0, 4, -4, 4)
+        src = gr.vector_source_c (src_data)
+        op = gr.complex_to_imag ()
+        dst = gr.vector_sink_f ()
+        self.fg.connect (src, op)
+        self.fg.connect (op, dst)
+        self.fg.run ()
+        actual_result = dst.data ()
+        self.assertFloatTuplesAlmostEqual (expected_result, actual_result,5)
+
+    def test_complex_to_mag (self):
+        src_data = (0, 1, -1, 3+4j, -3-4j, -3+4j)
+        expected_result = (0, 1, 1, 5, 5, 5)
+        src = gr.vector_source_c (src_data)
+        op = gr.complex_to_mag ()
+        dst = gr.vector_sink_f ()
+        self.fg.connect (src, op)
+        self.fg.connect (op, dst)
+        self.fg.run ()
+        actual_result = dst.data ()
+        self.assertFloatTuplesAlmostEqual (expected_result, actual_result,5)
+
+    def test_complex_to_arg (self):
+        pi = math.pi
+        expected_result = (0, pi/6, pi/4, pi/2, 3*pi/4, 7*pi/8,
+                           -pi/6, -pi/4, -pi/2, -3*pi/4, -7*pi/8)
+        src_data = tuple ([math.cos (x) + math.sin (x) * 1j for x in expected_result])
+        src = gr.vector_source_c (src_data)
+        op = gr.complex_to_arg ()
+        dst = gr.vector_sink_f ()
+        self.fg.connect (src, op)
+        self.fg.connect (op, dst)
+        self.fg.run ()
+        actual_result = dst.data ()
+        self.assertFloatTuplesAlmostEqual (expected_result, actual_result, 5)
+
+
+if __name__ == '__main__':
+    gr_unittest.main ()
+
diff --git a/gnuradio-core/src/python/gnuradio/gr/qa_constellation_decoder_cb.py b/gnuradio-core/src/python/gnuradio/gr/qa_constellation_decoder_cb.py
new file mode 100755 (executable)
index 0000000..9564122
--- /dev/null
@@ -0,0 +1,53 @@
+#!/usr/bin/env 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.
+# 
+
+from gnuradio import gr, gr_unittest
+import math
+
+class test_head (gr_unittest.TestCase):
+
+    def setUp (self):
+        self.fg = gr.flow_graph ()
+
+    def tearDown (self):
+        self.fg = None
+
+    def test_constellation_decoder_cb (self):
+        symbol_positions  = [1 + 0j, 0 + 1j , -1 + 0j, 0 - 1j]
+        symbol_values_out = [0, 1, 2, 3]
+       expected_result = (       0,          3,           2,            1,        0,       0,          3)
+       src_data =        (0.5 + 0j, 0.1 - 1.2j, -0.8 - 0.1j, -0.45 + 0.8j, 0.8 - 0j, 0.5 + 0j, 0.1 - 1.2j)
+        src = gr.vector_source_c (src_data)
+        op = gr.constellation_decoder_cb (symbol_positions, symbol_values_out)
+        dst = gr.vector_sink_b ()
+        self.fg.connect (src, op)
+        self.fg.connect (op, dst)
+        self.fg.run ()               # run the graph and wait for it to finish
+        actual_result = dst.data ()  # fetch the contents of the sink
+       #print "actual result", actual_result
+       #print "expected result", expected_result
+        self.assertFloatTuplesAlmostEqual (expected_result, actual_result)
+
+
+if __name__ == '__main__':
+    gr_unittest.main ()
+
diff --git a/gnuradio-core/src/python/gnuradio/gr/qa_correlate_access_code.py b/gnuradio-core/src/python/gnuradio/gr/qa_correlate_access_code.py
new file mode 100755 (executable)
index 0000000..89b4909
--- /dev/null
@@ -0,0 +1,83 @@
+#!/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 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.
+# 
+
+from gnuradio import gr, gr_unittest
+import math
+
+default_access_code = '\xAC\xDD\xA4\xE2\xF2\x8C\x20\xFC'
+
+def string_to_1_0_list(s):
+    r = []
+    for ch in s:
+        x = ord(ch)
+        for i in range(8):
+            t = (x >> i) & 0x1
+            r.append(t)
+
+    return r
+
+def to_1_0_string(L):
+    return ''.join(map(lambda x: chr(x + ord('0')), L))
+
+class test_correlate_access_code(gr_unittest.TestCase):
+
+    def setUp(self):
+        self.fg = gr.flow_graph()
+
+    def tearDown(self):
+        self.fg = None
+
+    def test_001(self):
+        pad = (0,) * 64
+        #           0  0  0  1  0  0  0  1
+        src_data = (1, 0, 1, 1, 1, 1, 0, 1, 1) + pad + (0,) * 7
+        expected_result = pad + (1, 0, 1, 1, 3, 1, 0, 1, 1, 2) + (0,) * 6
+        src = gr.vector_source_b (src_data)
+        op = gr.correlate_access_code_bb("1011", 0)
+        dst = gr.vector_sink_b ()
+        self.fg.connect (src, op, dst)
+        self.fg.run ()
+        result_data = dst.data ()
+        self.assertEqual (expected_result, result_data)
+
+
+    def test_002(self):
+        code = tuple(string_to_1_0_list(default_access_code))
+        access_code = to_1_0_string(code)
+        pad = (0,) * 64
+        #print code
+        #print access_code
+        src_data = code + (1, 0, 1, 1) + pad
+        expected_result = pad + code + (3, 0, 1, 1)
+        src = gr.vector_source_b (src_data)
+        op = gr.correlate_access_code_bb(access_code, 0)
+        dst = gr.vector_sink_b ()
+        self.fg.connect (src, op, dst)
+        self.fg.run ()
+        result_data = dst.data ()
+        self.assertEqual (expected_result, result_data)
+        
+        
+
+if __name__ == '__main__':
+    gr_unittest.main ()
+        
diff --git a/gnuradio-core/src/python/gnuradio/gr/qa_diff_encoder.py b/gnuradio-core/src/python/gnuradio/gr/qa_diff_encoder.py
new file mode 100755 (executable)
index 0000000..4484070
--- /dev/null
@@ -0,0 +1,86 @@
+#!/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 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.
+# 
+
+from gnuradio import gr, gr_unittest
+import math
+import random
+
+def make_random_int_tuple(L, min, max):
+    result = []
+    for x in range(L):
+        result.append(random.randint(min, max))
+    return tuple(result)
+
+    
+class test_encoder (gr_unittest.TestCase):
+
+    def setUp (self):
+        self.fg = gr.flow_graph ()
+
+    def tearDown (self):
+        self.fg = None
+
+    def test_diff_encdec_000(self):
+        random.seed(0)
+        modulus = 2
+        src_data = make_random_int_tuple(1000, 0, modulus-1)
+        expected_result = src_data
+        src = gr.vector_source_b(src_data)
+        enc = gr.diff_encoder_bb(modulus)
+        dec = gr.diff_decoder_bb(modulus)
+        dst = gr.vector_sink_b()
+        self.fg.connect(src, enc, dec, dst)
+        self.fg.run()               # run the graph and wait for it to finish
+        actual_result = dst.data()  # fetch the contents of the sink
+        self.assertEqual(expected_result, actual_result)
+
+    def test_diff_encdec_001(self):
+        random.seed(0)
+        modulus = 4
+        src_data = make_random_int_tuple(1000, 0, modulus-1)
+        expected_result = src_data
+        src = gr.vector_source_b(src_data)
+        enc = gr.diff_encoder_bb(modulus)
+        dec = gr.diff_decoder_bb(modulus)
+        dst = gr.vector_sink_b()
+        self.fg.connect(src, enc, dec, dst)
+        self.fg.run()               # run the graph and wait for it to finish
+        actual_result = dst.data()  # fetch the contents of the sink
+        self.assertEqual(expected_result, actual_result)
+
+    def test_diff_encdec_002(self):
+        random.seed(0)
+        modulus = 8
+        src_data = make_random_int_tuple(40000, 0, modulus-1)
+        expected_result = src_data
+        src = gr.vector_source_b(src_data)
+        enc = gr.diff_encoder_bb(modulus)
+        dec = gr.diff_decoder_bb(modulus)
+        dst = gr.vector_sink_b()
+        self.fg.connect(src, enc, dec, dst)
+        self.fg.run()               # run the graph and wait for it to finish
+        actual_result = dst.data()  # fetch the contents of the sink
+        self.assertEqual(expected_result, actual_result)
+
+if __name__ == '__main__':
+    gr_unittest.main ()
+
diff --git a/gnuradio-core/src/python/gnuradio/gr/qa_diff_phasor_cc.py b/gnuradio-core/src/python/gnuradio/gr/qa_diff_phasor_cc.py
new file mode 100755 (executable)
index 0000000..0b71602
--- /dev/null
@@ -0,0 +1,50 @@
+#!/usr/bin/env 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.
+# 
+
+from gnuradio import gr, gr_unittest
+import math
+
+class test_complex_ops (gr_unittest.TestCase):
+
+    def setUp (self):
+        self.fg = gr.flow_graph ()
+
+    def tearDown (self):
+        self.fg = None
+
+    def test_diff_phasor_cc (self):
+        src_data = (0+0j, 1+0j, -1+0j, 3+4j, -3-4j, -3+4j)
+        expected_result = (0+0j, 0+0j, -1+0j, -3-4j, -25+0j, -7-24j)
+        src = gr.vector_source_c (src_data)
+        op = gr.diff_phasor_cc ()
+        dst = gr.vector_sink_c ()
+        self.fg.connect (src, op)
+        self.fg.connect (op, dst)
+        self.fg.run ()               # run the graph and wait for it to finish
+        actual_result = dst.data ()  # fetch the contents of the sink
+        self.assertComplexTuplesAlmostEqual (expected_result, actual_result)
+
+
+
+if __name__ == '__main__':
+    gr_unittest.main ()
+
diff --git a/gnuradio-core/src/python/gnuradio/gr/qa_feval.py b/gnuradio-core/src/python/gnuradio/gr/qa_feval.py
new file mode 100755 (executable)
index 0000000..1de4936
--- /dev/null
@@ -0,0 +1,92 @@
+#!/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 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.
+# 
+
+from gnuradio import gr, gr_unittest
+
+class my_add2_dd(gr.feval_dd):
+    def eval(self, x):
+        return x + 2
+
+class my_add2_ll(gr.feval_ll):
+    def eval(self, x):
+        return x + 2
+
+class my_add2_cc(gr.feval_cc):
+    def eval(self, x):
+        return x + (2 - 2j)
+
+
+class test_feval(gr_unittest.TestCase):
+
+    def test_dd_1(self):
+        f = my_add2_dd()
+        src_data =        (0.0, 1.0, 2.0, 3.0, 4.0)
+        expected_result = (2.0, 3.0, 4.0, 5.0, 6.0)
+        # this is all in python...
+        actual_result = tuple([f.eval(x) for x in src_data])
+        self.assertEqual(expected_result, actual_result)
+
+    def test_dd_2(self):
+        f = my_add2_dd()
+        src_data =        (0.0, 1.0, 2.0, 3.0, 4.0)
+        expected_result = (2.0, 3.0, 4.0, 5.0, 6.0)
+        # this is python -> C++ -> python and back again...
+        actual_result = tuple([gr.feval_dd_example(f, x) for x in src_data])
+        self.assertEqual(expected_result, actual_result)
+
+        
+    def test_ll_1(self):
+        f = my_add2_ll()
+        src_data =        (0, 1, 2, 3, 4)
+        expected_result = (2, 3, 4, 5, 6)
+        # this is all in python...
+        actual_result = tuple([f.eval(x) for x in src_data])
+        self.assertEqual(expected_result, actual_result)
+
+    def test_ll_2(self):
+        f = my_add2_ll()
+        src_data =        (0, 1, 2, 3, 4)
+        expected_result = (2, 3, 4, 5, 6)
+        # this is python -> C++ -> python and back again...
+        actual_result = tuple([gr.feval_ll_example(f, x) for x in src_data])
+        self.assertEqual(expected_result, actual_result)
+
+
+    def test_cc_1(self):
+        f = my_add2_cc()
+        src_data =        (0+1j, 2+3j, 4+5j, 6+7j)
+        expected_result = (2-1j, 4+1j, 6+3j, 8+5j)
+        # this is all in python...
+        actual_result = tuple([f.eval(x) for x in src_data])
+        self.assertEqual(expected_result, actual_result)
+
+    def test_cc_2(self):
+        f = my_add2_cc()
+        src_data =        (0+1j, 2+3j, 4+5j, 6+7j)
+        expected_result = (2-1j, 4+1j, 6+3j, 8+5j)
+        # this is python -> C++ -> python and back again...
+        actual_result = tuple([gr.feval_cc_example(f, x) for x in src_data])
+        self.assertEqual(expected_result, actual_result)
+        
+
+if __name__ == '__main__':
+    gr_unittest.main ()
diff --git a/gnuradio-core/src/python/gnuradio/gr/qa_fft_filter.py b/gnuradio-core/src/python/gnuradio/gr/qa_fft_filter.py
new file mode 100755 (executable)
index 0000000..cb2e76b
--- /dev/null
@@ -0,0 +1,268 @@
+#!/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 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.
+# 
+
+from gnuradio import gr, gr_unittest
+import sys
+import random
+
+def make_random_complex_tuple(L):
+    result = []
+    for x in range(L):
+        result.append(complex(random.uniform(-1000,1000),
+                              random.uniform(-1000,1000)))
+    return tuple(result)
+
+def make_random_float_tuple(L):
+    result = []
+    for x in range(L):
+        result.append(float(int(random.uniform(-1000,1000))))
+    return tuple(result)
+
+
+def reference_filter_ccc(dec, taps, input):
+    """
+    compute result using conventional fir filter
+    """
+    fg = gr.flow_graph()
+    #src = gr.vector_source_c(((0,) * (len(taps) - 1)) + input)
+    src = gr.vector_source_c(input)
+    op = gr.fir_filter_ccc(dec, taps)
+    dst = gr.vector_sink_c()
+    fg.connect(src, op, dst)
+    fg.run()
+    return dst.data()
+
+def reference_filter_fff(dec, taps, input):
+    """
+    compute result using conventional fir filter
+    """
+    fg = gr.flow_graph()
+    #src = gr.vector_source_f(((0,) * (len(taps) - 1)) + input)
+    src = gr.vector_source_f(input)
+    op = gr.fir_filter_fff(dec, taps)
+    dst = gr.vector_sink_f()
+    fg.connect(src, op, dst)
+    fg.run()
+    return dst.data()
+
+
+def print_complex(x):
+    for i in x:
+        i = complex(i)
+        sys.stdout.write("(%6.3f,%6.3fj), " % (i.real, i.imag))
+    sys.stdout.write('\n')
+
+
+class test_fft_filter(gr_unittest.TestCase):
+
+    def setUp(self):
+        self.fg = gr.flow_graph ()
+
+    def tearDown(self):
+        self.fg = None
+
+    def assert_fft_ok2(self, expected_result, result_data):
+        expected_result = expected_result[:len(result_data)]
+        self.assertComplexTuplesAlmostEqual2 (expected_result, result_data,
+                                              abs_eps=1e-9, rel_eps=4e-4)
+
+    def assert_fft_float_ok2(self, expected_result, result_data, abs_eps=1e-9, rel_eps=4e-4):
+        expected_result = expected_result[:len(result_data)]
+        self.assertFloatTuplesAlmostEqual2 (expected_result, result_data,
+                                            abs_eps, rel_eps)
+
+    #def test_ccc_000(self):
+    #    self.assertRaises (RuntimeError, gr.fft_filter_ccc, 2, (1,))
+
+    def test_ccc_001(self):
+        src_data = (0,1,2,3,4,5,6,7)
+        taps = (1,)
+        expected_result = tuple([complex(x) for x in (0,1,2,3,4,5,6,7)])
+        src = gr.vector_source_c(src_data)
+        op = gr.fft_filter_ccc(1, taps)
+        dst = gr.vector_sink_c()
+        self.fg.connect(src, op, dst)
+        self.fg.run()
+        result_data = dst.data()
+        #print 'expected:', expected_result
+        #print 'results: ', result_data
+        self.assertComplexTuplesAlmostEqual (expected_result, result_data, 5)
+        
+
+    def test_ccc_002(self):
+        src_data = (0,1,2,3,4,5,6,7)
+        taps = (2,)
+        expected_result = tuple([2 * complex(x) for x in (0,1,2,3,4,5,6,7)])
+        src = gr.vector_source_c(src_data)
+        op = gr.fft_filter_ccc(1, taps)
+        dst = gr.vector_sink_c()
+        self.fg.connect(src, op, dst)
+        self.fg.run()
+        result_data = dst.data()
+        #print 'expected:', expected_result
+        #print 'results: ', result_data
+        self.assertComplexTuplesAlmostEqual (expected_result, result_data, 5)
+        
+    def test_ccc_004(self):
+        random.seed(0)
+        for i in xrange(25):
+            # sys.stderr.write("\n>>> Loop = %d\n" % (i,))
+            src_len = 4*1024
+            src_data = make_random_complex_tuple(src_len)
+            ntaps = int(random.uniform(2, 1000))
+            taps = make_random_complex_tuple(ntaps)
+            expected_result = reference_filter_ccc(1, taps, src_data)
+
+            src = gr.vector_source_c(src_data)
+            op = gr.fft_filter_ccc(1, taps)
+            dst = gr.vector_sink_c()
+            self.fg.connect(src, op, dst)
+            self.fg.run()
+            result_data = dst.data()
+
+            self.assert_fft_ok2(expected_result, result_data)
+
+    def test_ccc_005(self):
+        random.seed(0)
+        for i in xrange(25):
+            # sys.stderr.write("\n>>> Loop = %d\n" % (i,))
+            dec = i + 1
+            src_len = 4*1024
+            src_data = make_random_complex_tuple(src_len)
+            ntaps = int(random.uniform(2, 100))
+            taps = make_random_complex_tuple(ntaps)
+            expected_result = reference_filter_ccc(dec, taps, src_data)
+
+            src = gr.vector_source_c(src_data)
+            op = gr.fft_filter_ccc(dec, taps)
+            dst = gr.vector_sink_c()
+            self.fg.connect(src, op, dst)
+            self.fg.run()
+            result_data = dst.data()
+
+            self.assert_fft_ok2(expected_result, result_data)
+
+    # ----------------------------------------------------------------
+    # test _fff version
+    # ----------------------------------------------------------------
+
+    def test_fff_001(self):
+        src_data = (0,1,2,3,4,5,6,7)
+        taps = (1,)
+        expected_result = tuple([float(x) for x in (0,1,2,3,4,5,6,7)])
+        src = gr.vector_source_f(src_data)
+        op = gr.fft_filter_fff(1, taps)
+        dst = gr.vector_sink_f()
+        self.fg.connect(src, op, dst)
+        self.fg.run()
+        result_data = dst.data()
+        #print 'expected:', expected_result
+        #print 'results: ', result_data
+        self.assertFloatTuplesAlmostEqual (expected_result, result_data, 5)
+        
+
+    def test_fff_002(self):
+        src_data = (0,1,2,3,4,5,6,7)
+        taps = (2,)
+        expected_result = tuple([2 * float(x) for x in (0,1,2,3,4,5,6,7)])
+        src = gr.vector_source_f(src_data)
+        op = gr.fft_filter_fff(1, taps)
+        dst = gr.vector_sink_f()
+        self.fg.connect(src, op, dst)
+        self.fg.run()
+        result_data = dst.data()
+        #print 'expected:', expected_result
+        #print 'results: ', result_data
+        self.assertFloatTuplesAlmostEqual (expected_result, result_data, 5)
+        
+    def xtest_fff_003(self):
+        random.seed(0)
+        for i in xrange(25):
+            sys.stderr.write("\n>>> Loop = %d\n" % (i,))
+            src_len = 4096
+            src_data = make_random_float_tuple(src_len)
+            ntaps = int(random.uniform(2, 1000))
+            taps = make_random_float_tuple(ntaps)
+            expected_result = reference_filter_fff(1, taps, src_data)
+
+            src = gr.vector_source_f(src_data)
+            op = gr.fft_filter_fff(1, taps)
+            dst = gr.vector_sink_f()
+            self.fg.connect(src, op, dst)
+            self.fg.run()
+            result_data = dst.data()
+
+            #print "src_len =", src_len, " ntaps =", ntaps
+            try:
+                self.assert_fft_float_ok2(expected_result, result_data, abs_eps=1.0)
+            except:
+                expected = open('expected', 'w')
+                for x in expected_result:
+                    expected.write(`x` + '\n')
+                actual = open('actual', 'w')
+                for x in result_data:
+                    actual.write(`x` + '\n')
+                raise
+
+    def xtest_fff_004(self):
+        random.seed(0)
+        for i in xrange(25):
+            sys.stderr.write("\n>>> Loop = %d\n" % (i,))
+            src_len = 4*1024
+            src_data = make_random_float_tuple(src_len)
+            ntaps = int(random.uniform(2, 1000))
+            taps = make_random_float_tuple(ntaps)
+            expected_result = reference_filter_fff(1, taps, src_data)
+
+            src = gr.vector_source_f(src_data)
+            op = gr.fft_filter_fff(1, taps)
+            dst = gr.vector_sink_f()
+            self.fg.connect(src, op, dst)
+            self.fg.run()
+            result_data = dst.data()
+
+            self.assert_fft_float_ok2(expected_result, result_data, abs_eps=2.0)
+
+    def xtest_fff_005(self):
+        random.seed(0)
+        for i in xrange(25):
+            sys.stderr.write("\n>>> Loop = %d\n" % (i,))
+            dec = i + 1
+            src_len = 4*1024
+            src_data = make_random_float_tuple(src_len)
+            ntaps = int(random.uniform(2, 100))
+            taps = make_random_float_tuple(ntaps)
+            expected_result = reference_filter_fff(dec, taps, src_data)
+
+            src = gr.vector_source_f(src_data)
+            op = gr.fft_filter_fff(dec, taps)
+            dst = gr.vector_sink_f()
+            self.fg.connect(src, op, dst)
+            self.fg.run()
+            result_data = dst.data()
+
+            self.assert_fft_float_ok2(expected_result, result_data)
+
+
+if __name__ == '__main__':
+    gr_unittest.main ()
+        
diff --git a/gnuradio-core/src/python/gnuradio/gr/qa_filter_delay_fc.py b/gnuradio-core/src/python/gnuradio/gr/qa_filter_delay_fc.py
new file mode 100755 (executable)
index 0000000..191552c
--- /dev/null
@@ -0,0 +1,317 @@
+#!/usr/bin/env 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.
+# 
+
+from gnuradio import gr, gr_unittest
+import math
+
+class qa_filter_delay_fc (gr_unittest.TestCase):
+
+    def setUp (self):
+        self.fg = gr.flow_graph ()
+
+    def tearDown (self):
+        self.fg = None
+
+    def test_001_filter_delay_one_input (self):
+
+        # expected result
+        expected_result = (                             -1.4678005338941702e-11j, 
+                                                        -0.0011950774351134896j, 
+                                                        -0.0019336787518113852j, 
+                                                        -0.0034673355985432863j, 
+                                                        -0.0036765895783901215j, 
+                                                        -0.004916108213365078j, 
+                                                        -0.0042778430506587029j, 
+                                                        -0.006028641015291214j, 
+                                                        -0.005476709920912981j, 
+                                                        -0.0092810001224279404j, 
+                                                        -0.0095402700826525688j, 
+                                                        -0.016060983762145042j, 
+                                                        -0.016446959227323532j, 
+                                                        -0.02523401565849781j, 
+                                                        -0.024382550269365311j, 
+                                                        -0.035477779805660248j, 
+                                                        -0.033021725714206696j, 
+                                                        -0.048487484455108643j, 
+                                                        -0.04543270543217659j, 
+                                                        -0.069477587938308716j, 
+                                                        -0.066984444856643677j, 
+                                                        -0.10703597217798233j, 
+                                                        -0.10620346665382385j, 
+                                                        -0.1852707713842392j, 
+                                                        -0.19357112050056458j, 
+                            (7.2191945754696007e-09     -0.50004088878631592j), 
+                            (0.58778399229049683        -0.6155126690864563j), 
+                            (0.95105588436126709        -0.12377222627401352j), 
+                            (0.95105588436126709        +0.41524654626846313j), 
+                            (0.5877838134765625         +0.91611981391906738j), 
+                            (5.8516356205018383e-09     +1.0670661926269531j), 
+                            (-0.5877840518951416        +0.87856143712997437j), 
+                            (-0.95105588436126709       +0.35447561740875244j), 
+                            (-0.95105588436126709       -0.26055556535720825j), 
+                            (-0.5877838134765625        -0.77606213092803955j), 
+                            (-8.7774534307527574e-09    -0.96460390090942383j), 
+                            (0.58778399229049683        -0.78470128774642944j), 
+                            (0.95105588436126709        -0.28380891680717468j), 
+                            (0.95105588436126709        +0.32548999786376953j), 
+                            (0.5877838134765625         +0.82514488697052002j), 
+                            (1.4629089051254596e-08     +1.0096219778060913j), 
+                            (-0.5877840518951416        +0.81836479902267456j), 
+                            (-0.95105588436126709       +0.31451958417892456j), 
+                            (-0.95105588436126709       -0.3030143678188324j), 
+                            (-0.5877838134765625        -0.80480599403381348j), 
+                            (-1.7554906861505515e-08    -0.99516552686691284j), 
+                            (0.58778399229049683        -0.80540722608566284j), 
+                            (0.95105582475662231        -0.30557557940483093j), 
+                            (0.95105588436126709        +0.31097668409347534j), 
+                            (0.5877838134765625         +0.81027895212173462j), 
+                            (2.3406542482007353e-08     +1.0000816583633423j), 
+                            (-0.5877840518951416        +0.80908381938934326j), 
+                            (-0.95105588436126709       +0.30904293060302734j), 
+                            (-0.95105588436126709       -0.30904296040534973j), 
+                            (-0.5877838134765625        -0.80908387899398804j), 
+                            (-2.6332360292258272e-08    -1.0000815391540527j), 
+                            (0.58778399229049683        -0.80908381938934326j), 
+                            (0.95105582475662231        -0.30904299020767212j), 
+                            (0.95105588436126709        +0.30904293060302734j), 
+                            (0.5877838134765625         +0.80908381938934326j), 
+                            (3.218399768911695e-08      +1.0000815391540527j))            
+            
+        fg = self.fg
+
+        sampling_freq = 100
+
+        ntaps = 51
+        src1 = gr.sig_source_f (sampling_freq, gr.GR_SIN_WAVE,
+                               sampling_freq * 0.10, 1.0)
+        head = gr.head (gr.sizeof_float, int (ntaps + sampling_freq * 0.10))
+        dst2 = gr.vector_sink_c ()
+
+        # calculate taps
+        taps = gr.firdes_hilbert (ntaps)
+        hd = gr.filter_delay_fc (taps)
+
+        fg.connect (src1, head)
+        fg.connect (head, hd)
+        fg.connect (hd,dst2)
+        
+        fg.run ()
+
+        # get output
+        result_data = dst2.data ()
+        self.assertComplexTuplesAlmostEqual (expected_result, result_data, 5)
+
+    def test_002_filter_delay_two_inputs (self):
+
+        # giving the same signal to both the inputs should fetch the same results
+        # as above
+
+        # expected result
+        expected_result = (                             -1.4678005338941702e-11j, 
+                                                        -0.0011950774351134896j, 
+                                                        -0.0019336787518113852j, 
+                                                        -0.0034673355985432863j, 
+                                                        -0.0036765895783901215j, 
+                                                        -0.004916108213365078j, 
+                                                        -0.0042778430506587029j, 
+                                                        -0.006028641015291214j, 
+                                                        -0.005476709920912981j, 
+                                                        -0.0092810001224279404j, 
+                                                        -0.0095402700826525688j, 
+                                                        -0.016060983762145042j, 
+                                                        -0.016446959227323532j, 
+                                                        -0.02523401565849781j, 
+                                                        -0.024382550269365311j, 
+                                                        -0.035477779805660248j, 
+                                                        -0.033021725714206696j, 
+                                                        -0.048487484455108643j, 
+                                                        -0.04543270543217659j, 
+                                                        -0.069477587938308716j, 
+                                                        -0.066984444856643677j, 
+                                                        -0.10703597217798233j, 
+                                                        -0.10620346665382385j, 
+                                                        -0.1852707713842392j, 
+                                                        -0.19357112050056458j, 
+                            (7.2191945754696007e-09     -0.50004088878631592j), 
+                            (0.58778399229049683        -0.6155126690864563j), 
+                            (0.95105588436126709        -0.12377222627401352j), 
+                            (0.95105588436126709        +0.41524654626846313j), 
+                            (0.5877838134765625         +0.91611981391906738j), 
+                            (5.8516356205018383e-09     +1.0670661926269531j), 
+                            (-0.5877840518951416        +0.87856143712997437j), 
+                            (-0.95105588436126709       +0.35447561740875244j), 
+                            (-0.95105588436126709       -0.26055556535720825j), 
+                            (-0.5877838134765625        -0.77606213092803955j), 
+                            (-8.7774534307527574e-09    -0.96460390090942383j), 
+                            (0.58778399229049683        -0.78470128774642944j), 
+                            (0.95105588436126709        -0.28380891680717468j), 
+                            (0.95105588436126709        +0.32548999786376953j), 
+                            (0.5877838134765625         +0.82514488697052002j), 
+                            (1.4629089051254596e-08     +1.0096219778060913j), 
+                            (-0.5877840518951416        +0.81836479902267456j), 
+                            (-0.95105588436126709       +0.31451958417892456j), 
+                            (-0.95105588436126709       -0.3030143678188324j), 
+                            (-0.5877838134765625        -0.80480599403381348j), 
+                            (-1.7554906861505515e-08    -0.99516552686691284j), 
+                            (0.58778399229049683        -0.80540722608566284j), 
+                            (0.95105582475662231        -0.30557557940483093j), 
+                            (0.95105588436126709        +0.31097668409347534j), 
+                            (0.5877838134765625         +0.81027895212173462j), 
+                            (2.3406542482007353e-08     +1.0000816583633423j), 
+                            (-0.5877840518951416        +0.80908381938934326j), 
+                            (-0.95105588436126709       +0.30904293060302734j), 
+                            (-0.95105588436126709       -0.30904296040534973j), 
+                            (-0.5877838134765625        -0.80908387899398804j), 
+                            (-2.6332360292258272e-08    -1.0000815391540527j), 
+                            (0.58778399229049683        -0.80908381938934326j), 
+                            (0.95105582475662231        -0.30904299020767212j), 
+                            (0.95105588436126709        +0.30904293060302734j), 
+                            (0.5877838134765625         +0.80908381938934326j), 
+                            (3.218399768911695e-08      +1.0000815391540527j)) 
+
+        
+        fg = self.fg
+
+        sampling_freq = 100
+        ntaps = 51
+        src1 = gr.sig_source_f (sampling_freq, gr.GR_SIN_WAVE,
+                               sampling_freq * 0.10, 1.0)
+        head = gr.head (gr.sizeof_float, int (ntaps + sampling_freq * 0.10))
+        dst2 = gr.vector_sink_c ()
+
+
+        # calculate taps
+        taps = gr.firdes_hilbert (ntaps)
+        hd = gr.filter_delay_fc (taps)
+
+        fg.connect (src1, head)
+        fg.connect (head, (hd,0))
+        fg.connect (head, (hd,1))
+        fg.connect (hd,dst2)
+        fg.run ()
+
+        # get output
+        result_data = dst2.data ()
+
+        self.assertComplexTuplesAlmostEqual (expected_result, result_data, 5)
+
+
+    def test_003_filter_delay_two_inputs (self):
+
+        # give two different inputs
+
+        # expected result
+        expected_result =         (                          -0.0020331963896751404j, 
+                                                             -0.0016448829555884004j, 
+                                                             -0.0032375147566199303j, 
+                                                             -0.0014826074475422502j, 
+                                                             -0.0033034090884029865j, 
+                                                             -0.00051144487224519253j, 
+                                                             -0.0043686260469257832j, 
+                                                             -0.0010198024101555347j, 
+                                                             -0.0082517862319946289j, 
+                                                             -0.003456643782556057j, 
+                                                             -0.014193611219525337j, 
+                                                             -0.005875137634575367j, 
+                                                             -0.020293503999710083j, 
+                                                             -0.0067503536120057106j, 
+                                                             -0.026798896491527557j, 
+                                                             -0.0073488112539052963j, 
+                                                             -0.037041611969470978j, 
+                                                             -0.010557252913713455j, 
+                                                             -0.055669989436864853j, 
+                                                             -0.018332764506340027j, 
+                                                             -0.089904911816120148j, 
+                                                             -0.033361352980136871j, 
+                                                             -0.16902604699134827j, 
+                                                             -0.074318811297416687j, 
+                                                             -0.58429563045501709j, 
+                                    (7.2191945754696007e-09  -0.35892376303672791j), 
+                                    (0.58778399229049683     +0.63660913705825806j), 
+                                    (0.95105588436126709     +0.87681591510772705j), 
+                                    (0.95105588436126709     +0.98705857992172241j), 
+                                    (0.5877838134765625      +0.55447429418563843j), 
+                                    (5.8516356205018383e-09  +0.026006083935499191j), 
+                                    (-0.5877840518951416     -0.60616838932037354j), 
+                                    (-0.95105588436126709    -0.9311758279800415j), 
+                                    (-0.95105588436126709    -0.96169203519821167j), 
+                                    (-0.5877838134765625     -0.57292771339416504j), 
+                                    (-8.7774534307527574e-09 -0.0073488391935825348j), 
+                                    (0.58778399229049683     +0.59720659255981445j), 
+                                    (0.95105588436126709     +0.94438445568084717j), 
+                                    (0.95105588436126709     +0.95582199096679688j), 
+                                    (0.5877838134765625      +0.58196049928665161j), 
+                                    (1.4629089051254596e-08  +0.0026587247848510742j), 
+                                    (-0.5877840518951416     -0.59129220247268677j), 
+                                    (-0.95105588436126709    -0.94841635227203369j), 
+                                    (-0.95105588436126709    -0.95215457677841187j), 
+                                    (-0.5877838134765625     -0.58535969257354736j), 
+                                    (-1.7554906861505515e-08 -0.00051158666610717773j), 
+                                    (0.58778399229049683     +0.58867418766021729j), 
+                                    (0.95105582475662231     +0.94965213537216187j), 
+                                    (0.95105588436126709     +0.95050644874572754j), 
+                                    (0.5877838134765625      +0.58619076013565063j), 
+                                    (2.3406542482007353e-08  +1.1920928955078125e-07j), 
+                                    (-0.5877840518951416     -0.58783555030822754j), 
+                                    (-0.95105588436126709    -0.95113480091094971j), 
+                                    (-0.95105588436126709    -0.95113474130630493j), 
+                                    (-0.5877838134765625     -0.58783555030822754j), 
+                                    (-2.6332360292258272e-08 -8.1956386566162109e-08j), 
+                                    (0.58778399229049683     +0.58783555030822754j), 
+                                    (0.95105582475662231     +0.95113474130630493j), 
+                                    (0.95105588436126709     +0.95113474130630493j), 
+                                    (0.5877838134765625      +0.58783560991287231j), 
+                                    (3.218399768911695e-08   +1.1920928955078125e-07j))
+
+        fg = self.fg
+
+        sampling_freq = 100
+        ntaps = 51
+        
+        src1 = gr.sig_source_f (sampling_freq, gr.GR_SIN_WAVE,sampling_freq * 0.10, 1.0)
+        src2 = gr.sig_source_f (sampling_freq, gr.GR_COS_WAVE,sampling_freq * 0.10, 1.0)
+        
+        head1 = gr.head (gr.sizeof_float, int (ntaps + sampling_freq * 0.10))
+        head2 = gr.head (gr.sizeof_float, int (ntaps + sampling_freq * 0.10))
+
+        taps = gr.firdes_hilbert (ntaps)
+        hd = gr.filter_delay_fc (taps)
+
+        dst2 = gr.vector_sink_c ()
+
+        fg.connect (src1, head1)
+        fg.connect (src2, head2)
+        
+        fg.connect (head1, (hd,0))
+        fg.connect (head2, (hd,1))
+        fg.connect (hd, dst2)
+
+        fg.run ()
+
+        # get output
+        result_data = dst2.data ()
+
+        self.assertComplexTuplesAlmostEqual (expected_result, result_data, 5)
+
+        
+if __name__ == '__main__':
+    gr_unittest.main ()
diff --git a/gnuradio-core/src/python/gnuradio/gr/qa_flow_graph.py b/gnuradio-core/src/python/gnuradio/gr/qa_flow_graph.py
new file mode 100755 (executable)
index 0000000..455cc13
--- /dev/null
@@ -0,0 +1,356 @@
+#!/usr/bin/env 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.
+# 
+
+from gnuradio import gr, gr_unittest
+import qa_basic_flow_graph
+
+
+def all_counts ():
+    return (gr.block_ncurrently_allocated (),
+            gr.block_detail_ncurrently_allocated (),
+            gr.buffer_ncurrently_allocated (),
+            gr.buffer_reader_ncurrently_allocated ())
+
+
+class wrap_add(gr.hier_block):
+    def __init__(self, fg, a):
+        add = gr.add_const_ii (a)
+        gr.hier_block.__init__ (self, fg, add, add)
+
+class mult_add(gr.hier_block):
+    def __init__(self, fg, m, a):
+        mult = gr.multiply_const_ii (m)
+        add = gr.add_const_ii (a)
+        fg.connect (mult, add)
+        gr.hier_block.__init__ (self, fg, mult, add)
+
+
+class test_flow_graph (qa_basic_flow_graph.test_basic_flow_graph):
+
+    def setUp (self):
+        ''' override qa_basic_flow_graph setUp in order to use our class'''
+        self.fg = gr.flow_graph ()
+
+    def tearDown (self):
+        qa_basic_flow_graph.test_basic_flow_graph.tearDown (self)
+
+
+    # we inherit all their tests, so we can be sure we don't break
+    # any of the underlying code
+
+
+    def leak_check (self, fct):
+        begin = all_counts ()
+        fct ()
+        # tear down early so we can check for leaks
+        self.tearDown ()
+        end = all_counts ()
+        self.assertEqual (begin, end)
+
+    def test_100_tsort_null (self):
+        self.assertEqual ([], self.fg.topological_sort (self.fg.all_blocks ()))
+
+    def test_101_tsort_two (self):
+        fg = self.fg
+        src1 = gr.null_source (gr.sizeof_int)
+        dst1 = gr.null_sink (gr.sizeof_int)
+        fg.connect ((src1, 0), (dst1, 0))
+        fg.validate ()
+        self.assertEqual ([src1, dst1], fg.topological_sort (fg.all_blocks ()))
+        
+    def test_102_tsort_three_a (self):
+        fg = self.fg
+        src1 = gr.null_source (gr.sizeof_int)
+        nop1 = gr.nop (gr.sizeof_int)
+        dst1 = gr.null_sink (gr.sizeof_int)
+        fg.connect (src1, nop1)
+        fg.connect (nop1, dst1)
+        fg.validate ()
+        self.assertEqual ([src1, nop1, dst1], fg.topological_sort (fg.all_blocks ()))
+        
+    def test_103_tsort_three_b (self):
+        fg = self.fg
+        src1 = gr.null_source (gr.sizeof_int)
+        nop1 = gr.nop (gr.sizeof_int)
+        dst1 = gr.null_sink (gr.sizeof_int)
+        fg.connect (nop1, dst1)
+        fg.connect (src1, nop1)
+        fg.validate ()
+        self.assertEqual ([src1, nop1, dst1], fg.topological_sort (fg.all_blocks ()))
+        
+    def test_104_trivial_dag_check (self):
+        fg = self.fg
+        nop1 = gr.nop (gr.sizeof_int)
+        fg.connect (nop1, nop1)
+        fg.validate ()
+        self.assertRaises (gr.NotDAG,
+                           lambda : fg.topological_sort (fg.all_blocks ()))
+
+    def test_105 (self):
+        fg = self.fg
+        src1 = gr.null_source (gr.sizeof_int)
+        src2 = gr.null_source (gr.sizeof_int)
+        nop1 = gr.nop (gr.sizeof_int)
+        nop2 = gr.nop (gr.sizeof_int)
+        nop3 = gr.nop (gr.sizeof_int)
+        dst1 = gr.null_sink (gr.sizeof_int)
+        
+        fg.connect (src1, nop1)
+        fg.connect (src2, nop2)
+        fg.connect (nop1, (nop3, 0))
+        fg.connect (nop2, (nop3, 1))
+        fg.connect (nop3, dst1)
+        fg.validate ()
+        ts = fg.topological_sort (fg.all_blocks ())
+        self.assertEqual ([src2, nop2, src1, nop1, nop3, dst1], ts)
+                     
+
+    def test_106 (self):
+        fg = self.fg
+        src1 = gr.null_source (gr.sizeof_int)
+        src2 = gr.null_source (gr.sizeof_int)
+        nop1 = gr.nop (gr.sizeof_int)
+        nop2 = gr.nop (gr.sizeof_int)
+        nop3 = gr.nop (gr.sizeof_int)
+        dst1 = gr.null_sink (gr.sizeof_int)
+        
+        fg.connect (nop3, dst1)
+        fg.connect (nop2, (nop3, 1))
+        fg.connect (nop1, (nop3, 0))
+        fg.connect (src2, nop2)
+        fg.connect (src1, nop1)
+        fg.validate ()
+        ts = fg.topological_sort (fg.all_blocks ())
+        self.assertEqual ([src2, nop2, src1, nop1, nop3, dst1], ts)
+
+    def test_107 (self):
+        fg = self.fg
+        src1 = gr.null_source (gr.sizeof_int)
+        src2 = gr.null_source (gr.sizeof_int)
+        nop1 = gr.nop (gr.sizeof_int)
+        nop2 = gr.nop (gr.sizeof_int)
+        dst1 = gr.null_sink (gr.sizeof_int)
+        dst2 = gr.null_sink (gr.sizeof_int)
+        
+        fg.connect (src1, nop1)
+        fg.connect (nop1, dst1)
+        fg.connect (src2, nop2)
+        fg.connect (nop2, dst2)
+        fg.validate ()
+        ts = fg.topological_sort (fg.all_blocks ())
+        self.assertEqual ([src2, nop2, dst2, src1, nop1, dst1], ts)
+
+    def test_108 (self):
+        self.leak_check (self.body_108)
+        
+    def body_108 (self):
+        fg = self.fg
+        src1 = gr.null_source (gr.sizeof_int)
+        src2 = gr.null_source (gr.sizeof_int)
+        nop1 = gr.nop (gr.sizeof_int)
+        nop2 = gr.nop (gr.sizeof_int)
+        dst1 = gr.null_sink (gr.sizeof_int)
+        dst2 = gr.null_sink (gr.sizeof_int)
+        
+        fg.connect (nop2, dst2)
+        fg.connect (src1, nop1)
+        fg.connect (src2, nop2)
+        fg.connect (nop1, dst1)
+        fg.validate ()
+        ts = fg.topological_sort (fg.all_blocks ())
+        self.assertEqual ([src2, nop2, dst2, src1, nop1, dst1], ts)
+        self.assertEqual ((6,0,0,0), all_counts ())
+
+    def test_109__setup_connections (self):
+        self.leak_check (self.body_109)
+
+    def body_109 (self):
+        fg = self.fg
+        src1 = gr.null_source (gr.sizeof_int)
+        dst1 = gr.null_sink (gr.sizeof_int)
+        fg.connect (src1, dst1)
+        fg._setup_connections ()
+        self.assertEqual ((2,2,1,1), all_counts ())
+
+    def test_110_scheduler (self):
+        self.leak_check (self.body_110)
+
+    def body_110 (self):
+        fg = self.fg
+        src_data = (0, 1, 2, 3)
+        src1 = gr.vector_source_i (src_data)
+        dst1 = gr.vector_sink_i ()
+        fg.connect ((src1, 0), (dst1, 0))
+        fg.run ()
+        dst_data = dst1.data ()
+        self.assertEqual (src_data, dst_data)
+
+    def test_111_scheduler (self):
+        self.leak_check (self.body_111)
+
+    def body_111 (self):
+        fg = self.fg
+        src_data = (0, 1, 2, 3)
+        expected_result = (2, 3, 4, 5)
+        src1 = gr.vector_source_i (src_data)
+        op = gr.add_const_ii (2)
+        dst1 = gr.vector_sink_i ()
+        fg.connect (src1, op)
+        fg.connect (op, dst1)
+        fg.run ()
+        dst_data = dst1.data ()
+        self.assertEqual (expected_result, dst_data)
+        
+    def test_111v_scheduler (self):
+        self.leak_check (self.body_111v)
+
+    def body_111v (self):
+        fg = self.fg
+        src_data = (0, 1, 2, 3)
+        expected_result = (2, 3, 4, 5)
+        src1 = gr.vector_source_i (src_data)
+        op = gr.add_const_ii (2)
+        dst1 = gr.vector_sink_i ()
+        fg.connect (src1, op, dst1)
+        fg.run ()
+        dst_data = dst1.data ()
+        self.assertEqual (expected_result, dst_data)
+        
+    def test_112 (self):
+        fg = self.fg
+        nop1 = gr.nop (gr.sizeof_int)
+        nop2 = gr.nop (gr.sizeof_int)
+        nop3 = gr.nop (gr.sizeof_int)
+        fg.connect ((nop1, 0), (nop2, 0))
+        fg.connect ((nop1, 1), (nop3, 0))
+        fg._setup_connections ()
+        self.assertEqual (2, nop1.detail().noutputs())
+
+    def test_113 (self):
+        fg = self.fg
+        nop1 = gr.nop (gr.sizeof_int)
+        nop2 = gr.nop (gr.sizeof_int)
+        nop3 = gr.nop (gr.sizeof_int)
+        fg.connect ((nop1, 0), (nop2, 0))
+        fg.connect ((nop1, 0), (nop3, 0))
+        fg._setup_connections ()
+        self.assertEqual (1, nop1.detail().noutputs())
+
+    def test_200_partition (self):
+        self.leak_check (self.body_200)
+
+    def body_200 (self):
+        fg = self.fg
+        src1 = gr.null_source (gr.sizeof_int)
+        nop1 = gr.nop (gr.sizeof_int)
+        dst1 = gr.null_sink (gr.sizeof_int)
+        fg.connect (nop1, dst1)
+        fg.connect (src1, nop1)
+        fg.validate ()
+        p = fg.partition_graph (fg.all_blocks ())
+        self.assertEqual ([[src1, nop1, dst1]], p)
+        self.assertEqual ((3,0,0,0), all_counts ())
+        
+    def test_201_partition (self):
+        self.leak_check (self.body_201)
+
+    def body_201 (self):
+        fg = self.fg
+        src1 = gr.null_source (gr.sizeof_int)
+        src2 = gr.null_source (gr.sizeof_int)
+        nop1 = gr.nop (gr.sizeof_int)
+        nop2 = gr.nop (gr.sizeof_int)
+        dst1 = gr.null_sink (gr.sizeof_int)
+        dst2 = gr.null_sink (gr.sizeof_int)
+        
+        fg.connect (nop2, dst2)
+        fg.connect (src1, nop1)
+        fg.connect (src2, nop2)
+        fg.connect (nop1, dst1)
+        fg.validate ()
+        p = fg.partition_graph (fg.all_blocks ())
+        self.assertEqual ([[src2, nop2, dst2], [src1, nop1, dst1]], p)
+        self.assertEqual ((6,0,0,0), all_counts ())
+        
+    def test_300_hier (self):
+        self.leak_check (self.body_300_hier)
+
+    def body_300_hier (self):
+        fg = self.fg
+        src_data = (0, 1, 2, 3)
+        expected_result = (10, 11, 12, 13)
+        src1 = gr.vector_source_i (src_data)
+        op = wrap_add (fg, 10)
+        dst1 = gr.vector_sink_i ()
+        fg.connect (src1, op, dst1)
+        fg.run ()
+        dst_data = dst1.data ()
+        self.assertEqual (expected_result, dst_data)
+        
+    def test_301_hier (self):
+        self.leak_check (self.body_301_hier)
+
+    def body_301_hier (self):
+        fg = self.fg
+        src_data = (0, 1, 2, 3)
+        expected_result = (5, 8, 11, 14)
+        src1 = gr.vector_source_i (src_data)
+        op = mult_add (fg, 3, 5)
+        dst1 = gr.vector_sink_i ()
+        fg.connect (src1, op, dst1)
+        fg.run ()
+        dst_data = dst1.data ()
+        self.assertEqual (expected_result, dst_data)
+        
+    def test_302_hier (self):
+        self.leak_check (self.body_302_hier)
+
+    def body_302_hier (self):
+        fg = self.fg
+        src_data = (0, 1, 2, 3)
+        expected_result = (10, 11, 12, 13)
+        src1 = gr.vector_source_i (src_data)
+        op = gr.compose (fg, gr.add_const_ii (10))
+        dst1 = gr.vector_sink_i ()
+        fg.connect (src1, op, dst1)
+        fg.run ()
+        dst_data = dst1.data ()
+        self.assertEqual (expected_result, dst_data)
+
+    def test_303_hier (self):
+        self.leak_check (self.body_303_hier)
+
+    def body_303_hier (self):
+        fg = self.fg
+        src_data = (0, 1, 2, 3)
+        expected_result = (35, 38, 41, 44)
+        src1 = gr.vector_source_i (src_data)
+        op = gr.compose (fg, gr.add_const_ii (10), mult_add (fg, 3, 5))
+        dst1 = gr.vector_sink_i ()
+        fg.connect (src1, op, dst1)
+        fg.run ()
+        dst_data = dst1.data ()
+        self.assertEqual (expected_result, dst_data)
+        
+
+if __name__ == '__main__':
+    gr_unittest.main ()
diff --git a/gnuradio-core/src/python/gnuradio/gr/qa_frequency_modulator.py b/gnuradio-core/src/python/gnuradio/gr/qa_frequency_modulator.py
new file mode 100755 (executable)
index 0000000..cfa3483
--- /dev/null
@@ -0,0 +1,56 @@
+#!/usr/bin/env 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.
+# 
+
+from gnuradio import gr, gr_unittest
+import math
+
+def sincos(x):
+    return  math.cos(x) + math.sin(x) * 1j
+
+
+class test_frequency_modulator (gr_unittest.TestCase):
+
+    def setUp (self):
+        self.fg = gr.flow_graph ()
+
+    def tearDown (self):
+        self.fg = None
+
+    def test_fm_001 (self):
+        pi = math.pi
+        sensitivity = pi/4
+        src_data = (1.0/4, 1.0/2, 1.0/4, -1.0/4, -1.0/2, -1/4.0)
+        running_sum = (pi/16, 3*pi/16, pi/4, 3*pi/16, pi/16, 0)
+        expected_result = tuple ([sincos (x) for x in running_sum])
+        src = gr.vector_source_f (src_data)
+        op = gr.frequency_modulator_fc (sensitivity)
+        dst = gr.vector_sink_c ()
+        self.fg.connect (src, op)
+        self.fg.connect (op, dst)
+        self.fg.run ()
+        result_data = dst.data ()
+        self.assertComplexTuplesAlmostEqual (expected_result, result_data)
+
+
+if __name__ == '__main__':
+    gr_unittest.main ()
+        
diff --git a/gnuradio-core/src/python/gnuradio/gr/qa_fsk_stuff.py b/gnuradio-core/src/python/gnuradio/gr/qa_fsk_stuff.py
new file mode 100755 (executable)
index 0000000..d61ddb1
--- /dev/null
@@ -0,0 +1,75 @@
+#!/usr/bin/env 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.
+# 
+
+from gnuradio import gr, gr_unittest
+import math
+
+def sincos(x):
+    return  math.cos(x) + math.sin(x) * 1j
+
+class test_bytes_to_syms (gr_unittest.TestCase):
+
+    def setUp (self):
+        self.fg = gr.flow_graph ()
+
+    def tearDown (self):
+        self.fg = None
+
+    def test_bytes_to_syms_001 (self):
+        src_data = (0x01, 0x80, 0x03)
+        expected_result = (-1, -1, -1, -1, -1, -1, -1, +1,
+                           +1, -1, -1, -1, -1, -1, -1, -1,
+                           -1, -1, -1, -1, -1, -1, +1, +1)
+        src = gr.vector_source_b (src_data)
+        op = gr.bytes_to_syms ()
+        dst = gr.vector_sink_f ()
+        self.fg.connect (src, op)
+        self.fg.connect (op, dst)
+        self.fg.run ()
+        result_data = dst.data ()
+        self.assertEqual (expected_result, result_data)
+
+    def test_simple_framer (self):
+        src_data = (0x00, 0x11, 0x22, 0x33, 
+                    0x44, 0x55, 0x66, 0x77,
+                    0x88, 0x99, 0xaa, 0xbb, 
+                    0xcc, 0xdd, 0xee, 0xff)
+
+        expected_result = (
+            0xac, 0xdd, 0xa4, 0xe2, 0xf2, 0x8c, 0x20, 0xfc, 0x00, 0x00, 0x11, 0x22, 0x33, 0x55,
+            0xac, 0xdd, 0xa4, 0xe2, 0xf2, 0x8c, 0x20, 0xfc, 0x01, 0x44, 0x55, 0x66, 0x77, 0x55,
+            0xac, 0xdd, 0xa4, 0xe2, 0xf2, 0x8c, 0x20, 0xfc, 0x02, 0x88, 0x99, 0xaa, 0xbb, 0x55,
+            0xac, 0xdd, 0xa4, 0xe2, 0xf2, 0x8c, 0x20, 0xfc, 0x03, 0xcc, 0xdd, 0xee, 0xff, 0x55)
+
+        src = gr.vector_source_b (src_data)
+        op = gr.simple_framer (4)
+        dst = gr.vector_sink_b ()
+        self.fg.connect (src, op)
+        self.fg.connect (op, dst)
+        self.fg.run ()
+        result_data = dst.data ()
+        self.assertEqual (expected_result, result_data)
+        
+
+if __name__ == '__main__':
+    gr_unittest.main ()
+        
diff --git a/gnuradio-core/src/python/gnuradio/gr/qa_goertzel.py b/gnuradio-core/src/python/gnuradio/gr/qa_goertzel.py
new file mode 100755 (executable)
index 0000000..da9d65f
--- /dev/null
@@ -0,0 +1,64 @@
+#!/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 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.
+# 
+
+from gnuradio import gr, gr_unittest
+from math import pi, cos
+
+class test_goertzel(gr_unittest.TestCase):
+
+    def setUp(self):
+        self.fg = gr.flow_graph()
+
+    def tearDown(self):
+        self.fg = None
+
+    def make_tone_data(self, rate, freq):
+        return [cos(2*pi*x*freq/rate) for x in range(rate)]
+
+    def transform(self, src_data, rate, freq):
+       src = gr.vector_source_f(src_data, False)
+        dft = gr.goertzel_fc(rate, rate, freq)
+       dst = gr.vector_sink_c()
+       self.fg.connect(src, dft, dst)
+       self.fg.run()
+       return dst.data()       
+
+    def test_001(self): # Measure single tone magnitude
+       rate = 8000
+       freq = 100
+       bin = freq
+       src_data = self.make_tone_data(rate, freq)
+       expected_result = 0.5
+       actual_result = abs(self.transform(src_data, rate, bin)[0])
+       self.assertAlmostEqual(expected_result, actual_result, places=5)
+
+    def test_002(self): # Measure off frequency magnitude
+       rate = 8000
+       freq = 100
+       bin = freq/2
+       src_data = self.make_tone_data(rate, freq)
+       expected_result = 0.0
+       actual_result = abs(self.transform(src_data, rate, bin)[0])
+       self.assertAlmostEqual(expected_result, actual_result, places=5)
+
+if __name__ == '__main__':
+    gr_unittest.main()
diff --git a/gnuradio-core/src/python/gnuradio/gr/qa_head.py b/gnuradio-core/src/python/gnuradio/gr/qa_head.py
new file mode 100755 (executable)
index 0000000..a6fcd7f
--- /dev/null
@@ -0,0 +1,47 @@
+#!/usr/bin/env 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.
+# 
+
+from gnuradio import gr, gr_unittest
+
+class test_head (gr_unittest.TestCase):
+
+    def setUp (self):
+        self.fg = gr.flow_graph ()
+
+    def tearDown (self):
+        self.fg = None
+
+    def test_head (self):
+        src_data = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
+        expected_result = (1, 2, 3, 4)
+        src1 = gr.vector_source_i (src_data)
+        op = gr.head (gr.sizeof_int, 4)
+        dst1 = gr.vector_sink_i ()
+        self.fg.connect (src1, op)
+        self.fg.connect (op, dst1)
+        self.fg.run ()
+        dst_data = dst1.data ()
+        self.assertEqual (expected_result, dst_data)
+    
+
+if __name__ == '__main__':
+    gr_unittest.main ()
diff --git a/gnuradio-core/src/python/gnuradio/gr/qa_hilbert.py b/gnuradio-core/src/python/gnuradio/gr/qa_hilbert.py
new file mode 100755 (executable)
index 0000000..a8f39dd
--- /dev/null
@@ -0,0 +1,116 @@
+#!/usr/bin/env 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.
+# 
+
+from gnuradio import gr, gr_unittest
+import math
+
+class test_sig_source (gr_unittest.TestCase):
+
+    def setUp (self):
+        self.fg = gr.flow_graph ()
+
+    def tearDown (self):
+        self.fg = None
+
+    def test_hilbert (self):
+        fg = self.fg
+        ntaps = 51
+        sampling_freq = 100
+
+        expected_result = (                             -1.4678005338941702e-11j, 
+                                                        -0.0011950774351134896j, 
+                                                        -0.0019336787518113852j, 
+                                                        -0.0034673355985432863j, 
+                                                        -0.0036765895783901215j, 
+                                                        -0.004916108213365078j, 
+                                                        -0.0042778430506587029j, 
+                                                        -0.006028641015291214j, 
+                                                        -0.005476709920912981j, 
+                                                        -0.0092810001224279404j, 
+                                                        -0.0095402700826525688j, 
+                                                        -0.016060983762145042j, 
+                                                        -0.016446959227323532j, 
+                                                        -0.02523401565849781j, 
+                                                        -0.024382550269365311j, 
+                                                        -0.035477779805660248j, 
+                                                        -0.033021725714206696j, 
+                                                        -0.048487484455108643j, 
+                                                        -0.04543270543217659j, 
+                                                        -0.069477587938308716j, 
+                                                        -0.066984444856643677j, 
+                                                        -0.10703597217798233j, 
+                                                        -0.10620346665382385j, 
+                                                        -0.1852707713842392j, 
+                                                        -0.19357112050056458j, 
+                            (7.2191945754696007e-09     -0.50004088878631592j), 
+                            (0.58778399229049683        -0.6155126690864563j), 
+                            (0.95105588436126709        -0.12377222627401352j), 
+                            (0.95105588436126709        +0.41524654626846313j), 
+                            (0.5877838134765625         +0.91611981391906738j), 
+                            (5.8516356205018383e-09     +1.0670661926269531j), 
+                            (-0.5877840518951416        +0.87856143712997437j), 
+                            (-0.95105588436126709       +0.35447561740875244j), 
+                            (-0.95105588436126709       -0.26055556535720825j), 
+                            (-0.5877838134765625        -0.77606213092803955j), 
+                            (-8.7774534307527574e-09    -0.96460390090942383j), 
+                            (0.58778399229049683        -0.78470128774642944j), 
+                            (0.95105588436126709        -0.28380891680717468j), 
+                            (0.95105588436126709        +0.32548999786376953j), 
+                            (0.5877838134765625         +0.82514488697052002j), 
+                            (1.4629089051254596e-08     +1.0096219778060913j), 
+                            (-0.5877840518951416        +0.81836479902267456j), 
+                            (-0.95105588436126709       +0.31451958417892456j), 
+                            (-0.95105588436126709       -0.3030143678188324j), 
+                            (-0.5877838134765625        -0.80480599403381348j), 
+                            (-1.7554906861505515e-08    -0.99516552686691284j), 
+                            (0.58778399229049683        -0.80540722608566284j), 
+                            (0.95105582475662231        -0.30557557940483093j), 
+                            (0.95105588436126709        +0.31097668409347534j), 
+                            (0.5877838134765625         +0.81027895212173462j), 
+                            (2.3406542482007353e-08     +1.0000816583633423j), 
+                            (-0.5877840518951416        +0.80908381938934326j), 
+                            (-0.95105588436126709       +0.30904293060302734j), 
+                            (-0.95105588436126709       -0.30904296040534973j), 
+                            (-0.5877838134765625        -0.80908387899398804j), 
+                            (-2.6332360292258272e-08    -1.0000815391540527j), 
+                            (0.58778399229049683        -0.80908381938934326j), 
+                            (0.95105582475662231        -0.30904299020767212j), 
+                            (0.95105588436126709        +0.30904293060302734j), 
+                            (0.5877838134765625         +0.80908381938934326j), 
+                            (3.218399768911695e-08      +1.0000815391540527j))
+        
+
+        src1 = gr.sig_source_f (sampling_freq, gr.GR_SIN_WAVE,
+                                sampling_freq * 0.10, 1.0)
+
+        head = gr.head (gr.sizeof_float, int (ntaps + sampling_freq * 0.10))
+        hilb = gr.hilbert_fc (ntaps)
+        dst1 = gr.vector_sink_c ()
+        fg.connect (src1, head)
+        fg.connect (head, hilb)
+        fg.connect (hilb, dst1)
+        fg.run ()
+        dst_data = dst1.data ()
+        self.assertComplexTuplesAlmostEqual (expected_result, dst_data, 5)
+
+if __name__ == '__main__':
+    gr_unittest.main ()
diff --git a/gnuradio-core/src/python/gnuradio/gr/qa_iir.py b/gnuradio-core/src/python/gnuradio/gr/qa_iir.py
new file mode 100755 (executable)
index 0000000..a1f2aa0
--- /dev/null
@@ -0,0 +1,135 @@
+#!/usr/bin/env 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.
+# 
+
+from gnuradio import gr, gr_unittest
+
+class test_iir (gr_unittest.TestCase):
+
+    def setUp (self):
+        self.fg = gr.flow_graph ()
+
+    def tearDown (self):
+        self.fg = None
+
+    def test_iir_direct_001 (self):
+        src_data = (1, 2, 3, 4, 5, 6, 7, 8)
+        fftaps = ()
+        fbtaps = ()
+        expected_result = (0, 0, 0, 0, 0, 0, 0, 0)
+        src = gr.vector_source_f (src_data)
+        op = gr.iir_filter_ffd (fftaps, fbtaps)
+        dst = gr.vector_sink_f ()
+        self.fg.connect (src, op)
+        self.fg.connect (op, dst)
+        self.fg.run ()
+        result_data = dst.data ()
+        self.assertFloatTuplesAlmostEqual (expected_result, result_data)
+
+    def test_iir_direct_002 (self):
+        src_data = (1, 2, 3, 4, 5, 6, 7, 8)
+        fftaps = (2,)
+        fbtaps = (0,)
+        expected_result = (2, 4, 6, 8, 10, 12, 14, 16)
+        src = gr.vector_source_f (src_data)
+        op = gr.iir_filter_ffd (fftaps, fbtaps)
+        dst = gr.vector_sink_f ()
+        self.fg.connect (src, op)
+        self.fg.connect (op, dst)
+        self.fg.run ()
+        result_data = dst.data ()
+        self.assertFloatTuplesAlmostEqual (expected_result, result_data)
+
+    def test_iir_direct_003 (self):
+        src_data = (1, 2, 3, 4, 5, 6, 7, 8)
+        fftaps = (2, 11)
+        fbtaps = (0,  0)
+        expected_result = (2, 15, 28, 41, 54, 67, 80, 93)
+        src = gr.vector_source_f (src_data)
+        op = gr.iir_filter_ffd (fftaps, fbtaps)
+        dst = gr.vector_sink_f ()
+        self.fg.connect (src, op)
+        self.fg.connect (op, dst)
+        self.fg.run ()
+        result_data = dst.data ()
+        self.assertFloatTuplesAlmostEqual (expected_result, result_data)
+
+    def test_iir_direct_004 (self):
+        src_data = (1, 2, 3, 4, 5, 6, 7, 8)
+        fftaps = (2, 11)
+        fbtaps = (0,  -1)
+        expected_result = (2, 13, 15, 26, 28, 39, 41, 52)
+        src = gr.vector_source_f (src_data)
+        op = gr.iir_filter_ffd (fftaps, fbtaps)
+        dst = gr.vector_sink_f ()
+        self.fg.connect (src, op)
+        self.fg.connect (op, dst)
+        self.fg.run ()
+        result_data = dst.data ()
+        self.assertFloatTuplesAlmostEqual (expected_result, result_data)
+
+    def test_iir_direct_005 (self):
+        src_data = (1, 2, 3, 4, 5, 6, 7, 8)
+        fftaps = (2, 11,  0)
+        fbtaps = (0,  -1, 3)
+        expected_result = (2, 13, 21, 59, 58, 186, 68, 583)
+        src = gr.vector_source_f (src_data)
+        op = gr.iir_filter_ffd (fftaps, fbtaps)
+        dst = gr.vector_sink_f ()
+        self.fg.connect (src, op)
+        self.fg.connect (op, dst)
+        self.fg.run ()
+        result_data = dst.data ()
+        self.assertFloatTuplesAlmostEqual (expected_result, result_data)
+
+    def test_iir_direct_006 (self):
+        fftaps = (2, 11,  0)
+        fbtaps = (0,  -1)
+        self.assertRaises ((RuntimeError, ValueError), gr.iir_filter_ffd, fftaps, fbtaps)
+
+    def test_iir_direct_007 (self):
+        src_data = (1, 2, 3, 4, 5, 6, 7, 8)
+        expected_result = (2, 13, 21, 59, 58, 186, 68, 583)
+        fftaps = (2, 1)
+        fbtaps = (0, -1)
+        src = gr.vector_source_f (src_data)
+        op = gr.iir_filter_ffd (fftaps, fbtaps)
+        fftaps = (2, 11,  0)
+        fbtaps = (0,  -1, 3)
+        op.set_taps (fftaps, fbtaps)
+        dst = gr.vector_sink_f ()
+        self.fg.connect (src, op)
+        self.fg.connect (op, dst)
+        self.fg.run ()
+        result_data = dst.data ()
+        self.assertFloatTuplesAlmostEqual (expected_result, result_data)
+
+    def test_iir_direct_008 (self):
+        fftaps = (2, 1)
+        fbtaps = (0, -1)
+        op = gr.iir_filter_ffd (fftaps, fbtaps)
+        fftaps = (2, 11)
+        fbtaps = (0,  -1, 3)
+        self.assertRaises ((RuntimeError, ValueError), op.set_taps, fftaps, fbtaps)
+
+if __name__ == '__main__':
+    gr_unittest.main ()
+        
diff --git a/gnuradio-core/src/python/gnuradio/gr/qa_interleave.py b/gnuradio-core/src/python/gnuradio/gr/qa_interleave.py
new file mode 100755 (executable)
index 0000000..003d12e
--- /dev/null
@@ -0,0 +1,81 @@
+#!/usr/bin/env 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.
+# 
+
+from gnuradio import gr, gr_unittest
+import math
+
+class test_interleave (gr_unittest.TestCase):
+
+    def setUp (self):
+        self.fg = gr.flow_graph ()
+
+    def tearDown (self):
+        self.fg = None
+
+    def test_int_001 (self):
+        lenx = 64
+        src0 = gr.vector_source_f (range (0, lenx, 4))
+        src1 = gr.vector_source_f (range (1, lenx, 4))
+        src2 = gr.vector_source_f (range (2, lenx, 4))
+        src3 = gr.vector_source_f (range (3, lenx, 4))
+        op = gr.interleave (gr.sizeof_float)
+        dst = gr.vector_sink_f ()
+
+        self.fg.connect (src0, (op, 0))
+        self.fg.connect (src1, (op, 1))
+        self.fg.connect (src2, (op, 2))
+        self.fg.connect (src3, (op, 3))
+        self.fg.connect (op, dst)
+        self.fg.run ()
+        expected_result = tuple (range (lenx))
+        result_data = dst.data ()
+        self.assertFloatTuplesAlmostEqual (expected_result, result_data)
+
+    def test_deint_001 (self):
+        lenx = 64
+        src = gr.vector_source_f (range (lenx))
+        op = gr.deinterleave (gr.sizeof_float)
+        dst0 = gr.vector_sink_f ()
+        dst1 = gr.vector_sink_f ()
+        dst2 = gr.vector_sink_f ()
+        dst3 = gr.vector_sink_f ()
+
+        self.fg.connect (src, op)
+        self.fg.connect ((op, 0), dst0)
+        self.fg.connect ((op, 1), dst1)
+        self.fg.connect ((op, 2), dst2)
+        self.fg.connect ((op, 3), dst3)
+        self.fg.run ()
+
+        expected_result0 = tuple (range (0, lenx, 4))
+        expected_result1 = tuple (range (1, lenx, 4))
+        expected_result2 = tuple (range (2, lenx, 4))
+        expected_result3 = tuple (range (3, lenx, 4))
+
+        self.assertFloatTuplesAlmostEqual (expected_result0, dst0.data ())
+        self.assertFloatTuplesAlmostEqual (expected_result1, dst1.data ())
+        self.assertFloatTuplesAlmostEqual (expected_result2, dst2.data ())
+        self.assertFloatTuplesAlmostEqual (expected_result3, dst3.data ())
+
+if __name__ == '__main__':
+    gr_unittest.main ()
+        
diff --git a/gnuradio-core/src/python/gnuradio/gr/qa_interp_fir_filter.py b/gnuradio-core/src/python/gnuradio/gr/qa_interp_fir_filter.py
new file mode 100755 (executable)
index 0000000..4119e3e
--- /dev/null
@@ -0,0 +1,54 @@
+#!/usr/bin/env 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.
+# 
+
+from gnuradio import gr, gr_unittest
+import math
+
+class test_interp_fir_filter (gr_unittest.TestCase):
+
+    def setUp (self):
+        self.fg = gr.flow_graph ()
+
+    def tearDown (self):
+        self.fg = None
+
+    def test_fff (self):
+        taps = [1, 10, 100, 1000, 10000]
+        src_data = (0, 2, 3, 5, 7, 11, 13, 17)
+        interpolation = 3
+        xr = (0,0,0,0,2,20,200,2003,20030,300,3005,30050,500,5007,50070,700,7011,70110,1100,11013,110130,1300,13017,130170)
+        expected_result = tuple ([float (x) for x in xr])
+
+        src = gr.vector_source_f (src_data)
+        op = gr.interp_fir_filter_fff (interpolation, taps)
+        dst = gr.vector_sink_f ()
+        self.fg.connect (src, op)
+        self.fg.connect (op, dst)
+        self.fg.run ()
+        result_data = dst.data ()
+        L = min(len(result_data), len(expected_result))
+        self.assertEqual (expected_result[0:L], result_data[0:L])
+
+
+if __name__ == '__main__':
+    gr_unittest.main ()
+        
diff --git a/gnuradio-core/src/python/gnuradio/gr/qa_kludge_copy.py b/gnuradio-core/src/python/gnuradio/gr/qa_kludge_copy.py
new file mode 100755 (executable)
index 0000000..f5dee15
--- /dev/null
@@ -0,0 +1,89 @@
+#!/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 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.
+# 
+
+from gnuradio import gr, gr_unittest
+import math
+import random
+
+
+class test_kludge_copy(gr_unittest.TestCase):
+
+    def setUp(self):
+        self.fg = gr.flow_graph()
+        self.rng = random.Random()
+        self.rng.seed(0)
+
+    def tearDown(self):
+        self.fg = None
+        self.rng = None
+
+    def make_random_int_tuple(self, L):
+        result = []
+        for x in range(L):
+            result.append(self.rng.randint(int(-1e9), int(+1e9)))
+        return tuple(result)
+
+
+    def test_001(self):
+        # 1 input stream; 1 output stream
+        src0_data = self.make_random_int_tuple(16000)
+        src0 = gr.vector_source_i(src0_data)
+        op = gr.kludge_copy(gr.sizeof_int)
+        dst0 = gr.vector_sink_i()
+        self.fg.connect(src0, op, dst0)
+        self.fg.run()
+        dst0_data = dst0.data()
+        self.assertEqual(src0_data, dst0_data)
+
+    def test_002(self):
+        # 2 input streams; 2 output streams
+        src0_data = self.make_random_int_tuple(16000)
+        src1_data = self.make_random_int_tuple(16000)
+        src0 = gr.vector_source_i(src0_data)
+        src1 = gr.vector_source_i(src1_data)
+        op = gr.kludge_copy(gr.sizeof_int)
+        dst0 = gr.vector_sink_i()
+        dst1 = gr.vector_sink_i()
+        self.fg.connect(src0, (op, 0), dst0)
+        self.fg.connect(src1, (op, 1), dst1)
+        self.fg.run()
+        dst0_data = dst0.data()
+        dst1_data = dst1.data()
+        self.assertEqual(src0_data, dst0_data)
+        self.assertEqual(src1_data, dst1_data)
+
+    def test_003(self):
+        # number of input streams != number of output streams
+        src0_data = self.make_random_int_tuple(16000)
+        src1_data = self.make_random_int_tuple(16000)
+        src0 = gr.vector_source_i(src0_data)
+        src1 = gr.vector_source_i(src1_data)
+        op = gr.kludge_copy(gr.sizeof_int)
+        dst0 = gr.vector_sink_i()
+        dst1 = gr.vector_sink_i()
+        self.fg.connect(src0, (op, 0), dst0)
+        self.fg.connect(src1, (op, 1))
+        self.assertRaises(ValueError, self.fg.run)
+
+if __name__ == '__main__':
+    gr_unittest.main ()
+    
diff --git a/gnuradio-core/src/python/gnuradio/gr/qa_kludged_imports.py b/gnuradio-core/src/python/gnuradio/gr/qa_kludged_imports.py
new file mode 100755 (executable)
index 0000000..b208677
--- /dev/null
@@ -0,0 +1,43 @@
+#!/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 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.
+# 
+
+from gnuradio import gr, gr_unittest
+
+class test_head (gr_unittest.TestCase):
+
+    def setUp(self):
+        pass
+
+    def tearDown(self):
+        pass
+
+    def test_blks_import(self):
+        # make sure that this somewhat magic import works
+        from gnuradio import blks
+
+    def test_gru_import(self):
+        # make sure that this somewhat magic import works
+        from gnuradio import gru
+
+
+if __name__ == '__main__':
+    gr_unittest.main ()
diff --git a/gnuradio-core/src/python/gnuradio/gr/qa_message.py b/gnuradio-core/src/python/gnuradio/gr/qa_message.py
new file mode 100755 (executable)
index 0000000..d5d5111
--- /dev/null
@@ -0,0 +1,117 @@
+#!/usr/bin/env 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.
+# 
+
+from gnuradio import gr, gr_unittest
+import qa_basic_flow_graph
+
+
+def all_counts ():
+    return (gr.block_ncurrently_allocated (),
+            gr.block_detail_ncurrently_allocated (),
+            gr.buffer_ncurrently_allocated (),
+            gr.buffer_reader_ncurrently_allocated (),
+            gr.message_ncurrently_allocated ())
+
+
+class test_message (gr_unittest.TestCase):
+
+    def setUp (self):
+        self.fg = gr.flow_graph()
+        self.msgq = gr.msg_queue ()
+
+    def tearDown (self):
+        self.fg = None
+        self.msgq = None
+        
+    def leak_check (self, fct):
+        begin = all_counts ()
+        fct ()
+        # tear down early so we can check for leaks
+        self.tearDown ()
+        end = all_counts ()
+        self.assertEqual (begin, end)
+
+    def test_100 (self):
+        msg = gr.message (0, 1.5, 2.3)
+        self.assertEquals (0, msg.type())
+        self.assertAlmostEqual (1.5, msg.arg1())
+        self.assertAlmostEqual (2.3, msg.arg2())
+        self.assertEquals (0, msg.length())
+
+    def test_101 (self):
+        s = 'This is a test'
+        msg = gr.message_from_string(s)
+        self.assertEquals(s, msg.to_string())
+
+    def test_200 (self):
+        self.leak_check (self.body_200)
+        
+    def body_200 (self):
+        self.msgq.insert_tail (gr.message (0))
+        self.assertEquals (1, self.msgq.count())
+        self.msgq.insert_tail (gr.message (1))
+        self.assertEquals (2, self.msgq.count())
+        msg0 = self.msgq.delete_head ()
+        self.assertEquals (0, msg0.type())
+        msg1 = self.msgq.delete_head ()
+        self.assertEquals (1, msg1.type())
+        self.assertEquals (0, self.msgq.count())
+
+    def test_201 (self):
+        self.leak_check (self.body_201)
+        
+    def body_201 (self):
+        self.msgq.insert_tail (gr.message (0))
+        self.assertEquals (1, self.msgq.count())
+        self.msgq.insert_tail (gr.message (1))
+        self.assertEquals (2, self.msgq.count())
+
+    def test_202 (self):
+        self.leak_check (self.body_202)
+        
+    def body_202 (self):
+        # global msg
+        msg = gr.message (666)
+
+    def test_300(self):
+        input_data = (0,1,2,3,4,5,6,7,8,9)
+        src = gr.vector_source_b(input_data)
+        dst = gr.vector_sink_b()
+        self.fg.connect(src, dst)
+        self.fg.run()
+        self.assertEquals(input_data, dst.data())
+
+    def test_301(self):
+        src = gr.message_source(gr.sizeof_char)
+        dst = gr.vector_sink_b()
+        self.fg.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
+        self.fg.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_mute.py b/gnuradio-core/src/python/gnuradio/gr/qa_mute.py
new file mode 100755 (executable)
index 0000000..863c308
--- /dev/null
@@ -0,0 +1,89 @@
+#!/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 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.
+# 
+
+from gnuradio import gr, gr_unittest
+
+class test_head (gr_unittest.TestCase):
+
+    def setUp (self):
+        self.fg = gr.flow_graph ()
+
+    def tearDown (self):
+        self.fg = None
+
+    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.fg.connect (src, (op, s[0]))
+        dst = gr.vector_sink_i ()
+        self.fg.connect (op, dst)
+        self.fg.run ()
+        result_data = dst.data ()
+        self.assertEqual (exp_data, result_data)
+
+    def help_ff (self, src_data, exp_data, op):
+        for s in zip (range (len (src_data)), src_data):
+            src = gr.vector_source_f (s[1])
+            self.fg.connect (src, (op, s[0]))
+        dst = gr.vector_sink_f ()
+        self.fg.connect (op, dst)
+        self.fg.run ()
+        result_data = dst.data ()
+        self.assertEqual (exp_data, result_data)
+
+    def help_cc (self, src_data, exp_data, op):
+        for s in zip (range (len (src_data)), src_data):
+            src = gr.vector_source_c (s[1])
+            self.fg.connect (src, (op, s[0]))
+        dst = gr.vector_sink_c ()
+        self.fg.connect (op, dst)
+        self.fg.run ()
+        result_data = dst.data ()
+        self.assertEqual (exp_data, result_data)
+
+    def test_unmute_ii(self):
+        src_data = (1, 2, 3, 4, 5)
+        expected_result = (1, 2, 3, 4, 5)
+        op = gr.mute_ii (False)
+        self.help_ii ((src_data,), expected_result, op)
+
+    def test_mute_ii(self):
+        src_data = (1, 2, 3, 4, 5)
+        expected_result = (0, 0, 0, 0, 0)
+        op = gr.mute_ii (True)
+        self.help_ii ((src_data,), expected_result, op)
+
+    def test_unmute_cc (self):
+        src_data = (1+5j, 2+5j, 3+5j, 4+5j, 5+5j)
+        expected_result = (1+5j, 2+5j, 3+5j, 4+5j, 5+5j)
+        op = gr.mute_cc (False)
+        self.help_cc ((src_data,), expected_result, op)
+
+    def test_unmute_cc (self):
+        src_data = (1+5j, 2+5j, 3+5j, 4+5j, 5+5j)
+        expected_result = (0+0j, 0+0j, 0+0j, 0+0j, 0+0j)
+        op = gr.mute_cc (True)
+        self.help_cc ((src_data,), expected_result, op)
+
+
+if __name__ == '__main__':
+    gr_unittest.main ()
diff --git a/gnuradio-core/src/python/gnuradio/gr/qa_nlog10.py b/gnuradio-core/src/python/gnuradio/gr/qa_nlog10.py
new file mode 100755 (executable)
index 0000000..f056d11
--- /dev/null
@@ -0,0 +1,47 @@
+#!/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 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.
+# 
+
+from gnuradio import gr, gr_unittest
+
+class test_single_pole_iir(gr_unittest.TestCase):
+
+    def setUp (self):
+        self.fg = gr.flow_graph ()
+
+    def tearDown (self):
+        self.fg = None
+
+    def test_001(self):
+        src_data = (-10, 0, 10, 100, 1000, 10000, 100000)
+        expected_result = (-180, -180, 10, 20, 30, 40, 50)
+        src = gr.vector_source_f(src_data)
+        op = gr.nlog10_ff(10)
+        dst = gr.vector_sink_f()
+        self.fg.connect (src, op, dst)
+        self.fg.run()
+        result_data = dst.data()
+        self.assertFloatTuplesAlmostEqual (expected_result, result_data)
+
+
+if __name__ == '__main__':
+    gr_unittest.main ()
+        
diff --git a/gnuradio-core/src/python/gnuradio/gr/qa_packed_to_unpacked.py b/gnuradio-core/src/python/gnuradio/gr/qa_packed_to_unpacked.py
new file mode 100755 (executable)
index 0000000..d5472c8
--- /dev/null
@@ -0,0 +1,405 @@
+#!/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 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.
+# 
+
+from gnuradio import gr, gr_unittest
+import random
+
+class test_packing(gr_unittest.TestCase):
+
+    def setUp(self):
+        self.fg = gr.flow_graph ()
+
+    def tearDown(self):
+        self.fg = None
+
+    def test_001(self):
+        """
+        Test stream_to_streams.
+        """
+        src_data = (0x80,)
+        expected_results = (1,0,0,0,0,0,0,0)
+        src = gr.vector_source_b(src_data,False)
+        op = gr.packed_to_unpacked_bb(1, gr.GR_MSB_FIRST)
+        self.fg.connect(src, op)
+        
+        dst = gr.vector_sink_b()
+        self.fg.connect(op, dst)
+
+        self.fg.run()
+
+        self.assertEqual(expected_results, dst.data())
+
+    def test_002(self):
+        """
+        Test stream_to_streams.
+        """
+        src_data = (0x80,)
+        expected_results = (0,0,0,0,0,0,0, 1)
+        src = gr.vector_source_b(src_data,False)
+        op = gr.packed_to_unpacked_bb(1, gr.GR_LSB_FIRST)
+        self.fg.connect(src, op)
+        
+        dst = gr.vector_sink_b()
+        self.fg.connect(op, dst)
+
+        self.fg.run()
+
+        self.assertEqual(expected_results, dst.data())
+
+    def test_003(self):
+        """
+        Test stream_to_streams.
+        """
+        src_data = (0x11,)
+        expected_results = (4, 2)
+        src = gr.vector_source_b(src_data,False)
+        op = gr.packed_to_unpacked_bb(3, gr.GR_LSB_FIRST)
+        self.fg.connect(src, op)
+        
+        dst = gr.vector_sink_b()
+        self.fg.connect(op, dst)
+
+        self.fg.run()
+
+        self.assertEqual(expected_results, dst.data())
+
+    def test_004(self):
+        """
+        Test stream_to_streams.
+        """
+        src_data = (0x11,)
+        expected_results = (0, 4)
+        src = gr.vector_source_b(src_data,False)
+        op = gr.packed_to_unpacked_bb(3, gr.GR_MSB_FIRST)
+        self.fg.connect(src, op)
+        
+        dst = gr.vector_sink_b()
+        self.fg.connect(op, dst)
+
+        self.fg.run()
+
+        self.assertEqual(expected_results, dst.data())
+
+    def test_005(self):
+        """
+        Test stream_to_streams.
+        """
+        src_data = (1,0,0,0,0,0,1,0,0,1,0,1,1,0,1,0)
+        expected_results =  (0x82,0x5a)
+        src = gr.vector_source_b(src_data,False)
+        op = gr.unpacked_to_packed_bb(1, gr.GR_MSB_FIRST)
+        self.fg.connect(src, op)
+        
+        dst = gr.vector_sink_b()
+        self.fg.connect(op, dst)
+
+        self.fg.run()
+
+        self.assertEqual(expected_results, dst.data())
+
+    def test_006(self):
+        """
+        Test stream_to_streams.
+        """
+        src_data = (0,1,0,0,0,0,0,1,0,1,0,1,1,0,1,0)
+        expected_results =  (0x82,0x5a)
+        src = gr.vector_source_b(src_data,False)
+        op = gr.unpacked_to_packed_bb(1, gr.GR_LSB_FIRST)
+        self.fg.connect(src, op)
+        
+        dst = gr.vector_sink_b()
+        self.fg.connect(op, dst)
+
+        self.fg.run()
+
+        self.assertEqual(expected_results, dst.data())
+
+
+    def test_007(self):
+        """
+        Test stream_to_streams.
+        """
+        src_data = (4, 2, 0,0,0)
+        expected_results = (0x11,)
+        src = gr.vector_source_b(src_data,False)
+        op = gr.unpacked_to_packed_bb(3, gr.GR_LSB_FIRST)
+        self.fg.connect(src, op)
+        
+        dst = gr.vector_sink_b()
+        self.fg.connect(op, dst)
+
+        self.fg.run()
+
+        self.assertEqual(expected_results, dst.data())
+
+    def test_008(self):
+        """
+        Test stream_to_streams.
+        """
+        src_data = (0, 4, 2,0,0)
+        expected_results = (0x11,)
+        src = gr.vector_source_b(src_data,False)
+        op = gr.unpacked_to_packed_bb(3, gr.GR_MSB_FIRST)
+        self.fg.connect(src, op)
+        
+        dst = gr.vector_sink_b()
+        self.fg.connect(op, dst)
+
+        self.fg.run()
+
+        self.assertEqual(expected_results, dst.data())
+
+    def test_009(self):
+        """
+        Test stream_to_streams.
+        """
+
+        random.seed(0)
+        src_data = []
+        for i in xrange(202):
+            src_data.append((random.randint(0,255)))
+        src_data = tuple(src_data)
+        expected_results = src_data
+
+        src = gr.vector_source_b(tuple(src_data),False)
+        op1 = gr.packed_to_unpacked_bb(3, gr.GR_MSB_FIRST)
+        op2 = gr.unpacked_to_packed_bb(3, gr.GR_MSB_FIRST)
+        self.fg.connect(src, op1, op2)
+        
+        dst = gr.vector_sink_b()
+        self.fg.connect(op2, dst)
+
+        self.fg.run()
+        
+        self.assertEqual(expected_results[0:201], dst.data())
+
+    def test_010(self):
+        """
+        Test stream_to_streams.
+        """
+
+        random.seed(0)
+        src_data = []
+        for i in xrange(56):
+            src_data.append((random.randint(0,255)))
+        src_data = tuple(src_data)
+        expected_results = src_data
+        src = gr.vector_source_b(tuple(src_data),False)
+        op1 = gr.packed_to_unpacked_bb(7, gr.GR_MSB_FIRST)
+        op2 = gr.unpacked_to_packed_bb(7, gr.GR_MSB_FIRST)
+        self.fg.connect(src, op1, op2)
+        dst = gr.vector_sink_b()
+        self.fg.connect(op2, dst)
+
+        self.fg.run()
+        self.assertEqual(expected_results[0:201], dst.data())
+
+    def test_011(self):
+        """
+        Test stream_to_streams.
+        """
+
+        random.seed(0)
+        src_data = []
+        for i in xrange(56):
+            src_data.append((random.randint(0,255)))
+        src_data = tuple(src_data)
+        expected_results = src_data
+        src = gr.vector_source_b(tuple(src_data),False)
+        op1 = gr.packed_to_unpacked_bb(7, gr.GR_LSB_FIRST)
+        op2 = gr.unpacked_to_packed_bb(7, gr.GR_LSB_FIRST)
+        self.fg.connect(src, op1, op2)
+        dst = gr.vector_sink_b()
+        self.fg.connect(op2, dst)
+
+        self.fg.run()
+        self.assertEqual(expected_results[0:201], dst.data())
+        
+
+    # tests on shorts
+    
+    def test_100a(self):
+        """
+        test short version
+        """
+        random.seed(0)
+        src_data = []
+        for i in xrange(100):
+            src_data.append((random.randint(-2**15,2**15-1)))
+        src_data = tuple(src_data)
+        expected_results = src_data
+        src = gr.vector_source_s(tuple(src_data),False)
+        op1 = gr.packed_to_unpacked_ss(1, gr.GR_MSB_FIRST)
+        op2 = gr.unpacked_to_packed_ss(1, gr.GR_MSB_FIRST)
+        self.fg.connect(src, op1, op2)
+        dst = gr.vector_sink_s()
+        self.fg.connect(op2, dst)
+
+        self.fg.run()
+        self.assertEqual(expected_results, dst.data())
+
+    def test_100b(self):
+        """
+        test short version
+        """
+        random.seed(0)
+        src_data = []
+        for i in xrange(100):
+            src_data.append((random.randint(-2**15,2**15-1)))
+        src_data = tuple(src_data)
+        expected_results = src_data
+        src = gr.vector_source_s(tuple(src_data),False)
+        op1 = gr.packed_to_unpacked_ss(1, gr.GR_LSB_FIRST)
+        op2 = gr.unpacked_to_packed_ss(1, gr.GR_LSB_FIRST)
+        self.fg.connect(src, op1, op2)
+        dst = gr.vector_sink_s()
+        self.fg.connect(op2, dst)
+
+        self.fg.run()
+        self.assertEqual(expected_results, dst.data())
+
+    def test_101a(self):
+        """
+        test short version
+        """
+        random.seed(0)
+        src_data = []
+        for i in xrange(100):
+            src_data.append((random.randint(-2**15,2**15-1)))
+        src_data = tuple(src_data)
+        expected_results = src_data
+        src = gr.vector_source_s(tuple(src_data),False)
+        op1 = gr.packed_to_unpacked_ss(8, gr.GR_MSB_FIRST)
+        op2 = gr.unpacked_to_packed_ss(8, gr.GR_MSB_FIRST)
+        self.fg.connect(src, op1, op2)
+        dst = gr.vector_sink_s()
+        self.fg.connect(op2, dst)
+
+        self.fg.run()
+        self.assertEqual(expected_results, dst.data())
+
+    def test_101b(self):
+        """
+        test short version
+        """
+        random.seed(0)
+        src_data = []
+        for i in xrange(100):
+            src_data.append((random.randint(-2**15,2**15-1)))
+        src_data = tuple(src_data)
+        expected_results = src_data
+        src = gr.vector_source_s(tuple(src_data),False)
+        op1 = gr.packed_to_unpacked_ss(8, gr.GR_LSB_FIRST)
+        op2 = gr.unpacked_to_packed_ss(8, gr.GR_LSB_FIRST)
+        self.fg.connect(src, op1, op2)
+        dst = gr.vector_sink_s()
+        self.fg.connect(op2, dst)
+
+        self.fg.run()
+        self.assertEqual(expected_results, dst.data())
+
+    # tests on ints
+    
+    def test_200a(self):
+        """
+        test int version
+        """
+        random.seed(0)
+        src_data = []
+        for i in xrange(100):
+            src_data.append((random.randint(-2**31,2**31-1)))
+        src_data = tuple(src_data)
+        expected_results = src_data
+        src = gr.vector_source_i(tuple(src_data),False)
+        op1 = gr.packed_to_unpacked_ii(1, gr.GR_MSB_FIRST)
+        op2 = gr.unpacked_to_packed_ii(1, gr.GR_MSB_FIRST)
+        self.fg.connect(src, op1, op2)
+        dst = gr.vector_sink_i()
+        self.fg.connect(op2, dst)
+
+        self.fg.run()
+        self.assertEqual(expected_results, dst.data())
+
+    def test_200b(self):
+        """
+        test int version
+        """
+        random.seed(0)
+        src_data = []
+        for i in xrange(100):
+            src_data.append((random.randint(-2**31,2**31-1)))
+        src_data = tuple(src_data)
+        expected_results = src_data
+        src = gr.vector_source_i(tuple(src_data),False)
+        op1 = gr.packed_to_unpacked_ii(1, gr.GR_LSB_FIRST)
+        op2 = gr.unpacked_to_packed_ii(1, gr.GR_LSB_FIRST)
+        self.fg.connect(src, op1, op2)
+        dst = gr.vector_sink_i()
+        self.fg.connect(op2, dst)
+
+        self.fg.run()
+        self.assertEqual(expected_results, dst.data())
+
+    def test_201a(self):
+        """
+        test int version
+        """
+        random.seed(0)
+        src_data = []
+        for i in xrange(100):
+            src_data.append((random.randint(-2**31,2**31-1)))
+        src_data = tuple(src_data)
+        expected_results = src_data
+        src = gr.vector_source_i(tuple(src_data),False)
+        op1 = gr.packed_to_unpacked_ii(8, gr.GR_MSB_FIRST)
+        op2 = gr.unpacked_to_packed_ii(8, gr.GR_MSB_FIRST)
+        self.fg.connect(src, op1, op2)
+        dst = gr.vector_sink_i()
+        self.fg.connect(op2, dst)
+
+        self.fg.run()
+        self.assertEqual(expected_results, dst.data())
+
+    def test_201b(self):
+        """
+        test int version
+        """
+        random.seed(0)
+        src_data = []
+        for i in xrange(100):
+            src_data.append((random.randint(-2**31,2**31-1)))
+        src_data = tuple(src_data)
+        expected_results = src_data
+        src = gr.vector_source_i(tuple(src_data),False)
+        op1 = gr.packed_to_unpacked_ii(8, gr.GR_LSB_FIRST)
+        op2 = gr.unpacked_to_packed_ii(8, gr.GR_LSB_FIRST)
+        self.fg.connect(src, op1, op2)
+        dst = gr.vector_sink_i()
+        self.fg.connect(op2, dst)
+
+        self.fg.run()
+        self.assertEqual(expected_results, dst.data())
+
+
+if __name__ == '__main__':
+   gr_unittest.main ()
+        
diff --git a/gnuradio-core/src/python/gnuradio/gr/qa_pipe_fittings.py b/gnuradio-core/src/python/gnuradio/gr/qa_pipe_fittings.py
new file mode 100755 (executable)
index 0000000..dca18c8
--- /dev/null
@@ -0,0 +1,143 @@
+#!/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 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.
+# 
+
+from gnuradio import gr, gr_unittest
+
+if 0:
+    import os
+    print "pid =", os.getpid()
+    raw_input("Attach, then press Enter to continue")
+
+
+def calc_expected_result(src_data, n):
+    assert (len(src_data) % n) == 0
+    result = [list() for x in range(n)]
+    #print "len(result) =", len(result)
+    for i in xrange(len(src_data)):
+        (result[i % n]).append(src_data[i])
+    return [tuple(x) for x in result]
+
+
+class test_pipe_fittings(gr_unittest.TestCase):
+
+    def setUp(self):
+        self.fg = gr.flow_graph ()
+
+    def tearDown(self):
+        self.fg = None
+
+    def test_001(self):
+        """
+        Test stream_to_streams.
+        """
+        n = 8
+        src_len = n * 8
+        src_data = range(src_len)
+
+        expected_results = calc_expected_result(src_data, n)
+        #print "expected results: ", expected_results
+        src = gr.vector_source_i(src_data)
+        op = gr.stream_to_streams(gr.sizeof_int, n)
+        self.fg.connect(src, op)
+        
+        dsts = []
+        for i in range(n):
+            dst = gr.vector_sink_i()
+            self.fg.connect((op, i), (dst, 0))
+            dsts.append(dst)
+
+        self.fg.run()
+
+        for d in range(n):
+            self.assertEqual(expected_results[d], dsts[d].data())
+
+    def test_002(self):
+        """
+        Test streams_to_stream (using stream_to_streams).
+        """
+        n = 8
+        src_len = n * 8
+        src_data = tuple(range(src_len))
+        expected_results = src_data
+
+        src = gr.vector_source_i(src_data)
+        op1 = gr.stream_to_streams(gr.sizeof_int, n)
+        op2 = gr.streams_to_stream(gr.sizeof_int, n)
+        dst = gr.vector_sink_i()
+        
+        self.fg.connect(src, op1)
+        for i in range(n):
+            self.fg.connect((op1, i), (op2, i))
+        self.fg.connect(op2, dst)
+        
+        self.fg.run()
+        self.assertEqual(expected_results, dst.data())
+        
+    def test_003(self):
+        """
+        Test streams_to_vector (using stream_to_streams & vector_to_stream).
+        """
+        n = 8
+        src_len = n * 8
+        src_data = tuple(range(src_len))
+        expected_results = src_data
+
+        src = gr.vector_source_i(src_data)
+        op1 = gr.stream_to_streams(gr.sizeof_int, n)
+        op2 = gr.streams_to_vector(gr.sizeof_int, n)
+        op3 = gr.vector_to_stream(gr.sizeof_int, n)
+        dst = gr.vector_sink_i()
+        
+        self.fg.connect(src, op1)
+        for i in range(n):
+            self.fg.connect((op1, i), (op2, i))
+        self.fg.connect(op2, op3, dst)
+        
+        self.fg.run()
+        self.assertEqual(expected_results, dst.data())
+        
+    def test_004(self):
+        """
+        Test vector_to_streams.
+        """
+        n = 8
+        src_len = n * 8
+        src_data = tuple(range(src_len))
+        expected_results = src_data
+
+        src = gr.vector_source_i(src_data)
+        op1 = gr.stream_to_vector(gr.sizeof_int, n)
+        op2 = gr.vector_to_streams(gr.sizeof_int, n)
+        op3 = gr.streams_to_stream(gr.sizeof_int, n)
+        dst = gr.vector_sink_i()
+        
+        self.fg.connect(src, op1, op2)
+        for i in range(n):
+            self.fg.connect((op2, i), (op3, i))
+        self.fg.connect(op3, dst)
+        
+        self.fg.run()
+        self.assertEqual(expected_results, dst.data())
+
+if __name__ == '__main__':
+    gr_unittest.main ()
+        
diff --git a/gnuradio-core/src/python/gnuradio/gr/qa_rational_resampler.py b/gnuradio-core/src/python/gnuradio/gr/qa_rational_resampler.py
new file mode 100755 (executable)
index 0000000..2505482
--- /dev/null
@@ -0,0 +1,290 @@
+#!/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 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.
+# 
+
+from gnuradio import gr, gr_unittest
+from gnuradio import blks
+import math
+import random
+import sys
+
+#import os
+#print os.getpid()
+#raw_input('Attach with gdb, then press Enter: ')
+
+
+def random_floats(n):
+    r = []
+    for x in xrange(n):
+        r.append(float(random.randint(-32768, 32768)))
+    return tuple(r)
+
+
+def reference_dec_filter(src_data, decim, taps):
+    fg = gr.flow_graph()
+    src = gr.vector_source_f(src_data)
+    op = gr.fir_filter_fff(decim, taps)
+    dst = gr.vector_sink_f()
+    fg.connect(src, op, dst)
+    fg.run()
+    result_data = dst.data()
+    fg = None
+    return result_data
+
+def reference_interp_filter(src_data, interp, taps):
+    fg = gr.flow_graph()
+    src = gr.vector_source_f(src_data)
+    op = gr.interp_fir_filter_fff(interp, taps)
+    dst = gr.vector_sink_f()
+    fg.connect(src, op, dst)
+    fg.run()
+    result_data = dst.data()
+    fg = None
+    return result_data
+
+def reference_interp_dec_filter(src_data, interp, decim, taps):
+    fg = gr.flow_graph()
+    src = gr.vector_source_f(src_data)
+    up = gr.interp_fir_filter_fff(interp, (1,))
+    dn = gr.fir_filter_fff(decim, taps)
+    dst = gr.vector_sink_f()
+    fg.connect(src, up, dn, dst)
+    fg.run()
+    result_data = dst.data()
+    fg = None
+    return result_data
+    
+
+class test_rational_resampler (gr_unittest.TestCase):
+
+    def setUp(self):
+        self.fg = gr.flow_graph()
+
+    def tearDown(self):
+        self.fg = None
+
+    #
+    # test the gr.rational_resampler_base primitives...
+    #
+    
+    def test_000_1_to_1(self):
+        taps = (-4, 5)
+        src_data = (234,  -4,  23,  -56,  45,    98,  -23,  -7)
+        xr = (-936, 1186, -112, 339, -460, -167, 582)
+        expected_result = tuple([float(x) for x in xr])
+
+        src = gr.vector_source_f(src_data)
+        op = gr.rational_resampler_base_fff(1, 1, taps)
+        dst = gr.vector_sink_f()
+        self.fg.connect(src, op)
+        self.fg.connect(op, dst)
+        self.fg.run()
+        result_data = dst.data()
+        self.assertEqual(expected_result, result_data)
+        
+    def test_001_interp(self):
+        taps = [1, 10, 100, 1000, 10000]
+        src_data = (0, 2, 3, 5, 7, 11, 13, 17)
+        interpolation = 3
+        xr = (0,0,0,0,2,20,200,2003,20030,300,3005,30050,500,5007,50070,700,7011,70110,1100,11013,110130,1300,13017,130170,1700.0,17000.0,170000.0)
+        expected_result = tuple([float(x) for x in xr])
+
+        src = gr.vector_source_f(src_data)
+        op = gr.rational_resampler_base_fff(interpolation, 1, taps)
+        dst = gr.vector_sink_f()
+        self.fg.connect(src, op)
+        self.fg.connect(op, dst)
+        self.fg.run()
+        result_data = dst.data()
+        self.assertEqual(expected_result, result_data)
+
+    def test_002_interp(self):          
+        taps = random_floats(31)
+        #src_data = random_floats(10000)  # FIXME the 10k case fails!
+        src_data = random_floats(1000)
+        interpolation = 3
+
+        expected_result = reference_interp_filter(src_data, interpolation, taps)
+
+        src = gr.vector_source_f(src_data)
+        op = gr.rational_resampler_base_fff(interpolation, 1, taps)
+        dst = gr.vector_sink_f()
+        self.fg.connect(src, op)
+        self.fg.connect(op, dst)
+        self.fg.run()
+        result_data = dst.data()
+
+        L1 = len(result_data)
+        L2 = len(expected_result)
+        L = min(L1, L2)
+        if False:
+            sys.stderr.write('delta = %2d: ntaps = %d interp = %d ilen = %d\n' %
+                             (L2 - L1, len(taps), interpolation, len(src_data)))
+            sys.stderr.write('  len(result_data) = %d  len(expected_result) = %d\n' %
+                             (len(result_data), len(expected_result)))
+        #self.assertEqual(expected_result[0:L], result_data[0:L])
+        # FIXME check first 3 answers
+        self.assertEqual(expected_result[3:L], result_data[3:L])
+
+    def test_003_interp(self):
+        taps = random_floats(31)
+        src_data = random_floats(10000)
+        decimation = 3
+
+        expected_result = reference_dec_filter(src_data, decimation, taps)
+
+        src = gr.vector_source_f(src_data)
+        op = gr.rational_resampler_base_fff(1, decimation, taps)
+        dst = gr.vector_sink_f()
+        self.fg.connect(src, op)
+        self.fg.connect(op, dst)
+        self.fg.run()
+        result_data = dst.data()
+
+        L1 = len(result_data)
+        L2 = len(expected_result)
+        L = min(L1, L2)
+        if False:
+            sys.stderr.write('delta = %2d: ntaps = %d decim = %d ilen = %d\n' %
+                             (L2 - L1, len(taps), decimation, len(src_data)))
+            sys.stderr.write('  len(result_data) = %d  len(expected_result) = %d\n' %
+                             (len(result_data), len(expected_result)))
+        self.assertEqual(expected_result[0:L], result_data[0:L])
+
+    # FIXME disabled.  Triggers hang on SuSE 10.0
+    def xtest_004_decim_random_vals(self):
+        MAX_TAPS = 9
+        MAX_DECIM = 7
+        OUTPUT_LEN = 9
+
+        random.seed(0)    # we want reproducibility
+
+        for ntaps in xrange(1, MAX_TAPS + 1):
+            for decim in xrange(1, MAX_DECIM+1):
+                for ilen in xrange(ntaps + decim, ntaps + OUTPUT_LEN*decim):
+                    src_data = random_floats(ilen)
+                    taps = random_floats(ntaps)
+                    expected_result = reference_dec_filter(src_data, decim, taps)
+
+                    fg = gr.flow_graph()
+                    src = gr.vector_source_f(src_data)
+                    op = gr.rational_resampler_base_fff(1, decim, taps)
+                    dst = gr.vector_sink_f()
+                    fg.connect(src, op, dst)
+                    fg.run()
+                    fg = None
+                    result_data = dst.data()
+                    L1 = len(result_data)
+                    L2 = len(expected_result)
+                    L = min(L1, L2)
+                    if False:
+                        sys.stderr.write('delta = %2d: ntaps = %d decim = %d ilen = %d\n' % (L2 - L1, ntaps, decim, ilen))
+                        sys.stderr.write('  len(result_data) = %d  len(expected_result) = %d\n' %
+                                         (len(result_data), len(expected_result)))
+                    self.assertEqual(expected_result[0:L], result_data[0:L])
+
+
+    # FIXME disabled.  Triggers hang on SuSE 10.0
+    def xtest_005_interp_random_vals(self):
+        MAX_TAPS = 9
+        MAX_INTERP = 7
+        INPUT_LEN = 9
+
+        random.seed(0)    # we want reproducibility
+
+        for ntaps in xrange(1, MAX_TAPS + 1):
+            for interp in xrange(1, MAX_INTERP+1):
+                for ilen in xrange(ntaps, ntaps + INPUT_LEN):
+                    src_data = random_floats(ilen)
+                    taps = random_floats(ntaps)
+                    expected_result = reference_interp_filter(src_data, interp, taps)
+
+                    fg = gr.flow_graph()
+                    src = gr.vector_source_f(src_data)
+                    op = gr.rational_resampler_base_fff(interp, 1, taps)
+                    dst = gr.vector_sink_f()
+                    fg.connect(src, op, dst)
+                    fg.run()
+                    fg = None
+                    result_data = dst.data()
+                    L1 = len(result_data)
+                    L2 = len(expected_result)
+                    L = min(L1, L2)
+                    #if True or abs(L1-L2) > 1:
+                    if False:
+                        sys.stderr.write('delta = %2d: ntaps = %d interp = %d ilen = %d\n' % (L2 - L1, ntaps, interp, ilen))
+                        #sys.stderr.write('  len(result_data) = %d  len(expected_result) = %d\n' %
+                        #                 (len(result_data), len(expected_result)))
+                    #self.assertEqual(expected_result[0:L], result_data[0:L])
+                    # FIXME check first ntaps+1 answers
+                    self.assertEqual(expected_result[ntaps+1:L], result_data[ntaps+1:L])
+
+
+    def test_006_interp_decim(self):
+        taps = (0,1,0,0)
+        src_data = range(10000)
+        interp = 3
+        decimation = 2
+
+        expected_result = reference_interp_dec_filter(src_data, interp, decimation, taps)
+
+        src = gr.vector_source_f(src_data)
+        op = gr.rational_resampler_base_fff(interp, decimation, taps)
+        dst = gr.vector_sink_f()
+        self.fg.connect(src, op)
+        self.fg.connect(op, dst)
+        self.fg.run()
+        result_data = dst.data()
+
+        L1 = len(result_data)
+        L2 = len(expected_result)
+        L = min(L1, L2)
+        if False:
+            sys.stderr.write('delta = %2d: ntaps = %d decim = %d ilen = %d\n' %
+                             (L2 - L1, len(taps), decimation, len(src_data)))
+            sys.stderr.write('  len(result_data) = %d  len(expected_result) = %d\n' %
+                             (len(result_data), len(expected_result)))
+        self.assertEqual(expected_result[1:L], result_data[1:L])
+
+    #
+    # test the blks.rational_resampler_??? primitives...
+    #
+
+    def test_101_interp(self):
+        taps = [1, 10, 100, 1000, 10000]
+        src_data = (0, 2, 3, 5, 7, 11, 13, 17)
+        interpolation = 3
+        xr = (0,0,0,0,2,20,200,2003,20030,300,3005,30050,500,5007,50070,700,7011,70110,1100,11013,110130,1300,13017,130170,1700.0,17000.0,170000.0)
+        expected_result = tuple([float(x) for x in xr])
+
+        src = gr.vector_source_f(src_data)
+        op = blks.rational_resampler_fff(self.fg, interpolation, 1, taps=taps)
+        dst = gr.vector_sink_f()
+        self.fg.connect(src, op)
+        self.fg.connect(op, dst)
+        self.fg.run()
+        result_data = dst.data()
+        self.assertEqual(expected_result, result_data)
+
+
+if __name__ == '__main__':
+    gr_unittest.main()
+        
diff --git a/gnuradio-core/src/python/gnuradio/gr/qa_sig_source.py b/gnuradio-core/src/python/gnuradio/gr/qa_sig_source.py
new file mode 100755 (executable)
index 0000000..39866ac
--- /dev/null
@@ -0,0 +1,85 @@
+#!/usr/bin/env 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.
+# 
+
+from gnuradio import gr, gr_unittest
+import math
+
+class test_sig_source (gr_unittest.TestCase):
+
+    def setUp (self):
+        self.fg = gr.flow_graph ()
+
+    def tearDown (self):
+        self.fg = None
+
+    def test_const_f (self):
+        fg = self.fg
+        expected_result = (1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5)
+        src1 = gr.sig_source_f (1e6, gr.GR_CONST_WAVE, 0, 1.5)
+        op = gr.head (gr.sizeof_float, 10)
+        dst1 = gr.vector_sink_f ()
+        fg.connect (src1, op)
+        fg.connect (op, dst1)
+        fg.run ()
+        dst_data = dst1.data ()
+        self.assertEqual (expected_result, dst_data)
+    
+    def test_const_i (self):
+        fg = self.fg
+        expected_result = (1, 1, 1, 1)
+        src1 = gr.sig_source_i (1e6, gr.GR_CONST_WAVE, 0, 1)
+        op = gr.head (gr.sizeof_int, 4)
+        dst1 = gr.vector_sink_i ()
+        fg.connect (src1, op)
+        fg.connect (op, dst1)
+        fg.run ()
+        dst_data = dst1.data ()
+        self.assertEqual (expected_result, dst_data)
+    
+    def test_sine_f (self):
+        fg = self.fg
+        sqrt2 = math.sqrt(2) / 2
+        expected_result = (0, sqrt2, 1, sqrt2, 0, -sqrt2, -1, -sqrt2, 0)
+        src1 = gr.sig_source_f (8, gr.GR_SIN_WAVE, 1.0, 1.0)
+        op = gr.head (gr.sizeof_float, 9)
+        dst1 = gr.vector_sink_f ()
+        fg.connect (src1, op)
+        fg.connect (op, dst1)
+        fg.run ()
+        dst_data = dst1.data ()
+        self.assertFloatTuplesAlmostEqual (expected_result, dst_data, 5)
+
+    def test_cosine_f (self):
+        fg = self.fg
+        sqrt2 = math.sqrt(2) / 2
+        expected_result = (1, sqrt2, 0, -sqrt2, -1, -sqrt2, 0, sqrt2, 1)
+        src1 = gr.sig_source_f (8, gr.GR_COS_WAVE, 1.0, 1.0)
+        op = gr.head (gr.sizeof_float, 9)
+        dst1 = gr.vector_sink_f ()
+        fg.connect (src1, op)
+        fg.connect (op, dst1)
+        fg.run ()
+        dst_data = dst1.data ()
+        self.assertFloatTuplesAlmostEqual (expected_result, dst_data, 5)
+
+if __name__ == '__main__':
+    gr_unittest.main ()
diff --git a/gnuradio-core/src/python/gnuradio/gr/qa_single_pole_iir.py b/gnuradio-core/src/python/gnuradio/gr/qa_single_pole_iir.py
new file mode 100755 (executable)
index 0000000..5898188
--- /dev/null
@@ -0,0 +1,72 @@
+#!/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 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.
+# 
+
+from gnuradio import gr, gr_unittest
+
+class test_single_pole_iir(gr_unittest.TestCase):
+
+    def setUp (self):
+        self.fg = gr.flow_graph ()
+
+    def tearDown (self):
+        self.fg = None
+
+    def test_001(self):
+        src_data = (0, 1000, 2000, 3000, 4000, 5000)
+        expected_result = src_data
+        src = gr.vector_source_f(src_data)
+        op = gr.single_pole_iir_filter_ff (1.0)
+        dst = gr.vector_sink_f()
+        self.fg.connect (src, op, dst)
+        self.fg.run()
+        result_data = dst.data()
+        self.assertFloatTuplesAlmostEqual (expected_result, result_data)
+
+    def test_002(self):
+        src_data = (0, 1000, 2000, 3000, 4000, 5000)
+        expected_result = (0, 125, 359.375, 689.453125, 1103.271484, 1590.36255)
+        src = gr.vector_source_f(src_data)
+        op = gr.single_pole_iir_filter_ff (0.125)
+        dst = gr.vector_sink_f()
+        self.fg.connect (src, op, dst)
+        self.fg.run()
+        result_data = dst.data()
+        self.assertFloatTuplesAlmostEqual (expected_result, result_data, 3)
+
+    def test_003(self):
+        block_size = 2
+        src_data = (0, 1000, 2000, 3000, 4000, 5000)
+        expected_result = (0, 125, 250, 484.375, 718.75, 1048.828125)
+        src = gr.vector_source_f(src_data)
+        s2p = gr.serial_to_parallel(gr.sizeof_float, block_size)
+        op = gr.single_pole_iir_filter_ff (0.125, block_size)
+        p2s = gr.parallel_to_serial(gr.sizeof_float, block_size)
+        dst = gr.vector_sink_f()
+        self.fg.connect (src, s2p, op, p2s, dst)
+        self.fg.run()
+        result_data = dst.data()
+        self.assertFloatTuplesAlmostEqual (expected_result, result_data, 3)
+
+
+if __name__ == '__main__':
+    gr_unittest.main ()
+        
diff --git a/gnuradio-core/src/python/gnuradio/gr/qa_single_pole_iir_cc.py b/gnuradio-core/src/python/gnuradio/gr/qa_single_pole_iir_cc.py
new file mode 100755 (executable)
index 0000000..a7889d1
--- /dev/null
@@ -0,0 +1,72 @@
+#!/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 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.
+# 
+
+from gnuradio import gr, gr_unittest
+
+class test_single_pole_iir_cc(gr_unittest.TestCase):
+
+    def setUp (self):
+        self.fg = gr.flow_graph ()
+
+    def tearDown (self):
+        self.fg = None
+
+    def test_001(self):
+        src_data = (0+0j, 1000+1000j, 2000+2000j, 3000+3000j, 4000+4000j, 5000+5000j)
+        expected_result = src_data
+        src = gr.vector_source_c(src_data)
+        op = gr.single_pole_iir_filter_cc (1.0)
+        dst = gr.vector_sink_c()
+        self.fg.connect (src, op, dst)
+        self.fg.run()
+        result_data = dst.data()
+        self.assertComplexTuplesAlmostEqual (expected_result, result_data)
+
+    def test_002(self):
+        src_data = (complex(0,0), complex(1000,-1000), complex(2000,-2000), complex(3000,-3000), complex(4000,-4000), complex(5000,-5000))
+        expected_result = (complex(0,0), complex(125,-125), complex(359.375,-359.375), complex(689.453125,-689.453125), complex(1103.271484,-1103.271484), complex(1590.36255,-1590.36255))
+        src = gr.vector_source_c(src_data)
+        op = gr.single_pole_iir_filter_cc (0.125)
+        dst = gr.vector_sink_c()
+        self.fg.connect (src, op, dst)
+        self.fg.run()
+        result_data = dst.data()
+        self.assertComplexTuplesAlmostEqual (expected_result, result_data, 3)
+
+    def test_003(self):
+        block_size = 2
+        src_data = (complex(0,0), complex(1000,-1000), complex(2000,-2000), complex(3000,-3000), complex(4000,-4000), complex(5000,-5000))
+        expected_result = (complex(0,0), complex(125,-125), complex(250,-250), complex(484.375,-484.375), complex(718.75,-718.75), complex(1048.828125,-1048.828125))
+        src = gr.vector_source_c(src_data)
+        s2p = gr.serial_to_parallel(gr.sizeof_gr_complex, block_size)
+        op = gr.single_pole_iir_filter_cc (0.125, block_size)
+        p2s = gr.parallel_to_serial(gr.sizeof_gr_complex, block_size)
+        dst = gr.vector_sink_c()
+        self.fg.connect (src, s2p, op, p2s, dst)
+        self.fg.run()
+        result_data = dst.data()
+        self.assertComplexTuplesAlmostEqual (expected_result, result_data, 3)
+
+
+if __name__ == '__main__':
+    gr_unittest.main ()
+        
diff --git a/gnuradio-core/src/python/gnuradio/gr/qa_unpack_k_bits.py b/gnuradio-core/src/python/gnuradio/gr/qa_unpack_k_bits.py
new file mode 100755 (executable)
index 0000000..59f838a
--- /dev/null
@@ -0,0 +1,57 @@
+#!/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 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.
+# 
+
+from gnuradio import gr, gr_unittest
+import random
+
+class test_unpack(gr_unittest.TestCase):
+
+    def setUp(self):
+        self.fg = gr.flow_graph ()
+
+    def tearDown(self):
+        self.fg = None
+
+    def test_001(self):
+        src_data =         (1,0,1,1,0,1,1,0)
+        expected_results = (1,0,1,1,0,1,1,0)
+        src = gr.vector_source_b(src_data,False)
+        op = gr.unpack_k_bits_bb(1)
+        dst = gr.vector_sink_b()
+        self.fg.connect(src, op, dst)
+        self.fg.run()
+        self.assertEqual(expected_results, dst.data())
+
+    def test_002(self):
+        src_data =         (  2,  3,  0,  1)
+        expected_results = (1,0,1,1,0,0,0,1)
+        src = gr.vector_source_b(src_data,False)
+        op = gr.unpack_k_bits_bb(2)
+        dst = gr.vector_sink_b()
+        self.fg.connect(src, op, dst)
+        self.fg.run()
+        self.assertEqual(expected_results, dst.data())
+
+
+if __name__ == '__main__':
+   gr_unittest.main ()
+        
diff --git a/gnuradio-core/src/python/gnuradio/gr/run_tests.in b/gnuradio-core/src/python/gnuradio/gr/run_tests.in
new file mode 100755 (executable)
index 0000000..87d0afd
--- /dev/null
@@ -0,0 +1,33 @@
+#!/bin/sh
+
+swigbld=@abs_top_builddir@/gnuradio-core/src/lib/swig
+swigsrc=@abs_top_srcdir@/gnuradio-core/src/lib/swig
+py=@abs_top_srcdir@/gnuradio-core/src/python
+
+PYTHONPATH="$swigbld:$swigbld/.libs:$swigsrc:$py"
+export PYTHONPATH
+
+# for OS/X
+DYLD_LIBRARY_PATH="@abs_top_builddir@/gnuradio-core/src/lib/.libs"
+export DYLD_LIBRARY_PATH
+
+# Don't load user or system prefs
+GR_DONT_LOAD_PREFS=1
+export GR_DONT_LOAD_PREFS
+
+ok=yes
+for file in @srcdir@/qa_*.py
+do
+  echo $file
+  if ! $file
+  then
+    ok=no
+  fi  
+done
+
+if [ $ok = yes ]
+then
+  exit 0
+else
+  exit 1
+fi
diff --git a/gnuradio-core/src/python/gnuradio/gr/scheduler.py b/gnuradio-core/src/python/gnuradio/gr/scheduler.py
new file mode 100644 (file)
index 0000000..919d07f
--- /dev/null
@@ -0,0 +1,70 @@
+#
+# 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.
+# 
+
+from gnuradio.gr.exceptions import *
+from gnuradio_swig_python import single_threaded_scheduler, sts_pyrun
+import gr_threading as _threading
+#import threading as _threading
+
+class scheduler_thread(_threading.Thread):
+    def __init__(self, sts):
+        _threading.Thread.__init__(self)
+        self.sts = sts
+    def run(self):
+        # Invoke the single threaded scheduler's run method
+        #
+        # Note that we're in a new thread, and that sts_pyrun
+        # releases the global interpreter lock.  This has the
+        # effect of evaluating the graph in parallel to the
+        # main line control code.
+        sts_pyrun(self.sts)  
+        self.sts = None
+        
+class scheduler(object):
+    def __init__(self, fg):
+        graphs = fg.partition_graph(fg.blocks)
+        # print "@@@ # graphs = %d" % (len(graphs))
+        
+        self.state = []
+        
+        for g in graphs:
+            list_of_blocks = [x.block() for x in g]
+            sts = single_threaded_scheduler(list_of_blocks)
+            thread = scheduler_thread(sts)
+            thread.setDaemon(1)
+            self.state.append((sts, thread))
+
+    def start(self):
+        for (sts, thread) in self.state:
+            thread.start()
+
+    def stop(self):
+        for (sts, thread) in self.state:
+            sts.stop()
+        self.wait()
+
+    def wait(self):
+        for (sts, thread) in self.state:
+            timeout = 0.100
+            while True:
+                thread.join(timeout)
+                if not thread.isAlive():
+                    break
diff --git a/gnuradio-core/src/python/gnuradio/gr_unittest.py b/gnuradio-core/src/python/gnuradio/gr_unittest.py
new file mode 100755 (executable)
index 0000000..a74a061
--- /dev/null
@@ -0,0 +1,114 @@
+#!/usr/bin/env 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.
+# 
+
+import unittest
+import sys
+
+class TestCase(unittest.TestCase):
+    """A subclass of unittest.TestCase that adds additional assertions
+
+    Adds new methods assertComplexAlmostEqual,
+    assertComplexTuplesAlmostEqual and assertFloatTuplesAlmostEqual
+    """
+
+    def assertComplexAlmostEqual (self, first, second, places=7, msg=None):
+        """Fail if the two complex objects are unequal as determined by their
+           difference rounded to the given number of decimal places
+           (default 7) and comparing to zero.
+
+           Note that decimal places (from zero) is usually not the same
+           as significant digits (measured from the most signficant digit).
+        """
+        if round(second.real-first.real, places) != 0:
+            raise self.failureException, \
+                  (msg or '%s != %s within %s places' % (`first`, `second`, `places` ))
+        if round(second.imag-first.imag, places) != 0:
+            raise self.failureException, \
+                  (msg or '%s != %s within %s places' % (`first`, `second`, `places` ))
+        
+    def assertComplexAlmostEqual2 (self, ref, x, abs_eps=1e-12, rel_eps=1e-6, msg=None):
+        """
+        Fail if the two complex objects are unequal as determined by...
+        """
+        if abs(ref - x) < abs_eps:
+            return
+
+        if abs(ref) > abs_eps:
+            if abs(ref-x)/abs(ref) > rel_eps:
+                raise self.failureException, \
+                      (msg or '%s != %s rel_error = %s rel_limit = %s' % (
+                    `ref`, `x`, abs(ref-x)/abs(ref), `rel_eps` ))
+        else:
+            raise self.failureException, \
+                      (msg or '%s != %s rel_error = %s rel_limit = %s' % (
+                    `ref`, `x`, abs(ref-x)/abs(ref), `rel_eps` ))
+
+
+        
+    def assertComplexTuplesAlmostEqual (self, a, b, places=7, msg=None):
+        self.assertEqual (len(a), len(b))
+        for i in xrange (len(a)):
+            self.assertComplexAlmostEqual (a[i], b[i], places, msg)
+
+    def assertComplexTuplesAlmostEqual2 (self, ref, x,
+                                         abs_eps=1e-12, rel_eps=1e-6, msg=None):
+        self.assertEqual (len(ref), len(x))
+        for i in xrange (len(ref)):
+            try:
+                self.assertComplexAlmostEqual2 (ref[i], x[i], abs_eps, rel_eps, msg)
+            except self.failureException, e:
+                #sys.stderr.write("index = %d " % (i,))
+                #sys.stderr.write("%s\n" % (e,))
+                raise
+
+    def assertFloatTuplesAlmostEqual (self, a, b, places=7, msg=None):
+        self.assertEqual (len(a), len(b))
+        for i in xrange (len(a)):
+            self.assertAlmostEqual (a[i], b[i], places, msg)
+
+
+    def assertFloatTuplesAlmostEqual2 (self, ref, x,
+                                       abs_eps=1e-12, rel_eps=1e-6, msg=None):
+        self.assertEqual (len(ref), len(x))
+        for i in xrange (len(ref)):
+            try:
+                self.assertComplexAlmostEqual2 (ref[i], x[i], abs_eps, rel_eps, msg)
+            except self.failureException, e:
+                #sys.stderr.write("index = %d " % (i,))
+                #sys.stderr.write("%s\n" % (e,))
+                raise
+
+
+TestResult = unittest.TestResult
+TestSuite = unittest.TestSuite
+FunctionTestCase = unittest.FunctionTestCase
+TestLoader = unittest.TestLoader
+TextTestRunner = unittest.TextTestRunner
+TestProgram = unittest.TestProgram
+main = TestProgram
+
+##############################################################################
+# Executing this module from the command line
+##############################################################################
+
+if __name__ == "__main__":
+    main(module=None)
diff --git a/gnuradio-core/src/python/gnuradio/gru/Makefile.am b/gnuradio-core/src/python/gnuradio/gru/Makefile.am
new file mode 100644 (file)
index 0000000..44b52b6
--- /dev/null
@@ -0,0 +1,35 @@
+#
+# 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 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.
+# 
+
+include $(top_srcdir)/Makefile.common
+
+# EXTRA_DIST = run_tests.in
+# TESTS = run_tests
+
+grblkspythondir = $(grpythondir)/gru
+
+grblkspython_PYTHON =          \
+       __init__.py             
+
+
+noinst_PYTHON =                
+
+CLEANFILES = *.pyc *.pyo
diff --git a/gnuradio-core/src/python/gnuradio/gru/__init__.py b/gnuradio-core/src/python/gnuradio/gru/__init__.py
new file mode 100644 (file)
index 0000000..272c7a5
--- /dev/null
@@ -0,0 +1,37 @@
+#
+# 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 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.
+# 
+
+import glob
+import os.path
+
+# Semi-hideous kludge to import everything in the gruimpl directory
+# into the gnuradio.gru namespace.  This keeps us from having to remember 
+# to manually update this file.
+
+for p in __path__:
+    filenames = glob.glob (os.path.join (p, "..", "gruimpl", "*.py"))
+    for f in filenames:
+        f = os.path.basename(f).lower()
+        f = f[:-3]
+        if f == '__init__':
+            continue
+        # print f
+        exec "from gnuradio.gruimpl.%s import *" % (f,)
diff --git a/gnuradio-core/src/python/gnuradio/gruimpl/Makefile.am b/gnuradio-core/src/python/gnuradio/gruimpl/Makefile.am
new file mode 100644 (file)
index 0000000..06eb7a1
--- /dev/null
@@ -0,0 +1,40 @@
+#
+# 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 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.
+# 
+
+include $(top_srcdir)/Makefile.common
+
+grupythondir = $(grpythondir)/gruimpl
+
+grupython_PYTHON =                     \
+       __init__.py                     \
+       crc.py                          \
+       freqz.py                        \
+       gnuplot_freqz.py                \
+       hexint.py                       \
+       listmisc.py                     \
+       mathmisc.py                     \
+       lmx2306.py                      \
+       os_read_exactly.py              \
+       sdr_1000.py                     \
+       seq_with_cursor.py              \
+       socket_stuff.py                 
+
+CLEANFILES = *.pyc
diff --git a/gnuradio-core/src/python/gnuradio/gruimpl/__init__.py b/gnuradio-core/src/python/gnuradio/gruimpl/__init__.py
new file mode 100644 (file)
index 0000000..a4917cf
--- /dev/null
@@ -0,0 +1 @@
+# make this a package
diff --git a/gnuradio-core/src/python/gnuradio/gruimpl/crc.py b/gnuradio-core/src/python/gnuradio/gruimpl/crc.py
new file mode 100644 (file)
index 0000000..6a97c81
--- /dev/null
@@ -0,0 +1,36 @@
+#
+# 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 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.
+# 
+
+from gnuradio import gr
+from hexint import *
+import struct
+
+def gen_and_append_crc32(s):
+    crc = gr.crc32(s)
+    return s + struct.pack(">I", hexint(crc))
+
+def check_crc32(s):
+    msg = s[:-4]
+    #print "msg = '%s'" % (msg,)
+    actual = gr.crc32(msg)
+    (expected,) = struct.unpack(">I", s[-4:])
+    # print "actual =", hex(actual), "expected =", hex(expected)
+    return (actual == expected, msg)
diff --git a/gnuradio-core/src/python/gnuradio/gruimpl/freqz.py b/gnuradio-core/src/python/gnuradio/gruimpl/freqz.py
new file mode 100644 (file)
index 0000000..2170494
--- /dev/null
@@ -0,0 +1,344 @@
+#!/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 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 code lifted from various parts of www.scipy.org -eb 2005-01-24
+
+# Copyright (c) 2001, 2002 Enthought, Inc.
+# 
+# All rights reserved.
+# 
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+# 
+#   a. Redistributions of source code must retain the above copyright notice,
+#      this list of conditions and the following disclaimer.
+#   b. Redistributions in binary form must reproduce the above copyright
+#      notice, this list of conditions and the following disclaimer in the
+#      documentation and/or other materials provided with the distribution.
+#   c. Neither the name of the Enthought nor the names of its contributors
+#      may be used to endorse or promote products derived from this software
+#      without specific prior written permission.
+# 
+# 
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR
+# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+# DAMAGE.
+# 
+
+__all__ = ['freqz']
+
+import Numeric
+from Numeric import *
+Num=Numeric
+
+def atleast_1d(*arys):
+    """ Force a sequence of arrays to each be at least 1D.
+
+         Description:
+            Force an array to be at least 1D.  If an array is 0D, the 
+            array is converted to a single row of values.  Otherwise,
+            the array is unaltered.
+         Arguments:
+            *arys -- arrays to be converted to 1 or more dimensional array.
+         Returns:
+            input array converted to at least 1D array.
+    """
+    res = []
+    for ary in arys:
+        ary = asarray(ary)
+        if len(ary.shape) == 0: 
+            result = Numeric.array([ary[0]])
+        else:
+            result = ary
+        res.append(result)
+    if len(res) == 1:
+        return res[0]
+    else:
+        return res
+
+
+def polyval(p,x):
+    """Evaluate the polynomial p at x.  If x is a polynomial then composition.
+
+    Description:
+
+      If p is of length N, this function returns the value:
+      p[0]*(x**N-1) + p[1]*(x**N-2) + ... + p[N-2]*x + p[N-1]
+
+      x can be a sequence and p(x) will be returned for all elements of x.
+      or x can be another polynomial and the composite polynomial p(x) will be
+      returned.
+    """
+    p = asarray(p)
+    if isinstance(x,poly1d):
+        y = 0
+    else:
+        x = asarray(x)
+        y = Numeric.zeros(x.shape,x.typecode())
+    for i in range(len(p)):
+        y = x * y + p[i]
+    return y
+
+class poly1d:
+    """A one-dimensional polynomial class.
+
+    p = poly1d([1,2,3]) constructs the polynomial x**2 + 2 x + 3
+
+    p(0.5) evaluates the polynomial at the location
+    p.r  is a list of roots
+    p.c  is the coefficient array [1,2,3]
+    p.order is the polynomial order (after leading zeros in p.c are removed)
+    p[k] is the coefficient on the kth power of x (backwards from
+         sequencing the coefficient array.
+
+    polynomials can be added, substracted, multplied and divided (returns
+         quotient and remainder).
+    asarray(p) will also give the coefficient array, so polynomials can
+         be used in all functions that accept arrays.
+    """
+    def __init__(self, c_or_r, r=0):
+        if isinstance(c_or_r,poly1d):
+            for key in c_or_r.__dict__.keys():
+                self.__dict__[key] = c_or_r.__dict__[key]
+            return
+        if r:
+            c_or_r = poly(c_or_r)
+        c_or_r = atleast_1d(c_or_r)
+        if len(c_or_r.shape) > 1:
+            raise ValueError, "Polynomial must be 1d only."
+        c_or_r = trim_zeros(c_or_r, trim='f')
+        if len(c_or_r) == 0:
+            c_or_r = Numeric.array([0])
+        self.__dict__['coeffs'] = c_or_r
+        self.__dict__['order'] = len(c_or_r) - 1
+
+    def __array__(self,t=None):
+        if t:
+            return asarray(self.coeffs,t)
+        else:
+            return asarray(self.coeffs)
+
+    def __coerce__(self,other):
+        return None
+    
+    def __repr__(self):
+        vals = repr(self.coeffs)
+        vals = vals[6:-1]
+        return "poly1d(%s)" % vals
+
+    def __len__(self):
+        return self.order
+
+    def __str__(self):
+        N = self.order
+        thestr = "0"
+        for k in range(len(self.coeffs)):
+            coefstr ='%.4g' % abs(self.coeffs[k])
+            if coefstr[-4:] == '0000':
+                coefstr = coefstr[:-5]
+            power = (N-k)
+            if power == 0:
+                if coefstr != '0':
+                    newstr = '%s' % (coefstr,)
+                else:
+                    if k == 0:
+                        newstr = '0'
+                    else:
+                        newstr = ''
+            elif power == 1:
+                if coefstr == '0':
+                    newstr = ''
+                elif coefstr == '1':
+                    newstr = 'x'
+                else:                    
+                    newstr = '%s x' % (coefstr,)
+            else:
+                if coefstr == '0':
+                    newstr = ''
+                elif coefstr == '1':
+                    newstr = 'x**%d' % (power,)
+                else:                    
+                    newstr = '%s x**%d' % (coefstr, power)
+
+            if k > 0:
+                if newstr != '':
+                    if self.coeffs[k] < 0:
+                        thestr = "%s - %s" % (thestr, newstr)
+                    else:
+                        thestr = "%s + %s" % (thestr, newstr)
+            elif (k == 0) and (newstr != '') and (self.coeffs[k] < 0):
+                thestr = "-%s" % (newstr,)
+            else:
+                thestr = newstr
+        return _raise_power(thestr)
+        
+
+    def __call__(self, val):
+        return polyval(self.coeffs, val)
+
+    def __mul__(self, other):
+        if isscalar(other):
+            return poly1d(self.coeffs * other)
+        else:
+            other = poly1d(other)
+            return poly1d(polymul(self.coeffs, other.coeffs))
+
+    def __rmul__(self, other):
+        if isscalar(other):
+            return poly1d(other * self.coeffs)
+        else:
+            other = poly1d(other)
+            return poly1d(polymul(self.coeffs, other.coeffs))        
+    
+    def __add__(self, other):
+        other = poly1d(other)
+        return poly1d(polyadd(self.coeffs, other.coeffs))        
+        
+    def __radd__(self, other):
+        other = poly1d(other)
+        return poly1d(polyadd(self.coeffs, other.coeffs))
+
+    def __pow__(self, val):
+        if not isscalar(val) or int(val) != val or val < 0:
+            raise ValueError, "Power to non-negative integers only."
+        res = [1]
+        for k in range(val):
+            res = polymul(self.coeffs, res)
+        return poly1d(res)
+
+    def __sub__(self, other):
+        other = poly1d(other)
+        return poly1d(polysub(self.coeffs, other.coeffs))
+
+    def __rsub__(self, other):
+        other = poly1d(other)
+        return poly1d(polysub(other.coeffs, self.coeffs))
+
+    def __div__(self, other):
+        if isscalar(other):
+            return poly1d(self.coeffs/other)
+        else:
+            other = poly1d(other)
+            return map(poly1d,polydiv(self.coeffs, other.coeffs))
+
+    def __rdiv__(self, other):
+        if isscalar(other):
+            return poly1d(other/self.coeffs)
+        else:
+            other = poly1d(other)
+            return map(poly1d,polydiv(other.coeffs, self.coeffs))
+
+    def __setattr__(self, key, val):
+        raise ValueError, "Attributes cannot be changed this way."
+
+    def __getattr__(self, key):
+        if key in ['r','roots']:
+            return roots(self.coeffs)
+        elif key in ['c','coef','coefficients']:
+            return self.coeffs
+        elif key in ['o']:
+            return self.order
+        else:
+            return self.__dict__[key]
+        
+    def __getitem__(self, val):
+        ind = self.order - val
+        if val > self.order:
+            return 0
+        if val < 0:
+            return 0
+        return self.coeffs[ind]
+
+    def __setitem__(self, key, val):
+        ind = self.order - key
+        if key < 0:
+            raise ValueError, "Does not support negative powers."
+        if key > self.order:
+            zr = Numeric.zeros(key-self.order,self.coeffs.typecode())
+            self.__dict__['coeffs'] = Numeric.concatenate((zr,self.coeffs))
+            self.__dict__['order'] = key
+            ind = 0
+        self.__dict__['coeffs'][ind] = val
+        return
+
+    def integ(self, m=1, k=0):
+        return poly1d(polyint(self.coeffs,m=m,k=k))
+
+    def deriv(self, m=1):
+        return poly1d(polyder(self.coeffs,m=m))
+
+def freqz(b, a, worN=None, whole=0, plot=None):
+    """Compute frequency response of a digital filter.
+
+    Description:
+
+       Given the numerator (b) and denominator (a) of a digital filter compute
+       its frequency response.
+
+                  jw               -jw            -jmw
+           jw  B(e)    b[0] + b[1]e + .... + b[m]e
+        H(e) = ---- = ------------------------------------
+                  jw               -jw            -jnw
+               A(e)    a[0] + a[2]e + .... + a[n]e             
+
+    Inputs:
+
+       b, a --- the numerator and denominator of a linear filter.
+       worN --- If None, then compute at 512 frequencies around the unit circle.
+                If a single integer, the compute at that many frequencies.
+                Otherwise, compute the response at frequencies given in worN
+       whole -- Normally, frequencies are computed from 0 to pi (upper-half of
+                unit-circle.  If whole is non-zero compute frequencies from 0
+                to 2*pi.
+
+    Outputs: (h,w)
+
+       h -- The frequency response.
+       w -- The frequencies at which h was computed.
+    """
+    b, a = map(atleast_1d, (b,a))
+    if whole:
+        lastpoint = 2*pi
+    else:
+        lastpoint = pi
+    if worN is None:
+        N = 512
+        w = Num.arange(0,lastpoint,lastpoint/N)
+    elif isinstance(worN, types.IntType):
+        N = worN
+        w = Num.arange(0,lastpoint,lastpoint/N)
+    else:
+        w = worN
+    w = atleast_1d(w)
+    zm1 = exp(-1j*w)
+    h = polyval(b[::-1], zm1) / polyval(a[::-1], zm1)
+    # if not plot is None:
+    #    plot(w, h)
+    return h, w
diff --git a/gnuradio-core/src/python/gnuradio/gruimpl/gnuplot_freqz.py b/gnuradio-core/src/python/gnuradio/gruimpl/gnuplot_freqz.py
new file mode 100755 (executable)
index 0000000..5a11760
--- /dev/null
@@ -0,0 +1,82 @@
+#!/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 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.
+# 
+
+__all__ = ['gnuplot_freqz']
+
+import tempfile
+import os
+import math
+import Numeric
+
+from gnuradio import gr
+from gnuradio.gruimpl.freqz import freqz
+
+
+def gnuplot_freqz (hw, Fs=None, logfreq=False):
+
+    """hw is a tuple of the form (h, w) where h is sequence of complex
+    freq responses, and w is a sequence of corresponding frequency
+    points.  Plot the frequency response using gnuplot.  If Fs is
+    provide, use it as the sampling frequency, else use 2*pi.
+
+    Returns a handle to the gnuplot graph. When the handle is reclaimed
+    the graph is torn down."""
+    
+    data_file = tempfile.NamedTemporaryFile ()
+    cmd_file = os.popen ('gnuplot', 'w')
+
+    h, w = hw
+    ampl = 20 * Numeric.log10 (Numeric.absolute (h) + 1e-9)
+    phase = map (lambda x: math.atan2 (x.imag, x.real), h)
+    
+    if Fs:
+        w *= (Fs/(2*math.pi))
+
+    for freq, a, ph in zip (w, ampl, phase):
+        data_file.write ("%g\t%g\t%g\n" % (freq, a, ph))
+
+    data_file.flush ()
+
+    cmd_file.write ("set grid\n")
+    if logfreq:
+        cmd_file.write ("set logscale x\n")
+    else:
+        cmd_file.write ("unset logscale x\n")
+    cmd_file.write ("plot '%s' using 1:2 with lines\n" % (data_file.name,))
+    cmd_file.flush ()
+    
+    return (cmd_file, data_file)
+
+
+def test_plot ():
+    sample_rate = 2.0e6
+    taps = gr.firdes.low_pass (1.0,           # gain
+                               sample_rate,   # sampling rate
+                               200e3,         # low pass cutoff freq
+                               100e3,         # width of trans. band
+                               gr.firdes.WIN_HAMMING)
+    # print len (taps)
+    return gnuplot_freqz (freqz (taps, 1), sample_rate)
+
+if __name__ == '__main__':
+    handle = test_plot ()
+    raw_input ('Press Enter to continue: ')
diff --git a/gnuradio-core/src/python/gnuradio/gruimpl/hexint.py b/gnuradio-core/src/python/gnuradio/gruimpl/hexint.py
new file mode 100644 (file)
index 0000000..1220755
--- /dev/null
@@ -0,0 +1,32 @@
+#
+# 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 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.
+# 
+
+def hexint(mask):
+  """
+  Convert unsigned masks into signed ints.
+
+  This allows us to use hex constants like 0xf0f0f0f2 when talking to
+  our hardware and not get screwed by them getting treated as python
+  longs.
+  """
+  if mask >= 2**31:
+     return int(mask-2**32)
+  return mask
diff --git a/gnuradio-core/src/python/gnuradio/gruimpl/listmisc.py b/gnuradio-core/src/python/gnuradio/gruimpl/listmisc.py
new file mode 100644 (file)
index 0000000..857e417
--- /dev/null
@@ -0,0 +1,29 @@
+#
+# 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 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.
+# 
+
+def list_reverse(x):
+    """
+    Return a copy of x that is reverse order.
+    """
+    r = list(x)
+    r.reverse()
+    return r
+
diff --git a/gnuradio-core/src/python/gnuradio/gruimpl/lmx2306.py b/gnuradio-core/src/python/gnuradio/gruimpl/lmx2306.py
new file mode 100755 (executable)
index 0000000..b46c896
--- /dev/null
@@ -0,0 +1,186 @@
+#!/usr/bin/env 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.
+# 
+
+'''Control National LMX2306 based frequency synthesizer'''
+
+from gnuradio import gr
+from gnuradio import eng_notation
+from gnuradio.eng_option import eng_option
+from optparse import OptionParser
+
+# bottom two bits of 21 bit word select which register to program
+
+R_REG =  0x0
+AB_REG = 0x1
+F_REG  = 0x2
+
+F_counter_reset = (1 << 2)
+F_phase_detector_polarity = (1 << 7)
+
+F_LD_tri_state           = (0 << 4)
+F_LD_R_divider_output    = (4 << 4)
+F_LD_N_divider_output    = (2 << 4)
+F_LD_serial_data_output  = (6 << 4)
+F_LD_digital_lock_detect = (1 << 4)
+F_LD_open_drain          = (5 << 4)
+F_LD_high                = (3 << 4)
+F_LD_low                 = (7 << 4)
+
+# F_default = F_LD_digital_lock_detect | F_phase_detector_polarity
+F_default = F_LD_open_drain | F_phase_detector_polarity
+
+#
+# 4 control pins:
+#   CE   always high
+#   LE   load enable.  When LE goes high, data stored in the shift register
+#        is loaded into one of the three registers
+#   CLK  data is clocked in on the rising edge
+#   DATA single data bit.  Entered MSB first
+
+DB_CLK =  (1 << 0)
+DB_DATA = (1 << 1)
+DB_LE =   (1 << 2)
+DB_CE =   (1 << 3)
+
+class lmx2306 (object):
+    '''Control the National LMX2306 PLL'''
+    __slots__ = ['pp', 'shadow', 'fosc', 'r', 'step_size', 'verbose']
+    def __init__ (self, fosc, step_size, which_pp = 0):
+        '''FOSC is the frequency of the reference oscillator,
+        STEP_SIZE is the step between valid frequencies,
+        WHICH_PP specifies which parallel port to use
+        '''
+        self.pp = gr.make_ppio (which_pp)
+        self.shadow = DB_CE
+        self.pp.lock ()
+        self.pp.write_data (self.shadow)
+        self.pp.unlock ()
+        self.verbose = False
+        self._set_fosc (fosc)
+        self._set_step (step_size)
+
+        
+    def program (self, r, a, b):
+        if self.verbose:
+            print "lmx2306: r = %d  a = %d  b = %d" % (r, a, b)
+        self.pp.lock ()
+        self._write_word (F_REG | F_default | F_counter_reset)
+        self._write_word (R_REG | ((r & 0x3fff) << 2))
+        self._write_word (AB_REG | ((a & 0x1f) << 2) | ((b & 0x1fff) << 7))
+        self._write_word (F_REG | F_default)
+        self.pp.unlock ()
+
+    def set_freq (self, freq):
+        '''Set the PLL frequency to FREQ
+
+        Return the actual freq value set.  It will be rounded down to a
+        multiple of step_size
+        '''
+        divisor = int (freq / self.step_size)
+        actual = divisor * self.step_size
+        (a, b) = self._compute_ab (divisor)
+        self.program (self.r, a, b)
+        return actual
+
+    # ----------------------------------------------------------------
+    
+    def _set_fosc (self, ref_oscillator_freq):
+        self.fosc = ref_oscillator_freq
+        
+    def _set_step (self, step_size):
+        r = int (self.fosc / step_size)
+        if r * step_size != self.fosc:
+            raise ValueError, "step_size is not a factor of self.fosc"
+        if r < 3 or r > 16383:
+            raise ValueError, "r is out of range"
+        self.r = r
+        self.step_size = step_size
+        
+    def _compute_ab (self, divisor):
+        b = divisor / 8
+        a = divisor - (b * 8)
+        if b < 3 or b > 8191 or a > b:
+            raise ValueError, "Invalid divisor"
+        return (a, b)
+
+    def _write_word (self, w):
+        for i in range(21):
+            if w & (1 << 20):
+                self._set_DATA_1 ()
+            else:
+                self._set_DATA_0 ()
+            w = (w << 1) & 0x0ffffff
+            self._set_CLK_1 ()
+            self._set_CLK_0 ()
+        self._set_LE_1 ()
+        self._set_LE_0 ()
+
+    def _set_LE_0 (self):
+        self.shadow = self.shadow & ~DB_LE
+        self.pp.write_data (self.shadow)
+
+    def _set_LE_1 (self):
+        self.shadow = self.shadow | DB_LE
+        self.pp.write_data (self.shadow)
+
+    def _set_CLK_0 (self):
+        self.shadow = self.shadow & ~DB_CLK
+        self.pp.write_data (self.shadow)
+
+    def _set_CLK_1 (self):
+        self.shadow = self.shadow | DB_CLK
+        self.pp.write_data (self.shadow)
+
+    def _set_DATA_0 (self):
+        self.shadow = self.shadow & ~DB_DATA
+        self.pp.write_data (self.shadow)
+
+    def _set_DATA_1 (self):
+        self.shadow = self.shadow | DB_DATA
+        self.pp.write_data (self.shadow)
+
+if __name__ == '__main__':
+    parser = OptionParser (option_class=eng_option)
+    parser.add_option ("-o", "--fosc", type="eng_float", default=32e6,
+                       help="set reference oscillator freq to FREQ", metavar="FREQ")
+    parser.add_option ("-s", "--step-size", type="eng_float", default=10e3,
+                       help="set the frequency step size to STEP_SIZE")
+    parser.add_option ("-f", "--freq", type="eng_float", default=430e6,
+                       help="set VCO frequency to FREQ")
+    parser.add_option ("-v", "--verbose", action="store_true", default=False)
+    (options, args) = parser.parse_args ()
+
+    if options.verbose:
+        print "fosc = %s  step = %s  fvco = %s" % (
+            eng_notation.num_to_str (options.fosc),
+            eng_notation.num_to_str (options.step_size),
+            eng_notation.num_to_str (options.freq))
+    
+    lmx = lmx2306 (options.fosc, options.step_size)
+    lmx.verbose = options.verbose
+
+    actual = lmx.set_freq (options.freq)
+
+    if options.verbose:
+        print "fvco_actual = %s  delta = %s" % (
+            eng_notation.num_to_str (actual),
+            eng_notation.num_to_str (options.freq - actual))
diff --git a/gnuradio-core/src/python/gnuradio/gruimpl/mathmisc.py b/gnuradio-core/src/python/gnuradio/gruimpl/mathmisc.py
new file mode 100644 (file)
index 0000000..13e6de8
--- /dev/null
@@ -0,0 +1,33 @@
+#
+# 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 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.
+# 
+
+import math
+
+def gcd(a,b):
+    while b:
+        a,b = b, a % b
+    return a
+
+def lcm(a,b):
+    return a * b / gcd(a, b)
+
+def log2(x):
+    return math.log(x)/math.log(2)
diff --git a/gnuradio-core/src/python/gnuradio/gruimpl/os_read_exactly.py b/gnuradio-core/src/python/gnuradio/gruimpl/os_read_exactly.py
new file mode 100644 (file)
index 0000000..afdfb51
--- /dev/null
@@ -0,0 +1,36 @@
+#
+# 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 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.
+# 
+
+import os
+
+def os_read_exactly(file_descriptor, nbytes):
+    """
+    Replacement for os.read that blocks until it reads exactly nbytes.
+
+    """
+    s = ''
+    while nbytes > 0:
+        sbuf = os.read(file_descriptor, nbytes)
+        if not(sbuf):
+            return ''
+        nbytes -= len(sbuf)
+        s = s + sbuf
+    return s
diff --git a/gnuradio-core/src/python/gnuradio/gruimpl/sdr_1000.py b/gnuradio-core/src/python/gnuradio/gruimpl/sdr_1000.py
new file mode 100644 (file)
index 0000000..5de23b7
--- /dev/null
@@ -0,0 +1,84 @@
+#
+# Copyright 2003,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.
+# 
+
+from gnuradio import gr
+
+class sdr_1000 (gr.sdr_1000_base):
+    "Control the DDS on the SDR-1000"
+    def __init__(self, pport = 0):
+       gr.sdr_1000_base.__init__(self, pport)
+        self.write_latch (3, 0x00, 0xC0) # Reset low, WRS/ low
+        self.write_reg (0x20, 0x40)
+
+    def write_reg(self, addr, data):
+        self.write_latch (3, addr & 0x3f, 0x3f)
+        self.write_latch (2, data, 0xff)
+        self.write_latch (3, 0x40, 0x40)
+        self.write_latch (3, 0x00, 0x40)
+    
+    def set_freq(self, freq):
+        self.set_band (freq)
+        ftw = freq / 200e6;
+        for i in xrange(6):
+            word = int(ftw * 256)
+            ftw = ftw*256 - word
+            # print (('%d [%02x]') % (i, word))
+            self.write_reg (4+i, word)
+
+    def set_band (self, freq):
+        if freq <= 2.25e6:
+            band = 0
+        elif freq <= 5.5e6:
+            band = 1
+        elif freq <= 11e6:
+            band = 3   # due to wiring mistake on board
+        elif freq <= 22e6:
+            band = 2   # due to wiring mistake on board
+        elif freq <= 37.5e6:
+            band = 4
+        else:
+            band = 5
+        
+        self.write_latch (1, 1 << band, 0x3f)
+
+    def set_bit (self, reg, bit, state):
+        val = 0x00
+        if state: val = 1<<bit
+        self.write_latch (reg, val, 1<<bit)
+        
+    def set_tx (self, on = 1):
+        self.set_bit(1, 6, on)
+
+    def set_rx (self):
+        self.set_bit(1, 6, 0)
+    
+    def set_gain (self, high):
+        self.set_bit(0, 7, high)
+      
+    def set_mute (self, mute = 1):
+        self.set_bit(1, 7, mute)
+
+    def set_unmute (self):
+        self.set_bit(1, 7, 0)
+
+    def set_external_pin (self, pin, on = 1):
+        assert (pin < 8 and pin > 0), "Out of range 1..7"
+        self.set_bit(0, pin-1, on)
diff --git a/gnuradio-core/src/python/gnuradio/gruimpl/seq_with_cursor.py b/gnuradio-core/src/python/gnuradio/gruimpl/seq_with_cursor.py
new file mode 100644 (file)
index 0000000..5616dea
--- /dev/null
@@ -0,0 +1,77 @@
+#
+# Copyright 2003,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.
+# 
+
+# misc utilities
+
+import types
+import exceptions
+
+class seq_with_cursor (object):
+    __slots__ = [ 'items', 'index' ]
+
+    def __init__ (self, items, initial_index = None, initial_value = None):
+        assert len (items) > 0, "seq_with_cursor: len (items) == 0"
+        self.items = items
+        self.set_index (initial_index)
+        if initial_value is not None:
+            self.set_index_by_value(initial_value)
+
+    def set_index (self, initial_index):
+        if initial_index is None:
+            self.index = len (self.items) / 2
+        elif initial_index >= 0 and initial_index < len (self.items):
+            self.index = initial_index
+        else:
+            raise exceptions.ValueError
+        
+    def set_index_by_value(self, v):
+        """
+        Set index to the smallest value such that items[index] >= v.
+        If there is no such item, set index to the maximum value.
+        """
+        self.set_index(0)              # side effect!
+        cv = self.current()
+        more = True
+        while cv < v and more:
+            cv, more = self.next()      # side effect!
+        
+    def next (self):
+        new_index = self.index + 1
+        if new_index < len (self.items):
+            self.index = new_index
+            return self.items[new_index], True
+        else:
+            return self.items[self.index], False
+
+    def prev (self):
+        new_index = self.index - 1
+        if new_index >= 0:
+            self.index = new_index
+            return self.items[new_index], True
+        else:
+            return self.items[self.index], False
+
+    def current (self):
+        return self.items[self.index]
+
+    def get_seq (self):
+        return self.items[:]            # copy of items
+    
diff --git a/gnuradio-core/src/python/gnuradio/gruimpl/socket_stuff.py b/gnuradio-core/src/python/gnuradio/gruimpl/socket_stuff.py
new file mode 100644 (file)
index 0000000..05be0d4
--- /dev/null
@@ -0,0 +1,56 @@
+#
+# 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 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.
+# 
+
+# random socket related stuff
+
+import socket
+import os
+import sys
+
+def tcp_connect_or_die(sock_addr):
+    """
+    @param sock_addr: (host, port) to connect to
+    @type sock_addr: tuple
+    @returns: socket or exits
+    """
+    s = socket.socket (socket.AF_INET, socket.SOCK_STREAM)
+    try:
+        s.connect(sock_addr)
+    except socket.error, err:
+        sys.stderr.write('Failed to connect to %s: %s\n' %
+                         (sock_addr, os.strerror (err.args[0]),))
+        sys.exit(1)
+    return s
+
+def udp_connect_or_die(sock_addr):
+    """
+    @param sock_addr: (host, port) to connect to
+    @type sock_addr: tuple
+    @returns: socket or exits
+    """
+    s = socket.socket (socket.AF_INET, socket.SOCK_DGRAM)
+    try:
+        s.connect(sock_addr)
+    except socket.error, err:
+        sys.stderr.write('Failed to connect to %s: %s\n' %
+                         (sock_addr, os.strerror (err.args[0]),))
+        sys.exit(1)
+    return s
diff --git a/gnuradio-core/src/python/gnuradio/optfir.py b/gnuradio-core/src/python/gnuradio/optfir.py
new file mode 100644 (file)
index 0000000..eb3f321
--- /dev/null
@@ -0,0 +1,242 @@
+#
+# 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 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.
+# 
+
+'''
+Routines for designing optimal FIR filters.
+
+For a great intro to how all this stuff works, see section 6.6 of
+"Digital Signal Processing: A Practical Approach", Emmanuael C. Ifeachor
+and Barrie W. Jervis, Adison-Wesley, 1993.  ISBN 0-201-54413-X.
+'''
+
+import math
+from gnuradio import gr
+
+remez = gr.remez
+
+# ----------------------------------------------------------------
+
+def low_pass (gain, Fs, freq1, freq2, passband_ripple_db, stopband_atten_db,
+              nextra_taps=0):
+    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)
+    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"""
+    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)
+    taps = gr.remez (n + nextra_taps, fo, ao, w, "bandpass")
+    return taps
+
+# ----------------------------------------------------------------
+
+def stopband_atten_to_dev (atten_db):
+    """Convert a stopband attenuation in dB to an absolute value"""
+    return 10**(-atten_db/20)
+
+def passband_ripple_to_dev (ripple_db):
+    """Convert passband ripple spec expressed in dB to an absolute value"""
+    return (10**(ripple_db/20)-1)/(10**(ripple_db/20)+1)
+
+# ----------------------------------------------------------------
+
+def remezord (fcuts, mags, devs, fsamp = 2):
+    '''
+    FIR order estimator (lowpass, highpass, bandpass, mulitiband).
+
+    (n, fo, ao, w) = remezord (f, a, dev)
+    (n, fo, ao, w) = remezord (f, a, dev, fs)
+
+    (n, fo, ao, w) = remezord (f, a, dev) finds the approximate order,
+    normalized frequency band edges, frequency band amplitudes, and
+    weights that meet input specifications f, a, and dev, to use with
+    the remez command.
+
+    * f is a sequence of frequency band edges (between 0 and Fs/2, where
+      Fs is the sampling frequency), and a is a sequence specifying the
+      desired amplitude on the bands defined by f. The length of f is
+      twice the length of a, minus 2. The desired function is
+      piecewise constant.
+
+    * dev is a sequence the same size as a that specifies the maximum
+      allowable deviation or ripples between the frequency response
+      and the desired amplitude of the output filter, for each band.
+
+    Use remez with the resulting order n, frequency sequence fo,
+    amplitude response sequence ao, and weights w to design the filter b
+    which approximately meets the specifications given by remezord
+    input parameters f, a, and dev:
+
+    b = remez (n, fo, ao, w)
+
+    (n, fo, ao, w) = remezord (f, a, dev, Fs) specifies a sampling frequency Fs.
+
+    Fs defaults to 2 Hz, implying a Nyquist frequency of 1 Hz. You can
+    therefore specify band edges scaled to a particular applications
+    sampling frequency.
+
+    In some cases remezord underestimates the order n. If the filter
+    does not meet the specifications, try a higher order such as n+1
+    or n+2.
+    '''
+    # get local copies
+    fcuts = fcuts[:]
+    mags = mags[:]
+    devs = devs[:]
+    
+    for i in range (len (fcuts)):
+        fcuts[i] = float (fcuts[i]) / fsamp
+
+    nf = len (fcuts)
+    nm = len (mags)
+    nd = len (devs)
+    nbands = nm
+
+    if nm != nd:
+        raise ValueError, "Length of mags and devs must be equal"
+
+    if nf != 2 * (nbands - 1):
+        raise ValueError, "Length of f must be 2 * len (mags) - 2"
+    
+    for i in range (len (mags)):
+        if mags[i] != 0:                        # if not stopband, get relative deviation
+            devs[i] = devs[i] / mags[i]
+        
+    # separate the passband and stopband edges
+    f1 = fcuts[0::2]
+    f2 = fcuts[1::2]
+
+    n = 0
+    min_delta = 2
+    for i in range (len (f1)):
+        if f2[i] - f1[i] < min_delta:
+            n = i
+            min_delta = f2[i] - f1[i]
+
+    if nbands == 2:
+        # lowpass or highpass case (use formula)
+        l = lporder (f1[n], f2[n], devs[0], devs[1])
+    else:
+        # bandpass or multipass case
+        # try different lowpasses and take the worst one that
+        #  goes through the BP specs
+        l = 0
+        for i in range (1, nbands-1):
+            l1 = lporder (f1[i-1], f2[i-1], devs[i], devs[i-1])
+            l2 = lporder (f1[i], f2[i], devs[i], devs[i+1])
+            l = max (l, l1, l2)
+
+    n = int (math.ceil (l)) - 1               # need order, not length for remez
+    
+    # cook up remez compatible result
+    ff = [0] + fcuts + [1]
+    for i in range (1, len (ff) - 1):
+        ff[i] *= 2
+
+    aa = []
+    for a in mags:
+        aa = aa + [a, a]
+
+    max_dev = max (devs)
+    wts = [1] * len(devs)
+    for i in range (len (wts)):
+        wts[i] = max_dev / devs[i]
+
+    return (n, ff, aa, wts)
+
+# ----------------------------------------------------------------
+
+def lporder (freq1, freq2, delta_p, delta_s):
+    '''
+    FIR lowpass filter length estimator.  freq1 and freq2 are
+    normalized to the sampling frequency.  delta_p is the passband
+    deviation (ripple), delta_s is the stopband deviation (ripple).
+
+    Note, this works for high pass filters too (freq1 > freq2), but
+    doesnt work well if the transition is near f == 0 or f == fs/2
+
+    From Herrmann et al (1973), Practical design rules for optimum
+    finite impulse response filters.  Bell System Technical J., 52, 769-99
+    '''
+    df = abs (freq2 - freq1)
+    ddp = math.log10 (delta_p)
+    dds = math.log10 (delta_s)
+
+    a1 = 5.309e-3
+    a2 = 7.114e-2
+    a3 = -4.761e-1
+    a4 = -2.66e-3
+    a5 = -5.941e-1
+    a6 = -4.278e-1
+
+    b1 = 11.01217
+    b2 = 0.5124401
+
+    t1 = a1 * ddp * ddp
+    t2 = a2 * ddp
+    t3 = a4 * ddp * ddp
+    t4 = a5 * ddp
+
+    dinf=((t1 + t2 + a3) * dds) + (t3 + t4 + a6)
+    ff = b1 + b2 * (ddp - dds)
+    n = dinf / df - ff * df + 1
+    return n
+
+
+def bporder (freq1, freq2, delta_p, delta_s):
+    '''
+    FIR bandpass filter length estimator.  freq1 and freq2 are
+    normalized to the sampling frequency.  delta_p is the passband
+    deviation (ripple), delta_s is the stopband deviation (ripple).
+
+    From Mintzer and Liu (1979)
+    '''
+    df = abs (freq2 - freq1)
+    ddp = math.log10 (delta_p)
+    dds = math.log10 (delta_s)
+
+    a1 = 0.01201
+    a2 = 0.09664
+    a3 = -0.51325
+    a4 = 0.00203
+    a5 = -0.57054
+    a6 = -0.44314
+
+    t1 = a1 * ddp * ddp
+    t2 = a2 * ddp
+    t3 = a4 * ddp * ddp
+    t4 = a5 * ddp
+
+    cinf = dds * (t1 + t2 + a3) + t3 + t4 + a6
+    ginf = -14.6 * math.log10 (delta_p / delta_s) - 16.9
+    n = cinf / df + ginf * df + 1
+    return n
+
diff --git a/gnuradio-core/src/python/gnuradio/packet_utils.py b/gnuradio-core/src/python/gnuradio/packet_utils.py
new file mode 100644 (file)
index 0000000..d723554
--- /dev/null
@@ -0,0 +1,433 @@
+#
+# 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 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.
+# 
+
+import struct
+import Numeric
+from gnuradio import gru
+
+
+def conv_packed_binary_string_to_1_0_string(s):
+    """
+    '\xAF' --> '10101111'
+    """
+    r = []
+    for ch in s:
+        x = ord(ch)
+        for i in range(7,-1,-1):
+            t = (x >> i) & 0x1
+            r.append(t)
+
+    return ''.join(map(lambda x: chr(x + ord('0')), r))
+
+def conv_1_0_string_to_packed_binary_string(s):
+    """
+    '10101111' -> ('\xAF', False)
+
+    Basically the inverse of conv_packed_binary_string_to_1_0_string,
+    but also returns a flag indicating if we had to pad with leading zeros
+    to get to a multiple of 8.
+    """
+    if not is_1_0_string(s):
+        raise ValueError, "Input must be a string containing only 0's and 1's"
+    
+    # pad to multiple of 8
+    padded = False
+    rem = len(s) % 8
+    if rem != 0:
+        npad = 8 - rem
+        s = '0' * npad + s
+        padded = True
+
+    assert len(s) % 8 == 0
+
+    r = []
+    i = 0
+    while i < len(s):
+        t = 0
+        for j in range(8):
+            t = (t << 1) | (ord(s[i + j]) - ord('0'))
+        r.append(chr(t))
+        i += 8
+    return (''.join(r), padded)
+        
+
+default_access_code = \
+  conv_packed_binary_string_to_1_0_string('\xAC\xDD\xA4\xE2\xF2\x8C\x20\xFC')
+
+
+def is_1_0_string(s):
+    if not isinstance(s, str):
+        return False
+    for ch in s:
+        if not ch in ('0', '1'):
+            return False
+    return True
+
+def string_to_hex_list(s):
+    return map(lambda x: hex(ord(x)), s)
+
+
+def whiten(s):
+    sa = Numeric.fromstring(s, Numeric.UnsignedInt8)
+    z = sa ^ random_mask_vec8[0:len(sa)]
+    return z.tostring()
+
+def dewhiten(s):
+    return whiten(s)        # self inverse
+
+
+def make_header(payload_len):
+    return struct.pack('!HH', payload_len, payload_len)
+
+def make_packet(payload, spb, bits_per_baud, access_code=default_access_code, pad_for_usrp=True):
+    """
+    Build a packet, given access code and payload.
+
+    @param payload:       packet payload, len [0, 4096]
+    @param spb:           samples per baud (needed for padding calculation)
+    @type  spb:           int
+    @param bits_per_baud: (needed for padding calculation)
+    @type bits_per_baud:  int
+    @param access_code:   string of ascii 0's and 1's
+    
+    Packet will have access code at the beginning, followed by length, payload
+    and finally CRC-32.
+    """
+    if not is_1_0_string(access_code):
+        raise ValueError, "access_code must be a string containing only 0's and 1's (%r)" % (access_code,)
+
+    (packed_access_code, padded) = conv_1_0_string_to_packed_binary_string(access_code)
+    
+    payload_with_crc = gru.gen_and_append_crc32(payload)
+    #print "outbound crc =", string_to_hex_list(payload_with_crc[-4:])
+
+    L = len(payload_with_crc)
+    MAXLEN = len(random_mask_tuple)
+    if L > MAXLEN:
+        raise ValueError, "len(payload) must be in [0, %d]" % (MAXLEN,)
+
+    pkt = ''.join((packed_access_code, make_header(L), whiten(payload_with_crc), '\x55'))
+    if pad_for_usrp:
+        pkt = pkt + (_npadding_bytes(len(pkt), spb, bits_per_baud) * '\x55')
+
+    #print "make_packet: len(pkt) =", len(pkt)
+    return pkt
+
+def _npadding_bytes(pkt_byte_len, spb, bits_per_baud):
+    """
+    Generate sufficient padding such that each packet ultimately ends
+    up being a multiple of 512 bytes when sent across the USB.  We
+    send 4-byte samples across the USB (16-bit I and 16-bit Q), thus
+    we want to pad so that after modulation the resulting packet
+    is a multiple of 128 samples.
+
+    @param ptk_byte_len: len in bytes of packet, not including padding.
+    @param spb: samples per baud == samples per bit (1 bit / baud with GMSK)
+    @type spb: int
+
+    @returns number of bytes of padding to append.
+    """
+    modulus = 128
+    byte_modulus = gru.lcm(modulus/8, spb) * bits_per_baud / spb
+    r = pkt_byte_len % byte_modulus
+    if r == 0:
+        return 0
+    return byte_modulus - r
+    
+
+def unmake_packet(whitened_payload_with_crc):
+    """
+    Return (ok, payload)
+
+    @param whitened_payload_with_crc: string
+    """
+    payload_with_crc = dewhiten(whitened_payload_with_crc)
+    ok, payload = gru.check_crc32(payload_with_crc)
+
+    if 0:
+        print "payload_with_crc =", string_to_hex_list(payload_with_crc)
+        print "ok = %r, len(payload) = %d" % (ok, len(payload))
+        print "payload =", string_to_hex_list(payload)
+
+    return ok, payload
+
+
+# FYI, this PN code is the output of a 15-bit LFSR
+random_mask_tuple = (
+  255,  63,   0,  16,   0,  12,   0,   5, 192,   3,  16,   1, 204,   0,  85, 192, 
+   63,  16,  16,  12,  12,   5, 197, 195,  19,  17, 205, 204,  85, 149, 255,  47, 
+    0,  28,   0,   9, 192,   6, 208,   2, 220,   1, 153, 192, 106, 208,  47,  28, 
+   28,   9, 201, 198, 214, 210, 222, 221, 152,  89, 170, 186, 255,  51,   0,  21, 
+  192,  15,  16,   4,  12,   3,  69, 193, 243,  16,  69, 204,  51,  21, 213, 207, 
+   31,  20,   8,  15,  70, 132,  50, 227,  85, 137, 255,  38, 192,  26, 208,  11, 
+   28,   7,  73, 194, 182, 209, 182, 220, 118, 217, 230, 218, 202, 219,  23,  27, 
+   78, 139, 116, 103, 103, 106, 170, 175,  63,  60,  16,  17, 204,  12,  85, 197, 
+  255,  19,   0,  13, 192,   5, 144,   3,  44,   1, 221, 192,  89, 144,  58, 236, 
+   19,  13, 205, 197, 149, 147,  47,  45, 220,  29, 153, 201, 170, 214, 255,  30, 
+  192,   8,  80,   6, 188,   2, 241, 193, 132,  80,  99, 124,  41, 225, 222, 200, 
+   88,  86, 186, 190, 243,  48,  69, 212,  51,  31,  85, 200,  63,  22, 144,  14, 
+  236,   4,  77, 195, 117, 145, 231,  44,  74, 157, 247,  41, 134, 158, 226, 232, 
+   73, 142, 182, 228, 118, 203, 102, 215, 106, 222, 175,  24, 124,  10, 161, 199, 
+   56,  82, 146, 189, 173, 177, 189, 180, 113, 183, 100, 118, 171, 102, 255, 106, 
+  192,  47,  16,  28,  12,   9, 197, 198, 211,  18, 221, 205, 153, 149, 170, 239, 
+   63,  12,  16,   5, 204,   3,  21, 193, 207,  16,  84,  12,  63,  69, 208,  51, 
+   28,  21, 201, 207,  22, 212,  14, 223,  68,  88,  51, 122, 149, 227,  47,   9, 
+  220,   6, 217, 194, 218, 209, 155,  28, 107,  73, 239, 118, 204,  38, 213, 218, 
+  223,  27,  24,  11,  74, 135, 119,  34, 166, 153, 186, 234, 243,  15,   5, 196, 
+    3,  19,  65, 205, 240,  85, 132,  63,  35,  80,  25, 252,  10, 193, 199,  16, 
+   82, 140,  61, 165, 209, 187,  28, 115,  73, 229, 246, 203,   6, 215,  66, 222, 
+  177, 152, 116, 106, 167, 111,  58, 172,  19,  61, 205, 209, 149, 156, 111,  41, 
+  236,  30, 205, 200,  85, 150, 191,  46, 240,  28,  68,   9, 243,  70, 197, 242, 
+  211,   5, 157, 195,  41, 145, 222, 236,  88,  77, 250, 181, 131,  55,  33, 214, 
+  152,  94, 234, 184,  79,  50, 180,  21, 183,  79,  54, 180,  22, 247,  78, 198, 
+  180,  82, 247, 125, 134, 161, 162, 248, 121, 130, 162, 225, 185, 136, 114, 230, 
+  165, 138, 251,  39,   3,  90, 129, 251,  32,  67,  88,  49, 250, 148,  67,  47, 
+  113, 220,  36,  89, 219, 122, 219,  99,  27, 105, 203, 110, 215, 108,  94, 173, 
+  248, 125, 130, 161, 161, 184, 120, 114, 162, 165, 185, 187,  50, 243,  85, 133, 
+  255,  35,   0,  25, 192,  10, 208,   7,  28,   2, 137, 193, 166, 208, 122, 220, 
+   35,  25, 217, 202, 218, 215,  27,  30, 139,  72, 103, 118, 170, 166, 255,  58, 
+  192,  19,  16,  13, 204,   5, 149, 195,  47,  17, 220,  12,  89, 197, 250, 211, 
+    3,  29, 193, 201, 144,  86, 236,  62, 205, 208,  85, 156,  63,  41, 208,  30, 
+  220,   8,  89, 198, 186, 210, 243,  29, 133, 201, 163,  22, 249, 206, 194, 212, 
+   81, 159, 124, 104,  33, 238, 152,  76, 106, 181, 239,  55,  12,  22, 133, 206, 
+  227,  20,  73, 207, 118, 212,  38, 223,  90, 216,  59,  26, 147,  75,  45, 247, 
+   93, 134, 185, 162, 242, 249, 133, 130, 227,  33, 137, 216, 102, 218, 170, 219, 
+   63,  27,  80,  11, 124,   7,  97, 194, 168,  81, 190, 188, 112, 113, 228,  36, 
+   75,  91, 119, 123, 102, 163, 106, 249, 239,   2, 204,   1, 149, 192, 111,  16, 
+   44,  12,  29, 197, 201, 147,  22, 237, 206, 205, 148,  85, 175, 127,  60,  32, 
+   17, 216,  12,  90, 133, 251,  35,   3,  89, 193, 250, 208,  67,  28,  49, 201, 
+  212,  86, 223, 126, 216,  32,  90, 152,  59,  42, 147,  95,  45, 248,  29, 130, 
+  137, 161, 166, 248, 122, 194, 163,  17, 185, 204, 114, 213, 229, 159,  11,  40, 
+    7,  94, 130, 184,  97, 178, 168, 117, 190, 167,  48, 122, 148,  35,  47,  89, 
+  220,  58, 217, 211,  26, 221, 203,  25, 151,  74, 238, 183,  12, 118, 133, 230, 
+  227,  10, 201, 199,  22, 210, 142, 221, 164,  89, 187, 122, 243,  99,   5, 233, 
+  195,  14, 209, 196,  92,  83, 121, 253, 226, 193, 137, 144, 102, 236,  42, 205, 
+  223,  21, 152,  15,  42, 132,  31,  35,  72,  25, 246, 138, 198, 231,  18, 202, 
+  141, 151,  37, 174, 155,  60, 107,  81, 239, 124,  76,  33, 245, 216,  71,  26, 
+  178, 139,  53, 167,  87,  58, 190, 147,  48, 109, 212,  45, 159,  93, 168,  57, 
+  190, 146, 240, 109, 132,  45, 163,  93, 185, 249, 178, 194, 245, 145, 135,  44, 
+   98, 157, 233, 169, 142, 254, 228,  64,  75, 112,  55, 100,  22, 171,  78, 255, 
+  116,  64,  39, 112,  26, 164,  11,  59,  71,  83, 114, 189, 229, 177, 139,  52, 
+  103,  87, 106, 190, 175,  48, 124,  20,  33, 207,  88,  84,  58, 191,  83,  48, 
+   61, 212,  17, 159,  76, 104,  53, 238, 151,  12, 110, 133, 236,  99,  13, 233, 
+  197, 142, 211,  36,  93, 219, 121, 155,  98, 235, 105, 143, 110, 228,  44,  75, 
+   93, 247, 121, 134, 162, 226, 249, 137, 130, 230, 225, 138, 200, 103,  22, 170, 
+  142, 255,  36,  64,  27, 112,  11, 100,   7, 107,  66, 175, 113, 188,  36, 113, 
+  219, 100,  91, 107, 123, 111,  99, 108,  41, 237, 222, 205, 152,  85, 170, 191, 
+   63,  48,  16,  20,  12,  15,  69, 196,  51,  19,  85, 205, 255,  21, 128,  15, 
+   32,   4,  24,   3,  74, 129, 247,  32,  70, 152,  50, 234, 149, 143,  47,  36, 
+   28,  27,  73, 203, 118, 215, 102, 222, 170, 216, 127,  26, 160,  11,  56,   7, 
+   82, 130, 189, 161, 177, 184, 116, 114, 167, 101, 186, 171,  51,  63,  85, 208, 
+   63,  28,  16,   9, 204,   6, 213, 194, 223,  17, 152,  12, 106, 133, 239,  35, 
+   12,  25, 197, 202, 211,  23,  29, 206, 137, 148, 102, 239, 106, 204,  47,  21, 
+  220,  15,  25, 196,  10, 211,  71,  29, 242, 137, 133, 166, 227,  58, 201, 211, 
+   22, 221, 206, 217, 148,  90, 239, 123,  12,  35,  69, 217, 243,  26, 197, 203, 
+   19,  23,  77, 206, 181, 148, 119,  47, 102, 156,  42, 233, 223,  14, 216,   4, 
+   90, 131, 123,  33, 227,  88,  73, 250, 182, 195,  54, 209, 214, 220,  94, 217, 
+  248,  90, 194, 187,  17, 179,  76, 117, 245, 231,   7,  10, 130, 135,  33, 162, 
+  152, 121, 170, 162, 255,  57, 128,  18, 224,  13, 136,   5, 166, 131,  58, 225, 
+  211,   8,  93, 198, 185, 146, 242, 237, 133, 141, 163,  37, 185, 219,  50, 219, 
+   85, 155, 127,  43,  96,  31, 104,   8,  46, 134, 156,  98, 233, 233, 142, 206, 
+  228,  84,  75, 127, 119,  96,  38, 168,  26, 254, 139,   0, 103,  64,  42, 176, 
+   31,  52,   8,  23,  70, 142, 178, 228, 117, 139, 103,  39, 106, 154, 175,  43, 
+   60,  31,  81, 200,  60,  86, 145, 254, 236,  64,  77, 240,  53, 132,  23,  35, 
+   78, 153, 244, 106, 199, 111,  18, 172,  13, 189, 197, 177, 147,  52, 109, 215, 
+  109, 158, 173, 168, 125, 190, 161, 176, 120, 116,  34, 167,  89, 186, 186, 243, 
+   51,   5, 213, 195,  31,  17, 200,  12,  86, 133, 254, 227,   0,  73, 192,  54, 
+  208,  22, 220,  14, 217, 196,  90, 211, 123,  29, 227,  73, 137, 246, 230, 198, 
+  202, 210, 215,  29, 158, 137, 168, 102, 254, 170, 192, 127,  16,  32,  12,  24, 
+    5, 202, 131,  23,  33, 206, 152,  84, 106, 191, 111,  48,  44,  20,  29, 207, 
+   73, 148,  54, 239,  86, 204,  62, 213, 208,  95,  28,  56,   9, 210, 134, 221, 
+  162, 217, 185, 154, 242, 235,   5, 143,  67,  36,  49, 219,  84,  91, 127, 123, 
+   96,  35, 104,  25, 238, 138, 204, 103,  21, 234, 143,  15,  36,   4,  27,  67, 
+   75, 113, 247, 100,  70, 171, 114, 255, 101, 128,  43,  32,  31,  88,   8,  58, 
+  134, 147,  34, 237, 217, 141, 154, 229, 171,  11,  63,  71,  80,  50, 188,  21, 
+  177, 207,  52,  84,  23, 127,  78, 160,  52, 120,  23,  98, 142, 169, 164, 126, 
+  251,  96,  67, 104,  49, 238, 148,  76, 111, 117, 236,  39,  13, 218, 133, 155, 
+   35,  43,  89, 223, 122, 216,  35,  26, 153, 203,  42, 215,  95,  30, 184,   8, 
+  114, 134, 165, 162, 251,  57, 131,  82, 225, 253, 136,  65, 166, 176, 122, 244, 
+   35,   7,  89, 194, 186, 209, 179,  28, 117, 201, 231,  22, 202, 142, 215,  36, 
+   94, 155, 120, 107,  98, 175, 105, 188,  46, 241, 220,  68,  89, 243, 122, 197, 
+  227,  19,   9, 205, 198, 213, 146, 223,  45, 152,  29, 170, 137, 191,  38, 240, 
+   26, 196,  11,  19,  71,  77, 242, 181, 133, 183,  35,  54, 153, 214, 234, 222, 
+  207,  24,  84,  10, 191,  71,  48,  50, 148,  21, 175,  79,  60,  52,  17, 215, 
+   76,  94, 181, 248, 119,   2, 166, 129, 186, 224, 115,   8,  37, 198, 155,  18, 
+  235,  77, 143, 117, 164,  39,  59,  90, 147, 123,  45, 227,  93, 137, 249, 166, 
+  194, 250, 209, 131,  28,  97, 201, 232,  86, 206, 190, 212, 112,  95, 100,  56, 
+   43,  82, 159, 125, 168,  33, 190, 152, 112, 106, 164,  47,  59,  92,  19, 121, 
+  205, 226, 213, 137, 159,  38, 232,  26, 206, 139,  20, 103,  79, 106, 180,  47, 
+   55,  92,  22, 185, 206, 242, 212,  69, 159, 115,  40,  37, 222, 155,  24, 107, 
+   74, 175, 119,  60,  38, 145, 218, 236,  91,  13, 251,  69, 131, 115,  33, 229, 
+  216,  75,  26, 183,  75,  54, 183,  86, 246, 190, 198, 240,  82, 196,  61, 147, 
+   81, 173, 252, 125, 129, 225, 160,  72, 120,  54, 162, 150, 249, 174, 194, 252, 
+   81, 129, 252,  96,  65, 232,  48,  78, 148,  52, 111,  87, 108,  62, 173, 208, 
+  125, 156,  33, 169, 216, 126, 218, 160,  91,  56,  59,  82, 147, 125, 173, 225, 
+  189, 136, 113, 166, 164, 122, 251,  99,   3, 105, 193, 238, 208,  76,  92,  53, 
+  249, 215,   2, 222, 129, 152,  96, 106, 168,  47,  62, 156,  16, 105, 204,  46, 
+  213, 220,  95,  25, 248,  10, 194, 135,  17, 162, 140, 121, 165, 226, 251,   9, 
+  131,  70, 225, 242, 200,  69, 150, 179,  46, 245, 220,  71,  25, 242, 138, 197, 
+  167,  19,  58, 141, 211,  37, 157, 219,  41, 155,  94, 235, 120,  79,  98, 180, 
+   41, 183,  94, 246, 184,  70, 242, 178, 197, 181, 147,  55,  45, 214, 157, 158, 
+  233, 168,  78, 254, 180,  64, 119, 112,  38, 164,  26, 251,  75,   3, 119,  65, 
+  230, 176,  74, 244,  55,   7,  86, 130, 190, 225, 176,  72, 116,  54, 167,  86, 
+  250, 190, 195,  48,  81, 212,  60,  95,  81, 248,  60,  66, 145, 241, 172,  68, 
+  125, 243,  97, 133, 232,  99,  14, 169, 196, 126, 211,  96,  93, 232,  57, 142, 
+  146, 228, 109, 139, 109, 167, 109, 186, 173, 179,  61, 181, 209, 183,  28, 118, 
+  137, 230, 230, 202, 202, 215,  23,  30, 142, 136, 100, 102, 171, 106, 255, 111, 
+    0,  44,   0,  29, 192,   9, 144,   6, 236,   2, 205, 193, 149, 144, 111,  44, 
+   44,  29, 221, 201, 153, 150, 234, 238, 207,  12,  84,   5, 255,  67,   0,  49, 
+  192,  20,  80,  15, 124,   4,  33, 195,  88,  81, 250, 188,  67,  49, 241, 212, 
+   68,  95, 115, 120,  37, 226, 155,   9, 171,  70, 255, 114, 192,  37, 144,  27, 
+   44,  11,  93, 199, 121, 146, 162, 237, 185, 141, 178, 229, 181, 139,  55,  39, 
+   86, 154, 190, 235,  48,  79,  84,  52,  63,  87,  80,  62, 188,  16, 113, 204, 
+   36,  85, 219, 127,  27,  96,  11, 104,   7, 110, 130, 172,  97, 189, 232, 113, 
+  142, 164, 100, 123, 107,  99, 111, 105, 236,  46, 205, 220,  85, 153, 255,  42, 
+  192,  31,  16,   8,  12,   6, 133, 194, 227,  17, 137, 204, 102, 213, 234, 223, 
+   15,  24,   4,  10, 131,  71,  33, 242, 152,  69, 170, 179,  63,  53, 208,  23, 
+   28,  14, 137, 196, 102, 211, 106, 221, 239,  25, 140,  10, 229, 199,  11,  18, 
+  135,  77, 162, 181, 185, 183,  50, 246, 149, 134, 239,  34, 204,  25, 149, 202, 
+  239,  23,  12,  14, 133, 196,  99,  19, 105, 205, 238, 213, 140,  95,  37, 248, 
+   27,   2, 139,  65, 167, 112, 122, 164,  35,  59,  89, 211, 122, 221, 227,  25, 
+  137, 202, 230, 215,  10, 222, 135,  24,  98, 138, 169, 167,  62, 250, 144,  67, 
+   44,  49, 221, 212,  89, 159, 122, 232,  35,  14, 153, 196, 106, 211, 111,  29, 
+  236,   9, 141, 198, 229, 146, 203,  45, 151,  93, 174, 185, 188, 114, 241, 229, 
+  132,  75,  35, 119,  89, 230, 186, 202, 243,  23,   5, 206, 131,  20,  97, 207, 
+  104,  84,  46, 191,  92, 112,  57, 228,  18, 203,  77, 151, 117, 174, 167,  60, 
+  122, 145, 227,  44,  73, 221, 246, 217, 134, 218, 226, 219,   9, 155,  70, 235, 
+  114, 207, 101, 148,  43,  47,  95,  92,  56,  57, 210, 146, 221, 173, 153, 189, 
+  170, 241, 191,   4, 112,   3, 100,   1, 235,  64,  79, 112,  52,  36,  23,  91, 
+   78, 187, 116, 115, 103, 101, 234, 171,  15,  63,  68,  16,  51,  76,  21, 245, 
+  207,   7,  20,   2, 143,  65, 164,  48, 123,  84,  35, 127,  89, 224,  58, 200, 
+   19,  22, 141, 206, 229, 148,  75,  47, 119,  92,  38, 185, 218, 242, 219,   5, 
+  155,  67,  43, 113, 223, 100,  88,  43, 122, 159,  99,  40,  41, 222, 158, 216, 
+  104,  90, 174, 187,  60, 115,  81, 229, 252,  75,   1, 247,  64,  70, 176,  50, 
+  244,  21, 135,  79,  34, 180,  25, 183,  74, 246, 183,   6, 246, 130, 198, 225, 
+  146, 200, 109, 150, 173, 174, 253, 188,  65, 177, 240, 116,  68,  39, 115,  90, 
+  165, 251,  59,   3,  83,  65, 253, 240,  65, 132,  48,  99,  84,  41, 255,  94, 
+  192,  56,  80,  18, 188,  13, 177, 197, 180,  83,  55, 125, 214, 161, 158, 248, 
+  104,  66, 174, 177, 188, 116, 113, 231, 100,  74, 171, 119,  63, 102, 144,  42, 
+  236,  31,  13, 200,   5, 150, 131,  46, 225, 220,  72,  89, 246, 186, 198, 243, 
+   18, 197, 205, 147,  21, 173, 207,  61, 148,  17, 175,  76, 124,  53, 225, 215, 
+    8,  94, 134, 184,  98, 242, 169, 133, 190, 227,  48,  73, 212,  54, 223,  86, 
+  216,  62, 218, 144,  91,  44,  59,  93, 211, 121, 157, 226, 233, 137, 142, 230, 
+  228,  74, 203, 119,  23, 102, 142, 170, 228, 127,  11,  96,   7, 104,   2, 174, 
+  129, 188,  96, 113, 232,  36,  78, 155, 116, 107, 103, 111, 106, 172,  47,  61, 
+  220,  17, 153, 204, 106, 213, 239,  31,  12,   8,   5, 198, 131,  18, 225, 205, 
+  136,  85, 166, 191,  58, 240,  19,   4,  13, 195,  69, 145, 243,  44,  69, 221, 
+  243,  25, 133, 202, 227,  23,   9, 206, 134, 212,  98, 223, 105, 152,  46, 234, 
+  156,  79,  41, 244,  30, 199,  72,  82, 182, 189, 182, 241, 182, 196, 118, 211, 
+  102, 221, 234, 217, 143,  26, 228,  11,  11,  71,  71, 114, 178, 165, 181, 187, 
+   55,  51,  86, 149, 254, 239,   0,  76,   0,  53, 192,  23,  16,  14, 140,   4, 
+  101, 195, 107,  17, 239,  76,  76,  53, 245, 215,   7,  30, 130, 136,  97, 166, 
+  168, 122, 254, 163,   0, 121, 192,  34, 208,  25, 156,  10, 233, 199,  14, 210, 
+  132,  93, 163, 121, 185, 226, 242, 201, 133, 150, 227,  46, 201, 220,  86, 217, 
+  254, 218, 192,  91,  16,  59,  76,  19, 117, 205, 231,  21, 138, 143,  39,  36, 
+   26, 155,  75,  43, 119,  95, 102, 184,  42, 242, 159,   5, 168,   3,  62, 129, 
+  208,  96,  92,  40,  57, 222, 146, 216, 109, 154, 173, 171,  61, 191,  81, 176, 
+   60, 116,  17, 231,  76,  74, 181, 247,  55,   6, 150, 130, 238, 225, 140,  72, 
+  101, 246, 171,   6, 255,  66, 192,  49, 144,  20, 108,  15, 109, 196,  45, 147, 
+   93, 173, 249, 189, 130, 241, 161, 132, 120,  99,  98, 169, 233, 190, 206, 240, 
+   84,  68,  63, 115,  80,  37, 252,  27,   1, 203,  64,  87, 112,  62, 164,  16, 
+  123,  76,  35, 117, 217, 231,  26, 202, 139,  23,  39,  78, 154, 180, 107,  55, 
+  111,  86, 172,  62, 253, 208,  65, 156,  48, 105, 212,  46, 223,  92,  88,  57, 
+  250, 146, 195,  45, 145, 221, 172,  89, 189, 250, 241, 131,   4,  97, 195, 104, 
+   81, 238, 188,  76, 113, 245, 228,  71,  11, 114, 135, 101, 162, 171,  57, 191, 
+   82, 240,  61, 132,  17, 163,  76, 121, 245, 226, 199,   9, 146, 134, 237, 162, 
+  205, 185, 149, 178, 239,  53, 140,  23,  37, 206, 155,  20, 107,  79, 111, 116, 
+   44,  39,  93, 218, 185, 155,  50, 235,  85, 143, 127,  36,  32,  27,  88,  11, 
+  122, 135,  99,  34, 169, 217, 190, 218, 240,  91,   4,  59,  67,  83, 113, 253, 
+  228,  65, 139, 112, 103, 100,  42, 171,  95,  63, 120,  16,  34, 140,  25, 165, 
+  202, 251,  23,   3,  78, 129, 244,  96,  71, 104,  50, 174, 149, 188, 111,  49, 
+  236,  20,  77, 207, 117, 148,  39,  47,  90, 156,  59,  41, 211,  94, 221, 248, 
+   89, 130, 186, 225, 179,   8, 117, 198, 167,  18, 250, 141, 131,  37, 161, 219, 
+   56,  91,  82, 187, 125, 179,  97, 181, 232, 119,  14, 166, 132, 122, 227,  99, 
+    9, 233, 198, 206, 210, 212,  93, 159, 121, 168,  34, 254, 153, 128, 106, 224, 
+   47,   8,  28,   6, 137, 194, 230, 209, 138, 220, 103,  25, 234, 138, 207,  39, 
+   20,  26, 143,  75,  36,  55,  91,  86, 187, 126, 243,  96,  69, 232,  51,  14, 
+  149, 196, 111,  19, 108,  13, 237, 197, 141, 147,  37, 173, 219,  61, 155,  81, 
+  171, 124, 127,  97, 224,  40,  72,  30, 182, 136, 118, 230, 166, 202, 250, 215, 
+    3,  30, 129, 200,  96,  86, 168,  62, 254, 144,  64, 108,  48,  45, 212,  29, 
+  159,  73, 168,  54, 254, 150, 192, 110, 208,  44,  92,  29, 249, 201, 130, 214, 
+  225, 158, 200, 104,  86, 174, 190, 252, 112,  65, 228,  48,  75,  84,  55, 127, 
+   86, 160,  62, 248,  16,  66, 140,  49, 165, 212, 123,  31,  99,  72,  41, 246, 
+  158, 198, 232,  82, 206, 189, 148, 113, 175, 100, 124,  43,  97, 223, 104,  88, 
+   46, 186, 156, 115,  41, 229, 222, 203,  24,  87,  74, 190, 183,  48, 118, 148, 
+   38, 239,  90, 204,  59,  21, 211,  79,  29, 244,   9, 135,  70, 226, 178, 201, 
+  181, 150, 247,  46, 198, 156,  82, 233, 253, 142, 193, 164,  80, 123, 124,  35, 
+   97, 217, 232,  90, 206, 187,  20, 115,  79, 101, 244,  43,   7,  95,  66, 184, 
+   49, 178, 148, 117, 175, 103,  60,  42, 145, 223,  44,  88,  29, 250, 137, 131, 
+   38, 225, 218, 200,  91,  22, 187,  78, 243, 116,  69, 231, 115,  10, 165, 199, 
+   59,  18, 147,  77, 173, 245, 189, 135,  49, 162, 148, 121, 175,  98, 252,  41, 
+  129, 222, 224,  88,  72,  58, 182, 147,  54, 237, 214, 205, 158, 213, 168,  95, 
+   62, 184,  16, 114, 140,  37, 165, 219,  59,  27,  83,  75, 125, 247,  97, 134, 
+  168,  98, 254, 169, 128, 126, 224,  32,  72,  24,  54, 138, 150, 231,  46, 202, 
+  156,  87,  41, 254, 158, 192, 104,  80,  46, 188,  28, 113, 201, 228,  86, 203, 
+  126, 215,  96,  94, 168,  56, 126, 146, 160, 109, 184,  45, 178, 157, 181, 169, 
+  183,  62, 246, 144,  70, 236,  50, 205, 213, 149, 159,  47,  40,  28,  30, 137, 
+  200, 102, 214, 170, 222, 255,  24,  64,  10, 176,   7,  52,   2, 151,  65, 174, 
+  176, 124, 116,  33, 231,  88,  74, 186, 183,  51,  54, 149, 214, 239,  30, 204, 
+    8,  85, 198, 191,  18, 240,  13, 132,   5, 163,  67,  57, 241, 210, 196,  93, 
+  147, 121, 173, 226, 253, 137, 129, 166, 224, 122, 200,  35,  22, 153, 206, 234, 
+  212,  79,  31, 116,   8,  39,  70, 154, 178, 235,  53, 143,  87,  36,  62, 155, 
+   80, 107, 124,  47,  97, 220,  40,  89, 222, 186, 216, 115,  26, 165, 203,  59, 
+   23,  83,  78, 189, 244, 113, 135, 100,  98, 171, 105, 191, 110, 240,  44,  68, 
+   29, 243,  73, 133, 246, 227,   6, 201, 194, 214, 209, 158, 220, 104,  89, 238, 
+  186, 204, 115,  21, 229, 207,  11,  20,   7,  79,  66, 180,  49, 183,  84, 118, 
+  191, 102, 240,  42, 196,  31,  19,  72,  13, 246, 133, 134, 227,  34, 201, 217, 
+  150, 218, 238, 219,  12,  91,  69, 251, 115,   3, 101, 193, 235,  16,  79,  76, 
+   52,  53, 215,  87,  30, 190, 136, 112, 102, 164,  42, 251,  95,   3, 120,   1, 
+  226, 128,  73, 160,  54, 248,  22, 194, 142, 209, 164,  92, 123, 121, 227,  98, 
+  201, 233, 150, 206, 238, 212,  76,  95, 117, 248,  39,   2, 154, 129, 171,  32, 
+  127,  88,  32,  58, 152,  19,  42, 141, 223,  37, 152,  27,  42, 139,  95,  39, 
+  120,  26, 162, 139,  57, 167,  82, 250, 189, 131,  49, 161, 212, 120,  95,  98, 
+  184,  41, 178, 158, 245, 168,  71,  62, 178, 144, 117, 172,  39,  61, 218, 145, 
+  155,  44, 107,  93, 239, 121, 140,  34, 229, 217, 139,  26, 231,  75,  10, 183, 
+   71,  54, 178, 150, 245, 174, 199,  60,  82, 145, 253, 172,  65, 189, 240, 113, 
+  132,  36,  99,  91, 105, 251, 110, 195, 108,  81, 237, 252,  77, 129, 245, 160, 
+   71,  56,  50, 146, 149, 173, 175,  61, 188,  17, 177, 204, 116,  85, 231, 127, 
+   10, 160,   7,  56,   2, 146, 129, 173, 160, 125, 184,  33, 178, 152, 117, 170, 
+  167,  63,  58, 144,  19,  44,  13, 221, 197, 153, 147,  42, 237, 223,  13, 152, 
+    5, 170, 131,  63,  33, 208,  24,  92,  10, 185, 199,  50, 210, 149, 157, 175, 
+   41, 188,  30, 241, 200,  68,  86, 179, 126, 245, 224,  71,   8,  50, 134, 149, 
+  162, 239,  57, 140,  18, 229, 205, 139,  21, 167,  79,  58, 180,  19,  55,  77, 
+  214, 181, 158, 247,  40,  70, 158, 178, 232, 117, 142, 167,  36, 122, 155,  99, 
+   43, 105, 223, 110, 216,  44,  90, 157, 251,  41, 131,  94, 225, 248,  72,  66, 
+  182, 177, 182, 244, 118, 199, 102, 210, 170, 221, 191,  25, 176,  10, 244,   7, 
+    7,  66, 130, 177, 161, 180, 120, 119,  98, 166, 169, 186, 254, 243,   0,  69, 
+  192,  51,  16,  21, 204,  15,  21, 196,  15,  19,  68,  13, 243,  69, 133, 243, 
+   35,   5, 217, 195,  26, 209, 203,  28,  87,  73, 254, 182, 192, 118, 208,  38, 
+  220,  26, 217, 203,  26, 215,  75,  30, 183,  72, 118, 182, 166, 246, 250, 198, 
+  195,  18, 209, 205, 156,  85, 169, 255,  62, 192,  16,  80,  12,  60,   5, 209, 
+  195,  28,  81, 201, 252,  86, 193, 254, 208,  64,  92,  48,  57, 212,  18, 223, 
+   77, 152,  53, 170, 151,  63,  46, 144,  28, 108,   9, 237, 198, 205, 146, 213, 
+  173, 159,  61, 168,  17, 190, 140, 112, 101, 228,  43,  11,  95,  71, 120,  50, 
+  162, 149, 185, 175,  50, 252,  21, 129, 207,  32,  84,  24,  63,  74, 144,  55, 
+   44,  22, 157, 206, 233, 148,  78, 239, 116,  76,  39, 117, 218, 167,  27,  58, 
+  139,  83,  39, 125, 218, 161, 155,  56, 107,  82, 175, 125, 188,  33, 177, 216, 
+  116,  90, 167, 123,  58, 163,  83,  57, 253, 210, 193, 157, 144, 105, 172,  46, 
+  253, 220,  65, 153, 240, 106, 196,  47,  19,  92,  13, 249, 197, 130, 211,  33, 
+  157, 216, 105, 154, 174, 235,  60,  79,  81, 244,  60,  71,  81, 242, 188,  69, 
+  177, 243,  52,  69, 215, 115,  30, 165, 200, 123,  22, 163,  78, 249, 244,  66, 
+  199, 113, 146, 164, 109, 187, 109, 179, 109, 181, 237, 183,  13, 182, 133, 182, 
+  227,  54, 201, 214, 214, 222, 222, 216,  88,  90, 186, 187,  51,  51, 255,  63 )
+
+random_mask_vec8 = Numeric.array(random_mask_tuple, Numeric.UnsignedInt8)
+
diff --git a/gnuradio-core/src/python/gnuradio/window.py b/gnuradio-core/src/python/gnuradio/window.py
new file mode 100644 (file)
index 0000000..391b83c
--- /dev/null
@@ -0,0 +1,190 @@
+#
+# 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 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.
+# 
+
+'''
+Routines for designing window functions.
+'''
+
+import math
+from gnuradio import gr
+
+def izero(x):
+    izeroepsilon = 1e-21
+    halfx = x/2.0
+    accum = u = n = 1
+    while 1:
+        temp = halfx/n
+        n += 1
+        temp *= temp
+        u *= temp
+        accum += u
+        if u >= IzeroEPSILON*sum:
+            break
+    return accum
+
+def midm1(fft_size):
+    return (fft_size - 1)/2
+
+def midp1(fft_size):
+    return (fft_size+1)/2
+
+def freq(fft_size):
+    return 2.0*math.pi/fft_size
+
+def rate(fft_size):
+    return 1.0/(fft_size >> 1)
+
+def expn(fft_size):
+    math.log(2.0)/(midn(fft_size) + 1.0)
+    
+def hamming(fft_size):
+    window = []
+    for index in xrange(fft_size):
+        window.append(0.54 - 0.46 * math.cos (2 * math.pi / fft_size * index))  # Hamming window
+    return window
+
+def hanning(fft_size):
+    window = []
+    for index in xrange(fft_size):
+        window.append(0.5 - 0.5 * math.cos (2 * math.pi / fft_size * index))  #  von Hann window
+    return window
+
+def welch(fft_size):
+    window = [0 for i in range(fft_size)]
+    j = fft_size-1
+    for index in xrange(midn(fft_size)+1):
+        window[j] = window[index] = (1.0 - math.sqrt((index - midm1(fft_size)) / midp1(fft_size)))
+        j -= 1
+    return window
+
+def parzen(fft_size):
+    window = [0 for i in range(fft_size)]
+    j = fft_size-1
+    for index in xrange(midn(fft_size)+1):
+        window[j] = window[index] = (1.0 - math.abs((index - midm1(fft_size)) / midp1(fft_size)))
+        j -= 1
+    return window
+
+def bartlett(fft_size):
+    mfrq = freq(fft_size)
+    angle = 0
+    window = [0 for i in range(fft_size)]
+    j = fft_size-1
+    for index in xrange(midn(fft_size)+1):
+        window[j] = window[index] = angle
+        angle += freq
+        j -= 1
+    return window
+    
+def blackman2(fft_size):
+    mfrq = freq(fft_size)
+    angle = 0
+    window = [0 for i in range(fft_size)]
+    j = fft_size-1
+    for index in xrange(midn(fft_size)+1):
+        cx = math.cos(angle)
+        window[j] = window[index] = (.34401 + (cx * (-.49755 + (cx * .15844))))
+        angle += freq
+        j -= 1
+    return window
+    
+def blackman3(fft_size):
+    mfrq = freq(fft_size)
+    angle = 0
+    window = [0 for i in range(fft_size)]
+    j = fft_size-1
+    for index in xrange(midn(fft_size)+1):
+        cx = math.cos(angle)
+        window[j] = window[index] = (.21747 + (cx * (-.45325 + (cx * (.28256 - (cx * .04672))))))
+        angle += freq
+        j -= 1
+    return window
+    
+def blackman4(fft_size):
+    mfrq = freq(fft_size)
+    angle = 0
+    window = [0 for i in range(fft_size)]
+    j = fft_size-1
+    for index in xrange(midn(fft_size)+1):
+        cx = math.cos(angle)
+        window[j] = window[index] = (.084037 + (cx * (-.29145 + (cx * (.375696 + (cx * (-.20762 + (cx * .041194))))))))
+        angle += freq
+        j -= 1
+    return window
+    
+def exponential(fft_size):
+    expsum = 1.0
+    window = [0 for i in range(fft_size)]
+    j = fft_size-1
+    for index in xrange(midn(fft_size)+1):
+      window[j] = window[i] = (expsum - 1.0)
+      expsum *= expn(fft_size)
+      j -= 1
+    return window
+
+def riemann(fft_size):
+    sr1 = freq(fft_size)
+    window = [0 for i in range(fft_size)]
+    j = fft_size-1
+    for index in xrange(midn(fft_size)):
+        if index == midn(fft_size):
+            window[index] = window[j] = 1.0
+        else:
+            cx = sr1*midn(fft_size) - index
+            window[index] = window[j] = math.sin(cx)/cx
+        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)
+    window = [0 for i in range(fft_size)]
+    for index in xrange(fft_size):
+        window[index] = izero(beta*math.sqrt(1.0 - (index * inm1)*(index * inm1))) * ibeta
+    return window
+
+    
diff --git a/gnuradio-core/src/tests/Makefile.am b/gnuradio-core/src/tests/Makefile.am
new file mode 100644 (file)
index 0000000..1dd3dd0
--- /dev/null
@@ -0,0 +1,96 @@
+#
+# 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 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.
+# 
+
+include $(top_srcdir)/Makefile.common
+
+INCLUDES = $(STD_DEFINES_AND_INCLUDES) $(CPPUNIT_INCLUDES)
+
+# list of programs run by "make check" and "make distcheck"
+
+TESTS = test_all
+
+
+#      test_atsc               
+
+#Test program to test setting up buffers using gr_test which can be run manually
+EXTRA_DIST =                           \
+       test_buffers.py
+       
+noinst_PROGRAMS                =       \
+       benchmark_dotprod       \
+       benchmark_dotprod_fsf   \
+       benchmark_dotprod_fcc   \
+       benchmark_dotprod_scc   \
+       benchmark_dotprod_ccc   \
+       benchmark_dotprod_ccf   \
+       benchmark_nco           \
+       benchmark_vco           \
+       test_runtime            \
+       test_general            \
+       test_all                \
+       test_filter             \
+       test_vmcircbuf
+
+
+LIBGNURADIO =  $(top_builddir)/gnuradio-core/src/lib/libgnuradio-core.la
+LIBGNURADIOQA = $(top_builddir)/gnuradio-core/src/lib/libgnuradio-core-qa.la $(LIBGNURADIO)
+
+benchmark_dotprod_SOURCES = benchmark_dotprod.cc
+benchmark_dotprod_LDADD   = $(LIBGNURADIO)
+
+benchmark_dotprod_fsf_SOURCES = benchmark_dotprod_fsf.cc
+benchmark_dotprod_fsf_LDADD   = $(LIBGNURADIO)
+
+benchmark_dotprod_ccf_SOURCES = benchmark_dotprod_ccf.cc
+benchmark_dotprod_ccf_LDADD   = $(LIBGNURADIO)
+
+benchmark_dotprod_fcc_SOURCES = benchmark_dotprod_fcc.cc
+benchmark_dotprod_fcc_LDADD   = $(LIBGNURADIO)
+
+benchmark_dotprod_scc_SOURCES = benchmark_dotprod_scc.cc
+benchmark_dotprod_scc_LDADD   = $(LIBGNURADIO)
+
+benchmark_dotprod_ccc_SOURCES = benchmark_dotprod_ccc.cc
+benchmark_dotprod_ccc_LDADD   = $(LIBGNURADIO)
+
+benchmark_nco_SOURCES  = benchmark_nco.cc
+benchmark_nco_LDADD    = $(LIBGNURADIO)
+
+benchmark_vco_SOURCES  = benchmark_vco.cc
+benchmark_vco_LDADD    = $(LIBGNURADIO)
+
+test_runtime_SOURCES   = test_runtime.cc
+test_runtime_LDADD     = $(LIBGNURADIOQA)
+
+test_general_SOURCES   = test_general.cc
+test_general_LDADD     = $(LIBGNURADIOQA)
+
+test_filter_SOURCES    = test_filter.cc
+test_filter_LDADD      = $(LIBGNURADIOQA)
+
+# test_atsc_SOURCES    = test_atsc.cc
+#test_atsc_LDADD       = $(LIBGNURADIOQA)
+
+test_vmcircbuf_SOURCES = test_vmcircbuf.cc
+test_vmcircbuf_LDADD   = $(LIBGNURADIOQA)
+
+test_all_SOURCES       = test_all.cc
+test_all_LDADD                 = $(LIBGNURADIOQA)
diff --git a/gnuradio-core/src/tests/benchmark_dotprod.cc b/gnuradio-core/src/tests/benchmark_dotprod.cc
new file mode 100644 (file)
index 0000000..8986f72
--- /dev/null
@@ -0,0 +1,148 @@
+/* -*- 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 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.
+ */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include <stdio.h>
+#include <sys/time.h>
+#ifdef HAVE_SYS_RESOURCE_H
+#include <sys/resource.h>
+#endif
+
+#include <unistd.h>
+#include <gr_fir_util.h>
+#include <gr_fir_fff.h>
+#include <random.h>
+
+#define TOTAL_TEST_SIZE               (40 * 1000 * 1000L)
+#define        NTAPS                                256
+#define        BLOCK_SIZE                   (50 * 1000)        /* fits in cache */
+
+#if ((TOTAL_TEST_SIZE % BLOCK_SIZE) != 0)
+#error "TOTAL_TEST_SIZE % BLOCK_SIZE must equal 0"
+#endif
+
+typedef gr_fir_fff* (*fir_maker_t)(const std::vector<float> &taps);
+typedef gr_fir_fff  filter_t;
+
+
+static double
+timeval_to_double (const struct timeval *tv)
+{
+  return (double) tv->tv_sec + (double) tv->tv_usec * 1e-6;
+}
+
+
+static void
+benchmark (fir_maker_t filter_maker, const char *implementation_name)
+{
+  int  i;
+  float coeffs[NTAPS];
+  float input[BLOCK_SIZE + NTAPS];
+  long n;
+  float        result;
+#ifdef HAVE_SYS_RESOURCE_H
+  struct rusage        rusage_start;
+  struct rusage        rusage_stop;
+#else
+  double clock_start;
+  double clock_end;
+#endif
+  // setup coefficients and input data
+
+  for (i = 0; i < NTAPS; i++)
+    coeffs[i] = random() - RANDOM_MAX/2;
+
+  for (i = 0; i < BLOCK_SIZE + NTAPS; i++)
+    input[i] = random() - RANDOM_MAX/2;
+
+  std::vector<float> taps (&coeffs[0], &coeffs[NTAPS]);
+  filter_t *f = filter_maker (taps);
+
+  // get starting CPU usage
+#ifdef HAVE_SYS_RESOURCE_H
+  if (getrusage (RUSAGE_SELF, &rusage_start) < 0){
+    perror ("getrusage");
+    exit (1);
+  }
+#else
+  clock_start = (double) clock() * (1000000. / CLOCKS_PER_SEC);
+#endif
+  // do the actual work
+
+  for (n = 0; n < TOTAL_TEST_SIZE; n += BLOCK_SIZE){
+    int        j;
+    for (j = 0; j < BLOCK_SIZE; j++){
+      result = f->filter (&input[j]);
+    }
+  }
+
+  // get ending CPU usage
+#ifdef HAVE_SYS_RESOURCE_H
+  if (getrusage (RUSAGE_SELF, &rusage_stop) < 0){
+    perror ("getrusage");
+    exit (1);
+  }
+
+  // compute results
+
+  double user =
+    timeval_to_double (&rusage_stop.ru_utime)
+    - timeval_to_double (&rusage_start.ru_utime);
+
+  double sys =
+    timeval_to_double (&rusage_stop.ru_stime)
+    - timeval_to_double (&rusage_start.ru_stime);
+
+  double total = user + sys;
+#else
+  clock_end = (double) clock () * (1000000. / CLOCKS_PER_SEC);
+  double total = clock_end -clock_start;
+#endif
+  double macs = NTAPS * (double) TOTAL_TEST_SIZE;
+
+  printf ("%10s: taps: %4d  input: %4g  cpu: %6.3f  taps/sec: %10.4g  \n",
+         implementation_name, NTAPS, (double) TOTAL_TEST_SIZE, total, macs / total);
+
+  delete f;
+}
+
+static void
+do_all ()
+{
+  std::vector<gr_fir_fff_info>         info;
+  gr_fir_util::get_gr_fir_fff_info (&info);    // get all known FFF implementations
+
+  for (std::vector<gr_fir_fff_info>::iterator p = info.begin ();
+       p != info.end ();
+       ++p){
+
+    benchmark (p->create, p->name);
+  }
+}
+
+int
+main (int argc, char **argv)
+{
+  do_all ();
+  return 0;
+}
diff --git a/gnuradio-core/src/tests/benchmark_dotprod_ccc.cc b/gnuradio-core/src/tests/benchmark_dotprod_ccc.cc
new file mode 100644 (file)
index 0000000..afc24e0
--- /dev/null
@@ -0,0 +1,149 @@
+/* -*- 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 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.
+ */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include <stdio.h>
+#include <sys/time.h>
+#ifdef HAVE_SYS_RESOURCE_H
+#include <sys/resource.h>
+#endif
+#include <unistd.h>
+#include <gr_fir_util.h>
+#include <gr_fir_ccc.h>
+#include <random.h>
+
+#define TOTAL_TEST_SIZE               (40 * 1000 * 1000L)
+#define        NTAPS                                256
+#define        BLOCK_SIZE                   (50 * 1000)        /* fits in cache */
+
+#if ((TOTAL_TEST_SIZE % BLOCK_SIZE) != 0)
+#error "TOTAL_TEST_SIZE % BLOCK_SIZE must equal 0"
+#endif
+
+typedef gr_fir_ccc* (*fir_maker_t)(const std::vector<gr_complex> &taps);
+typedef gr_fir_ccc  filter_t;
+
+
+static double
+timeval_to_double (const struct timeval *tv)
+{
+  return (double) tv->tv_sec + (double) tv->tv_usec * 1e-6;
+}
+
+
+static void
+benchmark (fir_maker_t filter_maker, const char *implementation_name)
+{
+  int  i;
+  gr_complex   coeffs[NTAPS];
+  gr_complex   input[BLOCK_SIZE + NTAPS];
+  long n;
+  gr_complex   result;
+#ifdef HAVE_SYS_RESOURCE_H
+  struct rusage        rusage_start;
+  struct rusage        rusage_stop;
+#else
+  double clock_start;
+  double clock_end;
+#endif
+
+
+  // setup coefficients and input data
+
+  for (i = 0; i < NTAPS; i++)
+    coeffs[i] = gr_complex(random() - RANDOM_MAX/2, random() - RANDOM_MAX/2);
+
+  for (i = 0; i < BLOCK_SIZE + NTAPS; i++)
+    input[i] = gr_complex(random() - RANDOM_MAX/2, random() - RANDOM_MAX/2);
+
+  std::vector<gr_complex> taps (&coeffs[0], &coeffs[NTAPS]);
+  filter_t *f = filter_maker (taps);
+
+  // get starting CPU usage
+#ifdef HAVE_SYS_RESOURCE_H
+  if (getrusage (RUSAGE_SELF, &rusage_start) < 0){
+    perror ("getrusage");
+    exit (1);
+  }
+#else
+  clock_start= (double) clock() * (1000000. / CLOCKS_PER_SEC);
+#endif
+  // do the actual work
+
+  for (n = 0; n < TOTAL_TEST_SIZE; n += BLOCK_SIZE){
+    int        j;
+    for (j = 0; j < BLOCK_SIZE; j++){
+      result = f->filter ((gr_complex*)&input[j]);
+    }
+  }
+
+  // get ending CPU usage
+#ifdef HAVE_SYS_RESOURCE_H
+  if (getrusage (RUSAGE_SELF, &rusage_stop) < 0){
+    perror ("getrusage");
+    exit (1);
+  }
+
+  // compute results
+
+  double user =
+    timeval_to_double (&rusage_stop.ru_utime)
+    - timeval_to_double (&rusage_start.ru_utime);
+
+  double sys =
+    timeval_to_double (&rusage_stop.ru_stime)
+    - timeval_to_double (&rusage_start.ru_stime);
+
+  double total = user + sys;
+#else
+  clock_end = (double) clock() * (1000000. / CLOCKS_PER_SEC);
+  double total = clock_end - clock_start;
+#endif
+
+  double macs = NTAPS * (double) TOTAL_TEST_SIZE;
+
+  printf ("%10s: taps: %4d  input: %4g  cpu: %6.3f  taps/sec: %10.4g  \n",
+         implementation_name, NTAPS, (double) TOTAL_TEST_SIZE, total, macs / total);
+
+  delete f;
+}
+
+static void
+do_all ()
+{
+  std::vector<gr_fir_ccc_info>         info;
+  gr_fir_util::get_gr_fir_ccc_info (&info);    // get all known CCC implementations
+
+  for (std::vector<gr_fir_ccc_info>::iterator p = info.begin ();
+       p != info.end () ;
+       ++p){
+    benchmark (p->create, p->name);
+  }
+}
+
+int
+main (int argc, char **argv)
+{
+  do_all ();
+  return 0;
+}
diff --git a/gnuradio-core/src/tests/benchmark_dotprod_ccf.cc b/gnuradio-core/src/tests/benchmark_dotprod_ccf.cc
new file mode 100644 (file)
index 0000000..866f7f6
--- /dev/null
@@ -0,0 +1,151 @@
+/* -*- 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 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.
+ */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include <stdio.h>
+#include <sys/time.h>
+#ifdef HAVE_SYS_RESOURCE_H
+#include <sys/resource.h>
+#endif
+#include <unistd.h>
+#include <gr_fir_util.h>
+#include <gr_fir_ccf.h>
+#include <random.h>
+
+#define TOTAL_TEST_SIZE               (40 * 1000 * 1000L)
+#define        NTAPS                                256
+#define        BLOCK_SIZE                   (50 * 1000)        /* fits in cache */
+
+#if ((TOTAL_TEST_SIZE % BLOCK_SIZE) != 0)
+#error "TOTAL_TEST_SIZE % BLOCK_SIZE must equal 0"
+#endif
+
+typedef gr_fir_ccf* (*fir_maker_t)(const std::vector<float> &taps);
+typedef gr_fir_ccf  filter_t;
+
+
+static double
+timeval_to_double (const struct timeval *tv)
+{
+  return (double) tv->tv_sec + (double) tv->tv_usec * 1e-6;
+}
+
+
+static void
+benchmark (fir_maker_t filter_maker, const char *implementation_name)
+{
+  int  i;
+  float coeffs[NTAPS];
+  gr_complex   input[BLOCK_SIZE + NTAPS];
+  long n;
+  gr_complex   result;
+#ifdef HAVE_SYS_RESOURCE_H
+  struct rusage        rusage_start;
+  struct rusage        rusage_stop;
+#else
+  double clock_start;
+  double clock_end;
+#endif
+
+  // setup coefficients and input data
+
+  for (i = 0; i < NTAPS; i++)
+    coeffs[i] = random() - RANDOM_MAX/2;
+
+  for (i = 0; i < BLOCK_SIZE + NTAPS; i++)
+    input[i] = gr_complex(random() - RANDOM_MAX/2, random() - RANDOM_MAX/2);
+
+  std::vector<float> taps (&coeffs[0], &coeffs[NTAPS]);
+  filter_t *f = filter_maker (taps);
+
+  // get starting CPU usage
+
+#ifdef HAVE_SYS_RESOURCE_H
+  if (getrusage (RUSAGE_SELF, &rusage_start) < 0){
+    perror ("getrusage");
+    exit (1);
+  }
+#else
+  clock_start= (double) clock() * (1000000. / CLOCKS_PER_SEC);
+#endif
+
+  // do the actual work
+
+  for (n = 0; n < TOTAL_TEST_SIZE; n += BLOCK_SIZE){
+    int        j;
+    for (j = 0; j < BLOCK_SIZE; j++){
+      result = f->filter (&input[j]);
+    }
+  }
+
+  // get ending CPU usage
+
+#ifdef HAVE_SYS_RESOURCE_H
+  if (getrusage (RUSAGE_SELF, &rusage_stop) < 0){
+    perror ("getrusage");
+    exit (1);
+  }
+
+  // compute results
+
+  double user =
+    timeval_to_double (&rusage_stop.ru_utime)
+    - timeval_to_double (&rusage_start.ru_utime);
+
+  double sys =
+    timeval_to_double (&rusage_stop.ru_stime)
+    - timeval_to_double (&rusage_start.ru_stime);
+
+  double total = user + sys;
+#else
+  clock_end= (double) clock() * (1000000. / CLOCKS_PER_SEC);
+  double total = clock_end - clock_start;
+#endif
+
+  double macs = NTAPS * (double) TOTAL_TEST_SIZE;
+
+  printf ("%10s: taps: %4d  input: %4g  cpu: %6.3f  taps/sec: %10.4g  \n",
+         implementation_name, NTAPS, (double) TOTAL_TEST_SIZE, total, macs / total);
+
+  delete f;
+}
+
+static void
+do_all ()
+{
+  std::vector<gr_fir_ccf_info>         info;
+  gr_fir_util::get_gr_fir_ccf_info (&info);    // get all known CCF implementations
+
+  for (std::vector<gr_fir_ccf_info>::iterator p = info.begin ();
+       p != info.end () ;
+       ++p){
+    benchmark (p->create, p->name);
+  }
+}
+
+int
+main (int argc, char **argv)
+{
+  do_all ();
+  return 0;
+}
diff --git a/gnuradio-core/src/tests/benchmark_dotprod_fcc.cc b/gnuradio-core/src/tests/benchmark_dotprod_fcc.cc
new file mode 100644 (file)
index 0000000..af54707
--- /dev/null
@@ -0,0 +1,152 @@
+/* -*- 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 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.
+ */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include <stdio.h>
+#include <sys/time.h>
+#ifdef HAVE_SYS_RESOURCE_H
+#include <sys/resource.h>
+#endif
+#include <unistd.h>
+#include <gr_fir_util.h>
+#include <gr_fir_fcc.h>
+#include <random.h>
+
+#define TOTAL_TEST_SIZE               (40 * 1000 * 1000L)
+#define        NTAPS                                256
+#define        BLOCK_SIZE                   (50 * 1000)        /* fits in cache */
+
+#if ((TOTAL_TEST_SIZE % BLOCK_SIZE) != 0)
+#error "TOTAL_TEST_SIZE % BLOCK_SIZE must equal 0"
+#endif
+
+typedef gr_fir_fcc* (*fir_maker_t)(const std::vector<gr_complex> &taps);
+typedef gr_fir_fcc  filter_t;
+
+
+static double
+timeval_to_double (const struct timeval *tv)
+{
+  return (double) tv->tv_sec + (double) tv->tv_usec * 1e-6;
+}
+
+
+static void
+benchmark (fir_maker_t filter_maker, const char *implementation_name)
+{
+  int  i;
+  gr_complex coeffs[NTAPS];
+  float input[BLOCK_SIZE + NTAPS];
+  long n;
+  gr_complex   result;
+#ifdef HAVE_SYS_RESOURCE_H
+  struct rusage        rusage_start;
+  struct rusage        rusage_stop;
+#else
+  double clock_start;
+  double clock_end;
+#endif
+
+
+
+  // setup coefficients and input data
+
+  for (i = 0; i < NTAPS; i++)
+    coeffs[i] = gr_complex(random() - RANDOM_MAX/2, random() - RANDOM_MAX/2);
+
+  for (i = 0; i < BLOCK_SIZE + NTAPS; i++)
+    input[i] = random() - RANDOM_MAX/2;
+
+  std::vector<gr_complex> taps (&coeffs[0], &coeffs[NTAPS]);
+  filter_t *f = filter_maker (taps);
+  
+  // get starting CPU usage
+#ifdef HAVE_SYS_RESOURCE_H
+  if (getrusage (RUSAGE_SELF, &rusage_start) < 0){
+    perror ("getrusage");
+    exit (1);
+  }
+#else
+  clock_start = (double) clock() * (1000000. / CLOCKS_PER_SEC);
+#endif
+
+  // do the actual work
+
+  for (n = 0; n < TOTAL_TEST_SIZE; n += BLOCK_SIZE){
+    int        j;
+    for (j = 0; j < BLOCK_SIZE; j++){
+      result = f->filter (&input[j]);
+    }
+  }
+
+  // get ending CPU usage
+
+#ifdef HAVE_SYS_RESOURCE_H
+  if (getrusage (RUSAGE_SELF, &rusage_stop) < 0){
+    perror ("getrusage");
+    exit (1);
+  }
+
+  // compute results
+
+  double user =
+    timeval_to_double (&rusage_stop.ru_utime)
+    - timeval_to_double (&rusage_start.ru_utime);
+
+  double sys =
+    timeval_to_double (&rusage_stop.ru_stime)
+    - timeval_to_double (&rusage_start.ru_stime);
+
+  double total = user + sys;
+#else
+  clock_end= (double) clock() * (1000000. / CLOCKS_PER_SEC);
+  double total = clock_end - clock_start;
+#endif
+
+  double macs = NTAPS * (double) TOTAL_TEST_SIZE;
+
+  printf ("%10s: taps: %4d  input: %4g  cpu: %6.3f  taps/sec: %10.4g  \n",
+         implementation_name, NTAPS, (double) TOTAL_TEST_SIZE, total, macs / total);
+
+  delete f;
+}
+
+static void
+do_all ()
+{
+  std::vector<gr_fir_fcc_info>         info;
+  gr_fir_util::get_gr_fir_fcc_info (&info);    // get all known FCC implementations
+
+  for (std::vector<gr_fir_fcc_info>::iterator p = info.begin ();
+       p != info.end () ;
+       ++p){
+    benchmark (p->create, p->name);
+  }
+}
+
+int
+main (int argc, char **argv)
+{
+  do_all ();
+  return 0;
+}
diff --git a/gnuradio-core/src/tests/benchmark_dotprod_fsf.cc b/gnuradio-core/src/tests/benchmark_dotprod_fsf.cc
new file mode 100644 (file)
index 0000000..7317e83
--- /dev/null
@@ -0,0 +1,151 @@
+/* -*- 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 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.
+ */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include <stdio.h>
+#include <sys/time.h>
+#ifdef HAVE_SYS_RESOURCE_H
+#include <sys/resource.h>
+#endif
+#include <unistd.h>
+#include <gr_fir_util.h>
+#include <gr_fir_fsf.h>
+#include <random.h>
+
+#define TOTAL_TEST_SIZE               (40 * 1000 * 1000L)
+#define        NTAPS                                256
+#define        BLOCK_SIZE                   (50 * 1000)        /* fits in cache */
+
+#if ((TOTAL_TEST_SIZE % BLOCK_SIZE) != 0)
+#error "TOTAL_TEST_SIZE % BLOCK_SIZE must equal 0"
+#endif
+
+typedef gr_fir_fsf* (*fir_maker_t)(const std::vector<float> &taps);
+typedef gr_fir_fsf  filter_t;
+
+
+static double
+timeval_to_double (const struct timeval *tv)
+{
+  return (double) tv->tv_sec + (double) tv->tv_usec * 1e-6;
+}
+
+
+static void
+benchmark (fir_maker_t filter_maker, const char *implementation_name)
+{
+  int  i;
+  float coeffs[NTAPS];
+  float input[BLOCK_SIZE + NTAPS];
+  long n;
+  short        result;
+#ifdef HAVE_SYS_RESOURCE_H
+  struct rusage        rusage_start;
+  struct rusage        rusage_stop;
+#else
+  double clock_start;
+  double clock_end;
+#endif
+
+  // setup coefficients and input data
+
+  for (i = 0; i < NTAPS; i++)
+    coeffs[i] = random() - RANDOM_MAX/2;
+
+  for (i = 0; i < BLOCK_SIZE + NTAPS; i++)
+    input[i] = random() - RANDOM_MAX/2;
+
+  std::vector<float> taps (&coeffs[0], &coeffs[NTAPS]);
+  filter_t *f = filter_maker (taps);
+
+  // get starting CPU usage
+#ifdef HAVE_SYS_RESOURCE_H
+  if (getrusage (RUSAGE_SELF, &rusage_start) < 0){
+    perror ("getrusage");
+    exit (1);
+  }
+#else
+  clock_start= (double) clock() * (1000000. / CLOCKS_PER_SEC);
+#endif
+
+  // do the actual work
+
+  for (n = 0; n < TOTAL_TEST_SIZE; n += BLOCK_SIZE){
+    int        j;
+    for (j = 0; j < BLOCK_SIZE; j++){
+      result = f->filter (&input[j]);
+    }
+  }
+
+  // get ending CPU usage
+
+#ifdef HAVE_SYS_RESOURCE_H
+  if (getrusage (RUSAGE_SELF, &rusage_stop) < 0){
+    perror ("getrusage");
+    exit (1);
+  }
+
+  // compute results
+
+  double user =
+    timeval_to_double (&rusage_stop.ru_utime)
+    - timeval_to_double (&rusage_start.ru_utime);
+
+  double sys =
+    timeval_to_double (&rusage_stop.ru_stime)
+    - timeval_to_double (&rusage_start.ru_stime);
+
+  double total = user + sys;
+#else
+  clock_end= (double) clock() * (1000000. / CLOCKS_PER_SEC);
+  double total = clock_end - clock_start;
+#endif
+
+  double macs = NTAPS * (double) TOTAL_TEST_SIZE;
+
+  printf ("%10s: taps: %4d  input: %4g  cpu: %6.3f  taps/sec: %10.4g  \n",
+         implementation_name, NTAPS, (double) TOTAL_TEST_SIZE, total, macs / total);
+
+  delete f;
+}
+
+static void
+do_all ()
+{
+  std::vector<gr_fir_fsf_info>         info;
+  gr_fir_util::get_gr_fir_fsf_info (&info);    // get all known FFF implementations
+
+  for (std::vector<gr_fir_fsf_info>::iterator p = info.begin ();
+       p != info.end ();
+       ++p){
+
+    benchmark (p->create, p->name);
+  }
+}
+
+int
+main (int argc, char **argv)
+{
+  do_all ();
+  return 0;
+}
diff --git a/gnuradio-core/src/tests/benchmark_dotprod_scc.cc b/gnuradio-core/src/tests/benchmark_dotprod_scc.cc
new file mode 100644 (file)
index 0000000..d67fad5
--- /dev/null
@@ -0,0 +1,151 @@
+/* -*- 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 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.
+ */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include <stdio.h>
+#include <sys/time.h>
+#ifdef HAVE_SYS_RESOURCE_H
+#include <sys/resource.h>
+#endif
+#include <unistd.h>
+#include <gr_fir_util.h>
+#include <gr_fir_scc.h>
+#include <random.h>
+
+#define TOTAL_TEST_SIZE               (40 * 1000 * 1000L)
+#define        NTAPS                                256
+#define        BLOCK_SIZE                   (50 * 1000)        /* fits in cache */
+
+#if ((TOTAL_TEST_SIZE % BLOCK_SIZE) != 0)
+#error "TOTAL_TEST_SIZE % BLOCK_SIZE must equal 0"
+#endif
+
+typedef gr_fir_scc* (*fir_maker_t)(const std::vector<gr_complex> &taps);
+typedef gr_fir_scc  filter_t;
+
+
+static double
+timeval_to_double (const struct timeval *tv)
+{
+  return (double) tv->tv_sec + (double) tv->tv_usec * 1e-6;
+}
+
+
+static void
+benchmark (fir_maker_t filter_maker, const char *implementation_name)
+{
+  int  i;
+  gr_complex coeffs[NTAPS];
+  short input[BLOCK_SIZE + NTAPS];
+  long n;
+  gr_complex   result;
+#ifdef HAVE_SYS_RESOURCE_H
+  struct rusage        rusage_start;
+  struct rusage        rusage_stop;
+#else
+  double clock_start;
+  double clock_end;
+#endif
+  
+
+  // setup coefficients and input data
+
+  for (i = 0; i < NTAPS; i++)
+    coeffs[i] = gr_complex(random() - RANDOM_MAX/2, random() - RANDOM_MAX/2);
+
+  for (i = 0; i < BLOCK_SIZE + NTAPS; i++)
+    input[i] = random() - RANDOM_MAX/2;
+
+  std::vector<gr_complex> taps (&coeffs[0], &coeffs[NTAPS]);
+  filter_t *f = filter_maker (taps);
+  
+  // get starting CPU usage
+
+#ifdef HAVE_SYS_RESOURCE_H
+  if (getrusage (RUSAGE_SELF, &rusage_start) < 0){
+    perror ("getrusage");
+    exit (1);
+  }
+#else
+  clock_start = (double) clock() * (1000000. / CLOCKS_PER_SEC);
+#endif
+
+  // do the actual work
+
+  for (n = 0; n < TOTAL_TEST_SIZE; n += BLOCK_SIZE){
+    int        j;
+    for (j = 0; j < BLOCK_SIZE; j++){
+      result = f->filter (&input[j]);
+    }
+  }
+
+  // get ending CPU usage
+#ifdef HAVE_SYS_RESOURCE_H
+  if (getrusage (RUSAGE_SELF, &rusage_stop) < 0){
+    perror ("getrusage");
+    exit (1);
+  }
+
+  // compute results
+
+  double user =
+    timeval_to_double (&rusage_stop.ru_utime)
+    - timeval_to_double (&rusage_start.ru_utime);
+
+  double sys =
+    timeval_to_double (&rusage_stop.ru_stime)
+    - timeval_to_double (&rusage_start.ru_stime);
+
+  double total = user + sys;
+#else
+  clock_end= (double) clock () * (1000000. / CLOCKS_PER_SEC);
+  double total = clock_end -clock_start;
+#endif
+
+  double macs = NTAPS * (double) TOTAL_TEST_SIZE;
+
+  printf ("%10s: taps: %4d  input: %4g  cpu: %6.3f  taps/sec: %10.4g  \n",
+         implementation_name, NTAPS, (double) TOTAL_TEST_SIZE, total, macs / total);
+
+  delete f;
+}
+
+static void
+do_all ()
+{
+  std::vector<gr_fir_scc_info>         info;
+  gr_fir_util::get_gr_fir_scc_info (&info);    // get all known SCC implementations
+
+  for (std::vector<gr_fir_scc_info>::iterator p = info.begin ();
+       p != info.end () ;
+       ++p){
+    benchmark (p->create, p->name);
+  }
+}
+
+int
+main (int argc, char **argv)
+{
+  do_all ();
+  return 0;
+}
diff --git a/gnuradio-core/src/tests/benchmark_nco.cc b/gnuradio-core/src/tests/benchmark_nco.cc
new file mode 100644 (file)
index 0000000..fb0fe68
--- /dev/null
@@ -0,0 +1,219 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002,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.
+ */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include <stdio.h>
+#include <sys/time.h>
+#ifdef HAVE_SYS_RESOURCE_H
+#include <sys/resource.h>
+#endif
+#include <unistd.h>
+#include <gr_nco.h>
+#include <gr_fxpt_nco.h>
+
+#define ITERATIONS     20000000
+#define BLOCK_SIZE     (10 * 1000)     // fits in cache
+
+#define FREQ   5003.123
+
+static double
+timeval_to_double (const struct timeval *tv)
+{
+  return (double) tv->tv_sec + (double) tv->tv_usec * 1e-6;
+}
+
+
+static void
+benchmark (void test (float *x, float *y), const char *implementation_name)
+{
+#ifdef HAVE_SYS_RESOURCE_H
+  struct rusage        rusage_start;
+  struct rusage        rusage_stop;
+#else
+  double clock_start;
+  double clock_end;
+#endif
+  float output[2*BLOCK_SIZE];
+  float *x = &output[0], *y = &output[BLOCK_SIZE];
+
+  // touch memory
+  memset(output, 0, 2*BLOCK_SIZE*sizeof(float));
+
+  // get starting CPU usage
+#ifdef HAVE_SYS_RESOURCE_H
+  if (getrusage (RUSAGE_SELF, &rusage_start) < 0){
+    perror ("getrusage");
+    exit (1);
+  }
+#else
+  clock_start = (double) clock() * (1000000. / CLOCKS_PER_SEC);
+#endif
+  // do the actual work
+
+  test (x, y);
+
+  // get ending CPU usage
+
+#ifdef HAVE_SYS_RESOURCE_H
+  if (getrusage (RUSAGE_SELF, &rusage_stop) < 0){
+    perror ("getrusage");
+    exit (1);
+  }
+
+  // compute results
+
+  double user =
+    timeval_to_double (&rusage_stop.ru_utime)
+    - timeval_to_double (&rusage_start.ru_utime);
+
+  double sys =
+    timeval_to_double (&rusage_stop.ru_stime)
+    - timeval_to_double (&rusage_start.ru_stime);
+
+  double total = user + sys;
+#else
+  clock_end = (double) clock () * (1000000. / CLOCKS_PER_SEC);
+  double total = clock_end - clock_start;
+#endif
+
+  printf ("%18s:  cpu: %6.3f  steps/sec: %10.3e\n",
+         implementation_name, total, ITERATIONS / total);
+}
+
+// ----------------------------------------------------------------
+// Don't compare the _vec with other functions since memory store's
+// are involved.
+
+void basic_sincos_vec (float *x, float *y)
+{
+  gr_nco<float,float>  nco;
+
+  nco.set_freq (2 * M_PI / FREQ);
+
+  for (int i = 0; i < ITERATIONS/BLOCK_SIZE; i++){
+    for (int j = 0; j < BLOCK_SIZE; j++){
+      nco.sincos (&x[2*j+1], &x[2*j]);
+      nco.step ();
+    }
+  }
+}
+
+void native_sincos_vec (float *x, float *y)
+{
+  gr_nco<float,float>  nco;
+
+  nco.set_freq (2 * M_PI / FREQ);
+  for (int i = 0; i < ITERATIONS/BLOCK_SIZE; i++){
+    nco.sincos ((gr_complex*)x, BLOCK_SIZE);
+  }
+}
+
+void fxpt_sincos_vec (float *x, float *y)
+{
+  gr_fxpt_nco  nco;
+  
+  nco.set_freq (2 * M_PI / FREQ);
+  
+  for (int i = 0; i < ITERATIONS/BLOCK_SIZE; i++){
+    nco.sincos ((gr_complex*)x, BLOCK_SIZE);
+  }
+}
+
+// ----------------------------------------------------------------
+
+void native_sincos (float *x, float *y)
+{
+  gr_nco<float,float>  nco;
+
+  nco.set_freq (2 * M_PI / FREQ);
+
+  for (int i = 0; i < ITERATIONS; i++){
+    nco.sincos (x, y);
+    nco.step ();
+  }
+}
+
+void fxpt_sincos (float *x, float *y)
+{
+  gr_fxpt_nco  nco;
+
+  nco.set_freq (2 * M_PI / FREQ);
+
+  for (int i = 0; i < ITERATIONS; i++){
+    nco.sincos (x, y);
+    nco.step ();
+  }
+}
+
+// ----------------------------------------------------------------
+
+void native_sin (float *x, float *y)
+{
+  gr_nco<float,float>  nco;
+
+  nco.set_freq (2 * M_PI / FREQ);
+
+  for (int i = 0; i < ITERATIONS; i++){
+    *x = nco.sin ();
+    nco.step ();
+  }
+}
+
+void fxpt_sin (float *x, float *y)
+{
+  gr_fxpt_nco  nco;
+
+  nco.set_freq (2 * M_PI / FREQ);
+
+  for (int i = 0; i < ITERATIONS; i++){
+    *x = nco.sin ();
+    nco.step ();
+  }
+}
+
+// ----------------------------------------------------------------
+
+void nop_fct (float *x, float *y)
+{
+}
+
+void nop_loop (float *x, float *y)
+{
+  for (int i = 0; i < ITERATIONS; i++){
+    nop_fct (x, y);
+  }
+}
+
+int
+main (int argc, char **argv)
+{
+  benchmark (nop_loop, "nop loop");
+  benchmark (native_sin, "native sine");
+  benchmark (fxpt_sin, "fxpt sine");
+  benchmark (native_sincos, "native sin/cos");
+  benchmark (fxpt_sincos, "fxpt sin/cos");
+  benchmark (basic_sincos_vec, "basic sin/cos vec");
+  benchmark (native_sincos_vec, "native sin/cos vec");
+  benchmark (fxpt_sincos_vec, "fxpt sin/cos vec");
+}
diff --git a/gnuradio-core/src/tests/benchmark_vco.cc b/gnuradio-core/src/tests/benchmark_vco.cc
new file mode 100644 (file)
index 0000000..1b290df
--- /dev/null
@@ -0,0 +1,166 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002,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 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.
+ */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include <stdio.h>
+#include <sys/time.h>
+#ifdef HAVE_SYS_RESOURCE_H
+#include <sys/resource.h>
+#endif
+#include <unistd.h>
+#include <gr_vco.h>
+#include <gr_fxpt_vco.h>
+
+#define ITERATIONS     5000000
+#define BLOCK_SIZE     (10 * 1000)     // fits in cache
+
+#define FREQ   5003.123
+#define K      4.9999999
+#define AMPLITUDE      2.444444444
+
+
+static double
+timeval_to_double (const struct timeval *tv)
+{
+  return (double) tv->tv_sec + (double) tv->tv_usec * 1e-6;
+}
+
+
+static void
+benchmark (void test (float *x, const float *y), const char *implementation_name)
+{
+#ifdef HAVE_SYS_RESOURCE_H
+  struct rusage        rusage_start;
+  struct rusage        rusage_stop;
+#else
+  double clock_start;
+  double clock_end;
+#endif
+  float output[BLOCK_SIZE];
+  float input[BLOCK_SIZE];
+
+  // touch memory
+  memset(output, 0, BLOCK_SIZE*sizeof(float));
+  for (int i = 0; i<BLOCK_SIZE; i++)
+    input[i] = sin(i);
+
+  // get starting CPU usage
+#ifdef HAVE_SYS_RESOURCE_H
+  if (getrusage (RUSAGE_SELF, &rusage_start) < 0){
+    perror ("getrusage");
+    exit (1);
+  }
+#else
+  clock_start = (double) clock() * (1000000. / CLOCKS_PER_SEC);
+#endif
+  // do the actual work
+
+  test (output, input);
+
+  // get ending CPU usage
+
+#ifdef HAVE_SYS_RESOURCE_H
+  if (getrusage (RUSAGE_SELF, &rusage_stop) < 0){
+    perror ("getrusage");
+    exit (1);
+  }
+
+  // compute results
+
+  double user =
+    timeval_to_double (&rusage_stop.ru_utime)
+    - timeval_to_double (&rusage_start.ru_utime);
+
+  double sys =
+    timeval_to_double (&rusage_stop.ru_stime)
+    - timeval_to_double (&rusage_start.ru_stime);
+
+  double total = user + sys;
+#else
+  clock_end = (double) clock () * (1000000. / CLOCKS_PER_SEC);
+  double total = clock_end - clock_start;
+#endif
+
+  printf ("%18s:  cpu: %6.3f  steps/sec: %10.3e\n",
+         implementation_name, total, ITERATIONS / total);
+}
+
+// ----------------------------------------------------------------
+
+void basic_vco (float *output, const float *input)
+{
+  double phase = 0;
+
+  for (int j = 0; j < ITERATIONS/BLOCK_SIZE; j++){
+    for (int i = 0; i < BLOCK_SIZE; i++){
+      output[i] = cos(phase) * AMPLITUDE;
+      phase += input[i] * K;
+
+      while (phase > 2 * M_PI)
+       phase -= 2 * M_PI;
+
+      while (phase < -2 * M_PI)
+       phase += 2 * M_PI;
+    }
+  }
+}
+
+void native_vco (float *output, const float *input)
+{
+  gr_vco<float,float>  vco;
+
+  for (int j = 0; j < ITERATIONS/BLOCK_SIZE; j++){
+    vco.cos(output, input, BLOCK_SIZE, K, AMPLITUDE);
+  }
+    }
+
+void fxpt_vco (float *output, const float *input)
+{
+  gr_fxpt_vco  vco;
+
+  for (int j = 0; j < ITERATIONS/BLOCK_SIZE; j++){
+    vco.cos(output, input, BLOCK_SIZE, K, AMPLITUDE);
+  }
+}
+
+// ----------------------------------------------------------------
+
+void nop_fct (float *x, const float *y)
+{
+}
+
+void nop_loop (float *x, const float *y)
+{
+  for (int i = 0; i < ITERATIONS; i++){
+    nop_fct (x, y);
+  }
+}
+
+int
+main (int argc, char **argv)
+{
+  benchmark (nop_loop, "nop loop");
+  benchmark (basic_vco, "basic vco");
+  benchmark (native_vco, "native vco");
+  benchmark (fxpt_vco, "fxpt 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_all.cc b/gnuradio-core/src/tests/test_all.cc
new file mode 100644 (file)
index 0000000..b5e1b46
--- /dev/null
@@ -0,0 +1,46 @@
+/* -*- 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 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.
+ */
+
+#include <cppunit/TextTestRunner.h>
+
+#include <qa_runtime.h>
+#include <qa_general.h>
+#include <qa_filter.h>
+// #include <qa_atsc.h>
+
+// FIXME add atsc back in.
+
+int 
+main (int argc, char **argv)
+{
+  
+  CppUnit::TextTestRunner      runner;
+
+  runner.addTest (qa_runtime::suite ());
+  runner.addTest (qa_general::suite ());
+  runner.addTest (qa_filter::suite ());
+  // runner.addTest (qa_atsc::suite ());
+  
+  bool was_successful = runner.run ("", false);
+
+  return was_successful ? 0 : 1;
+}
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..cca96d5
--- /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 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.
+ */
+
+#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/tests/test_buffers.py b/gnuradio-core/src/tests/test_buffers.py
new file mode 100755 (executable)
index 0000000..b321132
--- /dev/null
@@ -0,0 +1,136 @@
+#!/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 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.
+# 
+
+from gnuradio import gr, gru
+from gnuradio import audio
+from gnuradio.eng_option import eng_option
+from optparse import OptionParser
+
+import time
+import sys
+
+# Test script to test setting up the buffers using gr_test
+# For very large buffers it will fail when you hit the circbuf memory limit.
+# On linux this limit is shmmax, it will fail when it tries to create a buffer > shmmax.
+# With a 2.6 or later kernel you can set the shmmax limit manually in a root console
+#show current shmmax limit
+#$ cat /proc/sys/kernel/shmmax
+#33554432
+
+#set shmmax limit manually to 300MB
+#echo 300000000 >/proc/sys/kernel/shmmax
+
+#show new shmmax limit
+#$ cat /proc/sys/kernel/shmmax
+#300000000
+
+class my_graph(gr.flow_graph):
+
+    def __init__(self, seconds,history,output_multiple):
+        gr.flow_graph.__init__(self)
+
+        parser = OptionParser(option_class=eng_option)
+        parser.add_option("-O", "--audio-output", type="string", default="",
+                          help="pcm output device name.  E.g., hw:0,0 or /dev/dsp")
+        parser.add_option("-r", "--sample-rate", type="eng_float", default=48000,
+                          help="set sample rate to RATE (48000)")
+        (options, args) = parser.parse_args ()
+        if len(args) != 0:
+            parser.print_help()
+            raise SystemExit, 1
+
+        sample_rate = int(options.sample_rate)
+        ampl = 0.1
+
+        src0 = gr.sig_source_f (sample_rate, gr.GR_SIN_WAVE, 350, ampl)
+
+        nsamples=int(sample_rate * seconds) #1 seconds
+        # gr.test (const std::string &name=std::string("gr_test"),
+        # int min_inputs=1, int max_inputs=1, unsigned int sizeof_input_item=1,
+        # int min_outputs=1, int max_outputs=1, unsigned int sizeof_output_item=1,
+        # unsigned int history=1,unsigned int output_multiple=1,double relative_rate=1.0,
+        # bool fixed_rate=true,gr_consume_type_t cons_type=CONSUME_NOUTPUT_ITEMS, gr_produce_type_t prod_type=PRODUCE_NOUTPUT_ITEMS);
+        name="gr_test"
+        min_inputs=1
+        max_inputs=1
+        sizeof_input_item=gr.sizeof_float
+        min_outputs=1
+        max_outputs=1
+        sizeof_output_item=gr.sizeof_float
+        #history=1 # problems start at 8150
+        #output_multiple=1 #problems start at 8000 in combination with large history
+        relative_rate=1.0
+        fixed_rate=True
+        consume_type=gr.CONSUME_NOUTPUT_ITEMS
+        produce_type=gr.PRODUCE_NOUTPUT_ITEMS
+        test = gr.test(name, min_inputs,max_inputs,sizeof_input_item,
+                                 min_outputs,max_outputs,sizeof_output_item,
+                                 history,output_multiple,relative_rate,
+                                 fixed_rate, consume_type,produce_type)
+        #test = gr.test("gr_test",1,1,gr.sizeof_float,
+        #                         1,1,gr.sizeof_float,
+        #                         1,1,1.0,
+        #                         True, gr.CONSUME_NOUTPUT_ITEMS,gr.PRODUCE_NOUTPUT_ITEMS)
+        #unsigned int history=1,unsigned int output_multiple=1,double relative_rate=1.0,
+        #bool fixed_rate=false
+        dst = audio.sink (sample_rate, options.audio_output)
+        head= gr.head(gr.sizeof_float, nsamples)
+
+        self.connect (src0,test,head,(dst, 0))
+
+
+if __name__ == '__main__':
+
+    seconds=5.0
+    output_multiple=1
+    for history in (1,1000,8000,8100,8150,8175,8190,8191,8192,8193,8194,8195,9000,10000,100000,1000000,10000000): #,100000000):
+      sys.stdout.flush()
+      sys.stderr.flush()
+      print 'Test with history=', history, 'output_multiple=',output_multiple
+      sys.stdout.flush()
+      sys.stderr.flush()
+      succeed=True
+      starttime=time.time()
+      try:
+          my_graph(seconds,history,output_multiple).run()
+      except KeyboardInterrupt:
+          pass
+      except:
+          print "\nAn exception has terminated the graph."
+          exception=True
+          succeed=False
+      sys.stdout.flush()
+      sys.stderr.flush()
+      if succeed:
+         print ''
+      endtime=time.time()
+      duration=endtime - starttime
+      if (duration < 0.5*seconds) and (succeed):
+         print "A problem has terminated the graph."
+         succeed=False
+      if (duration > 1.5*seconds) and (succeed):
+         print "Something slowed the graph down considerably."
+         succeed=False
+
+      print 'The test result was:' , succeed
+      print 'Test duration' , duration
+      print ''
diff --git a/gnuradio-core/src/tests/test_filter.cc b/gnuradio-core/src/tests/test_filter.cc
new file mode 100644 (file)
index 0000000..1b2c57b
--- /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 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.
+ */
+
+#include <cppunit/TextTestRunner.h>
+#include <qa_filter.h>
+
+int 
+main (int argc, char **argv)
+{
+  
+  CppUnit::TextTestRunner      runner;
+
+  runner.addTest (qa_filter::suite ());
+  
+  bool was_successful = runner.run ("", false);
+
+  return was_successful ? 0 : 1;
+}
diff --git a/gnuradio-core/src/tests/test_general.cc b/gnuradio-core/src/tests/test_general.cc
new file mode 100644 (file)
index 0000000..9f93b9d
--- /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 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.
+ */
+
+#include <cppunit/TextTestRunner.h>
+#include <qa_general.h>
+
+int 
+main (int argc, char **argv)
+{
+  
+  CppUnit::TextTestRunner      runner;
+
+  runner.addTest (qa_general::suite ());
+  
+  bool was_successful = runner.run ("", false);
+
+  return was_successful ? 0 : 1;
+}
diff --git a/gnuradio-core/src/tests/test_runtime.cc b/gnuradio-core/src/tests/test_runtime.cc
new file mode 100644 (file)
index 0000000..72290a9
--- /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 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.
+ */
+
+#include <cppunit/TextTestRunner.h>
+#include <qa_runtime.h>
+
+int 
+main (int argc, char **argv)
+{
+  
+  CppUnit::TextTestRunner      runner;
+
+  runner.addTest (qa_runtime::suite ());
+  
+  bool was_successful = runner.run ("", false);
+
+  return was_successful ? 0 : 1;
+}
diff --git a/gnuradio-core/src/tests/test_vmcircbuf.cc b/gnuradio-core/src/tests/test_vmcircbuf.cc
new file mode 100644 (file)
index 0000000..e00b170
--- /dev/null
@@ -0,0 +1,44 @@
+/* -*- 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 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.
+ */
+
+#include <gr_vmcircbuf.h>
+#include <stdio.h>
+
+int 
+main (int argc, char **argv)
+{
+  int  verbose = 1;            // summary
+
+  if (argc > 1)
+    verbose = 2;               // extra chatty
+
+  bool ok = gr_vmcircbuf_sysconfig::test_all_factories (verbose);
+
+  if (ok){
+    fprintf (stdout, "test_vmcircbuf: OK.  We've got at least one workable solution\n");
+    return 0;
+  }
+  else {
+    fprintf (stdout, "test_vmcircbuf: NOT OK.  We don't have a workable solution\n");
+    return 1;
+  }
+}
diff --git a/gnuradio-core/src/utils/Makefile.am b/gnuradio-core/src/utils/Makefile.am
new file mode 100644 (file)
index 0000000..ee0bd43
--- /dev/null
@@ -0,0 +1,43 @@
+#
+# 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 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.
+#
+
+include $(top_srcdir)/Makefile.common
+
+EXTRA_DIST =                   \
+       db_width.m              \
+       filter_tools.m          \
+       plot_freq_response.m    \
+       plot_freq_response_db.m \
+       plot_freq_response_phase.m      \
+       plotfft.m               \
+       plotfftavgk.m           \
+       plotfftavgk_db.m        \
+       plotfftk.m              \
+       plotfftk_db.m           \
+       put_markers.m           \
+       read_char_binary.m      \
+       read_complex_binary.m   \
+       read_float_binary.m     \
+       read_int_binary.m       \
+       read_short_binary.m     \
+       single_pole_iir.m       \
+       write_float_binary.m    \
+       write_short_binary.m
diff --git a/gnuradio-core/src/utils/cool.m b/gnuradio-core/src/utils/cool.m
new file mode 100644 (file)
index 0000000..eff194d
--- /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 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
+
+%% -*- 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/db_width.m b/gnuradio-core/src/utils/db_width.m
new file mode 100644 (file)
index 0000000..c12dfd1
--- /dev/null
@@ -0,0 +1,35 @@
+%
+% 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 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.
+
+%% find the N-dB width of the given filter
+%% E.g., to find the 3-dB width, use width = db_width (taps, -3.0)
+%% the result is normalized to nyquist == 1
+
+function width = db_width (taps, db)
+  [H,w] = freqz (taps, 1, 4096);
+  Habs = abs(H);
+  max_H = max(Habs);
+  min_H = min(Habs);
+  threshold = max_H * 10^(db/20);
+  if (min_H > threshold)
+    error ("The %g dB point is never reached", db);
+  end
+  above = Habs >= threshold;
+  width = sum(above) / length (above);
diff --git a/gnuradio-core/src/utils/filter_tools.m b/gnuradio-core/src/utils/filter_tools.m
new file mode 100644 (file)
index 0000000..78a50b7
--- /dev/null
@@ -0,0 +1,42 @@
+%
+% 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 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.
+% 
+%% equivalent to the C++ code in VrComplexFIRfilter::buildFilterComplex
+
+1;
+
+%% hamming window, nothing fancy
+
+function taps = build_filter_complex_lp (gain, ntaps)
+
+  taps = gain * (0.54 - 0.46 * cos (2 * pi * (0:ntaps-1)' / (ntaps-1)));
+
+end
+
+%% old_taps describes a low pass filter, convert it to bandpass
+%% centered at center_freq.  center_freq is normalized to Fs (sampling freq)
+
+function new_taps = freq_shift_filter (old_taps, center_freq)
+
+  ntaps = length(old_taps);
+  
+  new_taps = exp (j*2*pi*center_freq*(0:ntaps-1)') .* old_taps;
+
+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..a17b8ad
--- /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 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.
+# 
+
+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..8718bae
--- /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 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.
+# 
+
+## 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..e26883c
--- /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 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.
+# 
+
+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/plot_freq_response.m b/gnuradio-core/src/utils/plot_freq_response.m
new file mode 100644 (file)
index 0000000..bf186fa
--- /dev/null
@@ -0,0 +1,36 @@
+#
+# 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 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.
+# 
+
+function plot_freq_response (b,...)
+  if (nargin == 1)
+    ## Response of an FIR filter
+    a = 1;
+  elseif (nargin == 2)
+    ## response of an IIR filter
+    a = va_arg ();
+  endif
+
+  [H,w] = freqz (b,a);
+  plot (w/(2*pi), abs(H));
+  grid;
+  xlabel ('Normalized Frequency (Fs == 1)');
+  ylabel ('Magnitude (linear)');
+endfunction
diff --git a/gnuradio-core/src/utils/plot_freq_response_db.m b/gnuradio-core/src/utils/plot_freq_response_db.m
new file mode 100644 (file)
index 0000000..d6ebce3
--- /dev/null
@@ -0,0 +1,39 @@
+#
+# 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 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.
+# 
+
+function plot_freq_response_db (b,...)
+  if (nargin == 1)
+    ## Response of an FIR filter
+    a = 1;
+  elseif (nargin == 2)
+    ## response of an IIR filter
+    a = va_arg ();
+  endif
+
+  [H,w] = freqz (b,a);
+
+  grid;
+  xlabel ('Normalized Frequency (Fs == 1)');
+  ylabel ('Magnitude Squared (dB)');
+  abs = abs(H);
+# plot (w/(2*pi), 20 * log10 (abs/max(abs)));
+  plot (w/(2*pi), 20 * log10 (abs));
+endfunction
diff --git a/gnuradio-core/src/utils/plot_freq_response_phase.m b/gnuradio-core/src/utils/plot_freq_response_phase.m
new file mode 100644 (file)
index 0000000..f30ff7d
--- /dev/null
@@ -0,0 +1,38 @@
+#
+# 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 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.
+# 
+
+function plot_freq_response_db (b,...)
+  if (nargin == 1)
+    ## Response of an FIR filter
+    a = 1;
+  elseif (nargin == 2)
+    ## response of an IIR filter
+    a = va_arg ();
+  endif
+
+  [H,w] = freqz (b,a);
+
+  grid;
+  xlabel ('Normalized Frequency (Fs == 1)');
+  ylabel ('Phase (radians)');
+  abs = abs(H);
+  plot (w/(2*pi), atan2(imag(H), real(H)))
+endfunction
diff --git a/gnuradio-core/src/utils/plotfft.m b/gnuradio-core/src/utils/plotfft.m
new file mode 100644 (file)
index 0000000..5af149a
--- /dev/null
@@ -0,0 +1,40 @@
+#
+# 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 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.
+#
+
+function plotfft (data, sample_rate)
+
+  if (nargin == 1)
+    sample_rate = 1.0;
+  endif;
+
+  if ((m = nargchk (1,2,nargin)))
+    usage (m);
+  endif;
+
+  len = length(data);
+  s = fft (data.*kaiser(len, 5));
+
+  incr = sample_rate/len;
+  min_x = -sample_rate/2;
+  max_x = sample_rate/2 - incr;
+  plot (min_x:incr:max_x, abs(fftshift(s)));
+
+endfunction
diff --git a/gnuradio-core/src/utils/plotfftavgk.m b/gnuradio-core/src/utils/plotfftavgk.m
new file mode 100644 (file)
index 0000000..3e19f40
--- /dev/null
@@ -0,0 +1,61 @@
+#
+# 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 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.
+# 
+
+function plotfftavgk_db (all_data, k, sample_rate)
+
+  if (nargin == 2)
+    sample_rate = 1.0;
+  endif;
+
+  if ((m = nargchk (2,3,nargin)))
+    usage (m);
+  endif;
+
+  ## len = 1024;
+  len = 8192;
+  ##window = ones (len, 1);
+  window = kaiser (len, 5);
+
+  s = zeros (len,1);
+
+  count = min (100, floor (length (all_data)/len));
+
+  for i = 0:count-1;
+    data = all_data((k+i)*len + 1 : (k+i+1)*len);
+    s = s + abs (fft (data.*window));
+  endfor;
+
+  s = s ./ count;
+
+  incr = sample_rate/len;
+  min_x = -sample_rate/2;
+  max_x = sample_rate/2 - incr;
+
+  x = min_x:incr:max_x;
+  ## y = 20 * log10(fftshift(s));
+  y = (fftshift(s));
+  plot (x, y);
+
+  i = find (y == max(y))
+  x(i)
+  y(i)
+
+endfunction
diff --git a/gnuradio-core/src/utils/plotfftavgk_db.m b/gnuradio-core/src/utils/plotfftavgk_db.m
new file mode 100644 (file)
index 0000000..6dbb0f5
--- /dev/null
@@ -0,0 +1,73 @@
+#
+# 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 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.
+# 
+
+function plotfftavgk_db (all_data, k, sample_rate)
+
+  if (nargin == 2)
+    sample_rate = 1.0;
+  endif;
+
+  if ((m = nargchk (2,3,nargin)))
+    usage (m);
+  endif;
+
+  len = 1024;
+  ## len = 8192;
+  ##window = ones (len, 1);
+  #window = kaiser (len, 5);
+  window = hanning (len);
+
+  s = zeros (len,1);
+
+  count = min (100, floor (length (all_data)/len));
+
+  for i = 0:count-1;
+    data = all_data((k+i)*len + 1 : (k+i+1)*len);
+    s = s + abs (fft (data.*window));
+  endfor;
+
+  s = s ./ count;
+
+  incr = sample_rate/len;
+
+  if is_complex (all_data);
+    min_x = -sample_rate/2;
+    max_x = sample_rate/2 - incr;
+
+    x = min_x:incr:max_x;
+    y = 20 * log10(fftshift(s));
+    plot (x, y);
+  else
+    min_x = 0
+    max_x = sample_rate/2 - incr;
+
+    x = min_x:incr:max_x;
+    y = 20 * log10(s(1:len/2));
+    plot (x, y);
+    
+  endif;
+
+
+  i = find (y == max(y))
+  x(i)
+  y(i)
+
+endfunction
diff --git a/gnuradio-core/src/utils/plotfftk.m b/gnuradio-core/src/utils/plotfftk.m
new file mode 100644 (file)
index 0000000..bf93ea5
--- /dev/null
@@ -0,0 +1,41 @@
+#
+# 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 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.
+# 
+
+function plotfftk (all_data, k, sample_rate)
+
+  if (nargin == 2)
+    sample_rate = 1.0;
+  endif;
+
+  if ((m = nargchk (2,3,nargin)))
+    usage (m);
+  endif;
+
+  len = 1024;
+  data = all_data(k*len + 1 : (k+1)*len);
+  s = fft (data.*kaiser(len, 5));
+
+  incr = sample_rate/len;
+  min_x = -sample_rate/2;
+  max_x = sample_rate/2 - incr;
+  plot (min_x:incr:max_x, abs(fftshift(s)));
+
+endfunction
diff --git a/gnuradio-core/src/utils/plotfftk_db.m b/gnuradio-core/src/utils/plotfftk_db.m
new file mode 100644 (file)
index 0000000..498c22f
--- /dev/null
@@ -0,0 +1,43 @@
+#
+# 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 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.
+# 
+
+function plotfftk_db (all_data, k, sample_rate)
+
+  if (nargin == 2)
+    sample_rate = 1.0;
+  endif;
+
+  if ((m = nargchk (2,3,nargin)))
+    usage (m);
+  endif;
+
+  len = 1024;
+  data = all_data(k*len + 1 : (k+1)*len);
+  ## s = fft (data.*kaiser(len, 5));
+  ## s = fft (data.*hamming(len));
+  s = fft (data.*hanning(len));
+
+  incr = sample_rate/len;
+  min_x = -sample_rate/2;
+  max_x = sample_rate/2 - incr;
+  plot (min_x:incr:max_x, 20 * log10(abs(fftshift(s))));
+
+endfunction
diff --git a/gnuradio-core/src/utils/put_markers.m b/gnuradio-core/src/utils/put_markers.m
new file mode 100644 (file)
index 0000000..e35aee9
--- /dev/null
@@ -0,0 +1,32 @@
+#
+# 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 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.
+# 
+
+function put_markers (y)
+
+  if (nargin == 0)
+    y = 25;
+  endif;
+
+  hold on;
+  plot (3.06e6, y, '@');
+  plot (8.44e6, y, '@');
+
+endfunction
diff --git a/gnuradio-core/src/utils/rainbow.m b/gnuradio-core/src/utils/rainbow.m
new file mode 100644 (file)
index 0000000..e19bd67
--- /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 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
+
+## -*- 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_char_binary.m b/gnuradio-core/src/utils/read_char_binary.m
new file mode 100644 (file)
index 0000000..d33bd91
--- /dev/null
@@ -0,0 +1,45 @@
+%
+% 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 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.
+% 
+
+function v = read_char_binary (filename, count)
+
+  %% usage: read_char (filename, [count])
+  %%
+  %%  open filename and return the contents, treating them as
+  %%  signed short integers
+  %%
+
+  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
+    v = fread (f, count, 'char');
+    fclose (f);
+  end
diff --git a/gnuradio-core/src/utils/read_complex_binary.m b/gnuradio-core/src/utils/read_complex_binary.m
new file mode 100644 (file)
index 0000000..6f538f3
--- /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 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.
+% 
+
+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/gnuradio-core/src/utils/read_float_binary.m b/gnuradio-core/src/utils/read_float_binary.m
new file mode 100644 (file)
index 0000000..ac8461f
--- /dev/null
@@ -0,0 +1,45 @@
+%
+% 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 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.
+% 
+
+function v = read_float_binary (filename, count)
+
+  %% usage: read_float_binary (filename, [count])
+  %%
+  %%  open filename and return the contents, treating them as
+  %%  32 bit floats
+  %%
+
+  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
+    v = fread (f, count, 'float');
+    fclose (f);
+  end
diff --git a/gnuradio-core/src/utils/read_int_binary.m b/gnuradio-core/src/utils/read_int_binary.m
new file mode 100644 (file)
index 0000000..ca4f733
--- /dev/null
@@ -0,0 +1,46 @@
+%
+% Copyright 2001,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 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.
+% 
+
+function v = read_int_binary (filename, count)
+
+  %% usage: read_int_binary (filename, [count])
+  %%
+  %%  open filename and return the contents, treating them as
+  %%  signed integers
+  %%
+
+  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
+    v = fread (f, count, 'int');
+    fclose (f);
+  end
+end
diff --git a/gnuradio-core/src/utils/read_short_binary.m b/gnuradio-core/src/utils/read_short_binary.m
new file mode 100644 (file)
index 0000000..361392b
--- /dev/null
@@ -0,0 +1,45 @@
+%
+% 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 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.
+% 
+
+function v = read_short_binary (filename, count)
+
+  %% usage: read_short_binary (filename, [count])
+  %%
+  %%  open filename and return the contents, treating them as
+  %%  signed short integers
+  %%
+
+  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
+    v = fread (f, count, 'short');
+    fclose (f);
+  end
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..7533dda
--- /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 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.
+# 
+
+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/single_pole_iir.m b/gnuradio-core/src/utils/single_pole_iir.m
new file mode 100644 (file)
index 0000000..13d6b4d
--- /dev/null
@@ -0,0 +1,25 @@
+#
+# 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 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.
+# 
+
+function [b, a] = single_pole_iir (alpha)
+  b = [alpha];
+  a = [1, alpha - 1];
+endfunction
\ No newline at end of file
diff --git a/gnuradio-core/src/utils/write_float_binary.m b/gnuradio-core/src/utils/write_float_binary.m
new file mode 100644 (file)
index 0000000..c0d2743
--- /dev/null
@@ -0,0 +1,40 @@
+#
+# 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 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.
+# 
+
+function v = write_float_binary (data, filename)
+
+  ## usage: write_float_binary (data, filename)
+  ##
+  ##  open filename and write data to it as 32 bit floats
+  ##
+
+  if ((m = nargchk (2,2,nargin)))
+    usage (m);
+  endif;
+
+  f = fopen (filename, "wb");
+  if (f < 0)
+    v = 0;
+  else
+    v = fwrite (f, data, "float");
+    fclose (f);
+  endif;
+endfunction;
diff --git a/gnuradio-core/src/utils/write_short_binary.m b/gnuradio-core/src/utils/write_short_binary.m
new file mode 100644 (file)
index 0000000..ffe502e
--- /dev/null
@@ -0,0 +1,40 @@
+#
+# 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 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.
+# 
+
+function v = write_short_binary (data, filename)
+
+  ## usage: write_short_binary (data, filename)
+  ##
+  ##  open filename and write data to it as 16 bit shorts
+  ##
+
+  if ((m = nargchk (2,2,nargin)))
+    usage (m);
+  endif;
+
+  f = fopen (filename, "wb");
+  if (f < 0)
+    v = 0;
+  else
+    v = fwrite (f, data, "short");
+    fclose (f);
+  endif;
+endfunction;
diff --git a/gnuradio-examples/AUTHORS b/gnuradio-examples/AUTHORS
new file mode 100644 (file)
index 0000000..6bd4117
--- /dev/null
@@ -0,0 +1,2 @@
+Eric Blossom <eb@comsec.com>
+Matt Ettus <matt@ettus.com>
diff --git a/gnuradio-examples/ChangeLog b/gnuradio-examples/ChangeLog
new file mode 100644 (file)
index 0000000..e2c630e
--- /dev/null
@@ -0,0 +1,381 @@
+2006-06-20  Eric Blossom  <eb@comsec.com>
+
+       * python/gmsk2/receive_path.py, python/gmsk2/transmit_path.py,
+       benchmark_gmsk_{tx,rx}.py: refactored to use modulation
+       independent pkt.py code.  Lays the foundation for a single set of
+       tools that can exercise all modulations.  More work required to
+       meet that goal, but we're closing in.
+
+       * python/gmsk2/tunnel.py: refactored version of
+       tunnel_ip_null_mac.  This creates a virtual ethernet inteface
+       using the TAP driver, and then tunnels packets across the air
+       using GMSK and a simple carrier sense MAC.  Fixed problem with
+       truncation of large packets which was leading to stalls.
+       
+       * python/gmsk2/tunnel_ip_null_mac.py: removed.  Replaced with
+       tunnel.py
+
+2006-06-15  Eric Blossom  <eb@comsec.com>
+
+       * python/usrp/usrp_fft.py (app_flow_graph.set_decim): added
+       missing return value.
+
+       * python/usrp/usrp_oscope.py, python/usrp/usrp_fft.py: you can now
+       change the decimation factor in the GUI.
+
+2006-06-06  Eric Blossom  <eb@comsec.com>
+
+       * python/gmsk2/mpsk.py: Lots of rework.  QPSK is now
+       working with mpsk_test.py.   Need to confirm it on the air, and then
+       make BPSK work again.
+       
+
+2006-05-30  Eric Blossom  <eb@comsec.com>
+
+       Standardized on mpsk as the prefix.  Renamed a bunch of stuff to
+       restore sanity: 
+       * python/gmsk2/benchmark_xpsk_rx.py -> python/gmsk2/benchmark_mpsk_rx.py
+       * python/gmsk2/benchmark_xpsk_tx.py -> python/gmsk2/benchmark_mpsk_tx.py
+       * python/gmsk2/psk_receive_path.py  -> python/gmsk2/mpsk_receive_path.py
+       * python/gmsk2/psk_transmit_path.py -> python/gmsk2/mpsk_transmit_path.py
+       * python/gmsk2/xpsk.py              -> python/gmsk2/mpsk.py
+       * python/gmsk2/xpsk_pkt.py          -> python/gmsk2/mpsk_pkt.py
+       * python/gmsk2/xpsk_test.py         -> python/gmsk2/mpsk_test.py
+
+2006-05-29  Eric Blossom  <eb@comsec.com>
+
+       * python/gmsk2/qpsk_tester.py, python/gmsk2/qpsk_usrp_tester.py:
+       new.  Test benches for qpsk code. Thanks Tom!
+
+2005-12-19  Martin Dvh <gnuradiomail@olifantasia.com>
+
+       updated multi_usrp examples which should now work 'out-of-the-box' with current cvs
+        (you need updated usrp,gr-usrp, gnuradio-core and gnuradio-examples)
+
+       * configure.ac: added python/usrp_multi/Makefile
+       * python/Makefile.am: added multi_usrp
+       * python/multi_usrp/.cvsignore: new
+       * python/multi_usrp/Makefile.am: new
+       * python/multi_usrp/README: Made this into a real readme
+       * python/multi_usrp/multi_usrp_oscope.py: changed to work with current usrp_multi code in cvs
+       * python/multi_usrp/multi_usrp_rx_cfile.py: changed to work with current usrp_multi code in cvs
+       * python/multi_usrp/multi_usrp.py: removed
+       * python/multi_usrp/multi_usrp_oscope_showcounters.py: removed
+       * python/multi_usrp/multi_usrp_oscope_simple.py: removed
+       * python/multi_usrp/multi_usrp_oscope_standalone.py: removed
+       * python/multi_usrp/multi_usrp_rx_tofile.py: removed
+       * python/multi_usrp/multi_usrp_rx_tofile_standalone.py: removed
+       * python/multi_usrp/multi_usrp_test_counting.py: removed
+
+2006-05-10  Eric Blossom  <eb@comsec.com>
+
+       * python/gmsk2/psk_transmit_path.py: add diff=False per Bob Vincent.
+
+2006-04-06  Eric Blossom  <eb@comsec.com>
+
+       * python/usrp/usrp_fft.py: removed explicit setting of fft_rate.
+       The code will now pick it up from config files.
+
+2006-03-12  Eric Blossom  <eb@comsec.com>
+
+       * python/usrp/usrp_siggen.py: added daughterboard support.
+       * python/usrp/usrp_oscope.py, python/usrp/usrp_fft.py: fixed so
+       frequency can be set even after an invalid frequency is passed on
+       the command line.
+
+2006-03-10  Eric Blossom  <eb@comsec.com>
+
+       * python/gmsk2/xpsk.py: doc fixes.
+
+2006-03-08  Eric Blossom  <eb@comsec.com>
+
+       * python/usrp/fm_tx_2_daughterboards.py: example that transmits
+       different signals out two daughterboards.
+
+2006-02-02  Eric Blossom  <eb@comsec.com>
+
+       * python/usrp/usrp_oscope.py: support manual scaling of
+       Y-axis.  Smarter defaulting of rx_subdev_spec if user doesn't pick.
+       * python/usrp/usrp_fft.py: Smarter defaulting of rx_subdev_spec if user doesn't pick.
+
+2006-02-01  Eric Blossom  <eb@comsec.com>
+
+       * python/gmsk2/transmit_path.py: fixed so it works on both A and B sides.
+
+2006-01-30  Eric Blossom  <eb@comsec.com>
+
+       * python/gmsk2/receive_path.py (receive_path.set_auto_tr): added
+       set_auto_tr to the receive path to have it work properly with
+       changes in auto t/r switching semantics.
+
+       * python/usrp/fm_tx4.py (fm_tx_graph.__init__): changes to have it
+       work in both A and B sides.
+
+2005-12-19  Martin Dvh <gnuradiomail@olifantasia.com>
+
+       * multi_usrp/README, multi_usrp/multi_usrp.py, multi_usrp/multi_usrp_oscope.py,
+       multi_usrp/multi_usrp_oscope_showcounters.py, multi_usrp/multi_usrp_oscope_simple.py,
+       multi_usrp/multi_usrp_oscope_standalone.py, multi_usrp/multi_usrp_rx_tofile.py,
+       multi_usrp/multi_usrp_rx_tofile_standalone.py, multi_usrp/multi_usrp_test_counting.py:
+       new directory and examples to exercise multiple usrps coherently
+       connected together.  These require additional code that is not yet
+       in the repository.
+
+2005-12-13  Eric Blossom  <eb@comsec.com>
+
+       * python/usrp/usrp_wfm_rcv2_nogui.py: new: receive two FM stations
+       simultaneously.
+
+2005-12-09  Eric Blossom  <eb@comsec.com>
+
+       * python/gmsk2/tunnel_ip_null_mac.py: cleaned up.  gathered mac
+       functions together.
+       
+       * python/usrp/usrp_wfm_rcv_pll.py (pick_subdevice), 
+       python/usrp/usrp_wfm_rcv_nogui.py (pick_subdevice): use library version.
+       * python/usrp/fm_tx4.py: explicity call set_enable(True) to turn
+       on transmitter (required due to policy change).  Also removed
+       pick_tx_subdevice.  Now use version in usrp library.
+
+2005-12-09  Eric Blossom  <eb@comsec.com>
+
+       Made release 2.6
+
+2005-12-08  Eric Blossom  <eb@comsec.com>
+
+       * python/gmsk/rx.py, python/gmsk/rx2.py, python/gmsk/tx.py,
+       python/gmsk/tx2.py, python/gmsk/xcvr.py, python/gmsk/xcvr2.py,
+       ggmsk-test.py, gmsk-test.py: removed.  Use the code in ../gmsk2 instead.
+
+       * python/gmsk2/receive_path.py, python/gmsk2/transmit_path.py:
+       New.  Extracted hierarchical blocks from benchmark_gmsk_{tx,rx}.py
+
+2005-12-06  Eric Blossom  <eb@comsec.com>
+
+       * python/gmsk2/benchmark_gmsk_tx.py,
+       python/gmsk2/benchmark_gmsk_rx.py: now support "--bitrate" command
+       line arg.
+       * python/gmsk2/pick_bitrate.py: given a bitrate, determine
+       samples/baud and interp/decim ratio.
+
+2005-11-11  Eric Blossom  <eb@comsec.com>
+
+       * python/usrp/usrp_nbfm_ptt.py, python/usrp/usrp_wfm_rcv.py: moved
+       pick_xx_subdev to library.
+
+2005-11-01  Eric Blossom  <eb@comsec.com>
+
+       * python/usrp/dbs_nbfm.py: removed.  Use usrp_nbfm_rcv.py instead.
+
+2005-10-24  Eric Blossom  <eb@comsec.com>
+
+       * python/usrp/usrp_oscope.py: basically identical to usrp_fft.py,
+       but uses oscope sink.
+
+       * python/usrp/usrp_wfm_rcv_nogui.py, python/usr/usrp_wfm_rcv.py:
+       increased usrp decimation factor to 200 reduce host cpu
+       requirements.  With the half-band in the FPGA, good decimation
+       factors are even values in [8,256].
+
+2005-10-14  Eric Blossom  <eb@comsec.com>
+
+       * python/usrp/usrp_fft.py: gui mods.
+       * python/usrp/usrp_wfm_rcv.py: reworked gui.
+
+2005-10-11  Eric Blossom  <eb@comsec.com>
+
+       * python/usrp/usrp_waterfall.py: removed.  Use usrp_fft.py -W instead.
+
+2005-10-10  Eric Blossom  <eb@comsec.com>
+
+       * python/audio/audio_copy.py, python/audio/audio_play.py,
+       python/audio/audio_to_file.py, python/audio/dial_tone.py,
+       python/audio/mono_tone.py, python/audio/multi_tone.py,
+       python/audio/spectrum_inversion.py: revised to use standard
+       command line args and canonical structure.
+
+2005-09-21  Eric Blossom  <eb@comsec.com>
+
+       * python/usrp/usrp_fft.py: extensively reworked to use new
+       daughterboard auto-instantiation framework.
+
+2005-07-30 Martin Dvh <gnuradiomail@olifantasia.com>
+
+       * python/usrp/tvrx_tv_rcv.py: PAL/NTSC TV demod.  Work in progress.
+
+2005-07-21  Eric Blossom  <eb@comsec.com>
+
+       * python/usrp/benchmark_usb.py, python/usrp/usrp_rx_cfile.py,
+       python/usrp/usrp_oscope.py, python/usrp/dbs_debug: doc fix.
+
+2005-07-19  Eric Blossom  <eb@comsec.com>
+
+       * python/usrp/ayfabtu.py: new.  Transmit on 25 frequencies simultaneously!
+
+2005-07-02  Eric Blossom  <eb@comsec.com>
+
+       * config/gr_no_undefined.m4, config/gr_x86_64.m4: new, x86_64 support.
+       * config/gr_python.m4: backed out search for libpython, making
+       x86_64 work and breaking Cygwin/MinGW.
+       * configure.ac: mods for x86_64, $(NO_UNDEFINED)
+       
+       * python/usrp/usrp_waterfall.py, python/usrp/dbs_debug.py,
+       python/usrp/flexrf_debug.py, python/usrp/flexrf_siggen.py,
+       python/usrp/usrp_fft.py, python/usrp/usrp_oscope.py,
+       python/usrp/usrp_rx_cfile.py, python/usrp/usrp_rx_file.py,
+       python/usrp/usrp_siggen.py, python/usrp/usrp_waterfall.py:
+       gru.hexint fix for python 2.4.
+       
+2005-06-17  Eric Blossom  <eb@comsec.com>
+
+       * python/apps/README: new directory for applications.
+
+2005-06-16  Eric Blossom  <eb@comsec.com>
+
+       * python/usrp/tvrx_wfm_rcv_gui.py: add -d audio_device option; fix
+       volume increment so up == 1.0/down; fix default range of bottom FFT.
+
+2005-06-13  Eric Blossom  <eb@comsec.com>
+
+       * python/usrp/tvrx_wfm_rcv_gui.py: removed limit on what frequency
+       can be set.
+
+2005-05-09  Stephane Fillod  <f8cfe@free.fr>
+
+        * config/gr_sysv_shm.m4: SysV shared memory not mandatory
+       * config/gr_pwin32.m4, config/gr_python.m4, config/lf_cxx.m4:
+         fixes for Cygwin, MinGW
+
+2005-04-27  Eric Blossom  <eb@comsec.com>
+
+       * python/digital_voice/encdec.py: simulate gsm voice encode / 
+       gmsk mod / gmsk demod / gsm voice decode.
+       
+2005-03-29  Eric Blossom <eb@comsec.com>
+
+       * python/gmsk/ggmsk-test.py, python/gmsk/gmsk-test.py: new GMSK
+       test code from Joshua Lackey <jl@noether.uoregon.edu>
+
+       * python/gmsk/tx.py, python/gmsk/rx.py: new tx and rx modules that
+       depending on command line options do either FSK or GMSK and use
+       either files, sockets, named pipes or a USRP for their inputs and
+       outputs.  From Bob Vincent <bvincent@bbn.com>
+
+2005-03-29  Eric Blossom  <eb@comsec.com>
+       
+       * python/audio/audio_copy.py, python/audio/multi_tone.py,
+       python/audio/mono_tone.py: replace ALSA specific default argument
+       with ""
+
+2005-03-04  Eric Blossom  <eb@comsec.com>
+
+       * python/usrp/nbfm_ptt_quick_and_dirty.py: simple NBFM
+       push-to-talk transceiver. (Works, but has a latency problem that
+       needs to be fixed)
+
+2005-02-28  Eric Blossom  <eb@comsec.com>
+
+       * python/usrp/fsk_tx.py: reduced gain, added -N (no gui) flag.
+       * python/usrp/fsk_rx.py: added -N (no gui) flag.
+       Running Tx and Rx on same machine (1.4 GHz Pentium M) 100kb/sec
+       burns up about 70% of CPU with -N options on both.
+
+2005-02-25  Eric Blossom  <eb@comsec.com>
+
+       Removed usrp0 directory.
+       Moved contents of usrp1 directory into usrp directory.
+
+2005-02-22  Eric Blossom  <eb@comsec.com>
+
+       * python/usrp1/nbfm_rcv.py: added squelch.
+
+2004-10-13  Eric Blossom  <eb@comsec.com>
+
+       * configure.ac: upped rev to 0.2cvs
+
+2004-10-11  Eric Blossom  <eb@comsec.com>
+
+       * Makefile.am (EXTRA_DIST): added config.h.in
+
+2004-10-07  Chuck Swiger  <cswiger@widomaker.com>
+       
+       * python/audio/audio_to_file.py: coerce audio sample rate to int.
+
+2004-10-07  Eric Blossom  <eb@comsec.com>
+       
+       * python/usrp1/wfm_rcv.py: new.  Single channel broadcast FM
+       receiver for usrp1 + microtune 4937.
+
+2004-09-23  Eric Blossom  <eb@comsec.com>
+
+       * config/usrp_fusb_tech.m4, config/bnv_have_qt.m4, config/cppunit.m4,
+       config/gr_check_mc4020.m4, config/gr_check_usrp.m4, config/gr_doxygen.m4,
+       config/gr_gprof.m4, config/gr_scripting.m4, config/gr_set_md_cpu.m4,
+       config/pkg.m4, config/usrp_fusb_tech.m4: added additional quoting
+       to first arg of AC_DEFUN to silence automake warning.
+
+2004-09-18  Eric Blossom  <eb@comsec.com>
+
+       These changes happened somewhere around DCC
+
+       * python/usrp/usrp_fft.py: new
+       * python/usrp1/dsb_tx.py: new double sideband AM transmitter
+       * python/usrp1/fm_tx4.py: simultaneous 4 channel narrow band FM transmitter
+       * python/usrp1/fsk_rx.py: FSK Rx module.  Needs some work.
+       * python/usrp1/fsk_tx.py: FSK Tx module.  Needs some work.
+
+2004-08-19  Eric Blossom  <eb@comsec.com>
+
+       * python/usrp/usrp_rx_file.py (main): added command line parsing.
+       * python/usrp/usrp_siggen.py: added command line parsing.
+
+       * python/usrp1/test_digital_loopback_lfsr.py,
+       python/usrp1/test_digital_loopback_counting.py,
+       python/usrp1/test_digital_counting.py: new.  Take advantage of
+       scheduler fix to implement both the tx and rx path's in the same
+       flow graph.
+
+
+2004-07-31  Eric Blossom  <eb@comsec.com>
+
+       * python/usrp0, python/usrp1: new directories for rev specific examples.
+       * python/usrp1/loopback.py (main): new.
+
+2004-07-30  Eric Blossom  <eb@comsec.com>
+
+       * python/usrp/usrp_siggen.py: now directly queries hardware for dac freq.
+       * python/usrp/usrp_rx_file.py: now directly queries hardware for dac freq.
+
+2004-07-17  Eric Blossom  <eb@comsec.com>
+
+       * python/mc4020/fm_demod.py: updated to use new mc4020 block, formatting
+
+2004-07-12  Eric Blossom  <eb@comsec.com>
+
+       * configure.ac: upped rev to 0.1cvs
+
+2004-07-03  Eric Blossom  <eb@comsec.com>
+
+       * python/usrp/usrp_siggen.py: Yeah!  The first demo program that
+       reconfigures the flow graph on the fly!
+
+#
+# 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.
+# 
diff --git a/gnuradio-examples/Makefile.am b/gnuradio-examples/Makefile.am
new file mode 100644 (file)
index 0000000..7611138
--- /dev/null
@@ -0,0 +1,28 @@
+#
+# 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.
+# 
+
+include $(top_srcdir)/Makefile.common
+
+EXTRA_DIST = README.hacking
+SUBDIRS = python
+
+pkgconfigdir = $(libdir)/pkgconfig
+pkgconfig_DATA =
diff --git a/gnuradio-examples/NEWS b/gnuradio-examples/NEWS
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/gnuradio-examples/README b/gnuradio-examples/README
new file mode 100644 (file)
index 0000000..89515bb
--- /dev/null
@@ -0,0 +1,68 @@
+#
+# 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.
+# 
+
+Welcome!
+
+This package is a collection of examples for the GNU Radio 2.x toolkit.
+
+They assume that at a minimum, you've got the gnuradio-core
+package installed.  In addition, depending on what i/o devices you
+have, you may want to consider installing:
+
+  gr-usrp              : support for Universal Software Radio Peripheral (Rev 1)
+  gr-audio-oss         : sound card support using OSS
+  gr-audio-alsa                : sound card support using ALSA
+  gr-audio-osx         : sound card support for OS/X
+  gr-mc4020            : Measurement Computing PCI-DAS 4020/12 A/D card
+
+
+You'll need to set your PYTHONPATH environment variable so that the
+GNU Radio toolkit and optional packages can be found by python.
+
+PYTHONPATH should include the path of the local site-packages
+directory.  It has the general form:
+
+  ${prefix}/lib/python${pythonversion}/site-packages
+
+If the above packages were installed using the default prefix
+(/usr/local) and you're using python 2.3, this should work:
+
+  $ export PYTHONPATH=/usr/local/lib/python2.3/site-packages
+
+You may want to add this to your ~/.bash_profile or similar file.
+
+
+Once PYTHONPATH is set, you should be able to run any of the examples
+for which you have the required i/o devices.
+
+To ensure that your setup is sane, try this:
+
+  $ python
+  >>> from gnuradio import gr
+
+If this works, your PYTHONPATH is set correctly.
+
+
+Have fun!
+
+The GNU Radio team
+
+
diff --git a/gnuradio-examples/README.hacking b/gnuradio-examples/README.hacking
new file mode 100644 (file)
index 0000000..44d4247
--- /dev/null
@@ -0,0 +1,39 @@
+* Standard command line options
+
+When building applications or examples, if your command has any of
+these options, please use the following short and long names:
+
+
+
+  # General
+
+  parser = OptionParser(option_class=eng_option)
+  
+  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("-F", "--filename", type="string", default=None)
+
+  # Audio devices
+
+  parser.add_option("-I", "--audio-input", type=string, default="",
+                    help="pcm input device name.  E.g., hw:0,0 or /dev/dsp")
+  parser.add_option("-O", "--audio-output", type=string, default="",
+                    help="pcm output device name.  E.g., hw:0,0 or /dev/dsp")
+  parser.add_option("-r", "--sample-rate", type="eng_float", default=48000,
+                    help="set sample rate to RATE (48000)")
+  
+  # USRP specific
+  
+  parser.add_option("-R", "--rx-subdev-spec", type="subdev", default=(0, 0),
+                    help="select USRP Rx side A or B (default=A)")
+  parser.add_option("-T", "--tx-subdev-spec", type="subdev", default=(0, 0),
+                    help="select USRP Tx side A or B (default=A)")
+  parser.add_option("-d", "--decim", type="int", default=16,
+                    help="set fgpa decimation rate to DECIM (default=16)")
+  parser.add_option("-i", "--interp", type="int", default=32,
+                    help="set fgpa interpolation rate to INTERP (default=32)")
+  parser.add_option("-n", "--nchannels", type=intx, default=1,
+                    help="set number of channels to NCHANNELS (default=1)")
+
diff --git a/gnuradio-examples/python/Makefile.am b/gnuradio-examples/python/Makefile.am
new file mode 100644 (file)
index 0000000..73b7921
--- /dev/null
@@ -0,0 +1,22 @@
+#
+# 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.
+# 
+
+SUBDIRS = audio mc4020 usrp gmsk2 digital_voice multi_usrp
diff --git a/gnuradio-examples/python/apps/README b/gnuradio-examples/python/apps/README
new file mode 100644 (file)
index 0000000..a3f041b
--- /dev/null
@@ -0,0 +1,26 @@
+#
+# 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 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 directory servers as the parent directory for various and sundry
+applications such as scanners, HF radios, etc.  Each subdirectory
+shall have a README file that includes a short description of what the
+application does, and a list of hardware dependencies.  E.g., requires
+a USRP with an xyz daughterboard, connected to a footronics magic box.
diff --git a/gnuradio-examples/python/apps/hf_explorer/README b/gnuradio-examples/python/apps/hf_explorer/README
new file mode 100644 (file)
index 0000000..5f780b3
--- /dev/null
@@ -0,0 +1,48 @@
+hfx.py is meant to be a full-featured Long Wave / Medium Wave
+and Short Wave (250kHz to 30Mhz) AM and Single Sideband receiver.
+It uses the USRP with a Basic RX board, and will need an
+antenna and some preamps, about 30db gain will work. See the
+'Help' menu or hfx_help for more info.
+
+----------------------------------------------------------
+
+hfx2.py is a major revision built about complex fir filter
+coeffecients ability and cleaner python script. Inherits
+most features from hfx.py - Powermate knob supported but
+not required, tooltip frequency display, single click
+tuning, AGC, record to disk, play from disk and record audio.
+New feature is ability to tailor the audio passband with two
+sliders over the spectrum display. The sliders almost align
+with the actual frequency. Preset filter settings for LSB
+(-3000 to 0kHz), USB (0 to +3000kHz), CW (-400 to -800Hz)
+and AM (-5kHz from carrier to +5kHz).
+
+AM now switches in a synchronous PLL detector with the
+carriers at 7.5kHz. The PLL carrier is displayed in the
+bottom display and helps show where on the upper spectrum
+the demodulated signal lies. Everything gets shifted up
+7.5kHz in AM, center frequency, tooltips, etc.  The target
+AM carrier needs to be closely tuned in, it will have a
+hollow sound untill it is locked, and then the PLL carrier
+in the bottom display will jump up and remain relatively 
+constant. There is a slider "AM sync carrier" to play with
+different levels to mix with the signal for demodulation.
+The filter in AM is preset to 2500/12500 (7.5kHz +/- 5kHz)
+and is handy for removing adjacent channel interference.
+Change AM_SYNC_DISPLAY in script for whether to show AM
+Sync carrier or not.
+Run with "-h" for command line help with setting USRP 
+ddc center frequency, decimation, rf data record, playback
+and audio data recording.
+
+There are some controls for controlling a varactor and
+tuning an antenna - just ignore them unless you want
+to build a voltage tuned antenna to track frequency.
+
+There is also code for Web based control of frequency and
+volume - so I can tune the radio with an Ipaq from bed.
+Disabled by default - it takes a web server, some
+directories and scripts to use.
+
+
+
diff --git a/gnuradio-examples/python/apps/hf_explorer/hfx2.py b/gnuradio-examples/python/apps/hf_explorer/hfx2.py
new file mode 100755 (executable)
index 0000000..c09f962
--- /dev/null
@@ -0,0 +1,786 @@
+#!/usr/bin/env python
+# -*- coding: ANSI_X3.4-1968 -*-
+# generated by wxGlade 0.4 on Tue Mar 14 10:16:06 2006
+#
+# 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 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.
+#
+#-----------------------------------------------------------------
+#
+#                 +-->(fft)
+#                 |
+# (src)->(xlate)--+->(audio filter)--+-->(sel_am)-+--------------+
+#                                    |            |              |
+#                                    |          (pll)            |
+#                                    |            |              |
+#                                    |   (pll_carrier_scale)     |
+#                                    |            |              |
+#                                    |   (pll_carrier_filter)    |
+#                                    |            |              |
+#                                    |            +--(fft2)      |
+#                                    |            |              |
+#                                    |       +--(c2f3)--+        |
+#                                    |       |          |        |
+#                                    |   (phaser1)  (phaser2)    |
+#                                    |       |          |        |
+#                                    |       +--(f2c)---+        |
+#                                    |            |              V
+#                                    V            +---------->(am_det)
+#                                  (c2f)                         |
+#                                    |                         (c2f2)
+#                                    |                           |
+#                                    +-->(sel_sb)------------>(combine)
+#                                                                |
+#                                                                V
+#                                  +--------------------------(scale)
+#                                  |                             |
+#                                  |                             |
+#                                  |                            +++
+#                                  V                            | |
+#                                (agc)<--(offset)<--(intr)<---(sqr1)
+#                                  |
+#                                  V
+#                                (dst)
+#                                                       
+#----------------------------------------------------------------------
+#
+# Versions 2.2.1 adds loop antenna automatic tuner
+#
+# 2.3.1 adds web control, made AM Sync display optional,
+# added more comments.
+#
+# 2.4.1 updates usrp interface to support auto subdev
+
+# Web server control disabled by default. Do not enable
+# until directory structure and scripts are in place.
+WEB_CONTROL = False
+
+# Controls display of AM Sync Carrier - turn off for smaller
+# window if not needed
+AM_SYNC_DISPLAY = False
+
+import os, wx, sys, math
+import wx.lib.evtmgr as em
+from gnuradio.wxgui import powermate, fftsink
+from gnuradio import gr, audio, eng_notation, usrp, gru
+from gnuradio.eng_option import eng_option
+from optparse import OptionParser
+
+ID_BUTTON_1 = wx.NewId()       # LSB button
+ID_BUTTON_2 = wx.NewId()       # USB
+ID_BUTTON_3 = wx.NewId()       # AM
+ID_BUTTON_4 = wx.NewId()       # CW
+ID_BUTTON_5 = wx.NewId()       # Powermate controls: Upper audio freq cutoff
+ID_BUTTON_6 = wx.NewId()       #  "                  Lower audio freq cutoff
+ID_BUTTON_7 = wx.NewId()       #  "                  Frequency 
+ID_BUTTON_8 = wx.NewId()       #  "                  Volume
+ID_BUTTON_9 = wx.NewId()       #  "                  Time
+ID_BUTTON_10 = wx.NewId()      # Time Seek Forwards
+ID_BUTTON_11 = wx.NewId()      # Time Seek Backwards
+ID_BUTTON_12 = wx.NewId()      # Automatic Antenna Tune (AT) enable
+ID_BUTTON_13 = wx.NewId()      # AT Calibrate point
+ID_BUTTON_14 = wx.NewId()      # AT Reset
+ID_TEXT_1 = wx.NewId()         # Band Center, USRP ddc Freq
+ID_SPIN_1 = wx.NewId()         # Frequency display and control
+ID_SLIDER_1 = wx.NewId()       # Upper audio freq cutoff
+ID_SLIDER_2 = wx.NewId()       # Lower audio freq cutoff
+ID_SLIDER_3 = wx.NewId()       # Frequency 
+ID_SLIDER_4 = wx.NewId()       # Volume
+ID_SLIDER_5 = wx.NewId()       # Programmable Gain Amp, PGA, RF gain
+ID_SLIDER_6 = wx.NewId()       # AM Sync carrier level
+ID_SLIDER_7 = wx.NewId()       # AT control voltage output
+ID_EXIT        = wx.NewId()            # Menu Exit
+
+
+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 MyFrame(wx.Frame):
+    def __init__(self, *args, **kwds):
+        # begin wxGlade: MyFrame.__init__
+        kwds["style"] = wx.DEFAULT_FRAME_STYLE
+        wx.Frame.__init__(self, *args, **kwds)
+        
+        # Menu Bar
+        self.frame_1_menubar = wx.MenuBar()
+        self.SetMenuBar(self.frame_1_menubar)
+        wxglade_tmp_menu = wx.Menu()
+        self.Exit = wx.MenuItem(wxglade_tmp_menu, ID_EXIT, "Exit", "Exit", wx.ITEM_NORMAL)
+        wxglade_tmp_menu.AppendItem(self.Exit)
+        self.frame_1_menubar.Append(wxglade_tmp_menu, "File")
+        # Menu Bar end
+        self.panel_1 = wx.Panel(self, -1)
+        self.button_1 = wx.Button(self, ID_BUTTON_1, "LSB")
+        self.button_2 = wx.Button(self, ID_BUTTON_2, "USB")
+        self.button_3 = wx.Button(self, ID_BUTTON_3, "AM")
+        self.button_4 = wx.Button(self, ID_BUTTON_4, "CW")
+        self.button_5 = wx.ToggleButton(self, ID_BUTTON_5, "Upper")
+        self.slider_1 = wx.Slider(self, ID_SLIDER_1, 0, -15799, 15799, style=wx.SL_HORIZONTAL|wx.SL_LABELS)
+        self.button_6 = wx.ToggleButton(self, ID_BUTTON_6, "Lower")
+        self.slider_2 = wx.Slider(self, ID_SLIDER_2, 0, -15799, 15799, style=wx.SL_HORIZONTAL|wx.SL_LABELS)
+        self.panel_5 = wx.Panel(self, -1)
+        self.label_1 = wx.StaticText(self, -1, " Band\nCenter")
+        self.text_ctrl_1 = wx.TextCtrl(self, ID_TEXT_1, "")
+        self.panel_6 = wx.Panel(self, -1)
+        self.panel_7 = wx.Panel(self, -1)
+        self.panel_2 = wx.Panel(self, -1)
+        self.button_7 = wx.ToggleButton(self, ID_BUTTON_7, "Freq")
+        self.slider_3 = wx.Slider(self, ID_SLIDER_3, 3000, 0, 6000)
+        self.spin_ctrl_1 = wx.SpinCtrl(self, ID_SPIN_1, "", min=0, max=100)
+        self.button_8 = wx.ToggleButton(self, ID_BUTTON_8, "Vol")
+        self.slider_4 = wx.Slider(self, ID_SLIDER_4, 0, 0, 500)
+        self.slider_5 = wx.Slider(self, ID_SLIDER_5, 0, 0, 20)
+        self.button_9 = wx.ToggleButton(self, ID_BUTTON_9, "Time")
+        self.button_11 = wx.Button(self, ID_BUTTON_11, "Rew")
+        self.button_10 = wx.Button(self, ID_BUTTON_10, "Fwd")
+        self.panel_3 = wx.Panel(self, -1)
+        self.label_2 = wx.StaticText(self, -1, "PGA               ")
+        self.panel_4 = wx.Panel(self, -1)
+        self.panel_8 = wx.Panel(self, -1)
+        self.panel_9 = wx.Panel(self, -1)
+        self.label_3 = wx.StaticText(self, -1, "AM Sync\nCarrier")
+        self.slider_6 = wx.Slider(self, ID_SLIDER_6, 50, 0, 200, style=wx.SL_HORIZONTAL|wx.SL_LABELS)
+        self.label_4 = wx.StaticText(self, -1, "Antenna Tune")
+        self.slider_7 = wx.Slider(self, ID_SLIDER_7, 1575, 950, 2200, style=wx.SL_HORIZONTAL|wx.SL_LABELS)
+        self.panel_10 = wx.Panel(self, -1)
+        self.button_12 = wx.ToggleButton(self, ID_BUTTON_12, "Auto Tune")
+        self.button_13 = wx.Button(self, ID_BUTTON_13, "Calibrate")
+        self.button_14 = wx.Button(self, ID_BUTTON_14, "Reset")
+        self.panel_11 = wx.Panel(self, -1)
+        self.panel_12 = wx.Panel(self, -1)
+
+        self.__set_properties()
+        self.__do_layout()
+        # end wxGlade
+
+        parser = OptionParser (option_class=eng_option)
+        parser.add_option ("-c", "--ddc-freq", type="eng_float", default=3.9e6,
+                           help="set Rx DDC frequency to FREQ", metavar="FREQ")
+        parser.add_option ("-a", "--audio_file", default="",
+                           help="audio output file", metavar="FILE")
+        parser.add_option ("-r", "--radio_file", default="",
+                           help="radio output file", metavar="FILE")
+        parser.add_option ("-i", "--input_file", default="",
+                           help="radio input file", metavar="FILE")
+        parser.add_option ("-d", "--decim", type="int", default=250,
+                           help="USRP decimation")
+        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)")
+        (options, args) = parser.parse_args ()
+
+        self.usrp_center = options.ddc_freq
+        usb_rate = 64e6 / options.decim
+        self.slider_range = usb_rate * 0.9375
+        self.f_lo = self.usrp_center - (self.slider_range/2)
+        self.f_hi = self.usrp_center + (self.slider_range/2)
+       self.af_sample_rate = 32000
+       fir_decim = long (usb_rate / self.af_sample_rate)
+
+        # data point arrays for antenna tuner
+        self.xdata = []
+        self.ydata = []
+
+       self.fg = gr.flow_graph()
+
+        # radio variables, initial conditions
+        self.frequency = self.usrp_center
+        # these map the frequency slider (0-6000) to the actual range
+        self.f_slider_offset = self.f_lo
+        self.f_slider_scale = 10000/options.decim
+        self.spin_ctrl_1.SetRange(self.f_lo,self.f_hi)
+        self.text_ctrl_1.SetValue(str(int(self.usrp_center)))
+        self.slider_5.SetValue(0) 
+       self.AM_mode = False
+
+        self.slider_3.SetValue((self.frequency-self.f_slider_offset)/self.f_slider_scale)
+        self.spin_ctrl_1.SetValue(int(self.frequency))
+
+        POWERMATE = True
+        try:
+            self.pm = powermate.powermate(self)
+        except:
+            sys.stderr.write("Unable to find PowerMate or Contour Shuttle\n")
+            POWERMATE = False
+
+        if POWERMATE:
+          powermate.EVT_POWERMATE_ROTATE(self, self.on_rotate)
+          powermate.EVT_POWERMATE_BUTTON(self, self.on_pmButton)
+       self.active_button = 7
+
+        # command line options
+        if options.audio_file == "": SAVE_AUDIO_TO_FILE = False
+        else: SAVE_AUDIO_TO_FILE = True
+        if options.radio_file == "": SAVE_RADIO_TO_FILE = False
+        else: SAVE_RADIO_TO_FILE = True
+        if options.input_file == "": self.PLAY_FROM_USRP = True
+        else: self.PLAY_FROM_USRP = False
+
+        if self.PLAY_FROM_USRP:
+           self.src = usrp.source_c(decim_rate=options.decim)
+          if options.rx_subdev_spec is None:
+              options.rx_subdev_spec = pick_subdevice(self.src)
+           self.src.set_mux(usrp.determine_rx_mux_value(self.src, options.rx_subdev_spec))
+          self.subdev = usrp.selected_subdev(self.src, options.rx_subdev_spec)
+           self.src.tune(0, self.subdev, self.usrp_center)
+           self.tune_offset = 0 # -self.usrp_center - self.src.rx_freq(0)
+
+        else:
+           self.src = gr.file_source (gr.sizeof_gr_complex,options.input_file)
+           self.tune_offset = 2200 # 2200 works for 3.5-4Mhz band
+
+        # save radio data to a file
+        if SAVE_RADIO_TO_FILE:
+           file = gr.file_sink(gr.sizeof_gr_complex, options.radio_file)
+           self.fg.connect (self.src, file)
+
+       # 2nd DDC
+        xlate_taps = gr.firdes.low_pass ( \
+           1.0, usb_rate, 16e3, 4e3, gr.firdes.WIN_HAMMING )
+        self.xlate = gr.freq_xlating_fir_filter_ccf ( \
+           fir_decim, xlate_taps, self.tune_offset, usb_rate )
+
+       # Complex Audio filter
+        audio_coeffs = gr.firdes.complex_band_pass (
+                1.0,    # gain
+                self.af_sample_rate, # sample rate
+                -3000,    # low cutoff
+                0,   # high cutoff
+                100,    # transition
+                gr.firdes.WIN_HAMMING)  # window
+       self.slider_1.SetValue(0)
+       self.slider_2.SetValue(-3000)
+
+        self.audio_filter = gr.fir_filter_ccc ( 1, audio_coeffs)
+
+       # Main +/- 16Khz spectrum display
+        self.fft = fftsink.fft_sink_c (self.fg, self.panel_2, fft_size=512, sample_rate=self.af_sample_rate, average=True, size=(640,240))
+
+       # AM Sync carrier 
+       if AM_SYNC_DISPLAY:
+          self.fft2 = fftsink.fft_sink_c (self.fg, self.panel_9, y_per_div=20, fft_size=512, sample_rate=self.af_sample_rate, average=True, size=(640,240))
+
+        c2f = gr.complex_to_float()
+
+       # AM branch
+       self.sel_am = gr.multiply_const_cc(0)
+       # the following frequencies turn out to be in radians/sample
+       # gr.pll_refout_cc(alpha,beta,min_freq,max_freq)
+       # suggested alpha = X, beta = .25 * X * X
+       pll = gr.pll_refout_cc(.5,.0625,(2.*math.pi*7.5e3/self.af_sample_rate),(2.*math.pi*6.5e3/self.af_sample_rate))
+       self.pll_carrier_scale = gr.multiply_const_cc(complex(10,0))
+       am_det = gr.multiply_cc()
+       # these are for converting +7.5kHz to -7.5kHz
+       # for some reason gr.conjugate_cc() adds noise ??
+       c2f2 = gr.complex_to_float()
+       c2f3 = gr.complex_to_float()
+       f2c = gr.float_to_complex()
+       phaser1 = gr.multiply_const_ff(1)
+       phaser2 = gr.multiply_const_ff(-1)
+
+       # filter for pll generated carrier
+        pll_carrier_coeffs = gr.firdes.complex_band_pass (
+                2.0,    # gain
+                self.af_sample_rate, # sample rate
+                7400,    # low cutoff
+                7600,   # high cutoff
+                100,    # transition
+                gr.firdes.WIN_HAMMING)  # window
+
+        self.pll_carrier_filter = gr.fir_filter_ccc ( 1, pll_carrier_coeffs)
+
+       self.sel_sb = gr.multiply_const_ff(1)
+       combine = gr.add_ff()
+
+       #AGC
+       sqr1 = gr.multiply_ff()
+       intr = gr.iir_filter_ffd ( [.004, 0], [0, .999] )
+       offset = gr.add_const_ff(1)
+       agc = gr.divide_ff()
+
+
+        self.scale = gr.multiply_const_ff(0.00001)
+        dst = audio.sink(long(self.af_sample_rate))
+
+        self.fg.connect(self.src,self.xlate,self.fft)
+        self.fg.connect(self.xlate,self.audio_filter,self.sel_am,(am_det,0))
+       self.fg.connect(self.sel_am,pll,self.pll_carrier_scale,self.pll_carrier_filter,c2f3)
+       self.fg.connect((c2f3,0),phaser1,(f2c,0))
+       self.fg.connect((c2f3,1),phaser2,(f2c,1))
+       self.fg.connect(f2c,(am_det,1))
+       self.fg.connect(am_det,c2f2,(combine,0))
+       self.fg.connect(self.audio_filter,c2f,self.sel_sb,(combine,1))
+       if AM_SYNC_DISPLAY:
+         self.fg.connect(self.pll_carrier_filter,self.fft2)
+       self.fg.connect(combine,self.scale)
+       self.fg.connect(self.scale,(sqr1,0))
+       self.fg.connect(self.scale,(sqr1,1))
+       self.fg.connect(sqr1, intr, offset, (agc, 1))
+       self.fg.connect(self.scale,(agc, 0))
+       self.fg.connect(agc,dst)
+
+       if SAVE_AUDIO_TO_FILE:
+         f_out = gr.file_sink(gr.sizeof_short,options.audio_file)
+         sc1 = gr.multiply_const_ff(64000)
+         f2s1 = gr.float_to_short()
+         self.fg.connect(agc,sc1,f2s1,f_out)
+
+        self.fg.start()
+
+        # for mouse position reporting on fft display
+        em.eventManager.Register(self.Mouse, wx.EVT_MOTION, self.fft.win)
+        # and left click to re-tune
+        em.eventManager.Register(self.Click, wx.EVT_LEFT_DOWN, self.fft.win)
+
+        # start a timer to check for web commands
+        if WEB_CONTROL:
+          self.timer = UpdateTimer(self, 1000) # every 1000 mSec, 1 Sec
+
+
+       wx.EVT_BUTTON(self,ID_BUTTON_1,self.set_lsb)
+       wx.EVT_BUTTON(self,ID_BUTTON_2,self.set_usb)
+       wx.EVT_BUTTON(self,ID_BUTTON_3,self.set_am)
+       wx.EVT_BUTTON(self,ID_BUTTON_4,self.set_cw)
+       wx.EVT_BUTTON(self,ID_BUTTON_10,self.fwd)
+       wx.EVT_BUTTON(self,ID_BUTTON_11,self.rew)
+        wx.EVT_BUTTON(self, ID_BUTTON_13, self.AT_calibrate)
+        wx.EVT_BUTTON(self, ID_BUTTON_14, self.AT_reset)
+       wx.EVT_TOGGLEBUTTON(self,ID_BUTTON_5,self.on_button)
+       wx.EVT_TOGGLEBUTTON(self,ID_BUTTON_6,self.on_button)
+       wx.EVT_TOGGLEBUTTON(self,ID_BUTTON_7,self.on_button)
+       wx.EVT_TOGGLEBUTTON(self,ID_BUTTON_8,self.on_button)
+       wx.EVT_TOGGLEBUTTON(self,ID_BUTTON_9,self.on_button)
+        wx.EVT_SLIDER(self,ID_SLIDER_1,self.set_filter)
+        wx.EVT_SLIDER(self,ID_SLIDER_2,self.set_filter)
+        wx.EVT_SLIDER(self,ID_SLIDER_3,self.slide_tune)
+        wx.EVT_SLIDER(self,ID_SLIDER_4,self.set_volume)
+       wx.EVT_SLIDER(self,ID_SLIDER_5,self.set_pga)
+       wx.EVT_SLIDER(self,ID_SLIDER_6,self.am_carrier)
+        wx.EVT_SLIDER(self,ID_SLIDER_7,self.antenna_tune)
+        wx.EVT_SPINCTRL(self,ID_SPIN_1,self.spin_tune)
+
+        wx.EVT_MENU(self, ID_EXIT,  self.TimeToQuit)
+
+    def __set_properties(self):
+        # begin wxGlade: MyFrame.__set_properties
+        self.SetTitle("HF Explorer 2")
+        self.slider_1.SetMinSize((450, 38))
+        self.slider_2.SetMinSize((450, 38))
+        self.panel_2.SetMinSize((640, 240))
+        self.button_7.SetValue(1)
+        self.slider_3.SetMinSize((450, 19))
+        self.slider_4.SetMinSize((275, 19))
+        self.slider_5.SetMinSize((275, 19))
+       if AM_SYNC_DISPLAY:
+           self.panel_9.SetMinSize((640, 240))
+        self.slider_6.SetMinSize((300, 38))
+        self.slider_7.SetMinSize((400, 38))
+        # end wxGlade
+
+    def __do_layout(self):
+        # begin wxGlade: MyFrame.__do_layout
+        sizer_1 = wx.BoxSizer(wx.VERTICAL)
+        grid_sizer_1 = wx.FlexGridSizer(11, 2, 0, 0)
+        sizer_7 = wx.BoxSizer(wx.HORIZONTAL)
+        sizer_5 = wx.BoxSizer(wx.HORIZONTAL)
+        sizer_4 = wx.BoxSizer(wx.HORIZONTAL)
+        sizer_3 = wx.BoxSizer(wx.HORIZONTAL)
+        sizer_6 = wx.BoxSizer(wx.VERTICAL)
+        sizer_2 = wx.BoxSizer(wx.HORIZONTAL)
+        grid_sizer_1.Add(self.panel_1, 1, wx.EXPAND, 0)
+        sizer_2.Add(self.button_1, 0, wx.ADJUST_MINSIZE, 0)
+        sizer_2.Add(self.button_2, 0, wx.ADJUST_MINSIZE, 0)
+        sizer_2.Add(self.button_3, 0, wx.ADJUST_MINSIZE, 0)
+        sizer_2.Add(self.button_4, 0, wx.ADJUST_MINSIZE, 0)
+        grid_sizer_1.Add(sizer_2, 1, wx.EXPAND, 0)
+        grid_sizer_1.Add(self.button_5, 0, wx.ADJUST_MINSIZE, 0)
+        grid_sizer_1.Add(self.slider_1, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ADJUST_MINSIZE, 0)
+        grid_sizer_1.Add(self.button_6, 0, wx.ADJUST_MINSIZE, 0)
+        grid_sizer_1.Add(self.slider_2, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ADJUST_MINSIZE, 0)
+        sizer_6.Add(self.panel_5, 1, wx.EXPAND, 0)
+        sizer_6.Add(self.label_1, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ADJUST_MINSIZE, 0)
+        sizer_6.Add(self.text_ctrl_1, 0, wx.ADJUST_MINSIZE, 0)
+        sizer_6.Add(self.panel_6, 1, wx.EXPAND, 0)
+        sizer_6.Add(self.panel_7, 1, wx.EXPAND, 0)
+        grid_sizer_1.Add(sizer_6, 1, wx.EXPAND, 0)
+        grid_sizer_1.Add(self.panel_2, 1, wx.EXPAND, 0)
+        grid_sizer_1.Add(self.button_7, 0, wx.ADJUST_MINSIZE, 0)
+        sizer_3.Add(self.slider_3, 0, wx.ADJUST_MINSIZE, 0)
+        sizer_3.Add(self.spin_ctrl_1, 0, wx.ADJUST_MINSIZE, 0)
+        grid_sizer_1.Add(sizer_3, 1, wx.EXPAND, 0)
+        grid_sizer_1.Add(self.button_8, 0, wx.ADJUST_MINSIZE, 0)
+        sizer_4.Add(self.slider_4, 0, wx.ADJUST_MINSIZE, 0)
+        sizer_4.Add(self.slider_5, 0, wx.ADJUST_MINSIZE, 0)
+        grid_sizer_1.Add(sizer_4, 1, wx.EXPAND, 0)
+        grid_sizer_1.Add(self.button_9, 0, wx.ADJUST_MINSIZE, 0)
+        sizer_5.Add(self.button_11, 0, wx.ADJUST_MINSIZE, 0)
+        sizer_5.Add(self.button_10, 0, wx.ADJUST_MINSIZE, 0)
+        sizer_5.Add(self.panel_3, 1, wx.EXPAND, 0)
+        sizer_5.Add(self.label_2, 0, wx.ADJUST_MINSIZE, 0)
+        sizer_5.Add(self.panel_4, 1, wx.EXPAND, 0)
+        grid_sizer_1.Add(sizer_5, 1, wx.EXPAND, 0)
+        grid_sizer_1.Add(self.panel_8, 1, wx.EXPAND, 0)
+        grid_sizer_1.Add(self.panel_9, 1, wx.EXPAND, 0)
+        grid_sizer_1.Add(self.label_3, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALIGN_CENTER_VERTICAL|wx.ADJUST_MINSIZE, 0)
+        grid_sizer_1.Add(self.slider_6, 0, wx.ADJUST_MINSIZE, 0)
+        grid_sizer_1.Add(self.label_4, 0, wx.ALIGN_BOTTOM|wx.ADJUST_MINSIZE, 0)
+        grid_sizer_1.Add(self.slider_7, 0, wx.ADJUST_MINSIZE, 0)
+        grid_sizer_1.Add(self.panel_10, 1, wx.EXPAND, 0)
+        sizer_7.Add(self.button_12, 0, wx.ADJUST_MINSIZE, 0)
+        sizer_7.Add(self.button_13, 0, wx.ADJUST_MINSIZE, 0)
+        sizer_7.Add(self.button_14, 0, wx.ADJUST_MINSIZE, 0)
+        sizer_7.Add(self.panel_11, 1, wx.EXPAND, 0)
+        sizer_7.Add(self.panel_12, 1, wx.EXPAND, 0)
+        grid_sizer_1.Add(sizer_7, 1, wx.EXPAND, 0)
+        sizer_1.Add(grid_sizer_1, 1, wx.EXPAND, 0)
+        self.SetAutoLayout(True)
+        self.SetSizer(sizer_1)
+        sizer_1.Fit(self)
+        sizer_1.SetSizeHints(self)
+        self.Layout()
+        # end wxGlade
+
+    # Menu exit
+    def TimeToQuit(self, event):
+        self.fg.stop()
+        self.Close(True)
+
+    # Powermate being turned
+    def on_rotate(self, event):
+       if self.active_button == 5:
+          self.slider_1.SetValue(self.slider_1.GetValue()+event.delta)
+           if self.slider_2.GetValue() > (self.slider_1.GetValue() - 200) :
+              self.slider_2.SetValue(self.slider_1.GetValue() - 200)
+          self.filter()
+       if self.active_button == 6:
+          self.slider_2.SetValue(self.slider_2.GetValue()+event.delta)
+          if self.slider_1.GetValue() < (self.slider_2.GetValue() + 200) :
+             self.slider_1.SetValue(self.slider_2.GetValue() + 200)
+          self.filter()
+       if self.active_button == 7:
+           new = max(0, min(6000, self.slider_3.GetValue() + event.delta))
+           self.slider_3.SetValue(new)
+           self.frequency = (self.f_slider_scale * new) + self.f_slider_offset
+           self.spin_ctrl_1.SetValue(self.frequency)
+          if self.AM_mode == False:
+             self.xlate.set_center_freq( self.usrp_center - (self.frequency - self.tune_offset))
+          else:
+            self.xlate.set_center_freq( self.usrp_center - (self.frequency - self.tune_offset - 7.5e3))
+          if self.button_12.GetValue():
+             self.auto_antenna_tune()
+       if self.active_button == 8:
+           new = max(0, min(500, self.slider_4.GetValue() + event.delta))
+           self.slider_4.SetValue(new)
+           self.scale.set_k(math.pow(10.,((self.slider_4.GetValue()-500.)/100.)))
+       if self.active_button == 9:
+           if self.PLAY_FROM_USRP == False:
+              if event.delta == -1:
+                 self.src.seek(-1000000,gr.SEEK_CUR)
+              elif event.delta == 1:
+                 self.src.seek(1000000,gr.SEEK_CUR)
+
+
+    # Powermate pressed to switch controlled function
+    def on_pmButton(self, event):
+       if event.value == 0:
+          if self.active_button == 5:
+             self.active_button = 6
+             self.button_5.SetValue(False)
+             self.button_6.SetValue(True)
+          elif self.active_button == 6:
+             self.active_button = 7
+             self.button_6.SetValue(False)
+             self.button_7.SetValue(True)
+          elif self.active_button == 7:
+             self.active_button = 8
+             self.button_7.SetValue(False)
+             self.button_8.SetValue(True)
+          elif self.active_button == 8:
+             self.active_button = 9
+             self.button_8.SetValue(False)
+             self.button_9.SetValue(True)
+          elif self.active_button == 9:
+             self.active_button = 5
+             self.button_9.SetValue(False)
+             self.button_5.SetValue(True)
+
+    # Clicking one PM control button turns the rest off
+    def on_button(self, event):
+       id = event.GetId()
+       if id == ID_BUTTON_5:
+          self.active_button = 5
+          self.button_6.SetValue(False)
+          self.button_7.SetValue(False)
+          self.button_8.SetValue(False)
+          self.button_9.SetValue(False)
+       if id == ID_BUTTON_6:
+          self.active_button = 6
+           self.button_5.SetValue(False)
+           self.button_7.SetValue(False)
+           self.button_8.SetValue(False)
+           self.button_9.SetValue(False)
+        if id == ID_BUTTON_7:
+           self.active_button = 7
+           self.button_5.SetValue(False)
+           self.button_6.SetValue(False)
+           self.button_8.SetValue(False)
+           self.button_9.SetValue(False)
+        if id == ID_BUTTON_8:
+           self.active_button = 8
+           self.button_5.SetValue(False)
+           self.button_6.SetValue(False)
+           self.button_7.SetValue(False)
+           self.button_9.SetValue(False)
+        if id == ID_BUTTON_9:
+           self.active_button = 9
+           self.button_5.SetValue(False)
+           self.button_6.SetValue(False)
+           self.button_7.SetValue(False)
+           self.button_8.SetValue(False)
+
+    # Make sure filter settings are legal
+    def set_filter(self, event):
+        slider = event.GetId()
+        slider1 = self.slider_1.GetValue()
+        slider2 = self.slider_2.GetValue()
+        if slider == ID_SLIDER_1:
+           if slider2 > (self.slider_1.GetValue() - 200) :
+              self.slider_2.SetValue(slider1 - 200)
+        elif slider == ID_SLIDER_2:
+           if slider1 < (self.slider_2.GetValue() + 200) :
+              self.slider_1.SetValue(slider2 + 200)
+       self.filter()
+
+    # Calculate taps and apply
+    def filter(self):
+        audio_coeffs = gr.firdes.complex_band_pass (
+                1.0,    # gain
+                self.af_sample_rate, # sample rate
+                self.slider_2.GetValue(),    # low cutoff
+                self.slider_1.GetValue(),   # high cutoff
+                100,    # transition
+                gr.firdes.WIN_HAMMING)  # window
+        self.audio_filter.set_taps(audio_coeffs)
+
+    def set_lsb(self, event):
+       self.AM_mode = False
+       self.xlate.set_center_freq( self.usrp_center - (self.frequency - self.tune_offset))
+       self.sel_sb.set_k(1)
+       self.sel_am.set_k(0)
+       self.slider_1.SetValue(0)
+       self.slider_2.SetValue(-3000)
+       self.filter()
+
+    def set_usb(self, event):
+       self.AM_mode = False
+       self.xlate.set_center_freq( self.usrp_center - (self.frequency - self.tune_offset))
+       self.sel_sb.set_k(1)
+       self.sel_am.set_k(0)
+       self.slider_1.SetValue(3000)
+       self.slider_2.SetValue(0)
+       self.filter()
+
+    def set_am(self, event):
+       self.AM_mode = True
+       self.xlate.set_center_freq( self.usrp_center - (self.frequency - self.tune_offset - 7.5e3))
+       self.sel_sb.set_k(0)
+       self.sel_am.set_k(1)
+       self.slider_1.SetValue(12500)
+       self.slider_2.SetValue(2500)
+       self.filter()
+
+    def set_cw(self, event):
+       self.AM_mode = False
+       self.xlate.set_center_freq( self.usrp_center - (self.frequency - self.tune_offset))
+       self.AM_mode = False
+       self.sel_sb.set_k(1)
+       self.sel_am.set_k(0)
+       self.slider_1.SetValue(-400)
+       self.slider_2.SetValue(-800)
+       self.filter()
+
+    def set_volume(self, event):
+        self.scale.set_k(math.pow(10.,((self.slider_4.GetValue()-500.)/100.)))
+
+    def set_pga(self,event):
+       if self.PLAY_FROM_USRP:
+          self.subdev.set_gain(self.slider_5.GetValue())
+
+    def slide_tune(self, event):
+        self.frequency = (self.f_slider_scale * self.slider_3.GetValue()) + self.f_slider_offset
+       if self.AM_mode == False:
+          self.xlate.set_center_freq( self.usrp_center - (self.frequency - self.tune_offset))
+       else:
+         self.xlate.set_center_freq( self.usrp_center - (self.frequency - self.tune_offset - 7.5e3))
+        self.spin_ctrl_1.SetValue(self.frequency)
+       if self.button_12.GetValue():
+          self.auto_antenna_tune()
+
+    def spin_tune(self, event):
+       self.frequency = self.spin_ctrl_1.GetValue()
+       if self.AM_mode == False:
+           self.xlate.set_center_freq( self.usrp_center - (self.frequency - self.tune_offset))
+       else:
+          self.xlate.set_center_freq( self.usrp_center - (self.frequency - self.tune_offset - 7.5e3))
+        self.slider_3.SetValue(int((self.frequency-self.f_slider_offset)/self.f_slider_scale))
+       if self.button_12.GetValue():
+          self.auto_antenna_tune()
+
+    # Seek forwards in file
+    def fwd(self, event):
+       if self.PLAY_FROM_USRP == False:
+          self.src.seek(10000000,gr.SEEK_CUR)
+
+    # Seek backwards in file
+    def rew(self, event):
+       if self.PLAY_FROM_USRP == False:
+          self.src.seek(-10000000,gr.SEEK_CUR)
+
+    # Mouse over fft display - show frequency in tooltip
+    def Mouse(self,event):
+       if self.AM_mode:
+          fRel = ( event.GetX() - 330. ) / 14.266666 - 7.5
+       else:
+          fRel = ( event.GetX() - 330. ) / 14.266666 
+        self.fft.win.SetToolTip(wx.ToolTip(eng_notation.num_to_str(self.frequency + (fRel*1e3))))
+
+    # Mouse clicked on fft display - change frequency 
+    def Click(self,event):
+        fRel = ( event.GetX() - 330. ) / 14.266666
+       if self.AM_mode == False:
+           self.frequency = self.frequency + (fRel*1e3)
+       else:
+          self.frequency = self.frequency + (fRel*1e3) - 7.5e3
+        self.spin_ctrl_1.SetValue(int(self.frequency))
+        self.slider_3.SetValue(int((self.frequency-self.f_slider_offset)/self.f_slider_scale))
+        if self.AM_mode == False:
+          self.xlate.set_center_freq ( self.usrp_center - ( self.frequency - self.tune_offset ))
+       else:
+          self.xlate.set_center_freq( self.usrp_center - (self.frequency - self.tune_offset - 7.5e3))
+
+    # Set power of AM sync carrier
+    def am_carrier(self,event):
+       scale = math.pow(10,(self.slider_6.GetValue())/50.)
+       self.pll_carrier_scale.set_k(complex(scale,0))
+
+    # Reset AT data and start calibrate over
+    def AT_reset(self, event):
+        self.xdata = []
+        self.ydata = []
+
+    # Save AT setting for a particular frequency
+    def AT_calibrate(self, event):
+        self.xdata.append(float(self.frequency))
+        self.ydata.append(self.slider_7.GetValue())
+        if len(self.xdata) > 1:
+          self.m = []
+          self.b = []
+          for i in range(0,len(self.xdata)-1):
+            self.m.append( (self.ydata[i+1] - self.ydata[i]) / (self.xdata[i+1] - self.xdata[i]) )
+            self.b.append( self.ydata[i] - self.m[i] * self.xdata[i] )
+
+    # Lookup calibrated points and calculate interpolated antenna tune voltage.
+    # This is to automatically tune a narrowband loop antenna when the freq
+    # is changed, to keep signals peaked.
+    def auto_antenna_tune(self):
+        for i in range(0,len(self.xdata)-1):
+          if (self.frequency > self.xdata[i]) & (self.frequency < self.xdata[i+1]):
+            self.slider_7.SetValue(self.m[i]*self.frequency + self.b[i])
+        self.antenna_tune(0)
+
+    # Slider to set loop antenna capacitance
+    def antenna_tune(self, evt):
+        if self.PLAY_FROM_USRP:
+           self.src.write_aux_dac(0,3,self.slider_7.GetValue())
+
+    # Timer events - check for web commands
+    def OnUpdate(self):
+      cmds = os.listdir("/var/www/cgi-bin/commands/")
+      if cmds!=[]:
+        if cmds[0]=='chfreq':
+          fd=open("/var/www/cgi-bin/commands/chfreq","r")
+          new=fd.readline()
+          fd.close()
+          if new!='':
+            os.unlink("/var/www/cgi-bin/commands/chfreq")
+            if ( int(new) >= self.f_lo ) & ( int(new) <= self.f_hi ):
+               self.frequency = int(new)
+               self.slider_3.SetValue(( self.frequency - self.f_slider_offset) / self.f_slider_scale )
+               self.spin_ctrl_1.SetValue(self.frequency)
+               if self.button_12.GetValue():
+                 self.auto_antenna_tune()
+               if self.AM_mode:
+                 self.xlate.set_center_freq ( self.usrp_center - ( self.frequency - self.tune_offset - 7.5e3 ))
+               else:
+                 self.xlate.set_center_freq ( self.usrp_center - ( self.frequency - self.tune_offset ))
+
+        if cmds[0]=='chvolume':
+          fd=open("/var/www/cgi-bin/commands/chvolume","r")
+          new=fd.readline()
+          fd.close()
+          if new!='':
+            os.unlink("/var/www/cgi-bin/commands/chvolume")
+            if ( int(new) >= 0 ) & ( int(new) <= 500 ):
+               self.volume = int(new)
+               self.slider_4.SetValue(self.volume)
+               self.scale.set_k(math.pow(10.,((self.slider_4.GetValue()-500.)/100.)))
+
+      else: # no new web commands, update state
+        fh = open("/var/www/cgi-bin/state/freq","w")
+        fh.write(str(int(self.frequency))+'\n')
+        fh.close()
+        fh = open("/var/www/cgi-bin/state/volume","w")
+        fh.write(str(self.slider_4.GetValue())+'\n')
+        fh.close()
+
+
+# end of class MyFrame
+
+# wx.Timer to check for web updates
+class UpdateTimer(wx.Timer):
+    def __init__(self, target, dur=1000):
+        wx.Timer.__init__(self)
+        self.target = target
+        self.Start(dur)
+
+    def Notify(self):
+        """Called every timer interval"""
+        if self.target:
+            self.target.OnUpdate()
+
+
+class MyApp(wx.App):
+  def OnInit(self):
+    frame = MyFrame(None, -1, "HF Explorer 2")
+    frame.Show(True)
+    self.SetTopWindow(frame)
+    return True
+
+app = MyApp(0)
+app.MainLoop()
+
diff --git a/gnuradio-examples/python/apps/hf_explorer/hfx_help b/gnuradio-examples/python/apps/hf_explorer/hfx_help
new file mode 100644 (file)
index 0000000..9a52dd2
--- /dev/null
@@ -0,0 +1,180 @@
+
+               HF Explorer Help
+
+       -----------------------------------------------------------------------
+
+ Command Line Switches:
+
+       -c      DDC center frequency, set band.
+               -c 7.2e6 or -c 7.2M for 40 meter ham band.
+               Default is 3.9e6 80 meter ham band.
+               Example:
+
+               hfx.py -c 9500k 
+
+               starts up in the 31 meter band.
+
+       -a      Audio output file. Output file for 32kHz two channel
+               signed word audio. Two channels are used for
+               independent sideband. This file can be converted
+               to a wav file with sox. Example:
+
+               sox -c 2 -r 3200 file.sw file.wav
+
+               sox needs the .sw extension to indicate file type.
+               If not specified no audio file is created.
+
+       -r      Radio output file. File to write RF data to for later
+               demodulation. Records the entire band to disk, width
+               determined by sample rate/decimation. Be sure to
+               note the decimation and center freq for later use!
+               Example:
+
+               hfx.py -c 900e3 -d 80 -r rf_data_AM-c900e3-d80
+
+               writes a pre-demod rf file centered on 900kHz with a
+               bandwidth of 800kHz (That's 80 AM stations!). The
+               center and decimation could be put in the filename for
+               proper use later.
+               If not specified no rf data file is created.
+               At default 250 decimation disk usage is about
+               8Gb / hour.
+
+       -i      Radio input file. Use to play back a previously
+               recorded rf data file. Example:
+
+               hfx.py -c 900e3 -d 80 -i rf_data_AM-c900e3-d80
+
+               plays back the previously recorded band, no
+               usrp hardware needed. Tune about the 800kHz wide band.
+               When playing a recorded file, time controls
+               fast-forward and rewind are available.
+               
+       -d      Decimation. Sets sample rate and bandwidth.
+               This is the factor that the usrp sample rate, 64e6,
+               is divided by. Default is 250 for 256kHz bandwidth
+               which is enough to record a ham band without 
+               eating up disk space too fast. The 64e6 sample
+               rate limits the upper practical frequency to 32MHz.
+               The Basic RX transformer limits the lower frequency
+               to about 200kHz. 
+
+
+ Powermate Knob:
+
+       A Powermate knob is recommended but not necessary. If a knob
+       is used, it is in one of 3 or 4 modes controlling frequency,
+       volume, filter and (if playing a recorded file) time.
+       Pushing the knob switches mode and the buttons on the HFX panel
+       change to show which mode is in effect. Then just turn the knob
+       to set frequency, volume, filter or go fast forward or rewind.
+
+
+ Bandswitch:
+
+        Across the top are a set of predefined bands and buttons
+        to rapidly switch to the center of that band. To change a band,
+        type the frequency in Hz into the box under "Center Frequency",
+        then press "Set" on the left, then the button you want to
+        program. From then on (untill the program is exited) pushing
+        that button takes you to that band.  To make a band button
+        permenant edit the hfx.py script with whatever frequency you
+        want assigned to what button.
+
+
+ Frequency:
+
+       There are 6 ways to set the frequency.
+       1) Move the slider with the mouse
+       2) Use the Spin Control up/down arrows (very fine 1Hz control)
+       3) Type the frequency in Hz into the Spin Control
+       4) Turn the Powermate knob
+       5) Web control.
+       6) Clicking on the FFT display to set demod center. This is very
+          convenient for tuning +-15kHz when you see a signal on the
+          display. If in Lower Sideband, clicking just to the right of
+          a signal will tune to it immediately. Clicking several times
+          on the far right right or left of the display will rapidly
+          tune up or down the band.
+
+
+ Volume:
+
+       Move the volume slider with the mouse, or push the Powermate knob
+       untill the volume button is active, or click on the volume button,
+       then turn the knob. Volume can also be set by web control if web
+       control is setup and enabled.
+
+
+ Filter:
+
+       Similar to volume, switches in any of 30 audio filters from 600
+       to 3600Hz in Sideband or up to 5kHz in AM.
+
+
+ Mode:
+
+       Demodulation modes are chosen by clicking on the buttons for
+       Lower Sideband, Upper Sideband, or AM.
+
+
+ PGA:
+
+       PGA slider sets the rf gain in the Analog-to-Digital converter
+       before digitizing. 0 to 20db gain easily shows up on the FFT
+       display.
+
+
+ Time:
+
+       When playing back a recorded RF data file, you can enjoy the
+       freedom of rewinding or fast-forwarding. Replay a weak signal
+       or skip through annoying AM commercials.
+
+
+ Antennas and Preamps:
+
+       The USRP Basic RX board is not sensitive enough for anything but
+       the strongest signals. In my experience about 40 db of small
+       signal gain is required to make the HFX as sensitive as other
+       receivers. Some working amplifiers are the Ramsey PR-2 with 20db
+       gain, fairly low noise and more bandwidth than we can use here.
+       Also the amp modules from Advanced Receiver Research are nice.
+       I use an ARR 7-7.4MHz GaAsFET 29db amp with .5db noise at the
+       apex of a 40 meter dipole with excellent results. Another
+       amp I like is a Minicircuits ZHL-32A 29db amp but they are
+       expensive and hard to find. Also it may help to use some filters
+       to keep strong local signals from the ADC, or limit rf input
+       to the band of interest, etc.  
+       Resonant outdoor antennas, like a dipole, in a low-noise (away
+       from consumer electronics) environment are nice.  Long random wires
+       with a tuner work. I like a small indoor tuned loop made from 10ft
+       of 1/4" copper tube, a 365pf tuning cap and a pickup loop connected
+       to rg-58. 
+
+
+ Web Control:
+
+       To control your radio remotely, ensure you have a web server
+       (Apache, etc) working and a compatible directory structure in
+       place. Directories /var/www/cgi-bin/commands and
+       /var/www/cgi-bin/state must already exist. You will need a
+       home page with forms and a set of scripts to put commands in
+       and put the current state on the home page. email me for further
+       help. Setting WEB_CONTROL to True in hfx.py turns on the timers
+       that check for commands and update the state.
+
+
+ IF Output:
+
+       There is a provision for outputting un-demodulated complex 
+       through the audio out in stereo for use with Digital Radio
+       Mondial (DRM) or using a seperate demodulation program like
+       SDRadio (by I2PHD).
+       Set IF_OUTPUT to True in weaver_isb_am1_usrp4.py.
+
+
+ --Good luck and happy LW/MW/SW Exploring.
+       Chuck
+        chuckek@musicriver.homeunix.com
+
diff --git a/gnuradio-examples/python/apps/hf_radio/README.TXT b/gnuradio-examples/python/apps/hf_radio/README.TXT
new file mode 100644 (file)
index 0000000..df8a901
--- /dev/null
@@ -0,0 +1,53 @@
+The files in this directory implement a fairly simple HF radio that works
+with the basic rx daughter board on the USRP.
+
+Many thanks to the Gnu Radio folks for a great new way to waste large blocks 
+of time in infinitely tweaking a huge number of free parameters.
+
+Start the receiver by running the radio.py in this directory. Or from the 
+Python prompt type "from radio import *" and you'll get the prompt back
+with the receiver running. You can then poke around to see what's going on.
+
+There are two spectrum displays. One is the output of the USRP and displays
+about 300KHz of bandwidth centered at the current tuning freq. The other
+displays the output spectrum of the demodulator.
+
+The demodulator does AM demod using the complex modulus block from gr. It 
+does SSB demod using the frequency translating fir filter as a complex
+hilbert transformer. The taps for this filter were generated using a program
+called Scilab and the Scilab program in the file hfir.sci. More details in
+the associated files.
+
+Tune the receiver using the spin buttons under the big frequency display.
+
+The agc block is a roll your own. The standard agc in the newer CVS updates
+seems to work but doesn't seem to have adjustable time constants or provide
+access to internal signal nodes which are used for the RSSI.
+
+The AGC authority (a sort of gain parameter) and the reference level used
+in the power to dB computagion can be adjusted using the spin buttons.
+
+The audio bandwidth can be similarly adjusted from about 50Hz to 10KHz.
+
+The GUI layout was produced using wxGlade. The file radio.xml is the GUI
+specification. It will produce a file called ui.py which is subclassed
+by classes defined in radio.py. The ui.py is purely generated by wxGlade
+all app specific code for the GUI is in radio.py. 
+
+Most of the actual signal processing code is built up in the other included
+files using the hierarchical block facilities. This organization should
+make it easier to tweak to your heart's content.
+
+Known bugs weakness and other
+
+wxPython and wxGlade seem to conspire to insure that the layout can never
+be exactly what you have in mind.
+
+Some of the controls don't behave as one might like. wx spin controls 
+and spin boxes only support integers so it is rather a nuisance to make
+units come out nice. In the process of development I came up with a reasonable
+kluge so there is a mixture of approaches.
+
+Enjoy.
+
+M. Revnell 2006-Jan-06
diff --git a/gnuradio-examples/python/apps/hf_radio/hfir.sci b/gnuradio-examples/python/apps/hf_radio/hfir.sci
new file mode 100644 (file)
index 0000000..a2d5e2a
--- /dev/null
@@ -0,0 +1,59 @@
+// designs a complex tap fir filter akin to the hilbert transformer.
+//
+// The hilbert transformer is classified as a linear phase fir
+// with allpass magnitude response and 90 degree phase response for
+// positive frequencies and -90 degrees phase for negative frequencies.
+// Or, if you prefer, normalized frequencies between .5 and 1 since
+// negative frequencies don't really have much meaning outside the complex
+// domain.
+//
+// Normally one would use the hilbert transformer in one leg of a complex
+// processing block and a compensating delay in the other.
+//
+// This one differs in the following respects:
+//  It is low pass with a cutoff of .078125
+//  The filter is a lowpass kaiser windowed filter with parameter 3
+//  The phase response is 45 degrees for positive frequencies and -45
+//   for negative frequencies.
+//  The coefficent set is used in one path and the same coefficients
+//   are used time reversed in the other. This results in the net effect
+//   of +/- 90 degrees as in the usual hilbert application.
+//
+// The coefficient set can be used in the gnuradio frequency translating
+// fir filter for ssb demodulation.
+//
+// This isn't as computationally efficient as using the hilbert transformer
+// and compensating delay but fascinating none the less.
+//
+// This program is for the scilab language a very powerful free math 
+// package similar to Matlab with infinitely better price/performace.
+//
+// compute the prototype lowpass fir
+// length is 255 (odd) for the same symmetry reasons as the hilbert transformer
+
+len = 1023;
+l2 = floor(len/2);
+md = l2 + 1;
+l3 = md + 1;
+
+h = wfir( 'lp', len, [10.0/256 0], 'kr', [3 0] );
+
+H = fft(h);
+
+H(1:l2)=H(1:l2)*exp(%i*%pi/4);
+H(md)=0+%i*0;
+H(l3:len)=H(l3:len)*exp(-%i*%pi/4);
+
+j=real(ifft(H));
+k(1:len)=j(len:-1:1);
+x=j+%i.*k;
+X=fft(x);
+plot(abs(X))
+
+f = file('open','taps')
+for i=(1:len)
+  fprintf( f, '%f%+fj', j(i), k(i) )
+end
+
+file('close',f)
+
diff --git a/gnuradio-examples/python/apps/hf_radio/input.py b/gnuradio-examples/python/apps/hf_radio/input.py
new file mode 100644 (file)
index 0000000..3a62a68
--- /dev/null
@@ -0,0 +1,41 @@
+# Basic USRP setup and control.
+# It's only ever been tried with a basic rx daughter card.
+#
+# Imagine that the gnuradio boilerplate is here.
+#
+# M. Revnell 2005-Dec
+from gnuradio import gr, gru, optfir
+from gnuradio import usrp
+import usrp_dbid
+import math
+
+# Put special knowlege of usrp here.
+
+class input:
+    def __init__( self, decim ):
+        self.freq = -2.5e6
+        self.src = usrp.source_c( )
+        self.subdev = usrp.pick_subdev( self.src,
+                                        (usrp_dbid.BASIC_RX,
+                                         usrp_dbid.TV_RX))
+
+        print self.subdev
+
+        self.subdevice = usrp.selected_subdev( self.src,
+                                               self.subdev )
+
+        self.mux = usrp.determine_rx_mux_value( self.src,
+                                                self.subdev )
+        self.decim = decim
+
+        self.adc_rate = self.src.adc_rate()
+        self.usrp_rate = self.adc_rate / self.decim
+        self.src.set_decim_rate( self.decim )
+        self.src.set_mux( self.mux )
+        usrp.tune( self.src, 0, self.subdevice, self.freq )
+
+    def set_freq( self, x ):
+        r = usrp.tune( self.src, 0, self.subdevice, -x )
+        if r:
+            self.freq = -x
diff --git a/gnuradio-examples/python/apps/hf_radio/output.py b/gnuradio-examples/python/apps/hf_radio/output.py
new file mode 100644 (file)
index 0000000..dc9caf5
--- /dev/null
@@ -0,0 +1,17 @@
+# Audio output with a volume control.
+#
+# M. Revnell 2005-Dec
+
+from gnuradio import gr, gru
+from gnuradio import audio
+
+class output( gr.hier_block ):
+    def __init__( self, fg, rate ):
+        self.out = audio.sink( rate )
+        self.vol = gr.multiply_const_ff( 0.1 )
+        fg.connect( self.vol, self.out )
+        gr.hier_block.__init__(self, fg, self.vol, None )
+
+    def set( self, val ):
+        self.vol.set_k( val )
+        
diff --git a/gnuradio-examples/python/apps/hf_radio/radio.py b/gnuradio-examples/python/apps/hf_radio/radio.py
new file mode 100755 (executable)
index 0000000..9f444b9
--- /dev/null
@@ -0,0 +1,304 @@
+#!/usr/bin/env python
+
+# GUI interactions and high level connections handled here.
+#
+# Interacts with classes defined by wxGlade in ui.py.
+#
+# The usual gnuradio copyright boilerplate incorperated here by reference.
+#
+# M. Revnell 2006-Jan
+
+from threading import *
+import wx
+import wx.lib.evtmgr as em
+import time
+
+from gnuradio import gr, gru, eng_notation, optfir
+from gnuradio import audio
+from gnuradio import usrp
+from gnuradio import blks
+from gnuradio.wxgui import fftsink
+from gnuradio.wxgui import waterfallsink
+from gnuradio.wxgui import scopesink
+
+from input    import *
+from output   import *
+from ssbdemod import *
+from ssbagc   import *
+from ui       import *
+from math     import log10
+
+class graph( gr.hier_block ):
+    def __init__( self, fg ):
+        self.graph        = fg
+        self.fe_decim     = 250
+        self.src          = input( self.fe_decim )
+        self.adc_rate     = self.src.adc_rate
+        self.fe_rate      = self.adc_rate / self.fe_decim
+        self.filter_decim = 1
+        self.audio_decim  = 16
+        self.demod_rate   = self.fe_rate / self.filter_decim
+        self.audio_rate   = self.demod_rate / self.audio_decim
+
+        self.demod        = ssb_demod( fg, self.demod_rate, self.audio_rate )
+        self.agc          = agc( fg )
+        #self.agc          = gr.agc_ff()
+        self.out          = output( fg, self.audio_rate )
+
+        fg.connect( self.src.src,
+                    self.demod,
+                    self.agc,
+                    self.out )
+
+        gr.hier_block.__init__( self, fg, None, None )
+
+    def tune( self, freq ):
+        fe_target = -freq
+        self.src.set_freq( fe_target )
+        fe_freq = self.src.src.rx_freq( 0 )
+        demod_cf = fe_target - fe_freq
+        self.demod.tune( demod_cf )
+
+class radio_frame( ui_frame ):
+    def __init__( self, block, *args, **kwds ):
+        ui_frame.__init__( self, *args, **kwds )
+        self.block = block
+        self.freq_disp.SetRange(0, 30e6)
+        f = self.block.src.freq
+        self.freq_disp.SetValue( -f )
+        self.volume.SetRange( 0, 20 )
+        self.pga.SetRange( 0, 20 )
+        self.rssi_range = 1
+        self.rssi.SetRange( self.rssi_range )
+        self.agc_max.SetValue( str( self.rssi_range ) )
+        self.spin_e0.SetValue( 50 )
+        self.spin_e1.SetValue( 50 )
+        self.spin_e2.SetValue( 50 )
+        self.spin_e3.SetValue( 50 )
+        self.spin_e4.SetValue( 50 )
+        self.spin_e5.SetValue( 50 )
+        self.spin_e6.SetValue( 50 )
+        bw = 3.3e3
+        self.bandwidth.SetValue( str( bw ) )
+        self.block.demod.set_bw( bw )
+        self.bw_spin.SetValue( 5 )
+        agc_gain = self.block.agc.gain.k()
+        self.agc_gain_s.SetValue( 5 )
+        self.agc_gain.SetValue( str( agc_gain ) )
+        agc_ref = self.block.agc.offs.k()
+        self.agc_ref.SetValue( str( agc_ref ) )
+        self.agc_ref_s.SetValue( 5 )
+
+        self.fespectrum = fftsink.fft_sink_c(
+            self.block.graph,
+            self.fe_panel,
+            fft_size=512,
+            sample_rate = block.fe_rate,
+            baseband_freq = 0,
+            average = False,
+            size = ( 680, 140 ) )
+
+        self.ifspectrum = fftsink.fft_sink_c(
+            self.block.graph,
+            self.if_panel,
+            fft_size=512,
+            sample_rate = block.audio_rate,
+            baseband_freq = 0,
+            average = False,
+            size = ( 680, 140 ) )
+
+        em.eventManager.Register( self.fe_mouse,
+                                  wx.EVT_MOTION,
+                                  self.fespectrum.win )
+
+        em.eventManager.Register( self.fe_click,
+                                  wx.EVT_LEFT_DOWN,
+                                  self.fespectrum.win )
+
+        block.graph.connect( block.src.src, self.fespectrum )
+        block.graph.connect( block.demod.xlate, self.ifspectrum )
+
+    def agc_ref_up( self, event ):
+        self.agc_ref_s.SetValue( 5 )
+        r = float( self.agc_ref.GetValue() )
+        r = r + 5
+        self.agc_ref.SetValue( str( r ) )
+        self.block.agc.offs.set_k( r )
+        
+    def agc_ref_down( self, event ):
+        self.agc_ref_s.SetValue( 5 )
+        r = float( self.agc_ref.GetValue() )
+        r = r - 5
+        self.agc_ref.SetValue( str( r ) )
+        self.block.agc.offs.set_k( r )
+
+    def agc_gain_up( self, event ):
+        self.agc_gain_s.SetValue( 5 )
+        g = float(self.agc_gain.GetValue())
+        g = g + 10
+        self.agc_gain.SetValue( str( g ) )
+        self.block.agc.gain.set_k( g )
+
+    def agc_gain_down( self, event ):
+        self.agc_gain_s.SetValue( 5 )
+        g = float(self.agc_gain.GetValue())
+        g = g - 10
+        self.agc_gain.SetValue( str( g ) )
+        self.block.agc.gain.set_k( g )
+
+    def fe_mouse( self, event ):
+        f = int(self.freq_disp.GetValue())
+        f = f+((event.GetX()-346.)*(400./610.))*1000
+        self.fespectrum.win.SetToolTip(
+            wx.ToolTip( eng_notation.num_to_str(f)))
+
+    def fe_click( self, event ):
+        f = int(self.freq_disp.GetValue())
+        f = f+((event.GetX()-346.)*(400./610.))*1000
+        self.tune( f )
+
+    def setrssi( self, level ):
+        if level < 0:
+            level = 0
+        if level > self.rssi_range:
+            self.rssi_range = level
+            self.rssi.SetRange( level )
+            self.agc_max.SetValue( str( level ))
+        self.rssi.SetValue( level )
+        self.agc_level.SetValue( str( level ))
+
+    def tune_evt( self, event ):
+        f = self.freq_disp.GetValue()
+        self.tune( f )
+        
+    def tune( self, frequency ):
+        self.freq_disp.SetValue( frequency )
+        self.block.tune( frequency )
+
+    def up_e0( self, event ):
+        self.spin_e0.SetValue( 50 )
+        self.tune( self.freq_disp.GetValue() + 1e0 )
+
+    def down_e0( self, event ):
+        self.spin_e0.SetValue( 50 )
+        self.tune( self.freq_disp.GetValue() - 1e0 )
+
+    def up_e1( self, event ):
+        self.spin_e1.SetValue( 50 )
+        self.tune( self.freq_disp.GetValue() + 1e1 )
+
+    def down_e1( self, event ):
+        self.spin_e1.SetValue( 50 )
+        self.tune( self.freq_disp.GetValue() - 1e1 )
+
+    def up_e2( self, event ):
+        self.spin_e2.SetValue( 50 )
+        self.tune( self.freq_disp.GetValue() + 1e2 )
+
+    def down_e2( self, event ):
+        self.spin_e2.SetValue( 50 )
+        self.tune( self.freq_disp.GetValue() - 1e2 )
+
+    def up_e3( self, event ):
+        self.spin_e3.SetValue( 50 )
+        self.tune( self.freq_disp.GetValue() + 1e3 )
+
+    def down_e3( self, event ):
+        self.spin_e3.SetValue( 50 )
+        self.tune( self.freq_disp.GetValue() - 1e3 )
+
+    def up_e4( self, event ):
+        self.spin_e4.SetValue( 50 )
+        self.tune( self.freq_disp.GetValue() + 1e4 )
+
+    def down_e4( self, event ):
+        self.spin_e4.SetValue( 50 )
+        self.tune( self.freq_disp.GetValue() - 1e4 )
+
+    def up_e5( self, event ):
+        self.spin_e5.SetValue( 50 )
+        self.tune( self.freq_disp.GetValue() + 1e5 )
+
+    def down_e5( self, event ):
+        self.spin_e5.SetValue( 50 )
+        self.tune( self.freq_disp.GetValue() - 1e5 )
+
+    def up_e6( self, event ):
+        self.spin_e6.SetValue( 50 )
+        self.tune( self.freq_disp.GetValue() + 1e6 )
+
+    def down_e6( self, event ):
+        self.spin_e6.SetValue( 50 )
+        self.tune( self.freq_disp.GetValue() - 1e6 )
+
+    def event_pga( self, event ):
+        self.block.src.src.set_pga( 0, self.pga.GetValue())
+        
+    def event_vol( self, event ):
+        self.block.out.set( self.volume.GetValue()/20.0 )
+
+    def set_usb( self, event ):
+        self.block.demod.upper_sb()
+        
+    def set_lsb( self, event ):
+        self.block.demod.lower_sb()
+
+    def set_am( self, event ):
+        self.block.demod.set_am()
+
+    def bw_up( self, event ):
+        self.bw_spin.SetValue( 5 )
+        bw = float(self.bandwidth.GetValue())
+        bw = bw + 20.0
+        if bw > 10e3:
+            bw = 10e3
+        self.bandwidth.SetValue( str( bw ) )
+        self.block.demod.set_bw( bw )
+
+    def bw_down( self, event ):
+        self.bw_spin.SetValue( 5 )
+        bw = float(self.bandwidth.GetValue())
+        bw = bw - 20.0
+        if bw < 50:
+            bw = 50
+        self.bandwidth.SetValue( str( bw ) )
+        self.block.demod.set_bw( bw )
+
+
+class radio( wx.App ):
+    def OnInit( self ):
+        self.graph = gr.flow_graph()
+        self.block = graph( self.graph )
+        self.frame = radio_frame( self.block, None, -1, "Title" )
+        self.frame.Show( True )
+        self.SetTopWindow( self.frame )
+        return True
+
+a=radio( 0 )
+
+l=gr.probe_signal_f()
+#l=gr.probe_avg_mag_sqrd_f(1,.001)
+a.graph.connect(a.block.agc.offs,l )
+#a.graph.connect(a.block.demod,l)
+
+def main_function():
+    global a
+    a.MainLoop()
+
+
+def rssi_function():
+    global a
+    global l
+    while 1:
+        level = l.level()
+        wx.CallAfter( a.frame.setrssi, level )
+        time.sleep( .1 )
+
+thread1 = Thread( target = main_function )
+thread2 = Thread( target = rssi_function )
+
+thread1.start()
+thread2.start()
+
+a.graph.start()
+
diff --git a/gnuradio-examples/python/apps/hf_radio/radio.xml b/gnuradio-examples/python/apps/hf_radio/radio.xml
new file mode 100644 (file)
index 0000000..81daa19
--- /dev/null
@@ -0,0 +1,441 @@
+<?xml version="1.0"?>
+<!-- generated by wxGlade 0.4 on Fri Jan  6 09:51:36 2006 -->
+
+<application path="/root/radio/ui.py" name="" class="" option="0" language="python" top_window="" encoding="UTF-8" use_gettext="0" overwrite="0" use_new_namespace="1" for_version="2.6">
+    <object class="ui_frame" name="frame_1" base="EditFrame">
+        <style>wxDEFAULT_FRAME_STYLE</style>
+        <title>frame_1</title>
+        <object class="wxStaticBoxSizer" name="sizer_1" base="EditStaticBoxSizer">
+            <orient>wxVERTICAL</orient>
+            <label>sizer_1</label>
+            <object class="sizeritem">
+                <flag>wxEXPAND</flag>
+                <border>0</border>
+                <option>1</option>
+                <object class="wxBoxSizer" name="sizer_2" base="EditBoxSizer">
+                    <orient>wxHORIZONTAL</orient>
+                    <object class="sizeritem">
+                        <flag>wxEXPAND</flag>
+                        <border>0</border>
+                        <option>1</option>
+                        <object class="wxBoxSizer" name="sizer_3" base="EditBoxSizer">
+                            <orient>wxVERTICAL</orient>
+                            <object class="sizeritem">
+                                <flag>wxEXPAND|wxADJUST_MINSIZE</flag>
+                                <border>0</border>
+                                <option>1</option>
+                                <object class="wxSpinCtrl" name="freq_disp" base="EditSpinCtrl">
+                                    <font>
+                                        <size>32</size>
+                                        <family>default</family>
+                                        <style>normal</style>
+                                        <weight>normal</weight>
+                                        <underlined>0</underlined>
+                                        <face></face>
+                                    </font>
+                                    <events>
+                                        <handler event="EVT_SPINCTRL">tune_evt</handler>
+                                    </events>
+                                </object>
+                            </object>
+                            <object class="sizeritem">
+                                <flag>wxEXPAND</flag>
+                                <border>0</border>
+                                <option>1</option>
+                                <object class="wxGridSizer" name="grid_sizer_1" base="EditGridSizer">
+                                    <hgap>0</hgap>
+                                    <rows>2</rows>
+                                    <cols>3</cols>
+                                    <vgap>0</vgap>
+                                    <object class="sizeritem">
+                                        <flag>wxEXPAND</flag>
+                                        <border>0</border>
+                                        <option>1</option>
+                                        <object class="wxGridSizer" name="grid_sizer_2" base="EditGridSizer">
+                                            <hgap>0</hgap>
+                                            <rows>1</rows>
+                                            <cols>7</cols>
+                                            <vgap>0</vgap>
+                                            <object class="sizeritem">
+                                                <flag>wxADJUST_MINSIZE</flag>
+                                                <border>0</border>
+                                                <option>0</option>
+                                                <object class="wxSpinButton" name="spin_e6" base="EditSpinButton">
+                                                    <events>
+                                                        <handler event="EVT_SPIN_UP">up_e6</handler>
+                                                        <handler event="EVT_SPIN_DOWN">down_e6</handler>
+                                                    </events>
+                                                </object>
+                                            </object>
+                                            <object class="sizeritem">
+                                                <flag>wxADJUST_MINSIZE</flag>
+                                                <border>0</border>
+                                                <option>0</option>
+                                                <object class="wxSpinButton" name="spin_e5" base="EditSpinButton">
+                                                    <events>
+                                                        <handler event="EVT_SPIN_UP">up_e5</handler>
+                                                        <handler event="EVT_SPIN_DOWN">down_e5</handler>
+                                                    </events>
+                                                </object>
+                                            </object>
+                                            <object class="sizeritem">
+                                                <flag>wxADJUST_MINSIZE</flag>
+                                                <border>0</border>
+                                                <option>0</option>
+                                                <object class="wxSpinButton" name="spin_e4" base="EditSpinButton">
+                                                    <events>
+                                                        <handler event="EVT_SPIN_UP">up_e4</handler>
+                                                        <handler event="EVT_SPIN_DOWN">down_e4</handler>
+                                                    </events>
+                                                </object>
+                                            </object>
+                                            <object class="sizeritem">
+                                                <flag>wxADJUST_MINSIZE</flag>
+                                                <border>0</border>
+                                                <option>0</option>
+                                                <object class="wxSpinButton" name="spin_e3" base="EditSpinButton">
+                                                    <events>
+                                                        <handler event="EVT_SPIN_UP">up_e3</handler>
+                                                        <handler event="EVT_SPIN_DOWN">down_e3</handler>
+                                                    </events>
+                                                </object>
+                                            </object>
+                                            <object class="sizeritem">
+                                                <flag>wxADJUST_MINSIZE</flag>
+                                                <border>0</border>
+                                                <option>0</option>
+                                                <object class="wxSpinButton" name="spin_e2" base="EditSpinButton">
+                                                    <events>
+                                                        <handler event="EVT_SPIN_UP">up_e2</handler>
+                                                        <handler event="EVT_SPIN_DOWN">down_e2</handler>
+                                                    </events>
+                                                </object>
+                                            </object>
+                                            <object class="sizeritem">
+                                                <flag>wxADJUST_MINSIZE</flag>
+                                                <border>0</border>
+                                                <option>0</option>
+                                                <object class="wxSpinButton" name="spin_e1" base="EditSpinButton">
+                                                    <events>
+                                                        <handler event="EVT_SPIN_UP">up_e1</handler>
+                                                        <handler event="EVT_SPIN_DOWN">down_e1</handler>
+                                                    </events>
+                                                </object>
+                                            </object>
+                                            <object class="sizeritem">
+                                                <flag>wxADJUST_MINSIZE</flag>
+                                                <border>0</border>
+                                                <option>0</option>
+                                                <object class="wxSpinButton" name="spin_e0" base="EditSpinButton">
+                                                    <events>
+                                                        <handler event="EVT_SPIN_UP">up_e0</handler>
+                                                        <handler event="EVT_SPIN_DOWN">down_e0</handler>
+                                                    </events>
+                                                </object>
+                                            </object>
+                                        </object>
+                                    </object>
+                                    <object class="sizeritem">
+                                        <flag>wxEXPAND</flag>
+                                        <border>0</border>
+                                        <option>1</option>
+                                        <object class="wxPanel" name="panel_1" base="EditPanel">
+                                            <style>wxTAB_TRAVERSAL</style>
+                                        </object>
+                                    </object>
+                                    <object class="sizeritem">
+                                        <flag>wxEXPAND</flag>
+                                        <border>0</border>
+                                        <option>1</option>
+                                        <object class="wxPanel" name="panel_2" base="EditPanel">
+                                            <style>wxTAB_TRAVERSAL</style>
+                                        </object>
+                                    </object>
+                                    <object class="sizeritem">
+                                        <flag>wxADJUST_MINSIZE</flag>
+                                        <border>0</border>
+                                        <option>0</option>
+                                        <object class="wxButton" name="button_lsb" base="EditButton">
+                                            <label>LSB</label>
+                                            <events>
+                                                <handler event="EVT_BUTTON">set_lsb</handler>
+                                            </events>
+                                        </object>
+                                    </object>
+                                    <object class="sizeritem">
+                                        <flag>wxADJUST_MINSIZE</flag>
+                                        <border>0</border>
+                                        <option>0</option>
+                                        <object class="wxButton" name="button_usb" base="EditButton">
+                                            <label>USB</label>
+                                            <events>
+                                                <handler event="EVT_BUTTON">set_usb</handler>
+                                            </events>
+                                        </object>
+                                    </object>
+                                    <object class="sizeritem">
+                                        <flag>wxADJUST_MINSIZE</flag>
+                                        <border>0</border>
+                                        <option>0</option>
+                                        <object class="wxButton" name="button_am" base="EditButton">
+                                            <label>AM</label>
+                                            <events>
+                                                <handler event="EVT_BUTTON">set_am</handler>
+                                            </events>
+                                        </object>
+                                    </object>
+                                </object>
+                            </object>
+                        </object>
+                    </object>
+                    <object class="sizeritem">
+                        <flag>wxEXPAND</flag>
+                        <border>0</border>
+                        <option>1</option>
+                        <object class="wxBoxSizer" name="sizer_4" base="EditBoxSizer">
+                            <orient>wxVERTICAL</orient>
+                            <object class="sizeritem">
+                                <flag>wxEXPAND</flag>
+                                <border>0</border>
+                                <option>1</option>
+                                <object class="wxGridSizer" name="grid_sizer_3" base="EditGridSizer">
+                                    <hgap>0</hgap>
+                                    <rows>2</rows>
+                                    <cols>4</cols>
+                                    <vgap>0</vgap>
+                                    <object class="sizeritem">
+                                        <flag>wxADJUST_MINSIZE</flag>
+                                        <border>0</border>
+                                        <option>0</option>
+                                        <object class="wxStaticText" name="label_1" base="EditStaticText">
+                                            <attribute>1</attribute>
+                                            <label>VOLUME</label>
+                                        </object>
+                                    </object>
+                                    <object class="sizeritem">
+                                        <flag>wxADJUST_MINSIZE</flag>
+                                        <border>0</border>
+                                        <option>0</option>
+                                        <object class="wxStaticText" name="label_2" base="EditStaticText">
+                                            <attribute>1</attribute>
+                                            <label>PGA</label>
+                                        </object>
+                                    </object>
+                                    <object class="sizeritem">
+                                        <flag>wxADJUST_MINSIZE</flag>
+                                        <border>0</border>
+                                        <option>0</option>
+                                        <object class="wxTextCtrl" name="agc_level" base="EditTextCtrl">
+                                        </object>
+                                    </object>
+                                    <object class="sizeritem">
+                                        <flag>wxADJUST_MINSIZE</flag>
+                                        <border>0</border>
+                                        <option>0</option>
+                                        <object class="wxStaticText" name="label_6" base="EditStaticText">
+                                            <attribute>1</attribute>
+                                        </object>
+                                    </object>
+                                    <object class="sizeritem">
+                                        <flag>wxADJUST_MINSIZE</flag>
+                                        <border>0</border>
+                                        <option>0</option>
+                                        <object class="wxSpinCtrl" name="volume" base="EditSpinCtrl">
+                                            <events>
+                                                <handler event="EVT_SPINCTRL">event_vol</handler>
+                                            </events>
+                                        </object>
+                                    </object>
+                                    <object class="sizeritem">
+                                        <flag>wxADJUST_MINSIZE</flag>
+                                        <border>0</border>
+                                        <option>0</option>
+                                        <object class="wxSpinCtrl" name="pga" base="EditSpinCtrl">
+                                            <events>
+                                                <handler event="EVT_SPINCTRL">event_pga</handler>
+                                            </events>
+                                        </object>
+                                    </object>
+                                    <object class="sizeritem">
+                                        <flag>wxADJUST_MINSIZE</flag>
+                                        <border>0</border>
+                                        <option>0</option>
+                                        <object class="wxTextCtrl" name="agc_max" base="EditTextCtrl">
+                                        </object>
+                                    </object>
+                                    <object class="sizeritem">
+                                        <flag>wxADJUST_MINSIZE</flag>
+                                        <border>0</border>
+                                        <option>0</option>
+                                        <object class="wxStaticText" name="label_7" base="EditStaticText">
+                                            <attribute>1</attribute>
+                                        </object>
+                                    </object>
+                                </object>
+                            </object>
+                            <object class="sizeritem">
+                                <flag>wxEXPAND</flag>
+                                <border>0</border>
+                                <option>1</option>
+                                <object class="wxGridSizer" name="grid_sizer_4" base="EditGridSizer">
+                                    <hgap>0</hgap>
+                                    <rows>2</rows>
+                                    <cols>4</cols>
+                                    <vgap>0</vgap>
+                                    <object class="sizeritem">
+                                        <flag>wxADJUST_MINSIZE</flag>
+                                        <border>0</border>
+                                        <option>0</option>
+                                        <object class="wxStaticText" name="label_4" base="EditStaticText">
+                                            <attribute>1</attribute>
+                                            <label>AGC AUTHORITY</label>
+                                        </object>
+                                    </object>
+                                    <object class="sizeritem">
+                                        <flag>wxADJUST_MINSIZE</flag>
+                                        <border>0</border>
+                                        <option>0</option>
+                                        <object class="wxStaticText" name="label_5" base="EditStaticText">
+                                            <attribute>1</attribute>
+                                            <label>AGC REF LVL</label>
+                                        </object>
+                                    </object>
+                                    <object class="sizeritem">
+                                        <flag>wxADJUST_MINSIZE</flag>
+                                        <border>0</border>
+                                        <option>0</option>
+                                        <object class="wxStaticText" name="label_3" base="EditStaticText">
+                                            <attribute>1</attribute>
+                                            <label>BANDWIDTH</label>
+                                        </object>
+                                    </object>
+                                    <object class="sizeritem">
+                                        <flag>wxADJUST_MINSIZE</flag>
+                                        <border>0</border>
+                                        <option>0</option>
+                                        <object class="wxStaticText" name="label_8" base="EditStaticText">
+                                            <attribute>1</attribute>
+                                        </object>
+                                    </object>
+                                    <object class="sizeritem">
+                                        <flag>wxEXPAND</flag>
+                                        <border>0</border>
+                                        <option>1</option>
+                                        <object class="wxBoxSizer" name="sizer_6" base="EditBoxSizer">
+                                            <orient>wxHORIZONTAL</orient>
+                                            <object class="sizeritem">
+                                                <flag>wxADJUST_MINSIZE</flag>
+                                                <border>0</border>
+                                                <option>0</option>
+                                                <object class="wxTextCtrl" name="agc_gain" base="EditTextCtrl">
+                                                </object>
+                                            </object>
+                                            <object class="sizeritem">
+                                                <flag>wxADJUST_MINSIZE</flag>
+                                                <border>0</border>
+                                                <option>0</option>
+                                                <object class="wxSpinButton" name="agc_gain_s" base="EditSpinButton">
+                                                    <events>
+                                                        <handler event="EVT_SPIN_UP">agc_gain_up</handler>
+                                                        <handler event="EVT_SPIN_DOWN">agc_gain_down</handler>
+                                                    </events>
+                                                </object>
+                                            </object>
+                                        </object>
+                                    </object>
+                                    <object class="sizeritem">
+                                        <flag>wxEXPAND</flag>
+                                        <border>0</border>
+                                        <option>1</option>
+                                        <object class="wxBoxSizer" name="sizer_7" base="EditBoxSizer">
+                                            <orient>wxHORIZONTAL</orient>
+                                            <object class="sizeritem">
+                                                <flag>wxADJUST_MINSIZE</flag>
+                                                <border>0</border>
+                                                <option>0</option>
+                                                <object class="wxTextCtrl" name="agc_ref" base="EditTextCtrl">
+                                                </object>
+                                            </object>
+                                            <object class="sizeritem">
+                                                <flag>wxADJUST_MINSIZE</flag>
+                                                <border>0</border>
+                                                <option>0</option>
+                                                <object class="wxSpinButton" name="agc_ref_s" base="EditSpinButton">
+                                                    <events>
+                                                        <handler event="EVT_SPIN_UP">agc_ref_up</handler>
+                                                        <handler event="EVT_SPIN_DOWN">agc_ref_down</handler>
+                                                    </events>
+                                                </object>
+                                            </object>
+                                        </object>
+                                    </object>
+                                    <object class="sizeritem">
+                                        <flag>wxEXPAND</flag>
+                                        <border>0</border>
+                                        <option>1</option>
+                                        <object class="wxBoxSizer" name="sizer_5" base="EditBoxSizer">
+                                            <orient>wxHORIZONTAL</orient>
+                                            <object class="sizeritem">
+                                                <flag>wxADJUST_MINSIZE</flag>
+                                                <border>0</border>
+                                                <option>0</option>
+                                                <object class="wxTextCtrl" name="bandwidth" base="EditTextCtrl">
+                                                </object>
+                                            </object>
+                                            <object class="sizeritem">
+                                                <flag>wxADJUST_MINSIZE</flag>
+                                                <border>0</border>
+                                                <option>0</option>
+                                                <object class="wxSpinButton" name="bw_spin" base="EditSpinButton">
+                                                    <events>
+                                                        <handler event="EVT_SPIN_UP">bw_up</handler>
+                                                        <handler event="EVT_SPIN_DOWN">bw_down</handler>
+                                                    </events>
+                                                </object>
+                                            </object>
+                                        </object>
+                                    </object>
+                                    <object class="sizeritem">
+                                        <flag>wxADJUST_MINSIZE</flag>
+                                        <border>0</border>
+                                        <option>0</option>
+                                        <object class="wxStaticText" name="label_9" base="EditStaticText">
+                                            <attribute>1</attribute>
+                                        </object>
+                                    </object>
+                                </object>
+                            </object>
+                            <object class="sizeritem">
+                                <flag>wxEXPAND|wxADJUST_MINSIZE</flag>
+                                <border>0</border>
+                                <option>1</option>
+                                <object class="wxGauge" name="rssi" base="EditGauge">
+                                    <foreground>#ff0000</foreground>
+                                    <style>wxGA_HORIZONTAL|wxGA_SMOOTH</style>
+                                    <range>10</range>
+                                    <size>315, 10</size>
+                                </object>
+                            </object>
+                        </object>
+                    </object>
+                </object>
+            </object>
+            <object class="sizeritem">
+                <flag>wxEXPAND</flag>
+                <border>0</border>
+                <option>1</option>
+                <object class="wxPanel" name="fe_panel" base="EditPanel">
+                    <style>wxTAB_TRAVERSAL</style>
+                </object>
+            </object>
+            <object class="sizeritem">
+                <flag>wxEXPAND</flag>
+                <border>0</border>
+                <option>1</option>
+                <object class="wxPanel" name="if_panel" base="EditPanel">
+                    <style>wxTAB_TRAVERSAL</style>
+                </object>
+            </object>
+        </object>
+    </object>
+</application>
diff --git a/gnuradio-examples/python/apps/hf_radio/ssb_taps b/gnuradio-examples/python/apps/hf_radio/ssb_taps
new file mode 100644 (file)
index 0000000..0ef3bbf
--- /dev/null
@@ -0,0 +1,1023 @@
+-0.000035-0.000009j
+-0.000066-0.000020j
+-0.000080-0.000044j
+-0.000084-0.000071j
+-0.000077-0.000100j
+-0.000063-0.000127j
+-0.000041-0.000150j
+-0.000013-0.000167j
+0.000020-0.000177j
+0.000054-0.000180j
+0.000089-0.000174j
+0.000121-0.000161j
+0.000150-0.000140j
+0.000173-0.000113j
+0.000188-0.000081j
+0.000196-0.000046j
+0.000194-0.000011j
+0.000184+0.000022j
+0.000165+0.000052j
+0.000139+0.000077j
+0.000107+0.000093j
+0.000071+0.000102j
+0.000034+0.000101j
+-0.000002+0.000090j
+-0.000036+0.000070j
+-0.000064+0.000042j
+-0.000086+0.000006j
+-0.000098-0.000034j
+-0.000101-0.000077j
+-0.000093-0.000120j
+-0.000076-0.000161j
+-0.000049-0.000197j
+-0.000014-0.000227j
+0.000026-0.000248j
+0.000071-0.000259j
+0.000117-0.000259j
+0.000162-0.000249j
+0.000203-0.000228j
+0.000237-0.000199j
+0.000263-0.000162j
+0.000279-0.000120j
+0.000284-0.000075j
+0.000278-0.000031j
+0.000260+0.000010j
+0.000232+0.000045j
+0.000196+0.000073j
+0.000153+0.000090j
+0.000106+0.000095j
+0.000059+0.000089j
+0.000014+0.000071j
+-0.000027+0.000041j
+-0.000059+0.000002j
+-0.000082-0.000046j
+-0.000093-0.000098j
+-0.000091-0.000152j
+-0.000077-0.000206j
+-0.000050-0.000255j
+-0.000012-0.000298j
+0.000034-0.000330j
+0.000088-0.000351j
+0.000145-0.000359j
+0.000202-0.000354j
+0.000256-0.000335j
+0.000304-0.000304j
+0.000343-0.000262j
+0.000370-0.000213j
+0.000384-0.000158j
+0.000384-0.000102j
+0.000369-0.000048j
+0.000341+0.000002j
+0.000302+0.000042j
+0.000252+0.000072j
+0.000196+0.000088j
+0.000137+0.000089j
+0.000078+0.000075j
+0.000024+0.000047j
+-0.000023+0.000005j
+-0.000059-0.000048j
+-0.000082-0.000109j
+-0.000090-0.000175j
+-0.000081-0.000242j
+-0.000058-0.000306j
+-0.000019-0.000364j
+0.000032-0.000411j
+0.000093-0.000445j
+0.000161-0.000465j
+0.000232-0.000467j
+0.000301-0.000453j
+0.000365-0.000423j
+0.000419-0.000379j
+0.000461-0.000323j
+0.000487-0.000259j
+0.000497-0.000190j
+0.000489-0.000121j
+0.000464-0.000056j
+0.000423+0.000001j
+0.000369+0.000046j
+0.000304+0.000076j
+0.000233+0.000089j
+0.000160+0.000083j
+0.000089+0.000060j
+0.000025+0.000018j
+-0.000027-0.000038j
+-0.000065-0.000107j
+-0.000086-0.000185j
+-0.000088-0.000266j
+-0.000071-0.000347j
+-0.000035-0.000422j
+0.000019-0.000487j
+0.000086-0.000538j
+0.000164-0.000573j
+0.000248-0.000588j
+0.000334-0.000582j
+0.000415-0.000557j
+0.000488-0.000513j
+0.000548-0.000452j
+0.000592-0.000379j
+0.000616-0.000297j
+0.000619-0.000213j
+0.000600-0.000130j
+0.000561-0.000054j
+0.000504+0.000010j
+0.000432+0.000058j
+0.000350+0.000086j
+0.000261+0.000093j
+0.000173+0.000078j
+0.000090+0.000040j
+0.000017-0.000017j
+-0.000040-0.000092j
+-0.000078-0.000180j
+-0.000095-0.000275j
+-0.000088-0.000374j
+-0.000058-0.000469j
+-0.000006-0.000555j
+0.000065-0.000627j
+0.000152-0.000681j
+0.000250-0.000712j
+0.000352-0.000720j
+0.000454-0.000703j
+0.000548-0.000663j
+0.000630-0.000601j
+0.000694-0.000521j
+0.000737-0.000428j
+0.000755-0.000327j
+0.000748-0.000225j
+0.000715-0.000128j
+0.000659-0.000042j
+0.000582+0.000028j
+0.000490+0.000077j
+0.000387+0.000101j
+0.000280+0.000099j
+0.000175+0.000070j
+0.000080+0.000015j
+-0.000001-0.000063j
+-0.000061-0.000159j
+-0.000097-0.000268j
+-0.000106-0.000385j
+-0.000087-0.000501j
+-0.000040-0.000611j
+0.000032-0.000708j
+0.000125-0.000786j
+0.000235-0.000839j
+0.000354-0.000866j
+0.000477-0.000863j
+0.000595-0.000831j
+0.000702-0.000772j
+0.000792-0.000688j
+0.000859-0.000585j
+0.000898-0.000469j
+0.000907-0.000347j
+0.000886-0.000227j
+0.000835-0.000115j
+0.000757-0.000019j
+0.000657+0.000055j
+0.000540+0.000102j
+0.000415+0.000119j
+0.000287+0.000103j
+0.000165+0.000056j
+0.000058-0.000020j
+-0.000029-0.000122j
+-0.000090-0.000243j
+-0.000121-0.000378j
+-0.000118-0.000517j
+-0.000082-0.000653j
+-0.000014-0.000778j
+0.000082-0.000885j
+0.000201-0.000966j
+0.000337-0.001017j
+0.000481-0.001034j
+0.000626-0.001016j
+0.000762-0.000965j
+0.000882-0.000882j
+0.000978-0.000772j
+0.001044-0.000643j
+0.001076-0.000501j
+0.001072-0.000355j
+0.001032-0.000215j
+0.000958-0.000089j
+0.000854+0.000016j
+0.000726+0.000091j
+0.000582+0.000133j
+0.000431+0.000138j
+0.000281+0.000105j
+0.000143+0.000035j
+0.000024-0.000068j
+-0.000068-0.000199j
+-0.000126-0.000350j
+-0.000147-0.000513j
+-0.000128-0.000677j
+-0.000070-0.000834j
+0.000024-0.000974j
+0.000150-0.001089j
+0.000300-0.001171j
+0.000465-0.001216j
+0.000637-0.001219j
+0.000805-0.001182j
+0.000960-0.001105j
+0.001091-0.000993j
+0.001191-0.000853j
+0.001253-0.000692j
+0.001274-0.000521j
+0.001252-0.000350j
+0.001188-0.000189j
+0.001085-0.000049j
+0.000950+0.000062j
+0.000790+0.000136j
+0.000614+0.000168j
+0.000435+0.000156j
+0.000261+0.000099j
+0.000105+0.000000j
+-0.000024-0.000136j
+-0.000117-0.000301j
+-0.000169-0.000486j
+-0.000175-0.000680j
+-0.000134-0.000872j
+-0.000048-0.001051j
+0.000079-0.001206j
+0.000240-0.001326j
+0.000426-0.001406j
+0.000626-0.001439j
+0.000829-0.001424j
+0.001022-0.001361j
+0.001195-0.001252j
+0.001336-0.001106j
+0.001437-0.000929j
+0.001491-0.000733j
+0.001496-0.000529j
+0.001449-0.000330j
+0.001354-0.000148j
+0.001217+0.000005j
+0.001044+0.000120j
+0.000846+0.000188j
+0.000635+0.000206j
+0.000424+0.000170j
+0.000226+0.000083j
+0.000053-0.000053j
+-0.000084-0.000228j
+-0.000176-0.000434j
+-0.000216-0.000659j
+-0.000201-0.000889j
+-0.000131-0.001111j
+-0.000009-0.001312j
+0.000158-0.001480j
+0.000362-0.001604j
+0.000590-0.001677j
+0.000829-0.001694j
+0.001066-0.001653j
+0.001286-0.001556j
+0.001477-0.001408j
+0.001626-0.001219j
+0.001724-0.001000j
+0.001765-0.000762j
+0.001746-0.000522j
+0.001668-0.000293j
+0.001534-0.000090j
+0.001353+0.000075j
+0.001135+0.000190j
+0.000893+0.000247j
+0.000642+0.000243j
+0.000396+0.000176j
+0.000172+0.000049j
+-0.000017-0.000131j
+-0.000159-0.000355j
+-0.000244-0.000609j
+-0.000266-0.000880j
+-0.000222-0.001151j
+-0.000114-0.001406j
+0.000053-0.001630j
+0.000270-0.001810j
+0.000524-0.001934j
+0.000802-0.001994j
+0.001087-0.001987j
+0.001362-0.001911j
+0.001611-0.001772j
+0.001819-0.001576j
+0.001973-0.001336j
+0.002063-0.001065j
+0.002084-0.000779j
+0.002033-0.000497j
+0.001914-0.000236j
+0.001732-0.000011j
+0.001498+0.000162j
+0.001225+0.000272j
+0.000931+0.000312j
+0.000633+0.000277j
+0.000349+0.000168j
+0.000097-0.000009j
+-0.000107-0.000246j
+-0.000250-0.000528j
+-0.000322-0.000841j
+-0.000316-0.001166j
+-0.000233-0.001484j
+-0.000076-0.001775j
+0.000148-0.002024j
+0.000426-0.002213j
+0.000743-0.002332j
+0.001080-0.002373j
+0.001418-0.002332j
+0.001736-0.002211j
+0.002017-0.002017j
+0.002241-0.001760j
+0.002397-0.001457j
+0.002473-0.001124j
+0.002464-0.000783j
+0.002371-0.000453j
+0.002198-0.000156j
+0.001954+0.000091j
+0.001654+0.000269j
+0.001316+0.000369j
+0.000959+0.000381j
+0.000606+0.000303j
+0.000279+0.000139j
+-0.000003-0.000103j
+-0.000220-0.000411j
+-0.000359-0.000768j
+-0.000408-0.001152j
+-0.000365-0.001542j
+-0.000229-0.001915j
+-0.000006-0.002248j
+0.000292-0.002522j
+0.000648-0.002719j
+0.001042-0.002826j
+0.001452-0.002837j
+0.001853-0.002750j
+0.002223-0.002569j
+0.002537-0.002304j
+0.002778-0.001971j
+0.002930-0.001588j
+0.002984-0.001179j
+0.002933-0.000770j
+0.002782-0.000384j
+0.002538-0.000046j
+0.002215+0.000222j
+0.001831+0.000402j
+0.001410+0.000481j
+0.000976+0.000452j
+0.000557+0.000316j
+0.000179+0.000077j
+-0.000134-0.000252j
+-0.000362-0.000654j
+-0.000490-0.001105j
+-0.000506-0.001580j
+-0.000407-0.002052j
+-0.000197-0.002492j
+0.000113-0.002875j
+0.000508-0.003176j
+0.000966-0.003377j
+0.001460-0.003464j
+0.001963-0.003432j
+0.002444-0.003281j
+0.002876-0.003019j
+0.003231-0.002659j
+0.003488-0.002224j
+0.003631-0.001739j
+0.003649-0.001233j
+0.003540-0.000737j
+0.003309-0.000282j
+0.002969+0.000103j
+0.002539+0.000393j
+0.002044+0.000568j
+0.001515+0.000614j
+0.000982+0.000525j
+0.000480+0.000304j
+0.000039-0.000039j
+-0.000311-0.000487j
+-0.000547-0.001016j
+-0.000652-0.001595j
+-0.000615-0.002193j
+-0.000436-0.002773j
+-0.000122-0.003301j
+0.000311-0.003746j
+0.000842-0.004081j
+0.001440-0.004282j
+0.002071-0.004338j
+0.002700-0.004243j
+0.003289-0.004000j
+0.003803-0.003622j
+0.004210-0.003132j
+0.004485-0.002556j
+0.004610-0.001930j
+0.004574-0.001291j
+0.004379-0.000679j
+0.004034-0.000133j
+0.003558+0.000313j
+0.002977+0.000627j
+0.002327+0.000787j
+0.001647+0.000779j
+0.000977+0.000598j
+0.000360+0.000250j
+-0.000163-0.000249j
+-0.000559-0.000872j
+-0.000799-0.001587j
+-0.000864-0.002354j
+-0.000744-0.003129j
+-0.000442-0.003866j
+0.000031-0.004522j
+0.000651-0.005057j
+0.001385-0.005437j
+0.002193-0.005637j
+0.003030-0.005643j
+0.003848-0.005451j
+0.004597-0.005069j
+0.005234-0.004519j
+0.005718-0.003830j
+0.006019-0.003044j
+0.006114-0.002206j
+0.005997-0.001368j
+0.005669-0.000583j
+0.005147+0.000099j
+0.004460+0.000631j
+0.003647+0.000975j
+0.002757+0.001105j
+0.001842+0.001003j
+0.000961+0.000668j
+0.000168+0.000111j
+-0.000482-0.000643j
+-0.000944-0.001555j
+-0.001183-0.002578j
+-0.001176-0.003656j
+-0.000912-0.004727j
+-0.000397-0.005728j
+0.000346-0.006601j
+0.001284-0.007292j
+0.002368-0.007755j
+0.003540-0.007959j
+0.004735-0.007886j
+0.005885-0.007535j
+0.006922-0.006922j
+0.007782-0.006078j
+0.008412-0.005050j
+0.008769-0.003898j
+0.008825-0.002691j
+0.008572-0.001504j
+0.008016-0.000412j
+0.007185+0.000510j
+0.006123+0.001196j
+0.004891+0.001591j
+0.003560+0.001657j
+0.002212+0.001372j
+0.000933+0.000734j
+-0.000192-0.000236j
+-0.001083-0.001500j
+-0.001672-0.002998j
+-0.001905-0.004655j
+-0.001747-0.006384j
+-0.001182-0.008090j
+-0.000222-0.009676j
+0.001101-0.011045j
+0.002732-0.012114j
+0.004593-0.012810j
+0.006591-0.013081j
+0.008621-0.012896j
+0.010571-0.012253j
+0.012328-0.011175j
+0.013785-0.009712j
+0.014847-0.007941j
+0.015438-0.005962j
+0.015507-0.003893j
+0.015029-0.001863j
+0.014011-0.000011j
+0.012494+0.001529j
+0.010549+0.002630j
+0.008277+0.003179j
+0.005809+0.003090j
+0.003294+0.002304j
+0.000896+0.000795j
+-0.001212-0.001423j
+-0.002859-0.004299j
+-0.003886-0.007744j
+-0.004151-0.011630j
+-0.003539-0.015799j
+-0.001969-0.020066j
+0.000601-0.024225j
+0.004168-0.028064j
+0.008684-0.031367j
+0.014056-0.033927j
+0.020145-0.035558j
+0.026775-0.036101j
+0.033735-0.035433j
+0.040789-0.033475j
+0.047684-0.030197j
+0.054164-0.025619j
+0.059974-0.019815j
+0.064878-0.012907j
+0.068665-0.005067j
+0.071159+0.003494j
+0.072228+0.012531j
+0.071791+0.021776j
+0.069818+0.030947j
+0.066339+0.039761j
+0.061435+0.047944j
+0.055243+0.055243j
+0.047944+0.061435j
+0.039761+0.066339j
+0.030947+0.069818j
+0.021776+0.071791j
+0.012531+0.072228j
+0.003494+0.071159j
+-0.005067+0.068665j
+-0.012907+0.064878j
+-0.019815+0.059974j
+-0.025619+0.054164j
+-0.030197+0.047684j
+-0.033475+0.040789j
+-0.035433+0.033735j
+-0.036101+0.026775j
+-0.035558+0.020145j
+-0.033927+0.014056j
+-0.031367+0.008684j
+-0.028064+0.004168j
+-0.024225+0.000601j
+-0.020066-0.001969j
+-0.015799-0.003539j
+-0.011630-0.004151j
+-0.007744-0.003886j
+-0.004299-0.002859j
+-0.001423-0.001212j
+0.000795+0.000896j
+0.002304+0.003294j
+0.003090+0.005809j
+0.003179+0.008277j
+0.002630+0.010549j
+0.001529+0.012494j
+-0.000011+0.014011j
+-0.001863+0.015029j
+-0.003893+0.015507j
+-0.005962+0.015438j
+-0.007941+0.014847j
+-0.009712+0.013785j
+-0.011175+0.012328j
+-0.012253+0.010571j
+-0.012896+0.008621j
+-0.013081+0.006591j
+-0.012810+0.004593j
+-0.012114+0.002732j
+-0.011045+0.001101j
+-0.009676-0.000222j
+-0.008090-0.001182j
+-0.006384-0.001747j
+-0.004655-0.001905j
+-0.002998-0.001672j
+-0.001500-0.001083j
+-0.000236-0.000192j
+0.000734+0.000933j
+0.001372+0.002212j
+0.001657+0.003560j
+0.001591+0.004891j
+0.001196+0.006123j
+0.000510+0.007185j
+-0.000412+0.008016j
+-0.001504+0.008572j
+-0.002691+0.008825j
+-0.003898+0.008769j
+-0.005050+0.008412j
+-0.006078+0.007782j
+-0.006922+0.006922j
+-0.007535+0.005885j
+-0.007886+0.004735j
+-0.007959+0.003540j
+-0.007755+0.002368j
+-0.007292+0.001284j
+-0.006601+0.000346j
+-0.005728-0.000397j
+-0.004727-0.000912j
+-0.003656-0.001176j
+-0.002578-0.001183j
+-0.001555-0.000944j
+-0.000643-0.000482j
+0.000111+0.000168j
+0.000668+0.000961j
+0.001003+0.001842j
+0.001105+0.002757j
+0.000975+0.003647j
+0.000631+0.004460j
+0.000099+0.005147j
+-0.000583+0.005669j
+-0.001368+0.005997j
+-0.002206+0.006114j
+-0.003044+0.006019j
+-0.003830+0.005718j
+-0.004519+0.005234j
+-0.005069+0.004597j
+-0.005451+0.003848j
+-0.005643+0.003030j
+-0.005637+0.002193j
+-0.005437+0.001385j
+-0.005057+0.000651j
+-0.004522+0.000031j
+-0.003866-0.000442j
+-0.003129-0.000744j
+-0.002354-0.000864j
+-0.001587-0.000799j
+-0.000872-0.000559j
+-0.000249-0.000163j
+0.000250+0.000360j
+0.000598+0.000977j
+0.000779+0.001647j
+0.000787+0.002327j
+0.000627+0.002977j
+0.000313+0.003558j
+-0.000133+0.004034j
+-0.000679+0.004379j
+-0.001291+0.004574j
+-0.001930+0.004610j
+-0.002556+0.004485j
+-0.003132+0.004210j
+-0.003622+0.003803j
+-0.004000+0.003289j
+-0.004243+0.002700j
+-0.004338+0.002071j
+-0.004282+0.001440j
+-0.004081+0.000842j
+-0.003746+0.000311j
+-0.003301-0.000122j
+-0.002773-0.000436j
+-0.002193-0.000615j
+-0.001595-0.000652j
+-0.001016-0.000547j
+-0.000487-0.000311j
+-0.000039+0.000039j
+0.000304+0.000480j
+0.000525+0.000982j
+0.000614+0.001515j
+0.000568+0.002044j
+0.000393+0.002539j
+0.000103+0.002969j
+-0.000282+0.003309j
+-0.000737+0.003540j
+-0.001233+0.003649j
+-0.001739+0.003631j
+-0.002224+0.003488j
+-0.002659+0.003231j
+-0.003019+0.002876j
+-0.003281+0.002444j
+-0.003432+0.001963j
+-0.003464+0.001460j
+-0.003377+0.000966j
+-0.003176+0.000508j
+-0.002875+0.000113j
+-0.002492-0.000197j
+-0.002052-0.000407j
+-0.001580-0.000506j
+-0.001105-0.000490j
+-0.000654-0.000362j
+-0.000252-0.000134j
+0.000077+0.000179j
+0.000316+0.000557j
+0.000452+0.000976j
+0.000481+0.001410j
+0.000402+0.001831j
+0.000222+0.002215j
+-0.000046+0.002538j
+-0.000384+0.002782j
+-0.000770+0.002933j
+-0.001179+0.002984j
+-0.001588+0.002930j
+-0.001971+0.002778j
+-0.002304+0.002537j
+-0.002569+0.002223j
+-0.002750+0.001853j
+-0.002837+0.001452j
+-0.002826+0.001042j
+-0.002719+0.000648j
+-0.002522+0.000292j
+-0.002248-0.000006j
+-0.001915-0.000229j
+-0.001542-0.000365j
+-0.001152-0.000408j
+-0.000768-0.000359j
+-0.000411-0.000220j
+-0.000103-0.000003j
+0.000139+0.000279j
+0.000303+0.000606j
+0.000381+0.000959j
+0.000369+0.001316j
+0.000269+0.001654j
+0.000091+0.001954j
+-0.000156+0.002198j
+-0.000453+0.002371j
+-0.000783+0.002464j
+-0.001124+0.002473j
+-0.001457+0.002397j
+-0.001760+0.002241j
+-0.002017+0.002017j
+-0.002211+0.001736j
+-0.002332+0.001418j
+-0.002373+0.001080j
+-0.002332+0.000743j
+-0.002213+0.000426j
+-0.002024+0.000148j
+-0.001775-0.000076j
+-0.001484-0.000233j
+-0.001166-0.000316j
+-0.000841-0.000322j
+-0.000528-0.000250j
+-0.000246-0.000107j
+-0.000009+0.000097j
+0.000168+0.000349j
+0.000277+0.000633j
+0.000312+0.000931j
+0.000272+0.001225j
+0.000162+0.001498j
+-0.000011+0.001732j
+-0.000236+0.001914j
+-0.000497+0.002033j
+-0.000779+0.002084j
+-0.001065+0.002063j
+-0.001336+0.001973j
+-0.001576+0.001819j
+-0.001772+0.001611j
+-0.001911+0.001362j
+-0.001987+0.001087j
+-0.001994+0.000802j
+-0.001934+0.000524j
+-0.001810+0.000270j
+-0.001630+0.000053j
+-0.001406-0.000114j
+-0.001151-0.000222j
+-0.000880-0.000266j
+-0.000609-0.000244j
+-0.000355-0.000159j
+-0.000131-0.000017j
+0.000049+0.000172j
+0.000176+0.000396j
+0.000243+0.000642j
+0.000247+0.000893j
+0.000190+0.001135j
+0.000075+0.001353j
+-0.000090+0.001534j
+-0.000293+0.001668j
+-0.000522+0.001746j
+-0.000762+0.001765j
+-0.001000+0.001724j
+-0.001219+0.001626j
+-0.001408+0.001477j
+-0.001556+0.001286j
+-0.001653+0.001066j
+-0.001694+0.000829j
+-0.001677+0.000590j
+-0.001604+0.000362j
+-0.001480+0.000158j
+-0.001312-0.000009j
+-0.001111-0.000131j
+-0.000889-0.000201j
+-0.000659-0.000216j
+-0.000434-0.000176j
+-0.000228-0.000084j
+-0.000053+0.000053j
+0.000083+0.000226j
+0.000170+0.000424j
+0.000206+0.000635j
+0.000188+0.000846j
+0.000120+0.001044j
+0.000005+0.001217j
+-0.000148+0.001354j
+-0.000330+0.001449j
+-0.000529+0.001496j
+-0.000733+0.001491j
+-0.000929+0.001437j
+-0.001106+0.001336j
+-0.001252+0.001195j
+-0.001361+0.001022j
+-0.001424+0.000829j
+-0.001439+0.000626j
+-0.001406+0.000426j
+-0.001326+0.000240j
+-0.001206+0.000079j
+-0.001051-0.000048j
+-0.000872-0.000134j
+-0.000680-0.000175j
+-0.000486-0.000169j
+-0.000301-0.000117j
+-0.000136-0.000024j
+0.000000+0.000105j
+0.000099+0.000261j
+0.000156+0.000435j
+0.000168+0.000614j
+0.000136+0.000790j
+0.000062+0.000950j
+-0.000049+0.001085j
+-0.000189+0.001188j
+-0.000350+0.001252j
+-0.000521+0.001274j
+-0.000692+0.001253j
+-0.000853+0.001191j
+-0.000993+0.001091j
+-0.001105+0.000960j
+-0.001182+0.000805j
+-0.001219+0.000637j
+-0.001216+0.000465j
+-0.001171+0.000300j
+-0.001089+0.000150j
+-0.000974+0.000024j
+-0.000834-0.000070j
+-0.000677-0.000128j
+-0.000513-0.000147j
+-0.000350-0.000126j
+-0.000199-0.000068j
+-0.000068+0.000024j
+0.000035+0.000143j
+0.000105+0.000281j
+0.000138+0.000431j
+0.000133+0.000582j
+0.000091+0.000726j
+0.000016+0.000854j
+-0.000089+0.000958j
+-0.000215+0.001032j
+-0.000355+0.001072j
+-0.000501+0.001076j
+-0.000643+0.001044j
+-0.000772+0.000978j
+-0.000882+0.000882j
+-0.000965+0.000762j
+-0.001016+0.000626j
+-0.001034+0.000481j
+-0.001017+0.000337j
+-0.000966+0.000201j
+-0.000885+0.000082j
+-0.000778-0.000014j
+-0.000653-0.000082j
+-0.000517-0.000118j
+-0.000378-0.000121j
+-0.000243-0.000090j
+-0.000122-0.000029j
+-0.000020+0.000058j
+0.000056+0.000165j
+0.000103+0.000287j
+0.000119+0.000415j
+0.000102+0.000540j
+0.000055+0.000657j
+-0.000019+0.000757j
+-0.000115+0.000835j
+-0.000227+0.000886j
+-0.000347+0.000907j
+-0.000469+0.000898j
+-0.000585+0.000859j
+-0.000688+0.000792j
+-0.000772+0.000702j
+-0.000831+0.000595j
+-0.000863+0.000477j
+-0.000866+0.000354j
+-0.000839+0.000235j
+-0.000786+0.000125j
+-0.000708+0.000032j
+-0.000611-0.000040j
+-0.000501-0.000087j
+-0.000385-0.000106j
+-0.000268-0.000097j
+-0.000159-0.000061j
+-0.000063-0.000001j
+0.000015+0.000080j
+0.000070+0.000175j
+0.000099+0.000280j
+0.000101+0.000387j
+0.000077+0.000490j
+0.000028+0.000582j
+-0.000042+0.000659j
+-0.000128+0.000715j
+-0.000225+0.000748j
+-0.000327+0.000755j
+-0.000428+0.000737j
+-0.000521+0.000694j
+-0.000601+0.000630j
+-0.000663+0.000548j
+-0.000703+0.000454j
+-0.000720+0.000352j
+-0.000712+0.000250j
+-0.000681+0.000152j
+-0.000627+0.000065j
+-0.000555-0.000006j
+-0.000469-0.000058j
+-0.000374-0.000088j
+-0.000275-0.000095j
+-0.000180-0.000078j
+-0.000092-0.000040j
+-0.000017+0.000017j
+0.000040+0.000090j
+0.000078+0.000173j
+0.000093+0.000261j
+0.000086+0.000350j
+0.000058+0.000432j
+0.000010+0.000504j
+-0.000054+0.000561j
+-0.000130+0.000600j
+-0.000213+0.000619j
+-0.000297+0.000616j
+-0.000379+0.000592j
+-0.000452+0.000548j
+-0.000513+0.000488j
+-0.000557+0.000415j
+-0.000582+0.000334j
+-0.000588+0.000248j
+-0.000573+0.000164j
+-0.000538+0.000086j
+-0.000487+0.000019j
+-0.000422-0.000035j
+-0.000347-0.000071j
+-0.000266-0.000088j
+-0.000185-0.000086j
+-0.000107-0.000065j
+-0.000038-0.000027j
+0.000018+0.000025j
+0.000060+0.000089j
+0.000083+0.000160j
+0.000089+0.000233j
+0.000076+0.000304j
+0.000046+0.000369j
+0.000001+0.000423j
+-0.000056+0.000464j
+-0.000121+0.000489j
+-0.000190+0.000497j
+-0.000259+0.000487j
+-0.000323+0.000461j
+-0.000379+0.000419j
+-0.000423+0.000365j
+-0.000453+0.000301j
+-0.000467+0.000232j
+-0.000465+0.000161j
+-0.000445+0.000093j
+-0.000411+0.000032j
+-0.000364-0.000019j
+-0.000306-0.000058j
+-0.000242-0.000081j
+-0.000175-0.000090j
+-0.000109-0.000082j
+-0.000048-0.000059j
+0.000005-0.000023j
+0.000047+0.000024j
+0.000075+0.000078j
+0.000089+0.000137j
+0.000088+0.000196j
+0.000072+0.000252j
+0.000042+0.000302j
+0.000002+0.000341j
+-0.000048+0.000369j
+-0.000102+0.000384j
+-0.000158+0.000384j
+-0.000213+0.000370j
+-0.000262+0.000343j
+-0.000304+0.000304j
+-0.000335+0.000256j
+-0.000354+0.000202j
+-0.000359+0.000145j
+-0.000351+0.000088j
+-0.000330+0.000034j
+-0.000298-0.000012j
+-0.000255-0.000050j
+-0.000206-0.000077j
+-0.000152-0.000091j
+-0.000098-0.000093j
+-0.000046-0.000082j
+0.000002-0.000059j
+0.000041-0.000027j
+0.000071+0.000014j
+0.000089+0.000059j
+0.000095+0.000106j
+0.000090+0.000153j
+0.000073+0.000196j
+0.000045+0.000232j
+0.000010+0.000260j
+-0.000031+0.000278j
+-0.000075+0.000284j
+-0.000120+0.000279j
+-0.000162+0.000263j
+-0.000199+0.000237j
+-0.000228+0.000203j
+-0.000249+0.000162j
+-0.000259+0.000117j
+-0.000259+0.000071j
+-0.000248+0.000026j
+-0.000227-0.000014j
+-0.000197-0.000049j
+-0.000161-0.000076j
+-0.000120-0.000093j
+-0.000077-0.000101j
+-0.000034-0.000098j
+0.000006-0.000086j
+0.000042-0.000064j
+0.000070-0.000036j
+0.000090-0.000002j
+0.000101+0.000034j
+0.000102+0.000071j
+0.000093+0.000107j
+0.000077+0.000139j
+0.000052+0.000165j
+0.000022+0.000184j
+-0.000011+0.000194j
+-0.000046+0.000196j
+-0.000081+0.000188j
+-0.000113+0.000173j
+-0.000140+0.000150j
+-0.000161+0.000121j
+-0.000174+0.000089j
+-0.000180+0.000054j
+-0.000177+0.000020j
+-0.000167-0.000013j
+-0.000150-0.000041j
+-0.000127-0.000063j
+-0.000100-0.000077j
+-0.000071-0.000084j
+-0.000044-0.000080j
+-0.000020-0.000066j
+-0.000009-0.000035j
diff --git a/gnuradio-examples/python/apps/hf_radio/ssbagc.py b/gnuradio-examples/python/apps/hf_radio/ssbagc.py
new file mode 100644 (file)
index 0000000..fdf40bc
--- /dev/null
@@ -0,0 +1,48 @@
+# post detection agc processing
+#
+# Imagine that the usual gnuradio copyright stuff is right here.
+#
+# This agc strategy is copied more or less verbatim from
+# weaver_isb_am1_usrp3.py by cswiger.
+#
+# Thanks.
+#
+# Then modified in a variety of ways.
+#
+# There doesn't appear to be a way to hook multiple blocks to the
+# input port when building a hier block like this. Thus the
+# split below.
+#
+# Basic operation.
+# Power is estimated by squaring the input.
+# Low pass filter using a 1 pole iir.
+# The time constant can be tweaked by changing the taps.
+# Currently there is no implementation to change this while operating
+#   a potentially useful addition.
+# The log block turns this into dB
+# gain adjusts the agc authority.
+#
+# M. Revnell 2006-Jan
+
+from gnuradio import gr, gru
+
+class agc( gr.hier_block ):
+    def __init__( self, fg ):
+        self.split = gr.multiply_const_ff( 1 )
+        self.sqr   = gr.multiply_ff( )
+        self.int0  = gr.iir_filter_ffd( [.004, 0], [0, .999] )
+        self.offs  = gr.add_const_ff( -30 )
+        self.gain  = gr.multiply_const_ff( 70 )
+        self.log   = gr.nlog10_ff( 10, 1 )
+        self.agc   = gr.divide_ff( )
+
+        fg.connect(   self.split,        ( self.agc,   0 ) )
+        fg.connect(   self.split,        ( self.sqr,   0 ) )
+        fg.connect(   self.split,        ( self.sqr,   1 ) )
+        fg.connect(   self.sqr,            self.int0       )
+        fg.connect(   self.int0,           self.log        )
+        fg.connect(   self.log,            self.offs       )
+        fg.connect(   self.offs,           self.gain       )
+        fg.connect(   self.gain,         ( self.agc,   1 ) )
+
+        gr.hier_block.__init__( self, fg, self.split, self.agc )
diff --git a/gnuradio-examples/python/apps/hf_radio/ssbdemod.py b/gnuradio-examples/python/apps/hf_radio/ssbdemod.py
new file mode 100644 (file)
index 0000000..c73567b
--- /dev/null
@@ -0,0 +1,97 @@
+# This tries to push the hilbert transform for ssb demod back into the
+# freq. xlating filter.
+#
+# The usual gnuradio copyright notice is hereby included by reference.
+#
+# The starting point for this was weaver_isb_am1_usrp3.py.
+#
+# The tap coefficients for freq_xlating_fir_filter_ccf were generated
+# externally and are read from a file because I didn't want to learn how
+# to make fir filters with arbitrary phase response using python numeric
+# facilities.
+#
+# They were generated using Scilab which I am already familiar with.
+# M. Revnell Jan 06
+
+from gnuradio import gr, gru
+from gnuradio import audio
+from gnuradio import usrp
+
+class ssb_demod( gr.hier_block ):
+    def __init__( self, fg, if_rate, af_rate ):
+
+        self.if_rate  = if_rate
+        self.af_rate  = af_rate
+        self.if_decim = if_rate / af_rate
+        self.sideband = 1
+
+        self.xlate_taps = ([complex(v) for v in file('ssb_taps').readlines()])
+        
+        self.audio_taps = gr.firdes.low_pass(
+            1.0,
+            self.af_rate,
+            3e3,
+            600,
+            gr.firdes.WIN_HAMMING )
+
+        self.xlate = gr.freq_xlating_fir_filter_ccc(
+            self.if_decim,
+            self.xlate_taps,
+            0,
+            self.if_rate )
+
+        self.split = gr.complex_to_float()
+
+        self.lpf = gr.fir_filter_fff(
+            1, self.audio_taps )
+
+        self.sum   = gr.add_ff( )
+        self.am_sel = gr.multiply_const_ff( 0 )
+        self.sb_sel = gr.multiply_const_ff( 1 )
+        self.mixer  = gr.add_ff()
+        self.am_det = gr.complex_to_mag()
+                
+        fg.connect(   self.xlate,       self.split      )
+        fg.connect( ( self.split,0 ), ( self.sum,0    ) )
+        fg.connect( ( self.split,1 ), ( self.sum,1    ) )
+        fg.connect(    self.sum,        self.sb_sel     )
+        fg.connect(    self.xlate,      self.am_det     )
+        fg.connect(    self.sb_sel,   ( self.mixer, 0 ) )
+        fg.connect(    self.am_det,     self.am_sel     )
+        fg.connect(    self.am_sel,   ( self.mixer, 1 ) )
+        fg.connect(    self.mixer,      self.lpf        )
+        
+        gr.hier_block.__init__( self, fg, self.xlate, self.lpf )
+
+    def upper_sb( self ):
+        self.xlate.set_taps([v.conjugate() for v in self.xlate_taps])    
+        self.sb_sel.set_k( 1.0 )
+        self.am_sel.set_k( 0.0 )
+
+    def lower_sb( self ):
+        self.xlate.set_taps(self.xlate_taps)
+        self.sb_sel.set_k( 1.0 )
+        self.am_sel.set_k( 0.0 )
+        
+    def set_am( self ):
+        taps = gr.firdes.low_pass( 1.0,
+                                   self.if_rate,
+                                   5e3,
+                                   2e3,
+                                   gr.firdes.WIN_HAMMING )
+        self.xlate.set_taps( taps )
+        self.sb_sel.set_k( 0.0 )
+        self.am_sel.set_k( 1.0 )
+
+    def set_bw( self, bw ):
+        self.audio_taps = gr.firdes.low_pass(
+            1.0,
+            self.af_rate,
+            bw,
+            600,
+            gr.firdes.WIN_HAMMING )
+        self.lpf.set_taps( self.audio_taps )
+
+    def tune( self, freq ):
+        self.xlate.set_center_freq( freq )
+
diff --git a/gnuradio-examples/python/apps/hf_radio/startup.py b/gnuradio-examples/python/apps/hf_radio/startup.py
new file mode 100644 (file)
index 0000000..093369b
--- /dev/null
@@ -0,0 +1 @@
+from radio import *
diff --git a/gnuradio-examples/python/apps/hf_radio/ui.py b/gnuradio-examples/python/apps/hf_radio/ui.py
new file mode 100755 (executable)
index 0000000..71b73c1
--- /dev/null
@@ -0,0 +1,295 @@
+#!/usr/bin/env python
+# -*- coding: UTF-8 -*-
+# generated by wxGlade 0.4 on Mon Jan  2 19:02:03 2006
+
+import wx
+
+class ui_frame(wx.Frame):
+    def __init__(self, *args, **kwds):
+        # begin wxGlade: ui_frame.__init__
+        kwds["style"] = wx.DEFAULT_FRAME_STYLE
+        wx.Frame.__init__(self, *args, **kwds)
+        self.sizer_1_staticbox = wx.StaticBox(self, -1, "sizer_1")
+        self.freq_disp = wx.SpinCtrl(self, -1, "", min=0, max=100)
+        self.spin_e6 = wx.SpinButton(self, -1 )
+        self.spin_e5 = wx.SpinButton(self, -1 )
+        self.spin_e4 = wx.SpinButton(self, -1 )
+        self.spin_e3 = wx.SpinButton(self, -1 )
+        self.spin_e2 = wx.SpinButton(self, -1 )
+        self.spin_e1 = wx.SpinButton(self, -1 )
+        self.spin_e0 = wx.SpinButton(self, -1 )
+        self.panel_1 = wx.Panel(self, -1)
+        self.panel_2 = wx.Panel(self, -1)
+        self.button_lsb = wx.Button(self, -1, "LSB")
+        self.button_usb = wx.Button(self, -1, "USB")
+        self.button_am = wx.Button(self, -1, "AM")
+        self.label_1 = wx.StaticText(self, -1, "VOLUME")
+        self.label_2 = wx.StaticText(self, -1, "PGA")
+        self.agc_level = wx.TextCtrl(self, -1, "")
+        self.label_6 = wx.StaticText(self, -1, "")
+        self.volume = wx.SpinCtrl(self, -1, "", min=0, max=100)
+        self.pga = wx.SpinCtrl(self, -1, "", min=0, max=100)
+        self.agc_max = wx.TextCtrl(self, -1, "")
+        self.label_7 = wx.StaticText(self, -1, "")
+        self.label_4 = wx.StaticText(self, -1, "AGC AUTHORITY")
+        self.label_5 = wx.StaticText(self, -1, "AGC REF LVL")
+        self.label_3 = wx.StaticText(self, -1, "BANDWIDTH")
+        self.label_8 = wx.StaticText(self, -1, "")
+        self.agc_gain = wx.TextCtrl(self, -1, "")
+        self.agc_gain_s = wx.SpinButton(self, -1 )
+        self.agc_ref = wx.TextCtrl(self, -1, "")
+        self.agc_ref_s = wx.SpinButton(self, -1 )
+        self.bandwidth = wx.TextCtrl(self, -1, "")
+        self.bw_spin = wx.SpinButton(self, -1 )
+        self.label_9 = wx.StaticText(self, -1, "")
+        self.rssi = wx.Gauge(self, -1, 10, style=wx.GA_HORIZONTAL|wx.GA_SMOOTH)
+        self.fe_panel = wx.Panel(self, -1)
+        self.if_panel = wx.Panel(self, -1)
+
+        self.__set_properties()
+        self.__do_layout()
+
+        self.Bind(wx.EVT_SPINCTRL, self.tune_evt, self.freq_disp)
+        self.Bind(wx.EVT_SPIN_DOWN, self.down_e6, self.spin_e6)
+        self.Bind(wx.EVT_SPIN_UP, self.up_e6, self.spin_e6)
+        self.Bind(wx.EVT_SPIN_DOWN, self.down_e5, self.spin_e5)
+        self.Bind(wx.EVT_SPIN_UP, self.up_e5, self.spin_e5)
+        self.Bind(wx.EVT_SPIN_DOWN, self.down_e4, self.spin_e4)
+        self.Bind(wx.EVT_SPIN_UP, self.up_e4, self.spin_e4)
+        self.Bind(wx.EVT_SPIN_DOWN, self.down_e3, self.spin_e3)
+        self.Bind(wx.EVT_SPIN_UP, self.up_e3, self.spin_e3)
+        self.Bind(wx.EVT_SPIN_DOWN, self.down_e2, self.spin_e2)
+        self.Bind(wx.EVT_SPIN_UP, self.up_e2, self.spin_e2)
+        self.Bind(wx.EVT_SPIN_DOWN, self.down_e1, self.spin_e1)
+        self.Bind(wx.EVT_SPIN_UP, self.up_e1, self.spin_e1)
+        self.Bind(wx.EVT_SPIN_DOWN, self.down_e0, self.spin_e0)
+        self.Bind(wx.EVT_SPIN_UP, self.up_e0, self.spin_e0)
+        self.Bind(wx.EVT_BUTTON, self.set_lsb, self.button_lsb)
+        self.Bind(wx.EVT_BUTTON, self.set_usb, self.button_usb)
+        self.Bind(wx.EVT_BUTTON, self.set_am, self.button_am)
+        self.Bind(wx.EVT_SPINCTRL, self.event_vol, self.volume)
+        self.Bind(wx.EVT_SPINCTRL, self.event_pga, self.pga)
+        self.Bind(wx.EVT_SPIN_DOWN, self.agc_gain_down, self.agc_gain_s)
+        self.Bind(wx.EVT_SPIN_UP, self.agc_gain_up, self.agc_gain_s)
+        self.Bind(wx.EVT_SPIN_DOWN, self.agc_ref_down, self.agc_ref_s)
+        self.Bind(wx.EVT_SPIN_UP, self.agc_ref_up, self.agc_ref_s)
+        self.Bind(wx.EVT_SPIN_DOWN, self.bw_down, self.bw_spin)
+        self.Bind(wx.EVT_SPIN_UP, self.bw_up, self.bw_spin)
+        # end wxGlade
+
+    def __set_properties(self):
+        # begin wxGlade: ui_frame.__set_properties
+        self.SetTitle("frame_1")
+        self.freq_disp.SetFont(wx.Font(32, wx.DEFAULT, wx.NORMAL, wx.NORMAL, 0, ""))
+        self.rssi.SetMinSize((315, 10))
+        self.rssi.SetForegroundColour(wx.Colour(255, 0, 0))
+        # end wxGlade
+
+    def __do_layout(self):
+        # begin wxGlade: ui_frame.__do_layout
+        sizer_1 = wx.StaticBoxSizer(self.sizer_1_staticbox, wx.VERTICAL)
+        sizer_2 = wx.BoxSizer(wx.HORIZONTAL)
+        sizer_4 = wx.BoxSizer(wx.VERTICAL)
+        grid_sizer_4 = wx.GridSizer(2, 4, 0, 0)
+        sizer_5 = wx.BoxSizer(wx.HORIZONTAL)
+        sizer_7 = wx.BoxSizer(wx.HORIZONTAL)
+        sizer_6 = wx.BoxSizer(wx.HORIZONTAL)
+        grid_sizer_3 = wx.GridSizer(2, 4, 0, 0)
+        sizer_3 = wx.BoxSizer(wx.VERTICAL)
+        grid_sizer_1 = wx.GridSizer(2, 3, 0, 0)
+        grid_sizer_2 = wx.GridSizer(1, 7, 0, 0)
+        sizer_3.Add(self.freq_disp, 1, wx.EXPAND|wx.ADJUST_MINSIZE, 0)
+        grid_sizer_2.Add(self.spin_e6, 0, wx.ADJUST_MINSIZE, 0)
+        grid_sizer_2.Add(self.spin_e5, 0, wx.ADJUST_MINSIZE, 0)
+        grid_sizer_2.Add(self.spin_e4, 0, wx.ADJUST_MINSIZE, 0)
+        grid_sizer_2.Add(self.spin_e3, 0, wx.ADJUST_MINSIZE, 0)
+        grid_sizer_2.Add(self.spin_e2, 0, wx.ADJUST_MINSIZE, 0)
+        grid_sizer_2.Add(self.spin_e1, 0, wx.ADJUST_MINSIZE, 0)
+        grid_sizer_2.Add(self.spin_e0, 0, wx.ADJUST_MINSIZE, 0)
+        grid_sizer_1.Add(grid_sizer_2, 1, wx.EXPAND, 0)
+        grid_sizer_1.Add(self.panel_1, 1, wx.EXPAND, 0)
+        grid_sizer_1.Add(self.panel_2, 1, wx.EXPAND, 0)
+        grid_sizer_1.Add(self.button_lsb, 0, wx.ADJUST_MINSIZE, 0)
+        grid_sizer_1.Add(self.button_usb, 0, wx.ADJUST_MINSIZE, 0)
+        grid_sizer_1.Add(self.button_am, 0, wx.ADJUST_MINSIZE, 0)
+        sizer_3.Add(grid_sizer_1, 1, wx.EXPAND, 0)
+        sizer_2.Add(sizer_3, 1, wx.EXPAND, 0)
+        grid_sizer_3.Add(self.label_1, 0, wx.ADJUST_MINSIZE, 0)
+        grid_sizer_3.Add(self.label_2, 0, wx.ADJUST_MINSIZE, 0)
+        grid_sizer_3.Add(self.agc_level, 0, wx.ADJUST_MINSIZE, 0)
+        grid_sizer_3.Add(self.label_6, 0, wx.ADJUST_MINSIZE, 0)
+        grid_sizer_3.Add(self.volume, 0, wx.ADJUST_MINSIZE, 0)
+        grid_sizer_3.Add(self.pga, 0, wx.ADJUST_MINSIZE, 0)
+        grid_sizer_3.Add(self.agc_max, 0, wx.ADJUST_MINSIZE, 0)
+        grid_sizer_3.Add(self.label_7, 0, wx.ADJUST_MINSIZE, 0)
+        sizer_4.Add(grid_sizer_3, 1, wx.EXPAND, 0)
+        grid_sizer_4.Add(self.label_4, 0, wx.ADJUST_MINSIZE, 0)
+        grid_sizer_4.Add(self.label_5, 0, wx.ADJUST_MINSIZE, 0)
+        grid_sizer_4.Add(self.label_3, 0, wx.ADJUST_MINSIZE, 0)
+        grid_sizer_4.Add(self.label_8, 0, wx.ADJUST_MINSIZE, 0)
+        sizer_6.Add(self.agc_gain, 0, wx.ADJUST_MINSIZE, 0)
+        sizer_6.Add(self.agc_gain_s, 0, wx.ADJUST_MINSIZE, 0)
+        grid_sizer_4.Add(sizer_6, 1, wx.EXPAND, 0)
+        sizer_7.Add(self.agc_ref, 0, wx.ADJUST_MINSIZE, 0)
+        sizer_7.Add(self.agc_ref_s, 0, wx.ADJUST_MINSIZE, 0)
+        grid_sizer_4.Add(sizer_7, 1, wx.EXPAND, 0)
+        sizer_5.Add(self.bandwidth, 0, wx.ADJUST_MINSIZE, 0)
+        sizer_5.Add(self.bw_spin, 0, wx.ADJUST_MINSIZE, 0)
+        grid_sizer_4.Add(sizer_5, 1, wx.EXPAND, 0)
+        grid_sizer_4.Add(self.label_9, 0, wx.ADJUST_MINSIZE, 0)
+        sizer_4.Add(grid_sizer_4, 1, wx.EXPAND, 0)
+        sizer_4.Add(self.rssi, 1, wx.EXPAND|wx.ADJUST_MINSIZE, 0)
+        sizer_2.Add(sizer_4, 1, wx.EXPAND, 0)
+        sizer_1.Add(sizer_2, 1, wx.EXPAND, 0)
+        sizer_1.Add(self.fe_panel, 1, wx.EXPAND, 0)
+        sizer_1.Add(self.if_panel, 1, wx.EXPAND, 0)
+        self.SetAutoLayout(True)
+        self.SetSizer(sizer_1)
+        sizer_1.Fit(self)
+        sizer_1.SetSizeHints(self)
+        self.Layout()
+        # end wxGlade
+
+    def down_e6(self, event): # wxGlade: ui_frame.<event_handler>
+        print "Event handler `down_e6' not implemented"
+        event.Skip()
+
+    def up_e6(self, event): # wxGlade: ui_frame.<event_handler>
+        print "Event handler `up_e6' not implemented"
+        event.Skip()
+
+    def down_e5(self, event): # wxGlade: ui_frame.<event_handler>
+        print "Event handler `down_e5' not implemented"
+        event.Skip()
+
+    def up_e5(self, event): # wxGlade: ui_frame.<event_handler>
+        print "Event handler `up_e5' not implemented"
+        event.Skip()
+
+    def down_e4(self, event): # wxGlade: ui_frame.<event_handler>
+        print "Event handler `down_e4' not implemented"
+        event.Skip()
+
+    def up_e4(self, event): # wxGlade: ui_frame.<event_handler>
+        print "Event handler `up_e4' not implemented"
+        event.Skip()
+
+    def down_e3(self, event): # wxGlade: ui_frame.<event_handler>
+        print "Event handler `down_e3' not implemented"
+        event.Skip()
+
+    def up_e3(self, event): # wxGlade: ui_frame.<event_handler>
+        print "Event handler `up_e3' not implemented"
+        event.Skip()
+
+    def down_e2(self, event): # wxGlade: ui_frame.<event_handler>
+        print "Event handler `down_e2' not implemented"
+        event.Skip()
+
+    def up_e2(self, event): # wxGlade: ui_frame.<event_handler>
+        print "Event handler `up_e2' not implemented"
+        event.Skip()
+
+    def down_e1(self, event): # wxGlade: ui_frame.<event_handler>
+        print "Event handler `down_e1' not implemented"
+        event.Skip()
+
+    def up_e1(self, event): # wxGlade: ui_frame.<event_handler>
+        print "Event handler `up_e1' not implemented"
+        event.Skip()
+
+    def down_e0(self, event): # wxGlade: ui_frame.<event_handler>
+        print "Event handler `down_e0' not implemented"
+        event.Skip()
+
+    def up_e0(self, event): # wxGlade: ui_frame.<event_handler>
+        print "Event handler `up_e0' not implemented"
+        event.Skip()
+
+    def event_vol(self, event): # wxGlade: ui_frame.<event_handler>
+        print "Event handler `event_vol' not implemented"
+        event.Skip()
+
+    def event_pga(self, event): # wxGlade: ui_frame.<event_handler>
+        print "Event handler `event_pga' not implemented"
+        event.Skip()
+
+    def set_lsb(self, event): # wxGlade: ui_frame.<event_handler>
+        print "Event handler `set_lsb' not implemented"
+        event.Skip()
+
+    def set_usb(self, event): # wxGlade: ui_frame.<event_handler>
+        print "Event handler `set_usb' not implemented"
+        event.Skip()
+
+    def set_am(self, event): # wxGlade: ui_frame.<event_handler>
+        print "Event handler `set_am' not implemented"
+        event.Skip()
+
+    def set_bw(self, event): # wxGlade: ui_frame.<event_handler>
+        print "Event handler `set_bw' not implemented"
+        event.Skip()
+
+    def tune_evt(self, event): # wxGlade: ui_frame.<event_handler>
+        print "Event handler `tune_evt' not implemented"
+        event.Skip()
+
+    def bw_down(self, event): # wxGlade: ui_frame.<event_handler>
+        print "Event handler `bw_down' not implemented"
+        event.Skip()
+
+    def bw_up(self, event): # wxGlade: ui_frame.<event_handler>
+        print "Event handler `bw_up' not implemented"
+        event.Skip()
+
+    def agc_gain_down(self, event): # wxGlade: ui_frame.<event_handler>
+        print "Event handler `agc_gain_down' not implemented"
+        event.Skip()
+
+    def agc_gain_up(self, event): # wxGlade: ui_frame.<event_handler>
+        print "Event handler `agc_gain_up' not implemented"
+        event.Skip()
+
+    def agc_ref_down(self, event): # wxGlade: ui_frame.<event_handler>
+        print "Event handler `agc_ref_down' not implemented"
+        event.Skip()
+
+    def agc_ref_up(self, event): # wxGlade: ui_frame.<event_handler>
+        print "Event handler `agc_ref_up' not implemented"
+        event.Skip()
+
+# end of class ui_frame
+
+
+class RadioFrame(wx.Frame):
+    def __init__(self, *args, **kwds):
+        # content of this block not found: did you rename this class?
+        pass
+
+    def __set_properties(self):
+        # content of this block not found: did you rename this class?
+        pass
+
+    def __do_layout(self):
+        # content of this block not found: did you rename this class?
+        pass
+
+# end of class RadioFrame
+
+
+class MyFrame(wx.Frame):
+    def __init__(self, *args, **kwds):
+        # content of this block not found: did you rename this class?
+        pass
+
+    def __set_properties(self):
+        # content of this block not found: did you rename this class?
+        pass
+
+    def __do_layout(self):
+        # content of this block not found: did you rename this class?
+        pass
+
+# end of class MyFrame
+
+
diff --git a/gnuradio-examples/python/audio/Makefile.am b/gnuradio-examples/python/audio/Makefile.am
new file mode 100644 (file)
index 0000000..27cea62
--- /dev/null
@@ -0,0 +1,32 @@
+#
+# 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.
+# 
+
+EXTRA_DIST =                   \
+       audio_copy.py           \
+       audio_play.py           \
+       audio_to_file.py        \
+       dial_tone.py            \
+       mono_tone.py            \
+       multi_tone.py           \
+       spectrum_inversion.py   \
+       test_resampler.py       
+
+
diff --git a/gnuradio-examples/python/audio/audio_copy.py b/gnuradio-examples/python/audio/audio_copy.py
new file mode 100755 (executable)
index 0000000..56fa836
--- /dev/null
@@ -0,0 +1,64 @@
+#!/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 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.
+# 
+
+from gnuradio import gr
+from gnuradio import audio
+from gnuradio.eng_option import eng_option
+from optparse import OptionParser
+
+class my_graph(gr.flow_graph):
+
+    def __init__(self):
+        gr.flow_graph.__init__(self)
+
+        parser = OptionParser(option_class=eng_option)
+        parser.add_option("-I", "--audio-input", type="string", default="",
+                          help="pcm input device name.  E.g., hw:0,0 or /dev/dsp")
+        parser.add_option("-O", "--audio-output", type="string", default="",
+                          help="pcm output device name.  E.g., hw:0,0 or /dev/dsp")
+        parser.add_option("-r", "--sample-rate", type="eng_float", default=48000,
+                          help="set sample rate to RATE (48000)")
+        (options, args) = parser.parse_args ()
+        if len(args) != 0:
+            parser.print_help()
+            raise SystemExit, 1
+
+        sample_rate = int(options.sample_rate)
+        src = audio.source (sample_rate, options.audio_input)
+        dst = audio.sink (sample_rate, options.audio_output)
+
+        # Determine the maximum number of outputs on the source and
+        # maximum number of inputs on the sink, then connect together
+        # the most channels we can without overlap
+        nchan = min (src.output_signature().max_streams(),
+                     dst.input_signature().max_streams())
+
+        for i in range (nchan):
+            self.connect ((src, i), (dst, i))
+
+
+if __name__ == '__main__':
+    try:
+        my_graph().run()
+    except KeyboardInterrupt:
+        pass
+    
diff --git a/gnuradio-examples/python/audio/audio_play.py b/gnuradio-examples/python/audio/audio_play.py
new file mode 100755 (executable)
index 0000000..e70b0f9
--- /dev/null
@@ -0,0 +1,57 @@
+#!/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 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.
+# 
+
+from gnuradio import gr
+from gnuradio import audio
+from gnuradio.eng_option import eng_option
+from optparse import OptionParser
+
+
+class my_graph(gr.flow_graph):
+
+    def __init__(self):
+        gr.flow_graph.__init__(self)
+
+        parser = OptionParser(option_class=eng_option)
+        parser.add_option("-F", "--filename", type="string", default="audio.dat",
+                          help="read input from FILE")
+        parser.add_option("-r", "--sample-rate", type="eng_float", default=48000,
+                          help="set sample rate to RATE (48000)")
+        parser.add_option("-R", "--repeat", action="store_true", default=False)
+        parser.add_option("-O", "--audio-output", type="string", default="",
+                          help="pcm output device name.  E.g., hw:0,0 or /dev/dsp")
+        (options, args) = parser.parse_args()
+        if len(args) != 0:
+            parser.print_help()
+            raise SystemExit, 1
+
+        sample_rate = int(options.sample_rate)
+        src = gr.file_source (gr.sizeof_float, options.filename, options.repeat)
+        dst = audio.sink (sample_rate, options.audio_output)
+        self.connect(src, dst)
+
+
+if __name__ == '__main__':
+    try:
+        my_graph().run()
+    except KeyboardInterrupt:
+        pass
diff --git a/gnuradio-examples/python/audio/audio_to_file.py b/gnuradio-examples/python/audio/audio_to_file.py
new file mode 100755 (executable)
index 0000000..74e1ea7
--- /dev/null
@@ -0,0 +1,63 @@
+#!/usr/bin/env 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.
+# 
+
+from gnuradio import gr
+from gnuradio import audio
+from gnuradio.eng_option import eng_option
+from optparse import OptionParser
+
+class my_graph(gr.flow_graph):
+
+    def __init__(self):
+        gr.flow_graph.__init__(self)
+
+        usage="%prog: [options] output_filename"
+        parser = OptionParser(option_class=eng_option, usage=usage)
+        parser.add_option("-I", "--audio-input", type="string", default="",
+                          help="pcm input device name.  E.g., hw:0,0 or /dev/dsp")
+        parser.add_option("-r", "--sample-rate", type="eng_float", default=48000,
+                          help="set sample rate to RATE (48000)")
+        parser.add_option("-N", "--nsamples", type="eng_float", default=None,
+                          help="number of samples to collect [default=+inf]")
+     
+        (options, args) = parser.parse_args ()
+        if len(args) != 1:
+            parser.print_help()
+            raise SystemExit, 1
+        filename = args[0]
+
+        sample_rate = int(options.sample_rate)
+        src = audio.source (sample_rate, options.audio_input)
+        dst = gr.file_sink (gr.sizeof_float, filename)
+
+        if options.nsamples is None:
+            self.connect((src, 0), dst)
+        else:
+            head = gr.head(gr.sizeof_float, int(options.nsamples))
+            self.connect((src, 0), head, dst)
+
+
+if __name__ == '__main__':
+    try:
+        my_graph().run()
+    except KeyboardInterrupt:
+        pass
diff --git a/gnuradio-examples/python/audio/dial_squelch.py b/gnuradio-examples/python/audio/dial_squelch.py
new file mode 100755 (executable)
index 0000000..d947e58
--- /dev/null
@@ -0,0 +1,89 @@
+#!/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 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.
+# 
+
+from gnuradio import gr, audio, eng_option
+from gnuradio.eng_option import eng_option
+from math import pi, cos
+from optparse import OptionParser
+
+"""
+This script generates a standard dial tone and then applies a sinusoidal
+envelope to vary it's loudness.  The audio is then passed through the
+power squelch block before it gets sent to the sound card. By varying
+the command line parameters, one can see the effect of differing
+amounts of power averaging, threshold, and attack/decay ramping.
+"""
+
+class app_flow_graph(gr.flow_graph):
+    def __init__(self, options, args):
+        gr.flow_graph.__init__(self)
+       
+       # Create dial tone by adding two sine waves
+       SRC1 = gr.sig_source_f(options.rate, gr.GR_SIN_WAVE, 350, 0.5, 0.0)
+       SRC2 = gr.sig_source_f(options.rate, gr.GR_SIN_WAVE, 440, 0.5, 0.0)
+       ADD = gr.add_ff()
+
+       # Convert to vector stream (and back) to apply raised cosine envelope
+       # You could also do this with a vector_source_f block that repeats.
+       S2V = gr.stream_to_vector(gr.sizeof_float, options.rate)
+       ENV = [0.5-cos(2*pi*x/options.rate)/2 for x in range(options.rate)]
+       MLT = gr.multiply_const_vff(ENV)
+       V2S = gr.vector_to_stream(gr.sizeof_float, options.rate)
+
+       # Run through power squelch with user supplied or default options
+       # Zero output when squelch is invoked
+       SQL = gr.pwr_squelch_ff(options.threshold, options.alpha, options.ramp, False)
+       DST = audio.sink(options.rate)
+
+       # Solder it all together
+       self.connect(SRC1, (ADD, 0))
+       self.connect(SRC2, (ADD, 1))
+       self.connect(ADD, S2V, MLT, V2S, SQL, DST)
+       
+def main():
+    parser = OptionParser(option_class=eng_option)
+    parser.add_option("-r", "--rate", type="int", default=8000, help="set audio output sample rate to RATE", metavar="RATE")
+    parser.add_option("-t", "--threshold", type="eng_float", default=-10.0, help="set power squelch to DB", metavar="DB")
+    parser.add_option("-a", "--alpha", type="eng_float", default=None, help="set alpha to ALPHA", metavar="ALPHA")
+    parser.add_option("-m", "--ramp", type="int", default=None, help="set attack/decay ramp to SAMPLES", metavar="SAMPLES")
+    (options, args) = parser.parse_args()
+
+    if options.alpha == None:
+       options.alpha = 50.0/options.rate
+       
+    if options.ramp == None:
+       options.ramp = options.rate/50  # ~ 20 ms
+
+    print "Using audio rate of", options.rate
+    print "Using threshold of", options.threshold, "db"
+    print "Using alpha of", options.alpha
+    print "Using ramp of", options.ramp, "samples"
+
+    fg = app_flow_graph(options, args)
+
+    try:
+      fg.run()
+    except KeyboardInterrupt:
+      pass
+
+if __name__ == "__main__":
+    main()
diff --git a/gnuradio-examples/python/audio/dial_tone.py b/gnuradio-examples/python/audio/dial_tone.py
new file mode 100755 (executable)
index 0000000..3ce84eb
--- /dev/null
@@ -0,0 +1,57 @@
+#!/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 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.
+# 
+
+from gnuradio import gr
+from gnuradio import audio
+from gnuradio.eng_option import eng_option
+from optparse import OptionParser
+
+class my_graph(gr.flow_graph):
+
+    def __init__(self):
+        gr.flow_graph.__init__(self)
+
+        parser = OptionParser(option_class=eng_option)
+        parser.add_option("-O", "--audio-output", type="string", default="",
+                          help="pcm output device name.  E.g., hw:0,0 or /dev/dsp")
+        parser.add_option("-r", "--sample-rate", type="eng_float", default=48000,
+                          help="set sample rate to RATE (48000)")
+        (options, args) = parser.parse_args ()
+        if len(args) != 0:
+            parser.print_help()
+            raise SystemExit, 1
+
+        sample_rate = int(options.sample_rate)
+        ampl = 0.1
+
+        src0 = gr.sig_source_f (sample_rate, gr.GR_SIN_WAVE, 350, ampl)
+        src1 = gr.sig_source_f (sample_rate, gr.GR_SIN_WAVE, 440, ampl)
+        dst = audio.sink (sample_rate, options.audio_output)
+        self.connect (src0, (dst, 0))
+        self.connect (src1, (dst, 1))
+
+
+if __name__ == '__main__':
+    try:
+        my_graph().run()
+    except KeyboardInterrupt:
+        pass
diff --git a/gnuradio-examples/python/audio/dialtone_v.py b/gnuradio-examples/python/audio/dialtone_v.py
new file mode 100755 (executable)
index 0000000..e704414
--- /dev/null
@@ -0,0 +1,71 @@
+#!/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 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.
+# 
+
+from gnuradio import gr, audio
+from math import pi, sin
+
+"""
+This test script demonstrates the use of element-wise vector processing
+vs. stream processing.  The example is artificial in that the stream
+version in dial_tone.py is the normal way to do it; in addition, the
+envelope processing here is just for demo purposes and isn't needed.
+"""
+
+# For testing different buffer sizes
+rate = 48000
+
+fg = gr.flow_graph()
+
+# Two streams of floats
+a = gr.sig_source_f(rate, gr.GR_SIN_WAVE, 350, 0.5, 0.0);
+b = gr.sig_source_f(rate, gr.GR_SIN_WAVE, 440, 0.5, 0.0);
+
+# Turn them into vectors of length 'size'
+av = gr.stream_to_vector(gr.sizeof_float, rate)
+bv = gr.stream_to_vector(gr.sizeof_float, rate)
+
+# Make a vector adder for float vectors
+adder = gr.add_vff(rate)
+
+# Make a 1 Hz sine envelope
+envelope = [sin(2*pi*x/rate)*0.5 for x in range(rate)]
+multiplier = gr.multiply_const_vff(envelope)
+
+# Make an offset adder
+offset = gr.add_const_vff((0.5,)*rate)
+
+# Turn the vector back into a stream of floats
+result = gr.vector_to_stream(gr.sizeof_float, rate)
+
+# Play it
+sink = audio.sink(rate)
+
+fg.connect(a, av)
+fg.connect(b, bv)
+fg.connect(av, (adder, 0))
+fg.connect(bv, (adder, 1))
+fg.connect(adder, multiplier, offset, result, sink)
+
+try:
+    fg.run()
+except KeyboardInterrupt:
+    pass
diff --git a/gnuradio-examples/python/audio/mono_tone.py b/gnuradio-examples/python/audio/mono_tone.py
new file mode 100755 (executable)
index 0000000..84c3b54
--- /dev/null
@@ -0,0 +1,66 @@
+#!/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 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.
+# 
+
+from gnuradio import gr
+from gnuradio import audio
+from gnuradio.eng_option import eng_option
+from optparse import OptionParser
+
+#import os
+#print os.getpid()
+#raw_input('Attach gdb and press Enter: ')
+
+class my_graph(gr.flow_graph):
+
+    def __init__(self):
+        gr.flow_graph.__init__(self)
+
+        parser = OptionParser(option_class=eng_option)
+        parser.add_option("-O", "--audio-output", type="string", default="",
+                          help="pcm output device name.  E.g., hw:0,0 or /dev/dsp")
+        parser.add_option("-r", "--sample-rate", type="eng_float", default=48000,
+                          help="set sample rate to RATE (48000)")
+        parser.add_option("-D", "--dont-block", action="store_false", default=True,
+                          dest="ok_to_block")
+
+        (options, args) = parser.parse_args ()
+        if len(args) != 0:
+            parser.print_help()
+            raise SystemExit, 1
+
+        sample_rate = int(options.sample_rate)
+        ampl = 0.1
+
+        src0 = gr.sig_source_f (sample_rate, gr.GR_SIN_WAVE, 650, ampl)
+
+        dst = audio.sink (sample_rate,
+                          options.audio_output,
+                          options.ok_to_block)
+            
+        self.connect (src0, (dst, 0))
+
+
+if __name__ == '__main__':
+    try:
+        my_graph().run()
+    except KeyboardInterrupt:
+        pass
diff --git a/gnuradio-examples/python/audio/multi_tone.py b/gnuradio-examples/python/audio/multi_tone.py
new file mode 100755 (executable)
index 0000000..c6f8305
--- /dev/null
@@ -0,0 +1,90 @@
+#!/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 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.
+# 
+
+from gnuradio import gr
+from gnuradio import audio
+from gnuradio.eng_option import eng_option
+from optparse import OptionParser
+
+#import os
+#print os.getpid()
+#raw_input('Attach gdb and press Enter: ')
+
+class my_graph(gr.flow_graph):
+
+    def __init__(self):
+        gr.flow_graph.__init__(self)
+
+        parser = OptionParser(option_class=eng_option)
+        parser.add_option("-O", "--audio-output", type="string", default="",
+                          help="pcm output device name.  E.g., hw:0,0 or /dev/dsp")
+        parser.add_option("-r", "--sample-rate", type="eng_float", default=48000,
+                          help="set sample rate to RATE (48000)")
+        parser.add_option ("-m", "--max-channels", type="int", default="16",
+                           help="set maximum channels to use")
+        parser.add_option("-D", "--dont-block", action="store_false", default=True,
+                          dest="ok_to_block")
+        (options, args) = parser.parse_args ()
+        if len(args) != 0:
+            parser.print_help()
+            raise SystemExit, 1
+
+        sample_rate = int(options.sample_rate)
+        limit_channels = options.max_channels
+
+        ampl = 0.1
+
+        # With a tip of the hat to Harry Partch, may he R.I.P.
+        # See "Genesis of a Music".  He was into some very wild tunings...
+        base = 392
+        ratios = { 1 : 1.0,
+                   3 : 3.0/2,
+                   5 : 5.0/4,
+                   7 : 7.0/4,
+                   9 : 9.0/8,
+                   11 : 11.0/8 }
+
+        # progression = (1, 5, 3, 7)
+        # progression = (1, 9, 3, 7)
+        # progression = (3, 7, 9, 11)
+        # progression = (7, 11, 1, 5)
+        progression = (7, 11, 1, 5, 9)
+
+        dst = audio.sink (sample_rate,
+                          options.audio_output,
+                          options.ok_to_block)
+    
+        max_chan = dst.input_signature().max_streams()
+        if (max_chan == -1) or (max_chan > limit_channels):
+            max_chan = limit_channels
+
+        for i in range (max_chan):
+            quo, rem = divmod (i, len (progression))
+            freq = base * ratios[progression[rem]] * (quo + 1)
+            src = gr.sig_source_f (sample_rate, gr.GR_SIN_WAVE, freq, ampl)
+            self.connect (src, (dst, i))
+
+if __name__ == '__main__':
+    try:
+        my_graph().run()
+    except KeyboardInterrupt:
+        pass
diff --git a/gnuradio-examples/python/audio/spectrum_inversion.py b/gnuradio-examples/python/audio/spectrum_inversion.py
new file mode 100755 (executable)
index 0000000..9bb87aa
--- /dev/null
@@ -0,0 +1,48 @@
+#!/usr/bin/env python
+#
+# Gang - Here's a simple script that demonstrates spectrum inversion
+# using the multiply by [1,-1] method (mixing with Nyquist frequency).
+# Requires nothing but a sound card, and sounds just like listening
+# to a SSB signal on the wrong sideband.
+#
+
+from gnuradio import gr
+from gnuradio import audio
+from gnuradio.eng_option import eng_option
+from optparse import OptionParser
+
+class my_graph(gr.flow_graph):
+
+    def __init__(self):
+        gr.flow_graph.__init__(self)
+
+        parser = OptionParser(option_class=eng_option)
+        parser.add_option("-I", "--audio-input", type="string", default="",
+                          help="pcm input device name.  E.g., hw:0,0 or /dev/dsp")
+        parser.add_option("-O", "--audio-output", type="string", default="",
+                          help="pcm output device name.  E.g., hw:0,0 or /dev/dsp")
+        parser.add_option("-r", "--sample-rate", type="eng_float", default=8000,
+                          help="set sample rate to RATE (8000)")
+        (options, args) = parser.parse_args ()
+        if len(args) != 0:
+            parser.print_help()
+            raise SystemExit, 1
+
+        sample_rate = int(options.sample_rate)
+        src = audio.source (sample_rate, options.audio_input)
+        dst = audio.sink (sample_rate, options.audio_output)
+
+       vec1 = [1, -1]
+       vsource = gr.vector_source_f(vec1, True)
+       multiply = gr.multiply_ff()
+
+       self.connect(src, (multiply, 0))
+       self.connect(vsource, (multiply, 1))
+       self.connect(multiply, dst)
+
+
+if __name__ == '__main__':
+    try:
+        my_graph().run()
+    except KeyboardInterrupt:
+        pass
diff --git a/gnuradio-examples/python/audio/test_resampler.py b/gnuradio-examples/python/audio/test_resampler.py
new file mode 100755 (executable)
index 0000000..6c9e5a7
--- /dev/null
@@ -0,0 +1,66 @@
+#!/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 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.
+# 
+
+from gnuradio import gr, gru, blks
+from gnuradio import audio
+from gnuradio.eng_option import eng_option
+from optparse import OptionParser
+
+
+class my_graph(gr.flow_graph):
+
+    def __init__(self):
+        gr.flow_graph.__init__(self)
+
+        parser = OptionParser(option_class=eng_option)
+        parser.add_option("-O", "--audio-output", type="string", default="",
+                          help="pcm output device name.  E.g., hw:0,0 or /dev/dsp")
+        parser.add_option("-i", "--input-rate", type="eng_float", default=8000,
+                          help="set input sample rate to RATE (%default)")
+        parser.add_option("-o", "--output-rate", type="eng_float", default=48000,
+                          help="set output sample rate to RATE (%default)")
+        (options, args) = parser.parse_args ()
+        if len(args) != 0:
+            parser.print_help()
+            raise SystemExit, 1
+
+        input_rate = int(options.input_rate)
+        output_rate = int(options.output_rate)
+
+        interp = gru.lcm(input_rate, output_rate) / input_rate
+        decim = gru.lcm(input_rate, output_rate) / output_rate
+
+        print "interp =", interp
+        print "decim  =", decim
+
+        ampl = 0.1
+        src0 = gr.sig_source_f (input_rate, gr.GR_SIN_WAVE, 650, ampl)
+        rr = blks.rational_resampler_fff(self, interp, decim)
+        dst = audio.sink (output_rate, options.audio_output)
+        self.connect (src0, rr, (dst, 0))
+
+
+if __name__ == '__main__':
+    try:
+        my_graph().run()
+    except KeyboardInterrupt:
+        pass
diff --git a/gnuradio-examples/python/digital_voice/Makefile.am b/gnuradio-examples/python/digital_voice/Makefile.am
new file mode 100644 (file)
index 0000000..ed88c22
--- /dev/null
@@ -0,0 +1,23 @@
+#
+# 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 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.
+# 
+
+EXTRA_DIST =                                   \
+       encdec.py                               
diff --git a/gnuradio-examples/python/digital_voice/encdec.py b/gnuradio-examples/python/digital_voice/encdec.py
new file mode 100755 (executable)
index 0000000..11936a4
--- /dev/null
@@ -0,0 +1,58 @@
+#!/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 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.
+# 
+
+from gnuradio import gr, blks
+from gnuradio import audio
+from gnuradio.eng_option import eng_option
+from optparse import OptionParser
+
+class my_graph(gr.flow_graph):
+
+    def __init__(self):
+        gr.flow_graph.__init__(self)
+
+        parser = OptionParser(option_class=eng_option)
+        parser.add_option("-I", "--audio-input", type="string", default="",
+                          help="pcm input device name.  E.g., hw:0,0 or /dev/dsp")
+        parser.add_option("-O", "--audio-output", type="string", default="",
+                          help="pcm output device name.  E.g., hw:0,0 or /dev/dsp")
+        (options, args) = parser.parse_args ()
+        if len(args) != 0:
+            parser.print_help()
+            raise SystemExit, 1
+
+        sample_rate = 8000
+        src = audio.source(sample_rate, options.audio_input)
+        tx = blks.digital_voice_tx(self)
+        if_gain = gr.multiply_const_cc(10000)
+        # channel simulator here...
+        rx = blks.digital_voice_rx(self)
+        dst = audio.sink(sample_rate, options.audio_output)
+
+        self.connect(src, tx, if_gain, rx, dst)
+
+
+if __name__ == '__main__':
+    try:
+        my_graph().run()
+    except KeyboardInterrupt:
+        pass
diff --git a/gnuradio-examples/python/gmsk2/Makefile.am b/gnuradio-examples/python/gmsk2/Makefile.am
new file mode 100644 (file)
index 0000000..cf2ffb3
--- /dev/null
@@ -0,0 +1,38 @@
+#
+# 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.
+# 
+
+EXTRA_DIST =                   \
+       benchmark_gmsk_rx.py    \
+       benchmark_gmsk_tx.py    \
+       benchmark_mpsk_rx.py    \
+       benchmark_mpsk_tx.py    \
+       fusb_options.py         \
+       gen_whitener.py         \
+       gmsk_test.py            \
+       pick_bitrate.py         \
+       receive_path.py         \
+       transmit_path.py        \
+       tunnel_ip_null_mac.py   
+
+
+
+
+
diff --git a/gnuradio-examples/python/gmsk2/README b/gnuradio-examples/python/gmsk2/README
new file mode 100644 (file)
index 0000000..b3c343e
--- /dev/null
@@ -0,0 +1,81 @@
+Quick overview of what's here:
+
+* gmsk_test.py: stand-alone program that exercises the GMSK packet tx
+and rx code.  The two halves are connected with a simulated noisy
+channel.  It's easy to add extra instrumentation to log various internal 
+states.  We used a variant of this code to get this working in the
+first place. 
+
+* benchmark_gmsk_tx.py: generates packets of the size you
+specify and sends them across the air using the USRP.  Known to work
+well using the USRP with the Flex 400 transceiver daughterboard.
+You can specify the bitrate to use with the -r <bitrate> command line
+parameter.  The default is 500k.  Some machines will do 1M or more.
+
+* benchmark_gmsk_rx.py: the receiver half of benchmark_gmsk_tx.py.
+Command line arguments are pretty much the same as tx.  Works well
+with a USRP and Flex 400 transceiver daughterboard.  Will also work
+with TVRX daugherboard, but you'll need to fiddle with the gain.  See
+below.  Prints a summary of each packet received and keeps a running
+total of packets received, and how many of them were error free.
+There are two levels of error reporting going on.  If the access code
+(PN code) and header of a packet were properly detected, then you'll
+get an output line.  If the CRC32 of the payload was correct you get
+"ok = True", else "ok = False".  The "pktno" is extracted from the
+received packet.  If there are skipped numbers, you're missing some
+packets.  Be sure you've got a suitable antenna connected to the TX/RX
+port on each board.  A "70 cm" / 420 MHz antenna for a ham
+handi-talkie works great.  These are available at ham radio supplies,
+etc.  The boards need to be at least 3m apart.  You can also try
+experimenting with the rx gain (-g <gain> command line option).
+
+Generally speaking, I start the rx first on one machine, and then fire
+up the tx on the other machine.  The tx also supports a discontinous
+transmission mode where it sends bursts of 5 packets and then waits 1
+second.  This is useful for ensuring that all the receiver control
+loops lock up fast enough.
+
+* tunnel.py: This program provides a framework for building your own
+MACs.  It creates a "TAP" interface in the kernel, typically gr0,
+and sends and receives ethernet frames through it.  See
+/usr/src/linux/Documentation/networking/tuntap.txt and/or Google for
+"universal tun tap".  The Linux 2.6 kernel includes the tun module, you
+don't have to build it.  You may have to "modprobe tun" if it's not
+loaded by default.  If /dev/net/tun doesn't exist, try "modprobe tun".
+
+To run this program you'll need to be root or running with the
+appropriate capability to open the tun interface.  You'll need to fire
+up two copies on different machines.  Once each is running you'll need
+to ifconfig the gr0 interface to set the IP address.
+
+This will allow two machines to talk, but anything beyond the two
+machines depends on your networking setup.  Left as an exercise...
+
+On machine A:
+
+  $ su
+  # ./tunnel.py --freq 423.0M --bitrate 500k
+  # # in another window on A, also as root...
+  # ifconfig gr0 10.10.10.1
+
+
+On machine B:
+
+  $ su
+  # ./tunnel.py --freq 423.0M --bitrate 500k
+  # # in another window on B, also as root...
+  # ifconfig gr0 10.10.10.2
+
+Now, on machine A you shold be able to ping machine B:
+
+  $ ping 10.10.10.2
+
+and you should see some output for each packet in the
+tunnel.py window if you used the -v option.
+
+Likewise, on machine B:
+
+  $ ping 10.10.10.1
+
+This now uses a carrier sense MAC, so you should be able to ssh
+between the machines, web browse, etc.
diff --git a/gnuradio-examples/python/gmsk2/benchmark_gmsk_rx.py b/gnuradio-examples/python/gmsk2/benchmark_gmsk_rx.py
new file mode 100755 (executable)
index 0000000..d1f70c5
--- /dev/null
@@ -0,0 +1,128 @@
+#!/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 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.
+# 
+
+from gnuradio import gr, gru, blks
+from gnuradio import usrp
+from gnuradio import eng_notation
+from gnuradio.eng_option import eng_option
+from optparse import OptionParser
+
+import random
+import struct
+
+# from current dir
+from receive_path import receive_path
+import fusb_options
+
+#import os
+#print os.getpid()
+#raw_input('Attach and press enter')
+
+
+class my_graph(gr.flow_graph):
+
+    def __init__(self, demod_class, rx_subdev_spec,
+                 bitrate, decim_rate, spb,
+                 rx_callback, options, demod_kwargs):
+        gr.flow_graph.__init__(self)
+        self.rxpath = receive_path(self, demod_class, rx_subdev_spec,
+                                   bitrate, decim_rate, spb,
+                                   rx_callback, options, demod_kwargs)
+
+# /////////////////////////////////////////////////////////////////////////////
+#                                   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 = %r  pktno = %4d  n_rcvd = %4d  n_right = %4d" % (
+            ok, pktno, n_rcvd, n_right)
+
+    parser = OptionParser (option_class=eng_option)
+    parser.add_option("-R", "--rx-subdev-spec", type="subdev", default=None,
+                      help="select USRP Rx side A or B")
+    parser.add_option("-f", "--freq", type="eng_float", default=423.1e6,
+                      help="set Rx frequency to FREQ [default=%default]",
+                      metavar="FREQ")
+    parser.add_option("-r", "--bitrate", type="eng_float", default=None,
+                      help="specify bitrate.  spb and interp will be derived.")
+    parser.add_option("-g", "--rx-gain", type="eng_float", default=27,
+                      help="set rx gain")
+    parser.add_option("-S", "--spb", type="int", default=None,
+                      help="set samples/baud [default=%default]")
+    parser.add_option("-d", "--decim", type="intx", default=None,
+                      help="set fpga decim rate to DECIM [default=%default]")
+    fusb_options.add_options(parser)
+    (options, args) = parser.parse_args ()
+
+    if len(args) != 0:
+        parser.print_help()
+        sys.exit(1)
+
+    if options.freq < 1e6:
+        options.freq *= 1e6
+
+    demod_kwargs = { } # placeholder    
+    
+    # build the graph
+    fg = my_graph(blks.gmsk2_demod,
+                  options.rx_subdev_spec, options.bitrate,
+                  options.decim, options.spb, rx_callback,
+                  options, demod_kwargs)
+
+    print "bitrate: %sb/sec" % (eng_notation.num_to_str(fg.rxpath.bitrate()),)
+    print "spb:     %3d" % (fg.rxpath.spb(),)
+    print "decim:   %3d" % (fg.rxpath.decim(),)
+
+    ok = fg.rxpath.set_freq(options.freq)
+    if not ok:
+        print "Failed to set Rx frequency to %s" % (eng_notation.num_to_str(options.freq),)
+        raise SystemExit
+    
+    fg.rxpath.set_gain(options.rx_gain)
+    print "Rx gain_range: ", fg.rxpath.subdev.gain_range(), " using", fg.rxpath.gain
+
+    r = gr.enable_realtime_scheduling()
+    if r != gr.RT_OK:
+        print "Warning: Failed to enable realtime scheduling."
+
+    fg.start()        # start flow graph
+    fg.wait()         # wait for it to finish
+
+if __name__ == '__main__':
+    try:
+        main()
+    except KeyboardInterrupt:
+        pass
diff --git a/gnuradio-examples/python/gmsk2/benchmark_gmsk_tx.py b/gnuradio-examples/python/gmsk2/benchmark_gmsk_tx.py
new file mode 100755 (executable)
index 0000000..2994003
--- /dev/null
@@ -0,0 +1,146 @@
+#!/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 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.
+# 
+
+from gnuradio import gr, gru, blks
+from gnuradio import usrp
+from gnuradio import eng_notation
+from gnuradio.eng_option import eng_option
+from optparse import OptionParser
+
+import random
+import time
+import struct
+import sys
+
+# from current dir
+from transmit_path import transmit_path
+import fusb_options
+
+#import os
+#print os.getpid()
+#raw_input('Attach and press enter')
+
+
+class my_graph(gr.flow_graph):
+
+    def __init__(self, mod_class, tx_subdev_spec,
+                 bitrate, interp_rate, spb, gain,
+                 options, mod_kwargs):
+        gr.flow_graph.__init__(self)
+        self.txpath = transmit_path(self, mod_class, tx_subdev_spec,
+                                    bitrate, interp_rate, spb, gain,
+                                    options, mod_kwargs)
+
+
+# /////////////////////////////////////////////////////////////////////////////
+#                                   main
+# /////////////////////////////////////////////////////////////////////////////
+
+def main():
+
+    def send_pkt(payload='', eof=False):
+        return fg.txpath.send_pkt(payload, eof)
+
+    def rx_callback(ok, payload):
+        print "ok = %r, payload = '%s'" % (ok, payload)
+
+    parser = OptionParser (option_class=eng_option)
+    parser.add_option("-T", "--tx-subdev-spec", type="subdev", default=None,
+                      help="select USRP Tx side A or B")
+    parser.add_option("-f", "--freq", type="eng_float", default=423.1e6,
+                      help="set Tx and Rx frequency to FREQ [default=%default]",
+                      metavar="FREQ")
+    parser.add_option("-r", "--bitrate", type="eng_float", default=None,
+                      help="specify bitrate.  spb and interp will be derived.")
+    parser.add_option("-S", "--spb", type="int", default=None,
+                      help="set samples/baud [default=%default]")
+    parser.add_option("-i", "--interp", type="intx", default=None,
+                      help="set fpga interpolation rate to INTERP [default=%default]")
+    parser.add_option("-s", "--size", type="eng_float", default=1500,
+                      help="set packet size [default=%default]")
+    parser.add_option("", "--bt", type="float", default=0.3,
+                      help="set bandwidth-time product [default=%default]")
+    parser.add_option("-g", "--gain", type="eng_float", default=100.0,
+                      help="transmitter gain [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)")
+    fusb_options.add_options(parser)
+    (options, args) = parser.parse_args ()
+
+    if len(args) != 0:
+        parser.print_help()
+        sys.exit(1)
+
+    if options.freq < 1e6:
+        options.freq *= 1e6
+
+    pkt_size = int(options.size)
+
+    mod_kwargs = {
+        'bt' : options.bt,
+        }
+
+    # build the graph
+    fg = my_graph(blks.gmsk2_mod, options.tx_subdev_spec,
+                  options.bitrate, options.interp, options.spb, options.gain,
+                  options, mod_kwargs)
+
+    print "bitrate: %sb/sec" % (eng_notation.num_to_str(fg.txpath.bitrate()),)
+    print "spb:     %3d" % (fg.txpath.spb(),)
+    print "interp:  %3d" % (fg.txpath.interp(),)
+
+    ok = fg.txpath.set_freq(options.freq)
+    if not ok:
+        print "Failed to set Tx frequency to %s" % (eng_notation.num_to_str(options.freq),)
+        raise SystemExit
+
+    r = gr.enable_realtime_scheduling()
+    if r != gr.RT_OK:
+        print "Warning: failed to enable realtime scheduling"
+
+    fg.start()                       # start flow graph
+
+    # generate and send packets
+    nbytes = int(1e6 * options.megabytes)
+    n = 0
+    pktno = 0
+
+    while n < nbytes:
+        send_pkt(struct.pack('!H', pktno) + (pkt_size - 2) * chr(pktno & 0xff))
+        n += pkt_size
+        sys.stderr.write('.')
+        if options.discontinuous and pktno % 5 == 4:
+            time.sleep(1)
+        pktno += 1
+        
+    send_pkt(eof=True)
+    fg.wait()                       # wait for it to finish
+    fg.txpath.set_auto_tr(False)
+
+
+if __name__ == '__main__':
+    try:
+        main()
+    except KeyboardInterrupt:
+        pass
diff --git a/gnuradio-examples/python/gmsk2/benchmark_mpsk_rx.py b/gnuradio-examples/python/gmsk2/benchmark_mpsk_rx.py
new file mode 100755 (executable)
index 0000000..ad6218b
--- /dev/null
@@ -0,0 +1,149 @@
+#!/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 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.
+# 
+
+from gnuradio import gr, gru, blks
+from gnuradio import usrp
+from gnuradio import eng_notation
+from gnuradio.eng_option import eng_option
+from optparse import OptionParser
+
+import random
+import struct
+
+# from current dir
+from bpsk import bpsk_demod
+from dbpsk import dbpsk_demod
+from dqpsk import dqpsk_demod
+from receive_path import receive_path
+import fusb_options
+
+if 1:
+    import os
+    print os.getpid()
+    raw_input('Attach and press enter')
+
+
+class my_graph(gr.flow_graph):
+
+    def __init__(self, demod_class, rx_subdev_spec,
+                 bitrate, decim_rate, spb,
+                 rx_callback, options, demod_kwargs):
+        gr.flow_graph.__init__(self)
+        self.rxpath = receive_path(self, demod_class, rx_subdev_spec,
+                                   bitrate, decim_rate, spb,
+                                   rx_callback, options, demod_kwargs)
+
+# /////////////////////////////////////////////////////////////////////////////
+#                                   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 = %r  pktno = %4d  n_rcvd = %4d  n_right = %4d" % (
+            ok, pktno, n_rcvd, n_right)
+
+    parser = OptionParser (option_class=eng_option)
+    parser.add_option("-R", "--rx-subdev-spec", type="subdev", default=None,
+                      help="select USRP Rx side A or B")
+    parser.add_option("-f", "--freq", type="eng_float", default=423.1e6,
+                      help="set Rx frequency to FREQ [default=%default]",
+                      metavar="FREQ")
+    parser.add_option("-r", "--bitrate", type="eng_float", default=None,
+                      help="specify bitrate.  spb and interp will be derived.")
+    parser.add_option("-S", "--spb", type="int", default=None,
+                      help="set samples/baud [default=%default]")
+    parser.add_option("-d", "--decim", type="intx", default=None,
+                      help="set fpga decim rate to DECIM [default=%default]")
+    parser.add_option("-m", "--modulation", type="string", default='dbpsk',
+                      help="modulation type (bpsk, dbpsk, dqpsk) [default=%default]")
+    parser.add_option("", "--excess-bw", type="float", default=0.3,
+                      help="set RRC excess bandwith factor [default=%default]")
+    parser.add_option("-g", "--gain", type="eng_float", default=27,
+                      help="set rx gain")
+    parser.add_option("","--log", action="store_true", default=False,
+                      help="enable diagnostic logging")
+    fusb_options.add_options(parser)
+    (options, args) = parser.parse_args ()
+
+    if len(args) != 0:
+        parser.print_help()
+        sys.exit(1)
+
+    if options.freq < 1e6:
+        options.freq *= 1e6
+
+    demod_kwargs = {
+            'excess_bw' : options.excess_bw,
+            }
+
+    #FIXME: Needs to be worked in to overall structure; this will be fixed
+    #       once static class definitions for modulations are defined
+    if(options.modulation=='bpsk'):
+        modulation=bpsk_demod
+    elif(options.modulation=='dbpsk'):
+        modulation=dbpsk_demod
+    else:
+        modulation=dqpsk_demod
+
+    # build the graph
+    fg = my_graph(modulation,
+                  options.rx_subdev_spec, options.bitrate,
+                  options.decim, options.spb,
+                  rx_callback, options, demod_kwargs)
+
+    print "bitrate: %sb/sec" % (eng_notation.num_to_str(fg.rxpath.bitrate()),)
+    print "spb:     %3d" % (fg.rxpath.spb(),)
+    print "decim:   %3d" % (fg.rxpath.decim(),)
+
+    ok = fg.rxpath.set_freq(options.freq)
+    if not ok:
+        print "Failed to set Rx frequency to %s" % (eng_notation.num_to_str(options.freq),)
+        raise SystemExit
+    
+    fg.rxpath.set_gain(options.gain)
+    print "Rx gain_range: ", fg.rxpath.subdev.gain_range(), " using", fg.rxpath.gain
+
+    r = gr.enable_realtime_scheduling()
+    if r != gr.RT_OK:
+        print "Warning: Failed to enable realtime scheduling."
+
+    fg.start()        # start flow graph
+    fg.wait()         # wait for it to finish
+
+if __name__ == '__main__':
+    try:
+        main()
+    except KeyboardInterrupt:
+        pass
diff --git a/gnuradio-examples/python/gmsk2/benchmark_mpsk_tx.py b/gnuradio-examples/python/gmsk2/benchmark_mpsk_tx.py
new file mode 100755 (executable)
index 0000000..7b37da7
--- /dev/null
@@ -0,0 +1,157 @@
+#!/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 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.
+# 
+
+from gnuradio import gr, gru, blks
+from gnuradio import usrp
+from gnuradio import eng_notation
+from gnuradio.eng_option import eng_option
+from optparse import OptionParser
+
+import random, time, struct, sys
+
+# from current dir
+from bpsk  import bpsk_mod
+from dbpsk import dbpsk_mod
+from dqpsk import dqpsk_mod
+from transmit_path import transmit_path
+import fusb_options
+
+#import os
+#print os.getpid()
+#raw_input('Attach and press enter')
+
+
+class my_graph(gr.flow_graph):
+
+    def __init__(self, mod_class, tx_subdev_spec,
+                 bitrate, interp_rate, spb, gain,
+                 options, mod_kwargs):
+        gr.flow_graph.__init__(self)
+        self.txpath = transmit_path(self, mod_class, tx_subdev_spec,
+                                    bitrate, interp_rate, spb, gain,
+                                    options, mod_kwargs)
+
+
+# /////////////////////////////////////////////////////////////////////////////
+#                                   main
+# /////////////////////////////////////////////////////////////////////////////
+
+def main():
+
+    def send_pkt(payload='', eof=False):
+        return fg.txpath.send_pkt(payload, eof)
+
+    def rx_callback(ok, payload):
+        print "ok = %r, payload = '%s'" % (ok, payload)
+
+    parser = OptionParser (option_class=eng_option)
+    parser.add_option("-T", "--tx-subdev-spec", type="subdev", default=None,
+                      help="select USRP Tx side A or B")
+    parser.add_option("-f", "--freq", type="eng_float", default=423.1e6,
+                      help="set Tx and Rx frequency to FREQ [default=%default]",
+                      metavar="FREQ")
+    parser.add_option("-r", "--bitrate", type="eng_float", default=None,
+                      help="specify bitrate.  spb and interp will be derived.")
+    parser.add_option("-S", "--spb", type="int", default=None,
+                      help="set samples/baud [default=%default]")
+    parser.add_option("-i", "--interp", type="intx", default=None,
+                      help="set fpga interpolation rate to INTERP [default=%default]")
+    parser.add_option("-s", "--size", type="eng_float", default=1500,
+                      help="set packet size [default=%default]")
+    parser.add_option("-m", "--modulation", type="string", default='dbpsk',
+                      help="modulation type (bpsk, dbpsk, dqpsk) [default=%default]")
+    parser.add_option("", "--excess-bw", type="float", default=0.3,
+                      help="set RRC excess bandwith factor [default=%default]")
+    parser.add_option("-g", "--gain", type="eng_float", default=100.0,
+                      help="transmitter gain [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)")
+    fusb_options.add_options(parser)
+    (options, args) = parser.parse_args ()
+
+    if len(args) != 0:
+        parser.print_help()
+        sys.exit(1)
+
+    if options.freq < 1e6:
+        options.freq *= 1e6
+
+    pkt_size = int(options.size)
+
+    mod_kwargs = {
+        'excess_bw' : options.excess_bw,
+        }
+
+    #FIXME: rework when static class defintions are ready for the modulation types
+    if(options.modulation=='bpsk'):
+        modulation=bpsk_mod
+    elif( options.modulation=='dbpsk'):
+        modulation=dbpsk_mod
+    else:
+        modulation=dqpsk_mod
+
+    # build the graph
+    fg = my_graph(modulation,
+                  options.tx_subdev_spec, options.bitrate, options.interp,
+                  options.spb, options.gain,
+                  options, mod_kwargs)
+
+    print "bitrate: %sb/sec" % (eng_notation.num_to_str(fg.txpath.bitrate()),)
+    print "spb:     %3d" % (fg.txpath.spb(),)
+    print "interp:  %3d" % (fg.txpath.interp(),)
+
+    ok = fg.txpath.set_freq(options.freq)
+    if not ok:
+        print "Failed to set Tx frequency to %s" % (eng_notation.num_to_str(options.freq),)
+        raise SystemExit
+
+    r = gr.enable_realtime_scheduling()
+    if r != gr.RT_OK:
+        print "Warning: failed to enable realtime scheduling"
+
+    fg.start()                       # start flow graph
+
+    # generate and send packets
+    nbytes = int(1e6 * options.megabytes)
+    n = 0
+    pktno = 0
+
+    while n < nbytes:
+        send_pkt(struct.pack('!H', pktno) + (pkt_size - 2) * chr(pktno & 0xff))
+        n += pkt_size
+        sys.stderr.write('.')
+        if options.discontinuous and pktno % 5 == 4:
+            time.sleep(1)
+        pktno += 1
+        
+    send_pkt(eof=True)
+    fg.wait()                       # wait for it to finish
+    fg.txpath.set_auto_tr(False)
+
+
+if __name__ == '__main__':
+    try:
+        main()
+    except KeyboardInterrupt:
+        pass
diff --git a/gnuradio-examples/python/gmsk2/bpsk.py b/gnuradio-examples/python/gmsk2/bpsk.py
new file mode 100644 (file)
index 0000000..14cea7b
--- /dev/null
@@ -0,0 +1,256 @@
+#
+# 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 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.
+# 
+
+# See gnuradio-examples/python/gmsk2 for examples
+
+"""
+BPSK modulation and demodulation.
+"""
+
+from gnuradio import gr, gru
+from math import pi, sqrt
+import cmath
+import Numeric
+from pprint import pprint
+
+_use_gray_code = True
+
+def make_constellation(m):
+    return [cmath.exp(i * 2 * pi / m * 1j) for i in range(m)]
+        
+# Common definition of constellations for Tx and Rx
+constellation = {
+    2 : make_constellation(2),           # BPSK
+    4 : make_constellation(4),           # QPSK
+    8 : make_constellation(8)            # 8PSK
+    }
+
+if 0:
+    print "const(2) ="
+    pprint(constellation[2])
+    print "const(4) ="
+    pprint(constellation[4])
+    print "const(8) ="
+    pprint(constellation[8])
+
+
+if _use_gray_code:
+    # -----------------------
+    # Do Gray code
+    # -----------------------
+    # binary to gray coding
+    binary_to_gray = {
+        2 : (0, 1),
+        4 : (0, 1, 3, 2),
+        8 : (0, 1, 3, 2, 7, 6, 4, 5)
+        }
+    
+    # gray to binary
+    gray_to_binary = {
+        2 : (0, 1),
+        4 : (0, 1, 3, 2),
+        8 : (0, 1, 3, 2, 6, 7, 5, 4)
+        }
+else:
+    # -----------------------
+    # Don't Gray code
+    # -----------------------
+    # identity mapping
+    binary_to_gray = {
+        2 : (0, 1),
+        4 : (0, 1, 2, 3),
+        8 : (0, 1, 2, 3, 4, 5, 6, 7)
+        }
+    
+    # identity mapping
+    gray_to_binary = {
+        2 : (0, 1),
+        4 : (0, 1, 2, 3),
+        8 : (0, 1, 2, 3, 4, 5, 6, 7)
+        }
+
+
+# /////////////////////////////////////////////////////////////////////////////
+#            mPSK mod/demod with steams of bytes as data i/o
+# /////////////////////////////////////////////////////////////////////////////
+
+
+class bpsk_mod(gr.hier_block):
+
+    def __init__(self, fg, spb, excess_bw):
+        """
+       Hierarchical block for RRC-filtered BPSK modulation.
+
+       The input is a byte stream (unsigned char) and the
+       output is the complex modulated signal at baseband.
+
+       @param fg: flow graph
+       @type fg: flow graph
+       @param spb: samples per baud >= 2
+       @type spb: integer
+       @param excess_bw: Root-raised cosine filter excess bandwidth
+       @type excess_bw: float
+       """
+        if not isinstance(spb, int) or spb < 2:
+            raise TypeError, "sbp must be an integer >= 2"
+        self.spb = spb
+
+       ntaps = 11 * spb
+
+        bits_per_symbol = self.bits_per_baud()
+        arity = pow(2,bits_per_symbol)
+        print "bits_per_symbol =", bits_per_symbol
+        
+        # turn bytes into k-bit vectors
+        self.bytes2chunks = \
+          gr.packed_to_unpacked_bb(bits_per_symbol, gr.GR_MSB_FIRST)
+
+        self.chunks2symbols = gr.chunks_to_symbols_bc(constellation[arity])
+
+        # pulse shaping filter
+       self.rrc_taps = gr.firdes.root_raised_cosine(
+               spb,            # gain  (spb since we're interpolating by spb)
+               spb,            # sampling rate
+               1.0,            # symbol rate
+               excess_bw,      # excess bandwidth (roll-off factor)
+                ntaps)
+
+       self.rrc_filter = gr.interp_fir_filter_ccf(spb, self.rrc_taps)
+
+       # Connect
+        fg.connect(self.bytes2chunks, self.chunks2symbols, self.rrc_filter)
+
+        if 1:
+            fg.connect(self.rrc_filter,
+                       gr.file_sink(gr.sizeof_gr_complex, "rrc.dat"))
+            
+       # Initialize base class
+       gr.hier_block.__init__(self, fg, self.bytes2chunks, self.rrc_filter)
+
+    def samples_per_baud(self):
+        return self.spb
+
+    def bits_per_baud(self=None):   # staticmethod that's also callable on an instance
+        return 1
+    bits_per_baud = staticmethod(bits_per_baud)      # make it a static method.  RTFM
+
+
+class bpsk_demod__coherent_detection_of_psk(gr.hier_block):
+    def __init__(self, fg, spb, excess_bw, costas_alpha=0.005, gain_mu=0.05):
+        """
+       Hierarchical block for RRC-filtered 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 fg: flow graph
+       @type fg: flow graph
+       @param spb: samples per baud >= 2
+       @type spb: float
+       @param excess_bw: Root-raised cosine filter excess bandwidth
+       @type excess_bw: float
+        @param costas_alpha: loop filter gain
+        @type costas_alphas: float
+        @param gain_mu:
+        @type gain_mu: float
+       """
+        if spb < 2:
+            raise TypeError, "sbp must be >= 2"
+        self.spb = spb
+
+        bits_per_symbol = self.bits_per_baud()
+        arity = pow(2,bits_per_symbol)
+        print "bits_per_symbol =", bits_per_symbol
+
+        # Automatic gain control
+        self.preamp = gr.multiply_const_cc(10e-5)
+        self.agc = gr.agc_cc(1e-3, 1, 1)
+        
+        # Costas loop (carrier tracking)
+        # FIXME: need to decide how to handle this more generally; do we pull it from higher layer?
+        costas_order = 2
+        costas_alpha *= 15   # 2nd order loop needs more gain
+        beta = .25 * costas_alpha * costas_alpha
+        self.costas_loop = gr.costas_loop_cc(costas_alpha, beta, 0.05, -0.05, costas_order)
+
+        # RRC data filter
+        ntaps = 11 * spb
+        self.rrc_taps = gr.firdes.root_raised_cosine(
+            1.0,                # gain 
+            spb,                # sampling rate
+            1.0,                # symbol rate
+            excess_bw,          # excess bandwidth (roll-off factor)
+            ntaps)
+
+        self.rrc_filter=gr.fir_filter_ccf(1, self.rrc_taps)
+
+        # symbol clock recovery
+        omega = spb
+        gain_omega = .25 * gain_mu * gain_mu
+        omega_rel_limit = 0.5
+        mu = 0.05
+        gain_mu = 0.1
+        self.clock_recovery=gr.clock_recovery_mm_cc(omega, gain_omega,
+                                                    mu, gain_mu, omega_rel_limit)
+
+        # find closest constellation point
+        #rot = .707 + .707j
+        rot = 1
+        rotated_const = map(lambda pt: pt * rot, constellation[arity])
+        print "rotated_const =", rotated_const
+
+        self.slicer = gr.constellation_decoder_cb(rotated_const, range(arity))
+        self.gray_decoder = gr.map_bb(gray_to_binary[arity])
+        
+        # unpack the k bit vector into a stream of bits
+        self.unpack = gr.unpack_k_bits_bb(bits_per_symbol)
+
+        fg.connect(self.preamp, self.agc, self.costas_loop, self.rrc_filter, self.clock_recovery,
+                   self.slicer, self.gray_decoder, self.unpack)
+        
+        # Debug sinks
+        if 1:
+            fg.connect(self.agc,
+                       gr.file_sink(gr.sizeof_gr_complex, "agc.dat"))
+            fg.connect(self.costas_loop,
+                       gr.file_sink(gr.sizeof_gr_complex, "costas_loop.dat"))
+            fg.connect(self.rrc_filter,
+                       gr.file_sink(gr.sizeof_gr_complex, "rrc.dat"))
+            fg.connect(self.clock_recovery,
+                       gr.file_sink(gr.sizeof_gr_complex, "clock_recovery.dat"))
+            fg.connect(self.slicer,
+                       gr.file_sink(gr.sizeof_char, "slicer.dat"))
+            fg.connect(self.unpack,
+                       gr.file_sink(gr.sizeof_char, "unpack.dat"))
+
+        # Initialize base class
+        gr.hier_block.__init__(self, fg, self.preamp, self.unpack)
+
+    def samples_per_baud(self):
+        return self.spb
+
+    def bits_per_baud(self=None):   # staticmethod that's also callable on an instance
+        return 1
+    bits_per_baud = staticmethod(bits_per_baud)      # make it a static method.  RTFM
+
+
+bpsk_demod = bpsk_demod__coherent_detection_of_psk
+
diff --git a/gnuradio-examples/python/gmsk2/dbpsk.py b/gnuradio-examples/python/gmsk2/dbpsk.py
new file mode 100644 (file)
index 0000000..213e90c
--- /dev/null
@@ -0,0 +1,282 @@
+#
+# 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 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.
+# 
+
+# See gnuradio-examples/python/gmsk2 for examples
+
+"""
+differential BPSK modulation and demodulation.
+"""
+
+from gnuradio import gr, gru
+from math import pi, sqrt
+import cmath
+import Numeric
+from pprint import pprint
+
+_use_gray_code = True
+
+def make_constellation(m):
+    return [cmath.exp(i * 2 * pi / m * 1j) for i in range(m)]
+        
+# Common definition of constellations for Tx and Rx
+constellation = {
+    2 : make_constellation(2),           # BPSK
+    4 : make_constellation(4),           # QPSK
+    8 : make_constellation(8)            # 8PSK
+    }
+
+if 0:
+    print "const(2) ="
+    pprint(constellation[2])
+    print "const(4) ="
+    pprint(constellation[4])
+    print "const(8) ="
+    pprint(constellation[8])
+
+
+if _use_gray_code:
+    # -----------------------
+    # Do Gray code
+    # -----------------------
+    # binary to gray coding
+    binary_to_gray = {
+        2 : (0, 1),
+        4 : (0, 1, 3, 2),
+        8 : (0, 1, 3, 2, 7, 6, 4, 5)
+        }
+    
+    # gray to binary
+    gray_to_binary = {
+        2 : (0, 1),
+        4 : (0, 1, 3, 2),
+        8 : (0, 1, 3, 2, 6, 7, 5, 4)
+        }
+else:
+    # -----------------------
+    # Don't Gray code
+    # -----------------------
+    # identity mapping
+    binary_to_gray = {
+        2 : (0, 1),
+        4 : (0, 1, 2, 3),
+        8 : (0, 1, 2, 3, 4, 5, 6, 7)
+        }
+    
+    # identity mapping
+    gray_to_binary = {
+        2 : (0, 1),
+        4 : (0, 1, 2, 3),
+        8 : (0, 1, 2, 3, 4, 5, 6, 7)
+        }
+
+
+# /////////////////////////////////////////////////////////////////////////////
+#            BPSK mod/demod with steams of bytes as data i/o
+# /////////////////////////////////////////////////////////////////////////////
+
+
+class dbpsk_mod(gr.hier_block):
+
+    def __init__(self, fg, spb, excess_bw):
+        """
+       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 fg: flow graph
+       @type fg: flow graph
+       @param spb: samples per baud >= 2
+       @type spb: integer
+       @param excess_bw: Root-raised cosine filter excess bandwidth
+       @type excess_bw: float
+       """
+        if not isinstance(spb, int) or spb < 2:
+            raise TypeError, "sbp must be an integer >= 2"
+        self.spb = spb
+
+       ntaps = 11 * spb
+
+        bits_per_symbol = self.bits_per_baud()
+        arity = pow(2,bits_per_symbol)
+        self.bits_per_symbol = bits_per_symbol
+        print "bits_per_symbol =", bits_per_symbol
+        
+        # turn bytes into k-bit vectors
+        self.bytes2chunks = \
+          gr.packed_to_unpacked_bb(bits_per_symbol, gr.GR_MSB_FIRST)
+
+        if True:
+            self.gray_coder = gr.map_bb(binary_to_gray[arity])
+        else:
+            self.gray_coder = None
+
+        self.diffenc = gr.diff_encoder_bb(arity)
+        
+        self.chunks2symbols = gr.chunks_to_symbols_bc(constellation[arity])
+
+        # pulse shaping filter
+       self.rrc_taps = gr.firdes.root_raised_cosine(
+               spb,            # gain  (spb since we're interpolating by spb)
+               spb,            # sampling rate
+               1.0,            # symbol rate
+               excess_bw,      # excess bandwidth (roll-off factor)
+                ntaps)
+
+       self.rrc_filter = gr.interp_fir_filter_ccf(spb, self.rrc_taps)
+
+       # Connect
+        if self.gray_coder:
+            fg.connect(self.bytes2chunks, self.gray_coder)
+            t = self.gray_coder
+        else:
+            t = self.bytes2chunks
+
+        fg.connect(t, self.diffenc, self.chunks2symbols, self.rrc_filter)
+        
+        if 1:
+            fg.connect(self.gray_coder,
+                       gr.file_sink(gr.sizeof_char, "graycoder.dat"))
+            fg.connect(self.diffenc,
+                       gr.file_sink(gr.sizeof_char, "diffenc.dat"))
+            
+       # Initialize base class
+       gr.hier_block.__init__(self, fg, self.bytes2chunks, self.rrc_filter)
+
+    def samples_per_baud(self):
+        return self.spb
+
+    def bits_per_baud(self=None):   # staticmethod that's also callable on an instance
+        return 1
+    bits_per_baud = staticmethod(bits_per_baud)      # make it a static method.  RTFM
+
+
+
+class dbpsk_demod__coherent_detection_of_differentially_encoded_psk(gr.hier_block):
+    def __init__(self, fg, spb, excess_bw, costas_alpha=0.005, gain_mu=0.05):
+        """
+       Hierarchical block for RRC-filtered 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 fg: flow graph
+       @type fg: flow graph
+       @param spb: samples per baud >= 2
+       @type spb: float
+       @param excess_bw: Root-raised cosine filter excess bandwidth
+       @type excess_bw: float
+        @param costas_alpha: loop filter gain
+        @type costas_alphas: float
+        @param gain_mu:
+        @type gain_mu: float
+       """
+        if spb < 2:
+            raise TypeError, "sbp must be >= 2"
+        self.spb = spb
+
+        bits_per_symbol = self.bits_per_baud()
+        arity = pow(2,bits_per_symbol)
+        print "bits_per_symbol =", bits_per_symbol
+
+        # Automatic gain control
+        self.preamp = gr.multiply_const_cc(10e-5)
+        self.agc = gr.agc_cc(1e-3, 1, 1, 1000)
+        
+        # Costas loop (carrier tracking)
+        # FIXME: need to decide how to handle this more generally; do we pull it from higher layer?
+        costas_order = 2
+        costas_alpha *= 15   # 2nd order loop needs more gain
+        beta = .25 * costas_alpha * costas_alpha
+        self.costas_loop = gr.costas_loop_cc(costas_alpha, beta, 0.05, -0.05, costas_order)
+
+        # RRC data filter
+        ntaps = 11 * spb
+        self.rrc_taps = gr.firdes.root_raised_cosine(
+            1.0,                # gain 
+            spb,                # sampling rate
+            1.0,                # symbol rate
+            excess_bw,          # excess bandwidth (roll-off factor)
+            ntaps)
+
+        self.rrc_filter=gr.fir_filter_ccf(1, self.rrc_taps)
+
+        # symbol clock recovery
+        omega = spb
+        gain_omega = .25 * gain_mu * gain_mu
+        omega_rel_limit = 0.5
+        mu = 0.05
+        gain_mu = 0.1
+        self.clock_recovery=gr.clock_recovery_mm_cc(omega, gain_omega,
+                                                    mu, gain_mu, omega_rel_limit)
+
+        # find closest constellation point
+        #rot = .707 + .707j
+        rot = 1
+        rotated_const = map(lambda pt: pt * rot, constellation[arity])
+        print "rotated_const =", rotated_const
+
+        self.diffdec = gr.diff_phasor_cc()
+        #self.diffdec = gr.diff_decoder_bb(arity)
+
+        self.slicer = gr.constellation_decoder_cb(rotated_const, range(arity))
+        self.gray_decoder = gr.map_bb(gray_to_binary[arity])
+        
+        # unpack the k bit vector into a stream of bits
+        self.unpack = gr.unpack_k_bits_bb(bits_per_symbol)
+
+        fg.connect(self.preamp, self.agc, self.costas_loop, self.rrc_filter, self.clock_recovery,
+                   self.diffdec, self.slicer, self.gray_decoder, self.unpack)
+        #fg.connect(self.preamp, self.agc, self.costas_loop, self.rrc_filter, self.clock_recovery,
+        #           self.slicer, self.diffdec, self.gray_decoder, self.unpack)
+        
+        # Debug sinks
+        if 1:
+            fg.connect(self.agc,
+                       gr.file_sink(gr.sizeof_gr_complex, "agc.dat"))
+            fg.connect(self.costas_loop,
+                       gr.file_sink(gr.sizeof_gr_complex, "costas_loop.dat"))
+            fg.connect(self.rrc_filter,
+                       gr.file_sink(gr.sizeof_gr_complex, "rrc.dat"))
+            fg.connect(self.clock_recovery,
+                       gr.file_sink(gr.sizeof_gr_complex, "clock_recovery.dat"))
+            fg.connect(self.slicer,
+                       gr.file_sink(gr.sizeof_char, "slicer.dat"))
+            fg.connect(self.diffdec,
+                       gr.file_sink(gr.sizeof_gr_complex, "diffdec.dat"))
+            #fg.connect(self.diffdec,
+            #          gr.file_sink(gr.sizeof_char, "diffdec.dat"))
+            fg.connect(self.unpack,
+                       gr.file_sink(gr.sizeof_char, "unpack.dat"))
+
+        # Initialize base class
+        gr.hier_block.__init__(self, fg, self.preamp, self.unpack)
+
+    def samples_per_baud(self):
+        return self.spb
+
+    def bits_per_baud(self=None):   # staticmethod that's also callable on an instance
+        return 1
+    bits_per_baud = staticmethod(bits_per_baud)      # make it a static method.  RTFM
+
+
+dbpsk_demod = dbpsk_demod__coherent_detection_of_differentially_encoded_psk
+
diff --git a/gnuradio-examples/python/gmsk2/dqpsk.py b/gnuradio-examples/python/gmsk2/dqpsk.py
new file mode 100644 (file)
index 0000000..490dc6f
--- /dev/null
@@ -0,0 +1,280 @@
+#
+# 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 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.
+# 
+
+# See gnuradio-examples/python/gmsk2 for examples
+
+"""
+differential QPSK modulation and demodulation.
+"""
+
+from gnuradio import gr, gru
+from math import pi, sqrt
+import cmath
+import Numeric
+from pprint import pprint
+
+_use_gray_code = True
+
+def make_constellation(m):
+    return [cmath.exp(i * 2 * pi / m * 1j) for i in range(m)]
+        
+# Common definition of constellations for Tx and Rx
+constellation = {
+    2 : make_constellation(2),           # BPSK
+    4 : make_constellation(4),           # QPSK
+    8 : make_constellation(8)            # 8PSK
+    }
+
+if 0:
+    print "const(2) ="
+    pprint(constellation[2])
+    print "const(4) ="
+    pprint(constellation[4])
+    print "const(8) ="
+    pprint(constellation[8])
+
+
+if _use_gray_code:
+    # -----------------------
+    # Do Gray code
+    # -----------------------
+    # binary to gray coding
+    binary_to_gray = {
+        2 : (0, 1),
+        4 : (0, 1, 3, 2),
+        8 : (0, 1, 3, 2, 7, 6, 4, 5)
+        }
+    
+    # gray to binary
+    gray_to_binary = {
+        2 : (0, 1),
+        4 : (0, 1, 3, 2),
+        8 : (0, 1, 3, 2, 6, 7, 5, 4)
+        }
+else:
+    # -----------------------
+    # Don't Gray code
+    # -----------------------
+    # identity mapping
+    binary_to_gray = {
+        2 : (0, 1),
+        4 : (0, 1, 2, 3),
+        8 : (0, 1, 2, 3, 4, 5, 6, 7)
+        }
+    
+    # identity mapping
+    gray_to_binary = {
+        2 : (0, 1),
+        4 : (0, 1, 2, 3),
+        8 : (0, 1, 2, 3, 4, 5, 6, 7)
+        }
+
+
+# /////////////////////////////////////////////////////////////////////////////
+#            QPSK mod/demod with steams of bytes as data i/o
+# /////////////////////////////////////////////////////////////////////////////
+
+
+class dqpsk_mod(gr.hier_block):
+
+    def __init__(self, fg, spb, excess_bw):
+        """
+       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 fg: flow graph
+       @type fg: flow graph
+       @param spb: samples per baud >= 2
+       @type spb: integer
+       @param excess_bw: Root-raised cosine filter excess bandwidth
+       @type excess_bw: float
+       """
+        if not isinstance(spb, int) or spb < 2:
+            raise TypeError, "sbp must be an integer >= 2"
+        self.spb = spb
+
+       ntaps = 11 * spb
+
+        bits_per_symbol = self.bits_per_baud()
+        arity = pow(2,bits_per_symbol)
+        print "bits_per_symbol =", bits_per_symbol
+        
+        # turn bytes into k-bit vectors
+        self.bytes2chunks = \
+          gr.packed_to_unpacked_bb(bits_per_symbol, gr.GR_MSB_FIRST)
+
+        if True:
+            self.gray_coder = gr.map_bb(binary_to_gray[arity])
+        else:
+            self.gray_coder = None
+
+        self.diffenc = gr.diff_encoder_bb(arity)
+        
+        self.chunks2symbols = gr.chunks_to_symbols_bc(constellation[arity])
+
+        # pulse shaping filter
+       self.rrc_taps = gr.firdes.root_raised_cosine(
+               spb,            # gain  (spb since we're interpolating by spb)
+               spb,            # sampling rate
+               1.0,            # symbol rate
+               excess_bw,      # excess bandwidth (roll-off factor)
+                ntaps)
+
+       self.rrc_filter = gr.interp_fir_filter_ccf(spb, self.rrc_taps)
+
+       # Connect
+        if self.gray_coder:
+            fg.connect(self.bytes2chunks, self.gray_coder)
+            t = self.gray_coder
+        else:
+            t = self.bytes2chunks
+
+        fg.connect(t, self.diffenc, self.chunks2symbols, self.rrc_filter)
+        
+        if 1:
+            fg.connect(self.gray_coder,
+                       gr.file_sink(gr.sizeof_char, "graycoder.dat"))
+            fg.connect(self.diffenc,
+                       gr.file_sink(gr.sizeof_char, "diffenc.dat"))
+            
+       # Initialize base class
+       gr.hier_block.__init__(self, fg, self.bytes2chunks, self.rrc_filter)
+
+    def samples_per_baud(self):
+        return self.spb
+
+    def bits_per_baud(self=None):   # staticmethod that's also callable on an instance
+        return 2
+    bits_per_baud = staticmethod(bits_per_baud)      # make it a static method.  RTFM
+
+
+
+class dqpsk_demod__coherent_detection_of_differentially_encoded_psk(gr.hier_block):
+    def __init__(self, fg, spb, excess_bw, costas_alpha=0.005, gain_mu=0.05):
+        """
+       Hierarchical block for RRC-filtered QPSK demodulation
+
+       The input is the complex modulated signal at baseband.
+       The output is a stream of bits packed 1 bit per byte (LSB)
+
+       @param fg: flow graph
+       @type fg: flow graph
+       @param spb: samples per baud >= 2
+       @type spb: float
+       @param excess_bw: Root-raised cosine filter excess bandwidth
+       @type excess_bw: float
+        @param costas_alpha: loop filter gain
+        @type costas_alphas: float
+        @param gain_mu:
+        @type gain_mu: float
+       """
+        if spb < 2:
+            raise TypeError, "sbp must be >= 2"
+        self.spb = spb
+
+        bits_per_symbol = self.bits_per_baud()
+        arity = pow(2,bits_per_symbol)
+        print "bits_per_symbol =", bits_per_symbol
+
+        # Automatic gain control
+        self.preamp = gr.multiply_const_cc(10e-5)
+        self.agc = gr.agc_cc(1e-3, 1, 1)
+        
+        # Costas loop (carrier tracking)
+        # FIXME: need to decide how to handle this more generally; do we pull it from higher layer?
+        costas_order = 4
+        beta = .25 * costas_alpha * costas_alpha
+        self.costas_loop = gr.costas_loop_cc(costas_alpha, beta, 0.05, -0.05, costas_order)
+
+        # RRC data filter
+        ntaps = 11 * spb
+        self.rrc_taps = gr.firdes.root_raised_cosine(
+            1.0,                # gain 
+            spb,                # sampling rate
+            1.0,                # symbol rate
+            excess_bw,          # excess bandwidth (roll-off factor)
+            ntaps)
+
+        self.rrc_filter=gr.fir_filter_ccf(1, self.rrc_taps)
+
+        # symbol clock recovery
+        omega = spb
+        gain_omega = .25 * gain_mu * gain_mu
+        omega_rel_limit = 0.5
+        mu = 0.05
+        gain_mu = 0.1
+        self.clock_recovery=gr.clock_recovery_mm_cc(omega, gain_omega,
+                                                    mu, gain_mu, omega_rel_limit)
+
+        # find closest constellation point
+        #rot = .707 + .707j
+        rot = 1
+        rotated_const = map(lambda pt: pt * rot, constellation[arity])
+        print "rotated_const =", rotated_const
+
+        self.diffdec = gr.diff_phasor_cc()
+        #self.diffdec = gr.diff_decoder_bb(arity)
+
+        self.slicer = gr.constellation_decoder_cb(rotated_const, range(arity))
+        self.gray_decoder = gr.map_bb(gray_to_binary[arity])
+        
+        # unpack the k bit vector into a stream of bits
+        self.unpack = gr.unpack_k_bits_bb(bits_per_symbol)
+
+        fg.connect(self.preamp, self.agc, self.costas_loop, self.rrc_filter, self.clock_recovery,
+                   self.diffdec, self.slicer, self.gray_decoder, self.unpack)
+        #fg.connect(self.preamp, self.agc, self.costas_loop, self.rrc_filter, self.clock_recovery,
+        #           self.slicer, self.diffdec, self.gray_decoder, self.unpack)
+        
+        # Debug sinks
+        if 1:
+            fg.connect(self.agc,
+                       gr.file_sink(gr.sizeof_gr_complex, "agc.dat"))
+            fg.connect(self.costas_loop,
+                       gr.file_sink(gr.sizeof_gr_complex, "costas_loop.dat"))
+            fg.connect(self.rrc_filter,
+                       gr.file_sink(gr.sizeof_gr_complex, "rrc.dat"))
+            fg.connect(self.clock_recovery,
+                       gr.file_sink(gr.sizeof_gr_complex, "clock_recovery.dat"))
+            fg.connect(self.slicer,
+                       gr.file_sink(gr.sizeof_char, "slicer.dat"))
+            fg.connect(self.diffdec,
+                       gr.file_sink(gr.sizeof_gr_complex, "diffdec.dat"))
+            #fg.connect(self.diffdec,
+            #          gr.file_sink(gr.sizeof_char, "diffdec.dat"))
+            fg.connect(self.unpack,
+                       gr.file_sink(gr.sizeof_char, "unpack.dat"))
+
+        # Initialize base class
+        gr.hier_block.__init__(self, fg, self.preamp, self.unpack)
+
+    def samples_per_baud(self):
+        return self.spb
+
+    def bits_per_baud(self=None):   # staticmethod that's also callable on an instance
+        return 2
+    bits_per_baud = staticmethod(bits_per_baud)      # make it a static method.  RTFM
+
+
+dqpsk_demod = dqpsk_demod__coherent_detection_of_differentially_encoded_psk
+
diff --git a/gnuradio-examples/python/gmsk2/fusb_options.py b/gnuradio-examples/python/gmsk2/fusb_options.py
new file mode 100644 (file)
index 0000000..0d04e30
--- /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 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.
+# 
+
+def add_options(parser):
+    """
+    Add Fast USB specifc options to command line parser.
+    
+    @param parser: instance of OptionParser
+    """
+    parser.add_option("-B", "--fusb-block-size", type="int", default=0,
+                      help="specify fast usb block size [default=%default]")
+    parser.add_option("-N", "--fusb-nblocks", type="int", default=0,
+                      help="specify number of fast usb blocks [default=%default]")
diff --git a/gnuradio-examples/python/gmsk2/gen_whitener.py b/gnuradio-examples/python/gmsk2/gen_whitener.py
new file mode 100755 (executable)
index 0000000..93aea2b
--- /dev/null
@@ -0,0 +1,40 @@
+#!/usr/bin/env python
+
+from gnuradio import gr, gru
+from gnuradio.eng_option import eng_option
+from optparse import OptionParser
+import sys
+
+class my_graph(gr.flow_graph):
+
+    def __init__(self):
+        gr.flow_graph.__init__(self)
+
+        parser = OptionParser(option_class=eng_option)
+        (options, args) = parser.parse_args ()
+        if len(args) != 0:
+            parser.print_help()
+            raise SystemExit, 1
+
+        src = gr.lfsr_32k_source_s()
+        head = gr.head(gr.sizeof_short, 2048)
+        self.dst = gr.vector_sink_s()
+        self.connect(src, head, self.dst)
+
+if __name__ == '__main__':
+    try:
+        fg = my_graph()
+        fg.run()
+        f = sys.stdout
+        i = 0
+        for s in fg.dst.data():
+            f.write("%3d, " % (s & 0xff,))
+            f.write("%3d, " % ((s >> 8) & 0xff,))
+            i = i+2
+            if i % 16 == 0:
+                f.write('\n')
+                    
+    except KeyboardInterrupt:
+        pass
+    
+    
diff --git a/gnuradio-examples/python/gmsk2/gmsk_test.py b/gnuradio-examples/python/gmsk2/gmsk_test.py
new file mode 100755 (executable)
index 0000000..7ae69a0
--- /dev/null
@@ -0,0 +1,115 @@
+#!/usr/bin/env python
+
+from gnuradio import gr, blks
+from gnuradio.eng_option import eng_option
+from optparse import OptionParser
+import random
+import struct
+
+#import os
+#print os.getpid()
+#raw_input('Attach and press enter')
+
+
+class my_graph(gr.flow_graph):
+
+    def __init__(self, rx_callback, spb, bt, SNR, freq_error):
+        gr.flow_graph.__init__(self)
+
+        fg = self
+
+        # Tuning Parameters
+        gain_mu = 0.002*spb
+        omega = spb*(1+freq_error)
+
+        # transmitter
+        self.packet_transmitter = blks.gmsk2_mod_pkts(fg, spb=spb, bt=bt)
+
+        # add some noise
+        add = gr.add_cc()
+        noise = gr.noise_source_c(gr.GR_GAUSSIAN, pow(10.0,-SNR/20.0))
+
+        # channel filter
+        rx_filt_taps = gr.firdes.low_pass(1,spb,0.8,0.1,gr.firdes.WIN_HANN)
+        rx_filt = gr.fir_filter_ccf(1,rx_filt_taps)
+
+        # receiver
+        self.packet_receiver = blks.gmsk2_demod_pkts(fg, callback=rx_callback,
+                                                     spb=spb, gain_mu=gain_mu,
+                                                     freq_error=freq_error, omega=omega)
+
+        fg.connect (self.packet_transmitter, (add,0))
+        fg.connect (noise, (add,1))
+        fg.connect(add, rx_filt, self.packet_receiver)
+
+
+class stats(object):
+    def __init__(self):
+        self.npkts = 0
+        self.nright = 0
+        
+def main():
+    st = stats()
+    
+    def send_pkt(payload='', eof=False):
+        fg.packet_transmitter.send_pkt(payload, eof)
+
+    def rx_callback(ok, payload):
+        st.npkts += 1
+        if ok:
+            st.nright += 1
+        if len(payload) <= 16:
+            print "ok = %5r  payload = '%s'  %d/%d" % (ok, payload, st.nright, st.npkts)
+        else:
+            (pktno,) = struct.unpack('!H', payload[0:2])
+            print "ok = %5r  pktno = %4d  len(payload) = %4d  %d/%d" % (ok, pktno, len(payload),
+                                                                        st.nright, st.npkts)
+
+
+    parser = OptionParser (option_class=eng_option)
+    parser.add_option("-M", "--megabytes", type="eng_float", default=1,
+                      help="set megabytes to transmit [default=%default]")
+    parser.add_option("-s", "--size", type="eng_float", default=1500,
+                      help="set packet size [default=%default]")
+    parser.add_option("","--spb", type=int, default=4,
+                      help="set samples per baud to SPB [default=%default]")
+    parser.add_option("", "--bt", type="eng_float", default=0.3,
+                      help="set bandwidth time product for Gaussian filter [default=%default]")
+    parser.add_option("", "--snr", type="eng_float", default=20,
+                      help="set SNR in dB for simulation [default=%default]")
+    parser.add_option("", "--freq-error", type="eng_float", default=0,
+                      help="set frequency error for simulation [default=%default]")
+    (options, args) = parser.parse_args ()
+
+    if len(args) != 0:
+        parser.print_help()
+        sys.exit(1)
+
+    pkt_size = int(options.size)
+
+    fg = my_graph(rx_callback, options.spb, options.bt, options.snr, options.freq_error)
+    fg.start()
+
+    nbytes = int(1e6 * options.megabytes)
+    n = 0
+    pktno = 0
+
+    send_pkt('Hello World')
+
+    # generate and send packets
+    while n < nbytes:
+        send_pkt(struct.pack('!H', pktno) + (pkt_size - 2) * chr(pktno & 0xff))
+        n += pkt_size
+        pktno += 1
+
+    send_pkt('Goodbye World')
+    send_pkt(eof=True)             # tell modulator we're not sending any more pkts
+
+    fg.wait()
+
+
+if __name__ == '__main__':
+    try:
+        main()
+    except KeyboardInterrupt:
+        pass
diff --git a/gnuradio-examples/python/gmsk2/mpsk_test.py b/gnuradio-examples/python/gmsk2/mpsk_test.py
new file mode 100755 (executable)
index 0000000..1f257d9
--- /dev/null
@@ -0,0 +1,125 @@
+#!/usr/bin/env python
+
+from gnuradio import gr, blks
+from gnuradio.eng_option import eng_option
+from optparse import OptionParser
+import random
+import struct
+from mpsk_pkt import *
+import cmath
+
+class my_graph(gr.flow_graph):
+
+    def __init__(self, rx_callback, spb, excess_bw, SNR, freq_error, arity):
+        gr.flow_graph.__init__(self)
+
+        fg = self
+
+        # Tuning Parameters
+        gain_mu = 0.05/spb
+
+        # transmitter
+        self.packet_transmitter = \
+          mpsk_mod_pkts(fg, spb=spb, excess_bw=excess_bw, diff=True, arity=arity)
+
+        # ----------------------------------------------------------------
+        #                       Channel model
+        # ----------------------------------------------------------------
+
+        awgn = gr.noise_source_c(gr.GR_GAUSSIAN, pow(10.0,-SNR/20.0))
+        add = gr.add_cc()            # add some noise
+        fg.connect(awgn, (add,1))
+        radians = 17*pi/180
+        phase_rotate = gr.multiply_const_cc(cmath.exp(radians * 1j))
+
+        # ----------------------------------------------------------------
+
+        # channel filter
+        rx_filt_taps = gr.firdes.low_pass(1,spb,0.8,0.1,gr.firdes.WIN_HANN)
+        #rx_filt_taps = (1,)
+        rx_filt = gr.fir_filter_ccf(1,rx_filt_taps)
+
+        # receiver
+        self.packet_receiver = \
+            mpsk_demod_pkts(fg, callback=rx_callback,
+                            excess_bw=excess_bw, arity=arity, diff=True,
+                            costas_alpha=.005, gain_mu=gain_mu, spb=spb)
+        
+        fg.connect (self.packet_transmitter, (add,0))
+        fg.connect(add, phase_rotate, rx_filt, self.packet_receiver)
+
+
+class stats(object):
+    def __init__(self):
+        self.npkts = 0
+        self.nright = 0
+        
+def main():
+    st = stats()
+    
+    def send_pkt(payload='', eof=False):
+        fg.packet_transmitter.send_pkt(payload, eof)
+
+    def rx_callback(ok, payload):
+        st.npkts += 1
+        if ok:
+            st.nright += 1
+        if len(payload) <= 16:
+            print "ok = %5r  payload = '%s'  %d/%d" % (ok, payload, st.nright, st.npkts)
+        else:
+            (pktno,) = struct.unpack('!H', payload[0:2])
+            print "ok = %5r  pktno = %4d  len(payload) = %4d  %d/%d" % (ok, pktno, len(payload),
+                                                                        st.nright, st.npkts)
+
+
+    parser = OptionParser (option_class=eng_option)
+    parser.add_option("-M", "--megabytes", type="eng_float", default=1,
+                      help="set megabytes to transmit [default=%default]")
+    parser.add_option("-s", "--size", type="eng_float", default=1500,
+                      help="set packet size [default=%default]")
+    parser.add_option("","--spb", type=int, default=4,
+                      help="set samples per baud to SPB [default=%default]")
+    parser.add_option("", "--excess-bw", type="eng_float", default=0.4,
+                      help="set excess bandwidth for RRC filter [default=%default]")
+    parser.add_option("", "--snr", type="eng_float", default=40,
+                      help="set SNR in dB for simulation [default=%default]")
+    parser.add_option("", "--m-arity", type=int, default=4,
+                      help="PSK arity [default=%default]")
+    parser.add_option("", "--freq-error", type="eng_float", default=0,
+                      help="set frequency error for simulation [default=%default]")
+
+    (options, args) = parser.parse_args ()
+
+    if len(args) != 0:
+        parser.print_help()
+        sys.exit(1)
+
+    pkt_size = int(options.size)
+
+    fg = my_graph(rx_callback, options.spb, options.excess_bw, options.snr,
+                  options.freq_error, options.m_arity)
+    fg.start()
+
+    nbytes = int(1e6 * options.megabytes)
+    n = 0
+    pktno = 0
+
+    send_pkt('Hello World')
+
+    # generate and send packets
+    while n < nbytes:
+        send_pkt(struct.pack('!H', pktno) + (pkt_size - 2) * chr(pktno & 0xff))
+        n += pkt_size
+        pktno += 1
+
+    send_pkt('Goodbye World')
+    send_pkt(eof=True)             # tell modulator we're not sending any more pkts
+
+    fg.wait()
+
+
+if __name__ == '__main__':
+    try:
+        main()
+    except KeyboardInterrupt:
+        pass
diff --git a/gnuradio-examples/python/gmsk2/pick_bitrate.py b/gnuradio-examples/python/gmsk2/pick_bitrate.py
new file mode 100644 (file)
index 0000000..b35991c
--- /dev/null
@@ -0,0 +1,143 @@
+#
+# 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 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.
+# 
+
+_default_bitrate = 500e3
+
+_valid_spbs = (2,3,4,5,6,7)
+
+def _gen_tx_info(converter_rate):
+    results = []
+    for spb in _valid_spbs:
+        for interp in range(16, 512 + 1, 4):
+            bitrate = converter_rate / interp / spb
+            results.append((bitrate, spb, interp))
+    results.sort()
+    return results
+
+def _gen_rx_info(converter_rate):
+    results = []
+    for spb in _valid_spbs:
+        for decim in range(8, 256 + 1, 2):
+            bitrate = converter_rate / decim / spb
+            results.append((bitrate, spb, decim))
+    results.sort()
+    return results
+    
+def _filter_info(info, samples_per_baud, xrate):
+    if samples_per_baud is not None:
+        info = [x for x in info if x[1] == samples_per_baud]
+    if xrate is not None:
+        info = [x for x in info if x[2] == xrate]
+    return info
+
+def _pick_best(target_bitrate, bits_per_symbol, info):
+    """
+    @returns tuple (bitrate, samples_per_baud, interp_rate_or_decim_rate)
+    """
+    if len(info) == 0:
+        raise RuntimeError, "info is zero length!"
+
+    if target_bitrate is None:     # return the fastest one
+        return info[-1]
+    
+    # convert bit rate to symbol rate
+    target_symbolrate = target_bitrate / bits_per_symbol
+    
+    # Find the closest matching symbol rate.
+    # In the event of a tie, the one with the lowest samples_per_baud wins.
+    # (We already sorted them, so the first one is the one we take)
+
+    best = info[0]
+    best_delta = abs(target_symbolrate - best[0])
+    for x in info[1:]:
+        delta = abs(target_symbolrate - x[0])
+        if delta < best_delta:
+            best_delta = delta
+            best = x
+
+    # convert symbol rate back to bit rate
+    return ((best[0] * bits_per_symbol),) + best[1:]
+
+def _pick_bitrate(bitrate, bits_per_symbol, samples_per_baud,
+                  xrate, converter_rate, gen_info):
+    """
+    @returns tuple (bitrate, samples_per_baud, interp_rate_or_decim_rate)
+    """
+    if not isinstance(bits_per_symbol, int) or bits_per_symbol < 1:
+        raise ValueError, "bits_per_symbol must be an int >= 1"
+    
+    if samples_per_baud is not None and xrate is not None:  # completely determined
+        return (float(converter_rate) / xrate / samples_per_baud,
+                samples_per_baud, xrate)
+
+    if bitrate is None and samples_per_baud is None and xrate is None:
+        bitrate = _default_bitrate
+
+    # now we have a target bitrate and possibly an xrate or
+    # samples_per_baud constraint, but not both of them.
+
+    return _pick_best(bitrate, bits_per_symbol,
+                      _filter_info(gen_info(converter_rate), samples_per_baud, xrate))
+    
+# ---------------------------------------------------------------------------------------
+
+def pick_tx_bitrate(bitrate, bits_per_symbol, samples_per_baud,
+                    interp_rate, converter_rate=128e6):
+    """
+    Given the 4 input parameters, return at configuration that matches
+
+    @param bitrate: desired bitrate or None
+    @type bitrate: number or None
+    @param bits_per_symbol: E.g., BPSK -> 1, QPSK -> 2, 8-PSK -> 3
+    @type bits_per_symbol: integer >= 1
+    @param samples_per_baud: samples/baud (aka samples/symbol)
+    @type samples_per_baud: number or None
+    @param interp_rate: USRP interpolation factor
+    @type interp_rate: integer or None
+    @param converter_rate: converter sample rate in Hz
+    @type converter_rate: number
+
+    @returns tuple (bitrate, samples_per_baud, interp_rate)
+    """
+    return _pick_bitrate(bitrate, bits_per_symbol, samples_per_baud,
+                         interp_rate, converter_rate, _gen_tx_info)
+
+
+def pick_rx_bitrate(bitrate, bits_per_symbol, samples_per_baud,
+                    decim_rate, converter_rate=64e6):
+    """
+    Given the 4 input parameters, return at configuration that matches
+
+    @param bitrate: desired bitrate or None
+    @type bitrate: number or None
+    @param bits_per_symbol: E.g., BPSK -> 1, QPSK -> 2, 8-PSK -> 3
+    @type bits_per_symbol: integer >= 1
+    @param samples_per_baud: samples/baud (aka samples/symbol)
+    @type samples_per_baud: number or None
+    @param decim_rate: USRP decimation factor
+    @type decim_rate: integer or None
+    @param converter_rate: converter sample rate in Hz
+    @type converter_rate: number
+
+    @returns tuple (bitrate, samples_per_baud, decim_rate)
+    """
+    return _pick_bitrate(bitrate, bits_per_symbol, samples_per_baud,
+                         decim_rate, converter_rate, _gen_rx_info)
diff --git a/gnuradio-examples/python/gmsk2/qpsk.py b/gnuradio-examples/python/gmsk2/qpsk.py
new file mode 100644 (file)
index 0000000..6ca7f0e
--- /dev/null
@@ -0,0 +1,418 @@
+#
+# 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 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.
+# 
+
+# See gnuradio-examples/python/gmsk2 for examples
+
+"""
+PSK and differential PSK modulation and demodulation.
+"""
+
+from gnuradio import gr, gru
+from math import pi, sqrt
+import cmath
+import Numeric
+from pprint import pprint
+
+_use_gray_code = True
+
+def make_constellation(m):
+    return [cmath.exp(i * 2 * pi / m * 1j) for i in range(m)]
+        
+# Common definition of constellations for Tx and Rx
+constellation = {
+    2 : make_constellation(2),           # BPSK
+    4 : make_constellation(4),           # QPSK
+    8 : make_constellation(8)            # 8PSK
+    }
+
+if 0:
+    print "const(2) ="
+    pprint(constellation[2])
+    print "const(4) ="
+    pprint(constellation[4])
+    print "const(8) ="
+    pprint(constellation[8])
+
+
+if _use_gray_code:
+    # -----------------------
+    # Do Gray code
+    # -----------------------
+    # binary to gray coding
+    binary_to_gray = {
+        2 : (0, 1),
+        4 : (0, 1, 3, 2),
+        8 : (0, 1, 3, 2, 7, 6, 4, 5)
+        }
+    
+    # gray to binary
+    gray_to_binary = {
+        2 : (0, 1),
+        4 : (0, 1, 3, 2),
+        8 : (0, 1, 3, 2, 6, 7, 5, 4)
+        }
+else:
+    # -----------------------
+    # Don't Gray code
+    # -----------------------
+    # identity mapping
+    binary_to_gray = {
+        2 : (0, 1),
+        4 : (0, 1, 2, 3),
+        8 : (0, 1, 2, 3, 4, 5, 6, 7)
+        }
+    
+    # identity mapping
+    gray_to_binary = {
+        2 : (0, 1),
+        4 : (0, 1, 2, 3),
+        8 : (0, 1, 2, 3, 4, 5, 6, 7)
+        }
+
+
+# /////////////////////////////////////////////////////////////////////////////
+#            mPSK mod/demod with steams of bytes as data i/o
+# /////////////////////////////////////////////////////////////////////////////
+
+
+class mpsk_mod(gr.hier_block):
+
+    def __init__(self, fg, spb, arity, excess_bw, diff=False):
+        """
+       Hierarchical block for RRC-filtered PSK modulation.
+
+       The input is a byte stream (unsigned char) and the
+       output is the complex modulated signal at baseband.
+
+       @param fg: flow graph
+       @type fg: flow graph
+       @param spb: samples per baud >= 2
+       @type spb: integer
+       @param excess_bw: Root-raised cosine filter excess bandwidth
+       @type excess_bw: float
+        @param arity: whick PSK: 2, 4, 8
+        @type arity: int in {2, 4, 8}
+        @param diff: differential PSK if true
+        @type diff: bool
+       """
+        if not isinstance(spb, int) or spb < 2:
+            raise TypeError, "sbp must be an integer >= 2"
+        self.spb = spb
+
+        if not arity in (2, 4):
+            raise ValueError, "n must be 2, 4, or 8"
+
+       ntaps = 11 * spb
+
+        bits_per_symbol = int(gru.log2(arity))
+        self.bits_per_symbol = bits_per_symbol
+        print "bits_per_symbol =", bits_per_symbol
+        
+        # turn bytes into k-bit vectors
+        self.bytes2chunks = \
+          gr.packed_to_unpacked_bb(bits_per_symbol, gr.GR_MSB_FIRST)
+
+        if True or arity > 2:
+            self.gray_coder = gr.map_bb(binary_to_gray[arity])
+        else:
+            self.gray_coder = None
+
+        if diff:
+            self.diffenc = gr.diff_encoder_bb(arity)
+        else:
+            self.diffenc = None
+
+        self.chunks2symbols = gr.chunks_to_symbols_bc(constellation[arity])
+
+        # pulse shaping filter
+       self.rrc_taps = gr.firdes.root_raised_cosine(
+               spb,            # gain  (spb since we're interpolating by spb)
+               spb,            # sampling rate
+               1.0,            # symbol rate
+               excess_bw,      # excess bandwidth (roll-off factor)
+                ntaps)
+
+       self.rrc_filter = gr.interp_fir_filter_ccf(spb, self.rrc_taps)
+
+       # Connect
+        if self.gray_coder:
+            fg.connect(self.bytes2chunks, self.gray_coder)
+            t = self.gray_coder
+        else:
+            t = self.bytes2chunks
+
+        if diff:
+            fg.connect(t, self.diffenc, self.chunks2symbols, self.rrc_filter)
+        else:
+            fg.connect(t, self.chunks2symbols, self.rrc_filter)
+
+        if 1:
+            fg.connect(self.gray_coder,
+                       gr.file_sink(gr.sizeof_char, "graycoder.dat"))
+            if diff:
+                fg.connect(self.diffenc,
+                           gr.file_sink(gr.sizeof_char, "diffenc.dat"))
+            
+       # Initialize base class
+       gr.hier_block.__init__(self, fg, self.bytes2chunks, self.rrc_filter)
+
+    def samples_per_baud(self):
+        return self.spb
+
+    def bits_per_baud(self):
+        return self.bits_per_symbol
+
+
+class mpsk_demod__coherent_detection_of_differentially_encoded_psk(gr.hier_block):
+    def __init__(self, fg, spb, arity, excess_bw, diff=False, costas_alpha=0.005, gain_mu=0.05):
+        """
+       Hierarchical block for RRC-filtered PSK demodulation
+
+       The input is the complex modulated signal at baseband.
+       The output is a stream of bits packed 1 bit per byte (LSB)
+
+       @param fg: flow graph
+       @type fg: flow graph
+       @param spb: samples per baud >= 2
+       @type spb: float
+       @param excess_bw: Root-raised cosine filter excess bandwidth
+       @type excess_bw: float
+        @param arity: whick PSK: 2, 4, 8
+        @type arity: int in {2, 4, 8}
+        @param diff: differential PSK if true
+        @type diff: bool
+        @param costas_alpha: loop filter gain
+        @type costas_alphas: float
+        @param gain_mu:
+        @type gain_mu: float
+       """
+        if spb < 2:
+            raise TypeError, "sbp must be >= 2"
+        self.spb = spb
+
+        if not arity in (2, 4):
+            raise ValueError, "n must be 2 or 4"
+
+        if not diff and arity==4:
+            raise NotImplementedError, "non-differential QPSK not supported yet"
+
+        bits_per_symbol = int(gru.log2(arity))
+        print "bits_per_symbol =", bits_per_symbol
+
+        # Automatic gain control
+        self.agc = gr.agc_cc(1e-3, 1, 1)
+        
+        # Costas loop (carrier tracking)
+        # FIXME: need to decide how to handle this more generally; do we pull it from higher layer?
+        if arity == 2:
+            costas_order = 2
+            costas_alpha *= 15   # 2nd order loop needs more gain
+        else:
+            costas_order = 4
+        beta = .25 * costas_alpha * costas_alpha
+        self.costas_loop = gr.costas_loop_cc(costas_alpha, beta, 0.05, -0.05, costas_order)
+
+        # RRC data filter
+        ntaps = 11 * spb
+        self.rrc_taps = gr.firdes.root_raised_cosine(
+            1.0,                # gain 
+            spb,                # sampling rate
+            1.0,                # symbol rate
+            excess_bw,          # excess bandwidth (roll-off factor)
+            ntaps)
+
+        self.rrc_filter=gr.fir_filter_ccf(1, self.rrc_taps)
+
+        # symbol clock recovery
+        omega = spb
+        gain_omega = .25 * gain_mu * gain_mu
+        omega_rel_limit = 0.5
+        mu = 0.05
+        gain_mu = 0.1
+        self.clock_recovery=gr.clock_recovery_mm_cc(omega, gain_omega,
+                                                    mu, gain_mu, omega_rel_limit)
+
+        # find closest constellation point
+        #rot = .707 + .707j
+        rot = 1
+        rotated_const = map(lambda pt: pt * rot, constellation[arity])
+        print "rotated_const =", rotated_const
+
+        if(diff):
+            self.diffdec = gr.diff_phasor_cc()
+            #self.diffdec = gr.diff_decoder_bb(arity)
+
+        self.slicer = gr.constellation_decoder_cb(rotated_const, range(arity))
+        self.gray_decoder = gr.map_bb(gray_to_binary[arity])
+        
+        # unpack the k bit vector into a stream of bits
+        self.unpack = gr.unpack_k_bits_bb(bits_per_symbol)
+
+        if(diff):
+            fg.connect(self.agc, self.costas_loop, self.rrc_filter, self.clock_recovery,
+                       self.diffdec, self.slicer, self.gray_decoder, self.unpack)
+        else:
+            fg.connect(self.agc, self.costas_loop, self.rrc_filter, self.clock_recovery,
+                       self.slicer, self.gray_decoder, self.unpack)
+
+        #fg.connect(self.agc, self.costas_loop, self.rrc_filter, self.clock_recovery,
+        #           self.slicer, self.diffdec, self.gray_decoder, self.unpack)
+        
+        # Debug sinks
+        if 1:
+            fg.connect(self.agc,
+                       gr.file_sink(gr.sizeof_gr_complex, "agc.dat"))
+            fg.connect(self.costas_loop,
+                       gr.file_sink(gr.sizeof_gr_complex, "costas_loop.dat"))
+            fg.connect(self.rrc_filter,
+                       gr.file_sink(gr.sizeof_gr_complex, "rrc.dat"))
+            fg.connect(self.clock_recovery,
+                       gr.file_sink(gr.sizeof_gr_complex, "clock_recovery.dat"))
+            fg.connect(self.slicer,
+                       gr.file_sink(gr.sizeof_char, "slicer.dat"))
+            if(diff):
+                fg.connect(self.diffdec,
+                           gr.file_sink(gr.sizeof_gr_complex, "diffdec.dat"))
+                #fg.connect(self.diffdec,
+                #          gr.file_sink(gr.sizeof_char, "diffdec.dat"))
+            fg.connect(self.unpack,
+                       gr.file_sink(gr.sizeof_char, "unpack.dat"))
+
+        # Initialize base class
+        gr.hier_block.__init__(self, fg, self.agc, self.unpack)
+
+    def samples_per_baud(self):
+        return self.spb
+
+    def bits_per_baud(self):
+        return self.bits_per_symbol
+
+
+#########################################################################
+
+class mpsk_demod__coherent_detection_of_nondifferentially_encoded_psk(gr.hier_block):
+    def __init__(self, fg, spb, arity, excess_bw, diff=False, costas_alpha=0.005, gain_mu=0.05):
+        """
+       Hierarchical block for RRC-filtered PSK demodulation
+
+       The input is the complex modulated signal at baseband.
+       The output is a stream of bits packed 1 bit per byte (LSB)
+
+       @param fg: flow graph
+       @type fg: flow graph
+       @param spb: samples per baud >= 2
+       @type spb: float
+       @param excess_bw: Root-raised cosine filter excess bandwidth
+       @type excess_bw: float
+        @param arity: whick PSK: 2, 4, 8
+        @type arity: int in {2, 4, 8}
+        @param diff: differential PSK if true
+        @type diff: bool
+        @param costas_alpha: loop filter gain
+        @type costas_alphas: float
+        @param gain_mu:
+        @type gain_mu: float
+       """
+        if spb < 2:
+            raise TypeError, "sbp must be >= 2"
+        self.spb = spb
+
+        if not arity in (2, 4):
+            raise ValueError, "n must be 2 or 4"
+
+        bits_per_symbol = int(gru.log2(arity))
+        print "bits_per_symbol =", bits_per_symbol
+
+        # Automatic gain control
+        self.agc = gr.agc_cc(1e-3, 1, 1)
+        
+        # Costas loop (carrier tracking)
+        # FIXME: need to decide how to handle this more generally; do we pull it from higher layer?
+        if arity == 2:
+            costas_order = 2
+            costas_alpha *= 15   # 2nd order loop needs more gain
+        else:
+            costas_order = 4
+        beta = .25 * costas_alpha * costas_alpha
+        self.costas_loop = gr.costas_loop_cc(costas_alpha, beta, 0.05, -0.05, costas_order)
+
+        # RRC data filter
+        ntaps = 11 * spb
+        self.rrc_taps = gr.firdes.root_raised_cosine(
+            1.0,                # gain 
+            spb,                # sampling rate
+            1.0,                # symbol rate
+            excess_bw,          # excess bandwidth (roll-off factor)
+            ntaps)
+
+        self.rrc_filter=gr.fir_filter_ccf(1, self.rrc_taps)
+
+        # symbol clock recovery
+        omega = spb
+        gain_omega = .25 * gain_mu * gain_mu
+        omega_rel_limit = 0.5
+        mu = 0.05
+        gain_mu = 0.1
+        self.clock_recovery=gr.clock_recovery_mm_cc(omega, gain_omega,
+                                                    mu, gain_mu, omega_rel_limit)
+
+        # find closest constellation point
+        #rot = .707 + .707j
+        rot = 1
+        rotated_const = map(lambda pt: pt * rot, constellation[arity])
+        print "rotated_const =", rotated_const
+
+        self.slicer = gr.constellation_decoder_cb(rotated_const, range(arity))
+        self.gray_decoder = gr.map_bb(gray_to_binary[arity])
+        
+        # unpack the k bit vector into a stream of bits
+        self.unpack = gr.unpack_k_bits_bb(bits_per_symbol)
+
+        fg.connect(self.agc, self.costas_loop, self.rrc_filter, self.clock_recovery,
+                   self.slicer, self.gray_decoder, self.unpack)
+        
+        # Debug sinks
+        if 1:
+            fg.connect(self.agc,
+                       gr.file_sink(gr.sizeof_gr_complex, "agc.dat"))
+            fg.connect(self.costas_loop,
+                       gr.file_sink(gr.sizeof_gr_complex, "costas_loop.dat"))
+            fg.connect(self.rrc_filter,
+                       gr.file_sink(gr.sizeof_gr_complex, "rrc.dat"))
+            fg.connect(self.clock_recovery,
+                       gr.file_sink(gr.sizeof_gr_complex, "clock_recovery.dat"))
+            fg.connect(self.slicer,
+                       gr.file_sink(gr.sizeof_char, "slicer.dat"))
+            fg.connect(self.unpack,
+                       gr.file_sink(gr.sizeof_char, "unpack.dat"))
+
+        # Initialize base class
+        gr.hier_block.__init__(self, fg, self.agc, self.unpack)
+
+    def samples_per_baud(self):
+        return self.spb
+
+    def bits_per_baud(self):
+        return self.bits_per_symbol
+
+
+mpsk_demod = mpsk_demod__coherent_detection_of_differentially_encoded_psk
+#mpsk_demod = mpsk_demod__coherent_detection_of_nondifferentially_encoded_psk
diff --git a/gnuradio-examples/python/gmsk2/qpsk_tester.py b/gnuradio-examples/python/gmsk2/qpsk_tester.py
new file mode 100644 (file)
index 0000000..ea7bae2
--- /dev/null
@@ -0,0 +1,127 @@
+#!/usr/bin/env python
+
+import random
+from gnuradio import gr
+
+default_access_code = '\xAC\xDD\xA4\xE2\xF2\x8C\x20\xFC'
+
+def string_to_1_0_list(s):
+    r = []
+    for ch in s:
+        x = ord(ch)
+        for i in range(8):
+            t = (x >> i) & 0x1
+            r.append(t)
+
+    return r
+
+def to_1_0_string(L):
+    return ''.join(map(lambda x: chr(x + ord('0')), L))
+
+code = string_to_1_0_list(default_access_code)
+access_code = to_1_0_string(code)
+
+use_agc        = 0
+use_rrc_tx     = 1
+use_rrc_rx     = 1
+use_sync_loop  = 1
+use_clock_sync = 1
+
+def main():
+    fg = gr.flow_graph()
+
+#    data = (1,2,3,4,5,6,7,8,9)
+    random.seed()
+    data = [random.randint(1,100) for i in range(20000)]
+    data[0] = 0 # you know, for the diff encoding stuff
+    bytes_src = gr.vector_source_b(data,False)
+
+    k = 2
+    spb = 50
+    ntaps = 11*spb
+    excess_bw = 0.9
+    threshold = 12
+    constellation  = (1+0j, 0+1j, -1+0j, 0-1j)
+    
+    bytes2chunks   = gr.packed_to_unpacked_bb(k, gr.GR_MSB_FIRST)
+    diffenc        = gr.diff_encoder_bb(4)
+    chunks2symbols = gr.chunks_to_symbols_bc(constellation)
+
+    if use_rrc_tx:
+        rrc_taps_tx = gr.firdes.root_raised_cosine(spb, spb, 1.0, \
+                                                   excess_bw, ntaps)
+        rrc_tx = gr.interp_fir_filter_ccf(spb, rrc_taps_tx)
+    else:
+        rrc_tx = gr.interp_fir_filter_ccf(1, (1,))
+
+################### CHANNEL MODEL #############################
+
+    phase_rotate = gr.multiply_const_cc(1-0.36j)
+    channel      = gr.add_cc()
+    awgn         = gr.noise_source_c(gr.GR_GAUSSIAN, 0.5)
+    fg.connect(awgn, (channel,1))
+    
+################### CHANNEL MODEL #############################
+
+    if use_agc:
+        agc = gr.agc_cc(1e-4, 1, 1)
+    else:
+        agc = gr.multiply_const_cc(1)
+
+    # Downconverter
+    if use_sync_loop:
+        costas_alpha=0.005
+        beta = costas_alpha*costas_alpha*0.25
+        sync_loop = gr.costas_loop_cc(costas_alpha, beta, 0.05, -0.05, 0)
+    else:
+        sync_loop = gr.multiply_const_cc(1)
+
+    if use_rrc_rx:
+        rrc_taps_rx = gr.firdes.root_raised_cosine(1, spb, 1.0, \
+                                                   excess_bw, ntaps)
+        rrc_rx = gr.fir_filter_ccf(1, rrc_taps_rx)
+    else:
+        rrc_rx = gr.fir_filter_ccf(1, (1,))
+   
+    # Sampler
+    if use_clock_sync:
+        mu = 0.05
+        omega = spb
+        gain_mu = 0.05
+        gain_omega = 0.25*gain_mu*gain_mu
+        omega_rel_limit = 0.5
+        clock_sync = gr.clock_recovery_mm_cc(omega, gain_omega, mu, \
+                                             gain_mu, omega_rel_limit)
+        #clock_sync.set_verbose(True);
+    else:
+        clock_sync = gr.fir_filter_ccf(1, (1,))
+
+    diff_phasor = gr.diff_phasor_cc()
+    slicer = gr.constellation_decoder_cb((constellation), (0,1,2,3))
+    unpack = gr.unpack_k_bits_bb(k)
+    access = gr.correlate_access_code_bb(access_code,threshold)
+
+    sink = gr.file_sink(gr.sizeof_char, 'output.dat')
+
+    fg.connect(bytes_src, bytes2chunks, diffenc, chunks2symbols, rrc_tx)
+    fg.connect(rrc_tx, phase_rotate, channel, agc)
+    fg.connect(agc, sync_loop, rrc_rx, clock_sync, diff_phasor, slicer, sink)
+    test = gr.file_sink(gr.sizeof_gr_complex, 'test.dat')
+    fg.connect(rrc_rx, test)
+
+    fg.connect(chunks2symbols, gr.file_sink(gr.sizeof_gr_complex, 'rrc_tx.dat'))  # into TX RRC
+    fg.connect(channel, gr.file_sink(gr.sizeof_gr_complex, 'channel.dat'))        # Out of TX RRC
+    fg.connect(rrc_rx, gr.file_sink(gr.sizeof_gr_complex, 'rrc_rx.dat'))          # Out of RX RRC -> clock_sync
+    fg.connect(clock_sync, gr.file_sink(gr.sizeof_gr_complex, 'clock_sync.dat'))  # Out of M&M sync loop
+    fg.connect(bytes2chunks, gr.file_sink(gr.sizeof_char, 'source.dat'))
+
+    fg.start()
+    fg.wait()
+
+if __name__ == "__main__":
+    main()
+        
+    
+
diff --git a/gnuradio-examples/python/gmsk2/qpsk_usrp_tester.py b/gnuradio-examples/python/gmsk2/qpsk_usrp_tester.py
new file mode 100644 (file)
index 0000000..bf7698a
--- /dev/null
@@ -0,0 +1,103 @@
+#!/usr/bin/env python
+
+import random
+from gnuradio import gr, gru, usrp
+
+default_access_code = '\xAC\xDD\xA4\xE2\xF2\x8C\x20\xFC'
+
+def string_to_1_0_list(s):
+    r = []
+    for ch in s:
+        x = ord(ch)
+        for i in range(8):
+            t = (x >> i) & 0x1
+            r.append(t)
+
+    return r
+
+def to_1_0_string(L):
+    return ''.join(map(lambda x: chr(x + ord('0')), L))
+
+code = string_to_1_0_list(default_access_code)
+
+access_code = to_1_0_string(code)
+
+def main():
+
+    fg = gr.flow_graph()
+    f_rf = 5e6
+    fs = 400e3
+    sr = 100e3
+    alpha = 0.5
+    M = 4
+    k = int(gru.log2(M))
+    
+    # Source
+    src = usrp.source_c ()
+    adc_rate = src.adc_rate()
+    usrp_decim = int(adc_rate / fs)
+    src.set_decim_rate(usrp_decim)
+        
+    subdev_spec = usrp.pick_rx_subdevice(src)
+    subdev = usrp.selected_subdev(src, subdev_spec)
+    print "Using RX d'board %s" % (subdev.side_and_name(),)
+    src.set_mux(usrp.determine_rx_mux_value(src, subdev_spec))
+    src.tune(0, subdev, f_rf)
+        
+    g = subdev.gain_range()
+    subdev.set_gain(g[1])
+    subdev.set_auto_tr(True)
+        
+    print "USRP Decimation Rate = %d" % usrp_decim
+    print "RF Frequency = %d" % f_rf
+
+    agc = gr.multiply_const_cc(0.0025)
+        
+    # Downconverter
+    costas_alpha=0.005
+    beta = costas_alpha*costas_alpha*0.25
+    sync_loop = gr.costas_loop_cc(costas_alpha, beta, 0.05, -0.05, 0)
+
+    # Stage 2
+#    fs2 = 200e3
+#    D = int(fs / fs2)
+#    decimator = gr.keep_one_in_n(gr.sizeof_gr_complex, D)
+#    print "D = %d\nAfter decimator fs = %f" % (D, fs2)
+
+    # Demodulator
+    taps = gr.firdes.root_raised_cosine(1, fs, sr, alpha, 45)
+    rrc  = gr.fir_filter_ccf(1, taps)
+    
+    # Sampler
+    mu = 0.01
+    omega = 4.3
+    gain_mu = 0.05
+    gain_omega = 0.25*gain_mu*gain_mu
+    omega_rel_limit = 0.5
+    clock_sync = gr.clock_recovery_mm_cc(omega, gain_omega, mu,
+                                         gain_mu, omega_rel_limit)
+    clock_sync.set_verbose(False)
+
+    diff_phasor = gr.diff_phasor_cc()
+
+    threshold = 12
+    constellation = (1+0j, 0+1j, -1+0j, 0-1j)
+    slicer = gr.constellation_decoder_cb((constellation), (0,1,2,3))
+    unpack = gr.unpack_k_bits_bb(k)
+    access = gr.correlate_access_code_bb(access_code,threshold)
+
+    test = gr.file_sink(gr.sizeof_gr_complex, 'test.dat')
+    sink = gr.file_sink(gr.sizeof_char, 'output.dat')
+
+    fg.connect(src, agc, sync_loop, rrc, clock_sync)
+    fg.connect(clock_sync, diff_phasor, slicer, unpack, access, sink)
+
+    fg.connect(slicer, gr.file_sink(gr.sizeof_char, 'chunks.dat'))
+    fg.connect(unpack, gr.file_sink(gr.sizeof_char, 'unpack.dat'))
+    fg.connect(clock_sync, gr.file_sink(gr.sizeof_gr_complex, 'phasor.dat'))
+
+    fg.start()
+    fg.wait()
+
+if __name__ == "__main__":
+    main()
diff --git a/gnuradio-examples/python/gmsk2/receive_path.py b/gnuradio-examples/python/gmsk2/receive_path.py
new file mode 100644 (file)
index 0000000..505ff7c
--- /dev/null
@@ -0,0 +1,150 @@
+#!/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 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.
+# 
+
+from gnuradio import gr, gru, blks
+from gnuradio import usrp
+
+# from current dir
+from pick_bitrate import pick_rx_bitrate
+
+# /////////////////////////////////////////////////////////////////////////////
+#                              receive path
+# /////////////////////////////////////////////////////////////////////////////
+
+class receive_path(gr.hier_block):
+    def __init__(self, fg, demod_class, rx_subdev_spec,
+                 bitrate, decim, spb,
+                 rx_callback, options, demod_kwargs):
+
+        self.u = usrp.source_c (fusb_block_size=options.fusb_block_size,
+                                fusb_nblocks=options.fusb_nblocks)
+        adc_rate = self.u.adc_rate()
+
+        (self._bitrate, self._spb, self._decim) = \
+            pick_rx_bitrate(bitrate, demod_class.bits_per_baud(), spb, decim, adc_rate)
+
+        self.u.set_decim_rate(self._decim)
+        sw_decim = 1
+
+        if rx_subdev_spec is None:
+            rx_subdev_spec = usrp.pick_rx_subdevice(self.u)
+        self.subdev = usrp.selected_subdev(self.u, rx_subdev_spec)
+        print "Using RX d'board %s" % (self.subdev.side_and_name(),)
+
+        self.u.set_mux(usrp.determine_rx_mux_value(self.u, rx_subdev_spec))
+
+        # Create filter to get actual channel we want
+        chan_coeffs = gr.firdes.low_pass (1.0,                  # gain
+                                          sw_decim * self._spb, # sampling rate
+                                          1.0,                  # midpoint of trans. band
+                                          0.1,                  # width of trans. band
+                                          gr.firdes.WIN_HANN)   # filter type 
+
+        print "len(rx_chan_coeffs) =", len(chan_coeffs)
+
+        # Decimating Channel filter
+        # complex in and out, float taps
+        self.chan_filt = gr.fft_filter_ccc(sw_decim, chan_coeffs)
+        #self.chan_filt = gr.fir_filter_ccf(sw_decim, chan_coeffs)
+
+        # receiver
+        self.packet_receiver = \
+            blks.demod_pkts(fg,
+                            demod_class(fg, spb=self._spb, **demod_kwargs),
+                            access_code=None,
+                            callback=rx_callback,
+                            threshold=-1)
+
+        fg.connect(self.u, self.chan_filt, self.packet_receiver)
+        gr.hier_block.__init__(self, fg, None, None)
+
+        g = self.subdev.gain_range()
+        #self.set_gain((g[0] + g[1])/2)        # set gain to midpoint
+        self.set_gain(g[1])                    # set gain to max
+        self.set_auto_tr(True)                 # enable Auto Transmit/Receive switching
+
+        # Carrier Sensing Blocks
+        alpha = 0.001
+        thresh = 30   # in dB, will have to adjust
+        self.probe = gr.probe_avg_mag_sqrd_c(thresh,alpha)
+        fg.connect(self.chan_filt, self.probe)
+
+    def set_freq(self, target_freq):
+        """
+        Set the center frequency we're interested in.
+
+        @param target_freq: frequency in Hz
+        @rypte: bool
+
+        Tuning is a two step process.  First we ask the front-end to
+        tune as close to the desired frequency as it can.  Then we use
+        the result of that operation and our target_frequency to
+        determine the value for the digital up converter.
+        """
+        r = self.u.tune(0, self.subdev, target_freq)
+        if r:
+            return True
+
+        return False
+
+    def set_gain(self, gain):
+        if gain is None:
+            r = self.subdev.gain_range()
+            gain = (r[0] + r[1])/2               # set gain to midpoint
+        self.gain = gain
+        return self.subdev.set_gain(gain)
+
+    def set_auto_tr(self, enable):
+        return self.subdev.set_auto_tr(enable)
+        
+    def bitrate(self):
+        return self._bitrate
+
+    def spb(self):
+        return self._spb
+
+    def decim(self):
+        return self._decim
+
+
+    def carrier_sensed(self):
+        """
+        Return True if we think carrier is present.
+        """
+        #return self.probe.level() > X
+        return self.probe.unmuted()
+
+    def carrier_threshold(self):
+        """
+        Return current setting in dB.
+        """
+        return self.probe.threshold()
+
+    def set_carrier_threshold(self, threshold_in_db):
+        """
+        Set carrier threshold.
+
+        @param threshold_in_db: set detection threshold
+        @type threshold_in_db:  float (dB)
+        """
+        self.probe.set_threshold(threshold_in_db)
+    
diff --git a/gnuradio-examples/python/gmsk2/rx_voice.py b/gnuradio-examples/python/gmsk2/rx_voice.py
new file mode 100755 (executable)
index 0000000..3f5cc3b
--- /dev/null
@@ -0,0 +1,132 @@
+#!/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 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.
+# 
+
+from gnuradio import gr, gru, blks
+from gnuradio import usrp
+from gnuradio import audio
+from gnuradio import eng_notation
+from gnuradio.eng_option import eng_option
+from optparse import OptionParser
+
+from gnuradio.vocoder import gsm_full_rate
+
+import random
+import struct
+
+# from current dir
+from receive_path import receive_path
+
+#import os
+#print os.getpid()
+#raw_input('Attach and press enter')
+
+
+class audio_tx(gr.hier_block):
+    def __init__(self, fg):
+        self.packet_src = gr.message_source(33)
+        voice_decoder = gsm_full_rate.decode_ps()
+        s2f = gr.short_to_float ()
+        sink_scale = gr.multiply_const_ff(1.0/32767.)
+        audio_sink = audio.sink(8000)
+        fg.connect(self.packet_src, voice_decoder, s2f, sink_scale, audio_sink)
+        gr.hier_block.__init__(self, fg, self.packet_src, audio_sink)
+        
+    def msgq(self):
+        return self.packet_src.msgq()
+
+
+class my_graph(gr.flow_graph):
+
+    def __init__(self, rx_subdev_spec, bitrate, decim_rate, spb, rx_callback, log):
+        gr.flow_graph.__init__(self)
+        self.rxpath = receive_path(self, rx_subdev_spec, bitrate, decim_rate,
+                                   spb, rx_callback, log)
+
+        self.audio_tx = audio_tx(self)
+        
+
+# /////////////////////////////////////////////////////////////////////////////
+#                                   main
+# /////////////////////////////////////////////////////////////////////////////
+
+global n_rcvd, n_right
+
+def main():
+    global n_rcvd, n_right
+
+    n_rcvd = 0
+    n_right = 0
+    
+    def rx_callback(ok, payload):
+        global n_rcvd, n_right
+        n_rcvd += 1
+        if ok:
+            n_right += 1
+
+        fg.audio_tx.msgq().insert_tail(gr.message_from_string(payload))
+        
+        print "ok = %r  n_rcvd = %4d  n_right = %4d" % (
+            ok, n_rcvd, n_right)
+
+    parser = OptionParser (option_class=eng_option)
+    parser.add_option("-R", "--rx-subdev-spec", type="subdev", default=None,
+                      help="select USRP Rx side A or B")
+    parser.add_option("-f", "--freq", type="eng_float", default=423.1e6,
+                       help="set Rx frequency to FREQ [default=%default]", metavar="FREQ")
+    parser.add_option("-r", "--bitrate", type="eng_float", default=100e3,
+                      help="specify bitrate.  spb and interp will be derived.")
+    parser.add_option("-S", "--spb", type="int", default=None, help="set samples/baud [default=%default]")
+    parser.add_option("-d", "--decim", type="intx", default=None,
+                      help="set fpga decim rate to DECIM [default=%default]")
+    parser.add_option("-g", "--gain", type="eng_float", default=27,
+                      help="set rx gain")
+    parser.add_option("","--log", action="store_true", default=False,
+                      help="enable diagnostic logging")
+    (options, args) = parser.parse_args ()
+
+    if len(args) != 0:
+        parser.print_help()
+        sys.exit(1)
+
+    if options.freq < 1e6:
+        options.freq *= 1e6
+
+    # build the graph
+    fg = my_graph(options.rx_subdev_spec, options.bitrate,
+                  options.decim, options.spb, rx_callback, options.log)
+
+    print "bitrate: %sb/sec" % (eng_notation.num_to_str(fg.rxpath.bitrate()),)
+    print "spb:     %3d" % (fg.rxpath.spb(),)
+    print "decim:   %3d" % (fg.rxpath.decim(),)
+
+    fg.rxpath.set_freq(options.freq)
+    fg.rxpath.set_gain(options.gain)
+    print "Rx gain_range: ", fg.rxpath.subdev.gain_range(), " using", fg.rxpath.gain
+
+    fg.start()        # start flow graph
+    fg.wait()         # wait for it to finish
+
+if __name__ == '__main__':
+    try:
+        main()
+    except KeyboardInterrupt:
+        pass
diff --git a/gnuradio-examples/python/gmsk2/transmit_path.py b/gnuradio-examples/python/gmsk2/transmit_path.py
new file mode 100644 (file)
index 0000000..a1df157
--- /dev/null
@@ -0,0 +1,108 @@
+#
+# 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 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.
+# 
+
+from gnuradio import gr, gru, blks
+from gnuradio import usrp
+
+# from current dir
+from pick_bitrate import pick_tx_bitrate
+
+# /////////////////////////////////////////////////////////////////////////////
+#                              transmit path
+# /////////////////////////////////////////////////////////////////////////////
+
+class transmit_path(gr.hier_block): 
+    def __init__(self, fg, mod_class, tx_subdev_spec,
+                 bitrate, interp, spb, gain,
+                 options, mod_kwargs):
+
+        self.normal_gain = gain
+
+        self.u = usrp.sink_c (fusb_block_size=options.fusb_block_size,
+                              fusb_nblocks=options.fusb_nblocks)
+        dac_rate = self.u.dac_rate();
+
+        print mod_class
+        print mod_class.bits_per_baud()
+        (self._bitrate, self._spb, self._interp) = \
+            pick_tx_bitrate(bitrate, mod_class.bits_per_baud(), spb, interp, dac_rate)
+
+        self.u.set_interp_rate(self._interp)
+
+        # determine the daughterboard subdevice we're using
+        if tx_subdev_spec is None:
+            tx_subdev_spec = usrp.pick_tx_subdevice(self.u)
+        self.u.set_mux(usrp.determine_tx_mux_value(self.u, tx_subdev_spec))
+        self.subdev = usrp.selected_subdev(self.u, tx_subdev_spec)
+        print "Using TX d'board %s" % (self.subdev.side_and_name(),)
+
+        # transmitter
+        self.packet_transmitter = \
+            blks.mod_pkts(fg,
+                          mod_class(fg, spb=self._spb, **mod_kwargs),
+                          access_code=None,
+                          msgq_limit=4,
+                          pad_for_usrp=True)
+
+        self.amp = gr.multiply_const_cc (self.normal_gain)
+
+        fg.connect(self.packet_transmitter, self.amp, self.u)
+        gr.hier_block.__init__(self, fg, None, None)
+
+        self.set_gain(self.subdev.gain_range()[1])  # set max Tx gain
+        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.
+        """
+        r = self.u.tune(self.subdev._which, self.subdev, target_freq)
+        if r:
+            return True
+
+        return False
+
+    def set_gain(self, gain):
+        self.gain = gain
+        self.subdev.set_gain(gain)
+
+    def set_auto_tr(self, enable):
+        return self.subdev.set_auto_tr(enable)
+        
+    def send_pkt(self, payload='', eof=False):
+        return self.packet_transmitter.send_pkt(payload, eof)
+        
+    def bitrate(self):
+        return self._bitrate
+
+    def spb(self):
+        return self._spb
+
+    def interp(self):
+        return self._interp
diff --git a/gnuradio-examples/python/gmsk2/tunnel.py b/gnuradio-examples/python/gmsk2/tunnel.py
new file mode 100755 (executable)
index 0000000..bc10d3e
--- /dev/null
@@ -0,0 +1,300 @@
+#!/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 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 code sets up up a virtual ethernet interface (typically gr0),
+#    and relays packets between the interface and the GNU Radio PHY+MAC
+#
+#    What this means in plain language, is that if you've got a couple
+#    of USRPs on different machines, and if you run this code on those
+#    machines, you can talk between them using normal TCP/IP networking.
+#
+# /////////////////////////////////////////////////////////////////////////////
+
+
+from gnuradio import gr, gru, blks
+from gnuradio import usrp
+from gnuradio import eng_notation
+from gnuradio.eng_option import eng_option
+from optparse import OptionParser
+
+import random
+import time
+import struct
+import sys
+import os
+
+# from current dir
+from transmit_path import transmit_path
+from receive_path import receive_path
+import fusb_options
+
+#print os.getpid()
+#raw_input('Attach and press enter')
+
+
+# /////////////////////////////////////////////////////////////////////////////
+#
+#   Use the Universal TUN/TAP device driver to move packets to/from kernel
+#
+#   See /usr/src/linux/Documentation/networking/tuntap.txt
+#
+# /////////////////////////////////////////////////////////////////////////////
+
+# Linux specific...
+# TUNSETIFF ifr flags from <linux/tun_if.h>
+
+IFF_TUN                = 0x0001   # tunnel IP packets
+IFF_TAP                = 0x0002   # tunnel ethernet frames
+IFF_NO_PI      = 0x1000   # don't pass extra packet info
+IFF_ONE_QUEUE  = 0x2000   # beats me ;)
+
+def open_tun_interface(tun_device_filename):
+    from fcntl import ioctl
+    
+    mode = IFF_TAP | IFF_NO_PI
+    TUNSETIFF = 0x400454ca
+
+    tun = os.open(tun_device_filename, os.O_RDWR)
+    ifs = ioctl(tun, TUNSETIFF, struct.pack("16sH", "gr%d", mode))
+    ifname = ifs[:16].strip("\x00")
+    return (tun, ifname)
+    
+
+# /////////////////////////////////////////////////////////////////////////////
+#                             the flow graph
+# /////////////////////////////////////////////////////////////////////////////
+
+class my_graph(gr.flow_graph):
+
+    def __init__(self, mod_class, demod_class, tx_subdev_spec, rx_subdev_spec,
+                 bitrate, decim_rate, interp_rate, spb,
+                 bt, rx_callback, options):
+
+        gr.flow_graph.__init__(self)
+        self.txpath = transmit_path(self, mod_class, tx_subdev_spec,
+                                    bitrate, interp_rate, spb,
+                                    bt, options)
+        self.rxpath = receive_path(self, demod_class, rx_subdev_spec,
+                                   bitrate, decim_rate, spb,
+                                   rx_callback, options)
+
+    def send_pkt(self, payload='', eof=False):
+        return self.txpath.send_pkt(payload, eof)
+
+    def carrier_sensed(self):
+        """
+        Return True if the receive path thinks there's carrier
+        """
+        return self.rxpath.carrier_sensed()
+
+
+# /////////////////////////////////////////////////////////////////////////////
+#                           Carrier Sense MAC
+# /////////////////////////////////////////////////////////////////////////////
+
+class cs_mac(object):
+    """
+    Prototype carrier sense MAC
+
+    Reads packets from the TUN/TAP interface, and sends them to the PHY.
+    Receives packets from the PHY via phy_rx_callback, and sends them
+    into the TUN/TAP interface.
+
+    Of course, we're not restricted to getting packets via TUN/TAP, this
+    is just an example.
+    """
+    def __init__(self, tun_fd, verbose=False):
+        self.tun_fd = tun_fd       # file descriptor for TUN/TAP interface
+        self.verbose = verbose
+        self.fg = None             # flow graph (access to PHY)
+
+    def set_flow_graph(self, fg):
+        self.fg = fg
+
+    def phy_rx_callback(self, ok, payload):
+        """
+        Invoked by thread associated with PHY to pass received packet up.
+
+        @param ok: bool indicating whether payload CRC was OK
+        @param payload: contents of the packet (string)
+        """
+        if self.verbose:
+            print "Rx: ok = %r  len(payload) = %4d" % (ok, len(payload))
+        if ok:
+            os.write(self.tun_fd, payload)
+
+    def main_loop(self):
+        """
+        Main loop for MAC.
+        Only returns if we get an error reading from TUN.
+
+        FIXME: may want to check for EINTR and EAGAIN and reissue read
+        """
+        min_delay = 0.001               # seconds
+
+        while 1:
+            payload = os.read(self.tun_fd, 10*1024)
+            if not payload:
+                self.fg.send_pkt(eof=True)
+                break
+
+            if self.verbose:
+                print "Tx: len(payload) = %4d" % (len(payload),)
+
+            delay = min_delay
+            while self.fg.carrier_sensed():
+                sys.stderr.write('B')
+                time.sleep(delay)
+                if delay < 0.050:
+                    delay = delay * 2       # exponential back-off
+
+            self.fg.send_pkt(payload)
+
+
+# /////////////////////////////////////////////////////////////////////////////
+#                                   main
+# /////////////////////////////////////////////////////////////////////////////
+
+def main():
+
+    parser = OptionParser (option_class=eng_option)
+    parser.add_option("-f", "--freq", type="eng_float", default=423.1e6,
+                       help="set Tx and Rx frequency to FREQ [default=%default]", metavar="FREQ")
+    parser.add_option("-r", "--bitrate", type="eng_float", default=None,
+                      help="specify bitrate.  spb and interp will be derived.")
+    parser.add_option("-g", "--rx-gain", type="eng_float", default=27,
+                      help="set rx gain")
+    parser.add_option("-T", "--tx-subdev-spec", type="subdev", default=None,
+                      help="select USRP Tx side A or B")
+    parser.add_option("-R", "--rx-subdev-spec", type="subdev", default=None,
+                      help="select USRP Rx side A or B")
+    parser.add_option("-S", "--spb", type="int", default=None, help="set samples/baud [default=%default]")
+    parser.add_option("-d", "--decim", type="intx", default=None,
+                      help="set fpga decim rate to DECIM [default=%default]")
+    parser.add_option("-i", "--interp", type="intx", default=None,
+                      help="set fpga interpolation rate to INTERP [default=%default]")
+    parser.add_option("-c", "--carrier-threshold", type="eng_float", default=30,
+                      help="set carrier detect threshold (dB) [default=%default]")
+    parser.add_option("", "--bt", type="float", default=0.3, help="set bandwidth-time product [default=%default]")
+    parser.add_option("","--tun-device-filename", default="/dev/net/tun",
+                      help="path to tun device file [default=%default]")
+    parser.add_option("-v","--verbose", action="store_true", default=False)
+    fusb_options.add_options(parser)
+    (options, args) = parser.parse_args ()
+
+    if len(args) != 0:
+        parser.print_help()
+        sys.exit(1)
+
+    if options.freq < 1e6:
+        options.freq *= 1e6
+
+    # open the TUN/TAP interface
+    (tun_fd, tun_ifname) = open_tun_interface(options.tun_device_filename)
+
+    # Attempt to enable realtime scheduling
+    r = gr.enable_realtime_scheduling()
+    if r == gr.RT_OK:
+        realtime = True
+    else:
+        realtime = False
+        print "Note: failed to enable realtime scheduling"
+
+
+    # If the user hasn't set the fusb_* parameters on the command line,
+    # pick some values that will reduce latency.
+
+    if options.fusb_block_size == 0 and options.fusb_nblocks == 0:
+        if realtime:                        # be more aggressive
+            options.fusb_block_size = gr.prefs().get_long('fusb', 'rt_block_size', 1024)
+            options.fusb_nblocks    = gr.prefs().get_long('fusb', 'rt_nblocks', 16)
+        else:
+            options.fusb_block_size = gr.prefs().get_long('fusb', 'block_size', 4096)
+            options.fusb_nblocks    = gr.prefs().get_long('fusb', 'nblocks', 16)
+    
+    print "fusb_block_size =", options.fusb_block_size
+    print "fusb_nblocks    =", options.fusb_nblocks
+
+    # instantiate the MAC
+    mac = cs_mac(tun_fd, verbose=True)
+
+
+    # build the graph (PHY)
+    fg = my_graph(blks.gmsk2_mod, blks.gmsk2_demod,
+                  options.tx_subdev_spec, options.rx_subdev_spec,
+                  options.bitrate, options.decim, options.interp,
+                  options.spb, options.bt, mac.phy_rx_callback,
+                  options)
+
+    mac.set_flow_graph(fg)    # give the MAC a handle for the PHY
+
+    if fg.txpath.bitrate() != fg.rxpath.bitrate():
+        print "WARNING: Transmit bitrate = %sb/sec, Receive bitrate = %sb/sec" % (
+            eng_notation.num_to_str(fg.txpath.bitrate()),
+            eng_notation.num_to_str(fg.rxpath.bitrate()))
+             
+    print "bitrate: %sb/sec" % (eng_notation.num_to_str(fg.txpath.bitrate()),)
+    print "spb:     %3d" % (fg.txpath.spb(),)
+    print "interp:  %3d" % (fg.txpath.interp(),)
+
+    ok = fg.txpath.set_freq(options.freq)
+    if not ok:
+        print "Failed to set Tx frequency to %s" % (eng_notation.num_to_str(options.freq),)
+        raise SystemExit
+
+    ok = fg.rxpath.set_freq(options.freq)
+    if not ok:
+        print "Failed to set Rx frequency to %s" % (eng_notation.num_to_str(options.freq),)
+        raise SystemExit
+
+    fg.rxpath.set_gain(options.rx_gain)
+    print "Rx gain_range: ", fg.rxpath.subdev.gain_range(), " using", fg.rxpath.gain
+
+    fg.rxpath.set_carrier_threshold(options.carrier_threshold)
+    print "Carrier sense threshold:", options.carrier_threshold, "dB"
+    
+    print
+    print "Allocated virtual ethernet interface: %s" % (tun_ifname,)
+    print "You must now use ifconfig to set its IP address. E.g.,"
+    print
+    print "  $ sudo ifconfig %s 10.10.10.1" % (tun_ifname,)
+    print
+    print "Be sure to use a different address in the same subnet for each machine."
+    print
+
+
+    fg.start()    # Start executing the flow graph (runs in separate threads)
+
+    mac.main_loop()    # don't expect this to return...
+
+    fg.stop()     # but if it does, tell flow graph to stop.
+    fg.wait()     # wait for it to finish
+                
+
+if __name__ == '__main__':
+    try:
+        main()
+    except KeyboardInterrupt:
+        pass
diff --git a/gnuradio-examples/python/gmsk2/tx_voice.py b/gnuradio-examples/python/gmsk2/tx_voice.py
new file mode 100755 (executable)
index 0000000..9e274e5
--- /dev/null
@@ -0,0 +1,139 @@
+#!/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 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.
+# 
+
+from gnuradio import gr, gru, blks
+from gnuradio import usrp
+from gnuradio import audio
+from gnuradio import eng_notation
+from gnuradio.eng_option import eng_option
+from optparse import OptionParser
+
+from gnuradio.vocoder import gsm_full_rate
+
+import random
+import time
+import struct
+import sys
+
+# from current dir
+from transmit_path import transmit_path
+
+#import os
+#print os.getpid()
+#raw_input('Attach and press enter')
+
+
+class my_graph(gr.flow_graph):
+
+    def __init__(self, tx_subdev_spec, bitrate, interp_rate, spb, bt):
+        gr.flow_graph.__init__(self)
+        self.txpath = transmit_path(self, tx_subdev_spec, bitrate, interp_rate, spb, bt)
+
+        audio_input = ""
+        sample_rate = 8000
+        src = audio.source(sample_rate, audio_input)
+        src_scale = gr.multiply_const_ff(32767)
+        f2s = gr.float_to_short()
+        voice_coder = gsm_full_rate.encode_sp()
+        self.packets_from_encoder = gr.msg_queue()
+        packet_sink = gr.message_sink(33, self.packets_from_encoder, False)
+        self.connect(src, src_scale, f2s, voice_coder, packet_sink)
+
+
+
+# /////////////////////////////////////////////////////////////////////////////
+#                                   main
+# /////////////////////////////////////////////////////////////////////////////
+
+def main():
+
+    def send_pkt(payload='', eof=False):
+        return fg.txpath.send_pkt(payload, eof)
+
+    def rx_callback(ok, payload):
+        print "ok = %r, payload = '%s'" % (ok, payload)
+
+    parser = OptionParser (option_class=eng_option)
+    parser.add_option("-T", "--tx-subdev-spec", type="subdev", default=None,
+                      help="select USRP Tx side A or B")
+    parser.add_option("-f", "--freq", type="eng_float", default=423.1e6,
+                       help="set Tx and Rx frequency to FREQ [default=%default]", metavar="FREQ")
+    parser.add_option("-r", "--bitrate", type="eng_float", default=100e3,
+                      help="specify bitrate.  spb and interp will be derived.")
+    parser.add_option("-S", "--spb", type="int", default=None, help="set samples/baud [default=%default]")
+    parser.add_option("-i", "--interp", type="intx", default=None,
+                      help="set fpga interpolation rate to INTERP [default=%default]")
+    parser.add_option("-s", "--size", type="eng_float", default=1500,
+                      help="set packet size [default=%default]")
+    parser.add_option("", "--bt", type="float", default=0.3, help="set bandwidth-time product [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)")
+    (options, args) = parser.parse_args ()
+
+    if len(args) != 0:
+        parser.print_help()
+        sys.exit(1)
+
+    if options.freq < 1e6:
+        options.freq *= 1e6
+
+    pkt_size = int(options.size)
+
+    # build the graph
+    fg = my_graph(options.tx_subdev_spec, options.bitrate, options.interp,
+                  options.spb, options.bt)
+
+    print "bitrate: %sb/sec" % (eng_notation.num_to_str(fg.txpath.bitrate()),)
+    print "spb:     %3d" % (fg.txpath.spb(),)
+    print "interp:  %3d" % (fg.txpath.interp(),)
+
+    fg.txpath.set_freq(options.freq)
+
+    fg.start()                       # start flow graph
+
+    # generate and send packets
+    nbytes = int(1e6 * options.megabytes)
+    n = 0
+    pktno = 0
+
+    while n < nbytes:
+        packet = fg.packets_from_encoder.delete_head()
+        s = packet.to_string()
+        send_pkt(s)
+        n += len(s)
+        sys.stderr.write('.')
+        if options.discontinuous and pktno % 5 == 4:
+            time.sleep(1)
+        pktno += 1
+        
+    send_pkt(eof=True)
+    fg.wait()                       # wait for it to finish
+    fg.txpath.set_auto_tr(False)
+
+
+if __name__ == '__main__':
+    try:
+        main()
+    except KeyboardInterrupt:
+        pass
diff --git a/gnuradio-examples/python/mc4020/Makefile.am b/gnuradio-examples/python/mc4020/Makefile.am
new file mode 100644 (file)
index 0000000..21bed3e
--- /dev/null
@@ -0,0 +1,28 @@
+#
+# 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.
+# 
+
+EXTRA_DIST =                   \
+       fm_demod.py             \
+       mc4020_fft.py           
+
+
+
+
diff --git a/gnuradio-examples/python/mc4020/fm_demod.py b/gnuradio-examples/python/mc4020/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/gnuradio-examples/python/mc4020/mc4020_fft.py b/gnuradio-examples/python/mc4020/mc4020_fft.py
new file mode 100755 (executable)
index 0000000..3348ad4
--- /dev/null
@@ -0,0 +1,53 @@
+#!/usr/bin/env 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.
+# 
+
+from gnuradio import gr
+from gnuradio import mc4020
+from gnuradio.eng_option import eng_option
+from gnuradio.wxgui import stdgui, fftsink
+from optparse import OptionParser
+import wx
+
+class app_flow_graph (stdgui.gui_flow_graph):
+    def __init__(self, frame, panel, vbox, argv):
+        stdgui.gui_flow_graph.__init__ (self, frame, panel, vbox, argv)
+
+        
+        parser = OptionParser (option_class=eng_option)
+        (options, args) = parser.parse_args ()
+
+        input_rate = 20e6
+        src = mc4020.source (input_rate, mc4020.MCC_CH3_EN | mc4020.MCC_ALL_1V)
+        cvt = gr.short_to_float ()
+        block, fft_win = fftsink.make_fft_sink_f (self, panel, "Rx Data", 512, input_rate)
+
+        self.connect (src, cvt)
+        self.connect (cvt, block)
+        vbox.Add (fft_win, 1, wx.EXPAND)
+
+
+def main ():
+    app = stdgui.stdapp (app_flow_graph, "USRP FFT")
+    app.MainLoop ()
+
+if __name__ == '__main__':
+    main ()
diff --git a/gnuradio-examples/python/multi-antenna/multi_fft.py b/gnuradio-examples/python/multi-antenna/multi_fft.py
new file mode 100755 (executable)
index 0000000..ca9c614
--- /dev/null
@@ -0,0 +1,128 @@
+#!/usr/bin/env python
+
+from gnuradio import gr, gru, eng_notation
+from gnuradio import usrp
+from gnuradio.eng_option import eng_option
+from gnuradio import eng_notation
+from gnuradio import optfir
+from optparse import OptionParser
+from gnuradio.wxgui import stdgui, fftsink, waterfallsink, scopesink, form, slider
+import wx
+import usrp_dbid
+import time
+import os.path
+import sys
+
+# required FPGA that can do 4 rx channels.
+
+
+class my_graph(stdgui.gui_flow_graph):
+
+    def __init__(self, frame, panel, vbox, argv):
+        stdgui.gui_flow_graph.__init__(self)
+
+        self.frame = frame
+        self.panel = panel
+
+        parser = OptionParser (option_class=eng_option)
+        #parser.add_option("-S", "--subdev", type="subdev", default=(0, None),
+        #                  help="select USRP Rx side A or B (default=A)")
+        parser.add_option("-d", "--decim", type="int", default=128,
+                          help="set fgpa decimation rate to DECIM [default=%default]")
+        parser.add_option("-f", "--freq", type="eng_float", default=146.585e6,
+                          help="set frequency to FREQ [default=%default])", metavar="FREQ")
+        parser.add_option("-g", "--gain", type="eng_float", default=20,
+                          help="set gain in dB [default=%default]")
+        parser.add_option("-F", "--filter", action="store_true", default=True,
+                          help="Enable channel filter")
+        (options, args) = parser.parse_args()
+
+        if len(args) != 0:
+            parser.print_help()
+            raise SystemExit
+
+        nchan = 4
+
+        if options.filter:
+            sw_decim = 4
+        else:
+            sw_decim = 1
+
+        self.u = usrp.source_c(0, options.decim, fpga_filename="std_4rx_0tx.rbf")
+        if self.u.nddc() < nchan:
+            sys.stderr.write('This code requires an FPGA build with %d DDCs.  This FPGA has only %d.\n' % (
+                nchan, self.u.nddc()))
+            raise SystemExit
+                             
+        if not self.u.set_nchannels(nchan):
+            sys.stderr.write('set_nchannels(%d) failed\n' % (nchan,))
+            raise SystemExit
+        
+        input_rate = self.u.adc_freq() / self.u.decim_rate()
+        print "USB data rate   = %s" % (eng_notation.num_to_str(input_rate),)
+        print "Scope data rate = %s" % (eng_notation.num_to_str(input_rate/sw_decim),)
+
+        self.subdev = self.u.db[0] + self.u.db[1]
+
+        if (len (self.subdev) != 4 or
+            self.u.db[0][0].dbid() != usrp_dbid.BASIC_RX or
+            self.u.db[1][0].dbid() != usrp_dbid.BASIC_RX):
+            sys.stderr.write('This code requires a Basic Rx board on Sides A & B\n')
+            sys.exit(1)
+
+        self.u.set_mux(gru.hexint(0xf3f2f1f0))
+
+        # deinterleave four channels from FPGA
+        di = gr.deinterleave(gr.sizeof_gr_complex)
+
+        self.connect(self.u, di)
+        
+
+
+        # taps for channel filter
+        chan_filt_coeffs = optfir.low_pass (1,           # gain
+                                            input_rate,  # sampling rate
+                                            80e3,        # passband cutoff
+                                            115e3,       # stopband cutoff
+                                            0.1,         # passband ripple
+                                            60)          # stopband attenuation
+        #print len(chan_filt_coeffs)
+
+        for i in range(nchan):
+            scope = fftsink.fft_sink_c(self, panel, sample_rate=input_rate/sw_decim,
+                                       title="Input %d" % (i,),
+                                       ref_level=80, y_per_div=20)
+            vbox.Add(scope.win, 10, wx.EXPAND)
+
+            if options.filter:
+                chan_filt = gr.fir_filter_ccf(sw_decim, chan_filt_coeffs)
+                self.connect((di, i), chan_filt, scope)
+            else:
+                self.connect((di, i), scope)
+
+
+        self.set_gain(options.gain)
+        self.set_freq(options.freq)
+
+    def set_gain(self, gain):
+        for i in range(len(self.subdev)):
+            self.subdev[i].set_gain(gain)
+
+    def set_freq(self, target_freq):
+        ok = True
+        for i in range(len(self.subdev)):
+            r = usrp.tune(self.u, i, self.subdev[i], target_freq)
+            if not r:
+                ok = False
+                print "set_freq: failed to set subdev[%d] freq to %f" % (
+                    i, target_freq)
+
+        return ok
+
+
+def main ():
+    app = stdgui.stdapp(my_graph, "Multi Scope", nstatus=1)
+    app.MainLoop()
+
+if __name__ == '__main__':
+    main ()
diff --git a/gnuradio-examples/python/multi-antenna/multi_file.py b/gnuradio-examples/python/multi-antenna/multi_file.py
new file mode 100755 (executable)
index 0000000..e2a6e04
--- /dev/null
@@ -0,0 +1,136 @@
+#!/usr/bin/env python
+
+from gnuradio import gr, gru, eng_notation
+from gnuradio import usrp
+from gnuradio.eng_option import eng_option
+from gnuradio import eng_notation
+from gnuradio import optfir
+from optparse import OptionParser
+from gnuradio.wxgui import stdgui, fftsink, waterfallsink, scopesink, form, slider
+import wx
+import usrp_dbid
+import time
+import os.path
+import sys
+
+# required FPGA that can do 4 rx channels.
+
+
+class my_graph(gr.flow_graph):
+
+    def __init__(self):
+        gr.flow_graph.__init__(self)
+
+        parser = OptionParser (option_class=eng_option)
+        #parser.add_option("-S", "--subdev", type="subdev", default=(0, None),
+        #                  help="select USRP Rx side A or B (default=A)")
+        parser.add_option("-d", "--decim", type="int", default=128,
+                          help="set fgpa decimation rate to DECIM [default=%default]")
+        parser.add_option("-f", "--freq", type="eng_float", default=146.585e6,
+                          help="set frequency to FREQ [default=%default])", metavar="FREQ")
+        parser.add_option("-g", "--gain", type="eng_float", default=20,
+                          help="set gain in dB [default=%default]")
+        parser.add_option("-F", "--filter", action="store_true", default=True,
+                          help="Enable channel filter")
+        parser.add_option("-o", "--output", type="string", default=None,
+                          help="set output basename")
+        (options, args) = parser.parse_args()
+
+        if len(args) != 0:
+            parser.print_help()
+            raise SystemExit
+
+        if options.output is None:
+            parser.print_help()
+            sys.stderr.write("You must provide an output filename base with -o OUTPUT\n")
+            raise SystemExit
+        else:
+            basename = options.output
+
+        nchan = 4
+        nsecs = 4.0
+
+        if options.filter:
+            sw_decim = 4
+        else:
+            sw_decim = 1
+
+        self.u = usrp.source_c(0, options.decim, fpga_filename="std_4rx_0tx.rbf")
+        if self.u.nddc() < nchan:
+            sys.stderr.write('This code requires an FPGA build with %d DDCs.  This FPGA has only %d.\n' % (
+                nchan, self.u.nddc()))
+            raise SystemExit
+                             
+        if not self.u.set_nchannels(nchan):
+            sys.stderr.write('set_nchannels(%d) failed\n' % (nchan,))
+            raise SystemExit
+        
+        input_rate = self.u.adc_freq() / self.u.decim_rate()
+        print "USB data rate   = %s" % (eng_notation.num_to_str(input_rate),)
+        sink_data_rate = input_rate/sw_decim
+        print "Scope data rate = %s" % (eng_notation.num_to_str(sink_data_rate),)
+
+        self.subdev = self.u.db[0] + self.u.db[1]
+
+        if (len(self.subdev) != 4 or
+            self.u.db[0][0].dbid() != usrp_dbid.BASIC_RX or
+            self.u.db[1][0].dbid() != usrp_dbid.BASIC_RX):
+            sys.stderr.write('This code requires a Basic Rx board on Sides A & B\n')
+            sys.exit(1)
+
+        self.u.set_mux(gru.hexint(0xf3f2f1f0))
+
+        # collect 1 second worth of data
+        limit = int(nsecs * input_rate * nchan)
+        print "limit = ", limit
+        head = gr.head(gr.sizeof_gr_complex, limit)
+
+        # deinterleave four channels from FPGA
+        di = gr.deinterleave(gr.sizeof_gr_complex)
+
+        self.connect(self.u, head, di)
+        
+        # taps for channel filter
+        chan_filt_coeffs = optfir.low_pass (1,           # gain
+                                            input_rate,  # sampling rate
+                                            80e3,        # passband cutoff
+                                            115e3,       # stopband cutoff
+                                            0.1,         # passband ripple
+                                            60)          # stopband attenuation
+        #print len(chan_filt_coeffs)
+
+        for i in range(nchan):
+
+            sink = gr.file_sink(gr.sizeof_gr_complex,
+                                basename + ("-%s-%d.dat" % (eng_notation.num_to_str(sink_data_rate), i)))
+            if options.filter:
+                chan_filt = gr.fir_filter_ccf(sw_decim, chan_filt_coeffs)
+                self.connect((di, i), chan_filt, sink)
+            else:
+                self.connect((di, i), sink)
+
+
+        self.set_gain(options.gain)
+        self.set_freq(options.freq)
+
+    def set_gain(self, gain):
+        for i in range(len(self.subdev)):
+            self.subdev[i].set_gain(gain)
+
+    def set_freq(self, target_freq):
+        ok = True
+        for i in range(len(self.subdev)):
+            r = usrp.tune(self.u, i, self.subdev[i], target_freq)
+            if not r:
+                ok = False
+                print "set_freq: failed to set subdev[%d] freq to %f" % (
+                    i, target_freq)
+
+        return ok
+
+
+def main ():
+    my_graph().run()
+
+if __name__ == '__main__':
+    main ()
diff --git a/gnuradio-examples/python/multi-antenna/multi_scope.py b/gnuradio-examples/python/multi-antenna/multi_scope.py
new file mode 100755 (executable)
index 0000000..43aa77b
--- /dev/null
@@ -0,0 +1,138 @@
+#!/usr/bin/env python
+
+from gnuradio import gr, gru, eng_notation
+from gnuradio import usrp
+from gnuradio.eng_option import eng_option
+from gnuradio import eng_notation
+from gnuradio import optfir
+from optparse import OptionParser
+from gnuradio.wxgui import stdgui, fftsink, waterfallsink, scopesink, form, slider
+import wx
+import usrp_dbid
+import time
+import os.path
+import sys
+
+# required FPGA that can do 4 rx channels.
+
+
+class my_graph(stdgui.gui_flow_graph):
+
+    def __init__(self, frame, panel, vbox, argv):
+        stdgui.gui_flow_graph.__init__(self)
+
+        self.frame = frame
+        self.panel = panel
+
+        parser = OptionParser (option_class=eng_option)
+        #parser.add_option("-S", "--subdev", type="subdev", default=(0, None),
+        #                  help="select USRP Rx side A or B (default=A)")
+        parser.add_option("-d", "--decim", type="int", default=128,
+                          help="set fgpa decimation rate to DECIM [default=%default]")
+        parser.add_option("-f", "--freq", type="eng_float", default=146.585e6,
+                          help="set frequency to FREQ [default=%default])", metavar="FREQ")
+        parser.add_option("-g", "--gain", type="eng_float", default=20,
+                          help="set gain in dB [default=%default]")
+        parser.add_option("-F", "--filter", action="store_true", default=True,
+                          help="Enable channel filter")
+        (options, args) = parser.parse_args()
+
+        if len(args) != 0:
+            parser.print_help()
+            raise SystemExit
+
+        nchan = 4
+
+        if options.filter:
+            sw_decim = 4
+        else:
+            sw_decim = 1
+
+        self.u = usrp.source_c(0, options.decim, fpga_filename="std_4rx_0tx.rbf")
+        if self.u.nddc() < nchan:
+            sys.stderr.write('This code requires an FPGA build with %d DDCs.  This FPGA has only %d.\n' % (
+                nchan, self.u.nddc()))
+            raise SystemExit
+                             
+        if not self.u.set_nchannels(nchan):
+            sys.stderr.write('set_nchannels(%d) failed\n' % (nchan,))
+            raise SystemExit
+        
+        input_rate = self.u.adc_freq() / self.u.decim_rate()
+        print "USB data rate   = %s" % (eng_notation.num_to_str(input_rate),)
+        print "Scope data rate = %s" % (eng_notation.num_to_str(input_rate/sw_decim),)
+
+        self.subdev = self.u.db[0] + self.u.db[1]
+
+        if (len(self.subdev) != 4 or
+            self.u.db[0][0].dbid() != usrp_dbid.BASIC_RX or
+            self.u.db[1][0].dbid() != usrp_dbid.BASIC_RX):
+            sys.stderr.write('This code requires a Basic Rx board on Sides A & B\n')
+            sys.exit(1)
+
+        self.u.set_mux(gru.hexint(0xf3f2f1f0))
+
+        # deinterleave four channels from FPGA
+        di = gr.deinterleave(gr.sizeof_gr_complex)
+
+        self.connect(self.u, di)
+        
+        # our destination (8 float inputs)
+        self.scope = scopesink.scope_sink_f(self, panel, sample_rate=input_rate/sw_decim)
+
+        # taps for channel filter
+        chan_filt_coeffs = optfir.low_pass (1,           # gain
+                                            input_rate,  # sampling rate
+                                            80e3,        # passband cutoff
+                                            115e3,       # stopband cutoff
+                                            0.1,         # passband ripple
+                                            60)          # stopband attenuation
+        #print len(chan_filt_coeffs)
+
+        # bust the deinterleaved complex channels into floats
+        for i in range(nchan):
+
+            if options.filter:
+                chan_filt = gr.fir_filter_ccf(sw_decim, chan_filt_coeffs)
+                c2f = gr.complex_to_float()
+                self.connect((di, i), chan_filt, c2f)
+            else:
+                c2f = gr.complex_to_float()
+                self.connect((di, i), c2f)
+
+            self.connect((c2f, 0), (self.scope, 2*i + 0))
+            self.connect((c2f, 1), (self.scope, 2*i + 1))
+
+
+        self._build_gui(vbox)
+
+        self.set_gain(options.gain)
+        self.set_freq(options.freq)
+
+    def set_gain(self, gain):
+        for i in range(len(self.subdev)):
+            self.subdev[i].set_gain(gain)
+
+    def set_freq(self, target_freq):
+        ok = True
+        for i in range(len(self.subdev)):
+            r = usrp.tune(self.u, i, self.subdev[i], target_freq)
+            if not r:
+                ok = False
+                print "set_freq: failed to set subdev[%d] freq to %f" % (
+                    i, target_freq)
+
+        return ok
+
+
+    def _build_gui(self, vbox):
+        vbox.Add(self.scope.win, 10, wx.EXPAND)
+        
+
+
+def main ():
+    app = stdgui.stdapp(my_graph, "Multi Scope", nstatus=1)
+    app.MainLoop()
+
+if __name__ == '__main__':
+    main ()
diff --git a/gnuradio-examples/python/multi_usrp/Makefile.am b/gnuradio-examples/python/multi_usrp/Makefile.am
new file mode 100644 (file)
index 0000000..c2c6a29
--- /dev/null
@@ -0,0 +1,28 @@
+#
+# 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 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.
+# 
+
+EXTRA_DIST =                   \
+       README          \
+       multi_usrp_oscope.py            \
+       multi_usrp_rx_cfile.py
+
+
+
diff --git a/gnuradio-examples/python/multi_usrp/README b/gnuradio-examples/python/multi_usrp/README
new file mode 100644 (file)
index 0000000..c93d773
--- /dev/null
@@ -0,0 +1,260 @@
+Quick start multi-usrp:
+
+Unpack, build and install usrp, gnuradio-core and gr-usrp
+Versions need to be more recent then 2.7cvs/svn 11 may 2006
+
+Make sure usrp/fpga/rbf/rev2/multi*.rbf is installed in /usr/local/share/usrp/rev2/
+Make sure usrp/fpga/rbf/rev4/multi*.rbf is installed in /usr/local/share/usrp/rev4/
+(If in doubt, copy manually)
+build and install gr-wxgui gr-audio-xxx  and so on.
+
+unpack gnuradio-examples.
+
+There is a gnuradio-examples/python/multi_usrp directory which contains examples
+
+
+Put at least a basic RX or dbsrx board in RXA of the master and RXA of the slave board.
+Make sure that the usrps have a serial or unique identifier programmed in their eeprom.
+(All new rev 4.1 boards have this)
+You can do without a serial but then you never know which usrp is the master and which is the slave.
+
+
+CONNECTING THE CABLES
+Now connect the 64MHz clocks between the boards with a short sma coax cable.
+(See the wiki on how to enable clock-out and clock-in 
+http://comsec.com/wiki?USRPClockingNotes )
+
+You need one board with a clock out and one board with a clock in.
+
+You can choose any of the two boards as master or slave, this is not dependant on which board has the clock-out or in.
+In my experiments I had fewer problems when the board that has the clock-in will be the master board.
+
+You can use a standard 16-pole flatcable to connect tvrx, basic-rx or dbsrx boards.
+Of this 16pin flatcable only two pins are used (io15 and ground)
+For all new daughterboards which use up a lot of io pins you have to use a cable with fewer connections.
+The savest is using a 2pin headercable connected to io15,gnd (a cable like the ones used to connect frontpanel leds to the mainboard of a PC)
+
+If using basic rx board:
+  Connect a 16-pole flatcable from J25 on basicrx/dbs_rx in rxa of the master usrp to J25 on basicrx/dbsrx in RXA of the slave usrp
+  Don't twist the cable (Make sure the pin1 marker (red line on the flatcable) is on the same side of the connector (at io-8 on the master and at io8 on the slave.))
+  For basic_rx this means the marker should be on the side of the dboard with the sma connectors. 
+  For dbs_rx this means the marker should be on the side of the dboard with the two little chips.
+  In other words, don't twist the cable, you will burn your board if you do.
+
+You can also connect a flatcable with multiple connectors from master-J25 to slave1-J25 to slave2-J25 to ...
+You will however have to think of something to create a common 64Mhz clock for more then two usrps.
+
+For all other daughterboards, connect a 2wire cable from masterRXA J25 io15,gnd to slaveRXA J25 io15,gnd 
+
+
+So now the hardware is setup, software is setup. Lets do some tests.
+
+Connect power to both usrps.
+unpack the gnuradio_examples somewhere (cvs version later then 11 may 2006) 
+go to the gnuradio-examples/python/multi_usrp folder.
+
+Now run 
+ ./multi_usrp_oscope.py -x 12345678
+
+It should tell you that usrp 12345678 is not found and tell you which serials are available.
+
+Now run  ./multi_usrp_oscope.py -x actualserialnum 
+You should now get an oscope with two channels, one is from the master and one is from the slave
+It will which show the I-signal from channel 0 of the master usrp and I-signal from channel 0 of the slave usrp.
+(For testing connect the same signal source to the inputs of both boards)
+The signals should be aligned.
+If you click the sync button, it will resync the master and slave (should never be needed)
+
+Now run
+./multi_usrp_oscope.py --help
+To see all available options.
+
+
+Now you are ready to do phase-locked aligned signal processing.
+
+You can also capture to file with:
+./multi_usrp_rx_cfile.py 
+
+run ./multi_usrp_rx_cfile.py --help to see all available options.
+
+
+
+Here follows a description of the detail blocks used in usrp_multi.py
+
+Multi usrp
+
+With this code you can connect two or more usrps (with a locked clock) and get synchronised samples.
+You must connect a (flat)cable between a dboard on the master in RXA and a dboard on the slave in RXA.
+You then put one usrp in master mode, put the other in slave mode.
+
+The easiest thing to see how this works is just looking at the code in
+ multi_usrp_oscope.py
+ multi_usrp_rx_cfile.py 
+
+Use the usrp_multi block which is installed by gr-usrp.
+instantiate in the following way:
+
+        self.multi=usrp_multi.multi_source_align( fg=self, master_serialno=options.master_serialno, decim=options.decim, nchan=options.nchan )
+
+nchan should be 2 or 4.
+
+You determine which is the master by master_serialno (this is a text string a hexadecimal number).
+If you enter a serial number which is not found it will print the serial numbers which are available.
+If you give no serial number  (master_serialno=None), the code will pick a Master for you.
+
+You can get a reference to the master and the slave usrp in the following way:
+
+        self.um=self.multi.get_master_usrp()
+        self.us=self.multi.get_slave_usrp()
+
+You only need these references for setting freqs/gains or getting info about daughterboards.
+Don't use the output directly but use the aligned output from multi.get_master_source_c() and multi.get_slave_source_c()
+
+You get references to the aligned output samples in the following way:
+aligned_master_source_c=self.multi.get_master_source_c()
+aligned_slave_source_c=self.multi.get_slave_source_c()
+
+These blocks have multiple outputs.
+output 0 is the sample counter (high bits in I, low bits in Q)
+You normally don't need the samplecounters so you can ignore output 0
+
+output 1 is the first aligend output channel (if you enable 2 or 4 channels)
+output 2 is the second output channel (only if you enable 4 channels)
+
+so the usefull 4 channels are:
+self.aligned_master_chan1=(self.multi.get_master_source_c(),1)
+self.aligned_master_chan2=(self.multi.get_master_source_c(),2)
+self.aligned_slave_chan1=(self.multi.get_slave_source_c(),1)
+self.aligned_slave_chan2=(self.multi.get_slave_source_c(),2)
+
+The two samplecounters are:
+self.aligned_master_samplecounter=(self.multi.get_master_source_c(),0)
+self.aligned_slave_samplecounter=(self.multi.get_slave_source_c(),0)
+
+You can set the gain or tune the frequency for all 4 receive daughetrboards at once:
+        self.multi.set_gain_all_rx(options.gain)
+        result,r1,r2,r3,r4 = self.multi.tune_all_rx(options.freq)
+
+This will only work reliably when you have all the same daughterboards.
+Otherwise set all freqs and gains individually.
+
+You must call self.multi.sync() at least once AFTER the flowgraph has started running.
+(This will synchronise the streams of the two usrps)
+
+This work was funded by Toby Oliver at Sensus Analytics / Path Intelligence.
+Many Thanks for making this possible.
+
+It was written by Martin Dudok van Heel at Olifantasia.
+
+
+
+Here follows a brief of the new blocks and (changes)functionality written for multi-usrp support.
+
+You can also look at the generated documentation in  
+/usr/local/share/doc/gnuradio-core-X.X
+/usr/local/share/doc/usrp-X.X
+(Make sure to build and install the documentation, go to the doc directory of the sourcetree and issue make doc; make install)
+
+gnuradio-examples:
+new/changed files:
+multi_usrp/multi_usrp_oscope.py
+multi_usrp/multi_usrp_rx_cfile.py
+
+
+gnuradio-core:
+gr.align_on_samplenumbers_ss (int nchan,int align_interval) 
+
+align several complex short (interleaved short) input channels with corresponding unsigned 32 bit sample_counters (provided as interleaved 16 bit values)
+
+Parameters:
+       nchan   number of complex_short input channels (including the 32 bit counting channel)
+       align_interval  interval at which the samples are aligned, ignored for now.
+
+Pay attention on how you connect this block It expects a minimum of 2 usrp_source_s with nchan number of channels and as mode  usrp_prims.bmFR_MODE_RX_COUNTING_32BIT enabled. This means that the first complex_short channel is an interleaved 32 bit counter. The samples are aligned by dropping samples untill the samplenumbers match.
+
+files:
+gnuradio-core/src/lib/general/gr_align_on_samplenumbers_ss.cc
+gnuradio-core/src/lib/general/gr_align_on_samplenumbers_ss.h
+gnuradio-core/src/lib/general/gr_align_on_samplenumbers_ss.i
+
+
+gr-usrp
+   added _write_fpga_reg_masked
+   added usrp_multi.py
+  new usrp_multi block which can instantiate two linked usrps as master and slave and alignes their output.
+  It has a sync() function which should be called AFTER the flowgraph has started running.
+  bool sync();
+     \brief Call this on a master usrp to sync master and slave by outputing a sync pulse on rx_a_io[15].
+        The 32 bit samplecounter of master and slave will be reset to zero and all phase and buffer related things in the usrps are reset.
+        Call this only after the flowgraph has been started, otherwise there will be no effect since everything is kept in reset state as long as the flowgraph is not running.
+     \returns true if successfull.
+
+files:
+configure.ac
+src/Makefile.am
+src/usrp1.i
+src/usrp1_source_base.cc
+src/usrp1_source_base.h
+src/usrp_multi.py
+
+usrp-0.11cvsmulti:
+usrp:
+   new constant bmFR_MODE_RX_COUNTING_32BIT    (could also be added as extra mode like FPGA_MODE_COUNTING_32BIT)
+   Use this for the mode parameter when creating a usrp when you want to use the master/slave setup or if you want to use the 32 bit counter for other things, like testing with gr.check_counting_s(True)
+
+  added register FR_RX_MASTER_SLAVE
+  added bitno and bitmaskes:
+   bmFR_MODE_RX_COUNTING_32BIT
+
+   bitnoFR_RX_SYNC 
+   bitnoFR_RX_SYNC_MASTER
+   bitnoFR_RX_SYNC_SLAVE
+
+   bitnoFR_RX_SYNC_INPUT_IOPIN 15
+   bmFR_RX_SYNC_INPUT_IOPIN  (1<<bitnoFR_RX_SYNC_INPUT_IOPIN)
+   bitnoFR_RX_SYNC_OUTPUT_IOPIN 15
+   bmFR_RX_SYNC_OUTPUT_IOPIN (1<<bitnoFR_RX_SYNC_OUTPUT_IOPIN)
+   added _write_fpga_reg_masked()
+   added new toplevel folder usrp_multi
+   added usrp_multi.v and master_control_multi.v
+   added new MULTI_ON and COUNTER_32BIT_ON defines
+      If these are turned off usrp_multi.v will behave exactly as usrp_std.v
+
+   added setting_reg_masked.v
+   changed reset behaviour of phase_acc.v and rx_buffer.v
+
+   changed generate_regs.py to handle bm and bitno defines
+
+
+files:
+firmware/include/fpga_regs_standard.v
+firmware/include/fpga_regs_common.h
+firmware/include/generate_regs.py
+firmware/include/fpga_regs_standard.h
+host/lib/usrp_basic.h
+host/lib/usrp_basic.cc
+host/lib/usrp_standard.h
+fpga/rbf/Makefile.am
+fpga/toplevel/usrp_std/usrp_std.v
+fpga/toplevel/usrp_multi/usrp_multi.esf
+fpga/toplevel/usrp_multi/usrp_multi.vh
+fpga/toplevel/usrp_multi/usrp_std.vh
+fpga/toplevel/usrp_multi/usrp_multi_config_2rxhb_0tx.vh
+fpga/toplevel/usrp_multi/usrp_multi_config_2rxhb_2tx.vh
+fpga/toplevel/usrp_multi/usrp_multi.v
+fpga/toplevel/usrp_multi/usrp_multi.qpf
+fpga/toplevel/usrp_multi/usrp_multi.psf
+fpga/toplevel/usrp_multi/usrp_multi_config_2rx_0tx.vh
+fpga/toplevel/usrp_multi/usrp_multi.qsf
+fpga/toplevel/usrp_multi/usrp_multi_config_4rx_0tx.vh
+fpga/toplevel/usrp_multi/usrp_multi.csf
+fpga/toplevel/usrp_multi/.cvsignore
+fpga/sdr_lib/rx_buffer.v
+fpga/sdr_lib/master_control_multi.v
+fpga/sdr_lib/phase_acc.v
+fpga/sdr_lib/setting_reg_masked.v
+
+
diff --git a/gnuradio-examples/python/multi_usrp/multi_usrp_oscope.py b/gnuradio-examples/python/multi_usrp/multi_usrp_oscope.py
new file mode 100755 (executable)
index 0000000..d64cd1e
--- /dev/null
@@ -0,0 +1,343 @@
+#!/usr/bin/env python
+#
+# Copyright 2004,2005,2006 Free Software Foundation, Inc.
+# 
+# This file is part of GNU Radio
+# 
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 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.
+# 
+
+# print "Loading revised usrp_oscope with additional options for scopesink..."
+
+from gnuradio import gr, gru
+from gnuradio import usrp
+from gnuradio import eng_notation
+from gnuradio.eng_option import eng_option
+from gnuradio.wxgui import stdgui, fftsink, waterfallsink, scopesink, form, slider
+from optparse import OptionParser
+import wx
+import sys
+
+import time
+from gnuradio import usrp_multi
+
+
+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_flow_graph(stdgui.gui_flow_graph):
+    def __init__(self, frame, panel, vbox, argv):
+        stdgui.gui_flow_graph.__init__(self)
+
+        self.frame = frame
+        self.panel = panel
+        
+        parser = OptionParser(option_class=eng_option)
+        parser.add_option("-R", "--rx-subdev-spec", type="subdev", default=None,
+                          help="select USRP Rx side A or B (default=first one with a daughterboard)")
+        parser.add_option("-d", "--decim", type="int", default=128,
+                          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)")
+        #align interval is default not yet enabled in gr.align_on_samplenumbers_ss
+        #parser.add_option("-a", "--align_interval", type="int", default=-1,
+        #                  help="Align master and slave every so much samples.")
+
+        # width 8 does not work yet with multi_usrp because it interferes with the 32 bit samplecounter
+        #parser.add_option("-8", "--width-8", action="store_true", default=False,
+        #                  help="Enable 8-bit samples across USB")
+        parser.add_option("-m", "--mux", type="intx", default=None,
+                          help="set fpga FR_RX_MUX register to MUX")
+        parser.add_option("-n", "--frame-decim", type="int", default=1,
+                          help="set oscope frame decimation factor to n [default=1]")
+        parser.add_option("-N", "--nchan", type="int", default=2,
+                          help="set nchannels to NCHAN")
+        parser.add_option("-q", "--show-q", action="store_true", default=False,
+                          help="show the q value of the complex samples")
+        parser.add_option("-s", "--show-counters", action="store_true", default=False,
+                          help="show the counters")
+        parser.add_option("-v", "--v-scale", type="eng_float", default=1000,
+                          help="set oscope initial V/div to SCALE [default=%default]")
+        parser.add_option("-t", "--t-scale", type="eng_float", default=49e-6,
+                          help="set oscope initial s/div to SCALE [default=50us]")
+        parser.add_option("-x", "--master-serialno", type="string", default=None, 
+                          help="Serial_no of the usrp which should be the MASTER (default= select any)")
+        (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 = usrp.source_c(which=options.which_usrp,decim_rate=options.decim)
+        if (options.mux is None) | (4==options.nchan):
+           init_mux=None #use default mux which is 0x10321032
+        else:
+           init_mux=options.mux
+
+        init_gain=0.0
+        init_freq=0.0
+        init_align_interval=-1
+
+        self.multi=usrp_multi.multi_source_align( self,   options.master_serialno, options.decim,
+                                                 options.nchan, init_gain, init_freq, init_mux, init_align_interval)
+        self.um=self.multi.get_master_usrp()
+        self.us=self.multi.get_slave_usrp()
+
+        if options.rx_subdev_spec is None:
+            options.rx_subdev_spec = pick_subdevice(self.um)
+        if (options.mux==None) and (options.nchan!=4):
+          mux=usrp.determine_rx_mux_value(self.um, options.rx_subdev_spec)
+          mux= (mux<<8 & 0xffffffff) | (mux & 0xff)
+          self.um.set_mux(mux)
+          self.us.set_mux(mux)
+
+        # width 8 does not work yet with multi_usrp because it interferes with the 32 bit samplecounter
+        #if options.width_8:
+        #    width = 8
+        #    shift = 8
+        #    format = self.um.make_format(width, shift)
+        #    r = self.um.set_format(format)
+        #    r = self.us.set_format(format)
+            
+        # determine the daughterboard subdevice of the first channel we're using
+        self.subdevm = usrp.selected_subdev(self.um, options.rx_subdev_spec)
+        self.subdevs = usrp.selected_subdev(self.us, options.rx_subdev_spec)
+
+        input_rate = self.um.adc_freq() / self.um.decim_rate()
+
+        self.scope = scopesink.scope_sink_f(self, panel, sample_rate=input_rate,
+                                            frame_decim=options.frame_decim,
+                                            v_scale=options.v_scale,
+                                            t_scale=options.t_scale)
+        self.sink_count=0
+        self.add_to_scope((self.multi.get_master_source_c(),1),options.show_q)
+        self.add_to_scope((self.multi.get_slave_source_c(),1),options.show_q)
+        if 4==options.nchan:
+          self.add_to_scope((self.multi.get_master_source_c(),2),options.show_q)
+          self.add_to_scope((self.multi.get_slave_source_c(),2),options.show_q)
+
+        if options.show_counters:
+          self.add_to_scope((self.multi.get_master_source_c(),0),options.show_q)
+          self.add_to_scope((self.multi.get_slave_source_c(),0),options.show_q)
+
+        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.subdevm.gain_range()
+            options.gain = float(g[0]+g[1])/2
+
+        if options.freq is None:
+            # if no freq was specified, use the mid-point
+            r = self.subdevm.freq_range()
+            options.freq = float(r[0]+r[1])/2
+
+        self.set_gain(options.gain)
+
+        if self.show_debug_info:
+            self.myform['decim'].set_value(self.um.decim_rate())
+            self.myform['fs@usb'].set_value(self.um.adc_freq() / self.um.decim_rate())
+            self.myform['dbname'].set_value(self.subdevm.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")
+
+        self.multi.print_db_info()
+        self.unsynced=True
+        frame.Bind(wx.EVT_IDLE, self.onIdle)
+
+    def add_to_scope(self,source_c,show_q):
+        c2f= gr.complex_to_float ()
+        self.connect(source_c, c2f)
+        self.connect((c2f,0), (self.scope,self.sink_count))
+        self.sink_count=self.sink_count+1
+        if show_q:
+          self.connect((c2f,1), (self.scope,self.sink_count))
+          self.sink_count=self.sink_count+1
+        
+        
+    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.subdevm.gain_range()
+        myform['gain'] = form.slider_field(parent=self.panel, sizer=hbox, label="Gain",
+                                           weight=3,
+                                           min=int(g[0]), max=int(g[1]),
+                                           callback=self.set_gain)
+
+        hbox.Add((5,0), 0, 0)
+        buttonSync = form.button_with_callback(parent=self.panel, label='sync',callback=self.sync_usrps)
+        hbox.Add(buttonSync,0,wx.EXPAND)
+
+        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)
+        
+        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.static_float_field(
+            parent=panel, sizer=hbox, label="Decim")
+
+        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, sync=True):
+        """
+        Set the center frequency we're interested in for all channels,
+        on all rx daughterboards on MASTER and SLAVE.
+
+        @param target_freq: frequency in Hz
+        @param sync: sync the usrps after setting the freqs (this will clear any phase differences in the DDCS)
+        @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.
+        """
+        result,r1,r2,r3,r4 = self.multi.tune_all_rx(target_freq)
+        if sync:
+          self.sync_usrps() #sync master and slave and clear any DDC phase differences
+        if r1:
+            self.myform['freq'].set_value(target_freq)     # update displayed value
+            if self.show_debug_info:
+                self.myform['baseband'].set_value(r1.baseband_freq)
+                self.myform['ddc'].set_value(r1.dxc_freq)
+        return result
+
+    def set_freq_chan0(self, target_freq, sync=True):
+        """
+        Set the center frequency we're interested in for rx chan 0 only on MASTER and SLAVE.
+
+        @param target_freq: frequency in Hz
+        @param sync: sync the usrps after setting the freqs (this will clear any phase differences in the DDCS)
+        @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.
+        """
+        rm = usrp.tune(self.um, 0, self.subdevm, target_freq)
+        rs = usrp.tune(self.us, 0, self.subdevs, target_freq)
+        r=rm
+        if sync:
+          self.sync_usrps()  #sync master and slave and clear any DDC phase differences
+        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.multi.set_gain_all_rx(gain)
+
+    def set_gain_chan0(self, gain):
+        self.myform['gain'].set_value(gain)     # update displayed value
+        self.subdevm.set_gain(gain)
+        self.subdevs.set_gain(gain)
+
+    def onIdle(self,evt):
+        if self.unsynced:
+          time.sleep(0.5)
+          self.unsynced=True
+          self.multi.sync()
+          self.unsynced=False
+          #print 'synced'
+
+    def sync_usrps(self):
+        self.multi.sync()
+
+def main ():
+    app = stdgui.stdapp(app_flow_graph, "MULTI_USRP O'scope", nstatus=1)
+    app.MainLoop()
+
+if __name__ == '__main__':
+    main ()
diff --git a/gnuradio-examples/python/multi_usrp/multi_usrp_rx_cfile.py b/gnuradio-examples/python/multi_usrp/multi_usrp_rx_cfile.py
new file mode 100755 (executable)
index 0000000..6084aba
--- /dev/null
@@ -0,0 +1,131 @@
+#!/usr/bin/env python
+
+"""
+Read samples 2 from two linked synchronised USRP's and write to file formatted as binary
+single-precision complex values.
+Make sure you read README on how to link the two usrps
+
+"""
+
+from gnuradio import gr, eng_notation
+from gnuradio import audio
+from gnuradio import usrp
+from gnuradio.eng_option import eng_option
+from optparse import OptionParser
+import sys
+
+import time
+from gnuradio import usrp_multi
+
+class my_graph(gr.flow_graph):
+
+    def __init__(self):
+        gr.flow_graph.__init__(self)
+
+        usage="%prog: [options] output_filename"
+        parser = OptionParser(option_class=eng_option, usage=usage)
+        parser.add_option("-R", "--rx-subdev-spec", type="subdev", default=(0, 0),
+                          help="select USRP Rx side A or B (default=A)")
+        parser.add_option("-d", "--decim", type="int", default=128,
+                          help="set selfpa 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="eng_float", default=None,
+                          help="set gain in dB (default is midpoint)")
+        parser.add_option("-n", "--nchan", type="intx", default=2,
+                          help="set nchannels to NCHAN")
+        parser.add_option("-N", "--nsamples", type="eng_float", default=None,
+                          help="number of samples to collect [default=+inf]")
+        parser.add_option ("-o", "--output-file-m", default="usrp_rx_m.dat",
+                       help="write master data to FILE", metavar="FILE")
+        parser.add_option ("--output-file-m2", default="usrp_rx_m2.dat",
+                       help="write master data from second channel to FILE", metavar="FILE")
+        parser.add_option ("-p", "--output-file-s", default="usrp_rx_s.dat",
+                       help="write slave data to FILE", metavar="FILE")
+        parser.add_option ("--output-file-s2", default="usrp_rx_s2.dat",
+                       help="write slave data from second channel to FILE", metavar="FILE")
+        parser.add_option("-x", "--master-serialno", type="string", default=None, 
+                          help="Serial_no of the usrp which should be the MASTER (default= select any)")
+        (options, args) = parser.parse_args ()
+        if len(args) != 0:
+            parser.print_help()
+            raise SystemExit, 1
+
+        if options.freq is None:
+            parser.print_help()
+            sys.stderr.write('You must specify the frequency with -f FREQ\n');
+            raise SystemExit, 1
+
+        # build the graph
+        self.multi=usrp_multi.multi_source_align( fg=self, master_serialno=options.master_serialno, decim=options.decim, 
+                                                  nchan=options.nchan )
+        self.um=self.multi.get_master_usrp()
+        self.us=self.multi.get_slave_usrp()
+
+        dst_m=gr.file_sink (gr.sizeof_gr_complex, options.output_file_m)
+        dst_s=gr.file_sink (gr.sizeof_gr_complex, options.output_file_s)
+        if options.nsamples is None:
+            self.connect((self.multi.get_master_source_c(),1),dst_m)
+            self.connect((self.multi.get_slave_source_c(),1),dst_s)
+        else:
+            head_m = gr.head(gr.sizeof_gr_complex, int(options.nsamples))
+            head_s = gr.head(gr.sizeof_gr_complex, int(options.nsamples))
+            self.connect((self.multi.get_master_source_c(),1),head_m,dst_m)
+            self.connect((self.multi.get_slave_source_c(),1),head_s,dst_s)
+
+        if(4==options.nchan):
+            dst_m2=gr.file_sink (gr.sizeof_gr_complex, options.output_file_m2)
+            dst_s2=gr.file_sink (gr.sizeof_gr_complex, options.output_file_s2)
+            if options.nsamples is None:
+                self.connect((self.multi.get_master_source_c(),2),dst_m2)
+                self.connect((self.multi.get_slave_source_c(),2),dst_s2) 
+            else:
+                head_m2 = gr.head(gr.sizeof_gr_complex, int(options.nsamples))
+                head_s2 = gr.head(gr.sizeof_gr_complex, int(options.nsamples))
+                self.connect((self.multi.get_master_source_c(),2),head_m2,dst_m2)
+                self.connect((self.multi.get_slave_source_c(),2),head_s2,dst_s2) 
+
+        if options.rx_subdev_spec is None:
+            options.rx_subdev_spec = usrp.pick_rx_subdevice(self.um)
+
+        if (options.nchan!=4):
+          mux=usrp.determine_rx_mux_value(self.um, options.rx_subdev_spec)
+          mux= (mux<<8 & 0xffffffff) | (mux & 0xff)
+          self.um.set_mux(mux)
+          self.us.set_mux(mux)
+
+        # determine the daughterboard subdevice we're using
+        self.subdevm = usrp.selected_subdev(self.um, options.rx_subdev_spec)
+        self.subdevs = usrp.selected_subdev(self.us, options.rx_subdev_spec)
+        print "Using MASTER RX d'board %s" % (self.subdevm.side_and_name(),)
+        print "Using SLAVE RX d'board %s" % (self.subdevs.side_and_name(),)
+        input_rate = self.um.adc_freq() / self.um.decim_rate()
+        print "USB sample rate %s" % (eng_notation.num_to_str(input_rate))
+
+        if options.gain is None:
+            # if no gain was specified, use the mid-point in dB
+            g = self.subdevm.gain_range()
+            options.gain = float(g[0]+g[1])/2
+
+        self.multi.set_gain_all_rx(options.gain)
+        result,r1,r2,r3,r4 = self.multi.tune_all_rx(options.freq)
+        if not result:
+            sys.stderr.write('Failed to set frequency\n')
+            raise SystemExit, 1
+
+    def sync_usrps(self):
+        self.multi.sync()   
+       
+        
+if __name__ == '__main__':
+    fg=my_graph()
+    fg.start()
+    #time.sleep(0.5)
+    fg.sync_usrps() 
+    raw_input ('Press Enter to quit: ')
+    fg.stop()
+    #try:
+    #    fg.start()
+    #    fg.sync_usrps()
+    #except KeyboardInterrupt:
+    #    pass
diff --git a/gnuradio-examples/python/networking/measurement_slave.py b/gnuradio-examples/python/networking/measurement_slave.py
new file mode 100755 (executable)
index 0000000..2bc7c39
--- /dev/null
@@ -0,0 +1,241 @@
+#!/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 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.
+# 
+
+import struct
+import socket
+import asyncore
+import sys
+import optparse
+import random
+from gnuradio.eng_option import eng_option
+import gnuradio.gr.gr_threading as _threading
+
+LOOP_TIMEOUT = 0.001
+BROADCAST_ADDR = '255.255.255.255'
+
+BROADCAST_PORT = 27010   # UDP
+CONTROL_PORT   = 27011   # TCP
+
+PKT_HEADER_SIZE = 4      # 32-bit int
+
+logfile = None
+
+def unpack_header(s):
+    (len,) = struct.unpack('!i', s)
+    return (len,)
+
+def pack_header(len):
+    return struct.pack('!i', len)
+
+
+class control_port_listener(asyncore.dispatcher):
+    def __init__(self, port=CONTROL_PORT, udp_socket=None, verbose=False):
+        """
+        @param port: TCP port to listen on.
+        @type port: int
+        """
+        asyncore.dispatcher.__init__(self)
+
+        self._verbose = verbose
+        self._udp_socket = udp_socket
+
+        host = ''                       # symbolic name for localhost
+        self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
+        self.set_reuse_addr()
+
+        try:
+            self.bind((host, port))
+        except socket.error, err:
+            sys.stderr.write('Failed to bind to %s: %s\n' %
+                             ((host, port), os.strerror (err.args[0]),))
+            sys.exit(1)
+
+        self.listen(3)
+        
+    def handle_accept(self):
+        socket, addr = self.accept()
+        sys.stderr.write("handle_accept: %r\n" % (addr,))
+        if not(socket is None):
+            # instantiate a server
+            s = control_server(socket, addr, self._udp_socket, self._verbose)
+        
+
+class gr_dispatcher(asyncore.dispatcher):
+    def __init__(self, sock=None, map=None):
+        asyncore.dispatcher.__init__(self, sock=sock, map=map)
+
+    def read_packet(self):
+        """
+        Returns None or packet
+        """
+        s = self.recvall(PKT_HEADER_SIZE)
+        if s == '':
+            return None
+        
+        (payload_len,) = unpack_header(s)
+
+        payload_len = int(payload_len)
+        
+        if payload_len == 0:
+            payload = ''
+        else:
+            payload = self.recvall(payload_len)
+            if len(payload) != payload_len:
+                sys.stderr.write ('short recv, expected %d bytes, got %d\n' % (
+                    payload_len, len(payload)))
+                raise RuntimeError, "short recv"
+
+        return payload
+
+    def recvall(self, buffer_size):
+        result = ''
+        while len(result) < buffer_size:
+            data = self.recv(buffer_size - len(result))
+            if not data:
+                return ''
+            result += data
+        return result
+
+
+class pkt_receiver_thread(_threading.Thread):
+    def __init__(self, socket):
+        _threading.Thread.__init__(self)
+        self.setDaemon(1)
+        self.socket = socket
+        self.keep_running = True
+        self.start()
+
+    def run(self):
+        while self.keep_running:
+            pkt, sender = self.socket.recvfrom(10000)
+            if pkt:
+                if len(pkt) > 2:
+                    t = struct.unpack('!H', pkt[0:2])
+                    seqno = t[0]
+                else:
+                    seqno = -1
+                    
+                logfile.write('RCVD seqno %4d len %4d from %s\n' % (seqno, len(pkt), sender))
+                logfile.flush()
+
+
+class control_server(gr_dispatcher):
+    def __init__(self, socket, addr, udp_socket, verbose=False):
+        gr_dispatcher.__init__(self, sock=socket)
+        
+        self._udp_socket = udp_socket
+        self.verbose = verbose
+        self.setblocking(1)
+
+    def writable(self):
+        return False
+
+    def handle_read(self):
+        pkt = self.read_packet()
+        if pkt:
+            annotate = 'ANNOTATE'
+            if pkt.startswith(annotate):
+                logfile.write(pkt[len(annotate)+1:])
+                logfile.write('\n')
+                logfile.flush()
+            elif pkt.startswith('SEND'):
+                tokens = pkt.split()
+                if len(tokens) < 4:
+                    invalid_packet(pkt)
+                else:
+                    npkts = int(tokens[1])
+                    size = int(tokens[2])
+                    power = float(tokens[3])
+                    send_test_packets(self._udp_socket, npkts, size, power)
+            else:
+                invalid_packet(pkt)
+
+    def handle_close(self):
+        self.close()
+
+
+def invalid_packet(pkt):
+    sys.stderr.write('received unrecognized packet: %s\n' % (pkt,))
+
+
+def make_random_payload(size):
+    p = [0] * size
+    if 1:
+        for i in range(size):
+            p[i] = chr(random.randint(0, 255))
+    else:
+        for i in range(size):
+            p[i] = chr(i % 256)
+    return ''.join(p)
+
+
+def send_test_packets(udp_socket, npkts, size, power):
+    # we ignore power for now...
+    size = max(2, size)
+    payload = make_random_payload(size - 2)
+    for n in range(npkts):
+        pkt = struct.pack('!H', n) + payload
+        udp_socket.sendto(pkt, (BROADCAST_ADDR, BROADCAST_PORT))
+        #udp_socket.sendall(pkt)
+
+
+def open_udp_broadcast_socket(gr0_host_ip, port):
+    s  = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
+#    s.bind((gr0_host_ip, port))
+    s.bind(('', port))
+    s.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
+#    s.connect((BROADCAST_ADDR, port))
+    return s
+
+
+def main():
+    global logfile
+    
+    usage = 'usage: %prog [options] gr0-ip-addr'
+    parser = optparse.OptionParser (option_class=eng_option, usage=usage)
+    parser.add_option('-l', '--logfile', type='string', default=None,
+                      help="specify log file name [default=<stdout>]")
+    parser.add_option('-v', '--verbose', action="store_true", default=False,
+                      help="enable verbose diagnostics")
+
+    (options, args) = parser.parse_args ()
+    if len(args) != 1:
+        parser.print_help()
+        sys.exit(1)
+
+    gr0_ip_addr = args[0]
+    if options.logfile is None:
+        logfile = sys.stdout
+    else:
+        logfile = file(options.logfile, 'w')
+
+    udp_socket = open_udp_broadcast_socket(gr0_ip_addr, BROADCAST_PORT)
+    R = pkt_receiver_thread(udp_socket)
+    L = control_port_listener(CONTROL_PORT, udp_socket=udp_socket, verbose=options.verbose)
+    asyncore.loop(LOOP_TIMEOUT)
+
+
+if __name__ == '__main__':
+    try:
+        main()
+    except KeyboardInterrupt:
+        pass
diff --git a/gnuradio-examples/python/usrp/Makefile.am b/gnuradio-examples/python/usrp/Makefile.am
new file mode 100644 (file)
index 0000000..32442d5
--- /dev/null
@@ -0,0 +1,52 @@
+#
+# 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 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.
+# 
+
+EXTRA_DIST =                                   \
+       am_rcv.py                               \
+       ayfabtu.py                              \
+       benchmark_usb.py                        \
+       fm_tx4.py                               \
+       fsk_loopback.py                         \
+       fsk_rx.py                               \
+       fsk_tx.py                               \
+       max_power.py                            \
+       test_counting.py                        \
+       test_dft_analysis.py                    \
+       test_dft_synth.py                       \
+       test_digital_loopback_counting.py       \
+       test_digital_loopback_lfsr.py           \
+       tvrx_am_rcv_gui.py                      \
+       tvrx_tv_rcv.py                          \
+       usrp_fft.py                             \
+       usrp_fft_old.py                         \
+       usrp_nbfm_ptt.py                        \
+       usrp_nbfm_rcv.py                        \
+       usrp_oscope.py                          \
+       usrp_rx_cfile.py                        \
+       usrp_rx_file.py                         \
+       usrp_rx_nogui.py                        \
+       usrp_siggen.py                          \
+       usrp_wfm_rcv.py                         \
+       usrp_wfm_rcv_nogui.py                   \
+       usrp_wfm_rcv2_nogui.py                  \
+       usrp_wfm_rcv_pll.py                     \
+       usrp_wxapt_rcv.py                       \
+       wfm_rcv_file.py                         
diff --git a/gnuradio-examples/python/usrp/am_rcv.py b/gnuradio-examples/python/usrp/am_rcv.py
new file mode 100755 (executable)
index 0000000..2908dcb
--- /dev/null
@@ -0,0 +1,115 @@
+#!/usr/bin/env python
+
+from gnuradio import gr, eng_notation
+from gnuradio import audio
+from gnuradio import usrp
+from gnuradio.eng_option import eng_option
+from optparse import OptionParser
+import sys
+import math
+
+from gnuradio.wxgui import stdgui, fftsink
+import wx
+
+class am_rx_graph (stdgui.gui_flow_graph):
+    def __init__(self,frame,panel,vbox,argv):
+        stdgui.gui_flow_graph.__init__ (self,frame,panel,vbox,argv)
+
+        station = parseargs(argv[1:])
+        offset_freq = 30e3
+        IF_freq = offset_freq - station
+
+        adc_rate = 64e6
+        usrp_decim = 250
+        if_rate = adc_rate / usrp_decim               # 256 kHz
+        if_decim = 4
+        demod_rate = if_rate / if_decim        # 64 kHz
+        audio_decimation = 2
+        audio_rate = demod_rate / audio_decimation  # 16 kHz
+        
+        # usrp is data source
+        src = usrp.source_c (0, usrp_decim)
+        src.set_rx_freq (0, IF_freq)
+        actual_IF_freq =src.rx_freq(0)
+        actual_offset = actual_IF_freq + station
+        
+        #print actual_IF_freq
+        #print actual_offset
+        src.set_pga(0,20)
+        # sound card as final sink
+        audio_sink = audio.sink (int (audio_rate))
+        
+        channel_coeffs = \
+                       gr.firdes.low_pass (1.0,           # gain
+                                           if_rate,   # sampling rate
+                                           9e3,         # low pass cutoff freq
+                                           10e3,         # width of trans. band
+                                           gr.firdes.WIN_HANN)
+
+        ddc =  gr.freq_xlating_fir_filter_ccf (if_decim,channel_coeffs,-actual_offset,if_rate)
+
+        magblock = gr.complex_to_mag()
+        volumecontrol = gr.multiply_const_ff(.003)
+
+        # Deemphasis.  Is this necessary on AM?
+        TAU  = 75e-6  # 75us in US, 50us in EUR
+        fftaps = [ 1 - math.exp(-1/TAU/if_rate), 0]
+        fbtaps= [ 0 , math.exp(-1/TAU/if_rate) ]
+        
+        deemph = gr.iir_filter_ffd(fftaps,fbtaps)
+
+        # compute FIR filter taps for audio filter
+        width_of_transition_band = audio_rate / 8
+        audio_coeffs = gr.firdes.low_pass (1.0,            # gain
+                                           if_rate,      # sampling rate
+                                           9e3,         #audio_rate/2 - width_of_transition_band,
+                                           4e3,         # width_of_transition_band,
+                                           gr.firdes.WIN_HANN)
+        
+        # input: float; output: float
+        audio_filter = gr.fir_filter_fff (audio_decimation, audio_coeffs)
+
+
+
+        
+        print len(channel_coeffs)
+        print len(audio_coeffs)
+        
+        # now wire it all together
+        self.connect (src, ddc)
+        self.connect (ddc, magblock)
+        self.connect (magblock, volumecontrol)
+        self.connect (volumecontrol,deemph)
+        self.connect (deemph,audio_filter)
+        self.connect (audio_filter, (audio_sink, 0))
+
+        if 1:
+            pre_demod = fftsink.fft_sink_c (self, panel, title="Pre-Demodulation", fft_size=128, sample_rate=if_rate)
+            self.connect (src, pre_demod)
+            vbox.Add (pre_demod.win, 1, wx.EXPAND)
+
+        if 0:
+            post_demod = fftsink.fft_sink_c (self, panel, title="Post Demodulation", fft_size=256, sample_rate=demod_rate)
+            self.connect (ddc, post_demod)
+            vbox.Add (post_demod.win, 1, wx.EXPAND)
+
+        if 0:
+            post_filt = fftsink.fft_sink_f (self, panel, title="Post Filter", fft_size=512, sample_rate=audio_rate)
+            self.connect (magblock,post_filt)
+            vbox.Add (post_filt.win, 1, wx.EXPAND)
+        
+def parseargs (args):
+    nargs = len (args)
+    if nargs == 1:
+        freq1 = float (args[0]) * 1e3
+    else:
+        sys.stderr.write ('usage: am_rcv freq1\n')
+        sys.exit (1)
+
+    return freq1
+
+if __name__ == '__main__':
+    app = stdgui.stdapp (am_rx_graph, "AM RX")
+    app.MainLoop ()
+
diff --git a/gnuradio-examples/python/usrp/ayfabtu.dat b/gnuradio-examples/python/usrp/ayfabtu.dat
new file mode 100644 (file)
index 0000000..5c65cf4
Binary files /dev/null and b/gnuradio-examples/python/usrp/ayfabtu.dat differ
diff --git a/gnuradio-examples/python/usrp/ayfabtu.py b/gnuradio-examples/python/usrp/ayfabtu.py
new file mode 100755 (executable)
index 0000000..7647e93
--- /dev/null
@@ -0,0 +1,169 @@
+#!/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 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.
+# 
+
+#
+# All Your Frequencies are Belong to Us!
+#
+#   Transmit NBFM message on 25 channels simultaneously!
+#
+
+from gnuradio import gr, gru, eng_notation
+from gnuradio import usrp
+from gnuradio import audio
+from gnuradio import blks
+from gnuradio import optfir
+from gnuradio.eng_option import eng_option
+from optparse import OptionParser
+import math
+import sys
+import random
+
+from gnuradio.wxgui import stdgui, fftsink
+import wx
+
+
+def make_random_complex_tuple(L):
+    result = []
+    for x in range(L):
+        result.append(complex(random.gauss(0, 1),random.gauss(0, 1)))
+                      
+    return tuple(result)
+
+def random_noise_c():
+    src = gr.vector_source_c(make_random_complex_tuple(32*1024), True)
+    return src
+
+
+def plot_taps(taps, sample_rate=2):
+    return gru.gnuplot_freqz (gru.freqz (taps, 1), sample_rate)
+    
+
+class ayfabtu_graph (stdgui.gui_flow_graph):
+    def __init__(self, frame, panel, vbox, argv):
+        stdgui.gui_flow_graph.__init__ (self, frame, panel, vbox, argv)
+
+        parser = OptionParser (option_class=eng_option)
+        parser.add_option ("-c", "--duc-freq", type="eng_float", default=29.325e6,
+                           help="set Tx ddc frequency to FREQ", metavar="FREQ")
+        (options, args) = parser.parse_args ()
+
+        nchan = 25
+        IF_GAIN = 80000
+        AUDIO_GAIN = 100
+        
+        self.dac_rate = 128e6
+        self.usrp_interp = 256
+        self.usrp_rate = self.dac_rate / self.usrp_interp    # 500 kS/s
+        self.audio_rate = 32000                              # 32 kS/s
+
+        self.audio_src = gr.file_source(gr.sizeof_float, "ayfabtu.dat", True)
+
+        ahp_taps = gr.firdes.high_pass(1,     # gain
+                                       32e3,  # Fs
+                                       300,   # cutoff
+                                       600,   # trans width
+                                       gr.firdes.WIN_HANN)
+        self.audio_hp = gr.fir_filter_fff(1, ahp_taps)
+
+        self.audio_gain = gr.multiply_const_ff(AUDIO_GAIN)
+
+        null_src = gr.null_source(gr.sizeof_gr_complex)
+        #noise_src = gr.noise_source_c(gr.GR_UNIFORM, 1, 0)
+        noise_src = random_noise_c()
+
+        if 0:
+            artaps = optfir.low_pass(1,       # gain
+                                     2,       # Fs
+                                     .75/32,  # freq1
+                                     1.0/32,  # freq2
+                                     1,       # pb ripple in dB
+                                     50,      # stopband atten in dB
+                                     2)       # + extra taps
+        else:
+            artaps = gr.firdes.low_pass(1,      # gain
+                                        32e3*15,# Fs
+                                        2.7e3,  # cutoff
+                                         .3e3,  # trans width
+                                        gr.firdes.WIN_HANN)
+        print "len(artaps) =", len(artaps)
+        self.audio_resampler = blks.rational_resampler_fff(self, 15, 32, artaps)
+
+        self.fm_mod = blks.nbfm_tx(self, 15000, 15000, max_dev=4.5e3)
+
+
+        fbtaps = gr.firdes.low_pass(1,                # gain
+                                    25*15e3,          # rate
+                                    13e3,             # cutoff
+                                    2e3,              # trans width
+                                    gr.firdes.WIN_HANN)
+        print "len(fbtabs) =", len(fbtaps)
+        #self.plot = plot_taps(fbtaps, 25*15e3)
+        self.filter_bank = blks.synthesis_filterbank(self, nchan, fbtaps)
+        
+        self.if_gain = gr.multiply_const_cc(IF_GAIN)
+
+        if 0:
+            ifrtaps = optfir.low_pass(1,
+                                      2,       # Fs
+                                      .75/3,   # freq1
+                                      1.0/3,   # freq2
+                                      1,       # pb ripple in dB
+                                      50,      # stopband atten in dB
+                                      2)       # + extra taps
+        else:
+            ifrtaps = gr.firdes.low_pass(1,
+                                         2,       # Fs
+                                         .75/3,   # freq1
+                                         .25/3,   # trans width
+                                         gr.firdes.WIN_HANN)
+
+
+        print "len(ifrtaps) =", len(ifrtaps)
+        self.if_resampler = blks.rational_resampler_ccf(self, 4, 3, ifrtaps)
+
+
+        self.u = usrp.sink_c(0, 256)
+        self.u.set_tx_freq(0, options.duc_freq)
+        self.u.set_pga(0, self.u.pga_max())
+
+        # wire it all together
+        
+        self.connect(self.audio_src, self.audio_hp, self.audio_gain,
+                     self.audio_resampler, self.fm_mod)
+
+        null_sink = gr.null_sink(gr.sizeof_gr_complex)
+
+        for i in range(nchan):
+            if True or i == 0:
+                self.connect(self.fm_mod, (self.filter_bank, i))
+            else:
+                self.connect(null_src, (self.filter_bank, i))
+
+        self.connect(self.filter_bank, self.if_gain, self.if_resampler, self.u)
+        
+
+def main ():
+    app = stdgui.stdapp (ayfabtu_graph, "All Your Frequency Are Belong to Us")
+    app.MainLoop ()
+
+if __name__ == '__main__':
+    main ()
diff --git a/gnuradio-examples/python/usrp/benchmark_usb.py b/gnuradio-examples/python/usrp/benchmark_usb.py
new file mode 100755 (executable)
index 0000000..8418f50
--- /dev/null
@@ -0,0 +1,106 @@
+#!/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 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.
+# 
+
+"""
+Benchmark the USB/USRP throughput.  Finds the maximum full-duplex speed
+the USRP/USB combination can sustain without errors.
+
+This program does not currently give reliable results.  Sorry about that...
+"""
+
+from gnuradio import gr
+from gnuradio import usrp
+from gnuradio import eng_notation
+
+import sys
+
+def run_test (usb_throughput, verbose):
+    # usb_throughput is in bytes/sec.
+    #
+    # Returns True or False
+    
+    nsec = 1
+    stream_length = int (usb_throughput/2 * nsec)   # length of stream to examine
+
+    adc_freq =  64e6
+    dac_freq = 128e6
+    sizeof_sample = 2 * gr.sizeof_short
+
+    usb_throughput_in_samples = usb_throughput / sizeof_sample
+
+    # allocate usb throughput 50/50 between Tx and Rx
+
+    tx_interp = int (dac_freq) / int (usb_throughput_in_samples / 2)
+    rx_decim  = int (adc_freq) / int (usb_throughput_in_samples / 2)
+
+    # print "tx_interp =", tx_interp, "rx_decim =", rx_decim
+    assert (tx_interp == 2 * rx_decim)
+    
+    fg = gr.flow_graph ()
+
+    # Build the Tx pipeline
+    data_src = gr.lfsr_32k_source_s ()
+    src_head = gr.head (gr.sizeof_short, int (stream_length * 2))
+    usrp_tx = usrp.sink_s (0, tx_interp)
+    fg.connect (data_src, src_head, usrp_tx)
+
+    # and the Rx pipeline
+    usrp_rx = usrp.source_s (0, rx_decim, 1, 0x32103210, usrp.FPGA_MODE_LOOPBACK)
+    head = gr.head (gr.sizeof_short, stream_length)
+    check = gr.check_lfsr_32k_s ()
+    fg.connect (usrp_rx, head, check)
+
+    fg.run ()
+
+    ntotal = check.ntotal ()
+    nright = check.nright ()
+    runlength = check.runlength ()
+
+    if verbose:
+        print "usb_throughput =", eng_notation.num_to_str (usb_throughput)
+        print "ntotal    =", ntotal
+        print "nright    =", nright
+        print "runlength =", runlength
+        print "delta     =", ntotal - runlength
+
+    return runlength >= stream_length - 80000
+    
+def main ():
+    verbose = True
+    best_rate = 0
+    usb_rate = [ 2e6, 4e6, 8e6, 16e6, 32e6 ]
+    #usb_rate = [ 32e6, 32e6, 32e6, 32e6, 32e6 ]
+    # usb_rate.reverse ()
+    for rate in usb_rate:
+        sys.stdout.write ("Testing %sB/sec... " % (eng_notation.num_to_str (rate)))
+        sys.stdout.flush ()
+        ok = run_test (rate, verbose)
+        if ok:
+            best_rate = max (best_rate, rate)
+            sys.stdout.write ("OK\n")
+        else:
+            sys.stdout.write ("FAILED\n")
+
+    print "Max USB/USRP throughput = %sB/sec" % (eng_notation.num_to_str (best_rate),)
+
+if __name__ == '__main__':
+    main ()
diff --git a/gnuradio-examples/python/usrp/dsb_tx.py b/gnuradio-examples/python/usrp/dsb_tx.py
new file mode 100755 (executable)
index 0000000..df65761
--- /dev/null
@@ -0,0 +1,51 @@
+#!/usr/bin/env python
+
+from gnuradio import gr, eng_notation
+from gnuradio import usrp
+from gnuradio import audio
+from gnuradio.eng_option import eng_option
+from optparse import OptionParser
+
+
+def build_graph (cordic_freq):
+
+    audio_rate = 32000
+    sw_interp = 4
+    usrp_interp = 1000
+    audio_file = "/home/eb/demo/testing-audio.dat"
+    
+    fg = gr.flow_graph ()
+
+    src = gr.file_source (gr.sizeof_float, audio_file, True)
+    gain = gr.multiply_const_ff (10000)
+
+    interp = gr.interp_fir_filter_fff (sw_interp, (1, 1, 1, 1))
+
+    f2c = gr.float_to_complex ()
+    
+    u = usrp.sink_c (0, usrp_interp)
+    u.set_tx_freq (0, cordic_freq)
+
+    fg.connect (src, gain)
+    fg.connect (gain, interp)
+    fg.connect (interp, (f2c, 0))
+    fg.connect (interp, (f2c, 1))
+    fg.connect (f2c, u)
+
+    return fg
+
+def main ():
+    parser = OptionParser (option_class=eng_option)
+    parser.add_option ("-c", "--cordic-freq", type="eng_float", default=10e6,
+                       help="set Tx cordic frequency to FREQ", metavar="FREQ")
+    (options, args) = parser.parse_args ()
+
+    print "cordic_freq = %s" % (eng_notation.num_to_str (options.cordic_freq))
+    fg = build_graph (options.cordic_freq)
+    
+    fg.start ()
+    raw_input ('Press Enter to quit: ')
+    fg.stop ()
+
+if __name__ == '__main__':
+    main ()
diff --git a/gnuradio-examples/python/usrp/flexrf_debug.py b/gnuradio-examples/python/usrp/flexrf_debug.py
new file mode 100755 (executable)
index 0000000..70c6309
--- /dev/null
@@ -0,0 +1,169 @@
+#!/usr/bin/env 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.
+# 
+
+from gnuradio import gr, gru
+from gnuradio import usrp
+from gnuradio import eng_notation
+from gnuradio.eng_option import eng_option
+from gnuradio.wxgui import stdgui, fftsink, scopesink, slider
+from optparse import OptionParser
+import wx
+
+class app_flow_graph (stdgui.gui_flow_graph):
+    def __init__(self, frame, panel, vbox, argv):
+        stdgui.gui_flow_graph.__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=8,
+                           help="set fgpa decimation rate to DECIM")
+        parser.add_option ("-c", "--ddc-freq", type="eng_float", default=0,
+                           help="set Digital downconverter frequency to FREQ", metavar="FREQ")
+        parser.add_option ("-f", "--freq", type="eng_float", default=950e6,
+                           help="set RF downconverter frequency to FREQ", metavar="FREQ")
+        parser.add_option ("-m", "--mux", type="intx", default=0x32103210,
+                           help="set fpga FR_RX_MUX register to MUX")
+        parser.add_option ("-g", "--gain", type="eng_float", default=0,
+                           help="set Rx PGA gain in dB (default 0 dB)")
+        (options, args) = parser.parse_args ()
+
+        self.u = usrp.source_c (0, options.decim, 1, gru.hexint(options.mux), 0)
+        
+        self.u.set_verbose (0)
+        
+        input_rate = self.u.adc_freq () / self.u.decim_rate ()
+
+        block = fftsink.fft_sink_c (self, panel, fft_size=1024, sample_rate=input_rate)
+        self.connect (self.u, block)
+        vbox.Add (block.win, 10, wx.EXPAND)
+
+       if 0:
+            c2f_1 = gr.complex_to_float ()
+            scope = scopesink.scope_sink_f (self, panel, "Rx Data", input_rate)
+            vbox.Add (scope.win, 6, wx.EXPAND)
+
+            self.connect (self.u,c2f_1)
+            self.connect ((c2f_1, 0), (scope, 0))
+            self.connect ((c2f_1, 1), (scope, 1))
+
+        if 0:
+            rms_complex = gr.rms_cf(.0001)
+            rms_i = gr.rms_ff(.0001)
+            rms_q = gr.rms_ff(.0001)
+            
+            self.connect(self.u,rms_complex)
+            self.connect((c2f_1,0),rms_i)
+            self.connect((c2f_1,1),rms_q)
+            
+            ns1 = gr.null_sink(4)
+            ns2 = gr.null_sink(4)
+            ns3 = gr.null_sink(4)
+            
+            self.connect(rms_complex,ns1)
+            self.connect(rms_i,ns2)
+            self.connect(rms_q,ns3)
+
+        # sliders
+
+        #vbox.Add(slider.slider(panel, 0, 104, self.set_gain), 1, wx.ALIGN_CENTER)
+
+        #vbox.Add(slider.slider(panel, 0, 4095, self.set_gain_gc1), 1, wx.ALIGN_CENTER)
+        #vbox.Add(slider.slider(panel, 0, 31, self.set_gain_gc2), 1, wx.ALIGN_CENTER)
+        #vbox.Add(slider.slider(panel, 0, 1, self.set_gain_dl), 1, wx.ALIGN_CENTER)
+        #vbox.Add(slider.slider(panel, 0, 200, self.set_gain_i), 1, wx.ALIGN_CENTER)
+        #vbox.Add(slider.slider(panel, 0, 200, self.set_gain_q), 1, wx.ALIGN_CENTER)
+
+        self.offset = 0
+        #vbox.Add(slider.slider(panel, -200, 200, self.set_offset_i), 1, wx.ALIGN_CENTER)
+        #vbox.Add(slider.slider(panel, -200, 200, self.set_offset_q), 1, wx.ALIGN_CENTER)
+
+        vbox.Add(slider.slider(panel, 380, 480, self.set_rf_freq), 1, wx.EXPAND|wx.ALIGN_CENTER)
+        vbox.Add(slider.slider(panel, -32000, +32000, self.set_if_freq), 1, wx.EXPAND|wx.ALIGN_CENTER)
+        vbox.Add(slider.slider(panel, 0, 4095, self.set_gain), 1, wx.EXPAND|wx.ALIGN_CENTER)
+
+        # build small control area at bottom
+        hbox = wx.BoxSizer (wx.HORIZONTAL)
+        hbox.Add ((1, 1), 1, wx.EXPAND)
+        hbox.Add (wx.StaticText (panel, -1, "Set ddc freq: "), 0, wx.ALIGN_CENTER)
+        self.tc_freq = wx.TextCtrl (panel, -1, "", style=wx.TE_PROCESS_ENTER)
+        hbox.Add (self.tc_freq, 0, wx.ALIGN_CENTER)
+        wx.EVT_TEXT_ENTER (self.tc_freq, self.tc_freq.GetId(), self.handle_text_enter)
+        hbox.Add ((1, 1), 1, wx.EXPAND)
+        # add it to the main vbox
+        vbox.Add (hbox, 0, wx.EXPAND)
+
+        self.update_status_bar ()
+
+    def set_rf_freq (self,freq):
+        (success,actual_freq) = self.set_freq(1e6*freq)
+        if not success:
+            print "Failed on ",freq
+    def set_if_freq (self,freq):
+        self.u.set_rx_freq(0,freq*1e3)
+            
+    def set_gain (self,gain):
+        self.rfrx.set_gain(gain)
+
+    def set_gain_i (self,gain):
+        self.u.set_pga(0,gain/10.0)
+    def set_gain_q (self,gain):
+        self.u.set_pga(1,gain/10.0)
+
+    def set_offset_i(self,offset):
+        self.offset = (self.offset & 0x0000ffff) | ((offset&0xffff)<<16)
+        self.u._write_fpga_reg (3,self.offset)
+
+    def set_offset_q(self,offset):
+        self.offset = (self.offset & 0xffff0000) | (offset&0xffff)
+        self.u._write_fpga_reg (3,self.offset)
+
+    def handle_text_enter (self, event):
+        str = event.GetString ()
+        self.tc_freq.Clear ()
+        self.u.set_rx_freq (0, eng_notation.str_to_num (str))
+        self.update_status_bar ()
+
+    def update_status_bar (self):
+        ddc_freq = self.u.rx_freq (0)
+        decim_rate = self.u.decim_rate ()
+        sample_rate = self.u.adc_freq () / decim_rate
+        msg = "decim: %d  %sS/s  DDC: %s" % (
+            decim_rate,
+            eng_notation.num_to_str (sample_rate),
+            eng_notation.num_to_str (ddc_freq))
+            
+        self.frame.GetStatusBar().SetStatusText (msg, 1)
+
+    def set_gain(self,gain):
+        assert gain>=0 and gain<4096
+        self.u.write_aux_dac(0,0,int(gain))
+        
+def main ():
+    app = stdgui.stdapp (app_flow_graph, "USRP FFT")
+    app.MainLoop ()
+
+if __name__ == '__main__':
+    main ()
+
+
diff --git a/gnuradio-examples/python/usrp/flexrf_siggen.py b/gnuradio-examples/python/usrp/flexrf_siggen.py
new file mode 100755 (executable)
index 0000000..6a59148
--- /dev/null
@@ -0,0 +1,148 @@
+#!/usr/bin/env python
+
+from gnuradio import gr, gru
+from gnuradio import usrp
+from gnuradio.eng_option import eng_option
+from optparse import OptionParser
+from gnuradio.wxgui import stdgui, slider
+import wx
+
+class flex_siggen (stdgui.gui_flow_graph):
+    __slots__ = ['interp', 'waveform_type', 'waveform_ampl',
+                 'waveform_freq', 'waveform_offset', 'fg', 'usrp',
+                 'siggen', 'noisegen', 'src', 'file_sink' ]
+
+    def __init__ (self,frame,panel,vbox,argv):
+        stdgui.gui_flow_graph.__init__ (self, frame, panel, vbox, argv)
+        
+        self.frame = frame
+        self.panel = panel
+
+        parser = OptionParser (option_class=eng_option)
+        parser.add_option ("-a", "--amplitude", type="int", default=32000,
+                           help="amplitude")
+        parser.add_option ("-i", "--interp", type="int", default=64,
+                           help="set fpga interpolation rate to INTERP")
+        parser.add_option ("-n", "--nchannels", type="int", default=1,
+                           help="set number of output channels to NCHANNELS")
+        (options, args) = parser.parse_args ()
+
+        self.waveform_type = gr.GR_CONST_WAVE
+        self.waveform_ampl = options.amplitude
+        self.waveform_freq = 100.12345e3
+        self.waveform_offset = 0
+
+        self.interp = options.interp
+        self._instantiate_blocks ()
+        self.usrp.set_nchannels (options.nchannels)
+        
+        self.dboard=self.usrp.db[0][0]
+        
+        self.set_waveform_type (self.waveform_type)
+        vbox.Add(slider.slider(panel, 390, 510, self.set_rf_freq), 1, wx.EXPAND|wx.ALIGN_CENTER)
+        vbox.Add(slider.slider(panel, -45000, +45000, self.set_if_freq), 1, wx.EXPAND|wx.ALIGN_CENTER)
+        #vbox.Add(slider.slider(panel, 0, 4095, self.set_gain), 1, wx.EXPAND|wx.ALIGN_CENTER)
+        
+    def usb_freq (self):
+        return self.usrp.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_if_freq (self, freq):
+        self.if_freq = freq
+        self.usrp.set_tx_freq (0,freq*1e3)
+        
+    def set_rf_freq (self, freq):
+        self.rf_freq = freq
+        (success,actual_freq) = self.dboard.set_freq (freq*1e6)
+        if not success:
+            print "Failed on ", 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.usrp.set_interp_rate (interp)
+
+    def set_duc_freq (self, freq):
+        self.usrp.set_tx_freq (0, freq)
+        
+    def _instantiate_blocks (self):
+        self.src = None
+        self.usrp = 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)
+        print "done"
+        
+    def _configure_graph (self, type):
+        was_running = self.is_running ()
+        if was_running:
+            self.stop ()
+        self.disconnect_all ()
+        if type == gr.GR_SIN_WAVE or type == gr.GR_CONST_WAVE:
+            self.connect (self.siggen, self.usrp)
+            self.siggen.set_waveform (type)
+            self.src = self.siggen
+        elif type == gr.GR_UNIFORM or type == gr.GR_GAUSSIAN:
+            self.connect (self.noisegen, self.usrp)
+            self.noisegen.set_type (type)
+            self.src = self.noisegen
+        else:
+            raise ValueError, type
+        if was_running:
+            self.start ()
+
+
+if __name__ == '__main__':
+    parser = OptionParser (option_class=eng_option)
+    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 ("-f", "--freq", type="eng_float", default=100e3,
+                       help="set waveform frequency to FREQ")
+    parser.add_option ("-r", "--rf-freq", type="eng_float", default=910e6,
+                       help="set waveform frequency to FREQ")
+    parser.add_option ("-a", "--amplitude", type="eng_float", default=16e3,
+                       help="set waveform amplitude to AMPLITUDE", metavar="AMPL")
+    parser.add_option ("-o", "--offset", type="eng_float", default=0,
+                       help="set waveform offset to OFFSET")
+    parser.add_option ("-c", "--duc-freq", type="eng_float", default=0,
+                       help="set Tx DUC frequency to FREQ", metavar="FREQ")
+    parser.add_option ("-m", "--mux", type="intx", default=0x98,
+                       help="set output mux register")
+    
+    app = stdgui.stdapp (flex_siggen, "USRP FlexRF Siggen")
+    app.MainLoop ()
diff --git a/gnuradio-examples/python/usrp/fm_tx4.py b/gnuradio-examples/python/usrp/fm_tx4.py
new file mode 100755 (executable)
index 0000000..a9201b3
--- /dev/null
@@ -0,0 +1,171 @@
+#!/usr/bin/env python
+
+"""
+Transmit N simultaneous narrow band FM signals.
+
+They will be centered at the frequency specified on the command line,
+and will spaced at 25kHz steps from there.
+
+The program opens N files with names audio-N.dat where N is in [0,7].
+These files should contain floating point audio samples in the range [-1,1]
+sampled at 32kS/sec.  You can create files like this using
+audio_to_file.py
+"""
+
+from gnuradio import gr, eng_notation
+from gnuradio import usrp
+from gnuradio import audio
+from gnuradio import blks
+from gnuradio.eng_option import eng_option
+from optparse import OptionParser
+import usrp_dbid
+import math
+import sys
+
+from gnuradio.wxgui import stdgui, fftsink
+from gnuradio import tx_debug_gui
+import wx
+
+
+########################################################
+# instantiate one transmit chain for each call
+
+class pipeline(gr.hier_block):
+    def __init__(self, fg, filename, lo_freq, audio_rate, if_rate):
+
+        src = gr.file_source (gr.sizeof_float, filename, True)
+        fmtx = blks.nbfm_tx (fg, 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 ()
+    
+        fg.connect (src, fmtx, (mixer, 0))
+        fg.connect (lo, (mixer, 1))
+
+        gr.hier_block.__init__(self, fg, src, mixer)
+
+
+
+class fm_tx_graph (stdgui.gui_flow_graph):
+    def __init__(self, frame, panel, vbox, argv):
+        MAX_CHANNELS = 7
+        stdgui.gui_flow_graph.__init__ (self, frame, panel, vbox, argv)
+
+        parser = OptionParser (option_class=eng_option)
+        parser.add_option("-T", "--tx-subdev-spec", type="subdev", default=None,
+                          help="select USRP Tx side A or B")
+        parser.add_option("-f", "--freq", type="eng_float", default=None,
+                           help="set Tx frequency to FREQ [required]", metavar="FREQ")
+        parser.add_option("-n", "--nchannels", type="int", default=4,
+                           help="number of Tx channels [1,4]")
+        parser.add_option("","--debug", action="store_true", default=False,
+                          help="Launch Tx debugger")
+        (options, args) = parser.parse_args ()
+
+        if len(args) != 0:
+            parser.print_help()
+            sys.exit(1)
+
+        if options.nchannels < 1 or options.nchannels > MAX_CHANNELS:
+            sys.stderr.write ("fm_tx4: nchannels out of range.  Must be in [1,%d]\n" % MAX_CHANNELS)
+            sys.exit(1)
+        
+        if options.freq is None:
+            sys.stderr.write("fm_tx4: must specify frequency with -f FREQ\n")
+            parser.print_help()
+            sys.exit(1)
+
+        # ----------------------------------------------------------------
+        # Set up constants and parameters
+
+        self.u = usrp.sink_c ()       # the USRP sink (consumes samples)
+
+        self.dac_rate = self.u.dac_rate()                    # 128 MS/s
+        self.usrp_interp = 400
+        self.u.set_interp_rate(self.usrp_interp)
+        self.usrp_rate = self.dac_rate / self.usrp_interp    # 320 kS/s
+        self.sw_interp = 10
+        self.audio_rate = self.usrp_rate / self.sw_interp    # 32 kS/s
+
+        # determine the daughterboard subdevice we're using
+        if options.tx_subdev_spec is None:
+            options.tx_subdev_spec = usrp.pick_tx_subdevice(self.u)
+
+        m = usrp.determine_tx_mux_value(self.u, options.tx_subdev_spec)
+        #print "mux = %#04x" % (m,)
+        self.u.set_mux(m)
+        self.subdev = usrp.selected_subdev(self.u, options.tx_subdev_spec)
+        print "Using TX d'board %s" % (self.subdev.side_and_name(),)
+
+        self.subdev.set_gain(self.subdev.gain_range()[1])    # set max Tx gain
+        self.set_freq(options.freq)
+        self.subdev.set_enable(True)                         # enable transmitter
+
+        sum = gr.add_cc ()
+
+        # Instantiate N NBFM channels
+        step = 25e3
+        offset = (0 * step, 1 * step, -1 * step, 2 * step, -2 * step, 3 * step, -3 * step)
+        for i in range (options.nchannels):
+            t = pipeline (self, "audio-%d.dat" % (i % 4), offset[i],
+                          self.audio_rate, self.usrp_rate)
+            self.connect (t, (sum, i))
+
+        gain = gr.multiply_const_cc (4000.0 / options.nchannels)
+
+        # connect it all
+        self.connect (sum, gain)
+        self.connect (gain, self.u)
+
+        # plot an FFT to verify we are sending what we want
+        if 1:
+            post_mod = fftsink.fft_sink_c(self, panel, title="Post Modulation",
+                                          fft_size=512, sample_rate=self.usrp_rate,
+                                          y_per_div=20, ref_level=40)
+            self.connect (sum, post_mod)
+            vbox.Add (post_mod.win, 1, wx.EXPAND)
+            
+
+        if options.debug:
+            self.debugger = tx_debug_gui.tx_debug_gui(self.subdev)
+            self.debugger.Show(True)
+
+
+    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.  Finally, we feed
+        any residual_freq to the s/w freq translater.
+        """
+
+        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
+            
+            # Could use residual_freq in s/w freq translator
+            return True
+
+        return False
+
+def main ():
+    app = stdgui.stdapp (fm_tx_graph, "Multichannel FM Tx")
+    app.MainLoop ()
+
+if __name__ == '__main__':
+    main ()
diff --git a/gnuradio-examples/python/usrp/fm_tx_2_daughterboards.py b/gnuradio-examples/python/usrp/fm_tx_2_daughterboards.py
new file mode 100755 (executable)
index 0000000..1cb1610
--- /dev/null
@@ -0,0 +1,160 @@
+#!/usr/bin/env python
+
+"""
+Transmit 2 signals, one out each daughterboard.
+
+Outputs SSB (USB) signals on side A and side B at frequencies
+specified on command line.
+
+Side A is 600 Hz tone.
+Side B is 350 + 440 Hz tones.
+"""
+
+from gnuradio import gr
+from gnuradio.eng_notation import num_to_str, str_to_num
+from gnuradio import usrp
+from gnuradio import audio
+from gnuradio import blks
+from gnuradio.eng_option import eng_option
+from optparse import OptionParser
+import usrp_dbid
+import math
+import sys
+
+
+class example_signal_0(gr.hier_block):
+    """
+    Sinusoid at 600 Hz.
+    """
+    def __init__(self, fg, sample_rate):
+
+        src = gr.sig_source_c (sample_rate,    # sample rate
+                               gr.GR_SIN_WAVE, # waveform type
+                               600,            # frequency
+                               1.0,            # amplitude
+                               0)              # DC Offset
+    
+        gr.hier_block.__init__(self, fg, None, src)
+
+
+class example_signal_1(gr.hier_block):
+    """
+    North American dial tone (350 + 440 Hz).
+    """
+    def __init__(self, fg, sample_rate):
+
+        src0 = gr.sig_source_c (sample_rate,    # sample rate
+                                gr.GR_SIN_WAVE, # waveform type
+                                350,            # frequency
+                                1.0,            # amplitude
+                                0)              # DC Offset
+
+        src1 = gr.sig_source_c (sample_rate,    # sample rate
+                                gr.GR_SIN_WAVE, # waveform type
+                                440,            # frequency
+                                1.0,            # amplitude
+                                0)              # DC Offset
+        sum = gr.add_cc()
+        fg.connect(src0, (sum, 0))
+        fg.connect(src1, (sum, 1))
+        
+        gr.hier_block.__init__(self, fg, None, sum)
+    
+
+
+class my_graph(gr.flow_graph):
+
+    def __init__(self):
+        gr.flow_graph.__init__ (self)
+
+        usage="%prog: [options] side-A-tx-freq side-B-tx-freq"
+        parser = OptionParser (option_class=eng_option, usage=usage)
+        (options, args) = parser.parse_args ()
+
+        if len(args) != 2:
+            parser.print_help()
+            raise SystemExit
+        else:
+            freq0 = str_to_num(args[0])
+            freq1 = str_to_num(args[1])
+
+        # ----------------------------------------------------------------
+        # Set up USRP to transmit on both daughterboards
+
+        self.u = usrp.sink_c(nchan=2)          # say we want two channels
+
+        self.dac_rate = self.u.dac_rate()                    # 128 MS/s
+        self.usrp_interp = 400
+        self.u.set_interp_rate(self.usrp_interp)
+        self.usrp_rate = self.dac_rate / self.usrp_interp    # 320 kS/s
+
+        # we're using both daughterboard slots, thus subdev is a 2-tuple
+        self.subdev = (self.u.db[0][0], self.u.db[1][0])
+        print "Using TX d'board %s" % (self.subdev[0].side_and_name(),)
+        print "Using TX d'board %s" % (self.subdev[1].side_and_name(),)
+        
+        # set up the Tx mux so that
+        #  channel 0 goes to Slot A I&Q and channel 1 to Slot B I&Q
+        self.u.set_mux(0xba98)
+
+        self.subdev[0].set_gain(self.subdev[0].gain_range()[1])    # set max Tx gain
+        self.subdev[1].set_gain(self.subdev[1].gain_range()[1])    # set max Tx gain
+
+        self.set_freq(0, freq0)
+        self.set_freq(1, freq1)
+        self.subdev[0].set_enable(True)             # enable transmitter
+        self.subdev[1].set_enable(True)             # enable transmitter
+
+        # ----------------------------------------------------------------
+        # build two signal sources, interleave them, amplify and connect them to usrp
+
+        sig0 = example_signal_0(self, self.usrp_rate)
+        sig1 = example_signal_1(self, self.usrp_rate)
+
+        intl = gr.interleave(gr.sizeof_gr_complex)
+        self.connect(sig0, (intl, 0))
+        self.connect(sig1, (intl, 1))
+
+        # apply some gain
+        if_gain = 10000
+        ifamp = gr.multiply_const_cc(if_gain)
+        
+        # and wire them up
+        self.connect(intl, ifamp, self.u)
+        
+
+    def set_freq(self, side, target_freq):
+        """
+        Set the center frequency we're interested in.
+
+        @param side: 0 = side A, 1 = side B
+        @param target_freq: frequency in Hz
+        @rtype: 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.
+        """
+
+        print "Tuning side %s to %sHz" % (("A", "B")[side], num_to_str(target_freq))
+        r = self.u.tune(self.subdev[side]._which, self.subdev[side], target_freq)
+        if r:
+            print "  r.baseband_freq =", num_to_str(r.baseband_freq)
+            print "  r.dxc_freq      =", num_to_str(r.dxc_freq)
+            print "  r.residual_freq =", num_to_str(r.residual_freq)
+            print "  r.inverted      =", r.inverted
+            print "  OK"
+            return True
+
+        else:
+            print "  Failed!"
+            
+        return False
+
+
+if __name__ == '__main__':
+    try:
+        my_graph().run()
+    except KeyboardInterrupt:
+        pass
diff --git a/gnuradio-examples/python/usrp/max_power.py b/gnuradio-examples/python/usrp/max_power.py
new file mode 100755 (executable)
index 0000000..b4ad86b
--- /dev/null
@@ -0,0 +1,83 @@
+#!/usr/bin/env 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.
+# 
+
+"""
+Setup USRP for maximum power consumption.
+"""
+
+
+from gnuradio import gr
+from gnuradio import usrp
+from gnuradio.eng_option import eng_option
+from optparse import OptionParser
+
+def ramp_source (fg):
+    period = 2**16
+    src = gr.vector_source_s (range (-period/2, period/2, 1), True)
+    return src
+
+def build_graph (tx_enable, rx_enable):
+    max_usb_rate = 8e6                  # 8 MS/sec
+    dac_freq = 128e6
+    adc_freq =  64e6
+    
+    tx_nchan = 2
+    tx_mux = 0x0000ba98
+    tx_interp =  int (dac_freq / (max_usb_rate/2 * tx_nchan)) # 16
+    
+    rx_nchan = 2
+    rx_mux = 0x00003210
+    rx_decim = int ((adc_freq * rx_nchan) / (max_usb_rate/2)) # 32
+    
+    fg = gr.flow_graph ()
+
+    if tx_enable:
+        tx_src0 = gr.sig_source_c (dac_freq/tx_interp, gr.GR_CONST_WAVE, 0, 16e3, 0)
+        usrp_tx = usrp.sink_c (0, tx_interp, tx_nchan, tx_mux)
+        usrp_tx.set_tx_freq (0, 10e6)
+        usrp_tx.set_tx_freq (1,  9e6)
+        fg.connect (tx_src0, usrp_tx)
+
+    if rx_enable:
+        usrp_rx = usrp.source_c (0, rx_decim, rx_nchan, rx_mux)
+        usrp_rx.set_rx_freq (0, 5.5e6)
+        usrp_rx.set_rx_freq (1, 6.5e6)
+        rx_dst0 = gr.null_sink (gr.sizeof_gr_complex)
+        fg.connect (usrp_rx, rx_dst0)
+
+    return fg
+    
+def main ():
+    parser = OptionParser (option_class=eng_option)
+    parser.add_option ("-t", action="store_true", dest="tx_enable",
+                       default=False, help="enable Tx path")
+    parser.add_option ("-r", action="store_true", dest="rx_enable",
+                       default=False, help="enable Rx path")
+    (options, args) = parser.parse_args ()
+    fg = build_graph (options.tx_enable, options.rx_enable)
+
+    fg.start ()
+    raw_input ('Press Enter to quit: ')
+    fg.stop ()
+
+if __name__ == '__main__':
+    main ()
diff --git a/gnuradio-examples/python/usrp/siggen_min2.py b/gnuradio-examples/python/usrp/siggen_min2.py
new file mode 100755 (executable)
index 0000000..8709e33
--- /dev/null
@@ -0,0 +1,62 @@
+#!/usr/bin/env python
+
+from gnuradio import gr
+from gnuradio import usrp
+from gnuradio import eng_notation
+from gnuradio.eng_option import eng_option
+from optparse import OptionParser
+
+
+
+def build_graph ():
+
+    # interp = 32
+    interp = 64
+    nchan = 2
+    
+    if nchan == 1:
+        mux = 0x0098
+        #mux = 0x9800
+    else:
+        mux = 0xba98
+
+    f0 = 100e3
+    a0 = 16e3
+    duc0 = 5e6
+
+    f1 = 50e3
+    a1 = 16e3
+    duc1 = 7e6
+
+    fg = gr.flow_graph ()
+
+    u = usrp.sink_c (0, interp, nchan, mux)
+    sample_rate = u.dac_freq () / interp
+    print "sample_rate = ", eng_notation.num_to_str (sample_rate)
+    print "usb_sample_rate = ", eng_notation.num_to_str (sample_rate * nchan)
+
+    u.set_tx_freq (0, duc0)
+    u.set_tx_freq (1, duc1)
+
+    interleave = gr.interleave (gr.sizeof_gr_complex)
+    fg.connect (interleave, u)
+
+    src0 = gr.sig_source_c (sample_rate, gr.GR_SIN_WAVE, f0, a0, 0)
+    fg.connect (src0, (interleave, 0))
+
+    if nchan == 2:
+        if 1:
+            src1 = gr.sig_source_c (sample_rate, gr.GR_SIN_WAVE, f1, a1, 0)
+        else:
+            src1 = gr.noise_source_c (gr.GR_UNIFORM, a1)
+        fg.connect (src1, (interleave, 1))
+    
+    return fg
+
+
+if __name__ == '__main__':
+    fg = build_graph ()
+    fg.start ()
+    raw_input ('Press Enter to quit: ')
+    fg.stop ()
+
diff --git a/gnuradio-examples/python/usrp/test_counting.py b/gnuradio-examples/python/usrp/test_counting.py
new file mode 100755 (executable)
index 0000000..ed9328a
--- /dev/null
@@ -0,0 +1,53 @@
+#!/usr/bin/env 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.
+# 
+
+"""
+Check Rx path or USRP Rev 1.
+
+This configures the USRP to return a periodic sequence of integers
+"""
+
+from gnuradio import gr
+from gnuradio import usrp
+
+def build_graph ():
+    rx_decim  = 32
+    
+    fg = gr.flow_graph ()
+    usrp_rx = usrp.source_s (0, rx_decim, 1, 0x32103210, usrp.FPGA_MODE_COUNTING)
+    sink = gr.check_counting_s ()
+    fg.connect (usrp_rx, sink)
+
+    # file_sink = gr.file_sink (gr.sizeof_short, 'counting.dat')
+    # fg.connect (usrp_rx, file_sink)
+
+    return fg
+    
+def main ():
+    fg = build_graph ()
+    try:
+        fg.run()
+    except KeyboardInterrupt:
+        pass
+
+if __name__ == '__main__':
+    main ()
diff --git a/gnuradio-examples/python/usrp/test_dft_analysis.py b/gnuradio-examples/python/usrp/test_dft_analysis.py
new file mode 100755 (executable)
index 0000000..a1d9eda
--- /dev/null
@@ -0,0 +1,72 @@
+#!/usr/bin/env python
+
+from gnuradio import gr, gru, blks
+from gnuradio.wxgui import stdgui, fftsink, slider
+from gnuradio.eng_option import eng_option
+from optparse import OptionParser
+import wx
+
+class test_graph (stdgui.gui_flow_graph):
+    def __init__(self, frame, panel, vbox, argv):
+        stdgui.gui_flow_graph.__init__(self, frame, panel, vbox, argv)
+
+        parser = OptionParser (option_class=eng_option)
+        (options, args) = parser.parse_args ()
+
+        sample_rate = 16e3
+        mpoints = 4
+        ampl = 1000
+        freq = 0
+
+        lo_freq = 1e6
+        lo_ampl = 1
+        
+        vbox.Add(slider.slider(panel,
+                               -sample_rate/2, sample_rate/2,
+                               self.set_lo_freq), 0, wx.ALIGN_CENTER)
+
+
+        src = gr.sig_source_c(sample_rate, gr.GR_CONST_WAVE,
+                              freq, ampl, 0)
+
+        self.lo = gr.sig_source_c(sample_rate, gr.GR_SIN_WAVE,
+                                  lo_freq, lo_ampl, 0)
+
+        mixer = gr.multiply_cc()
+        self.connect(src, (mixer, 0))
+        self.connect(self.lo, (mixer, 1))
+        
+        # We add these throttle blocks so that this demo doesn't
+        # suck down all the CPU available.  Normally you wouldn't use these.
+        thr = gr.throttle(gr.sizeof_gr_complex, sample_rate)
+
+        taps = gr.firdes.low_pass(1,   # gain
+                                  1,   # rate
+                                  1.0/mpoints * 0.4,  # cutoff
+                                  1.0/mpoints * 0.1,  # trans width
+                                  gr.firdes.WIN_HANN)
+        print len(taps)
+        analysis = blks.analysis_filterbank(self, mpoints, taps)
+        
+        self.connect(mixer, thr)
+        self.connect(thr, analysis)
+
+        for i in range(mpoints):
+            fft = fftsink.fft_sink_c(self, frame, fft_size=128,
+                                     sample_rate=sample_rate/mpoints,
+                                     fft_rate=5,
+                                     title="Ch %d" % (i,))
+            self.connect((analysis, i), fft)
+            vbox.Add(fft.win, 1, wx.EXPAND)
+
+    def set_lo_freq(self, freq):
+        self.lo.set_frequency(freq)
+        
+                                     
+
+def main ():
+    app = stdgui.stdapp (test_graph, "Test DFT filterbank")
+    app.MainLoop ()
+
+if __name__ == '__main__':
+    main ()
diff --git a/gnuradio-examples/python/usrp/test_dft_synth.py b/gnuradio-examples/python/usrp/test_dft_synth.py
new file mode 100755 (executable)
index 0000000..60a49e3
--- /dev/null
@@ -0,0 +1,79 @@
+#!/usr/bin/env python
+
+from gnuradio import gr, gru, blks
+from gnuradio.wxgui import stdgui, fftsink
+from gnuradio.eng_option import eng_option
+from optparse import OptionParser
+import wx
+import random
+
+
+def make_random_complex_tuple(L, gain=1):
+    result = []
+    for x in range(L):
+        result.append(gain * complex(random.gauss(0, 1),random.gauss(0, 1)))
+                      
+    return tuple(result)
+
+def random_noise_c(gain=1):
+    src = gr.vector_source_c(make_random_complex_tuple(32*1024, gain), True)
+    return src
+
+
+class test_graph (stdgui.gui_flow_graph):
+    def __init__(self, frame, panel, vbox, argv):
+        stdgui.gui_flow_graph.__init__(self, frame, panel, vbox, argv)
+
+        parser = OptionParser (option_class=eng_option)
+        (options, args) = parser.parse_args ()
+
+        sample_rate = 16e6
+        mpoints = 16
+        ampl = 1000
+        
+        enable = mpoints * [0]
+        enable[0] = 1
+
+        taps = gr.firdes.low_pass(1,   # gain
+                                  1,   # rate
+                                  1.0/mpoints * 0.4,  # cutoff
+                                  1.0/mpoints * 0.1,  # trans width
+                                  gr.firdes.WIN_HANN)
+
+        synth = blks.synthesis_filterbank(self, mpoints, taps)
+        
+        null_source = gr.null_source(gr.sizeof_gr_complex)
+        
+        if 0:
+            for i in range(mpoints):
+                s = gr.sig_source_c(sample_rate/mpoints, gr.GR_SIN_WAVE,
+                                    300e3, ampl * enable[i], 0)
+                self.connect(s, (synth, i))
+
+        else:
+            for i in range(mpoints):
+                if i == 0:
+                    s = gr.sig_source_c(sample_rate/mpoints, gr.GR_SIN_WAVE,
+                                        300e3, ampl * enable[i], 0)
+                    #s = random_noise_c(ampl)
+                    self.connect(s, (synth, i))
+                else:
+                    self.connect(null_source, (synth, i))
+            
+
+        # We add these throttle blocks so that this demo doesn't
+        # suck down all the CPU available.  Normally you wouldn't use these.
+        thr = gr.throttle(gr.sizeof_gr_complex, sample_rate)
+        fft = fftsink.fft_sink_c(self, frame, fft_size=1024,
+                                 sample_rate=sample_rate)
+        vbox.Add(fft.win, 1, wx.EXPAND)
+
+        self.connect(synth, thr, fft)
+
+
+def main ():
+    app = stdgui.stdapp (test_graph, "Test DFT filterbank")
+    app.MainLoop ()
+
+if __name__ == '__main__':
+    main ()
diff --git a/gnuradio-examples/python/usrp/test_digital_loopback_counting.py b/gnuradio-examples/python/usrp/test_digital_loopback_counting.py
new file mode 100755 (executable)
index 0000000..e985e4b
--- /dev/null
@@ -0,0 +1,65 @@
+#!/usr/bin/env 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.
+# 
+
+"""
+Digital loopback (Tx to Rx) for the USRP Rev1.
+"""
+
+
+from gnuradio import gr
+from gnuradio import usrp
+
+
+def ramp_source (fg):
+    period = 2**16
+    src = gr.vector_source_s (range (-period/2, period/2, 1), True)
+    return src
+
+def build_graph ():
+    tx_interp =  32       # tx should be twice rx
+    rx_decim  =  16
+    
+    fg = gr.flow_graph ()
+
+    data_src = ramp_source (fg)
+    # usrp_tx = usrp.sink_s (0, tx_interp, 1, 0x98)
+    usrp_tx = usrp.sink_s (0, tx_interp)
+    fg.connect (data_src, usrp_tx)
+
+    usrp_rx = usrp.source_s (0, rx_decim, 1, 0x32103210, usrp.FPGA_MODE_LOOPBACK)
+    sink = gr.check_counting_s ()
+    fg.connect (usrp_rx, sink)
+
+    # file_sink = gr.file_sink (gr.sizeof_short, "loopback.dat")
+    # fg.connect (usrp_rx, file_sink)
+    
+    return fg
+    
+def main ():
+    fg = build_graph ()
+    try:
+        fg.run()
+    except KeyboardInterrupt:
+        pass
+
+if __name__ == '__main__':
+    main ()
diff --git a/gnuradio-examples/python/usrp/test_digital_loopback_lfsr.py b/gnuradio-examples/python/usrp/test_digital_loopback_lfsr.py
new file mode 100755 (executable)
index 0000000..ae78c71
--- /dev/null
@@ -0,0 +1,62 @@
+#!/usr/bin/env 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.
+# 
+
+"""
+Digital loopback (Tx to Rx) for the USRP Rev1.
+"""
+
+from gnuradio import gr
+from gnuradio import usrp
+
+
+def build_graph ():
+    tx_interp =  32       # tx should be twice rx
+    rx_decim  =  16
+    
+    fg = gr.flow_graph ()
+
+    data_src = gr.lfsr_32k_source_s ()
+
+    # usrp_tx = usrp.sink_s (0, tx_interp, 1, 0x98)
+    usrp_tx = usrp.sink_s (0, tx_interp)
+
+    fg.connect (data_src, usrp_tx)
+
+    usrp_rx = usrp.source_s (0, rx_decim, 1, 0x32103210, usrp.FPGA_MODE_LOOPBACK)
+
+    sink = gr.check_lfsr_32k_s ()
+    fg.connect (usrp_rx, sink)
+
+    # file_sink = gr.file_sink (gr.sizeof_short, "loopback.dat")
+    # fg.connect (usrp_rx, file_sink)
+    
+    return fg
+    
+def main ():
+    fg = build_graph ()
+    try:
+        fg.run()
+    except KeyboardInterrupt:
+        pass
+
+if __name__ == '__main__':
+    main ()
diff --git a/gnuradio-examples/python/usrp/tvrx_am_rcv_gui.py b/gnuradio-examples/python/usrp/tvrx_am_rcv_gui.py
new file mode 100755 (executable)
index 0000000..e4ad369
--- /dev/null
@@ -0,0 +1,154 @@
+#!/usr/bin/env 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.
+# 
+#
+# Demodulate an AM signal from the TVRX or a recorded file.
+# The file format must be 256 ksps, complex data.
+#
+
+from gnuradio import gr, gru, eng_notation
+from gnuradio import audio_oss as audio
+from gnuradio import usrp
+from gnuradio import tv_rx
+from gnuradio.eng_option import eng_option
+from optparse import OptionParser
+import sys
+import math
+from gnuradio.wxgui import stdgui, fftsink, scopesink
+import wx
+
+#
+# return a gr.flow_graph
+#
+class wfm_rx_graph (stdgui.gui_flow_graph):
+  def __init__(self,frame,panel,vbox,argv):
+    stdgui.gui_flow_graph.__init__ (self,frame,panel,vbox,argv)
+    
+    #set rf freq
+    rf_freq = 120.e6
+    
+    # Decimation rate from USRP ADC to IF.
+    usrp_decim = 100
+    
+    # Calculate the sampling rate of the USRP and capture file.
+    # Decimate the IF sampling rate down by 4 to 64 ksps
+    # This is a flow graph that has an input (capture file) and output (audio channel).
+    #self = gr.flow_graph ()
+  
+    # Signal source is assumed to be 256 kspb / complex data stream.
+    which_side = 0
+    # usrp is data source
+    if which_side == 0:
+        src = usrp.source_c (0, usrp_decim, 1, gru.hexint(0xf0f0f0f0), 0)
+    else:
+        src = usrp.source_c (0, usrp_decim, 1, gru.hexint(0xf0f0f0f2), 0)
+
+    if_rate = 640e3 # src.adc_freq() / usrp_decim
+    if_decim = 5
+    demod_rate = if_rate / if_decim
+    
+    audio_decimation = 4
+    audio_rate = demod_rate / audio_decimation
+
+    # set up frontend
+    dboard = tv_rx.tv_rx (src, which_side)
+    self.dboard = dboard
+    (success, actual_freq) = dboard.set_freq(rf_freq)
+    assert success
+
+    if_freq = rf_freq - actual_freq
+    src.set_rx_freq (0, -if_freq)
+
+    print "actual freq ", actual_freq
+    print "IF freq ", if_freq
+        
+    dboard.set_gain(50)
+    
+    #src = gr.file_source (gr.sizeof_gr_complex, "samples/atis_ffz_am_baseband_256k_complex.dat")
+    #src = gr.file_source (gr.sizeof_gr_complex, "samples/garagedoor1.dat", True)
+    
+    #channel_coeffs = gr.firdes.band_pass (
+    #    1.0,    # gain
+    #    if_rate,
+    #    10,   # center of low transition band
+    #    10000,   # center of hi transition band
+    #    200,    # width of transition band
+    #    gr.firdes.WIN_HAMMING)
+    
+    channel_coeffs = gr.firdes.low_pass (1.0, if_rate, 10e3, 4e3, gr.firdes.WIN_HANN)
+    print "len(channel_coeffs) = ", len(channel_coeffs)
+
+    # Tune to the desired frequency.
+    ddc = gr.freq_xlating_fir_filter_ccf (if_decim, channel_coeffs, -20e3, if_rate)
+
+    # Demodule with classic sqrt (I*I + Q*Q)
+    magblock = gr.complex_to_mag()
+
+    # Scale the audio
+    volumecontrol = gr.multiply_const_ff(.1)
+
+    #band-pass
+    audio_coeffs = gr.firdes.band_pass (
+        1.0,    # gain
+        demod_rate,
+        10,   # center of low transition band
+        6000,   # center of hi transition band
+        200,    # width of transition band
+        gr.firdes.WIN_HAMMING)
+    
+    
+    # Low pass filter the demodulator output
+    #audio_coeffs = gr.firdes.low_pass (1.0, demod_rate, 500, 200, gr.firdes.WIN_HANN)
+    print "len(audio_coeffs) = ", len(audio_coeffs)
+
+    # input: float; output: float
+    audio_filter = gr.fir_filter_fff (audio_decimation, audio_coeffs)
+
+    # sound card as final sink
+    audio_sink = audio.sink (int (audio_rate))
+
+    # now wire it all together
+    self.connect (src, ddc)
+    self.connect (ddc, magblock)
+    self.connect (magblock, volumecontrol)
+    self.connect (volumecontrol, audio_filter)
+    self.connect (audio_filter, (audio_sink, 0))
+    
+    d_win = fftsink.fft_sink_c (self, panel, title="RF", fft_size=512, sample_rate=if_rate)
+    self.connect (src,d_win)
+    vbox.Add (d_win.win, 4, wx.EXPAND)
+       
+    p_win = fftsink.fft_sink_c (self, panel, title="IF", fft_size=512, sample_rate=demod_rate)
+    self.connect (ddc,p_win)
+    vbox.Add (p_win.win, 4, wx.EXPAND)
+       
+    r_win = fftsink.fft_sink_f (self, panel, title="Audio", fft_size=512, sample_rate=audio_rate)
+    self.connect (audio_filter,r_win)
+    vbox.Add (r_win.win, 4, wx.EXPAND)
+    
+    #audio_oscope = scopesink.scope_sink_f (self, panel, "Oscope Data", audio_rate)
+    #self.connect (audio_filter, audio_oscope)
+    #vbox.Add (audio_oscope.win, 4, wx.EXPAND) 
+                
+if __name__ == '__main__':
+    
+    app = stdgui.stdapp (wfm_rx_graph, "TVRX AM RX")
+    app.MainLoop ()
diff --git a/gnuradio-examples/python/usrp/usrp_fft.py b/gnuradio-examples/python/usrp/usrp_fft.py
new file mode 100755 (executable)
index 0000000..f760e39
--- /dev/null
@@ -0,0 +1,251 @@
+#!/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 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.
+# 
+
+from gnuradio import gr, gru
+from gnuradio import usrp
+from gnuradio import eng_notation
+from gnuradio.eng_option import eng_option
+from gnuradio.wxgui import stdgui, fftsink, waterfallsink, scopesink, form, slider
+from 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_flow_graph(stdgui.gui_flow_graph):
+    def __init__(self, frame, panel, vbox, argv):
+        stdgui.gui_flow_graph.__init__(self)
+
+        self.frame = frame
+        self.panel = panel
+        
+        parser = OptionParser(option_class=eng_option)
+        parser.add_option("-R", "--rx-subdev-spec", type="subdev", default=None,
+                          help="select USRP Rx side A or B (default=first one with a daughterboard)")
+        parser.add_option("-d", "--decim", type="int", default=16,
+                          help="set fgpa decimation rate to DECIM [default=%default]")
+        parser.add_option("-f", "--freq", type="eng_float", default=None,
+                          help="set frequency to FREQ", metavar="FREQ")
+        parser.add_option("-g", "--gain", type="eng_float", default=None,
+                          help="set gain in dB (default is midpoint)")
+        parser.add_option("-W", "--waterfall", action="store_true", default=False,
+                          help="Enable waterfall display")
+        parser.add_option("-8", "--width-8", action="store_true", default=False,
+                          help="Enable 8-bit samples across USB")
+        parser.add_option("-S", "--oscilloscope", action="store_true", default=False,
+                          help="Enable oscilloscope display")
+        (options, args) = parser.parse_args()
+        if len(args) != 0:
+            parser.print_help()
+            sys.exit(1)
+
+        self.show_debug_info = True
+        
+        # build the graph
+
+        self.u = usrp.source_c(decim_rate=options.decim)
+        if options.rx_subdev_spec is None:
+            options.rx_subdev_spec = pick_subdevice(self.u)
+        self.u.set_mux(usrp.determine_rx_mux_value(self.u, options.rx_subdev_spec))
+
+        if options.width_8:
+            width = 8
+            shift = 8
+            format = self.u.make_format(width, shift)
+            print "format =", hex(format)
+            r = self.u.set_format(format)
+            print "set_format =", r
+            
+        # determine the daughterboard subdevice we're using
+        self.subdev = usrp.selected_subdev(self.u, options.rx_subdev_spec)
+
+        input_rate = self.u.adc_freq() / self.u.decim_rate()
+
+        if options.waterfall:
+            self.scope = \
+              waterfallsink.waterfall_sink_c (self, panel, fft_size=1024, sample_rate=input_rate)
+        elif options.oscilloscope:
+            self.scope = scopesink.scope_sink_c(self, panel, sample_rate=input_rate)
+        else:
+            self.scope = fftsink.fft_sink_c (self, panel, fft_size=1024, sample_rate=input_rate)
+
+        self.connect(self.u, self.scope)
+
+        self._build_gui(vbox)
+
+        # set initial values
+
+        if options.gain is None:
+            # if no gain was specified, use the mid-point in dB
+            g = self.subdev.gain_range()
+            options.gain = float(g[0]+g[1])/2
+
+        if options.freq is None:
+            # if no freq was specified, use the mid-point
+            r = self.subdev.freq_range()
+            options.freq = float(r[0]+r[1])/2
+
+        self.set_gain(options.gain)
+
+        if self.show_debug_info:
+            self.myform['decim'].set_value(self.u.decim_rate())
+            self.myform['fs@usb'].set_value(self.u.adc_freq() / self.u.decim_rate())
+            self.myform['dbname'].set_value(self.subdev.name())
+            self.myform['baseband'].set_value(0)
+            self.myform['ddc'].set_value(0)
+
+        if not(self.set_freq(options.freq)):
+            self._set_status_msg("Failed to set initial frequency")
+
+    def _set_status_msg(self, msg):
+        self.frame.GetStatusBar().SetStatusText(msg, 0)
+
+    def _build_gui(self, vbox):
+
+        def _form_set_freq(kv):
+            return self.set_freq(kv['freq'])
+            
+        vbox.Add(self.scope.win, 10, wx.EXPAND)
+        
+        # add control area at the bottom
+        self.myform = myform = form.form()
+        hbox = wx.BoxSizer(wx.HORIZONTAL)
+        hbox.Add((5,0), 0, 0)
+        myform['freq'] = form.float_field(
+            parent=self.panel, sizer=hbox, label="Center freq", weight=1,
+            callback=myform.check_input_and_call(_form_set_freq, self._set_status_msg))
+
+        hbox.Add((5,0), 0, 0)
+        g = self.subdev.gain_range()
+        myform['gain'] = form.slider_field(parent=self.panel, sizer=hbox, label="Gain",
+                                           weight=3,
+                                           min=int(g[0]), max=int(g[1]),
+                                           callback=self.set_gain)
+
+        hbox.Add((5,0), 0, 0)
+        vbox.Add(hbox, 0, wx.EXPAND)
+
+        self._build_subpanel(vbox)
+
+    def _build_subpanel(self, vbox_arg):
+        # build a secondary information panel (sometimes hidden)
+
+        # FIXME figure out how to have this be a subpanel that is always
+        # created, but has its visibility controlled by foo.Show(True/False)
+        
+        def _form_set_decim(kv):
+            return self.set_decim(kv['decim'])
+
+        if not(self.show_debug_info):
+            return
+
+        panel = self.panel
+        vbox = vbox_arg
+        myform = self.myform
+
+        #panel = wx.Panel(self.panel, -1)
+        #vbox = wx.BoxSizer(wx.VERTICAL)
+
+        hbox = wx.BoxSizer(wx.HORIZONTAL)
+        hbox.Add((5,0), 0)
+
+        myform['decim'] = form.int_field(
+            parent=panel, sizer=hbox, label="Decim",
+            callback=myform.check_input_and_call(_form_set_decim, self._set_status_msg))
+
+        hbox.Add((5,0), 1)
+        myform['fs@usb'] = form.static_float_field(
+            parent=panel, sizer=hbox, label="Fs@USB")
+
+        hbox.Add((5,0), 1)
+        myform['dbname'] = form.static_text_field(
+            parent=panel, sizer=hbox)
+
+        hbox.Add((5,0), 1)
+        myform['baseband'] = form.static_float_field(
+            parent=panel, sizer=hbox, label="Analog BB")
+
+        hbox.Add((5,0), 1)
+        myform['ddc'] = form.static_float_field(
+            parent=panel, sizer=hbox, label="DDC")
+
+        hbox.Add((5,0), 0)
+        vbox.Add(hbox, 0, wx.EXPAND)
+
+        
+    def set_freq(self, target_freq):
+        """
+        Set the center frequency we're interested in.
+
+        @param target_freq: frequency in Hz
+        @rypte: bool
+
+        Tuning is a two step process.  First we ask the front-end to
+        tune as close to the desired frequency as it can.  Then we use
+        the result of that operation and our target_frequency to
+        determine the value for the digital down converter.
+        """
+        r = self.u.tune(0, self.subdev, target_freq)
+        
+        if r:
+            self.myform['freq'].set_value(target_freq)     # update displayed value
+            if self.show_debug_info:
+                self.myform['baseband'].set_value(r.baseband_freq)
+                self.myform['ddc'].set_value(r.dxc_freq)
+            return True
+
+        return False
+
+    def set_gain(self, gain):
+        self.myform['gain'].set_value(gain)     # update displayed value
+        self.subdev.set_gain(gain)
+
+    def set_decim(self, decim):
+        ok = self.u.set_decim_rate(decim)
+        if not ok:
+            print "set_decim failed"
+        input_rate = self.u.adc_freq() / self.u.decim_rate()
+        self.scope.set_sample_rate(input_rate)
+        if self.show_debug_info:  # update displayed values
+            self.myform['decim'].set_value(self.u.decim_rate())
+            self.myform['fs@usb'].set_value(self.u.adc_freq() / self.u.decim_rate())
+        return ok
+
+def main ():
+    app = stdgui.stdapp(app_flow_graph, "USRP FFT", nstatus=1)
+    app.MainLoop()
+
+if __name__ == '__main__':
+    main ()
diff --git a/gnuradio-examples/python/usrp/usrp_fft_old.py b/gnuradio-examples/python/usrp/usrp_fft_old.py
new file mode 100755 (executable)
index 0000000..c0776ea
--- /dev/null
@@ -0,0 +1,110 @@
+#!/usr/bin/env 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.
+# 
+
+from gnuradio import gr, gru
+from gnuradio import usrp
+from gnuradio import eng_notation
+from gnuradio.eng_option import eng_option
+from gnuradio.wxgui import stdgui, fftsink, scopesink
+from optparse import OptionParser
+import wx
+
+class app_flow_graph (stdgui.gui_flow_graph):
+    def __init__(self, frame, panel, vbox, argv):
+        stdgui.gui_flow_graph.__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")
+        parser.add_option ("-c", "--ddc-freq", type="eng_float", default=0,
+                           help="set Rx DDC frequency to FREQ", metavar="FREQ")
+        parser.add_option ("-m", "--mux", type="intx", default=0x32103210,
+                           help="set fpga FR_RX_MUX register to MUX")
+        parser.add_option ("-g", "--gain", type="eng_float", default=0,
+                           help="set Rx PGA gain in dB (default 0 dB)")
+        (options, args) = parser.parse_args ()
+
+        self.u = usrp.source_c (0, options.decim, 1, gru.hexint(options.mux), 0)
+        self.u.set_rx_freq (0, options.ddc_freq)
+
+        self.u.set_pga (0, options.gain)
+        self.u.set_pga (1, options.gain)
+
+        self.u.set_verbose (0)
+        
+        input_rate = self.u.adc_freq () / self.u.decim_rate ()
+
+        fft = fftsink.fft_sink_c (self, panel, fft_size=1024, sample_rate=input_rate)
+        #fft = fftsink.fft_sink_c (self, panel, fft_size=1024, fft_rate=50, sample_rate=input_rate)
+        self.connect (self.u, fft)
+        vbox.Add (fft.win, 10, wx.EXPAND)
+
+       if 0:
+            c2f_1 = gr.complex_to_float ()
+            scope = scopesink.scope_sink_f (self, panel, "Rx Data", input_rate)
+            vbox.Add (scope.win, 4, wx.EXPAND)
+
+            self.connect (self.u,c2f_1)
+            self.connect ((c2f_1, 0), (scope, 0))
+            self.connect ((c2f_1, 1), (scope, 1))
+
+        # build small control area at bottom
+        hbox = wx.BoxSizer (wx.HORIZONTAL)
+        hbox.Add ((1, 1), 1, wx.EXPAND)
+        hbox.Add (wx.StaticText (panel, -1, "Set ddc freq: "), 0, wx.ALIGN_CENTER)
+        self.tc_freq = wx.TextCtrl (panel, -1, "", style=wx.TE_PROCESS_ENTER)
+        hbox.Add (self.tc_freq, 0, wx.ALIGN_CENTER)
+        wx.EVT_TEXT_ENTER (self.tc_freq, self.tc_freq.GetId(), self.handle_text_enter)
+        hbox.Add ((1, 1), 1, wx.EXPAND)
+        # add it to the main vbox
+        vbox.Add (hbox, 0, wx.EXPAND)
+
+        self.update_status_bar ()
+
+    def handle_text_enter (self, event):
+        str = event.GetString ()
+        self.tc_freq.Clear ()
+        self.u.set_rx_freq (0, eng_notation.str_to_num (str))
+        self.update_status_bar ()
+
+    def update_status_bar (self):
+        ddc_freq = self.u.rx_freq (0)
+        decim_rate = self.u.decim_rate ()
+        sample_rate = self.u.adc_freq () / decim_rate
+        msg = "decim: %d  %sS/s  DDC: %s" % (
+            decim_rate,
+            eng_notation.num_to_str (sample_rate),
+            eng_notation.num_to_str (ddc_freq))
+            
+        self.frame.GetStatusBar().SetStatusText (msg, 1)
+
+        
+
+def main ():
+    app = stdgui.stdapp (app_flow_graph, "USRP FFT")
+    app.MainLoop ()
+
+if __name__ == '__main__':
+    main ()
diff --git a/gnuradio-examples/python/usrp/usrp_nbfm_ptt.py b/gnuradio-examples/python/usrp/usrp_nbfm_ptt.py
new file mode 100755 (executable)
index 0000000..3e930bb
--- /dev/null
@@ -0,0 +1,491 @@
+#!/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 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.
+# 
+
+import math
+import sys
+import wx
+from optparse import OptionParser
+
+from gnuradio import gr, gru, eng_notation
+from gnuradio import usrp
+from gnuradio import audio
+from gnuradio import blks
+from gnuradio.eng_option import eng_option
+from gnuradio.wxgui import stdgui, fftsink, scopesink, slider, form
+import usrp_dbid
+
+from Numeric import convolve, array
+
+#import os
+#print "pid =", os.getpid()
+#raw_input('Press Enter to continue: ')
+
+# ////////////////////////////////////////////////////////////////////////
+#                           Control Stuff
+# ////////////////////////////////////////////////////////////////////////
+
+class ptt_graph(stdgui.gui_flow_graph):
+    def __init__(self, frame, panel, vbox, argv):
+        stdgui.gui_flow_graph.__init__ (self, frame, panel, vbox, argv)
+
+        self.frame = frame
+        self.space_bar_pressed = False
+        
+        parser = OptionParser (option_class=eng_option)
+        parser.add_option("-R", "--rx-subdev-spec", type="subdev", default=None,
+                          help="select USRP Rx side A or B")
+        parser.add_option("-T", "--tx-subdev-spec", type="subdev", default=None,
+                          help="select USRP Tx side A or B")
+        parser.add_option ("-f", "--freq", type="eng_float", default=442.1e6,
+                           help="set Tx and Rx frequency to FREQ", metavar="FREQ")
+        parser.add_option ("-g", "--rx-gain", type="eng_float", default=None,
+                           help="set rx gain [default=midpoint in dB]")
+        parser.add_option("-I", "--audio-input", type="string", default="",
+                          help="pcm input device name.  E.g., hw:0,0 or /dev/dsp")
+        parser.add_option("-O", "--audio-output", type="string", default="",
+                          help="pcm output device name.  E.g., hw:0,0 or /dev/dsp")
+        parser.add_option ("-N", "--no-gui", action="store_true", default=False)
+        (options, args) = parser.parse_args ()
+
+        if len(args) != 0:
+            parser.print_help()
+            sys.exit(1)
+
+        if options.freq < 1e6:
+            options.freq *= 1e6
+            
+        self.txpath = transmit_path(self, options.tx_subdev_spec, options.audio_input)
+        self.rxpath = receive_path(self, options.rx_subdev_spec, options.rx_gain, options.audio_output)
+        self._build_gui(frame, panel, vbox, argv, options.no_gui)
+
+        self.set_transmit(False)
+        self.set_freq(options.freq)
+        self.set_rx_gain(self.rxpath.gain)               # update gui
+        self.set_volume(self.rxpath.volume)              # update gui
+        self.set_squelch(self.rxpath.threshold())        # update gui
+
+
+    def set_transmit(self, enabled):
+        self.txpath.set_enable(enabled)
+        self.rxpath.set_enable(not(enabled))
+        if enabled:
+            self.frame.SetStatusText ("Transmitter ON", 1)
+        else:
+            self.frame.SetStatusText ("Receiver ON", 1)
+
+
+    def set_rx_gain(self, gain):
+        self.myform['rx_gain'].set_value(gain)            # update displayed value
+        self.rxpath.set_gain(gain)
+        
+    def set_tx_gain(self, gain):
+        self.txpath.set_gain(gain)
+
+    def set_squelch(self, threshold):
+        self.rxpath.set_squelch(threshold)
+        self.myform['squelch'].set_value(self.rxpath.threshold())
+
+    def set_volume (self, vol):
+        self.rxpath.set_volume(vol)
+        self.myform['volume'].set_value(self.rxpath.volume)
+        #self.update_status_bar ()
+
+    def set_freq(self, freq):
+        r1 = self.txpath.set_freq(freq)
+        r2 = self.rxpath.set_freq(freq)
+        #print "txpath.set_freq =", r1
+        #print "rxpath.set_freq =", r2
+        if r1 and r2:
+            self.myform['freq'].set_value(freq)     # update displayed value
+        return r1 and r2
+
+    def _build_gui(self, frame, panel, vbox, argv, no_gui):
+
+        def _form_set_freq(kv):
+            return self.set_freq(kv['freq'])
+            
+        self.panel = panel
+        
+        # FIXME This REALLY needs to be replaced with a hand-crafted button
+        # that sends both button down and button up events
+        hbox = wx.BoxSizer(wx.HORIZONTAL)
+        hbox.Add((10,0), 1)
+        self.status_msg = wx.StaticText(panel, -1, "Press Space Bar to Transmit")
+        of = self.status_msg.GetFont()
+        self.status_msg.SetFont(wx.Font(15, of.GetFamily(), of.GetStyle(), of.GetWeight()))
+        hbox.Add(self.status_msg, 0, wx.ALIGN_CENTER)
+        hbox.Add((10,0), 1)
+        vbox.Add(hbox, 0, wx.EXPAND | wx.ALIGN_CENTER)
+
+        panel.Bind(wx.EVT_KEY_DOWN, self._on_key_down)
+        panel.Bind(wx.EVT_KEY_UP, self._on_key_up)
+        panel.Bind(wx.EVT_KILL_FOCUS, self._on_kill_focus)
+        panel.SetFocus()
+
+        if 1 and not(no_gui):
+            rx_fft = fftsink.fft_sink_c (self, panel, title="Rx Input", fft_size=512,
+                                         sample_rate=self.rxpath.if_rate,
+                                         ref_level=80, y_per_div=20)
+            self.connect (self.rxpath.u, rx_fft)
+            vbox.Add (rx_fft.win, 1, wx.EXPAND)
+
+        if 1 and not(no_gui):
+            rx_fft = fftsink.fft_sink_c (self, panel, title="Post s/w DDC",
+                                         fft_size=512, sample_rate=self.rxpath.quad_rate,
+                                         ref_level=80, y_per_div=20)
+            self.connect (self.rxpath.ddc, rx_fft)
+            vbox.Add (rx_fft.win, 1, wx.EXPAND)
+
+        if 0 and not(no_gui):
+            foo = scopesink.scope_sink_f (self, panel, title="Squelch",
+                                               sample_rate=32000)
+            self.connect (self.rxpath.fmrx.div, (foo,0))
+            self.connect (self.rxpath.fmrx.gate, (foo,1))
+            self.connect (self.rxpath.fmrx.squelch_lpf, (foo,2))
+            vbox.Add (foo.win, 1, wx.EXPAND)
+
+        if 0 and not(no_gui):
+            tx_fft = fftsink.fft_sink_c (self, panel, title="Tx Output",
+                                         fft_size=512, sample_rate=self.txpath.usrp_rate)
+            self.connect (self.txpath.amp, tx_fft)
+            vbox.Add (tx_fft.win, 1, wx.EXPAND)
+
+
+        # add control area at the bottom
+
+        self.myform = myform = form.form()
+
+        # first row
+        hbox = wx.BoxSizer(wx.HORIZONTAL)
+        hbox.Add((5,0), 0, 0)
+        myform['freq'] = form.float_field(
+            parent=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, 0)
+        vbox.Add(hbox, 0, wx.EXPAND)
+
+
+        # second row
+        hbox = wx.BoxSizer(wx.HORIZONTAL)
+        myform['volume'] = \
+            form.quantized_slider_field(parent=self.panel, sizer=hbox, label="Volume",
+                                        weight=3, range=self.rxpath.volume_range(),
+                                        callback=self.set_volume)
+        hbox.Add((5,0), 0)
+        myform['squelch'] = \
+            form.quantized_slider_field(parent=self.panel, sizer=hbox, label="Squelch",
+                                        weight=3, range=self.rxpath.squelch_range(),
+                                        callback=self.set_squelch)
+        hbox.Add((5,0), 0)
+        myform['rx_gain'] = \
+            form.quantized_slider_field(parent=self.panel, sizer=hbox, label="Rx Gain",
+                                        weight=3, range=self.rxpath.subdev.gain_range(),
+                                        callback=self.set_rx_gain)
+        hbox.Add((5,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)
+        
+        #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.static_float_field(
+        #    parent=panel, sizer=hbox, label="Decim")
+
+        #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), 0)
+        vbox.Add(hbox, 0, wx.EXPAND)
+
+
+    def _set_status_msg(self, msg, which=0):
+        self.frame.GetStatusBar().SetStatusText(msg, which)
+
+    def _on_key_down(self, evt):
+        # print "key_down:", evt.m_keyCode
+        if evt.m_keyCode == wx.WXK_SPACE and not(self.space_bar_pressed):
+            self.space_bar_pressed = True
+            self.set_transmit(True)
+
+    def _on_key_up(self, evt):
+        # print "key_up", evt.m_keyCode
+        if evt.m_keyCode == wx.WXK_SPACE:
+            self.space_bar_pressed = False
+            self.set_transmit(False)
+
+    def _on_kill_focus(self, evt):
+        # if we lose the keyboard focus, turn off the transmitter
+        self.space_bar_pressed = False
+        self.set_transmit(False)
+        
+
+# ////////////////////////////////////////////////////////////////////////
+#                           Transmit Path
+# ////////////////////////////////////////////////////////////////////////
+
+class transmit_path(gr.hier_block):
+    def __init__(self, fg, subdev_spec, audio_input):
+
+        self.u = usrp.sink_c ()
+
+        dac_rate = self.u.dac_rate();
+        self.if_rate = 320e3                               # 320 kS/s
+        self.usrp_interp = int(dac_rate // self.if_rate)
+        self.u.set_interp_rate(self.usrp_interp)
+        self.sw_interp = 10
+        self.audio_rate = self.if_rate // self.sw_interp   #  32 kS/s
+
+        self.audio_gain = 10
+        self.normal_gain = 32000
+
+        self.audio = audio.source(int(self.audio_rate), audio_input)
+        self.audio_amp = gr.multiply_const_ff(self.audio_gain)
+
+        lpf = gr.firdes.low_pass (1,                # gain
+                                  self.audio_rate,            # sampling rate
+                                  3800,               # low pass cutoff freq
+                                  300,                # width of trans. band
+                                  gr.firdes.WIN_HANN) # filter type 
+
+        hpf = gr.firdes.high_pass (1,                # gain
+                                  self.audio_rate,            # sampling rate
+                                  325,               # low pass cutoff freq
+                                  50,                # width of trans. band
+                                  gr.firdes.WIN_HANN) # filter type 
+
+        audio_taps = convolve(array(lpf),array(hpf))
+        self.audio_filt = gr.fir_filter_fff(1,audio_taps)
+
+        self.pl = blks.ctcss_gen_f(fg, self.audio_rate,123.0)
+        self.add_pl = gr.add_ff()
+        fg.connect(self.pl,(self.add_pl,1))
+
+        self.fmtx = blks.nbfm_tx(fg, self.audio_rate, self.if_rate)
+        self.amp = gr.multiply_const_cc (self.normal_gain)
+
+        # determine the daughterboard subdevice we're using
+        if subdev_spec is None:
+            subdev_spec = usrp.pick_tx_subdevice(self.u)
+        self.u.set_mux(usrp.determine_tx_mux_value(self.u, subdev_spec))
+        self.subdev = usrp.selected_subdev(self.u, subdev_spec)
+        print "TX using", self.subdev.name()
+
+        fg.connect(self.audio, self.audio_amp, self.audio_filt,
+                   (self.add_pl,0), self.fmtx, self.amp, self.u)
+        
+        gr.hier_block.__init__(self, fg, None, None)
+
+        self.set_gain(self.subdev.gain_range()[1])  # set max Tx 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.  Finally, we feed
+        any residual_freq to the s/w freq translater.
+        """
+        r = self.u.tune(self.subdev._which, self.subdev, target_freq)
+        if r:
+            # Use residual_freq in s/w freq translator
+            return True
+
+        return False
+
+    def set_gain(self, gain):
+        self.gain = gain
+        self.subdev.set_gain(gain)
+
+    def set_enable(self, enable):
+        self.subdev.set_enable(enable)            # set H/W Tx enable
+        if enable:
+            self.amp.set_k (self.normal_gain)
+        else:
+            self.amp.set_k (0)
+
+
+
+# ////////////////////////////////////////////////////////////////////////
+#                           Receive Path
+# ////////////////////////////////////////////////////////////////////////
+
+class receive_path(gr.hier_block):
+    def __init__(self, fg, subdev_spec, gain, audio_output):
+
+        self.u = usrp.source_c ()
+        adc_rate = self.u.adc_rate()
+
+        self.if_rate = 256e3                         # 256 kS/s
+        usrp_decim = int(adc_rate // self.if_rate)
+        if_decim = 4
+        self.u.set_decim_rate(usrp_decim)
+        self.quad_rate = self.if_rate // if_decim    #  64 kS/s
+        audio_decim = 2
+        audio_rate = self.quad_rate // audio_decim   #  32 kS/s
+
+        if subdev_spec is None:
+            subdev_spec = usrp.pick_rx_subdevice(self.u)
+        self.subdev = usrp.selected_subdev(self.u, subdev_spec)
+        print "RX using", self.subdev.name()
+
+        self.u.set_mux(usrp.determine_rx_mux_value(self.u, subdev_spec))
+
+        # Create filter to get actual channel we want
+        chan_coeffs = gr.firdes.low_pass (1.0,                # gain
+                                          self.if_rate,       # sampling rate
+                                          13e3,               # low pass cutoff freq
+                                          4e3,                # width of trans. band
+                                          gr.firdes.WIN_HANN) # filter type 
+
+        print "len(rx_chan_coeffs) =", len(chan_coeffs)
+
+        # Decimating Channel filter with frequency translation
+        # complex in and out, float taps
+        self.ddc = gr.freq_xlating_fir_filter_ccf(if_decim,       # decimation rate
+                                                  chan_coeffs,    # taps
+                                                  0,              # frequency translation amount
+                                                  self.if_rate)   # input sample rate
+
+        # instantiate the guts of the single channel receiver
+        self.fmrx = blks.nbfm_rx(fg, audio_rate, self.quad_rate)
+
+        # standard squelch block
+        self.squelch = blks.standard_squelch(fg, audio_rate)
+
+        # audio gain / mute block
+        self._audio_gain = gr.multiply_const_ff(1.0)
+
+        # sound card as final sink
+        audio_sink = audio.sink (int(audio_rate), audio_output)
+        
+        # now wire it all together
+        fg.connect (self.u, self.ddc, self.fmrx, self.squelch, self._audio_gain, audio_sink)
+        gr.hier_block.__init__(self, fg, self.u, audio_sink)
+
+        if gain is None:
+            # if no gain was specified, use the mid-point in dB
+            g = self.subdev.gain_range()
+            gain = float(g[0]+g[1])/2
+
+        self.enabled = True
+        self.set_gain(gain)
+        v = self.volume_range()
+        self.set_volume((v[0]+v[1])/2)
+        s = self.squelch_range()
+        self.set_squelch((s[0]+s[1])/2)
+        
+        
+    def volume_range(self):
+        return (-20.0, 0.0, 0.5)
+
+    def set_volume (self, vol):
+        g = self.volume_range()
+        self.volume = max(g[0], min(g[1], vol))
+        self._update_audio_gain()
+
+    def set_enable(self, enable):
+        self.enabled = enable
+        self._update_audio_gain()
+
+    def _update_audio_gain(self):
+        if self.enabled:
+            self._audio_gain.set_k(10**(self.volume/10))
+        else:
+            self._audio_gain.set_k(0)
+
+    def squelch_range(self):
+        return self.squelch.squelch_range()
+    
+    def set_squelch(self, threshold):
+        print "SQL =", threshold
+        self.squelch.set_threshold(threshold)
+
+    def threshold(self):
+        return self.squelch.threshold()
+    
+    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 in the
+        FPGA.  Finally, we feed any residual_freq to the s/w freq
+        translator.
+        """
+        r = self.u.tune(0, self.subdev, target_freq)
+        if r:
+            # Use residual_freq in s/w freq translater
+            # print "residual_freq =", r.residual_freq
+            self.ddc.set_center_freq(-r.residual_freq)
+            return True
+
+        return False
+
+    def set_gain(self, gain):
+        self.gain = gain
+        self.subdev.set_gain(gain)
+
+
+# ////////////////////////////////////////////////////////////////////////
+#                                Main
+# ////////////////////////////////////////////////////////////////////////
+
+def main():
+    app = stdgui.stdapp(ptt_graph, "NBFM Push to Talk")
+    app.MainLoop()
+
+if __name__ == '__main__':
+    main()
diff --git a/gnuradio-examples/python/usrp/usrp_nbfm_rcv.py b/gnuradio-examples/python/usrp/usrp_nbfm_rcv.py
new file mode 100755 (executable)
index 0000000..018a5b7
--- /dev/null
@@ -0,0 +1,362 @@
+#!/usr/bin/env python
+
+from gnuradio import gr, gru, eng_notation, optfir
+from gnuradio import audio
+from gnuradio import usrp
+from gnuradio import blks
+from gnuradio.eng_option import eng_option
+from gnuradio.wxgui import slider, powermate
+from gnuradio.wxgui import stdgui, fftsink, form
+from optparse import OptionParser
+import usrp_dbid
+import sys
+import math
+import wx
+
+
+#////////////////////////////////////////////////////////////////////////
+#                           Control Stuff
+#////////////////////////////////////////////////////////////////////////
+
+class my_graph (stdgui.gui_flow_graph):
+    def __init__(self,frame,panel,vbox,argv):
+        stdgui.gui_flow_graph.__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 USRP Rx side A or B (default=A)")
+        parser.add_option("-f", "--freq", type="eng_float", default=146.585e6,
+                          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("-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")
+        parser.add_option("-N", "--no-gui", action="store_true", default=False)
+
+        (options, args) = parser.parse_args()
+        if len(args) != 0:
+            parser.print_help()
+            sys.exit(1)
+        
+        if options.freq < 1e6:
+            options.freq *= 1e6
+            
+        self.frame = frame
+        self.panel = panel
+        
+        self.state = "FREQ"
+        self.freq = 0
+        self.freq_step = 25e3
+
+        self.rxpath = receive_path(self, options.rx_subdev_spec, options.gain, options.audio_output)
+
+        self._build_gui(vbox, options.no_gui)
+
+        # set initial values
+
+        if options.volume is not None:
+            self.set_volume(options.volume)
+
+        if not(self.set_freq(options.freq)):
+            self._set_status_msg("Failed to set initial frequency")
+
+        self.set_gain(self.rxpath.gain)               # update gui
+        self.set_volume(self.rxpath.volume)           # update gui
+        self.set_squelch(self.rxpath.threshold())     # update gui
+
+
+    def _set_status_msg(self, msg, which=0):
+        self.frame.GetStatusBar().SetStatusText(msg, which)
+
+
+    def _build_gui(self, vbox, no_gui):
+
+        def _form_set_freq(kv):
+            return self.set_freq(kv['freq'])
+
+
+        self.src_fft = None
+        if 1 and not(no_gui):
+            self.src_fft = fftsink.fft_sink_c (self, self.panel, title="Data from USRP",
+                                               fft_size=512, sample_rate=self.rxpath.if_rate,
+                                               ref_level=80, y_per_div=20)
+            self.connect (self.rxpath.u, self.src_fft)
+            vbox.Add (self.src_fft.win, 4, wx.EXPAND)
+
+        if 1 and not(no_gui):
+            rx_fft = fftsink.fft_sink_c (self, self.panel, title="Post s/w DDC",
+                                         fft_size=512, sample_rate=self.rxpath.quad_rate,
+                                         ref_level=80, y_per_div=20)
+            self.connect (self.rxpath.ddc, rx_fft)
+            vbox.Add (rx_fft.win, 4, wx.EXPAND)
+        
+        if 1 and not(no_gui):
+            post_deemph_fft = fftsink.fft_sink_f (self, self.panel, title="Post Deemph",
+                                                  fft_size=512, sample_rate=self.rxpath.audio_rate,
+                                                  y_per_div=10, ref_level=-40)
+            self.connect (self.rxpath.fmrx.deemph, post_deemph_fft)
+            vbox.Add (post_deemph_fft.win, 4, wx.EXPAND)
+
+        if 0:
+            post_filt_fft = fftsink.fft_sink_f (self, self.panel, title="Post Filter", 
+                                                fft_size=512, sample_rate=audio_rate,
+                                                y_per_div=10, ref_level=-40)
+            self.connect (self.guts.audio_filter, post_filt)
+            vbox.Add (fft_win4, 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=(87.9e6, 108.1e6, 0.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_volume)
+        hbox.Add((5,0), 0)
+        myform['squelch'] = \
+            form.quantized_slider_field(parent=self.panel, sizer=hbox, label="Squelch",
+                                        weight=3, range=self.rxpath.squelch_range(),
+                                        callback=self.set_squelch)
+        hbox.Add((5,0), 0)
+        myform['gain'] = \
+            form.quantized_slider_field(parent=self.panel, sizer=hbox, label="Gain",
+                                        weight=3, range=self.rxpath.subdev.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 + self.freq_step)
+                self.rot -= 3
+            elif self.rot <=-3:
+                self.set_freq(self.freq - self.freq_step)
+                self.rot += 3
+        else:
+            step = self.volume_range()[2]
+            if self.rot >= 3:
+                self.set_volume(self.rxpath.volume + step)
+                self.rot -= 3
+            elif self.rot <=-3:
+                self.set_volume(self.rxpath.volume - 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_squelch(self, threshold_in_db):
+        self.rxpath.set_squelch(threshold_in_db)
+        self.myform['squelch'].set_value(self.rxpath.threshold())
+
+    def set_volume (self, vol):
+        self.rxpath.set_volume(vol)
+        self.myform['volume'].set_value(self.rxpath.volume)
+        self.update_status_bar ()
+                                        
+    def set_freq(self, target_freq):
+        r = self.rxpath.set_freq(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.rxpath.set_gain(gain)
+
+    def update_status_bar (self):
+        msg = "Volume:%r  Setting:%s" % (self.rxpath.volume, self.state)
+        self._set_status_msg(msg, 1)
+        if self.src_fft:
+            self.src_fft.set_baseband_freq(self.freq)
+
+    def volume_range(self):
+        return (-20.0, 0.0, 0.5)
+        
+
+#////////////////////////////////////////////////////////////////////////
+#                           Receive Path
+#////////////////////////////////////////////////////////////////////////
+
+USE_SIMPLE_SQUELCH = False
+
+class receive_path(gr.hier_block):
+    def __init__(self, fg, subdev_spec, gain, audio_output):
+
+        self.u = usrp.source_c ()
+        adc_rate = self.u.adc_rate()
+
+        self.if_rate = 256e3                              # 256 kS/s
+        usrp_decim = int(adc_rate // self.if_rate)
+        if_decim = 4
+        self.u.set_decim_rate(usrp_decim)
+        self.quad_rate = self.if_rate // if_decim         #  64 kS/s
+        audio_decim = 2
+        self.audio_rate = self.quad_rate // audio_decim   #  32 kS/s
+
+
+        if subdev_spec is None:
+            subdev_spec = usrp.pick_rx_subdevice(self.u)
+        self.subdev = usrp.selected_subdev(self.u, subdev_spec)
+        print "Using RX d'board %s" % (self.subdev.side_and_name(),)
+
+        self.u.set_mux(usrp.determine_rx_mux_value(self.u, subdev_spec))
+
+        # Create filter to get actual channel we want
+        chan_coeffs = gr.firdes.low_pass (1.0,                # gain
+                                          self.if_rate,       # sampling rate
+                                          13e3,               # low pass cutoff freq
+                                          4e3,                # width of trans. band
+                                          gr.firdes.WIN_HANN) # filter type 
+
+        print "len(rx_chan_coeffs) =", len(chan_coeffs)
+
+        # Decimating Channel filter with frequency translation
+        # complex in and out, float taps
+        self.ddc = gr.freq_xlating_fir_filter_ccf(if_decim,       # decimation rate
+                                                  chan_coeffs,    # taps
+                                                  0,              # frequency translation amount
+                                                  self.if_rate)   # input sample rate
+
+        if USE_SIMPLE_SQUELCH:
+            self.squelch = gr.simple_squelch_cc(20)
+        else:
+            self.squelch = blks.standard_squelch(fg, self.audio_rate)
+
+        # instantiate the guts of the single channel receiver
+        self.fmrx = blks.nbfm_rx(fg, self.audio_rate, self.quad_rate)
+
+        # audio gain / mute block
+        self._audio_gain = gr.multiply_const_ff(1.0)
+
+        # sound card as final sink
+        audio_sink = audio.sink (int(self.audio_rate), audio_output)
+        
+        # now wire it all together
+        if USE_SIMPLE_SQUELCH:
+            fg.connect (self.u, self.ddc, self.squelch, self.fmrx,
+                        self._audio_gain, audio_sink)
+        else:
+            fg.connect (self.u, self.ddc, self.fmrx, self.squelch,
+                        self._audio_gain, audio_sink)
+
+        gr.hier_block.__init__(self, fg, self.u, audio_sink)
+
+        if gain is None:
+            # if no gain was specified, use the mid-point in dB
+            g = self.subdev.gain_range()
+            gain = float(g[0]+g[1])/2
+
+        self.set_gain(gain)
+
+        v = self.volume_range()
+        self.set_volume((v[0]+v[1])/2)
+        s = self.squelch_range()
+        self.set_squelch((s[0]+s[1])/2)
+
+    def volume_range(self):
+        return (-20.0, 0.0, 0.5)
+
+    def set_volume (self, vol):
+        g = self.volume_range()
+        self.volume = max(g[0], min(g[1], vol))
+        self._update_audio_gain()
+
+    def _update_audio_gain(self):
+        self._audio_gain.set_k(10**(self.volume/10))
+        
+    def squelch_range(self):
+        r = self.squelch.squelch_range()
+        #print "squelch_range: ", r
+        return r
+    
+    def set_squelch(self, threshold):
+        #print "SQL =", threshold
+        self.squelch.set_threshold(threshold)
+
+    def threshold(self):
+        t = self.squelch.threshold()
+        #print "t =", t
+        return t
+
+    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 in the
+        FPGA.  Finally, we feed any residual_freq to the s/w freq
+        translator.
+        """
+
+        r = usrp.tune(self.u, 0, self.subdev, target_freq)
+        if r:
+            # Use residual_freq in s/w freq translater
+            # print "residual_freq =", r.residual_freq
+            self.ddc.set_center_freq(-r.residual_freq)
+            return True
+
+        return False
+
+    def set_gain(self, gain):
+        self.gain = gain
+        self.subdev.set_gain(gain)
+
+
+# ////////////////////////////////////////////////////////////////////////
+#                                Main
+# ////////////////////////////////////////////////////////////////////////
+
+if __name__ == '__main__':
+    app = stdgui.stdapp (my_graph, "USRP NBFM RX")
+    app.MainLoop ()
diff --git a/gnuradio-examples/python/usrp/usrp_oscope.py b/gnuradio-examples/python/usrp/usrp_oscope.py
new file mode 100755 (executable)
index 0000000..f4469f9
--- /dev/null
@@ -0,0 +1,252 @@
+#!/usr/bin/env python
+#
+# Copyright 2004,2005,2006 Free Software Foundation, Inc.
+# 
+# This file is part of GNU Radio
+# 
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 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.
+# 
+
+# print "Loading revised usrp_oscope with additional options for scopesink..."
+
+from gnuradio import gr, gru
+from gnuradio import usrp
+from gnuradio import eng_notation
+from gnuradio.eng_option import eng_option
+from gnuradio.wxgui import stdgui, fftsink, waterfallsink, scopesink, form, slider
+from 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_flow_graph(stdgui.gui_flow_graph):
+    def __init__(self, frame, panel, vbox, argv):
+        stdgui.gui_flow_graph.__init__(self)
+
+        self.frame = frame
+        self.panel = panel
+        
+        parser = OptionParser(option_class=eng_option)
+        parser.add_option("-R", "--rx-subdev-spec", type="subdev", default=None,
+                          help="select USRP Rx side A or B (default=first one with a daughterboard)")
+        parser.add_option("-d", "--decim", type="int", default=16,
+                          help="set fgpa decimation rate to DECIM [default=%default]")
+        parser.add_option("-f", "--freq", type="eng_float", default=None,
+                          help="set frequency to FREQ", metavar="FREQ")
+        parser.add_option("-g", "--gain", type="eng_float", default=None,
+                          help="set gain in dB (default is midpoint)")
+        parser.add_option("-8", "--width-8", action="store_true", default=False,
+                          help="Enable 8-bit samples across USB")
+        parser.add_option("-n", "--frame-decim", type="int", default=1,
+                          help="set oscope frame decimation factor to n [default=1]")
+        parser.add_option("-v", "--v-scale", type="eng_float", default=1000,
+                          help="set oscope initial V/div to SCALE [default=%default]")
+        parser.add_option("-t", "--t-scale", type="eng_float", default=49e-6,
+                          help="set oscope initial s/div to SCALE [default=50us]")
+        (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 = usrp.source_c(decim_rate=options.decim)
+        if options.rx_subdev_spec is None:
+            options.rx_subdev_spec = pick_subdevice(self.u)
+        self.u.set_mux(usrp.determine_rx_mux_value(self.u, options.rx_subdev_spec))
+
+        if options.width_8:
+            width = 8
+            shift = 8
+            format = self.u.make_format(width, shift)
+            #print "format =", hex(format)
+            r = self.u.set_format(format)
+            #print "set_format =", r
+            
+        # determine the daughterboard subdevice we're using
+        self.subdev = usrp.selected_subdev(self.u, options.rx_subdev_spec)
+
+        input_rate = self.u.adc_freq() / self.u.decim_rate()
+
+        self.scope = scopesink.scope_sink_c(self, panel, sample_rate=input_rate,
+                                            frame_decim=options.frame_decim,
+                                            v_scale=options.v_scale,
+                                            t_scale=options.t_scale)
+        self.connect(self.u, self.scope)
+
+        self._build_gui(vbox)
+
+        # set initial values
+
+        if options.gain is None:
+            # if no gain was specified, use the mid-point in dB
+            g = self.subdev.gain_range()
+            options.gain = float(g[0]+g[1])/2
+
+        if options.freq is None:
+            # if no freq was specified, use the mid-point
+            r = self.subdev.freq_range()
+            options.freq = float(r[0]+r[1])/2
+
+        self.set_gain(options.gain)
+
+        if self.show_debug_info:
+            self.myform['decim'].set_value(self.u.decim_rate())
+            self.myform['fs@usb'].set_value(self.u.adc_freq() / self.u.decim_rate())
+            self.myform['dbname'].set_value(self.subdev.name())
+            self.myform['baseband'].set_value(0)
+            self.myform['ddc'].set_value(0)
+                        
+        if not(self.set_freq(options.freq)):
+            self._set_status_msg("Failed to set initial frequency")
+
+
+    def _set_status_msg(self, msg):
+        self.frame.GetStatusBar().SetStatusText(msg, 0)
+
+    def _build_gui(self, vbox):
+
+        def _form_set_freq(kv):
+            return self.set_freq(kv['freq'])
+            
+        vbox.Add(self.scope.win, 10, wx.EXPAND)
+        
+        # add control area at the bottom
+        self.myform = myform = form.form()
+        hbox = wx.BoxSizer(wx.HORIZONTAL)
+        hbox.Add((5,0), 0, 0)
+        myform['freq'] = form.float_field(
+            parent=self.panel, sizer=hbox, label="Center freq", weight=1,
+            callback=myform.check_input_and_call(_form_set_freq, self._set_status_msg))
+
+        hbox.Add((5,0), 0, 0)
+        g = self.subdev.gain_range()
+        myform['gain'] = form.slider_field(parent=self.panel, sizer=hbox, label="Gain",
+                                           weight=3,
+                                           min=int(g[0]), max=int(g[1]),
+                                           callback=self.set_gain)
+
+        hbox.Add((5,0), 0, 0)
+        vbox.Add(hbox, 0, wx.EXPAND)
+
+        self._build_subpanel(vbox)
+
+    def _build_subpanel(self, vbox_arg):
+        # build a secondary information panel (sometimes hidden)
+
+        # FIXME figure out how to have this be a subpanel that is always
+        # created, but has its visibility controlled by foo.Show(True/False)
+        
+        def _form_set_decim(kv):
+            return self.set_decim(kv['decim'])
+
+        if not(self.show_debug_info):
+            return
+
+        panel = self.panel
+        vbox = vbox_arg
+        myform = self.myform
+
+        #panel = wx.Panel(self.panel, -1)
+        #vbox = wx.BoxSizer(wx.VERTICAL)
+
+        hbox = wx.BoxSizer(wx.HORIZONTAL)
+        hbox.Add((5,0), 0)
+
+        myform['decim'] = form.int_field(
+            parent=panel, sizer=hbox, label="Decim",
+            callback=myform.check_input_and_call(_form_set_decim, self._set_status_msg))
+
+        hbox.Add((5,0), 1)
+        myform['fs@usb'] = form.static_float_field(
+            parent=panel, sizer=hbox, label="Fs@USB")
+
+        hbox.Add((5,0), 1)
+        myform['dbname'] = form.static_text_field(
+            parent=panel, sizer=hbox)
+
+        hbox.Add((5,0), 1)
+        myform['baseband'] = form.static_float_field(
+            parent=panel, sizer=hbox, label="Analog BB")
+
+        hbox.Add((5,0), 1)
+        myform['ddc'] = form.static_float_field(
+            parent=panel, sizer=hbox, label="DDC")
+
+        hbox.Add((5,0), 0)
+        vbox.Add(hbox, 0, wx.EXPAND)
+
+        
+    def set_freq(self, target_freq):
+        """
+        Set the center frequency we're interested in.
+
+        @param target_freq: frequency in Hz
+        @rypte: bool
+
+        Tuning is a two step process.  First we ask the front-end to
+        tune as close to the desired frequency as it can.  Then we use
+        the result of that operation and our target_frequency to
+        determine the value for the digital down converter.
+        """
+        r = usrp.tune(self.u, 0, self.subdev, target_freq)
+        
+        if r:
+            self.myform['freq'].set_value(target_freq)     # update displayed value
+            if self.show_debug_info:
+                self.myform['baseband'].set_value(r.baseband_freq)
+                self.myform['ddc'].set_value(r.dxc_freq)
+            return True
+
+        return False
+
+    def set_gain(self, gain):
+        self.myform['gain'].set_value(gain)     # update displayed value
+        self.subdev.set_gain(gain)
+
+    def set_decim(self, decim):
+        ok = self.u.set_decim_rate(decim)
+        if not ok:
+            print "set_decim failed"
+        input_rate = self.u.adc_freq() / self.u.decim_rate()
+        self.scope.set_sample_rate(input_rate)
+        if self.show_debug_info:  # update displayed values
+            self.myform['decim'].set_value(self.u.decim_rate())
+            self.myform['fs@usb'].set_value(self.u.adc_freq() / self.u.decim_rate())
+        return ok
+
+def main ():
+    app = stdgui.stdapp(app_flow_graph, "USRP O'scope", nstatus=1)
+    app.MainLoop()
+
+if __name__ == '__main__':
+    main ()
diff --git a/gnuradio-examples/python/usrp/usrp_rx_cfile.py b/gnuradio-examples/python/usrp/usrp_rx_cfile.py
new file mode 100755 (executable)
index 0000000..306e101
--- /dev/null
@@ -0,0 +1,107 @@
+#!/usr/bin/env python
+
+"""
+Read samples from the USRP and write to file formatted as binary
+outputs single precision complex float values or complex short values (interleaved 16 bit signed short integers).
+
+"""
+
+from gnuradio import gr, eng_notation
+from gnuradio import audio
+from gnuradio import usrp
+from gnuradio.eng_option import eng_option
+from optparse import OptionParser
+
+class my_graph(gr.flow_graph):
+
+    def __init__(self):
+        gr.flow_graph.__init__(self)
+
+        usage="%prog: [options] output_filename"
+        parser = OptionParser(option_class=eng_option, usage=usage)
+        parser.add_option("-R", "--rx-subdev-spec", type="subdev", default=(0, 0),
+                          help="select USRP Rx side A or B (default=A)")
+        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("-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","--output-shorts", action="store_true", default=False,
+                          help="output interleaved shorts in stead of complex floats")
+        parser.add_option("-N", "--nsamples", type="eng_float", default=None,
+                          help="number of samples to collect [default=+inf]")
+        (options, args) = parser.parse_args ()
+        if len(args) != 1:
+            parser.print_help()
+            raise SystemExit, 1
+        filename = args[0]
+
+        if options.freq is None:
+            parser.print_help()
+            sys.stderr.write('You must specify the frequency with -f FREQ\n');
+            raise SystemExit, 1
+
+        # build the graph
+        if options.no_hb or (options.decim<8):
+          self.fpga_filename="std_4rx_0tx.rbf" #Min decimation of this firmware is 4. contains 4 Rx paths without halfbands and 0 tx paths.
+          if options.output_shorts:
+            self.u = usrp.source_s(decim_rate=options.decim,fpga_filename=self.fpga_filename)
+          else:
+            self.u = usrp.source_c(decim_rate=options.decim,fpga_filename=self.fpga_filename)
+        else:
+          #standard fpga firmware "std_2rxhb_2tx.rbf" contains 2 Rx paths with halfband filters and 2 tx paths (the default) min decimation 8
+          if options.output_shorts:
+            self.u = usrp.source_s(decim_rate=options.decim)
+          else:
+            self.u = usrp.source_c(decim_rate=options.decim)
+        if options.width_8:
+            sample_width = 8
+            sample_shift = 8
+            format = self.u.make_format(sample_width, sample_shift)
+            r = self.u.set_format(format)
+        if options.output_shorts:
+          self.dst = gr.file_sink(gr.sizeof_short, filename)
+        else:
+          self.dst = gr.file_sink(gr.sizeof_gr_complex, filename)
+        if options.nsamples is None:
+            self.connect(self.u, self.dst)
+        else:
+            if options.output_shorts:
+              self.head = gr.head(gr.sizeof_short, int(options.nsamples)*2)
+            else:
+              self.head = gr.head(gr.sizeof_gr_complex, int(options.nsamples))
+            self.connect(self.u, self.head, self.dst)
+
+        if options.rx_subdev_spec is None:
+            options.rx_subdev_spec = usrp.pick_rx_subdevice(self.u)
+        self.u.set_mux(usrp.determine_rx_mux_value(self.u, options.rx_subdev_spec))
+
+        # determine the daughterboard subdevice we're using
+        self.subdev = usrp.selected_subdev(self.u, options.rx_subdev_spec)
+        print "Using RX d'board %s" % (self.subdev.side_and_name(),)
+        input_rate = self.u.adc_freq() / self.u.decim_rate()
+        print "USB sample rate %s" % (eng_notation.num_to_str(input_rate))
+
+        if options.gain is None:
+            # if no gain was specified, use the mid-point in dB
+            g = self.subdev.gain_range()
+            options.gain = float(g[0]+g[1])/2
+
+        self.subdev.set_gain(options.gain)
+
+        r = self.u.tune(0, self.subdev, options.freq)
+        if not r:
+            sys.stderr.write('Failed to set frequency\n')
+            raise SystemExit, 1
+
+        
+if __name__ == '__main__':
+    try:
+        my_graph().run()
+    except KeyboardInterrupt:
+        pass
diff --git a/gnuradio-examples/python/usrp/usrp_rx_nogui.py b/gnuradio-examples/python/usrp/usrp_rx_nogui.py
new file mode 100755 (executable)
index 0000000..b33d626
--- /dev/null
@@ -0,0 +1,186 @@
+#!/usr/bin/env python
+
+from gnuradio import gr, gru, usrp, optfir, audio, eng_notation, blks
+from gnuradio.eng_option import eng_option
+from optparse import OptionParser
+
+"""
+This example application demonstrates receiving and demodulating 
+different types of signals using the USRP. 
+
+A receive chain is built up of the following signal processing
+blocks:
+
+USRP  - Daughter board source generating complex baseband signal.
+CHAN  - Low pass filter to select channel bandwidth
+RFSQL - RF squelch zeroing output when input power below threshold
+AGC   - Automatic gain control leveling signal at [-1.0, +1.0]
+DEMOD - Demodulation block appropriate to selected signal type.
+        This converts the complex baseband to real audio frequencies,
+       and applies an appropriate low pass decimating filter.
+CTCSS - Optional tone squelch zeroing output when tone is not present.
+RSAMP - Resampler block to convert audio sample rate to user specified
+        sound card output rate.
+AUDIO - Audio sink for playing final output to speakers.
+
+The following are required command line parameters:
+
+-f FREQ                USRP receive frequency
+-m MOD         Modulation type, select from AM, FM, or WFM
+
+The following are optional command line parameters:
+
+-R SUBDEV       Daughter board specification, defaults to first found
+-c FREQ         Calibration offset.  Gets added to receive frequency.
+                Defaults to 0.0 Hz.
+-g GAIN         Daughterboard gain setting. Defaults to mid-range.
+-o RATE         Sound card output rate. Defaults to 32000. Useful if
+                your sound card only accepts particular sample rates.
+-r RFSQL       RF squelch in db. Defaults to -50.0.
+-p FREQ                CTCSS frequency.  Opens squelch when tone is present.
+
+Once the program is running, ctrl-break (Ctrl-C) stops operation.
+
+Please see fm_demod.py and am_demod.py for details of the demodulation
+blocks.
+"""
+
+# (usrp_decim, channel_decim, audio_decim, channel_pass, channel_stop, demod)
+demod_params = {
+               'AM'  : (250, 16, 1,  5000,   8000, blks.demod_10k0a3e_cf),
+               'FM'  : (250,  8, 4,  8000,   9000, blks.demod_20k0f3e_cf),
+               'WFM' : (250,  1, 8, 90000, 100000, blks.demod_200kf3e_cf)
+              }
+
+class usrp_source_c(gr.hier_block):
+    """
+    Create a USRP source object supplying complex floats.
+    
+    Selects user supplied subdevice or chooses first available one.
+
+    Calibration value is the offset from the tuned frequency to 
+    the actual frequency.       
+    """
+    def __init__(self, fg, subdev_spec, decim, gain=None, calibration=0.0):
+       self._decim = decim
+        self._src = usrp.source_c()
+        if subdev_spec is None:
+            subdev_spec = usrp.pick_rx_subdevice(self._src)
+        self._subdev = usrp.selected_subdev(self._src, subdev_spec)
+        self._src.set_mux(usrp.determine_rx_mux_value(self._src, subdev_spec))
+        self._src.set_decim_rate(self._decim)
+
+       # If no gain specified, set to midrange
+       if gain is None:
+           g = self._subdev.gain_range()
+           gain = (g[0]+g[1])/2.0
+
+        self._subdev.set_gain(gain)
+        self._cal = calibration
+       gr.hier_block.__init__(self, fg, self._src, self._src)
+
+    def tune(self, freq):
+       result = usrp.tune(self._src, 0, self._subdev, freq+self._cal)
+       # TODO: deal with residual
+
+    def rate(self):
+       return self._src.adc_rate()/self._decim
+
+class app_flow_graph(gr.flow_graph):
+    def __init__(self, options, args):
+       gr.flow_graph.__init__(self)
+       self.options = options
+       self.args = args
+
+       (usrp_decim, channel_decim, audio_decim, 
+        channel_pass, channel_stop, demod) = demod_params[options.modulation]
+
+        USRP = usrp_source_c(self,                 # Flow graph
+                           options.rx_subdev_spec, # Daugherboard spec
+                           usrp_decim,             # IF decimation ratio
+                           options.gain,           # Receiver gain
+                           options.calibration)    # Frequency offset
+       USRP.tune(options.frequency)
+
+       if_rate = USRP.rate()
+        channel_rate = if_rate // channel_decim
+       audio_rate = channel_rate // audio_decim
+
+       CHAN_taps = optfir.low_pass(1.0,         # Filter gain
+                                  if_rate,      # Sample rate
+                                  channel_pass, # One sided modulation bandwidth
+                                  channel_stop, # One sided channel bandwidth
+                                  0.1,          # Passband ripple
+                                  60)           # Stopband attenuation
+
+       CHAN = gr.freq_xlating_fir_filter_ccf(channel_decim, # Decimation rate
+                                             CHAN_taps,     # Filter taps
+                                             0.0,           # Offset frequency
+                                             if_rate)       # Sample rate
+
+       RFSQL = gr.pwr_squelch_cc(options.rf_squelch,    # Power threshold
+                                 125.0/channel_rate,    # Time constant
+                                 channel_rate/20,       # 50ms rise/fall
+                                 False)                 # Zero, not gate output
+
+       AGC = gr.agc_cc(1.0/channel_rate,  # Time constant
+                       1.0,               # Reference power 
+                       1.0,               # Initial gain
+                       1.0)               # Maximum gain
+
+       DEMOD = demod(self, channel_rate, audio_decim)
+
+       # From RF to audio
+        self.connect(USRP, CHAN, RFSQL, AGC, DEMOD)
+
+       # Optionally add CTCSS and RSAMP if needed
+       tail = DEMOD
+       if options.ctcss != None and options.ctcss > 60.0:
+           CTCSS = gr.ctcss_squelch_ff(audio_rate,    # Sample rate
+                                       options.ctcss) # Squelch tone
+           self.connect(DEMOD, CTCSS)
+           tail = CTCSS
+
+       if options.output_rate != audio_rate:
+           out_lcm = gru.lcm(audio_rate, options.output_rate)
+           out_interp = int(out_lcm // audio_rate)
+           out_decim = int(out_lcm // options.output_rate)
+           RSAMP = blks.rational_resampler_fff(self, out_interp, out_decim)
+           self.connect(tail, RSAMP)
+           tail = RSAMP 
+
+       # Send to default audio output
+        AUDIO = audio.sink(options.output_rate, "")
+       self.connect(tail, AUDIO)
+       
+def main():
+    parser = OptionParser(option_class=eng_option)
+    parser.add_option("-f", "--frequency", type="eng_float",
+                      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("-m", "--modulation", type="choice", choices=('AM','FM','WFM'),
+                      help="set modulation type (AM,FM)", metavar="TYPE")
+    parser.add_option("-o", "--output-rate", type="int", default=32000,
+                      help="set audio output rate to RATE", metavar="RATE")
+    parser.add_option("-r", "--rf-squelch", type="eng_float", default=-50.0,
+                      help="set RF squelch to dB", metavar="dB")
+    parser.add_option("-p", "--ctcss", type="float",
+                     help="set CTCSS squelch to FREQ", metavar="FREQ")
+    (options, args) = parser.parse_args()
+
+    if options.frequency < 1e6:
+       options.frequency *= 1e6
+       
+    fg = app_flow_graph(options, args)
+    try:
+        fg.run()
+    except KeyboardInterrupt:
+        pass
+
+if __name__ == "__main__":
+    main()
diff --git a/gnuradio-examples/python/usrp/usrp_siggen.py b/gnuradio-examples/python/usrp/usrp_siggen.py
new file mode 100755 (executable)
index 0000000..59e01e0
--- /dev/null
@@ -0,0 +1,180 @@
+#!/usr/bin/env python
+
+from gnuradio import gr, gru
+from gnuradio import usrp
+from gnuradio.eng_option import eng_option
+from gnuradio import eng_notation
+from optparse import OptionParser
+import sys
+
+
+class my_graph(gr.flow_graph):
+    def __init__ (self):
+        gr.flow_graph.__init__(self)
+        
+        # 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._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.file_sink = gr.file_sink (gr.sizeof_gr_complex, "siggen.dat")
+
+    def _configure_graph (self, type):
+        was_running = self.is_running ()
+        if was_running:
+            self.stop ()
+        self.disconnect_all ()
+        if type == gr.GR_SIN_WAVE or type == gr.GR_CONST_WAVE:
+            self.connect (self.siggen, self.u)
+            # 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, self.u)
+            self.noisegen.set_type (type)
+            self.src = self.noisegen
+        else:
+            raise ValueError, type
+        if was_running:
+            self.start ()
+
+    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")
+
+    parser.add_option ("--sine", dest="type", action="store_const", const=gr.GR_SIN_WAVE,
+                       help="generate a complex sinusoid [default]", default=gr.GR_SIN_WAVE)
+    parser.add_option ("--const", dest="type", action="store_const", const=gr.GR_CONST_WAVE, 
+                       help="generate a constant output")
+    parser.add_option ("--gaussian", dest="type", action="store_const", const=gr.GR_GAUSSIAN,
+                       help="generate Gaussian random output")
+    parser.add_option ("--uniform", dest="type", action="store_const", const=gr.GR_UNIFORM,
+                       help="generate Uniform random output")
+
+    parser.add_option ("-w", "--waveform-freq", type="eng_float", default=100e3,
+                       help="set waveform frequency to FREQ")
+    parser.add_option ("-a", "--amplitude", type="eng_float", default=16e3,
+                       help="set waveform amplitude to AMPLITUDE", metavar="AMPL")
+    parser.add_option ("-o", "--offset", type="eng_float", default=0,
+                       help="set waveform offset to OFFSET")
+    (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
+
+    fg = my_graph()
+    fg.set_interpolator (options.interp)
+    fg.set_waveform_type (options.type)
+    fg.set_waveform_freq (options.waveform_freq)
+    fg.set_waveform_ampl (options.amplitude)
+    fg.set_waveform_offset (options.offset)
+
+    # determine the daughterboard subdevice we're using
+    if options.tx_subdev_spec is None:
+        options.tx_subdev_spec = usrp.pick_tx_subdevice(fg.u)
+
+    m = usrp.determine_tx_mux_value(fg.u, options.tx_subdev_spec)
+    #print "mux = %#04x" % (m,)
+    fg.u.set_mux(m)
+    fg.subdev = usrp.selected_subdev(fg.u, options.tx_subdev_spec)
+    print "Using TX d'board %s" % (fg.subdev.side_and_name(),)
+    
+    fg.subdev.set_gain(fg.subdev.gain_range()[1])    # set max Tx gain
+
+    if not fg.set_freq(options.rf_freq):
+        sys.stderr.write('Failed to set RF frequency\n')
+        raise SystemExit
+    
+    fg.subdev.set_enable(True)                       # enable transmitter
+
+    try:
+        fg.run()
+    except KeyboardInterrupt:
+        pass
+
+if __name__ == '__main__':
+    main ()
diff --git a/gnuradio-examples/python/usrp/usrp_tv_rcv.py b/gnuradio-examples/python/usrp/usrp_tv_rcv.py
new file mode 100755 (executable)
index 0000000..ed78273
--- /dev/null
@@ -0,0 +1,394 @@
+#!/usr/bin/env python
+"""
+Realtime capture and display of analog Tv stations.
+Can also use a file as source or sink
+When you use an output file you can show the results frame-by-frame using ImageMagick
+When you want to use the realtime sdl display window you must first install gr-video-sdl (is in gnuradio cvs).
+When you use a file source, in stead of the usrp, make sure you capture interleaved shorts.
+(Use usrp_rx_file.py, or use usrp_rx_cfile.py --output-shorts if you have a recent enough usrp_rx_cfile.py)
+There is no synchronisation yet. The sync blocks are in development but not yet in cvs.
+
+"""
+from gnuradio import gr, gru, eng_notation, optfir
+try:
+  from gnuradio import video_sdl
+except:
+  print "FYI: gr-video-sdl is not installed"
+  print "realtime SDL video output window will not be available"
+from gnuradio import usrp
+from gnuradio import blks
+from gnuradio.eng_option import eng_option
+from gnuradio.wxgui import slider, powermate
+from gnuradio.wxgui import stdgui, fftsink, form
+from optparse import OptionParser
+import usrp_dbid
+import sys
+import math
+import wx
+
+# To debug, 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...
+
+def pick_subdevice(u):
+    """
+    The user didn't specify a subdevice on the command line.
+    Try for one of these, in order: TV_RX, BASIC_RX, whatever is on side A.
+
+    @return a subdev_spec
+    """
+    return usrp.pick_subdev(u, (usrp_dbid.TV_RX,
+                                usrp_dbid.TV_RX_REV_2,
+                                usrp_dbid.BASIC_RX))
+
+
+class tv_rx_graph (stdgui.gui_flow_graph):
+    def __init__(self,frame,panel,vbox,argv):
+        stdgui.gui_flow_graph.__init__ (self,frame,panel,vbox,argv)
+
+        usage="%prog: [options] [input_filename]. \n If you don't specify an input filename the usrp will be used as source\n " \
+              "Make sure your input capture file containes interleaved shorts not complex floats"
+        parser=OptionParser(option_class=eng_option)
+        parser.add_option("-R", "--rx-subdev-spec", type="subdev", default=None,
+                          help="select USRP Rx side A or B (default=A)")
+        parser.add_option("-d", "--decim", type="int", default=64,
+                          help="set fgpa decimation rate to DECIM [default=%default]")
+        parser.add_option("-f", "--freq", type="eng_float", default=519.25e6,
+                          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("-c", "--contrast", type="eng_float", default=1.0,
+                          help="set contrast (default is 1.0)")
+        parser.add_option("-b", "--brightness", type="eng_float", default=0.0,
+                          help="set brightness (default is 0)")
+        parser.add_option("-8", "--width-8", action="store_true", default=False,
+                          help="Enable 8-bit samples across USB")
+        parser.add_option("-p", "--pal", action="store_true", default=False,
+                          help="PAL video format (this is the default)")
+        parser.add_option("-n", "--ntsc", action="store_true", default=False,
+                          help="NTSC video format")
+        parser.add_option("-o", "--out-filename", type="string", default="sdl",
+                          help="For example out_raw_uchar.gray. If you don't specify an output filename you will get a video_sink_sdl realtime output window. You then need to have gr-video-sdl installed)")
+        parser.add_option("-r", "--repeat", action="store_false", default=True,
+                          help="repeat file in a loop")
+        parser.add_option("-N", "--no-hb", action="store_true", default=False,
+                          help="don't use halfband filter in usrp")
+
+        (options, args) = parser.parse_args()
+        if not ((len(args) == 1) or (len(args) == 0)):
+            parser.print_help()
+            sys.exit(1)
+        
+        if len(args) == 1:
+          filename = args[0]
+        else:
+          filename = None
+
+        self.frame = frame
+        self.panel = panel
+        
+        self.contrast = options.contrast
+        self.brightness = options.brightness
+        self.state = "FREQ"
+        self.freq = 0
+
+        # build graph
+
+        self.u=None
+
+        usrp_decim = options.decim # 32
+
+        if not (options.out_filename=="sdl"):
+          options.repeat=False
+
+        if not ((filename is None) or (filename=="usrp")):
+          self.filesource = gr.file_source(gr.sizeof_short,filename,options.repeat) # file is data source
+          self.istoc = gr.interleaved_short_to_complex()
+          self.connect(self.filesource,self.istoc)
+          adc_rate=64e6
+          self.src=self.istoc
+          options.gain=0.0
+          self.gain=0.0
+        else:
+          if options.no_hb or (options.decim<8):
+            self.fpga_filename="std_4rx_0tx.rbf" #contains 4 Rx paths without halfbands and 0 tx paths
+          else:
+            self.fpga_filename="std_2rxhb_2tx.rbf" # contains 2 Rx paths with halfband filters and 2 tx paths (the default)
+          self.u = usrp.source_c(0,fpga_filename=self.fpga_filename)                    # usrp is data source
+          if options.width_8:
+              sample_width = 8
+              sample_shift = 8
+              format = self.u.make_format(sample_width, sample_shift)
+              r = self.u.set_format(format)
+          adc_rate = self.u.adc_rate()                # 64 MS/s
+          self.u.set_decim_rate(usrp_decim)
+          if options.rx_subdev_spec is None:
+            options.rx_subdev_spec = pick_subdevice(self.u)
+          self.u.set_mux(usrp.determine_rx_mux_value(self.u, options.rx_subdev_spec))
+          self.subdev = usrp.selected_subdev(self.u, options.rx_subdev_spec)
+          print "Using RX d'board %s" % (self.subdev.side_and_name(),)
+          if options.gain is None:
+            # if no gain was specified, use the mid-point in dB
+            g = self.subdev.gain_range()
+            options.gain = float(g[0]+g[1])/2
+          self.src=self.u
+
+        usrp_rate = adc_rate / usrp_decim           # 320 kS/s
+
+        f2uc=gr.float_to_uchar()
+        # sdl window as final sink
+        if not (options.pal or options.ntsc):
+          options.pal=True #set default to PAL
+        if options.pal:
+          lines_per_frame=625.0
+          frames_per_sec=25.0
+          show_width=768
+        elif options.ntsc:
+          lines_per_frame=525.0
+          frames_per_sec=29.97002997
+          show_width=640
+        width=int(usrp_rate/(lines_per_frame*frames_per_sec))
+        height=int(lines_per_frame)
+
+        if (options.out_filename=="sdl"):
+          #Here comes the tv screen, you have to build and install gr-video-sdl for this (subproject of gnuradio, only in cvs for now)
+          try:
+            video_sink = video_sdl.sink_uc ( frames_per_sec, width, height,0,show_width,height)
+          except:
+            print "gr-video-sdl is not installed"
+            print "realtime \"sdl\" video output window is not available"
+            raise SystemExit, 1
+          self.dst=video_sink
+        else:
+          print "You can use the imagemagick display tool to show the resulting imagesequence"
+          print "use the following line to show the demodulated TV-signal:"
+          print "display -depth 8 -size " +str(width)+ "x" + str(height) + " gray:" + options.out_filename
+          print "(Use the spacebar to advance to next frames)" 
+          options.repeat=False
+          file_sink=gr.file_sink(gr.sizeof_char, options.out_filename)
+          self.dst =file_sink 
+
+        self.agc=gr.agc_cc(1e-7,1.0,1.0) #1e-7
+        self.am_demod = gr.complex_to_mag ()
+        self.set_blacklevel=gr.add_const_ff(0.0)
+        self.invert_and_scale = gr.multiply_const_ff (0.0) #-self.contrast *128.0*255.0/(200.0)
+
+        # now wire it all together
+        #sample_rate=options.width*options.height*options.framerate
+
+        process_type='do_no_sync'
+        if process_type=='do_no_sync':
+          self.connect (self.src, self.agc,self.am_demod,self.invert_and_scale, self.set_blacklevel,f2uc,self.dst)
+        elif process_type=='do_tv_sync_adv':
+          #defaults: gr.tv_sync_adv (double sampling_freq, unsigned int tv_format,bool output_active_video_only=false, bool do_invert=false, double wanted_black_level=0.0, double wanted_white_level=255.0, double avg_alpha=0.1, double initial_gain=1.0, double initial_offset=0.0,bool debug=false)
+          self.tv_sync_adv=gr.tv_sync_adv(usrp_rate,0,False,False,0.0,255.0,0.01,1.0,0.0,False) #note, this block is not yet in cvs
+          self.connect (self.src, self.am_demod,self.invert_and_scale,self.tv_sync_adv,s2f,f2uc,self.dst) 
+        elif process_type=='do_nullsink':
+          #self.connect (self.src, self.am_demod,self.invert_and_scale,f2uc,video_sink)
+          c2r=gr.complex_to_real()
+          nullsink=gr.null_sink(gr.sizeof_float)
+          self.connect (self.src, c2r,nullsink) #video_sink)
+        elif process_type=='do_tv_sync_corr':
+          frame_size=width*height #int(usrp_rate/25.0)
+          nframes=10# 32
+          search_window=20*nframes 
+          debug=False
+          video_alpha=0.3 #0.1
+          corr_alpha=0.3
+          tv_corr=gr.tv_correlator_ff(frame_size,nframes, search_window, video_alpha, corr_alpha,debug) #Note: this block is not yet in cvs
+          shift=gr.add_const_ff(-0.7)
+          self.connect (self.src, self.agc,self.am_demod,tv_corr,self.invert_and_scale, self.set_blacklevel,f2uc,self.dst) #self.agc,
+        else: # process_type=='do_test_image':
+          src_vertical_bars = gr.sig_source_f (usrp_rate, gr.GR_SIN_WAVE, 10.0 *usrp_rate/320, 255,128)
+          self.connect(src_vertical_bars,f2uc,self.dst)
+
+        self._build_gui(vbox, usrp_rate, usrp_rate, usrp_rate)
+
+   
+        if abs(options.freq) < 1e6:
+            options.freq *= 1e6
+
+        # set initial values
+        self.set_gain(options.gain)
+        self.set_contrast(self.contrast)
+        self.set_brightness(options.brightness)
+        if not(self.set_freq(options.freq)):
+            self._set_status_msg("Failed to set initial frequency")
+
+
+    def _set_status_msg(self, msg, which=0):
+        self.frame.GetStatusBar().SetStatusText(msg, which)
+
+
+    def _build_gui(self, vbox, usrp_rate, demod_rate, audio_rate):
+
+        def _form_set_freq(kv):
+            return self.set_freq(kv['freq'])
+
+
+        if 0:
+            self.src_fft = fftsink.fft_sink_c (self, self.panel, title="Data from USRP",
+                                               fft_size=512, sample_rate=usrp_rate)
+            self.connect (self.src, self.src_fft)
+            vbox.Add (self.src_fft.win, 4, wx.EXPAND)
+
+        if 0:
+            post_demod_fft = fftsink.fft_sink_f (self, self.panel, title="Post Demod",
+                                                  fft_size=512, sample_rate=demod_rate,
+                                                  y_per_div=10, ref_level=-40)
+            self.connect (self.am_demod, post_demod_fft)
+            vbox.Add (post_demod_fft.win, 4, wx.EXPAND)
+
+        if 0:
+            post_filt_fft = fftsink.fft_sink_f (self, self.panel, title="Post Filter", 
+                                                fft_size=512, sample_rate=audio_rate,
+                                                y_per_div=10, ref_level=-40)
+            self.connect (self.set_blacklevel, post_filt)
+            vbox.Add (fft_win4, 4, wx.EXPAND)
+
+        
+        # control area form at bottom
+        self.myform = myform = form.form()
+
+        if not (self.u is None):
+          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=(50.25e6, 900.25e6, 0.25e6),
+                                        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['contrast'] = \
+            form.quantized_slider_field(parent=self.panel, sizer=hbox, label="Contrast",
+                                        weight=3, range=(-2.0, 2.0, 0.1),
+                                        callback=self.set_contrast)
+        hbox.Add((5,0), 1)
+
+        myform['brightness'] = \
+            form.quantized_slider_field(parent=self.panel, sizer=hbox, label="Brightness",
+                                        weight=3, range=(-255.0, 255.0, 1.0),
+                                        callback=self.set_brightness)
+        hbox.Add((5,0), 0)
+
+        if not (self.u is None):
+          myform['gain'] = \
+              form.quantized_slider_field(parent=self.panel, sizer=hbox, label="Gain",
+                                        weight=3, range=self.subdev.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
+        elif (self.state == "CONTRAST"):
+            step = 0.1
+            if self.rot >= 3:
+                self.set_contrast(self.contrast + step)
+                self.rot -= 3
+            elif self.rot <=-3:
+                self.set_contrast(self.contrast - step)
+                self.rot += 3
+        else:
+            step = 1
+            if self.rot >= 3:
+                self.set_brightness(self.brightness + step)
+                self.rot -= 3
+            elif self.rot <=-3:
+                self.set_brightness(self.brightness - 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 = "CONTRAST"
+        elif self.state == "CONTRAST":
+            self.state = "BRIGHTNESS"
+        else:
+            self.state = "FREQ"
+        self.update_status_bar ()
+        
+
+    def set_contrast (self, contrast):
+        self.contrast = contrast
+        self.invert_and_scale.set_k(-self.contrast *128.0*255.0/(200.0))
+        self.myform['contrast'].set_value(self.contrast)
+        self.update_status_bar ()
+
+    def set_brightness (self, brightness):
+        self.brightness = brightness
+        self.set_blacklevel.set_k(self.brightness +255.0)
+        self.myform['brightness'].set_value(self.brightness)
+        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.
+        """
+        if not (self.u is None):
+          r = usrp.tune(self.u, 0, self.subdev, 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):
+        if not (self.u is None):
+          self.gain=gain
+          self.myform['gain'].set_value(gain)     # update displayed value
+          self.subdev.set_gain(gain)
+          self.update_status_bar()
+
+    def update_status_bar (self):
+        msg = "Setting:%s Contrast:%r Brightness:%r Gain: %r" % (self.state, self.contrast,self.brightness,self.gain)
+        self._set_status_msg(msg, 1)
+        #self.src_fft.set_baseband_freq(self.freq)
+
+        
+
+if __name__ == '__main__':
+    app = stdgui.stdapp (tv_rx_graph, "USRP TV RX black-and-white")
+    app.MainLoop ()
diff --git a/gnuradio-examples/python/usrp/usrp_tv_rcv_nogui.py b/gnuradio-examples/python/usrp/usrp_tv_rcv_nogui.py
new file mode 100755 (executable)
index 0000000..e563188
--- /dev/null
@@ -0,0 +1,179 @@
+#!/usr/bin/env python
+
+"""
+Reads from a file and generates PAL TV pictures in black and white
+which can be displayed using ImageMagick or realtime using gr-video-sdl
+(To capture the input file Use usrp_rx_file.py, or use usrp_rx_cfile.py --output-shorts if you have a recent enough usrp_rx_cfile.py)
+Can also use usrp directly as capture source, but then you need a higher decimation factor (64)
+and thus get a lower horizontal resulution.
+There is no synchronisation yet. The sync blocks are in development but not yet in cvs.
+
+"""
+
+from gnuradio import gr, eng_notation
+from gnuradio import audio
+from gnuradio import usrp
+from gnuradio.eng_option import eng_option
+from optparse import OptionParser
+import sys
+
+try:
+  from gnuradio import video_sdl
+except:
+  print "FYI: gr-video-sdl is not installed"
+  print "realtime \"sdl\" video output window will not be available"
+
+
+class my_graph(gr.flow_graph):
+
+    def __init__(self):
+        gr.flow_graph.__init__(self)
+
+        usage="%prog: [options] output_filename. \n Special output_filename \"sdl\" will use video_sink_sdl as realtime output window. " \
+              "You then need to have gr-video-sdl installed. \n" \
+              "Make sure your input capture file containes interleaved shorts not complex floats"
+        parser = OptionParser(option_class=eng_option, usage=usage)
+        parser.add_option("-R", "--rx-subdev-spec", type="subdev", default=(0, 0),
+                          help="select USRP Rx side A or B (default=A)")
+        parser.add_option("-c", "--contrast", type="eng_float", default=1.0,
+                          help="set contrast (default is 1.0)")
+        parser.add_option("-b", "--brightness", type="eng_float", default=0.0,
+                          help="set brightness (default is 0)")
+        parser.add_option("-d", "--decim", type="int", default=8,
+                          help="set fgpa decimation rate to DECIM [default=%default]")
+        parser.add_option("-i", "--in-filename", type="string", default=None,
+                          help="Use input file as source. samples must be interleaved shorts \n " +
+                               "Use usrp_rx_file.py or usrp_rx_cfile.py --output-shorts. \n"
+                               "Special name \"usrp\"  results in realtime capturing and processing using usrp. \n" +
+                               "You then probably need a decimation factor of 64 or higher.")
+        parser.add_option("-f", "--freq", type="eng_float", default=None,
+                          help="set frequency to FREQ.\nNote that the frequency of the video carrier is not at the middle of the TV channel", metavar="FREQ")
+        parser.add_option("-g", "--gain", type="eng_float", default=None,
+                          help="set gain in dB (default is midpoint)")
+        parser.add_option("-p", "--pal", action="store_true", default=False,
+                          help="PAL video format (this is the default)")
+        parser.add_option("-n", "--ntsc", action="store_true", default=False,
+                          help="NTSC video format")
+        parser.add_option("-r", "--repeat", action="store_false", default=True,
+                          help="repeat in_file in a loop")
+        parser.add_option("-8", "--width-8", action="store_true", default=False,
+                          help="Enable 8-bit samples across USB")
+        parser.add_option("-N", "--nframes", type="eng_float", default=None,
+                          help="number of frames to collect [default=+inf]")
+        parser.add_option( "--no-hb", action="store_true", default=False,
+                          help="don't use halfband filter in usrp")
+        (options, args) = parser.parse_args ()
+        if not (len(args) == 1):
+            parser.print_help()
+            sys.stderr.write('You must specify the output. FILENAME or sdl \n');
+            sys.exit(1)
+        
+        filename = args[0]
+
+        if options.in_filename is None:
+            parser.print_help()
+            sys.stderr.write('You must specify the input -i FILENAME or -i usrp\n');
+            raise SystemExit, 1
+
+        if not (filename=="sdl"):
+          options.repeat=False
+
+        if not (options.in_filename=="usrp"):
+          self.filesource = gr.file_source(gr.sizeof_short,options.in_filename,options.repeat) # file is data source, capture with usr_rx_csfile.py
+          self.istoc = gr.interleaved_short_to_complex()
+          self.connect(self.filesource,self.istoc)
+          self.adc_rate=64e6
+          self.src=self.istoc
+        else:
+          if options.freq is None:
+            parser.print_help()
+            sys.stderr.write('You must specify the frequency with -f FREQ\n');
+            raise SystemExit, 1
+          if abs(options.freq) < 1e6:
+              options.freq *= 1e6
+          if options.no_hb or (options.decim<8):
+            self.fpga_filename="std_4rx_0tx.rbf" #contains 4 Rx paths without halfbands and 0 tx paths
+          else:
+            self.fpga_filename="std_2rxhb_2tx.rbf" # contains 2 Rx paths with halfband filters and 2 tx paths (the default)
+
+          # build the graph
+          self.u = usrp.source_c(decim_rate=options.decim,fpga_filename=self.fpga_filename)
+          self.src=self.u
+          if options.width_8:
+              sample_width = 8
+              sample_shift = 8
+              format = self.u.make_format(sample_width, sample_shift)
+              r = self.u.set_format(format)
+          self.adc_rate=self.u.adc_freq()
+          if options.rx_subdev_spec is None:
+              options.rx_subdev_spec = usrp.pick_rx_subdevice(self.u)
+          self.u.set_mux(usrp.determine_rx_mux_value(self.u, options.rx_subdev_spec))
+          # determine the daughterboard subdevice we're using
+          self.subdev = usrp.selected_subdev(self.u, options.rx_subdev_spec)
+          print "Using RX d'board %s" % (self.subdev.side_and_name(),)
+
+          if options.gain is None:
+              # if no gain was specified, use the mid-point in dB
+              g = self.subdev.gain_range()
+              options.gain = float(g[0]+g[1])/2
+          self.subdev.set_gain(options.gain)
+
+          r = self.u.tune(0, self.subdev, options.freq)
+          if not r:
+              sys.stderr.write('Failed to set frequency\n')
+              raise SystemExit, 1
+
+        input_rate = self.adc_rate / options.decim
+        print "video sample rate %s" % (eng_notation.num_to_str(input_rate))
+
+        self.agc=gr.agc_cc(1e-7,1.0,1.0) #1e-7
+        self.am_demod = gr.complex_to_mag ()
+        self.set_blacklevel=gr.add_const_ff(options.brightness +255.0)
+        self.invert_and_scale = gr.multiply_const_ff (-options.contrast *128.0*255.0/(200.0))
+        self.f2uc=gr.float_to_uchar()
+
+          # sdl window as final sink
+        if not (options.pal or options.ntsc):
+          options.pal=True #set default to PAL
+        if options.pal:
+          lines_per_frame=625.0
+          frames_per_sec=25.0
+          show_width=768
+        elif options.ntsc:
+          lines_per_frame=525.0
+          frames_per_sec=29.97002997
+          show_width=640
+        width=int(input_rate/(lines_per_frame*frames_per_sec))
+        height=int(lines_per_frame)
+
+        if filename=="sdl":
+          #Here comes the tv screen, you have to build and install gr-video-sdl for this (subproject of gnuradio, only in cvs for now)
+          try:
+            video_sink = video_sdl.sink_uc ( frames_per_sec, width, height,0,show_width,height)
+          except:
+            print "gr-video-sdl is not installed"
+            print "realtime \"sdl\" video output window is not available"
+            raise SystemExit, 1
+          self.dst=video_sink
+        else:
+          print "You can use the imagemagick display tool to show the resulting imagesequence"
+          print "use the following line to show the demodulated TV-signal:"
+          print "display -depth 8 -size " +str(width)+ "x" + str(height) + " gray:" +filename
+          print "(Use the spacebar to advance to next frames)" 
+          file_sink=gr.file_sink(gr.sizeof_char, filename)
+          self.dst =file_sink 
+
+        if options.nframes is None:
+            self.connect(self.src, self.agc)
+        else:
+            self.head = gr.head(gr.sizeof_gr_complex, int(options.nframes*width*height))
+            self.connect(self.src, self.head, self.agc)
+
+        self.connect (self.agc,self.am_demod,self.invert_and_scale, self.set_blacklevel,self.f2uc,self.dst)
+
+        
+if __name__ == '__main__':
+    try:
+        my_graph().run()
+    except KeyboardInterrupt:
+        pass
diff --git a/gnuradio-examples/python/usrp/usrp_wfm_rcv.py b/gnuradio-examples/python/usrp/usrp_wfm_rcv.py
new file mode 100755 (executable)
index 0000000..2029107
--- /dev/null
@@ -0,0 +1,269 @@
+#!/usr/bin/env python
+
+from gnuradio import gr, gru, eng_notation, optfir
+from gnuradio import audio
+from gnuradio import usrp
+from gnuradio import blks
+from gnuradio.eng_option import eng_option
+from gnuradio.wxgui import slider, powermate
+from gnuradio.wxgui import stdgui, fftsink, form
+from optparse import OptionParser
+import usrp_dbid
+import sys
+import math
+import wx
+
+def pick_subdevice(u):
+    """
+    The user didn't specify a subdevice on the command line.
+    Try for one of these, in order: TV_RX, BASIC_RX, whatever is on side A.
+
+    @return a subdev_spec
+    """
+    return usrp.pick_subdev(u, (usrp_dbid.TV_RX,
+                                usrp_dbid.TV_RX_REV_2,
+                                usrp_dbid.BASIC_RX))
+
+
+class wfm_rx_graph (stdgui.gui_flow_graph):
+    def __init__(self,frame,panel,vbox,argv):
+        stdgui.gui_flow_graph.__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 USRP 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.state = "FREQ"
+        self.freq = 0
+
+        # build graph
+        
+        self.u = usrp.source_c()                    # usrp is data source
+
+        adc_rate = self.u.adc_rate()                # 64 MS/s
+        usrp_decim = 200
+        self.u.set_decim_rate(usrp_decim)
+        usrp_rate = adc_rate / usrp_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 = blks.wfm_rcv (self, 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, usrp_rate, demod_rate, audio_rate)
+
+        if options.gain is None:
+            # if no gain was specified, use the mid-point in dB
+            g = self.subdev.gain_range()
+            options.gain = float(g[0]+g[1])/2
+
+        if options.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")
+
+
+    def _set_status_msg(self, msg, which=0):
+        self.frame.GetStatusBar().SetStatusText(msg, which)
+
+
+    def _build_gui(self, vbox, usrp_rate, demod_rate, audio_rate):
+
+        def _form_set_freq(kv):
+            return self.set_freq(kv['freq'])
+
+
+        if 1:
+            self.src_fft = fftsink.fft_sink_c (self, self.panel, title="Data from USRP",
+                                               fft_size=512, sample_rate=usrp_rate)
+            self.connect (self.u, self.src_fft)
+            vbox.Add (self.src_fft.win, 4, wx.EXPAND)
+
+        if 1:
+            post_filt_fft = fftsink.fft_sink_f (self, self.panel, title="Post Demod", 
+                                                fft_size=1024, sample_rate=usrp_rate,
+                                                y_per_div=10, ref_level=0)
+            self.connect (self.guts.fm_demod, post_filt_fft)
+            vbox.Add (post_filt_fft.win, 4, wx.EXPAND)
+
+        if 0:
+            post_deemph_fft = fftsink.fft_sink_f (self, self.panel, title="Post Deemph",
+                                                  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=(87.9e6, 108.1e6, 0.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.subdev.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 = usrp.tune(self.u, 0, self.subdev, 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.subdev.set_gain(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 = stdgui.stdapp (wfm_rx_graph, "USRP WFM RX")
+    app.MainLoop ()
diff --git a/gnuradio-examples/python/usrp/usrp_wfm_rcv2_nogui.py b/gnuradio-examples/python/usrp/usrp_wfm_rcv2_nogui.py
new file mode 100755 (executable)
index 0000000..40e7dd7
--- /dev/null
@@ -0,0 +1,144 @@
+#!/usr/bin/env python
+
+from gnuradio import gr, gru, eng_notation, optfir
+from gnuradio import audio
+from gnuradio import usrp
+from gnuradio import blks
+from gnuradio.eng_option import eng_option
+from optparse import OptionParser
+import usrp_dbid
+import sys
+import math
+
+def pick_subdevice(u):
+    """
+    The user didn't specify a subdevice on the command line.
+    Try for one of these, in order: TV_RX, BASIC_RX, whatever is on side A.
+
+    @return a subdev_spec
+    """
+    return usrp.pick_subdev(u, (usrp_dbid.TV_RX,
+                                usrp_dbid.TV_RX_REV_2,
+                                usrp_dbid.BASIC_RX))
+
+
+class wfm_rx_graph (gr.flow_graph):
+
+    def __init__(self):
+        gr.flow_graph.__init__(self)
+
+        parser=OptionParser(option_class=eng_option)
+        parser.add_option("-R", "--rx-subdev-spec", type="subdev", default=None,
+                          help="select USRP Rx side A or B (default=A)")
+        parser.add_option("", "--f1", type="eng_float", default=100.7e6,
+                          help="set 1st station frequency to FREQ", metavar="FREQ")
+        parser.add_option("", "--f2", type="eng_float", default=102.5e6,
+                          help="set 2nd station freq 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("-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)
+        
+        if abs(options.f1) < 1e6:
+            options.f1 *= 1e6
+
+        if abs(options.f2) < 1e6:
+            options.f2 *= 1e6
+
+        if abs(options.f1 - options.f2) > 5.5e6:
+            print "Sorry, two stations must be within 5.5MHz of each other"
+            raise SystemExit
+
+        f = (options.f1, options.f2)
+        
+        self.vol = .1
+        self.state = "FREQ"
+
+        # build graph
+        
+        self.u = usrp.source_c(0, nchan=2)          # usrp is data source
+
+        adc_rate = self.u.adc_rate()                # 64 MS/s
+        usrp_decim = 200
+        self.u.set_decim_rate(usrp_decim)
+        usrp_rate = adc_rate / usrp_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)
+
+        mv = usrp.determine_rx_mux_value(self.u, options.rx_subdev_spec)
+        mv |= (mv << 8) & 0xff00   # both DDC inputs setup same way
+        self.u.set_mux(mv)
+        self.subdev = usrp.selected_subdev(self.u, options.rx_subdev_spec)
+        print "Using RX d'board %s" % (self.subdev.side_and_name(),)
+
+
+        # deinterleave two channels from FPGA
+        di = gr.deinterleave(gr.sizeof_gr_complex)
+        
+        # wire up the head of the chain
+        self.connect(self.u, di)
+        
+        # sound card as final sink
+        audio_sink = audio.sink(int(audio_rate), options.audio_output)
+
+        # taps for channel filter
+        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)
+
+        mid_freq = (f[0] + f[1]) / 2
+        # set front end PLL to middle frequency
+        ok, baseband_freq = self.subdev.set_freq(mid_freq)
+
+        for n in range(2):
+            chan_filt = gr.fir_filter_ccf (chanfilt_decim, chan_filt_coeffs)
+            guts = blks.wfm_rcv (self, demod_rate, audio_decimation)
+            volume_control = gr.multiply_const_ff(self.vol)
+            self.connect((di, n), chan_filt)
+            self.connect(chan_filt, guts, volume_control)
+            self.connect(volume_control, (audio_sink, n))
+            dxc_freq, inverted = usrp.calc_dxc_freq(f[n], baseband_freq,
+                                                    self.u.converter_rate())
+            self.u.set_rx_freq(n, dxc_freq)
+        
+
+        if options.gain is None:
+            # if no gain was specified, use the mid-point in dB
+            g = self.subdev.gain_range()
+            options.gain = float(g[0]+g[1])/2
+
+
+        # set initial values
+        self.set_gain(options.gain)
+
+
+    def set_vol (self, vol):
+        self.vol = vol
+        self.volume_control.set_k(self.vol)
+
+
+    def set_gain(self, gain):
+        self.subdev.set_gain(gain)
+
+    
+if __name__ == '__main__':
+    fg = wfm_rx_graph()
+    try:
+        fg.run()
+    except KeyboardInterrupt:
+        pass
diff --git a/gnuradio-examples/python/usrp/usrp_wfm_rcv_nogui.py b/gnuradio-examples/python/usrp/usrp_wfm_rcv_nogui.py
new file mode 100755 (executable)
index 0000000..69f810b
--- /dev/null
@@ -0,0 +1,153 @@
+#!/usr/bin/env python
+
+from gnuradio import gr, gru, eng_notation, optfir
+from gnuradio import audio
+from gnuradio import usrp
+from gnuradio import blks
+from gnuradio.eng_option import eng_option
+from optparse import OptionParser
+import usrp_dbid
+import sys
+import math
+
+def pick_subdevice(u):
+    """
+    The user didn't specify a subdevice on the command line.
+    Try for one of these, in order: TV_RX, BASIC_RX, whatever is on side A.
+
+    @return a subdev_spec
+    """
+    return usrp.pick_subdev(u, (usrp_dbid.TV_RX,
+                                usrp_dbid.TV_RX_REV_2,
+                                usrp_dbid.BASIC_RX))
+
+
+class wfm_rx_graph (gr.flow_graph):
+
+    def __init__(self):
+        gr.flow_graph.__init__(self)
+
+        parser=OptionParser(option_class=eng_option)
+        parser.add_option("-R", "--rx-subdev-spec", type="subdev", default=None,
+                          help="select USRP Rx side A or B (default=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=None,
+                          help="set gain in dB (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.vol = .1
+        self.state = "FREQ"
+        self.freq = 0
+
+        # build graph
+        
+        self.u = usrp.source_c()                    # usrp is data source
+
+        adc_rate = self.u.adc_rate()                # 64 MS/s
+        usrp_decim = 200
+        self.u.set_decim_rate(usrp_decim)
+        usrp_rate = adc_rate / usrp_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 = blks.wfm_rcv (self, 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)
+
+
+        if options.gain is None:
+            # if no gain was specified, use the mid-point in dB
+            g = self.subdev.gain_range()
+            options.gain = float(g[0]+g[1])/2
+
+        if abs(options.freq) < 1e6:
+            options.freq *= 1e6
+
+        # set initial values
+
+        self.set_gain(options.gain)
+
+        if not(self.set_freq(options.freq)):
+            self._set_status_msg("Failed to set initial frequency")
+
+    def set_vol (self, vol):
+        self.vol = vol
+        self.volume_control.set_k(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.tune(0, self.subdev, target_freq)
+        
+        if r:
+            self.freq = target_freq
+            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.subdev.set_gain(gain)
+
+    def update_status_bar (self):
+        msg = "Freq: %s  Volume:%f  Setting:%s" % (
+            eng_notation.num_to_str(self.freq), self.vol, self.state)
+        self._set_status_msg(msg, 1)
+        
+    def _set_status_msg(self, msg, which=0):
+        print msg
+
+    
+if __name__ == '__main__':
+    fg = wfm_rx_graph()
+    try:
+        fg.run()
+    except KeyboardInterrupt:
+        pass
diff --git a/gnuradio-examples/python/usrp/usrp_wfm_rcv_pll.py b/gnuradio-examples/python/usrp/usrp_wfm_rcv_pll.py
new file mode 100755 (executable)
index 0000000..773076a
--- /dev/null
@@ -0,0 +1,311 @@
+#!/usr/bin/env python
+
+from gnuradio import gr, gru, eng_notation, optfir
+from gnuradio import audio
+from gnuradio import usrp
+from gnuradio import blks
+from gnuradio.eng_option import eng_option
+from gnuradio.wxgui import slider, powermate
+from gnuradio.wxgui import stdgui, fftsink, form, scopesink
+from optparse import OptionParser
+import usrp_dbid
+import sys
+import math
+import wx
+
+def pick_subdevice(u):
+    """
+    The user didn't specify a subdevice on the command line.
+    Try for one of these, in order: TV_RX, BASIC_RX, whatever is on side A.
+
+    @return a subdev_spec
+    """
+    return usrp.pick_subdev(u, (usrp_dbid.TV_RX,
+                                usrp_dbid.TV_RX_REV_2,
+                                usrp_dbid.BASIC_RX))
+
+class wfm_rx_graph (stdgui.gui_flow_graph):
+    def __init__(self,frame,panel,vbox,argv):
+        stdgui.gui_flow_graph.__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 USRP 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=65,
+                          help="set gain in dB (default is midpoint)")
+        parser.add_option("-s", "--squelch", type="eng_float", default=0,
+                          help="set squelch level (default is 0)")
+        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.state = "FREQ"
+        self.freq = 0
+
+        # build graph
+        
+        self.u = usrp.source_c()                    # usrp is data source
+
+        adc_rate = self.u.adc_rate()                # 64 MS/s
+        usrp_decim = 200
+        self.u.set_decim_rate(usrp_decim)
+        usrp_rate = adc_rate / usrp_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)
+
+
+        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 = blks.wfm_rcv (self, demod_rate, audio_decimation)
+        self.guts = blks.wfm_rcv_pll (self, demod_rate, audio_decimation)
+
+        # FIXME rework {add,multiply}_const_* to handle multiple streams
+        self.volume_control_l = gr.multiply_const_ff(self.vol)
+        self.volume_control_r = 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.connect ((self.guts, 0), self.volume_control_l, (audio_sink, 0))
+        self.connect ((self.guts, 1), self.volume_control_r, (audio_sink, 1))
+        self.guts.stereo_carrier_pll_recovery.squelch_enable(True);
+
+        self._build_gui(vbox, usrp_rate, demod_rate, audio_rate)
+
+        if options.gain is None:
+            # if no gain was specified, use the mid-point in dB
+            g = self.subdev.gain_range()
+            options.gain = float(g[0]+g[1])/2
+
+        if options.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)
+        self.guts.stereo_carrier_pll_recovery.set_lock_threshold(options.squelch);
+        if not(self.set_freq(options.freq)):
+            self._set_status_msg("Failed to set initial frequency")
+
+
+    def _set_status_msg(self, msg, which=0):
+        self.frame.GetStatusBar().SetStatusText(msg, which)
+
+
+    def _build_gui(self, vbox, usrp_rate, demod_rate, audio_rate):
+
+        def _form_set_freq(kv):
+            return self.set_freq(kv['freq'])
+
+
+        if 1:
+            self.src_fft = fftsink.fft_sink_c (self, self.panel, title="Data from USRP",
+                                               fft_size=512, sample_rate=usrp_rate)
+            self.connect (self.u, self.src_fft)
+            vbox.Add (self.src_fft.win, 4, wx.EXPAND)
+
+        if 1:
+            post_fm_demod_fft = fftsink.fft_sink_f (self, self.panel, title="Post FM Demod",
+                                                  fft_size=512, sample_rate=demod_rate,
+                                                  y_per_div=10, ref_level=0)
+            self.connect (self.guts.fm_demod, post_fm_demod_fft)
+            vbox.Add (post_fm_demod_fft.win, 4, wx.EXPAND)
+
+        if 0:
+            post_stereo_carrier_generator_fft = fftsink.fft_sink_c (self, self.panel, title="Post Stereo_carrier_generator",
+                                                  fft_size=512, sample_rate=audio_rate,
+                                                  y_per_div=10, ref_level=0)
+            self.connect (self.guts.stereo_carrier_generator, post_stereo_carrier_generator_fft)
+            vbox.Add (post_stereo_carrier_generator_fft.win, 4, wx.EXPAND)
+
+        if 0:
+            post_deemphasis_left = fftsink.fft_sink_f (self, self.panel, title="Post_Deemphasis_Left",
+                                                  fft_size=512, sample_rate=audio_rate,
+                                                  y_per_div=10, ref_level=0)
+            self.connect (self.guts.deemph_Left, post_deemphasis_left)
+            vbox.Add (post_deemphasis_left.win, 4, wx.EXPAND)
+
+        if 0:
+            post_deemphasis_right = fftsink.fft_sink_f (self, self.panel, title="Post_Deemphasis_Right",
+                                                  fft_size=512, sample_rate=audio_rate,
+                                                  y_per_div=10, ref_level=-20)
+            self.connect (self.guts.deemph_Left, post_deemphasis_right)
+            vbox.Add (post_deemphasis_right.win, 4, wx.EXPAND)
+
+
+        if 0:
+            LmR_fft = fftsink.fft_sink_f (self, self.panel, title="LmR", 
+                                                fft_size=512, sample_rate=audio_rate,
+                                                y_per_div=10, ref_level=-20)
+            self.connect (self.guts.LmR_real,LmR_fft)
+            vbox.Add (LmR_fft.win, 4, wx.EXPAND)
+
+        if 0:
+            self.scope = scopesink.scope_sink_f(self, self.panel, sample_rate=demod_rate)
+            self.connect (self.guts.fm_demod_a,self.scope)
+            vbox.Add (self.scope.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=(87.9e6, 108.1e6, 0.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.subdev.gain_range(),
+                                        callback=self.set_gain)
+        hbox.Add((5,0), 0)
+
+        myform['sqlch_thrsh'] = \
+            form.quantized_slider_field(parent=self.panel, sizer=hbox, label="Stereo Squelch Threshold",
+                                        weight=3, range=(0.0,1.0,0.01),
+                                        callback=self.guts.stereo_carrier_pll_recovery.set_lock_threshold)
+        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_l.set_k(10**(self.vol/10))
+        self.volume_control_r.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 = usrp.tune(self.u, 0, self.subdev, 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.subdev.set_gain(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 = stdgui.stdapp (wfm_rx_graph, "USRP WFM RX")
+    app.MainLoop ()
diff --git a/gnuradio-examples/python/usrp/usrp_wxapt_rcv.py b/gnuradio-examples/python/usrp/usrp_wxapt_rcv.py
new file mode 100755 (executable)
index 0000000..7c04c98
--- /dev/null
@@ -0,0 +1,267 @@
+#!/usr/bin/env python
+
+from gnuradio import gr, gru, eng_notation, optfir
+from gnuradio import audio
+from gnuradio import usrp
+from gnuradio import blks
+from gnuradio.eng_option import eng_option
+from gnuradio.wxgui import slider, powermate
+from gnuradio.wxgui import stdgui, fftsink, form
+from optparse import OptionParser
+import usrp_dbid
+import sys
+import math
+import wx
+
+def pick_subdevice(u):
+    """
+    The user didn't specify a subdevice on the command line.
+    Try for one of these, in order: TV_RX, BASIC_RX, whatever is on side A.
+
+    @return a subdev_spec
+    """
+    return usrp.pick_subdev(u, (usrp_dbid.TV_RX,
+                                usrp_dbid.TV_RX_REV_2,
+                                usrp_dbid.BASIC_RX))
+
+
+class wxapt_rx_graph (stdgui.gui_flow_graph):
+    def __init__(self,frame,panel,vbox,argv):
+        stdgui.gui_flow_graph.__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 USRP Rx side A or B (default=A)")
+        parser.add_option("-f", "--freq", type="eng_float", default=137.5e6,
+                          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("-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.state = "FREQ"
+        self.freq = 0
+
+        # build graph
+        
+        self.u = usrp.source_c()                    # usrp is data source
+
+        adc_rate = self.u.adc_rate()                # 64 MS/s
+        usrp_decim = 200
+        self.u.set_decim_rate(usrp_decim)
+        usrp_rate = adc_rate / usrp_decim           # 320 kS/s
+        chanfilt_decim = 4
+        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
+                                            40e3,        # passband cutoff
+                                            60e3,       # 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 = blks.wfm_rcv (self, 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)
+        
+        # now wire it all together
+        self.connect (self.u, chan_filt, self.guts, self.volume_control, audio_sink)
+
+        self._build_gui(vbox, usrp_rate, demod_rate, audio_rate)
+
+        if options.gain is None:
+            # if no gain was specified, use the mid-point in dB
+            g = self.subdev.gain_range()
+            options.gain = float(g[0]+g[1])/2
+
+        if options.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")
+
+
+    def _set_status_msg(self, msg, which=0):
+        self.frame.GetStatusBar().SetStatusText(msg, which)
+
+
+    def _build_gui(self, vbox, usrp_rate, demod_rate, audio_rate):
+
+        def _form_set_freq(kv):
+            return self.set_freq(kv['freq'])
+
+
+        if 1:
+            self.src_fft = fftsink.fft_sink_c (self, self.panel, title="Data from USRP",
+                                               fft_size=512, sample_rate=usrp_rate)
+            self.connect (self.u, self.src_fft)
+            vbox.Add (self.src_fft.win, 4, wx.EXPAND)
+
+        if 1:
+            post_deemph_fft = fftsink.fft_sink_f (self, self.panel, title="Post Deemph",
+                                                  fft_size=512, sample_rate=demod_rate,
+                                                  y_per_div=10, ref_level=-20)
+            self.connect (self.guts.deemph, post_deemph_fft)
+            vbox.Add (post_deemph_fft.win, 4, wx.EXPAND)
+
+        if 1:
+            post_filt_fft = fftsink.fft_sink_f (self, self.panel, title="Post Filter", 
+                                                fft_size=512, sample_rate=audio_rate,
+                                                y_per_div=10, ref_level=0)
+            self.connect (self.guts.audio_filter, post_filt_fft)
+            vbox.Add (post_filt_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=(137.0e6, 138.0e6, 0.0005e6),
+                                        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.subdev.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 = usrp.tune(self.u, 0, self.subdev, 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.subdev.set_gain(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 = stdgui.stdapp (wxapt_rx_graph, "USRP WXAPT RX")
+    app.MainLoop ()
diff --git a/gnuradio-examples/python/usrp/wfm_rcv_file.py b/gnuradio-examples/python/usrp/wfm_rcv_file.py
new file mode 100755 (executable)
index 0000000..2c8d4f7
--- /dev/null
@@ -0,0 +1,99 @@
+#!/usr/bin/env python
+
+from gnuradio import gr, eng_notation
+from gnuradio import audio
+# from gnuradio import usrp
+from gnuradio.eng_option import eng_option
+from optparse import OptionParser
+import sys
+import math
+
+
+#
+# return a gr.flow_graph
+#
+def build_graph (input_filename, repeat):
+    adc_rate = 64e6                             # USRP A/D sampling rate
+    decim = 250                                 # FPGA decimated by this amount
+
+    quad_rate = adc_rate / decim                # 256 kHz (the sample rate of the file)
+    audio_decimation = 8
+    audio_rate = quad_rate / audio_decimation   # 32 kHz
+
+    fg = gr.flow_graph ()
+    
+    # usrp is data source
+    # src = usrp.source_c (0, decim)
+    # src.set_rx_freq (0, -IF_freq)
+
+    src = gr.file_source (gr.sizeof_gr_complex, input_filename, repeat)
+    
+    (head, tail) = 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, head)
+    fg.connect (tail, (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 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)
+
+    TAU  = 75e-6  # 75us in US, 50us in EUR
+    fftaps = [ 1 - math.exp(-1/TAU/quad_rate), 0]
+    fbtaps= [ 0 , math.exp(-1/TAU/quad_rate) ]
+    deemph = gr.iir_filter_ffd(fftaps,fbtaps)
+
+    # input: float; output: float
+    audio_filter = gr.fir_filter_fff (audio_decimation, audio_coeffs)
+
+    fg.connect (fm_demod, deemph)
+    fg.connect (deemph, audio_filter)
+    return ((fm_demod, 0), (audio_filter, 0))
+    
+
+def main ():
+    usage = "usage: %prog [options] filename"
+    parser = OptionParser (option_class=eng_option, usage=usage)
+    parser.add_option ("-r", "--repeat", action="store_true", default=False)
+    # parser.add_option (... your stuff here...)
+    (options, args) = parser.parse_args ()
+
+    if len (args) != 1:
+        parser.print_help ()
+        sys.exit (1)
+
+    fg = build_graph (args[0], options.repeat)
+
+    fg.start ()        # fork thread(s) and return
+    raw_input ('Press Enter to quit: ')
+    fg.stop ()
+
+if __name__ == '__main__':
+    main ()
+
+
diff --git a/gr-atsc/AUTHORS b/gr-atsc/AUTHORS
new file mode 100644 (file)
index 0000000..fe4e73c
--- /dev/null
@@ -0,0 +1,3 @@
+Eric Blossom <eb@comsec.com>
+Matt Ettus <matt@ettus.com>
+
diff --git a/gr-atsc/ChangeLog b/gr-atsc/ChangeLog
new file mode 100644 (file)
index 0000000..e11f520
--- /dev/null
@@ -0,0 +1,37 @@
+2006-03-23  Eric Blossom  <eb@comsec.com>
+
+       * src/lib/atsc_rs_encoder.{h,cc}, src/lib/atsc_rs_decoder.{h,cc}:
+       ported from old ATSC code.
+       * src/lib/atsci_reed_solomon.{h,cc}: const correctness fix.
+       * src/lib/atsc_randomizer.{h,cc}, src/lib/atsc_derandomizer.{h,cc}:
+       ported from old ATSC code.
+       * src/python/qa_atsc.py: new: python based test code.
+       * src/lib/atsci_randomizer.{h,cc}: renamed class vars match new conventions.
+
+2006-03-22  Eric Blossom  <eb@comsec.com>
+
+       * src/lib/atsc_sliding_correlator.cc (shift_in),
+       src/lib/atsc_trellis_encoder.cc (encode_helper),
+       src/lib/atsc_viterbi_gen.cc (build_decode_structures): 64-bit
+       fixes.
+
+#
+# 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 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.
+# 
diff --git a/gr-atsc/Makefile.am b/gr-atsc/Makefile.am
new file mode 100644 (file)
index 0000000..4ed403a
--- /dev/null
@@ -0,0 +1,28 @@
+#
+# 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.
+# 
+
+include $(top_srcdir)/Makefile.common
+
+SUBDIRS = src
+DIST_SUBDIRS = src doc
+
+pkgconfigdir = $(libdir)/pkgconfig
+pkgconfig_DATA =
diff --git a/gr-atsc/NEWS b/gr-atsc/NEWS
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/gr-atsc/README b/gr-atsc/README
new file mode 100644 (file)
index 0000000..9124571
--- /dev/null
@@ -0,0 +1,50 @@
+#
+# 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 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 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.
+
+
+To build this, you must already have built and installed
+gnuradio-core.  Then if you're building from a tarball:
+
+  $ ./configure
+  $ make
+  $ make check
+  $ sudo make install
+
+If you're building from CVS, you'll need to use this sequence, since
+CVS doesn't contain configure or the generated Makefiles.
+
+  $ ./bootstrap
+  $ ./configure
+  $ make
+  $ make check
+  $ sudo make install
+
+
+The doc directory is not built by default.  This is to avoid spurious
+build problems on systems that don't have xmlto installed.  If you
+have xmlto and its dependencies installed, you can build the html
+version of the howto article by cd'ing to doc and invoking make.
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/Makefile.am b/gr-atsc/doc/Makefile.am
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/gr-atsc/src/Makefile.am b/gr-atsc/src/Makefile.am
new file mode 100644 (file)
index 0000000..122fc72
--- /dev/null
@@ -0,0 +1,22 @@
+#
+# 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.
+# 
+
+SUBDIRS = lib python
diff --git a/gr-atsc/src/lib/GrAtscBitTimingLoop.cc b/gr-atsc/src/lib/GrAtscBitTimingLoop.cc
new file mode 100644 (file)
index 0000000..9577dad
--- /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 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.
+ */
+
+#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..3bb1ade
--- /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 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.
+ */
+
+#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..25eadd3
--- /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 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.
+ */
+
+#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..1942234
--- /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 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.
+ */
+
+#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..2b21f2f
--- /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 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.
+ */
+
+#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..299dc79
--- /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 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.
+ */
+
+#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..79811df
--- /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 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.
+ */
+
+#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..a8f802b
--- /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 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.
+ */
+#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..577330e
--- /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 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.
+ */
+
+#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..0cab046
--- /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 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.
+ */
+
+#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..2148e8a
--- /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 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.
+ */
+
+#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..d4cb44e
--- /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 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.
+ */
+
+#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..2cd7d39
--- /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 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.
+ */
+
+#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..22888c2
--- /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 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.
+ */
+
+#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..cd930ad
--- /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 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.
+ */
+
+#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..46282ba
--- /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 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.
+ */
+
+#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..e6a7ff6
--- /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 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.
+ */
+
+#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..0868f9a
--- /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 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.
+ */
+
+
+#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..18b81ac
--- /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 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.
+ */
+
+#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..f64ebcb
--- /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 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.
+ */
+
+#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..23eabe8
--- /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 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.
+ */
+
+#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..78ff9c6
--- /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 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.
+ */
+
+#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..04a39bd
--- /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 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.
+ */
+
+#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..2eb6084
--- /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 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.
+ */
+
+#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..4292195
--- /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 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.
+ */
+
+#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..5235603
--- /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 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.
+ */
+
+#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..e766dcf
--- /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 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.
+ */
+
+#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..26bf643
--- /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 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.
+ */
+
+#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..58a6929
--- /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 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.
+ */
+
+#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..78bc96d
--- /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 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.
+ */
+
+#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..7b2a7af
--- /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 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.
+ */
+
+#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..f14267d
--- /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 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.
+ */
+
+#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..d2a14de
--- /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 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.
+ */
+
+#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..39c1b65
--- /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 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.
+ */
+
+#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..ad2384b
--- /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 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.
+ */
+
+#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..1e32e16
--- /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 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.
+ */
+
+#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..ce27eb3
--- /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 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.
+ */
+
+#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..d038740
--- /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 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.
+ */
+#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..b58dcee
--- /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 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.
+ */
+
+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..061f4aa
--- /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 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.
+ */
+
+#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..8c55e14
--- /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 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.
+ */
+
+#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..ac17de3
--- /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 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.
+ */
+
+#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..2b7174b
--- /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 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.
+ */
+
+#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..10e3480
--- /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 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.
+ */
+
+#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..d5ae6ed
--- /dev/null
@@ -0,0 +1,268 @@
+#
+# Copyright 2001,2004,2005,2006 Free Software Foundation, Inc.
+# 
+# This file is part of GNU Radio
+# 
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 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.
+# 
+
+include $(top_srcdir)/Makefile.common
+
+# Install this stuff so that it ends up as the gnuradio.atsc 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) $(CPPUNIT_INCLUDES)
+
+#LIBS += $(GNURADIO_CORE_LIBS)
+
+EXTRA_DIST =                                   \
+       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  
+
+
+BUILT_SOURCES =                                \
+       atsci_viterbi_mux.cc                    \
+       $(swig_built_sources)
+
+
+TESTS =                                                \
+       test_atsci                              
+
+
+# We build two libtool convenience libraries
+
+noinst_LTLIBRARIES = libatsc.la libatsc-qa.la
+
+# FIXME
+#      atsci_exp2_lp.cc                        \
+#      atsci_root_raised_cosine.cc             \
+#      atsci_root_raised_cosine_bandpass.cc    \
+#      atsci_vsbtx_lp.cc                       \
+#
+
+libatsc_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                           \
+       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                               
+
+libatsc_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                  
+
+
+# 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_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 =                              \
+       atsci_viterbi_gen                       \
+       test_atsci                              
+
+
+atsci_viterbi_gen_SOURCES = atsci_viterbi_gen.cc
+
+atsci_viterbi_mux.cc: atsci_viterbi_gen$(EXEEXT) 
+       $(MAKE) $(AM_MAKEFLAGS) CXX="$(CXX_FOR_BUILD)" atsci_viterbi_gen$(EXEEXT)
+       ./atsci_viterbi_gen$(EXEEXT) -o atsci_viterbi_mux.cc
+
+
+test_atsci_SOURCES = test_atsci.cc
+test_atsci_LDADD   = libatsc-qa.la libatsc.la $(GNURADIO_CORE_LIBS) $(CPPUNIT_LIBS)
+
+
+# ------------------------------------------------------------------------
+#  This is the swig-ish part of the Makefile.
+#  It builds the atsc module which we'll load into python
+# ------------------------------------------------------------------------
+
+SWIGCPPPYTHONARGS = -fvirtual -python -modern $(PYTHON_CPPFLAGS) \
+       $(STD_DEFINES_AND_INCLUDES)
+
+ALL_IFILES =                           \
+       $(LOCAL_IFILES)                 \
+       $(NON_LOCAL_IFILES)             
+
+NON_LOCAL_IFILES =                     \
+       $(top_srcdir)/gnuradio-core/src/lib/swig/gnuradio.i
+
+LOCAL_IFILES =                                 \
+       atsc.i                          
+
+# These files are built by SWIG.  The first is the C++ glue.
+# The second is the python wrapper that loads the _atsc shared library
+# and knows how to call our extensions.
+
+swig_built_sources =                   \
+       atsc.cc                         \
+       atsc.py                         
+
+# This gets atsc.py installed in the right place
+ourpython_PYTHON =                     \
+       atsc.py
+
+ourlib_LTLIBRARIES = _atsc.la
+
+# These are the source files that go into the shared library
+_atsc_la_SOURCES =                     \
+       atsc.cc                 
+
+# magic flags
+_atsc_la_LDFLAGS = $(NO_UNDEFINED) -module -avoid-version
+
+# link the library against some comon swig runtime code and the 
+# c++ standard library
+_atsc_la_LIBADD =                      \
+       $(GNURADIO_CORE_LIBS)           \
+       $(PYTHON_LDFLAGS)               \
+       libatsc.la                      \
+       -lstdc++                        
+
+atsc.cc atsc.py: atsc.i $(ALL_IFILES)
+       $(SWIG) $(SWIGCPPPYTHONARGS) -module atsc -o atsc.cc $<
+
+# These swig headers get installed in ${prefix}/include/gnuradio/swig
+swiginclude_HEADERS =                  \
+       $(LOCAL_IFILES)                 
+
+# ------------------------------------------------------------------------
+#  Cleanup
+# ------------------------------------------------------------------------
+
+CLEANFILES =      atsci_viterbi_mux.cc
+MOSTLYCLEANFILES = $(BUILT_SOURCES) *.pyc
+
diff --git a/gr-atsc/src/lib/atsc.i b/gr-atsc/src/lib/atsc.i
new file mode 100644 (file)
index 0000000..026332b
--- /dev/null
@@ -0,0 +1,269 @@
+/* -*- c++ -*- */
+
+%feature("autodoc", "1");                      // generate python docstrings
+
+%include "exception.i"
+%import "gnuradio.i"                           // the common stuff
+
+%{
+#include "gnuradio_swig_bug_workaround.h"      // mandatory bug fix
+#include <stdexcept>
+#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_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_sync_decimator
+{
+  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();
+
+};
+
+// ----------------------------------------------------------------
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..432ad4c
--- /dev/null
@@ -0,0 +1,118 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <atsc_bit_timing_loop.h>
+#include <gr_io_signature.h>
+#include <atsc_consts.h>
+
+float input_rate = 20e6;
+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)
+{
+  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] = noutput_items * d_rx_clock_to_symbol_freq + 1500 - 1;
+
+  inputs0_size = noutput_items * d_rx_clock_to_symbol_freq + 1500 - 1;
+  inputs0_index = d_next_input;
+}
+
+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 (r * d_rx_clock_to_symbol_freq);
+  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           si = 0;         // source index
+  unsigned int  k;              // output index
+
+  float         interp_sample;
+  int           symbol_index;
+  double        timing_adjustment = 0;
+  bool          seg_locked;
+  atsc::syminfo    tag;
+
+  memset (&tag, 0, sizeof (tag));
+
+  
+  for (k = 0; k < noutput_items; k++){
+    if (!d_interp.update (in, inputs0_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/atsc_bit_timing_loop.h b/gr-atsc/src/lib/atsc_bit_timing_loop.h
new file mode 100644 (file)
index 0000000..5820927
--- /dev/null
@@ -0,0 +1,89 @@
+/* -*- 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 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.
+ */
+#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;
+
+  unsigned long long            inputs0_index;     // for inputs[0].index
+  unsigned long                        inputs0_size;      // for inputs[0].size
+
+
+};
+
+#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..197ec57
--- /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 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.
+ */
+
+#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..f698726
--- /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 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.
+ */
+
+#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..17527b5
--- /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 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.
+ */
+#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..e63eebc
--- /dev/null
@@ -0,0 +1,80 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <atsc_depad.h>
+#include <gr_io_signature.h>
+#include <atsc_types.h>
+
+static const int INTR = ATSC_MPEG_PKT_LENGTH;
+
+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)),
+                 INTR)
+{
+  reset();
+}
+
+void
+atsc_depad::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_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];
+
+  // size with padding (256)
+  unsigned int ATSC_MPEG_PKT = sizeof(atsc_mpeg_packet);
+  unsigned int i;
+
+  for (i = 0; i < noutput_items/ATSC_MPEG_PKT + 1; i++){
+    for (int j = 0; j < ATSC_MPEG_PKT_LENGTH; j++)
+       out[i * ATSC_MPEG_PKT_LENGTH + j] = in[i * ATSC_MPEG_PKT].data[j];
+
+  }
+
+  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..3db933b
--- /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 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.
+ */
+#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:
+  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_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..2a41127
--- /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 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.
+ */
+
+#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..97cb3a2
--- /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 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.
+ */
+#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..682cea0
--- /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 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.
+ */
+
+#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..837da7d
--- /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 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.
+ */
+#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..168d622
--- /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 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.
+ */
+
+#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 ();
+  int npretaps = d_equalizer->npretaps ();
+
+  assert (ntaps >= 1);
+  assert (npretaps >= 0 && npretaps < 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);
+}
+
+
+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));
+
+
+  // peform the actual equalization
+
+  d_equalizer->filter (in, in_tags,
+                       out, noutput_items);
+
+  // write the output tags
+
+  for (int i = 0; i < noutput_items; i++)
+    out_tags[i] = in_tags[i];
+
+  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..a8f448d
--- /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 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.
+ */
+#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..d30947d
--- /dev/null
@@ -0,0 +1,188 @@
+/* -*- 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 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.
+ */
+
+#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.h>
+
+using std::abs;
+
+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_sync_decimator("atsc_field_sync_demux",
+                 gr_make_io_signature(2, 2, sizeof(float)),
+                 gr_make_io_signature(1, 1, sizeof(atsc_soft_data_segment)),DEC),
+                 d_locked(false), d_in_field2(true), d_segment_number(0),
+                 d_next_input(0), d_lost_index(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 - 1;
+
+  inputs0_index = d_next_input;
+  inputs0_size = noutput_items * DEC + 2 * DEC - 1;
+  }
+}
+
+
+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));
+
+  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 = 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 "
+    //      << inputs0_index + ii << endl;
+
+    for (ii = 1; ii < 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 "
+             << inputs0_index + ii
+             << " [delta = " << inputs0_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...
+
+  int  k = 0;          // output index
+
+  while (k < noutput_items){
+
+    if (inputs0_size - ii <  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 "
+           << 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
+  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..7ce64b5
--- /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 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.
+ */
+#ifndef INCLUDED_ATSC_FIELD_SYNC_DEMUX_H
+#define INCLUDED_ATSC_FIELD_SYNC_DEMUX_H
+
+#include <gr_sync_decimator.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
+ *
+ * input: atsc_data_segment; output: atsc_data_segment
+ */
+class atsc_field_sync_demux : public gr_sync_decimator
+{
+  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 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 inputs0_index;    // for inputs[0].index
+  unsigned long          inputs0_size;         // for inputs[0].size
+
+};
+
+
+#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..edaa241
--- /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 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.
+ */
+
+#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 (unsigned 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..91000e1
--- /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 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.
+ */
+#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..087a808
--- /dev/null
@@ -0,0 +1,136 @@
+/* -*- 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 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.
+ */
+
+#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"
+
+
+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 = 20e6;
+
+  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);
+
+    // 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..b6213ba
--- /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 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.
+ */
+#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.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                        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..10d8353
--- /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 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.
+ */
+
+#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..a844cd3
--- /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 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.
+ */
+#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..567c1b4
--- /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 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.
+ */
+
+#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..18fd8e5
--- /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 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.
+ */
+#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_randomizer.cc b/gr-atsc/src/lib/atsc_randomizer.cc
new file mode 100644 (file)
index 0000000..7b9fed0
--- /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 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.
+ */
+
+#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..31f20c8
--- /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 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.
+ */
+#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..7885cca
--- /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 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.
+ */
+
+#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..7c10a3d
--- /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 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.
+ */
+#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..53f45d5
--- /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 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.
+ */
+
+#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..da1fd63
--- /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 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.
+ */
+#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..77cf08a
--- /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 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.
+ */
+
+#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..98b549e
--- /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 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.
+ */
+#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..1a7708e
--- /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 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.
+ */
+
+#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..394ee50
--- /dev/null
@@ -0,0 +1,84 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <atsc_viterbi_decoder.h>
+#include <gr_io_signature.h>
+#include <atsc_consts.h>
+#include <iostream.h>
+
+
+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..931397e
--- /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 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.
+ */
+#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..35081eb
--- /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 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.
+ */
+
+#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..34c45e4
--- /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 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.
+ */
+#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..4826df7
--- /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 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.
+ */
+
+#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..26286b5
--- /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 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.
+ */
+
+#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..163a6f0
--- /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 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.
+ */
+
+/*
+ * 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..29c248c
--- /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 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.
+ */
+
+#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..53bc9b6
--- /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 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.
+ */
+
+#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..2fc084b
--- /dev/null
@@ -0,0 +1,306 @@
+/* -*- 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 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.
+ */
+
+#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);
+}
+
+
+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];
+}
+
+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..8303647
--- /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 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.
+ */
+
+#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..d461d60
--- /dev/null
@@ -0,0 +1,373 @@
+/* -*- 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 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.
+ */
+
+#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);
+}
+
+
+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];
+}
+
+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..60ac894
--- /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 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.
+ */
+
+#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..681a6b2
--- /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 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.
+ */
+
+#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..b5f5b0c
--- /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 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.
+ */
+
+#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..9c7216d
--- /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 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.
+ */
+
+#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..5370e40
--- /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 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.
+ */
+
+#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..365350c
--- /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 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.
+ */
+
+#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..19f6774
--- /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 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.
+ */
+
+#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..52b20f8
--- /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 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.
+ */
+
+#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..66e6507
--- /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 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.
+ */
+#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..aac4c82
--- /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 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.
+ */
+
+#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..b86ab18
--- /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 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.
+ */
+
+#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..29cf292
--- /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 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.
+ */
+
+#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..80622d9
--- /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 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.
+ */
+#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..7c4946b
--- /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 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.
+ */
+
+#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..7f9b562
--- /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 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.
+ */
+
+#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..efa61e0
--- /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 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.
+ */
+
+#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..1cb9b1b
--- /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 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.
+ */
+
+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..5cdcaa8
--- /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 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.
+ */
+
+#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..c9f3b66
--- /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 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.
+ */
+
+#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..26265d3
--- /dev/null
@@ -0,0 +1,93 @@
+/* -*- 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 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.
+ */
+
+#include <atsci_reed_solomon.h>
+#include <assert.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..882741f
--- /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 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.
+ */
+
+#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..00912ad
--- /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 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.
+ */
+
+#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..c3f0a9e
--- /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 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.
+ */
+#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..fbdc4ca
--- /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 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.
+ */
+
+#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..5de2475
--- /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 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.
+ */
+#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..edc2cd1
--- /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 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.
+ */
+
+#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..907b41c
--- /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 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.
+ */
+
+#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..f1244bd
--- /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 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.
+ */
+
+#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..dc821db
--- /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 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.
+ */
+
+#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..9bb14db
--- /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 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.
+ */
+#ifndef _ATSC_SLIDING_CORRELATOR_H_
+#define _ATSC_SLIDING_CORRELATOR_H_
+
+#include <string>
+
+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..7790c65
--- /dev/null
@@ -0,0 +1,286 @@
+/* -*- 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 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.
+ */
+
+#include <atsci_sssr.h>
+#include <algorithm>
+#include <cmath>
+#include <cstdio>
+#include <assert.h>
+#include <atsci_diag_output.h>
+#include <gr_math.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 ()
+{
+  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)
+{
+  assert (nominal_ratio_of_rx_clock_to_symbol_freq >= 1.8);
+  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..0d575cd
--- /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 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.
+ */
+
+/*
+ *   --- 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..8d42118
--- /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 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.
+ */
+#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..bca8b86
--- /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 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.
+ */
+#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..8e09739
--- /dev/null
@@ -0,0 +1,207 @@
+/* -*- 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 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.
+ */
+
+#include <atsci_trellis_encoder.h>
+#include <assert.h>
+#include <stdio.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..429d3d1
--- /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 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.
+ */
+
+#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..4e017a9
--- /dev/null
@@ -0,0 +1,175 @@
+/* -*- 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 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.
+ */
+
+#include <atsci_viterbi_decoder.h>
+#include <assert.h>
+#include <stdio.h>
+#include <cmath>
+#include "atsci_viterbi_mux.cc"
+
+
+/* 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..a804b66
--- /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 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.
+ */
+
+#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..2004dbb
--- /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 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.
+ */
+
+#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..d0878dc
--- /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 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.
+ */
+
+#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..112a4bb
--- /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 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.
+ */
+
+#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..bb33625
--- /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 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.
+ */
+
+#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..0f3bdbc
--- /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 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.
+ */
+
+#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..5e1023d
--- /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 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.
+ */
+#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..a0a0f3d
--- /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 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.
+ */
+
+#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..6b258bc
--- /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 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.
+ */
+
+#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..6664003
--- /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 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.
+ */
+
+#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..511bce9
--- /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 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.
+ */
+
+#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..f5c90f9
--- /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 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.
+ */
+#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..0a2a508
--- /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 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.
+# 
+
+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..e20b968
--- /dev/null
@@ -0,0 +1,86 @@
+/* -*- 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 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.
+ */
+
+#ifndef _INTERLEAVER_FIFO_H_
+#define _INTERLEAVER_FIFO_H_
+
+
+#include <interleaver_fifo.h>
+#include <string.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..b28a13d
--- /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 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.
+ */
+
+#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..bc7fba3
--- /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 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 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..cf861a8
--- /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 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.
+ */
+
+#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..c6212f3
--- /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 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.
+ */
+
+#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..5d76f5e
--- /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 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.
+ */
+#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..c09d123
--- /dev/null
@@ -0,0 +1,196 @@
+/* -*- 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 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.
+ */
+
+#include <cppunit/TestAssert.h>
+#include <qa_atsci_data_interleaver.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..9d72f1a
--- /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 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.
+ */
+
+#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..a12f253
--- /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 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.
+ */
+
+#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>
+
+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..cfe8920
--- /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 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.
+ */
+
+#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..f0ff635
--- /dev/null
@@ -0,0 +1,143 @@
+/* -*- 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 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.
+ */
+
+#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>
+
+
+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..2161d5d
--- /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 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.
+ */
+
+#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..97d45f5
--- /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 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.
+ */
+
+#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..a38a5e2
--- /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 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.
+ */
+#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..46b228f
--- /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 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.
+ */
+
+#include <qa_atsci_randomizer.h>
+
+#include <cppunit/TestAssert.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..5a805df
--- /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 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.
+ */
+#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..8b52359
--- /dev/null
@@ -0,0 +1,114 @@
+/* -*- 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 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.
+ */
+
+#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>
+
+
+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..d78aa74
--- /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 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.
+ */
+
+#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..ea94e69
--- /dev/null
@@ -0,0 +1,283 @@
+/* -*- 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 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.
+ */
+
+#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>
+
+
+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..0c0a334
--- /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 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.
+ */
+
+#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..e315847
--- /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 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.
+ */
+
+#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..508020c
--- /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 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.
+ */
+
+#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..193f2b3
--- /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 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.
+ */
+
+#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>
+
+#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..4065716
--- /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 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.
+ */
+
+#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..5cc3297
--- /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 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.
+ */
+
+#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..78b57de
--- /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 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.
+ */
+
+#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..2850549
--- /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 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.
+ */
+
+#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..54f3b1e
--- /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 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.
+ */
+
+#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..920e68b
--- /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 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.
+ */
+
+#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..3002e8c
--- /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 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.
+ */
+
+#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..655c3aa
--- /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 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.
+ */
+
+#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/Makefile.am b/gr-atsc/src/python/Makefile.am
new file mode 100644 (file)
index 0000000..bdca325
--- /dev/null
@@ -0,0 +1,33 @@
+#
+# 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.
+# 
+
+include $(top_srcdir)/Makefile.common
+
+EXTRA_DIST = run_tests.in
+
+
+TESTS =                                \
+       run_tests
+
+
+noinst_PYTHON =                        \
+       atsc_utils.py                   \
+       qa_atsc.py                      
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..1197664
--- /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 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.
+# 
+
+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/qa_atsc.py b/gr-atsc/src/python/qa_atsc.py
new file mode 100755 (executable)
index 0000000..d9c94e1
--- /dev/null
@@ -0,0 +1,217 @@
+#!/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 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.
+# 
+
+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_block):
+    """
+    MPEG Transport stream source for testing.
+    """
+    def __init__(self, fg, ts):
+        """
+        Pad tranport stream packets to 256 bytes and reformat appropriately.
+        
+        @param fg: flow graph
+        @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)
+        fg.connect(src, s2v)
+        gr.hier_block.__init__(self, fg, None, s2v)
+
+
+class vector_sink_ts(gr.hier_block):
+    """
+    MPEG Transport stream sink for testing.
+    """
+    def __init__(self, fg):
+        """
+        @param fg: flow graph
+        """
+        v2s = gr.vector_to_stream(gr.sizeof_char, atsc.sizeof_atsc_mpeg_packet)
+        self.sink = gr.vector_sink_b()
+        fg.connect(v2s, self.sink)
+        gr.hier_block.__init__(self, fg, v2s, None)
+
+    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.fg = gr.flow_graph()
+
+    def tearDown(self):
+        self.fg = 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(self.fg, src_data)
+        rand = atsc.randomizer()
+        derand = atsc.derandomizer()
+        dst = vector_sink_ts(self.fg)
+        self.fg.connect(src, rand, derand, dst)
+        self.fg.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(self.fg, src_data)
+        rand = atsc.randomizer()
+        rs_enc = atsc.rs_encoder()
+        rs_dec = atsc.rs_decoder()
+        derand = atsc.derandomizer()
+        dst = vector_sink_ts(self.fg)
+        self.fg.connect(src, rand, rs_enc, rs_dec, derand, dst)
+        self.fg.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(self.fg, 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.fg)
+        self.fg.connect(src, rand, rs_enc, inter, deinter, rs_dec, derand, dst)
+        self.fg.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(self.fg, 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.fg)
+       self.fg.connect(src, rand, rs_enc, inter, trellis, softds, viterbi, deinter, rs_dec, derand, dst)
+        self.fg.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..b83d85b
--- /dev/null
@@ -0,0 +1,47 @@
+#!/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@/gr-atsc/src/lib
+# Where to look in the src tree for swig generated python code
+libsrc=@abs_top_srcdir@/gr-atsc/src/lib
+# Where to look in the src tree for hand written python code
+py=@abs_top_srcdir@/gr-atsc/src/python
+
+# Where to look for GNU Radio python modules in current build tree
+# FIXME this is wrong on a distcheck.  We really need to ask gnuradio-core
+# where it put its python files.
+grpythonbld=@abs_top_builddir@/gnuradio-core/src/python/:@abs_top_builddir@/gnuradio-core/src/lib/swig/:@abs_top_builddir@/gnuradio-core/src/lib/swig/.libs
+
+PYTHONPATH="$grpythonbld:$libbld:$libbld/.libs:$libsrc:$py:$PYTHONPATH"
+export PYTHONPATH
+
+#
+# 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-audio-alsa/AUTHORS b/gr-audio-alsa/AUTHORS
new file mode 100644 (file)
index 0000000..65ca901
--- /dev/null
@@ -0,0 +1,2 @@
+Eric Blossom <eb@comsec.com>
+Ramakrishnan Muthukrishnan <rkrishnan@debian.org>
diff --git a/gr-audio-alsa/ChangeLog b/gr-audio-alsa/ChangeLog
new file mode 100644 (file)
index 0000000..95e0c04
--- /dev/null
@@ -0,0 +1,88 @@
+2006-03-30  Eric Blossom  <eb@comsec.com>
+
+       * gr-audio-alsa.conf: new config file
+       * src/audio_alsa_source.{h,cc,i}, src/audio_alsa_sink.{h,cc,i}:
+       added ok_to_block ctor arg.  Now use prefs for default devices, etc.
+
+2006-02-27  Eric Blossom  <eb@comsec.com>
+
+       * src/Makefile.am (audio_alsa.cc audio_alsa.py): added missing
+       dependency. 
+
+2005-07-02  Eric Blossom  <eb@comsec.com>
+
+       * config/gr_no_undefined.m4, config/gr_x86_64.m4: new, x86_64 support.
+       * config/gr_python.m4: backed out search for libpython, making
+       x86_64 work and breaking Cygwin/MinGW.
+       * configure.ac, src/Makefile.am: mods for x86_64, $(NO_UNDEFINED)
+       
+2005-06-18  Eric Blossom  <eb@comsec.com>
+
+       * src/audio_alsa_sink.cc (check_topology): set start threshold to
+       help avoid audio underruns.
+
+2005-05-09  Stephane Fillod  <f8cfe@free.fr>
+
+        * config/gr_sysv_shm.m4: SysV shared memory not mandatory
+       * config/gr_pwin32.m4, config/gr_python.m4, config/lf_cxx.m4:
+         fixes for Cygwin, MinGW
+
+2005-01-29  Eric Blossom  <eb@comsec.com>
+
+       * src/Makefile.am: cleanup for SWIG 1.3.24
+
+2005-01-17  Eric Blossom  <eb@comsec.com>
+
+       * src/audio_alsa_source.{h,cc}: emulate mono source even on
+       stereo-only hardware.
+
+2005-01-12  Eric Blossom  <eb@comsec.com>
+
+       * src/audio_alsa_source.cc,src/audio_alsa_sink.cc: overruns are
+       now indicated with aO, underruns with aU to distinguish them from
+       usrp under/overruns.
+
+2004-11-11  Eric Blossom  <eb@comsec.com>
+
+       * src/audio_alsa_source.cc (audio_alsa_source): working!
+
+2004-11-10  Eric Blossom  <eb@comsec.com>
+
+       * src/audio_alsa_sink.cc (audio_alsa_sink): working!
+
+2004-11-08  Eric Blossom  <eb@comsec.com>
+
+       * src/audio_alsa.i (audio_alsa_make_source): added throw
+       declarations so that swig generates the proper catch.
+
+2004-10-25  Ramakrishnan Muthukrishnan <rkrishnan@debian.org>
+
+       * playout works. But segfaults on exit.
+       * capture is untested.
+       
+2004-10-23  Ramakrishnan Muthukrishnan <rkrishnan@debian.org>
+
+       * src/audio_oss_source.{h,cc}: first cut from oss sources.
+       * src/audio_oss_sink.{h,cc}: first cut from oss sources.
+
+
+#
+# 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.
+# 
diff --git a/gr-audio-alsa/Makefile.am b/gr-audio-alsa/Makefile.am
new file mode 100644 (file)
index 0000000..18a5dc4
--- /dev/null
@@ -0,0 +1,32 @@
+#
+# 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 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.
+# 
+
+include $(top_srcdir)/Makefile.common
+
+EXTRA_DIST = gr-audio-alsa.conf
+
+SUBDIRS = src
+
+pkgconfigdir = $(libdir)/pkgconfig
+pkgconfig_DATA =
+
+etcdir = $(sysconfdir)/gnuradio/conf.d
+etc_DATA = gr-audio-alsa.conf
diff --git a/gr-audio-alsa/README b/gr-audio-alsa/README
new file mode 100644 (file)
index 0000000..325759b
--- /dev/null
@@ -0,0 +1,4 @@
+N.B. This is currently a work-in-progress and is not ready for use.
+
+Stay tuned.  It should be ready in a couple of days...
+
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/gr-audio-alsa.conf b/gr-audio-alsa/gr-audio-alsa.conf
new file mode 100644 (file)
index 0000000..5cec63e
--- /dev/null
@@ -0,0 +1,11 @@
+# This file contains system wide configuration data for GNU Radio.
+# You may override any setting on a per-user basis by editing
+# ~/.gnuradio/config.conf
+
+[audio_alsa]
+
+default_input_device = hw:0,0
+default_output_device = hw:0,0
+period_time = 0.010                      # in seconds
+nperiods = 4                            # total buffering = period_time * nperiods
+verbose = false
diff --git a/gr-audio-alsa/src/Makefile.am b/gr-audio-alsa/src/Makefile.am
new file mode 100644 (file)
index 0000000..e06fef9
--- /dev/null
@@ -0,0 +1,91 @@
+#
+# 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.
+# 
+
+include $(top_srcdir)/Makefile.common
+
+# Install this stuff so that it ends up as the gnuradio.audio_alsa module
+# This usually ends up at:
+#   ${prefix}/lib/python${python_version}/site-packages/gnuradio
+
+ourpythondir = $(grpythondir)
+ourlibdir    = $(grpyexecdir)
+
+LIBS += $(GNURADIO_CORE_LIBS)
+
+EXTRA_DIST = run_tests.in
+
+TESTS = run_tests
+
+LOCAL_IFILES =                                 \
+       audio_alsa.i                            
+
+NON_LOCAL_IFILES =                     \
+       $(top_srcdir)/gnuradio-core/src/lib/swig/gnuradio.i
+
+ALL_IFILES =                           \
+       $(LOCAL_IFILES)                 \
+       $(NON_LOCAL_IFILES)             
+
+BUILT_SOURCES =                        \
+       audio_alsa.cc                   \
+       audio_alsa.py                           
+
+ourpython_PYTHON =                     \
+       audio_alsa.py
+
+INCLUDES = $(STD_DEFINES_AND_INCLUDES) $(PYTHON_CPPFLAGS)
+
+SWIGPYTHONARGS = $(SWIGPYTHONFLAGS) $(STD_DEFINES_AND_INCLUDES)
+
+ourlib_LTLIBRARIES = _audio_alsa.la
+
+_audio_alsa_la_SOURCES =               \
+       audio_alsa.cc                   \
+       audio_alsa_sink.cc              \
+       audio_alsa_source.cc            \
+       gri_alsa.cc                     
+
+grinclude_HEADERS =                    \
+       audio_alsa_sink.h               \
+       audio_alsa_source.h             
+
+noinst_HEADERS =                       \
+       gri_alsa.h                      
+
+
+swiginclude_HEADERS =                  \
+       $(LOCAL_IFILES)
+
+_audio_alsa_la_LIBADD =                \
+       $(PYTHON_LDFLAGS)               \
+       -lstdc++                                
+
+_audio_alsa_la_LDFLAGS = $(NO_UNDEFINED) -module -avoid-version
+
+audio_alsa.cc audio_alsa.py: audio_alsa.i $(NON_LOCAL_IFILES)
+       $(SWIG) $(SWIGPYTHONARGS) -module audio_alsa -o audio_alsa.cc $<
+
+
+noinst_PYTHON =                        \
+       qa_alsa.py                      
+
+MOSTLYCLEANFILES = \
+       $(BUILT_SOURCES) *~ *.pyc
diff --git a/gr-audio-alsa/src/audio_alsa.i b/gr-audio-alsa/src/audio_alsa.i
new file mode 100644 (file)
index 0000000..1cb13b8
--- /dev/null
@@ -0,0 +1,80 @@
+/* -*- 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 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.
+ */
+
+%feature("autodoc","1");
+
+%include "exception.i"
+%import "gnuradio.i"                           // the common stuff
+
+%{
+#include "gnuradio_swig_bug_workaround.h"      // mandatory bug fix
+#include "audio_alsa_sink.h"
+#include "audio_alsa_source.h"
+#include <stdexcept>
+%}
+
+// ----------------------------------------------------------------
+
+GR_SWIG_BLOCK_MAGIC(audio_alsa,source)
+
+audio_alsa_source_sptr
+audio_alsa_make_source (int sampling_rate,
+                       const std::string dev = "",
+                       bool ok_to_block = true
+                       ) throw (std::runtime_error);
+
+class audio_alsa_source : public gr_sync_block {
+
+ protected:
+  audio_alsa_source (int sampling_rate,
+                    const std::string device_name,
+                    bool ok_to_block = true
+                    ) throw (std::runtime_error);
+
+ public:
+  ~audio_alsa_source ();
+
+  bool start();
+  bool stop();
+};
+
+// ----------------------------------------------------------------
+
+GR_SWIG_BLOCK_MAGIC(audio_alsa,sink)
+
+audio_alsa_sink_sptr
+audio_alsa_make_sink (int sampling_rate,
+                     const std::string dev = "",
+                     bool ok_to_block = true
+                     ) throw (std::runtime_error);
+
+class audio_alsa_sink : public gr_sync_block {
+
+ protected:
+  audio_alsa_sink (int sampling_rate,
+                  const std::string device_name,
+                  bool ok_to_block
+                  ) throw (std::runtime_error);
+
+ public:
+  ~audio_alsa_sink ();
+};
diff --git a/gr-audio-alsa/src/audio_alsa_sink.cc b/gr-audio-alsa/src/audio_alsa_sink.cc
new file mode 100644 (file)
index 0000000..bdf9dbb
--- /dev/null
@@ -0,0 +1,538 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <audio_alsa_sink.h>
+#include <gr_io_signature.h>
+#include <gr_prefs.h>
+#include <stdio.h>
+#include <iostream>
+#include <stdexcept>
+#include <gri_alsa.h>
+
+
+static bool CHATTY_DEBUG = false;
+
+
+static snd_pcm_format_t acceptable_formats[] = {
+  // these are in our preferred order...
+  SND_PCM_FORMAT_S32,
+  SND_PCM_FORMAT_S16
+};
+
+#define NELEMS(x) (sizeof(x)/sizeof(x[0]))
+
+
+static std::string 
+default_device_name ()
+{
+  return gr_prefs::singleton()->get_string("audio_alsa", "default_output_device", "hw:0,0");
+}
+
+static double
+default_period_time ()
+{
+  return std::max(0.001, gr_prefs::singleton()->get_double("audio_alsa", "period_time", 0.010));
+}
+
+static int
+default_nperiods ()
+{
+  return std::max(2L, gr_prefs::singleton()->get_long("audio_alsa", "nperiods", 4));
+}
+
+// ----------------------------------------------------------------
+
+audio_alsa_sink_sptr
+audio_alsa_make_sink (int sampling_rate,
+                     const std::string dev,
+                     bool ok_to_block)
+{
+  return audio_alsa_sink_sptr (new audio_alsa_sink (sampling_rate, dev,
+                                                   ok_to_block));
+}
+
+audio_alsa_sink::audio_alsa_sink (int sampling_rate,
+                                 const std::string device_name,
+                                 bool ok_to_block)
+  : gr_sync_block ("audio_alsa_sink",
+                  gr_make_io_signature (0, 0, 0),
+                  gr_make_io_signature (0, 0, 0)),
+    d_sampling_rate (sampling_rate),
+    d_device_name (device_name.empty() ? default_device_name() : device_name),
+    d_pcm_handle (0),
+    d_hw_params ((snd_pcm_hw_params_t *)(new char[snd_pcm_hw_params_sizeof()])),
+    d_sw_params ((snd_pcm_sw_params_t *)(new char[snd_pcm_sw_params_sizeof()])),
+    d_nperiods (default_nperiods()),
+    d_period_time_us ((unsigned int) (default_period_time() * 1e6)),
+    d_period_size (0),
+    d_buffer_size_bytes (0), d_buffer (0),
+    d_worker (0), d_special_case_mono_to_stereo (false),
+    d_nunderuns (0), d_nsuspends (0)
+{
+  CHATTY_DEBUG = gr_prefs::singleton()->get_bool("audio_alsa", "verbose", false);
+
+  int          error;
+  int  dir;
+
+  // open the device for playback
+  error = snd_pcm_open(&d_pcm_handle, d_device_name.c_str (),
+                      SND_PCM_STREAM_PLAYBACK, 0);
+  if (error < 0){
+    fprintf (stderr, "audio_alsa_sink[%s]: %s\n",
+            d_device_name.c_str(), snd_strerror(error));
+    throw std::runtime_error ("audio_alsa_sink");
+  }
+
+  // Fill params with a full configuration space for a PCM.
+  error = snd_pcm_hw_params_any(d_pcm_handle, d_hw_params);
+  if (error < 0)
+    bail ("broken configuration for playback", error);
+
+
+  if (CHATTY_DEBUG)
+    gri_alsa_dump_hw_params (d_pcm_handle, d_hw_params, stdout);
+
+
+  // now that we know how many channels the h/w can handle, set input signature
+  unsigned int umin_chan, umax_chan;
+  snd_pcm_hw_params_get_channels_min (d_hw_params, &umin_chan);
+  snd_pcm_hw_params_get_channels_max (d_hw_params, &umax_chan);
+  int min_chan = std::min (umin_chan, 1000U);
+  int max_chan = std::min (umax_chan, 1000U);
+
+  // As a special case, if the hw's min_chan is two, we'll accept
+  // a single input and handle the duplication ourselves.
+
+  if (min_chan == 2){
+    min_chan = 1;
+    d_special_case_mono_to_stereo = true;
+  }
+  set_input_signature (gr_make_io_signature (min_chan, max_chan,
+                                            sizeof (float)));
+  
+  // fill in portions of the d_hw_params that we know now...
+
+  // Specify the access methods we implement
+  // For now, we only handle RW_INTERLEAVED...
+  snd_pcm_access_mask_t *access_mask;
+  snd_pcm_access_mask_alloca (&access_mask);
+  snd_pcm_access_mask_none (access_mask);
+  snd_pcm_access_mask_set (access_mask, SND_PCM_ACCESS_RW_INTERLEAVED);
+  // snd_pcm_access_mask_set (access_mask, SND_PCM_ACCESS_RW_NONINTERLEAVED);
+
+  if ((error = snd_pcm_hw_params_set_access_mask (d_pcm_handle,
+                                                 d_hw_params, access_mask)) < 0)
+    bail ("failed to set access mask", error);
+
+
+  // set sample format
+  if (!gri_alsa_pick_acceptable_format (d_pcm_handle, d_hw_params,
+                                       acceptable_formats,
+                                       NELEMS (acceptable_formats),
+                                       &d_format,
+                                       "audio_alsa_sink",
+                                       CHATTY_DEBUG))
+    throw std::runtime_error ("audio_alsa_sink");
+  
+
+  // sampling rate
+  unsigned int orig_sampling_rate = d_sampling_rate;
+  if ((error = snd_pcm_hw_params_set_rate_near (d_pcm_handle, d_hw_params,
+                                               &d_sampling_rate, 0)) < 0)
+    bail ("failed to set rate near", error);
+  
+  if (orig_sampling_rate != d_sampling_rate){
+    fprintf (stderr, "audio_alsa_sink[%s]: unable to support sampling rate %d\n",
+            snd_pcm_name (d_pcm_handle), orig_sampling_rate);
+    fprintf (stderr, "  card requested %d instead.\n", d_sampling_rate);
+  }
+
+  /*
+   * ALSA transfers data in units of "periods".
+   * We indirectly determine the underlying buffersize by specifying
+   * the number of periods we want (typically 4) and the length of each
+   * period in units of time (typically 1ms).
+   */
+  unsigned int min_nperiods, max_nperiods;
+  snd_pcm_hw_params_get_periods_min (d_hw_params, &min_nperiods, &dir);
+  snd_pcm_hw_params_get_periods_max (d_hw_params, &max_nperiods, &dir);
+  //fprintf (stderr, "alsa_sink: min_nperiods = %d, max_nperiods = %d\n",
+  // min_nperiods, max_nperiods);
+
+  unsigned int orig_nperiods = d_nperiods;
+  d_nperiods = std::min (std::max (min_nperiods, d_nperiods), max_nperiods);
+
+  // adjust period time so that total buffering remains more-or-less constant
+  d_period_time_us = (d_period_time_us * orig_nperiods) / d_nperiods;
+
+  error = snd_pcm_hw_params_set_periods (d_pcm_handle, d_hw_params,
+                                        d_nperiods, 0);
+  if (error < 0)
+    bail ("set_periods failed", error);
+
+  dir = 0;
+  error = snd_pcm_hw_params_set_period_time_near (d_pcm_handle, d_hw_params,
+                                                 &d_period_time_us, &dir);
+  if (error < 0)
+    bail ("set_period_time_near failed", error);
+
+  dir = 0;
+  error = snd_pcm_hw_params_get_period_size (d_hw_params,
+                                            &d_period_size, &dir);
+  if (error < 0)
+    bail ("get_period_size failed", error);
+  
+  set_output_multiple (d_period_size);
+}
+
+
+bool
+audio_alsa_sink::check_topology (int ninputs, int noutputs)
+{
+  // ninputs is how many channels the user has connected.
+  // Now we can finish up setting up the hw params...
+
+  int nchan = ninputs;
+  int err;
+
+  // FIXME check_topology may be called more than once.
+  // Ensure that the pcm is in a state where we can still mess with the hw_params
+
+  bool special_case = nchan == 1 && d_special_case_mono_to_stereo;
+  if (special_case)
+    nchan = 2;
+  
+  err = snd_pcm_hw_params_set_channels (d_pcm_handle, d_hw_params, nchan);
+
+  if (err < 0){
+    output_error_msg ("set_channels failed", err);
+    return false;
+  }
+
+  // set the parameters into the driver...
+  err = snd_pcm_hw_params(d_pcm_handle, d_hw_params);
+  if (err < 0){
+    output_error_msg ("snd_pcm_hw_params failed", err);
+    return false;
+  }
+
+  // get current s/w params
+  err = snd_pcm_sw_params_current (d_pcm_handle, d_sw_params);
+  if (err < 0)
+    bail ("snd_pcm_sw_params_current", err);
+  
+  // Tell the PCM device to wait to start until we've filled
+  // it's buffers half way full.  This helps avoid audio underruns.
+
+  err = snd_pcm_sw_params_set_start_threshold(d_pcm_handle,
+                                             d_sw_params,
+                                             d_nperiods * d_period_size / 2);
+  if (err < 0)
+    bail ("snd_pcm_sw_params_set_start_threshold", err);
+
+  // store the s/w params
+  err = snd_pcm_sw_params (d_pcm_handle, d_sw_params);
+  if (err < 0)
+    bail ("snd_pcm_sw_params", err);
+
+  d_buffer_size_bytes =
+    d_period_size * nchan * snd_pcm_format_size (d_format, 1);
+
+  d_buffer = new char [d_buffer_size_bytes];
+
+  if (CHATTY_DEBUG)
+    fprintf (stdout, "audio_alsa_sink[%s]: sample resolution = %d bits\n",
+            snd_pcm_name (d_pcm_handle),
+            snd_pcm_hw_params_get_sbits (d_hw_params));
+
+  switch (d_format){
+  case SND_PCM_FORMAT_S16:
+    if (special_case)
+      d_worker = &audio_alsa_sink::work_s16_1x2;
+    else
+      d_worker = &audio_alsa_sink::work_s16;
+    break;
+
+  case SND_PCM_FORMAT_S32:
+    if (special_case)
+      d_worker = &audio_alsa_sink::work_s32_1x2;
+    else
+      d_worker = &audio_alsa_sink::work_s32;
+    break;
+
+  default:
+    assert (0);
+  }
+
+  return true;
+}
+
+audio_alsa_sink::~audio_alsa_sink ()
+{
+  if (snd_pcm_state (d_pcm_handle) == SND_PCM_STATE_RUNNING)
+    snd_pcm_drop (d_pcm_handle);
+
+  snd_pcm_close(d_pcm_handle);
+  delete [] ((char *) d_hw_params);
+  delete [] ((char *) d_sw_params);
+  delete [] d_buffer;
+}
+
+int
+audio_alsa_sink::work (int noutput_items,
+                      gr_vector_const_void_star &input_items,
+                      gr_vector_void_star &output_items)
+{
+  assert ((noutput_items % d_period_size) == 0);
+
+  // this is a call through a pointer to a method...
+  return (this->*d_worker)(noutput_items, input_items, output_items);
+}
+
+/*
+ * Work function that deals with float to S16 conversion
+ */
+int
+audio_alsa_sink::work_s16 (int noutput_items,
+                          gr_vector_const_void_star &input_items,
+                          gr_vector_void_star &output_items)
+{
+  typedef gr_int16     sample_t;       // the type of samples we're creating
+  static const int NBITS = 16;         // # of bits in a sample
+  
+  unsigned int nchan = input_items.size ();
+  const float **in = (const float **) &input_items[0];
+  sample_t *buf = (sample_t *) d_buffer;
+  int bi;
+  int n;
+
+  unsigned int sizeof_frame = nchan * sizeof (sample_t);
+  assert (d_buffer_size_bytes == d_period_size * sizeof_frame);
+
+  for (n = 0; n < noutput_items; n += d_period_size){
+
+    // process one period of data
+    bi = 0;
+    for (unsigned int i = 0; i < d_period_size; i++){
+      for (unsigned int chan = 0; chan < nchan; chan++){
+       buf[bi++] = (sample_t) (in[chan][i] * (float) ((1L << (NBITS-1)) - 1));
+      }
+    }
+
+    // update src pointers
+    for (unsigned int chan = 0; chan < nchan; chan++)
+      in[chan] += d_period_size;
+
+    if (!write_buffer (buf, d_period_size, sizeof_frame))  
+      return -1;       // No fixing this problem.  Say we're done.
+  }
+
+  return n;
+}
+
+
+/*
+ * Work function that deals with float to S32 conversion
+ */
+int
+audio_alsa_sink::work_s32 (int noutput_items,
+                          gr_vector_const_void_star &input_items,
+                          gr_vector_void_star &output_items)
+{
+  typedef gr_int32     sample_t;       // the type of samples we're creating
+  static const int NBITS = 32;         // # of bits in a sample
+  
+  unsigned int nchan = input_items.size ();
+  const float **in = (const float **) &input_items[0];
+  sample_t *buf = (sample_t *) d_buffer;
+  int bi;
+  int n;
+
+  unsigned int sizeof_frame = nchan * sizeof (sample_t);
+  assert (d_buffer_size_bytes == d_period_size * sizeof_frame);
+
+  for (n = 0; n < noutput_items; n += d_period_size){
+
+    // process one period of data
+    bi = 0;
+    for (unsigned int i = 0; i < d_period_size; i++){
+      for (unsigned int chan = 0; chan < nchan; chan++){
+       buf[bi++] = (sample_t) (in[chan][i] * (float) ((1L << (NBITS-1)) - 1));
+      }
+    }
+
+    // update src pointers
+    for (unsigned int chan = 0; chan < nchan; chan++)
+      in[chan] += d_period_size;
+
+    if (!write_buffer (buf, d_period_size, sizeof_frame))  
+      return -1;       // No fixing this problem.  Say we're done.
+  }
+
+  return n;
+}
+
+/*
+ * Work function that deals with float to S16 conversion and
+ * mono to stereo kludge.
+ */
+int
+audio_alsa_sink::work_s16_1x2 (int noutput_items,
+                              gr_vector_const_void_star &input_items,
+                              gr_vector_void_star &output_items)
+{
+  typedef gr_int16     sample_t;       // the type of samples we're creating
+  static const int NBITS = 16;         // # of bits in a sample
+  
+  assert (input_items.size () == 1);
+  static const unsigned int nchan = 2;
+  const float **in = (const float **) &input_items[0];
+  sample_t *buf = (sample_t *) d_buffer;
+  int bi;
+  int n;
+
+  unsigned int sizeof_frame = nchan * sizeof (sample_t);
+  assert (d_buffer_size_bytes == d_period_size * sizeof_frame);
+
+  for (n = 0; n < noutput_items; n += d_period_size){
+
+    // process one period of data
+    bi = 0;
+    for (unsigned int i = 0; i < d_period_size; i++){
+      sample_t t = (sample_t) (in[0][i] * (float) ((1L << (NBITS-1)) - 1));
+      buf[bi++] = t;
+      buf[bi++] = t;
+    }
+
+    // update src pointers
+    in[0] += d_period_size;
+
+    if (!write_buffer (buf, d_period_size, sizeof_frame))  
+      return -1;       // No fixing this problem.  Say we're done.
+  }
+
+  return n;
+}
+
+/*
+ * Work function that deals with float to S32 conversion and
+ * mono to stereo kludge.
+ */
+int
+audio_alsa_sink::work_s32_1x2 (int noutput_items,
+                              gr_vector_const_void_star &input_items,
+                              gr_vector_void_star &output_items)
+{
+  typedef gr_int32     sample_t;       // the type of samples we're creating
+  static const int NBITS = 32;         // # of bits in a sample
+  
+  assert (input_items.size () == 1);
+  static unsigned int nchan = 2;
+  const float **in = (const float **) &input_items[0];
+  sample_t *buf = (sample_t *) d_buffer;
+  int bi;
+  int n;
+
+  unsigned int sizeof_frame = nchan * sizeof (sample_t);
+  assert (d_buffer_size_bytes == d_period_size * sizeof_frame);
+
+  for (n = 0; n < noutput_items; n += d_period_size){
+
+    // process one period of data
+    bi = 0;
+    for (unsigned int i = 0; i < d_period_size; i++){
+      sample_t t = (sample_t) (in[0][i] * (float) ((1L << (NBITS-1)) - 1));
+      buf[bi++] = t;
+      buf[bi++] = t;
+    }
+
+    // update src pointers
+    in[0] += d_period_size;
+
+    if (!write_buffer (buf, d_period_size, sizeof_frame))  
+      return -1;       // No fixing this problem.  Say we're done.
+  }
+
+  return n;
+}
+
+bool
+audio_alsa_sink::write_buffer (const void *vbuffer,
+                              unsigned nframes, unsigned sizeof_frame)
+{
+  const unsigned char *buffer = (const unsigned char *) vbuffer;
+
+  while (nframes > 0){
+    int r = snd_pcm_writei (d_pcm_handle, buffer, nframes);
+    if (r == -EAGAIN)
+      continue;                        // try again
+
+    else if (r == -EPIPE){     // underrun
+      d_nunderuns++;
+      fputs ("aU", stderr);
+      if ((r = snd_pcm_prepare (d_pcm_handle)) < 0){
+       output_error_msg ("snd_pcm_prepare failed. Can't recover from underrun", r);
+       return false;
+      }
+      continue;                        // try again
+    }
+
+    else if (r == -ESTRPIPE){  // h/w is suspended (whatever that means)
+                               // This is apparently related to power management
+      d_nsuspends++;
+      if ((r = snd_pcm_resume (d_pcm_handle)) < 0){
+       output_error_msg ("failed to resume from suspend", r);
+       return false;
+      }
+      continue;                        // try again
+    }
+
+    else if (r < 0){
+      output_error_msg ("snd_pcm_writei failed", r);
+      return false;
+    }
+
+    nframes -= r;
+    buffer += r * sizeof_frame;
+  }
+
+  return true;
+}
+
+
+void
+audio_alsa_sink::output_error_msg (const char *msg, int err)
+{
+  fprintf (stderr, "audio_alsa_sink[%s]: %s: %s\n",
+          snd_pcm_name (d_pcm_handle), msg,  snd_strerror (err));
+}
+
+void
+audio_alsa_sink::bail (const char *msg, int err) throw (std::runtime_error)
+{
+  output_error_msg (msg, err);
+  throw std::runtime_error ("audio_alsa_sink");
+}
diff --git a/gr-audio-alsa/src/audio_alsa_sink.h b/gr-audio-alsa/src/audio_alsa_sink.h
new file mode 100644 (file)
index 0000000..bb61e49
--- /dev/null
@@ -0,0 +1,124 @@
+/* -*- 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 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.
+ */
+
+#ifndef INCLUDED_AUDIO_ALSA_SINK_H
+#define INCLUDED_AUDIO_ALSA_SINK_H
+
+// use new ALSA API
+#define ALSA_PCM_NEW_HW_PARAMS_API
+#define ALSA_PCM_NEW_SW_PARAMS_API
+
+#include <gr_sync_block.h>
+#include <string>
+#include <alsa/asoundlib.h>
+#include <stdexcept>
+
+
+class audio_alsa_sink;
+typedef boost::shared_ptr<audio_alsa_sink> audio_alsa_sink_sptr;
+
+/*!
+ * \brief make an alsa audio sink.
+ *
+ * \param sampling_rate        sampling rate in Hz
+ * \param dev ALSA pcm device name, e.g., "hw:0,0"
+ * \param ok_to_block (currently ignored)
+ */
+audio_alsa_sink_sptr
+audio_alsa_make_sink (int sampling_rate,
+                     const std::string dev = "",
+                     bool ok_to_block = true);
+
+/*!
+ * \brief audio sink using ALSA
+ *
+ * The sink has N input streams of floats, where N depends
+ * on the hardware characteristics of the selected device.
+ *
+ * Input samples must be in the range [-1,1].
+ */
+class audio_alsa_sink : public gr_sync_block {
+  friend audio_alsa_sink_sptr
+  audio_alsa_make_sink (int sampling_rate, const std::string device_name,
+                       bool ok_to_block);
+
+  // typedef for pointer to class work method
+  typedef int (audio_alsa_sink::*work_t)(int noutput_items,
+                                        gr_vector_const_void_star &input_items,
+                                        gr_vector_void_star &output_items);
+
+  unsigned int         d_sampling_rate;
+  std::string          d_device_name;
+  snd_pcm_t            *d_pcm_handle;
+  snd_pcm_hw_params_t  *d_hw_params;
+  snd_pcm_sw_params_t  *d_sw_params;
+  snd_pcm_format_t     d_format;
+  unsigned int         d_nperiods;
+  unsigned int         d_period_time_us;       // microseconds
+  snd_pcm_uframes_t    d_period_size;          // in frames
+  unsigned int         d_buffer_size_bytes;    // sizeof of d_buffer
+  char                *d_buffer;
+  work_t               d_worker;               // the work method to use
+  bool                 d_special_case_mono_to_stereo;
+
+  // random stats
+  int                  d_nunderuns;            // count of underruns
+  int                  d_nsuspends;            // count of suspends
+
+  void output_error_msg (const char *msg, int err);
+  void bail (const char *msg, int err) throw (std::runtime_error);
+
+ protected:
+  audio_alsa_sink (int sampling_rate, const std::string device_name,
+                  bool ok_to_block);
+
+ public:
+  ~audio_alsa_sink ();
+  
+  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);
+
+
+protected:
+  bool write_buffer (const void *buffer, unsigned nframes, unsigned sizeof_frame);
+
+  int work_s16 (int noutput_items,
+               gr_vector_const_void_star &input_items,
+               gr_vector_void_star &output_items);
+
+  int work_s16_1x2 (int noutput_items,
+                   gr_vector_const_void_star &input_items,
+                   gr_vector_void_star &output_items);
+
+  int work_s32 (int noutput_items,
+               gr_vector_const_void_star &input_items,
+               gr_vector_void_star &output_items);
+
+  int work_s32_1x2 (int noutput_items,
+                   gr_vector_const_void_star &input_items,
+                   gr_vector_void_star &output_items);
+};
+
+#endif /* INCLUDED_AUDIO_ALSA_SINK_H */
diff --git a/gr-audio-alsa/src/audio_alsa_source.cc b/gr-audio-alsa/src/audio_alsa_source.cc
new file mode 100644 (file)
index 0000000..4e7ee94
--- /dev/null
@@ -0,0 +1,506 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <audio_alsa_source.h>
+#include <gr_io_signature.h>
+#include <gr_prefs.h>
+#include <stdio.h>
+#include <iostream>
+#include <stdexcept>
+#include <gri_alsa.h>
+
+
+static bool CHATTY_DEBUG = false;
+
+static snd_pcm_format_t acceptable_formats[] = {
+  // these are in our preferred order...
+  SND_PCM_FORMAT_S32,
+  SND_PCM_FORMAT_S16
+};
+
+#define NELEMS(x) (sizeof(x)/sizeof(x[0]))
+
+
+static std::string 
+default_device_name ()
+{
+  return gr_prefs::singleton()->get_string("audio_alsa", "default_input_device", "hw:0,0");
+}
+
+static double
+default_period_time ()
+{
+  return std::max(0.001, gr_prefs::singleton()->get_double("audio_alsa", "period_time", 0.010));
+}
+
+static int
+default_nperiods ()
+{
+  return std::max(2L, gr_prefs::singleton()->get_long("audio_alsa", "nperiods", 4));
+}
+
+// ----------------------------------------------------------------
+
+audio_alsa_source_sptr
+audio_alsa_make_source (int sampling_rate, const std::string dev,
+                       bool ok_to_block)
+{
+  return audio_alsa_source_sptr (new audio_alsa_source (sampling_rate, dev,
+                                                       ok_to_block));
+}
+
+audio_alsa_source::audio_alsa_source (int sampling_rate,
+                                     const std::string device_name,
+                                     bool ok_to_block)
+  : gr_sync_block ("audio_alsa_source",
+                  gr_make_io_signature (0, 0, 0),
+                  gr_make_io_signature (0, 0, 0)),
+    d_sampling_rate (sampling_rate),
+    d_device_name (device_name.empty() ? default_device_name() : device_name),
+    d_pcm_handle (0),
+    d_hw_params ((snd_pcm_hw_params_t *)(new char[snd_pcm_hw_params_sizeof()])),
+    d_sw_params ((snd_pcm_sw_params_t *)(new char[snd_pcm_sw_params_sizeof()])),
+    d_nperiods (default_nperiods()),
+    d_period_time_us ((unsigned int) (default_period_time() * 1e6)),
+    d_period_size (0),
+    d_buffer_size_bytes (0), d_buffer (0),
+    d_worker (0), d_hw_nchan (0),
+    d_special_case_stereo_to_mono (false),
+    d_noverruns (0), d_nsuspends (0)
+{
+
+  CHATTY_DEBUG = gr_prefs::singleton()->get_bool("audio_alsa", "verbose", false);
+
+  int          error;
+  int  dir;
+
+  // open the device for capture
+  error = snd_pcm_open(&d_pcm_handle, d_device_name.c_str (),
+                      SND_PCM_STREAM_CAPTURE, 0);
+  if (error < 0){
+    fprintf (stderr, "audio_alsa_source[%s]: %s\n",
+            d_device_name.c_str(), snd_strerror(error));
+    throw std::runtime_error ("audio_alsa_source");
+  }
+
+  // Fill params with a full configuration space for a PCM.
+  error = snd_pcm_hw_params_any(d_pcm_handle, d_hw_params);
+  if (error < 0)
+    bail ("broken configuration for playback", error);
+
+  if (CHATTY_DEBUG)
+    gri_alsa_dump_hw_params (d_pcm_handle, d_hw_params, stdout);
+
+  // now that we know how many channels the h/w can handle, set output signature
+  unsigned int umax_chan;
+  unsigned int umin_chan;
+  snd_pcm_hw_params_get_channels_min (d_hw_params, &umin_chan);
+  snd_pcm_hw_params_get_channels_max (d_hw_params, &umax_chan);
+  int min_chan = std::min (umin_chan, 1000U);
+  int max_chan = std::min (umax_chan, 1000U);
+
+  // As a special case, if the hw's min_chan is two, we'll accept
+  // a single output and handle the demux ourselves.
+
+  if (min_chan == 2){
+    min_chan = 1;
+    d_special_case_stereo_to_mono = true;
+  }
+  
+  set_output_signature (gr_make_io_signature (min_chan, max_chan,
+                                             sizeof (float)));
+  
+  // fill in portions of the d_hw_params that we know now...
+
+  // Specify the access methods we implement
+  // For now, we only handle RW_INTERLEAVED...
+  snd_pcm_access_mask_t *access_mask;
+  snd_pcm_access_mask_alloca (&access_mask);
+  snd_pcm_access_mask_none (access_mask);
+  snd_pcm_access_mask_set (access_mask, SND_PCM_ACCESS_RW_INTERLEAVED);
+  // snd_pcm_access_mask_set (access_mask, SND_PCM_ACCESS_RW_NONINTERLEAVED);
+
+  if ((error = snd_pcm_hw_params_set_access_mask (d_pcm_handle,
+                                                 d_hw_params, access_mask)) < 0)
+    bail ("failed to set access mask", error);
+
+
+  // set sample format
+  if (!gri_alsa_pick_acceptable_format (d_pcm_handle, d_hw_params,
+                                       acceptable_formats,
+                                       NELEMS (acceptable_formats),
+                                       &d_format,
+                                       "audio_alsa_source",
+                                       CHATTY_DEBUG))
+    throw std::runtime_error ("audio_alsa_source");
+  
+
+  // sampling rate
+  unsigned int orig_sampling_rate = d_sampling_rate;
+  if ((error = snd_pcm_hw_params_set_rate_near (d_pcm_handle, d_hw_params,
+                                               &d_sampling_rate, 0)) < 0)
+    bail ("failed to set rate near", error);
+  
+  if (orig_sampling_rate != d_sampling_rate){
+    fprintf (stderr, "audio_alsa_source[%s]: unable to support sampling rate %d\n",
+            snd_pcm_name (d_pcm_handle), orig_sampling_rate);
+    fprintf (stderr, "  card requested %d instead.\n", d_sampling_rate);
+  }
+
+  /*
+   * ALSA transfers data in units of "periods".
+   * We indirectly determine the underlying buffersize by specifying
+   * the number of periods we want (typically 4) and the length of each
+   * period in units of time (typically 1ms).
+   */
+  unsigned int min_nperiods, max_nperiods;
+  snd_pcm_hw_params_get_periods_min (d_hw_params, &min_nperiods, &dir);
+  snd_pcm_hw_params_get_periods_max (d_hw_params, &max_nperiods, &dir);
+  //fprintf (stderr, "alsa_source: min_nperiods = %d, max_nperiods = %d\n",
+  // min_nperiods, max_nperiods);
+
+
+  unsigned int orig_nperiods = d_nperiods;
+  d_nperiods = std::min (std::max (min_nperiods, d_nperiods), max_nperiods);
+
+  // adjust period time so that total buffering remains more-or-less constant
+  d_period_time_us = (d_period_time_us * orig_nperiods) / d_nperiods;
+
+  error = snd_pcm_hw_params_set_periods (d_pcm_handle, d_hw_params,
+                                        d_nperiods, 0);
+  if (error < 0)
+    bail ("set_periods failed", error);
+
+  dir = 0;
+  error = snd_pcm_hw_params_set_period_time_near (d_pcm_handle, d_hw_params,
+                                                 &d_period_time_us, &dir);
+  if (error < 0)
+    bail ("set_period_time_near failed", error);
+
+  dir = 0;
+  error = snd_pcm_hw_params_get_period_size (d_hw_params,
+                                            &d_period_size, &dir);
+  if (error < 0)
+    bail ("get_period_size failed", error);
+  
+  set_output_multiple (d_period_size);
+}
+
+bool
+audio_alsa_source::check_topology (int ninputs, int noutputs)
+{
+  // noutputs is how many channels the user has connected.
+  // Now we can finish up setting up the hw params...
+
+  unsigned int nchan = noutputs;
+  int err;
+
+  // FIXME check_topology may be called more than once.
+  // Ensure that the pcm is in a state where we can still mess with the hw_params
+
+  bool special_case = nchan == 1 && d_special_case_stereo_to_mono;
+  if (special_case)
+    nchan = 2;
+
+  d_hw_nchan = nchan;
+  err = snd_pcm_hw_params_set_channels (d_pcm_handle, d_hw_params, d_hw_nchan);
+  if (err < 0){
+    output_error_msg ("set_channels failed", err);
+    return false;
+  }
+
+  // set the parameters into the driver...
+  err = snd_pcm_hw_params(d_pcm_handle, d_hw_params);
+  if (err < 0){
+    output_error_msg ("snd_pcm_hw_params failed", err);
+    return false;
+  }
+
+  d_buffer_size_bytes =
+    d_period_size * d_hw_nchan * snd_pcm_format_size (d_format, 1);
+
+  d_buffer = new char [d_buffer_size_bytes];
+
+  if (CHATTY_DEBUG)
+    fprintf (stdout, "audio_alsa_source[%s]: sample resolution = %d bits\n",
+            snd_pcm_name (d_pcm_handle),
+            snd_pcm_hw_params_get_sbits (d_hw_params));
+
+  switch (d_format){
+  case SND_PCM_FORMAT_S16:
+    if (special_case)
+      d_worker = &audio_alsa_source::work_s16_2x1;
+    else
+      d_worker = &audio_alsa_source::work_s16;
+    break;
+
+  case SND_PCM_FORMAT_S32:
+    if (special_case)
+      d_worker = &audio_alsa_source::work_s32_2x1;
+    else
+      d_worker = &audio_alsa_source::work_s32;
+    break;
+
+  default:
+    assert (0);
+  }
+
+  return true;
+}
+
+audio_alsa_source::~audio_alsa_source ()
+{
+  if (snd_pcm_state (d_pcm_handle) == SND_PCM_STATE_RUNNING)
+    snd_pcm_drop (d_pcm_handle);
+
+  snd_pcm_close(d_pcm_handle);
+  delete [] ((char *) d_hw_params);
+  delete [] ((char *) d_sw_params);
+  delete [] d_buffer;
+}
+
+int
+audio_alsa_source::work (int noutput_items,
+                        gr_vector_const_void_star &input_items,
+                        gr_vector_void_star &output_items)
+{
+  assert ((noutput_items % d_period_size) == 0);
+  assert (noutput_items != 0);
+
+  // this is a call through a pointer to a method...
+  return (this->*d_worker)(noutput_items, input_items, output_items);
+}
+
+/*
+ * Work function that deals with float to S16 conversion
+ */
+int
+audio_alsa_source::work_s16 (int noutput_items,
+                            gr_vector_const_void_star &input_items,
+                            gr_vector_void_star &output_items)
+{
+  typedef gr_int16     sample_t;       // the type of samples we're creating
+  static const int NBITS = 16;         // # of bits in a sample
+  
+  unsigned int nchan = output_items.size ();
+  float **out = (float **) &output_items[0];
+  sample_t *buf = (sample_t *) d_buffer;
+  int bi;
+
+  unsigned int sizeof_frame = d_hw_nchan * sizeof (sample_t);
+  assert (d_buffer_size_bytes == d_period_size * sizeof_frame);
+
+  // To minimize latency, return at most a single period's worth of samples.
+  // [We could also read the first one in a blocking mode and subsequent
+  //  ones in non-blocking mode, but we'll leave that for later (or never).]
+  
+  if (!read_buffer (buf, d_period_size, sizeof_frame))
+    return -1;         // No fixing this problem.  Say we're done.
+
+  // process one period of data
+  bi = 0;
+  for (unsigned int i = 0; i < d_period_size; i++){
+    for (unsigned int chan = 0; chan < nchan; chan++){
+      out[chan][i] = (float) buf[bi++] * (1.0 / (float) ((1L << (NBITS-1)) - 1));
+    }
+  }
+
+  return d_period_size;
+}
+
+/*
+ * Work function that deals with float to S16 conversion
+ * and stereo to mono kludge...
+ */
+int
+audio_alsa_source::work_s16_2x1 (int noutput_items,
+                                gr_vector_const_void_star &input_items,
+                                gr_vector_void_star &output_items)
+{
+  typedef gr_int16     sample_t;       // the type of samples we're creating
+  static const int NBITS = 16;         // # of bits in a sample
+  
+  unsigned int nchan = output_items.size ();
+  float **out = (float **) &output_items[0];
+  sample_t *buf = (sample_t *) d_buffer;
+  int bi;
+
+  assert (nchan == 1);
+
+  unsigned int sizeof_frame = d_hw_nchan * sizeof (sample_t);
+  assert (d_buffer_size_bytes == d_period_size * sizeof_frame);
+
+  // To minimize latency, return at most a single period's worth of samples.
+  // [We could also read the first one in a blocking mode and subsequent
+  //  ones in non-blocking mode, but we'll leave that for later (or never).]
+  
+  if (!read_buffer (buf, d_period_size, sizeof_frame))
+    return -1;         // No fixing this problem.  Say we're done.
+
+  // process one period of data
+  bi = 0;
+  for (unsigned int i = 0; i < d_period_size; i++){
+    int t = (buf[bi] + buf[bi+1]) / 2;
+    bi += 2;
+    out[0][i] = (float) t * (1.0 / (float) ((1L << (NBITS-1)) - 1));
+  }
+
+  return d_period_size;
+}
+
+/*
+ * Work function that deals with float to S32 conversion
+ */
+int
+audio_alsa_source::work_s32 (int noutput_items,
+                            gr_vector_const_void_star &input_items,
+                            gr_vector_void_star &output_items)
+{
+  typedef gr_int32     sample_t;       // the type of samples we're creating
+  static const int NBITS = 32;         // # of bits in a sample
+  
+  unsigned int nchan = output_items.size ();
+  float **out = (float **) &output_items[0];
+  sample_t *buf = (sample_t *) d_buffer;
+  int bi;
+
+  unsigned int sizeof_frame = d_hw_nchan * sizeof (sample_t);
+  assert (d_buffer_size_bytes == d_period_size * sizeof_frame);
+
+  // To minimize latency, return at most a single period's worth of samples.
+  // [We could also read the first one in a blocking mode and subsequent
+  //  ones in non-blocking mode, but we'll leave that for later (or never).]
+  
+  if (!read_buffer (buf, d_period_size, sizeof_frame))
+    return -1;         // No fixing this problem.  Say we're done.
+
+  // process one period of data
+  bi = 0;
+  for (unsigned int i = 0; i < d_period_size; i++){
+    for (unsigned int chan = 0; chan < nchan; chan++){
+      out[chan][i] = (float) buf[bi++] * (1.0 / (float) ((1L << (NBITS-1)) - 1));
+    }
+  }
+
+  return d_period_size;
+}
+
+/*
+ * Work function that deals with float to S32 conversion
+ * and stereo to mono kludge...
+ */
+int
+audio_alsa_source::work_s32_2x1 (int noutput_items,
+                                gr_vector_const_void_star &input_items,
+                                gr_vector_void_star &output_items)
+{
+  typedef gr_int32     sample_t;       // the type of samples we're creating
+  static const int NBITS = 32;         // # of bits in a sample
+  
+  unsigned int nchan = output_items.size ();
+  float **out = (float **) &output_items[0];
+  sample_t *buf = (sample_t *) d_buffer;
+  int bi;
+
+  assert (nchan == 1);
+
+  unsigned int sizeof_frame = d_hw_nchan * sizeof (sample_t);
+  assert (d_buffer_size_bytes == d_period_size * sizeof_frame);
+
+  // To minimize latency, return at most a single period's worth of samples.
+  // [We could also read the first one in a blocking mode and subsequent
+  //  ones in non-blocking mode, but we'll leave that for later (or never).]
+  
+  if (!read_buffer (buf, d_period_size, sizeof_frame))
+    return -1;         // No fixing this problem.  Say we're done.
+
+  // process one period of data
+  bi = 0;
+  for (unsigned int i = 0; i < d_period_size; i++){
+    int t = (buf[bi] + buf[bi+1]) / 2;
+    bi += 2;
+    out[0][i] = (float) t * (1.0 / (float) ((1L << (NBITS-1)) - 1));
+  }
+
+  return d_period_size;
+}
+
+bool
+audio_alsa_source::read_buffer (void *vbuffer, unsigned nframes, unsigned sizeof_frame)
+{
+  unsigned char *buffer = (unsigned char *) vbuffer;
+
+  while (nframes > 0){
+    int r = snd_pcm_readi (d_pcm_handle, buffer, nframes);
+    if (r == -EAGAIN)
+      continue;                        // try again
+
+    else if (r == -EPIPE){     // overrun
+      d_noverruns++;
+      fputs ("aO", stderr);
+      if ((r = snd_pcm_prepare (d_pcm_handle)) < 0){
+       output_error_msg ("snd_pcm_prepare failed. Can't recover from overrun", r);
+       return false;
+      }
+      continue;                        // try again
+    }
+
+    else if (r == -ESTRPIPE){  // h/w is suspended (whatever that means)
+                               // This is apparently related to power management
+      d_nsuspends++;
+      if ((r = snd_pcm_resume (d_pcm_handle)) < 0){
+       output_error_msg ("failed to resume from suspend", r);
+       return false;
+      }
+      continue;                        // try again
+    }
+
+    else if (r < 0){
+      output_error_msg ("snd_pcm_readi failed", r);
+      return false;
+    }
+
+    nframes -= r;
+    buffer += r * sizeof_frame;
+  }
+
+  return true;
+}
+
+
+void
+audio_alsa_source::output_error_msg (const char *msg, int err)
+{
+  fprintf (stderr, "audio_alsa_source[%s]: %s: %s\n",
+          snd_pcm_name (d_pcm_handle), msg,  snd_strerror (err));
+}
+
+void
+audio_alsa_source::bail (const char *msg, int err) throw (std::runtime_error)
+{
+  output_error_msg (msg, err);
+  throw std::runtime_error ("audio_alsa_source");
+}
diff --git a/gr-audio-alsa/src/audio_alsa_source.h b/gr-audio-alsa/src/audio_alsa_source.h
new file mode 100644 (file)
index 0000000..cc1ae11
--- /dev/null
@@ -0,0 +1,124 @@
+/* -*- 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 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.
+ */
+
+#ifndef INCLUDED_AUDIO_ALSA_SOURCE_H
+#define INCLUDED_AUDIO_ALSA_SOURCE_H
+
+// use new ALSA API
+#define ALSA_PCM_NEW_HW_PARAMS_API
+#define ALSA_PCM_NEW_SW_PARAMS_API
+
+#include <gr_sync_block.h>
+#include <string>
+#include <alsa/asoundlib.h>
+#include <stdexcept>
+
+class audio_alsa_source;
+typedef boost::shared_ptr<audio_alsa_source> audio_alsa_source_sptr;
+
+/*!
+ * \brief Make an ALSA audio source.
+ *
+ * \param sampling_rate        sampling rate
+ * \param dev ALSA pcm device name, e.g., "hw:0,0"
+ * \param ok_to_block  (currently ignored)
+ */
+audio_alsa_source_sptr
+audio_alsa_make_source (int sampling_rate,
+                       const std::string dev = "",
+                       bool ok_to_block = true);
+
+/*!
+ * \brief audio source using ALSA
+ *
+ * The source has between 1 and N input streams of floats, where N is
+ * depends on the hardware characteristics of the selected device.
+ *
+ * Output samples will be in the range [-1,1].
+ */
+class audio_alsa_source : public gr_sync_block {
+  friend audio_alsa_source_sptr
+  audio_alsa_make_source (int sampling_rate,
+                         const std::string device_name,
+                         bool ok_to_block);
+
+  // typedef for pointer to class work method
+  typedef int (audio_alsa_source::*work_t)(int noutput_items,
+                                          gr_vector_const_void_star &input_items,
+                                          gr_vector_void_star &output_items);
+
+  unsigned int         d_sampling_rate;
+  std::string          d_device_name;
+  snd_pcm_t            *d_pcm_handle;
+  snd_pcm_hw_params_t  *d_hw_params;
+  snd_pcm_sw_params_t  *d_sw_params;
+  snd_pcm_format_t     d_format;
+  unsigned int         d_nperiods;
+  unsigned int         d_period_time_us;       // microseconds
+  snd_pcm_uframes_t    d_period_size;          // in frames
+  unsigned int         d_buffer_size_bytes;    // sizeof of d_buffer
+  char                *d_buffer;
+  work_t               d_worker;               // the work method to use
+  unsigned int         d_hw_nchan;             // # of configured h/w channels
+  bool                 d_special_case_stereo_to_mono;
+
+  // random stats
+  int                  d_noverruns;            // count of overruns
+  int                  d_nsuspends;            // count of suspends
+
+  void output_error_msg (const char *msg, int err);
+  void bail (const char *msg, int err) throw (std::runtime_error);
+
+ protected:
+  audio_alsa_source (int sampling_rate, const std::string device_name,
+                    bool ok_to_block);
+
+ public:
+  ~audio_alsa_source ();
+  
+  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);
+
+protected:
+  bool read_buffer (void *buffer, unsigned nframes, unsigned sizeof_frame);
+
+  int work_s16 (int noutput_items,
+               gr_vector_const_void_star &input_items,
+               gr_vector_void_star &output_items);
+
+  int work_s16_2x1 (int noutput_items,
+                   gr_vector_const_void_star &input_items,
+                   gr_vector_void_star &output_items);
+
+  int work_s32 (int noutput_items,
+               gr_vector_const_void_star &input_items,
+               gr_vector_void_star &output_items);
+
+  int work_s32_2x1 (int noutput_items,
+                   gr_vector_const_void_star &input_items,
+                   gr_vector_void_star &output_items);
+};
+
+#endif /* INCLUDED_AUDIO_ALSA_SOURCE_H */
diff --git a/gr-audio-alsa/src/gri_alsa.cc b/gr-audio-alsa/src/gri_alsa.cc
new file mode 100644 (file)
index 0000000..25ff7f6
--- /dev/null
@@ -0,0 +1,175 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gri_alsa.h>
+#include <algorithm>
+
+static snd_pcm_access_t access_types[] = {
+  SND_PCM_ACCESS_MMAP_INTERLEAVED,
+  SND_PCM_ACCESS_MMAP_NONINTERLEAVED,
+  SND_PCM_ACCESS_MMAP_COMPLEX,
+  SND_PCM_ACCESS_RW_INTERLEAVED,
+  SND_PCM_ACCESS_RW_NONINTERLEAVED
+};
+
+static snd_pcm_format_t format_types[] = {
+  // SND_PCM_FORMAT_UNKNOWN,
+  SND_PCM_FORMAT_S8,
+  SND_PCM_FORMAT_U8,
+  SND_PCM_FORMAT_S16_LE,
+  SND_PCM_FORMAT_S16_BE,
+  SND_PCM_FORMAT_U16_LE,
+  SND_PCM_FORMAT_U16_BE,
+  SND_PCM_FORMAT_S24_LE,
+  SND_PCM_FORMAT_S24_BE,
+  SND_PCM_FORMAT_U24_LE,
+  SND_PCM_FORMAT_U24_BE,
+  SND_PCM_FORMAT_S32_LE,
+  SND_PCM_FORMAT_S32_BE,
+  SND_PCM_FORMAT_U32_LE,
+  SND_PCM_FORMAT_U32_BE,
+  SND_PCM_FORMAT_FLOAT_LE,
+  SND_PCM_FORMAT_FLOAT_BE,
+  SND_PCM_FORMAT_FLOAT64_LE,
+  SND_PCM_FORMAT_FLOAT64_BE,
+  SND_PCM_FORMAT_IEC958_SUBFRAME_LE,
+  SND_PCM_FORMAT_IEC958_SUBFRAME_BE,
+  SND_PCM_FORMAT_MU_LAW,
+  SND_PCM_FORMAT_A_LAW,
+  SND_PCM_FORMAT_IMA_ADPCM,
+  SND_PCM_FORMAT_MPEG,
+  SND_PCM_FORMAT_GSM,
+  SND_PCM_FORMAT_SPECIAL,
+  SND_PCM_FORMAT_S24_3LE,
+  SND_PCM_FORMAT_S24_3BE,
+  SND_PCM_FORMAT_U24_3LE,
+  SND_PCM_FORMAT_U24_3BE,
+  SND_PCM_FORMAT_S20_3LE,
+  SND_PCM_FORMAT_S20_3BE,
+  SND_PCM_FORMAT_U20_3LE,
+  SND_PCM_FORMAT_U20_3BE,
+  SND_PCM_FORMAT_S18_3LE,
+  SND_PCM_FORMAT_S18_3BE,
+  SND_PCM_FORMAT_U18_3LE,
+  SND_PCM_FORMAT_U18_3BE
+};
+
+static unsigned int test_rates[] = {
+  8000, 16000, 22050, 32000, 44100, 48000, 96000, 192000
+};
+
+#define NELEMS(x) (sizeof(x)/sizeof(x[0]))
+
+void
+gri_alsa_dump_hw_params (snd_pcm_t *pcm, snd_pcm_hw_params_t *hwparams, FILE *fp)
+{
+  fprintf (fp, "PCM name: %s\n", snd_pcm_name (pcm));
+  
+  fprintf (fp, "Access types:\n");
+  for (unsigned i = 0; i < NELEMS (access_types); i++){
+    snd_pcm_access_t   at = access_types[i];
+    fprintf (fp, "    %-20s %s\n",
+            snd_pcm_access_name (at),
+            snd_pcm_hw_params_test_access (pcm, hwparams, at) == 0 ? "YES" : "NO");
+  }
+
+  fprintf (fp, "Formats:\n");
+  for (unsigned i = 0; i < NELEMS (format_types); i++){
+    snd_pcm_format_t   ft = format_types[i];
+    if (0)
+      fprintf (fp, "    %-20s %s\n",
+              snd_pcm_format_name (ft),
+              snd_pcm_hw_params_test_format (pcm, hwparams, ft) == 0 ? "YES" : "NO");
+    else {
+      if (snd_pcm_hw_params_test_format (pcm, hwparams, ft) == 0)
+       fprintf (fp, "    %-20s YES\n", snd_pcm_format_name (ft));
+    }
+  }
+
+  fprintf (fp, "Number of channels\n");
+  unsigned int min_chan, max_chan;
+  snd_pcm_hw_params_get_channels_min (hwparams, &min_chan);
+  snd_pcm_hw_params_get_channels_max (hwparams, &max_chan);
+  fprintf (fp, "    min channels: %d\n", min_chan);
+  fprintf (fp, "    max channels: %d\n", max_chan);
+  unsigned int chan;
+  max_chan = std::min (max_chan, 16U); // truncate display...
+  for (chan = min_chan; chan <= max_chan; chan++){
+    fprintf (fp, "    %d channels\t%s\n", chan,
+            snd_pcm_hw_params_test_channels (pcm, hwparams, chan) == 0 ? "YES" : "NO");
+  }
+
+  fprintf (fp, "Sample Rates:\n");
+  unsigned int min_rate, max_rate;
+  int  min_dir, max_dir;
+
+  snd_pcm_hw_params_get_rate_min (hwparams, &min_rate, &min_dir);
+  snd_pcm_hw_params_get_rate_max (hwparams, &max_rate, &max_dir);
+  fprintf (fp, "    min rate: %7d (dir = %d)\n", min_rate, min_dir);
+  fprintf (fp, "    max rate: %7d (dir = %d)\n", max_rate, max_dir);
+  for (unsigned i = 0; i < NELEMS (test_rates); i++){
+    unsigned int rate = test_rates[i];
+    fprintf (fp, "    %6u  %s\n", rate,
+            snd_pcm_hw_params_test_rate (pcm, hwparams, rate, 0) == 0 ? "YES" : "NO");
+  }
+
+  fflush (fp);
+}
+
+bool
+gri_alsa_pick_acceptable_format (snd_pcm_t *pcm,
+                                snd_pcm_hw_params_t *hwparams,
+                                snd_pcm_format_t acceptable_formats[],
+                                unsigned nacceptable_formats,
+                                snd_pcm_format_t *selected_format,
+                                const char *error_msg_tag,
+                                bool verbose)
+{
+  int err;
+
+  // pick a format that we like...
+  for (unsigned i = 0; i < nacceptable_formats; i++){
+    if (snd_pcm_hw_params_test_format (pcm, hwparams,
+                                      acceptable_formats[i]) == 0){
+      err = snd_pcm_hw_params_set_format (pcm, hwparams, acceptable_formats[i]);
+      if (err < 0){
+       fprintf (stderr, "%s[%s]: failed to set format: %s\n",
+                error_msg_tag, snd_pcm_name (pcm), snd_strerror (err));
+       return false;
+      }
+      if (verbose)
+       fprintf (stdout, "%s[%s]: using %s\n",
+                error_msg_tag, snd_pcm_name (pcm),
+                snd_pcm_format_name (acceptable_formats[i]));
+      *selected_format = acceptable_formats[i];
+      return true;
+    }
+  }
+  
+  fprintf (stderr, "%s[%s]: failed to find acceptable format",
+          error_msg_tag, snd_pcm_name (pcm));
+  return false;
+}
diff --git a/gr-audio-alsa/src/gri_alsa.h b/gr-audio-alsa/src/gri_alsa.h
new file mode 100644 (file)
index 0000000..841c54d
--- /dev/null
@@ -0,0 +1,44 @@
+/* -*- 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 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.
+ */
+
+#ifndef INCLUDED_GRI_ALSA_H
+#define INCLUDED_GRI_ALSA_H
+
+#include <stdio.h>
+#include <alsa/asoundlib.h>
+
+void 
+gri_alsa_dump_hw_params (snd_pcm_t *pcm,
+                        snd_pcm_hw_params_t *hwparams,
+                        FILE *fp);
+
+bool
+gri_alsa_pick_acceptable_format (snd_pcm_t *pcm,
+                                snd_pcm_hw_params_t *hwparams,
+                                snd_pcm_format_t acceptable_formats[],
+                                unsigned nacceptable_formats,
+                                snd_pcm_format_t *selected_format,
+                                const char *error_msg_tag,
+                                bool verbose);
+
+
+#endif /* INCLUDED_GRI_ALSA_H */
diff --git a/gr-audio-alsa/src/qa_alsa.py b/gr-audio-alsa/src/qa_alsa.py
new file mode 100755 (executable)
index 0000000..2994573
--- /dev/null
@@ -0,0 +1,40 @@
+#!/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 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.
+# 
+
+from gnuradio import gr, gr_unittest
+import audio_alsa
+
+class qa_alsa (gr_unittest.TestCase):
+
+    def setUp (self):
+        self.fg = gr.flow_graph ()
+
+    def tearDown (self):
+        self.fg = None
+
+    def test_000_nop (self):
+        """Just see if we can import the module...
+        They may not have ALSA drivers, etc.  Don't try to run anything"""
+        pass
+    
+if __name__ == '__main__':
+    gr_unittest.main ()
diff --git a/gr-audio-alsa/src/run_tests.in b/gr-audio-alsa/src/run_tests.in
new file mode 100644 (file)
index 0000000..4bfb076
--- /dev/null
@@ -0,0 +1,47 @@
+#!/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@/gr-audio-alsa/src
+# Where to look in the src tree for swig generated python code
+libsrc=@abs_top_srcdir@/gr-audio-alsa/src
+# Where to look in the src tree for hand written python code
+py=@abs_top_srcdir@/gr-audio-alsa/src
+
+# Where to look for GNU Radio python modules in current build tree
+# FIXME this is wrong on a distcheck.  We really need to ask gnuradio-core
+# where it put its python files.
+grpythonbld=@abs_top_builddir@/gnuradio-core/src/python/:@abs_top_builddir@/gnuradio-core/src/lib/swig/:@abs_top_builddir@/gnuradio-core/src/lib/swig/.libs
+
+PYTHONPATH="$grpythonbld:$libbld:$libbld/.libs:$libsrc:$py:$PYTHONPATH"
+export PYTHONPATH
+
+#
+# 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-audio-jack/AUTHORS b/gr-audio-jack/AUTHORS
new file mode 100644 (file)
index 0000000..624606f
--- /dev/null
@@ -0,0 +1 @@
+Stephane Fillod <f8cfe@free.fr>
diff --git a/gr-audio-jack/ChangeLog b/gr-audio-jack/ChangeLog
new file mode 100644 (file)
index 0000000..3851f66
--- /dev/null
@@ -0,0 +1,42 @@
+2006-03-30  Eric Blossom  <eb@comsec.com>
+
+       * gr-audio-jack.conf: new config file.
+       * src/audio_jack_source.{h,cc}, src/audio_jack_sink.{h,cc}: added
+       ok_to_block ctor argument (currently ignored).  Also query prefs
+       for default input and output device names.
+
+2005-10-13  Stephane Fillod <f8cfe@free.fr>
+
+       * src/audio_jack_{source,sink}.cc: don't use jack_get_client_name
+       since older jack versions don't have it.
+
+2005-10-09  Stephane Fillod <f8cfe@free.fr>
+
+       * src/audio_jack_{source,sink}.cc: fix, don't retrieve jack buffer 
+       when ringbuffer overflows/underflows.
+
+2005-09-30  Stephane Fillod <f8cfe@free.fr>
+
+       * src/audio_jack_source.{h,cc}: new.
+       * src/audio_jack_sink.{h,cc}: new.
+
+#
+# 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 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.
+# 
diff --git a/gr-audio-jack/Makefile.am b/gr-audio-jack/Makefile.am
new file mode 100644 (file)
index 0000000..329f569
--- /dev/null
@@ -0,0 +1,28 @@
+#
+# 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.
+# 
+
+include $(top_srcdir)/Makefile.common
+
+EXTRA_DIST = gr-audio-jack.conf
+SUBDIRS = src
+
+etcdir = $(sysconfdir)/gnuradio/conf.d
+etc_DATA = gr-audio-jack.conf
diff --git a/gr-audio-jack/gr-audio-jack.conf b/gr-audio-jack/gr-audio-jack.conf
new file mode 100644 (file)
index 0000000..bdbc1fd
--- /dev/null
@@ -0,0 +1,8 @@
+# This file contains system wide configuration data for GNU Radio.
+# You may override any setting on a per-user basis by editing
+# ~/.gnuradio/config.conf
+
+[audio_jack]
+
+default_input_device = gr_source
+default_output_device = gr_sink
diff --git a/gr-audio-jack/src/Makefile.am b/gr-audio-jack/src/Makefile.am
new file mode 100644 (file)
index 0000000..a00e574
--- /dev/null
@@ -0,0 +1,98 @@
+#
+# 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 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.
+# 
+
+include $(top_srcdir)/Makefile.common
+
+LIBS += $(GNURADIO_CORE_LIBS)
+
+# Install this stuff so that it ends up as the gnuradio.audio_jack module
+# This usually ends up at:
+#   ${prefix}/lib/python${python_version}/site-packages/gnuradio
+
+ourpythondir = $(grpythondir)
+ourlibdir    = $(grpyexecdir)
+
+EXTRA_DIST = run_tests.in
+
+TESTS = run_tests
+
+LOCAL_IFILES =                                 \
+       audio_jack.i                            
+
+NON_LOCAL_IFILES =                     \
+       $(top_srcdir)/gnuradio-core/src/lib/swig/gnuradio.i
+
+ALL_IFILES =                           \
+       $(LOCAL_IFILES)                 \
+       $(NON_LOCAL_IFILES)             
+
+BUILT_SOURCES =                        \
+       audio_jack.cc                   \
+       audio_jack.py                           
+
+ourpython_PYTHON =                     \
+       audio_jack.py
+
+INCLUDES = $(STD_DEFINES_AND_INCLUDES) $(PYTHON_CPPFLAGS)
+
+SWIGPYTHONARGS = $(SWIGPYTHONFLAGS) $(STD_DEFINES_AND_INCLUDES)
+
+
+ourlib_LTLIBRARIES = _audio_jack.la
+
+
+_audio_jack_la_SOURCES =               \
+       audio_jack.cc                   \
+       audio_jack_sink.cc              \
+       audio_jack_source.cc            \
+       gri_jack.cc                     
+
+grinclude_HEADERS =                    \
+       audio_jack_sink.h               \
+       audio_jack_source.h             
+
+noinst_HEADERS =                       \
+       gri_jack.h                      
+
+
+swiginclude_HEADERS =                  \
+       $(LOCAL_IFILES)
+
+_audio_jack_la_LIBADD =                \
+       $(PYTHON_LDFLAGS)               \
+       -lstdc++                                
+
+_audio_jack_la_LDFLAGS = $(NO_UNDEFINED) -module -avoid-version
+
+audio_jack.cc audio_jack.py: audio_jack.i $(NON_LOCAL_IFILES)
+       $(SWIG) $(SWIGPYTHONARGS) -module audio_jack -o audio_jack.cc $<
+
+
+noinst_PYTHON =                        \
+       qa_jack.py                      
+
+MOSTLYCLEANFILES = \
+       $(BUILT_SOURCES) *~ *.pyc
+
+# Don't distribute output of swig
+dist-hook:
+       @for file in $(BUILT_SOURCES); do echo $(RM) $(distdir)/$$file; done
+       @for file in $(BUILT_SOURCES); do $(RM) $(distdir)/$$file; done
diff --git a/gr-audio-jack/src/audio_jack.i b/gr-audio-jack/src/audio_jack.i
new file mode 100644 (file)
index 0000000..1a21066
--- /dev/null
@@ -0,0 +1,80 @@
+/* -*- 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 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.
+ */
+
+%feature("autodoc","1");
+
+%include "exception.i"
+%import "gnuradio.i"                           // the common stuff
+
+%{
+#include "gnuradio_swig_bug_workaround.h"      // mandatory bug fix
+#include "audio_jack_sink.h"
+#include "audio_jack_source.h"
+#include <stdexcept>
+%}
+
+// ----------------------------------------------------------------
+
+GR_SWIG_BLOCK_MAGIC(audio_jack,source)
+
+audio_jack_source_sptr
+audio_jack_make_source (int sampling_rate,
+                       const std::string dev = "",
+                       bool ok_to_block = true
+                       ) throw (std::runtime_error);
+
+class audio_jack_source : public gr_sync_block {
+
+ protected:
+  audio_jack_source (int sampling_rate,
+                    const std::string device_name,
+                    bool ok_to_block
+                    ) throw (std::runtime_error);
+
+ public:
+  ~audio_jack_source ();
+
+  bool start();
+  bool stop();
+};
+
+// ----------------------------------------------------------------
+
+GR_SWIG_BLOCK_MAGIC(audio_jack,sink)
+
+audio_jack_sink_sptr
+audio_jack_make_sink (int sampling_rate,
+                     const std::string dev = "",
+                     bool ok_to_block = true
+                     ) throw (std::runtime_error);
+
+class audio_jack_sink : public gr_sync_block {
+
+ protected:
+  audio_jack_sink (int sampling_rate,
+                  const std::string device_name,
+                  bool ok_to_block
+                  ) throw (std::runtime_error);
+
+ public:
+  ~audio_jack_sink ();
+};
diff --git a/gr-audio-jack/src/audio_jack_sink.cc b/gr-audio-jack/src/audio_jack_sink.cc
new file mode 100644 (file)
index 0000000..b5a8373
--- /dev/null
@@ -0,0 +1,231 @@
+/* -*- c++ -*- */
+/*
+ * 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <audio_jack_sink.h>
+#include <gr_io_signature.h>
+#include <gr_prefs.h>
+#include <stdio.h>
+#include <iostream>
+#include <stdexcept>
+#include <gri_jack.h>
+
+#ifndef NO_PTHREAD
+#include <pthread.h>
+#endif
+
+typedef jack_default_audio_sample_t sample_t;
+
+
+// Number of jack buffers in the ringbuffer
+// TODO: make it to match at least the quantity of items passed by work()
+static const unsigned int N_BUFFERS = 16;
+
+static std::string 
+default_device_name ()
+{
+  return gr_prefs::singleton()->get_string("audio_jack", "default_output_device", "gr_sink");
+}
+
+int
+jack_sink_process (jack_nframes_t nframes, void *arg)
+{
+  audio_jack_sink *self = (audio_jack_sink *)arg;
+  unsigned int read_size = nframes*sizeof(sample_t);
+
+  if (jack_ringbuffer_read_space (self->d_ringbuffer) < read_size) {
+    self->d_nunderuns++;
+    // FIXME: move this fputs out, we shouldn't use blocking calls in process()
+    fputs ("jU", stderr);
+    return 0;
+  }
+
+  char *buffer = (char *) jack_port_get_buffer (self->d_jack_output_port, nframes);
+
+  jack_ringbuffer_read (self->d_ringbuffer, buffer, read_size);
+
+#ifndef NO_PTHREAD
+  // Tell the sink thread there is room in the ringbuffer.
+  // If it is already running, the lock will not be available.
+  // We can't wait here in the process() thread, but we don't
+  // need to signal in that case, because the sink thread will 
+  // check for room availability.
+
+  if (pthread_mutex_trylock (&self->d_jack_process_lock) == 0) {
+    pthread_cond_signal (&self->d_ringbuffer_ready);
+    pthread_mutex_unlock (&self->d_jack_process_lock);
+  }
+#endif
+
+  return 0;
+}
+
+// ----------------------------------------------------------------
+
+audio_jack_sink_sptr
+audio_jack_make_sink(int sampling_rate, const std::string dev, bool ok_to_block)
+{
+  return audio_jack_sink_sptr (new audio_jack_sink (sampling_rate, dev,
+                                                   ok_to_block));
+}
+
+audio_jack_sink::audio_jack_sink (int sampling_rate,
+                                 const std::string device_name,
+                                 bool ok_to_block)
+  : gr_sync_block ("audio_jack_sink",
+                  gr_make_io_signature (0, 0, 0),
+                  gr_make_io_signature (0, 0, 0)),
+    d_sampling_rate (sampling_rate),
+    d_device_name (device_name.empty() ? default_device_name() : device_name),
+    d_ok_to_block (ok_to_block),
+    d_jack_client (0),
+    d_ringbuffer (0),
+    d_nunderuns (0)
+{
+#ifndef NO_PTHREAD
+    pthread_cond_init(&d_ringbuffer_ready, NULL);;
+    pthread_mutex_init(&d_jack_process_lock, NULL);
+#endif
+
+  // try to become a client of the JACK server
+  if ((d_jack_client = jack_client_new (d_device_name.c_str ())) == 0) {
+    fprintf (stderr, "audio_jack_sink[%s]: jack server not running?\n",
+            d_device_name.c_str());
+    throw std::runtime_error ("audio_jack_sink");
+  }
+
+  // tell the JACK server to call `jack_sink_process()' whenever
+  // there is work to be done.
+  jack_set_process_callback (d_jack_client, &jack_sink_process, (void*)this);
+
+  // tell the JACK server to call `jack_shutdown()' if
+  // it ever shuts down, either entirely, or if it
+  // just decides to stop calling us.
+
+  //jack_on_shutdown (d_jack_client, &jack_shutdown, (void*)this);
+  d_jack_output_port = 
+    jack_port_register (d_jack_client, "out", 
+                       JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
+
+
+  d_jack_buffer_size = jack_get_buffer_size (d_jack_client);
+
+  set_output_multiple (d_jack_buffer_size);
+
+  d_ringbuffer =
+    jack_ringbuffer_create (N_BUFFERS*d_jack_buffer_size*sizeof(sample_t));
+  if (d_ringbuffer == NULL)
+    bail ("jack_ringbuffer_create failed", 0);
+
+  assert(sizeof(float)==sizeof(sample_t));
+  set_input_signature (gr_make_io_signature (1, 1, sizeof (sample_t)));
+
+
+  jack_nframes_t sample_rate = jack_get_sample_rate (d_jack_client);
+
+  if ((jack_nframes_t)sampling_rate != sample_rate){
+    fprintf (stderr, "audio_jack_sink[%s]: unable to support sampling rate %d\n",
+            d_device_name.c_str (), sampling_rate);
+    fprintf (stderr, "  card requested %d instead.\n", sample_rate);
+  }
+}
+
+
+bool
+audio_jack_sink::check_topology (int ninputs, int noutputs)
+{
+  if (ninputs != 1)
+    return false;
+
+  // tell the JACK server that we are ready to roll 
+  if (jack_activate (d_jack_client))
+    throw std::runtime_error ("audio_jack_sink");
+
+  return true;
+}
+
+audio_jack_sink::~audio_jack_sink ()
+{
+  jack_client_close (d_jack_client);
+  jack_ringbuffer_free (d_ringbuffer);
+}
+
+int
+audio_jack_sink::work (int noutput_items,
+                      gr_vector_const_void_star &input_items,
+                      gr_vector_void_star &output_items)
+{
+  // write_size and work_size are in bytes
+  int work_size = noutput_items*sizeof(sample_t);
+  unsigned int write_size;
+
+  while (work_size > 0) {
+    unsigned int write_space;  // bytes
+
+#ifdef NO_PTHREAD
+    while ((write_space=jack_ringbuffer_write_space (d_ringbuffer)) < 
+          d_jack_buffer_size*sizeof(sample_t)) {
+      usleep(1000000*((d_jack_buffer_size-write_space/sizeof(sample_t))/d_sampling_rate));
+    }
+#else
+    // JACK actually requires POSIX
+
+    pthread_mutex_lock (&d_jack_process_lock);
+    while ((write_space=jack_ringbuffer_write_space (d_ringbuffer)) < 
+          d_jack_buffer_size*sizeof(sample_t)) {
+
+      // wait until jack_sink_process() signals more room
+      pthread_cond_wait (&d_ringbuffer_ready, &d_jack_process_lock);
+    }
+    pthread_mutex_unlock (&d_jack_process_lock);
+#endif
+
+    write_space -= write_space%(d_jack_buffer_size*sizeof(sample_t));
+    write_size = std::min(write_space, (unsigned int)work_size);
+
+    if (jack_ringbuffer_write (d_ringbuffer, (char *) input_items[0],
+                              write_size) < write_size) {
+      bail ("jack_ringbuffer_write failed", 0);
+    }
+    work_size -= write_size;
+  }
+
+  return noutput_items;
+}
+
+void
+audio_jack_sink::output_error_msg (const char *msg, int err)
+{
+  fprintf (stderr, "audio_jack_sink[%s]: %s: %d\n",
+          d_device_name.c_str (), msg,  err);
+}
+
+void
+audio_jack_sink::bail (const char *msg, int err) throw (std::runtime_error)
+{
+  output_error_msg (msg, err);
+  throw std::runtime_error ("audio_jack_sink");
+}
diff --git a/gr-audio-jack/src/audio_jack_sink.h b/gr-audio-jack/src/audio_jack_sink.h
new file mode 100644 (file)
index 0000000..00b9499
--- /dev/null
@@ -0,0 +1,97 @@
+/* -*- c++ -*- */
+/*
+ * 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 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.
+ */
+#ifndef INCLUDED_AUDIO_JACK_SINK_H
+#define INCLUDED_AUDIO_JACK_SINK_H
+
+#include <gr_sync_block.h>
+#include <string>
+#include <jack/jack.h>
+#include <jack/ringbuffer.h>
+#include <stdexcept>
+
+class audio_jack_sink;
+typedef boost::shared_ptr<audio_jack_sink> audio_jack_sink_sptr;
+
+/*!
+ * \brief make an JACK audio sink.
+ *
+ * \param sampling_rate        sampling rate in Hz
+ * \param dev JACK device name, e.g., "gr_sink"
+ * \param ok_to_block
+ */
+audio_jack_sink_sptr
+audio_jack_make_sink (int sampling_rate,
+                     const std::string dev = "",
+                     bool ok_to_block = true);
+
+int jack_sink_process (jack_nframes_t nframes, void *arg);
+
+/*!
+ * \brief audio sink using JACK
+ *
+ * The sink has one input stream of floats.
+ *
+ * Input samples must be in the range [-1,1].
+ */
+class audio_jack_sink : public gr_sync_block {
+  friend audio_jack_sink_sptr
+  audio_jack_make_sink (int sampling_rate, const std::string device_name, bool ok_to_block);
+
+  friend int jack_sink_process (jack_nframes_t nframes, void *arg);
+
+  // typedef for pointer to class work method
+  typedef int (audio_jack_sink::*work_t)(int noutput_items,
+                                        gr_vector_const_void_star &input_items,
+                                        gr_vector_void_star &output_items);
+
+  unsigned int         d_sampling_rate;
+  std::string          d_device_name;
+  bool                 d_ok_to_block;
+
+  jack_client_t                *d_jack_client;
+  jack_port_t          *d_jack_output_port;
+  jack_ringbuffer_t    *d_ringbuffer;
+  jack_nframes_t       d_jack_buffer_size;
+  pthread_cond_t       d_ringbuffer_ready;
+  pthread_mutex_t      d_jack_process_lock;
+
+  // 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:
+  audio_jack_sink (int sampling_rate, const std::string device_name, bool ok_to_block);
+
+ public:
+  ~audio_jack_sink ();
+  
+  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_AUDIO_JACK_SINK_H */
diff --git a/gr-audio-jack/src/audio_jack_source.cc b/gr-audio-jack/src/audio_jack_source.cc
new file mode 100644 (file)
index 0000000..baa7db1
--- /dev/null
@@ -0,0 +1,231 @@
+/* -*- c++ -*- */
+/*
+ * 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <audio_jack_source.h>
+#include <gr_io_signature.h>
+#include <gr_prefs.h>
+#include <stdio.h>
+#include <iostream>
+#include <stdexcept>
+#include <gri_jack.h>
+
+#ifndef NO_PTHREAD
+#include <pthread.h>
+#endif
+
+typedef jack_default_audio_sample_t sample_t;
+
+
+// Number of jack buffers in the ringbuffer
+// TODO: make it to match at least the quantity of items passed to work()
+static const unsigned int N_BUFFERS = 16;
+
+static std::string 
+default_device_name ()
+{
+  return gr_prefs::singleton()->get_string("audio_jack", "default_input_device", "gr_source");
+}
+
+
+int
+jack_source_process (jack_nframes_t nframes, void *arg)
+{
+  audio_jack_source *self = (audio_jack_source *)arg;
+  unsigned int write_size = nframes*sizeof(sample_t);
+
+  if (jack_ringbuffer_write_space (self->d_ringbuffer) < write_size) {
+    self->d_noverruns++;
+    // FIXME: move this fputs out, we shouldn't use blocking calls in process()
+    fputs ("jO", stderr);
+    return 0;
+  }
+
+  char *buffer = (char *) jack_port_get_buffer (self->d_jack_input_port, nframes);
+
+  jack_ringbuffer_write (self->d_ringbuffer, buffer, write_size);
+
+#ifndef NO_PTHREAD
+  // Tell the source thread there is data in the ringbuffer.
+  // If it is already running, the lock will not be available.
+  // We can't wait here in the process() thread, but we don't
+  // need to signal in that case, because the source thread will 
+  // check for data availability.
+
+  if (pthread_mutex_trylock (&self->d_jack_process_lock) == 0) {
+    pthread_cond_signal (&self->d_ringbuffer_ready);
+    pthread_mutex_unlock (&self->d_jack_process_lock);
+  }
+#endif
+
+  return 0;
+}
+
+// ----------------------------------------------------------------
+
+audio_jack_source_sptr
+audio_jack_make_source (int sampling_rate, const std::string dev, bool ok_to_block)
+{
+  return audio_jack_source_sptr (new audio_jack_source (sampling_rate, dev, ok_to_block));
+}
+
+audio_jack_source::audio_jack_source (int sampling_rate,
+                                     const std::string device_name,
+                                     bool ok_to_block)
+  : gr_sync_block ("audio_jack_source",
+                  gr_make_io_signature (0, 0, 0),
+                  gr_make_io_signature (0, 0, 0)),
+    d_sampling_rate (sampling_rate),
+    d_device_name (device_name.empty() ? default_device_name() : device_name),
+    d_ok_to_block(ok_to_block),
+    d_jack_client (0),
+    d_ringbuffer (0),
+    d_noverruns (0)
+{
+#ifndef NO_PTHREAD
+    pthread_cond_init(&d_ringbuffer_ready, NULL);;
+    pthread_mutex_init(&d_jack_process_lock, NULL);
+#endif
+
+  // try to become a client of the JACK server
+  if ((d_jack_client = jack_client_new (d_device_name.c_str ())) == 0) {
+    fprintf (stderr, "audio_jack_source[%s]: jack server not running?\n",
+            d_device_name.c_str());
+    throw std::runtime_error ("audio_jack_source");
+  }
+
+  // tell the JACK server to call `jack_source_process()' whenever
+  // there is work to be done.
+  jack_set_process_callback (d_jack_client, &jack_source_process, (void*)this);
+
+  // tell the JACK server to call `jack_shutdown()' if
+  // it ever shuts down, either entirely, or if it
+  // just decides to stop calling us.
+
+  //jack_on_shutdown (d_jack_client, &jack_shutdown, (void*)this);
+  d_jack_input_port = jack_port_register (d_jack_client, "in", 
+                                         JACK_DEFAULT_AUDIO_TYPE,
+                                         JackPortIsInput, 0);
+
+
+  d_jack_buffer_size = jack_get_buffer_size (d_jack_client);
+
+  set_output_multiple (d_jack_buffer_size);
+
+  d_ringbuffer = jack_ringbuffer_create (N_BUFFERS*d_jack_buffer_size*sizeof(sample_t));
+  if (d_ringbuffer == NULL)
+    bail ("jack_ringbuffer_create failed", 0);
+
+  assert(sizeof(float)==sizeof(sample_t));
+  set_output_signature (gr_make_io_signature (1, 1, sizeof (sample_t)));
+
+
+  jack_nframes_t sample_rate = jack_get_sample_rate (d_jack_client);
+
+  if ((jack_nframes_t)sampling_rate != sample_rate){
+    fprintf (stderr, "audio_jack_source[%s]: unable to support sampling rate %d\n",
+            d_device_name.c_str (), sampling_rate);
+    fprintf (stderr, "  card requested %d instead.\n", sample_rate);
+  }
+}
+
+
+bool
+audio_jack_source::check_topology (int ninputs, int noutputs)
+{
+  // tell the JACK server that we are ready to roll 
+  if (jack_activate (d_jack_client))
+    throw std::runtime_error ("audio_jack_source");
+
+  return true;
+}
+
+audio_jack_source::~audio_jack_source ()
+{
+  jack_client_close (d_jack_client);
+  jack_ringbuffer_free (d_ringbuffer);
+}
+
+int
+audio_jack_source::work (int noutput_items,
+                        gr_vector_const_void_star &input_items,
+                        gr_vector_void_star &output_items)
+{
+  // read_size and work_size are in bytes
+  unsigned int read_size;
+
+  // Minimize latency
+  noutput_items = std::min (noutput_items, (int)d_jack_buffer_size);
+
+  int work_size = noutput_items*sizeof(sample_t);
+
+  while (work_size > 0) {
+    unsigned int read_space;   // bytes
+
+#ifdef NO_PTHREAD
+    while ((read_space=jack_ringbuffer_read_space (d_ringbuffer)) < 
+          d_jack_buffer_size*sizeof(sample_t)) {
+      usleep(1000000*((d_jack_buffer_size-read_space/sizeof(sample_t))/d_sampling_rate));
+    }
+#else
+    // JACK actually requires POSIX
+
+    pthread_mutex_lock (&d_jack_process_lock);
+    while ((read_space=jack_ringbuffer_read_space (d_ringbuffer)) < 
+                   d_jack_buffer_size*sizeof(sample_t)) {
+
+      // wait until jack_source_process() signals more data
+      pthread_cond_wait (&d_ringbuffer_ready, &d_jack_process_lock);
+    }
+    pthread_mutex_unlock (&d_jack_process_lock);
+#endif
+
+    read_space -= read_space%(d_jack_buffer_size*sizeof(sample_t));
+    read_size = std::min(read_space, (unsigned int)work_size);
+
+    if (jack_ringbuffer_read (d_ringbuffer, (char *) output_items[0],
+                             read_size) < read_size) {
+      bail ("jack_ringbuffer_read failed", 0);
+    }
+    work_size -= read_size;
+  }
+
+  return noutput_items;
+}
+
+void
+audio_jack_source::output_error_msg (const char *msg, int err)
+{
+  fprintf (stderr, "audio_jack_source[%s]: %s: %d\n",
+          d_device_name.c_str (), msg,  err);
+}
+
+void
+audio_jack_source::bail (const char *msg, int err) throw (std::runtime_error)
+{
+  output_error_msg (msg, err);
+  throw std::runtime_error ("audio_jack_source");
+}
diff --git a/gr-audio-jack/src/audio_jack_source.h b/gr-audio-jack/src/audio_jack_source.h
new file mode 100644 (file)
index 0000000..4d64714
--- /dev/null
@@ -0,0 +1,97 @@
+/* -*- c++ -*- */
+/*
+ * 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 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.
+ */
+#ifndef INCLUDED_AUDIO_JACK_SOURCE_H
+#define INCLUDED_AUDIO_JACK_SOURCE_H
+
+#include <gr_sync_block.h>
+#include <string>
+#include <jack/jack.h>
+#include <jack/ringbuffer.h>
+#include <stdexcept>
+
+class audio_jack_source;
+typedef boost::shared_ptr<audio_jack_source> audio_jack_source_sptr;
+
+/*!
+ * \brief make a JACK audio source.
+ *
+ * \param sampling_rate        sampling rate in Hz
+ * \param dev JACK device name, e.g., "gr_source"
+ * \param ok_to_block
+ */
+audio_jack_source_sptr
+audio_jack_make_source (int sampling_rate,
+                       const std::string dev = "",
+                       bool ok_to_block = true);
+
+int jack_source_process (jack_nframes_t nframes, void *arg);
+
+/*!
+ * \brief audio source using JACK
+ *
+ * The source has one input stream of floats.
+ *
+ * Output samples will be in the range [-1,1].
+ */
+class audio_jack_source : public gr_sync_block {
+  friend audio_jack_source_sptr
+  audio_jack_make_source (int sampling_rate, const std::string device_name, bool ok_to_block);
+
+  friend int jack_source_process (jack_nframes_t nframes, void *arg);
+
+  // typedef for pointer to class work method
+  typedef int (audio_jack_source::*work_t)(int noutput_items,
+                                          gr_vector_const_void_star &input_items,
+                                          gr_vector_void_star &output_items);
+
+  unsigned int         d_sampling_rate;
+  std::string          d_device_name;
+  bool                 d_ok_to_block;
+
+  jack_client_t                *d_jack_client;
+  jack_port_t          *d_jack_input_port;
+  jack_ringbuffer_t    *d_ringbuffer;
+  jack_nframes_t       d_jack_buffer_size;
+  pthread_cond_t       d_ringbuffer_ready;
+  pthread_mutex_t      d_jack_process_lock;
+
+  // 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:
+  audio_jack_source (int sampling_rate, const std::string device_name, bool ok_to_block);
+
+ public:
+  ~audio_jack_source ();
+  
+  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_AUDIO_JACK_SOURCE_H */
diff --git a/gr-audio-jack/src/gri_jack.cc b/gr-audio-jack/src/gri_jack.cc
new file mode 100644 (file)
index 0000000..9ae80d0
--- /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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gri_jack.h>
+#include <algorithm>
+
+
diff --git a/gr-audio-jack/src/gri_jack.h b/gr-audio-jack/src/gri_jack.h
new file mode 100644 (file)
index 0000000..564672b
--- /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 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.
+ */
+
+#ifndef INCLUDED_GRI_JACK_H
+#define INCLUDED_GRI_JACK_H
+
+#include <stdio.h>
+
+#endif /* INCLUDED_GRI_JACK_H */
diff --git a/gr-audio-jack/src/qa_jack.py b/gr-audio-jack/src/qa_jack.py
new file mode 100755 (executable)
index 0000000..58f860c
--- /dev/null
@@ -0,0 +1,40 @@
+#!/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 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.
+# 
+
+from gnuradio import gr, gr_unittest
+import audio_jack
+
+class qa_jack (gr_unittest.TestCase):
+
+    def setUp (self):
+        self.fg = gr.flow_graph ()
+
+    def tearDown (self):
+        self.fg = None
+
+    def test_000_nop (self):
+        """Just see if we can import the module...
+        They may not have JACK library, etc.  Don't try to run anything"""
+        pass
+    
+if __name__ == '__main__':
+    gr_unittest.main ()
diff --git a/gr-audio-jack/src/run_tests.in b/gr-audio-jack/src/run_tests.in
new file mode 100644 (file)
index 0000000..3e58989
--- /dev/null
@@ -0,0 +1,47 @@
+#!/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@/gr-audio-jack/src
+# Where to look in the src tree for swig generated python code
+libsrc=@abs_top_srcdir@/gr-audio-jack/src
+# Where to look in the src tree for hand written python code
+py=@abs_top_srcdir@/gr-audio-jack/src
+
+# Where to look for GNU Radio python modules in current build tree
+# FIXME this is wrong on a distcheck.  We really need to ask gnuradio-core
+# where it put its python files.
+grpythonbld=@abs_top_builddir@/gnuradio-core/src/python/:@abs_top_builddir@/gnuradio-core/src/lib/swig/:@abs_top_builddir@/gnuradio-core/src/lib/swig/.libs
+
+PYTHONPATH="$grpythonbld:$libbld:$libbld/.libs:$libsrc:$py:$PYTHONPATH"
+export PYTHONPATH
+
+#
+# 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-audio-oss/AUTHORS b/gr-audio-oss/AUTHORS
new file mode 100644 (file)
index 0000000..ee4560a
--- /dev/null
@@ -0,0 +1 @@
+Eric Blossom <eb@comsec.com>
diff --git a/gr-audio-oss/ChangeLog b/gr-audio-oss/ChangeLog
new file mode 100644 (file)
index 0000000..ab917e5
--- /dev/null
@@ -0,0 +1,91 @@
+2006-03-30  Eric Blossom  <eb@comsec.com>
+
+       * gr-audio-oss.conf: new config file.
+       * src/audio_oss_sink.{h,cc,i}, src/audio_oss_source.{h,cc,i}:
+       added ok_to_block constructor arg (currrently ignored), and now query
+       preferences for latency and default input and output devices.
+
+2005-07-02  Eric Blossom  <eb@comsec.com>
+
+       * config/gr_no_undefined.m4, config/gr_x86_64.m4: new, x86_64 support.
+       * config/gr_python.m4: backed out search for libpython, making
+       x86_64 work and breaking Cygwin/MinGW.
+       * configure.ac, src/Makefile.am: mods for x86_64, $(NO_UNDEFINED)
+
+2005-05-09  Stephane Fillod  <f8cfe@free.fr>
+
+        * config/gr_sysv_shm.m4: SysV shared memory not mandatory
+       * config/gr_pwin32.m4, config/gr_python.m4, config/lf_cxx.m4:
+         fixes for Cygwin, MinGW
+
+2005-03-29  Eric Blossom  <eb@comsec.com>
+
+       * src/audio_oss.i, src/audio_oss_sink.{h,cc},
+       src/audio_oss_source.{h,cc}: map zero length device name to default.
+
+2005-02-06  Eric Blossom  <eb@comsec.com>
+
+       * configure.ac: upped rev to 0.5 for release
+       * src/Makefile.am: backed out dependency on libpython
+
+2005-01-29  Eric Blossom  <eb@comsec.com>
+
+       * src/Makefile.am: cleanup for SWIG 1.3.24
+
+2005-01-28  Stephane Fillod <f8cfe@free.fr>
+
+       * src/Makefile.am: fixes for MinGW.
+
+2004-11-04  Eric Blossom  <eb@comsec.com>
+
+       * configure.ac: upped rev to 0.3cvs
+
+       * configure.ac: added AC_HAVE_LIBRARY(ossaudio) check for NetBSD.
+       upped rev to 0.3.  Made release.
+
+2004-10-13  Eric Blossom  <eb@comsec.com>
+
+       * configure.ac: upped rev to 0.2cvs
+
+2004-10-11  Eric Blossom  <eb@comsec.com>
+
+       * configure.ac: bumped rev to 0.2, make release
+       * Makefile.am (EXTRA_DIST): added config.h.in
+
+2004-09-23  Eric Blossom  <eb@comsec.com>
+
+       * config/usrp_fusb_tech.m4, config/bnv_have_qt.m4, config/cppunit.m4,
+       config/gr_check_mc4020.m4, config/gr_check_usrp.m4, config/gr_doxygen.m4,
+       config/gr_gprof.m4, config/gr_scripting.m4, config/gr_set_md_cpu.m4,
+       config/pkg.m4, config/usrp_fusb_tech.m4: added additional quoting
+       to first arg of AC_DEFUN to silence automake warning.
+
+2004-07-12  Eric Blossom  <eb@comsec.com>
+
+       * configure.ac: upped rev to 0.1cvs
+
+2004-07-09  Eric Blossom  <eb@comsec.com>
+
+       * src/audio_oss_source.{h,cc}: new.
+       * src/audio_oss_sink.{h,cc}: new.
+       
+#
+# Copyright 2004,2005,2006 Free Software Foundation, Inc.
+# 
+# This file is part of GNU Radio
+# 
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 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.
+# 
diff --git a/gr-audio-oss/Makefile.am b/gr-audio-oss/Makefile.am
new file mode 100644 (file)
index 0000000..77595d9
--- /dev/null
@@ -0,0 +1,30 @@
+#
+# 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 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.
+# 
+
+include $(top_srcdir)/Makefile.common
+
+EXTRA_DIST = \
+       gr-audio-oss.conf
+
+SUBDIRS = src
+
+etcdir = $(sysconfdir)/gnuradio/conf.d
+etc_DATA = gr-audio-oss.conf
diff --git a/gr-audio-oss/gr-audio-oss.conf b/gr-audio-oss/gr-audio-oss.conf
new file mode 100644 (file)
index 0000000..6ea14d6
--- /dev/null
@@ -0,0 +1,9 @@
+# This file contains system wide configuration data for GNU Radio.
+# You may override any setting on a per-user basis by editing
+# ~/.gnuradio/config.conf
+
+[audio_oss]
+
+default_input_device = /dev/dsp
+default_output_device = /dev/dsp
+latency = 0.005                      # in seconds
diff --git a/gr-audio-oss/src/Makefile.am b/gr-audio-oss/src/Makefile.am
new file mode 100644 (file)
index 0000000..656d665
--- /dev/null
@@ -0,0 +1,90 @@
+#
+# Copyright 2004,2005,2006 Free Software Foundation, Inc.
+# 
+# This file is part of GNU Radio
+# 
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 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.
+# 
+
+include $(top_srcdir)/Makefile.common
+
+LIBS += $(GNURADIO_CORE_LIBS)
+
+# Install this stuff so that it ends up as the gnuradio.audio_oss module
+# This usually ends up at:
+#   ${prefix}/lib/python${python_version}/site-packages/gnuradio
+
+ourpythondir = $(grpythondir)
+ourlibdir    = $(grpyexecdir)
+
+EXTRA_DIST = run_tests.in
+TESTS = run_tests
+
+LOCAL_IFILES =                                 \
+       audio_oss.i                             
+
+NON_LOCAL_IFILES =                     \
+       $(top_srcdir)/gnuradio-core/src/lib/swig/gnuradio.i
+
+ALL_IFILES =                           \
+       $(LOCAL_IFILES)                 \
+       $(NON_LOCAL_IFILES)             
+
+BUILT_SOURCES =                        \
+       audio_oss.cc                    \
+       audio_oss.py                    
+
+ourpython_PYTHON =                     \
+       audio_oss.py
+
+INCLUDES = $(STD_DEFINES_AND_INCLUDES) $(PYTHON_CPPFLAGS)
+
+SWIGPYTHONARGS = $(SWIGPYTHONFLAGS) $(STD_DEFINES_AND_INCLUDES)
+
+ourlib_LTLIBRARIES = _audio_oss.la
+
+_audio_oss_la_SOURCES =                \
+       audio_oss.cc                    \
+       audio_oss_sink.cc               \
+       audio_oss_source.cc                     
+
+
+grinclude_HEADERS =                    \
+       audio_oss_sink.h                \
+       audio_oss_source.h                      
+
+swiginclude_HEADERS =                  \
+       $(LOCAL_IFILES)
+
+_audio_oss_la_LIBADD =                         \
+       $(PYTHON_LDFLAGS)               \
+       -lstdc++                                
+
+_audio_oss_la_LDFLAGS = $(NO_UNDEFINED) -module -avoid-version
+
+audio_oss.cc audio_oss.py: audio_oss.i $(NON_LOCAL_IFILES)
+       $(SWIG) $(SWIGPYTHONARGS) -module audio_oss -o audio_oss.cc $<
+
+# Don't distribute output of swig
+dist-hook:
+       @for file in $(BUILT_SOURCES); do echo $(RM) $(distdir)/$$file; done
+       @for file in $(BUILT_SOURCES); do $(RM) $(distdir)/$$file; done
+
+noinst_PYTHON = qa_oss.py
+
+MOSTLYCLEANFILES = \
+       $(BUILT_SOURCES) *~ *.pyc
+
diff --git a/gr-audio-oss/src/audio_oss.i b/gr-audio-oss/src/audio_oss.i
new file mode 100644 (file)
index 0000000..75bb31e
--- /dev/null
@@ -0,0 +1,70 @@
+/* -*- 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 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.
+ */
+
+%feature("autodoc","1");
+
+%include "exception.i"
+%import "gnuradio.i"                           // the common stuff
+
+%{
+#include "gnuradio_swig_bug_workaround.h"      // mandatory bug fix
+#include "audio_oss_sink.h"
+#include "audio_oss_source.h"
+#include <stdexcept>
+%}
+
+// ----------------------------------------------------------------
+
+GR_SWIG_BLOCK_MAGIC(audio_oss,sink)
+
+audio_oss_sink_sptr
+audio_oss_make_sink (int sampling_rate,
+                    const std::string dev = "",
+                    bool ok_to_block = true
+                    ) throw (std::runtime_error);
+
+
+class audio_oss_sink : public gr_sync_block {
+ protected:
+  audio_oss_sink (int sampling_rate, const std::string device_name = "", bool ok_to_block = true);
+
+ public:
+  ~audio_oss_sink ();
+};
+
+// ----------------------------------------------------------------
+
+GR_SWIG_BLOCK_MAGIC(audio_oss,source)
+
+audio_oss_source_sptr
+audio_oss_make_source (int sampling_rate,
+                      const std::string dev = "",
+                      bool ok_to_block = true
+                      ) throw (std::runtime_error);
+
+class audio_oss_source : public gr_sync_block {
+ protected:
+  audio_oss_source (int sampling_rate, const std::string device_name = "", bool ok_to_block = true);
+
+ public:
+  ~audio_oss_source ();
+};
diff --git a/gr-audio-oss/src/audio_oss_sink.cc b/gr-audio-oss/src/audio_oss_sink.cc
new file mode 100644 (file)
index 0000000..eff3de4
--- /dev/null
@@ -0,0 +1,161 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <audio_oss_sink.h>
+#include <gr_io_signature.h>
+#include <gr_prefs.h>
+#include <sys/soundcard.h>
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <iostream>
+#include <stdexcept>
+
+
+static std::string
+default_device_name ()
+{
+  return gr_prefs::singleton()->get_string("audio_oss", "default_output_device", "/dev/dsp");
+}
+
+audio_oss_sink_sptr
+audio_oss_make_sink (int sampling_rate, const std::string dev, bool ok_to_block)
+{
+  return audio_oss_sink_sptr (new audio_oss_sink (sampling_rate, dev, ok_to_block));
+}
+
+audio_oss_sink::audio_oss_sink (int sampling_rate,
+                               const std::string device_name,
+                               bool ok_to_block)
+  : gr_sync_block ("audio_oss_sink",
+                  gr_make_io_signature (1, 2, sizeof (float)),
+                  gr_make_io_signature (0, 0, 0)),
+    d_sampling_rate (sampling_rate),
+    d_device_name (device_name.empty() ? default_device_name() : device_name),
+    d_fd (-1), d_buffer (0), d_chunk_size (0)
+{
+  if ((d_fd = open (d_device_name.c_str (), O_WRONLY)) < 0){
+    fprintf (stderr, "audio_oss_sink: ");
+    perror (d_device_name.c_str ());
+    throw std::runtime_error ("audio_oss_sink");
+  }
+
+  double CHUNK_TIME = 
+    std::max(0.001, gr_prefs::singleton()->get_double("audio_oss", "latency", 0.005));
+
+  d_chunk_size = (int) (d_sampling_rate * CHUNK_TIME);
+  set_output_multiple (d_chunk_size);
+
+  d_buffer = new short [d_chunk_size * 2];
+
+  int format = AFMT_S16_NE;
+  int orig_format = format;
+  if (ioctl (d_fd, SNDCTL_DSP_SETFMT, &format) < 0){
+    std::cerr << "audio_oss_sink: " << d_device_name << " ioctl failed\n";
+    perror (d_device_name.c_str ());
+    throw std::runtime_error ("audio_oss_sink");
+  }
+
+  if (format != orig_format){
+    fprintf (stderr, "audio_oss_sink: unable to support format %d\n", orig_format);
+    fprintf (stderr, "  card requested %d instead.\n", format);
+  }
+
+  // set to stereo no matter what.  Some hardware only does stereo
+  int channels = 2;
+  if (ioctl (d_fd, SNDCTL_DSP_CHANNELS, &channels) < 0 || channels != 2){
+    perror ("audio_oss_sink: could not set STEREO mode");
+    throw std::runtime_error ("audio_oss_sink");
+  }
+
+  // set sampling freq
+  int sf = sampling_rate;
+  if (ioctl (d_fd, SNDCTL_DSP_SPEED, &sf) < 0){
+    std::cerr << "audio_oss_sink: "
+             << d_device_name << ": invalid sampling_rate "
+             << sampling_rate << "\n";
+    sampling_rate = 8000;
+    if (ioctl (d_fd, SNDCTL_DSP_SPEED, &sf) < 0){
+      std::cerr << "audio_oss_sink: failed to set sampling_rate to 8000\n";
+      throw std::runtime_error ("audio_oss_sink");
+    }
+  }
+}
+
+audio_oss_sink::~audio_oss_sink ()
+{
+  close (d_fd);
+  delete [] d_buffer;
+}
+
+
+int
+audio_oss_sink::work (int noutput_items,
+                     gr_vector_const_void_star &input_items,
+                     gr_vector_void_star &output_items)
+{
+  const float  *f0, *f1;
+  
+  switch (input_items.size ()){
+
+  case 1:              // mono input
+
+    f0 = (const float *) input_items[0];
+
+    for (int i = 0; i < noutput_items; i += d_chunk_size){
+      for (int j = 0; j < d_chunk_size; j++){
+       d_buffer[2*j+0] = (short) (f0[j] * 32767);
+       d_buffer[2*j+1] = (short) (f0[j] * 32767);
+      }
+      f0 += d_chunk_size;
+      if (write (d_fd, d_buffer, 2 * d_chunk_size * sizeof (short)) < 0)
+       perror ("audio_oss_sink: write");
+    }
+    break;
+    
+  case 2:              // stereo input
+
+    f0 = (const float *) input_items[0];
+    f1 = (const float *) input_items[1];
+
+    for (int i = 0; i < noutput_items; i += d_chunk_size){
+      for (int j = 0; j < d_chunk_size; j++){
+       d_buffer[2*j+0] = (short) (f0[j] * 32767);
+       d_buffer[2*j+1] = (short) (f1[j] * 32767);
+      }
+      f0 += d_chunk_size;
+      f1 += d_chunk_size;
+      if (write (d_fd, d_buffer, 2 * d_chunk_size * sizeof (short)) < 0)
+       perror ("audio_oss_sink: write");
+    }
+    break;
+  }
+
+  return noutput_items;
+}
diff --git a/gr-audio-oss/src/audio_oss_sink.h b/gr-audio-oss/src/audio_oss_sink.h
new file mode 100644 (file)
index 0000000..940ce46
--- /dev/null
@@ -0,0 +1,66 @@
+/* -*- 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 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.
+ */
+
+#ifndef INCLUDED_AUDIO_OSS_SINK_H
+#define INCLUDED_AUDIO_OSS_SINK_H
+
+#include <gr_sync_block.h>
+#include <string>
+
+
+class audio_oss_sink;
+typedef boost::shared_ptr<audio_oss_sink> audio_oss_sink_sptr;
+
+audio_oss_sink_sptr
+audio_oss_make_sink (int sampling_rate,
+                    const std::string dev = "",
+                    bool ok_to_block = true);
+
+/*!
+ * \brief audio sink using OSS
+ *
+ * input signature is one or two streams of floats.
+ * Input samples must be in the range [-1,1].
+ */
+
+class audio_oss_sink : public gr_sync_block {
+  friend audio_oss_sink_sptr
+  audio_oss_make_sink (int sampling_rate, const std::string device_name, bool ok_to_block);
+
+  int          d_sampling_rate;
+  std::string  d_device_name;
+  int          d_fd;
+  short               *d_buffer;
+  int          d_chunk_size;
+
+ protected:
+  audio_oss_sink (int sampling_rate, const std::string device_name = "", bool ok_to_block = true);
+
+ public:
+  ~audio_oss_sink ();
+  
+  int work (int noutput_items,
+           gr_vector_const_void_star &input_items,
+           gr_vector_void_star &output_items);
+};
+
+#endif /* INCLUDED_AUDIO_OSS_SINK_H */
diff --git a/gr-audio-oss/src/audio_oss_source.cc b/gr-audio-oss/src/audio_oss_source.cc
new file mode 100644 (file)
index 0000000..6afb088
--- /dev/null
@@ -0,0 +1,178 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <audio_oss_source.h>
+#include <gr_io_signature.h>
+#include <gr_prefs.h>
+#include <sys/soundcard.h>
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <iostream>
+#include <stdexcept>
+
+
+static std::string
+default_device_name ()
+{
+  return gr_prefs::singleton()->get_string("audio_oss", "default_input_device", "/dev/dsp");
+}
+
+audio_oss_source_sptr
+audio_oss_make_source (int sampling_rate, const std::string dev, bool ok_to_block)
+{
+  return audio_oss_source_sptr (new audio_oss_source (sampling_rate, dev, ok_to_block));
+}
+
+
+audio_oss_source::audio_oss_source (int sampling_rate,
+                                   const std::string device_name,
+                                   bool ok_to_block)
+  : gr_sync_block ("audio_oss_source",
+                  gr_make_io_signature (0, 0, 0),
+                  gr_make_io_signature (1, 2, sizeof (float))),
+    d_sampling_rate (sampling_rate),
+    d_device_name (device_name.empty() ? default_device_name() : device_name),
+    d_fd (-1), d_buffer (0), d_chunk_size (0)
+{
+  if ((d_fd = open (d_device_name.c_str (), O_RDONLY)) < 0){
+    fprintf (stderr, "audio_oss_source: ");
+    perror (d_device_name.c_str ());
+    throw std::runtime_error ("audio_oss_source");
+  }
+
+  double CHUNK_TIME =
+    std::max(0.001, gr_prefs::singleton()->get_double("audio_oss", "latency", 0.005));
+
+  d_chunk_size = (int) (d_sampling_rate * CHUNK_TIME);
+  set_output_multiple (d_chunk_size);
+
+  d_buffer = new short [d_chunk_size * 2];
+
+  int format = AFMT_S16_NE;
+  int orig_format = format;
+  if (ioctl (d_fd, SNDCTL_DSP_SETFMT, &format) < 0){
+    std::cerr << "audio_oss_source: " << d_device_name << " ioctl failed\n";
+    perror (d_device_name.c_str ());
+    throw std::runtime_error ("audio_oss_source");
+  }
+
+  if (format != orig_format){
+    fprintf (stderr, "audio_oss_source: unable to support format %d\n", orig_format);
+    fprintf (stderr, "  card requested %d instead.\n", format);
+  }
+
+  // set to stereo no matter what.  Some hardware only does stereo
+  int channels = 2;
+  if (ioctl (d_fd, SNDCTL_DSP_CHANNELS, &channels) < 0 || channels != 2){
+    perror ("audio_oss_source: could not set STEREO mode");
+    throw std::runtime_error ("audio_oss_source");
+  }
+
+  // set sampling freq
+  int sf = sampling_rate;
+  if (ioctl (d_fd, SNDCTL_DSP_SPEED, &sf) < 0){
+    std::cerr << "audio_oss_source: "
+             << d_device_name << ": invalid sampling_rate "
+             << sampling_rate << "\n";
+    sampling_rate = 8000;
+    if (ioctl (d_fd, SNDCTL_DSP_SPEED, &sf) < 0){
+      std::cerr << "audio_oss_source: failed to set sampling_rate to 8000\n";
+      throw std::runtime_error ("audio_oss_source");
+    }
+  }
+}
+
+audio_oss_source::~audio_oss_source ()
+{
+  close (d_fd);
+  delete [] d_buffer;
+}
+
+int
+audio_oss_source::work (int noutput_items,
+                       gr_vector_const_void_star &input_items,
+                       gr_vector_void_star &output_items)
+{
+  float *f0 = (float *) output_items[0];
+  float *f1 = (float *) output_items[1];       // will be invalid if this is mono output
+
+  const int shorts_per_item = 2;               // L + R
+  const int bytes_per_item = shorts_per_item * sizeof (short);
+
+  // To minimize latency, never return more than CHUNK_TIME
+  // worth of samples per call to work.  
+
+  noutput_items = std::min (noutput_items, d_chunk_size);
+
+  int  base = 0;
+  int  ntogo = noutput_items;
+  
+  while (ntogo > 0){
+    int nbytes = std::min (ntogo, d_chunk_size) * bytes_per_item;
+    int result_nbytes = read (d_fd, d_buffer, nbytes);
+
+    if (result_nbytes < 0){
+      perror ("audio_oss_source");
+      return -1;               // say we're done
+    }
+
+    if ((result_nbytes & (bytes_per_item - 1)) != 0){
+      fprintf (stderr, "audio_oss_source: internal error.\n");
+      throw std::runtime_error ("internal error");
+    }
+
+    int result_nitems = result_nbytes / bytes_per_item;
+
+    // now unpack samples into output streams
+
+    switch (output_items.size ()){
+      case 1:                  // mono output
+       for (int i = 0; i < result_nitems; i++){
+         f0[base+i] = d_buffer[2*i+0] * (1.0 / 32767);
+       }
+       break;
+
+      case 2:                  // stereo output        
+       for (int i = 0; i < result_nitems; i++){
+         f0[base+i] = d_buffer[2*i+0] * (1.0 / 32767);
+         f1[base+i] = d_buffer[2*i+1] * (1.0 / 32767);
+       }
+       break;
+
+      default:
+       assert (0);
+      }
+
+    ntogo -= result_nitems;
+    base += result_nitems;
+  }
+
+  return noutput_items - ntogo;
+}
diff --git a/gr-audio-oss/src/audio_oss_source.h b/gr-audio-oss/src/audio_oss_source.h
new file mode 100644 (file)
index 0000000..4f0facd
--- /dev/null
@@ -0,0 +1,70 @@
+/* -*- 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 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.
+ */
+
+#ifndef INCLUDED_AUDIO_OSS_SOURCE_H
+#define INCLUDED_AUDIO_OSS_SOURCE_H
+
+#include <gr_sync_block.h>
+#include <string>
+
+
+class audio_oss_source;
+typedef boost::shared_ptr<audio_oss_source> audio_oss_source_sptr;
+
+audio_oss_source_sptr
+audio_oss_make_source (int sampling_rate,
+                      const std::string dev = "",
+                      bool ok_to_block = true);
+
+/*!
+ * \brief audio source using OSS
+ *
+ * Output signature is one or two streams of floats.
+ * Output samples will be in the range [-1,1].
+ */
+
+class audio_oss_source : public gr_sync_block {
+  friend audio_oss_source_sptr
+  audio_oss_make_source (int sampling_rate, const std::string device_name, bool ok_to_block);
+
+  int          d_sampling_rate;
+  std::string  d_device_name;
+  int          d_fd;
+  short               *d_buffer;
+  int          d_chunk_size;
+
+ protected:
+  audio_oss_source (int sampling_rate,
+                   const std::string device_name = "",
+                   bool ok_to_block = true);
+
+ public:
+  ~audio_oss_source ();
+  
+  int work (int noutput_items,
+           gr_vector_const_void_star &input_items,
+           gr_vector_void_star &output_items);
+};
+
+
+
+#endif /* INCLUDED_AUDIO_OSS_SOURCE_H */
diff --git a/gr-audio-oss/src/qa_oss.py b/gr-audio-oss/src/qa_oss.py
new file mode 100755 (executable)
index 0000000..f747654
--- /dev/null
@@ -0,0 +1,40 @@
+#!/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 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.
+# 
+
+from gnuradio import gr, gr_unittest
+import audio_oss
+
+class qa_oss (gr_unittest.TestCase):
+
+    def setUp (self):
+        self.fg = gr.flow_graph ()
+
+    def tearDown (self):
+        self.fg = None
+
+    def test_000_nop (self):
+        """Just see if we can import the module...
+        They may not have OSS drivers, etc.  Don't try to run anything"""
+        pass
+    
+if __name__ == '__main__':
+    gr_unittest.main ()
diff --git a/gr-audio-oss/src/run_tests.in b/gr-audio-oss/src/run_tests.in
new file mode 100644 (file)
index 0000000..ec252d5
--- /dev/null
@@ -0,0 +1,47 @@
+#!/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@/gr-audio-oss/src
+# Where to look in the src tree for swig generated python code
+libsrc=@abs_top_srcdir@/gr-audio-oss/src
+# Where to look in the src tree for hand written python code
+py=@abs_top_srcdir@/gr-audio-oss/src
+
+# Where to look for GNU Radio python modules in current build tree
+# FIXME this is wrong on a distcheck.  We really need to ask gnuradio-core
+# where it put its python files.
+grpythonbld=@abs_top_builddir@/gnuradio-core/src/python/:@abs_top_builddir@/gnuradio-core/src/lib/swig/:@abs_top_builddir@/gnuradio-core/src/lib/swig/.libs
+
+PYTHONPATH="$grpythonbld:$libbld:$libbld/.libs:$libsrc:$py:$PYTHONPATH"
+export PYTHONPATH
+
+#
+# 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-audio-osx/AUTHORS b/gr-audio-osx/AUTHORS
new file mode 100644 (file)
index 0000000..ecc9577
--- /dev/null
@@ -0,0 +1 @@
+Michael Dickens <mdickens@nd.edu>    NCIP Lab, University of Notre Dame
diff --git a/gr-audio-osx/ChangeLog b/gr-audio-osx/ChangeLog
new file mode 100644 (file)
index 0000000..0ae5acf
--- /dev/null
@@ -0,0 +1,25 @@
+2006-04-22  Michael Dickens <mdickens@nd.edu> 
+            NCIP Lab, University of Notre Dame
+
+       Everything is new.
+
+#
+# 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 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.
+# 
diff --git a/gr-audio-osx/Makefile.am b/gr-audio-osx/Makefile.am
new file mode 100644 (file)
index 0000000..077d2aa
--- /dev/null
@@ -0,0 +1,25 @@
+#
+# 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 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.
+# 
+
+include $(top_srcdir)/Makefile.common
+
+EXTRA_DIST = README_OSX
+SUBDIRS = src
diff --git a/gr-audio-osx/README_OSX b/gr-audio-osx/README_OSX
new file mode 100644 (file)
index 0000000..2a98e96
--- /dev/null
@@ -0,0 +1,61 @@
+Michael Dickens
+2006-Apr-30
+
+0) This module should compile and install in the same manner as the
+other GNURadio modules (e.g. gnuradio-core), with the possible
+exception that GNU libtool 1.5.20 or newer should be installed and
+used (if not first in the path) via "make LIBTOOL=/..." and so forth.
+Version 1.5.10 has failed making, and while picking version 1.5.20 is
+somewhat arbitrary, the newer version compiles and installs easily
+under OSX.
+
+1) This module should be automatically loaded by the Python command
+"from gr import audio".  The audio import script will automatically
+select gr.audio_osx if it is available (though it will try to import
+ALSA first, then OSS, then OSX, and finally WINDOWS audio modules, in
+that order).  If that import command doesn't work, try reinstalling
+gnuradio-core from scratch followed by gr-audio-osx.
+
+2) Instantiation arguments for either source or sink are:
+
+* sample_rate : integer : default == 44100
+  OSX converts the integer sample rate to a double internally; it
+  would be nice to have this input as a double natively, but that
+  doesn't work with other audio devices.
+
+* device_name : string : default == "2"
+  For OSX, the device name should be an integer string.  This value is
+  the maximum number of channels to allocate (for input or output).
+  In the "source" case (input), the actual number of channels will be
+  whatever is available on that current system input device.  In the
+  "sink" case (output), OSX will convert the provided channels into
+  whatever format is required by the current system output device.
+  For example, "3" would try to setup for 3 input or output channels.
+  NOTE that this is a very different use than that for other audio
+  modules (though they can interpret the number of channels from this
+  argument).
+
+* do_block : boolean : default == true
+  If the data transfer buffer between OSX internals and GNURadio gets
+  full, either block (true) or overwrite (false) depending on this
+  variable.
+
+The following are currently non-standard arguments:
+
+* channel_config : integer : default == -1
+  An enum (internally) describing the channel configuration.  Not
+  currently used, but rather reserved for future expansion.
+
+* max_sample_count : integer : default == -1
+  The maximum number of samples to buffer between OSX internals and
+  GNURadio.  The value -1 is mapped to 1 second's worth of data.
+
+3) When the buffer is full and do_block is false and new data comes
+in, the oldest data will be overwritten.  The source will print out
+"iX" each time this happens; the sink will print out "oX".
+
+4) In the "src" directory is a python script "test_audio_loop" which
+connects the default audio input device to the default audio output
+device.  This script is very useful in testing that audio is correctly
+installed and both the source and sink are functional.  This script is
+not run by "make check".
diff --git a/gr-audio-osx/TODO b/gr-audio-osx/TODO
new file mode 100644 (file)
index 0000000..e36ed2b
--- /dev/null
@@ -0,0 +1,51 @@
+List as of 2006-Apr-22, by Michael Dickens, primary author
+
+* Change buffering to use gr_buffer's and necessary related classes.
+  Currently uses a circular_buffer I wrote myself (in
+  ./src/circular_buffer.h ), which hides the "circular" part from the
+  user but otherwise is very fast as well as thread safe.
+
+* A current limitation of this implementation is that the user cannot
+  dynamically switch audio devices (input or output) during playback
+  and use the new device without stopping the current executing GR and
+  restarting the process.  I would like to figure out how to get a
+  CoreAudio "listener" for when the default hardware input / output
+  device changes (e.g. when switched by the user in the "Sound" system
+  preference pane).  The code in ./src/audio-osx-source.cc creates
+  listeners for the AudioUnit being used as well as the Hardware
+  device, but these for some reason don't do the trick.  It's possible
+  that the Python framework doesn't allow for one to do this.
+
+* In both the source and sink, move the code which defines the "Audio
+  Stream Basic Description" (ASBD) to a routine to do this as needed
+  as start-up as well as in a callback ("listener") if the default
+  device changes.
+
+* Tweak the mutex (d_internal) to only where it is truly needed
+  (around class-specific variables used across all threads) in order
+  to improve performance.  Currently the mutex is used at the
+  start and end of any function requiring access to the class variables.
+
+* Change the instantiation arguments ... once those arguments are
+  finalized.  Right now gr.audio.source () takes the sample rate (int
+  - should be double), the device name (std::string), a boolean for
+  blocking or not, and 2 completely non-standard ones for channel
+  configuration and the maximum sample count to buffer.  These are
+  reasonable for OSX, but might not be for other OSs.  Nothing to do
+  right now but wait and discuss.
+
+* Once the previous issue has been resolved, then the current method
+  of determining the number of channels needs to be updated.
+  Currently the "device_name" for OSX should contain a numeric string
+  for the maximum number of channels to use (e.g. "3" means 3
+  channels, generally mapped to 2 channel stereo by OSX).  The
+  "device_name" is generally input via "-O" in Python scripts, so "-O
+  3" would allow for 3 incoming output channels (or fewer).  In theory
+  the "channel_config" argument would make more sense for determining
+  channel usage.  Example config strings might be "2.1" for stereo w/
+  subwoofer (3 channels), "5.1" or "6.1" for various surround w/
+  subwoofer (6 & 7 channels, respectively).  OSX can handle all sorts
+  of channel configurations, but the names for these will be different
+  than those use for OSS or ALMA or Windows ... thus the need for a
+  common naming scheme for all cared-about configurations, possibly
+  with options for other OS-specific options.
diff --git a/gr-audio-osx/src/Makefile.am b/gr-audio-osx/src/Makefile.am
new file mode 100644 (file)
index 0000000..54cc327
--- /dev/null
@@ -0,0 +1,88 @@
+#
+# 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 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.
+# 
+
+include $(top_srcdir)/Makefile.common
+
+# Install this stuff so that it ends up as the gnuradio.audio_osx module
+# This usually ends up at:
+#   ${prefix}/lib/python${python_version}/site-packages/gnuradio
+
+ourpythondir = $(grpythondir)
+ourlibdir    = $(grpyexecdir)
+
+EXTRA_DIST = run_tests.in
+TESTS = run_tests
+
+LOCAL_IFILES =                                 \
+       audio_osx.i                             
+
+NON_LOCAL_IFILES =                     \
+       $(top_srcdir)/gnuradio-core/src/lib/swig/gnuradio.i
+
+ALL_IFILES =                           \
+       $(LOCAL_IFILES)                 \
+       $(NON_LOCAL_IFILES)             
+
+BUILT_SOURCES =                        \
+       audio_osx.cc                    \
+       audio_osx.py                            
+
+ourpython_PYTHON =                     \
+       audio_osx.py
+
+INCLUDES = $(STD_DEFINES_AND_INCLUDES) $(PYTHON_CPPFLAGS)
+
+SWIGCPPPYTHONARGS = -python $(PYTHON_CPPFLAGS) $(STD_DEFINES_AND_INCLUDES)
+
+ourlib_LTLIBRARIES = _audio_osx.la
+
+_audio_osx_la_SOURCES =                \
+       audio_osx.cc                    \
+       audio_osx_sink.cc               \
+       audio_osx_source.cc                     
+
+noinst_HEADERS =                       \
+       audio_osx.h                     \
+       circular_buffer.h               \
+       mld_threads.h
+
+grinclude_HEADERS =                    \
+       audio_osx_sink.h                \
+       audio_osx_source.h                      
+
+swiginclude_HEADERS =                  \
+       $(LOCAL_IFILES)
+
+_audio_osx_la_LIBADD =                         \
+       $(PYTHON_LDFLAGS)               \
+       $(GNURADIO_CORE_LIBS)           \
+       -lstdc++                                
+
+_audio_osx_la_LDFLAGS = $(NO_UNDEFINED) -module -avoid-version -framework AudioUnit -framework CoreAudio -framework AudioToolbox
+
+audio_osx.cc audio_osx.py: audio_osx.i
+       $(SWIG) $(SWIGCPPPYTHONARGS) -module audio_osx -o audio_osx.cc $<
+
+noinst_PYTHON = qa_osx.py test_audio_loop.py
+
+MOSTLYCLEANFILES = $(BUILT_SOURCES) *~ *.pyc run_tests *.loT
+
+CONFIG_CLEAN_FILES = Makefile.in run_tests *.loT
diff --git a/gr-audio-osx/src/audio_osx.h b/gr-audio-osx/src/audio_osx.h
new file mode 100644 (file)
index 0000000..f92ca3f
--- /dev/null
@@ -0,0 +1,49 @@
+/* -*- 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 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.
+ */
+
+#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); \
+}
+
+#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); \
+}
+
+#ifdef WORDS_BIGENDIAN
+#define GR_PCM_ENDIANNESS kLinearPCMFormatFlagIsBigEndian
+#else
+#define GR_PCM_ENDIANNESS 0
+#endif
+
+#endif /* INCLUDED_AUDIO_OSX_H */
diff --git a/gr-audio-osx/src/audio_osx.i b/gr-audio-osx/src/audio_osx.i
new file mode 100644 (file)
index 0000000..9ced419
--- /dev/null
@@ -0,0 +1,95 @@
+/* -*- 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 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.
+ */
+
+%feature("autodoc","1");
+
+%include "exception.i"
+%import "gnuradio.i"                           // the common stuff
+
+%{
+#include "gnuradio_swig_bug_workaround.h"      // mandatory bug fix
+#include "audio_osx_sink.h"
+#include "audio_osx_source.h"
+#include <stdexcept>
+%}
+
+// ----------------------------------------------------------------
+
+GR_SWIG_BLOCK_MAGIC(audio_osx,sink)
+
+audio_osx_sink_sptr
+audio_osx_make_sink (int sample_rate = 44100,
+                    const std::string device_name = "2",
+                    bool do_block = TRUE,
+                    int channel_config = -1,
+                    int max_sample_count = -1
+                    ) throw (std::runtime_error);
+
+class audio_osx_sink : public gr_sync_block {
+ protected:
+  audio_osx_sink (int sample_rate = 44100,
+                 const std::string device_name = "2",
+                 bool do_block = TRUE,
+                 int channel_config = -1,
+                 int max_sample_count = -1);
+
+ public:
+  ~audio_osx_sink ();
+
+  bool start ();
+  bool stop ();
+
+  int work (int noutput_items,
+           gr_vector_const_void_star &input_items,
+           gr_vector_void_star &output_items);
+};
+
+// ----------------------------------------------------------------
+
+GR_SWIG_BLOCK_MAGIC(audio_osx,source)
+
+audio_osx_source_sptr
+audio_osx_make_source (int sample_rate = 44100,
+                    const std::string device_name = "2",
+                    bool do_block = TRUE,
+                    int channel_config = -1,
+                    int max_sample_count = -1
+                    ) throw (std::runtime_error);
+
+class audio_osx_source : public gr_sync_block {
+ protected:
+  audio_osx_source (int sample_rate = 44100,
+                 const std::string device_name = "2",
+                 bool do_block = TRUE,
+                 int channel_config = -1,
+                 int max_sample_count = -1);
+
+ public:
+  ~audio_osx_source ();
+  
+  bool start ();
+  bool stop ();
+
+  int work (int noutput_items,
+           gr_vector_const_void_star &input_items,
+           gr_vector_void_star &output_items);
+};
diff --git a/gr-audio-osx/src/audio_osx_sink.cc b/gr-audio-osx/src/audio_osx_sink.cc
new file mode 100644 (file)
index 0000000..14b4a51
--- /dev/null
@@ -0,0 +1,398 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#define _USE_OMNI_THREADS_
+
+#include <audio_osx_sink.h>
+#include <gr_io_signature.h>
+#include <stdexcept>
+#include <audio_osx.h>
+
+#define _OSX_AU_DEBUG_ 0
+
+audio_osx_sink::audio_osx_sink (int sample_rate,
+                               const std::string device_name,
+                               bool do_block,
+                               int channel_config,
+                               int max_sample_count)
+  : gr_sync_block ("audio_osx_sink",
+                  gr_make_io_signature (0, 0, 0),
+                  gr_make_io_signature (0, 0, 0)),
+    d_sample_rate (0.0), d_channel_config (0), d_n_channels (0),
+    d_queueSampleCount (0), d_max_sample_count (0),
+    d_do_block (do_block), d_internal (0), d_cond_data (0),
+    d_OutputAU (0)
+{
+  if (sample_rate <= 0) {
+    fprintf (stderr, "Invalid Sample Rate: %d\n", sample_rate);
+    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);
+    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);
+      throw std::invalid_argument ("audio_osx_sink::audio_osx_sink");
+    }
+    if (l_n_channels <= 0)
+      channel_config = 2;
+    else
+      channel_config = l_n_channels;
+  }
+
+  d_n_channels = d_channel_config = channel_config;
+
+// set the input signature
+
+  set_input_signature (gr_make_io_signature (1, d_n_channels, sizeof (float)));
+
+// check that the max # of samples to store is valid
+
+  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);
+    throw std::invalid_argument ("audio_osx_sink::audio_osx_sink");
+  }
+
+  d_max_sample_count = max_sample_count;
+
+// allocate the output circular buffer(s), one per channel
+
+  d_buffers = (circular_buffer<float>**) new
+    circular_buffer<float>* [d_n_channels];
+  UInt32 n_alloc = (UInt32) ceil ((double) d_max_sample_count);
+  for (UInt32 n = 0; n < d_n_channels; n++) {
+    d_buffers[n] = new circular_buffer<float> (n_alloc, false, false);
+  }
+
+// create the default AudioUnit for output
+  OSStatus err = noErr;
+
+// Open the default output unit
+  ComponentDescription desc;
+  desc.componentType = kAudioUnitType_Output;
+  desc.componentSubType = kAudioUnitSubType_DefaultOutput;
+  desc.componentManufacturer = kAudioUnitManufacturer_Apple;
+  desc.componentFlags = 0;
+  desc.componentFlagsMask = 0;
+
+  Component comp = FindNextComponent (NULL, &desc);
+  if (comp == NULL) {
+    fprintf (stderr, "FindNextComponent Error\n");
+    throw std::runtime_error ("audio_osx_sink::audio_osx_sink");
+  }
+
+  err = OpenAComponent (comp, &d_OutputAU);
+  CheckErrorAndThrow (err, "OpenAComponent", "audio_osx_sink::audio_osx_sink");
+
+// Set up a callback function to generate output to the output unit
+
+  AURenderCallbackStruct input;
+  input.inputProc = (AURenderCallback)(audio_osx_sink::AUOutputCallback);
+  input.inputProcRefCon = this;
+
+  err = AudioUnitSetProperty (d_OutputAU,
+                             kAudioUnitProperty_SetRenderCallback, 
+                             kAudioUnitScope_Input,
+                             0, 
+                             &input, 
+                             sizeof (input));
+  CheckErrorAndThrow (err, "AudioUnitSetProperty Render Callback", "audio_osx_sink::audio_osx_sink");
+
+// tell the Output Unit what format data will be supplied to it
+// so that it handles any format conversions
+
+  AudioStreamBasicDescription streamFormat;
+  streamFormat.mSampleRate = (Float64)(sample_rate);
+  streamFormat.mFormatID = kAudioFormatLinearPCM;
+  streamFormat.mFormatFlags = (kLinearPCMFormatFlagIsFloat |
+                              GR_PCM_ENDIANNESS |
+                              kLinearPCMFormatFlagIsPacked |
+                              kAudioFormatFlagIsNonInterleaved);
+  streamFormat.mBytesPerPacket = 4;
+  streamFormat.mFramesPerPacket = 1;
+  streamFormat.mBytesPerFrame = 4;
+  streamFormat.mChannelsPerFrame = d_n_channels;
+  streamFormat.mBitsPerChannel = 32;
+
+  err = AudioUnitSetProperty (d_OutputAU,
+                             kAudioUnitProperty_StreamFormat,
+                             kAudioUnitScope_Input,
+                             0,
+                             &streamFormat,
+                             sizeof (AudioStreamBasicDescription));
+  CheckErrorAndThrow (err, "AudioUnitSetProperty StreamFormat", "audio_osx_sink::audio_osx_sink");
+
+// create the stuff to regulate I/O
+
+  d_internal = new mld_mutex ();
+  if (d_internal == NULL)
+    CheckErrorAndThrow (errno, "new mld_mutex (internal)",
+                       "audio_osx_source::audio_osx_source");
+
+  d_cond_data = new mld_condition ();
+  if (d_cond_data == NULL)
+    CheckErrorAndThrow (errno, "new mld_condition (data)",
+                       "audio_osx_source::audio_osx_source");
+
+// initialize the AU for output
+
+  err = AudioUnitInitialize (d_OutputAU);
+  CheckErrorAndThrow (err, "AudioUnitInitialize",
+                     "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);
+#endif
+}
+
+bool audio_osx_sink::IsRunning ()
+{
+  UInt32 AURunning = 0, AUSize = sizeof (UInt32);
+
+  OSStatus err = AudioUnitGetProperty (d_OutputAU,
+                                      kAudioOutputUnitProperty_IsRunning,
+                                      kAudioUnitScope_Global,
+                                      0,
+                                      &AURunning,
+                                      &AUSize);
+  CheckErrorAndThrow (err, "AudioUnitGetProperty IsRunning",
+                     "audio_osx_sink::IsRunning");
+
+  return (AURunning);
+}
+
+bool audio_osx_sink::start ()
+{
+  if (! IsRunning ()) {
+    OSStatus err = AudioOutputUnitStart (d_OutputAU);
+    CheckErrorAndThrow (err, "AudioOutputUnitStart", "audio_osx_sink::start");
+  }
+
+  return (true);
+}
+
+bool audio_osx_sink::stop ()
+{
+  if (IsRunning ()) {
+    OSStatus err = AudioOutputUnitStop (d_OutputAU);
+    CheckErrorAndThrow (err, "AudioOutputUnitStop", "audio_osx_sink::stop");
+
+    for (UInt32 n = 0; n < d_n_channels; n++) {
+      d_buffers[n]->abort ();
+    }
+  }
+
+  return (true);
+}
+
+audio_osx_sink::~audio_osx_sink ()
+{
+// stop and close the AudioUnit
+  stop ();
+  AudioUnitUninitialize (d_OutputAU);
+  CloseComponent (d_OutputAU);
+
+// empty and delete the queues
+  for (UInt32 n = 0; n < d_n_channels; n++) {
+    delete d_buffers[n];
+    d_buffers[n] = 0;
+  }
+  delete [] d_buffers;
+  d_buffers = 0;
+
+// close and delete control stuff
+  delete d_internal;
+  delete d_cond_data;
+}
+
+audio_osx_sink_sptr
+audio_osx_make_sink (int sampling_freq,
+                    const std::string dev,
+                    bool do_block,
+                    int channel_config,
+                    int max_sample_count)
+{
+  return audio_osx_sink_sptr (new audio_osx_sink (sampling_freq,
+                                                 dev,
+                                                 do_block,
+                                                 channel_config,
+                                                 max_sample_count));
+}
+
+int
+audio_osx_sink::work (int noutput_items,
+                     gr_vector_const_void_star &input_items,
+                     gr_vector_void_star &output_items)
+{
+  d_internal->wait ();
+
+  /* take the input data, copy it, and push it to the bottom of the queue
+     mono input are pushed onto queue[0];
+     stereo input are pushed onto queue[1].
+     Start the AudioUnit if necessary. */
+
+  UInt32 l_max_count;
+  int diff_count = d_max_sample_count - noutput_items;
+  if (diff_count < 0)
+    l_max_count = 0;
+  else
+    l_max_count = (UInt32) diff_count;
+
+#if 0
+  if (l_max_count < d_queueItemLength->back()) {
+//  allow 2 buffers at a time, regardless of length
+    l_max_count = d_queueItemLength->back();
+  }
+#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);
+#endif
+
+  if (d_queueSampleCount > l_max_count) {
+// data coming in too fast; do_block decides what to do
+    if (d_do_block == true) {
+// block until there is data to return
+      while (d_queueSampleCount > l_max_count) {
+// release control so-as to allow data to be retrieved
+       d_internal->post ();
+// block until there is data to return
+       d_cond_data->wait ();
+// the condition's signal() was called; acquire control
+// to keep thread safe
+       d_internal->wait ();
+      }
+    }
+  }
+// not blocking case and overflow is handled by the circular buffer
+
+// add the input frames to the buffers' queue, checking for overflow
+
+  UInt32 l_counter;
+  int res = 0;
+  float* inBuffer = (float*) input_items[0];
+  const UInt32 l_size = input_items.size();
+  for (l_counter = 0; l_counter < l_size; l_counter++) {
+    inBuffer = (float*) input_items[l_counter];
+    int l_res = d_buffers[l_counter]->enqueue (inBuffer,
+                                              noutput_items);
+    if (l_res == -1)
+      res = -1;
+  }
+  while (l_counter < d_n_channels) {
+// for extra channels, copy the last input's data
+    int l_res = d_buffers[l_counter++]->enqueue (inBuffer,
+                                                noutput_items);
+    if (l_res == -1)
+      res = -1;
+  }
+
+  if (res == -1) {
+// data coming in too fast
+// drop oldest buffer
+    fputs ("oX", stderr);
+    fflush (stderr);
+// set the local number of samples available to the max
+    d_queueSampleCount = d_buffers[0]->buffer_length_items ();
+  } else {
+// keep up the local sample count
+    d_queueSampleCount += noutput_items;
+  }
+
+#if _OSX_AU_DEBUG_
+  fprintf (stderr, "work2: #OI = %4d, #Cnt = %4ld, mSC = %ld\n",
+          noutput_items, d_queueSampleCount, d_max_sample_count);
+#endif
+
+// release control to allow for other processing parts to run
+  d_internal->post ();
+
+  return (noutput_items);
+}
+
+OSStatus audio_osx_sink::AUOutputCallback
+(void *inRefCon, 
+ AudioUnitRenderActionFlags *ioActionFlags, 
+ const AudioTimeStamp *inTimeStamp, 
+ UInt32 inBusNumber, 
+ UInt32 inNumberFrames, 
+ AudioBufferList *ioData)
+{
+  audio_osx_sink* This = (audio_osx_sink*) inRefCon;
+  OSStatus err = noErr;
+
+  This->d_internal->wait ();
+
+#if _OSX_AU_DEBUG_
+  fprintf (stderr, "cb_in: SC = %4ld, in#F = %4ld\n",
+          This->d_queueSampleCount, inNumberFrames);
+#endif
+
+  if (This->d_queueSampleCount < inNumberFrames) {
+// not enough data to fill request
+    err = -1;
+  } else {
+// enough data; remove data from our buffers into the AU's buffers
+    int l_counter = This->d_n_channels;
+
+    while (--l_counter >= 0) {
+      UInt32 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) {
+       throw std::runtime_error ("audio_osx_sink::AUOutputCallback(): "
+                                 "number of available items changing "
+                                 "unexpectedly.\n");
+      }
+    }
+
+    This->d_queueSampleCount -= inNumberFrames;
+  }
+
+#if _OSX_AU_DEBUG_
+  fprintf (stderr, "cb_out: SC = %4ld\n", This->d_queueSampleCount);
+#endif
+
+// signal that data is available
+  This->d_cond_data->signal ();
+
+// release control to allow for other processing parts to run
+  This->d_internal->post ();
+
+  return (err);
+}
diff --git a/gr-audio-osx/src/audio_osx_sink.h b/gr-audio-osx/src/audio_osx_sink.h
new file mode 100644 (file)
index 0000000..8cd3be0
--- /dev/null
@@ -0,0 +1,96 @@
+/* -*- 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 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.
+ */
+
+#ifndef INCLUDED_AUDIO_OSX_SINK_H
+#define INCLUDED_AUDIO_OSX_SINK_H
+
+#include <gr_sync_block.h>
+#include <string>
+#include <list>
+#include <AudioUnit/AudioUnit.h>
+#include <circular_buffer.h>
+
+class audio_osx_sink;
+typedef boost::shared_ptr<audio_osx_sink> audio_osx_sink_sptr;
+
+audio_osx_sink_sptr
+audio_osx_make_sink (int sample_rate = 44100,
+                    const std::string device_name = "2",
+                    bool do_block = true,
+                    int channel_config = -1,
+                    int max_sample_count = -1);
+
+/*!
+ * \brief audio sink using OSX
+ *
+ * input signature is one or two streams of floats.
+ * Input samples must be in the range [-1,1].
+ */
+
+class audio_osx_sink : public gr_sync_block {
+  friend audio_osx_sink_sptr
+  audio_osx_make_sink (int sample_rate,
+                      const std::string device_name,
+                      bool do_block,
+                      int channel_config,
+                      int max_sample_count);
+
+  Float64             d_sample_rate;
+  int                 d_channel_config;
+  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;
+  circular_buffer<float>** d_buffers;
+
+// AudioUnits and Such
+  AudioUnit           d_OutputAU;
+
+protected:
+  audio_osx_sink (int sample_rate = 44100,
+                 const std::string device_name = "2",
+                 bool do_block = true,
+                 int channel_config = -1,
+                 int max_sample_count = -1);
+
+public:
+  ~audio_osx_sink ();
+
+  bool IsRunning ();
+  bool start ();
+  bool stop ();
+
+  int work (int noutput_items,
+           gr_vector_const_void_star &input_items,
+           gr_vector_void_star &output_items);
+
+private:
+  static OSStatus AUOutputCallback (void *inRefCon, 
+                                   AudioUnitRenderActionFlags *ioActionFlags, 
+                                   const AudioTimeStamp *inTimeStamp, 
+                                   UInt32 inBusNumber, 
+                                   UInt32 inNumberFrames, 
+                                   AudioBufferList *ioData);
+};
+
+#endif /* INCLUDED_AUDIO_OSX_SINK_H */
diff --git a/gr-audio-osx/src/audio_osx_source.cc b/gr-audio-osx/src/audio_osx_source.cc
new file mode 100644 (file)
index 0000000..2abf1c2
--- /dev/null
@@ -0,0 +1,978 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#define _USE_OMNI_THREADS_
+
+#include <audio_osx_source.h>
+#include <gr_io_signature.h>
+#include <stdexcept>
+#include <audio_osx.h>
+
+#define _OSX_AU_DEBUG_ 0
+#define _OSX_DO_LISTENERS_ 0
+
+void PrintStreamDesc (AudioStreamBasicDescription *inDesc)
+{
+  if (inDesc == NULL) {
+    fprintf (stderr, "PrintStreamDesc: Can't print a NULL desc!\n");
+    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);
+}
+
+// FIXME these should query some kind of user preference
+
+audio_osx_source::audio_osx_source (int sample_rate,
+                                   const std::string device_name,
+                                   bool do_block,
+                                   int channel_config,
+                                   int max_sample_count)
+  : gr_sync_block ("audio_osx_source",
+                  gr_make_io_signature (0, 0, 0),
+                  gr_make_io_signature (0, 0, 0)),
+    d_deviceSampleRate (0.0), d_outputSampleRate (0.0),
+    d_channel_config (0),
+    d_inputBufferSizeFrames (0), d_inputBufferSizeBytes (0),
+    d_outputBufferSizeFrames (0), d_outputBufferSizeBytes (0),
+    d_deviceBufferSizeFrames (0), d_deviceBufferSizeBytes (0),
+    d_leadSizeFrames (0), d_leadSizeBytes (0),
+    d_trailSizeFrames (0), d_trailSizeBytes (0),
+    d_extraBufferSizeFrames (0), d_extraBufferSizeBytes (0),
+    d_queueSampleCount (0), d_max_sample_count (0),
+    d_n_AvailableInputFrames (0), d_n_ActualInputFrames (0),
+    d_n_user_channels (0), d_n_max_channels (0), d_n_deviceChannels (0),
+    d_do_block (do_block), d_passThrough (false),
+    d_internal (0), d_cond_data (0),
+    d_buffers (0),
+    d_InputAU (0), d_InputBuffer (0), d_OutputBuffer (0),
+    d_AudioConverter (0)
+{
+  if (sample_rate <= 0) {
+    fprintf (stderr, "Invalid Sample Rate: %d\n", sample_rate);
+    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);
+    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);
+      throw std::invalid_argument ("audio_osx_source::audio_osx_source");
+    }
+    if (l_n_channels <= 0)
+      channel_config = 2;
+    else
+      channel_config = l_n_channels;
+  }
+
+  d_channel_config = channel_config;
+
+// check that the max # of samples to store is valid
+
+  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);
+    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", d_max_sample_count);
+#endif
+
+  OSStatus err = noErr;
+
+// create the default AudioUnit for input
+
+// Open the default input unit
+  ComponentDescription InputDesc;
+
+  InputDesc.componentType = kAudioUnitType_Output;
+  InputDesc.componentSubType = kAudioUnitSubType_HALOutput;
+  InputDesc.componentManufacturer = kAudioUnitManufacturer_Apple;
+  InputDesc.componentFlags = 0;
+  InputDesc.componentFlagsMask = 0;
+
+  Component comp = FindNextComponent (NULL, &InputDesc);
+  if (comp == NULL) {
+    fprintf (stderr, "FindNextComponent Error\n");
+    throw std::runtime_error ("audio_osx_source::audio_osx_source");
+  }
+
+  err = OpenAComponent (comp, &d_InputAU);
+  CheckErrorAndThrow (err, "OpenAComponent",
+                     "audio_osx_source::audio_osx_source");
+
+  UInt32 enableIO;
+
+// must enable the AUHAL for input and disable output 
+// before setting the AUHAL's current device
+
+// Enable input on the AUHAL
+  enableIO = 1;
+  err = AudioUnitSetProperty (d_InputAU,
+                             kAudioOutputUnitProperty_EnableIO,
+                             kAudioUnitScope_Input,
+                             1, // input element
+                             &enableIO,
+                             sizeof (UInt32));
+  CheckErrorAndThrow (err, "AudioUnitSetProperty Input Enable",
+                     "audio_osx_source::audio_osx_source");
+
+// Disable output on the AUHAL
+  enableIO = 0;
+  err = AudioUnitSetProperty (d_InputAU,
+                             kAudioOutputUnitProperty_EnableIO,
+                             kAudioUnitScope_Output,
+                             0, // output element
+                             &enableIO,
+                             sizeof (UInt32));
+  CheckErrorAndThrow (err, "AudioUnitSetProperty Output Disable",
+                     "audio_osx_source::audio_osx_source");
+
+// set the default input device for our input AU
+
+  SetDefaultInputDeviceAsCurrent ();
+
+#if _OSX_DO_LISTENERS_
+// set up a listener if default hardware input device changes
+
+  err = AudioHardwareAddPropertyListener
+    (kAudioHardwarePropertyDefaultInputDevice,
+     (AudioHardwarePropertyListenerProc) HardwareListener,
+     this);
+
+  CheckErrorAndThrow (err, "AudioHardwareAddPropertyListener",
+                     "audio_osx_source::audio_osx_source");
+
+// Add a listener for any changes in the input AU's output stream
+// the function "UnitListener" will be called if the stream format
+// changes for whatever reason
+
+  err = AudioUnitAddPropertyListener
+    (d_InputAU,
+     kAudioUnitProperty_StreamFormat,
+     (AudioUnitPropertyListenerProc) UnitListener,
+     this);
+  CheckErrorAndThrow (err, "Adding Unit Property Listener",
+                     "audio_osx_source::audio_osx_source");
+#endif
+
+// Now find out if it actually can do input.
+
+  UInt32 hasInput = 0;
+  UInt32 dataSize = sizeof (hasInput);
+  err = AudioUnitGetProperty (d_InputAU,
+                             kAudioOutputUnitProperty_HasIO,
+                             kAudioUnitScope_Input,
+                             1,
+                             &hasInput,
+                             &dataSize);
+  CheckErrorAndThrow (err, "AudioUnitGetProperty HasIO",
+                     "audio_osx_source::audio_osx_source");
+  if (hasInput == 0) {
+    fprintf (stderr, "Selected Audio Device does not support Input.\n");
+    throw std::runtime_error ("audio_osx_source::audio_osx_source");
+  }
+
+// Set up a callback function to retrieve input from the Audio Device
+
+  AURenderCallbackStruct AUCallBack;
+
+  AUCallBack.inputProc = (AURenderCallback)(audio_osx_source::AUInputCallback);
+  AUCallBack.inputProcRefCon = this;
+
+  err = AudioUnitSetProperty (d_InputAU,
+                             kAudioOutputUnitProperty_SetInputCallback,
+                             kAudioUnitScope_Global,
+                             0,
+                             &AUCallBack,
+                             sizeof (AURenderCallbackStruct));
+  CheckErrorAndThrow (err, "AudioUnitSetProperty Input Callback",
+                     "audio_osx_source::audio_osx_source");
+
+  UInt32 propertySize;
+  AudioStreamBasicDescription asbd_device, asbd_client, asbd_user;
+
+// asbd_device: ASBD of the device that is creating the input data stream
+// asbd_client: ASBD of the client size (output) of the hardware device
+// asbd_user:   ASBD of the user's arguments
+
+// Get the Stream Format (device side)
+
+  propertySize = sizeof (asbd_device);
+  err = AudioUnitGetProperty (d_InputAU,
+                             kAudioUnitProperty_StreamFormat,
+                             kAudioUnitScope_Input,
+                             1,
+                             &asbd_device,
+                             &propertySize);
+  CheckErrorAndThrow (err, "AudioUnitGetProperty Device Input Stream Format",
+                     "audio_osx_source::audio_osx_source");
+
+#if _OSX_AU_DEBUG_
+  fprintf (stderr, "---- Device Stream Format ----\n" );
+  PrintStreamDesc (&asbd_device);
+#endif
+
+// Get the Stream Format (client side)
+  propertySize = sizeof (asbd_client);
+  err = AudioUnitGetProperty (d_InputAU,
+                             kAudioUnitProperty_StreamFormat,
+                             kAudioUnitScope_Output,
+                             1,
+                             &asbd_client,
+                             &propertySize);
+  CheckErrorAndThrow (err, "AudioUnitGetProperty Device Ouput Stream Format",
+                     "audio_osx_source::audio_osx_source");
+
+#if _OSX_AU_DEBUG_
+  fprintf (stderr, "---- Client Stream Format ----\n");
+  PrintStreamDesc (&asbd_client);
+#endif
+
+// Set the format of all the AUs to the input/output devices channel count
+
+// get the max number of input (& thus output) channels supported by
+// this device
+  d_n_max_channels = asbd_client.mChannelsPerFrame;
+
+// create the output io signature;
+// no input siganture to set (source is hardware)
+  set_output_signature (gr_make_io_signature (1,
+                                             d_n_max_channels,
+                                             sizeof (float)));
+
+// allocate the output circular buffer(s), one per channel
+  d_buffers = (circular_buffer<float>**) new
+    circular_buffer<float>* [d_n_max_channels];
+  UInt32 n_alloc = (UInt32) ceil ((double) d_max_sample_count);
+  for (UInt32 n = 0; n < d_n_max_channels; n++) {
+    d_buffers[n] = new circular_buffer<float> (n_alloc, false, false);
+  }
+
+  d_deviceSampleRate = asbd_device.mSampleRate;
+  d_n_deviceChannels = asbd_device.mChannelsPerFrame;
+
+// create an ASBD for the user's wants
+
+  asbd_user.mSampleRate = d_outputSampleRate;
+  asbd_user.mFormatID = kAudioFormatLinearPCM;
+  asbd_user.mFormatFlags = (kLinearPCMFormatFlagIsFloat |
+                           GR_PCM_ENDIANNESS |
+                           kLinearPCMFormatFlagIsPacked |
+                           kAudioFormatFlagIsNonInterleaved);
+  asbd_user.mBytesPerPacket = 4;
+  asbd_user.mFramesPerPacket = 1;
+  asbd_user.mBytesPerFrame = 4;
+  asbd_user.mChannelsPerFrame = d_n_max_channels;
+  asbd_user.mBitsPerChannel = 32;
+
+  if (d_deviceSampleRate == d_outputSampleRate) {
+// no need to do conversion if asbd_client matches user wants
+    d_passThrough = true;
+    d_leadSizeFrames = d_trailSizeFrames = 0L;
+  } else {
+    d_passThrough = false;
+// Create the audio converter
+
+    err = AudioConverterNew (&asbd_client, &asbd_user, &d_AudioConverter);
+    CheckErrorAndThrow (err, "AudioConverterNew",
+                       "audio_osx_source::audio_osx_source");
+
+// Set the audio converter sample rate quality to "max" ...
+// requires more samples, but should sound nicer
+
+    UInt32 ACQuality = kAudioConverterQuality_Max;
+    propertySize = sizeof (ACQuality);
+    err = AudioConverterSetProperty (d_AudioConverter,
+                                    kAudioConverterSampleRateConverterQuality,
+                                    propertySize,
+                                    &ACQuality);
+    CheckErrorAndThrow (err, "AudioConverterSetProperty "
+                       "SampleRateConverterQuality",
+                       "audio_osx_source::audio_osx_source");
+
+// set the audio converter's prime method to "pre",
+// which uses both leading and trailing frames
+// from the "current input".  All of this is handled
+// internally by the AudioConverter; we just supply
+// the frames for conversion.
+
+//   UInt32 ACPrimeMethod = kConverterPrimeMethod_None;
+    UInt32 ACPrimeMethod = kConverterPrimeMethod_Pre;
+    propertySize = sizeof (ACPrimeMethod);
+    err = AudioConverterSetProperty (d_AudioConverter, 
+                                    kAudioConverterPrimeMethod,
+                                    propertySize,
+                                    &ACPrimeMethod);
+    CheckErrorAndThrow (err, "AudioConverterSetProperty PrimeMethod",
+                       "audio_osx_source::audio_osx_source");
+
+// Get the size of the I/O buffer(s) to allow for pre-allocated buffers
+      
+// lead frame info (trail frame info is ignored)
+
+    AudioConverterPrimeInfo ACPrimeInfo = {0, 0};
+    propertySize = sizeof (ACPrimeInfo);
+    err = AudioConverterGetProperty (d_AudioConverter, 
+                                    kAudioConverterPrimeInfo,
+                                    &propertySize,
+                                    &ACPrimeInfo);
+    CheckErrorAndThrow (err, "AudioConverterGetProperty PrimeInfo",
+                       "audio_osx_source::audio_osx_source");
+
+    switch (ACPrimeMethod) {
+    case (kConverterPrimeMethod_None):
+      d_leadSizeFrames =
+       d_trailSizeFrames = 0L;
+      break;
+    case (kConverterPrimeMethod_Normal):
+      d_leadSizeFrames = 0L;
+      d_trailSizeFrames = ACPrimeInfo.trailingFrames;
+      break;
+    default:
+      d_leadSizeFrames = ACPrimeInfo.leadingFrames;
+      d_trailSizeFrames = ACPrimeInfo.trailingFrames;
+    }
+  }
+  d_leadSizeBytes = d_leadSizeFrames * sizeof (Float32);
+  d_trailSizeBytes = d_trailSizeFrames * sizeof (Float32);
+
+  propertySize = sizeof (d_deviceBufferSizeFrames);
+  err = AudioUnitGetProperty (d_InputAU,
+                             kAudioDevicePropertyBufferFrameSize,
+                             kAudioUnitScope_Global,
+                             0,
+                             &d_deviceBufferSizeFrames,
+                             &propertySize);
+  CheckErrorAndThrow (err, "AudioUnitGetProperty Buffer Frame Size",
+                     "audio_osx_source::audio_osx_source");
+
+  d_deviceBufferSizeBytes = d_deviceBufferSizeFrames * sizeof (Float32);
+  d_inputBufferSizeBytes = d_deviceBufferSizeBytes + d_leadSizeBytes;
+  d_inputBufferSizeFrames = d_deviceBufferSizeFrames + d_leadSizeFrames;
+
+// outBufSizeBytes = floor (inBufSizeBytes * rate_out / rate_in)
+// since this is rarely exact, we need another buffer to hold
+// "extra" samples not processed at any given sampling period
+// this buffer must be at least 4 floats in size, but generally
+// follows the rule that
+// extraBufSize =  ceil (rate_in / rate_out)*sizeof(float)
+
+  d_extraBufferSizeFrames = ((UInt32) ceil (d_deviceSampleRate
+                                           / d_outputSampleRate)
+                            * sizeof (float));
+  if (d_extraBufferSizeFrames < 4)
+    d_extraBufferSizeFrames = 4;
+  d_extraBufferSizeBytes = d_extraBufferSizeFrames * sizeof (float);
+
+  d_outputBufferSizeFrames = (UInt32) ceil (((Float64) d_inputBufferSizeFrames)
+                                           * d_outputSampleRate
+                                           / d_deviceSampleRate);
+  d_outputBufferSizeBytes = d_outputBufferSizeFrames * sizeof (float);
+  d_inputBufferSizeFrames += d_extraBufferSizeFrames;
+
+// pre-alloc all buffers
+
+  AllocAudioBufferList (&d_InputBuffer, d_n_deviceChannels,
+                       d_inputBufferSizeBytes);
+  if (d_passThrough == false) {
+    AllocAudioBufferList (&d_OutputBuffer, d_n_max_channels,
+                         d_outputBufferSizeBytes);
+  } else {
+    d_OutputBuffer = d_InputBuffer;
+  }
+
+// create the stuff to regulate I/O
+
+  d_internal = new mld_mutex ();
+  if (d_internal == NULL)
+    CheckErrorAndThrow (errno, "new mld_mutex (internal)",
+                       "audio_osx_source::audio_osx_source");
+
+  d_cond_data = new mld_condition ();
+  if (d_cond_data == NULL)
+    CheckErrorAndThrow (errno, "new mld_condition (data)",
+                       "audio_osx_source::audio_osx_source");
+
+// initialize the AU for input
+
+  err = AudioUnitInitialize (d_InputAU);
+  CheckErrorAndThrow (err, "AudioUnitInitialize",
+                     "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);
+#endif
+}
+
+void
+audio_osx_source::AllocAudioBufferList (AudioBufferList** t_ABL,
+                                       UInt32 n_channels,
+                                       UInt32 bufferSizeBytes)
+{
+  FreeAudioBufferList (t_ABL);
+  UInt32 propertySize = (offsetof (AudioBufferList, mBuffers[0]) +
+                        (sizeof (AudioBuffer) * n_channels));
+  *t_ABL = (AudioBufferList*) calloc (1, propertySize);
+  (*t_ABL)->mNumberBuffers = n_channels;
+
+  int counter = n_channels;
+
+  while (--counter >= 0) {
+    (*t_ABL)->mBuffers[counter].mNumberChannels = 1;
+    (*t_ABL)->mBuffers[counter].mDataByteSize = bufferSizeBytes;
+    (*t_ABL)->mBuffers[counter].mData = calloc (1, bufferSizeBytes);
+  }
+}
+
+void
+audio_osx_source::FreeAudioBufferList (AudioBufferList** t_ABL)
+{
+// free pre-allocated audio buffer, if it exists
+  if (*t_ABL != NULL) {
+    int counter = (*t_ABL)->mNumberBuffers;
+    while (--counter >= 0)
+      free ((*t_ABL)->mBuffers[counter].mData);
+    free (*t_ABL);
+    (*t_ABL) = 0;
+  }
+}
+
+bool audio_osx_source::IsRunning ()
+{
+  UInt32 AURunning = 0, AUSize = sizeof (UInt32);
+
+  OSStatus err = AudioUnitGetProperty (d_InputAU,
+                                      kAudioOutputUnitProperty_IsRunning,
+                                      kAudioUnitScope_Global,
+                                      0,
+                                      &AURunning,
+                                      &AUSize);
+  CheckErrorAndThrow (err, "AudioUnitGetProperty IsRunning",
+                     "audio_osx_source::IsRunning");
+
+  return (AURunning);
+}
+
+bool audio_osx_source::start ()
+{
+  if (! IsRunning ()) {
+    OSStatus err = AudioOutputUnitStart (d_InputAU);
+    CheckErrorAndThrow (err, "AudioOutputUnitStart",
+                       "audio_osx_source::start");
+  }
+
+  return (true);
+}
+
+bool audio_osx_source::stop ()
+{
+  if (IsRunning ()) {
+    OSStatus err = AudioOutputUnitStop (d_InputAU);
+    CheckErrorAndThrow (err, "AudioOutputUnitStart",
+                       "audio_osx_source::stop");
+    for (UInt32 n = 0; n < d_n_user_channels; n++) {
+      d_buffers[n]->abort ();
+    }
+  }
+
+  return (true);
+}
+
+audio_osx_source::~audio_osx_source ()
+{
+  OSStatus err = noErr;
+
+// stop the AudioUnit
+  stop();
+
+#if _OSX_DO_LISTENERS_
+// remove the listeners
+
+  err = AudioUnitRemovePropertyListener
+    (d_InputAU,
+     kAudioUnitProperty_StreamFormat,
+     (AudioUnitPropertyListenerProc) UnitListener);
+  CheckError (err, "~audio_osx_source: AudioUnitRemovePropertyListener");
+
+  err = AudioHardwareRemovePropertyListener
+    (kAudioHardwarePropertyDefaultInputDevice,
+     (AudioHardwarePropertyListenerProc) HardwareListener);
+  CheckError (err, "~audio_osx_source: AudioHardwareRemovePropertyListener");
+#endif
+
+// free pre-allocated audio buffers
+  FreeAudioBufferList (&d_InputBuffer);
+
+  if (d_passThrough == false) {
+    err = AudioConverterDispose (d_AudioConverter);
+    CheckError (err, "~audio_osx_source: AudioConverterDispose");
+    FreeAudioBufferList (&d_OutputBuffer);
+  }
+
+// remove the audio unit
+  err = AudioUnitUninitialize (d_InputAU);
+  CheckError (err, "~audio_osx_source: AudioUnitUninitialize");
+
+  err = CloseComponent (d_InputAU);
+  CheckError (err, "~audio_osx_source: CloseComponent");
+
+// empty and delete the queues
+  for (UInt32 n = 0; n < d_n_max_channels; n++) {
+    delete d_buffers[n];
+    d_buffers[n] = 0;
+  }
+  delete [] d_buffers;
+  d_buffers = 0;
+
+// close and delete the control stuff
+  delete d_internal;
+  delete d_cond_data;
+}
+
+audio_osx_source_sptr
+audio_osx_make_source (int sampling_freq,
+                      const std::string device_name,
+                      bool do_block,
+                      int channel_config,
+                      int max_sample_count)
+{
+  return audio_osx_source_sptr (new audio_osx_source (sampling_freq,
+                                                     device_name,
+                                                     do_block,
+                                                     channel_config,
+                                                     max_sample_count));
+}
+
+bool
+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);
+    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);
+    throw std::runtime_error ("audio_osx_source::check_topology()");
+  }
+
+// save the actual number of output (user) channels
+  d_n_user_channels = noutputs;
+
+#if _OSX_AU_DEBUG_
+  fprintf (stderr, "chk_topo: Actual # user output channels = %d\n",
+          noutputs);
+#endif
+
+  return (true);
+}
+
+int
+audio_osx_source::work (int noutput_items,
+                       gr_vector_const_void_star &input_items,
+                       gr_vector_void_star &output_items)
+{
+// acquire control to do processing here only
+  d_internal->wait ();
+
+#if _OSX_AU_DEBUG_
+  fprintf (stderr, "work1: SC = %4ld, #OI = %4d, #Chan = %ld\n",
+          d_queueSampleCount, noutput_items, output_items.size());
+#endif
+
+// ?: always block until there is something to output from the source
+//    or return anything that is available, even if it's less than desired?
+
+  UInt32 actual_noutput_items = noutput_items;
+
+  if (d_queueSampleCount < actual_noutput_items) {
+    if (d_queueSampleCount == 0) {
+// no data; do_block decides what to do
+      if (d_do_block == true) {
+       while (d_queueSampleCount == 0) {
+// release control so-as to allow data to be retrieved
+         d_internal->post ();
+// block until there is data to return
+         d_cond_data->wait ();
+// the condition's signal() was called; acquire control
+// to keep thread safe
+         d_internal->wait ();
+       }
+      } else {
+// not enough data & not blocking; return nothing
+       return (0);
+      }
+    }
+    actual_noutput_items = d_queueSampleCount;
+  }
+
+  int l_counter = (int) output_items.size();
+
+// get the items from the circular buffers
+  while (--l_counter >= 0) {
+    UInt32 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);
+      throw std::runtime_error ("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->post ();
+
+  return (actual_noutput_items);
+}
+
+OSStatus
+audio_osx_source::ConverterCallback (AudioConverterRef inAudioConverter,
+                                    UInt32* ioNumberDataPackets,
+                                    AudioBufferList* ioData,
+                                    AudioStreamPacketDescription** ioASPD,
+                                    void* inUserData)
+{
+// take current device buffers and copy them to the tail of the input buffers
+// the lead buffer is already there in the first d_leadSizeFrames slots
+
+  audio_osx_source* This = static_cast<audio_osx_source*>(inUserData);
+  AudioBufferList* l_inputABL = This->d_InputBuffer;
+  UInt32 totalInputBufferSizeBytes = ((*ioNumberDataPackets) * sizeof (float));
+  int counter = This->d_n_deviceChannels;
+  ioData->mNumberBuffers = This->d_n_deviceChannels;
+  This->d_n_ActualInputFrames = (*ioNumberDataPackets);
+
+#if _OSX_AU_DEBUG_
+  fprintf (stderr, "cc1: io#DP = %ld, TIBSB = %ld, #C = %d\n",
+          *ioNumberDataPackets, totalInputBufferSizeBytes, counter);
+#endif
+
+  while (--counter >= 0)  {
+    AudioBuffer* l_ioD_AB = &(ioData->mBuffers[counter]);
+    l_ioD_AB->mNumberChannels = 1;
+    l_ioD_AB->mData = (float*)(l_inputABL->mBuffers[counter].mData);
+    l_ioD_AB->mDataByteSize = totalInputBufferSizeBytes;
+  }
+
+  return (noErr);
+}
+
+OSStatus
+audio_osx_source::AUInputCallback (void* inRefCon,
+                                  AudioUnitRenderActionFlags* ioActionFlags,
+                                  const AudioTimeStamp* inTimeStamp,
+                                  UInt32 inBusNumber,
+                                  UInt32 inNumberFrames,
+                                  AudioBufferList* ioData)
+{
+  OSStatus err = noErr;
+  audio_osx_source* This = static_cast<audio_osx_source*>(inRefCon);
+
+  This->d_internal->wait ();
+
+#if _OSX_AU_DEBUG_
+  fprintf (stderr, "cb0: in#F = %4ld, inBN = %ld, SC = %4ld\n",
+          inNumberFrames, inBusNumber, This->d_queueSampleCount);
+#endif
+
+// Get the new audio data from the input device
+
+  err = AudioUnitRender (This->d_InputAU,
+                        ioActionFlags,
+                        inTimeStamp,
+                        1, //inBusNumber,
+                        inNumberFrames,
+                        This->d_InputBuffer);
+  CheckErrorAndThrow (err, "AudioUnitRender",
+                     "audio_osx_source::AUInputCallback");
+
+  UInt32 AvailableInputFrames = inNumberFrames;
+  This->d_n_AvailableInputFrames = inNumberFrames;
+
+// get the number of actual output frames,
+// either via converting the buffer or not
+
+  UInt32 ActualOutputFrames;
+
+  if (This->d_passThrough == true) {
+    ActualOutputFrames = AvailableInputFrames;
+  } else {
+    UInt32 AvailableInputBytes = AvailableInputFrames * sizeof (float);
+    UInt32 AvailableOutputBytes = AvailableInputBytes;
+    UInt32 AvailableOutputFrames = AvailableOutputBytes / sizeof (float);
+    UInt32 propertySize = sizeof (AvailableOutputBytes);
+    err = AudioConverterGetProperty (This->d_AudioConverter,
+                  kAudioConverterPropertyCalculateOutputBufferSize,
+                                    &propertySize,
+                                    &AvailableOutputBytes);
+    CheckErrorAndThrow (err, "AudioConverterGetProperty CalculateOutputBufferSize", "audio_osx_source::audio_osx_source");
+
+    AvailableOutputFrames = AvailableOutputBytes / sizeof (float);
+
+#if 0
+// when decimating too much, the output sounds warbly due to
+// fluctuating # of output frames
+// This should not be a surprise, but there's probably some
+// clever programming that could lessed the effect ...
+// like finding the "ideal" # of output frames, and keeping
+// that number constant no matter the # of input frames
+    UInt32 l_InputBytes = AvailableOutputBytes;
+    propertySize = sizeof (AvailableOutputBytes);
+    err = AudioConverterGetProperty (This->d_AudioConverter,
+                    kAudioConverterPropertyCalculateInputBufferSize,
+                                    &propertySize,
+                                    &l_InputBytes);
+    CheckErrorAndThrow (err, "AudioConverterGetProperty CalculateInputBufferSize", "audio_osx_source::audio_osx_source");
+
+    if (l_InputBytes < AvailableInputBytes) {
+// OK to zero pad the input a little
+      AvailableOutputFrames += 1;
+      AvailableOutputBytes = AvailableOutputFrames * sizeof (float);
+    }
+#endif
+
+#if _OSX_AU_DEBUG_
+    fprintf (stderr, "cb1:  avail: #IF = %ld, #OF = %ld\n",
+            AvailableInputFrames, AvailableOutputFrames);
+#endif
+    ActualOutputFrames = AvailableOutputFrames;
+
+// convert the data to the correct rate
+// on input, ActualOutputFrames is the number of available output frames
+
+    err = AudioConverterFillComplexBuffer (This->d_AudioConverter,
+          (AudioConverterComplexInputDataProc)(This->ConverterCallback),
+                                          inRefCon,
+                                          &ActualOutputFrames,
+                                          This->d_OutputBuffer,
+                                          NULL);
+    CheckErrorAndThrow (err, "AudioConverterFillComplexBuffer",
+                       "audio_osx_source::AUInputCallback");
+
+// 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);
+    if (This->d_n_ActualInputFrames != AvailableInputFrames)
+      fprintf (stderr, "cb2.1: avail#IF = %ld, actual#IF = %ld\n",
+              AvailableInputFrames, This->d_n_ActualInputFrames);
+#endif
+  }
+
+// add the output frames to the buffers' queue, checking for overflow
+
+  int l_counter = This->d_n_user_channels;
+  int res = 0;
+
+  while (--l_counter >= 0) {
+    float* inBuffer = (float*) This->d_OutputBuffer->mBuffers[l_counter].mData;
+    int l_res = This->d_buffers[l_counter]->enqueue (inBuffer, ActualOutputFrames);
+    if (l_res == -1)
+      res = -1;
+  }
+
+  if (res == -1) {
+// data coming in too fast
+// drop oldest buffer
+    fputs ("aO", stderr);
+    fflush (stderr);
+// set the local number of samples available to the max
+    This->d_queueSampleCount = This->d_buffers[0]->buffer_length_items ();
+  } else {
+// keep up the local sample count
+    This->d_queueSampleCount += ActualOutputFrames;
+  }
+
+#if _OSX_AU_DEBUG_
+  fprintf (stderr, "cb5: #OI = %4ld, #Cnt = %4ld, mSC = %ld, \n",
+          ActualOutputFrames, This->d_queueSampleCount,
+          This->d_max_sample_count);
+#endif
+
+// signal that data is available, if appropraite
+  This->d_cond_data->signal ();
+
+// release control to allow for other processing parts to run
+  This->d_internal->post ();
+
+  return (err);
+}
+
+void
+audio_osx_source::SetDefaultInputDeviceAsCurrent
+()
+{
+// set the default input device
+  AudioDeviceID deviceID;
+  UInt32 dataSize = sizeof (AudioDeviceID);
+  AudioHardwareGetProperty (kAudioHardwarePropertyDefaultInputDevice,
+                           &dataSize,
+                           &deviceID);
+  OSStatus err = AudioUnitSetProperty (d_InputAU,
+                                      kAudioOutputUnitProperty_CurrentDevice,
+                                      kAudioUnitScope_Global,
+                                      0,
+                                      &deviceID,
+                                      sizeof (AudioDeviceID));
+  CheckErrorAndThrow (err, "AudioUnitSetProperty Current Device",
+                     "audio_osx_source::SetDefaultInputDeviceAsCurrent");
+}
+
+#if _OSX_DO_LISTENERS_
+OSStatus
+audio_osx_source::HardwareListener
+(AudioHardwarePropertyID inPropertyID, 
+ void *inClientData)
+{
+  OSStatus err = noErr;
+  audio_osx_source* This = static_cast<audio_osx_source*>(inClientData);
+
+  fprintf (stderr, "a_o_s::HardwareListener\n");
+
+// set the new default hardware input device for use by our AU
+
+  This->SetDefaultInputDeviceAsCurrent ();
+
+// reset the converter to tell it that the stream has changed
+
+  err = AudioConverterReset (This->d_AudioConverter);
+  CheckErrorAndThrow (err, "AudioConverterReset",
+                     "audio_osx_source::UnitListener");
+
+  return (err);
+}
+
+OSStatus
+audio_osx_source::UnitListener
+(void *inRefCon,
+ AudioUnit ci,
+ AudioUnitPropertyID inID,
+ AudioUnitScope inScope,
+ AudioUnitElement inElement)
+{
+  OSStatus err = noErr;
+  audio_osx_source* This = static_cast<audio_osx_source*>(inRefCon);
+  AudioStreamBasicDescription asbd;                    
+
+  fprintf (stderr, "a_o_s::UnitListener\n");
+
+// get the converter's input ASBD (for printing)
+
+  UInt32 propertySize = sizeof (asbd);
+  err = AudioConverterGetProperty (This->d_AudioConverter,
+                                  kAudioConverterCurrentInputStreamDescription,
+                                  &propertySize,
+                                  &asbd);
+  CheckErrorAndThrow (err, "AudioConverterGetProperty "
+                     "CurrentInputStreamDescription",
+                     "audio_osx_source::UnitListener");
+
+  fprintf (stderr, "UnitListener: Input Source changed.\n"
+          "Old Source Output Info:\n");
+  PrintStreamDesc (&asbd);
+
+// get the new input unit's output ASBD
+
+  propertySize = sizeof (asbd);
+  err = AudioUnitGetProperty (This->d_InputAU,
+                             kAudioUnitProperty_StreamFormat,
+                             kAudioUnitScope_Output, 1,
+                             &asbd, &propertySize);
+  CheckErrorAndThrow (err, "AudioUnitGetProperty StreamFormat",
+                     "audio_osx_source::UnitListener");
+
+  fprintf (stderr, "New Source Output Info:\n");
+  PrintStreamDesc (&asbd);
+
+// set the converter's input ASBD to this
+
+  err = AudioConverterSetProperty (This->d_AudioConverter,
+                                  kAudioConverterCurrentInputStreamDescription,
+                                  propertySize,
+                                  &asbd);
+  CheckErrorAndThrow (err, "AudioConverterSetProperty "
+                     "CurrentInputStreamDescription",
+                     "audio_osx_source::UnitListener");
+
+// reset the converter to tell it that the stream has changed
+
+  err = AudioConverterReset (This->d_AudioConverter);
+  CheckErrorAndThrow (err, "AudioConverterReset",
+                     "audio_osx_source::UnitListener");
+
+  return (err);
+}
+#endif
diff --git a/gr-audio-osx/src/audio_osx_source.h b/gr-audio-osx/src/audio_osx_source.h
new file mode 100644 (file)
index 0000000..1799588
--- /dev/null
@@ -0,0 +1,132 @@
+/* -*- 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 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.
+ */
+
+#ifndef INCLUDED_AUDIO_OSX_SOURCE_H
+#define INCLUDED_AUDIO_OSX_SOURCE_H
+
+#include <gr_sync_block.h>
+#include <string>
+#include <AudioToolbox/AudioToolbox.h>
+#include <AudioUnit/AudioUnit.h>
+#include <circular_buffer.h>
+
+class audio_osx_source;
+typedef boost::shared_ptr<audio_osx_source> audio_osx_source_sptr;
+
+audio_osx_source_sptr
+audio_osx_make_source (int sample_rate = 44100,
+                      const std::string device_name = "",
+                      bool do_block = true,
+                      int channel_config = -1,
+                      int max_sample_count = -1);
+
+/*!
+ * \brief audio source using OSX
+ *
+ * Input signature is one or two streams of floats.
+ * Samples must be in the range [-1,1].
+ */
+
+class audio_osx_source : public gr_sync_block {
+  friend audio_osx_source_sptr
+  audio_osx_make_source (int sample_rate,
+                        const std::string device_name,
+                        bool do_block,
+                        int channel_config,
+                        int max_sample_count);
+
+  Float64             d_deviceSampleRate, d_outputSampleRate;
+  int                 d_channel_config;
+  UInt32              d_inputBufferSizeFrames, d_inputBufferSizeBytes;
+  UInt32              d_outputBufferSizeFrames, d_outputBufferSizeBytes;
+  UInt32              d_deviceBufferSizeFrames, d_deviceBufferSizeBytes;
+  UInt32              d_leadSizeFrames, d_leadSizeBytes;
+  UInt32              d_trailSizeFrames, d_trailSizeBytes;
+  UInt32              d_extraBufferSizeFrames, d_extraBufferSizeBytes;
+  UInt32              d_queueSampleCount, d_max_sample_count;
+  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;
+  circular_buffer<float>** d_buffers;
+
+// AudioUnits and Such
+  AudioUnit           d_InputAU;
+  AudioBufferList*    d_InputBuffer;
+  AudioBufferList*    d_OutputBuffer;
+  AudioConverterRef   d_AudioConverter;
+
+protected:
+  audio_osx_source (int sample_rate = 44100,
+                   const std::string device_name = "",
+                   bool do_block = true,
+                   int channel_config = -1,
+                   int max_sample_count = -1);
+
+public:
+  ~audio_osx_source ();
+
+  bool start ();
+  bool stop ();
+  bool IsRunning ();
+
+  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);
+
+private:
+  void SetDefaultInputDeviceAsCurrent ();
+
+  void AllocAudioBufferList (AudioBufferList** t_ABL,
+                            UInt32 n_channels,
+                            UInt32 inputBufferSizeBytes);
+
+  void FreeAudioBufferList (AudioBufferList** t_ABL);
+
+  static OSStatus ConverterCallback (AudioConverterRef inAudioConverter,
+                                    UInt32* ioNumberDataPackets,
+                                    AudioBufferList* ioData,
+                                    AudioStreamPacketDescription** outASPD,
+                                    void* inUserData);
+
+  static OSStatus AUInputCallback (void *inRefCon,
+                                  AudioUnitRenderActionFlags *ioActionFlags,
+                                  const AudioTimeStamp *inTimeStamp,
+                                  UInt32 inBusNumber,
+                                  UInt32 inNumberFrames,
+                                  AudioBufferList *ioData);
+#if _OSX_DO_LISTENERS_
+  static OSStatus UnitListener (void *inRefCon,
+                               AudioUnit ci,
+                               AudioUnitPropertyID inID,
+                               AudioUnitScope inScope,
+                               AudioUnitElement inElement);
+
+  static OSStatus HardwareListener (AudioHardwarePropertyID inPropertyID, 
+                                   void *inClientData);
+#endif
+};
+
+#endif /* INCLUDED_AUDIO_OSX_SOURCE_H */
diff --git a/gr-audio-osx/src/circular_buffer.h b/gr-audio-osx/src/circular_buffer.h
new file mode 100644 (file)
index 0000000..f644e7d
--- /dev/null
@@ -0,0 +1,326 @@
+/* -*- 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 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.
+ */
+
+#ifndef _CIRCULAR_BUFFER_H_
+#define _CIRCULAR_BUFFER_H_
+
+#include "mld_threads.h"
+#include <stdexcept>
+
+#define DO_DEBUG 0
+
+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;
+
+// stuff to control access to class internals
+  mld_mutex_ptr d_internal;
+  mld_condition_ptr d_readBlock, 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 (UInt32 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 ();
+#if DO_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"));
+#endif
+  };
+
+  ~circular_buffer () {
+    delete_mutex_cond ();
+    delete [] d_buffer;
+  };
+
+  inline UInt32 n_avail_write_items () {
+    d_internal->lock ();
+    UInt32 retVal = d_n_avail_write_I;
+    d_internal->unlock ();
+    return (retVal);
+  };
+
+  inline UInt32 n_avail_read_items () {
+    d_internal->lock ();
+    UInt32 retVal = d_n_avail_read_I;
+    d_internal->unlock ();
+    return (retVal);
+  };
+
+  inline UInt32 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 ();
+    d_internal = new mld_mutex ();
+    d_readBlock = new mld_condition ();
+    d_writeBlock = new mld_condition ();
+  };
+
+/*
+ * 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, UInt32 bufLen_I) {
+#if DO_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);
+#endif
+    if (bufLen_I > d_bufLen_I) {
+      fprintf (stderr, "cannot add buffer longer (%ld"
+              ") than instantiated length (%ld"
+              ").\n", bufLen_I, d_bufLen_I);
+      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");
+    d_internal->lock ();
+    if (d_doAbort) {
+      d_internal->unlock ();
+      return (2);
+    }
+    if (bufLen_I > d_n_avail_write_I) {
+      if (d_doWriteBlock) {
+       while (bufLen_I > d_n_avail_write_I) {
+#if DO_DEBUG
+         fprintf (stderr, "enqueue: #len > #a, waiting.\n");
+#endif
+         d_internal->unlock ();
+         d_writeBlock->wait ();
+         d_internal->lock ();
+         if (d_doAbort) {
+           d_internal->unlock ();
+#if DO_DEBUG
+           fprintf (stderr, "enqueue: #len > #a, aborting.\n");
+#endif
+           return (2);
+         }
+#if DO_DEBUG
+         fprintf (stderr, "enqueue: #len > #a, done waiting.\n");
+#endif
+       }
+      } else {
+       d_n_avail_read_I = d_bufLen_I - bufLen_I;
+       d_n_avail_write_I = bufLen_I;
+#if DO_DEBUG
+       fprintf (stderr, "circular_buffer::enqueue: overflow\n");
+#endif
+       return (-1);
+      }
+    }
+    UInt32 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->signal ();
+    d_internal->unlock ();
+    return (1);
+  };
+
+/*
+ * 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, UInt32* bufLen_I) {
+#if DO_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);
+#endif
+    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;
+    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);
+      throw std::runtime_error ("circular_buffer::dequeue()");
+    }
+
+    d_internal->lock ();
+    if (d_doAbort) {
+      d_internal->unlock ();
+      return (2);
+    }
+    if (d_doFullRead) {
+      while (d_n_avail_read_I < l_bufLen_I) {
+#if DO_DEBUG
+       fprintf (stderr, "dequeue: #a < #len, waiting.\n");
+#endif
+       d_internal->unlock ();
+       d_readBlock->wait ();
+       d_internal->lock ();
+       if (d_doAbort) {
+         d_internal->unlock ();
+#if DO_DEBUG
+         fprintf (stderr, "dequeue: #a < #len, aborting.\n");
+#endif
+         return (2);
+       }
+#if DO_DEBUG
+       fprintf (stderr, "dequeue: #a < #len, done waiting.\n");
+#endif
+     }
+    } else {
+      while (d_n_avail_read_I == 0) {
+#if DO_DEBUG
+       fprintf (stderr, "dequeue: #a == 0, waiting.\n");
+#endif
+       d_internal->unlock ();
+       d_readBlock->wait ();
+       d_internal->lock ();
+       if (d_doAbort) {
+         d_internal->unlock ();
+#if DO_DEBUG
+         fprintf (stderr, "dequeue: #a == 0, aborting.\n");
+#endif
+         return (2);
+       }
+#if DO_DEBUG
+       fprintf (stderr, "dequeue: #a == 0, done waiting.\n");
+#endif
+      }
+    }
+    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;
+    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->signal ();
+    d_internal->unlock ();
+    return (1);
+  };
+
+  void abort () {
+    d_internal->lock ();
+    d_doAbort = true;
+    d_writeBlock->signal ();
+    d_readBlock->signal ();
+    d_internal->unlock ();
+  };
+};
+
+#endif /* _CIRCULAR_BUFFER_H_ */
diff --git a/gr-audio-osx/src/mld_threads.h b/gr-audio-osx/src/mld_threads.h
new file mode 100644 (file)
index 0000000..12adc23
--- /dev/null
@@ -0,0 +1,255 @@
+/* -*- 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 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.
+ */
+
+#ifndef _INCLUDED_MLD_THREADS_H_
+#define _INCLUDED_MLD_THREADS_H_
+
+/* classes which allow for either pthreads or omni_threads */
+
+#ifdef _USE_OMNI_THREADS_
+#include <gnuradio/omnithread.h>
+#else
+#include <pthread.h>
+#endif
+
+#include <stdexcept>
+
+#define __INLINE__ inline
+
+class mld_condition_t;
+
+class mld_mutex_t {
+#ifdef _USE_OMNI_THREADS_
+  typedef omni_mutex l_mutex, *l_mutex_ptr;
+#else
+  typedef pthread_mutex_t l_mutex, *l_mutex_ptr;
+#endif
+
+  friend class mld_condition_t;
+
+private:
+  l_mutex_ptr d_mutex;
+
+protected:
+  inline l_mutex_ptr mutex () { return (d_mutex); };
+
+public:
+  __INLINE__ mld_mutex_t () {
+#ifdef _USE_OMNI_THREADS_
+    d_mutex = new omni_mutex ();
+#else
+    d_mutex = (l_mutex_ptr) new l_mutex;
+    int l_ret = pthread_mutex_init (d_mutex, NULL);
+    if (l_ret != 0) {
+      fprintf (stderr, "Error %d creating mutex.\n", l_ret);
+      throw std::runtime_error ("mld_mutex_t::mld_mutex_t()\n");
+    }
+#endif
+  };
+
+  __INLINE__ ~mld_mutex_t () {
+    unlock ();
+#ifndef _USE_OMNI_THREADS_
+    int l_ret = pthread_mutex_destroy (d_mutex);
+    if (l_ret != 0) {
+      fprintf (stderr, "mld_mutex_t::~mld_mutex_t(): "
+              "Error %d destroying mutex.\n", l_ret);
+    }
+#endif
+    delete d_mutex;
+    d_mutex = NULL;
+  };
+
+  __INLINE__ void lock () {
+#ifdef _USE_OMNI_THREADS_
+    d_mutex->lock ();
+#else
+    int l_ret = pthread_mutex_lock (d_mutex);
+    if (l_ret != 0) {
+      fprintf (stderr, "mld_mutex_t::lock(): "
+              "Error %d locking mutex.\n", l_ret);
+    }
+#endif
+  };
+
+  __INLINE__ void unlock () {
+#ifdef _USE_OMNI_THREADS_
+    d_mutex->unlock ();
+#else
+    int l_ret = pthread_mutex_unlock (d_mutex);
+    if (l_ret != 0) {
+      fprintf (stderr, "mld_mutex_t::unlock(): "
+              "Error %d locking mutex.\n", l_ret);
+    }
+#endif
+  };
+
+  __INLINE__ bool trylock () {
+#ifdef _USE_OMNI_THREADS_
+    int l_ret = d_mutex->trylock ();
+#else
+    int l_ret = pthread_mutex_unlock (d_mutex);
+#endif
+    return (l_ret == 0 ? true : false);
+  };
+
+  inline void acquire () { lock(); };
+  inline void release () { unlock(); };
+  inline void wait () { lock(); };
+  inline void post () { unlock(); };
+};
+
+typedef mld_mutex_t mld_mutex, *mld_mutex_ptr;
+
+class mld_condition_t {
+#ifdef _USE_OMNI_THREADS_
+  typedef omni_condition l_condition, *l_condition_ptr;
+#else
+  typedef pthread_cond_t l_condition, *l_condition_ptr;
+#endif
+
+private:
+  l_condition_ptr d_condition;
+  mld_mutex_ptr d_mutex;
+  bool d_waiting;
+
+public:
+  __INLINE__ mld_condition_t () {
+    d_waiting = false;
+    d_mutex = new mld_mutex ();
+#ifdef _USE_OMNI_THREADS_
+    d_condition = new omni_condition (d_mutex->mutex ());
+#else
+    d_condition = (l_condition_ptr) new l_condition;
+    int l_ret = pthread_cond_init (d_condition, NULL);
+    if (l_ret != 0) {
+      fprintf (stderr, "Error %d creating condition.\n", l_ret);
+      throw std::runtime_error ("mld_condition_t::mld_condition_t()\n");
+    }
+#endif
+  };
+
+  __INLINE__ ~mld_condition_t () {
+    signal ();
+#ifndef _USE_OMNI_THREADS_
+    int l_ret = pthread_cond_destroy (d_condition);
+    if (l_ret != 0) {
+      fprintf (stderr, "mld_condition_t::mld_condition_t(): "
+              "Error %d destroying condition.\n", l_ret);
+    }
+#endif
+    delete d_condition;
+    d_condition = NULL;
+    delete d_mutex;
+    d_mutex = NULL;
+  };
+
+  __INLINE__ void signal () {
+    if (d_waiting == true) {
+#ifdef _USE_OMNI_THREADS_
+      d_condition->signal ();
+#else
+      int l_ret = pthread_cond_signal (d_condition);
+      if (l_ret != 0) {
+       fprintf (stderr, "mld_condition_t::signal(): "
+                "Error %d.\n", l_ret);
+      }
+#endif
+      d_waiting = false;
+    }
+  };
+
+  __INLINE__ void wait () {
+    if (d_waiting == false) {
+      d_waiting = true;
+#ifdef _USE_OMNI_THREADS_
+      d_condition->wait ();
+#else
+      int l_ret = pthread_cond_wait (d_condition, d_mutex->mutex ());
+      if (l_ret != 0) {
+       fprintf (stderr, "mld_condition_t::wait(): "
+                "Error %d.\n", l_ret);
+      }
+#endif
+    }
+  };
+};
+
+typedef mld_condition_t mld_condition, *mld_condition_ptr;
+
+class mld_thread_t {
+#ifdef _USE_OMNI_THREADS_
+  typedef omni_thread l_thread, *l_thread_ptr;
+#else
+  typedef pthread_t l_thread, *l_thread_ptr;
+#endif
+
+private:
+#ifndef _USE_OMNI_THREADS_
+  l_thread d_thread;
+  void (*d_start_routine)(void*);
+  void *d_arg;
+#else
+  l_thread_ptr d_thread;
+#endif
+
+#ifndef _USE_OMNI_THREADS_
+  static void* local_start_routine (void *arg) {
+    mld_thread_t* This = (mld_thread_t*) arg;
+    (*(This->d_start_routine))(This->d_arg);
+    return (NULL);
+  };
+#endif
+
+public:
+  __INLINE__ mld_thread_t (void (*start_routine)(void *), void *arg) {
+#ifdef _USE_OMNI_THREADS_
+    d_thread = new omni_thread (start_routine, arg);
+    d_thread->start ();
+#else
+    d_start_routine = start_routine;
+    d_arg = arg;
+    int l_ret = pthread_create (&d_thread, NULL, local_start_routine, this);
+    if (l_ret != 0) {
+      fprintf (stderr, "Error %d creating thread.\n", l_ret);
+      throw std::runtime_error ("mld_thread_t::mld_thread_t()\n");
+    }
+#endif
+  };
+
+  __INLINE__ ~mld_thread_t () {
+#ifdef _USE_OMNI_THREADS_
+//  delete d_thread;
+    d_thread = NULL;
+#else
+    int l_ret = pthread_detach (d_thread);
+    if (l_ret != 0) {
+      fprintf (stderr, "Error %d detaching thread.\n", l_ret);
+      throw std::runtime_error ("mld_thread_t::~mld_thread_t()\n");
+    }
+#endif
+  };
+};
+
+typedef mld_thread_t mld_thread, *mld_thread_ptr;
+
+#endif /* _INCLUDED_MLD_THREADS_H_ */
diff --git a/gr-audio-osx/src/qa_osx.py b/gr-audio-osx/src/qa_osx.py
new file mode 100755 (executable)
index 0000000..1e85c15
--- /dev/null
@@ -0,0 +1,40 @@
+#!/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 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.
+# 
+
+from gnuradio import gr, gr_unittest
+import audio_osx
+
+class qa_osx (gr_unittest.TestCase):
+
+    def setUp (self):
+        self.fg = gr.flow_graph ()
+
+    def tearDown (self):
+        self.fg = None
+
+    def test_000_nop (self):
+        """Just see if we can import the module...
+        They may not have OSX drivers, etc.  Don't try to run anything"""
+        pass
+    
+if __name__ == '__main__':
+    gr_unittest.main ()
diff --git a/gr-audio-osx/src/run_tests.in b/gr-audio-osx/src/run_tests.in
new file mode 100644 (file)
index 0000000..52de4dd
--- /dev/null
@@ -0,0 +1,47 @@
+#!/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@/gr-audio-osx/src
+# Where to look in the src tree for swig generated python code
+libsrc=@abs_top_srcdir@/gr-audio-osx/src
+# Where to look in the src tree for hand written python code
+py=@abs_top_srcdir@/gr-audio-osx/src
+
+# Where to look for GNU Radio python modules in current build tree
+# FIXME this is wrong on a distcheck.  We really need to ask gnuradio-core
+# where it put its python files.
+grpythonbld=@abs_top_builddir@/gnuradio-core/src/python/:@abs_top_builddir@/gnuradio-core/src/lib/swig/:@abs_top_builddir@/gnuradio-core/src/lib/swig/.libs
+
+PYTHONPATH="$grpythonbld:$libbld:$libbld/.libs:$libsrc:$py:$PYTHONPATH"
+export PYTHONPATH
+
+#
+# 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-audio-osx/src/test_audio_loop.py b/gr-audio-osx/src/test_audio_loop.py
new file mode 100755 (executable)
index 0000000..825908f
--- /dev/null
@@ -0,0 +1,65 @@
+#!/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 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.
+# 
+
+from gnuradio import gr
+from gnuradio import audio
+from gnuradio.eng_option import eng_option
+from optparse import OptionParser
+
+class my_graph(gr.flow_graph):
+
+    def __init__(self):
+        gr.flow_graph.__init__(self)
+
+        parser = OptionParser(option_class=eng_option)
+        parser.add_option("-O", "--audio-output",
+                         type="string",
+                         default="",
+                          help="audio output device name. E.g., hw:0,0 or /dev/dsp")
+        parser.add_option("-I", "--audio-input",
+                         type="string",
+                         default="",
+                          help="audio input device name.  E.g., hw:0,0 or /dev/dsp")
+        parser.add_option("-r", "--sample-rate",
+                         type="eng_float",
+                         default=48000,
+                          help="set sample rate to RATE (48000)")
+        (options, args) = parser.parse_args ()
+        if len(args) != 0:
+            parser.print_help()
+            raise SystemExit, 1
+
+        sample_rate = int(options.sample_rate)
+        src = audio.source (sample_rate, options.audio_output)
+        dst = audio.sink (sample_rate, options.audio_output)
+
+        max_chan = max (src.output_signature().max_streams(),
+                       dst.output_signature().max_streams())
+
+       for i in range (max_chan):
+               self.connect ((src, i), (dst, i))
+
+if __name__ == '__main__':
+    try:
+        my_graph().run()
+    except KeyboardInterrupt:
+        pass
diff --git a/gr-audio-portaudio/AUTHORS b/gr-audio-portaudio/AUTHORS
new file mode 100644 (file)
index 0000000..65ca901
--- /dev/null
@@ -0,0 +1,2 @@
+Eric Blossom <eb@comsec.com>
+Ramakrishnan Muthukrishnan <rkrishnan@debian.org>
diff --git a/gr-audio-portaudio/ChangeLog b/gr-audio-portaudio/ChangeLog
new file mode 100644 (file)
index 0000000..3683890
--- /dev/null
@@ -0,0 +1,31 @@
+2006-03-17  Eric Blossom  <eb@comsec.com>
+
+       * src/audio_portaudio_sink.{h,cc}: revised to use a gr_buffer as the
+       ring buffer.
+
+2006-03-12  Stephane Fillod  <f8cfe@free.fr>
+
+       * src/audio_portaudio_source.{h,cc}: first cut from gr-audio-jack sources.
+       * src/audio_portaudio_sink.{h,cc}: first cut from gr-audio-jack sources.
+
+
+#
+# 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 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.
+# 
diff --git a/gr-audio-portaudio/Makefile.am b/gr-audio-portaudio/Makefile.am
new file mode 100644 (file)
index 0000000..d7a05ea
--- /dev/null
@@ -0,0 +1,28 @@
+#
+# 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 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.
+# 
+
+include $(top_srcdir)/Makefile.common
+
+EXTRA_DIST = gr-audio-portaudio.conf
+SUBDIRS = src
+
+etcdir = $(sysconfdir)/gnuradio/conf.d
+etc_DATA = gr-audio-portaudio.conf
diff --git a/gr-audio-portaudio/README b/gr-audio-portaudio/README
new file mode 100644 (file)
index 0000000..6074c0b
--- /dev/null
@@ -0,0 +1,92 @@
+These instructions are intended for Linux. On other systems you will have to
+construct something compatible to build gr-audio-portaudio.
+
+In order to use portaudio with gnuradio you will need to download and install
+a late version of portaudio.  Please cd to a directory where the cvs command
+below will be allowed to build the portaudio directory tree.
+
+cvs -d:pserver:anonymous@www.portaudio.com:/home/cvs co -r v19-devel portaudio
+
+This will make a directory portaudio unless you already have one.  It will
+check out the Portaudio API version 2 release 1.9.
+
+In the directory where this README is found, there is a patch file.  Hopefully
+this patch will not be needed for long.  Portaudio is working with us to use
+auto*, libtool, etc.  The patch is autoconfiscate.patch.  
+
+cd to the portaudio directory and run
+
+patch -p0 <autoconfiscate.patch
+
+this will modify the portaudio source tree to use standard tools and prepare
+it for use with gnuradio.  Now run
+
+chmod u+x bootstrap
+
+you may need to edit bootstrap and remove the 2.50 at the end of some of the
+commands (on SUSE 10.0 for example).
+
+./bootstrap
+
+./configure --help 
+
+
+will reveal the options for configure that are available to you. If you do not
+understand the options or wish to accept the defaults please just run
+
+./configure
+
+If you do not want the includes and libraries install in /usr/local (standard)
+then enter the prefix arguments to ./configure.  This document will assume you
+are doing the standard installation and that will be into /usr/local.
+
+On Linux if you have the jack tool available from 
+
+http://jackit.sourceforge.net
+
+the portaudio configure will enable the library to talk to jack.
+
+Now you are ready to make the portaudio library.
+
+make; sudo make install;sudo ldconfig  (possibly /sbin/ldconfig).
+
+will make the code and install it into the prefix (/usr/local) selected and
+will cache the configuration information for other programs to use for their
+configuration options.
+
+Now you are ready to install gr-audio-portaudio.  In the gr-build directory
+you may run
+
+cvs co gr-audio-portaudio
+
+cd gr-audio-portaudio
+../buildit
+
+will configure, make, and install the portaudio sink and source.
+
+In gnuradio-examples/python/audio please test by running
+
+./mono_tone_portaudio.py
+
+
+If this runs you are likely in business but this chooses the default device
+(typically /dev/dsp which is being run by alsa under oss emulation and on a
+Mac it will choose coreaudio).
+
+./mono_tone_portaudio.py -O hw:0,0
+
+chooses the default alsa device.
+
+./mono_tone_portaudio.py -O /dev/dsp
+
+will force the use of OSS and the default oss device. To run with jack,  you
+will probably enter the following command:
+
+./mono_tone_portaudio.py -O alsa_pcm
+
+
+In the portaudio directory,  you may list the devices visible to portaudio by
+searching for and running the command
+
+pa_devs
+
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/gr-audio-portaudio.conf b/gr-audio-portaudio/gr-audio-portaudio.conf
new file mode 100644 (file)
index 0000000..0dd1474
--- /dev/null
@@ -0,0 +1,10 @@
+# This file contains system wide configuration data for GNU Radio.
+# You may override any setting on a per-user basis by editing
+# ~/.gnuradio/config.conf
+
+[audio_portaudio]
+
+#default_input_device = hw:0,0
+#default_output_device = hw:0,0
+
+verbose = false
diff --git a/gr-audio-portaudio/src/Makefile.am b/gr-audio-portaudio/src/Makefile.am
new file mode 100644 (file)
index 0000000..1b6d518
--- /dev/null
@@ -0,0 +1,92 @@
+#
+# 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.
+# 
+
+include $(top_srcdir)/Makefile.common
+
+LIBS += $(GNURADIO_CORE_LIBS)
+
+# Install this stuff so that it ends up as the gnuradio.audio_portaudio module
+# This usually ends up at:
+#   ${prefix}/lib/python${python_version}/site-packages/gnuradio
+
+ourpythondir = $(grpythondir)
+ourlibdir    = $(grpyexecdir)
+
+EXTRA_DIST = run_tests.in
+
+TESTS = run_tests
+
+LOCAL_IFILES =                                 \
+       audio_portaudio.i                               
+
+NON_LOCAL_IFILES =                     \
+       $(top_srcdir)/gnuradio-core/src/lib/swig/gnuradio.i
+
+ALL_IFILES =                           \
+       $(LOCAL_IFILES)                 \
+       $(NON_LOCAL_IFILES)             
+
+BUILT_SOURCES =                        \
+       audio_portaudio.cc                      \
+       audio_portaudio.py                              
+
+ourpython_PYTHON =                     \
+       audio_portaudio.py
+
+INCLUDES = $(STD_DEFINES_AND_INCLUDES) $(PYTHON_CPPFLAGS)
+
+SWIGPYTHONARGS = $(SWIGPYTHONFLAGS) $(STD_DEFINES_AND_INCLUDES) -I/usr/include
+
+ourlib_LTLIBRARIES = _audio_portaudio.la
+
+
+_audio_portaudio_la_SOURCES =          \
+       audio_portaudio.cc              \
+       audio_portaudio_sink.cc         \
+       audio_portaudio_source.cc       \
+       gri_portaudio.cc                        
+
+grinclude_HEADERS =                    \
+       audio_portaudio_sink.h          \
+       audio_portaudio_source.h                
+
+noinst_HEADERS =                       \
+       gri_portaudio.h                 
+
+
+swiginclude_HEADERS =                  \
+       $(LOCAL_IFILES)
+
+_audio_portaudio_la_LIBADD =           \
+       $(PYTHON_LDFLAGS)               \
+       -lstdc++                                
+
+_audio_portaudio_la_LDFLAGS = $(NO_UNDEFINED) -module -avoid-version
+
+audio_portaudio.cc audio_portaudio.py: $(ALL_IFILES) audio_portaudio_sink.h audio_portaudio_source.h
+       $(SWIG) $(SWIGPYTHONARGS) -module audio_portaudio -o audio_portaudio.cc $<
+
+
+noinst_PYTHON =                        \
+       qa_portaudio.py                 
+
+MOSTLYCLEANFILES = \
+       $(BUILT_SOURCES) *~ *.pyc
diff --git a/gr-audio-portaudio/src/audio_portaudio.i b/gr-audio-portaudio/src/audio_portaudio.i
new file mode 100644 (file)
index 0000000..35fc5c6
--- /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 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.
+ */
+
+%feature("autodoc","1");
+
+%include "exception.i"
+%import "gnuradio.i"                           // the common stuff
+
+%{
+#include "gnuradio_swig_bug_workaround.h"      // mandatory bug fix
+#include "audio_portaudio_sink.h"
+#include "audio_portaudio_source.h"
+#include <stdexcept>
+%}
+
+// ----------------------------------------------------------------
+
+GR_SWIG_BLOCK_MAGIC(audio_portaudio,source)
+
+audio_portaudio_source_sptr
+audio_portaudio_make_source (int sampling_rate,
+                            const std::string dev = "",
+                            bool ok_to_block = true
+                            ) throw (std::runtime_error);
+
+class audio_portaudio_source : public gr_sync_block {
+
+ protected:
+  audio_portaudio_source (int sampling_rate,
+                         const std::string device_name,
+                         bool ok_to_block
+                         ) throw (std::runtime_error);
+
+ public:
+  ~audio_portaudio_source ();
+};
+
+// ----------------------------------------------------------------
+
+GR_SWIG_BLOCK_MAGIC(audio_portaudio,sink)
+
+audio_portaudio_sink_sptr
+audio_portaudio_make_sink (int sampling_rate,
+                          const std::string dev = "",
+                          bool ok_to_block = true
+                          ) throw (std::runtime_error);
+
+class audio_portaudio_sink : public gr_sync_block {
+
+ protected:
+  audio_portaudio_sink (int sampling_rate,
+                       const std::string device_name,
+                       bool ok_to_block
+                       ) throw (std::runtime_error);
+
+ public:
+  ~audio_portaudio_sink ();
+};
diff --git a/gr-audio-portaudio/src/audio_portaudio_sink.cc b/gr-audio-portaudio/src/audio_portaudio_sink.cc
new file mode 100644 (file)
index 0000000..06bcc95
--- /dev/null
@@ -0,0 +1,340 @@
+/* -*- 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 2, or (at your option)
+ * any later version.
+ * 
+ * GNU Radio is distributed in he hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <audio_portaudio_sink.h>
+#include <gr_io_signature.h>
+#include <gr_prefs.h>
+#include <stdio.h>
+#include <iostream>
+#include <unistd.h>
+#include <stdexcept>
+#include <gri_portaudio.h>
+#include <omnithread.h>
+
+#define        LOGGING   0             // define to 0 or 1
+
+#define SAMPLE_FORMAT          paFloat32
+typedef float sample_t;
+
+// Number of portaudio buffers in the ringbuffer
+static const unsigned int N_BUFFERS = 4;
+
+static std::string 
+default_device_name ()
+{
+  return gr_prefs::singleton()->get_string("audio_portaudio", "default_output_device", "");
+}
+
+void
+audio_portaudio_sink::create_ringbuffer(void)
+{
+  int bufsize_samples = d_portaudio_buffer_size_frames * d_output_parameters.channelCount;
+  
+  if (d_verbose)
+    fprintf(stderr,"ring buffer size  = %d frames\n",
+           N_BUFFERS*bufsize_samples/d_output_parameters.channelCount);
+
+  // FYI, the buffer indicies are in units of samples.
+  d_writer = gr_make_buffer(N_BUFFERS * bufsize_samples, sizeof(sample_t));
+  d_reader = gr_buffer_add_reader(d_writer, 0);
+}
+
+/*
+ * This routine will be called by the PortAudio engine when audio is needed.
+ * It may called at interrupt level on some machines so don't do anything
+ * that could mess up the system like calling malloc() or free().
+ *
+ * Our job is to write framesPerBuffer frames into outputBuffer.
+ */
+int
+portaudio_sink_callback (const void *inputBuffer,
+                        void *outputBuffer,
+                        unsigned long framesPerBuffer,
+                        const PaStreamCallbackTimeInfo* timeInfo,
+                        PaStreamCallbackFlags statusFlags,
+                        void *arg)
+{
+  audio_portaudio_sink *self = (audio_portaudio_sink *)arg;
+  int nreqd_samples =
+    framesPerBuffer * self->d_output_parameters.channelCount;
+
+  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);
+        
+    // Tell the sink thread there is new room in the ringbuffer.
+    self->d_ringbuffer_ready.post();
+    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!
+    return paContinue;
+  }
+}
+
+
+// ----------------------------------------------------------------
+
+audio_portaudio_sink_sptr
+audio_portaudio_make_sink (int sampling_rate, const std::string dev, bool ok_to_block)
+{
+  return audio_portaudio_sink_sptr (new audio_portaudio_sink (sampling_rate,
+                                                             dev, ok_to_block));
+}
+
+audio_portaudio_sink::audio_portaudio_sink(int sampling_rate,
+                                          const std::string device_name,
+                                          bool ok_to_block)
+  : gr_sync_block ("audio_portaudio_sink",
+                  gr_make_io_signature(0, 0, 0),
+                  gr_make_io_signature(0, 0, 0)),
+    d_sampling_rate(sampling_rate),
+    d_device_name(device_name.empty() ? default_device_name() : device_name),
+    d_ok_to_block(ok_to_block),
+    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_nunderuns(0)
+{
+  memset(&d_output_parameters, 0, sizeof(d_output_parameters));
+  if (LOGGING)
+    d_log = gri_logger::singleton();
+
+  PaError            err;
+  int                i, numDevices;
+  PaDeviceIndex              device = 0;
+  const PaDeviceInfo *deviceInfo = NULL;
+
+  err = Pa_Initialize();
+  if (err != paNoError) {
+    bail ("Initialize failed", err);
+  }
+
+  if (d_verbose)
+    gri_print_devices();
+
+  numDevices = Pa_GetDeviceCount();
+  if (numDevices < 0)
+    bail("Pa Device count failed", 0);
+  if (numDevices == 0)
+    bail("no devices available", 0);
+
+  if (d_device_name.empty()) 
+  {
+    // FIXME Get smarter about picking something
+    fprintf(stderr,"\nUsing Default Device\n");
+    device = Pa_GetDefaultOutputDevice();
+    deviceInfo = Pa_GetDeviceInfo(device);
+    fprintf(stderr,"%s is the chosen device using %s as the host\n",
+           deviceInfo->name, Pa_GetHostApiInfo(deviceInfo->hostApi)->name);
+  }
+  else
+  {
+    bool found = false;
+    fprintf(stderr,"\nTest Devices\n");
+    for (i=0;i<numDevices;i++) {
+      deviceInfo = Pa_GetDeviceInfo( i );
+      fprintf(stderr,"Testing device name: %s",deviceInfo->name);
+      if (strstr(deviceInfo->name, d_device_name.c_str())){
+       fprintf(stderr,"  Chosen!\n");
+       device = gri_pa_find_device_by_name(deviceInfo->name);
+       fprintf(stderr,"%s using %s as the host\n",d_device_name.c_str(),
+               Pa_GetHostApiInfo(deviceInfo->hostApi)->name), fflush(stderr);
+       found = true;
+       deviceInfo = Pa_GetDeviceInfo(device);
+       i = numDevices;         // force loop exit
+      }
+      fprintf(stderr,"\n"),fflush(stderr);
+    }
+
+    if (!found){
+      bail("Failed to find specified device name", 0);
+      exit(1);
+    }
+  }
+
+
+  d_output_parameters.device = device;
+  d_output_parameters.channelCount     = deviceInfo->maxOutputChannels;
+  d_output_parameters.sampleFormat     = SAMPLE_FORMAT;
+  d_output_parameters.suggestedLatency = deviceInfo->defaultLowOutputLatency;
+  d_output_parameters.hostApiSpecificStreamInfo = NULL;
+
+  // We fill in the real channelCount in check_topology when we know
+  // how many inputs are connected to us.
+
+  // Now that we know the maximum number of channels (allegedly)
+  // supported by the h/w, we can compute a reasonable input
+  // signature.  The portaudio specs say that they'll accept any
+  // number of channels from 1 to max.
+  set_input_signature(gr_make_io_signature(1, deviceInfo->maxOutputChannels,
+                                          sizeof (sample_t)));
+}
+
+
+bool
+audio_portaudio_sink::check_topology (int ninputs, int noutputs)
+{
+  PaError err;
+
+  if (Pa_IsStreamActive(d_stream))
+  {
+      Pa_CloseStream(d_stream);
+      d_stream = 0;
+      d_reader.reset();                // boost::shared_ptr for d_reader = 0
+      d_writer.reset();                // boost::shared_ptr for d_write = 0
+  }
+
+  d_output_parameters.channelCount = ninputs;  // # of channels we're really using
+
+#if 1
+  d_portaudio_buffer_size_frames = (int)(0.0213333333  * d_sampling_rate + 0.5);  // Force 1024 frame buffers at 48000
+  fprintf(stderr, "Latency = %8.5f, requested sampling_rate = %g\n", // Force latency to 21.3333333.. ms
+         0.0213333333, (double)d_sampling_rate);
+#endif
+  err = Pa_OpenStream(&d_stream,
+                     NULL,                     // No input
+                     &d_output_parameters,
+                     d_sampling_rate,
+                     d_portaudio_buffer_size_frames,
+                     paClipOff,
+                     &portaudio_sink_callback,
+                     (void*)this);
+
+  if (err != paNoError) {
+    output_error_msg ("OpenStream failed", err);
+    return false;
+  }
+
+#if 0  
+  const PaStreamInfo *psi = Pa_GetStreamInfo(d_stream);
+
+  d_portaudio_buffer_size_frames = (int)(d_output_parameters.suggestedLatency  * psi->sampleRate);
+  fprintf(stderr, "Latency = %7.4f, psi->sampleRate = %g\n",
+         d_output_parameters.suggestedLatency, psi->sampleRate);
+#endif
+
+  fprintf(stderr, "d_portaudio_buffer_size_frames = %d\n", d_portaudio_buffer_size_frames);
+
+  assert(d_portaudio_buffer_size_frames != 0);
+
+  create_ringbuffer();
+
+  err = Pa_StartStream(d_stream);
+  if (err != paNoError) {
+    output_error_msg ("StartStream failed", err);
+    return false;
+  }
+
+  return true;
+}
+
+audio_portaudio_sink::~audio_portaudio_sink ()
+{
+  Pa_StopStream(d_stream);     // wait for output to drain
+  Pa_CloseStream(d_stream);
+  Pa_Terminate();
+}
+
+/*
+ * This version consumes everything sent to it, blocking if required.
+ * I think this will allow us better control of the total buffering/latency
+ * in the audio path.
+ */
+int
+audio_portaudio_sink::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 unsigned nchan = d_output_parameters.channelCount; // # of channels == samples/frame
+
+  int k;
+  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
+       continue;
+      }
+      else {
+       // There's no room and we're not allowed to block.
+       // (A USRP is most likely controlling the pacing through the pipeline.)
+       // We drop the samples on the ground, and say we processed them all ;)
+       //
+       // FIXME, there's probably room for a bit more finesse here.
+       return 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];
+      }
+    }
+    d_writer->update_write_pointer(nf * nchan);
+    k += nf;
+  }
+
+  return k;  // tell how many we actually did
+}
+
+void
+audio_portaudio_sink::output_error_msg (const char *msg, int err)
+{
+  fprintf (stderr, "audio_portaudio_sink[%s]: %s: %s\n",
+          d_device_name.c_str (), msg, Pa_GetErrorText(err));
+}
+
+void
+audio_portaudio_sink::bail (const char *msg, int err) throw (std::runtime_error)
+{
+  output_error_msg (msg, err);
+  throw std::runtime_error ("audio_portaudio_sink");
+}
diff --git a/gr-audio-portaudio/src/audio_portaudio_sink.h b/gr-audio-portaudio/src/audio_portaudio_sink.h
new file mode 100644 (file)
index 0000000..2069f7c
--- /dev/null
@@ -0,0 +1,102 @@
+/* -*- 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 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.
+ */
+#ifndef INCLUDED_AUDIO_PORTAUDIO_SINK_H
+#define INCLUDED_AUDIO_PORTAUDIO_SINK_H
+
+#include <gr_sync_block.h>
+#include <gr_buffer.h>
+#include <omnithread.h>
+#include <string>
+#include <portaudio.h>
+#include <stdexcept>
+#include <gri_logger.h>
+
+class audio_portaudio_sink;
+typedef boost::shared_ptr<audio_portaudio_sink> audio_portaudio_sink_sptr;
+
+/*!
+ * \PORTAUDIO audio sink.
+ * \param sampling_rate        sampling rate in Hz
+ * \param dev PORTAUDIO device name, e.g., "pa:"
+ * \param ok_to_block  true if it's ok for us to block
+ */
+audio_portaudio_sink_sptr
+audio_portaudio_make_sink (int sampling_rate,
+                          const std::string dev = "",
+                          bool ok_to_block = true);
+
+PaStreamCallback portaudio_sink_callback;
+
+
+/*!
+ * \ Audio sink using PORTAUDIO
+ *
+ * Input samples must be in the range [-1,1].
+ */
+class audio_portaudio_sink : public gr_sync_block {
+  friend audio_portaudio_sink_sptr
+  audio_portaudio_make_sink (int sampling_rate,
+                            const std::string device_name,
+                            bool ok_to_block);
+
+  friend PaStreamCallback portaudio_sink_callback;
+
+
+  unsigned int         d_sampling_rate;
+  std::string          d_device_name;
+  bool                 d_ok_to_block;
+  bool                 d_verbose;
+
+  unsigned int         d_portaudio_buffer_size_frames; // number of frames in a portaudio buffer
+
+  PaStream             *d_stream;
+  PaStreamParameters   d_output_parameters;
+
+  gr_buffer_sptr       d_writer;               // buffer used between work and callback
+  gr_buffer_reader_sptr        d_reader;
+  omni_semaphore       d_ringbuffer_ready;     // binary semaphore
+
+
+  // random stats
+  int                  d_nunderuns;            // count of underruns
+  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);
+  void create_ringbuffer();
+
+
+ protected:
+  audio_portaudio_sink (int sampling_rate, const std::string device_name,
+                       bool ok_to_block);
+
+ public:
+  ~audio_portaudio_sink ();
+  
+  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_AUDIO_PORTAUDIO_SINK_H */
diff --git a/gr-audio-portaudio/src/audio_portaudio_source.cc b/gr-audio-portaudio/src/audio_portaudio_source.cc
new file mode 100644 (file)
index 0000000..3741e82
--- /dev/null
@@ -0,0 +1,355 @@
+/* -*- 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 2, or (at your option)
+ * any later version.
+ * 
+ * GNU Radio is distributed in he hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <audio_portaudio_source.h>
+#include <gr_io_signature.h>
+#include <gr_prefs.h>
+#include <stdio.h>
+#include <iostream>
+#include <unistd.h>
+#include <stdexcept>
+#include <gri_portaudio.h>
+#include <omnithread.h>
+
+#define        LOGGING 0               // define to 0 or 1
+
+#define SAMPLE_FORMAT          paFloat32
+typedef float sample_t;
+
+// Number of portaudio buffers in the ringbuffer
+static const unsigned int N_BUFFERS = 4;
+
+static std::string 
+default_device_name ()
+{
+  return gr_prefs::singleton()->get_string("audio_portaudio", "default_input_device", "");
+}
+
+void
+audio_portaudio_source::create_ringbuffer(void)
+{
+  int bufsize_samples = d_portaudio_buffer_size_frames * d_input_parameters.channelCount;
+  
+  if (d_verbose)
+    fprintf(stderr, "ring buffer size  = %d frames\n",
+           N_BUFFERS*bufsize_samples/d_input_parameters.channelCount);
+
+  // FYI, the buffer indicies are in units of samples.
+  d_writer = gr_make_buffer(N_BUFFERS * bufsize_samples, sizeof(sample_t));
+  d_reader = gr_buffer_add_reader(d_writer, 0);
+}
+
+/*
+ * This routine will be called by the PortAudio engine when audio is needed.
+ * It may called at interrupt level on some machines so don't do anything
+ * that could mess up the system like calling malloc() or free().
+ *
+ * Our job is to copy framesPerBuffer frames from inputBuffer.
+ */
+int
+portaudio_source_callback (const void *inputBuffer,
+                          void *outputBuffer,
+                          unsigned long framesPerBuffer,
+                          const PaStreamCallbackTimeInfo* timeInfo,
+                          PaStreamCallbackFlags statusFlags,
+                          void *arg)
+{
+  audio_portaudio_source *self = (audio_portaudio_source *)arg;
+  int nchan = self->d_input_parameters.channelCount;
+  int nframes_to_copy = framesPerBuffer;
+  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);
+
+    // 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);
+        
+    // Tell the source thread there is new data in the ringbuffer.
+    self->d_ringbuffer_ready.post();
+    return paContinue;
+  }
+
+  else {                       // overrun
+    if (LOGGING)
+      self->d_log->printf("PAsrc  cb: f/b = %4ld OVERRUN\n", framesPerBuffer);
+
+    self->d_noverruns++;
+    ::write(2, "aU", 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!
+    return paContinue;
+  }
+}
+
+
+// ----------------------------------------------------------------
+
+audio_portaudio_source_sptr
+audio_portaudio_make_source (int sampling_rate, const std::string dev, bool ok_to_block)
+{
+  return audio_portaudio_source_sptr (new audio_portaudio_source (sampling_rate,
+                                                                 dev, ok_to_block));
+}
+
+audio_portaudio_source::audio_portaudio_source(int sampling_rate,
+                                              const std::string device_name,
+                                              bool ok_to_block)
+  : gr_sync_block ("audio_portaudio_source",
+                  gr_make_io_signature(0, 0, 0),
+                  gr_make_io_signature(0, 0, 0)),
+    d_sampling_rate(sampling_rate),
+    d_device_name(device_name.empty() ? default_device_name() : device_name),
+    d_ok_to_block(ok_to_block),
+    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_noverruns(0)
+{
+  memset(&d_input_parameters, 0, sizeof(d_input_parameters));
+  if (LOGGING)
+    d_log = gri_logger::singleton();
+
+  PaError            err;
+  int                i, numDevices;
+  PaDeviceIndex              device = 0;
+  const PaDeviceInfo *deviceInfo = NULL;
+
+
+  err = Pa_Initialize();
+  if (err != paNoError) {
+    bail ("Initialize failed", err);
+  }
+
+  if (d_verbose)
+    gri_print_devices();
+
+  numDevices = Pa_GetDeviceCount();
+  if (numDevices < 0)
+    bail("Pa Device count failed", 0);
+  if (numDevices == 0)
+    bail("no devices available", 0);
+
+  if (d_device_name.empty()) 
+  {
+    // FIXME Get smarter about picking something
+    device = Pa_GetDefaultInputDevice();
+    deviceInfo = Pa_GetDeviceInfo(device);
+    fprintf(stderr,"%s is the chosen device using %s as the host\n",
+           deviceInfo->name, Pa_GetHostApiInfo(deviceInfo->hostApi)->name);
+  }
+  else
+  {
+    bool found = false;
+    
+    for (i=0;i<numDevices;i++) {
+      deviceInfo = Pa_GetDeviceInfo( i );
+      fprintf(stderr,"Testing device name: %s",deviceInfo->name);
+      if (strstr(deviceInfo->name, d_device_name.c_str())){
+       fprintf(stderr,"  Chosen!\n");
+       device = gri_pa_find_device_by_name(deviceInfo->name);
+       fprintf(stderr,"%s using %s as the host\n",d_device_name.c_str(),
+               Pa_GetHostApiInfo(deviceInfo->hostApi)->name), fflush(stderr);
+       found = true;
+       deviceInfo = Pa_GetDeviceInfo(device);
+       i = numDevices;         // force loop exit
+      }
+      fprintf(stderr,"\n"),fflush(stderr);
+    }
+
+    if (!found){
+      bail("Failed to find specified device name", 0);
+    }
+  }
+
+
+  d_input_parameters.device = device;
+  d_input_parameters.channelCount     = deviceInfo->maxInputChannels;
+  d_input_parameters.sampleFormat     = SAMPLE_FORMAT;
+  d_input_parameters.suggestedLatency = deviceInfo->defaultLowInputLatency;
+  d_input_parameters.hostApiSpecificStreamInfo = NULL;
+
+  // We fill in the real channelCount in check_topology when we know
+  // how many inputs are connected to us.
+
+  // Now that we know the maximum number of channels (allegedly)
+  // supported by the h/w, we can compute a reasonable output
+  // signature.  The portaudio specs say that they'll accept any
+  // number of channels from 1 to max.
+  set_output_signature(gr_make_io_signature(1, deviceInfo->maxInputChannels,
+                                           sizeof (sample_t)));
+}
+
+
+bool
+audio_portaudio_source::check_topology (int ninputs, int noutputs)
+{
+  PaError err;
+
+  if (Pa_IsStreamActive(d_stream))
+  {
+      Pa_CloseStream(d_stream);
+      d_stream = 0;
+      d_reader.reset();                // boost::shared_ptr for d_reader = 0
+      d_writer.reset();                // boost::shared_ptr for d_write = 0
+  }
+
+  d_input_parameters.channelCount = noutputs;  // # of channels we're really using
+
+#if 1
+  d_portaudio_buffer_size_frames = (int)(0.0213333333  * d_sampling_rate + 0.5);  // Force 512 frame buffers at 48000
+  fprintf(stderr, "Latency = %8.5f, requested sampling_rate = %g\n", // Force latency to 21.3333333.. ms
+         0.0213333333, (double)d_sampling_rate);
+#endif
+  err = Pa_OpenStream(&d_stream,
+                     &d_input_parameters,
+                     NULL,                     // No output
+                     d_sampling_rate,
+                     d_portaudio_buffer_size_frames,
+                     paClipOff,
+                     &portaudio_source_callback,
+                     (void*)this);
+
+  if (err != paNoError) {
+    output_error_msg ("OpenStream failed", err);
+    return false;
+  }
+
+#if 0  
+  const PaStreamInfo *psi = Pa_GetStreamInfo(d_stream);
+
+  d_portaudio_buffer_size_frames = (int)(d_input_parameters.suggestedLatency  * psi->sampleRate);
+  fprintf(stderr, "Latency = %7.4f, psi->sampleRate = %g\n",
+         d_input_parameters.suggestedLatency, psi->sampleRate);
+#endif
+
+  fprintf(stderr, "d_portaudio_buffer_size_frames = %d\n", d_portaudio_buffer_size_frames);
+
+  assert(d_portaudio_buffer_size_frames != 0);
+
+  create_ringbuffer();
+
+  err = Pa_StartStream(d_stream);
+  if (err != paNoError) {
+    output_error_msg ("StartStream failed", err);
+    return false;
+  }
+
+  return true;
+}
+
+audio_portaudio_source::~audio_portaudio_source ()
+{
+  Pa_StopStream(d_stream);     // wait for output to drain
+  Pa_CloseStream(d_stream);
+  Pa_Terminate();
+}
+
+int
+audio_portaudio_source::work (int noutput_items,
+                             gr_vector_const_void_star &input_items,
+                             gr_vector_void_star &output_items)
+{
+  float **out = (float **) &output_items[0];
+  const unsigned nchan = d_input_parameters.channelCount; // # of channels == samples/frame
+
+  int k;
+  for (k = 0; k < noutput_items; ){
+
+    int nframes = d_reader->items_available() / nchan; // # of frames in ringbuffer
+    if (nframes == 0){         // no data right now...
+      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
+       continue;
+      }
+
+      assert(k == 0);
+
+      // There's no data and we're not allowed to block.
+      // (A USRP is most likely controlling the pacing through the pipeline.)
+      // This is an underun.  The scheduler wouldn't have called us if it
+      // had anything better to do.  Thus we really need to produce some amount
+      // of "fill".
+      //
+      // There are lots of options for comfort noise, etc.
+      // 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;
+       }
+      }
+      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);
+
+    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;
+  }
+
+  return k;  // tell how many we actually did
+}
+
+void
+audio_portaudio_source::output_error_msg (const char *msg, int err)
+{
+  fprintf (stderr, "audio_portaudio_source[%s]: %s: %s\n",
+          d_device_name.c_str (), msg, Pa_GetErrorText(err));
+}
+
+void
+audio_portaudio_source::bail (const char *msg, int err) throw (std::runtime_error)
+{
+  output_error_msg (msg, err);
+  throw std::runtime_error ("audio_portaudio_source");
+}
diff --git a/gr-audio-portaudio/src/audio_portaudio_source.h b/gr-audio-portaudio/src/audio_portaudio_source.h
new file mode 100644 (file)
index 0000000..25b0c4b
--- /dev/null
@@ -0,0 +1,101 @@
+/* -*- 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 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.
+ */
+#ifndef INCLUDED_AUDIO_PORTAUDIO_SOURCE_H
+#define INCLUDED_AUDIO_PORTAUDIO_SOURCE_H
+
+#include <gr_sync_block.h>
+#include <gr_buffer.h>
+#include <omnithread.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;
+
+/*!
+ * \PORTAUDIO audio source.
+ * \param sampling_rate        sampling rate in Hz
+ * \param dev PORTAUDIO device name, e.g., "pa:"
+ * \param ok_to_block  true if it's ok for us to block
+ */
+audio_portaudio_source_sptr
+audio_portaudio_make_source (int sampling_rate,
+                          const std::string dev = "",
+                          bool ok_to_block = true);
+
+PaStreamCallback portaudio_source_callback;
+
+
+/*!
+ * \ Audio source using PORTAUDIO
+ *
+ * Input samples must be in the range [-1,1].
+ */
+class audio_portaudio_source : public gr_sync_block {
+  friend audio_portaudio_source_sptr
+  audio_portaudio_make_source (int sampling_rate,
+                            const std::string device_name,
+                            bool ok_to_block);
+
+  friend PaStreamCallback portaudio_source_callback;
+
+
+  unsigned int         d_sampling_rate;
+  std::string          d_device_name;
+  bool                 d_ok_to_block;
+  bool                 d_verbose;
+
+  unsigned int         d_portaudio_buffer_size_frames; // number of frames in a portaudio buffer
+
+  PaStream             *d_stream;
+  PaStreamParameters   d_input_parameters;
+
+  gr_buffer_sptr       d_writer;               // buffer used between work and callback
+  gr_buffer_reader_sptr        d_reader;
+  omni_semaphore       d_ringbuffer_ready;     // binary semaphore
+
+  // 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);
+  void create_ringbuffer();
+
+
+ protected:
+  audio_portaudio_source (int sampling_rate, const std::string device_name,
+                       bool ok_to_block);
+
+ public:
+  ~audio_portaudio_source ();
+  
+  bool check_topology (int ninputs, int noutputs);
+
+  int work (int ninput_items,
+           gr_vector_const_void_star &input_items,
+           gr_vector_void_star &output_items);
+};
+
+#endif /* INCLUDED_AUDIO_PORTAUDIO_SOURCE_H */
diff --git a/gr-audio-portaudio/src/gri_portaudio.cc b/gr-audio-portaudio/src/gri_portaudio.cc
new file mode 100644 (file)
index 0000000..a2b08af
--- /dev/null
@@ -0,0 +1,111 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gri_portaudio.h>
+#include <portaudio.h>
+#include <string.h>
+
+
+PaDeviceIndex
+gri_pa_find_device_by_name(const char *name)
+{
+  int   i;
+  int   numDevices;
+  const PaDeviceInfo *pdi;
+  int   len = strlen( name );
+  PaDeviceIndex result = paNoDevice;
+  numDevices = Pa_GetDeviceCount();
+  for( i=0; i<numDevices; i++ )
+  {
+    pdi = Pa_GetDeviceInfo( i );
+    if( strncmp( name, pdi->name, len ) == 0 )
+    {
+      result = i;
+      break;
+    }
+  }
+  return result;
+}
+
+
+void
+gri_print_devices()
+{
+  int     numDevices, defaultDisplayed, myDevice=0;
+  const   PaDeviceInfo *deviceInfo;
+
+  numDevices = Pa_GetDeviceCount();
+  if (numDevices < 0)
+    return;
+
+  printf("Number of devices found = %d\n", numDevices);
+
+  for (int i=0; i < numDevices; i++ ) {
+    deviceInfo = Pa_GetDeviceInfo( i );
+    printf( "--------------------------------------- device #%d\n", i );
+    /* Mark global and API specific default devices */
+    defaultDisplayed = 0;
+    if( i == Pa_GetDefaultInputDevice() )
+      {
+       myDevice = i;
+       printf( "[ Default Input" );
+       defaultDisplayed = 1;
+      }
+    else if( i == Pa_GetHostApiInfo( deviceInfo->hostApi )->defaultInputDevice )
+      {
+       const PaHostApiInfo *hostInfo = Pa_GetHostApiInfo( deviceInfo->hostApi );
+       printf( "[ Default %s Input", hostInfo->name );
+       defaultDisplayed = 1;
+      }
+        
+    if( i == Pa_GetDefaultOutputDevice() )
+      {
+       printf( (defaultDisplayed ? "," : "[") );
+       printf( " Default Output" );
+       defaultDisplayed = 1;
+      }
+    else if( i == Pa_GetHostApiInfo( deviceInfo->hostApi )->defaultOutputDevice )
+      {
+       const PaHostApiInfo *hostInfo = Pa_GetHostApiInfo( deviceInfo->hostApi );
+       printf( (defaultDisplayed ? "," : "[") );                
+       printf( " Default %s Output", hostInfo->name );
+       defaultDisplayed = 1;
+      }
+    if( defaultDisplayed )
+      printf( " ]\n" );
+
+    /* print device info fields */
+    printf( "Name                        = %s\n", deviceInfo->name );
+    printf( "Host API                    = %s\n",  Pa_GetHostApiInfo( deviceInfo->hostApi )->name );
+    printf( "Max inputs = %d", deviceInfo->maxInputChannels  );
+    printf( ", Max outputs = %d\n", deviceInfo->maxOutputChannels  );
+
+    printf( "Default low input latency   = %8.3f\n", deviceInfo->defaultLowInputLatency  );
+    printf( "Default low output latency  = %8.3f\n", deviceInfo->defaultLowOutputLatency  );
+    printf( "Default high input latency  = %8.3f\n", deviceInfo->defaultHighInputLatency  );
+    printf( "Default high output latency = %8.3f\n", deviceInfo->defaultHighOutputLatency  );
+  }
+}
diff --git a/gr-audio-portaudio/src/gri_portaudio.h b/gr-audio-portaudio/src/gri_portaudio.h
new file mode 100644 (file)
index 0000000..ca84aec
--- /dev/null
@@ -0,0 +1,32 @@
+/* -*- 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 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.
+ */
+
+#ifndef INCLUDED_GRI_PORTAUDIO_H
+#define INCLUDED_GRI_PORTAUDIO_H
+
+#include <stdio.h>
+#include <portaudio.h>
+
+PaDeviceIndex gri_pa_find_device_by_name(const char *name);
+void gri_print_devices();
+
+#endif /* INCLUDED_GRI_PORTAUDIO_H */
diff --git a/gr-audio-portaudio/src/qa_portaudio.py b/gr-audio-portaudio/src/qa_portaudio.py
new file mode 100755 (executable)
index 0000000..5356904
--- /dev/null
@@ -0,0 +1,40 @@
+#!/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 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.
+# 
+
+from gnuradio import gr, gr_unittest
+import audio_portaudio
+
+class qa_portaudio (gr_unittest.TestCase):
+
+    def setUp (self):
+        self.fg = gr.flow_graph ()
+
+    def tearDown (self):
+        self.fg = None
+
+    def test_000_nop (self):
+        """Just see if we can import the module...
+        They may not have PORTAUDIO drivers, etc.  Don't try to run anything"""
+        pass
+    
+if __name__ == '__main__':
+    gr_unittest.main ()
diff --git a/gr-audio-portaudio/src/run_tests.in b/gr-audio-portaudio/src/run_tests.in
new file mode 100644 (file)
index 0000000..2f2f40e
--- /dev/null
@@ -0,0 +1,47 @@
+#!/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@/gr-audio-portaudio/src
+# Where to look in the src tree for swig generated python code
+libsrc=@abs_top_srcdir@/gr-audio-portaudio/src
+# Where to look in the src tree for hand written python code
+py=@abs_top_srcdir@/gr-audio-portaudio/src
+
+# Where to look for GNU Radio python modules in current build tree
+# FIXME this is wrong on a distcheck.  We really need to ask gnuradio-core
+# where it put its python files.
+grpythonbld=@abs_top_builddir@/gnuradio-core/src/python/:@abs_top_builddir@/gnuradio-core/src/lib/swig/:@abs_top_builddir@/gnuradio-core/src/lib/swig/.libs
+
+PYTHONPATH="$grpythonbld:$libbld:$libbld/.libs:$libsrc:$py:$PYTHONPATH"
+export PYTHONPATH
+
+#
+# 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-audio-windows/AUTHORS b/gr-audio-windows/AUTHORS
new file mode 100644 (file)
index 0000000..a11898d
--- /dev/null
@@ -0,0 +1,2 @@
+Eric Blossom <eb@comsec.com>
+Martin Dvh <nldudok1 at olifantasia com >
diff --git a/gr-audio-windows/ChangeLog b/gr-audio-windows/ChangeLog
new file mode 100644 (file)
index 0000000..3e5ffe0
--- /dev/null
@@ -0,0 +1,42 @@
+2005-08-09  Eric Blossom  <eb@comsec.com>
+
+       * config/gr_python.m4: tweak for cygwin from Andrew Beck.
+       * src/audio_windows_sink.h: #define NOMINMAX to keep windows from
+       defining min and max under Cygwin.
+
+2005-07-23  Stephane Fillod  <f8cfe@free.fr>
+
+       * config/gr_libgnuradio_core_extra_ldflags.m4: new
+       * config/Makefile.am, configure.ac, src/Makefile.am: added 
+       EXTRA_LDFLAGS for --enable-runtime-pseudo-reloc option.
+       * config/gr_python.m4: update from gnuradio-core
+
+2005-07-07  Eric Blossom  <eb@comsec.com>
+
+       * src/audio_windows_source.cc: reformatted slightly.
+
+2005-05-12  Martin Dvh <nldudok1 at olifantasia com>
+       
+       Initial version based loosely on gr-audio-oss-0.6
+        only audio_sink for now (audio_source is empty stub)
+       
+#
+# 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 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.
+# 
diff --git a/gr-audio-windows/Makefile.am b/gr-audio-windows/Makefile.am
new file mode 100644 (file)
index 0000000..ed5e752
--- /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 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.
+# 
+
+include $(top_srcdir)/Makefile.common
+
+SUBDIRS = src
diff --git a/gr-audio-windows/README b/gr-audio-windows/README
new file mode 100644 (file)
index 0000000..70fbe3a
--- /dev/null
@@ -0,0 +1,66 @@
+
+# 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 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.
+
+gr-audio-windows will add an audio-sink to gnuradio for windows
+
+Requirements for building:
+make sure you have the following installed:
+mingw
+libtool (recent version ,built yourself, (if needed remove old libtool macros from /usr/share/aclocal))
+msys
+python2.4 (just install the prebuild binary for windows)
+boost  (built yourself, maybe just unpacking the source somewhere will do, we only use header files)
+cppunit (built yourself)
+gnuradio-core (built with mingw)
+
+Building:
+sources from cvs:
+edit bootstrap to your needs (see below for example)
+./bootstrap 
+./configure /configure --with-cppunit-prefix=/whereiscppunit --with-boost-include-dir=/c/whereisboost PYTHON=/c/Python24/python am_cv_python_pythondir=/c/Python24/Lib/site-packages am_cv_python_pyexecdir=/c/Python24/Lib/site-packages
+make
+make check
+make install
+
+
+If you have multiple versions of aclocal then edit bootstrap and change aclocal and automake to the latest version
+
+You really need a recent libtool to get this built on mingw.
+If you build it with default options it will be placed in /usr/local, but the default libtool will still be in /usr.
+This will result in old m4 macros will be used by aclocal.
+So if you have a more recent libtool installed in /usr/local add -I /usr/local/share/aclocal to the aclocal commandline in bootstrap.
+(And add any other directories with the most recent m4 macros)
+You could also uninstall (delete) the old libtool macros in /usr/share/aclocal
+
+bootstrap example:
+
+!/bin/sh
+rm -fr config.cache autom4te*.cache
+aclocal-1.8 -I /usr/local/share/aclocal -I config
+autoconf
+autoheader
+libtoolize --automake
+automake-1.8 --add-missing
+
+
+configuration example:
+./configure --with-cppunit-prefix=/usr/local --with-boost-include-dir=/d/boost_1_32_0/include/boost-1_32 PYTHON=/d/Python24/python am_cv_python_pythondir=/d/Python24/Lib/site-packages am_cv_python_pyexecdir=/d/Python24/Lib/site-packages
+
+Martin Dvh, juli 2005
diff --git a/gr-audio-windows/src/Makefile.am b/gr-audio-windows/src/Makefile.am
new file mode 100644 (file)
index 0000000..3d9446d
--- /dev/null
@@ -0,0 +1,87 @@
+#
+# 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 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.
+# 
+
+include $(top_srcdir)/Makefile.common
+
+# Install this stuff so that it ends up as the gnuradio.audio_windows module
+# This usually ends up at:
+#   ${prefix}/lib/python${python_version}/site-packages/gnuradio
+
+ourpythondir = $(grpythondir)
+ourlibdir    = $(grpyexecdir)
+
+EXTRA_DIST = run_tests.in
+TESTS = run_tests
+
+LOCAL_IFILES =                                 \
+       audio_windows.i                         
+
+NON_LOCAL_IFILES =                     \
+       $(top_srcdir)/gnuradio-core/src/lib/swig/gnuradio.i
+
+ALL_IFILES =                           \
+       $(LOCAL_IFILES)                 \
+       $(NON_LOCAL_IFILES)             
+
+BUILT_SOURCES =                        \
+       audio_windows.cc                        \
+       audio_windows.py                                
+
+ourpython_PYTHON =                     \
+       audio_windows.py
+
+INCLUDES = $(STD_DEFINES_AND_INCLUDES) $(PYTHON_CPPFLAGS)
+
+SWIGCPPPYTHONARGS = -python $(PYTHON_CPPFLAGS) \
+                   -I$(swigincludedir) -I$(grincludedir)
+
+ourlib_LTLIBRARIES = _audio_windows.la
+
+_audio_windows_la_SOURCES =            \
+       audio_windows.cc                        \
+       audio_windows_sink.cc           \
+       audio_windows_source.cc                 
+
+
+grinclude_HEADERS =                    \
+       audio_windows_sink.h            \
+       audio_windows_source.h                  
+
+swiginclude_HEADERS =                  \
+       $(LOCAL_IFILES)
+
+_audio_windows_la_LIBADD =             \
+       $(PYTHON_LDFLAGS)               \
+       $(GNURADIO_CORE_LIBS)           \
+       -lwinmm                         \
+       -lstdc++                                
+
+_audio_windows_la_LDFLAGS = -no-undefined -module -avoid-version \
+                            $(LIBGNURADIO_CORE_EXTRA_LDFLAGS)
+
+audio_windows.cc audio_windows.py: audio_windows.i
+       $(SWIG) $(SWIGCPPPYTHONARGS) -module audio_windows -o audio_windows.cc $<
+
+
+noinst_PYTHON = qa_audio_windows.py
+
+MOSTLYCLEANFILES = \
+       $(BUILT_SOURCES) *~ *.pyc
diff --git a/gr-audio-windows/src/audio_windows.i b/gr-audio-windows/src/audio_windows.i
new file mode 100644 (file)
index 0000000..99e9e43
--- /dev/null
@@ -0,0 +1,68 @@
+/* -*- 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 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.
+ */
+
+%feature("autodoc","1");
+
+%include "exception.i"
+%import "gnuradio.i"                           // the common stuff
+
+%{
+#include "gnuradio_swig_bug_workaround.h"      // mandatory bug fix
+#include "audio_windows_sink.h"
+#include "audio_windows_source.h"
+#include <stdexcept>
+%}
+
+// ----------------------------------------------------------------
+
+GR_SWIG_BLOCK_MAGIC(audio_windows,sink)
+
+audio_windows_sink_sptr
+audio_windows_make_sink (int sampling_freq,
+                    const std::string dev = ""
+                    ) throw (std::runtime_error);
+
+
+class audio_windows_sink : public gr_sync_block {
+ protected:
+  audio_windows_sink (int sampling_freq, const std::string device_name = "");
+
+ public:
+  ~audio_windows_sink ();
+};
+
+// ----------------------------------------------------------------
+
+GR_SWIG_BLOCK_MAGIC(audio_windows,source)
+
+audio_windows_source_sptr
+audio_windows_make_source (int sampling_freq,
+                      const std::string dev = ""
+                      ) throw (std::runtime_error);
+
+class audio_windows_source : public gr_sync_block {
+ protected:
+  audio_windows_source (int sampling_freq, const std::string device_name = "");
+
+ public:
+  ~audio_windows_source ();
+};
diff --git a/gr-audio-windows/src/audio_windows_sink.cc b/gr-audio-windows/src/audio_windows_sink.cc
new file mode 100644 (file)
index 0000000..ff1d19c
--- /dev/null
@@ -0,0 +1,324 @@
+/* -*- 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 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.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <audio_windows_sink.h>
+#include <gr_io_signature.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <iostream>
+#include <stdexcept>
+#include <string>
+#include <sstream>
+
+static const double CHUNK_TIME = 0.1;  //0.001;           // 100 ms
+
+// FIXME these should query some kind of user preference
+
+static std::string
+default_device_name ()
+{
+  return "WAVE_MAPPER";
+}
+
+audio_windows_sink::audio_windows_sink (int sampling_freq, const std::string device_name)
+  : gr_sync_block ("audio_windows_sink",
+                  gr_make_io_signature (1, 2, sizeof (float)),
+                  gr_make_io_signature (0, 0, 0)),
+    d_sampling_freq (sampling_freq),
+    d_device_name (device_name.empty ()? default_device_name () : device_name),
+    d_fd (-1), d_buffer (0), d_chunk_size (0)
+{
+  d_wave_write_event = CreateEvent (NULL, FALSE, FALSE, NULL);
+  if (open_waveout_device () < 0)
+    {
+      //fprintf (stderr, "audio_windows_sink:open_waveout_device() failed\n");
+      perror ("audio_windows_sink:open_waveout_device( ) failed\n");
+      throw
+      std::runtime_error ("audio_windows_sink:open_waveout_device() failed");
+    }
+
+  d_chunk_size = (int) (d_sampling_freq * CHUNK_TIME);
+  set_output_multiple (d_chunk_size);
+
+  d_buffer = new short[d_chunk_size * 2];
+
+}
+
+audio_windows_sink::~audio_windows_sink ()
+{
+  /* Free the callback Event */
+  CloseHandle (d_wave_write_event);
+  waveOutClose (d_h_waveout);
+  delete[]d_buffer;
+}
+
+audio_windows_sink_sptr
+audio_windows_make_sink (int sampling_freq, const std::string dev)
+{
+  return audio_windows_sink_sptr (new
+                                 audio_windows_sink (sampling_freq, dev));
+}
+
+
+int
+audio_windows_sink::work (int noutput_items,
+                         gr_vector_const_void_star & input_items,
+                         gr_vector_void_star & output_items)
+{
+  const float *f0, *f1;
+  bool playtestsound = false;
+  if (playtestsound)
+    {
+      // dummy
+
+      f0 = (const float *) input_items[0];
+
+      for (int i = 0; i < noutput_items; i += d_chunk_size)
+       {
+         for (int j = 0; j < d_chunk_size; j++)
+           {
+             d_buffer[2 * j + 0] = (short) (sin (2.0 * 3.1415926535897932384626 * (float) j * 1000.0 / (float) d_sampling_freq) * 8192 + 0);   //+32767
+             d_buffer[2 * j + 1] = d_buffer[2 * j + 0];
+           }
+         f0 += d_chunk_size;
+         if (write_waveout
+             ((HPSTR) d_buffer, 2 * d_chunk_size * sizeof (short)) < 0)
+           {
+             fprintf (stderr, "audio_windows_sink: write failed\n");
+             perror ("audio_windows_sink: write failed");
+           }
+       }
+      // break;
+    }
+  else
+    {
+      switch (input_items.size ())
+       {
+
+       case 1:         // mono input
+
+         f0 = (const float *) input_items[0];
+
+         for (int i = 0; i < noutput_items; i += d_chunk_size)
+           {
+             for (int j = 0; j < d_chunk_size; j++)
+               {
+                 d_buffer[2 * j + 0] = (short) (f0[j] * 32767);
+                 d_buffer[2 * j + 1] = (short) (f0[j] * 32767);
+               }
+             f0 += d_chunk_size;
+             if (write_waveout
+                 ((HPSTR) d_buffer, 2 * d_chunk_size * sizeof (short)) < 0)
+               {
+                 //fprintf (stderr, "audio_windows_sink: write failed\n");
+                 perror ("audio_windows_sink: write failed");
+               }
+           }
+         break;
+
+       case 2:         // stereo input
+
+         f0 = (const float *) input_items[0];
+         f1 = (const float *) input_items[1];
+
+         for (int i = 0; i < noutput_items; i += d_chunk_size)
+           {
+             for (int j = 0; j < d_chunk_size; j++)
+               {
+                 d_buffer[2 * j + 0] = (short) (f0[j] * 32767);
+                 d_buffer[2 * j + 1] = (short) (f1[j] * 32767);
+               }
+             f0 += d_chunk_size;
+             f1 += d_chunk_size;
+             if (write_waveout
+                 ((HPSTR) d_buffer, 2 * d_chunk_size * sizeof (short)) < 0)
+               {
+                 //fprintf (stderr, "audio_windows_sink: write failed\n");
+                 perror ("audio_windows_sink: write failed");
+               }
+           }
+         break;
+       }
+    }
+  return noutput_items;
+}
+
+int
+audio_windows_sink::string_to_int (const std::string & s)
+{
+  int i;
+  std::istringstream (s) >> i;
+  return i;
+}                              //ToInt()
+
+int
+audio_windows_sink::open_waveout_device (void)
+{
+
+  UINT /*UINT_PTR */ u_device_id;
+       /** Identifier of the waveform-audio output device to open. It can be either a device identifier or a handle of an open waveform-audio input device. You can use the following flag instead of a device identifier.
+       *
+       * Value Meaning
+       * WAVE_MAPPER The function selects a waveform-audio output device capable of playing the given format.
+       */
+  if (d_device_name.empty () || default_device_name () == d_device_name)
+    u_device_id = WAVE_MAPPER;
+  else
+    u_device_id = (UINT) string_to_int (d_device_name);
+  // Open a waveform device for output using event callback.
+
+  unsigned long result;
+  //HWAVEOUT      outHandle;
+  WAVEFORMATEX wave_format;
+
+  /* Initialize the WAVEFORMATEX for 16-bit, 44KHz, stereo */
+  wave_format.wFormatTag = WAVE_FORMAT_PCM;
+  wave_format.nChannels = 2;
+  wave_format.nSamplesPerSec = d_sampling_freq;        //44100;
+  wave_format.wBitsPerSample = 16;
+  wave_format.nBlockAlign =
+    wave_format.nChannels * (wave_format.wBitsPerSample / 8);
+  wave_format.nAvgBytesPerSec =
+    wave_format.nSamplesPerSec * wave_format.nBlockAlign;
+  wave_format.cbSize = 0;
+
+  /* Open the (preferred) Digital Audio Out device. */
+  result = waveOutOpen (&d_h_waveout, WAVE_MAPPER, &wave_format, (DWORD_PTR) d_wave_write_event, 0, CALLBACK_EVENT | WAVE_ALLOWSYNC);  //|WAVE_FORMAT_DIRECT | CALLBACK_EVENT| WAVE_ALLOWSYNC
+  if (result)
+    {
+      fprintf (stderr,
+              "audio_windows_sink: Failed to open waveform output device.\n");
+      perror ("audio_windows_sink: Failed to open waveform output device.");
+      //LocalUnlock(hFormat);
+      //LocalFree(hFormat);
+      //mmioClose(hmmio, 0);
+      return -1;
+    }
+
+  //
+  // Do not Swallow the "open" event.
+  //
+  //WaitForSingleObject(d_wave_write_event, INFINITE);
+
+  // Allocate and lock memory for the header.
+
+  d_h_wave_hdr = GlobalAlloc (GMEM_MOVEABLE | GMEM_SHARE,
+                             (DWORD) sizeof (WAVEHDR));
+  if (d_h_wave_hdr == NULL)
+    {
+      //GlobalUnlock(hData);
+      //GlobalFree(hData);
+      //fprintf (stderr, "audio_windows_sink: Not enough memory for header.\n");
+      perror ("audio_windows_sink: Not enough memory for header.");
+      return -1;
+    }
+
+  d_lp_wave_hdr = (LPWAVEHDR) GlobalLock (d_h_wave_hdr);
+  if (d_lp_wave_hdr == NULL)
+    {
+      //GlobalUnlock(hData);
+      //GlobalFree(hData);
+      //fprintf (stderr, "audio_windows_sink: Failed to lock memory for header.\n");
+      perror ("audio_windows_sink: Failed to lock memory for header.");
+      return -1;
+    }
+  //d_lp_wave_hdr->dwFlags = WHDR_DONE;
+  return 0;
+}
+
+int
+audio_windows_sink::write_waveout (HPSTR lp_data, DWORD dw_data_size)
+{
+  UINT w_result;
+  int teller = 100;
+  // After allocation, set up and prepare header.
+  /*while ((d_lp_wave_hdr->dwFlags & WHDR_DONE)==0 && teller>0)
+     {
+     teller--;
+     Sleep(1);
+     } */
+  // Wait until previous wave write completes (first event is the open event).
+  WaitForSingleObject (d_wave_write_event, 100);       //INFINITE
+  d_lp_wave_hdr->lpData = lp_data;
+  d_lp_wave_hdr->dwBufferLength = dw_data_size;
+  d_lp_wave_hdr->dwFlags = 0L;
+  /* Clear the WHDR_DONE bit (which the driver set last time that
+     this WAVEHDR was sent via waveOutWrite and was played). Some
+     drivers need this to be cleared */
+  //d_lp_wave_hdr->dwFlags &= ~WHDR_DONE;
+
+  d_lp_wave_hdr->dwLoops = 0L;
+  w_result =
+    waveOutPrepareHeader (d_h_waveout, d_lp_wave_hdr, sizeof (WAVEHDR));
+  if (w_result != 0)
+    {
+      //GlobalUnlock( hData);
+      //GlobalFree(hData);
+      //fprintf (stderr, "audio_windows_sink: Failed to waveOutPrepareHeader. error %i\n",w_result);
+      perror ("audio_windows_sink: Failed to waveOutPrepareHeader");
+    }
+  // Now the data block can be sent to the output device. The
+  // waveOutWrite function returns immediately and waveform
+  // data is sent to the output device in the background.
+  //while (!  readyforplayback) Sleep(1);
+  //readyforplayback=false;
+  //
+  //
+
+  w_result = waveOutWrite (d_h_waveout, d_lp_wave_hdr, sizeof (WAVEHDR));
+  if (w_result != 0)
+    {
+      //GlobalUnlock( hData);
+      //GlobalFree(hData);
+      //fprintf (stderr, "audio_windows_sink: Failed to write block to device.error %i\n",w_result);
+      perror ("audio_windows_sink: Failed to write block to device");
+      switch (w_result)
+       {
+       case MMSYSERR_INVALHANDLE:
+         fprintf (stderr, "Specified device handle is invalid. \n");
+         break;
+       case MMSYSERR_NODRIVER:
+         fprintf (stderr, " No device driver is present.  \n");
+         break;
+       case MMSYSERR_NOMEM:
+         fprintf (stderr, " Unable to allocate or lock memory.  \n");
+         break;
+       case WAVERR_UNPREPARED:
+         fprintf (stderr,
+                  " The data block pointed to by the pwh parameter hasn't been prepared.  \n");
+         break;
+       default:
+         fprintf (stderr, "Unknown error %i\n", w_result);
+       }
+      waveOutUnprepareHeader (d_h_waveout, d_lp_wave_hdr, sizeof (WAVEHDR));
+      return -1;
+    }
+  //   WaitForSingleObject(d_wave_write_event, INFINITE);
+  return 0;
+}
diff --git a/gr-audio-windows/src/audio_windows_sink.h b/gr-audio-windows/src/audio_windows_sink.h
new file mode 100644 (file)
index 0000000..0d7e630
--- /dev/null
@@ -0,0 +1,83 @@
+/* -*- 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 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.
+ */
+
+#ifndef INCLUDED_AUDIO_WINDOWS_SINK_H
+#define INCLUDED_AUDIO_WINDOWS_SINK_H
+
+#define WIN32_LEAN_AND_MEAN
+#define NOMINMAX               // stops windef.h defining max/min under cygwin
+
+#include <windows.h>
+#include <mmsystem.h>
+
+#include <gr_sync_block.h>
+#include <string>
+
+
+class audio_windows_sink;
+typedef boost::shared_ptr <audio_windows_sink> audio_windows_sink_sptr;
+
+audio_windows_sink_sptr
+audio_windows_make_sink (int sampling_freq, const std::string dev = "");
+
+/*!
+ * \brief audio sink using winmm mmsystem (win32 only)
+ *
+ * input signature is one or two streams of floats.
+ * Input samples must be in the range [-1,1].
+ */
+
+class audio_windows_sink : public gr_sync_block
+{
+  friend
+    audio_windows_sink_sptr
+  audio_windows_make_sink (int sampling_freq, const std::string device_name);
+
+  int          d_sampling_freq;
+  std::string   d_device_name;
+  int          d_fd;
+  short        *d_buffer;
+  int           d_chunk_size;
+  HWAVEOUT      d_h_waveout;
+  HGLOBAL       d_h_wave_hdr;
+  LPWAVEHDR     d_lp_wave_hdr;
+  HANDLE        d_wave_write_event;
+
+protected:
+  int
+  string_to_int (const std::string & s);
+  audio_windows_sink (int sampling_freq, const std::string device_name = "");
+  int
+  open_waveout_device (void);
+  int
+  write_waveout (HPSTR lp_data, DWORD dw_data_size);
+
+public:
+  ~audio_windows_sink ();
+
+  int
+  work (int noutput_items,
+       gr_vector_const_void_star & input_items,
+       gr_vector_void_star & output_items);
+};
+
+#endif /* INCLUDED_AUDIO_WINDOWS_SINK_H */
diff --git a/gr-audio-windows/src/audio_windows_source.cc b/gr-audio-windows/src/audio_windows_source.cc
new file mode 100644 (file)
index 0000000..8879e3b
--- /dev/null
@@ -0,0 +1,208 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <audio_windows_source.h>
+#include <gr_io_signature.h>
+//include <sys/soundcard.h>
+//include <sys/ioctl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <iostream>
+#include <stdexcept>
+
+
+static const double CHUNK_TIME = 0.005;        // 5 ms
+
+// FIXME these should query some kind of user preference
+
+static std::string
+default_device_name ()
+{
+  return "/dev/dsp";
+}
+
+audio_windows_source::audio_windows_source (int sampling_freq, const std::string device_name)
+  : gr_sync_block ("audio_windows_source",
+                  gr_make_io_signature (0, 0, 0),
+                  gr_make_io_signature (1, 2, sizeof (float))),
+    d_sampling_freq (sampling_freq),
+    d_device_name (device_name.empty ()? default_device_name () : device_name),
+    d_fd (-1), d_buffer (0), d_chunk_size (0)
+{
+  //FIXME TODO implement me
+#if 0
+  if ((d_fd = open (d_device_name.c_str (), O_RDONLY)) < 0)
+    {
+      fprintf (stderr, "audio_windows_source: ");
+      perror (d_device_name.c_str ());
+      throw
+      std::runtime_error ("audio_windows_source");
+    }
+
+  d_chunk_size = (int) (d_sampling_freq * CHUNK_TIME);
+  set_output_multiple (d_chunk_size);
+
+  d_buffer = new short[d_chunk_size * 2];
+
+  int  format = AFMT_S16_NE;
+  int  orig_format = format;
+  if (ioctl (d_fd, SNDCTL_DSP_SETFMT, &format) < 0)
+    {
+      std::
+       cerr << "audio_windows_source: " << d_device_name <<
+       " ioctl failed\n";
+      perror (d_device_name.c_str ());
+      throw
+      std::runtime_error ("audio_windows_source");
+    }
+
+  if (format != orig_format)
+    {
+      fprintf (stderr, "audio_windows_source: unable to support format %d\n",
+              orig_format);
+      fprintf (stderr, "  card requested %d instead.\n", format);
+    }
+
+  // set to stereo no matter what.  Some hardware only does stereo
+  int channels = 2;
+  if (ioctl (d_fd, SNDCTL_DSP_CHANNELS, &channels) < 0 || channels != 2)
+    {
+      perror ("audio_windows_source: could not set STEREO mode");
+      throw
+      std::runtime_error ("audio_windows_source");
+    }
+
+  // set sampling freq
+  int sf = sampling_freq;
+  if (ioctl (d_fd, SNDCTL_DSP_SPEED, &sf) < 0)
+    {
+      std::cerr << "audio_windows_source: "
+       << d_device_name << ": invalid sampling_freq "
+       << sampling_freq << "\n";
+      sampling_freq = 8000;
+      if (ioctl (d_fd, SNDCTL_DSP_SPEED, &sf) < 0)
+       {
+         std::
+           cerr <<
+           "audio_windows_source: failed to set sampling_freq to 8000\n";
+         throw
+         std::runtime_error ("audio_windows_source");
+       }
+    }
+#endif
+}
+
+audio_windows_source::~audio_windows_source ()
+{
+  /*close (d_fd);
+     delete [] d_buffer;
+   */
+}
+
+audio_windows_source_sptr
+audio_windows_make_source (int sampling_freq, const std::string dev)
+{
+  return audio_windows_source_sptr (new
+                                   audio_windows_source (sampling_freq,
+                                                         dev));
+}
+
+
+int
+audio_windows_source::work (int noutput_items,
+                           gr_vector_const_void_star & input_items,
+                           gr_vector_void_star & output_items)
+{
+  //FIXME TODO implement me
+#if 0
+  float *f0 = (float *) output_items[0];
+  float *f1 = (float *) output_items[1];       // will be invalid if this is mono output
+
+  const int shorts_per_item = 2;       // L + R
+  const int bytes_per_item = shorts_per_item * sizeof (short);
+
+  // To minimize latency, never return more than CHUNK_TIME
+  // worth of samples per call to work.
+  // FIXME, we need an API to set this value
+
+  noutput_items = std::min (noutput_items, d_chunk_size);
+
+  int base = 0;
+  int ntogo = noutput_items;
+
+  while (ntogo > 0)
+    {
+      int nbytes = std::min (ntogo, d_chunk_size) * bytes_per_item;
+      int result_nbytes = read (d_fd, d_buffer, nbytes);
+
+      if (result_nbytes < 0)
+       {
+         perror ("audio_windows_source");
+         return -1;            // say we're done
+       }
+
+      if ((result_nbytes & (bytes_per_item - 1)) != 0)
+       {
+         fprintf (stderr, "audio_windows_source: internal error.\n");
+         throw std::runtime_error ("internal error");
+       }
+
+      int result_nitems = result_nbytes / bytes_per_item;
+
+      // now unpack samples into output streams
+
+      switch (output_items.size ())
+       {
+       case 1:         // mono output
+         for (int i = 0; i < result_nitems; i++)
+           {
+             f0[base + i] = d_buffer[2 * i + 0] * (1.0 / 32767);
+           }
+         break;
+
+       case 2:         // stereo output
+         for (int i = 0; i < result_nitems; i++)
+           {
+             f0[base + i] = d_buffer[2 * i + 0] * (1.0 / 32767);
+             f1[base + i] = d_buffer[2 * i + 1] * (1.0 / 32767);
+           }
+         break;
+
+       default:
+         assert (0);
+       }
+
+      ntogo -= result_nitems;
+      base += result_nitems;
+    }
+
+  return noutput_items - ntogo;
+#endif
+  return -1;                   // EOF
+}
diff --git a/gr-audio-windows/src/audio_windows_source.h b/gr-audio-windows/src/audio_windows_source.h
new file mode 100644 (file)
index 0000000..718ac2f
--- /dev/null
@@ -0,0 +1,68 @@
+/* -*- 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 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.
+ */
+
+#ifndef INCLUDED_AUDIO_WINDOWS_SOURCE_H
+#define INCLUDED_AUDIO_WINDOWS_SOURCE_H
+
+#include <gr_sync_block.h>
+#include <string>
+
+
+class audio_windows_source;
+typedef boost::shared_ptr <audio_windows_source> audio_windows_source_sptr;
+
+audio_windows_source_sptr
+audio_windows_make_source (int sampling_freq, const std::string dev = "");
+
+/*!
+ * \brief audio source using winmm mmsystem (win32 only)
+ *
+ * Output signature is one or two streams of floats.
+ * Output samples will be in the range [-1,1].
+ */
+
+class audio_windows_source : public gr_sync_block
+{
+  friend
+    audio_windows_source_sptr
+  audio_windows_make_source (int sampling_freq,
+                            const std::string device_name);
+
+  int          d_sampling_freq;
+  std::string   d_device_name;
+  int          d_fd;
+  short        *d_buffer;
+  int          d_chunk_size;
+
+protected:
+  audio_windows_source (int sampling_freq, const std::string device_name = "");
+
+public:
+  ~audio_windows_source ();
+
+  int
+  work (int noutput_items,
+       gr_vector_const_void_star & input_items,
+       gr_vector_void_star & output_items);
+};
+
+#endif /* INCLUDED_AUDIO_WINDOWS_SOURCE_H */
diff --git a/gr-audio-windows/src/qa_audio_windows.py b/gr-audio-windows/src/qa_audio_windows.py
new file mode 100755 (executable)
index 0000000..e7663a8
--- /dev/null
@@ -0,0 +1,40 @@
+#!/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 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.
+# 
+
+from gnuradio import gr, gr_unittest
+import audio_windows
+
+class qa_oss (gr_unittest.TestCase):
+
+    def setUp (self):
+        self.fg = gr.flow_graph ()
+
+    def tearDown (self):
+        self.fg = None
+
+    def test_000_nop (self):
+        """Just see if we can import the module...
+        They may not have audio drivers, soundcard, etc.  Don't try to run anything"""
+        pass
+    
+if __name__ == '__main__':
+    gr_unittest.main ()
diff --git a/gr-audio-windows/src/run_tests.in b/gr-audio-windows/src/run_tests.in
new file mode 100755 (executable)
index 0000000..6eb5963
--- /dev/null
@@ -0,0 +1,47 @@
+#!/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@/gr-audio-windows/src
+# Where to look in the src tree for swig generated python code
+libsrc=@abs_top_srcdir@/gr-audio-windows/src
+# Where to look in the src tree for hand written python code
+py=@abs_top_srcdir@/gr-audio-windows/src
+
+# Where to look for GNU Radio python modules in current build tree
+# FIXME this is wrong on a distcheck.  We really need to ask gnuradio-core
+# where it put its python files.
+grpythonbld=@abs_top_builddir@/gnuradio-core/src/python/:@abs_top_builddir@/gnuradio-core/src/lib/swig/:@abs_top_builddir@/gnuradio-core/src/lib/swig/.libs
+
+PYTHONPATH="$grpythonbld:$libbld:$libbld/.libs:$libsrc:$py:$PYTHONPATH"
+export PYTHONPATH
+
+#
+# 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-comedi/AUTHORS b/gr-comedi/AUTHORS
new file mode 100644 (file)
index 0000000..624606f
--- /dev/null
@@ -0,0 +1 @@
+Stephane Fillod <f8cfe@free.fr>
diff --git a/gr-comedi/ChangeLog b/gr-comedi/ChangeLog
new file mode 100644 (file)
index 0000000..92ee15b
--- /dev/null
@@ -0,0 +1,25 @@
+2005-10-10  Stephane Fillod <f8cfe@free.fr>
+
+       * src/comedi_source.{h,cc}: new.
+       * src/comedi_sink.{h,cc}: new.
+
+#
+# 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 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.
+# 
diff --git a/gr-comedi/Makefile.am b/gr-comedi/Makefile.am
new file mode 100644 (file)
index 0000000..0b0234e
--- /dev/null
@@ -0,0 +1,24 @@
+#
+# 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 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.
+# 
+
+include $(top_srcdir)/Makefile.common
+
+SUBDIRS = src
diff --git a/gr-comedi/src/Makefile.am b/gr-comedi/src/Makefile.am
new file mode 100644 (file)
index 0000000..3311cd5
--- /dev/null
@@ -0,0 +1,91 @@
+#
+# 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 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.
+# 
+
+include $(top_srcdir)/Makefile.common
+
+# Install this stuff so that it ends up as the gnuradio.comedi module
+# This usually ends up at:
+#   ${prefix}/lib/python${python_version}/site-packages/gnuradio
+
+ourpythondir = $(grpythondir)
+ourlibdir    = $(grpyexecdir)
+
+EXTRA_DIST = run_tests.in
+
+TESTS = run_tests
+
+LOCAL_IFILES =                                 \
+       comedi.i                                
+
+NON_LOCAL_IFILES =                     \
+       $(top_srcdir)/gnuradio-core/src/lib/swig/gnuradio.i
+
+ALL_IFILES =                           \
+       $(LOCAL_IFILES)                 \
+       $(NON_LOCAL_IFILES)             
+
+BUILT_SOURCES =                        \
+       comedi.cc                       \
+       comedi.py                               
+
+ourpython_PYTHON =                     \
+       comedi.py
+
+INCLUDES = $(STD_DEFINES_AND_INCLUDES) $(PYTHON_CPPFLAGS)
+
+SWIGCPPPYTHONARGS = -c++ -python $(PYTHON_CPPFLAGS) $(STD_DEFINES_AND_INCLUDES)
+#      -I$(swigincludedir) $(S-I$(grincludedir) -I$(comediincludedir)
+
+ourlib_LTLIBRARIES = _comedi.la
+
+_comedi_la_SOURCES =           \
+       comedi.cc               \
+       comedi_sink_s.cc        \
+       comedi_source_s.cc      \
+       gri_comedi.cc                   
+
+grinclude_HEADERS =            \
+       comedi_sink_s.h         \
+       comedi_source_s.h               
+
+noinst_HEADERS =               \
+       gri_comedi.h                    
+
+
+swiginclude_HEADERS =          \
+       $(LOCAL_IFILES)
+
+_comedi_la_LIBADD =            \
+       $(PYTHON_LDFLAGS)       \
+       $(GNURADIO_CORE_LIBS)   \
+       -lstdc++                                
+
+_comedi_la_LDFLAGS = $(NO_UNDEFINED) -module -avoid-version
+
+comedi.cc comedi.py: comedi.i
+       $(SWIG) $(SWIGCPPPYTHONARGS) -module comedi -o comedi.cc $<
+
+
+noinst_PYTHON =                \
+       qa_comedi.py                    
+
+MOSTLYCLEANFILES = \
+       $(BUILT_SOURCES) *~ *.pyc
diff --git a/gr-comedi/src/comedi.i b/gr-comedi/src/comedi.i
new file mode 100644 (file)
index 0000000..18f4f44
--- /dev/null
@@ -0,0 +1,76 @@
+/* -*- 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 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.
+ */
+
+%feature("autodoc","1");
+
+%include "exception.i"
+%import "gnuradio.i"                           // the common stuff
+
+%{
+#include "gnuradio_swig_bug_workaround.h"      // mandatory bug fix
+#include "comedi_sink_s.h"
+#include "comedi_source_s.h"
+#include <stdexcept>
+%}
+
+// ----------------------------------------------------------------
+
+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..2c1ffb7
--- /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 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.
+ */
+
+#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..08fce25
--- /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 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.
+ */
+#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 device_name);
+
+  // 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..5041c9c
--- /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 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.
+ */
+
+#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..e759c43
--- /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 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.
+ */
+#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 device_name);
+
+  // 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..e456262
--- /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 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.
+ */
+
+#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..5e1f00e
--- /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 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.
+ */
+
+#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..98b2f91
--- /dev/null
@@ -0,0 +1,40 @@
+#!/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 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.
+# 
+
+from gnuradio import gr, gr_unittest
+import comedi
+
+class qa_comedi (gr_unittest.TestCase):
+
+    def setUp (self):
+        self.fg = gr.flow_graph ()
+
+    def tearDown (self):
+        self.fg = 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..6c0ba9d
--- /dev/null
@@ -0,0 +1,47 @@
+#!/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@/gr-comedi/src
+# Where to look in the src tree for swig generated python code
+libsrc=@abs_top_srcdir@/gr-comedi/src
+# Where to look in the src tree for hand written python code
+py=@abs_top_srcdir@/gr-comedi/src
+
+# Where to look for GNU Radio python modules in current build tree
+# FIXME this is wrong on a distcheck.  We really need to ask gnuradio-core
+# where it put its python files.
+grpythonbld=@abs_top_builddir@/gnuradio-core/src/python/:@abs_top_builddir@/gnuradio-core/src/lib/swig/:@abs_top_builddir@/gnuradio-core/src/lib/swig/.libs
+
+PYTHONPATH="$grpythonbld:$libbld:$libbld/.libs:$libsrc:$py:$PYTHONPATH"
+export PYTHONPATH
+
+#
+# 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-error-correcting-codes/AUTHORS b/gr-error-correcting-codes/AUTHORS
new file mode 100644 (file)
index 0000000..bb4f6a6
--- /dev/null
@@ -0,0 +1 @@
+Michael Dickens <mdickens@nd.edu>
diff --git a/gr-error-correcting-codes/ChangeLog b/gr-error-correcting-codes/ChangeLog
new file mode 100644 (file)
index 0000000..6c49533
--- /dev/null
@@ -0,0 +1,31 @@
+2006-07-09  Eric Blossom  <eb@comsec.com>
+
+       * src/lib/gr_streams_encode_convolutional.{h,cc,i}: fixes to
+       access second constructor via SWIG.
+
+       * src/lib/libecc/code_metrics.cc: added missing include.
+
+2006-07-03  Michael Dickens  <mdickens@nd.edu>
+
+       * In development.
+
+#
+# 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 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.
+# 
diff --git a/gr-error-correcting-codes/Makefile.am b/gr-error-correcting-codes/Makefile.am
new file mode 100644 (file)
index 0000000..67a9e92
--- /dev/null
@@ -0,0 +1,27 @@
+#
+# 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.
+# 
+
+include $(top_srcdir)/Makefile.common
+
+SUBDIRS = src
+DIST_SUBDIRS = src
+
+MOSTLYCLEANFILES = *~
diff --git a/gr-error-correcting-codes/src/Makefile.am b/gr-error-correcting-codes/src/Makefile.am
new file mode 100644 (file)
index 0000000..a7da9c7
--- /dev/null
@@ -0,0 +1,24 @@
+#
+# 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 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.
+# 
+
+SUBDIRS = lib python
+
+MOSTLYCLEANFILES = *~
diff --git a/gr-error-correcting-codes/src/lib/Makefile.am b/gr-error-correcting-codes/src/lib/Makefile.am
new file mode 100644 (file)
index 0000000..3168a58
--- /dev/null
@@ -0,0 +1,101 @@
+#
+# 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 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.
+# 
+
+include $(top_srcdir)/Makefile.common
+
+SUBDIRS = libecc
+
+LIBS += $(GNURADIO_CORE_LIBS)
+
+# Install this stuff so that it ends up as the gnuradio.und module
+# This usually ends up at:
+#   ${prefix}/lib/python${python_version}/site-packages/gnuradio
+
+ourpythondir = $(grpythondir)
+ourlibdir    = $(grpythondir)
+
+INCLUDES = $(STD_DEFINES_AND_INCLUDES) $(PYTHON_CPPFLAGS) $(GNURADIO_INCLUDES)
+
+SWIGCPPPYTHONARGS = -fvirtual -python -modern $(PYTHON_CPPFLAGS) \
+       $(GNURADIO_INCLUDES)
+
+ALL_IFILES =                           \
+       $(LOCAL_IFILES)                 \
+       $(NON_LOCAL_IFILES)
+
+NON_LOCAL_IFILES =                     \
+       $(top_srcdir)/gnuradio-core/src/lib/swig/gnuradio.i
+
+LOCAL_IFILES =                                                 \
+       gr_syms_to_metrics.i                            \
+       gr_metrics_decode_viterbi_full_block.i          \
+       gr_streams_encode_convolutional.i               \
+       gr_streams_encode_turbo.i                       \
+       ecc.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 =        \
+       ecc.cc          \
+       ecc.py          
+
+# This gets ecc.py installed in the right place
+ourpython_PYTHON =                     \
+       __init__.py                     \
+       ecc.py
+
+ourlib_LTLIBRARIES = _ecc.la
+
+# These are the source files that go into the shared library
+_ecc_la_SOURCES =                                      \
+       gr_syms_to_metrics.cc                           \
+       gr_metrics_decode_viterbi_full_block.cc         \
+       gr_streams_encode_convolutional.cc              \
+       gr_streams_encode_turbo.cc                      \
+       ecc.cc
+
+# magic flags
+_ecc_la_LDFLAGS = $(NO_UNDEFINED) -module -avoid-version
+
+# link the library against the c++ standard library
+_ecc_la_LIBADD =               \
+       libecc/libecc.la        \
+       $(PYTHON_LDFLAGS)       \
+       -lstdc++
+
+# These headers get installed in ${prefix}/include/gnuradio
+grinclude_HEADERS =                                    \
+       gr_syms_to_metrics.h                            \
+       gr_metrics_decode_viterbi_full_block.h          \
+       gr_streams_encode_convolutional.h               \
+       gr_streams_encode_turbo.h
+
+# These swig headers get installed in ${prefix}/include/gnuradio/swig
+swiginclude_HEADERS = $(LOCAL_IFILES)
+
+ecc.cc ecc.py: ecc.i $(ALL_IFILES)
+       $(SWIG) $(SWIGCPPPYTHONARGS) -module ecc -o ecc.cc $<
+
+MOSTLYCLEANFILES = $(BUILT_SOURCES) *.pyc *.loT *~
+
+CONFIG_CLEAN_FILES = *.in
diff --git a/gr-error-correcting-codes/src/lib/__init__.py b/gr-error-correcting-codes/src/lib/__init__.py
new file mode 100644 (file)
index 0000000..911b38b
--- /dev/null
@@ -0,0 +1,20 @@
+#
+# 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 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.
+# 
diff --git a/gr-error-correcting-codes/src/lib/ecc.i b/gr-error-correcting-codes/src/lib/ecc.i
new file mode 100644 (file)
index 0000000..32ea9d2
--- /dev/null
@@ -0,0 +1,41 @@
+/* -*- 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 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.
+ */
+
+%feature("autodoc","1");
+%include "exception.i"
+%import "gnuradio.i"
+
+%{
+
+#include "gnuradio_swig_bug_workaround.h"      // mandatory bug fix
+#include <gr_streams_encode_convolutional.h>
+#include <gr_streams_encode_turbo.h>
+#include <gr_metrics_decode_viterbi_full_block.h>
+#include <gr_syms_to_metrics.h>
+#include <stdexcept>
+
+%}
+
+%include "gr_streams_encode_convolutional.i"
+%include "gr_streams_encode_turbo.i"
+%include "gr_metrics_decode_viterbi_full_block.i"
+%include "gr_syms_to_metrics.i"
diff --git a/gr-error-correcting-codes/src/lib/gr_metrics_decode_viterbi_full_block.cc b/gr-error-correcting-codes/src/lib/gr_metrics_decode_viterbi_full_block.cc
new file mode 100644 (file)
index 0000000..94a7fe4
--- /dev/null
@@ -0,0 +1,228 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_metrics_decode_viterbi_full_block.h>
+#include <gr_io_signature.h>
+#include <assert.h>
+#include <iostream>
+
+gr_metrics_decode_viterbi_full_block_sptr
+gr_make_metrics_decode_viterbi_full_block
+(int sample_precision,
+ int frame_size_bits,
+ int n_code_inputs,
+ int n_code_outputs,
+ const std::vector<int> &code_generator,
+ bool do_termination,
+ int start_memory_state,
+ int end_memory_state)
+{
+  return gr_metrics_decode_viterbi_full_block_sptr
+    (new gr_metrics_decode_viterbi_full_block
+     (sample_precision,
+      frame_size_bits,
+      n_code_inputs,
+      n_code_outputs,
+      code_generator,
+      do_termination,
+      start_memory_state,
+      end_memory_state));
+}
+
+gr_metrics_decode_viterbi_full_block_feedback_sptr
+gr_make_metrics_decode_viterbi_full_block_feedback
+(int sample_precision,
+ int frame_size_bits,
+ int n_code_inputs,
+ int n_code_outputs,
+ const std::vector<int> &code_generator,
+ const std::vector<int> &code_feedback,
+ bool do_termination,
+ int start_memory_state,
+ int end_memory_state)
+{
+  return gr_metrics_decode_viterbi_full_block_feedback_sptr
+    (new gr_metrics_decode_viterbi_full_block
+     (sample_precision,
+      frame_size_bits,
+      n_code_inputs,
+      n_code_outputs,
+      code_generator,
+      code_feedback,
+      do_termination,
+      start_memory_state,
+      end_memory_state));
+}
+
+gr_metrics_decode_viterbi_full_block::gr_metrics_decode_viterbi_full_block
+(int sample_precision,
+ int frame_size_bits,
+ int n_code_inputs,
+ int n_code_outputs,
+ const std::vector<int> &code_generator,
+ bool do_termination,
+ int start_memory_state,
+ int end_memory_state)
+  : gr_block ("metrics_decode_viterbi_full_block",
+             gr_make_io_signature (0, 0, 0),
+             gr_make_io_signature (0, 0, 0))
+{
+  d_encoder = new encoder_convolutional_ic1_ic1 (frame_size_bits,
+                                                n_code_inputs,
+                                                n_code_outputs,
+                                                code_generator,
+                                                do_termination,
+                                                start_memory_state,
+                                                end_memory_state);
+
+  setup_io_signatures (sample_precision, n_code_inputs, n_code_outputs);
+}
+
+gr_metrics_decode_viterbi_full_block::gr_metrics_decode_viterbi_full_block
+(int sample_precision,
+ int frame_size_bits,
+ int n_code_inputs,
+ int n_code_outputs,
+ const std::vector<int> &code_generator,
+ const std::vector<int> &code_feedback,
+ bool do_termination,
+ int start_memory_state,
+ int end_memory_state)
+  : gr_block ("metrics_decode_viterbi_full_block_feedback",
+             gr_make_io_signature (0, 0, 0),
+             gr_make_io_signature (0, 0, 0))
+{
+  d_encoder = new encoder_convolutional_ic1_ic1 (frame_size_bits,
+                                                n_code_inputs,
+                                                n_code_outputs,
+                                                code_generator,
+                                                code_feedback,
+                                                do_termination,
+                                                start_memory_state,
+                                                end_memory_state);
+
+  setup_io_signatures (sample_precision, n_code_inputs, n_code_outputs);
+}
+
+gr_metrics_decode_viterbi_full_block::~gr_metrics_decode_viterbi_full_block
+()
+{
+  delete d_decoder;
+  delete d_encoder;
+}
+
+void
+gr_metrics_decode_viterbi_full_block::setup_io_signatures
+(int sample_precision,
+ int n_code_inputs,
+ int n_code_outputs)
+{
+  // create the decoder using:
+  //
+  // the "i1" input model: individual input streams; two per metric
+  // type (0-bit, 1-bit), single metric per input item (char, short, long)
+  //
+  // the "ic1" output model:
+  // individual output streams per decoded code input stream;
+  // each item is a 'char' type with 1 bit aligned on the LSB.
+
+  d_decoder = new decoder_viterbi_full_block_i1_ic1 (sample_precision,
+                                                    d_encoder);
+
+  // error checking is done in the encoder and decoder classes
+  // so just use the parameters as given; will be correct!
+
+  d_n_code_inputs = n_code_inputs;
+  d_n_code_outputs = n_code_outputs;
+
+  // output signature is always the same:
+  // sizeof (char) with 1 bit per char as the LSB
+
+  set_output_signature (gr_make_io_signature (d_n_code_inputs,
+                                             d_n_code_inputs,
+                                             sizeof (char)));
+
+  // determine the input signature element size
+  size_t l_input_item_size_bytes;
+
+  if (sample_precision == 0) {
+    // float
+    l_input_item_size_bytes = sizeof (float);
+  } else if (sample_precision <= 8) {
+    // use char
+    l_input_item_size_bytes = sizeof (char);
+  } else if (sample_precision <= 16) {
+    // use short
+    l_input_item_size_bytes = sizeof (short);
+  } else {
+    // use long
+    l_input_item_size_bytes = sizeof (long);
+  }
+
+  set_input_signature (gr_make_io_signature (2*d_n_code_outputs,
+                                            2*d_n_code_outputs,
+                                            l_input_item_size_bytes));
+}
+
+void gr_metrics_decode_viterbi_full_block::forecast
+(int noutput_items,
+ gr_vector_int &ninput_items_required)
+{
+  int ninput_items = d_decoder->compute_n_input_metrics (noutput_items);
+  size_t ninputs = ninput_items_required.size();
+  for (size_t n = 0; n < ninputs; n++)
+    ninput_items_required[n] = ninput_items;
+}
+
+int
+gr_metrics_decode_viterbi_full_block::general_work
+(int noutput_items,
+ gr_vector_int &ninput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+  // FIXME: compute the actual number of output items (1 bit char's) created.
+
+  size_t t_n_input_items = d_decoder->compute_n_input_metrics (noutput_items);
+  size_t t_n_output_items = d_decoder->compute_n_output_bits (t_n_input_items);
+
+  assert (t_n_output_items == ((size_t)noutput_items));
+
+  // "work" is handled by the decoder; which returns the actual number
+  // of input items (metrics) used.
+
+  t_n_input_items = d_decoder->decode ((const char**)(&input_items[0]),
+                                      (char**)(&output_items[0]),
+                                      noutput_items);
+
+  // consume the number of used input items on all input streams
+
+  consume_each (t_n_input_items);
+
+  // returns number of items written to each output stream
+
+  return (noutput_items);
+}
diff --git a/gr-error-correcting-codes/src/lib/gr_metrics_decode_viterbi_full_block.h b/gr-error-correcting-codes/src/lib/gr_metrics_decode_viterbi_full_block.h
new file mode 100644 (file)
index 0000000..57ca1ba
--- /dev/null
@@ -0,0 +1,163 @@
+/* -*- 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 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.
+ */
+
+#ifndef INCLUDED_GR_METRICS_DECODE_VITERBI_FULL_BLOCK_H
+#define INCLUDED_GR_METRICS_DECODE_VITERBI_FULL_BLOCK_H
+
+#include <gr_block.h>
+#include <libecc/decoder_viterbi_full_block_i1_ic1.h>
+#include <libecc/encoder_convolutional_ic1_ic1.h>
+
+class gr_metrics_decode_viterbi_full_block;
+
+typedef boost::shared_ptr<gr_metrics_decode_viterbi_full_block>
+gr_metrics_decode_viterbi_full_block_sptr,
+gr_metrics_decode_viterbi_full_block_feedback_sptr;
+
+gr_metrics_decode_viterbi_full_block_sptr
+gr_make_metrics_decode_viterbi_full_block
+(int frame_size_bits,
+ int n_code_inputs,
+ int n_code_outputs,
+ std::vector<int> code_generator,
+ bool do_termination = true,
+ int start_memory_state = 0,
+ int end_memory_state = 0);
+
+gr_metrics_decode_viterbi_full_block_feedback_sptr
+gr_make_metrics_decode_viterbi_full_block_feedback
+(int frame_size_bits,
+ int n_code_inputs,
+ int n_code_outputs,
+ std::vector<int> code_generator,
+ std::vector<int> code_feedback,
+ bool do_termination = true,
+ int start_memory_state = 0,
+ int end_memory_state = 0);
+
+/*!
+ * \brief Decode the incoming streams using a Viterbi-style decoder,
+ *     full trellis block decoding.
+ *
+ * input: symbol metrics data.
+ *
+ * output: stream(s) of char, single bit stored in the LSB.
+ */
+
+class gr_metrics_decode_viterbi_full_block : public gr_block
+{
+  friend gr_metrics_decode_viterbi_full_block_sptr
+  gr_make_metrics_decode_viterbi_full_block
+  (int sample_precision,
+   int frame_size_bits,
+   int n_code_inputs,
+   int n_code_outputs,
+   const std::vector<int> &code_generator,
+   bool do_termination,
+   int start_memory_state,
+   int end_memory_state);
+
+  friend gr_metrics_decode_viterbi_full_block_feedback_sptr
+  gr_make_metrics_decode_viterbi_full_block_feedback
+  (int sample_precision,
+   int frame_size_bits,
+   int n_code_inputs,
+   int n_code_outputs,
+   const std::vector<int> &code_generator,
+   const std::vector<int> &code_feedback,
+   bool do_termination,
+   int start_memory_state,
+   int end_memory_state);
+/*
+ * frame_size_bits: if == 0, then do streaming decoding (infinite
+ *     trellis); otherwise this is the block size to decode before
+ *     terminating the trellis.
+ *
+ * code_generator: vector of integers (32 bit) representing the code
+ *     to be implemented in octal form.  E.g. "04" in binary is "100",
+ *     which would be "D^2" for code generation.  "06" == 110b == "D^2 + D"
+ *  ==> The vector is listed in order for each input stream, so if there
+ *     are 2 input streams (I1, I2) [specified in "n_code_inputs"]
+ *     and 2 output streams (O1, O2) [specified in "n_code_outputs"],
+ *     then the vector would be the code generator for:
+ *       [I1->O1, I1->O2, I2->O1, I2->O2]
+ *     with each element being the octal representation of the code.
+ *
+ * do_termination is valid only if frame_size_bits != 0, and defines
+ *     whether or not to to trellis termination.
+ *
+ * do_mux_input: is true, then the one input stream will be
+ *     interpreted as the multiplexing all of the input bits.  For
+ *     example for a 3 input decoder, the input stream would be
+ *     [I1[k], I2[k], I3[k], I1[k+1], I2[k+1], ...], where "k" is the
+ *     input sample time, and "I1" through "I3" are the 3 input
+ *     streams.
+ *
+ * n_code_inputs: the number of decoder-input (encoder-output)
+ *     streams, no matter if separate or mux'ed
+ *
+ * n_code_outputs: the number of decoder-output (encoder-input) streams
+ */
+
+  gr_metrics_decode_viterbi_full_block
+  (int sample_precision,
+   int frame_size_bits,
+   int n_code_inputs,
+   int n_code_outputs,
+   const std::vector<int> &code_generator,
+   bool do_termination,
+   int start_memory_state,
+   int end_memory_state);
+
+  gr_metrics_decode_viterbi_full_block
+  (int sample_precision,
+   int frame_size_bits,
+   int n_code_inputs,
+   int n_code_outputs,
+   const std::vector<int> &code_generator,
+   const std::vector<int> &code_feedback,
+   bool do_termination,
+   int start_memory_state,
+   int end_memory_state);
+
+public:
+  ~gr_metrics_decode_viterbi_full_block ();
+
+  virtual void forecast (int noutput_items,
+                        gr_vector_int &ninput_items_required);
+
+  virtual int general_work (int noutput_items,
+                           gr_vector_int &ninput_items,
+                           gr_vector_const_void_star &input_items,
+                           gr_vector_void_star &output_items);
+
+protected:
+  void setup_io_signatures (int sample_precision,
+                           int n_code_inputs,
+                           int n_code_outputs);
+
+  int d_n_code_inputs, d_n_code_outputs;
+  decoder_viterbi_full_block_i1_ic1* d_decoder;
+  encoder_convolutional_ic1_ic1* d_encoder;
+};
+
+#endif /* INCLUDED_GR_METRICS_DECODE_VITERBI_FULL_BLOCK_H */
diff --git a/gr-error-correcting-codes/src/lib/gr_metrics_decode_viterbi_full_block.i b/gr-error-correcting-codes/src/lib/gr_metrics_decode_viterbi_full_block.i
new file mode 100644 (file)
index 0000000..a7cd1ba
--- /dev/null
@@ -0,0 +1,77 @@
+/* -*- 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 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.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,metrics_decode_viterbi_full_block);
+
+// corrected "class NAME" statement, which uses slightly different NAMEs
+
+typedef boost::shared_ptr<gr_metrics_decode_viterbi_full_block>
+gr_metrics_decode_viterbi_full_block_feedback_sptr;
+
+LOCAL_GR_SWIG_BLOCK_MAGIC(gr,metrics_decode_viterbi_full_block_feedback);
+
+gr_metrics_decode_viterbi_full_block_sptr
+gr_make_metrics_decode_viterbi_full_block
+(int sample_precision,
+ int frame_size_bits,
+ int n_code_inputs,
+ int n_code_outputs,
+ const std::vector<int> &code_generator,
+ bool do_termination,
+ int start_memory_state,
+ int end_memory_state);
+
+gr_metrics_decode_viterbi_full_block_feedback_sptr
+gr_make_metrics_decode_viterbi_full_block_feedback
+(int sample_precision,
+ int frame_size_bits,
+ int n_code_inputs,
+ int n_code_outputs,
+ const std::vector<int> &code_generator,
+ const std::vector<int> &code_feedback,
+ bool do_termination,
+ int start_memory_state,
+ int end_memory_state);
+
+class gr_metrics_decode_viterbi_full_block : public gr_block
+{
+  gr_metrics_decode_viterbi_full_block
+  (int sample_precision,
+   int frame_size_bits,
+   int n_code_inputs,
+   int n_code_outputs,
+   const std::vector<int> &code_generator,
+   bool do_termination,
+   int start_memory_state,
+   int end_memory_state);
+
+  gr_metrics_decode_viterbi_full_block
+  (int sample_precision,
+   int frame_size_bits,
+   int n_code_inputs,
+   int n_code_outputs,
+   const std::vector<int> &code_generator,
+   const std::vector<int> &code_feedback,
+   bool do_termination,
+   int start_memory_state,
+   int end_memory_state);
+};
diff --git a/gr-error-correcting-codes/src/lib/gr_streams_encode_convolutional.cc b/gr-error-correcting-codes/src/lib/gr_streams_encode_convolutional.cc
new file mode 100644 (file)
index 0000000..98e2926
--- /dev/null
@@ -0,0 +1,220 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_streams_encode_convolutional.h>
+#include <gr_io_signature.h>
+#include <assert.h>
+#include <iostream>
+
+gr_streams_encode_convolutional_sptr 
+gr_make_streams_encode_convolutional
+(int frame_size_bits,
+ int n_code_inputs,
+ int n_code_outputs,
+ const std::vector<int> &code_generator,
+ bool do_termination,
+ int start_memory_state,
+ int end_memory_state)
+{
+  return gr_streams_encode_convolutional_sptr
+    (new gr_streams_encode_convolutional (frame_size_bits,
+                                         n_code_inputs,
+                                         n_code_outputs,
+                                         code_generator,
+                                         do_termination,
+                                         start_memory_state,
+                                         end_memory_state));
+}
+
+gr_streams_encode_convolutional_sptr 
+gr_make_streams_encode_convolutional_feedback
+(int frame_size_bits,
+ int n_code_inputs,
+ int n_code_outputs,
+ const std::vector<int> &code_generator,
+ const std::vector<int> &code_feedback,
+ bool do_termination,
+ int start_memory_state,
+ int end_memory_state)
+{
+  return gr_streams_encode_convolutional_sptr
+    (new gr_streams_encode_convolutional (frame_size_bits,
+                                         n_code_inputs,
+                                         n_code_outputs,
+                                         code_generator,
+                                         code_feedback,
+                                         do_termination,
+                                         start_memory_state,
+                                         end_memory_state));
+}
+
+gr_streams_encode_convolutional::gr_streams_encode_convolutional
+(int frame_size_bits,
+ int n_code_inputs,
+ int n_code_outputs,
+ const std::vector<int> &code_generators,
+ bool do_termination,
+ int start_memory_state,
+ int end_memory_state)
+  : gr_block ("streams_encode_convolutional",
+             gr_make_io_signature (0, 0, 0),
+             gr_make_io_signature (0, 0, 0))
+{
+  // error checking is done by the encoder class itself;
+  // just pass items on here.
+
+  d_encoder = new encoder_convolutional_ic1_ic1 (frame_size_bits,
+                                                n_code_inputs,
+                                                n_code_outputs,
+                                                code_generators,
+                                                do_termination,
+                                                start_memory_state,
+                                                end_memory_state);
+
+  setup_io_signatures (n_code_inputs, n_code_outputs);
+}
+
+gr_streams_encode_convolutional::gr_streams_encode_convolutional
+(int frame_size_bits,
+ int n_code_inputs,
+ int n_code_outputs,
+ const std::vector<int> &code_generators,
+ const std::vector<int> &code_feedback,
+ bool do_termination,
+ int start_memory_state,
+ int end_memory_state)
+  : gr_block ("streams_encode_convolutional_feedback",
+             gr_make_io_signature (0, 0, 0),
+             gr_make_io_signature (0, 0, 0))
+{
+  // error checking is done by the encoder class itself;
+  // just pass items on here.
+
+  d_encoder = new encoder_convolutional_ic1_ic1 (frame_size_bits,
+                                                n_code_inputs,
+                                                n_code_outputs,
+                                                code_generators,
+                                                code_feedback,
+                                                do_termination,
+                                                start_memory_state,
+                                                end_memory_state);
+
+  setup_io_signatures (n_code_inputs, n_code_outputs);
+}
+
+void
+gr_streams_encode_convolutional::setup_io_signatures
+(int n_code_inputs,
+ int n_code_outputs)
+{
+  fprintf (stderr, "gr_s_e_c: d_encoder == %X\n", (unsigned int)d_encoder);
+
+  // create the correct input signature; 1 bit per input char
+
+  set_input_signature (gr_make_io_signature (n_code_inputs,
+                                            n_code_inputs,
+                                            sizeof (char)));
+
+  // create the correct output signature; 1 bit per output char
+
+  set_output_signature (gr_make_io_signature (n_code_outputs,
+                                             n_code_outputs,
+                                             sizeof (char)));
+
+  // no need to set the output multiple (to 1 item), since 1 is the
+  // default, and the encoder class handles the rest internally
+
+  // no need to set the relative rate (# out / # in) because for each
+  // input bit per input stream there is 1 output bit per output
+  // stream ... with a little added for termination, but ignore those.
+}
+
+gr_streams_encode_convolutional::~gr_streams_encode_convolutional
+()
+{
+  delete d_encoder;
+  d_encoder = 0;
+}
+
+/*
+ * Compute the number of input items needed to produce 'n_output'
+ * bits.  Handled internally by the encoder.
+ */
+
+void gr_streams_encode_convolutional::forecast
+(int noutput_items,
+ gr_vector_int &ninput_items_required)
+{
+  fprintf (stderr, "gr_s_e_c::forecast: #out = %d\n",
+         noutput_items);
+
+  int ninput_items = d_encoder->compute_n_input_bits (noutput_items);
+
+  fprintf (stderr, "s_e_c::forecast: #out = %d, #in = %d\n",
+         noutput_items, ninput_items);
+
+  size_t ninputs = ninput_items_required.size();
+  for (size_t n = 0; n < ninputs; n++)
+    ninput_items_required[n] = ninput_items;
+}
+
+int
+gr_streams_encode_convolutional::general_work
+(int noutput_items,
+ gr_vector_int &ninput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+  fprintf (stderr, "gr_s_e_c::general_work: Starting #out = %d\n",
+          noutput_items);
+
+  // FIXME: compute the actual number of output items (1 bit char's) created.
+
+  size_t t_n_input_items = d_encoder->compute_n_input_bits (noutput_items);
+
+#if 0
+  size_t t_n_output_items = d_encoder->compute_n_output_bits (t_n_input_items);
+
+  assert (t_n_output_items == ((size_t)noutput_items));
+#endif
+
+  // "work" is handled by the encoder; which returns the actual number
+  // of input items (1-bit char's) used.
+
+  t_n_input_items = d_encoder->encode ((const char **)(&input_items[0]), 
+                                      (char **)(&output_items[0]),
+                                      (size_t) noutput_items);
+
+  assert (0);
+
+  // consume the number of used input items on all input streams
+
+  consume_each (t_n_input_items);
+
+  // returns number of items written to each output stream
+
+  return (noutput_items);
+}
diff --git a/gr-error-correcting-codes/src/lib/gr_streams_encode_convolutional.h b/gr-error-correcting-codes/src/lib/gr_streams_encode_convolutional.h
new file mode 100644 (file)
index 0000000..66e9109
--- /dev/null
@@ -0,0 +1,155 @@
+/* -*- 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 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.
+ */
+
+#ifndef INCLUDED_GR_STREAMS_ENCODE_CONVOLUTIONAL_H
+#define INCLUDED_GR_STREAMS_ENCODE_CONVOLUTIONAL_H
+
+#include <gr_block.h>
+#include <libecc/encoder_convolutional_ic1_ic1.h>
+
+/*!
+ * \brief Encode the incoming streams using a convolutional encoder
+ *
+ * input: streams of char, one stream per input as defined by the
+ *     instantiated code, using only the right-most justified bit as
+ *     the single input bit per input item.
+ *
+ * output: streams of char, one stream per output as defined by the
+ *     instantiated code, using only the right-most justified bit as
+ *     the single output bit per output item.
+ *
+ * frame_size_bits: if == 0, then do streaming encoding ("infinite"
+ *     trellis); otherwise this is the frame size in bits to encode
+ *     before terminating the trellis.  This value -does not- include
+ *     any termination bits.
+ *
+ * n_code_inputs:
+ * n_code_outputs:
+ * code_generator: vector of integers (32 bit) representing the code
+ *     to be implemented.  E.g. "4" in binary is "100", which would be
+ *     "D^2" for code generation.  "6" == 110b == "D^2 + D"
+ *  ==> The vector is listed in order for each output stream, so if there
+ *     are 2 input streams (I1, I2) [specified in "n_code_inputs"]
+ *     and 2 output streams (O1, O2) [specified in "n_code_outputs"],
+ *     then the vector would be the code generator for:
+ *       [I1->O1, I2->O1, I1->O2, I2->O2]
+ *     with each element being an integer representation of the code.
+ *
+ * do_termination: valid only if frame_size_bits != 0, and defines
+ *     whether or not to use trellis termination.  Default is to use
+ *     termination when doing block coding.
+ *
+ * start_memory_state: when starting a new block, the starting memory
+ *     state to begin encoding; there will be a helper function to
+ *     assist in creating this value for a given set of inputs;
+ *     default is the "all zero" state.
+ * 
+ * end_memory_state: when terminating a block, the ending memory
+ *     state to stop encoding; there will be a helper function to
+ *     assist in creating this value for a given set of inputs;
+ *     default is the "all zero" state.
+ */
+
+class gr_streams_encode_convolutional;
+typedef boost::shared_ptr<gr_streams_encode_convolutional>
+  gr_streams_encode_convolutional_sptr;
+
+gr_streams_encode_convolutional_sptr
+gr_make_streams_encode_convolutional
+(int frame_size_bits,
+ int n_code_inputs,
+ int n_code_outputs,
+ const std::vector<int> &code_generator,
+ bool do_termination = true,
+ int start_memory_state = 0,
+ int end_memory_state = 0);
+
+gr_streams_encode_convolutional_sptr
+gr_make_streams_encode_convolutional_feedback
+(int frame_size_bits,
+ int n_code_inputs,
+ int n_code_outputs,
+ const std::vector<int> &code_generator,
+ const std::vector<int> &code_feedback,
+ bool do_termination = true,
+ int start_memory_state = 0,
+ int end_memory_state = 0);
+
+class gr_streams_encode_convolutional : public gr_block
+{
+  friend gr_streams_encode_convolutional_sptr
+  gr_make_streams_encode_convolutional
+  (int frame_size_bits,
+   int n_code_inputs,
+   int n_code_outputs,
+   const std::vector<int> &code_generator,
+   bool do_termination,
+   int start_memory_state,
+   int end_memory_state);
+
+  friend gr_streams_encode_convolutional_sptr
+  gr_make_streams_encode_convolutional_feedback
+  (int frame_size_bits,
+   int n_code_inputs,
+   int n_code_outputs,
+   const std::vector<int> &code_generator,
+   const std::vector<int> &code_feedback,
+   bool do_termination,
+   int start_memory_state,
+   int end_memory_state);
+
+  gr_streams_encode_convolutional (int frame_size_bits,
+                                  int n_code_inputs,
+                                  int n_code_outputs,
+                                  const std::vector<int> &code_generator,
+                                  bool do_termination,
+                                  int start_memory_state,
+                                  int end_memory_state);
+
+  gr_streams_encode_convolutional (int frame_size_bits,
+                                  int n_code_inputs,
+                                  int n_code_outputs,
+                                  const std::vector<int> &code_generator,
+                                  const std::vector<int> &code_feedback,
+                                  bool do_termination,
+                                  int start_memory_state,
+                                  int end_memory_state);
+
+  void setup_io_signatures (int n_code_inputs, int n_code_outputs);
+
+  encoder_convolutional_ic1_ic1* d_encoder;
+
+public:
+  ~gr_streams_encode_convolutional ();
+
+  inline encoder_convolutional_ic1_ic1* encoder () {return (d_encoder);};
+
+  virtual void forecast (int noutput_items,
+                        gr_vector_int &ninput_items_required);
+
+  virtual 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_GR_STREAMS_ENCODE_CONVOLUTIONAL_H */
diff --git a/gr-error-correcting-codes/src/lib/gr_streams_encode_convolutional.i b/gr-error-correcting-codes/src/lib/gr_streams_encode_convolutional.i
new file mode 100644 (file)
index 0000000..63d60c6
--- /dev/null
@@ -0,0 +1,77 @@
+/* -*- 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 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.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,streams_encode_convolutional);
+
+// Rename second constructor
+%rename(streams_encode_convolutional_feedback) gr_make_streams_encode_convolutional_feedback;
+
+// support vectors of these ... for use in the convolutional decoder
+// as well as Turbo Codes (both encoder and decoder).
+
+namespace std {
+  %template(x_vector_gr_streams_encode_convolutional_sptr) vector<gr_streams_encode_convolutional_sptr>;
+};
+
+gr_streams_encode_convolutional_sptr
+gr_make_streams_encode_convolutional
+(int block_size_bits,
+ int n_code_inputs,
+ int n_code_outputs,
+ const std::vector<int> &code_generator,
+ bool do_termination = true,
+ int start_memory_state = 0,
+ int end_memory_state = 0);
+
+gr_streams_encode_convolutional_sptr
+gr_make_streams_encode_convolutional_feedback
+(int block_size_bits,
+ int n_code_inputs,
+ int n_code_outputs,
+ const std::vector<int> &code_generator,
+ const std::vector<int> &code_feedback,
+ bool do_termination = true,
+ int start_memory_state = 0,
+ int end_memory_state = 0);
+
+class gr_streams_encode_convolutional : public gr_block
+{
+private:
+  gr_streams_encode_convolutional
+  (int block_size_bits,
+   int n_code_inputs,
+   int n_code_outputs,
+   const std::vector<int> &code_generator,
+   bool do_termination,
+   int start_memory_state,
+   int end_memory_state);
+
+  gr_streams_encode_convolutional
+  (int block_size_bits,
+   int n_code_inputs,
+   int n_code_outputs,
+   const std::vector<int> &code_generator,
+   const std::vector<int> &code_feedback,
+   bool do_termination,
+   int start_memory_state,
+   int end_memory_state);
+};
diff --git a/gr-error-correcting-codes/src/lib/gr_streams_encode_turbo.cc b/gr-error-correcting-codes/src/lib/gr_streams_encode_turbo.cc
new file mode 100644 (file)
index 0000000..9d7f72f
--- /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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_streams_encode_turbo.h>
+#include <gr_io_signature.h>
+#include <assert.h>
+#include <iostream>
+
+gr_streams_encode_turbo_sptr 
+gr_make_streams_encode_turbo
+(int n_code_inputs,
+ int n_code_outputs,
+ const std::vector<gr_streams_encode_convolutional_sptr> &encoders,
+ const std::vector<size_t> &interleavers)
+{
+  return gr_streams_encode_turbo_sptr
+    (new gr_streams_encode_turbo (n_code_inputs,
+                                 n_code_outputs,
+                                 encoders,
+                                 interleavers));
+}
+
+gr_streams_encode_turbo::gr_streams_encode_turbo
+(int n_code_inputs,
+ int n_code_outputs,
+ const std::vector<gr_streams_encode_convolutional_sptr> &encoders,
+ const std::vector<size_t> &interleavers)
+  : gr_block ("streams_encode_turbo",
+             gr_make_io_signature (0, 0, 0),
+             gr_make_io_signature (0, 0, 0))
+{
+  // error checking is done by the encoder class itself;
+  // just pass items on here.
+
+  // check out individual encoders, to make sure the total input /
+  // output matches those specified by the user.
+
+  d_n_encoders = encoders.size ();
+
+  if (d_n_encoders < 2) {
+    std::cerr << "gr_streams_encode_turbo: Error: "
+      "too few (" << d_n_encoders << ") encoders specified; a Turbo "
+      "code requires at least 2 constituent encoders.\n";
+    assert (0);
+  }
+
+  // make sure that the block size and termination are consistent for
+  // all encoders; warn the user if not, since it doesn't really
+  // matter to the encoder (but it might to the decoder; remains to be
+  // seen).
+
+  encoder_convolutional_ic1_ic1* t_ec = encoders[0]->encoder ();
+  d_block_size_bits = t_ec->block_size_bits ();
+  d_do_termination = t_ec->do_termination ();
+  bool t_diff_block_size, t_diff_termination;
+  t_diff_block_size = t_diff_termination = false;
+
+  for (size_t m = 1; m < d_n_encoders; m++) {
+    t_ec = encoders[0]->encoder ();
+    size_t t_block_size_bits = t_ec->block_size_bits ();
+    if (t_block_size_bits != d_block_size_bits)
+      t_diff_block_size = true;
+    bool t_do_termination = t_ec->do_termination ();
+    if (t_do_termination != d_do_termination)
+      t_do_termination = true;
+  }
+
+  if (t_diff_block_size == true) {
+    std::cout << "gr_streams_encode_turbo: Warning: "
+      "Some constituent encoders have different block size (bits).\n";
+  }
+  if (t_diff_termination == true) {
+    std::cout << "gr_streams_encode_turbo: Warning: "
+      "Some constituent encoders are differently terminationed.\n";
+  }
+
+  std::cout << "gr_streams_encode_turbo: setup:\n"
+    "d_n_encoders = " << d_n_encoders << "\n"
+    "n_code_inputs = " << n_code_inputs << "\n"
+    "n_code_outputs = " << n_code_outputs << "\n\n"
+    "Individual Encoders:\n";
+
+  for (size_t m = 0; m < d_n_encoders; m++) {
+    t_ec = encoders[m]->encoder ();
+    std::cout << "  [" << (m+1) << "]:\n"
+      "n_code_inputs = " << (t_ec->n_code_inputs()) << "\n"
+      "n_code_outputs = " << (t_ec->n_code_outputs()) << "\n"
+      "block_size_bits = " << (t_ec->block_size_bits()) << "\n"
+      "do_termination = " <<
+      ((t_ec->do_termination()==true)?"true":"false") << "\n";
+  }
+
+#if 1
+  assert (0);
+#else
+  if (d_n_encoders != (interleavers.size())) {}
+
+  d_encoder = new encoder_turbo_ic1_ic1 (n_code_inputs,
+                                        n_code_outputs,
+                                        code_generators,
+                                        do_termination,
+                                        start_memory_state,
+                                        end_memory_state);
+#endif
+
+  // create the correct input signature; 1 bit per input char
+
+  set_input_signature (gr_make_io_signature (n_code_inputs,
+                                            n_code_inputs,
+                                            sizeof (char)));
+
+  // create the correct output signature; 1 bit per output char
+
+  set_output_signature (gr_make_io_signature (n_code_outputs,
+                                             n_code_outputs,
+                                             sizeof (char)));
+
+// set the output multiple to 1 item, then let the encoder class
+// handle the rest internally
+
+  set_output_multiple (1);
+}
+
+gr_streams_encode_turbo::~gr_streams_encode_turbo
+()
+{
+  if (d_encoder)
+    delete d_encoder;
+}
+
+/*
+ * Compute the number of input bits (items in this case, since each
+ * item has 1 bit in it) needed to produce 'n_output' bits (items in
+ * this case, since each item has 1 bit in it).
+ *
+ * For turbo encoders, there is 1 bit output per bit input per
+ * stream, with the addition of a some bits for trellis termination if
+ * selected.  Thus the input:output bit ratio will be:
+ * 
+ * if (streaming | no termination), 1:1
+ *
+ * if (not streaming & termination), roughly 1:(1+X), where "X" is the
+ * total memory size of the code divided by the block length in bits.
+ * But this also depends on the state of the FSM ... how many bits are
+ * left before termination.
+ */
+
+void gr_streams_encode_turbo::forecast
+(int noutput_items,
+ gr_vector_int &ninput_items_required)
+{
+  int ninput_items = d_encoder->compute_n_input_bits (noutput_items);
+  size_t ninputs = ninput_items_required.size();
+  for (size_t n = 0; n < ninputs; n++)
+    ninput_items_required[n] = ninput_items;
+}
+
+int
+gr_streams_encode_turbo::general_work
+(int noutput_items,
+ gr_vector_int &ninput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+  // FIXME: compute the actual number of output items (1 bit char's) created.
+
+  size_t t_n_input_items = d_encoder->compute_n_input_bits (noutput_items);
+  size_t t_n_output_items = d_encoder->compute_n_output_bits (t_n_input_items);
+
+  assert (t_n_output_items == ((size_t)noutput_items));
+
+  // "work" is handled by the encoder; which returns the actual number
+  // of input items (1-bit char's) used.
+
+  t_n_input_items = d_encoder->encode ((const char **)(&input_items[0]), 
+                                      (char **)(&output_items[0]),
+                                      (size_t) noutput_items);
+
+  // consume the number of used input items on all input streams
+
+  consume_each (t_n_input_items);
+
+  // returns number of items written to each output stream
+
+  return (noutput_items);
+}
diff --git a/gr-error-correcting-codes/src/lib/gr_streams_encode_turbo.h b/gr-error-correcting-codes/src/lib/gr_streams_encode_turbo.h
new file mode 100644 (file)
index 0000000..9427724
--- /dev/null
@@ -0,0 +1,104 @@
+/* -*- 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 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.
+ */
+
+#ifndef INCLUDED_GR_STREAMS_ENCODE_TURBO_H
+#define INCLUDED_GR_STREAMS_ENCODE_TURBO_H
+
+#include <gr_block.h>
+#include <gr_streams_encode_convolutional.h>
+
+#if 0
+#include <libecc/encoder_turbo_ic1_ic1.h>
+#else
+#include <libecc/encoder_turbo.h>
+#endif
+
+/*!
+ * \brief Encode the incoming stream(s) using a turbo encoder
+ *
+ * input: streams of char, one stream per input as defined by the
+ *     instantiated code, using only the right-most justified bit as
+ *     the single input bit per input item.
+ *
+ * output: streams of char, one stream per output as defined by the
+ *     instantiated code, using only the right-most justified bit as
+ *     the single output bit per output item.
+ *
+ * n_code_inputs:
+ * n_code_outputs: the total number of code inputs and outputs for the
+ *     overall turbo encoder (not just the constituent codes).
+ *
+ * encoders: the constituent encoders to be used; all -should- be
+ *     configured with the same "block_size" and "termination", though
+ *     from this encoder's perspective it doesn't really matter.
+ *
+ * interleavers: the interleavers to use before each encoder,
+ *     respectively, except the first encoder which will not use an
+ *     interleaver.
+ */
+
+class gr_streams_encode_turbo;
+
+typedef boost::shared_ptr<gr_streams_encode_turbo>
+gr_streams_encode_turbo_sptr;
+
+gr_streams_encode_turbo_sptr
+gr_make_streams_encode_turbo
+(int n_code_inputs,
+ int n_code_outputs,
+ const std::vector<gr_streams_encode_convolutional_sptr> &encoders,
+ const std::vector<size_t> &interleavers);
+
+class gr_streams_encode_turbo : public gr_block
+{
+  friend gr_streams_encode_turbo_sptr
+  gr_make_streams_encode_turbo
+    (int n_code_inputs,
+     int n_code_outputs,
+     const std::vector<gr_streams_encode_convolutional_sptr> &d_encoders,
+     const std::vector<size_t> &d_interleavers);
+
+  gr_streams_encode_turbo
+    (int n_code_inputs,
+     int n_code_outputs,
+     const std::vector<gr_streams_encode_convolutional_sptr> &d_encoders,
+     const std::vector<size_t> &d_interleavers);
+
+  std::vector<gr_streams_encode_turbo_sptr> d_encoders;
+  std::vector<size_t> d_interleavers;
+  size_t d_n_encoders, d_block_size_bits;
+  bool d_do_termination;
+  encoder_turbo* d_encoder;
+
+public:
+  ~gr_streams_encode_turbo ();
+
+  virtual void forecast (int noutput_items,
+                        gr_vector_int &ninput_items_required);
+
+  virtual 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_GR_STREAMS_ENCODE_TURBO_H */
diff --git a/gr-error-correcting-codes/src/lib/gr_streams_encode_turbo.i b/gr-error-correcting-codes/src/lib/gr_streams_encode_turbo.i
new file mode 100644 (file)
index 0000000..59ca5c5
--- /dev/null
@@ -0,0 +1,41 @@
+/* -*- 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 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.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,streams_encode_turbo);
+
+#include <gr_streams_encode_convolutional.h>
+
+gr_streams_encode_turbo_sptr
+gr_make_streams_encode_turbo
+(int n_code_inputs,
+ int n_code_outputs,
+ const std::vector<gr_streams_encode_convolutional_sptr> &encoders,
+ const std::vector<size_t> &interleavers);
+
+class gr_streams_encode_turbo : public gr_block
+{
+  gr_streams_encode_turbo
+  (int frame_size_bits,
+   int n_code_inputs,
+   const std::vector<gr_streams_encode_convolutional_sptr> &encoders,
+   const std::vector<size_t> &interleavers);
+};
diff --git a/gr-error-correcting-codes/src/lib/gr_syms_to_metrics.cc b/gr-error-correcting-codes/src/lib/gr_syms_to_metrics.cc
new file mode 100644 (file)
index 0000000..7a12309
--- /dev/null
@@ -0,0 +1,167 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_syms_to_metrics.h>
+#include <gr_io_signature.h>
+#include <assert.h>
+
+gr_syms_to_metrics_sptr 
+gr_make_syms_to_metrics (gr_feval_ff* pdf_fcn_0_bit,
+                        gr_feval_ff* pdf_fcn_1_bit,
+                        int n_samples,
+                        float min_sample,
+                        float max_sample,
+                        int sample_precision)
+{
+  return gr_syms_to_metrics_sptr
+    (new gr_syms_to_metrics (pdf_fcn_0_bit,
+                            pdf_fcn_1_bit,
+                            n_samples,
+                            min_sample,
+                            max_sample,
+                            sample_precision));
+}
+
+/*
+ * dummy functions and variables to get the float(*)(float) function
+ * to work properly with the gr_feval_XX stuff.
+ */
+
+static gr_feval_ff* l_pdf_fcn_0_bit;
+static gr_feval_ff* l_pdf_fcn_1_bit;
+
+static float pdf_fcn_0 (float x)
+{
+  return (l_pdf_fcn_0_bit->eval (x));
+}
+
+static float pdf_fcn_1 (float x)
+{
+  return (l_pdf_fcn_1_bit->eval (x));
+}
+
+gr_syms_to_metrics::gr_syms_to_metrics
+(gr_feval_ff* pdf_fcn_0_bit,
+ gr_feval_ff* pdf_fcn_1_bit,
+ int n_samples,
+ float min_sample,
+ float max_sample,
+ int sample_precision)
+  : gr_block ("syms_to_metrics",
+             gr_make_io_signature (1, -1, sizeof (float)),
+             gr_make_io_signature (0, 0, 0))
+{
+  if ((sample_precision < 0) | (sample_precision > 32)) {
+    fprintf (stderr, "gr_syms_to_metrics: sample_precision must be "
+            " between 0 and 32.\n");
+    assert (0);
+  }
+
+  l_pdf_fcn_0_bit = pdf_fcn_0_bit;
+  l_pdf_fcn_1_bit = pdf_fcn_1_bit;
+
+  if (sample_precision == 0) {
+    // float
+    d_out_item_size_bytes = sizeof (float);
+    d_code_metrics = new code_metric_ff (&pdf_fcn_0,
+                                        &pdf_fcn_1,
+                                        n_samples,
+                                        min_sample,
+                                        max_sample);
+  } else if (sample_precision <= 8) {
+    // use char
+    d_out_item_size_bytes = sizeof (char);
+    d_code_metrics = new code_metric_fb (&pdf_fcn_0,
+                                        &pdf_fcn_1,
+                                        n_samples,
+                                        min_sample,
+                                        max_sample,
+                                        sample_precision);
+  } else if (sample_precision <= 16) {
+    // use short
+    d_out_item_size_bytes = sizeof (short);
+    d_code_metrics = new code_metric_fs (&pdf_fcn_0,
+                                        &pdf_fcn_1,
+                                        n_samples,
+                                        min_sample,
+                                        max_sample,
+                                        sample_precision);
+  } else {
+    // use long
+    d_out_item_size_bytes = sizeof (long);
+    d_code_metrics = new code_metric_fl (&pdf_fcn_0,
+                                        &pdf_fcn_1,
+                                        n_samples,
+                                        min_sample,
+                                        max_sample,
+                                        sample_precision);
+  }
+
+  set_output_signature (gr_make_io_signature (1, -1, d_out_item_size_bytes));
+}
+
+bool gr_syms_to_metrics::check_topology (int ninputs, int noutputs)
+{
+  return ((noutputs == (2*ninputs)) ? true : false);
+}
+
+void
+gr_syms_to_metrics::forecast
+(int noutput_items,
+ gr_vector_int &ninput_items_required)
+{
+  // always 1:1, for all streams
+  for (size_t n = 0; n < ninput_items_required.size(); n++) {
+    ninput_items_required[n] = noutput_items;
+  }
+}
+
+int
+gr_syms_to_metrics::general_work
+(int noutput_items,
+ gr_vector_int &ninput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+  size_t l_n_output_items = noutput_items;
+
+  for (size_t n = 0; n < input_items.size(); n++) {
+    float* t_in_buf = (float*)(&input_items[n]);
+    void* t_out_buf_0_bit = (void*)(&(output_items[2*n]));
+    void* t_out_buf_1_bit = (void*)(&(output_items[(2*n)+1]));
+
+    d_code_metrics->convert (l_n_output_items, t_in_buf,
+                            t_out_buf_0_bit, t_out_buf_1_bit);
+  }
+
+  // consume the number of used input items on all input streams
+
+  consume_each (noutput_items);
+
+  // returns number of items written to each output stream
+
+  return (noutput_items);
+}
diff --git a/gr-error-correcting-codes/src/lib/gr_syms_to_metrics.h b/gr-error-correcting-codes/src/lib/gr_syms_to_metrics.h
new file mode 100644 (file)
index 0000000..d084fde
--- /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 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.
+ */
+
+#ifndef INCLUDED_SYMS_TO_METRICS_H
+#define INCLUDED_SYMS_TO_METRICS_H
+
+#include <gr_block.h>
+#include <gr_feval.h>
+#include <vector>
+#include <libecc/code_metrics.h>
+
+class gr_syms_to_metrics;
+typedef boost::shared_ptr<gr_syms_to_metrics> gr_syms_to_metrics_sptr;
+
+gr_syms_to_metrics_sptr gr_make_syms_to_metrics
+(gr_feval_ff* pdf_fcn_0_bit,
+ gr_feval_ff* pdf_fcn_1_bit,
+ int n_samples,
+ float min_sample,
+ float max_sample,
+ int sample_precision);
+
+/*!
+ * \brief Convert the input stream(s) of soft (float) symbols to
+ * log-probability metrics of user-specified precision; output is 2
+ * streams per input stream, each stream consisting of the metric for
+ * receiving a 0-bit and 1-bit, respectively, with the lower-numbered
+ * stream being the 0-bit.
+ *
+ * input: stream(s) of float; output: stream(s) of metrics
+ */
+
+class gr_syms_to_metrics : public gr_block
+{
+  friend gr_syms_to_metrics_sptr
+  gr_make_syms_to_metrics (gr_feval_ff* pdf_fcn_0_bit,
+                          gr_feval_ff* pdf_fcn_1_bit,
+                          int n_samples,
+                          float min_sample,
+                          float max_sample,
+                          int sample_precision);
+
+/*
+ * gr_syms_to_metrics: Convert the input soft (float) symbols into
+ *     log-probabilities (metrics) for use in the convolutional
+ *     decoder.  Samples the provided PDF function in 'n_samples'
+ *     places from 'min_sample' to 'max_sample', takes the log of that
+ *     value, then converts the result into a given precision and
+ *     stores all results in a "handy dandy" lookup table for much
+ *     faster processing.
+ *
+ * pdf_fcn_0_bit: point to a probability distribution function which
+ *     takes a float and returns a float, for the 0-bit probabilities.
+ *
+ * pdf_fcn_1_bit: point to a probability distribution function which
+ *     takes a float and returns a float, for the 1-bit probabilities.
+ *
+ * n_samples: the number of samples between min_sample and max_sample
+ *     to store in the lookup table.  Must be at least 2, but
+ *     otherwise is limited only by the amount of available memory;
+ *     generally, 65536 (1 << 16) is plenty of samples.
+ *
+ * min_sample: the minimum value below which any incoming value is
+ *     "rounded" up.
+ *
+ * max_sample: the maximum value above which any incoming value is
+ *     "rounded" down.
+ *
+ * sample_precision: the precision with which to sample the returned
+ *     value of the PDF function.
+ *  +  Cannot be < 0 or > 32.
+ *  +  "soft float" == 0
+ *  + otherwise, convert to an integer of the given value
+ *
+ * in "work", finds the (linearly) closest sample value for the given
+ *     input and outputs the metric for a 0-bit input on the first
+ *     stream and a 1-bit input on the second stream.
+ *
+ */
+
+  gr_syms_to_metrics (gr_feval_ff* pdf_fcn_0_bit,
+                     gr_feval_ff* pdf_fcn_1_bit,
+                     int n_samples,
+                     float min_sample,
+                     float max_sample,
+                     int sample_precision);
+
+  size_t d_out_item_size_bytes;
+  code_metrics* d_code_metrics;
+
+public:
+  bool check_topology (int ninputs, int noutputs);
+
+  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);
+};
+
+#endif /* INCLUDED_SYMS_TO_METRICS_H */
diff --git a/gr-error-correcting-codes/src/lib/gr_syms_to_metrics.i b/gr-error-correcting-codes/src/lib/gr_syms_to_metrics.i
new file mode 100644 (file)
index 0000000..6a76a71
--- /dev/null
@@ -0,0 +1,41 @@
+/* -*- 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 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.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,syms_to_metrics);
+
+gr_syms_to_metrics_sptr gr_make_syms_to_metrics
+(gr_feval_ff* pdf_fcn_0_bit,
+ gr_feval_ff* pdf_fcn_1_bit,
+ int n_samples,
+ float min_sample, 
+ float max_sample,
+ int sample_precision);
+
+class gr_syms_to_metrics : public gr_block
+{
+  gr_syms_to_metrics (gr_feval_ff* pdf_fcn_0_bit,
+                     gr_feval_ff* pdf_fcn_1_bit,
+                     int n_samples,
+                     float min_sample, 
+                     float max_sample,
+                     int sample_precision);
+};
diff --git a/gr-error-correcting-codes/src/lib/libecc/Makefile.am b/gr-error-correcting-codes/src/lib/libecc/Makefile.am
new file mode 100644 (file)
index 0000000..e2fa9ec
--- /dev/null
@@ -0,0 +1,60 @@
+#
+# 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 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.
+# 
+
+include $(top_srcdir)/Makefile.common
+
+SUBDIRS = mld . tests
+
+INCLUDES = $(STD_DEFINES_AND_INCLUDES) -I..
+
+noinst_LTLIBRARIES = libecc.la
+
+libecc_la_SOURCES =                            \
+       code_convolutional_trellis.cc           \
+       code_metrics.cc                         \
+       encoder.cc                              \
+       encoder_convolutional.cc                \
+       encoder_convolutional_ic1_ic1.cc        \
+       encoder_turbo.cc                        \
+       decoder.cc                              \
+       decoder_viterbi.cc                      \
+       decoder_viterbi_full_block.cc           \
+       decoder_viterbi_full_block_i1_ic1.cc
+
+noinst_HEADERS =                               \
+       code_types.h code_metrics.h             \
+       code_convolutional_trellis.h            \
+       encoder.h encoder_turbo.h               \
+       encoder_convolutional.h                 \
+       encoder_convolutional_ic1_ic1.h         \
+       decoder.h decoder_viterbi.h             \
+       decoder_viterbi_full_block.h            \
+       decoder_viterbi_full_block_i1_ic1.h
+
+# link the library against the c++ standard library
+libecc_la_LIBADD =             \
+       mld/libmld.la           \
+       $(PYTHON_LDFLAGS)       \
+       -lstdc++
+
+MOSTLYCLEANFILES = *.loT *~
+
+CONFIG_CLEAN_FILES = *.in
diff --git a/gr-error-correcting-codes/src/lib/libecc/code_convolutional_trellis.cc b/gr-error-correcting-codes/src/lib/libecc/code_convolutional_trellis.cc
new file mode 100644 (file)
index 0000000..72b8adb
--- /dev/null
@@ -0,0 +1,1028 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "code_convolutional_trellis.h"
+#include <assert.h>
+#include <iostream>
+
+#define DO_TIME_THOUGHPUT 0
+#define DO_PRINT_DEBUG 1
+#define DO_PRINT_DEBUG_ENCODE 1
+
+#include <mld/mld_timer.h>
+#include <mld/n2bs.h>
+
+static const int g_max_block_size_bits = 10000000;
+static const int g_max_num_streams = 10;
+static const int g_num_bits_per_byte = 8;
+
+/*
+ * sum_bits_mod2:
+ * sum the number of set bits, mod 2, for the output bit
+ */
+
+char
+code_convolutional_trellis::sum_bits_mod2
+(memory_t in_mem,
+ size_t max_memory)
+{
+  // there are faster ways to do this, but this works for now; could
+  // certainly do a single inline asm, which most processors provide
+  // to deal with summing the bits in an integer.
+  // this routine can be overridden by another method if desired.
+
+  char t_out_bit = (char)(in_mem & 1);
+  for (size_t r = max_memory; r > 0; r--) {
+    in_mem >>= 1;
+    t_out_bit ^= ((char)(in_mem & 1));
+  }
+  return (t_out_bit);
+}
+
+void
+code_convolutional_trellis::code_convolutional_trellis_init
+(int block_size_bits,
+ int n_code_inputs,
+ int n_code_outputs,
+ const std::vector<int>& code_generators,
+ const std::vector<int>* code_feedback,
+ bool do_termination,
+ int end_memory_state)
+{
+  // do error checking on the input arguments
+
+  // make sure the block length makes sense
+
+  if ((block_size_bits < 0) | (block_size_bits > g_max_block_size_bits)) {
+    std::cerr << "code_convolutional_trellis: " <<
+      "Requested block length (" << block_size_bits <<
+      " bits) must be between 0 and " << g_max_block_size_bits <<
+      " bits, with 0 being a streaming encoder.\n";
+    assert (0);
+  }
+
+  // check to make sure the number of input streams makes sense
+
+  if ((n_code_inputs <= 0) | (n_code_inputs > g_max_num_streams)) {
+    std::cerr << "code_convolutional_trellis: " <<
+      "Requested number of input streams (" <<
+      n_code_inputs << ") must be between 1 and " <<
+      g_max_num_streams << ".\n";
+    assert (0);
+  }
+
+  // check to make sure the number of output streams makes sense
+
+  if ((n_code_outputs <= 0) | (n_code_outputs > g_max_num_streams)) {
+    std::cerr << "code_convolutional_trellis: " <<
+      "Requested number of output streams (" <<
+      n_code_outputs << ") must be between 1 and " <<
+      g_max_num_streams << ".\n";
+    assert (0);
+  }
+
+  // make sure the code_generator is the correct length
+
+  if (code_generators.size () !=
+      ((size_t)(n_code_inputs * n_code_outputs))) {
+    std::cerr << "code_convolutional_trellis: " <<
+      "Number of code generator entries (" << code_generators.size () <<
+      ") is not equal to the product of the number of input and output" <<
+      " streams (" << (n_code_inputs * n_code_outputs) << ").\n";
+    assert (0);
+  }
+
+  // check for feedback (== NULL or not)
+
+  d_do_feedback = (code_feedback != NULL);
+
+  // create the class block variables
+
+  d_block_size_bits = block_size_bits;
+  d_n_code_inputs = n_code_inputs;
+  d_n_code_outputs = n_code_outputs;
+  d_do_streaming = (block_size_bits == 0);
+  d_do_termination = (d_do_streaming == true) ? false : do_termination;
+
+  if (DO_PRINT_DEBUG) {
+    std::cout <<
+      "d_block_size_bits = " << d_block_size_bits << "\n"
+      "d_n_code_inputs   = " << d_n_code_inputs << "\n"
+      "d_n_code_outputs  = " << d_n_code_outputs << "\n"
+      "d_do_streaming    = " <<
+      ((d_do_streaming == true) ? "true" : "false") << "\n"
+      "d_do_termination  = " <<
+      ((d_do_termination == true) ? "true" : "false") << "\n"
+      "d_do_feedback     = " <<
+      ((d_do_feedback == true) ? "true" : "false") << "\n";
+  }
+
+  // allocate the vectors for doing the encoding.  use memory_t (an
+  // interger type, at least 32 bits) bits to represent memory and the
+  // code, as it makes the operations quite simple the state vectors.
+
+  // d_states is a "matrix" [#input by #outputs] containing indices
+  // to memory_t's; this is done to make feedback function properly,
+  // and doesn't effect the computation time for feedforward.  The
+  // issue is that any code with the same feedback can use the same
+  // memory - thus reducing the actual number of memories required.
+  // These overlapping encoders will use the same actual memory, but
+  // given that there is no way to know a-priori where they are, use
+  // pointers over the full I/O matrix-space to make sure each I/O
+  // encoder uses the correct memory.
+  // reference the matrix using "maoi(i,o)" ... see .h file.
+
+  // code generators (feedforward part) are [#inputs x #outputs],
+  // always - one for each I/O combination.
+  // reference the matrix using "maoi(i,o)" ... see .h file
+
+  d_code_generators.assign (d_n_code_inputs * d_n_code_outputs, 0);
+
+  // check the feedback for correctness, before anything else, since
+  // any feedback impacts the total # of delays in the encoder:
+  // without feedback, this is the sum of the individual delays max'ed
+  // over each input (if siao) or output (if soai).
+
+  if (d_do_feedback == true) {
+    memory_t t_OR_all_feedback = 0;
+    for (size_t n = 0; n < d_n_code_outputs; n++) {
+      for (size_t m = 0; m < d_n_code_inputs; m++) {
+       memory_t t_in_code = (*code_feedback)[maoi(m,n)];
+
+       // OR this feedback with the overall,
+       // to check for any delays used at all
+
+       t_OR_all_feedback |= t_in_code;
+      }
+    }
+
+    // check to see if all the feedback entries were either "0" or "1",
+    // which implies no feedback; warn the user in that case and reset
+    // the do_feedback parameter to false.
+
+    if ((t_OR_all_feedback | 1) == 1) {
+      std::cout << "code_convolutional_trellis: Warning: " <<
+       "No feedback is required, ignoring feedback.\n";
+      d_do_feedback = false;
+    }
+  }
+
+  // copy over the FF code generators
+
+  for (size_t n = 0; n < d_n_code_outputs; n++)
+    for (size_t m = 0; m < d_n_code_inputs; m++)
+      d_code_generators[maio(m,n)] = code_generators[maio(m,n)];
+
+  // check the input FF (and FB) code generators for correctness, and
+  // find the minimum memory configuration: combining via a single
+  // input / all outputs (SIAO), or a single output / all inputs (SOAI).
+  //
+  // for FF only, look over both the SOAI and SIAO realizations to
+  // find the minimum total # of delays, and use that realization
+  // (SOAI is preferred if total # of delays is equal, since it's much
+  // simpler to implement).
+  //
+  // for FB:
+  //   for SIAO, check each input row (all outputs for a given input)
+  //     for unique feedback; duplicate feedback entries can be
+  //     combined into a single computation to reduce total # of delays.
+  //   for SOAI: check each output column (all inputs for a given
+  //     output) for unique feedback; duplicate feedback entries can
+  //     be combined into a simgle computation (ditto).
+
+  // check for SOAI all '0' output
+
+  for (size_t n = 0; n < d_n_code_outputs; n++) {
+    memory_t t_all_inputs_zero = 0;
+    for (size_t m = 0; m < d_n_code_inputs; m++)
+      t_all_inputs_zero |= d_code_generators[maio(m,n)];
+
+    // check this input to see if all encoders were '0'; this might be
+    // OK for some codes, but warn the user just in case
+
+    if (t_all_inputs_zero == 0) {
+      std::cout << "code_convolutional_trellis: Warning:"
+       "Output " << n+1 << " (of " << d_n_code_outputs <<
+       ") will always be 0.\n";
+    }
+  }
+
+  // check for SIAO all '0' input
+
+  for (size_t m = 0; m < d_n_code_inputs; m++) {
+    memory_t t_all_outputs_zero = 0;
+    for (size_t n = 0; n < d_n_code_outputs; n++)
+      t_all_outputs_zero |= d_code_generators[maio(m,n)];
+
+    // check this input to see if all encoders were '0'; this might be
+    // OK for some codes, but warn the user just in case
+
+    if (t_all_outputs_zero == 0) {
+      std::cout << "code_convolutional_trellis: Warning:"
+       "Input " << m+1 << " (of " << d_n_code_inputs <<
+       ") will not be used; all encoders are '0'.\n";
+    }
+  }
+
+  // check and compute memory requirements in order to determine which
+  // realization uses the least memory; create and save findings to
+  // not have to re-do these computations later.
+
+  // single output, all inputs (SOAI) realization:
+  // reset the global parameters
+
+  d_code_feedback.assign (d_n_code_inputs * d_n_code_outputs, 0);
+  d_n_delays.assign (d_n_code_inputs * d_n_code_outputs, 0);
+  d_io_num.assign (d_n_code_inputs * d_n_code_outputs, 0);
+  d_states_ndx.assign (d_n_code_inputs * d_n_code_outputs, 0);
+  d_max_delay = d_total_n_delays = d_n_memories = 0;
+  d_do_encode_soai = true;
+
+  for (size_t n = 0; n < d_n_code_outputs; n++) {
+    size_t t_max_mem = 0;
+    size_t t_n_unique_fb_prev_start = d_n_memories;
+
+    for (size_t m = 0; m < d_n_code_inputs; m++) {
+      get_memory_requirements (m, n, t_max_mem,
+                              t_n_unique_fb_prev_start, code_feedback);
+      if (d_do_feedback == false) {
+       d_states_ndx[maio(m,n)] = n;
+      }
+    }
+    if (d_do_feedback == false) {
+      // not feedback; just store memory requirements for this output
+      d_total_n_delays += t_max_mem;
+      d_n_delays[n] = t_max_mem;
+      d_io_num[n] = n;
+    }
+  }
+  if (d_do_feedback == false) {
+    d_n_memories = d_n_code_outputs;
+  }
+
+  // store the parameters for SOAI
+
+  std::vector<size_t> t_fb_generators_soai, t_n_delays_soai, t_io_num_soai;
+  std::vector<size_t> t_states_ndx_soai;
+  size_t t_max_delay_soai, t_total_n_delays_soai, t_n_memories_soai;
+
+  t_fb_generators_soai.assign (d_code_feedback.size (), 0);
+  t_fb_generators_soai = d_code_feedback;
+  t_n_delays_soai.assign (d_n_delays.size (), 0);
+  t_n_delays_soai = d_n_delays;
+  t_io_num_soai.assign (d_io_num.size (), 0);
+  t_io_num_soai = d_io_num;
+  t_states_ndx_soai.assign (d_states_ndx.size (), 0);
+  t_states_ndx_soai = d_states_ndx;
+
+  t_n_memories_soai = d_n_memories;
+  t_total_n_delays_soai = d_total_n_delays;
+  t_max_delay_soai = d_max_delay;
+
+  // single input, all outputs (SIAO) realization
+  // reset the global parameters
+
+  d_code_feedback.assign (d_n_code_inputs * d_n_code_outputs, 0);
+  d_n_delays.assign (d_n_code_inputs * d_n_code_outputs, 0);
+  d_io_num.assign (d_n_code_inputs * d_n_code_outputs, 0);
+  d_states_ndx.assign (d_n_code_inputs * d_n_code_outputs, 0);
+  d_max_delay = d_total_n_delays = d_n_memories = 0;
+  d_do_encode_soai = false;
+
+  for (size_t m = 0; m < d_n_code_inputs; m++) {
+    size_t t_max_mem = 0;
+    size_t t_n_unique_fb_prev_start = d_n_memories;
+
+    for (size_t n = 0; n < d_n_code_outputs; n++) {
+      get_memory_requirements (m, n, t_max_mem,
+                              t_n_unique_fb_prev_start, code_feedback);
+      if (d_do_feedback == false) {
+       d_states_ndx[maio(m,n)] = m;
+      }
+    }
+    if (d_do_feedback == false) {
+      // not feedback; just store memory requirements for this output
+      d_total_n_delays += t_max_mem;
+      d_n_delays[m] = t_max_mem;
+      d_io_num[m] = m;
+    }
+  }
+  if (d_do_feedback == false) {
+    d_n_memories = d_n_code_inputs;
+  }
+
+  if (DO_PRINT_DEBUG) {
+    std::cout <<
+      "  t_total_n_delays_siao  = " << d_total_n_delays << "\n"
+      "  t_total_n_delays_soai  = " << t_total_n_delays_soai << "\n";
+  }
+
+  // pick which realization to use; soai is preferred since it's faster
+  // ... but unfortunately it's also less likely
+
+  if (d_total_n_delays < t_total_n_delays_soai) {
+    // use siao
+    // nothing else to do, since the global variables already hold
+    // the correct values.
+  } else {
+    // use soai
+    d_do_encode_soai = true;
+    d_code_feedback = t_fb_generators_soai;
+    d_n_delays = t_n_delays_soai;
+    d_io_num = t_io_num_soai;
+    d_states_ndx = t_states_ndx_soai;
+    d_n_memories = t_n_memories_soai;
+    d_total_n_delays = t_total_n_delays_soai;
+    d_max_delay = t_max_delay_soai;
+  }
+
+  // make sure the block length makes sense, #2
+
+  if ((d_do_streaming == false) & (d_block_size_bits < d_max_delay)) {
+    std::cerr << "code_convolutional_trellis: " <<
+      "Requested block length (" << d_block_size_bits <<
+      " bit" << (d_block_size_bits > 1 ? "s" : "") <<
+      ") must be at least 1 memory length (" << d_max_delay <<
+      " bit" << (d_max_delay > 1 ? "s" : "") <<
+      " for this code) when doing block coding.\n";
+    assert (0);
+  }
+
+  // check & mask off the init states
+
+  d_n_states = (1 << d_total_n_delays);
+  d_n_input_combinations = (1 << d_n_code_inputs);
+
+  memory_t t_mask = (memory_t)((2 << d_total_n_delays) - 1);
+
+  if (end_memory_state & t_mask) {
+    std::cout << "code_convolutional_trellis: Warning: " <<
+      "provided end memory state out (" << end_memory_state <<
+      ") is out of the state range [0, " <<
+      (d_n_states-1) << "]; masking off the unused bits.\n";
+
+    end_memory_state &= t_mask;
+  }
+
+  // create the max_mem_mask to be used in encoding
+
+  d_max_mem_masks.assign (d_n_memories, 0);
+
+  for (size_t m = 0; m < d_n_memories; m++) {
+    if (d_n_delays[m] == sizeof (memory_t) * g_num_bits_per_byte)
+      d_max_mem_masks[m] = ((memory_t) -1);
+    else
+      d_max_mem_masks[m] = (memory_t)((2 << (d_n_delays[m])) - 1);
+  }
+
+  if (DO_PRINT_DEBUG) {
+    std::cout <<
+      "  d_n_memories      = " << d_n_memories << "\n"
+      "  d_total_n_delays  = " << d_total_n_delays << "\n"
+      "  d_max_delay       = " << d_max_delay << "\n"
+      "  d_do_encode_soai  = " << 
+      ((d_do_encode_soai == true) ? "true" : "false") << "\n";
+  }
+
+  // zero the memories
+
+  d_memory.assign (d_n_memories, 0);
+
+  // create the inputs and outputs buffers
+
+  d_current_inputs.assign (d_n_code_inputs, 0);
+  d_current_outputs.assign (d_n_code_outputs, 0);
+
+  // create the trellis for this code:
+
+  create_trellis ();
+
+  if (d_do_termination == true) {
+
+    // create the termination lookup table
+
+    create_termination_table (end_memory_state);
+  }
+}
+
+void
+code_convolutional_trellis::get_memory_requirements
+(size_t m,   // input number
+ size_t n,   // output number
+ size_t& t_max_mem,
+ size_t& t_n_unique_fb_prev_start,
+ const std::vector<int>* code_feedback)
+{
+  size_t t_in_code = d_code_generators[maio(m,n)];
+
+  // find the memory requirement for this code generator
+
+  size_t t_code_mem_ff = max_bit_position (t_in_code);
+
+  // check to see if this is bigger than any others in this row/column
+
+  if (t_code_mem_ff > t_max_mem)
+    t_max_mem = t_code_mem_ff;
+
+  if (DO_PRINT_DEBUG) {
+    std::cout << "c_g[" << m << "][" << n << "]{" <<
+      maio(m,n) << "} = " << n2bs(t_in_code, 8) <<
+      ", code_mem = " << t_code_mem_ff;
+  }
+
+  // check the feedback portion, if it exists;
+  // for soai, check all the inputs which generate this output for
+  // uniqueness; duplicate entries can be combined to reduce total
+  // # of memories as well as required computations.
+
+  if (d_do_feedback == true) {
+    if (DO_PRINT_DEBUG) {
+      std::cout << "\n";
+    }
+
+    // get the FB code; AND off the LSB for correct functionality
+    // during internal computations.
+
+    t_in_code = ((memory_t)((*code_feedback)[maio(m,n)]));
+    t_in_code &= ((memory_t)(-2));
+
+    // find the memory requirement
+
+    size_t t_code_mem_fb = max_bit_position (t_in_code);
+
+    if (DO_PRINT_DEBUG) {
+      std::cout << "c_f[" << m << "][" << n << "]{" <<
+       maio(m,n) << "} = " << n2bs(t_in_code, 8) <<
+       ", code_mem = " << t_code_mem_fb;
+    }
+
+    // check to see if this feedback is unique
+
+    size_t l_n_unique_fb = t_n_unique_fb_prev_start;
+    while (l_n_unique_fb < d_n_memories) {
+      if (d_code_feedback[l_n_unique_fb] == t_in_code)
+       break;
+      l_n_unique_fb++;
+    }
+    if (l_n_unique_fb == d_n_memories) {
+
+      // this is a unique feedback;
+
+      d_code_feedback[l_n_unique_fb] = t_in_code;
+      d_n_delays[l_n_unique_fb] = t_code_mem_fb;
+
+      // increase the number of unique feedback codes
+
+      d_n_memories++;
+
+      // store memory requirements for this output
+
+      if (t_max_mem < t_code_mem_fb)
+       t_max_mem = t_code_mem_fb;
+      d_total_n_delays += t_max_mem;
+
+      if (DO_PRINT_DEBUG) {
+       std::cout << ",  uq # " << l_n_unique_fb <<
+         ", tot_mem = " << d_total_n_delays;
+      }
+    } else {
+      // not a unique feedback, but the FF might require more memory
+
+      if (DO_PRINT_DEBUG) {
+       std::cout << ", !uq # " << l_n_unique_fb <<
+         " = " << d_n_delays[l_n_unique_fb];
+      }
+
+      if (d_n_delays[l_n_unique_fb] < t_code_mem_ff) {
+       d_total_n_delays += (t_code_mem_ff - d_n_delays[l_n_unique_fb]);
+       d_n_delays[l_n_unique_fb] = t_code_mem_ff;
+
+       if (DO_PRINT_DEBUG) {
+         std::cout << " => " << d_n_delays[l_n_unique_fb] <<
+           ", tot_mem = " << d_total_n_delays;
+       }
+      }
+    }
+    d_io_num[l_n_unique_fb] = ((d_do_encode_soai == true) ? n : m);
+    d_states_ndx[maio(m,n)] = l_n_unique_fb;
+  }
+  if (DO_PRINT_DEBUG) {
+    std::cout << "\n";
+  }
+  if (d_max_delay < t_max_mem)
+    d_max_delay = t_max_mem;
+}
+
+void
+code_convolutional_trellis::create_trellis
+()
+{
+  if (DO_PRINT_DEBUG_ENCODE) {
+    std::cout << "c_t: # states = " << d_n_states <<
+      ", d_n_input_combinations = " << d_n_input_combinations << "\n";
+  }
+
+  // first dimension is the number of states
+
+  d_trellis.resize (d_n_states);
+
+  // second dimension (one per first dimension) is the number of input
+  // combinations
+
+  for (size_t m = 0; m < d_n_states; m++) {
+    d_trellis[m].resize (d_n_input_combinations);
+    for (size_t n = 0; n < d_n_input_combinations; n++) {
+      connection_t_ptr t_connection = &(d_trellis[m][n]);
+      t_connection->d_output_bits.resize (d_n_code_outputs);
+    }
+  }
+
+  // fill in the trellis
+
+  for (size_t m = 0; m < d_n_states; m++) {
+    for (size_t n = 0; n < d_n_input_combinations; n++) {
+      connection_t_ptr t_connection = &(d_trellis[m][n]);
+      encode_single (m, n, t_connection->d_to_state,
+                    t_connection->d_output_bits);
+      if (DO_PRINT_DEBUG_ENCODE) {
+       std::cout << "set d_t[" << n2bs(m,d_total_n_delays) << "][" <<
+         n2bs(n,d_n_code_inputs) << "] : to_st = " <<
+         n2bs(t_connection->d_to_state,d_total_n_delays) << "\n";
+      }
+    }
+  }
+}
+
+void
+code_convolutional_trellis::demux_state
+(memory_t in_state,
+ std::vector<memory_t>& memories)
+{
+  // de-mux bits for the given memory state;
+  // copy them into the provided vector;
+  // assumes state bits start after the LSB (not at &1)
+
+  memories.resize (d_n_memories);
+  if (DO_PRINT_DEBUG_ENCODE) {
+    std::cout << "in_st = " << n2bs(in_state,d_total_n_delays) << " ->\n";
+  }
+  for (size_t m = 0; m < d_n_memories; m++) {
+    memories[m] = (in_state << 1) & d_max_mem_masks[m];
+    in_state >>= d_n_delays[m];
+    if (DO_PRINT_DEBUG_ENCODE) {
+      std::cout << "  #d = " << d_n_delays[m] << ", mem[" << m << "] = " <<
+       n2bs(memories[m], d_n_delays[m]+1) << "\n";
+    }
+  }
+}
+
+memory_t
+code_convolutional_trellis::mux_state
+(const std::vector<memory_t>& memories)
+{
+  // mux bits for the given memory states in d_memory
+  // assumes state bits start after the LSB (not at &1)
+  memory_t t_state = 0;
+  size_t shift = 0;
+  for (size_t m = 0; m < d_n_memories; m++) {
+    t_state |= (memories[m] >> 1) << shift;
+    shift += d_n_delays[m];
+    if (DO_PRINT_DEBUG_ENCODE) {
+      std::cout << "  #d = " << d_n_delays[m] << ", mem[" << m << "] = " <<
+       n2bs(memories[m], d_n_delays[m]+1) << " -> st = " <<
+       n2bs(t_state, d_total_n_delays) << "\n";
+    }
+  }
+  return (t_state);
+}
+
+void
+code_convolutional_trellis::demux_inputs
+(memory_t inputs,
+ std::vector<char>& in_vec)
+{
+  for (size_t m = 0; m < d_n_code_inputs; m++, inputs >>= 1) {
+    in_vec[m] = (char)(inputs & 1);
+  }
+}
+
+memory_t
+code_convolutional_trellis::mux_inputs
+(const std::vector<char>& in_vec)
+{
+  size_t bit_shift = 0;
+  memory_t inputs = 0;
+  for (size_t m = 0; m < in_vec.size(); m++, bit_shift++) {
+    inputs |= (((memory_t)(in_vec[m]&1)) << bit_shift);
+  }
+  return (inputs);
+}
+
+void
+code_convolutional_trellis::encode_single
+(memory_t in_state,
+ size_t inputs,
+ memory_t& out_state,
+ std::vector<char>& out_bits)
+{
+  // set input parameters
+
+  demux_state (in_state, d_memory);
+  demux_inputs (inputs, d_current_inputs);
+
+  // call the correct function to do the work
+
+  if (d_do_encode_soai == true) {
+    if (d_do_feedback == true) {
+      encode_single_soai_fb ();
+    } else {
+      encode_single_soai ();
+    }
+  } else {
+    if (d_do_feedback == true) {
+      encode_single_siao_fb ();
+    } else {
+      encode_single_siao ();
+    }
+  }
+
+  // retrieve the output parameters
+
+  out_state = mux_state (d_memory);
+  out_bits = d_current_outputs;
+}
+
+void
+code_convolutional_trellis::encode_lookup
+(memory_t& state,
+ const std::vector<char>& inputs,
+ std::vector<char>& out_bits)
+{
+  if (DO_PRINT_DEBUG_ENCODE) {
+    std::cout << "using d_t[" << state << "][" << mux_inputs(inputs) <<
+      "] = ";
+    std::cout.flush ();
+  }
+
+  connection_t_ptr t_connection = &(d_trellis[state][mux_inputs(inputs)]);
+
+  if (DO_PRINT_DEBUG_ENCODE) {
+    std::cout << t_connection << ": to_state = "
+             << t_connection->d_to_state << "\n";
+  }
+
+  state = t_connection->d_to_state;
+  out_bits = t_connection->d_output_bits;
+}
+
+void
+code_convolutional_trellis::get_termination_inputs
+(memory_t term_start_state,
+ size_t bit_num,
+ std::vector<char>& inputs)
+{
+  inputs.resize (d_n_code_inputs);
+  for (size_t m = 0; m < d_n_code_inputs; m++) {
+    inputs[m] = ((d_term_inputs[term_start_state][m]) >> bit_num) & 1;
+  }
+}
+
+void
+code_convolutional_trellis::create_termination_table
+(memory_t end_memory_state)
+{
+  // somewhat involved, but basically start with the terminating state
+  // and work backwards d_total_n_delays, then create a
+  // std::vector<memory_t> of length n_states, once per path required
+  // to get from the given state to the desired termination state.
+  //
+  // each entry represents the bits required to terminate that
+  // particular state, listed in order from LSB for the first input
+  // bit to the MSB for the last input bit.
+
+#if 0
+  // create a reverse trellis
+  // it's temporary, just for doing the termination, so just do it locally
+
+  trellis_t t_trellis;
+
+  // first dimension is the number of states
+
+  t_trellis.resize (d_n_states);
+
+  // second dimension (one per first dimension) is the number of input
+  // combinations
+
+  for (size_t m = 0; m < d_n_states; m++) {
+    t_trellis[m].resize (d_n_input_combinations);
+  }
+
+  std::vector<char> outputs (d_n_code_outputs);
+  memory_t to_state;
+
+  // fill in the trellis
+
+  for (memory_t m = 0; m < d_n_states; m++) {
+    for (memory_t n = 0; n < d_n_input_combinations; n++) {
+      encode_single (m, n, to_state, outputs);
+
+      connection_t_ptr t_connection = &(t_trellis[to_state][n]);
+      t_connection->d_to_state = m;
+#if 0
+      t_connection->d_output_bits.resize (d_n_code_outputs);
+      t_connection->d_output_bits = outputs;
+#endif
+    }
+  }
+
+  // create the output vectors
+
+  term_input_t t_term_inputs;
+  t_term_inputs.resize (d_n_states);
+  for (size_t m = 0; m < d_n_states; m++) {
+    t_term_inputs[m].assign (d_n_code_inputs, 0);
+  }
+
+
+  std::vector<memory_t> t_used_states;
+  t_used_states.assign (d_n_states, 0);
+
+  // setup the first state
+
+  t_states[0] = end_memory_state;
+  size_t n_states = 1;
+
+  for (size_t m = 0; m < d_total_n_delays; m++) {
+    for (size_t n = 0; n < n_states; n++) {
+      memory_t t_end_state = t_states[n];
+      for (size_t p = 0; p < d_n_code_inputs; p++) {
+       connection_t_ptr t_connection = &(t_trellis[t_end_state][p]);
+       memory_t_ptr t_mem = &(t_term_inputs[t_end_state][p]);
+
+
+
+      
+    }
+  }
+
+  t_inputs[0] = t_trellis
+#endif
+}
+
+void
+code_convolutional_trellis::encode_single_soai
+()
+{
+  // single-output, all inputs; no feedback
+
+  if (DO_PRINT_DEBUG) {
+    std::cout << "Starting encode_single_soai.\n";
+  }
+
+  // shift memories down by 1 bit to make room for feedback; no
+  // masking required.
+
+  for (size_t p = 0; p < d_n_memories; p++) {
+    if (DO_PRINT_DEBUG) {
+      std::cout << "m_i[" << p << "] = " <<
+       n2bs(d_memory[p], 1+d_n_delays[p]);
+    }
+
+    d_memory[p] >>= 1;
+
+    if (DO_PRINT_DEBUG) {
+      std::cout << "  >>= 1 -> " <<
+       n2bs(d_memory[p], 1+d_n_delays[p]) << "\n";
+    }
+  }
+
+  // for each input bit, if that bit's a '1', then XOR the code
+  // generators into the correct state's memory.
+
+  for (size_t m = 0; m < d_n_code_inputs; m++) {
+    if (DO_PRINT_DEBUG) {
+      std::cout << "c_i[" << m << "] = " <<
+       n2bs(d_current_inputs[m],1);
+    }
+    if (d_current_inputs[m] == 1) {
+      if (DO_PRINT_DEBUG) {
+       std::cout << "\n";
+      }
+      for (size_t n = 0; n < d_n_code_outputs; n++) {
+       if (DO_PRINT_DEBUG) {
+         std::cout << "m_i[s_ndx[" << m << "][" << n << "] == " <<
+           d_states_ndx[maio(m,n)] << "] = " <<
+           n2bs(d_memory[d_states_ndx[maio(m,n)]],
+                1+d_n_delays[d_states_ndx[maio(m,n)]]);
+       }
+
+       d_memory[d_states_ndx[maio(m,n)]] ^= d_code_generators[maio(m,n)];
+
+       if (DO_PRINT_DEBUG) {
+         std::cout << " ^= c_g[][] == " <<
+           n2bs(d_code_generators[maio(m,n)],
+                1+d_n_delays[d_states_ndx[maio(m,n)]]) <<
+           " -> " << n2bs(d_memory[d_states_ndx[maio(m,n)]],
+                          1+d_n_delays[d_states_ndx[maio(m,n)]]) << "\n";
+       }
+      }
+    } else if (DO_PRINT_DEBUG) {
+      std::cout << " ... nothing to do\n";
+    }
+  }
+
+  for (size_t p = 0; p < d_n_code_outputs; p++) {
+    d_current_outputs[p] = 0;
+  }
+
+  // create the output bits, by XOR'ing the individual unique
+  // memory(ies) into the correct output bit
+
+  for (size_t p = 0; p < d_n_memories; p++) {
+    d_current_outputs[d_io_num[p]] ^= ((char)(d_memory[p] & 1));
+  }
+
+  if (DO_PRINT_DEBUG) {
+    std::cout << "ending encode_single_soai.\n";
+  }
+}
+
+void
+code_convolutional_trellis::encode_single_soai_fb
+()
+{
+  // single-output, all inputs; with feedback
+
+  if (DO_PRINT_DEBUG) {
+    std::cout << "Starting encode_single_soai_fb.\n";
+  }
+
+  // shift memories down by 1 bit to make room for feedback; no
+  // masking required.
+
+  for (size_t p = 0; p < d_n_memories; p++) {
+    if (DO_PRINT_DEBUG) {
+      std::cout << "m_i[" << p << "] = " << d_memory[p];
+    }
+
+    d_memory[p] >>= 1;
+
+    if (DO_PRINT_DEBUG) {
+      std::cout << " -> " << d_memory[p] << "\n";
+    }
+  }
+
+  // for each input bit, if that bit's a '1', then XOR the code
+  // generators into the correct state's memory.
+
+  for (size_t m = 0; m < d_n_code_inputs; m++) {
+    if (d_current_inputs[m] == 1) {
+      for (size_t n = 0; n < d_n_code_outputs; n++) {
+       d_memory[d_states_ndx[maio(m,n)]] ^= d_code_generators[maio(m,n)];
+      }
+    }
+  }
+
+  for (size_t p = 0; p < d_n_code_outputs; p++) {
+    d_current_outputs[p] = 0;
+  }
+
+  // create the output bits, by XOR'ing the individual unique
+  // memory(ies) into the correct output bit
+
+  for (size_t p = 0; p < d_n_memories; p++) {
+    d_current_outputs[d_io_num[p]] ^= ((char)(d_memory[p] & 1));
+  }
+
+  // now that the output bits are fully created, XOR the FB back
+  // into the memories; the feedback bits have the LSB (&1) masked
+  // off already so that it doesn't contribute.
+
+  for (size_t p = 0; p < d_n_memories; p++) {
+    if (d_current_outputs[d_io_num[p]] == 1) {
+      d_memory[p] ^= d_code_feedback[p];
+    }
+  }
+
+  if (DO_PRINT_DEBUG) {
+    std::cout << "ending encode_single_soai.\n";
+  }
+}
+
+void
+code_convolutional_trellis::encode_single_siao
+()
+{
+  // single input, all outputs; no feedback
+
+  if (DO_PRINT_DEBUG) {
+    std::cout << "starting encode_single_siao.\n";
+  }
+
+  // update the memories with the current input bits;
+
+  // for each unique memory (1 per input), shift the delays and mask
+  // off the extra high bits; then XOR in the input bit.
+
+  for (size_t p = 0; p < d_n_memories; p++) {
+    d_memory[p] |= ((memory_t)(d_current_inputs[d_io_num[p]]));
+  }
+
+  // create the output bits: for each output, loop over all inputs,
+  // find the output bits for each encoder, and XOR each together
+  // then sum (would usually be sum then XOR, but they're mutable in
+  // base-2 and it's faster this way).
+
+  for (size_t n = 0; n < d_n_code_outputs; n++) {
+    memory_t t_mem = 0;
+    for (size_t m = 0; m < d_n_code_inputs; m++) {
+      t_mem ^= ((d_memory[d_states_ndx[maio(m,n)]]) &
+               d_code_generators[maio(m,n)]);
+    }
+    d_current_outputs[n] = sum_bits_mod2 (t_mem, d_max_delay);
+  }
+
+  // post-shift & mask the memory to guarantee that output
+  // state is in the correct bit positions (1 up, not the LSB)
+
+  for (size_t p = 0; p < d_n_memories; p++) {
+    d_memory[p] = (d_memory[p] << 1) & d_max_mem_masks[p];
+  }
+
+  if (DO_PRINT_DEBUG) {
+    std::cout << "ending encode_single_siao.\n";
+  }
+}
+
+void
+code_convolutional_trellis::encode_single_siao_fb
+()
+{
+  // single input, all outputs; with feedback
+
+  if (DO_PRINT_DEBUG) {
+    std::cout << "starting encode_single_siao_fb.\n";
+  }
+
+  // update the memories with the current input bits;
+
+  // for each unique memory (1 per input), shift the delays and mask
+  // off the extra high bits; then XOR in the input bit.
+  // with FB: find the feedback bit, and OR it into the input bit's slot;
+
+  for (size_t p = 0; p < d_n_memories; p++) {
+    memory_t t_mem = d_memory[p];
+    memory_t t_fb = t_mem & d_code_feedback[p];
+    char t_fb_bit = sum_bits_mod2 (t_fb, d_max_delay);
+    t_mem |= ((memory_t) t_fb_bit);
+    d_memory[p] = t_mem ^ ((memory_t)(d_current_inputs[d_io_num[p]]));
+  }
+
+  // create the output bits: for each output, loop over all inputs,
+  // find the output bits for each encoder, and XOR each together
+  // then sum (would usually be sum then XOR, but they're mutable in
+  // base-2 and it's faster this way).
+
+  for (size_t n = 0; n < d_n_code_outputs; n++) {
+    memory_t t_mem = 0;
+    for (size_t m = 0; m < d_n_code_inputs; m++) {
+      t_mem ^= ((d_memory[d_states_ndx[maio(m,n)]]) &
+               d_code_generators[maio(m,n)]);
+    }
+    d_current_outputs[n] = sum_bits_mod2 (t_mem, d_max_delay);
+  }
+
+  // post-shift & mask the memory to guarantee that output
+  // state is in the correct bit positions (1 up, not the LSB)
+
+  for (size_t p = 0; p < d_n_memories; p++) {
+    d_memory[p] = (d_memory[p] << 1) & d_max_mem_masks[p];
+  }
+
+  if (DO_PRINT_DEBUG) {
+    std::cout << "ending encode_loop_siao_fb.\n";
+  }
+}
diff --git a/gr-error-correcting-codes/src/lib/libecc/code_convolutional_trellis.h b/gr-error-correcting-codes/src/lib/libecc/code_convolutional_trellis.h
new file mode 100644 (file)
index 0000000..205ccc0
--- /dev/null
@@ -0,0 +1,372 @@
+/* -*- 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 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.
+ */
+
+#ifndef INCLUDED_CODE_CONVOLUTIONAL_TRELLIS_H
+#define INCLUDED_CODE_CONVOLUTIONAL_TRELLIS_H
+
+#include "code_types.h"
+#include <vector>
+
+/*
+ * connection_t: describes an output connection from the current
+ *     time-bit memory state to the next time-bit memory state
+ *
+ * d_to_state: memory configuration of the "to" state
+ *
+ * d_output_bits: the output bits for this connection
+ */
+
+typedef struct connection_t {
+  memory_t d_to_state;
+  std::vector<char> d_output_bits;
+} connection_t, *connection_t_ptr;
+
+/*
+ * trellis_t: describes a single set of trellis connections, from a
+ *     time-bit to the next, forward transitions only
+ *
+ * This is a 2d "matrix", where the first dimention is the starting
+ *     memory state, and the second is the (combined) input as an
+ *     integer: e.g. for a 2 input code, if I1 = 0 and I2 = 1, then
+ *     the combined input is the "number" found by appending I2 and I1
+ *     together, in this case 10b = 3.
+ *
+ * The trellis is used to lookup information: given a starting state
+ *     and inputs, return the output bits and next state.
+ */
+
+typedef std::vector<std::vector<connection_t> > trellis_t, *trellis_t_ptr;
+
+class code_convolutional_trellis
+{
+/*!
+ * class code_convolutional_trellis
+ *
+ * Create a convolutional code trellis structure, but encoding,
+ * decoding, determining termination transitions, and anything else
+ * which might be useful.
+ *
+ * block_size_bits: if == 0, then do streaming encoding ("infinite"
+ *     trellis); otherwise this is the block size in bits to encode
+ *     before terminating the trellis.  This value -does not- include
+ *     any termination bits.
+ *
+ * n_code_inputs:
+ * n_code_outputs:
+ * code_generator: vector of integers (32 bit) representing the code
+ *     to be implemented.  E.g. "4" in binary is "100", which would be
+ *     "D^2" for code generation.  "6" == 110b == "D^2 + D"
+ *  ==> The vector is listed in order for each output stream, so if there
+ *     are 2 input streams (I1, I2) [specified in "n_code_inputs"]
+ *     and 2 output streams (O1, O2) [specified in "n_code_outputs"],
+ *     then the vector would be the code generator for:
+ *       [I1->O1, I2->O1, I1->O2, I2->O2]
+ *     with each element being an integer representation of the code.
+ *     The "octal" representation is used frequently in the literature
+ *     (e.g. [015, 06] == [1101, 0110] in binary) due to its close
+ *     relationship with binary (each number is 3 binary digits)
+ *     ... but any integer representation will suffice.
+ *
+ * do_termination: valid only if block_size_bits != 0, and defines
+ *     whether or not to use trellis termination.  Default is to use
+ *     termination when doing block coding.
+ *
+ * start_memory_state: when starting a new block, the starting memory
+ *     state to begin encoding; there will be a helper function to
+ *     assist in creating this value for a given set of inputs;
+ *     default is the "all zero" state.
+ * 
+ * end_memory_state: when terminating a block, the ending memory
+ *     state to stop encoding; there will be a helper function to
+ *     assist in creating this value for a given set of inputs;
+ *     default is the "all zero" state.
+ */
+
+public:
+  inline code_convolutional_trellis
+  (int block_size_bits,
+   int n_code_inputs,
+   int n_code_outputs,
+   const std::vector<int> &code_generators,
+   bool do_termination = true,
+   int end_memory_state = 0)
+  {code_convolutional_trellis_init (block_size_bits,
+                                   n_code_inputs,
+                                   n_code_outputs,
+                                   code_generators,
+                                   NULL,
+                                   do_termination,
+                                   end_memory_state);};
+
+/*!
+ * Encoder with feedback.
+ *
+ * code_feedback: vector of integers (32 bit) representing the code
+ *     feedback to be implemented (same as for the code_generator).
+ *     For this feedback type, the LSB ("& 1") is ignored (set to "1"
+ *     internally, since it's always 1) ... this (effectively)
+ *     represents the input bit for the given encoder, without which
+ *     there would be no encoding!  Each successive higher-order bit
+ *     represents the output of that delay block; for example "6" ==
+ *     110b == "D^2 + D" means use the current input bit + the output
+ *     of the second delay block.  Listing order is the same as for
+ *     the code_generator.
+ */
+
+  inline code_convolutional_trellis
+  (int block_size_bits,
+   int n_code_inputs,
+   int n_code_outputs,
+   const std::vector<int> &code_generators,
+   const std::vector<int> &code_feedback,
+   bool do_termination = true,
+   int end_memory_state = 0)
+  {code_convolutional_trellis_init (block_size_bits,
+                                   n_code_inputs,
+                                   n_code_outputs,
+                                   code_generators,
+                                   &code_feedback,
+                                   do_termination,
+                                   end_memory_state);};
+
+  virtual ~code_convolutional_trellis () {};
+
+/* for remote access to internal info */
+
+  inline size_t block_size_bits () {return (d_block_size_bits);};
+  inline size_t n_code_inputs () {return (d_n_code_inputs);};
+  inline size_t n_code_outputs () {return (d_n_code_outputs);};
+  inline const bool do_termination () {return (d_do_termination);};
+  inline const bool do_feedback () {return (d_do_feedback);};
+  inline const bool do_streaming () {return (d_do_streaming);};
+  inline const size_t total_n_delays () {return (d_total_n_delays);};
+
+  virtual char sum_bits_mod2 (memory_t in_mem, size_t max_memory);
+  void get_termination_inputs (memory_t term_start_state,
+                              size_t bit_num,
+                              std::vector<char>& inputs);
+
+  void encode_lookup (memory_t& state,
+                     const std::vector<char>& inputs,
+                     std::vector<char>& out_bits);
+
+  void demux_state (memory_t in_state, std::vector<memory_t>& memories);
+  memory_t mux_state (const std::vector<memory_t>& memories);
+  void demux_inputs (memory_t inputs, std::vector<char>& in_vec);
+  memory_t mux_inputs (const std::vector<char>& in_vec);
+
+protected:
+#if 0
+/*
+ * state_get_from(v,i,k): use to retrieve a given bit-memory state,
+ *     from the inputs:
+ *
+ * memory_t v: the value from which to retrieve the given state
+ * size_t i: for which input stream (0 to #I-1)
+ * size_t k: the number of memory slots per input (e.g. 1+D^2 -> 2)
+ */
+
+  inline memory_t state_get_from (memory_t v,
+                                 size_t i,
+                                 size_t k)
+  {return (((v)>>((i)*(k)))&((1<<(k))-1));};
+
+/*
+ * state_add_to(s,v,i,k): use to create a given bit-memory state,
+ *     from the inputs:
+ *
+ * memory_t s: the state value to modify
+ * memory_t v: value to set the state to for this input
+ * size_t i: for which input stream (0 to #I-1)
+ * size_t k: the number of memory slots per input (e.g. 1+D^2 -> 2)
+ */
+
+  inline void state_add_to (memory_t s,
+                           memory_t v,
+                           size_t i,
+                           size_t k)
+  {(s)|=(((v)&((1<<(k))-1))<<((i)*(k)));};
+#endif
+
+/*
+ * maio(i,o): matrix access into a vector, knowing the # of code
+ *     outputs (from inside the class). References into a vector with
+ *     code inputs ordered by code output.
+ *
+ * 'i' is the 1st dimension - faster memory - the code input
+ * 'o' is the 2nd dimension - slower memory - the code output
+ *
+ * returns ((o*n_code_inputs) + i)
+ */
+
+  inline size_t maio(size_t i, size_t o) {return ((o*d_n_code_inputs) + i);};
+
+/*
+ * maoi(i,o): matrix access into a vector, knowing the # of code
+ *     inputs (from inside the class). References into a vector with
+ *     code outputs ordered by code input.
+ *
+ * 'o' is the 1st dimension - faster memory - the code output
+ * 'i' is the 2nd dimension - slower memory - the code input
+ *
+ * returns ((i*n_code_outputs) + o)
+ */
+
+  inline size_t maoi(size_t i, size_t o) {return ((i*d_n_code_outputs) + o);};
+
+/*
+ * max_bit_position (x): returns the bit-number of the highest "1" bit
+ * in the provided value, such that the LSB would return 0 and the MSB
+ * of a long would return 31.
+ */
+
+  inline size_t max_bit_position (memory_t x)
+  {
+    size_t t_code_mem = 0;
+    memory_t t_in_code = x >> 1;
+    while (t_in_code != 0) {
+      t_in_code >>= 1;
+      t_code_mem++;
+    }
+
+    return (t_code_mem);
+  }
+
+  // methods defined in this class
+
+  void code_convolutional_trellis_init
+  (int block_size_bits,
+   int n_code_inputs,
+   int n_code_outputs,
+   const std::vector<int>& code_generators,
+   const std::vector<int>* code_generators,
+   bool do_termination,
+   int end_memory_state);
+
+  void create_trellis ();
+  void create_termination_table (memory_t end_memory_state);
+  void encode_single (memory_t in_state,
+                     memory_t inputs,
+                     memory_t& out_state,
+                     std::vector<char>& out_bits);
+  virtual void encode_single_soai ();
+  virtual void encode_single_siao ();
+  virtual void encode_single_soai_fb ();
+  virtual void encode_single_siao_fb ();
+
+  void get_memory_requirements (size_t m,
+                               size_t n,
+                               size_t& t_max_mem,
+                               size_t& t_n_unique_fb_prev_start,
+                               const std::vector<int>* code_feedback);
+
+  // variables
+
+  size_t d_block_size_bits, d_n_code_outputs;
+  size_t d_n_code_inputs, d_n_input_combinations;
+  bool d_do_streaming, d_do_termination, d_do_feedback, d_do_encode_soai;
+
+  // "max_delay" is the max # of delays for all unique generators (ff and fb), 
+  // needed to determine (e.g.) termination
+
+  size_t d_max_delay;
+
+  // "n_memories" is the number of unique memories as determined by
+  // either the feedforward or feedback generators (not both).  For
+  // FF, this number equals either the number of code inputs (for
+  // SIAO) or outputs (for SOAI).
+
+  size_t d_n_memories;
+
+  // "total_n_delays" is the total # of delays, needed to determine the
+  // # of states in the decoder
+  // "n_states" = (2^n_delays) - 1 .. the number of memory states
+
+  size_t d_total_n_delays, d_n_states;
+
+  // "code generators" are stored internally in "maXY(i,o)" order this
+  // allows for looping over all a single output and computing all
+  // input parts sequentially.
+
+  std::vector<memory_t> d_code_generators;
+
+  // "feedback" are found as "d_n_memories" unique entries, and stored
+  // in at most 1 entry per I/O combination.  Listed in the same order
+  // as "d_io_num" entries show.
+
+  std::vector<memory_t> d_code_feedback;
+
+  // "n_delays" is a vector, the number of delays for the FB generator
+  // in the same [] location; also relates directly to the
+  // "max_mem_masks" in the same [] location.
+
+  std::vector<size_t> d_n_delays;
+
+  // "io_num" is a vector, mapping which FB in SIAO goes with which
+  // input, or which FB in SOAI goes with which output
+
+  std::vector<size_t> d_io_num;
+
+  // "max_mem_masks" are the memory masks, one per unique FB for SIAO;
+  // otherwise not used.
+
+  std::vector<size_t> d_states_ndx;
+
+  // "memory" are the actual stored delay bits, one memory for each
+  // unique FF or FB code generator;
+  // interpreted w/r.t. the actual FF and FB code generators and
+  // SOAI / SIAO realization;
+
+  std::vector<memory_t> d_max_mem_masks;
+
+  // "states_ndx" is a "matrix" whose contents are the indices into
+  // the "io_num" vector, telling which input goes with which
+  // state; uses the same "maXY(i,o)" as the code generators.
+
+  std::vector<memory_t> d_memory;
+
+  // "term_inputs" are the inputs required to terminate the trellis -
+  //     interpreted w/r.t. the actual FF and FB code generators and
+  //     SOAI / SIAO realization;
+  // first dimension is the memory state #;
+  // second dimension is the input stream #;
+  // bits are packed, with the first input being the LSB and the last
+  //     input being closest to the MSB.
+
+  typedef std::vector<std::vector<memory_t> > term_input_t;
+  term_input_t d_term_inputs;
+
+  // "inputs" are the current input bits, in the LSB (&1) of each "char"
+
+  std::vector<char> d_current_inputs;
+
+  // "outputs" are the current output bits, in the LSB (&1) of each "char"
+
+  std::vector<char> d_current_outputs;
+
+  // "trellis" is the single-stage memory state transition ("trellis")
+  // representation for this code; forward paths only
+
+  trellis_t d_trellis;
+};
+
+#endif /* INCLUDED_CODE_CONVOLUTIONAL_TRELLIS_H */
diff --git a/gr-error-correcting-codes/src/lib/libecc/code_metrics.cc b/gr-error-correcting-codes/src/lib/libecc/code_metrics.cc
new file mode 100644 (file)
index 0000000..3924508
--- /dev/null
@@ -0,0 +1,445 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <code_metrics.h>
+#include <iostream>
+#include <math.h>
+#include <assert.h>
+
+code_metric_ff::code_metric_ff
+(pdf_fcn_t pdf_fcn_0_bit,
+ pdf_fcn_t pdf_fcn_1_bit,
+ size_t n_samples,
+ pdf_fcn_io_t min_sample,
+ pdf_fcn_io_t max_sample)
+{
+  if (n_samples < 2) {
+    fprintf (stderr, "code_metric_f32:: n_samples "
+            "must be at least 2.\n");
+    assert (0);
+  }
+  if (min_sample >= max_sample) {
+    fprintf (stderr, "code_metric_f32:: min_sample must be "
+            "less than max_sample.\n");
+    assert (0);
+  }
+  if (! pdf_fcn_0_bit) {
+    fprintf (stderr, "code_metric_f32:: pdf_fcn_0_bit must be "
+            "a non-null pointer to function.\n");
+    assert (0);
+  }
+  if (! pdf_fcn_1_bit) {
+    fprintf (stderr, "code_metric_f32:: pdf_fcn_0_bit must be "
+            "a non-null pointer to function.\n");
+    assert (0);
+  }
+
+  d_n_samples = n_samples;
+  d_max_sample = max_sample;
+  d_min_sample = min_sample;
+  d_delta = (max_sample - min_sample) / (n_samples - 1);
+  d_pdf_fcn_0_bit = pdf_fcn_0_bit;
+  d_pdf_fcn_1_bit = pdf_fcn_1_bit;
+  d_metric_table_0_bit.assign (n_samples, 0);
+  d_metric_table_1_bit.assign (n_samples, 0);
+
+  pdf_fcn_io_t l_val = min_sample;
+  for (size_t m = 0; m < n_samples; m++) {
+    d_metric_table_0_bit[m] = logf ((*pdf_fcn_0_bit)(l_val));
+    d_metric_table_1_bit[m] = logf ((*pdf_fcn_1_bit)(l_val));
+    l_val += d_delta;
+  }
+}
+
+void code_metric_ff::lookup
+(pdf_fcn_io_t sym,
+ void* bit_0,
+ void* bit_1)
+{
+  metric_ptr_t l_bit_0 = (metric_ptr_t) bit_0;
+  metric_ptr_t l_bit_1 = (metric_ptr_t) bit_1;
+
+  if (sym <= d_min_sample) {
+    *l_bit_0 = d_metric_table_0_bit[0];
+    *l_bit_1 = d_metric_table_1_bit[0];
+    return;
+  }
+  if (sym >= d_max_sample) {
+    *l_bit_0 = d_metric_table_0_bit.back ();
+    *l_bit_1 = d_metric_table_1_bit.back ();
+    return;
+  }
+
+  size_t l_ndx = (size_t) roundf ((sym - d_min_sample) / d_delta);
+  *l_bit_0 = d_metric_table_0_bit[l_ndx];
+  *l_bit_1 = d_metric_table_1_bit[l_ndx];
+}
+
+void code_metric_ff::convert
+(size_t n_syms,
+ pdf_fcn_io_t* sym,
+ void* bit_0,
+ void* bit_1)
+{
+  metric_ptr_t l_bit_0 = (metric_ptr_t) bit_0;
+  metric_ptr_t l_bit_1 = (metric_ptr_t) bit_1;
+
+  for (size_t m = n_syms; m > 0; m--)
+    lookup (*sym++, (void*) l_bit_0++, (void*) l_bit_1++);
+}
+
+code_metric_fl::code_metric_fl
+(pdf_fcn_t pdf_fcn_0_bit,
+ pdf_fcn_t pdf_fcn_1_bit,
+ size_t n_samples,
+ pdf_fcn_io_t min_sample,
+ pdf_fcn_io_t max_sample,
+ int sample_precision)
+{
+  if (n_samples < 2) {
+    fprintf (stderr, "code_metric_fl:: n_samples "
+            "must be at least 2.\n");
+    assert (0);
+  }
+  if (min_sample >= max_sample) {
+    fprintf (stderr, "code_metric_fl:: min_sample must be "
+            "less than max_sample.\n");
+    assert (0);
+  }
+  if (! pdf_fcn_0_bit) {
+    fprintf (stderr, "code_metric_fl:: pdf_fcn_0_bit must be "
+            "a non-null pointer to function.\n");
+    assert (0);
+  }
+  if (! pdf_fcn_1_bit) {
+    fprintf (stderr, "code_metric_fl:: pdf_fcn_0_bit must be "
+            "a non-null pointer to function.\n");
+    assert (0);
+  }
+  if (sample_precision < 16 || sample_precision > 32) {
+    fprintf (stderr, "code_metric_fl:: sample_precision must be "
+            "between 16 and 32 for this class.\n");
+    assert (0);
+  }
+
+  d_sample_precision = sample_precision;
+  d_n_samples = n_samples;
+  d_max_sample = max_sample;
+  d_min_sample = min_sample;
+  d_delta = (max_sample - min_sample) / (n_samples - 1);
+  d_pdf_fcn_0_bit = pdf_fcn_0_bit;
+  d_pdf_fcn_1_bit = pdf_fcn_1_bit;
+  d_metric_table_0_bit.assign (n_samples, 0);
+  d_metric_table_1_bit.assign (n_samples, 0);
+
+  // get the scale factor for converting from float to sample_precision
+  // maps:
+  //    logf (pdf_fcn_0_bit->eval (d_min_sample))  ->  l_min_map
+  //    logf (pdf_fcn_0_bit->eval (d_max_sample))  ->  l_max_map
+
+  metric_t l_min_map = - (1 << (sample_precision - 1));
+
+  pdf_fcn_io_t l_min_log_val_0 = logf ((*pdf_fcn_0_bit)(d_min_sample));
+  pdf_fcn_io_t l_max_log_val_0 = logf ((*pdf_fcn_0_bit)(d_max_sample));
+  pdf_fcn_io_t l_slope_0 = (powf (2.0, (pdf_fcn_io_t)(d_sample_precision)) /
+                           (l_max_log_val_0 - l_min_log_val_0));
+  pdf_fcn_io_t l_min_log_val_1 = logf ((*pdf_fcn_1_bit)(d_min_sample));
+  pdf_fcn_io_t l_max_log_val_1 = logf ((*pdf_fcn_1_bit)(d_max_sample));
+  pdf_fcn_io_t l_slope_1 = (powf (2.0, (pdf_fcn_io_t)(d_sample_precision)) /
+                           (l_max_log_val_1 - l_min_log_val_1));
+
+  pdf_fcn_io_t l_val = d_min_sample;
+  for (size_t m = 0; m < d_n_samples; m++) {
+    d_metric_table_0_bit[m] =
+      (metric_t) roundf (((pdf_fcn_io_t) l_min_map) +
+                        (l_slope_0 * (logf ((*pdf_fcn_0_bit)(l_val)) -
+                                      l_min_log_val_0)));
+    d_metric_table_1_bit[m] =
+      (metric_t) roundf (((pdf_fcn_io_t) l_min_map) +
+                        (l_slope_1 * (logf ((*pdf_fcn_1_bit)(l_val)) -
+                                      l_min_log_val_1)));
+    l_val += d_delta;
+  }
+}
+
+void code_metric_fl::lookup
+(pdf_fcn_io_t sym,
+ void* bit_0,
+ void* bit_1)
+{
+  metric_ptr_t l_bit_0 = (metric_ptr_t) bit_0;
+  metric_ptr_t l_bit_1 = (metric_ptr_t) bit_1;
+
+  if (sym <= d_min_sample) {
+    *l_bit_0 = d_metric_table_0_bit[0];
+    *l_bit_1 = d_metric_table_1_bit[0];
+    return;
+  }
+  if (sym >= d_max_sample) {
+    *l_bit_0 = d_metric_table_0_bit.back ();
+    *l_bit_1 = d_metric_table_1_bit.back ();
+    return;
+  }
+
+  size_t l_ndx = (size_t) roundf ((sym - d_min_sample) / d_delta);
+  *l_bit_0 = d_metric_table_0_bit[l_ndx];
+  *l_bit_1 = d_metric_table_1_bit[l_ndx];
+}
+
+void code_metric_fl::convert
+(size_t n_syms,
+ pdf_fcn_io_t* sym,
+ void* bit_0,
+ void* bit_1)
+{
+  metric_ptr_t l_bit_0 = (metric_ptr_t) bit_0;
+  metric_ptr_t l_bit_1 = (metric_ptr_t) bit_1;
+
+  for (size_t m = n_syms; m > 0; m--)
+    lookup (*sym++, (void*) l_bit_0++, (void*) l_bit_1++);
+}
+
+code_metric_fs::code_metric_fs
+(pdf_fcn_t pdf_fcn_0_bit,
+ pdf_fcn_t pdf_fcn_1_bit,
+ size_t n_samples,
+ pdf_fcn_io_t min_sample,
+ pdf_fcn_io_t max_sample,
+ int sample_precision)
+{
+  if (n_samples < 2) {
+    fprintf (stderr, "code_metric_fs:: n_samples "
+            "must be at least 2.\n");
+    assert (0);
+  }
+  if (min_sample >= max_sample) {
+    fprintf (stderr, "code_metric_fs:: min_sample must be "
+            "less than max_sample.\n");
+    assert (0);
+  }
+  if (! pdf_fcn_0_bit) {
+    fprintf (stderr, "code_metric_fs:: pdf_fcn_0_bit must be "
+            "a non-null pointer to function.\n");
+    assert (0);
+  }
+  if (! pdf_fcn_1_bit) {
+    fprintf (stderr, "code_metric_fs:: pdf_fcn_0_bit must be "
+            "a non-null pointer to function.\n");
+    assert (0);
+  }
+  if (sample_precision < 9 || sample_precision > 16) {
+    fprintf (stderr, "code_metric_fs:: sample_precision must be "
+            "between 9 and 16 for this class.\n");
+    assert (0);
+  }
+
+  d_sample_precision = sample_precision;
+  d_n_samples = n_samples;
+  d_max_sample = max_sample;
+  d_min_sample = min_sample;
+  d_delta = (max_sample - min_sample) / (n_samples - 1);
+  d_pdf_fcn_0_bit = pdf_fcn_0_bit;
+  d_pdf_fcn_1_bit = pdf_fcn_1_bit;
+  d_metric_table_0_bit.assign (n_samples, 0);
+  d_metric_table_1_bit.assign (n_samples, 0);
+
+  // get the scale factor for converting from float to sample_precision
+  // maps:
+  //    logf (pdf_fcn_0_bit->eval (d_min_sample))  ->  l_min_map
+  //    logf (pdf_fcn_0_bit->eval (d_max_sample))  ->  l_max_map
+
+  metric_t l_min_map = - (1 << (sample_precision - 1));
+
+  pdf_fcn_io_t l_min_log_val_0 = logf ((*pdf_fcn_0_bit)(d_min_sample));
+  pdf_fcn_io_t l_max_log_val_0 = logf ((*pdf_fcn_0_bit)(d_max_sample));
+  pdf_fcn_io_t l_slope_0 = (powf (2.0, (pdf_fcn_io_t)(d_sample_precision)) /
+                           (l_max_log_val_0 - l_min_log_val_0));
+  pdf_fcn_io_t l_min_log_val_1 = logf ((*pdf_fcn_1_bit)(d_min_sample));
+  pdf_fcn_io_t l_max_log_val_1 = logf ((*pdf_fcn_1_bit)(d_max_sample));
+  pdf_fcn_io_t l_slope_1 = (powf (2.0, (pdf_fcn_io_t)(d_sample_precision)) /
+                           (l_max_log_val_1 - l_min_log_val_1));
+
+  pdf_fcn_io_t l_val = d_min_sample;
+  for (size_t m = 0; m < d_n_samples; m++) {
+    d_metric_table_0_bit[m] =
+      (metric_t) roundf (((pdf_fcn_io_t) l_min_map) +
+                        (l_slope_0 * (logf ((*pdf_fcn_0_bit)(l_val)) -
+                                      l_min_log_val_0)));
+    d_metric_table_1_bit[m] =
+      (metric_t) roundf (((pdf_fcn_io_t) l_min_map) +
+                        (l_slope_1 * (logf ((*pdf_fcn_1_bit)(l_val)) -
+                                      l_min_log_val_1)));
+    l_val += d_delta;
+  }
+}
+
+void code_metric_fs::lookup
+(pdf_fcn_io_t sym,
+ void* bit_0,
+ void* bit_1)
+{
+  metric_ptr_t l_bit_0 = (metric_ptr_t) bit_0;
+  metric_ptr_t l_bit_1 = (metric_ptr_t) bit_1;
+
+  if (sym <= d_min_sample) {
+    *l_bit_0 = d_metric_table_0_bit[0];
+    *l_bit_1 = d_metric_table_1_bit[0];
+    return;
+  }
+  if (sym >= d_max_sample) {
+    *l_bit_0 = d_metric_table_0_bit.back ();
+    *l_bit_1 = d_metric_table_1_bit.back ();
+    return;
+  }
+
+  size_t l_ndx = (size_t) roundf ((sym - d_min_sample) / d_delta);
+  *l_bit_0 = d_metric_table_0_bit[l_ndx];
+  *l_bit_1 = d_metric_table_1_bit[l_ndx];
+}
+
+void code_metric_fs::convert
+(size_t n_syms,
+ pdf_fcn_io_t* sym,
+ void* bit_0,
+ void* bit_1)
+{
+  metric_ptr_t l_bit_0 = (metric_ptr_t) bit_0;
+  metric_ptr_t l_bit_1 = (metric_ptr_t) bit_1;
+
+  for (size_t m = n_syms; m > 0; m--)
+    lookup (*sym++, (void*) l_bit_0++, (void*) l_bit_1++);
+}
+
+code_metric_fb::code_metric_fb
+(pdf_fcn_t pdf_fcn_0_bit,
+ pdf_fcn_t pdf_fcn_1_bit,
+ size_t n_samples,
+ pdf_fcn_io_t min_sample,
+ pdf_fcn_io_t max_sample,
+ int sample_precision)
+{
+  if (n_samples < 2) {
+    fprintf (stderr, "code_metric_fb:: n_samples "
+            "must be at least 2.\n");
+    assert (0);
+  }
+  if (min_sample >= max_sample) {
+    fprintf (stderr, "code_metric_fb:: min_sample must be "
+            "less than max_sample.\n");
+    assert (0);
+  }
+  if (! pdf_fcn_0_bit) {
+    fprintf (stderr, "code_metric_fb:: pdf_fcn_0_bit must be "
+            "a non-null pointer to function.\n");
+    assert (0);
+  }
+  if (! pdf_fcn_1_bit) {
+    fprintf (stderr, "code_metric_fb:: pdf_fcn_0_bit must be "
+            "a non-null pointer to function.\n");
+    assert (0);
+  }
+  if (sample_precision < 1 || sample_precision > 8) {
+    fprintf (stderr, "code_metric_fb:: sample_precision must be "
+            "between 1 and 8 for this class.\n");
+    assert (0);
+  }
+
+  d_sample_precision = sample_precision;
+  d_n_samples = n_samples;
+  d_max_sample = max_sample;
+  d_min_sample = min_sample;
+  d_delta = (max_sample - min_sample) / (n_samples - 1);
+  d_pdf_fcn_0_bit = pdf_fcn_0_bit;
+  d_pdf_fcn_1_bit = pdf_fcn_1_bit;
+  d_metric_table_0_bit.assign (n_samples, 0);
+  d_metric_table_1_bit.assign (n_samples, 0);
+
+  // get the scale factor for converting from float to sample_precision
+  // maps:
+  //    logf (pdf_fcn_0_bit->eval (d_min_sample))  ->  l_min_map
+  //    logf (pdf_fcn_0_bit->eval (d_max_sample))  ->  l_max_map
+
+  metric_t l_min_map = - (1 << (sample_precision - 1));
+
+  pdf_fcn_io_t l_min_log_val_0 = logf ((*pdf_fcn_0_bit)(d_min_sample));
+  pdf_fcn_io_t l_max_log_val_0 = logf ((*pdf_fcn_0_bit)(d_max_sample));
+  pdf_fcn_io_t l_slope_0 = (powf (2.0, (pdf_fcn_io_t)(d_sample_precision)) /
+                           (l_max_log_val_0 - l_min_log_val_0));
+  pdf_fcn_io_t l_min_log_val_1 = logf ((*pdf_fcn_1_bit)(d_min_sample));
+  pdf_fcn_io_t l_max_log_val_1 = logf ((*pdf_fcn_1_bit)(d_max_sample));
+  pdf_fcn_io_t l_slope_1 = (powf (2.0, (pdf_fcn_io_t)(d_sample_precision)) /
+                           (l_max_log_val_1 - l_min_log_val_1));
+
+  pdf_fcn_io_t l_val = d_min_sample;
+  for (size_t m = 0; m < d_n_samples; m++) {
+    d_metric_table_0_bit[m] =
+      (metric_t) roundf (((pdf_fcn_io_t) l_min_map) +
+                        (l_slope_0 * (logf ((*pdf_fcn_0_bit)(l_val)) -
+                                      l_min_log_val_0)));
+    d_metric_table_1_bit[m] =
+      (metric_t) roundf (((pdf_fcn_io_t) l_min_map) +
+                        (l_slope_1 * (logf ((*pdf_fcn_1_bit)(l_val)) -
+                                      l_min_log_val_1)));
+    l_val += d_delta;
+  }
+}
+
+void code_metric_fb::lookup
+(pdf_fcn_io_t sym,
+ void* bit_0,
+ void* bit_1)
+{
+  metric_ptr_t l_bit_0 = (metric_ptr_t) bit_0;
+  metric_ptr_t l_bit_1 = (metric_ptr_t) bit_1;
+
+  if (sym <= d_min_sample) {
+    *l_bit_0 = d_metric_table_0_bit[0];
+    *l_bit_1 = d_metric_table_1_bit[0];
+    return;
+  }
+  if (sym >= d_max_sample) {
+    *l_bit_0 = d_metric_table_0_bit.back ();
+    *l_bit_1 = d_metric_table_1_bit.back ();
+    return;
+  }
+
+  size_t l_ndx = (size_t) roundf ((sym - d_min_sample) / d_delta);
+  *l_bit_0 = d_metric_table_0_bit[l_ndx];
+  *l_bit_1 = d_metric_table_1_bit[l_ndx];
+}
+
+void code_metric_fb::convert
+(size_t n_syms,
+ pdf_fcn_io_t* sym,
+ void* bit_0,
+ void* bit_1)
+{
+  metric_ptr_t l_bit_0 = (metric_ptr_t) bit_0;
+  metric_ptr_t l_bit_1 = (metric_ptr_t) bit_1;
+
+  for (size_t m = n_syms; m > 0; m--)
+    lookup (*sym++, (void*) l_bit_0++, (void*) l_bit_1++);
+}
diff --git a/gr-error-correcting-codes/src/lib/libecc/code_metrics.h b/gr-error-correcting-codes/src/lib/libecc/code_metrics.h
new file mode 100644 (file)
index 0000000..9530dd6
--- /dev/null
@@ -0,0 +1,155 @@
+/* -*- 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 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.
+ */
+
+#ifndef INCLUDED_CODE_METRIC_H
+#define INCLUDED_CODE_METRIC_H
+
+#include <sys/types.h>
+#include <vector>
+
+class code_metrics
+{
+public:
+  typedef float pdf_fcn_io_t;
+
+  code_metrics () {};
+  virtual ~code_metrics () {};
+
+// lookup() returns either a float, or a sign-extended
+// 'sample_precision'-bit integer value.
+
+  virtual void lookup (pdf_fcn_io_t sym,
+                      void* bit_0,
+                      void* bit_1) = 0;
+
+  virtual void convert (size_t n_syms,
+                       pdf_fcn_io_t* syms,
+                       void* bit_0,
+                       void* bit_1) = 0;
+};
+
+class code_metric_ff : public code_metrics
+{
+  typedef pdf_fcn_io_t (*pdf_fcn_t) (pdf_fcn_io_t);
+  typedef float metric_t, *metric_ptr_t;
+
+private:
+  size_t d_n_samples;
+  pdf_fcn_io_t d_max_sample, d_min_sample, d_delta;
+  pdf_fcn_t d_pdf_fcn_0_bit, d_pdf_fcn_1_bit;
+  std::vector<metric_t> d_metric_table_0_bit;
+  std::vector<metric_t> d_metric_table_1_bit;
+
+public:
+  code_metric_ff (pdf_fcn_t pdf_fcn_0_bit,
+                 pdf_fcn_t pdf_fcn_1_bit,
+                 size_t n_samples,
+                 pdf_fcn_io_t min_sample,
+                 pdf_fcn_io_t max_sample);
+  ~code_metric_ff () {};
+
+  void lookup (pdf_fcn_io_t sym, void* bit_0, void* bit_1);
+  void convert (size_t n_syms, pdf_fcn_io_t* sym, void* bit_0, void* bit_1);
+};
+
+class code_metric_fl : public code_metrics
+{
+  typedef float pdf_fcn_io_t;
+  typedef pdf_fcn_io_t (*pdf_fcn_t) (pdf_fcn_io_t);
+  typedef long metric_t, *metric_ptr_t;
+
+private:
+  char d_sample_precision;
+  size_t d_n_samples, d_sample_mask;
+  pdf_fcn_io_t d_max_sample, d_min_sample, d_delta;
+  pdf_fcn_t d_pdf_fcn_0_bit, d_pdf_fcn_1_bit;
+  std::vector<metric_t> d_metric_table_0_bit;
+  std::vector<metric_t> d_metric_table_1_bit;
+
+public:
+  code_metric_fl (pdf_fcn_t pdf_fcn_0_bit,
+                 pdf_fcn_t pdf_fcn_1_bit,
+                 size_t n_samples,
+                 pdf_fcn_io_t min_sample,
+                 pdf_fcn_io_t max_sample,
+                 int sample_precision = 32);
+  ~code_metric_fl () {};
+
+  void lookup (pdf_fcn_io_t sym, void* bit_0, void* bit_1);
+  void convert (size_t n_syms, pdf_fcn_io_t* sym, void* bit_0, void* bit_1);
+};
+
+class code_metric_fs : public code_metrics
+{
+  typedef float pdf_fcn_io_t;
+  typedef pdf_fcn_io_t (*pdf_fcn_t) (pdf_fcn_io_t);
+  typedef short metric_t, *metric_ptr_t;
+
+private:
+  char d_sample_precision;
+  size_t d_n_samples, d_sample_mask;
+  pdf_fcn_io_t d_max_sample, d_min_sample, d_delta;
+  pdf_fcn_t d_pdf_fcn_0_bit, d_pdf_fcn_1_bit;
+  std::vector<metric_t> d_metric_table_0_bit;
+  std::vector<metric_t> d_metric_table_1_bit;
+
+public:
+  code_metric_fs (pdf_fcn_t pdf_fcn_0_bit,
+                 pdf_fcn_t pdf_fcn_1_bit,
+                 size_t n_samples,
+                 pdf_fcn_io_t min_sample,
+                 pdf_fcn_io_t max_sample,
+                 int sample_precision = 16);
+  ~code_metric_fs () {};
+
+  void lookup (pdf_fcn_io_t sym, void* bit_0, void* bit_1);
+  void convert (size_t n_syms, pdf_fcn_io_t* sym, void* bit_0, void* bit_1);
+};
+
+class code_metric_fb : public code_metrics
+{
+  typedef float pdf_fcn_io_t;
+  typedef pdf_fcn_io_t (*pdf_fcn_t) (pdf_fcn_io_t);
+  typedef char metric_t, *metric_ptr_t;
+
+private:
+  char d_sample_precision;
+  size_t d_n_samples, d_sample_mask;
+  pdf_fcn_io_t d_max_sample, d_min_sample, d_delta;
+  pdf_fcn_t d_pdf_fcn_0_bit, d_pdf_fcn_1_bit;
+  std::vector<metric_t> d_metric_table_0_bit;
+  std::vector<metric_t> d_metric_table_1_bit;
+
+public:
+  code_metric_fb (pdf_fcn_t pdf_fcn_0_bit,
+                 pdf_fcn_t pdf_fcn_1_bit,
+                 size_t n_samples,
+                 pdf_fcn_io_t min_sample,
+                 pdf_fcn_io_t max_sample,
+                 int sample_precision = 8);
+  ~code_metric_fb () {};
+
+  void lookup (pdf_fcn_io_t sym, void* bit_0, void* bit_1);
+  void convert (size_t n_syms, pdf_fcn_io_t* sym, void* bit_0, void* bit_1);
+};
+
+#endif /* INCLUDED_CODE_METRIC_H */
diff --git a/gr-error-correcting-codes/src/lib/libecc/code_types.h b/gr-error-correcting-codes/src/lib/libecc/code_types.h
new file mode 100644 (file)
index 0000000..cc77143
--- /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 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.
+ */
+
+#ifndef INCLUDED_CODE_TYPES_H
+#define INCLUDED_CODE_TYPES_H
+
+#include <sys/types.h>
+
+// the following is the type used for encoder memory
+
+typedef unsigned long memory_t, *memory_ptr_t;
+
+#endif /* INCLUDED_CODE_TYPES_H */
diff --git a/gr-error-correcting-codes/src/lib/libecc/decoder.cc b/gr-error-correcting-codes/src/lib/libecc/decoder.cc
new file mode 100644 (file)
index 0000000..0b77f77
--- /dev/null
@@ -0,0 +1,117 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <decoder.h>
+#include <assert.h>
+#include <iostream>
+
+#define DO_PRINT_DEBUG 1
+
+#if DO_PRINT_DEBUG
+#include <mld/n2bs.h>
+#endif
+
+/*
+ * decode a certain number of output bits
+ *
+ * the 'in_buf' and 'out_buf' must have enough memory to handle the
+ *     number of input metrics and output bits; no error checking is done!
+ *
+ * n_bits_to_output: the number of bits per output stream to output.
+ *
+ * returns the actual number of metrics used per input stream.
+ */
+
+size_t
+decoder::decode
+(const char** in_buf,
+ char** out_buf,
+ size_t n_bits_to_output)
+{
+  // set the class-internal number of input metrics
+  // and output bits left to decode
+
+  size_t saved_n_input_metrics;
+  saved_n_input_metrics = d_n_input_metrics_left =
+    compute_n_input_metrics (n_bits_to_output);
+  d_n_output_bits_left = n_bits_to_output;
+
+  // call the private decode function
+
+  decode_private (in_buf, out_buf);
+
+  if (DO_PRINT_DEBUG) {
+    std::cout << "n_input_metrics_used = " <<
+      (saved_n_input_metrics - d_n_input_metrics_left) << "\n"
+      "n_output_bits_used = " <<
+      (n_bits_to_output - d_n_output_bits_left) << '\n';
+  }
+
+  // return the actual number of input metrics used
+
+  return (saved_n_input_metrics - d_n_input_metrics_left);
+}
+
+/*
+ * decode a certain number of input metrics
+ *
+ * the 'in_buf' and 'out_buf' must have enough memory to handle the
+ *     number of input metrics and output bits; no error checking is done!
+ *
+ * n_metrics_to_input: the number of metrics per input stream to decode
+ *
+ * returns the actual number of bits written per output stream
+ */
+
+size_t
+decoder::decode
+(const char** in_buf,  
+ size_t n_metrics_to_input,
+ char** out_buf)
+{
+  // set the class-internal number of input metrics and
+  // output bits left to decode
+
+  size_t saved_n_output_bits;
+  saved_n_output_bits = d_n_output_bits_left =
+    compute_n_output_bits (n_metrics_to_input);
+  d_n_input_metrics_left = n_metrics_to_input;
+
+  // call the private decode function
+
+  decode_private (in_buf, out_buf);
+
+  if (DO_PRINT_DEBUG) {
+    std::cout << "n_input_metrics_used = " <<
+      (n_metrics_to_input - d_n_input_metrics_left) << '\n';
+    std::cout << "n_output_bits_used = " <<
+      (saved_n_output_bits - d_n_output_bits_left) << '\n';
+  }
+
+  // return the actual number of output bits written
+
+  return (saved_n_output_bits - d_n_output_bits_left);
+}
diff --git a/gr-error-correcting-codes/src/lib/libecc/decoder.h b/gr-error-correcting-codes/src/lib/libecc/decoder.h
new file mode 100644 (file)
index 0000000..76a24b2
--- /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 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.
+ */
+
+#ifndef INCLUDED_DECODER_H
+#define INCLUDED_DECODER_H
+
+#include "code_types.h"
+
+// the 'decoder' class is a virtual class upon which all decoder types
+// can be built.
+
+class decoder
+{
+public:
+  decoder () {};
+  virtual ~decoder () {};
+
+  virtual size_t compute_n_input_metrics (size_t n_output_bits) = 0;
+  virtual size_t compute_n_output_bits (size_t n_input_metrics) = 0;
+  virtual size_t decode (const char** in_buf,
+                        char** out_buf,
+                        size_t n_bits_to_output);
+  virtual size_t decode (const char** in_buf,
+                        size_t n_metrics_to_input,
+                        char** out_buf);
+
+protected:
+  virtual void decode_private (const char** in_buf, char** out_buf) = 0;
+  virtual char get_next_input (const char** in_buf, size_t code_input_n) = 0;
+  virtual void output_bit (char t_out_bit, char** out_buf,
+                          size_t t_output_stream) = 0;
+
+  size_t d_block_size_bits, d_n_code_inputs, d_n_code_outputs;
+  size_t d_n_dec_bits;
+  size_t d_in_buf_ndx, d_out_buf_ndx;
+  size_t d_in_bit_shift, d_out_bit_shift;
+  size_t d_n_input_metrics_left, d_n_output_bits_left;
+};
+
+#endif /* INCLUDED_DECODER_H */
diff --git a/gr-error-correcting-codes/src/lib/libecc/decoder_viterbi.cc b/gr-error-correcting-codes/src/lib/libecc/decoder_viterbi.cc
new file mode 100644 (file)
index 0000000..bce2cac
--- /dev/null
@@ -0,0 +1,1060 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <decoder_viterbi.h>
+#include <assert.h>
+#include <iostream>
+
+const int g_max_block_size_bits = 10000000;
+const int g_max_num_streams = 10;
+const int g_num_bits_per_byte = 8;
+
+#define DO_TIME_THOUGHPUT 0
+#define DO_PRINT_DEBUG_INST 0
+#define DO_PRINT_DEBUG_INST_0 0
+#define DO_PRINT_DEBUG_INST_1 0
+#define DO_PRINT_DEBUG_INST_2 0
+#define DO_PRINT_DEBUG_FSM 0
+#define DO_PRINT_DEBUG_INIT 0
+#define DO_PRINT_DEBUG_UP 0
+#define DO_PRINT_DEBUG_UP_0 0
+#define DO_PRINT_DEBUG_UP_1 0
+#define DO_PRINT_DEBUG_MIDDLE 0
+#define DO_PRINT_DEBUG_MIDDLE_0 0
+#define DO_PRINT_DEBUG_MIDDLE_1 0
+#define DO_PRINT_DEBUG_TERM 0
+#define DO_PRINT_DEBUG_TERM_1 0
+#define DO_PRINT_DEBUG_OUTPUT 0
+#define DO_PRINT_DEBUG_OUTPUT_0 0
+#define DO_PRINT_DEBUG_EXIT 0
+#define DO_PRINT_DEBUG 0
+
+#if DO_TIME_THOUGHPUT
+#include <mld/mld_timer.h>
+#endif
+#if DO_PRINT_DEBUG
+#include <mld/n2bs.h>
+#endif
+
+decoder_viterbi::decoder_viterbi
+(int sample_precision,
+ encoder_convolutional* l_encoder)
+{
+  // make sure the sample precitions makes sense
+
+  if ((sample_precision < 0) | (sample_precision > 32)) {
+    std::cerr << "decoder_viterbi: "
+      "Requested sample_precision (" << sample_precision <<
+      "must be between 0 and 32.\n";
+    assert (0);
+  }
+
+  // make sure that the encoder is "valid"
+
+  if (! l_encoder) {
+    std::cerr << "decoder_viterbi: Error: Encoder is a NULL pointer.\n";
+    assert (0);
+  }
+
+  // keep around a pointer to the encoder
+
+  d_encoder = l_encoder;
+
+  // fill the class variables
+
+  d_block_size_bits = d_encoder->block_size_bits ();
+  d_do_streaming = (d_block_size_bits == 0);
+  d_n_code_inputs = d_encoder->n_code_inputs ();
+  d_n_code_outputs = d_encoder->n_code_outputs ();
+  d_do_termination = d_encoder->do_termination ();
+#if 0
+  d_total_memory = d_encoder->total_memory ();
+#endif
+
+  // NOTE: d_n_states is a 'long', and thus is quite limited in terms
+  // of max memory and # of input streams to 2^32 states This is OK,
+  // since that many states would be impossibly slow to decode!  might
+  // make this a "long long" (64 bits) in the future
+
+  d_n_states = 1 << d_total_memory;
+  d_n_input_combinations = 1 << d_n_code_inputs;
+
+  // really nothing else to do here, since this class doesn't "know"
+  // how to process streaming versus block decoding, or partial
+  // trellis versus full-trellis.  Those will be handled by
+  // sub-classes which inherit from this one.
+
+  if (DO_PRINT_DEBUG_INST_0) {
+    std::cout << "Init:\n" <<
+      "d_block_size_bits          = " << d_block_size_bits << "\n" <<
+      "d_n_code_inputs            = " << d_n_code_inputs << "\n" <<
+      "d_n_code_outputs           = " << d_n_code_outputs << "\n" <<
+      "d_do_streaming             = " <<
+      ((d_do_streaming == true) ? "true" : "false") << "\n" <<
+      "d_do_termination           = " <<
+      ((d_do_termination == true) ? "true" : "false") << "\n" <<
+      "d_total_memory             = " << d_total_memory << "\n" <<
+      "d_n_states                 = " << d_n_states << "\n" <<
+      "d_n_input_combinations     = " << d_n_input_combinations << "\n";
+  }
+
+  // always start the fsm in the "init" state
+
+  d_fsm_state = fsm_dec_viterbi_init;
+
+  // create a vector of indexes to states when doing "up" or "termination";
+
+  d_up_term_states_ndx[0] = new size_t [d_n_states];
+  d_up_term_states_ndx[1] = new size_t [d_n_states];
+
+  // get the total number of out bits per stream
+
+  d_n_total_inputs_per_stream = d_block_size_bits;
+  if (d_do_termination == true)
+    d_n_total_inputs_per_stream += d_max_memory;
+
+
+
+}
+
+decoder_viterbi::~decoder_viterbi
+()
+{
+  // reverse over from allocation
+
+  delete [] d_up_term_states_ndx[0];
+  delete [] d_up_term_states_ndx[1];
+
+  // delete the state's structures
+
+  state_t_ptr t_state = d_states[0];
+  for (size_t n = d_n_states; n > 0; n--, t_state++) {
+    connection_t_ptr t_connection = t_state->d_connections;
+    for (size_t m = d_n_input_combinations; m > 0; m--, t_connection++) {
+      delete [] t_connection->d_output_bits;
+    }
+    delete [] t_state->d_connections;
+  }
+  delete [] d_states[0];
+
+  t_state = d_states[1];
+  for (size_t n = d_n_states; n > 0; n--, t_state++) {
+    connection_t_ptr t_connection = t_state->d_connections;
+    for (size_t m = d_n_input_combinations; m > 0; m--, t_connection++) {
+      delete [] t_connection->d_output_bits;
+    }
+    delete [] t_state->d_connections;
+  }
+  delete [] d_states[1];
+
+  // delete the save buffer
+
+  char** t_save_buffer = d_save_buffer;
+  for (size_t n = 0; n < d_n_code_inputs; n++) {
+    delete [] (*t_save_buffer++);
+  }
+  delete [] d_save_buffer;
+}
+
+void
+decoder_viterbi::reset_metrics
+(u_char which)
+{
+  state_t_ptr t_state = d_states[which&1];
+  for (size_t n = d_n_states; n > 0; n--, t_state++) {
+    t_state->d_max_metric = -1e10;
+#if 0
+// probably don't need to do these, try removing them later
+    t_state->d_max_state_ndx = 0;
+    t_state->d_max_input = -1;
+#endif
+  }
+}
+
+void
+decoder_viterbi::zero_metrics
+(u_char which)
+{
+  state_t_ptr t_state = d_states[which&1];
+  for (size_t n = d_n_states; n > 0; n--, t_state++) {
+    t_state->d_max_metric = 0;
+#if 0
+// probably don't need to do these, try removing them later
+    t_state->d_max_state_ndx = -1;
+    t_state->d_max_input = -1;
+#endif
+  }
+}
+
+//FIXME 
+
+char
+decoder_viterbi::get_next_input
+(const char** in_buf,
+size_t code_input_n)
+{
+  return (0);
+}
+
+void
+decoder_viterbi::decode_private
+(const char** in_buf,
+ char** out_buf)
+{
+#if 0
+
+#if DO_TIME_THOUGHPUT
+  struct timeval t_tp;
+  start_timer (&t_tp);
+#endif
+#if DO_PRINT_DEBUG
+  size_t t_state_print_bits = d_total_memory + 1;
+  size_t t_mem_print_bits = d_max_memory + 2;
+#endif
+// setup variables for quicker access
+  const char **in_buf = (const char **) &input_items[0];
+  char **out_buf = (char **) &output_items[0];
+  int t_in_buf_ndx = 0, t_out_buf_ndx = 0;
+  int t_out_bit_shift = 0;
+  int t_ninput_items = compute_n_input_metrics (noutput_items);
+  int t_noutput_bits = noutput_items;
+
+#if DO_PRINT_DEBUG_INST
+  std::cout << "# output items = " << noutput_items << " (" <<
+    t_noutput_bytes << " Bytes, " << (t_noutput_bytes * g_num_bits_per_byte) <<
+    " bits), # input items = " << t_ninput_items << " Symbols\n";
+  for (size_t n = 0; n < ninput_items.size(); n++) {
+    std::cout << "# input items [" << n << "] = " << ninput_items[n] << "\n";
+  }
+#endif
+
+// put any leftover bits into the output
+  if (d_n_saved_bits != 0) {
+// copy the leftover from the save buffer
+// check to make sure it will all fit
+    size_t t_noutput_bits = t_noutput_bytes * g_num_bits_per_byte;
+    size_t t_n_copy;
+    if (t_noutput_bits < d_n_saved_bits) {
+// asking for fewer bits than available; set to copy
+// just what's being asked for
+      t_n_copy = t_noutput_bytes;
+    } else {
+// asking for at least as many bits as available; set to copy all
+      t_out_buf_ndx = d_n_saved_bits / g_num_bits_per_byte;
+      t_out_bit_shift = d_n_saved_bits % g_num_bits_per_byte;
+      t_n_copy = t_out_buf_ndx + (t_out_bit_shift != 0 ? 1 : 0);
+    }
+// do the copy for all output streams (code inputs)
+// copy starting at save buffer index "start"
+    for (size_t n = 0; n < d_n_code_inputs; n++)
+      bcopy (&(d_save_buffer[n][d_n_saved_bits_start_ndx]),
+            out_buf[n], t_n_copy);
+#if DO_PRINT_DEBUG_INST
+    std::cout << "Copied " << t_n_copy << " Byte" <<
+      (t_n_copy != 1 ? "s" : "") << ": s_b[][" <<
+      d_n_saved_bits_start_ndx << "] => o_b[][0]\n" <<
+      "# saved bits = " << d_n_saved_bits <<
+      ", o_b_ndx = " << t_out_buf_ndx <<
+      ", bit shift = " << t_out_bit_shift << "\n";
+#endif
+//  update the number of saved bits and start
+    if (t_noutput_bits < d_n_saved_bits) {
+// asking for fewer bit than available: update
+// the number of saved bits and their starting index
+      d_n_saved_bits_start_ndx += t_noutput_bytes;
+      d_n_saved_bits -= (t_noutput_bytes * g_num_bits_per_byte);
+#if DO_PRINT_DEBUG_INST
+      std::cout << "Updated # saved bits = " << d_n_saved_bits <<
+       ", index = " << d_n_saved_bits_start_ndx << "\n";
+#endif
+// nothing to consume; return the desired number of output items
+      return (noutput_items);
+    } else {
+      d_n_saved_bits_start_ndx = d_n_saved_bits = 0;
+    }
+  }
+#if DO_PRINT_DEBUG_INST
+  std::cout << "Starting FSM in state: " <<
+    (d_fsm_state == fsm_dec_viterbi_init ? "init" :
+     (d_fsm_state == fsm_dec_viterbi_doing_up ? "up" :
+      (d_fsm_state == fsm_dec_viterbi_doing_middle ? "middle" :
+       (d_fsm_state == fsm_dec_viterbi_doing_term ? "term" :
+       (d_fsm_state == fsm_dec_viterbi_output ? "output" : "unknown"))))) << "\n";
+#endif
+
+// while there are input items to create
+  while (t_out_buf_ndx < t_noutput_bytes) {
+#if DO_PRINT_DEBUG_FMS
+    std::cout << "Starting 'while': processing " << t_in_buf_ndx << " of " <<
+      t_ninput_items << " items.\nJumping to state '" <<
+      (d_fsm_state == fsm_dec_viterbi_init ? "init" :
+       (d_fsm_state == fsm_dec_viterbi_doing_up ? "up" :
+       (d_fsm_state == fsm_dec_viterbi_doing_middle ? "middle" :
+        (d_fsm_state == fsm_dec_viterbi_doing_term ? "term" :
+         (d_fsm_state == fsm_dec_viterbi_output ? "output" : "unknown"))))) << "'\n";
+#endif
+// jump to the correct state in the fsm
+    switch (d_fsm_state) {
+    case fsm_dec_viterbi_doing_up:
+#if DO_PRINT_DEBUG_FSM
+      std::cout << "Starting fsm_dec_viterbi_doing_up\n";
+#endif
+// set the number of up_down indices
+      size_t t_n_up_down_ndx = 1 << (d_n_code_inputs *
+                                    d_time_count);
+// stay in this state until the correct number of input symbols are
+// reached; exit also if we run out of input symbols to process
+      while ((d_time_count < d_max_memory) &
+            (t_in_buf_ndx < t_ninput_items)) {
+#if DO_PRINT_DEBUG_UP_0
+       std::cout << "Doing 'while' loop:\n" <<
+         "t_n_up_down_ndx    = " << t_n_up_down_ndx << "\n" <<
+         "d_time_count       = " << d_time_count << "\n" <<
+         "d_max_memory       = " << d_max_memory << "\n" <<
+         "t_in_buf_ndx       = " << t_in_buf_ndx << "\n" <<
+         "t_ninput_items     = " << t_ninput_items << "\n";
+#endif
+// use the "from" states, loop over all inputs and compute the metric for
+// each & store it in the "to" state at the end of the connection.
+// no need to compare metrics yet, since none join into any given state
+
+#if 0
+// reset the "to" state's metrics
+// probably don't need to do this; try removing later
+        reset_metrics (d_states_ndx ^ 1);
+#if DO_PRINT_DEBUG_UP
+       std::cout << "Reset Metrics\n";
+#endif
+#endif
+
+// reset the state's index for each set of new inputs
+       size_t* t_state_ndx_ptr = d_up_term_states_ndx[d_up_term_ndx];
+       size_t* t_next_state_ndx_ptr = d_up_term_states_ndx[d_up_term_ndx ^ 1];
+// loop over all current stored "up" states
+       for (size_t n = 0; n < t_n_up_down_ndx; n++) {
+         size_t t_state_ndx = *t_state_ndx_ptr++;
+// get a pointer to this state's structure
+         state_t_ptr t_state = &(d_states[d_states_ndx][t_state_ndx]);
+// get the connections for all inputs
+         connection_t_ptr t_connection = t_state->d_connections;
+#if DO_PRINT_DEBUG_UP_0
+         std::cout << "Looping over all 'up' states:\n" <<
+           "n                  = " << n << "\n" <<
+           "t_n_up_down_ndx    = " << t_n_up_down_ndx << "\n" <<
+           "d_states_ndx       = " << d_states_ndx << "\n" <<
+           "t_state_ndx        = " << t_state_ndx << "\n" <<
+           "d_n_input_combs    = " << d_n_input_combinations << "\n" <<
+           "t_state            = " << t_state << "\n" <<
+           "t_connection       = " << t_connection << "\n";
+#endif
+// loop over all possible input values, 1 bit per input stream
+         for (size_t q = 0; q < d_n_input_combinations; q++, t_connection++) {
+// find the "to" state for this connection
+           state_t_ptr t_to_state = t_connection->d_to;
+// get the output bits for this connection
+           float* t_output_bit = t_connection->d_output_bits;
+// start with this state's metric
+           float t_metric = t_state->d_max_metric;
+#if DO_PRINT_DEBUG_UP_0
+           std::cout <<
+             "to state index     = " << t_connection->d_to_ndx << "\n" <<
+             "current metric     = " << t_metric << "\n";
+#endif
+           if (d_do_mux_inputs == true) {
+// if using mux'ed input streams, handle differently
+              const float* t_in_buf = &(in_buf[0][t_in_buf_ndx]);
+// loop over all encoder-output values
+             for (size_t r = d_n_code_outputs; r > 0; r--) {
+#if DO_PRINT_DEBUG_UP
+               std::cout << "in_sym = " << *t_in_buf << ", code_out_bit = " <<
+                 *t_output_bit << " ==> metric -> ";
+#endif
+               t_metric += ((*t_in_buf++) * (*t_output_bit++));
+#if DO_PRINT_DEBUG_UP
+               std::cout << t_metric << "\n";
+#endif
+             }
+           } else {
+// loop over all encoder-output values
+             for (size_t r = 0; r < d_n_code_outputs; r++) {
+#if DO_PRINT_DEBUG_UP
+               std::cout << "in_sym = " << in_buf[r][t_in_buf_ndx] <<
+                 ", code_out_bit = " << *t_output_bit << " ==> metric -> ";
+#endif
+               t_metric += (in_buf[r][t_in_buf_ndx] * (*t_output_bit++));
+#if DO_PRINT_DEBUG_UP
+               std::cout << t_metric << "\n";
+#endif
+             }
+           }
+// get the "to" state index
+           size_t t_to_ndx = t_connection->d_to_ndx;
+// store the metric in the "to" state; should not have been used before
+           t_to_state->d_max_metric = t_metric;
+// add the "to" state index to the "up" state list
+           *t_next_state_ndx_ptr++ = t_to_ndx;
+// update the traceback structure, depending on which variety it is
+// doing full trellis before decoding; use d_out_buf
+// simple: get the current state & output state
+           traceback_t_ptr t_out_buf = &(d_out_buf[d_time_count]
+                                         [t_state_ndx]);
+           traceback_t_ptr t_next_out_buf = &(d_out_buf[d_time_count+1]
+                                              [t_to_ndx]);
+#if DO_PRINT_DEBUG_UP_1
+           std::cout << "d_o_b[" << d_time_count+1 << "] => d_o_b prev\n" <<
+             "ndx[" << n << "] == " << t_state_ndx <<
+             ", s[" << n2bs(t_state_ndx,t_state_print_bits) <<
+             "]: max_ndx = " <<
+             n2bs(t_state->d_max_state_ndx,t_state_print_bits) <<
+             ", input = " << n2bs(q, d_n_code_inputs+1) <<
+             ": " << t_next_out_buf << " => " << t_out_buf << "\n";
+#endif
+// and connect output to the current, set inputs on output
+           t_next_out_buf->d_prev = t_out_buf;
+           t_next_out_buf->d_inputs = q;
+// finished (for) this input value
+         }
+// finished (for) this "up_term" state
+       }
+// increment the in_buf index, depending on mux'ing or not
+       t_in_buf_ndx += (d_do_mux_inputs == false) ? 1 : d_n_code_outputs;
+// increment the time counter
+        d_time_count++;
+// update the number of "up_term" states
+        d_up_term_ndx ^= 1;
+// increase the number of using states
+        t_n_up_down_ndx <<= d_n_code_inputs;
+// change which d_states' index to use as starting
+        d_states_ndx ^= 1;
+// finished (while) staying in this fsm state or not
+      }
+// if reached the end of doing the "up" part of the trellis,
+// switch states into the middle
+      if (d_time_count == d_max_memory) {
+#if DO_PRINT_DEBUG_FSM
+       std::cout << "Setting FSM to fsm_dec_viterbi_doing_middle\n";
+#endif
+        d_fsm_state = fsm_dec_viterbi_doing_middle;
+      }
+#if DO_PRINT_DEBUG_FSM
+      std::cout << "Exited fsm_dec_viterbi_doing_up\n";
+#endif
+      break;
+    case (fsm_dec_viterbi_doing_middle):
+#if DO_PRINT_DEBUG_FSM
+      std::cout << "Entered fsm_dec_viterbi_doing_middle\n";
+#endif
+// stay in this state until the correct number of input symbols is
+// reached (if doing block coding), or until there are no more input
+// symbols to parse
+      while (((d_block_size_bits != 0) &
+             (d_time_count < d_block_size_bits) &
+             (t_in_buf_ndx < t_ninput_items)) |
+            ((d_block_size_bits == 0) &
+             (t_in_buf_ndx < t_ninput_items))) {
+// use all states, loop over all inputs, compute the metric for
+// each; compare the current metric with all previous stored metric in the
+// endpoint of the connection to find the highest one.
+
+// reset the "to" state's metrics
+        reset_metrics (d_states_ndx ^ 1);
+// get the state's index for each set of new inputs
+       state_t_ptr t_state = d_states[d_states_ndx];
+#if DO_PRINT_DEBUG_MIDDLE
+       std::cout << "Time Count " << (d_time_count+1) << " of " <<
+         d_block_size_bits << "\n" <<
+         "d_states_ndx = " << d_states_ndx << "\n";;
+#endif
+// loop over all current states
+       for (size_t n = 0; n < d_n_states; n++, t_state++) {
+// loop over all possible input values, 1 bit per input stream
+         connection_t_ptr t_connection = t_state->d_connections;
+#if DO_PRINT_DEBUG_MIDDLE_0
+         std::cout << "Looping over all 'middle' states: " <<
+           n << " of " << d_n_states << "\n";
+#endif
+         for (size_t q = 0; q < d_n_input_combinations; q++, t_connection++) {
+#if DO_PRINT_DEBUG_MIDDLE_0
+           std::cout << "Input = " << n2bs(q, d_n_code_inputs+1) << "\n";
+#endif
+// start with this state's metric
+           float t_metric = t_state->d_max_metric;
+// get the "to" state
+            state_t_ptr t_to_state = t_connection->d_to;
+// get that state's metric
+            float t_to_metric = t_to_state->d_max_metric;
+// see if the computation is even needed;
+// maximum change is d_n_code_outputs if all bits match exactly
+            if ((t_to_metric - t_metric) > ((float) 2*d_n_code_outputs)) {
+#if DO_PRINT_DEBUG_MIDDLE_0
+             std::cout << "!not computing metric!\n";
+#endif
+              continue;
+           }
+// metrics are close enough; do the computation and the compare
+// get the output bits for this connection
+           float* t_output_bit = t_connection->d_output_bits;
+           if (d_do_mux_inputs == true) {
+// if using mux'ed input streams, handle differently
+              const float* t_in_buf = &(in_buf[0][t_in_buf_ndx]);
+// loop over all encoder-output values
+             for (size_t r = d_n_code_outputs; r > 0; r--) {
+#if DO_PRINT_DEBUG_MIDDLE_0
+               std::cout << "in_sym = " << *t_in_buf << ", code_out_bit = " <<
+                 *t_output_bit << " ==> metric -> ";
+#endif
+               t_metric += ((*t_in_buf++) * (*t_output_bit++));
+#if DO_PRINT_DEBUG_MIDDLE_0
+               std::cout << t_metric << "\n";
+#endif
+             }
+           } else {
+// loop over all encoder-output values
+             for (size_t r = 0; r < d_n_code_outputs; r++) {
+#if DO_PRINT_DEBUG_MIDDLE_0
+               std::cout << "in_sym = " << in_buf[r][t_in_buf_ndx] <<
+                 ", code_out_bit = " << *t_output_bit << " ==> metric -> ";
+#endif
+               t_metric += (in_buf[r][t_in_buf_ndx] * (*t_output_bit++));
+#if DO_PRINT_DEBUG_MIDDLE_0
+               std::cout << t_metric << "\n";
+#endif
+             }
+           }
+// done with this input value; compare old and new metrics
+            if (t_metric > t_to_metric) {
+#if DO_PRINT_DEBUG_MIDDLE
+             std::cout << "New Metric to s[" <<
+               n2bs (t_connection->d_to_ndx,t_state_print_bits) << "]: ";
+             if (t_to_state->d_max_metric == -1e10) {
+               std::cout << "setting to ";
+             } else {
+               std::cout << "was s[" <<
+                 n2bs(t_to_state->d_max_state_ndx,t_state_print_bits) <<
+                 "]i[" << n2bs (t_to_state->d_max_input, d_n_code_inputs+1) <<
+                 "]@ " << t_to_state->d_max_metric << "  now ";
+             }
+             std::cout << "s[" << n2bs(n,t_state_print_bits) << "] i[" <<
+               n2bs (q, d_n_code_inputs+1) << "]@ " << t_metric << "\n";
+#endif
+// new metric is better; copy that info into the "to" state
+              t_to_state->d_max_metric = t_metric;
+              t_to_state->d_max_state_ndx = n;
+              t_to_state->d_max_input = q;
+            }
+// finished (for) this input value
+         }
+// finished (for) this state
+       }
+// done with all states and all inputs; now update the traceback structure
+// change which d_states' index to use as starting
+        d_states_ndx ^= 1;
+// get the state's index for the "to" set of new inputs to get the
+// "max" stuff from
+       t_state = d_states[d_states_ndx];
+// update the traceback structure
+// loop over all current states
+       traceback_t_ptr t_prev_out_bufs = d_out_buf[d_time_count];
+       traceback_t_ptr t_out_bufs = d_out_buf[d_time_count+1];
+#if DO_PRINT_DEBUG_MIDDLE_1
+       std::cout << "d_o_b[" << d_time_count+1 << "] => d_o_b prev\n";
+#endif
+       for (size_t n = d_n_states; n > 0; n--, t_state++) {
+// simple: get the current state & output state
+// and connect output to the current, set inputs on output
+         traceback_t_ptr t_out_buf = t_out_bufs++;
+         traceback_t_ptr t_prev_out_buf =
+           &(t_prev_out_bufs[t_state->d_max_state_ndx]);
+#if DO_PRINT_DEBUG_MIDDLE_1
+         std::cout << "s[" << n2bs(d_n_states-n,t_state_print_bits) <<
+           "]: max_ndx = " <<
+           n2bs(t_state->d_max_state_ndx,t_state_print_bits) <<
+           ", input = " << n2bs(t_state->d_max_input, d_n_code_inputs+1) <<
+           ": " << t_out_buf << " => " << t_prev_out_buf << "\n";
+#endif
+         t_out_buf->d_prev = t_prev_out_buf;
+         t_out_buf->d_inputs = t_state->d_max_input;
+// finished doing this state
+       }
+// increment the in_buf index, depending on mux'ing or not
+       t_in_buf_ndx += (d_do_mux_inputs == false) ? 1 : d_n_code_outputs;
+// increment the time counter
+        d_time_count++;
+// finished (while) staying in this fsm state or not
+      }
+      if ((d_block_size_bits != 0) &
+          (d_time_count == d_block_size_bits)) {
+#if DO_PRINT_DEBUG_FSM
+       std::cout << "Setting FSM to fsm_dec_viterbi_doing_term\n";
+#endif
+        d_fsm_state = fsm_dec_viterbi_doing_term;
+      }
+      break;
+#if DO_PRINT_DEBUG_FSM
+      std::cout << "Exited fsm_dec_viterbi_doing_middle\n";
+#endif
+    case (fsm_dec_viterbi_doing_term):
+#if DO_PRINT_DEBUG_FSM
+      std::cout << "Entered fsm_dec_viterbi_doing_term\n";
+#endif
+// set the "next" up_down index to the end of their states
+      size_t t_time_count = d_max_memory - (d_time_count - d_block_size_bits);
+      t_n_up_down_ndx = 1 << (d_n_code_inputs * t_time_count);
+// stay in this state until the correct number of input symbols are
+// reached; exit also if we run out of input symbols to process
+      while ((t_time_count > 0) &
+            (t_in_buf_ndx < t_ninput_items)) {
+#if DO_PRINT_DEBUG_TERM
+       std::cout << "Doing time " << (d_max_memory - t_time_count + 1) <<
+         " of " << d_max_memory << "; starting buf[" << t_in_buf_ndx <<
+         "] of [" << t_ninput_items << "]\n";
+#endif
+// use the "to" states,
+// FIXME: loop over just the "0" inputs
+// and compute the metric for
+// each, compare & store it in the "to" state at the end of the connection.
+
+// reset the "to" state's metrics
+        reset_metrics (d_states_ndx ^ 1);
+// reset the state's index for each set of new inputs
+       size_t* t_state_ndx_ptr = d_up_term_states_ndx[d_up_term_ndx];
+       size_t* t_next_state_ndx_ptr = d_up_term_states_ndx[d_up_term_ndx ^ 1];
+// loop over all current stored "term" state indeces
+       for (size_t n = 0; n < t_n_up_down_ndx; n++) {
+         size_t t_state_ndx = *t_state_ndx_ptr++;
+         state_t_ptr t_state = &(d_states[d_states_ndx][t_state_ndx]);
+// loop over just the all 0 input value (d_connections[0])
+         connection_t_ptr t_connection = t_state->d_connections;
+// get the "to" state
+          state_t_ptr t_to_state = t_connection->d_to;
+// start with this state's metric
+          float t_metric = t_state->d_max_metric;
+// get that state's metric
+          float t_to_metric = t_to_state->d_max_metric;
+#if DO_PRINT_DEBUG_TERM
+         std::cout << "Term state " << (n+1) << " of " << t_n_up_down_ndx <<
+           "; using d_s[" << d_states_ndx << "][" <<
+           n2bs(t_state_ndx,t_state_print_bits) << "]\n";
+#endif
+// see if the computation is even needed;
+// maximum change is d_n_code_outputs if all bits match exactly
+          if ((t_to_metric - t_metric) > ((float) 2*d_n_code_outputs)) {
+#if DO_PRINT_DEBUG_TERM
+           std::cout << "!not computing metric!\n";
+#endif
+           continue;
+         }
+// metrics are close enough; do the computation and the compare
+// get the output bits for this connection
+          float* t_output_bit = t_connection->d_output_bits;
+         if (d_do_mux_inputs == true) {
+// if using mux'ed input streams, handle differently
+            const float* t_in_buf = &(in_buf[0][t_in_buf_ndx]);
+// loop over all encoder-output values
+           for (size_t r = d_n_code_outputs; r > 0; r--) {
+             t_metric += ((*t_in_buf++) * (*t_output_bit++));
+           }
+         } else {
+// loop over all encoder-output values
+           for (size_t r = 0; r < d_n_code_outputs; r++) {
+              t_metric += (in_buf[r][t_in_buf_ndx] * (*t_output_bit++));
+           }
+         }
+// done with this input value; compare old and new metrics
+// see if it's the best metric
+          if (t_metric > t_to_metric) {
+#if DO_PRINT_DEBUG_TERM
+           std::cout << "New Metric to s[" <<
+             n2bs (t_connection->d_to_ndx,t_state_print_bits) << "]: ";
+           if (t_to_state->d_max_metric == -1e10) {
+             std::cout << "setting to ";
+           } else {
+             std::cout << "was s[" <<
+               n2bs(t_to_state->d_max_state_ndx,t_state_print_bits) <<
+               "]i[" << n2bs (t_to_state->d_max_input, d_n_code_inputs+1) <<
+               "]@ " << t_to_state->d_max_metric << "  now ";
+           }
+           std::cout << "s[" << n2bs(t_state_ndx,t_state_print_bits) <<
+             "] i[" << n2bs (0, d_n_code_inputs+1) << "]@ " << t_metric << "\n";
+#endif
+            t_to_state->d_max_metric = t_metric;
+            t_to_state->d_max_state_ndx = t_state_ndx;
+            t_to_state->d_max_input = 0;
+         }
+// add the "to" state's index to the "next" set of state's indices list
+          *t_next_state_ndx_ptr++ = t_connection->d_to_ndx;
+// finished (for) this state
+       }
+// done with all states and all inputs; now update the traceback structure
+// change which d_states' index to use as starting
+        d_states_ndx ^= 1;
+// update the number of "up_term" states
+        d_up_term_ndx ^= 1;
+// reduce the number of using states
+        t_n_up_down_ndx >>= d_n_code_inputs;
+// reset the state's index for each set of new inputs
+       t_state_ndx_ptr = d_up_term_states_ndx[d_up_term_ndx];
+// update the traceback structure
+// loop over all current states
+       traceback_t_ptr t_prev_out_bufs = d_out_buf[d_time_count];
+       traceback_t_ptr t_out_bufs = d_out_buf[d_time_count+1];
+#if DO_PRINT_DEBUG_TERM_1
+       std::cout << "d_o_b[" << d_time_count+1 << "] => d_o_b prev\n";
+#endif
+// loop over all current stored "term" state indices
+       for (size_t n = 0; n < t_n_up_down_ndx; n++) {
+// get the start index and then pointer to each of the "to" states,
+// which hold the newest "max" stuff
+         size_t t_state_ndx = *t_state_ndx_ptr++;
+         state_t_ptr t_state = &(d_states[d_states_ndx][t_state_ndx]);
+// simple: get the current state & output state
+// and connect output to the current, set inputs on output
+         traceback_t_ptr t_out_buf = &(t_out_bufs[t_state_ndx]);
+         traceback_t_ptr t_prev_out_buf =
+           &(t_prev_out_bufs[t_state->d_max_state_ndx]);
+#if DO_PRINT_DEBUG_TERM_1
+         std::cout << "ndx[" << n << "] == " << t_state_ndx <<
+           ", s[" << n2bs(t_state_ndx,t_state_print_bits) <<
+           "]: max_ndx = " <<
+           n2bs(t_state->d_max_state_ndx,t_state_print_bits) <<
+           ", input = " << n2bs(t_state->d_max_input, d_n_code_inputs+1) <<
+           ": " << t_out_buf << " => " << t_prev_out_buf << "\n";
+#endif
+         t_out_buf->d_prev = t_prev_out_buf;
+         t_out_buf->d_inputs = t_state->d_max_input;
+// finished (for) this state
+       }
+// increment the in_buf index, depending on mux'ing or not
+       t_in_buf_ndx += (d_do_mux_inputs == false) ? 1 : d_n_code_outputs;
+// increment the time counters
+        t_time_count--;
+        d_time_count++;
+// finished (while) staying in this fsm state or not
+      }
+      if (t_time_count == 0) {
+// finished this trellis, now move as much of the decoded input to the
+// output buffer as possible
+#if DO_PRINT_DEBUG_FSM
+       std::cout << "Setting FSM to fsm_dec_viterbi_output\n";
+#endif
+       d_fsm_state = fsm_dec_viterbi_output;
+      }
+#if DO_PRINT_DEBUG_FSM
+      std::cout << "Exited fsm_dec_viterbi_doing_term\n";
+#endif
+      break;
+    case (fsm_dec_viterbi_output):
+#if DO_PRINT_DEBUG_FSM
+      std::cout << "Entered fsm_dec_viterbi_output.\n";
+#endif
+// this is done in reverse bit order (last time to first time)
+// using the traceback structure in d_out_buf, starting with
+// the maximum valued one in the last time slot, then using
+// the traceback's "d_prev" link to trace the trellis back
+
+// see where the output data will terminate
+      int t_next_out_buf_ndx = (t_out_buf_ndx +
+                               (d_block_size_bits / g_num_bits_per_byte));
+      int t_next_out_bit_shift = (t_out_bit_shift +
+                                 (d_block_size_bits % g_num_bits_per_byte));
+      if (t_next_out_bit_shift >= g_num_bits_per_byte) {
+       t_next_out_bit_shift -= g_num_bits_per_byte;
+       t_next_out_buf_ndx++;
+      }
+#if DO_PRINT_DEBUG_OUTPUT
+      std::cout << "First bit in at out[][" << t_out_buf_ndx << "].[" <<
+       t_out_bit_shift << "] -> " << d_block_size_bits << " bits == " <<
+       (d_block_size_bits / g_num_bits_per_byte) << " Byte" <<
+       ((d_block_size_bits / g_num_bits_per_byte) != 1 ? "s" : "") <<
+       " + " << (d_block_size_bits % g_num_bits_per_byte) << " bit" <<
+       ((d_block_size_bits % g_num_bits_per_byte) != 1 ? "s" : "") <<
+       "\nNext set of bits start at out[][" << t_next_out_buf_ndx <<
+       "].[" << t_next_out_bit_shift << "]\n";
+#endif
+// find the starting traceback structure
+      traceback_t_ptr t_out_buf;
+      if (d_do_termination == true) {
+// FIXME: assume termination state == 0
+#if DO_PRINT_DEBUG_OUTPUT_0
+       std::cout << "Using termination; going through trellis for " <<
+         d_max_memory << " bit" <<
+         ((d_max_memory != 1) ? "s" : "") << "\n";
+#endif
+       t_out_buf = &(d_out_buf[d_time_count][0]);
+#if DO_PRINT_DEBUG_OUTPUT_0
+       std::cout << "Starting traceback ptr " << t_out_buf << "\n";
+#endif
+// skip over the termination bits
+       for (size_t n = d_max_memory; n > 0; n--) {
+         t_out_buf = t_out_buf->d_prev;
+#if DO_PRINT_DEBUG_OUTPUT_0
+         std::cout << "Next traceback ptr " << t_out_buf << "\n";
+#endif
+       }
+      } else {
+// no termination but doing block coding;
+// FIXME: use the state with the bext metric
+// get the state's index for each set of new inputs
+       state_t_ptr t_state = d_states[d_states_ndx];
+       float t_max_metric = t_state->d_max_metric;
+       size_t t_max_state_ndx = 0;
+       t_state++;
+// loop over all current states
+       for (size_t n = 1; n < d_n_states; n++, t_state++) {
+// start with this state's metric
+         float t_metric = t_state->d_max_metric;
+// compare with current max
+         if (t_metric > t_max_metric) {
+           t_max_metric = t_metric;
+           t_max_state_ndx = n;
+         }
+       }
+// get the correct out_buf reference to start with
+       t_out_buf = &(d_out_buf[d_time_count][t_max_state_ndx]);
+      }
+#if DO_PRINT_DEBUG_OUTPUT
+      std::cout << "Found starting traceback ptr " << t_out_buf <<
+       "; getting all " << d_block_size_bits << " bits per stream.\n";
+#endif
+// now we've got the starting traceback structure address;
+// check to make sure there is enough space in each output buffer
+      size_t t_block_bit_ndx = d_block_size_bits;
+      if ((t_next_out_buf_ndx > t_noutput_bytes) |
+         ((t_next_out_buf_ndx == t_noutput_bytes) &
+          (t_next_out_bit_shift != 0))) {
+// not enough space for all output bits;
+// find the number of extra bits to save
+       size_t t_save_buf_ndx = t_next_out_buf_ndx - t_noutput_bytes;
+       size_t t_n_extra_bits = ((t_save_buf_ndx * g_num_bits_per_byte) +
+                                t_next_out_bit_shift);
+// set the number of saved bits
+       d_n_saved_bits = t_n_extra_bits;
+// remove the extra bits from the number to copy to the output buffer
+       t_block_bit_ndx -= t_n_extra_bits;
+// find the actual output buf index, once we get there
+       t_next_out_buf_ndx -= t_save_buf_ndx;
+#if DO_PRINT_DEBUG_OUTPUT
+       std::cout << "Not enough output buffer space:\n" <<
+         "len (o_b) = " << t_noutput_bytes << " ==> " <<
+         t_n_extra_bits << " extra bit" <<
+         (t_n_extra_bits != 1 ? "s" : "") << " == " <<
+         t_save_buf_ndx << " Byte" <<
+         (t_save_buf_ndx != 1 ? "s" : "") << ", " <<
+         t_next_out_bit_shift << " bit" <<
+         (t_next_out_bit_shift != 1 ? "s" : "") << "\n";
+#endif
+// zero each output buffers' bytes
+       size_t t_n_zero = t_save_buf_ndx + (t_next_out_bit_shift ? 1 : 0);
+#if DO_PRINT_DEBUG_OUTPUT
+       size_t t_n_out_bytes = ((d_block_size_bits / g_num_bits_per_byte) +
+                               ((d_block_size_bits % g_num_bits_per_byte) ? 1 : 0));
+       std::cout << "Zeroing save buffer from for " << t_n_zero <<
+         " Byte" << (t_n_zero != 1 ? "s" : "") << " (of " <<
+         d_block_size_bits << " bit" <<
+         (d_block_size_bits != 1 ? "s" : "") << " == " << t_n_out_bytes <<
+         " Byte" << (t_n_out_bytes != 1 ? "s" : "") << ")\n";
+#endif
+       for (size_t m = 0; m < d_n_code_inputs; m++)
+         bzero (d_save_buffer[m], t_n_zero);
+// loop over all extra bits
+       for (size_t n = t_n_extra_bits; n > 0; n--) {
+// first decrement the output bit & byte as necessary
+         if (--t_next_out_bit_shift < 0) {
+           t_next_out_bit_shift += g_num_bits_per_byte;
+           t_save_buf_ndx--;
+         }
+// get the encoder inputs to output
+         size_t t_inputs = t_out_buf->d_inputs;
+// loop over all code inputs (decoder-outputs), 1 bit per stream
+         for (size_t m = 0; m < d_n_code_inputs; m++) {
+           d_save_buffer[m][t_save_buf_ndx] |=
+             ((t_inputs & 1) << t_next_out_bit_shift);
+           t_inputs >>= 1;
+         }
+         t_out_buf = t_out_buf->d_prev;
+#if DO_PRINT_DEBUG_OUTPUT_0
+         std::cout << "Next traceback ptr " << t_out_buf << "\n";
+#endif
+       }
+// at exit, "t_out_buf_ndx" should be == t_noutput_bytes, and
+// "t_out_bit_shift" should be 0; check these!
+#if DO_PRINT_DEBUG_OUTPUT
+       std::cout << "n_o_b_ndx (" << t_next_out_buf_ndx << ") ?=? " <<
+         "#o_B (" << t_noutput_bytes << ") & t_o_b_sh (" <<
+         t_next_out_bit_shift << ") ?=? 0\n";
+       assert (t_next_out_buf_ndx == t_noutput_bytes);
+       assert (t_next_out_bit_shift == 0);
+#endif
+      }
+// set the correct output buffer index and bit shift
+      t_out_bit_shift = t_next_out_bit_shift;
+      t_out_buf_ndx = t_next_out_buf_ndx;
+// copy any remaining bits looping backwards in bit-time
+// through the traceback trellis
+      for (size_t n = t_block_bit_ndx; n > 0; n--) {
+// first decrement the output bit & byte as necessary
+       if (--t_out_bit_shift < 0) {
+         t_out_bit_shift += g_num_bits_per_byte;
+         t_out_buf_ndx--;
+       }
+// get the encoder inputs to output
+       size_t t_inputs = t_out_buf->d_inputs;
+// loop over all code inputs (decoder-outputs), 1 bit per stream
+       for (size_t m = 0; m < d_n_code_inputs; m++) {
+         out_buf[m][t_out_buf_ndx] |= ((t_inputs & 1) << t_out_bit_shift);
+         t_inputs >>= 1;
+       }
+       t_out_buf = t_out_buf->d_prev;
+#if DO_PRINT_DEBUG_OUTPUT_0
+       std::cout << "Next traceback ptr " << t_out_buf << "\n";
+#endif
+      }
+// set the next output byte and bit-shift
+      t_out_bit_shift = t_next_out_bit_shift;
+      t_out_buf_ndx = t_next_out_buf_ndx;
+#if DO_PRINT_DEBUG_FSM
+      std::cout << "Set FSM to fsm_dec_viterbi_init\n";
+#endif
+      d_fsm_state = fsm_dec_viterbi_init;
+#if DO_PRINT_DEBUG_FSM
+      std::cout << "Exited fsm_dec_viterbi_output\n";
+#endif
+      break;
+    case (fsm_dec_viterbi_init):
+#if DO_PRINT_DEBUG_FSM
+      std::cout << "Entered fsm_dec_viterbi_init\n";
+#endif
+// this is called immediately (first input bit upon startup),
+// or after termination of a trellis.
+
+// reset states to the 0'th one
+      d_up_term_ndx = d_states_ndx = 0;
+// zero the metrics for those states
+      zero_metrics (0);
+#if 0
+// might not need to do this; check and see after it works
+// reset up_term states and number so that there is 1 item, the "0" state.
+      bzero (d_up_term_states_ndx[0], sizeof (size_t) * d_n_states);
+      bzero (d_up_term_states_ndx[1], sizeof (size_t) * d_n_states);
+#else
+      d_up_term_states_ndx[0][0] = 0;
+#endif
+// reset time count back to the start
+      d_time_count = 0;
+#if 0
+// reset the traceback structures
+// might not need to do this; check and see after it works
+      traceback_t_hdl t_out_bufs = d_out_buf;
+      for (size_t n = d_n_traceback_els; n > 0; n--) {
+       traceback_t_ptr t_out_buf = (*t_out_bufs++);
+       for (size_t m = d_n_states; m > 0; m--, t_out_buf++) {
+         t_out_buf->d_prev = NULL;
+         t_out_buf->d_inputs = -1;
+       }
+      }
+#endif
+// set the fsm to "doing up"
+#if DO_PRINT_DEBUG_FSM
+      std::cout << "Set FSM to fsm_dec_viterbi_doing_up\n";
+#endif
+      d_fsm_state = fsm_dec_viterbi_doing_up;
+#if DO_PRINT_DEBUG_FSM
+      std::cout << "Exited fsm_dec_viterbi_init\n";
+#endif
+      break;
+// should never get here!
+    default:
+      assert (0);
+// done (switch) with FSM
+    }
+// done (while) there are inputs
+  }
+
+// consume all of the input items on all input streams
+// "ninput_items[]" doesn't seem to be reliable,
+// so compute this from the actual number of blocks processed
+#if DO_PRINT_DEBUG_EXIT
+  std::cout << "Exiting FSM in state: " <<
+    (d_fsm_state == fsm_dec_viterbi_init ? "init" :
+     (d_fsm_state == fsm_dec_viterbi_doing_up ? "up" :
+      (d_fsm_state == fsm_dec_viterbi_doing_middle ? "middle" :
+       (d_fsm_state == fsm_dec_viterbi_doing_term ? "term" :
+       (d_fsm_state == fsm_dec_viterbi_output ? "output" : "unknown"))))) << "\n" <<
+    "Consuming " << t_in_buf_ndx <<
+    " input items on each input stream (of " << t_ninput_items << ").\n";
+#endif
+  consume_each (t_in_buf_ndx);
+
+// make sure the number of output items makes sense
+// t_out_buf_ndx always points to the current index
+// t_out_bit_shift always points to the next bit position to be written
+  int t_leftover_bytes = t_out_buf_ndx % d_out_stream_el_size_bytes;
+  int t_leftover_bits = ((t_leftover_bytes * g_num_bits_per_byte) +
+                        t_out_bit_shift);
+  int t_noutput_items = noutput_items;
+#if DO_PRINT_DEBUG_EXIT
+  std::cout << "Final o_b[" << t_out_buf_ndx << "][" <<
+    t_out_bit_shift << "] of " << t_noutput_bytes <<
+    ", el_size = " << d_out_stream_el_size_bytes <<
+    ", lo_Bytes = " << t_leftover_bytes <<
+    ", t_lo_bits = " << t_leftover_bits << "\n" <<
+    "Desired # output items = " << noutput_items << "\n";
+#endif
+  if (t_leftover_bits != 0) {
+    // should never get here!
+#if 1
+    assert (0);
+#else
+    int t_ndx = t_out_buf_ndx - t_leftover_bytes;
+    size_t t_n_copy = t_leftover_bytes + ((t_out_bit_shift != 0) ? 1 : 0);
+    assert (t_n_copy <= d_out_stream_el_size_bytes);
+// copy the leftover into the save buffer
+    for (size_t n = 0; n < d_n_code_inputs; n++) {
+      bcopy (&(out_buf[n][t_ndx]), d_save_buffer[n], t_n_copy);
+    }
+    t_noutput_items = t_ndx / d_out_stream_el_size_bytes;
+    d_n_saved_bits = t_leftover_bits;
+#if DO_PRINT_DEBUG_EXIT
+    std::cout << "Copied " << t_n_copy << " Byte" <<
+      (t_n_copy != 1 ? "s" : "") << " from o_b[][" << t_ndx <<
+      "] into each save buffer.\n" <<
+      "Actual #output items = " << t_noutput_items <<
+      ", # saved bit(s) = " << d_n_saved_bits << "\n";
+#endif
+#endif
+  }
+
+#endif
+
+#if DO_TIME_THOUGHPUT
+  u_long d_t = end_timer (&t_tp);
+
+  std::cout << "dec_blk_conv_soft_full: Completed " << t_ninput_items <<
+    " bits in " << d_t << " usec => " <<
+    1e6*(((double)(t_ninput_items))/((double) d_t)) <<
+    " b/s\n";
+#endif
+}
diff --git a/gr-error-correcting-codes/src/lib/libecc/decoder_viterbi.h b/gr-error-correcting-codes/src/lib/libecc/decoder_viterbi.h
new file mode 100644 (file)
index 0000000..66a6ba4
--- /dev/null
@@ -0,0 +1,189 @@
+/* -*- 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 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.
+ */
+
+#ifndef INCLUDED_DECODER_VITERBI_H
+#define INCLUDED_DECODER_VITERBI_H
+
+#include "decoder.h"
+#include "encoder_convolutional.h"
+
+class decoder_viterbi : public decoder
+{
+public:
+/*!
+ * \brief Decode the incoming metrics streams using the Viterbi algorithm.
+ *
+ * input: streams of metrics, 2 streams per n_code_outputs - one each for
+ *     a 0- and 1-bit metric.
+ *
+ * output: streams of char, one stream per n_code_inputs, using only
+ *     the right-most justified bit as the single bit per output item.
+ *
+ * sample_precision: precision of the incoming metrics
+ *     if == 0, then use soft precision (32 bit float);
+ *     otherwise, use an integer up to 32 bits, already sign-extended
+ *     to the nearest power-of-2-sized type (char, short, long).
+ *
+ * l_encoder: pointer to an encoder class from which to determine the
+ *     trellis transitions (states and i/o bits).
+ */
+
+  decoder_viterbi (int sample_precision,
+                  encoder_convolutional* l_encoder);
+
+  virtual ~decoder_viterbi ();
+
+protected:
+  struct state_t;
+
+/*
+ * connection_t: describes an output connection from the current
+ *     time-bit memory state to the next time-bit memory state
+ *
+ * d_to: state pointer to which this connection going
+ *
+ * d_to_ndx: index of the "to" state
+ *
+ * d_output_bits: what are the output bits, coverted into
+ *     1->+1.0, 0->-1.0, for this connection
+ */
+
+  typedef struct connection_t {
+    struct state_t *d_to;
+    int d_to_ndx;
+    float* d_output_bits;
+  } connection_t, *connection_t_ptr;
+
+/*
+ * state_t: describes a given memory state
+ *
+ * d_connections:  a pointer to an array of these structures
+ *     will be used to describes a given time-bit's memory state;
+ *     an entry will be referenced via "state_add_to", to find the
+ *     connections to the next time-bit memory states.  There is
+ *     one entry per each input bit combination -> 2^#I connections in all.
+ *     e.g. [0] means the all 0 input;
+ *     [1] means that input #1 was 1 while all the others were 0;
+ *     [2] means that input #2 was 1, while all the others were 0;
+ *     [3] means that inputs #1 and #2 were 1, while the others were 0.
+ *
+ * d_max_metric: the maximum metric thus far for this state
+ *
+ * d_max_state: the state from which the maximum metric was attained
+ *
+ * d_max_input: the input bits from which the maximum metric was attained
+ */
+
+  typedef struct state_t {
+    connection_t_ptr d_connections;
+    float d_max_metric;
+    int d_max_state_ndx;
+    int d_max_input;
+  } state_t, *state_t_ptr;
+
+/*
+ * state_get_from(v,i,k): use to retrieve a given bit-memory state,
+ *     from the inputs:
+ *
+ * memory_t v: the value from which to retrieve the given state
+ * size_t i: for which input stream (0 to #I-1)
+ * size_t k: the number of memory slots per input (e.g. 1+D^2 -> 2)
+ */
+
+  inline memory_t state_get_from (memory_t v,
+                                 size_t i,
+                                 size_t k)
+  {return (((v)>>((i)*(k)))&((1<<(k))-1));};
+
+/*
+ * state_add_to(s,v,i,k): use to create a given bit-memory state,
+ *     from the inputs:
+ *
+ * memory_t s: the state value to modify
+ * memory_t v: value to set the state to for this input
+ * size_t i: for which input stream (0 to #I-1)
+ * size_t k: the number of memory slots per input (e.g. 1+D^2 -> 2)
+ */
+
+  inline void state_add_to (memory_t s,
+                           memory_t v,
+                           size_t i,
+                           size_t k)
+  {(s)|=(((v)&((1<<(k))-1))<<((i)*(k)));};
+
+/*
+ * fsm_dec_viterbi_t: finite state machine for the Viterbi decoder
+ *
+ * fsm_dec_viterbi_init: initialize for a new block / block; this is
+ *     already done at instantiation, so do it only at the end of a
+ *     block.
+ *
+ * fsm_dec_viterbi_doing_up: encoding at the start of a block
+ *
+ * fsm_dec_viterbi_doing_middle: doing encoding inside the trellis
+ *
+ * fsm_dec_viterbi_doing_term: termination trellis, if requested
+ */
+
+  enum fsm_dec_viterbi_t {
+    fsm_dec_viterbi_init, fsm_dec_viterbi_doing_up,
+    fsm_dec_viterbi_doing_middle, fsm_dec_viterbi_doing_term
+  };
+
+  virtual void decode_private (const char** in_buf, char** out_buf);
+  virtual char get_next_input (const char** in_buf, size_t code_input_n);
+#if 0
+  virtual void decode_loop (const char** in_buf, char** out_buf,
+                           size_t* which_counter, size_t how_many);
+
+  virtual char get_next_input__up (const char** in_buf,
+                                     size_t code_input_n) = 0;
+  virtual char get_next_input__middle (const char** in_buf,
+                                         size_t code_input_n) = 0;
+  virtual char get_next_input__term (size_t code_input_n) = 0;
+#endif
+  virtual void increment_input_indices (bool while_decoding) = 0;
+  virtual void increment_output_indices (bool while_decoding) = 0;
+  virtual void update_traceback__up (size_t from_state_ndx,
+                                    size_t to_state_ndx,
+                                    size_t l_input) = 0;
+  virtual void update_traceback__middle () = 0;
+  virtual void update_traceback__term () = 0;
+
+  void reset_metrics (u_char which);
+  void zero_metrics (u_char which);
+
+  encoder_convolutional* d_encoder;
+  fsm_dec_viterbi_t d_fsm_state;
+  size_t d_max_memory, d_total_memory;
+  size_t d_time_count, d_n_total_inputs_per_stream;
+  size_t d_n_saved_bits, d_n_saved_bits_start_ndx, d_n_traceback_els;
+  size_t d_n_states, d_n_input_combinations;
+  size_t d_states_ndx, d_up_term_ndx;
+  bool d_do_streaming, d_do_termination;
+  std::vector<memory_t> d_init_states, d_term_states;
+  char **d_save_buffer;
+  state_t_ptr d_states[2];
+  size_t* d_up_term_states_ndx[2];
+};
+
+#endif /* INCLUDED_DECODER_VITERBI_H */
diff --git a/gr-error-correcting-codes/src/lib/libecc/decoder_viterbi_full_block.cc b/gr-error-correcting-codes/src/lib/libecc/decoder_viterbi_full_block.cc
new file mode 100644 (file)
index 0000000..308d277
--- /dev/null
@@ -0,0 +1,1120 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "decoder_viterbi_full_block.h"
+#include <assert.h>
+#include <iostream>
+#include <math.h>
+
+const int g_max_block_size_bits = 10000000;
+const int g_max_num_streams = 10;
+const int g_num_bits_per_byte = 8;
+
+#define DO_TIME_THOUGHPUT 0
+
+#define DO_PRINT_DEBUG_INST 0
+#define DO_PRINT_DEBUG_FSM 0
+#define DO_PRINT_DEBUG_INIT 0
+#define DO_PRINT_DEBUG_UP 0
+#define DO_PRINT_DEBUG_UP_0 0
+#define DO_PRINT_DEBUG_UP_1 0
+#define DO_PRINT_DEBUG_MIDDLE 0
+#define DO_PRINT_DEBUG_MIDDLE_0 0
+#define DO_PRINT_DEBUG_MIDDLE_1 0
+#define DO_PRINT_DEBUG_TERM 0
+#define DO_PRINT_DEBUG_TERM_1 0
+#define DO_PRINT_DEBUG_OUTPUT 0
+#define DO_PRINT_DEBUG_OUTPUT_0 0
+#define DO_PRINT_DEBUG_EXIT 0
+#define DO_PRINT_DEBUG 1
+
+#if DO_TIME_THOUGHPUT
+#include <mld/mld_timer.h>
+#endif
+#if DO_PRINT_DEBUG
+#include <mld/n2bs.h>
+#endif
+
+decoder_viterbi_full_block::decoder_viterbi_full_block
+(int sample_precision,
+ encoder_convolutional* l_encoder)
+  : decoder_viterbi (sample_precision, l_encoder)
+{
+  // verify that the block size is non-zero
+
+  if (d_block_size_bits == 0) {
+    std::cerr << "decoder_viterbi_full_block: Error: "
+      "Block size is 0, and must be positive for block decoding.\n";
+    assert (0);
+  }
+
+  // the traceback buffers are specific to the type of decoding
+  // (full/block, partial/block, partial/stream)
+
+  // create the traceback buffers; for full/block, use the total # of
+  // bits to decode + 1: each bit is represented by a transition
+  // between traceback elements.
+
+  d_n_traceback_els = d_n_total_inputs_per_stream + 1;
+
+  // create the output buffers:
+  // this is a 2d matrix structure, where the first dimension
+  // is the number of output bits; the second dimension is
+  // the number of states.
+  // When doing full blocks, each bit-time's state's traceback
+  // contains just the pointer to the previous bit-time's state's traceback
+  // as well as the inputs for that connection.
+  // No further work is required because each reverse-path is unique
+  // once a given end-bit-time's state is determined to be "the one".
+
+  traceback_t_hdl t_out_buf =
+    d_out_buf = new traceback_t_ptr [d_n_traceback_els];
+  for (size_t n = d_n_traceback_els; n > 0; n--) {
+    (*t_out_buf++) = new traceback_t [d_n_states];
+  }
+
+  if (DO_PRINT_DEBUG_INST) {
+    std::cout <<
+      "total # in bits / stream = " << d_n_total_inputs_per_stream << "\n" <<
+      "d_n_traceback_els        = " << d_n_traceback_els << "\n";
+  }
+
+  if (DO_PRINT_DEBUG_INST) {
+    traceback_t_hdl t_out_bufs = d_out_buf;
+    for (size_t n = 0; n < d_n_traceback_els; n++, *t_out_bufs++) {
+      traceback_t_ptr t_out_buf = *t_out_bufs;
+      for (size_t m = 0; m < d_n_states; m++, t_out_buf++) {
+       std::cout << "tb[" << n << "] = " << t_out_bufs <<
+         ", &tb[" << n << "][" << m << "] = " << (&d_out_buf[n][m]) <<
+         ", tb[" << n << "," << m << "] = " << t_out_buf << "\n";
+      }
+    }
+  }
+}
+
+decoder_viterbi_full_block::~decoder_viterbi_full_block
+()
+{
+  // delete the traceback buffers
+
+  traceback_t_hdl t_out_buf = d_out_buf;
+  for (size_t n = d_n_traceback_els; n > 0; n--) {
+    delete [] (*t_out_buf++);
+  }
+  delete [] d_out_buf;
+}
+
+void
+decoder_viterbi_full_block::update_traceback__up
+(size_t from_state_ndx,
+ size_t to_state_ndx,
+ size_t l_input)
+{
+#if 0
+#if DO_PRINT_DEBUG
+  size_t t_state_print_bits = d_total_memory + 1;
+  size_t t_mem_print_bits = d_max_memory + 2;
+#endif
+  // update the traceback structure, depending on which variety it is
+  // doing full trellis before decoding; use d_out_buf
+
+  // get the current state & output state
+
+  traceback_t_ptr t_out_buf = &(d_out_buf[d_time_count]
+                               [from_state_ndx]);
+  traceback_t_ptr t_next_out_buf = &(d_out_buf[d_time_count+1]
+                                    [to_state_ndx]);
+  if (DO_PRINT_DEBUG_UP_1) {
+    std::cout << "d_o_b[" << d_time_count+1 << "] => d_o_b prev\n" <<
+      "ndx[" << n << "] == " << from_state_ndx <<
+      ", s[" << n2bs(from_state_ndx,t_state_print_bits) <<
+      "]: max_ndx = " <<
+      n2bs(t_state->d_max_state_ndx,t_state_print_bits) <<
+      ", input = " << n2bs(l_input, d_n_code_inputs+1) <<
+      ": " << t_next_out_buf << " => " << t_out_buf << "\n";
+  }
+
+  // and connect output to the current, set inputs on output
+
+  t_next_out_buf->d_prev = t_out_buf;
+  t_next_out_buf->d_inputs = l_input;
+#endif
+}
+
+void
+decoder_viterbi_full_block::update_traceback__middle
+()
+{
+#if 0
+
+#if DO_PRINT_DEBUG
+  size_t t_state_print_bits = d_total_memory + 1;
+  size_t t_mem_print_bits = d_max_memory + 2;
+#endif
+  // change which d_states' index to use as starting
+
+  d_states_ndx ^= 1;
+
+  // get the state's index for the "to" set of new inputs to get the
+  // "max" stuff from
+
+  state_t_ptr t_state = d_states[d_states_ndx];
+
+  // update the traceback structure
+  // loop over all current states
+
+  traceback_t_ptr t_prev_out_bufs = d_out_buf[d_time_count];
+  traceback_t_ptr t_out_bufs = d_out_buf[d_time_count+1];
+
+  if (DO_PRINT_DEBUG_MIDDLE_1) {
+    std::cout << "d_o_b[" << d_time_count+1 << "] => d_o_b prev\n";
+  }
+
+  for (size_t n = d_n_states; n > 0; n--, t_state++) {
+
+    // simple: get the current state & output state
+    // and connect output to the current, set inputs on output
+
+    traceback_t_ptr t_out_buf = t_out_bufs++;
+    traceback_t_ptr t_prev_out_buf =
+      &(t_prev_out_bufs[t_state->d_max_state_ndx]);
+
+    if (DO_PRINT_DEBUG_MIDDLE_1) {
+      std::cout << "s[" << n2bs(d_n_states-n,t_state_print_bits) <<
+       "]: max_ndx = " <<
+       n2bs(t_state->d_max_state_ndx,t_state_print_bits) <<
+       ", input = " << n2bs(t_state->d_max_input, d_n_code_inputs+1) <<
+       ": " << t_out_buf << " => " << t_prev_out_buf << "\n";
+    }
+
+    t_out_buf->d_prev = t_prev_out_buf;
+    t_out_buf->d_inputs = t_state->d_max_input;
+  }
+
+#endif
+}
+
+void
+decoder_viterbi_full_block::update_traceback__term
+()
+{
+#if 0
+
+#if DO_PRINT_DEBUG
+  size_t t_state_print_bits = d_total_memory + 1;
+  size_t t_mem_print_bits = d_max_memory + 2;
+#endif
+// done with all states and all inputs; now update the traceback structure
+// change which d_states' index to use as starting
+        d_states_ndx ^= 1;
+// update the number of "up_term" states
+        d_up_term_ndx ^= 1;
+// reduce the number of using states
+        t_n_up_down_ndx >>= d_n_code_inputs;
+// reset the state's index for each set of new inputs
+       t_state_ndx_ptr = d_up_term_states_ndx[d_up_term_ndx];
+// update the traceback structure
+// loop over all current states
+       traceback_t_ptr t_prev_out_bufs = d_out_buf[d_time_count];
+       traceback_t_ptr t_out_bufs = d_out_buf[d_time_count+1];
+#if DO_PRINT_DEBUG_TERM_1
+       std::cout << "d_o_b[" << d_time_count+1 << "] => d_o_b prev\n";
+#endif
+// loop over all current stored "term" state indices
+       for (size_t n = 0; n < t_n_up_down_ndx; n++) {
+// get the start index and then pointer to each of the "to" states,
+// which hold the newest "max" stuff
+         size_t t_state_ndx = *t_state_ndx_ptr++;
+         state_t_ptr t_state = &(d_states[d_states_ndx][t_state_ndx]);
+// simple: get the current state & output state
+// and connect output to the current, set inputs on output
+         traceback_t_ptr t_out_buf = &(t_out_bufs[t_state_ndx]);
+         traceback_t_ptr t_prev_out_buf =
+           &(t_prev_out_bufs[t_state->d_max_state_ndx]);
+#if DO_PRINT_DEBUG_TERM_1
+         std::cout << "ndx[" << n << "] == " << t_state_ndx <<
+           ", s[" << n2bs(t_state_ndx,t_state_print_bits) <<
+           "]: max_ndx = " <<
+           n2bs(t_state->d_max_state_ndx,t_state_print_bits) <<
+           ", input = " << n2bs(t_state->d_max_input, d_n_code_inputs+1) <<
+           ": " << t_out_buf << " => " << t_prev_out_buf << "\n";
+#endif
+         t_out_buf->d_prev = t_prev_out_buf;
+         t_out_buf->d_inputs = t_state->d_max_input;
+// finished (for) this state
+       }
+
+#endif
+}
+
+void
+decoder_viterbi_full_block::decode_private
+(const char** in_buf,
+ char** out_buf)
+{
+#if 0
+
+#if DO_TIME_THOUGHPUT
+  struct timeval t_tp;
+  start_timer (&t_tp);
+#endif
+#if DO_PRINT_DEBUG
+  size_t t_state_print_bits = d_total_memory + 1;
+  size_t t_mem_print_bits = d_max_memory + 2;
+#endif
+// setup variables for quicker access
+  int t_in_buf_ndx = 0, t_out_buf_ndx = 0;
+  int t_out_bit_shift = 0;
+  int t_ninput_items = fixed_rate_noutput_to_ninput (noutput_items);
+  int t_noutput_bytes = noutput_items * d_out_stream_el_size_bytes;
+
+#if DO_PRINT_DEBUG_INST
+  std::cout << "# output items = " << noutput_items << " (" <<
+    t_noutput_bytes << " Bytes, " << (t_noutput_bytes * g_num_bits_per_byte) <<
+    " bits), # input items = " << t_ninput_items << " Symbols\n";
+  for (size_t n = 0; n < ninput_items.size(); n++) {
+    std::cout << "# input items [" << n << "] = " << ninput_items[n] << "\n";
+  }
+#endif
+
+// put any leftover bits into the output
+  if (d_n_saved_bits != 0) {
+// copy the leftover from the save buffer
+// check to make sure it will all fit
+    size_t t_noutput_bits = t_noutput_bytes * g_num_bits_per_byte;
+    size_t t_n_copy;
+    if (t_noutput_bits < d_n_saved_bits) {
+// asking for fewer bits than available; set to copy
+// just what's being asked for
+      t_n_copy = t_noutput_bytes;
+    } else {
+// asking for at least as many bits as available; set to copy all
+      t_out_buf_ndx = d_n_saved_bits / g_num_bits_per_byte;
+      t_out_bit_shift = d_n_saved_bits % g_num_bits_per_byte;
+      t_n_copy = t_out_buf_ndx + (t_out_bit_shift != 0 ? 1 : 0);
+    }
+// do the copy for all output streams (code inputs)
+// copy starting at save buffer index "start"
+    for (size_t n = 0; n < d_n_code_inputs; n++)
+      bcopy (&(d_save_buffer[n][d_n_saved_bits_start_ndx]),
+            out_buf[n], t_n_copy);
+#if DO_PRINT_DEBUG_INST
+    std::cout << "Copied " << t_n_copy << " Byte" <<
+      (t_n_copy != 1 ? "s" : "") << ": s_b[][" <<
+      d_n_saved_bits_start_ndx << "] => o_b[][0]\n" <<
+      "# saved bits = " << d_n_saved_bits <<
+      ", o_b_ndx = " << t_out_buf_ndx <<
+      ", bit shift = " << t_out_bit_shift << "\n";
+#endif
+//  update the number of saved bits and start
+    if (t_noutput_bits < d_n_saved_bits) {
+// asking for fewer bit than available: update
+// the number of saved bits and their starting index
+      d_n_saved_bits_start_ndx += t_noutput_bytes;
+      d_n_saved_bits -= (t_noutput_bytes * g_num_bits_per_byte);
+#if DO_PRINT_DEBUG_INST
+      std::cout << "Updated # saved bits = " << d_n_saved_bits <<
+       ", index = " << d_n_saved_bits_start_ndx << "\n";
+#endif
+// nothing to consume; return the desired number of output items
+      return (noutput_items);
+    } else {
+      d_n_saved_bits_start_ndx = d_n_saved_bits = 0;
+    }
+  }
+#if DO_PRINT_DEBUG_INST
+  std::cout << "Starting FSM in state: " <<
+    (d_fsm == fsm_dec_init ? "init" :
+     (d_fsm == fsm_dec_doing_up ? "up" :
+      (d_fsm == fsm_dec_doing_middle ? "middle" :
+       (d_fsm == fsm_dec_doing_term ? "term" :
+       (d_fsm == fsm_dec_output ? "output" : "unknown"))))) << "\n";
+#endif
+
+// while there are input items to create
+  while (t_out_buf_ndx < t_noutput_bytes) {
+#if DO_PRINT_DEBUG_FMS
+    std::cout << "Starting 'while': processing " << t_in_buf_ndx << " of " <<
+      t_ninput_items << " items.\nJumping to state '" <<
+      (d_fsm == fsm_dec_init ? "init" :
+       (d_fsm == fsm_dec_doing_up ? "up" :
+       (d_fsm == fsm_dec_doing_middle ? "middle" :
+        (d_fsm == fsm_dec_doing_term ? "term" :
+         (d_fsm == fsm_dec_output ? "output" : "unknown"))))) << "'\n";
+#endif
+// jump to the correct state in the fsm
+    switch (d_fsm) {
+    case fsm_dec_doing_up:
+#if DO_PRINT_DEBUG_FSM
+      std::cout << "Starting fsm_dec_doing_up\n";
+#endif
+// set the number of up_down indices
+      size_t t_n_up_down_ndx = 1 << (d_n_code_inputs *
+                                    d_time_count);
+// stay in this state until the correct number of input symbols are
+// reached; exit also if we run out of input symbols to process
+      while ((d_time_count < d_max_memory) &
+            (t_in_buf_ndx < t_ninput_items)) {
+#if DO_PRINT_DEBUG_UP_0
+       std::cout << "Doing 'while' loop:\n" <<
+         "t_n_up_down_ndx    = " << t_n_up_down_ndx << "\n" <<
+         "d_time_count       = " << d_time_count << "\n" <<
+         "d_max_memory       = " << d_max_memory << "\n" <<
+         "t_in_buf_ndx       = " << t_in_buf_ndx << "\n" <<
+         "t_ninput_items     = " << t_ninput_items << "\n";
+#endif
+// use the "from" states, loop over all inputs and compute the metric for
+// each & store it in the "to" state at the end of the connection.
+// no need to compare metrics yet, since none join into any given state
+
+#if 0
+// reset the "to" state's metrics
+// probably don't need to do this; try removing later
+        reset_metrics (d_states_ndx ^ 1);
+#if DO_PRINT_DEBUG_UP
+       std::cout << "Reset Metrics\n";
+#endif
+#endif
+
+// reset the state's index for each set of new inputs
+       size_t* t_state_ndx_ptr = d_up_term_states_ndx[d_up_term_ndx];
+       size_t* t_next_state_ndx_ptr = d_up_term_states_ndx[d_up_term_ndx ^ 1];
+// loop over all current stored "up" states
+       for (size_t n = 0; n < t_n_up_down_ndx; n++) {
+         size_t t_state_ndx = *t_state_ndx_ptr++;
+// get a pointer to this state's structure
+         state_t_ptr t_state = &(d_states[d_states_ndx][t_state_ndx]);
+// get the connections for all inputs
+         connection_t_ptr t_connection = t_state->d_connections;
+#if DO_PRINT_DEBUG_UP_0
+         std::cout << "Looping over all 'up' states:\n" <<
+           "n                  = " << n << "\n" <<
+           "t_n_up_down_ndx    = " << t_n_up_down_ndx << "\n" <<
+           "d_states_ndx       = " << d_states_ndx << "\n" <<
+           "t_state_ndx        = " << t_state_ndx << "\n" <<
+           "d_n_input_combs    = " << d_n_input_combinations << "\n" <<
+           "t_state            = " << t_state << "\n" <<
+           "t_connection       = " << t_connection << "\n";
+#endif
+// loop over all possible input values, 1 bit per input stream
+         for (size_t q = 0; q < d_n_input_combinations; q++, t_connection++) {
+// find the "to" state for this connection
+           state_t_ptr t_to_state = t_connection->d_to;
+// get the output bits for this connection
+           float* t_output_bit = t_connection->d_output_bits;
+// start with this state's metric
+           float t_metric = t_state->d_max_metric;
+#if DO_PRINT_DEBUG_UP_0
+           std::cout <<
+             "to state index     = " << t_connection->d_to_ndx << "\n" <<
+             "current metric     = " << t_metric << "\n";
+#endif
+           if (d_do_mux_inputs == true) {
+// if using mux'ed input streams, handle differently
+              const float* t_in_buf = &(in_buf[0][t_in_buf_ndx]);
+// loop over all encoder-output values
+             for (size_t r = d_n_code_outputs; r > 0; r--) {
+#if DO_PRINT_DEBUG_UP
+               std::cout << "in_sym = " << *t_in_buf << ", code_out_bit = " <<
+                 *t_output_bit << " ==> metric -> ";
+#endif
+               t_metric += ((*t_in_buf++) * (*t_output_bit++));
+#if DO_PRINT_DEBUG_UP
+               std::cout << t_metric << "\n";
+#endif
+             }
+           } else {
+// loop over all encoder-output values
+             for (size_t r = 0; r < d_n_code_outputs; r++) {
+#if DO_PRINT_DEBUG_UP
+               std::cout << "in_sym = " << in_buf[r][t_in_buf_ndx] <<
+                 ", code_out_bit = " << *t_output_bit << " ==> metric -> ";
+#endif
+               t_metric += (in_buf[r][t_in_buf_ndx] * (*t_output_bit++));
+#if DO_PRINT_DEBUG_UP
+               std::cout << t_metric << "\n";
+#endif
+             }
+           }
+           // get the "to" state index
+
+           size_t t_to_ndx = t_connection->d_to_ndx;
+
+           // store the metric in the "to" state; should not have
+           // been used before
+
+           t_to_state->d_max_metric = t_metric;
+
+           // add the "to" state index to the "up" state list
+
+           *t_next_state_ndx_ptr++ = t_to_ndx;
+
+           // update the traceback structure
+
+           update_traceback__up (t_state, t_to_state, q);
+
+           // next (for) input value
+         }
+
+         // next (for) "up_term" state
+       }
+
+       // increment the input buffer indices
+
+       increment_input_indices (false);
+
+       // increment the time counter
+
+        d_time_count++;
+
+       // change which up-term index to use
+
+        d_up_term_ndx ^= 1;
+
+       // increase the number of states to be used
+
+        t_n_up_down_ndx <<= d_n_code_inputs;
+
+       // change which d_states' index to use as starting
+
+        d_states_ndx ^= 1;
+
+       // next (while) input
+      }
+
+      // if reached the end of doing the "up" part of the trellis,
+      // switch states into the middle
+
+      if (d_time_count == d_max_memory) {
+       if (DO_PRINT_DEBUG_FSM) {
+         std::cout << "Setting FSM to fsm_dec_doing_middle\n";
+       }
+        d_fsm = fsm_dec_doing_middle;
+      }
+      if (DO_PRINT_DEBUG_FSM) {
+       std::cout << "Exited fsm_dec_doing_up\n";
+      }
+      break;
+
+    case (fsm_dec_doing_middle):
+      if (DO_PRINT_DEBUG_FSM) {
+       std::cout << "Entered fsm_dec_doing_middle\n";
+      }
+
+      // stay in this state until a full block (+ optional
+      // termination) of input metrics is reached, or until there are
+      // no more input metrics to parse
+
+      while ((d_time_count < d_block_size_bits) &
+            (t_in_buf_ndx < t_ninput_items)) {
+
+       // use all states, loop over all inputs, compute the metric
+       // for each; compare the current metric with all previous
+       // stored metric in the endpoint of the connection to find the
+       // highest one.
+
+       // reset the "to" state's metrics
+
+        reset_metrics (d_states_ndx ^ 1);
+
+       // get the state's index for each set of new inputs
+
+       state_t_ptr t_state = d_states[d_states_ndx];
+
+       if (DO_PRINT_DEBUG_MIDDLE) {
+         std::cout << "Time Count " << (d_time_count+1) << " of " <<
+           d_block_size_bits << "\nd_states_ndx = " << d_states_ndx << "\n";
+       }
+
+       // loop over all current states
+
+       for (size_t n = 0; n < d_n_states; n++, t_state++) {
+
+         // loop over all possible input values, 1 bit per input stream
+
+         connection_t_ptr t_connection = t_state->d_connections;
+
+         if (DO_PRINT_DEBUG_MIDDLE_0) {
+           std::cout << "Looping over all 'middle' states: " <<
+             n << " of " << d_n_states << "\n";
+         }
+
+         for (size_t q = 0; q < d_n_input_combinations; q++, t_connection++) {
+
+           if (DO_PRINT_DEBUG_MIDDLE_0) {
+             std::cout << "Input = " << n2bs(q, d_n_code_inputs+1) << "\n";
+           }
+
+           // start with this state's metric
+
+           float t_metric = t_state->d_max_metric;
+
+           // get the "to" state
+
+            state_t_ptr t_to_state = t_connection->d_to;
+
+           // get that state's metric
+
+            float t_to_metric = t_to_state->d_max_metric;
+
+           // see if the computation is even needed;
+           // maximum change is d_n_code_outputs if all bits match exactly
+
+            if ((t_to_metric - t_metric) > ((float) 2*d_n_code_outputs)) {
+             if (DO_PRINT_DEBUG_MIDDLE_0) {
+               std::cout << "!not computing metric!\n";
+             }
+              continue;
+           }
+
+           // metrics are close enough; do the computation and the
+           // compare get the output bits for this connection
+
+           float* t_output_bit = t_connection->d_output_bits;
+           if (d_do_mux_inputs == true) {
+
+             // if using mux'ed input streams, handle differently
+
+              const float* t_in_buf = &(in_buf[0][t_in_buf_ndx]);
+
+             // loop over all encoder-output values
+
+             for (size_t r = d_n_code_outputs; r > 0; r--) {
+#if DO_PRINT_DEBUG_MIDDLE_0
+               std::cout << "in_sym = " << *t_in_buf << ", code_out_bit = " <<
+                 *t_output_bit << " ==> metric -> ";
+#endif
+               t_metric += ((*t_in_buf++) * (*t_output_bit++));
+#if DO_PRINT_DEBUG_MIDDLE_0
+               std::cout << t_metric << "\n";
+#endif
+             }
+           } else {
+// loop over all encoder-output values
+             for (size_t r = 0; r < d_n_code_outputs; r++) {
+#if DO_PRINT_DEBUG_MIDDLE_0
+               std::cout << "in_sym = " << in_buf[r][t_in_buf_ndx] <<
+                 ", code_out_bit = " << *t_output_bit << " ==> metric -> ";
+#endif
+               t_metric += (in_buf[r][t_in_buf_ndx] * (*t_output_bit++));
+#if DO_PRINT_DEBUG_MIDDLE_0
+               std::cout << t_metric << "\n";
+#endif
+             }
+           }
+// done with this input value; compare old and new metrics
+            if (t_metric > t_to_metric) {
+#if DO_PRINT_DEBUG_MIDDLE
+             std::cout << "New Metric to s[" <<
+               n2bs (t_connection->d_to_ndx,t_state_print_bits) << "]: ";
+             if (t_to_state->d_max_metric == -1e10) {
+               std::cout << "setting to ";
+             } else {
+               std::cout << "was s[" <<
+                 n2bs(t_to_state->d_max_state_ndx,t_state_print_bits) <<
+                 "]i[" << n2bs (t_to_state->d_max_input, d_n_code_inputs+1) <<
+                 "]@ " << t_to_state->d_max_metric << "  now ";
+             }
+             std::cout << "s[" << n2bs(n,t_state_print_bits) << "] i[" <<
+               n2bs (q, d_n_code_inputs+1) << "]@ " << t_metric << "\n";
+#endif
+// new metric is better; copy that info into the "to" state
+              t_to_state->d_max_metric = t_metric;
+              t_to_state->d_max_state_ndx = n;
+              t_to_state->d_max_input = q;
+            }
+           // next (for) input value
+         }
+         // next (for) state
+       }
+
+       // done with all states and all inputs;
+       // update the traceback buffers
+
+       update_traceback__middle ();
+
+       // increment the input buffer indices
+
+       increment_input_indices ();
+
+       // increment the time counter
+
+        d_time_count++;
+
+       // check (while) staying in this fsm state or not
+      }
+
+      if ((d_block_size_bits != 0) &
+          (d_time_count == d_block_size_bits)) {
+       if (DO_PRINT_DEBUG_FSM) {
+         std::cout << "Setting FSM to fsm_dec_doing_term\n";
+       }
+        d_fsm = fsm_dec_doing_term;
+      }
+      if (DO_PRINT_DEBUG_FSM) {
+       std::cout << "Exited fsm_dec_doing_middle\n";
+      }
+      break;
+
+    case (fsm_dec_doing_term):
+      if (DO_PRINT_DEBUG_FSM) {
+       std::cout << "Entered fsm_dec_doing_term\n";
+      }
+
+      // set the "next" up_down index to the end of their states
+
+      size_t t_time_count = d_max_memory - (d_time_count - d_block_size_bits);
+      t_n_up_down_ndx = 1 << (d_n_code_inputs * t_time_count);
+
+      // stay in this state until the correct number of input metrics
+      // are reached; exit if we run out of input metrics to process
+
+      while ((t_time_count > 0) &
+            (t_in_buf_ndx < t_ninput_items)) {
+
+       if (DO_PRINT_DEBUG_TERM) {
+         std::cout << "Doing time " << (d_max_memory - t_time_count + 1) <<
+           " of " << d_max_memory << "; starting buf[" << t_in_buf_ndx <<
+           "] of [" << t_ninput_items << "]\n";
+       }
+
+       // FIXME: loop over just the "0" inputs
+
+       // use the "to" states, and compute the metric for each,
+       // compare & store it in the "to" state at the end of the
+       // connection.
+
+       // reset the "to" state's metrics
+
+        reset_metrics (d_states_ndx ^ 1);
+
+       // reset the state's index for each set of new inputs
+
+       size_t* t_state_ndx_ptr = d_up_term_states_ndx[d_up_term_ndx];
+       size_t* t_next_state_ndx_ptr = d_up_term_states_ndx[d_up_term_ndx ^ 1];
+
+       // loop over all current stored "term" state indeces
+
+       for (size_t n = 0; n < t_n_up_down_ndx; n++) {
+         size_t t_state_ndx = *t_state_ndx_ptr++;
+         state_t_ptr t_state = &(d_states[d_states_ndx][t_state_ndx]);
+
+         // loop over just the all 0 input value (d_connections[0])
+
+         connection_t_ptr t_connection = t_state->d_connections;
+
+         // get the "to" state
+
+          state_t_ptr t_to_state = t_connection->d_to;
+
+         // start with this state's metric
+
+          float t_metric = t_state->d_max_metric;
+
+         // get that state's metric
+
+          float t_to_metric = t_to_state->d_max_metric;
+
+         if (DO_PRINT_DEBUG_TERM) {
+           std::cout << "Term state " << (n+1) << " of " <<
+             t_n_up_down_ndx << "; using d_s[" << d_states_ndx << "][" <<
+             n2bs(t_state_ndx,t_state_print_bits) << "]\n";
+         }
+
+         // see if the computation is even needed;
+         // maximum change is d_n_code_outputs if all bits match exactly
+
+          if ((t_to_metric - t_metric) > ((float) 2*d_n_code_outputs)) {
+           if (DO_PRINT_DEBUG_TERM) {
+             std::cout << "!not computing metric!\n";
+           }
+           continue;
+         }
+
+         // metrics are close enough; do the computation and the
+         // compare get the output bits for this connection
+
+          float* t_output_bit = t_connection->d_output_bits;
+         if (d_do_mux_inputs == true) {
+// if using mux'ed input streams, handle differently
+            const float* t_in_buf = &(in_buf[0][t_in_buf_ndx]);
+// loop over all encoder-output values
+           for (size_t r = d_n_code_outputs; r > 0; r--) {
+             t_metric += ((*t_in_buf++) * (*t_output_bit++));
+           }
+         } else {
+// loop over all encoder-output values
+           for (size_t r = 0; r < d_n_code_outputs; r++) {
+              t_metric += (in_buf[r][t_in_buf_ndx] * (*t_output_bit++));
+           }
+         }
+// done with this input value; compare old and new metrics
+// see if it's the best metric
+          if (t_metric > t_to_metric) {
+#if DO_PRINT_DEBUG_TERM
+           std::cout << "New Metric to s[" <<
+             n2bs (t_connection->d_to_ndx,t_state_print_bits) << "]: ";
+           if (t_to_state->d_max_metric == -1e10) {
+             std::cout << "setting to ";
+           } else {
+             std::cout << "was s[" <<
+               n2bs(t_to_state->d_max_state_ndx,t_state_print_bits) <<
+               "]i[" << n2bs (t_to_state->d_max_input, d_n_code_inputs+1) <<
+               "]@ " << t_to_state->d_max_metric << "  now ";
+           }
+           std::cout << "s[" << n2bs(t_state_ndx,t_state_print_bits) <<
+             "] i[" << n2bs (0, d_n_code_inputs+1) << "]@ " << t_metric << "\n";
+#endif
+            t_to_state->d_max_metric = t_metric;
+            t_to_state->d_max_state_ndx = t_state_ndx;
+            t_to_state->d_max_input = 0;
+         }
+// add the "to" state's index to the "next" set of state's indices list
+          *t_next_state_ndx_ptr++ = t_connection->d_to_ndx;
+// finished (for) this state
+       }
+
+       // update the traceback buffers
+
+       update_traceback__term ();
+       increment_input_indices (false);
+
+       // increment the time counters
+
+        t_time_count--;
+        d_time_count++;
+
+       // finished (while) staying in this fsm state or not
+
+      }
+
+      if (t_time_count == 0) {
+       // finished this trellis, now move as much of the decoded
+       // input to the output buffer as possible
+       if (DO_PRINT_DEBUG_FSM) {
+         std::cout << "Setting FSM to fsm_dec_output\n";
+       }
+       d_fsm = fsm_dec_output;
+      }
+      if (DO_PRINT_DEBUG_FSM) {
+       std::cout << "Exited fsm_dec_doing_term\n";
+      }
+      break;
+
+    case (fsm_dec_output):
+      if (DO_PRINT_DEBUG_FSM) {
+       std::cout << "Entered fsm_dec_output.\n";
+      }
+
+      // this is done in reverse bit order (last time to first time)
+      // using the traceback structure in d_out_buf, starting with the
+      // maximum valued one in the last time slot, then using the
+      // traceback's "d_prev" link to trace the trellis back
+
+      // see where the output data will terminate
+
+      int t_next_out_buf_ndx = (t_out_buf_ndx +
+                               (d_block_size_bits / g_num_bits_per_byte));
+      int t_next_out_bit_shift = (t_out_bit_shift +
+                                 (d_block_size_bits % g_num_bits_per_byte));
+      if (t_next_out_bit_shift >= g_num_bits_per_byte) {
+       t_next_out_bit_shift -= g_num_bits_per_byte;
+       t_next_out_buf_ndx++;
+      }
+#if DO_PRINT_DEBUG_OUTPUT
+      std::cout << "First bit in at out[][" << t_out_buf_ndx << "].[" <<
+       t_out_bit_shift << "] -> " << d_block_size_bits << " bits == " <<
+       (d_block_size_bits / g_num_bits_per_byte) << " Byte" <<
+       ((d_block_size_bits / g_num_bits_per_byte) != 1 ? "s" : "") <<
+       " + " << (d_block_size_bits % g_num_bits_per_byte) << " bit" <<
+       ((d_block_size_bits % g_num_bits_per_byte) != 1 ? "s" : "") <<
+       "\nNext set of bits start at out[][" << t_next_out_buf_ndx <<
+       "].[" << t_next_out_bit_shift << "]\n";
+#endif
+// find the starting traceback structure
+      traceback_t_ptr t_out_buf;
+      if (d_do_termination == true) {
+// FIXME: assume termination state == 0
+#if DO_PRINT_DEBUG_OUTPUT_0
+       std::cout << "Using termination; going through trellis for " <<
+         d_max_memory << " bit" <<
+         ((d_max_memory != 1) ? "s" : "") << "\n";
+#endif
+       t_out_buf = &(d_out_buf[d_time_count][0]);
+#if DO_PRINT_DEBUG_OUTPUT_0
+       std::cout << "Starting traceback ptr " << t_out_buf << "\n";
+#endif
+// skip over the termination bits
+       for (size_t n = d_max_memory; n > 0; n--) {
+         t_out_buf = t_out_buf->d_prev;
+#if DO_PRINT_DEBUG_OUTPUT_0
+         std::cout << "Next traceback ptr " << t_out_buf << "\n";
+#endif
+       }
+      } else {
+// no termination but doing block coding;
+// FIXME: use the state with the bext metric
+// get the state's index for each set of new inputs
+       state_t_ptr t_state = d_states[d_states_ndx];
+       float t_max_metric = t_state->d_max_metric;
+       size_t t_max_state_ndx = 0;
+       t_state++;
+// loop over all current states
+       for (size_t n = 1; n < d_n_states; n++, t_state++) {
+// start with this state's metric
+         float t_metric = t_state->d_max_metric;
+// compare with current max
+         if (t_metric > t_max_metric) {
+           t_max_metric = t_metric;
+           t_max_state_ndx = n;
+         }
+       }
+// get the correct out_buf reference to start with
+       t_out_buf = &(d_out_buf[d_time_count][t_max_state_ndx]);
+      }
+#if DO_PRINT_DEBUG_OUTPUT
+      std::cout << "Found starting traceback ptr " << t_out_buf <<
+       "; getting all " << d_block_size_bits << " bits per stream.\n";
+#endif
+// now we've got the starting traceback structure address;
+// check to make sure there is enough space in each output buffer
+      size_t t_block_bit_ndx = d_block_size_bits;
+      if ((t_next_out_buf_ndx > t_noutput_bytes) |
+         ((t_next_out_buf_ndx == t_noutput_bytes) &
+          (t_next_out_bit_shift != 0))) {
+// not enough space for all output bits;
+// find the number of extra bits to save
+       size_t t_save_buf_ndx = t_next_out_buf_ndx - t_noutput_bytes;
+       size_t t_n_extra_bits = ((t_save_buf_ndx * g_num_bits_per_byte) +
+                                t_next_out_bit_shift);
+// set the number of saved bits
+       d_n_saved_bits = t_n_extra_bits;
+// remove the extra bits from the number to copy to the output buffer
+       t_block_bit_ndx -= t_n_extra_bits;
+// find the actual output buf index, once we get there
+       t_next_out_buf_ndx -= t_save_buf_ndx;
+#if DO_PRINT_DEBUG_OUTPUT
+       std::cout << "Not enough output buffer space:\n" <<
+         "len (o_b) = " << t_noutput_bytes << " ==> " <<
+         t_n_extra_bits << " extra bit" <<
+         (t_n_extra_bits != 1 ? "s" : "") << " == " <<
+         t_save_buf_ndx << " Byte" <<
+         (t_save_buf_ndx != 1 ? "s" : "") << ", " <<
+         t_next_out_bit_shift << " bit" <<
+         (t_next_out_bit_shift != 1 ? "s" : "") << "\n";
+#endif
+// zero each output buffers' bytes
+       size_t t_n_zero = t_save_buf_ndx + (t_next_out_bit_shift ? 1 : 0);
+#if DO_PRINT_DEBUG_OUTPUT
+       size_t t_n_out_bytes = ((d_block_size_bits / g_num_bits_per_byte) +
+                               ((d_block_size_bits % g_num_bits_per_byte) ? 1 : 0));
+       std::cout << "Zeroing save buffer from for " << t_n_zero <<
+         " Byte" << (t_n_zero != 1 ? "s" : "") << " (of " <<
+         d_block_size_bits << " bit" <<
+         (d_block_size_bits != 1 ? "s" : "") << " == " << t_n_out_bytes <<
+         " Byte" << (t_n_out_bytes != 1 ? "s" : "") << ")\n";
+#endif
+       for (size_t m = 0; m < d_n_code_inputs; m++)
+         bzero (d_save_buffer[m], t_n_zero);
+// loop over all extra bits
+       for (size_t n = t_n_extra_bits; n > 0; n--) {
+// first decrement the output bit & byte as necessary
+         if (--t_next_out_bit_shift < 0) {
+           t_next_out_bit_shift += g_num_bits_per_byte;
+           t_save_buf_ndx--;
+         }
+// get the encoder inputs to output
+         size_t t_inputs = t_out_buf->d_inputs;
+// loop over all code inputs (decoder-outputs), 1 bit per stream
+         for (size_t m = 0; m < d_n_code_inputs; m++) {
+           d_save_buffer[m][t_save_buf_ndx] |=
+             ((t_inputs & 1) << t_next_out_bit_shift);
+           t_inputs >>= 1;
+         }
+         t_out_buf = t_out_buf->d_prev;
+#if DO_PRINT_DEBUG_OUTPUT_0
+         std::cout << "Next traceback ptr " << t_out_buf << "\n";
+#endif
+       }
+// at exit, "t_out_buf_ndx" should be == t_noutput_bytes, and
+// "t_out_bit_shift" should be 0; check these!
+#if DO_PRINT_DEBUG_OUTPUT
+       std::cout << "n_o_b_ndx (" << t_next_out_buf_ndx << ") ?=? " <<
+         "#o_B (" << t_noutput_bytes << ") & t_o_b_sh (" <<
+         t_next_out_bit_shift << ") ?=? 0\n";
+       assert (t_next_out_buf_ndx == t_noutput_bytes);
+       assert (t_next_out_bit_shift == 0);
+#endif
+      }
+// set the correct output buffer index and bit shift
+      t_out_bit_shift = t_next_out_bit_shift;
+      t_out_buf_ndx = t_next_out_buf_ndx;
+// copy any remaining bits looping backwards in bit-time
+// through the traceback trellis
+      for (size_t n = t_block_bit_ndx; n > 0; n--) {
+// first decrement the output bit & byte as necessary
+       if (--t_out_bit_shift < 0) {
+         t_out_bit_shift += g_num_bits_per_byte;
+         t_out_buf_ndx--;
+       }
+// get the encoder inputs to output
+       size_t t_inputs = t_out_buf->d_inputs;
+// loop over all code inputs (decoder-outputs), 1 bit per stream
+       for (size_t m = 0; m < d_n_code_inputs; m++) {
+         out_buf[m][t_out_buf_ndx] |= ((t_inputs & 1) << t_out_bit_shift);
+         t_inputs >>= 1;
+       }
+       t_out_buf = t_out_buf->d_prev;
+#if DO_PRINT_DEBUG_OUTPUT_0
+       std::cout << "Next traceback ptr " << t_out_buf << "\n";
+#endif
+      }
+// set the next output byte and bit-shift
+      t_out_bit_shift = t_next_out_bit_shift;
+      t_out_buf_ndx = t_next_out_buf_ndx;
+#if DO_PRINT_DEBUG_FSM
+      std::cout << "Set FSM to fsm_dec_init\n";
+#endif
+      d_fsm = fsm_dec_init;
+#if DO_PRINT_DEBUG_FSM
+      std::cout << "Exited fsm_dec_output\n";
+#endif
+      break;
+    case (fsm_dec_init):
+#if DO_PRINT_DEBUG_FSM
+      std::cout << "Entered fsm_dec_init\n";
+#endif
+// this is called immediately (first input bit upon startup),
+// or after termination of a trellis.
+
+// reset states to the 0'th one
+      d_up_term_ndx = d_states_ndx = 0;
+// zero the metrics for those states
+      zero_metrics (0);
+#if 0
+// might not need to do this; check and see after it works
+// reset up_term states and number so that there is 1 item, the "0" state.
+      bzero (d_up_term_states_ndx[0], sizeof (size_t) * d_n_states);
+      bzero (d_up_term_states_ndx[1], sizeof (size_t) * d_n_states);
+#else
+      d_up_term_states_ndx[0][0] = 0;
+#endif
+// reset time count back to the start
+      d_time_count = 0;
+#if 0
+// reset the traceback structures
+// might not need to do this; check and see after it works
+      traceback_t_hdl t_out_bufs = d_out_buf;
+      for (size_t n = d_n_traceback_els; n > 0; n--) {
+       traceback_t_ptr t_out_buf = (*t_out_bufs++);
+       for (size_t m = d_n_states; m > 0; m--, t_out_buf++) {
+         t_out_buf->d_prev = NULL;
+         t_out_buf->d_inputs = -1;
+       }
+      }
+#endif
+// set the fsm to "doing up"
+#if DO_PRINT_DEBUG_FSM
+      std::cout << "Set FSM to fsm_dec_doing_up\n";
+#endif
+      d_fsm = fsm_dec_doing_up;
+#if DO_PRINT_DEBUG_FSM
+      std::cout << "Exited fsm_dec_init\n";
+#endif
+      break;
+// should never get here!
+    default:
+      assert (0);
+// done (switch) with FSM
+    }
+// done (while) there are inputs
+  }
+
+// consume all of the input items on all input streams
+// "ninput_items[]" doesn't seem to be reliable,
+// so compute this from the actual number of blocks processed
+#if DO_PRINT_DEBUG_EXIT
+  std::cout << "Exiting FSM in state: " <<
+    (d_fsm == fsm_dec_init ? "init" :
+     (d_fsm == fsm_dec_doing_up ? "up" :
+      (d_fsm == fsm_dec_doing_middle ? "middle" :
+       (d_fsm == fsm_dec_doing_term ? "term" :
+       (d_fsm == fsm_dec_output ? "output" : "unknown"))))) << "\n" <<
+    "Consuming " << t_in_buf_ndx <<
+    " input items on each input stream (of " << t_ninput_items << ").\n";
+#endif
+  consume_each (t_in_buf_ndx);
+
+// make sure the number of output items makes sense
+// t_out_buf_ndx always points to the current index
+// t_out_bit_shift always points to the next bit position to be written
+  int t_leftover_bytes = t_out_buf_ndx % d_out_stream_el_size_bytes;
+  int t_leftover_bits = ((t_leftover_bytes * g_num_bits_per_byte) +
+                        t_out_bit_shift);
+  int t_noutput_items = noutput_items;
+#if DO_PRINT_DEBUG_EXIT
+  std::cout << "Final o_b[" << t_out_buf_ndx << "][" <<
+    t_out_bit_shift << "] of " << t_noutput_bytes <<
+    ", el_size = " << d_out_stream_el_size_bytes <<
+    ", lo_Bytes = " << t_leftover_bytes <<
+    ", t_lo_bits = " << t_leftover_bits << "\n" <<
+    "Desired # output items = " << noutput_items << "\n";
+#endif
+  if (t_leftover_bits != 0) {
+    // should never get here!
+#if 1
+    assert (0);
+#else
+    int t_ndx = t_out_buf_ndx - t_leftover_bytes;
+    size_t t_n_copy = t_leftover_bytes + ((t_out_bit_shift != 0) ? 1 : 0);
+    assert (t_n_copy <= d_out_stream_el_size_bytes);
+// copy the leftover into the save buffer
+    for (size_t n = 0; n < d_n_code_inputs; n++) {
+      bcopy (&(out_buf[n][t_ndx]), d_save_buffer[n], t_n_copy);
+    }
+    t_noutput_items = t_ndx / d_out_stream_el_size_bytes;
+    d_n_saved_bits = t_leftover_bits;
+#if DO_PRINT_DEBUG_EXIT
+    std::cout << "Copied " << t_n_copy << " Byte" <<
+      (t_n_copy != 1 ? "s" : "") << " from o_b[][" << t_ndx <<
+      "] into each save buffer.\n" <<
+      "Actual #output items = " << t_noutput_items <<
+      ", # saved bit(s) = " << d_n_saved_bits << "\n";
+#endif
+#endif
+  }
+
+#endif
+
+#if DO_TIME_THOUGHPUT
+  u_long d_t = end_timer (&t_tp);
+
+  std::cout << "decoder_viterbi_full_block: Completed " << t_ninput_items <<
+    " bits in " << d_t << " usec => " <<
+    1e6*(((double)(t_ninput_items))/((double) d_t)) <<
+    " b/s\n";
+#endif
+}
diff --git a/gr-error-correcting-codes/src/lib/libecc/decoder_viterbi_full_block.h b/gr-error-correcting-codes/src/lib/libecc/decoder_viterbi_full_block.h
new file mode 100644 (file)
index 0000000..531b7a6
--- /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 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.
+ */
+
+#ifndef INCLUDED_DECODER_VITERBI_FULL_BLOCK_H
+#define INCLUDED_DECODER_VITERBI_FULL_BLOCK_H
+
+#include "decoder_viterbi.h"
+
+class decoder_viterbi_full_block : public decoder_viterbi
+{
+/*!
+ * \brief Decode the incoming streams using a Viterbi-style decoder,
+ *     doing full trellis block decoding before putting out
+ *     any bits
+ *
+ * input: streams of metrics, two per code output: one for the 0-bit
+ *     metrics and the other for the 1-bit metric.
+ *
+ * output: stream(s) of output bits
+ */
+
+public:
+  decoder_viterbi_full_block (int sample_precision,
+                             encoder_convolutional* l_encoder);
+
+  virtual ~decoder_viterbi_full_block ();
+
+protected:
+  virtual void decode_private (const char** in_buf, char** out_buf);
+  virtual void update_traceback__up (size_t from_state_ndx,
+                                    size_t to_state_ndx,
+                                    size_t l_input);
+  virtual void update_traceback__middle ();
+  virtual void update_traceback__term ();
+
+/*
+ * traceback_t: used to store all encode-input bits for
+ *     all possible paths, when computing all trellis bits before
+ *     determining the ML decode-output sequence.
+ *
+ * d_prev: the connection to the previous bit's traceback structure
+ *
+ * d_inputs: the inputs (one per bit) for this connection
+ */
+
+  typedef struct traceback_t {
+    struct traceback_t *d_prev;
+    int d_inputs;
+  } traceback_t, *traceback_t_ptr, **traceback_t_hdl;
+
+/*
+ * d_n_total_inputs_per_stream: how many bits to store for each
+ *     state to determine the best decoder-output (encoder-input) bits 
+ */
+  size_t d_n_inputs_per_stream;
+  traceback_t_hdl d_out_buf;
+};
+
+#endif /* INCLUDED_DECODER_VITERBI_FULL_BLOCK_H */
diff --git a/gr-error-correcting-codes/src/lib/libecc/decoder_viterbi_full_block_i1_ic1.cc b/gr-error-correcting-codes/src/lib/libecc/decoder_viterbi_full_block_i1_ic1.cc
new file mode 100644 (file)
index 0000000..b0fc4f3
--- /dev/null
@@ -0,0 +1,162 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "decoder_viterbi_full_block_i1_ic1.h"
+#include <assert.h>
+#include <iostream>
+#include <math.h>
+
+const int g_max_block_size_bits = 10000000;
+const int g_max_num_streams = 10;
+const int g_num_bits_per_byte = 8;
+
+#define DO_TIME_THOUGHPUT 0
+
+#define DO_PRINT_DEBUG_INST 0
+#define DO_PRINT_DEBUG_FSM 0
+#define DO_PRINT_DEBUG_INIT 0
+#define DO_PRINT_DEBUG_UP 0
+#define DO_PRINT_DEBUG_UP_0 0
+#define DO_PRINT_DEBUG_UP_1 0
+#define DO_PRINT_DEBUG_MIDDLE 0
+#define DO_PRINT_DEBUG_MIDDLE_0 0
+#define DO_PRINT_DEBUG_MIDDLE_1 0
+#define DO_PRINT_DEBUG_TERM 0
+#define DO_PRINT_DEBUG_TERM_1 0
+#define DO_PRINT_DEBUG_OUTPUT 0
+#define DO_PRINT_DEBUG_OUTPUT_0 0
+#define DO_PRINT_DEBUG_EXIT 0
+#define DO_PRINT_DEBUG 1
+
+#if DO_TIME_THOUGHPUT
+#include <mld/mld_timer.h>
+#endif
+#if DO_PRINT_DEBUG
+#include <mld/n2bs.h>
+#endif
+
+// FIXME
+
+size_t
+decoder_viterbi_full_block_i1_ic1::compute_n_output_bits
+(size_t n_input_items)
+{
+  assert (0);
+  return (0);
+}
+
+/*
+ * Compute the number of input items (metrics) needed to produce
+ * 'noutput' bits.  For convolutional decoders, there is 1
+ * bit output per metric input per stream, with the addition of a some
+ * metrics for trellis termination if selected.  Without termination,
+ * there is exactly 1:1 input to output (1 metric in to 1 bit out),
+ * no matter the encoding type.
+ *
+ * if (not terminating), then get the number of output bits.
+ *
+ * otherwise, find the number of blocks (not necessarily an integer),
+ * and then compute the number of input metrics (including termination)
+ * required to produce those blocks.  Subtract the number of bits
+ * leftover from the previous computation, then find the number of input
+ * metrics, ceil'd to make sure there are enough.
+ */
+
+size_t
+decoder_viterbi_full_block_i1_ic1::compute_n_input_metrics
+(size_t n_output_bits)
+{
+  int t_ninput_items = 0;
+  int t_noutput_bits = ((int) n_output_bits) - ((int) d_n_saved_bits);
+
+  // if there are enough saved bits, just use those, no inputs required
+
+  if (t_noutput_bits <= 0)
+    return (0);
+
+  // remove any bits already in the decoding trellis
+
+  if (d_time_count != 0) {
+    int t_time_bits = ((d_time_count > d_block_size_bits) ? 0 :
+                      d_block_size_bits - d_time_count);
+    t_noutput_bits -= t_time_bits;
+    t_ninput_items += t_time_bits;
+  }
+  // if completing this trellis doesn't create enough outputs ...
+
+  if (t_noutput_bits > 0) {
+
+    // there is a 1:1 ratio between input symbols and output bits (per
+    // stream), except for termination bits which are already taken
+    // into account in the total # of input bits per stream class
+    // variable; need to round the # output bits to the
+
+    // find the number of blocks, ceil'd to the next higher integer
+
+    int t_nblocks = (int) ceilf (((float) t_noutput_bits) /
+                                ((float) d_block_size_bits));
+
+    // find the number of required input bits
+
+    t_ninput_items += t_nblocks * d_n_total_inputs_per_stream;
+  }
+
+  return (t_ninput_items);
+}
+
+// FIXME, from here down dummies to get correct compiling; for testing
+// purposes only.
+
+void
+decoder_viterbi_full_block_i1_ic1::increment_input_indices
+(bool while_decoding)
+{
+  if (while_decoding)
+    std::cout << "foo!";
+
+#if 0
+// increment the in_buf index, depending on mux'ing or not
+  t_in_buf_ndx += (d_do_mux_inputs == false) ? 1 : d_n_code_outputs;
+#endif
+}
+
+void
+decoder_viterbi_full_block_i1_ic1::increment_output_indices
+(bool while_decoding)
+{
+  if (while_decoding)
+    std::cout << "bar!";
+}
+
+void
+decoder_viterbi_full_block_i1_ic1::output_bit
+(char t_out_bit,
+ char** out_buf,
+ size_t t_output_stream)
+{
+  if (t_out_bit)
+    std::cout << "mop!";
+}
diff --git a/gr-error-correcting-codes/src/lib/libecc/decoder_viterbi_full_block_i1_ic1.h b/gr-error-correcting-codes/src/lib/libecc/decoder_viterbi_full_block_i1_ic1.h
new file mode 100644 (file)
index 0000000..a7afeb3
--- /dev/null
@@ -0,0 +1,66 @@
+/* -*- 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 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.
+ */
+
+#ifndef INCLUDED_DECODER_VITERBI_FULL_BLOCK_IC1_H
+#define INCLUDED_DECODER_VITERBI_FULL_BLOCK_IC1_H
+
+#include "decoder_viterbi_full_block.h"
+
+class decoder_viterbi_full_block_i1_ic1 : public decoder_viterbi_full_block
+{
+/*!
+ * class decoder_viterbi_full_block_i1_ic1 :
+ *     public decoder_viterbi_full_block
+ *
+ * Decode the incoming metrics using a Viterbi-style decoder, doing
+ *     full trellis block decoding before putting out any bits
+ *
+ * input is "i1": one stream per input (as defined by the
+ *     code-output), with one metric per input item.
+ *
+ * output is "ic1": streams of char, one stream per output (as defined
+ *     by the code-input), using only the right-most justified (LSB?)
+ *     bit as the single output bit per output item.
+ *
+ * The rest of the options are outlined in the inherited classes'
+ *     header files.
+ */
+
+public:
+  inline decoder_viterbi_full_block_i1_ic1
+  (int sample_precision,
+   encoder_convolutional* l_encoder)
+    : decoder_viterbi_full_block (sample_precision, l_encoder) {};
+
+  virtual ~decoder_viterbi_full_block_i1_ic1 () {};
+
+  virtual size_t compute_n_input_metrics (size_t n_output_bits);
+  virtual size_t compute_n_output_bits (size_t n_input_metrics);
+
+protected:
+  virtual void increment_input_indices (bool while_decoding);
+  virtual void output_bit (char t_out_bit, char** out_buf,
+                          size_t t_output_stream);
+  virtual void increment_output_indices (bool while_decoding);
+};
+
+#endif /* INCLUDED_DECODER_VITERBI_FULL_BLOCK_I1_IC1_H */
diff --git a/gr-error-correcting-codes/src/lib/libecc/encoder.cc b/gr-error-correcting-codes/src/lib/libecc/encoder.cc
new file mode 100644 (file)
index 0000000..5bc97e7
--- /dev/null
@@ -0,0 +1,123 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <encoder.h>
+#include <iostream>
+
+#define DO_PRINT_DEBUG 0
+
+/*
+ * encode a certain number of output bits
+ *
+ * the 'in_buf' and 'out_buf' must have enough memory to handle the
+ *     number of input and output bits; no error checking is done!
+ *
+ * n_bits_to_output: the number of bits per output stream to encode
+ *
+ * returns the actual number of bits used per input stream
+ */
+
+size_t
+encoder::encode
+(const char** in_buf,
+ char** out_buf,
+ size_t n_bits_to_output)
+{
+  if (DO_PRINT_DEBUG) {
+    std::cout << "encode{out}(): Starting:";
+  }
+
+  // set the class-internal number of input bits and
+  // output bits left to encode
+
+  size_t saved_n_input_bits;
+  saved_n_input_bits = d_n_input_bits_left =
+    compute_n_input_bits (n_bits_to_output);
+  d_n_output_bits_left = n_bits_to_output;
+
+  if (DO_PRINT_DEBUG) {
+    std::cout <<
+      "# output bits provided = " << d_n_output_bits_left << "\n"
+      "# input bits computed  = " << d_n_input_bits_left << "\n";
+  }
+
+  // call the private encode function
+
+  encode_private (in_buf, out_buf);
+
+  if (DO_PRINT_DEBUG) {
+    std::cout <<
+      "n_input_bits_used  = " <<
+      (saved_n_input_bits - d_n_input_bits_left) << "\n"
+      "n_output_bits_used = " <<
+      (n_bits_to_output - d_n_output_bits_left) << '\n';
+  }
+
+  // return the actual number of input bits used
+
+  return (saved_n_input_bits - d_n_input_bits_left);
+}
+
+/*
+ * encode a certain number of input bits
+ *
+ * the 'in_buf' and 'out_buf' must have enough memory to handle the
+ *     number of input and output bits; no error checking is done!
+ *
+ * n_bits_to_input: the number of bits per input stream to encode
+ *
+ * returns the actual number of bits written per output stream
+ */
+
+size_t
+encoder::encode
+(const char** in_buf,  
+ size_t n_bits_to_input,
+ char** out_buf)
+{
+  // set the class-internal number of input and
+  // output bits left to encode
+
+  size_t saved_n_output_bits;
+  saved_n_output_bits = d_n_output_bits_left =
+    compute_n_output_bits (n_bits_to_input);
+  d_n_input_bits_left = n_bits_to_input;
+
+  // call the private encode function
+
+  encode_private (in_buf, out_buf);
+
+  if (DO_PRINT_DEBUG) {
+    std::cout << "n_input_bits_used = " <<
+      (n_bits_to_input - d_n_input_bits_left) << '\n';
+    std::cout << "n_output_bits_used = " <<
+      (saved_n_output_bits - d_n_output_bits_left) << '\n';
+  }
+
+  // return the actual number of output bits written
+
+  return (saved_n_output_bits - d_n_output_bits_left);
+}
diff --git a/gr-error-correcting-codes/src/lib/libecc/encoder.h b/gr-error-correcting-codes/src/lib/libecc/encoder.h
new file mode 100644 (file)
index 0000000..2c3dde1
--- /dev/null
@@ -0,0 +1,72 @@
+/* -*- 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 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.
+ */
+
+#ifndef INCLUDED_ENCODER_H
+#define INCLUDED_ENCODER_H
+
+#include "code_types.h"
+
+// the 'encoder' class is a virtual class upon which all encoder types
+// can be built.
+
+class encoder
+{
+public:
+  encoder () {};
+  virtual ~encoder () {};
+
+  virtual size_t compute_n_input_bits (size_t n_output_bits) = 0;
+  virtual size_t compute_n_output_bits (size_t n_input_bits) = 0;
+  virtual size_t encode (const char** in_buf,
+                        char** out_buf,
+                        size_t n_bits_to_output);
+  virtual size_t encode (const char** in_buf,
+                        size_t n_bits_to_input,
+                        char** out_buf);
+
+/* for remote access to internal info */
+
+  inline size_t block_size_bits () {return (d_block_size_bits);};
+  inline size_t n_code_inputs () {return (d_n_code_inputs);};
+  inline size_t n_code_outputs () {return (d_n_code_outputs);};
+
+protected:
+  /* encode_private: encode the given in_buf and write the output bits
+   * to the out_buf, using internal class variables.  This function is
+   * called from the publically available "encode()" methods, which
+   * first set the internal class variables before executing.
+   */
+
+  virtual void encode_private (const char** in_buf, char** out_buf) = 0;
+
+  /* inheriting methods need to figure out what makes the most sense
+   * for them in terms of getting new inputs and writing outputs.
+   */
+
+  size_t d_block_size_bits, d_n_code_inputs, d_n_code_outputs;
+  size_t d_n_enc_bits, d_total_n_enc_bits;
+  size_t d_in_buf_ndx, d_out_buf_ndx;
+  size_t d_in_bit_shift, d_out_bit_shift;
+  size_t d_n_input_bits_left, d_n_output_bits_left;
+};
+
+#endif /* INCLUDED_ENCODER_H */
diff --git a/gr-error-correcting-codes/src/lib/libecc/encoder_convolutional.cc b/gr-error-correcting-codes/src/lib/libecc/encoder_convolutional.cc
new file mode 100644 (file)
index 0000000..b7bd87d
--- /dev/null
@@ -0,0 +1,290 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "encoder_convolutional.h"
+#include <assert.h>
+#include <iostream>
+
+#define DO_TIME_THOUGHPUT 0
+#define DO_PRINT_DEBUG 1
+
+#include <mld/mld_timer.h>
+#include <mld/n2bs.h>
+
+static const int g_max_block_size_bits = 10000000;
+static const int g_max_num_streams = 10;
+static const int g_num_bits_per_byte = 8;
+
+void encoder_convolutional::encoder_convolutional_init
+(int block_size_bits,
+ int n_code_inputs,
+ int n_code_outputs,
+ const std::vector<int>& code_generators,
+ const std::vector<int>* code_feedback,
+ bool do_termination,
+ int start_memory_state,
+ int end_memory_state)
+{
+  // error checking on the input arguments is done by the trellis class
+
+  if (code_feedback)
+    d_trellis = new code_convolutional_trellis
+      (block_size_bits,
+       n_code_inputs,
+       n_code_outputs,
+       code_generators,
+       *code_feedback,
+       do_termination,
+       end_memory_state);
+  else
+    d_trellis = new code_convolutional_trellis
+      (block_size_bits,
+       n_code_inputs,
+       n_code_outputs,
+       code_generators,
+       do_termination,
+       end_memory_state);
+
+  // set the initial FSM state to 'init'
+
+  d_fsm_state = fsm_enc_conv_init;
+
+  // create the class block variables
+
+  d_block_size_bits = block_size_bits;
+  d_n_code_inputs = n_code_inputs;
+  d_n_code_outputs = n_code_outputs;
+  d_do_streaming = d_trellis->do_streaming ();
+  d_do_termination = d_trellis->do_termination ();
+  d_total_n_delays = d_trellis->total_n_delays ();
+
+  // parse the init state
+
+  memory_t t_mask = (memory_t)((2 << d_total_n_delays) - 1);
+  size_t t_n_states = (1 << d_total_n_delays);
+
+  if (start_memory_state & t_mask) {
+    std::cout << "encoder_convolutional: Warning: " <<
+      "provided end memory state out (" << end_memory_state <<
+      ") is out of the state range [0, " <<
+      (t_n_states-1) << "]; masking off the unused bits.\n";
+
+    start_memory_state &= t_mask;
+  }
+
+  d_init_state = start_memory_state;
+
+  d_current_inputs.assign (d_n_code_inputs, 0);
+  d_current_outputs.assign (d_n_code_outputs, 0);
+}
+
+void
+encoder_convolutional::encode_private
+(const char** in_buf,
+ char** out_buf)
+{
+  struct timeval t_tp;
+  if (DO_TIME_THOUGHPUT) {
+    start_timer (&t_tp);
+  }
+
+  // reset buffer indices
+
+  d_total_n_enc_bits = d_in_buf_ndx = d_out_buf_ndx =
+    d_in_bit_shift = d_out_bit_shift = 0;
+
+  if (DO_PRINT_DEBUG) {
+    std::cout << "Beginning this encode() call; starting parameters.\n";
+    std::cout << "d_n_input_bits_left = " << d_n_input_bits_left << '\n';
+    std::cout << "d_n_output_bits_left = " << d_n_output_bits_left << '\n';
+  }
+
+  // while there are inputs and outputs left to process ...
+
+  while ((d_n_input_bits_left != 0) & (d_n_output_bits_left != 0)) {
+
+    // jump to the correct state in the fsm
+
+    switch (d_fsm_state) {
+
+    case fsm_enc_conv_init:
+
+      // copy the init states to the current memory
+
+      d_memory = d_init_state;
+
+      // if not doing streaming, things to do; else nothing more do
+
+      if (d_do_streaming == false) {
+
+       // reset the number of encoded bits in this block (which is
+       // used to compare with the number of bits in the block)
+
+       d_n_enc_bits = 0;
+      }
+
+      // move to the 'input' state
+
+      d_fsm_state = fsm_enc_conv_doing_input;
+      break;
+
+    case fsm_enc_conv_doing_input:
+
+      // working through the trellis section which requires input bits
+      // from external sources; loop up to the block size (before
+      // termination bits, if any), counting down the number of
+      // available input bits.
+
+      encode_loop (in_buf, out_buf, &d_n_input_bits_left, d_block_size_bits);
+
+      // finished this loop; check for jumping to the next state
+
+      if ((d_n_enc_bits == d_block_size_bits) & (d_do_streaming == false)) {
+
+       // jump to another state, depending on termination requirement
+
+       if (d_do_termination == true) {
+         d_n_enc_bits = 0;
+         d_fsm_state = fsm_enc_conv_doing_term;
+       } else {
+         d_fsm_state = fsm_enc_conv_init;
+       }
+      }
+      break;
+
+    case fsm_enc_conv_doing_term:
+
+      // terminating the trellis, trying to get to a specific state;
+      // better get here only when do_termination is true, but check
+      // just in case; lop up to the max memory, counting down the
+      // number of output bits left
+
+      if (d_do_termination == true) {
+       encode_loop (in_buf, out_buf, &d_n_output_bits_left, d_total_n_delays);
+
+       // finished this loop; check for jumping to the next state
+
+       if (d_n_enc_bits == d_total_n_delays)
+         d_fsm_state = fsm_enc_conv_init;
+
+      } else {
+       // should never get here!
+       assert (0);
+      }
+      break;
+
+    default:
+      // better never get here!
+      assert (0);
+      break;
+
+      // done (switch) with FSM
+    }
+
+    // done (while) there are inputs and outputs
+  }
+
+  if (DO_PRINT_DEBUG) {
+    std::cout << "Done with this encode() call; ending parameters.\n"
+      "d_in_bit_shift = " << d_in_bit_shift << "\n"
+      "d_out_bit_shift = " << d_out_bit_shift << "\n"
+      "d_in_buf_ndx = " << d_in_buf_ndx << "\n"
+      "d_out_buf_ndx = " << d_out_buf_ndx << "\n"
+      "d_n_input_bits_left = " << d_n_input_bits_left << "\n"
+      "d_n_output_bits_left = " << d_n_output_bits_left << "\n"
+      "d_total_n_enc_bits = " << d_total_n_enc_bits << "\n";
+  }
+
+  if (DO_TIME_THOUGHPUT) {
+    // compute the throughput for this particular function call
+    u_long d_t = end_timer (&t_tp);
+    std::cout << "Completed " << d_total_n_enc_bits <<
+      " bits in " << d_t << " usec => " <<
+      1e6*(((double) d_total_n_enc_bits)/((double) d_t)) <<
+      " b/s\n";
+  }
+}
+
+void
+encoder_convolutional::encode_loop
+(const char** in_buf,
+ char** out_buf,
+ size_t* which_counter,
+ size_t how_many)
+{
+  // generic encode_loop
+
+  if (DO_PRINT_DEBUG) {
+    std::cout << "Starting encode_loop.\n";
+  }
+
+  while (((*which_counter) > 0) & (d_n_enc_bits < how_many)) {
+    if (DO_PRINT_DEBUG) {
+      std::cout << "*w_c = " << (*which_counter) << ", "
+       "# enc_bits = " << d_n_enc_bits << " of " << how_many << ".\n"
+       "Getting new inputs.\n";
+    }
+
+    // get the next set of input bits from all streams;
+    // written into d_current_inputs
+
+    get_next_inputs (in_buf);
+
+    // use the trellis to do the encoding;
+    // updates the input memory to the new memory state for the given input
+    // and writes the output bits to the current_outputs
+
+    d_trellis->encode_lookup (d_memory, d_current_inputs, d_current_outputs);
+
+    // write the bits in d_current_outputs into the output buffer
+
+    write_output_bits (out_buf);
+
+    // increment the number of encoded bits for the current block, and
+    // the total number of bits for this running of "encode()"
+
+    d_n_enc_bits++;
+    d_total_n_enc_bits++;
+  }
+
+  if (DO_PRINT_DEBUG) {
+    std::cout << "ending encode_loop.\n";
+  }
+}
+
+void
+encoder_convolutional::get_next_inputs__term
+()
+{
+  // FIXME: how to figure out which term bit to get?
+  // loop to set each entry of "d_current_inputs"
+
+  // need to do feedback separately, since it involves determining the
+  // FB bit value & using that as the input value to cancel it out
+
+  d_current_inputs.assign (d_n_code_inputs, 0);
+  //   return (d_term_states[code_input_n] & 1);
+}
diff --git a/gr-error-correcting-codes/src/lib/libecc/encoder_convolutional.h b/gr-error-correcting-codes/src/lib/libecc/encoder_convolutional.h
new file mode 100644 (file)
index 0000000..4a0d479
--- /dev/null
@@ -0,0 +1,230 @@
+/* -*- 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 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.
+ */
+
+#ifndef INCLUDED_ENCODER_CONVOLUTIONAL_H
+#define INCLUDED_ENCODER_CONVOLUTIONAL_H
+
+#include "encoder.h"
+#include "code_convolutional_trellis.h"
+
+class encoder_convolutional : public encoder
+{
+/*!
+ * class encoder_convolutional : public encoder
+ *
+ * Encode the incoming streams using a convolutional encoder; This is
+ *     a virtual class which defines the basics of a convolutional
+ *     encoder, but not how input and output bits are handled, nor
+ *     feedback in the encoder.  These features are all defined by
+ *     overriding methods appropriately.
+ *
+ * block_size_bits: if == 0, then do streaming encoding ("infinite"
+ *     trellis); otherwise this is the block size in bits to encode
+ *     before terminating the trellis.  This value -does not- include
+ *     any termination bits.
+ *
+ * n_code_inputs:
+ * n_code_outputs:
+ * code_generator: vector of integers (32 bit) representing the code
+ *     to be implemented.  E.g. "4" in binary is "100", which would be
+ *     "D^2" for code generation.  "6" == 110b == "D^2 + D"
+ *  ==> The vector is listed in order for each output stream, so if there
+ *     are 2 input streams (I1, I2) [specified in "n_code_inputs"]
+ *     and 2 output streams (O1, O2) [specified in "n_code_outputs"],
+ *     then the vector would be the code generator for:
+ *       [I1->O1, I2->O1, I1->O2, I2->O2]
+ *     with each element being an integer representation of the code.
+ *     The "octal" representation is used frequently in the literature
+ *     (e.g. [015, 06] == [1101, 0110] in binary) due to its close
+ *     relationship with binary (each number is 3 binary digits)
+ *     ... but any integer representation will suffice.
+ *
+ * do_termination: valid only if block_size_bits != 0, and defines
+ *     whether or not to use trellis termination.  Default is to use
+ *     termination when doing block coding.
+ *
+ * start_memory_state: when starting a new block, the starting memory
+ *     state to begin encoding; there will be a helper function to
+ *     assist in creating this value for a given set of inputs;
+ *     default is the "all zero" state.
+ * 
+ * end_memory_state: when terminating a block, the ending memory
+ *     state to stop encoding; there will be a helper function to
+ *     assist in creating this value for a given set of inputs;
+ *     default is the "all zero" state.
+ */
+
+public:
+  inline encoder_convolutional
+  (int block_size_bits,
+   int n_code_inputs,
+   int n_code_outputs,
+   const std::vector<int> &code_generators,
+   bool do_termination = true,
+   int start_memory_state = 0,
+   int end_memory_state = 0)
+  {encoder_convolutional_init (block_size_bits,
+                              n_code_inputs,
+                              n_code_outputs,
+                              code_generators,
+                              0,
+                              do_termination,
+                              start_memory_state,
+                              end_memory_state);};
+
+/*!
+ * Encoder with feedback.
+ *
+ * code_feedback: vector of integers (32 bit) representing the code
+ *     feedback to be implemented (same as for the code_generator).
+ *     For this feedback type, the LSB ("& 1") is ignored (set to "1"
+ *     internally, since it's always 1) ... this (effectively)
+ *     represents the input bit for the given encoder, without which
+ *     there would be no encoding!  Each successive higher-order bit
+ *     represents the output of that delay block; for example "6" ==
+ *     110b == "D^2 + D" means use the current input bit + the output
+ *     of the second delay block.  Listing order is the same as for
+ *     the code_generator.
+ */
+
+  inline encoder_convolutional
+  (int block_size_bits,
+   int n_code_inputs,
+   int n_code_outputs,
+   const std::vector<int>& code_generators,
+   const std::vector<int>& code_feedback,
+   bool do_termination = true,
+   int start_memory_state = 0,
+   int end_memory_state = 0)
+  {encoder_convolutional_init (block_size_bits,
+                              n_code_inputs,
+                              n_code_outputs,
+                              code_generators,
+                              &code_feedback,
+                              do_termination,
+                              start_memory_state,
+                              end_memory_state);};
+
+  virtual ~encoder_convolutional () {delete d_trellis;};
+
+/* for remote access to internal info */
+
+  inline const bool do_termination () {return (d_do_termination);};
+  inline const bool do_feedback () {return (d_trellis->do_feedback());};
+  inline const bool do_streaming () {return (d_do_streaming);};
+  inline const size_t total_n_delays () {return (d_total_n_delays);};
+
+protected:
+/*
+ * fsm_enc_conv_t: finite state machine for the convolutional encoder;
+ *     output happens all the time, so that's built-in to each state.
+ *
+ * fsm_enc_conv_init: initialize for a new block / block; this is already
+ *     done at instantiation, so do it only at the end of a block.
+ *
+ * fsm_enc_conv_doing_input: doing encoding inside the trellis
+ *
+ * fsm_enc_conv_doing_term: termination trellis, if requested
+ */
+
+  enum fsm_enc_conv_t {
+    fsm_enc_conv_init, fsm_enc_conv_doing_input, fsm_enc_conv_doing_term
+  };
+
+  // methods defined in this class
+
+  void encoder_convolutional_init (int block_size_bits,
+                                  int n_code_inputs,
+                                  int n_code_outputs,
+                                  const std::vector<int>& code_generators,
+                                  const std::vector<int>* code_generators,
+                                  bool do_termination,
+                                  int start_memory_state,
+                                  int end_memory_state);
+
+  virtual void encode_private (const char** in_buf, char** out_buf);
+
+  virtual void encode_loop (const char** in_buf, char** out_buf,
+                           size_t* which_counter, size_t how_many);
+
+  inline void get_next_inputs (const char** in_buf) {
+    switch (d_fsm_state) {
+    case fsm_enc_conv_doing_input:
+      get_next_inputs__input (in_buf);
+      break;
+    case fsm_enc_conv_doing_term:
+      get_next_inputs__term ();
+      break;
+    default:
+      assert (0);
+      break;
+    }
+  };
+
+  virtual void get_next_inputs__term ();
+
+  void get_memory_requirements (size_t m,
+                               size_t n,
+                               size_t& t_max_mem,
+                               size_t& t_n_unique_fb_prev_start,
+                               const std::vector<int>* code_feedback);
+
+  // methods which are required by classes which inherit from this
+  // one; primarily just the parts which deal with getting input bits
+  // and writing output bits, changing the indices for those buffers.
+
+  virtual void write_output_bits (char** out_buf) = 0;
+  virtual void get_next_inputs__input (const char** in_buf) = 0;
+
+  // variables
+
+  fsm_enc_conv_t d_fsm_state;
+  bool d_do_streaming, d_do_termination;
+
+  // "total_n_delays" is the total # of delays, needed to determine the
+  // # of states in the decoder
+
+  size_t d_total_n_delays;
+
+  // the current state of the encoder (all delays / memories)
+
+  memory_t d_memory;
+
+  // "inputs" are the current input bits, in the LSB (&1) of each "char"
+
+  std::vector<char> d_current_inputs;
+
+  // "outputs" are the current output bits, in the LSB (&1) of each "char"
+
+  std::vector<char> d_current_outputs;
+
+  // "trellis" is the code trellis for the given input parameters
+
+  code_convolutional_trellis* d_trellis;
+
+  // "init_states" are the user-provided init states,
+  // interpreted w/r.t. the actual trellis;
+
+  memory_t d_init_state;
+};
+
+#endif /* INCLUDED_ENCODER_CONVOLUTIONAL_H */
diff --git a/gr-error-correcting-codes/src/lib/libecc/encoder_convolutional_ic1_ic1.cc b/gr-error-correcting-codes/src/lib/libecc/encoder_convolutional_ic1_ic1.cc
new file mode 100644 (file)
index 0000000..aa83c07
--- /dev/null
@@ -0,0 +1,188 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <encoder_convolutional_ic1_ic1.h>
+#include <assert.h>
+#include <iostream>
+#include <mld/n2bs.h>
+
+#define DO_PRINT_DEBUG 0
+
+static const int g_num_bits_per_byte = 8;
+
+// FIXME
+size_t
+encoder_convolutional_ic1_ic1::compute_n_output_bits
+(size_t n_input_bits)
+{
+  assert (0);
+  return (0);
+}
+
+/*
+ * Compute the number of input bits needed to produce
+ * 'n_output' bits.  For convolutional encoders, there is
+ * 1 bit output per bit input per stream, with the addition of a some
+ * bits for trellis termination if selected.  Thus the input:output
+ * bit ratio will be:
+ * 
+ * if (streaming | no termination), 1:1
+ *
+ * if (not streaming & termination), roughly 1:(1+X), where "X" is the
+ * total memory size of the code divided by the block length in bits.
+ * But this also depends on the state of the FSM ... how many bits are
+ * left before termination.
+ *
+ * The returned value will also depend on whether bits are packed, as
+ * well as whether streams are mux'ed together.
+ */
+
+size_t
+encoder_convolutional_ic1_ic1::compute_n_input_bits
+(size_t n_output_bits)
+{
+  size_t t_n_output_bits, t_n_input_bits;
+  t_n_output_bits = t_n_input_bits = n_output_bits;
+
+  if (d_do_termination == true) {
+
+    // not streaming, doing termination; find the number of bits
+    // currently available with no required inputs, if any
+
+    size_t n_extra = 0;
+    if (d_fsm_state == fsm_enc_conv_doing_term) {
+      n_extra = d_total_n_delays - d_n_enc_bits;
+    }
+
+    // check to see if this is enough; return 0 if it is.
+
+    if (n_extra >= t_n_output_bits)
+      return (0);
+
+    // remove those which require no input
+
+    t_n_output_bits -= n_extra;
+
+    // find the number of blocks of data which could be processed
+
+    size_t t_n_output_bits_per_block = d_block_size_bits + d_total_n_delays;
+
+    // get the base number of input items required for the given
+    // number of blocks to be generated
+
+    size_t t_n_blocks = t_n_output_bits / t_n_output_bits_per_block;
+    t_n_input_bits = t_n_blocks * d_block_size_bits;
+
+    // add to that the number of leftover inputs needed to generate
+    // the remainder of the outputs within the remaining block, up to
+    // the given block size (since anything beyond that within this
+    // block requires no inputs)
+
+    size_t t_leftover_bits = t_n_output_bits % t_n_output_bits_per_block;
+    t_n_input_bits += ((t_leftover_bits > d_block_size_bits) ?
+                      d_block_size_bits : t_leftover_bits);
+  }
+
+  return (t_n_input_bits);
+}
+
+void
+encoder_convolutional_ic1_ic1::write_output_bits
+(char** out_buf)
+{
+  // write all the outputs bits in d_current_outputs LSB (&1) to the
+  // given output buffer.
+
+  // one bit per output 'char' for "ic1" type output
+
+  for (size_t n = 0; n < d_n_code_outputs; n++) {
+    if (DO_PRINT_DEBUG) {
+      std::cout << "Starting output_bit:\n"
+       "  O_i[" << n << "][" << d_out_buf_ndx << "] = " <<
+       n2bs (out_buf[n][d_out_buf_ndx], g_num_bits_per_byte) <<
+       ", b_out = " << n2bs (d_current_outputs[n], 1) << ", ";
+    }
+
+    out_buf[n][d_out_buf_ndx] = d_current_outputs[n];
+
+    if (DO_PRINT_DEBUG) {
+      std::cout << "O_o[][] = " <<
+       n2bs (out_buf[n][d_out_buf_ndx], g_num_bits_per_byte) <<
+       "\n";
+    }
+  }
+
+  if (DO_PRINT_DEBUG) {
+    std::cout << "Ending write_output_bits.\n";
+  }
+
+  // decrement the number of output bits left on all streams
+
+  d_n_output_bits_left--;
+
+  // increment the output index (not the bit shift index) for the next
+  // write
+
+  d_out_buf_ndx++;
+}
+
+void
+encoder_convolutional_ic1_ic1::get_next_inputs__input
+(const char** in_buf)
+{
+  // get the next set of input bits, moved into the LSB (&1) of
+  // d_current_inputs
+
+  // one bit per input 'char' for "ic1" type input
+
+  for (size_t m = 0; m < d_n_code_inputs; m++) {
+    d_current_inputs[m] = ((in_buf[m][d_in_buf_ndx]) & 1);
+
+    if (DO_PRINT_DEBUG) {
+      std::cout << "I[" << m << "][" << d_in_buf_ndx << "] = " <<
+       n2bs (d_current_inputs[m], 1) << "\n";
+    }
+  }
+
+  // decrement the number of bits left on all streams
+
+  if (DO_PRINT_DEBUG) {
+    std::cout << "# in bits left: " << d_n_input_bits_left <<
+      " -> " << (d_n_input_bits_left-1) << "\n";
+  }
+
+  d_n_input_bits_left--;
+
+  // increment the input index (not the bit shift index) for the next
+  // read
+
+  if (DO_PRINT_DEBUG) {
+    std::cout << "# in buf ndx: " << d_in_buf_ndx <<
+      " -> " << (d_in_buf_ndx+1) << "\n";
+  }
+
+  d_in_buf_ndx++;
+}
diff --git a/gr-error-correcting-codes/src/lib/libecc/encoder_convolutional_ic1_ic1.h b/gr-error-correcting-codes/src/lib/libecc/encoder_convolutional_ic1_ic1.h
new file mode 100644 (file)
index 0000000..a742b09
--- /dev/null
@@ -0,0 +1,91 @@
+/* -*- 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 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.
+ */
+
+#ifndef INCLUDED_ENCODER_CONVOLUTIONAL_IC1_IC1_H
+#define INCLUDED_ENCODER_CONVOLUTIONAL_IC1_IC1_H
+
+#include "encoder_convolutional.h"
+
+class encoder_convolutional_ic1_ic1 : public encoder_convolutional
+{
+public:
+/*!
+ * class encoder_convolutional_ic1_ic1 : public encoder_convolutional
+ *
+ * Encode the incoming streams using a convolutional encoder,
+ *     "feedforward" or feedback.  Optional termination, data
+ *     streaming, and starting and ending memory states.
+ *
+ * input is "ic1": streams of char, one stream per input as defined by the
+ *     instantiated code, using only the right-most justified bit as
+ *     the single input bit per input item.
+ *
+ * output is "ic1": streams of char, one stream per output as defined by the
+ *     instantiated code, using only the right-most justified bit as
+ *     the single output bit per output item.
+ */
+
+  encoder_convolutional_ic1_ic1
+  (int frame_size_bits,
+   int n_code_inputs,
+   int n_code_outputs,
+   const std::vector<int> &code_generators,
+   bool do_termination = true,
+   int start_memory_state = 0,
+   int end_memory_state = 0)
+    : encoder_convolutional (frame_size_bits,
+                            n_code_inputs,
+                            n_code_outputs,
+                            code_generators,
+                            do_termination,
+                            start_memory_state,
+                            end_memory_state) {};
+
+  encoder_convolutional_ic1_ic1
+  (int frame_size_bits,
+   int n_code_inputs,
+   int n_code_outputs,
+   const std::vector<int> &code_generators,
+   const std::vector<int> &code_feedback,
+   bool do_termination = true,
+   int start_memory_state = 0,
+   int end_memory_state = 0)
+    : encoder_convolutional (frame_size_bits,
+                            n_code_inputs,
+                            n_code_outputs,
+                            code_generators,
+                            code_feedback,
+                            do_termination,
+                            start_memory_state,
+                            end_memory_state) {};
+
+  virtual ~encoder_convolutional_ic1_ic1 () {};
+
+  virtual size_t compute_n_input_bits (size_t n_output_bits);
+  virtual size_t compute_n_output_bits (size_t n_input_bits);
+
+protected:
+  virtual void get_next_inputs__input (const char** in_buf);
+  virtual void write_output_bits (char** out_buf);
+};
+
+#endif /* INCLUDED_ENCODER_CONVOLUTIONAL_IC1_IC1_H */
diff --git a/gr-error-correcting-codes/src/lib/libecc/encoder_convolutional_ic8_ic8.cc b/gr-error-correcting-codes/src/lib/libecc/encoder_convolutional_ic8_ic8.cc
new file mode 100644 (file)
index 0000000..5d2a4bb
--- /dev/null
@@ -0,0 +1,224 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <encoder_convolutional_ic8_ic8.h>
+#include <assert.h>
+#include <iostream>
+
+#define DO_TIME_THOUGHPUT 1
+#define DO_PRINT_DEBUG 1
+
+#if DO_TIME_THOUGHPUT
+#include <mld/mld_timer.h>
+#endif
+#if DO_PRINT_DEBUG
+#include <mld/n2bs.h>
+#endif
+
+// FIXME: when doing packed, should probably allow user to select how
+// bits are selected, so-as to make sure it's always the same
+// no matter the CPU endianness
+
+// FIXME
+size_t
+encoder_convolutional_ic8_ic8::compute_n_output_bits
+(size_t n_input_bits)
+{
+  assert (0);
+  return (0);
+}
+
+/*
+ * Compute the number of input bits needed to produce
+ * 'n_output' bits.  For convolutional encoders, there is
+ * 1 bit output per bit input per stream, with the addition of a some
+ * bits for trellis termination if selected.  Thus the input:output
+ * bit ratio will be:
+ * 
+ * if (streaming | no termination), 1:1
+ *
+ * if (not streaming & termination), roughly 1:(1+X), where "X" is the
+ * total memory size of the code divided by the block length in bits.
+ * But this also depends on the state of the FSM ... how many bits are
+ * left before termination.
+ *
+ * The returned value will also depend on whether bits are packed, as
+ * well as whether streams are mux'ed together.
+ */
+
+size_t
+encoder_convolutional_ic8_ic8::compute_n_input_bits
+(size_t n_output_bits)
+{
+  size_t t_n_output_bits, t_n_input_bits;
+  t_n_output_bits = t_n_input_bits = n_output_bits;
+
+  if (d_do_termination == true) {
+
+    // not streaming, doing termination; find the number of bits
+    // currently available with no required inputs, if any
+
+    size_t n_extra = 0;
+    if (d_fsm_state == fsm_enc_conv_doing_term) {
+      n_extra = d_max_memory - d_n_enc_bits;
+    }
+
+    // check to see if this is enough; return 0 if it is.
+
+    if (n_extra >= t_n_output_bits)
+      return (0);
+
+    // remove those which require no input
+
+    t_n_output_bits -= n_extra;
+
+    // find the number of frames of data which could be processed
+
+    size_t t_n_output_bits_per_frame = d_frame_size_bits + d_max_memory;
+
+    // get the base number of input items required for the given
+    // number of frames to be generated
+
+    size_t t_n_frames = t_n_output_bits / t_n_output_bits_per_frame;
+    t_n_input_bits = t_n_frames * d_frame_size_bits;
+
+    // add to that the number of leftover inputs needed to generate
+    // the remainder of the outputs within the remaining frame, up to
+    // the given frame size (since anything beyond that within this
+    // frame requires no inputs)
+
+    size_t t_leftover_bits = t_n_output_bits % t_n_output_bits_per_frame;
+    t_n_input_bits += ((t_leftover_bits > d_frame_size_bits) ?
+                      d_frame_size_bits : t_leftover_bits);
+  }
+
+  return (t_n_input_bits);
+}
+
+void
+encoder_convolutional_ic8_ic8::increment_io_indices
+(bool while_encoding)
+{
+  // increment the buffer index only for this version, only after
+  // encoding is done and all resulting outputs are stored on the
+  // output streams
+
+  if (while_encoding == false) {
+    d_out_buf_ndx++;
+    d_in_buf_ndx++;
+  }
+
+  // nothing to do while encoding, so no else
+
+#if 0
+// move counters to the next input bit, wrapping to the next input
+// byte as necessary
+  if (++d_in_bit_shift % g_num_bits_per_byte == 0) {
+    d_in_bit_shift = 0;
+    d_in_buf_ndx++;
+  }
+// move counters to the next output bit, wrapping to the next output
+// byte as necessary
+    if (++d_out_bit_shift % g_num_bits_per_byte == 0) {
+      d_out_bit_shift = 0;
+      d_out_buf_ndx++;
+    }
+#endif
+}
+
+void
+encoder_convolutional_ic8_ic8::output_bit
+(char t_out_bit,
+ char** out_buf,
+ size_t t_output_stream)
+{
+  // store the result for this particular output stream
+  // one bit per output item for "ic8" type output
+
+  if (DO_PRINT_DEBUG) {
+    std::cout << ", O_i[" << t_output_stream <<
+      "][" << d_out_buf_ndx << "] = " <<
+      n2bs (out_buf[t_output_stream][d_out_buf_ndx], 2);
+  }
+
+  out_buf[t_output_stream][d_out_buf_ndx] = t_out_bit;
+
+  if (DO_PRINT_DEBUG) {
+    std::cout << ", b_out = " << t_out_bit <<
+      ", O_o[" << t_output_stream << "][" << d_out_buf_ndx << "][" <<
+      d_out_bit_shift << "] = " <<
+      n2bs (out_buf[t_output_stream][d_out_buf_ndx], 2) << '\n';
+  }
+
+#if 0
+#if DO_PRINT_DEBUG
+  std::cout << ", O_i[" << t_output_stream <<
+    "][" << d_out_buf_ndx << "] = " <<
+    n2bs (out_buf[t_output_stream][d_out_buf_ndx], g_num_bits_per_byte);
+#endif
+
+// packed bits in each output item
+  out_buf[t_output_stream][d_out_buf_ndx] |=
+    (t_out_bit << d_out_bit_shift);
+
+#if DO_PRINT_DEBUG
+  std::cout << ", b_out = " << t_out_bit <<
+    ", O_o[" << t_output_stream << "][" << d_out_buf_ndx << "][" <<
+    d_out_bit_shift << "] = " <<
+    n2bs (out_buf[t_output_stream][d_out_buf_ndx], g_num_bits_per_byte) << '\n';
+#endif
+#endif
+}
+
+char
+encoder_convolutional_ic8_ic8::get_next_bit__input
+(const char** in_buf,
+ size_t code_input_n)
+{
+  // get a bit from this particular input stream
+  // one bit per output item for "ic8" type input
+
+  if (DO_PRINT_DEBUG) {
+    std::cout << "I[" << p << "][" << d_in_buf_ndx << "] = ";
+    cout_binary (t_next_bit, g_num_bits_per_byte);
+    std::cout << ", st_i[" << p << "] = ";
+    cout_binary ((*t_states_ptr), d_max_memory+2);
+    std::cout << ", I[" << p << "][" << d_in_buf_ndx << "][" <<
+      d_in_bit_shift << "] = " << t_next_bit <<
+      ", st_o[" << p << "] = ";
+    cout_binary (t_state, d_max_memory+2);
+    std::cout << '\n';
+  }
+
+   return ((in_buf[code_input_n][d_in_buf_ndx] >> d_in_bit_shift) & 1);
+}
+
+char
+encoder_convolutional_ic8_ic8::get_next_bit__term
+(size_t code_input_n)
+{
+  return ((d_term_states[code_input_n] >> d_in_bit_shift) & 1);
+}
diff --git a/gr-error-correcting-codes/src/lib/libecc/encoder_convolutional_ic8_ic8.h b/gr-error-correcting-codes/src/lib/libecc/encoder_convolutional_ic8_ic8.h
new file mode 100644 (file)
index 0000000..dad3940
--- /dev/null
@@ -0,0 +1,96 @@
+/* -*- 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 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.
+ */
+
+#ifndef INCLUDED_ENCODER_CONVOLUTIONAL_IC8_IC8_H
+#define INCLUDED_ENCODER_CONVOLUTIONAL_IC8_IC8_H
+
+#include "encoder_convolutional.h"
+
+/*!
+ * class encoder_convolutional_ic8_ic8 : public encoder_convolutional
+ *
+ * Encode the incoming streams using a convolutional encoder,
+ *     "feedforward" or feedback.  Optional termination, data
+ *     streaming, and starting and ending memory states.
+ *
+ * input is "ic8": streams of char, one stream per input as defined by the
+ *     instantiated code, using all 8 bits in the char.
+ *
+ * FIXME: need to have inputs for MSB or LSB first input and output.
+ *
+ * output is "ic8": streams of char, one stream per output as defined by the
+ *     instantiated code, using all 8 bits in the char.
+ */
+
+class encoder_convolutional_ic8_ic8 : public encoder_convolutional
+{
+public:
+  encoder_convolutional_ic8_ic8
+  (int frame_size_bits,
+   int n_code_inputs,
+   int n_code_outputs,
+   const std::vector<int> &code_generators,
+   bool do_termination = true,
+   int start_memory_state = 0,
+   int end_memory_state = 0)
+    : encoder_convolutional (frame_size_bits,
+                            n_code_inputs,
+                            n_code_outputs,
+                            code_generators,
+                            do_termination,
+                            start_memory_state,
+                            end_memory_state) {};
+
+  encoder_convolutional_ic8_ic8
+  (int frame_size_bits,
+   int n_code_inputs,
+   int n_code_outputs,
+   const std::vector<int> &code_generators,
+   const std::vector<int> &code_feedback,
+   bool do_termination = true,
+   int start_memory_state = 0,
+   int end_memory_state = 0)
+    : encoder_convolutional (frame_size_bits,
+                            n_code_inputs,
+                            n_code_outputs,
+                            code_generators,
+                            code_feedback,
+                            do_termination,
+                            start_memory_state,
+                            end_memory_state) {};
+
+  virtual ~encoder_convolutional_ic8_ic8 () {};
+
+  virtual size_t compute_n_input_bits (size_t n_output_bits);
+  virtual size_t compute_n_output_bits (size_t n_input_bits);
+
+protected:
+  virtual char get_next_bit__input (const char** in_buf,
+                                   size_t code_input_n);
+  virtual char get_next_bit__term (size_t code_input_n);
+  virtual void output_bit (char t_out_bit, char** out_buf,
+                          size_t t_output_stream);
+  virtual void increment_io_indices (bool while_encoding);
+  virtual void update_memory_post_encode ();
+};
+
+#endif /* INCLUDED_ENCODER_CONVOLUTIONAL_IC8_IC8_H */
diff --git a/gr-error-correcting-codes/src/lib/libecc/encoder_turbo.cc b/gr-error-correcting-codes/src/lib/libecc/encoder_turbo.cc
new file mode 100644 (file)
index 0000000..3f528cb
--- /dev/null
@@ -0,0 +1,52 @@
+#include "encoder_turbo.h"
+
+encoder_turbo::encoder_turbo
+(int n_code_inputs,
+ int n_code_outputs,
+ const std::vector<encoder_convolutional*> &encoders,
+ const std::vector<size_t> &interleavers)
+{
+  // need error checking on inputs
+
+  d_encoders = encoders;
+  d_interleavers = interleavers;
+}
+
+// dummy stuff for now to test std::vector<gr_streams_convolutional...> stuff
+
+size_t
+encoder_turbo::compute_n_input_bits
+(size_t n_output_bits)
+{
+  return (0);
+}
+
+size_t
+encoder_turbo::compute_n_output_bits
+(size_t n_input_bits)
+{
+  return (0);
+}
+
+void
+encoder_turbo::encode_private
+(const char** in_buf,
+ char** out_buf)
+{
+}
+
+char
+encoder_turbo::get_next_bit
+(const char** in_buf,
+ size_t code_input_n)
+{
+  return (0);
+}
+
+void
+encoder_turbo::output_bit
+(char t_out_bit,
+ char** out_buf,
+ size_t t_output_stream)
+{
+}
diff --git a/gr-error-correcting-codes/src/lib/libecc/encoder_turbo.h b/gr-error-correcting-codes/src/lib/libecc/encoder_turbo.h
new file mode 100644 (file)
index 0000000..8c295f1
--- /dev/null
@@ -0,0 +1,147 @@
+/* -*- 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 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.
+ */
+
+#ifndef INCLUDED_ENCODER_TURBO_H
+#define INCLUDED_ENCODER_TURBO_H
+
+#include "encoder_convolutional.h"
+#include <vector>
+
+class encoder_turbo : public encoder
+{
+public:
+/*!
+ * class encoder_turbo : public encoder
+ *
+ * Encode the incoming streams using a turbo encoder; This is a
+ *     virtual class which defines the basics of a turbo encoder, but
+ *     not how input and output bits are handled.  These features are
+ *     all defined by overriding methods appropriately.
+ *
+ * n_code_inputs:
+ * n_code_outputs: the total number of code inputs and outputs for the
+ *     overall turbo encoder (not just the constituent codes).
+ *
+ * encoders: the constituent encoders to be used; all -should- be
+ *     configured with the same "block_size" and "termination", though
+ *     from this encoder's perspective it doesn't really matter.
+ *
+ * interleavers: the interleavers to use before each encoder,
+ *     respectively, except the first encoder which will not use an
+ *     interleaver.
+ */
+
+  encoder_turbo
+  (int n_code_inputs,
+   int n_code_outputs,
+   const std::vector<encoder_convolutional*> &encoders,
+   const std::vector<size_t> &interleavers);
+
+  virtual ~encoder_turbo () {};
+
+/* for remote access to internal info */
+
+  inline bool do_termination () {return (d_do_termination);};
+
+#if 1
+  virtual size_t compute_n_input_bits (size_t n_output_bits);
+  virtual size_t compute_n_output_bits (size_t n_input_bits);
+#endif
+
+protected:
+/*
+ * fsm_enc_turbo_t: finite state machine for the turbo encoder;
+ *     output happens all the time, so that's built-in to each state.
+ *
+ * fsm_enc_turbo_init: initialize for a new frame / block; this is already
+ *     done at instantiation, so do it only at the end of a block.
+ *
+ * fsm_enc_turbo_doing_input: doing encoding inside the trellis
+ *
+ * fsm_enc_turbo_doing_term: termination trellis, if requested
+ */
+
+  enum fsm_enc_turbo_t {
+    fsm_enc_turbo_init, fsm_enc_turbo_doing_input, fsm_enc_turbo_doing_term
+  };
+
+/*
+ * maio(i,o): matrix access into a vector, knowing the # of code
+ *     outputs (from inside the class). References into a vector with
+ *     code inputs ordered by code output.
+ *
+ * 'i' is the first dimension - immediate memory order first - the code input
+ * 'o' is the second dimension - slower memory order second - the code output
+ *
+ * returns ((o*n_code_outputs) + i)
+ */
+
+  inline size_t maio(size_t i, size_t o) {return ((o*d_n_code_outputs) + i);};
+
+/*
+ * maoi(i,o): matrix access into a vector, knowing the # of code
+ *     inputs (from inside the class). References into a vector with
+ *     code outputs ordered by code input.
+ *
+ * 'o' is the first dimension - immediate memory order first - the code output
+ * 'i' is the second dimension - slower memory order second - the code input
+ *
+ * returns ((i*n_code_inputs) + o)
+ */
+
+  inline size_t maoi(size_t i, size_t o) {return ((i*d_n_code_inputs) + o);};
+
+  // methods defined in this class
+#if 1
+  // temporary just to get full compilation
+
+  virtual void encode_private (const char** in_buf, char** out_buf);
+  virtual char get_next_bit (const char** in_buf, size_t code_input_n);
+  virtual void output_bit (char t_out_bit, char** out_buf,
+                          size_t t_output_stream);
+#else
+  virtual void encode_private (const char** in_buf, char** out_buf) = 0;
+  virtual void encode_loop (const char** in_buf, char** out_buf,
+                           size_t* which_counter, size_t how_many) = 0;
+  virtual char get_next_bit (const char** in_buf, size_t code_input_n) = 0;
+  virtual char get_next_bit__term (size_t code_input_n) = 0;
+
+  // methods which are required by classes which inherit from this
+  // one; primarily just the parts which deal with getting input bits
+  // and writing output bits, changing the indices for those buffers.
+
+  virtual char get_next_bit__input (const char** in_buf,
+                                   size_t code_input_n) = 0;
+  virtual void increment_io_indices (bool while_encoding) = 0;
+#endif
+
+  // variables
+
+  fsm_enc_turbo_t d_fsm_state;
+  bool d_do_termination;
+  size_t d_max_memory, d_n_memories;
+
+  std::vector<encoder_convolutional*> d_encoders;
+  std::vector<size_t> d_interleavers;
+};
+
+#endif /* INCLUDED_ENCODER_TURBO_H */
diff --git a/gr-error-correcting-codes/src/lib/libecc/mld/Makefile.am b/gr-error-correcting-codes/src/lib/libecc/mld/Makefile.am
new file mode 100644 (file)
index 0000000..b5accd5
--- /dev/null
@@ -0,0 +1,36 @@
+#
+# 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 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.
+# 
+
+include $(top_srcdir)/Makefile.common
+
+INCLUDES = $(STD_DEFINES_AND_INCLUDES) -I.. -I../..
+
+noinst_LTLIBRARIES = libmld.la
+
+libmld_la_SOURCES =    \
+       mld_timer.cc n2bs.cc
+
+noinst_HEADERS =       \
+       mld_timer.h n2bs.h
+
+MOSTLYCLEANFILES = *.loT *~
+
+CONFIG_CLEAN_FILES = *.in
diff --git a/gr-error-correcting-codes/src/lib/libecc/mld/mld_timer.cc b/gr-error-correcting-codes/src/lib/libecc/mld/mld_timer.cc
new file mode 100644 (file)
index 0000000..91708ce
--- /dev/null
@@ -0,0 +1,50 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio.
+ *
+ * Primary Author: Michael Dickens, NCIP Lab, University of Notre Dame
+ * 
+ * GNU Radio is free software; you can 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.
+ */
+
+#include <sys/types.h>
+#include <mld_timer.h>
+
+void start_timer (struct timeval *t_tp)
+{
+  gettimeofday (t_tp, 0);
+}
+
+u_long end_timer (struct timeval *g_tp)
+{
+  struct timeval t_tp;
+  gettimeofday (&t_tp, 0);
+
+  u_long retVal = (t_tp.tv_sec - g_tp->tv_sec);
+  u_long df_usec;
+
+  if (t_tp.tv_usec < g_tp->tv_usec) {
+    retVal -= 1;
+    df_usec = 1000000 - (g_tp->tv_usec - t_tp.tv_usec);
+  } else
+    df_usec = t_tp.tv_usec - g_tp->tv_usec;
+
+  retVal *= 1000000;
+  retVal += df_usec;
+  return (retVal);
+}
diff --git a/gr-error-correcting-codes/src/lib/libecc/mld/mld_timer.h b/gr-error-correcting-codes/src/lib/libecc/mld/mld_timer.h
new file mode 100644 (file)
index 0000000..5e5f89c
--- /dev/null
@@ -0,0 +1,28 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio.
+ *
+ * Primary Author: Michael Dickens, NCIP Lab, University of Notre Dame
+ * 
+ * GNU Radio is free software; you can 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.
+ */
+
+#include <sys/time.h>
+
+extern void start_timer (struct timeval *t_tp);
+extern u_long end_timer (struct timeval *g_tp);
diff --git a/gr-error-correcting-codes/src/lib/libecc/mld/n2bs.cc b/gr-error-correcting-codes/src/lib/libecc/mld/n2bs.cc
new file mode 100644 (file)
index 0000000..909aa08
--- /dev/null
@@ -0,0 +1,73 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio.
+ *
+ * Primary Author: Michael Dickens, NCIP Lab, University of Notre Dame
+ * 
+ * GNU Radio is free software; you can 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.
+ */
+
+#include <n2bs.h>
+#include <iostream>
+
+const int g_num_bits_per_byte = 8;
+
+std::string n2bs (long long number, size_t digits)
+{
+  if (digits > (sizeof (long long) * g_num_bits_per_byte))
+    digits = sizeof (long long);
+  std::string retVal (digits, '0');
+  if (number != 0)
+    for (int n = --digits; n >= 0; n--) {
+      if (number & 1) {
+       retVal[n] = '1';
+      }
+      number >>= 1;
+    }
+  return (retVal);
+}
+std::string n2bs (char number, size_t digits)
+{
+  if (digits > (sizeof (char) * g_num_bits_per_byte))
+    digits = sizeof (char);
+  return n2bs ((long long) number, digits);
+}
+std::string n2bs (int number, size_t digits)
+{
+  if (digits > (sizeof (int) * g_num_bits_per_byte))
+    digits = sizeof (int);
+  return n2bs ((long long) number, digits);
+}
+std::string n2bs (long number, size_t digits)
+{
+  if (digits > (sizeof (long) * g_num_bits_per_byte))
+    digits = sizeof (long);
+  return n2bs ((long long) number, digits);
+}
+std::string n2bs (size_t number, size_t digits)
+{
+  if (digits > (sizeof (size_t) * g_num_bits_per_byte))
+    digits = sizeof (size_t);
+  return n2bs ((long long) number, digits);
+}
+
+void cout_binary (int number, int digits)
+{
+  while (digits-- > 0)
+    std::cout << ((number >> digits) & 1);
+}
diff --git a/gr-error-correcting-codes/src/lib/libecc/mld/n2bs.h b/gr-error-correcting-codes/src/lib/libecc/mld/n2bs.h
new file mode 100644 (file)
index 0000000..a663dce
--- /dev/null
@@ -0,0 +1,32 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio.
+ *
+ * Primary Author: Michael Dickens, NCIP Lab, University of Notre Dame
+ * 
+ * GNU Radio is free software; you can 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.
+ */
+
+#include <string>
+
+extern std::string n2bs (char number, size_t digits);
+extern std::string n2bs (int number, size_t digits);
+extern std::string n2bs (long number, size_t digits);
+extern std::string n2bs (size_t number, size_t digits);
+extern std::string n2bs (long long number, size_t digits);
+extern void cout_binary (int number, int digits);
diff --git a/gr-error-correcting-codes/src/lib/libecc/tests/Makefile.am b/gr-error-correcting-codes/src/lib/libecc/tests/Makefile.am
new file mode 100644 (file)
index 0000000..79850ba
--- /dev/null
@@ -0,0 +1,47 @@
+#
+# 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 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.
+# 
+
+include $(top_srcdir)/Makefile.common
+
+INCLUDES = $(STD_DEFINES_AND_INCLUDES) $(CPPUNIT_INCLUDES) -I..
+
+noinst_LTLIBRARIES = libecc-qa.la
+
+noinst_HEADERS =                               \
+       qa_encoder_convolutional_ic1_ic1.h      \
+       qa_ecc.h
+
+libecc_qa_la_SOURCES =                                 \
+       qa_encoder_convolutional_ic1_ic1.cc     \
+       qa_ecc.cc
+
+# list of programs run by "make check" and "make distcheck"
+
+TESTS = test_all
+
+noinst_PROGRAMS = test_all
+
+LIBECC = ../libecc.la
+LIBECCQA = libecc-qa.la $(LIBECC)
+
+test_all_SOURCES = test_all.cc
+test_all_LDADD = $(LIBECCQA)           \
+       $(CPPUNIT_LIBS)
diff --git a/gr-error-correcting-codes/src/lib/libecc/tests/qa_ecc.cc b/gr-error-correcting-codes/src/lib/libecc/tests/qa_ecc.cc
new file mode 100644 (file)
index 0000000..03b185b
--- /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 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 class gathers together all the test cases for the gr
+ * directory into a single test suite.  As you create new test cases,
+ * add them here.
+ */
+
+#include <qa_ecc.h>
+#include <qa_encoder_convolutional_ic1_ic1.h>
+
+CppUnit::TestSuite*
+qa_ecc::suite
+()
+{
+  CppUnit::TestSuite* s = new CppUnit::TestSuite ("ecc");
+
+  s->addTest (qa_encoder_convolutional_ic1_ic1::suite ());
+  
+  return (s);
+}
diff --git a/gr-error-correcting-codes/src/lib/libecc/tests/qa_ecc.h b/gr-error-correcting-codes/src/lib/libecc/tests/qa_ecc.h
new file mode 100644 (file)
index 0000000..ef41167
--- /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 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.
+ */
+
+#ifndef _QA_ECC_H_
+#define _QA_ECC_H_
+
+#include <cppunit/TestSuite.h>
+
+//! collect all the tests for the gr directory
+
+class qa_ecc {
+public:
+  //! return suite of tests for all of gr directory
+  static CppUnit::TestSuite *suite ();
+};
+
+#endif /* _QA_ECC_H_ */
diff --git a/gr-error-correcting-codes/src/lib/libecc/tests/qa_encoder_convolutional_ic1_ic1.cc b/gr-error-correcting-codes/src/lib/libecc/tests/qa_encoder_convolutional_ic1_ic1.cc
new file mode 100644 (file)
index 0000000..6ea72b6
--- /dev/null
@@ -0,0 +1,430 @@
+/* -*- 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 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.
+ */
+
+#include "encoder_convolutional_ic1_ic1.h"
+#include <qa_encoder_convolutional_ic1_ic1.h>
+#include <cppunit/TestAssert.h>
+#include <string.h>
+#include <iostream>
+#include <iomanip>
+#include <stdio.h>
+
+
+void
+qa_encoder_convolutional_ic1_ic1::do_encoder_check
+(const char** c_in,
+ const char** c_res,
+ int n_output_items,
+ int block_size_bits,
+ int n_code_inputs,
+ int n_code_outputs,
+ const int* code_generators,
+ const int* code_feedback)
+{
+  std::vector<int> t_code_generators;
+  t_code_generators.assign (n_code_inputs * n_code_outputs, 0);
+  for (int m = 0; m < n_code_inputs * n_code_outputs; m++)
+    t_code_generators[m] = code_generators[m];
+
+  encoder_convolutional_ic1_ic1* t_encoder;
+
+  if (code_feedback) {
+    std::vector<int> t_code_feedback;
+    t_code_feedback.assign (n_code_inputs * n_code_outputs, 0);
+    for (int m = 0; m < n_code_inputs * n_code_outputs; m++)
+      t_code_feedback[m] = code_feedback[m];
+
+    t_encoder = new encoder_convolutional_ic1_ic1
+      (block_size_bits,
+       n_code_inputs,
+       n_code_outputs,
+       t_code_generators,
+       t_code_feedback);
+  } else {
+    t_encoder = new encoder_convolutional_ic1_ic1
+      (block_size_bits,
+       n_code_inputs,
+       n_code_outputs,
+       t_code_generators);
+  }
+
+  char** t_out = new char*[n_code_outputs];
+  for (int m = 0; m < n_code_outputs; m++) {
+    t_out[m] = new char[n_output_items];
+  }
+
+  t_encoder->encode (c_in, (char**) t_out, n_output_items);
+
+  for (int m = 0; m < n_code_outputs; m++) {
+    for (int n = 0; n < n_output_items; n++) {
+      CPPUNIT_ASSERT_EQUAL (c_res[m][n], t_out[m][n]);
+    }
+  }
+
+  delete t_encoder;
+  t_encoder = 0;
+
+  for (int m = 0; m < n_code_outputs; m++) {
+    delete [] t_out[m];
+    t_out[m] = 0;
+  }
+  delete [] t_out;
+  t_out = 0;
+}
+
+// TEST 0
+//
+// checking for SOAI realization (implicitely)
+// no feedback, no termination
+
+const static int t0_code_generator[6] = {1, 0, 5, 0, 1, 6};
+const static int t0_n_code_inputs = 3;
+const static int t0_n_code_outputs = 2;
+const static int t0_n_input_items = 10;
+const static int t0_n_output_items = 10;
+
+const static char t0_in_0[t0_n_input_items] =
+  {0, 1, 0, 0, 1, 0, 1, 0, 0, 0};
+const static char t0_in_1[t0_n_input_items] =
+  {0, 1, 0, 0, 0, 1, 1, 0, 0, 0};
+const static char t0_in_2[t0_n_input_items] =
+  {0, 0, 1, 1, 1, 1, 1, 0, 0, 0};
+const static char* t0_in[t0_n_code_inputs] =
+  {t0_in_0, t0_in_1, t0_in_2};
+
+const static char t0_res_0[t0_n_output_items] =
+  {0, 1, 1, 1, 1, 0, 1, 1, 1, 0};
+const static char t0_res_1[t0_n_output_items] =
+  {0, 1, 0, 1, 0, 1, 1, 0, 1, 0};
+const static char* t0_res[t0_n_code_outputs] =
+  {t0_res_0, t0_res_1};
+
+void
+qa_encoder_convolutional_ic1_ic1::t0
+()
+{
+  do_encoder_check ((const char**) t0_in, (const char**) t0_res,
+                   t0_n_output_items, 100, t0_n_code_inputs,
+                   t0_n_code_outputs, (const int*) t0_code_generator);
+}
+
+// TEST 1
+//
+// checking for SIAO realization (implicitely)
+// no feedback, no termination
+
+const static int t1_code_generator[6] = {1, 0, 0, 1, 5, 6};
+const static int t1_n_code_inputs = 2;
+const static int t1_n_code_outputs = 3;
+const static int t1_n_input_items = 9;
+const static int t1_n_output_items = 9;
+
+const static char t1_in_0[t1_n_input_items] =
+  {0, 1, 1, 1, 0, 0, 0, 1, 0};
+const static char t1_in_1[t1_n_input_items] =
+  {0, 0, 0, 0, 0, 1, 1, 1, 0};
+const static char* t1_in[t1_n_code_inputs] =
+  {t1_in_0, t1_in_1};
+
+const static char t1_res_0[t1_n_output_items] =
+  {0, 1, 1, 1, 0, 0, 0, 1, 0};
+const static char t1_res_1[t1_n_output_items] =
+  {0, 0, 0, 0, 0, 1, 1, 1, 0};
+const static char t1_res_2[t1_n_output_items] =
+  {0, 1, 1, 0, 1, 1, 1, 1, 0};
+const static char* t1_res[t1_n_code_outputs] =
+  {t1_res_0, t1_res_1, t1_res_2};
+
+void
+qa_encoder_convolutional_ic1_ic1::t1
+()
+{
+  do_encoder_check ((const char**) t1_in, (const char**) t1_res,
+                   t1_n_output_items, 100, t1_n_code_inputs,
+                   t1_n_code_outputs, (const int*) t1_code_generator);
+}
+
+// TEST 2
+//
+// checking for SIAO realization (implicitely)
+// with same feedback, no termination
+
+const static int t2_code_generator[6] = {1, 0, 0, 1, 5, 6};
+const static int t2_code_feedback[6] = {0, 0, 0, 0, 7, 7};
+const static int t2_n_code_inputs = 2;
+const static int t2_n_code_outputs = 3;
+const static int t2_n_input_items = 19;
+const static int t2_n_output_items = 19;
+
+const static char t2_in_0[t2_n_input_items] =
+  {0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0};
+const static char t2_in_1[t2_n_input_items] =
+  {0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 0};
+const static char* t2_in[t2_n_code_inputs] =
+  {t2_in_0, t2_in_1};
+
+const static char t2_res_0[t2_n_output_items] =
+  {0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0};
+const static char t2_res_1[t2_n_output_items] =
+  {0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 0};
+const static char t2_res_2[t2_n_output_items] =
+  {0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0};
+const static char* t2_res[t2_n_code_outputs] =
+  {t2_res_0, t2_res_1, t2_res_2};
+
+void
+qa_encoder_convolutional_ic1_ic1::t2
+()
+{
+  do_encoder_check ((const char**) t2_in, (const char**) t2_res,
+                   t2_n_output_items, 100, t2_n_code_inputs,
+                   t2_n_code_outputs, (const int*) t2_code_generator,
+                   (const int*) t2_code_feedback);
+}
+
+// TEST 3
+//
+// checking for SOAI realization (implicitely)
+// with same feedback, no termination
+
+const static int t3_code_generator[6] = {1, 0, 5, 0, 1, 6};
+const static int t3_code_feedback[6] = {0, 0, 7, 0, 0, 7};
+const static int t3_n_code_inputs = 3;
+const static int t3_n_code_outputs = 2;
+const static int t3_n_input_items = 17;
+const static int t3_n_output_items = 17;
+
+const static char t3_in_0[t3_n_input_items] =
+  {0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0};
+const static char t3_in_1[t3_n_input_items] =
+  {0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+const static char t3_in_2[t3_n_input_items] =
+  {0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0};
+const static char* t3_in[t3_n_code_inputs] =
+  {t3_in_0, t3_in_1, t3_in_2};
+
+const static char t3_res_0[t3_n_output_items] =
+  {0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0};
+const static char t3_res_1[t3_n_output_items] =
+  {0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0};
+const static char* t3_res[t3_n_code_outputs] =
+  {t3_res_0, t3_res_1};
+
+void
+qa_encoder_convolutional_ic1_ic1::t3
+()
+{
+  do_encoder_check ((const char**) t3_in, (const char**) t3_res,
+                   t3_n_output_items, 100, t3_n_code_inputs,
+                   t3_n_code_outputs, (const int*) t3_code_generator,
+                   (const int*) t3_code_feedback);
+}
+
+// TEST 4
+//
+// checking for SIAO realization (implicitely),
+// with different feedbacks, no termination
+
+const static int t4_code_generator[6] = {1, 4, 0, 3, 1, 6};
+const static int t4_code_feedback[6] = {0, 7, 0, 5, 0, 5};
+const static int t4_n_code_inputs = 2;
+const static int t4_n_code_outputs = 3;
+const static int t4_n_input_items = 20;
+const static int t4_n_output_items = 20;
+
+const static char t4_in_0[t4_n_input_items] =
+  {0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0};
+const static char t4_in_1[t4_n_input_items] =
+  {0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 0};
+const static char* t4_in[t4_n_code_inputs] =
+  {t4_in_0, t4_in_1};
+
+const static char t4_res_0[t4_n_output_items] =
+  {0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0};
+const static char t4_res_1[t4_n_output_items] =
+  {0, 0, 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 0, 0, 1, 0, 1, 1, 0, 0};
+const static char t4_res_2[t4_n_output_items] =
+  {0, 1, 0, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0};
+const static char* t4_res[t4_n_code_outputs] =
+  {t4_res_0, t4_res_1, t4_res_2};
+
+void
+qa_encoder_convolutional_ic1_ic1::t4
+()
+{
+  do_encoder_check ((const char**) t4_in, (const char**) t4_res,
+                   t4_n_output_items, 100, t4_n_code_inputs,
+                   t4_n_code_outputs, (const int*) t4_code_generator,
+                   (const int*) t4_code_feedback);
+}
+
+// TEST 5
+//
+// checking for SOAI realization (implicitely),
+// with different feedbacks, no termination
+
+const static int t5_code_generator[6] = {1, 0, 0, 1, 5, 7};
+const static int t5_code_feedback[6] = {0, 0, 0, 0, 7, 3};
+const static int t5_n_code_inputs = 2;
+const static int t5_n_code_outputs = 3;
+const static int t5_n_input_items = 19;
+const static int t5_n_output_items = 19;
+
+const static char t5_in_0[t5_n_input_items] =
+  {0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0};
+const static char t5_in_1[t5_n_input_items] =
+  {0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0};
+const static char* t5_in[t5_n_code_inputs] =
+  {t5_in_0, t5_in_1};
+
+const static char t5_res_0[t5_n_output_items] =
+  {0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0};
+const static char t5_res_1[t5_n_output_items] =
+  {0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0};
+const static char t5_res_2[t5_n_output_items] =
+  {0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0};
+const static char* t5_res[t5_n_code_outputs] =
+  {t5_res_0, t5_res_1, t5_res_2};
+
+void
+qa_encoder_convolutional_ic1_ic1::t5
+()
+{
+#if 0
+  do_encoder_check ((const char**) t5_in, (const char**) t5_res,
+                   t5_n_output_items, 100, t5_n_code_inputs,
+                   t5_n_code_outputs, (const int*) t5_code_generator);
+#endif
+}
+
+// TEST 6
+//
+// checking for termination, no feedback
+
+const static int t6_code_generator[6] = {1, 0, 5, 0, 1, 6};
+const static int t6_n_code_inputs = 3;
+const static int t6_n_code_outputs = 2;
+const static int t6_n_input_items = 6;
+const static int t6_n_output_items = 8;
+
+const static char t6_in_0[t6_n_input_items] =
+  {0, 1, 0, 0, 1, 0};
+const static char t6_in_1[t6_n_input_items] =
+  {0, 1, 0, 0, 0, 0};
+const static char t6_in_2[t6_n_input_items] =
+  {0, 0, 1, 1, 1, 0};
+const static char* t6_in[t6_n_code_inputs] =
+  {t6_in_0, t6_in_1, t6_in_2};
+
+const static char t6_res_0[t6_n_output_items] =
+  {0, 1, 1, 1, 1, 1, 1, 0};
+const static char t6_res_1[t6_n_output_items] =
+  {0, 1, 0, 1, 0, 0, 1, 0};
+const static char* t6_res[t6_n_code_outputs] =
+  {t6_res_0, t6_res_1};
+
+void
+qa_encoder_convolutional_ic1_ic1::t6
+()
+{
+  do_encoder_check ((const char**) t6_in, (const char**) t6_res,
+                   t6_n_output_items, 5, t6_n_code_inputs,
+                   t6_n_code_outputs, (const int*) t6_code_generator);
+}
+
+// TEST 7
+//
+// checking for termination, with same feedback
+
+const static int t7_code_generator[6] = {1, 0, 5, 0, 1, 6};
+const static int t7_code_feedback[6] = {0, 0, 7, 0, 0, 7};
+const static int t7_n_code_inputs = 3;
+const static int t7_n_code_outputs = 2;
+const static int t7_n_input_items = 17;
+const static int t7_n_output_items = 17;
+
+const static char t7_in_0[t7_n_input_items] =
+  {0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0};
+const static char t7_in_1[t7_n_input_items] =
+  {0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+const static char t7_in_2[t7_n_input_items] =
+  {0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0};
+const static char* t7_in[t7_n_code_inputs] =
+  {t7_in_0, t7_in_1, t7_in_2};
+
+const static char t7_res_0[t7_n_output_items] =
+  {0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0};
+const static char t7_res_1[t7_n_output_items] =
+  {0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0};
+const static char* t7_res[t7_n_code_outputs] =
+  {t7_res_0, t7_res_1};
+
+void
+qa_encoder_convolutional_ic1_ic1::t7
+()
+{
+#if 0
+  do_encoder_check ((const char**) t7_in, (const char**) t7_res,
+                   t7_n_output_items, 5, t7_n_code_inputs,
+                   t7_n_code_outputs, (const int*) t7_code_generator,
+                   (const int*) t7_code_feedback);
+#endif
+}
+
+// TEST 8
+//
+// checking for termination, with different feedback
+
+const static int t8_code_generator[6] = {1, 0, 5, 0, 1, 6};
+const static int t8_code_feedback[6] = {0, 0, 7, 0, 0, 3};
+const static int t8_n_code_inputs = 3;
+const static int t8_n_code_outputs = 2;
+const static int t8_n_input_items = 17;
+const static int t8_n_output_items = 17;
+
+const static char t8_in_0[t8_n_input_items] =
+  {0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0};
+const static char t8_in_1[t8_n_input_items] =
+  {0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+const static char t8_in_2[t8_n_input_items] =
+  {0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0};
+const static char* t8_in[t8_n_code_inputs] =
+  {t8_in_0, t8_in_1, t8_in_2};
+
+const static char t8_res_0[t8_n_output_items] =
+  {0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0};
+const static char t8_res_1[t8_n_output_items] =
+  {0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0};
+const static char* t8_res[t8_n_code_outputs] =
+  {t8_res_0, t8_res_1};
+
+void
+qa_encoder_convolutional_ic1_ic1::t8
+()
+{
+#if 0
+  do_encoder_check ((const char**) t8_in, (const char**) t8_res,
+                   t8_n_output_items, 5, t8_n_code_inputs,
+                   t8_n_code_outputs, (const int*) t8_code_generator,
+                   (const int*) t8_code_feedback);
+#endif
+}
diff --git a/gr-error-correcting-codes/src/lib/libecc/tests/qa_encoder_convolutional_ic1_ic1.h b/gr-error-correcting-codes/src/lib/libecc/tests/qa_encoder_convolutional_ic1_ic1.h
new file mode 100644 (file)
index 0000000..4449e9e
--- /dev/null
@@ -0,0 +1,65 @@
+/* -*- 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 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.
+ */
+
+#ifndef INCLUDED_QA_ENCODER_CONVOLUTIONAL_IC1_IC1_H
+#define INCLUDED_QA_ENCODER_CONVOLUTIONAL_IC1_IC1_H
+
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/TestCase.h>
+#include <stdexcept>
+
+class qa_encoder_convolutional_ic1_ic1 : public CppUnit::TestCase {
+
+  CPPUNIT_TEST_SUITE (qa_encoder_convolutional_ic1_ic1);
+  CPPUNIT_TEST (t0);
+  CPPUNIT_TEST (t1);
+  CPPUNIT_TEST (t2);
+  CPPUNIT_TEST (t3);
+  CPPUNIT_TEST (t4);
+  CPPUNIT_TEST (t5);
+  CPPUNIT_TEST (t6);
+  CPPUNIT_TEST (t7);
+  CPPUNIT_TEST (t8);
+  CPPUNIT_TEST_SUITE_END ();
+
+ private:
+  void do_encoder_check (const char** c_t1_in,
+                        const char** c_t1_res,
+                        int n_output_items,
+                        int block_size_bits,
+                        int n_code_inputs,
+                        int n_code_outputs,
+                        const int* code_generators,
+                        const int* code_feedback = 0);
+
+  void t0 ();
+  void t1 ();
+  void t2 ();
+  void t3 ();
+  void t4 ();
+  void t5 ();
+  void t6 ();
+  void t7 ();
+  void t8 ();
+};
+
+#endif /* INCLUDED_QA_ENCODER_CONVOLUTIONAL_IC1_IC1_H */
diff --git a/gr-error-correcting-codes/src/lib/libecc/tests/test_all.cc b/gr-error-correcting-codes/src/lib/libecc/tests/test_all.cc
new file mode 100644 (file)
index 0000000..2cd6f66
--- /dev/null
@@ -0,0 +1,38 @@
+/* -*- 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 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.
+ */
+
+#include <cppunit/TextTestRunner.h>
+#include <qa_ecc.h>
+
+int
+main
+(int argc,
+ char **argv)
+{
+  CppUnit::TextTestRunner runner;
+
+  runner.addTest (qa_ecc::suite ());
+
+  bool was_successful = runner.run ("", false);
+
+  return ((was_successful == true) ? 0 : 1);
+}
diff --git a/gr-error-correcting-codes/src/lib/qa_ecc.py b/gr-error-correcting-codes/src/lib/qa_ecc.py
new file mode 100755 (executable)
index 0000000..6f06c9d
--- /dev/null
@@ -0,0 +1,39 @@
+#!/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 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.
+# 
+
+from gnuradio import gr, gr_unittest, ecc
+
+class qa_ecc (gr_unittest.TestCase):
+
+    def setUp (self):
+        self.fg = gr.flow_graph ()
+
+    def tearDown (self):
+        self.fg = None
+
+    def test_000_nop (self):
+        """Just see if we can import the module...
+        They may not have drivers, etc.  Don't try to run anything"""
+        pass
+
+if __name__ == '__main__':
+    gr_unittest.main ()
diff --git a/gr-error-correcting-codes/src/python/Makefile.am b/gr-error-correcting-codes/src/python/Makefile.am
new file mode 100644 (file)
index 0000000..7c387f9
--- /dev/null
@@ -0,0 +1,32 @@
+#
+# 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 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.
+# 
+
+include $(top_srcdir)/Makefile.common
+
+EXTRA_DIST = run_tests.in
+
+TESTS = run_tests
+
+noinst_PYTHON =  qa_test_coding_1.py qa_test_coding_2.py
+
+grpython_PYTHON =
+
+MOSTLYCLEANFILES = *.pyc *~ run_tests
diff --git a/gr-error-correcting-codes/src/python/qa_test_coding_1.py b/gr-error-correcting-codes/src/python/qa_test_coding_1.py
new file mode 100755 (executable)
index 0000000..90c479d
--- /dev/null
@@ -0,0 +1,94 @@
+#!/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 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.
+# 
+
+from gnuradio import gr, audio
+from gnuradio.eng_option import eng_option
+from optparse import OptionParser
+# must be imported from local directory so that make check
+# can run before installation
+import ecc
+
+class my_graph(gr.flow_graph):
+
+    def __init__(self):
+        gr.flow_graph.__init__(self)
+
+        parser = OptionParser(option_class=eng_option)
+        parser.add_option("-O", "--audio-output", type="string", default="",
+                          help="pcm output device name.  E.g., hw:0,0 or /dev/dsp")
+        parser.add_option("-r", "--sample-rate", type="eng_float", default=48000,
+                          help="set sample rate to RATE (48000)")
+        (options, args) = parser.parse_args ()
+        if len(args) != 0:
+            parser.print_help()
+            raise SystemExit, 1
+
+        sample_rate = int(options.sample_rate)
+       audio_option = options.audio_output
+        src = audio.source (sample_rate, audio_option)
+       src_out_chan = src.output_signature().max_streams()
+        dst = audio.sink (sample_rate, str(src_out_chan))
+       dst_in_chan = dst.input_signature().max_streams()
+       audio_el_size = src.output_signature().sizeof_stream_item(1)
+       frame_size = 1000
+       do_mux_outputs = 0
+       enc_code_in_chan = src_out_chan
+       code_generators = [05, 06] #, 03, 04] # , 0, 07]
+       enc_code_out_chan = len (code_generators) / enc_code_in_chan
+       do_termination = 1
+
+       if do_mux_outputs == 1:
+           enc_dec_chan = 1
+       else:
+           enc_dec_chan = enc_code_out_chan
+
+       ss_enc = ecc.streams_encode_convolutional (frame_size,
+                                                  enc_code_in_chan,
+                                                  enc_code_out_chan,
+                                                  code_generators,
+                                                  do_termination)
+# for now
+       ss2s = gr.streams_to_stream (1, enc_dec_chan);
+       ns = gr.null_sink (1);
+# end for now
+
+#      ss_dec = error-correcting-codes.frames_to_streams (audio_el_size, 1, 1000)
+
+       for i in range (src_out_chan):
+           self.connect ((src, i), (ss_enc, i))
+# for now
+       for i in range (enc_dec_chan):
+           self.connect ((ss_enc, i), (ss2s, i))
+       self.connect (ss2s, ns)
+# end for now
+
+#      for i in range (enc_dec_chan):
+#          self.connect ((ss_enc, i), (ss_dec, i))
+
+#      for i in range (dst_in_chan):
+#          self.connect ((ss_dec, i), (dst, i))
+
+if __name__ == '__main__':
+    try:
+        my_graph().run()
+    except KeyboardInterrupt:
+        pass
diff --git a/gr-error-correcting-codes/src/python/qa_test_coding_2.py b/gr-error-correcting-codes/src/python/qa_test_coding_2.py
new file mode 100755 (executable)
index 0000000..1ddd50c
--- /dev/null
@@ -0,0 +1,91 @@
+#!/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 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.
+# 
+
+from gnuradio import gr, audio
+from gnuradio.eng_option import eng_option
+from optparse import OptionParser
+# must be imported from local directory so that make check
+# can run before installation
+import ecc
+
+class my_graph(gr.flow_graph):
+
+    def __init__(self):
+        gr.flow_graph.__init__(self)
+
+        parser = OptionParser(option_class=eng_option)
+        parser.add_option("-O", "--audio-output", type="string", default="",
+                          help="pcm output device name.  E.g., hw:0,0 or /dev/dsp")
+        parser.add_option("-r", "--sample-rate", type="eng_float", default=48000,
+                          help="set sample rate to RATE (48000)")
+        (options, args) = parser.parse_args ()
+        if len(args) != 0:
+            parser.print_help()
+            raise SystemExit, 1
+
+        sample_rate = int(options.sample_rate)
+       audio_option = options.audio_output
+        src = audio.source (sample_rate, audio_option)
+       enc_chan_in = 2
+       src_out_chan = src.output_signature().max_streams()
+        dst = audio.sink (sample_rate, str(enc_chan_in))
+       dst_in_chan = dst.input_signature().max_streams()
+       audio_el_size = dst.input_signature().sizeof_stream_item(0)
+       frame_size = 10
+       enc_code_in_chan = enc_chan_in
+       code_generators = [05, 06] #, 03, 04] #, 0, 07]
+       enc_code_out_chan = len (code_generators) / enc_code_in_chan
+       do_termination = 1
+
+       ss_enc = ecc.streams_encode_convolutional (frame_size,
+                                                  enc_code_in_chan,
+                                                  enc_code_out_chan,
+                                                  code_generators,
+                                                  do_termination)
+
+       for i in range (src_out_chan):
+           p2up = gr.packed_to_unpacked_bb (1, 1)
+           self.connect ((src, i), p2up, (ss_enc, i))
+
+       tau_bits = 0  # 0 -> decode all first
+       ss_dec = error-correcting-codes.dec_blk_conv_soft_full (audio_el_size,
+                                            frame_size,
+                                            do_termination,
+                                            do_mux_outputs,
+                                            enc_code_in_chan,
+                                            enc_code_out_chan,
+                                            code_generators)
+        up2bf0 = gr.chunks_to_symbols_bf ([1.0, -1.0])
+        self.connect ((ss_enc, 0), p2up0, up2bf0, (ss_dec, 0))
+        if enc_dec_chan > 1:
+           p2up1 = gr.packed_to_unpacked_bb (1, 1)
+           up2bf1 = gr.chunks_to_symbols_bf ([1.0, -1.0])
+           self.connect ((ss_enc, 1), p2up1, up2bf1, (ss_dec, 1))
+
+       for i in range (dst_in_chan):
+           self.connect ((ss_dec, i), (dst, i))
+
+if __name__ == '__main__':
+    try:
+        my_graph().run()
+    except KeyboardInterrupt:
+        pass
diff --git a/gr-error-correcting-codes/src/python/qa_test_encoder_convolutional_1.py b/gr-error-correcting-codes/src/python/qa_test_encoder_convolutional_1.py
new file mode 100755 (executable)
index 0000000..0eeca99
--- /dev/null
@@ -0,0 +1,74 @@
+#!/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 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.
+# 
+
+from gnuradio import gr, audio
+from gnuradio.eng_option import eng_option
+from optparse import OptionParser
+# must be imported from local directory so that make check
+# can run before installation
+import ecc
+
+class my_graph(gr.flow_graph):
+
+    def __init__(self):
+        gr.flow_graph.__init__(self)
+
+        parser = OptionParser(option_class=eng_option)
+        parser.add_option("-O", "--audio-output", type="string", default="",
+                          help="pcm output device name.  E.g., hw:0,0 or /dev/dsp")
+        parser.add_option("-r", "--sample-rate", type="eng_float", default=48000,
+                          help="set sample rate to RATE (48000)")
+        (options, args) = parser.parse_args ()
+        if len(args) != 0:
+            parser.print_help()
+            raise SystemExit, 1
+
+        sample_rate = int(options.sample_rate)
+       audio_option = options.audio_output
+        src = audio.source (sample_rate, audio_option)
+       src_out_chan = src.output_signature().max_streams()
+        dst = audio.sink (sample_rate, str(src_out_chan))
+       dst_in_chan = dst.input_signature().max_streams()
+       audio_el_size = src.output_signature().sizeof_stream_item(1)
+       frame_size = 10
+       enc_code_in_chan = src_out_chan
+       code_generators = [05, 06] #, 03, 04] # , 0, 07]
+       enc_code_out_chan = len (code_generators) / enc_code_in_chan
+       do_termination = 1
+
+       ss_enc = ecc.streams_encode_convolutional (frame_size,
+                                                  enc_code_in_chan,
+                                                  enc_code_out_chan,
+                                                  code_generators,
+                                                  do_termination)
+       for i in range (enc_code_in_chan):
+           self.connect ((src, i), (ss_enc, i))
+
+       for i in range (enc_code_out_chan):
+           ns = gr.null_sink (1)
+           self.connect ((ss_enc, i), ns)
+
+if __name__ == '__main__':
+    try:
+        my_graph().run()
+    except KeyboardInterrupt:
+        pass
diff --git a/gr-error-correcting-codes/src/python/qa_test_encoder_convolutional_2.py b/gr-error-correcting-codes/src/python/qa_test_encoder_convolutional_2.py
new file mode 100755 (executable)
index 0000000..f2ccadb
--- /dev/null
@@ -0,0 +1,35 @@
+#!/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 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.
+# 
+
+from gnuradio import gr
+from gnuradio.eng_option import eng_option
+import ecc
+
+def main ():
+       e1 = ecc.streams_encode_convolutional (100, 3, 2, [1, 0, 5, 0, 1, 6])
+
+       e2 = ecc.streams_encode_convolutional (100, 2, 3, [1, 0, 0, 1, 5, 6])
+
+       e3 = ecc.streams_encode_convolutional_feedback (100, 2, 3, [1, 7, 0, 1, 5, 6], [1, 1, 1, 1, 017, 017])
+
+if __name__ == '__main__':
+    main ()
diff --git a/gr-error-correcting-codes/src/python/run_tests.in b/gr-error-correcting-codes/src/python/run_tests.in
new file mode 100644 (file)
index 0000000..4618f76
--- /dev/null
@@ -0,0 +1,47 @@
+#!/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@/gr-error-correcting-codes/src/lib
+# Where to look in the src tree for swig generated python code
+libsrc=@abs_top_srcdir@/gr-error-correcting-codes/src/lib
+# Where to look in the src tree for hand written python code
+py=@abs_top_srcdir@/gr-error-correcting-codes/src/python
+
+# Where to look for GNU Radio python modules in current build tree
+# FIXME this is wrong on a distcheck.  We really need to ask gnuradio-core
+# where it put its python files.
+grpythonbld=@abs_top_builddir@/gnuradio-core/src/python/:@abs_top_builddir@/gnuradio-core/src/lib/swig/:@abs_top_builddir@/gnuradio-core/src/lib/swig/.libs
+
+PYTHONPATH="$grpythonbld:$libbld:$libbld/.libs:$libsrc:$py:$PYTHONPATH"
+export PYTHONPATH
+
+#
+# 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-gsm-fr-vocoder/AUTHORS b/gr-gsm-fr-vocoder/AUTHORS
new file mode 100644 (file)
index 0000000..11c18b4
--- /dev/null
@@ -0,0 +1,3 @@
+Eric Blossom <eb@comsec.com>           GNU Radio glue, Makefiles, etc.
+Jutta Degener <jutta@cs.tu-berlin.de>  GSM 06.10 vocoder
+Carsten Bormann <cabo@cs.tu-berlin.de> GSM 06.10 vocoder
diff --git a/gr-gsm-fr-vocoder/ChangeLog b/gr-gsm-fr-vocoder/ChangeLog
new file mode 100644 (file)
index 0000000..f0ed1e8
--- /dev/null
@@ -0,0 +1,45 @@
+2006-04-15  Eric Blossom  <eb@comsec.com>
+
+       * src/lib/gsm/config.h: modified to remove warnings.
+
+2005-07-02  Eric Blossom  <eb@comsec.com>
+
+       * config/gr_no_undefined.m4, config/gr_x86_64.m4: new, x86_64 support.
+       * config/gr_python.m4: backed out search for libpython, making
+       x86_64 work and breaking Cygwin/MinGW.
+       * configure.ac, src/lib/Makefile.am: mods for x86_64, $(NO_UNDEFINED)
+       
+2005-05-09  Stephane Fillod  <f8cfe@free.fr>
+
+        * config/gr_sysv_shm.m4: SysV shared memory not mandatory
+       * config/gr_pwin32.m4, config/gr_python.m4, config/lf_cxx.m4:
+         fixes for Cygwin, MinGW
+
+2005-01-29  Eric Blossom  <eb@comsec.com>
+
+       * src/lib/Makefile.am: mods for SWIG 1.3.24
+
+2005-01-20  Eric Blossom  <eb@comsec.com>
+
+       * doc/howto-write-a-block.xml: made release 0.1
+
+#
+# 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 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.
+# 
diff --git a/gr-gsm-fr-vocoder/INSTALL b/gr-gsm-fr-vocoder/INSTALL
new file mode 100644 (file)
index 0000000..54caf7c
--- /dev/null
@@ -0,0 +1,229 @@
+Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002 Free Software
+Foundation, Inc.
+
+   This file is free documentation; the Free Software Foundation gives
+unlimited permission to copy, distribute and modify it.
+
+Basic Installation
+==================
+
+   These are generic installation instructions.
+
+   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 only 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.  If you're
+     using `csh' on an old version of System V, you might need to type
+     `sh ./configure' instead to prevent `csh' from trying to execute
+     `configure' itself.
+
+     Running `configure' takes awhile.  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.
+
+  4. Type `make install' to install the programs and any data files and
+     documentation.
+
+  5. 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.
+
+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=c89 CFLAGS=-O2 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 must use a version of `make' that
+supports the `VPATH' variable, such as 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 `..'.
+
+   If you have to use a `make' that does not support the `VPATH'
+variable, you have 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.
+
+Installation Names
+==================
+
+   By default, `make install' will install the package's files in
+`/usr/local/bin', `/usr/local/man', etc.  You can specify an
+installation prefix other than `/usr/local' by giving `configure' the
+option `--prefix=PATH'.
+
+   You can specify separate installation prefixes for
+architecture-specific files and architecture-independent files.  If you
+give `configure' the option `--exec-prefix=PATH', the package will use
+PATH as the prefix for installing programs and libraries.
+Documentation and other data files will still use the regular prefix.
+
+   In addition, if you use an unusual directory layout you can give
+options like `--bindir=PATH' 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.
+
+   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'.
+
+Optional Features
+=================
+
+   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.
+
+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 `--target=TYPE' option 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
+
+will cause the specified gcc to be used as the C compiler (unless it is
+overridden in the site shell script).
+
+`configure' Invocation
+======================
+
+   `configure' recognizes the following options to control how it
+operates.
+
+`--help'
+`-h'
+     Print a summary of the options to `configure', and exit.
+
+`--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.
+
+`configure' also accepts some other, not widely useful, options.  Run
+`configure --help' for more details.
+
diff --git a/gr-gsm-fr-vocoder/Makefile.am b/gr-gsm-fr-vocoder/Makefile.am
new file mode 100644 (file)
index 0000000..9c64613
--- /dev/null
@@ -0,0 +1,25 @@
+#
+# 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.
+# 
+
+include $(top_srcdir)/Makefile.common
+
+SUBDIRS = src
+DIST_SUBDIRS = src
diff --git a/gr-gsm-fr-vocoder/src/Makefile.am b/gr-gsm-fr-vocoder/src/Makefile.am
new file mode 100644 (file)
index 0000000..122fc72
--- /dev/null
@@ -0,0 +1,22 @@
+#
+# 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.
+# 
+
+SUBDIRS = lib python
diff --git a/gr-gsm-fr-vocoder/src/lib/Makefile.am b/gr-gsm-fr-vocoder/src/lib/Makefile.am
new file mode 100644 (file)
index 0000000..974604d
--- /dev/null
@@ -0,0 +1,102 @@
+#
+# 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 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.
+# 
+
+include $(top_srcdir)/Makefile.common
+
+SUBDIRS = gsm .
+
+LIBS += $(GNURADIO_CORE_LIBS)
+
+# Install this stuff so that it ends up as the gnuradio.vocoder module
+# This usually ends up at:
+#   ${prefix}/lib/python${python_version}/site-packages/gnuradio/vocoder
+
+ourpythondir = $(grpythondir)/vocoder
+ourlibdir    = $(grpyexecdir)/vocoder
+
+INCLUDES = $(STD_DEFINES_AND_INCLUDES) $(PYTHON_CPPFLAGS)
+
+SWIGPYTHONARGS = $(SWIGPYTHONFLAGS) $(STD_DEFINES_AND_INCLUDES)
+
+
+ALL_IFILES =                           \
+       $(LOCAL_IFILES)                 \
+       $(NON_LOCAL_IFILES)             
+
+NON_LOCAL_IFILES =                     \
+       $(top_srcdir)/gnuradio-core/src/lib/swig/gnuradio.i
+
+
+LOCAL_IFILES =                                 \
+       gsm_full_rate.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 =                        \
+       gsm_full_rate.cc                \
+       gsm_full_rate.py                                
+
+# This gets gsm_full_rate.py installed in the right place
+ourpython_PYTHON =                     \
+       __init__.py                     \
+       gsm_full_rate.py
+
+ourlib_LTLIBRARIES = _gsm_full_rate.la
+
+# These are the source files that go into the shared library
+_gsm_full_rate_la_SOURCES =            \
+       gsm_fr_decode_ps.cc             \
+       gsm_fr_encode_sp.cc             \
+       gsm_full_rate.cc                
+
+
+# magic flags
+_gsm_full_rate_la_LDFLAGS = $(NO_UNDEFINED) -module -avoid-version
+
+# link the library against the gsm library and the
+# c++ standard library
+_gsm_full_rate_la_LIBADD =     \
+       gsm/libgsm.la           \
+       $(PYTHON_LDFLAGS)       \
+       -lstdc++                        
+
+gsm_full_rate.cc gsm_full_rate.py: gsm_full_rate.i $(ALL_IFILES)
+       $(SWIG) $(SWIGPYTHONARGS) -module gsm_full_rate -o gsm_full_rate.cc $<
+
+# These headers get installed in ${prefix}/include/gnuradio
+grinclude_HEADERS =                    \
+       gsm_fr_decode_ps.h              \
+       gsm_fr_encode_sp.h              
+
+# These swig headers get installed in ${prefix}/include/gnuradio/swig
+swiginclude_HEADERS =                  \
+       $(LOCAL_IFILES)
+
+
+MOSTLYCLEANFILES = $(BUILT_SOURCES) *.pyc
+
+# Don't distribute output of swig
+dist-hook:
+       @for file in $(BUILT_SOURCES); do echo $(RM) $(distdir)/$$file; done
+       @for file in $(BUILT_SOURCES); do $(RM) $(distdir)/$$file; done
+
diff --git a/gr-gsm-fr-vocoder/src/lib/__init__.py b/gr-gsm-fr-vocoder/src/lib/__init__.py
new file mode 100644 (file)
index 0000000..dde8414
--- /dev/null
@@ -0,0 +1,20 @@
+#
+# 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 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.
+# 
diff --git a/gr-gsm-fr-vocoder/src/lib/gsm/COPYRIGHT b/gr-gsm-fr-vocoder/src/lib/gsm/COPYRIGHT
new file mode 100644 (file)
index 0000000..eba0e52
--- /dev/null
@@ -0,0 +1,16 @@
+Copyright 1992, 1993, 1994 by Jutta Degener and Carsten Bormann,
+Technische Universitaet Berlin
+
+Any use of this software is permitted provided that this notice is not
+removed and that neither the authors nor the Technische Universitaet Berlin
+are deemed to have made any representations as to the suitability of this
+software for any purpose nor are held responsible for any defects of
+this software.  THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
+
+As a matter of courtesy, the authors request to be informed about uses
+this software has found, about bugs in this software, and about any
+improvements that may be of general interest.
+
+Berlin, 28.11.1994
+Jutta Degener
+Carsten Bormann
diff --git a/gr-gsm-fr-vocoder/src/lib/gsm/Makefile.am b/gr-gsm-fr-vocoder/src/lib/gsm/Makefile.am
new file mode 100644 (file)
index 0000000..0d718f3
--- /dev/null
@@ -0,0 +1,75 @@
+#
+# 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 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.
+# 
+
+include $(top_srcdir)/Makefile.common
+
+# Machine- or installation dependent flags you should configure to port
+
+SASR   = -DSASR
+######### Define SASR if >> is a signed arithmetic shift (-1 >> 1 == -1)
+
+MULHACK = -DUSE_FLOAT_MUL
+######### Define this if your host multiplies floats faster than integers,
+######### e.g. on a SPARCstation.
+
+FAST   = -DFAST
+######### Define together with USE_FLOAT_MUL to enable the GSM library's
+######### approximation option for incorrect, but good-enough results.
+
+# LTP_CUT      = -DLTP_CUT
+LTP_CUT        =
+######### Define to enable the GSM library's long-term correlation 
+######### approximation option---faster, but worse; works for
+######### both integer and floating point multiplications.
+######### This flag is still in the experimental stage.
+
+OPTIONS = $(SASR) $(MULHACK) $(FAST) $(LTP_CUT)
+
+INCLUDES = $(STD_DEFINES_AND_INCLUDES) -DNeedFunctionPrototypes=1 $(OPTIONS)
+
+noinst_LTLIBRARIES = libgsm.la
+
+libgsm_la_SOURCES =    \
+       add.c           \
+       code.c          \
+       debug.c         \
+       decode.c        \
+       gsm_create.c    \
+       gsm_decode.c    \
+       gsm_destroy.c   \
+       gsm_encode.c    \
+       gsm_explode.c   \
+       gsm_implode.c   \
+       gsm_option.c    \
+       gsm_print.c     \
+       long_term.c     \
+       lpc.c           \
+       preprocess.c    \
+       rpe.c           \
+       short_term.c    \
+       table.c         
+
+noinst_HEADERS =       \
+       config.h        \
+       gsm.h           \
+       private.h       \
+       proto.h         \
+       unproto.h       
diff --git a/gr-gsm-fr-vocoder/src/lib/gsm/README b/gr-gsm-fr-vocoder/src/lib/gsm/README
new file mode 100644 (file)
index 0000000..1927d87
--- /dev/null
@@ -0,0 +1,4 @@
+This code was extracted from gsm-1.0-pl10.tar.gz
+See COPYRIGHT for the copyright.
+
+See http://kbs.cs.tu-berlin.de/~jutta/toast.html for docs.
diff --git a/gr-gsm-fr-vocoder/src/lib/gsm/README.orig b/gr-gsm-fr-vocoder/src/lib/gsm/README.orig
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/lib/gsm/add.c b/gr-gsm-fr-vocoder/src/lib/gsm/add.c
new file mode 100644 (file)
index 0000000..21ccfab
--- /dev/null
@@ -0,0 +1,235 @@
+/*
+ * 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.
+ */
+
+/* $Header$ */
+
+/*
+ *  See private.h for the more commonly used macro versions.
+ */
+
+#include       <stdio.h>
+#include       <assert.h>
+
+#include       "private.h"
+#include       "gsm.h"
+#include       "proto.h"
+
+#define        saturate(x)     \
+       ((x) < MIN_WORD ? MIN_WORD : (x) > MAX_WORD ? MAX_WORD: (x))
+
+word gsm_add P2((a,b), word a, word b)
+{
+       longword sum = (longword)a + (longword)b;
+       return saturate(sum);
+}
+
+word gsm_sub P2((a,b), word a, word b)
+{
+       longword diff = (longword)a - (longword)b;
+       return saturate(diff);
+}
+
+word gsm_mult P2((a,b), word a, word b)
+{
+       if (a == MIN_WORD && b == MIN_WORD) return MAX_WORD;
+       else return SASR( (longword)a * (longword)b, 15 );
+}
+
+word gsm_mult_r P2((a,b), word a, word b)
+{
+       if (b == MIN_WORD && a == MIN_WORD) return MAX_WORD;
+       else {
+               longword prod = (longword)a * (longword)b + 16384;
+               prod >>= 15;
+               return prod & 0xFFFF;
+       }
+}
+
+word gsm_abs P1((a), word a)
+{
+       return a < 0 ? (a == MIN_WORD ? MAX_WORD : -a) : a;
+}
+
+longword gsm_L_mult P2((a,b),word a, word b)
+{
+       assert( a != MIN_WORD || b != MIN_WORD );
+       return ((longword)a * (longword)b) << 1;
+}
+
+longword gsm_L_add P2((a,b), longword a, longword b)
+{
+       if (a < 0) {
+               if (b >= 0) return a + b;
+               else {
+                       ulongword A = (ulongword)-(a + 1) + (ulongword)-(b + 1);
+                       return A >= MAX_LONGWORD ? MIN_LONGWORD :-(longword)A-2;
+               }
+       }
+       else if (b <= 0) return a + b;
+       else {
+               ulongword A = (ulongword)a + (ulongword)b;
+               return A > MAX_LONGWORD ? MAX_LONGWORD : A;
+       }
+}
+
+longword gsm_L_sub P2((a,b), longword a, longword b)
+{
+       if (a >= 0) {
+               if (b >= 0) return a - b;
+               else {
+                       /* a>=0, b<0 */
+
+                       ulongword A = (ulongword)a + -(b + 1);
+                       return A >= MAX_LONGWORD ? MAX_LONGWORD : (A + 1);
+               }
+       }
+       else if (b <= 0) return a - b;
+       else {
+               /* a<0, b>0 */  
+
+               ulongword A = (ulongword)-(a + 1) + b;
+               return A >= MAX_LONGWORD ? MIN_LONGWORD : -(longword)A - 1;
+       }
+}
+
+static unsigned char const bitoff[ 256 ] = {
+        8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4,
+        3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+        2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+        2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+word gsm_norm P1((a), longword a )
+/*
+ * the number of left shifts needed to normalize the 32 bit
+ * variable L_var1 for positive values on the interval
+ *
+ * with minimum of
+ * minimum of 1073741824  (01000000000000000000000000000000) and 
+ * maximum of 2147483647  (01111111111111111111111111111111)
+ *
+ *
+ * and for negative values on the interval with
+ * minimum of -2147483648 (-10000000000000000000000000000000) and
+ * maximum of -1073741824 ( -1000000000000000000000000000000).
+ *
+ * in order to normalize the result, the following
+ * operation must be done: L_norm_var1 = L_var1 << norm( L_var1 );
+ *
+ * (That's 'ffs', only from the left, not the right..)
+ */
+{
+       assert(a != 0);
+
+       if (a < 0) {
+               if (a <= -1073741824) return 0;
+               a = ~a;
+       }
+
+       return    a & 0xffff0000 
+               ? ( a & 0xff000000
+                 ?  -1 + bitoff[ 0xFF & (a >> 24) ]
+                 :   7 + bitoff[ 0xFF & (a >> 16) ] )
+               : ( a & 0xff00
+                 ?  15 + bitoff[ 0xFF & (a >> 8) ]
+                 :  23 + bitoff[ 0xFF & a ] );
+}
+
+longword gsm_L_asl P2((a,n), longword a, int n)
+{
+       if (n >= 32) return 0;
+       if (n <= -32) return -(a < 0);
+       if (n < 0) return gsm_L_asr(a, -n);
+       return a << n;
+}
+
+word gsm_asl P2((a,n), word a, int n)
+{
+       if (n >= 16) return 0;
+       if (n <= -16) return -(a < 0);
+       if (n < 0) return gsm_asr(a, -n);
+       return a << n;
+}
+
+longword gsm_L_asr P2((a,n), longword a, int n)
+{
+       if (n >= 32) return -(a < 0);
+       if (n <= -32) return 0;
+       if (n < 0) return a << -n;
+
+#      ifdef   SASR
+               return a >> n;
+#      else
+               if (a >= 0) return a >> n;
+               else return -(longword)( -(ulongword)a >> n );
+#      endif
+}
+
+word gsm_asr P2((a,n), word a, int n)
+{
+       if (n >= 16) return -(a < 0);
+       if (n <= -16) return 0;
+       if (n < 0) return a << -n;
+
+#      ifdef   SASR
+               return a >> n;
+#      else
+               if (a >= 0) return a >> n;
+               else return -(word)( -(uword)a >> n );
+#      endif
+}
+
+/* 
+ *  (From p. 46, end of section 4.2.5)
+ *
+ *  NOTE: The following lines gives [sic] one correct implementation
+ *       of the div(num, denum) arithmetic operation.  Compute div
+ *        which is the integer division of num by denum: with denum
+ *       >= num > 0
+ */
+
+word gsm_div P2((num,denum), word num, word denum)
+{
+       longword        L_num   = num;
+       longword        L_denum = denum;
+       word            div     = 0;
+       int             k       = 15;
+
+       /* The parameter num sometimes becomes zero.
+        * Although this is explicitly guarded against in 4.2.5,
+        * we assume that the result should then be zero as well.
+        */
+
+       /* assert(num != 0); */
+
+       assert(num >= 0 && denum >= num);
+       if (num == 0)
+           return 0;
+
+       while (k--) {
+               div   <<= 1;
+               L_num <<= 1;
+
+               if (L_num >= L_denum) {
+                       L_num -= L_denum;
+                       div++;
+               }
+       }
+
+       return div;
+}
diff --git a/gr-gsm-fr-vocoder/src/lib/gsm/code.c b/gr-gsm-fr-vocoder/src/lib/gsm/code.c
new file mode 100644 (file)
index 0000000..7395542
--- /dev/null
@@ -0,0 +1,99 @@
+/*
+ * 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.
+ */
+
+/* $Header$ */
+
+#include       "config.h"
+
+
+#ifdef HAS_STDLIB_H
+#include       <stdlib.h>
+#else
+#      include "proto.h"
+       extern char     * memcpy P((char *, char *, int));
+#endif
+
+#include       "private.h"
+#include       "gsm.h"
+#include       "proto.h"
+
+/* 
+ *  4.2 FIXED POINT IMPLEMENTATION OF THE RPE-LTP CODER 
+ */
+
+void Gsm_Coder P8((S,s,LARc,Nc,bc,Mc,xmaxc,xMc),
+
+       struct gsm_state        * S,
+
+       word    * s,    /* [0..159] samples                     IN      */
+
+/*
+ * The RPE-LTD coder works on a frame by frame basis.  The length of
+ * the frame is equal to 160 samples.  Some computations are done
+ * once per frame to produce at the output of the coder the
+ * LARc[1..8] parameters which are the coded LAR coefficients and 
+ * also to realize the inverse filtering operation for the entire
+ * frame (160 samples of signal d[0..159]).  These parts produce at
+ * the output of the coder:
+ */
+
+       word    * LARc, /* [0..7] LAR coefficients              OUT     */
+
+/*
+ * Procedure 4.2.11 to 4.2.18 are to be executed four times per
+ * frame.  That means once for each sub-segment RPE-LTP analysis of
+ * 40 samples.  These parts produce at the output of the coder:
+ */
+
+       word    * Nc,   /* [0..3] LTP lag                       OUT     */
+       word    * bc,   /* [0..3] coded LTP gain                OUT     */
+       word    * Mc,   /* [0..3] RPE grid selection            OUT     */
+       word    * xmaxc,/* [0..3] Coded maximum amplitude       OUT     */
+       word    * xMc   /* [13*4] normalized RPE samples        OUT     */
+)
+{
+       int     k;
+       word    * dp  = S->dp0 + 120;   /* [ -120...-1 ] */
+       word    * dpp = dp;             /* [ 0...39 ]    */
+
+       static word e[50];
+
+       word    so[160];
+
+       Gsm_Preprocess                  (S, s, so);
+       Gsm_LPC_Analysis                (S, so, LARc);
+       Gsm_Short_Term_Analysis_Filter  (S, LARc, so);
+
+       for (k = 0; k <= 3; k++, xMc += 13) {
+
+               Gsm_Long_Term_Predictor ( S,
+                                        so+k*40, /* d      [0..39] IN  */
+                                        dp,      /* dp  [-120..-1] IN  */
+                                       e + 5,    /* e      [0..39] OUT */
+                                       dpp,      /* dpp    [0..39] OUT */
+                                        Nc++,
+                                        bc++);
+
+               Gsm_RPE_Encoding        ( S,
+                                       e + 5,  /* e      ][0..39][ IN/OUT */
+                                         xmaxc++, Mc++, xMc );
+               /*
+                * Gsm_Update_of_reconstructed_short_time_residual_signal
+                *                      ( dpp, e + 5, dp );
+                */
+
+               { register int i;
+                 register longword ltmp;
+                 for (i = 0; i <= 39; i++)
+                       dp[ i ] = GSM_ADD( e[5 + i], dpp[i] );
+               }
+               dp  += 40;
+               dpp += 40;
+
+       }
+       (void)memcpy( (char *)S->dp0, (char *)(S->dp0 + 160),
+               120 * sizeof(*S->dp0) );
+}
diff --git a/gr-gsm-fr-vocoder/src/lib/gsm/config.h b/gr-gsm-fr-vocoder/src/lib/gsm/config.h
new file mode 100644 (file)
index 0000000..2a962ac
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * 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.
+ */
+
+/*$Header$*/
+
+#ifndef        CONFIG_H
+#define        CONFIG_H
+
+#undef SIGHANDLER_T                    /* signal handlers are void     */
+#undef HAS_SYSV_SIGNAL                 /* sigs not blocked/reset?      */
+
+#define        HAS_STDLIB_H    1               /* /usr/include/stdlib.h        */
+#undef HAS_LIMITS_H                    /* /usr/include/limits.h        */
+#define        HAS_FCNTL_H     1               /* /usr/include/fcntl.h         */
+#undef HAS_ERRNO_DECL                  /* errno.h declares errno       */
+
+#define        HAS_FSTAT       1               /* fstat syscall                */
+#define        HAS_FCHMOD      1               /* fchmod syscall               */
+#define        HAS_CHMOD       1               /* chmod syscall                */
+#define        HAS_FCHOWN      1               /* fchown syscall               */
+#define        HAS_CHOWN       1               /* chown syscall                */
+#undef HAS__FSETMODE                   /* _fsetmode -- set file mode   */
+
+#define        HAS_STRING_H    1               /* /usr/include/string.h        */
+#undef HAS_STRINGS_H                   /* /usr/include/strings.h       */
+
+#define        HAS_UNISTD_H    1               /* /usr/include/unistd.h        */
+#define        HAS_UTIME       1               /* POSIX utime(path, times)     */
+#undef HAS_UTIMES                      /* use utimes() syscall instead */
+#define        HAS_UTIME_H     1               /* UTIME header file            */
+#undef HAS_UTIMBUF                     /* struct utimbuf               */
+#undef HAS_UTIMEUSEC                   /* microseconds in utimbuf?     */
+
+#endif /* CONFIG_H */
diff --git a/gr-gsm-fr-vocoder/src/lib/gsm/debug.c b/gr-gsm-fr-vocoder/src/lib/gsm/debug.c
new file mode 100644 (file)
index 0000000..e052104
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * 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.
+ */
+
+/* $Header$ */
+
+#include "private.h"
+
+#ifndef        NDEBUG
+
+/* If NDEBUG _is_ defined and no debugging should be performed,
+ * calls to functions in this module are #defined to nothing
+ * in private.h.
+ */
+
+#include <stdio.h>
+#include "proto.h"
+
+void gsm_debug_words P4( (name, from, to, ptr), 
+       char          * name,
+       int             from,
+       int             to,
+       word            * ptr)
+{
+       int     nprinted = 0;
+
+       fprintf( stderr, "%s [%d .. %d]: ", name, from, to );
+       while (from <= to) {
+               fprintf(stderr, "%d ", ptr[ from ] );
+               from++;
+               if (nprinted++ >= 7) {
+                       nprinted = 0;
+                       if (from < to) putc('\n', stderr);
+               }
+       }
+       putc('\n', stderr);
+}
+
+void gsm_debug_longwords P4( (name, from, to, ptr),
+       char          * name,
+       int             from,
+       int             to,
+       longword      * ptr)
+{
+       int     nprinted = 0;
+
+       fprintf( stderr, "%s [%d .. %d]: ", name, from, to );
+       while (from <= to) {
+
+               fprintf(stderr, "%ld ", ptr[ from ] );
+               from++;
+               if (nprinted++ >= 7) {
+                       nprinted = 0;
+                       if (from < to) putc('\n', stderr);
+               }
+       }
+       putc('\n', stderr);
+}
+
+void gsm_debug_longword P2(  (name, value),
+       char            * name,
+       longword          value )
+{
+       fprintf(stderr, "%s: %ld\n", name, (long)value );
+}
+
+void gsm_debug_word P2(  (name, value),
+       char    * name,
+       word      value )
+{
+       fprintf(stderr, "%s: %ld\n", name, (long)value);
+}
+
+#endif
diff --git a/gr-gsm-fr-vocoder/src/lib/gsm/decode.c b/gr-gsm-fr-vocoder/src/lib/gsm/decode.c
new file mode 100644 (file)
index 0000000..34e5586
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * 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.
+ */
+
+/* $Header$ */
+
+#include <stdio.h>
+
+#include       "private.h"
+#include       "gsm.h"
+#include       "proto.h"
+
+/*
+ *  4.3 FIXED POINT IMPLEMENTATION OF THE RPE-LTP DECODER
+ */
+
+static void Postprocessing P2((S,s),
+       struct gsm_state        * S,
+       register word           * s)
+{
+       register int            k;
+       register word           msr = S->msr;
+       register longword       ltmp;   /* for GSM_ADD */
+       register word           tmp;
+
+       for (k = 160; k--; s++) {
+               tmp = GSM_MULT_R( msr, 28180 );
+               msr = GSM_ADD(*s, tmp);            /* Deemphasis             */
+               *s  = GSM_ADD(msr, msr) & 0xFFF8;  /* Truncation & Upscaling */
+       }
+       S->msr = msr;
+}
+
+void Gsm_Decoder P8((S,LARcr, Ncr,bcr,Mcr,xmaxcr,xMcr,s),
+       struct gsm_state        * S,
+
+       word            * LARcr,        /* [0..7]               IN      */
+
+       word            * Ncr,          /* [0..3]               IN      */
+       word            * bcr,          /* [0..3]               IN      */
+       word            * Mcr,          /* [0..3]               IN      */
+       word            * xmaxcr,       /* [0..3]               IN      */
+       word            * xMcr,         /* [0..13*4]            IN      */
+
+       word            * s)            /* [0..159]             OUT     */
+{
+       int             j, k;
+       word            erp[40], wt[160];
+       word            * drp = S->dp0 + 120;
+
+       for (j=0; j <= 3; j++, xmaxcr++, bcr++, Ncr++, Mcr++, xMcr += 13) {
+
+               Gsm_RPE_Decoding( S, *xmaxcr, *Mcr, xMcr, erp );
+               Gsm_Long_Term_Synthesis_Filtering( S, *Ncr, *bcr, erp, drp );
+
+               for (k = 0; k <= 39; k++) wt[ j * 40 + k ] =  drp[ k ];
+       }
+
+       Gsm_Short_Term_Synthesis_Filter( S, LARcr, wt, s );
+       Postprocessing(S, s);
+}
diff --git a/gr-gsm-fr-vocoder/src/lib/gsm/gsm.h b/gr-gsm-fr-vocoder/src/lib/gsm/gsm.h
new file mode 100644 (file)
index 0000000..990e42a
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ * 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.
+ */
+
+/*$Header$*/
+
+#ifndef        GSM_H
+#define        GSM_H
+
+#ifdef __cplusplus
+#      define  NeedFunctionPrototypes  1
+#endif
+
+#if __STDC__
+#      define  NeedFunctionPrototypes  1
+#endif
+
+#ifdef _NO_PROTO
+#      undef   NeedFunctionPrototypes
+#endif
+
+#ifdef NeedFunctionPrototypes
+#   include    <stdio.h>               /* for FILE *   */
+#endif
+
+#undef GSM_P
+#if NeedFunctionPrototypes
+#      define  GSM_P( protos ) protos
+#else
+#      define  GSM_P( protos ) ( /* protos */ )
+#endif
+
+/*
+ *     Interface
+ */
+
+typedef struct gsm_state *     gsm;
+typedef short                  gsm_signal;             /* signed 16 bit */
+typedef unsigned char          gsm_byte;
+typedef gsm_byte               gsm_frame[33];          /* 33 * 8 bits   */
+
+#define        GSM_MAGIC               0xD                     /* 13 kbit/s RPE-LTP */
+
+#define        GSM_PATCHLEVEL          10
+#define        GSM_MINOR               0
+#define        GSM_MAJOR               1
+
+#define        GSM_OPT_VERBOSE         1
+#define        GSM_OPT_FAST            2
+#define        GSM_OPT_LTP_CUT         3
+#define        GSM_OPT_WAV49           4
+#define        GSM_OPT_FRAME_INDEX     5
+#define        GSM_OPT_FRAME_CHAIN     6
+
+#define GSM_SAMPLES_PER_FRAME  160
+
+extern gsm  gsm_create         GSM_P((void));
+extern void gsm_destroy GSM_P((gsm));  
+
+extern int  gsm_print   GSM_P((FILE *, gsm, gsm_byte  *));
+extern int  gsm_option  GSM_P((gsm, int, int *));
+
+extern void gsm_encode  GSM_P((gsm, gsm_signal *, gsm_byte  *));
+extern int  gsm_decode  GSM_P((gsm, gsm_byte   *, gsm_signal *));
+
+extern int  gsm_explode GSM_P((gsm, gsm_byte   *, gsm_signal *));
+extern void gsm_implode GSM_P((gsm, gsm_signal *, gsm_byte   *));
+
+#undef GSM_P
+
+#endif /* GSM_H */
diff --git a/gr-gsm-fr-vocoder/src/lib/gsm/gsm_create.c b/gr-gsm-fr-vocoder/src/lib/gsm/gsm_create.c
new file mode 100644 (file)
index 0000000..a59aa2f
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * 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.
+ */
+
+static char const      ident[] = "$Header$";
+
+#include       "config.h"
+
+#ifdef HAS_STRING_H
+#include       <string.h>
+#else
+#      include "proto.h"
+       extern char     * memset P((char *, int, int));
+#endif
+
+#ifdef HAS_STDLIB_H
+#      include <stdlib.h>
+#else
+#      ifdef   HAS_MALLOC_H
+#              include         <malloc.h>
+#      else
+               extern char * malloc();
+#      endif
+#endif
+
+#include <stdio.h>
+
+#include "gsm.h"
+#include "private.h"
+#include "proto.h"
+
+gsm gsm_create P0()
+{
+       gsm  r;
+
+       r = (gsm)malloc(sizeof(struct gsm_state));
+       if (!r) return r;
+
+       memset((char *)r, 0, sizeof(*r));
+       r->nrp = 40;
+
+       return r;
+}
diff --git a/gr-gsm-fr-vocoder/src/lib/gsm/gsm_decode.c b/gr-gsm-fr-vocoder/src/lib/gsm/gsm_decode.c
new file mode 100644 (file)
index 0000000..7318ba2
--- /dev/null
@@ -0,0 +1,361 @@
+/*
+ * 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.
+ */
+
+/* $Header$ */
+
+#include "private.h"
+
+#include "gsm.h"
+#include "proto.h"
+
+int gsm_decode P3((s, c, target), gsm s, gsm_byte * c, gsm_signal * target)
+{
+       word    LARc[8], Nc[4], Mc[4], bc[4], xmaxc[4], xmc[13*4];
+
+#ifdef WAV49
+       if (s->wav_fmt) {
+
+               uword sr = 0;
+
+               s->frame_index = !s->frame_index;
+               if (s->frame_index) {
+
+                       sr = *c++;
+                       LARc[0] = sr & 0x3f;  sr >>= 6;
+                       sr |= (uword)*c++ << 2;
+                       LARc[1] = sr & 0x3f;  sr >>= 6;
+                       sr |= (uword)*c++ << 4;
+                       LARc[2] = sr & 0x1f;  sr >>= 5;
+                       LARc[3] = sr & 0x1f;  sr >>= 5;
+                       sr |= (uword)*c++ << 2;
+                       LARc[4] = sr & 0xf;  sr >>= 4;
+                       LARc[5] = sr & 0xf;  sr >>= 4;
+                       sr |= (uword)*c++ << 2;                 /* 5 */
+                       LARc[6] = sr & 0x7;  sr >>= 3;
+                       LARc[7] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 4;
+                       Nc[0] = sr & 0x7f;  sr >>= 7;
+                       bc[0] = sr & 0x3;  sr >>= 2;
+                       Mc[0] = sr & 0x3;  sr >>= 2;
+                       sr |= (uword)*c++ << 1;
+                       xmaxc[0] = sr & 0x3f;  sr >>= 6;
+                       xmc[0] = sr & 0x7;  sr >>= 3;
+                       sr = *c++;
+                       xmc[1] = sr & 0x7;  sr >>= 3;
+                       xmc[2] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 2;
+                       xmc[3] = sr & 0x7;  sr >>= 3;
+                       xmc[4] = sr & 0x7;  sr >>= 3;
+                       xmc[5] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 1;                 /* 10 */
+                       xmc[6] = sr & 0x7;  sr >>= 3;
+                       xmc[7] = sr & 0x7;  sr >>= 3;
+                       xmc[8] = sr & 0x7;  sr >>= 3;
+                       sr = *c++;
+                       xmc[9] = sr & 0x7;  sr >>= 3;
+                       xmc[10] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 2;
+                       xmc[11] = sr & 0x7;  sr >>= 3;
+                       xmc[12] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 4;
+                       Nc[1] = sr & 0x7f;  sr >>= 7;
+                       bc[1] = sr & 0x3;  sr >>= 2;
+                       Mc[1] = sr & 0x3;  sr >>= 2;
+                       sr |= (uword)*c++ << 1;
+                       xmaxc[1] = sr & 0x3f;  sr >>= 6;
+                       xmc[13] = sr & 0x7;  sr >>= 3;
+                       sr = *c++;                              /* 15 */
+                       xmc[14] = sr & 0x7;  sr >>= 3;
+                       xmc[15] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 2;
+                       xmc[16] = sr & 0x7;  sr >>= 3;
+                       xmc[17] = sr & 0x7;  sr >>= 3;
+                       xmc[18] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 1;
+                       xmc[19] = sr & 0x7;  sr >>= 3;
+                       xmc[20] = sr & 0x7;  sr >>= 3;
+                       xmc[21] = sr & 0x7;  sr >>= 3;
+                       sr = *c++;
+                       xmc[22] = sr & 0x7;  sr >>= 3;
+                       xmc[23] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 2;
+                       xmc[24] = sr & 0x7;  sr >>= 3;
+                       xmc[25] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 4;                 /* 20 */
+                       Nc[2] = sr & 0x7f;  sr >>= 7;
+                       bc[2] = sr & 0x3;  sr >>= 2;
+                       Mc[2] = sr & 0x3;  sr >>= 2;
+                       sr |= (uword)*c++ << 1;
+                       xmaxc[2] = sr & 0x3f;  sr >>= 6;
+                       xmc[26] = sr & 0x7;  sr >>= 3;
+                       sr = *c++;
+                       xmc[27] = sr & 0x7;  sr >>= 3;
+                       xmc[28] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 2;
+                       xmc[29] = sr & 0x7;  sr >>= 3;
+                       xmc[30] = sr & 0x7;  sr >>= 3;
+                       xmc[31] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 1;
+                       xmc[32] = sr & 0x7;  sr >>= 3;
+                       xmc[33] = sr & 0x7;  sr >>= 3;
+                       xmc[34] = sr & 0x7;  sr >>= 3;
+                       sr = *c++;                              /* 25 */
+                       xmc[35] = sr & 0x7;  sr >>= 3;
+                       xmc[36] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 2;
+                       xmc[37] = sr & 0x7;  sr >>= 3;
+                       xmc[38] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 4;
+                       Nc[3] = sr & 0x7f;  sr >>= 7;
+                       bc[3] = sr & 0x3;  sr >>= 2;
+                       Mc[3] = sr & 0x3;  sr >>= 2;
+                       sr |= (uword)*c++ << 1;
+                       xmaxc[3] = sr & 0x3f;  sr >>= 6;
+                       xmc[39] = sr & 0x7;  sr >>= 3;
+                       sr = *c++;
+                       xmc[40] = sr & 0x7;  sr >>= 3;
+                       xmc[41] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 2;                 /* 30 */
+                       xmc[42] = sr & 0x7;  sr >>= 3;
+                       xmc[43] = sr & 0x7;  sr >>= 3;
+                       xmc[44] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 1;
+                       xmc[45] = sr & 0x7;  sr >>= 3;
+                       xmc[46] = sr & 0x7;  sr >>= 3;
+                       xmc[47] = sr & 0x7;  sr >>= 3;
+                       sr = *c++;
+                       xmc[48] = sr & 0x7;  sr >>= 3;
+                       xmc[49] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 2;
+                       xmc[50] = sr & 0x7;  sr >>= 3;
+                       xmc[51] = sr & 0x7;  sr >>= 3;
+
+                       s->frame_chain = sr & 0xf;
+               }
+               else {
+                       sr = s->frame_chain;
+                       sr |= (uword)*c++ << 4;                 /* 1 */
+                       LARc[0] = sr & 0x3f;  sr >>= 6;
+                       LARc[1] = sr & 0x3f;  sr >>= 6;
+                       sr = *c++;
+                       LARc[2] = sr & 0x1f;  sr >>= 5;
+                       sr |= (uword)*c++ << 3;
+                       LARc[3] = sr & 0x1f;  sr >>= 5;
+                       LARc[4] = sr & 0xf;  sr >>= 4;
+                       sr |= (uword)*c++ << 2;
+                       LARc[5] = sr & 0xf;  sr >>= 4;
+                       LARc[6] = sr & 0x7;  sr >>= 3;
+                       LARc[7] = sr & 0x7;  sr >>= 3;
+                       sr = *c++;                              /* 5 */
+                       Nc[0] = sr & 0x7f;  sr >>= 7;
+                       sr |= (uword)*c++ << 1;
+                       bc[0] = sr & 0x3;  sr >>= 2;
+                       Mc[0] = sr & 0x3;  sr >>= 2;
+                       sr |= (uword)*c++ << 5;
+                       xmaxc[0] = sr & 0x3f;  sr >>= 6;
+                       xmc[0] = sr & 0x7;  sr >>= 3;
+                       xmc[1] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 1;
+                       xmc[2] = sr & 0x7;  sr >>= 3;
+                       xmc[3] = sr & 0x7;  sr >>= 3;
+                       xmc[4] = sr & 0x7;  sr >>= 3;
+                       sr = *c++;
+                       xmc[5] = sr & 0x7;  sr >>= 3;
+                       xmc[6] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 2;                 /* 10 */
+                       xmc[7] = sr & 0x7;  sr >>= 3;
+                       xmc[8] = sr & 0x7;  sr >>= 3;
+                       xmc[9] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 1;
+                       xmc[10] = sr & 0x7;  sr >>= 3;
+                       xmc[11] = sr & 0x7;  sr >>= 3;
+                       xmc[12] = sr & 0x7;  sr >>= 3;
+                       sr = *c++;
+                       Nc[1] = sr & 0x7f;  sr >>= 7;
+                       sr |= (uword)*c++ << 1;
+                       bc[1] = sr & 0x3;  sr >>= 2;
+                       Mc[1] = sr & 0x3;  sr >>= 2;
+                       sr |= (uword)*c++ << 5;
+                       xmaxc[1] = sr & 0x3f;  sr >>= 6;
+                       xmc[13] = sr & 0x7;  sr >>= 3;
+                       xmc[14] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 1;                 /* 15 */
+                       xmc[15] = sr & 0x7;  sr >>= 3;
+                       xmc[16] = sr & 0x7;  sr >>= 3;
+                       xmc[17] = sr & 0x7;  sr >>= 3;
+                       sr = *c++;
+                       xmc[18] = sr & 0x7;  sr >>= 3;
+                       xmc[19] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 2;
+                       xmc[20] = sr & 0x7;  sr >>= 3;
+                       xmc[21] = sr & 0x7;  sr >>= 3;
+                       xmc[22] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 1;
+                       xmc[23] = sr & 0x7;  sr >>= 3;
+                       xmc[24] = sr & 0x7;  sr >>= 3;
+                       xmc[25] = sr & 0x7;  sr >>= 3;
+                       sr = *c++;
+                       Nc[2] = sr & 0x7f;  sr >>= 7;
+                       sr |= (uword)*c++ << 1;                 /* 20 */
+                       bc[2] = sr & 0x3;  sr >>= 2;
+                       Mc[2] = sr & 0x3;  sr >>= 2;
+                       sr |= (uword)*c++ << 5;
+                       xmaxc[2] = sr & 0x3f;  sr >>= 6;
+                       xmc[26] = sr & 0x7;  sr >>= 3;
+                       xmc[27] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 1; 
+                       xmc[28] = sr & 0x7;  sr >>= 3;
+                       xmc[29] = sr & 0x7;  sr >>= 3;
+                       xmc[30] = sr & 0x7;  sr >>= 3;
+                       sr = *c++;
+                       xmc[31] = sr & 0x7;  sr >>= 3;
+                       xmc[32] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 2;
+                       xmc[33] = sr & 0x7;  sr >>= 3;
+                       xmc[34] = sr & 0x7;  sr >>= 3;
+                       xmc[35] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 1;                 /* 25 */
+                       xmc[36] = sr & 0x7;  sr >>= 3;
+                       xmc[37] = sr & 0x7;  sr >>= 3;
+                       xmc[38] = sr & 0x7;  sr >>= 3;
+                       sr = *c++;
+                       Nc[3] = sr & 0x7f;  sr >>= 7;
+                       sr |= (uword)*c++ << 1;         
+                       bc[3] = sr & 0x3;  sr >>= 2;
+                       Mc[3] = sr & 0x3;  sr >>= 2;
+                       sr |= (uword)*c++ << 5;
+                       xmaxc[3] = sr & 0x3f;  sr >>= 6;
+                       xmc[39] = sr & 0x7;  sr >>= 3;
+                       xmc[40] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 1;
+                       xmc[41] = sr & 0x7;  sr >>= 3;
+                       xmc[42] = sr & 0x7;  sr >>= 3;
+                       xmc[43] = sr & 0x7;  sr >>= 3;
+                       sr = *c++;                              /* 30 */
+                       xmc[44] = sr & 0x7;  sr >>= 3;
+                       xmc[45] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 2;
+                       xmc[46] = sr & 0x7;  sr >>= 3;
+                       xmc[47] = sr & 0x7;  sr >>= 3;
+                       xmc[48] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 1;
+                       xmc[49] = sr & 0x7;  sr >>= 3;
+                       xmc[50] = sr & 0x7;  sr >>= 3;
+                       xmc[51] = sr & 0x7;  sr >>= 3;
+               }
+       }
+       else
+#endif
+       {
+               /* GSM_MAGIC  = (*c >> 4) & 0xF; */
+
+               if (((*c >> 4) & 0x0F) != GSM_MAGIC) return -1;
+
+               LARc[0]  = (*c++ & 0xF) << 2;           /* 1 */
+               LARc[0] |= (*c >> 6) & 0x3;
+               LARc[1]  = *c++ & 0x3F;
+               LARc[2]  = (*c >> 3) & 0x1F;
+               LARc[3]  = (*c++ & 0x7) << 2;
+               LARc[3] |= (*c >> 6) & 0x3;
+               LARc[4]  = (*c >> 2) & 0xF;
+               LARc[5]  = (*c++ & 0x3) << 2;
+               LARc[5] |= (*c >> 6) & 0x3;
+               LARc[6]  = (*c >> 3) & 0x7;
+               LARc[7]  = *c++ & 0x7;
+               Nc[0]  = (*c >> 1) & 0x7F;
+               bc[0]  = (*c++ & 0x1) << 1;
+               bc[0] |= (*c >> 7) & 0x1;
+               Mc[0]  = (*c >> 5) & 0x3;
+               xmaxc[0]  = (*c++ & 0x1F) << 1;
+               xmaxc[0] |= (*c >> 7) & 0x1;
+               xmc[0]  = (*c >> 4) & 0x7;
+               xmc[1]  = (*c >> 1) & 0x7;
+               xmc[2]  = (*c++ & 0x1) << 2;
+               xmc[2] |= (*c >> 6) & 0x3;
+               xmc[3]  = (*c >> 3) & 0x7;
+               xmc[4]  = *c++ & 0x7;
+               xmc[5]  = (*c >> 5) & 0x7;
+               xmc[6]  = (*c >> 2) & 0x7;
+               xmc[7]  = (*c++ & 0x3) << 1;            /* 10 */
+               xmc[7] |= (*c >> 7) & 0x1;
+               xmc[8]  = (*c >> 4) & 0x7;
+               xmc[9]  = (*c >> 1) & 0x7;
+               xmc[10]  = (*c++ & 0x1) << 2;
+               xmc[10] |= (*c >> 6) & 0x3;
+               xmc[11]  = (*c >> 3) & 0x7;
+               xmc[12]  = *c++ & 0x7;
+               Nc[1]  = (*c >> 1) & 0x7F;
+               bc[1]  = (*c++ & 0x1) << 1;
+               bc[1] |= (*c >> 7) & 0x1;
+               Mc[1]  = (*c >> 5) & 0x3;
+               xmaxc[1]  = (*c++ & 0x1F) << 1;
+               xmaxc[1] |= (*c >> 7) & 0x1;
+               xmc[13]  = (*c >> 4) & 0x7;
+               xmc[14]  = (*c >> 1) & 0x7;
+               xmc[15]  = (*c++ & 0x1) << 2;
+               xmc[15] |= (*c >> 6) & 0x3;
+               xmc[16]  = (*c >> 3) & 0x7;
+               xmc[17]  = *c++ & 0x7;
+               xmc[18]  = (*c >> 5) & 0x7;
+               xmc[19]  = (*c >> 2) & 0x7;
+               xmc[20]  = (*c++ & 0x3) << 1;
+               xmc[20] |= (*c >> 7) & 0x1;
+               xmc[21]  = (*c >> 4) & 0x7;
+               xmc[22]  = (*c >> 1) & 0x7;
+               xmc[23]  = (*c++ & 0x1) << 2;
+               xmc[23] |= (*c >> 6) & 0x3;
+               xmc[24]  = (*c >> 3) & 0x7;
+               xmc[25]  = *c++ & 0x7;
+               Nc[2]  = (*c >> 1) & 0x7F;
+               bc[2]  = (*c++ & 0x1) << 1;             /* 20 */
+               bc[2] |= (*c >> 7) & 0x1;
+               Mc[2]  = (*c >> 5) & 0x3;
+               xmaxc[2]  = (*c++ & 0x1F) << 1;
+               xmaxc[2] |= (*c >> 7) & 0x1;
+               xmc[26]  = (*c >> 4) & 0x7;
+               xmc[27]  = (*c >> 1) & 0x7;
+               xmc[28]  = (*c++ & 0x1) << 2;
+               xmc[28] |= (*c >> 6) & 0x3;
+               xmc[29]  = (*c >> 3) & 0x7;
+               xmc[30]  = *c++ & 0x7;
+               xmc[31]  = (*c >> 5) & 0x7;
+               xmc[32]  = (*c >> 2) & 0x7;
+               xmc[33]  = (*c++ & 0x3) << 1;
+               xmc[33] |= (*c >> 7) & 0x1;
+               xmc[34]  = (*c >> 4) & 0x7;
+               xmc[35]  = (*c >> 1) & 0x7;
+               xmc[36]  = (*c++ & 0x1) << 2;
+               xmc[36] |= (*c >> 6) & 0x3;
+               xmc[37]  = (*c >> 3) & 0x7;
+               xmc[38]  = *c++ & 0x7;
+               Nc[3]  = (*c >> 1) & 0x7F;
+               bc[3]  = (*c++ & 0x1) << 1;
+               bc[3] |= (*c >> 7) & 0x1;
+               Mc[3]  = (*c >> 5) & 0x3;
+               xmaxc[3]  = (*c++ & 0x1F) << 1;
+               xmaxc[3] |= (*c >> 7) & 0x1;
+               xmc[39]  = (*c >> 4) & 0x7;
+               xmc[40]  = (*c >> 1) & 0x7;
+               xmc[41]  = (*c++ & 0x1) << 2;
+               xmc[41] |= (*c >> 6) & 0x3;
+               xmc[42]  = (*c >> 3) & 0x7;
+               xmc[43]  = *c++ & 0x7;                  /* 30  */
+               xmc[44]  = (*c >> 5) & 0x7;
+               xmc[45]  = (*c >> 2) & 0x7;
+               xmc[46]  = (*c++ & 0x3) << 1;
+               xmc[46] |= (*c >> 7) & 0x1;
+               xmc[47]  = (*c >> 4) & 0x7;
+               xmc[48]  = (*c >> 1) & 0x7;
+               xmc[49]  = (*c++ & 0x1) << 2;
+               xmc[49] |= (*c >> 6) & 0x3;
+               xmc[50]  = (*c >> 3) & 0x7;
+               xmc[51]  = *c & 0x7;                    /* 33 */
+       }
+
+       Gsm_Decoder(s, LARc, Nc, bc, Mc, xmaxc, xmc, target);
+
+       return 0;
+}
diff --git a/gr-gsm-fr-vocoder/src/lib/gsm/gsm_destroy.c b/gr-gsm-fr-vocoder/src/lib/gsm/gsm_destroy.c
new file mode 100644 (file)
index 0000000..4807c0a
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+
+/* $Header$ */
+
+#include "gsm.h"
+#include "config.h"
+#include "proto.h"
+
+#ifdef HAS_STDLIB_H
+#      include <stdlib.h>
+#else
+#      ifdef   HAS_MALLOC_H
+#              include         <malloc.h>
+#      else
+               extern void free();
+#      endif
+#endif
+
+void gsm_destroy P1((S), gsm S)
+{
+       if (S) free((char *)S);
+}
diff --git a/gr-gsm-fr-vocoder/src/lib/gsm/gsm_encode.c b/gr-gsm-fr-vocoder/src/lib/gsm/gsm_encode.c
new file mode 100644 (file)
index 0000000..6233830
--- /dev/null
@@ -0,0 +1,451 @@
+/*
+ * 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.
+ */
+
+/* $Header$ */
+
+#include "private.h"
+#include "gsm.h"
+#include "proto.h"
+
+void gsm_encode P3((s, source, c), gsm s, gsm_signal * source, gsm_byte * c)
+{
+       word            LARc[8], Nc[4], Mc[4], bc[4], xmaxc[4], xmc[13*4];
+
+       Gsm_Coder(s, source, LARc, Nc, bc, Mc, xmaxc, xmc);
+
+
+       /*      variable        size
+
+               GSM_MAGIC       4
+
+               LARc[0]         6
+               LARc[1]         6
+               LARc[2]         5
+               LARc[3]         5
+               LARc[4]         4
+               LARc[5]         4
+               LARc[6]         3
+               LARc[7]         3
+
+               Nc[0]           7
+               bc[0]           2
+               Mc[0]           2
+               xmaxc[0]        6
+               xmc[0]          3
+               xmc[1]          3
+               xmc[2]          3
+               xmc[3]          3
+               xmc[4]          3
+               xmc[5]          3
+               xmc[6]          3
+               xmc[7]          3
+               xmc[8]          3
+               xmc[9]          3
+               xmc[10]         3
+               xmc[11]         3
+               xmc[12]         3
+
+               Nc[1]           7
+               bc[1]           2
+               Mc[1]           2
+               xmaxc[1]        6
+               xmc[13]         3
+               xmc[14]         3
+               xmc[15]         3
+               xmc[16]         3
+               xmc[17]         3
+               xmc[18]         3
+               xmc[19]         3
+               xmc[20]         3
+               xmc[21]         3
+               xmc[22]         3
+               xmc[23]         3
+               xmc[24]         3
+               xmc[25]         3
+
+               Nc[2]           7
+               bc[2]           2
+               Mc[2]           2
+               xmaxc[2]        6
+               xmc[26]         3
+               xmc[27]         3
+               xmc[28]         3
+               xmc[29]         3
+               xmc[30]         3
+               xmc[31]         3
+               xmc[32]         3
+               xmc[33]         3
+               xmc[34]         3
+               xmc[35]         3
+               xmc[36]         3
+               xmc[37]         3
+               xmc[38]         3
+
+               Nc[3]           7
+               bc[3]           2
+               Mc[3]           2
+               xmaxc[3]        6
+               xmc[39]         3
+               xmc[40]         3
+               xmc[41]         3
+               xmc[42]         3
+               xmc[43]         3
+               xmc[44]         3
+               xmc[45]         3
+               xmc[46]         3
+               xmc[47]         3
+               xmc[48]         3
+               xmc[49]         3
+               xmc[50]         3
+               xmc[51]         3
+       */
+
+#ifdef WAV49
+
+       if (s->wav_fmt) {
+               s->frame_index = !s->frame_index;
+               if (s->frame_index) {
+
+                       uword sr;
+
+                       sr = 0;
+                       sr = sr >> 6 | LARc[0] << 10;
+                       sr = sr >> 6 | LARc[1] << 10;
+                       *c++ = sr >> 4;
+                       sr = sr >> 5 | LARc[2] << 11;
+                       *c++ = sr >> 7;
+                       sr = sr >> 5 | LARc[3] << 11;
+                       sr = sr >> 4 | LARc[4] << 12;
+                       *c++ = sr >> 6;
+                       sr = sr >> 4 | LARc[5] << 12;
+                       sr = sr >> 3 | LARc[6] << 13;
+                       *c++ = sr >> 7;
+                       sr = sr >> 3 | LARc[7] << 13;
+                       sr = sr >> 7 | Nc[0] << 9;
+                       *c++ = sr >> 5;
+                       sr = sr >> 2 | bc[0] << 14;
+                       sr = sr >> 2 | Mc[0] << 14;
+                       sr = sr >> 6 | xmaxc[0] << 10;
+                       *c++ = sr >> 3;
+                       sr = sr >> 3 | xmc[0] << 13;
+                       *c++ = sr >> 8;
+                       sr = sr >> 3 | xmc[1] << 13;
+                       sr = sr >> 3 | xmc[2] << 13;
+                       sr = sr >> 3 | xmc[3] << 13;
+                       *c++ = sr >> 7;
+                       sr = sr >> 3 | xmc[4] << 13;
+                       sr = sr >> 3 | xmc[5] << 13;
+                       sr = sr >> 3 | xmc[6] << 13;
+                       *c++ = sr >> 6;
+                       sr = sr >> 3 | xmc[7] << 13;
+                       sr = sr >> 3 | xmc[8] << 13;
+                       *c++ = sr >> 8;
+                       sr = sr >> 3 | xmc[9] << 13;
+                       sr = sr >> 3 | xmc[10] << 13;
+                       sr = sr >> 3 | xmc[11] << 13;
+                       *c++ = sr >> 7;
+                       sr = sr >> 3 | xmc[12] << 13;
+                       sr = sr >> 7 | Nc[1] << 9;
+                       *c++ = sr >> 5;
+                       sr = sr >> 2 | bc[1] << 14;
+                       sr = sr >> 2 | Mc[1] << 14;
+                       sr = sr >> 6 | xmaxc[1] << 10;
+                       *c++ = sr >> 3;
+                       sr = sr >> 3 | xmc[13] << 13;
+                       *c++ = sr >> 8;
+                       sr = sr >> 3 | xmc[14] << 13;
+                       sr = sr >> 3 | xmc[15] << 13;
+                       sr = sr >> 3 | xmc[16] << 13;
+                       *c++ = sr >> 7;
+                       sr = sr >> 3 | xmc[17] << 13;
+                       sr = sr >> 3 | xmc[18] << 13;
+                       sr = sr >> 3 | xmc[19] << 13;
+                       *c++ = sr >> 6;
+                       sr = sr >> 3 | xmc[20] << 13;
+                       sr = sr >> 3 | xmc[21] << 13;
+                       *c++ = sr >> 8;
+                       sr = sr >> 3 | xmc[22] << 13;
+                       sr = sr >> 3 | xmc[23] << 13;
+                       sr = sr >> 3 | xmc[24] << 13;
+                       *c++ = sr >> 7;
+                       sr = sr >> 3 | xmc[25] << 13;
+                       sr = sr >> 7 | Nc[2] << 9;
+                       *c++ = sr >> 5;
+                       sr = sr >> 2 | bc[2] << 14;
+                       sr = sr >> 2 | Mc[2] << 14;
+                       sr = sr >> 6 | xmaxc[2] << 10;
+                       *c++ = sr >> 3;
+                       sr = sr >> 3 | xmc[26] << 13;
+                       *c++ = sr >> 8;
+                       sr = sr >> 3 | xmc[27] << 13;
+                       sr = sr >> 3 | xmc[28] << 13;
+                       sr = sr >> 3 | xmc[29] << 13;
+                       *c++ = sr >> 7;
+                       sr = sr >> 3 | xmc[30] << 13;
+                       sr = sr >> 3 | xmc[31] << 13;
+                       sr = sr >> 3 | xmc[32] << 13;
+                       *c++ = sr >> 6;
+                       sr = sr >> 3 | xmc[33] << 13;
+                       sr = sr >> 3 | xmc[34] << 13;
+                       *c++ = sr >> 8;
+                       sr = sr >> 3 | xmc[35] << 13;
+                       sr = sr >> 3 | xmc[36] << 13;
+                       sr = sr >> 3 | xmc[37] << 13;
+                       *c++ = sr >> 7;
+                       sr = sr >> 3 | xmc[38] << 13;
+                       sr = sr >> 7 | Nc[3] << 9;
+                       *c++ = sr >> 5;
+                       sr = sr >> 2 | bc[3] << 14;
+                       sr = sr >> 2 | Mc[3] << 14;
+                       sr = sr >> 6 | xmaxc[3] << 10;
+                       *c++ = sr >> 3;
+                       sr = sr >> 3 | xmc[39] << 13;
+                       *c++ = sr >> 8;
+                       sr = sr >> 3 | xmc[40] << 13;
+                       sr = sr >> 3 | xmc[41] << 13;
+                       sr = sr >> 3 | xmc[42] << 13;
+                       *c++ = sr >> 7;
+                       sr = sr >> 3 | xmc[43] << 13;
+                       sr = sr >> 3 | xmc[44] << 13;
+                       sr = sr >> 3 | xmc[45] << 13;
+                       *c++ = sr >> 6;
+                       sr = sr >> 3 | xmc[46] << 13;
+                       sr = sr >> 3 | xmc[47] << 13;
+                       *c++ = sr >> 8;
+                       sr = sr >> 3 | xmc[48] << 13;
+                       sr = sr >> 3 | xmc[49] << 13;
+                       sr = sr >> 3 | xmc[50] << 13;
+                       *c++ = sr >> 7;
+                       sr = sr >> 3 | xmc[51] << 13;
+                       sr = sr >> 4;
+                       *c = sr >> 8;
+                       s->frame_chain = *c;
+               }
+               else {
+                       uword sr;
+
+                       sr = 0;
+                       sr = sr >> 4 | s->frame_chain << 12;
+                       sr = sr >> 6 | LARc[0] << 10;
+                       *c++ = sr >> 6;
+                       sr = sr >> 6 | LARc[1] << 10;
+                       *c++ = sr >> 8;
+                       sr = sr >> 5 | LARc[2] << 11;
+                       sr = sr >> 5 | LARc[3] << 11;
+                       *c++ = sr >> 6;
+                       sr = sr >> 4 | LARc[4] << 12;
+                       sr = sr >> 4 | LARc[5] << 12;
+                       *c++ = sr >> 6;
+                       sr = sr >> 3 | LARc[6] << 13;
+                       sr = sr >> 3 | LARc[7] << 13;
+                       *c++ = sr >> 8;
+                       sr = sr >> 7 | Nc[0] << 9;
+                       sr = sr >> 2 | bc[0] << 14;
+                       *c++ = sr >> 7;
+                       sr = sr >> 2 | Mc[0] << 14;
+                       sr = sr >> 6 | xmaxc[0] << 10;
+                       *c++ = sr >> 7;
+                       sr = sr >> 3 | xmc[0] << 13;
+                       sr = sr >> 3 | xmc[1] << 13;
+                       sr = sr >> 3 | xmc[2] << 13;
+                       *c++ = sr >> 6;
+                       sr = sr >> 3 | xmc[3] << 13;
+                       sr = sr >> 3 | xmc[4] << 13;
+                       *c++ = sr >> 8;
+                       sr = sr >> 3 | xmc[5] << 13;
+                       sr = sr >> 3 | xmc[6] << 13;
+                       sr = sr >> 3 | xmc[7] << 13;
+                       *c++ = sr >> 7;
+                       sr = sr >> 3 | xmc[8] << 13;
+                       sr = sr >> 3 | xmc[9] << 13;
+                       sr = sr >> 3 | xmc[10] << 13;
+                       *c++ = sr >> 6;
+                       sr = sr >> 3 | xmc[11] << 13;
+                       sr = sr >> 3 | xmc[12] << 13;
+                       *c++ = sr >> 8;
+                       sr = sr >> 7 | Nc[1] << 9;
+                       sr = sr >> 2 | bc[1] << 14;
+                       *c++ = sr >> 7;
+                       sr = sr >> 2 | Mc[1] << 14;
+                       sr = sr >> 6 | xmaxc[1] << 10;
+                       *c++ = sr >> 7;
+                       sr = sr >> 3 | xmc[13] << 13;
+                       sr = sr >> 3 | xmc[14] << 13;
+                       sr = sr >> 3 | xmc[15] << 13;
+                       *c++ = sr >> 6;
+                       sr = sr >> 3 | xmc[16] << 13;
+                       sr = sr >> 3 | xmc[17] << 13;
+                       *c++ = sr >> 8;
+                       sr = sr >> 3 | xmc[18] << 13;
+                       sr = sr >> 3 | xmc[19] << 13;
+                       sr = sr >> 3 | xmc[20] << 13;
+                       *c++ = sr >> 7;
+                       sr = sr >> 3 | xmc[21] << 13;
+                       sr = sr >> 3 | xmc[22] << 13;
+                       sr = sr >> 3 | xmc[23] << 13;
+                       *c++ = sr >> 6;
+                       sr = sr >> 3 | xmc[24] << 13;
+                       sr = sr >> 3 | xmc[25] << 13;
+                       *c++ = sr >> 8;
+                       sr = sr >> 7 | Nc[2] << 9;
+                       sr = sr >> 2 | bc[2] << 14;
+                       *c++ = sr >> 7;
+                       sr = sr >> 2 | Mc[2] << 14;
+                       sr = sr >> 6 | xmaxc[2] << 10;
+                       *c++ = sr >> 7;
+                       sr = sr >> 3 | xmc[26] << 13;
+                       sr = sr >> 3 | xmc[27] << 13;
+                       sr = sr >> 3 | xmc[28] << 13;
+                       *c++ = sr >> 6;
+                       sr = sr >> 3 | xmc[29] << 13;
+                       sr = sr >> 3 | xmc[30] << 13;
+                       *c++ = sr >> 8;
+                       sr = sr >> 3 | xmc[31] << 13;
+                       sr = sr >> 3 | xmc[32] << 13;
+                       sr = sr >> 3 | xmc[33] << 13;
+                       *c++ = sr >> 7;
+                       sr = sr >> 3 | xmc[34] << 13;
+                       sr = sr >> 3 | xmc[35] << 13;
+                       sr = sr >> 3 | xmc[36] << 13;
+                       *c++ = sr >> 6;
+                       sr = sr >> 3 | xmc[37] << 13;
+                       sr = sr >> 3 | xmc[38] << 13;
+                       *c++ = sr >> 8;
+                       sr = sr >> 7 | Nc[3] << 9;
+                       sr = sr >> 2 | bc[3] << 14;
+                       *c++ = sr >> 7;
+                       sr = sr >> 2 | Mc[3] << 14;
+                       sr = sr >> 6 | xmaxc[3] << 10;
+                       *c++ = sr >> 7;
+                       sr = sr >> 3 | xmc[39] << 13;
+                       sr = sr >> 3 | xmc[40] << 13;
+                       sr = sr >> 3 | xmc[41] << 13;
+                       *c++ = sr >> 6;
+                       sr = sr >> 3 | xmc[42] << 13;
+                       sr = sr >> 3 | xmc[43] << 13;
+                       *c++ = sr >> 8;
+                       sr = sr >> 3 | xmc[44] << 13;
+                       sr = sr >> 3 | xmc[45] << 13;
+                       sr = sr >> 3 | xmc[46] << 13;
+                       *c++ = sr >> 7;
+                       sr = sr >> 3 | xmc[47] << 13;
+                       sr = sr >> 3 | xmc[48] << 13;
+                       sr = sr >> 3 | xmc[49] << 13;
+                       *c++ = sr >> 6;
+                       sr = sr >> 3 | xmc[50] << 13;
+                       sr = sr >> 3 | xmc[51] << 13;
+                       *c++ = sr >> 8;
+               }
+       }
+
+       else
+
+#endif /* WAV49 */
+       {
+
+               *c++ =   ((GSM_MAGIC & 0xF) << 4)               /* 1 */
+                      | ((LARc[0] >> 2) & 0xF);
+               *c++ =   ((LARc[0] & 0x3) << 6)
+                      | (LARc[1] & 0x3F);
+               *c++ =   ((LARc[2] & 0x1F) << 3)
+                      | ((LARc[3] >> 2) & 0x7);
+               *c++ =   ((LARc[3] & 0x3) << 6)
+                      | ((LARc[4] & 0xF) << 2)
+                      | ((LARc[5] >> 2) & 0x3);
+               *c++ =   ((LARc[5] & 0x3) << 6)
+                      | ((LARc[6] & 0x7) << 3)
+                      | (LARc[7] & 0x7);
+               *c++ =   ((Nc[0] & 0x7F) << 1)
+                      | ((bc[0] >> 1) & 0x1);
+               *c++ =   ((bc[0] & 0x1) << 7)
+                      | ((Mc[0] & 0x3) << 5)
+                      | ((xmaxc[0] >> 1) & 0x1F);
+               *c++ =   ((xmaxc[0] & 0x1) << 7)
+                      | ((xmc[0] & 0x7) << 4)
+                      | ((xmc[1] & 0x7) << 1)
+                      | ((xmc[2] >> 2) & 0x1);
+               *c++ =   ((xmc[2] & 0x3) << 6)
+                      | ((xmc[3] & 0x7) << 3)
+                      | (xmc[4] & 0x7);
+               *c++ =   ((xmc[5] & 0x7) << 5)                  /* 10 */
+                      | ((xmc[6] & 0x7) << 2)
+                      | ((xmc[7] >> 1) & 0x3);
+               *c++ =   ((xmc[7] & 0x1) << 7)
+                      | ((xmc[8] & 0x7) << 4)
+                      | ((xmc[9] & 0x7) << 1)
+                      | ((xmc[10] >> 2) & 0x1);
+               *c++ =   ((xmc[10] & 0x3) << 6)
+                      | ((xmc[11] & 0x7) << 3)
+                      | (xmc[12] & 0x7);
+               *c++ =   ((Nc[1] & 0x7F) << 1)
+                      | ((bc[1] >> 1) & 0x1);
+               *c++ =   ((bc[1] & 0x1) << 7)
+                      | ((Mc[1] & 0x3) << 5)
+                      | ((xmaxc[1] >> 1) & 0x1F);
+               *c++ =   ((xmaxc[1] & 0x1) << 7)
+                      | ((xmc[13] & 0x7) << 4)
+                      | ((xmc[14] & 0x7) << 1)
+                      | ((xmc[15] >> 2) & 0x1);
+               *c++ =   ((xmc[15] & 0x3) << 6)
+                      | ((xmc[16] & 0x7) << 3)
+                      | (xmc[17] & 0x7);
+               *c++ =   ((xmc[18] & 0x7) << 5)
+                      | ((xmc[19] & 0x7) << 2)
+                      | ((xmc[20] >> 1) & 0x3);
+               *c++ =   ((xmc[20] & 0x1) << 7)
+                      | ((xmc[21] & 0x7) << 4)
+                      | ((xmc[22] & 0x7) << 1)
+                      | ((xmc[23] >> 2) & 0x1);
+               *c++ =   ((xmc[23] & 0x3) << 6)
+                      | ((xmc[24] & 0x7) << 3)
+                      | (xmc[25] & 0x7);
+               *c++ =   ((Nc[2] & 0x7F) << 1)                  /* 20 */
+                      | ((bc[2] >> 1) & 0x1);
+               *c++ =   ((bc[2] & 0x1) << 7)
+                      | ((Mc[2] & 0x3) << 5)
+                      | ((xmaxc[2] >> 1) & 0x1F);
+               *c++ =   ((xmaxc[2] & 0x1) << 7)
+                      | ((xmc[26] & 0x7) << 4)
+                      | ((xmc[27] & 0x7) << 1)
+                      | ((xmc[28] >> 2) & 0x1);
+               *c++ =   ((xmc[28] & 0x3) << 6)
+                      | ((xmc[29] & 0x7) << 3)
+                      | (xmc[30] & 0x7);
+               *c++ =   ((xmc[31] & 0x7) << 5)
+                      | ((xmc[32] & 0x7) << 2)
+                      | ((xmc[33] >> 1) & 0x3);
+               *c++ =   ((xmc[33] & 0x1) << 7)
+                      | ((xmc[34] & 0x7) << 4)
+                      | ((xmc[35] & 0x7) << 1)
+                      | ((xmc[36] >> 2) & 0x1);
+               *c++ =   ((xmc[36] & 0x3) << 6)
+                      | ((xmc[37] & 0x7) << 3)
+                      | (xmc[38] & 0x7);
+               *c++ =   ((Nc[3] & 0x7F) << 1)
+                      | ((bc[3] >> 1) & 0x1);
+               *c++ =   ((bc[3] & 0x1) << 7)
+                      | ((Mc[3] & 0x3) << 5)
+                      | ((xmaxc[3] >> 1) & 0x1F);
+               *c++ =   ((xmaxc[3] & 0x1) << 7)
+                      | ((xmc[39] & 0x7) << 4)
+                      | ((xmc[40] & 0x7) << 1)
+                      | ((xmc[41] >> 2) & 0x1);
+               *c++ =   ((xmc[41] & 0x3) << 6)                 /* 30 */
+                      | ((xmc[42] & 0x7) << 3)
+                      | (xmc[43] & 0x7);
+               *c++ =   ((xmc[44] & 0x7) << 5)
+                      | ((xmc[45] & 0x7) << 2)
+                      | ((xmc[46] >> 1) & 0x3);
+               *c++ =   ((xmc[46] & 0x1) << 7)
+                      | ((xmc[47] & 0x7) << 4)
+                      | ((xmc[48] & 0x7) << 1)
+                      | ((xmc[49] >> 2) & 0x1);
+               *c++ =   ((xmc[49] & 0x3) << 6)
+                      | ((xmc[50] & 0x7) << 3)
+                      | (xmc[51] & 0x7);
+
+       }
+}
diff --git a/gr-gsm-fr-vocoder/src/lib/gsm/gsm_explode.c b/gr-gsm-fr-vocoder/src/lib/gsm/gsm_explode.c
new file mode 100644 (file)
index 0000000..a906fc2
--- /dev/null
@@ -0,0 +1,417 @@
+/*
+ * 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.
+ */
+
+/* $Header$ */
+
+#include "private.h"
+#include "gsm.h"
+#include "proto.h"
+
+int gsm_explode P3((s, c, target), gsm s, gsm_byte * c, gsm_signal * target)
+{
+#      define  LARc    target
+#      define  Nc      *((gsm_signal (*) [17])(target + 8))
+#      define  bc      *((gsm_signal (*) [17])(target + 9))
+#      define  Mc      *((gsm_signal (*) [17])(target + 10))
+#      define  xmaxc   *((gsm_signal (*) [17])(target + 11))
+
+
+#ifdef WAV49
+       if (s->wav_fmt) {
+
+               uword sr = 0;
+
+               if (s->frame_index == 1) {
+
+                       sr = *c++;
+                       LARc[0] = sr & 0x3f;  sr >>= 6;
+                       sr |= (uword)*c++ << 2;
+                       LARc[1] = sr & 0x3f;  sr >>= 6;
+                       sr |= (uword)*c++ << 4;
+                       LARc[2] = sr & 0x1f;  sr >>= 5;
+                       LARc[3] = sr & 0x1f;  sr >>= 5;
+                       sr |= (uword)*c++ << 2;
+                       LARc[4] = sr & 0xf;  sr >>= 4;
+                       LARc[5] = sr & 0xf;  sr >>= 4;
+                       sr |= (uword)*c++ << 2;                 /* 5 */
+                       LARc[6] = sr & 0x7;  sr >>= 3;
+                       LARc[7] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 4;
+                       Nc[0] = sr & 0x7f;  sr >>= 7;
+                       bc[0] = sr & 0x3;  sr >>= 2;
+                       Mc[0] = sr & 0x3;  sr >>= 2;
+                       sr |= (uword)*c++ << 1;
+                       xmaxc[0] = sr & 0x3f;  sr >>= 6;
+#undef xmc
+#define        xmc     (target + 12)
+                       xmc[0] = sr & 0x7;  sr >>= 3;
+                       sr = *c++;
+                       xmc[1] = sr & 0x7;  sr >>= 3;
+                       xmc[2] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 2;
+                       xmc[3] = sr & 0x7;  sr >>= 3;
+                       xmc[4] = sr & 0x7;  sr >>= 3;
+                       xmc[5] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 1;                 /* 10 */
+                       xmc[6] = sr & 0x7;  sr >>= 3;
+                       xmc[7] = sr & 0x7;  sr >>= 3;
+                       xmc[8] = sr & 0x7;  sr >>= 3;
+                       sr = *c++;
+                       xmc[9] = sr & 0x7;  sr >>= 3;
+                       xmc[10] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 2;
+                       xmc[11] = sr & 0x7;  sr >>= 3;
+                       xmc[12] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 4;
+                       Nc[1] = sr & 0x7f;  sr >>= 7;
+                       bc[1] = sr & 0x3;  sr >>= 2;
+                       Mc[1] = sr & 0x3;  sr >>= 2;
+                       sr |= (uword)*c++ << 1;
+                       xmaxc[1] = sr & 0x3f;  sr >>= 6;
+#undef xmc
+#define        xmc     (target + 29 - 13)
+
+                       xmc[13] = sr & 0x7;  sr >>= 3;
+                       sr = *c++;                              /* 15 */
+                       xmc[14] = sr & 0x7;  sr >>= 3;
+                       xmc[15] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 2;
+                       xmc[16] = sr & 0x7;  sr >>= 3;
+                       xmc[17] = sr & 0x7;  sr >>= 3;
+                       xmc[18] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 1;
+                       xmc[19] = sr & 0x7;  sr >>= 3;
+                       xmc[20] = sr & 0x7;  sr >>= 3;
+                       xmc[21] = sr & 0x7;  sr >>= 3;
+                       sr = *c++;
+                       xmc[22] = sr & 0x7;  sr >>= 3;
+                       xmc[23] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 2;
+                       xmc[24] = sr & 0x7;  sr >>= 3;
+                       xmc[25] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 4;                 /* 20 */
+                       Nc[2] = sr & 0x7f;  sr >>= 7;
+                       bc[2] = sr & 0x3;  sr >>= 2;
+                       Mc[2] = sr & 0x3;  sr >>= 2;
+                       sr |= (uword)*c++ << 1;
+                       xmaxc[2] = sr & 0x3f;  sr >>= 6;
+
+#undef xmc
+#define        xmc     (target + 46 - 26)
+
+                       xmc[26] = sr & 0x7;  sr >>= 3;
+                       sr = *c++;
+                       xmc[27] = sr & 0x7;  sr >>= 3;
+                       xmc[28] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 2;
+                       xmc[29] = sr & 0x7;  sr >>= 3;
+                       xmc[30] = sr & 0x7;  sr >>= 3;
+                       xmc[31] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 1;
+                       xmc[32] = sr & 0x7;  sr >>= 3;
+                       xmc[33] = sr & 0x7;  sr >>= 3;
+                       xmc[34] = sr & 0x7;  sr >>= 3;
+                       sr = *c++;                              /* 25 */
+                       xmc[35] = sr & 0x7;  sr >>= 3;
+                       xmc[36] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 2;
+                       xmc[37] = sr & 0x7;  sr >>= 3;
+                       xmc[38] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 4;
+                       Nc[3] = sr & 0x7f;  sr >>= 7;
+                       bc[3] = sr & 0x3;  sr >>= 2;
+                       Mc[3] = sr & 0x3;  sr >>= 2;
+                       sr |= (uword)*c++ << 1;
+                       xmaxc[3] = sr & 0x3f;  sr >>= 6;
+#undef xmc
+#define        xmc     (target + 63 - 39)
+
+                       xmc[39] = sr & 0x7;  sr >>= 3;
+                       sr = *c++;
+                       xmc[40] = sr & 0x7;  sr >>= 3;
+                       xmc[41] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 2;                 /* 30 */
+                       xmc[42] = sr & 0x7;  sr >>= 3;
+                       xmc[43] = sr & 0x7;  sr >>= 3;
+                       xmc[44] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 1;
+                       xmc[45] = sr & 0x7;  sr >>= 3;
+                       xmc[46] = sr & 0x7;  sr >>= 3;
+                       xmc[47] = sr & 0x7;  sr >>= 3;
+                       sr = *c++;
+                       xmc[48] = sr & 0x7;  sr >>= 3;
+                       xmc[49] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 2;
+                       xmc[50] = sr & 0x7;  sr >>= 3;
+                       xmc[51] = sr & 0x7;  sr >>= 3;
+
+                       s->frame_chain = sr & 0xf;
+               }
+               else {
+                       sr = s->frame_chain;
+                       sr |= (uword)*c++ << 4;                 /* 1 */
+                       LARc[0] = sr & 0x3f;  sr >>= 6;
+                       LARc[1] = sr & 0x3f;  sr >>= 6;
+                       sr = *c++;
+                       LARc[2] = sr & 0x1f;  sr >>= 5;
+                       sr |= (uword)*c++ << 3;
+                       LARc[3] = sr & 0x1f;  sr >>= 5;
+                       LARc[4] = sr & 0xf;  sr >>= 4;
+                       sr |= (uword)*c++ << 2;
+                       LARc[5] = sr & 0xf;  sr >>= 4;
+                       LARc[6] = sr & 0x7;  sr >>= 3;
+                       LARc[7] = sr & 0x7;  sr >>= 3;
+                       sr = *c++;                              /* 5 */
+                       Nc[0] = sr & 0x7f;  sr >>= 7;
+                       sr |= (uword)*c++ << 1;
+                       bc[0] = sr & 0x3;  sr >>= 2;
+                       Mc[0] = sr & 0x3;  sr >>= 2;
+                       sr |= (uword)*c++ << 5;
+                       xmaxc[0] = sr & 0x3f;  sr >>= 6;
+#undef xmc
+#define        xmc     (target + 12)
+                       xmc[0] = sr & 0x7;  sr >>= 3;
+                       xmc[1] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 1;
+                       xmc[2] = sr & 0x7;  sr >>= 3;
+                       xmc[3] = sr & 0x7;  sr >>= 3;
+                       xmc[4] = sr & 0x7;  sr >>= 3;
+                       sr = *c++;
+                       xmc[5] = sr & 0x7;  sr >>= 3;
+                       xmc[6] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 2;                 /* 10 */
+                       xmc[7] = sr & 0x7;  sr >>= 3;
+                       xmc[8] = sr & 0x7;  sr >>= 3;
+                       xmc[9] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 1;
+                       xmc[10] = sr & 0x7;  sr >>= 3;
+                       xmc[11] = sr & 0x7;  sr >>= 3;
+                       xmc[12] = sr & 0x7;  sr >>= 3;
+                       sr = *c++;
+                       Nc[1] = sr & 0x7f;  sr >>= 7;
+                       sr |= (uword)*c++ << 1;
+                       bc[1] = sr & 0x3;  sr >>= 2;
+                       Mc[1] = sr & 0x3;  sr >>= 2;
+                       sr |= (uword)*c++ << 5;
+                       xmaxc[1] = sr & 0x3f;  sr >>= 6;
+#undef xmc
+#define        xmc     (target + 29 - 13)
+
+                       xmc[13] = sr & 0x7;  sr >>= 3;
+                       xmc[14] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 1;                 /* 15 */
+                       xmc[15] = sr & 0x7;  sr >>= 3;
+                       xmc[16] = sr & 0x7;  sr >>= 3;
+                       xmc[17] = sr & 0x7;  sr >>= 3;
+                       sr = *c++;
+                       xmc[18] = sr & 0x7;  sr >>= 3;
+                       xmc[19] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 2;
+                       xmc[20] = sr & 0x7;  sr >>= 3;
+                       xmc[21] = sr & 0x7;  sr >>= 3;
+                       xmc[22] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 1;
+                       xmc[23] = sr & 0x7;  sr >>= 3;
+                       xmc[24] = sr & 0x7;  sr >>= 3;
+                       xmc[25] = sr & 0x7;  sr >>= 3;
+                       sr = *c++;
+                       Nc[2] = sr & 0x7f;  sr >>= 7;
+                       sr |= (uword)*c++ << 1;                 /* 20 */
+                       bc[2] = sr & 0x3;  sr >>= 2;
+                       Mc[2] = sr & 0x3;  sr >>= 2;
+                       sr |= (uword)*c++ << 5;
+                       xmaxc[2] = sr & 0x3f;  sr >>= 6;
+#undef xmc
+#define        xmc     (target + 46 - 26)
+                       xmc[26] = sr & 0x7;  sr >>= 3;
+                       xmc[27] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 1; 
+                       xmc[28] = sr & 0x7;  sr >>= 3;
+                       xmc[29] = sr & 0x7;  sr >>= 3;
+                       xmc[30] = sr & 0x7;  sr >>= 3;
+                       sr = *c++;
+                       xmc[31] = sr & 0x7;  sr >>= 3;
+                       xmc[32] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 2;
+                       xmc[33] = sr & 0x7;  sr >>= 3;
+                       xmc[34] = sr & 0x7;  sr >>= 3;
+                       xmc[35] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 1;                 /* 25 */
+                       xmc[36] = sr & 0x7;  sr >>= 3;
+                       xmc[37] = sr & 0x7;  sr >>= 3;
+                       xmc[38] = sr & 0x7;  sr >>= 3;
+                       sr = *c++;
+                       Nc[3] = sr & 0x7f;  sr >>= 7;
+                       sr |= (uword)*c++ << 1;         
+                       bc[3] = sr & 0x3;  sr >>= 2;
+                       Mc[3] = sr & 0x3;  sr >>= 2;
+                       sr |= (uword)*c++ << 5;
+                       xmaxc[3] = sr & 0x3f;  sr >>= 6;
+
+#undef xmc
+#define        xmc     (target + 63 - 39)
+
+                       xmc[39] = sr & 0x7;  sr >>= 3;
+                       xmc[40] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 1;
+                       xmc[41] = sr & 0x7;  sr >>= 3;
+                       xmc[42] = sr & 0x7;  sr >>= 3;
+                       xmc[43] = sr & 0x7;  sr >>= 3;
+                       sr = *c++;                              /* 30 */
+                       xmc[44] = sr & 0x7;  sr >>= 3;
+                       xmc[45] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 2;
+                       xmc[46] = sr & 0x7;  sr >>= 3;
+                       xmc[47] = sr & 0x7;  sr >>= 3;
+                       xmc[48] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 1;
+                       xmc[49] = sr & 0x7;  sr >>= 3;
+                       xmc[50] = sr & 0x7;  sr >>= 3;
+                       xmc[51] = sr & 0x7;  sr >>= 3;
+               }
+       }
+       else 
+#endif
+       {
+       /* GSM_MAGIC  = (*c >> 4) & 0xF; */
+
+       if (((*c >> 4) & 0x0F) != GSM_MAGIC) return -1;
+
+       LARc[0]  = (*c++ & 0xF) << 2;           /* 1 */
+       LARc[0] |= (*c >> 6) & 0x3;
+       LARc[1]  = *c++ & 0x3F;
+       LARc[2]  = (*c >> 3) & 0x1F;
+       LARc[3]  = (*c++ & 0x7) << 2;
+       LARc[3] |= (*c >> 6) & 0x3;
+       LARc[4]  = (*c >> 2) & 0xF;
+       LARc[5]  = (*c++ & 0x3) << 2;
+       LARc[5] |= (*c >> 6) & 0x3;
+       LARc[6]  = (*c >> 3) & 0x7;
+       LARc[7]  = *c++ & 0x7;
+
+       Nc[0]  = (*c >> 1) & 0x7F;
+
+       bc[0]  = (*c++ & 0x1) << 1;
+       bc[0] |= (*c >> 7) & 0x1;
+
+       Mc[0]  = (*c >> 5) & 0x3;
+
+       xmaxc[0]  = (*c++ & 0x1F) << 1;
+       xmaxc[0] |= (*c >> 7) & 0x1;
+
+#undef xmc
+#define        xmc     (target + 12)
+
+       xmc[0]  = (*c >> 4) & 0x7;
+       xmc[1]  = (*c >> 1) & 0x7;
+       xmc[2]  = (*c++ & 0x1) << 2;
+       xmc[2] |= (*c >> 6) & 0x3;
+       xmc[3]  = (*c >> 3) & 0x7;
+       xmc[4]  = *c++ & 0x7;
+       xmc[5]  = (*c >> 5) & 0x7;
+       xmc[6]  = (*c >> 2) & 0x7;
+       xmc[7]  = (*c++ & 0x3) << 1;            /* 10 */
+       xmc[7] |= (*c >> 7) & 0x1;
+       xmc[8]  = (*c >> 4) & 0x7;
+       xmc[9]  = (*c >> 1) & 0x7;
+       xmc[10]  = (*c++ & 0x1) << 2;
+       xmc[10] |= (*c >> 6) & 0x3;
+       xmc[11]  = (*c >> 3) & 0x7;
+       xmc[12]  = *c++ & 0x7;
+
+       Nc[1]  = (*c >> 1) & 0x7F;
+
+       bc[1]  = (*c++ & 0x1) << 1;
+       bc[1] |= (*c >> 7) & 0x1;
+
+       Mc[1]  = (*c >> 5) & 0x3;
+
+       xmaxc[1]  = (*c++ & 0x1F) << 1;
+       xmaxc[1] |= (*c >> 7) & 0x1;
+
+#undef xmc
+#define        xmc     (target + 29 - 13)
+
+       xmc[13]  = (*c >> 4) & 0x7;
+       xmc[14]  = (*c >> 1) & 0x7;
+       xmc[15]  = (*c++ & 0x1) << 2;
+       xmc[15] |= (*c >> 6) & 0x3;
+       xmc[16]  = (*c >> 3) & 0x7;
+       xmc[17]  = *c++ & 0x7;
+       xmc[18]  = (*c >> 5) & 0x7;
+       xmc[19]  = (*c >> 2) & 0x7;
+       xmc[20]  = (*c++ & 0x3) << 1;
+       xmc[20] |= (*c >> 7) & 0x1;
+       xmc[21]  = (*c >> 4) & 0x7;
+       xmc[22]  = (*c >> 1) & 0x7;
+       xmc[23]  = (*c++ & 0x1) << 2;
+       xmc[23] |= (*c >> 6) & 0x3;
+       xmc[24]  = (*c >> 3) & 0x7;
+       xmc[25]  = *c++ & 0x7;
+
+       Nc[2]  = (*c >> 1) & 0x7F;
+
+       bc[2]  = (*c++ & 0x1) << 1;             /* 20 */
+       bc[2] |= (*c >> 7) & 0x1;
+
+       Mc[2]  = (*c >> 5) & 0x3;
+
+       xmaxc[2]  = (*c++ & 0x1F) << 1;
+       xmaxc[2] |= (*c >> 7) & 0x1;
+
+#undef xmc
+#define        xmc     (target + 46 - 26)
+
+       xmc[26]  = (*c >> 4) & 0x7;
+       xmc[27]  = (*c >> 1) & 0x7;
+       xmc[28]  = (*c++ & 0x1) << 2;
+       xmc[28] |= (*c >> 6) & 0x3;
+       xmc[29]  = (*c >> 3) & 0x7;
+       xmc[30]  = *c++ & 0x7;
+       xmc[31]  = (*c >> 5) & 0x7;
+       xmc[32]  = (*c >> 2) & 0x7;
+       xmc[33]  = (*c++ & 0x3) << 1;
+       xmc[33] |= (*c >> 7) & 0x1;
+       xmc[34]  = (*c >> 4) & 0x7;
+       xmc[35]  = (*c >> 1) & 0x7;
+       xmc[36]  = (*c++ & 0x1) << 2;
+       xmc[36] |= (*c >> 6) & 0x3;
+       xmc[37]  = (*c >> 3) & 0x7;
+       xmc[38]  = *c++ & 0x7;
+
+       Nc[3]  = (*c >> 1) & 0x7F;
+
+       bc[3]  = (*c++ & 0x1) << 1;
+       bc[3] |= (*c >> 7) & 0x1;
+
+       Mc[3]  = (*c >> 5) & 0x3;
+
+       xmaxc[3]  = (*c++ & 0x1F) << 1;
+       xmaxc[3] |= (*c >> 7) & 0x1;
+
+#undef xmc
+#define        xmc     (target + 63 - 39)
+
+       xmc[39]  = (*c >> 4) & 0x7;
+       xmc[40]  = (*c >> 1) & 0x7;
+       xmc[41]  = (*c++ & 0x1) << 2;
+       xmc[41] |= (*c >> 6) & 0x3;
+       xmc[42]  = (*c >> 3) & 0x7;
+       xmc[43]  = *c++ & 0x7;                  /* 30  */
+       xmc[44]  = (*c >> 5) & 0x7;
+       xmc[45]  = (*c >> 2) & 0x7;
+       xmc[46]  = (*c++ & 0x3) << 1;
+       xmc[46] |= (*c >> 7) & 0x1;
+       xmc[47]  = (*c >> 4) & 0x7;
+       xmc[48]  = (*c >> 1) & 0x7;
+       xmc[49]  = (*c++ & 0x1) << 2;
+       xmc[49] |= (*c >> 6) & 0x3;
+       xmc[50]  = (*c >> 3) & 0x7;
+       xmc[51]  = *c & 0x7;                    /* 33 */
+       }
+
+       return 0;
+}
diff --git a/gr-gsm-fr-vocoder/src/lib/gsm/gsm_implode.c b/gr-gsm-fr-vocoder/src/lib/gsm/gsm_implode.c
new file mode 100644 (file)
index 0000000..453b8cf
--- /dev/null
@@ -0,0 +1,515 @@
+/*
+ * 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.
+ */
+
+/* $Header$ */
+
+#include "private.h"
+
+#include "gsm.h"
+#include "proto.h"
+
+void gsm_implode P3((s, source, c), gsm s, gsm_signal * source, gsm_byte * c)
+{
+       /*      variable        size    index
+
+               GSM_MAGIC       4       -
+
+               LARc[0]         6       0
+               LARc[1]         6       1
+               LARc[2]         5       2
+               LARc[3]         5       3
+               LARc[4]         4       4
+               LARc[5]         4       5
+               LARc[6]         3       6
+               LARc[7]         3       7
+
+               Nc[0]           7       8
+               bc[0]           2       9
+               Mc[0]           2       10
+               xmaxc[0]        6       11
+               xmc[0]          3       12
+               xmc[1]          3       13
+               xmc[2]          3       14
+               xmc[3]          3       15
+               xmc[4]          3       16
+               xmc[5]          3       17
+               xmc[6]          3       18
+               xmc[7]          3       19
+               xmc[8]          3       20
+               xmc[9]          3       21
+               xmc[10]         3       22
+               xmc[11]         3       23
+               xmc[12]         3       24
+
+               Nc[1]           7       25
+               bc[1]           2       26
+               Mc[1]           2       27
+               xmaxc[1]        6       28
+               xmc[13]         3       29
+               xmc[14]         3       30
+               xmc[15]         3       31
+               xmc[16]         3       32
+               xmc[17]         3       33
+               xmc[18]         3       34
+               xmc[19]         3       35
+               xmc[20]         3       36
+               xmc[21]         3       37
+               xmc[22]         3       38
+               xmc[23]         3       39
+               xmc[24]         3       40
+               xmc[25]         3       41
+
+               Nc[2]           7       42
+               bc[2]           2       43
+               Mc[2]           2       44
+               xmaxc[2]        6       45
+               xmc[26]         3       46
+               xmc[27]         3       47
+               xmc[28]         3       48
+               xmc[29]         3       49
+               xmc[30]         3       50
+               xmc[31]         3       51
+               xmc[32]         3       52
+               xmc[33]         3       53
+               xmc[34]         3       54
+               xmc[35]         3       55
+               xmc[36]         3       56
+               xmc[37]         3       57
+               xmc[38]         3       58
+
+               Nc[3]           7       59
+               bc[3]           2       60
+               Mc[3]           2       61
+               xmaxc[3]        6       62
+               xmc[39]         3       63
+               xmc[40]         3       64
+               xmc[41]         3       65
+               xmc[42]         3       66
+               xmc[43]         3       67
+               xmc[44]         3       68
+               xmc[45]         3       69
+               xmc[46]         3       70
+               xmc[47]         3       71
+               xmc[48]         3       72
+               xmc[49]         3       73
+               xmc[50]         3       74
+               xmc[51]         3       75
+       */
+
+       /*      There are 76 parameters per frame.  The first eight are
+        *      unique.  The remaining 68 are four identical subframes of
+        *      17 parameters each.  gsm_implode converts from a representation
+        *      of these parameters as values in one array of signed words
+        *      to the "packed" version of a GSM frame.
+        */
+
+#      define  LARc    source
+#      define  Nc      *((gsm_signal (*) [17])(source + 8))
+#      define  bc      *((gsm_signal (*) [17])(source + 9))
+#      define  Mc      *((gsm_signal (*) [17])(source + 10))
+#      define  xmaxc   *((gsm_signal (*) [17])(source + 11))
+
+#ifdef WAV49
+       if (s->wav_fmt) {
+
+               uword sr = 0;
+               if (s->frame_index == 0) {
+
+                       sr = *c++;
+                       LARc[0] = sr & 0x3f;  sr >>= 6;
+                       sr |= (uword)*c++ << 2;
+                       LARc[1] = sr & 0x3f;  sr >>= 6;
+                       sr |= (uword)*c++ << 4;
+                       LARc[2] = sr & 0x1f;  sr >>= 5;
+                       LARc[3] = sr & 0x1f;  sr >>= 5;
+                       sr |= (uword)*c++ << 2;
+                       LARc[4] = sr & 0xf;  sr >>= 4;
+                       LARc[5] = sr & 0xf;  sr >>= 4;
+                       sr |= (uword)*c++ << 2;                 /* 5 */
+                       LARc[6] = sr & 0x7;  sr >>= 3;
+                       LARc[7] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 4;
+                       Nc[0] = sr & 0x7f;  sr >>= 7;
+                       bc[0] = sr & 0x3;  sr >>= 2;
+                       Mc[0] = sr & 0x3;  sr >>= 2;
+                       sr |= (uword)*c++ << 1;
+                       xmaxc[0] = sr & 0x3f;  sr >>= 6;
+#undef xmc
+#define        xmc     (source + 12)
+                       xmc[0] = sr & 0x7;  sr >>= 3;
+                       sr = *c++;
+                       xmc[1] = sr & 0x7;  sr >>= 3;
+                       xmc[2] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 2;
+                       xmc[3] = sr & 0x7;  sr >>= 3;
+                       xmc[4] = sr & 0x7;  sr >>= 3;
+                       xmc[5] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 1;                 /* 10 */
+                       xmc[6] = sr & 0x7;  sr >>= 3;
+                       xmc[7] = sr & 0x7;  sr >>= 3;
+                       xmc[8] = sr & 0x7;  sr >>= 3;
+                       sr = *c++;
+                       xmc[9] = sr & 0x7;  sr >>= 3;
+                       xmc[10] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 2;
+                       xmc[11] = sr & 0x7;  sr >>= 3;
+                       xmc[12] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 4;
+                       Nc[1] = sr & 0x7f;  sr >>= 7;
+                       bc[1] = sr & 0x3;  sr >>= 2;
+                       Mc[1] = sr & 0x3;  sr >>= 2;
+                       sr |= (uword)*c++ << 1;
+                       xmaxc[1] = sr & 0x3f;  sr >>= 6;
+#undef xmc
+#define        xmc     (source + 29 - 13)
+                       xmc[13] = sr & 0x7;  sr >>= 3;
+                       sr = *c++;                              /* 15 */
+                       xmc[14] = sr & 0x7;  sr >>= 3;
+                       xmc[15] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 2;
+                       xmc[16] = sr & 0x7;  sr >>= 3;
+                       xmc[17] = sr & 0x7;  sr >>= 3;
+                       xmc[18] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 1;
+                       xmc[19] = sr & 0x7;  sr >>= 3;
+                       xmc[20] = sr & 0x7;  sr >>= 3;
+                       xmc[21] = sr & 0x7;  sr >>= 3;
+                       sr = *c++;
+                       xmc[22] = sr & 0x7;  sr >>= 3;
+                       xmc[23] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 2;
+                       xmc[24] = sr & 0x7;  sr >>= 3;
+                       xmc[25] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 4;                 /* 20 */
+                       Nc[2] = sr & 0x7f;  sr >>= 7;
+                       bc[2] = sr & 0x3;  sr >>= 2;
+                       Mc[2] = sr & 0x3;  sr >>= 2;
+                       sr |= (uword)*c++ << 1;
+                       xmaxc[2] = sr & 0x3f;  sr >>= 6;
+#undef xmc
+#define        xmc     (source + 46 - 26)
+                       xmc[26] = sr & 0x7;  sr >>= 3;
+                       sr = *c++;
+                       xmc[27] = sr & 0x7;  sr >>= 3;
+                       xmc[28] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 2;
+                       xmc[29] = sr & 0x7;  sr >>= 3;
+                       xmc[30] = sr & 0x7;  sr >>= 3;
+                       xmc[31] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 1;
+                       xmc[32] = sr & 0x7;  sr >>= 3;
+                       xmc[33] = sr & 0x7;  sr >>= 3;
+                       xmc[34] = sr & 0x7;  sr >>= 3;
+                       sr = *c++;                              /* 25 */
+                       xmc[35] = sr & 0x7;  sr >>= 3;
+                       xmc[36] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 2;
+                       xmc[37] = sr & 0x7;  sr >>= 3;
+                       xmc[38] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 4;
+                       Nc[3] = sr & 0x7f;  sr >>= 7;
+                       bc[3] = sr & 0x3;  sr >>= 2;
+                       Mc[3] = sr & 0x3;  sr >>= 2;
+                       sr |= (uword)*c++ << 1;
+                       xmaxc[3] = sr & 0x3f;  sr >>= 6;
+#undef xmc
+#define        xmc     (source + 63 - 39)
+
+                       xmc[39] = sr & 0x7;  sr >>= 3;
+                       sr = *c++;
+                       xmc[40] = sr & 0x7;  sr >>= 3;
+                       xmc[41] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 2;                 /* 30 */
+                       xmc[42] = sr & 0x7;  sr >>= 3;
+                       xmc[43] = sr & 0x7;  sr >>= 3;
+                       xmc[44] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 1;
+                       xmc[45] = sr & 0x7;  sr >>= 3;
+                       xmc[46] = sr & 0x7;  sr >>= 3;
+                       xmc[47] = sr & 0x7;  sr >>= 3;
+                       sr = *c++;
+                       xmc[48] = sr & 0x7;  sr >>= 3;
+                       xmc[49] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 2;
+                       xmc[50] = sr & 0x7;  sr >>= 3;
+                       xmc[51] = sr & 0x7;  sr >>= 3;
+
+                       s->frame_chain = sr & 0xf;
+               }
+               else {
+                       sr = s->frame_chain;
+                       sr |= (uword)*c++ << 4;                 /* 1 */
+                       LARc[0] = sr & 0x3f;  sr >>= 6;
+                       LARc[1] = sr & 0x3f;  sr >>= 6;
+                       sr = *c++;
+                       LARc[2] = sr & 0x1f;  sr >>= 5;
+                       sr |= (uword)*c++ << 3;
+                       LARc[3] = sr & 0x1f;  sr >>= 5;
+                       LARc[4] = sr & 0xf;  sr >>= 4;
+                       sr |= (uword)*c++ << 2;
+                       LARc[5] = sr & 0xf;  sr >>= 4;
+                       LARc[6] = sr & 0x7;  sr >>= 3;
+                       LARc[7] = sr & 0x7;  sr >>= 3;
+                       sr = *c++;                              /* 5 */
+                       Nc[0] = sr & 0x7f;  sr >>= 7;
+                       sr |= (uword)*c++ << 1;
+                       bc[0] = sr & 0x3;  sr >>= 2;
+                       Mc[0] = sr & 0x3;  sr >>= 2;
+                       sr |= (uword)*c++ << 5;
+                       xmaxc[0] = sr & 0x3f;  sr >>= 6;
+#undef xmc
+#define        xmc     (source + 12)
+                       xmc[0] = sr & 0x7;  sr >>= 3;
+                       xmc[1] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 1;
+                       xmc[2] = sr & 0x7;  sr >>= 3;
+                       xmc[3] = sr & 0x7;  sr >>= 3;
+                       xmc[4] = sr & 0x7;  sr >>= 3;
+                       sr = *c++;
+                       xmc[5] = sr & 0x7;  sr >>= 3;
+                       xmc[6] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 2;                 /* 10 */
+                       xmc[7] = sr & 0x7;  sr >>= 3;
+                       xmc[8] = sr & 0x7;  sr >>= 3;
+                       xmc[9] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 1;
+                       xmc[10] = sr & 0x7;  sr >>= 3;
+                       xmc[11] = sr & 0x7;  sr >>= 3;
+                       xmc[12] = sr & 0x7;  sr >>= 3;
+                       sr = *c++;
+                       Nc[1] = sr & 0x7f;  sr >>= 7;
+                       sr |= (uword)*c++ << 1;
+                       bc[1] = sr & 0x3;  sr >>= 2;
+                       Mc[1] = sr & 0x3;  sr >>= 2;
+                       sr |= (uword)*c++ << 5;
+                       xmaxc[1] = sr & 0x3f;  sr >>= 6;
+#undef xmc
+#define        xmc     (source + 29 - 13)
+                       xmc[13] = sr & 0x7;  sr >>= 3;
+                       xmc[14] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 1;                 /* 15 */
+                       xmc[15] = sr & 0x7;  sr >>= 3;
+                       xmc[16] = sr & 0x7;  sr >>= 3;
+                       xmc[17] = sr & 0x7;  sr >>= 3;
+                       sr = *c++;
+                       xmc[18] = sr & 0x7;  sr >>= 3;
+                       xmc[19] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 2;
+                       xmc[20] = sr & 0x7;  sr >>= 3;
+                       xmc[21] = sr & 0x7;  sr >>= 3;
+                       xmc[22] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 1;
+                       xmc[23] = sr & 0x7;  sr >>= 3;
+                       xmc[24] = sr & 0x7;  sr >>= 3;
+                       xmc[25] = sr & 0x7;  sr >>= 3;
+                       sr = *c++;
+                       Nc[2] = sr & 0x7f;  sr >>= 7;
+                       sr |= (uword)*c++ << 1;                 /* 20 */
+                       bc[2] = sr & 0x3;  sr >>= 2;
+                       Mc[2] = sr & 0x3;  sr >>= 2;
+                       sr |= (uword)*c++ << 5;
+                       xmaxc[2] = sr & 0x3f;  sr >>= 6;
+#undef xmc
+#define        xmc     (source + 46 - 26)
+                       xmc[26] = sr & 0x7;  sr >>= 3;
+                       xmc[27] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 1; 
+                       xmc[28] = sr & 0x7;  sr >>= 3;
+                       xmc[29] = sr & 0x7;  sr >>= 3;
+                       xmc[30] = sr & 0x7;  sr >>= 3;
+                       sr = *c++;
+                       xmc[31] = sr & 0x7;  sr >>= 3;
+                       xmc[32] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 2;
+                       xmc[33] = sr & 0x7;  sr >>= 3;
+                       xmc[34] = sr & 0x7;  sr >>= 3;
+                       xmc[35] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 1;                 /* 25 */
+                       xmc[36] = sr & 0x7;  sr >>= 3;
+                       xmc[37] = sr & 0x7;  sr >>= 3;
+                       xmc[38] = sr & 0x7;  sr >>= 3;
+                       sr = *c++;
+                       Nc[3] = sr & 0x7f;  sr >>= 7;
+                       sr |= (uword)*c++ << 1;         
+                       bc[3] = sr & 0x3;  sr >>= 2;
+                       Mc[3] = sr & 0x3;  sr >>= 2;
+                       sr |= (uword)*c++ << 5;
+                       xmaxc[3] = sr & 0x3f;  sr >>= 6;
+#undef xmc
+#define        xmc     (source + 63 - 39)
+
+                       xmc[39] = sr & 0x7;  sr >>= 3;
+                       xmc[40] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 1;
+                       xmc[41] = sr & 0x7;  sr >>= 3;
+                       xmc[42] = sr & 0x7;  sr >>= 3;
+                       xmc[43] = sr & 0x7;  sr >>= 3;
+                       sr = *c++;                              /* 30 */
+                       xmc[44] = sr & 0x7;  sr >>= 3;
+                       xmc[45] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 2;
+                       xmc[46] = sr & 0x7;  sr >>= 3;
+                       xmc[47] = sr & 0x7;  sr >>= 3;
+                       xmc[48] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 1;
+                       xmc[49] = sr & 0x7;  sr >>= 3;
+                       xmc[50] = sr & 0x7;  sr >>= 3;
+                       xmc[51] = sr & 0x7;  sr >>= 3;
+               }
+       }
+       else
+#endif 
+       {
+
+       *c++ =   ((GSM_MAGIC & 0xF) << 4)               /* 1 */
+              | ((LARc[0] >> 2) & 0xF);
+       *c++ =   ((LARc[0] & 0x3) << 6)
+              | (LARc[1] & 0x3F);
+       *c++ =   ((LARc[2] & 0x1F) << 3)
+              | ((LARc[3] >> 2) & 0x7);
+       *c++ =   ((LARc[3] & 0x3) << 6)
+              | ((LARc[4] & 0xF) << 2)
+              | ((LARc[5] >> 2) & 0x3);
+       *c++ =   ((LARc[5] & 0x3) << 6)
+              | ((LARc[6] & 0x7) << 3)
+              | (LARc[7] & 0x7);
+
+
+       *c++ =   ((Nc[0] & 0x7F) << 1)
+
+
+              | ((bc[0] >> 1) & 0x1);
+       *c++ =   ((bc[0] & 0x1) << 7)
+
+
+              | ((Mc[0] & 0x3) << 5)
+
+              | ((xmaxc[0] >> 1) & 0x1F);
+       *c++ =   ((xmaxc[0] & 0x1) << 7)
+
+#undef xmc
+#define        xmc     (source + 12)
+
+              | ((xmc[0] & 0x7) << 4)
+              | ((xmc[1] & 0x7) << 1)
+              | ((xmc[2] >> 2) & 0x1);
+       *c++ =   ((xmc[2] & 0x3) << 6)
+              | ((xmc[3] & 0x7) << 3)
+              | (xmc[4] & 0x7);
+       *c++ =   ((xmc[5] & 0x7) << 5)                  /* 10 */
+              | ((xmc[6] & 0x7) << 2)
+              | ((xmc[7] >> 1) & 0x3);
+       *c++ =   ((xmc[7] & 0x1) << 7)
+              | ((xmc[8] & 0x7) << 4)
+              | ((xmc[9] & 0x7) << 1)
+              | ((xmc[10] >> 2) & 0x1);
+       *c++ =   ((xmc[10] & 0x3) << 6)
+              | ((xmc[11] & 0x7) << 3)
+              | (xmc[12] & 0x7);
+
+
+       *c++ =   ((Nc[1] & 0x7F) << 1)
+
+
+              | ((bc[1] >> 1) & 0x1);
+       *c++ =   ((bc[1] & 0x1) << 7)
+
+
+              | ((Mc[1] & 0x3) << 5)
+
+
+              | ((xmaxc[1] >> 1) & 0x1F);
+       *c++ =   ((xmaxc[1] & 0x1) << 7)
+
+#undef xmc
+#define        xmc     (source + 29 - 13)
+
+              | ((xmc[13] & 0x7) << 4)
+              | ((xmc[14] & 0x7) << 1)
+              | ((xmc[15] >> 2) & 0x1);
+       *c++ =   ((xmc[15] & 0x3) << 6)
+              | ((xmc[16] & 0x7) << 3)
+              | (xmc[17] & 0x7);
+       *c++ =   ((xmc[18] & 0x7) << 5)
+              | ((xmc[19] & 0x7) << 2)
+              | ((xmc[20] >> 1) & 0x3);
+       *c++ =   ((xmc[20] & 0x1) << 7)
+              | ((xmc[21] & 0x7) << 4)
+              | ((xmc[22] & 0x7) << 1)
+              | ((xmc[23] >> 2) & 0x1);
+       *c++ =   ((xmc[23] & 0x3) << 6)
+              | ((xmc[24] & 0x7) << 3)
+              | (xmc[25] & 0x7);
+
+
+       *c++ =   ((Nc[2] & 0x7F) << 1)                  /* 20 */
+
+
+              | ((bc[2] >> 1) & 0x1);
+       *c++ =   ((bc[2] & 0x1) << 7)
+
+
+              | ((Mc[2] & 0x3) << 5)
+
+
+              | ((xmaxc[2] >> 1) & 0x1F);
+       *c++ =   ((xmaxc[2] & 0x1) << 7)
+
+#undef xmc
+#define        xmc     (source + 46 - 26)
+
+              | ((xmc[26] & 0x7) << 4)
+              | ((xmc[27] & 0x7) << 1)
+              | ((xmc[28] >> 2) & 0x1);
+       *c++ =   ((xmc[28] & 0x3) << 6)
+              | ((xmc[29] & 0x7) << 3)
+              | (xmc[30] & 0x7);
+       *c++ =   ((xmc[31] & 0x7) << 5)
+              | ((xmc[32] & 0x7) << 2)
+              | ((xmc[33] >> 1) & 0x3);
+       *c++ =   ((xmc[33] & 0x1) << 7)
+              | ((xmc[34] & 0x7) << 4)
+              | ((xmc[35] & 0x7) << 1)
+              | ((xmc[36] >> 2) & 0x1);
+       *c++ =   ((xmc[36] & 0x3) << 6)
+              | ((xmc[37] & 0x7) << 3)
+              | (xmc[38] & 0x7);
+
+
+       *c++ =   ((Nc[3] & 0x7F) << 1)
+
+
+              | ((bc[3] >> 1) & 0x1);
+       *c++ =   ((bc[3] & 0x1) << 7)
+
+
+              | ((Mc[3] & 0x3) << 5)
+
+
+              | ((xmaxc[3] >> 1) & 0x1F);
+       *c++ =   ((xmaxc[3] & 0x1) << 7)
+
+#undef xmc
+#define        xmc     (source + 63 - 39)
+
+              | ((xmc[39] & 0x7) << 4)
+              | ((xmc[40] & 0x7) << 1)
+              | ((xmc[41] >> 2) & 0x1);
+       *c++ =   ((xmc[41] & 0x3) << 6)                 /* 30 */
+              | ((xmc[42] & 0x7) << 3)
+              | (xmc[43] & 0x7);
+       *c++ =   ((xmc[44] & 0x7) << 5)
+              | ((xmc[45] & 0x7) << 2)
+              | ((xmc[46] >> 1) & 0x3);
+       *c++ =   ((xmc[46] & 0x1) << 7)
+              | ((xmc[47] & 0x7) << 4)
+              | ((xmc[48] & 0x7) << 1)
+              | ((xmc[49] >> 2) & 0x1);
+       *c++ =   ((xmc[49] & 0x3) << 6)
+              | ((xmc[50] & 0x7) << 3)
+              | (xmc[51] & 0x7);
+       }
+}
diff --git a/gr-gsm-fr-vocoder/src/lib/gsm/gsm_option.c b/gr-gsm-fr-vocoder/src/lib/gsm/gsm_option.c
new file mode 100644 (file)
index 0000000..2807801
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * 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.
+ */
+
+/* $Header$ */
+
+#include "private.h"
+
+#include "gsm.h"
+#include "proto.h"
+
+int gsm_option P3((r, opt, val), gsm r, int opt, int * val)
+{
+       int     result = -1;
+
+       switch (opt) {
+       case GSM_OPT_LTP_CUT:
+#ifdef         LTP_CUT
+               result = r->ltp_cut;
+               if (val) r->ltp_cut = *val;
+#endif
+               break;
+
+       case GSM_OPT_VERBOSE:
+#ifndef        NDEBUG
+               result = r->verbose;
+               if (val) r->verbose = *val;
+#endif
+               break;
+
+       case GSM_OPT_FAST:
+
+#if    defined(FAST) && defined(USE_FLOAT_MUL)
+               result = r->fast;
+               if (val) r->fast = !!*val;
+#endif
+               break;
+
+       case GSM_OPT_FRAME_CHAIN:
+
+#ifdef WAV49
+               result = r->frame_chain;
+               if (val) r->frame_chain = *val;
+#endif
+               break;
+
+       case GSM_OPT_FRAME_INDEX:
+
+#ifdef WAV49
+               result = r->frame_index;
+               if (val) r->frame_index = *val;
+#endif
+               break;
+
+       case GSM_OPT_WAV49:
+
+#ifdef WAV49 
+               result = r->wav_fmt;
+               if (val) r->wav_fmt = !!*val;
+#endif
+               break;
+
+       default:
+               break;
+       }
+       return result;
+}
diff --git a/gr-gsm-fr-vocoder/src/lib/gsm/gsm_print.c b/gr-gsm-fr-vocoder/src/lib/gsm/gsm_print.c
new file mode 100644 (file)
index 0000000..af745bc
--- /dev/null
@@ -0,0 +1,167 @@
+/*
+ * 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.
+ */
+
+/* $Header$ */
+
+#include       <stdio.h>
+
+#include "private.h"
+
+#include "gsm.h"
+#include "proto.h"
+
+int gsm_print P3((f, s, c), FILE * f, gsm s, gsm_byte * c)
+{
+       word    LARc[8], Nc[4], Mc[4], bc[4], xmaxc[4], xmc[13*4];
+
+       /* GSM_MAGIC  = (*c >> 4) & 0xF; */
+
+       if (((*c >> 4) & 0x0F) != GSM_MAGIC) return -1;
+
+       LARc[0]  = (*c++ & 0xF) << 2;           /* 1 */
+       LARc[0] |= (*c >> 6) & 0x3;
+       LARc[1]  = *c++ & 0x3F;
+       LARc[2]  = (*c >> 3) & 0x1F;
+       LARc[3]  = (*c++ & 0x7) << 2;
+       LARc[3] |= (*c >> 6) & 0x3;
+       LARc[4]  = (*c >> 2) & 0xF;
+       LARc[5]  = (*c++ & 0x3) << 2;
+       LARc[5] |= (*c >> 6) & 0x3;
+       LARc[6]  = (*c >> 3) & 0x7;
+       LARc[7]  = *c++ & 0x7;
+
+
+       Nc[0]  = (*c >> 1) & 0x7F;
+       bc[0]  = (*c++ & 0x1) << 1;
+       bc[0] |= (*c >> 7) & 0x1;
+       Mc[0]  = (*c >> 5) & 0x3;
+       xmaxc[0]  = (*c++ & 0x1F) << 1;
+       xmaxc[0] |= (*c >> 7) & 0x1;
+       xmc[0]  = (*c >> 4) & 0x7;
+       xmc[1]  = (*c >> 1) & 0x7;
+       xmc[2]  = (*c++ & 0x1) << 2;
+       xmc[2] |= (*c >> 6) & 0x3;
+       xmc[3]  = (*c >> 3) & 0x7;
+       xmc[4]  = *c++ & 0x7;
+       xmc[5]  = (*c >> 5) & 0x7;
+       xmc[6]  = (*c >> 2) & 0x7;
+       xmc[7]  = (*c++ & 0x3) << 1;            /* 10 */
+       xmc[7] |= (*c >> 7) & 0x1;
+       xmc[8]  = (*c >> 4) & 0x7;
+       xmc[9]  = (*c >> 1) & 0x7;
+       xmc[10]  = (*c++ & 0x1) << 2;
+       xmc[10] |= (*c >> 6) & 0x3;
+       xmc[11]  = (*c >> 3) & 0x7;
+       xmc[12]  = *c++ & 0x7;
+
+       Nc[1]  = (*c >> 1) & 0x7F;
+       bc[1]  = (*c++ & 0x1) << 1;
+       bc[1] |= (*c >> 7) & 0x1;
+       Mc[1]  = (*c >> 5) & 0x3;
+       xmaxc[1]  = (*c++ & 0x1F) << 1;
+       xmaxc[1] |= (*c >> 7) & 0x1;
+       xmc[13]  = (*c >> 4) & 0x7;
+       xmc[14]  = (*c >> 1) & 0x7;
+       xmc[15]  = (*c++ & 0x1) << 2;
+       xmc[15] |= (*c >> 6) & 0x3;
+       xmc[16]  = (*c >> 3) & 0x7;
+       xmc[17]  = *c++ & 0x7;
+       xmc[18]  = (*c >> 5) & 0x7;
+       xmc[19]  = (*c >> 2) & 0x7;
+       xmc[20]  = (*c++ & 0x3) << 1;
+       xmc[20] |= (*c >> 7) & 0x1;
+       xmc[21]  = (*c >> 4) & 0x7;
+       xmc[22]  = (*c >> 1) & 0x7;
+       xmc[23]  = (*c++ & 0x1) << 2;
+       xmc[23] |= (*c >> 6) & 0x3;
+       xmc[24]  = (*c >> 3) & 0x7;
+       xmc[25]  = *c++ & 0x7;
+
+
+       Nc[2]  = (*c >> 1) & 0x7F;
+       bc[2]  = (*c++ & 0x1) << 1;             /* 20 */
+       bc[2] |= (*c >> 7) & 0x1;
+       Mc[2]  = (*c >> 5) & 0x3;
+       xmaxc[2]  = (*c++ & 0x1F) << 1;
+       xmaxc[2] |= (*c >> 7) & 0x1;
+       xmc[26]  = (*c >> 4) & 0x7;
+       xmc[27]  = (*c >> 1) & 0x7;
+       xmc[28]  = (*c++ & 0x1) << 2;
+       xmc[28] |= (*c >> 6) & 0x3;
+       xmc[29]  = (*c >> 3) & 0x7;
+       xmc[30]  = *c++ & 0x7;
+       xmc[31]  = (*c >> 5) & 0x7;
+       xmc[32]  = (*c >> 2) & 0x7;
+       xmc[33]  = (*c++ & 0x3) << 1;
+       xmc[33] |= (*c >> 7) & 0x1;
+       xmc[34]  = (*c >> 4) & 0x7;
+       xmc[35]  = (*c >> 1) & 0x7;
+       xmc[36]  = (*c++ & 0x1) << 2;
+       xmc[36] |= (*c >> 6) & 0x3;
+       xmc[37]  = (*c >> 3) & 0x7;
+       xmc[38]  = *c++ & 0x7;
+
+       Nc[3]  = (*c >> 1) & 0x7F;
+       bc[3]  = (*c++ & 0x1) << 1;
+       bc[3] |= (*c >> 7) & 0x1;
+       Mc[3]  = (*c >> 5) & 0x3;
+       xmaxc[3]  = (*c++ & 0x1F) << 1;
+       xmaxc[3] |= (*c >> 7) & 0x1;
+
+       xmc[39]  = (*c >> 4) & 0x7;
+       xmc[40]  = (*c >> 1) & 0x7;
+       xmc[41]  = (*c++ & 0x1) << 2;
+       xmc[41] |= (*c >> 6) & 0x3;
+       xmc[42]  = (*c >> 3) & 0x7;
+       xmc[43]  = *c++ & 0x7;                  /* 30  */
+       xmc[44]  = (*c >> 5) & 0x7;
+       xmc[45]  = (*c >> 2) & 0x7;
+       xmc[46]  = (*c++ & 0x3) << 1;
+       xmc[46] |= (*c >> 7) & 0x1;
+       xmc[47]  = (*c >> 4) & 0x7;
+       xmc[48]  = (*c >> 1) & 0x7;
+       xmc[49]  = (*c++ & 0x1) << 2;
+       xmc[49] |= (*c >> 6) & 0x3;
+       xmc[50]  = (*c >> 3) & 0x7;
+       xmc[51]  = *c & 0x7;                    /* 33 */
+
+       fprintf(f,
+             "LARc:\t%2.2d  %2.2d  %2.2d  %2.2d  %2.2d  %2.2d  %2.2d  %2.2d\n",
+              LARc[0],LARc[1],LARc[2],LARc[3],LARc[4],LARc[5],LARc[6],LARc[7]);
+
+       fprintf(f, "#1:         Nc %4.4d    bc %d    Mc %d    xmaxc %d\n",
+               Nc[0], bc[0], Mc[0], xmaxc[0]);
+       fprintf(f,
+"\t%.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d\n",
+               xmc[0],xmc[1],xmc[2],xmc[3],xmc[4],xmc[5],xmc[6],
+               xmc[7],xmc[8],xmc[9],xmc[10],xmc[11],xmc[12] );
+
+       fprintf(f, "#2:         Nc %4.4d    bc %d    Mc %d    xmaxc %d\n",
+               Nc[1], bc[1], Mc[1], xmaxc[1]);
+       fprintf(f,
+"\t%.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d\n",
+               xmc[13+0],xmc[13+1],xmc[13+2],xmc[13+3],xmc[13+4],xmc[13+5],
+               xmc[13+6], xmc[13+7],xmc[13+8],xmc[13+9],xmc[13+10],xmc[13+11],
+               xmc[13+12] );
+
+       fprintf(f, "#3:         Nc %4.4d    bc %d    Mc %d    xmaxc %d\n",
+               Nc[2], bc[2], Mc[2], xmaxc[2]);
+       fprintf(f,
+"\t%.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d\n",
+               xmc[26+0],xmc[26+1],xmc[26+2],xmc[26+3],xmc[26+4],xmc[26+5],
+               xmc[26+6], xmc[26+7],xmc[26+8],xmc[26+9],xmc[26+10],xmc[26+11],
+               xmc[26+12] );
+
+       fprintf(f, "#4:         Nc %4.4d    bc %d    Mc %d    xmaxc %d\n",
+               Nc[3], bc[3], Mc[3], xmaxc[3]);
+       fprintf(f,
+"\t%.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d\n",
+               xmc[39+0],xmc[39+1],xmc[39+2],xmc[39+3],xmc[39+4],xmc[39+5],
+               xmc[39+6], xmc[39+7],xmc[39+8],xmc[39+9],xmc[39+10],xmc[39+11],
+               xmc[39+12] );
+
+       return 0;
+}
diff --git a/gr-gsm-fr-vocoder/src/lib/gsm/long_term.c b/gr-gsm-fr-vocoder/src/lib/gsm/long_term.c
new file mode 100644 (file)
index 0000000..fd67bda
--- /dev/null
@@ -0,0 +1,949 @@
+/*
+ * 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.
+ */
+
+/* $Header$ */
+
+#include <stdio.h>
+#include <assert.h>
+
+#include "private.h"
+
+#include "gsm.h"
+#include "proto.h"
+
+/*
+ *  4.2.11 .. 4.2.12 LONG TERM PREDICTOR (LTP) SECTION
+ */
+
+
+/*
+ * This module computes the LTP gain (bc) and the LTP lag (Nc)
+ * for the long term analysis filter.   This is done by calculating a
+ * maximum of the cross-correlation function between the current
+ * sub-segment short term residual signal d[0..39] (output of
+ * the short term analysis filter; for simplification the index
+ * of this array begins at 0 and ends at 39 for each sub-segment of the
+ * RPE-LTP analysis) and the previous reconstructed short term
+ * residual signal dp[ -120 .. -1 ].  A dynamic scaling must be
+ * performed to avoid overflow.
+ */
+
+ /* The next procedure exists in six versions.  First two integer
+  * version (if USE_FLOAT_MUL is not defined); then four floating
+  * point versions, twice with proper scaling (USE_FLOAT_MUL defined),
+  * once without (USE_FLOAT_MUL and FAST defined, and fast run-time
+  * option used).  Every pair has first a Cut version (see the -C
+  * option to toast or the LTP_CUT option to gsm_option()), then the
+  * uncut one.  (For a detailed explanation of why this is altogether
+  * a bad idea, see Henry Spencer and Geoff Collyer, ``#ifdef Considered
+  * Harmful''.)
+  */
+
+#ifndef  USE_FLOAT_MUL
+
+#ifdef LTP_CUT
+
+static void Cut_Calculation_of_the_LTP_parameters P5((st, d,dp,bc_out,Nc_out),
+
+       struct gsm_state * st,
+
+       register word   * d,            /* [0..39]      IN      */
+       register word   * dp,           /* [-120..-1]   IN      */
+       word            * bc_out,       /*              OUT     */
+       word            * Nc_out        /*              OUT     */
+)
+{
+       register int    k, lambda;
+       word            Nc, bc;
+       word            wt[40];
+
+       longword        L_result;
+       longword        L_max, L_power;
+       word            R, S, dmax, scal, best_k;
+       word            ltp_cut;
+
+       register word   temp, wt_k;
+
+       /*  Search of the optimum scaling of d[0..39].
+        */
+       dmax = 0;
+       for (k = 0; k <= 39; k++) {
+               temp = d[k];
+               temp = GSM_ABS( temp );
+               if (temp > dmax) {
+                       dmax = temp;
+                       best_k = k;
+               }
+       }
+       temp = 0;
+       if (dmax == 0) scal = 0;
+       else {
+               assert(dmax > 0);
+               temp = gsm_norm( (longword)dmax << 16 );
+       }
+       if (temp > 6) scal = 0;
+       else scal = 6 - temp;
+       assert(scal >= 0);
+
+       /* Search for the maximum cross-correlation and coding of the LTP lag
+        */
+       L_max = 0;
+       Nc    = 40;     /* index for the maximum cross-correlation */
+       wt_k  = SASR(d[best_k], scal);
+
+       for (lambda = 40; lambda <= 120; lambda++) {
+               L_result = (longword)wt_k * dp[best_k - lambda];
+               if (L_result > L_max) {
+                       Nc    = lambda;
+                       L_max = L_result;
+               }
+       }
+       *Nc_out = Nc;
+       L_max <<= 1;
+
+       /*  Rescaling of L_max
+        */
+       assert(scal <= 100 && scal >= -100);
+       L_max = L_max >> (6 - scal);    /* sub(6, scal) */
+
+       assert( Nc <= 120 && Nc >= 40);
+
+       /*   Compute the power of the reconstructed short term residual
+        *   signal dp[..]
+        */
+       L_power = 0;
+       for (k = 0; k <= 39; k++) {
+
+               register longword L_temp;
+
+               L_temp   = SASR( dp[k - Nc], 3 );
+               L_power += L_temp * L_temp;
+       }
+       L_power <<= 1;  /* from L_MULT */
+
+       /*  Normalization of L_max and L_power
+        */
+
+       if (L_max <= 0)  {
+               *bc_out = 0;
+               return;
+       }
+       if (L_max >= L_power) {
+               *bc_out = 3;
+               return;
+       }
+
+       temp = gsm_norm( L_power );
+
+       R = SASR( L_max   << temp, 16 );
+       S = SASR( L_power << temp, 16 );
+
+       /*  Coding of the LTP gain
+        */
+
+       /*  Table 4.3a must be used to obtain the level DLB[i] for the
+        *  quantization of the LTP gain b to get the coded version bc.
+        */
+       for (bc = 0; bc <= 2; bc++) if (R <= gsm_mult(S, gsm_DLB[bc])) break;
+       *bc_out = bc;
+}
+
+#endif         /* LTP_CUT */
+
+static void Calculation_of_the_LTP_parameters P4((d,dp,bc_out,Nc_out),
+       register word   * d,            /* [0..39]      IN      */
+       register word   * dp,           /* [-120..-1]   IN      */
+       word            * bc_out,       /*              OUT     */
+       word            * Nc_out        /*              OUT     */
+)
+{
+       register int    k, lambda;
+       word            Nc, bc;
+       word            wt[40];
+
+       longword        L_max, L_power;
+       word            R, S, dmax, scal;
+       register word   temp;
+
+       /*  Search of the optimum scaling of d[0..39].
+        */
+       dmax = 0;
+
+       for (k = 0; k <= 39; k++) {
+               temp = d[k];
+               temp = GSM_ABS( temp );
+               if (temp > dmax) dmax = temp;
+       }
+
+       temp = 0;
+       if (dmax == 0) scal = 0;
+       else {
+               assert(dmax > 0);
+               temp = gsm_norm( (longword)dmax << 16 );
+       }
+
+       if (temp > 6) scal = 0;
+       else scal = 6 - temp;
+
+       assert(scal >= 0);
+
+       /*  Initialization of a working array wt
+        */
+
+       for (k = 0; k <= 39; k++) wt[k] = SASR( d[k], scal );
+
+       /* Search for the maximum cross-correlation and coding of the LTP lag
+        */
+       L_max = 0;
+       Nc    = 40;     /* index for the maximum cross-correlation */
+
+       for (lambda = 40; lambda <= 120; lambda++) {
+
+# undef STEP
+#              define STEP(k)  (longword)wt[k] * dp[k - lambda]
+
+               register longword L_result;
+
+               L_result  = STEP(0)  ; L_result += STEP(1) ;
+               L_result += STEP(2)  ; L_result += STEP(3) ;
+               L_result += STEP(4)  ; L_result += STEP(5)  ;
+               L_result += STEP(6)  ; L_result += STEP(7)  ;
+               L_result += STEP(8)  ; L_result += STEP(9)  ;
+               L_result += STEP(10) ; L_result += STEP(11) ;
+               L_result += STEP(12) ; L_result += STEP(13) ;
+               L_result += STEP(14) ; L_result += STEP(15) ;
+               L_result += STEP(16) ; L_result += STEP(17) ;
+               L_result += STEP(18) ; L_result += STEP(19) ;
+               L_result += STEP(20) ; L_result += STEP(21) ;
+               L_result += STEP(22) ; L_result += STEP(23) ;
+               L_result += STEP(24) ; L_result += STEP(25) ;
+               L_result += STEP(26) ; L_result += STEP(27) ;
+               L_result += STEP(28) ; L_result += STEP(29) ;
+               L_result += STEP(30) ; L_result += STEP(31) ;
+               L_result += STEP(32) ; L_result += STEP(33) ;
+               L_result += STEP(34) ; L_result += STEP(35) ;
+               L_result += STEP(36) ; L_result += STEP(37) ;
+               L_result += STEP(38) ; L_result += STEP(39) ;
+
+               if (L_result > L_max) {
+
+                       Nc    = lambda;
+                       L_max = L_result;
+               }
+       }
+
+       *Nc_out = Nc;
+
+       L_max <<= 1;
+
+       /*  Rescaling of L_max
+        */
+       assert(scal <= 100 && scal >=  -100);
+       L_max = L_max >> (6 - scal);    /* sub(6, scal) */
+
+       assert( Nc <= 120 && Nc >= 40);
+
+       /*   Compute the power of the reconstructed short term residual
+        *   signal dp[..]
+        */
+       L_power = 0;
+       for (k = 0; k <= 39; k++) {
+
+               register longword L_temp;
+
+               L_temp   = SASR( dp[k - Nc], 3 );
+               L_power += L_temp * L_temp;
+       }
+       L_power <<= 1;  /* from L_MULT */
+
+       /*  Normalization of L_max and L_power
+        */
+
+       if (L_max <= 0)  {
+               *bc_out = 0;
+               return;
+       }
+       if (L_max >= L_power) {
+               *bc_out = 3;
+               return;
+       }
+
+       temp = gsm_norm( L_power );
+
+       R = SASR( L_max   << temp, 16 );
+       S = SASR( L_power << temp, 16 );
+
+       /*  Coding of the LTP gain
+        */
+
+       /*  Table 4.3a must be used to obtain the level DLB[i] for the
+        *  quantization of the LTP gain b to get the coded version bc.
+        */
+       for (bc = 0; bc <= 2; bc++) if (R <= gsm_mult(S, gsm_DLB[bc])) break;
+       *bc_out = bc;
+}
+
+#else  /* USE_FLOAT_MUL */
+
+#ifdef LTP_CUT
+
+static void Cut_Calculation_of_the_LTP_parameters P5((st, d,dp,bc_out,Nc_out),
+       struct gsm_state * st,          /*              IN      */
+       register word   * d,            /* [0..39]      IN      */
+       register word   * dp,           /* [-120..-1]   IN      */
+       word            * bc_out,       /*              OUT     */
+       word            * Nc_out        /*              OUT     */
+)
+{
+       register int    k, lambda;
+       word            Nc, bc;
+       word            ltp_cut;
+
+       float           wt_float[40];
+       float           dp_float_base[120], * dp_float = dp_float_base + 120;
+
+       longword        L_max, L_power;
+       word            R, S, dmax, scal;
+       register word   temp;
+
+       /*  Search of the optimum scaling of d[0..39].
+        */
+       dmax = 0;
+
+       for (k = 0; k <= 39; k++) {
+               temp = d[k];
+               temp = GSM_ABS( temp );
+               if (temp > dmax) dmax = temp;
+       }
+
+       temp = 0;
+       if (dmax == 0) scal = 0;
+       else {
+               assert(dmax > 0);
+               temp = gsm_norm( (longword)dmax << 16 );
+       }
+
+       if (temp > 6) scal = 0;
+       else scal = 6 - temp;
+
+       assert(scal >= 0);
+       ltp_cut = (longword)SASR(dmax, scal) * st->ltp_cut / 100; 
+
+
+       /*  Initialization of a working array wt
+        */
+
+       for (k = 0; k < 40; k++) {
+               register word w = SASR( d[k], scal );
+               if (w < 0 ? w > -ltp_cut : w < ltp_cut) {
+                       wt_float[k] = 0.0;
+               }
+               else {
+                       wt_float[k] =  w;
+               }
+       }
+       for (k = -120; k <  0; k++) dp_float[k] =  dp[k];
+
+       /* Search for the maximum cross-correlation and coding of the LTP lag
+        */
+       L_max = 0;
+       Nc    = 40;     /* index for the maximum cross-correlation */
+
+       for (lambda = 40; lambda <= 120; lambda += 9) {
+
+               /*  Calculate L_result for l = lambda .. lambda + 9.
+                */
+               register float *lp = dp_float - lambda;
+
+               register float  W;
+               register float  a = lp[-8], b = lp[-7], c = lp[-6],
+                               d = lp[-5], e = lp[-4], f = lp[-3],
+                               g = lp[-2], h = lp[-1];
+               register float  E; 
+               register float  S0 = 0, S1 = 0, S2 = 0, S3 = 0, S4 = 0,
+                               S5 = 0, S6 = 0, S7 = 0, S8 = 0;
+
+#              undef STEP
+#              define  STEP(K, a, b, c, d, e, f, g, h) \
+                       if ((W = wt_float[K]) != 0.0) { \
+                       E = W * a; S8 += E;             \
+                       E = W * b; S7 += E;             \
+                       E = W * c; S6 += E;             \
+                       E = W * d; S5 += E;             \
+                       E = W * e; S4 += E;             \
+                       E = W * f; S3 += E;             \
+                       E = W * g; S2 += E;             \
+                       E = W * h; S1 += E;             \
+                       a  = lp[K];                     \
+                       E = W * a; S0 += E; } else (a = lp[K])
+
+#              define  STEP_A(K)       STEP(K, a, b, c, d, e, f, g, h)
+#              define  STEP_B(K)       STEP(K, b, c, d, e, f, g, h, a)
+#              define  STEP_C(K)       STEP(K, c, d, e, f, g, h, a, b)
+#              define  STEP_D(K)       STEP(K, d, e, f, g, h, a, b, c)
+#              define  STEP_E(K)       STEP(K, e, f, g, h, a, b, c, d)
+#              define  STEP_F(K)       STEP(K, f, g, h, a, b, c, d, e)
+#              define  STEP_G(K)       STEP(K, g, h, a, b, c, d, e, f)
+#              define  STEP_H(K)       STEP(K, h, a, b, c, d, e, f, g)
+
+               STEP_A( 0); STEP_B( 1); STEP_C( 2); STEP_D( 3);
+               STEP_E( 4); STEP_F( 5); STEP_G( 6); STEP_H( 7);
+
+               STEP_A( 8); STEP_B( 9); STEP_C(10); STEP_D(11);
+               STEP_E(12); STEP_F(13); STEP_G(14); STEP_H(15);
+
+               STEP_A(16); STEP_B(17); STEP_C(18); STEP_D(19);
+               STEP_E(20); STEP_F(21); STEP_G(22); STEP_H(23);
+
+               STEP_A(24); STEP_B(25); STEP_C(26); STEP_D(27);
+               STEP_E(28); STEP_F(29); STEP_G(30); STEP_H(31);
+
+               STEP_A(32); STEP_B(33); STEP_C(34); STEP_D(35);
+               STEP_E(36); STEP_F(37); STEP_G(38); STEP_H(39);
+
+               if (S0 > L_max) { L_max = S0; Nc = lambda;     }
+               if (S1 > L_max) { L_max = S1; Nc = lambda + 1; }
+               if (S2 > L_max) { L_max = S2; Nc = lambda + 2; }
+               if (S3 > L_max) { L_max = S3; Nc = lambda + 3; }
+               if (S4 > L_max) { L_max = S4; Nc = lambda + 4; }
+               if (S5 > L_max) { L_max = S5; Nc = lambda + 5; }
+               if (S6 > L_max) { L_max = S6; Nc = lambda + 6; }
+               if (S7 > L_max) { L_max = S7; Nc = lambda + 7; }
+               if (S8 > L_max) { L_max = S8; Nc = lambda + 8; }
+
+       }
+       *Nc_out = Nc;
+
+       L_max <<= 1;
+
+       /*  Rescaling of L_max
+        */
+       assert(scal <= 100 && scal >=  -100);
+       L_max = L_max >> (6 - scal);    /* sub(6, scal) */
+
+       assert( Nc <= 120 && Nc >= 40);
+
+       /*   Compute the power of the reconstructed short term residual
+        *   signal dp[..]
+        */
+       L_power = 0;
+       for (k = 0; k <= 39; k++) {
+
+               register longword L_temp;
+
+               L_temp   = SASR( dp[k - Nc], 3 );
+               L_power += L_temp * L_temp;
+       }
+       L_power <<= 1;  /* from L_MULT */
+
+       /*  Normalization of L_max and L_power
+        */
+
+       if (L_max <= 0)  {
+               *bc_out = 0;
+               return;
+       }
+       if (L_max >= L_power) {
+               *bc_out = 3;
+               return;
+       }
+
+       temp = gsm_norm( L_power );
+
+       R = SASR( L_max   << temp, 16 );
+       S = SASR( L_power << temp, 16 );
+
+       /*  Coding of the LTP gain
+        */
+
+       /*  Table 4.3a must be used to obtain the level DLB[i] for the
+        *  quantization of the LTP gain b to get the coded version bc.
+        */
+       for (bc = 0; bc <= 2; bc++) if (R <= gsm_mult(S, gsm_DLB[bc])) break;
+       *bc_out = bc;
+}
+
+#endif /* LTP_CUT */
+
+static void Calculation_of_the_LTP_parameters P4((d,dp,bc_out,Nc_out),
+       register word   * d,            /* [0..39]      IN      */
+       register word   * dp,           /* [-120..-1]   IN      */
+       word            * bc_out,       /*              OUT     */
+       word            * Nc_out        /*              OUT     */
+)
+{
+       register int    k, lambda;
+       word            Nc, bc;
+
+       float           wt_float[40];
+       float           dp_float_base[120], * dp_float = dp_float_base + 120;
+
+       longword        L_max, L_power;
+       word            R, S, dmax, scal;
+       register word   temp;
+
+       /*  Search of the optimum scaling of d[0..39].
+        */
+       dmax = 0;
+
+       for (k = 0; k <= 39; k++) {
+               temp = d[k];
+               temp = GSM_ABS( temp );
+               if (temp > dmax) dmax = temp;
+       }
+
+       temp = 0;
+       if (dmax == 0) scal = 0;
+       else {
+               assert(dmax > 0);
+               temp = gsm_norm( (longword)dmax << 16 );
+       }
+
+       if (temp > 6) scal = 0;
+       else scal = 6 - temp;
+
+       assert(scal >= 0);
+
+       /*  Initialization of a working array wt
+        */
+
+       for (k =    0; k < 40; k++) wt_float[k] =  SASR( d[k], scal );
+       for (k = -120; k <  0; k++) dp_float[k] =  dp[k];
+
+       /* Search for the maximum cross-correlation and coding of the LTP lag
+        */
+       L_max = 0;
+       Nc    = 40;     /* index for the maximum cross-correlation */
+
+       for (lambda = 40; lambda <= 120; lambda += 9) {
+
+               /*  Calculate L_result for l = lambda .. lambda + 9.
+                */
+               register float *lp = dp_float - lambda;
+
+               register float  W;
+               register float  a = lp[-8], b = lp[-7], c = lp[-6],
+                               d = lp[-5], e = lp[-4], f = lp[-3],
+                               g = lp[-2], h = lp[-1];
+               register float  E; 
+               register float  S0 = 0, S1 = 0, S2 = 0, S3 = 0, S4 = 0,
+                               S5 = 0, S6 = 0, S7 = 0, S8 = 0;
+
+#              undef STEP
+#              define  STEP(K, a, b, c, d, e, f, g, h) \
+                       W = wt_float[K];                \
+                       E = W * a; S8 += E;             \
+                       E = W * b; S7 += E;             \
+                       E = W * c; S6 += E;             \
+                       E = W * d; S5 += E;             \
+                       E = W * e; S4 += E;             \
+                       E = W * f; S3 += E;             \
+                       E = W * g; S2 += E;             \
+                       E = W * h; S1 += E;             \
+                       a  = lp[K];                     \
+                       E = W * a; S0 += E
+
+#              define  STEP_A(K)       STEP(K, a, b, c, d, e, f, g, h)
+#              define  STEP_B(K)       STEP(K, b, c, d, e, f, g, h, a)
+#              define  STEP_C(K)       STEP(K, c, d, e, f, g, h, a, b)
+#              define  STEP_D(K)       STEP(K, d, e, f, g, h, a, b, c)
+#              define  STEP_E(K)       STEP(K, e, f, g, h, a, b, c, d)
+#              define  STEP_F(K)       STEP(K, f, g, h, a, b, c, d, e)
+#              define  STEP_G(K)       STEP(K, g, h, a, b, c, d, e, f)
+#              define  STEP_H(K)       STEP(K, h, a, b, c, d, e, f, g)
+
+               STEP_A( 0); STEP_B( 1); STEP_C( 2); STEP_D( 3);
+               STEP_E( 4); STEP_F( 5); STEP_G( 6); STEP_H( 7);
+
+               STEP_A( 8); STEP_B( 9); STEP_C(10); STEP_D(11);
+               STEP_E(12); STEP_F(13); STEP_G(14); STEP_H(15);
+
+               STEP_A(16); STEP_B(17); STEP_C(18); STEP_D(19);
+               STEP_E(20); STEP_F(21); STEP_G(22); STEP_H(23);
+
+               STEP_A(24); STEP_B(25); STEP_C(26); STEP_D(27);
+               STEP_E(28); STEP_F(29); STEP_G(30); STEP_H(31);
+
+               STEP_A(32); STEP_B(33); STEP_C(34); STEP_D(35);
+               STEP_E(36); STEP_F(37); STEP_G(38); STEP_H(39);
+
+               if (S0 > L_max) { L_max = S0; Nc = lambda;     }
+               if (S1 > L_max) { L_max = S1; Nc = lambda + 1; }
+               if (S2 > L_max) { L_max = S2; Nc = lambda + 2; }
+               if (S3 > L_max) { L_max = S3; Nc = lambda + 3; }
+               if (S4 > L_max) { L_max = S4; Nc = lambda + 4; }
+               if (S5 > L_max) { L_max = S5; Nc = lambda + 5; }
+               if (S6 > L_max) { L_max = S6; Nc = lambda + 6; }
+               if (S7 > L_max) { L_max = S7; Nc = lambda + 7; }
+               if (S8 > L_max) { L_max = S8; Nc = lambda + 8; }
+       }
+       *Nc_out = Nc;
+
+       L_max <<= 1;
+
+       /*  Rescaling of L_max
+        */
+       assert(scal <= 100 && scal >=  -100);
+       L_max = L_max >> (6 - scal);    /* sub(6, scal) */
+
+       assert( Nc <= 120 && Nc >= 40);
+
+       /*   Compute the power of the reconstructed short term residual
+        *   signal dp[..]
+        */
+       L_power = 0;
+       for (k = 0; k <= 39; k++) {
+
+               register longword L_temp;
+
+               L_temp   = SASR( dp[k - Nc], 3 );
+               L_power += L_temp * L_temp;
+       }
+       L_power <<= 1;  /* from L_MULT */
+
+       /*  Normalization of L_max and L_power
+        */
+
+       if (L_max <= 0)  {
+               *bc_out = 0;
+               return;
+       }
+       if (L_max >= L_power) {
+               *bc_out = 3;
+               return;
+       }
+
+       temp = gsm_norm( L_power );
+
+       R = SASR( L_max   << temp, 16 );
+       S = SASR( L_power << temp, 16 );
+
+       /*  Coding of the LTP gain
+        */
+
+       /*  Table 4.3a must be used to obtain the level DLB[i] for the
+        *  quantization of the LTP gain b to get the coded version bc.
+        */
+       for (bc = 0; bc <= 2; bc++) if (R <= gsm_mult(S, gsm_DLB[bc])) break;
+       *bc_out = bc;
+}
+
+#ifdef FAST
+#ifdef LTP_CUT
+
+static void Cut_Fast_Calculation_of_the_LTP_parameters P5((st,
+                                                       d,dp,bc_out,Nc_out),
+       struct gsm_state * st,          /*              IN      */
+       register word   * d,            /* [0..39]      IN      */
+       register word   * dp,           /* [-120..-1]   IN      */
+       word            * bc_out,       /*              OUT     */
+       word            * Nc_out        /*              OUT     */
+)
+{
+       register int    k, lambda;
+       register float  wt_float;
+       word            Nc, bc;
+       word            wt_max, best_k, ltp_cut;
+
+       float           dp_float_base[120], * dp_float = dp_float_base + 120;
+
+       register float  L_result, L_max, L_power;
+
+       wt_max = 0;
+
+       for (k = 0; k < 40; ++k) {
+               if      ( d[k] > wt_max) wt_max =  d[best_k = k];
+               else if (-d[k] > wt_max) wt_max = -d[best_k = k];
+       }
+
+       assert(wt_max >= 0);
+       wt_float = (float)wt_max;
+
+       for (k = -120; k < 0; ++k) dp_float[k] = (float)dp[k];
+
+       /* Search for the maximum cross-correlation and coding of the LTP lag
+        */
+       L_max = 0;
+       Nc    = 40;     /* index for the maximum cross-correlation */
+
+       for (lambda = 40; lambda <= 120; lambda++) {
+               L_result = wt_float * dp_float[best_k - lambda];
+               if (L_result > L_max) {
+                       Nc    = lambda;
+                       L_max = L_result;
+               }
+       }
+
+       *Nc_out = Nc;
+       if (L_max <= 0.)  {
+               *bc_out = 0;
+               return;
+       }
+
+       /*  Compute the power of the reconstructed short term residual
+        *  signal dp[..]
+        */
+       dp_float -= Nc;
+       L_power = 0;
+       for (k = 0; k < 40; ++k) {
+               register float f = dp_float[k];
+               L_power += f * f;
+       }
+
+       if (L_max >= L_power) {
+               *bc_out = 3;
+               return;
+       }
+
+       /*  Coding of the LTP gain
+        *  Table 4.3a must be used to obtain the level DLB[i] for the
+        *  quantization of the LTP gain b to get the coded version bc.
+        */
+       lambda = L_max / L_power * 32768.;
+       for (bc = 0; bc <= 2; ++bc) if (lambda <= gsm_DLB[bc]) break;
+       *bc_out = bc;
+}
+
+#endif /* LTP_CUT */
+
+static void Fast_Calculation_of_the_LTP_parameters P4((d,dp,bc_out,Nc_out),
+       register word   * d,            /* [0..39]      IN      */
+       register word   * dp,           /* [-120..-1]   IN      */
+       word            * bc_out,       /*              OUT     */
+       word            * Nc_out        /*              OUT     */
+)
+{
+       register int    k, lambda;
+       word            Nc, bc;
+
+       float           wt_float[40];
+       float           dp_float_base[120], * dp_float = dp_float_base + 120;
+
+       register float  L_max, L_power;
+
+       for (k = 0; k < 40; ++k) wt_float[k] = (float)d[k];
+       for (k = -120; k < 0; ++k) dp_float[k] = (float)dp[k];
+
+       /* Search for the maximum cross-correlation and coding of the LTP lag
+        */
+       L_max = 0;
+       Nc    = 40;     /* index for the maximum cross-correlation */
+
+       for (lambda = 40; lambda <= 120; lambda += 9) {
+
+               /*  Calculate L_result for l = lambda .. lambda + 9.
+                */
+               register float *lp = dp_float - lambda;
+
+               register float  W;
+               register float  a = lp[-8], b = lp[-7], c = lp[-6],
+                               d = lp[-5], e = lp[-4], f = lp[-3],
+                               g = lp[-2], h = lp[-1];
+               register float  E; 
+               register float  S0 = 0, S1 = 0, S2 = 0, S3 = 0, S4 = 0,
+                               S5 = 0, S6 = 0, S7 = 0, S8 = 0;
+
+#              undef STEP
+#              define  STEP(K, a, b, c, d, e, f, g, h) \
+                       W = wt_float[K];                \
+                       E = W * a; S8 += E;             \
+                       E = W * b; S7 += E;             \
+                       E = W * c; S6 += E;             \
+                       E = W * d; S5 += E;             \
+                       E = W * e; S4 += E;             \
+                       E = W * f; S3 += E;             \
+                       E = W * g; S2 += E;             \
+                       E = W * h; S1 += E;             \
+                       a  = lp[K];                     \
+                       E = W * a; S0 += E
+
+#              define  STEP_A(K)       STEP(K, a, b, c, d, e, f, g, h)
+#              define  STEP_B(K)       STEP(K, b, c, d, e, f, g, h, a)
+#              define  STEP_C(K)       STEP(K, c, d, e, f, g, h, a, b)
+#              define  STEP_D(K)       STEP(K, d, e, f, g, h, a, b, c)
+#              define  STEP_E(K)       STEP(K, e, f, g, h, a, b, c, d)
+#              define  STEP_F(K)       STEP(K, f, g, h, a, b, c, d, e)
+#              define  STEP_G(K)       STEP(K, g, h, a, b, c, d, e, f)
+#              define  STEP_H(K)       STEP(K, h, a, b, c, d, e, f, g)
+
+               STEP_A( 0); STEP_B( 1); STEP_C( 2); STEP_D( 3);
+               STEP_E( 4); STEP_F( 5); STEP_G( 6); STEP_H( 7);
+
+               STEP_A( 8); STEP_B( 9); STEP_C(10); STEP_D(11);
+               STEP_E(12); STEP_F(13); STEP_G(14); STEP_H(15);
+
+               STEP_A(16); STEP_B(17); STEP_C(18); STEP_D(19);
+               STEP_E(20); STEP_F(21); STEP_G(22); STEP_H(23);
+
+               STEP_A(24); STEP_B(25); STEP_C(26); STEP_D(27);
+               STEP_E(28); STEP_F(29); STEP_G(30); STEP_H(31);
+
+               STEP_A(32); STEP_B(33); STEP_C(34); STEP_D(35);
+               STEP_E(36); STEP_F(37); STEP_G(38); STEP_H(39);
+
+               if (S0 > L_max) { L_max = S0; Nc = lambda;     }
+               if (S1 > L_max) { L_max = S1; Nc = lambda + 1; }
+               if (S2 > L_max) { L_max = S2; Nc = lambda + 2; }
+               if (S3 > L_max) { L_max = S3; Nc = lambda + 3; }
+               if (S4 > L_max) { L_max = S4; Nc = lambda + 4; }
+               if (S5 > L_max) { L_max = S5; Nc = lambda + 5; }
+               if (S6 > L_max) { L_max = S6; Nc = lambda + 6; }
+               if (S7 > L_max) { L_max = S7; Nc = lambda + 7; }
+               if (S8 > L_max) { L_max = S8; Nc = lambda + 8; }
+       }
+       *Nc_out = Nc;
+
+       if (L_max <= 0.)  {
+               *bc_out = 0;
+               return;
+       }
+
+       /*  Compute the power of the reconstructed short term residual
+        *  signal dp[..]
+        */
+       dp_float -= Nc;
+       L_power = 0;
+       for (k = 0; k < 40; ++k) {
+               register float f = dp_float[k];
+               L_power += f * f;
+       }
+
+       if (L_max >= L_power) {
+               *bc_out = 3;
+               return;
+       }
+
+       /*  Coding of the LTP gain
+        *  Table 4.3a must be used to obtain the level DLB[i] for the
+        *  quantization of the LTP gain b to get the coded version bc.
+        */
+       lambda = L_max / L_power * 32768.;
+       for (bc = 0; bc <= 2; ++bc) if (lambda <= gsm_DLB[bc]) break;
+       *bc_out = bc;
+}
+
+#endif /* FAST          */
+#endif /* USE_FLOAT_MUL */
+
+
+/* 4.2.12 */
+
+static void Long_term_analysis_filtering P6((bc,Nc,dp,d,dpp,e),
+       word            bc,     /*                                      IN  */
+       word            Nc,     /*                                      IN  */
+       register word   * dp,   /* previous d   [-120..-1]              IN  */
+       register word   * d,    /* d            [0..39]                 IN  */
+       register word   * dpp,  /* estimate     [0..39]                 OUT */
+       register word   * e     /* long term res. signal [0..39]        OUT */
+)
+/*
+ *  In this part, we have to decode the bc parameter to compute
+ *  the samples of the estimate dpp[0..39].  The decoding of bc needs the
+ *  use of table 4.3b.  The long term residual signal e[0..39]
+ *  is then calculated to be fed to the RPE encoding section.
+ */
+{
+       register int      k;
+       register longword ltmp;
+
+#      undef STEP
+#      define STEP(BP)                                 \
+       for (k = 0; k <= 39; k++) {                     \
+               dpp[k]  = GSM_MULT_R( BP, dp[k - Nc]);  \
+               e[k]    = GSM_SUB( d[k], dpp[k] );      \
+       }
+
+       switch (bc) {
+       case 0: STEP(  3277 ); break;
+       case 1: STEP( 11469 ); break;
+       case 2: STEP( 21299 ); break;
+       case 3: STEP( 32767 ); break; 
+       }
+}
+
+void Gsm_Long_Term_Predictor P7((S,d,dp,e,dpp,Nc,bc),  /* 4x for 160 samples */
+
+       struct gsm_state        * S,
+
+       word    * d,    /* [0..39]   residual signal    IN      */
+       word    * dp,   /* [-120..-1] d'                IN      */
+
+       word    * e,    /* [0..39]                      OUT     */
+       word    * dpp,  /* [0..39]                      OUT     */
+       word    * Nc,   /* correlation lag              OUT     */
+       word    * bc    /* gain factor                  OUT     */
+)
+{
+       assert( d  ); assert( dp ); assert( e  );
+       assert( dpp); assert( Nc ); assert( bc );
+
+#if defined(FAST) && defined(USE_FLOAT_MUL)
+       if (S->fast) 
+#if   defined (LTP_CUT)
+               if (S->ltp_cut)
+                       Cut_Fast_Calculation_of_the_LTP_parameters(S,
+                               d, dp, bc, Nc);
+               else
+#endif /* LTP_CUT */
+                       Fast_Calculation_of_the_LTP_parameters(d, dp, bc, Nc );
+       else 
+#endif /* FAST & USE_FLOAT_MUL */
+#ifdef LTP_CUT
+               if (S->ltp_cut)
+                       Cut_Calculation_of_the_LTP_parameters(S, d, dp, bc, Nc);
+               else
+#endif
+                       Calculation_of_the_LTP_parameters(d, dp, bc, Nc);
+
+       Long_term_analysis_filtering( *bc, *Nc, dp, d, dpp, e );
+}
+
+/* 4.3.2 */
+void Gsm_Long_Term_Synthesis_Filtering P5((S,Ncr,bcr,erp,drp),
+       struct gsm_state        * S,
+
+       word                    Ncr,
+       word                    bcr,
+       register word           * erp,     /* [0..39]                    IN */
+       register word           * drp      /* [-120..-1] IN, [-120..40] OUT */
+)
+/*
+ *  This procedure uses the bcr and Ncr parameter to realize the
+ *  long term synthesis filtering.  The decoding of bcr needs
+ *  table 4.3b.
+ */
+{
+       register longword       ltmp;   /* for ADD */
+       register int            k;
+       word                    brp, drpp, Nr;
+
+       /*  Check the limits of Nr.
+        */
+       Nr = Ncr < 40 || Ncr > 120 ? S->nrp : Ncr;
+       S->nrp = Nr;
+       assert(Nr >= 40 && Nr <= 120);
+
+       /*  Decoding of the LTP gain bcr
+        */
+       brp = gsm_QLB[ bcr ];
+
+       /*  Computation of the reconstructed short term residual 
+        *  signal drp[0..39]
+        */
+       assert(brp != MIN_WORD);
+
+       for (k = 0; k <= 39; k++) {
+               drpp   = GSM_MULT_R( brp, drp[ k - Nr ] );
+               drp[k] = GSM_ADD( erp[k], drpp );
+       }
+
+       /*
+        *  Update of the reconstructed short term residual signal
+        *  drp[ -1..-120 ]
+        */
+
+       for (k = 0; k <= 119; k++) drp[ -120 + k ] = drp[ -80 + k ];
+}
diff --git a/gr-gsm-fr-vocoder/src/lib/gsm/lpc.c b/gr-gsm-fr-vocoder/src/lib/gsm/lpc.c
new file mode 100644 (file)
index 0000000..ac2b8a9
--- /dev/null
@@ -0,0 +1,341 @@
+/*
+ * 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.
+ */
+
+/* $Header$ */
+
+#include <stdio.h>
+#include <assert.h>
+
+#include "private.h"
+
+#include "gsm.h"
+#include "proto.h"
+
+#undef P
+
+/*
+ *  4.2.4 .. 4.2.7 LPC ANALYSIS SECTION
+ */
+
+/* 4.2.4 */
+
+
+static void Autocorrelation P2((s, L_ACF),
+       word     * s,           /* [0..159]     IN/OUT  */
+       longword * L_ACF)       /* [0..8]       OUT     */
+/*
+ *  The goal is to compute the array L_ACF[k].  The signal s[i] must
+ *  be scaled in order to avoid an overflow situation.
+ */
+{
+       register int    k, i;
+
+       word            temp, smax, scalauto;
+
+#ifdef USE_FLOAT_MUL
+       float           float_s[160];
+#endif
+
+       /*  Dynamic scaling of the array  s[0..159]
+        */
+
+       /*  Search for the maximum.
+        */
+       smax = 0;
+       for (k = 0; k <= 159; k++) {
+               temp = GSM_ABS( s[k] );
+               if (temp > smax) smax = temp;
+       }
+
+       /*  Computation of the scaling factor.
+        */
+       if (smax == 0) scalauto = 0;
+       else {
+               assert(smax > 0);
+               scalauto = 4 - gsm_norm( (longword)smax << 16 );/* sub(4,..) */
+       }
+
+       /*  Scaling of the array s[0...159]
+        */
+
+       if (scalauto > 0) {
+
+# ifdef USE_FLOAT_MUL
+#   define SCALE(n)    \
+       case n: for (k = 0; k <= 159; k++) \
+                       float_s[k] = (float)    \
+                               (s[k] = GSM_MULT_R(s[k], 16384 >> (n-1)));\
+               break;
+# else 
+#   define SCALE(n)    \
+       case n: for (k = 0; k <= 159; k++) \
+                       s[k] = GSM_MULT_R( s[k], 16384 >> (n-1) );\
+               break;
+# endif /* USE_FLOAT_MUL */
+
+               switch (scalauto) {
+               SCALE(1)
+               SCALE(2)
+               SCALE(3)
+               SCALE(4)
+               }
+# undef        SCALE
+       }
+# ifdef        USE_FLOAT_MUL
+       else for (k = 0; k <= 159; k++) float_s[k] = (float) s[k];
+# endif
+
+       /*  Compute the L_ACF[..].
+        */
+       {
+# ifdef        USE_FLOAT_MUL
+               register float * sp = float_s;
+               register float   sl = *sp;
+
+#              define STEP(k)   L_ACF[k] += (longword)(sl * sp[ -(k) ]);
+# else
+               word  * sp = s;
+               word    sl = *sp;
+
+#              define STEP(k)   L_ACF[k] += ((longword)sl * sp[ -(k) ]);
+# endif
+
+#      define NEXTI     sl = *++sp
+
+
+       for (k = 9; k--; L_ACF[k] = 0) ;
+
+       STEP (0);
+       NEXTI;
+       STEP(0); STEP(1);
+       NEXTI;
+       STEP(0); STEP(1); STEP(2);
+       NEXTI;
+       STEP(0); STEP(1); STEP(2); STEP(3);
+       NEXTI;
+       STEP(0); STEP(1); STEP(2); STEP(3); STEP(4);
+       NEXTI;
+       STEP(0); STEP(1); STEP(2); STEP(3); STEP(4); STEP(5);
+       NEXTI;
+       STEP(0); STEP(1); STEP(2); STEP(3); STEP(4); STEP(5); STEP(6);
+       NEXTI;
+       STEP(0); STEP(1); STEP(2); STEP(3); STEP(4); STEP(5); STEP(6); STEP(7);
+
+       for (i = 8; i <= 159; i++) {
+
+               NEXTI;
+
+               STEP(0);
+               STEP(1); STEP(2); STEP(3); STEP(4);
+               STEP(5); STEP(6); STEP(7); STEP(8);
+       }
+
+       for (k = 9; k--; L_ACF[k] <<= 1) ; 
+
+       }
+       /*   Rescaling of the array s[0..159]
+        */
+       if (scalauto > 0) {
+               assert(scalauto <= 4); 
+               for (k = 160; k--; *s++ <<= scalauto) ;
+       }
+}
+
+#if defined(USE_FLOAT_MUL) && defined(FAST)
+
+static void Fast_Autocorrelation P2((s, L_ACF),
+       word * s,               /* [0..159]     IN/OUT  */
+       longword * L_ACF)       /* [0..8]       OUT     */
+{
+       register int    k, i;
+       float f_L_ACF[9];
+       float scale;
+
+       float          s_f[160];
+       register float *sf = s_f;
+
+       for (i = 0; i < 160; ++i) sf[i] = s[i];
+       for (k = 0; k <= 8; k++) {
+               register float L_temp2 = 0;
+               register float *sfl = sf - k;
+               for (i = k; i < 160; ++i) L_temp2 += sf[i] * sfl[i];
+               f_L_ACF[k] = L_temp2;
+       }
+       scale = MAX_LONGWORD / f_L_ACF[0];
+
+       for (k = 0; k <= 8; k++) {
+               L_ACF[k] = f_L_ACF[k] * scale;
+       }
+}
+#endif /* defined (USE_FLOAT_MUL) && defined (FAST) */
+
+/* 4.2.5 */
+
+static void Reflection_coefficients P2( (L_ACF, r),
+       longword        * L_ACF,                /* 0...8        IN      */
+       register word   * r                     /* 0...7        OUT     */
+)
+{
+       register int    i, m, n;
+       register word   temp;
+       register longword ltmp;
+       word            ACF[9]; /* 0..8 */
+       word            P[  9]; /* 0..8 */
+       word            K[  9]; /* 2..8 */
+
+       /*  Schur recursion with 16 bits arithmetic.
+        */
+
+       if (L_ACF[0] == 0) {
+               for (i = 8; i--; *r++ = 0) ;
+               return;
+       }
+
+       assert( L_ACF[0] != 0 );
+       temp = gsm_norm( L_ACF[0] );
+
+       assert(temp >= 0 && temp < 32);
+
+       /* ? overflow ? */
+       for (i = 0; i <= 8; i++) ACF[i] = SASR( L_ACF[i] << temp, 16 );
+
+       /*   Initialize array P[..] and K[..] for the recursion.
+        */
+
+       for (i = 1; i <= 7; i++) K[ i ] = ACF[ i ];
+       for (i = 0; i <= 8; i++) P[ i ] = ACF[ i ];
+
+       /*   Compute reflection coefficients
+        */
+       for (n = 1; n <= 8; n++, r++) {
+
+               temp = P[1];
+               temp = GSM_ABS(temp);
+               if (P[0] < temp) {
+                       for (i = n; i <= 8; i++) *r++ = 0;
+                       return;
+               }
+
+               *r = gsm_div( temp, P[0] );
+
+               assert(*r >= 0);
+               if (P[1] > 0) *r = -*r;         /* r[n] = sub(0, r[n]) */
+               assert (*r != MIN_WORD);
+               if (n == 8) return; 
+
+               /*  Schur recursion
+                */
+               temp = GSM_MULT_R( P[1], *r );
+               P[0] = GSM_ADD( P[0], temp );
+
+               for (m = 1; m <= 8 - n; m++) {
+                       temp     = GSM_MULT_R( K[ m   ],    *r );
+                       P[m]     = GSM_ADD(    P[ m+1 ],  temp );
+
+                       temp     = GSM_MULT_R( P[ m+1 ],    *r );
+                       K[m]     = GSM_ADD(    K[ m   ],  temp );
+               }
+       }
+}
+
+/* 4.2.6 */
+
+static void Transformation_to_Log_Area_Ratios P1((r),
+       register word   * r                     /* 0..7    IN/OUT */
+)
+/*
+ *  The following scaling for r[..] and LAR[..] has been used:
+ *
+ *  r[..]   = integer( real_r[..]*32768. ); -1 <= real_r < 1.
+ *  LAR[..] = integer( real_LAR[..] * 16384 );
+ *  with -1.625 <= real_LAR <= 1.625
+ */
+{
+       register word   temp;
+       register int    i;
+
+
+       /* Computation of the LAR[0..7] from the r[0..7]
+        */
+       for (i = 1; i <= 8; i++, r++) {
+
+               temp = *r;
+               temp = GSM_ABS(temp);
+               assert(temp >= 0);
+
+               if (temp < 22118) {
+                       temp >>= 1;
+               } else if (temp < 31130) {
+                       assert( temp >= 11059 );
+                       temp -= 11059;
+               } else {
+                       assert( temp >= 26112 );
+                       temp -= 26112;
+                       temp <<= 2;
+               }
+
+               *r = *r < 0 ? -temp : temp;
+               assert( *r != MIN_WORD );
+       }
+}
+
+/* 4.2.7 */
+
+static void Quantization_and_coding P1((LAR),
+       register word * LAR     /* [0..7]       IN/OUT  */
+)
+{
+       register word   temp;
+       longword        ltmp;
+
+
+       /*  This procedure needs four tables; the following equations
+        *  give the optimum scaling for the constants:
+        *  
+        *  A[0..7] = integer( real_A[0..7] * 1024 )
+        *  B[0..7] = integer( real_B[0..7] *  512 )
+        *  MAC[0..7] = maximum of the LARc[0..7]
+        *  MIC[0..7] = minimum of the LARc[0..7]
+        */
+
+#      undef STEP
+#      define  STEP( A, B, MAC, MIC )          \
+               temp = GSM_MULT( A,   *LAR );   \
+               temp = GSM_ADD(  temp,   B );   \
+               temp = GSM_ADD(  temp, 256 );   \
+               temp = SASR(     temp,   9 );   \
+               *LAR  =  temp>MAC ? MAC - MIC : (temp<MIC ? 0 : temp - MIC); \
+               LAR++;
+
+       STEP(  20480,     0,  31, -32 );
+       STEP(  20480,     0,  31, -32 );
+       STEP(  20480,  2048,  15, -16 );
+       STEP(  20480, -2560,  15, -16 );
+
+       STEP(  13964,    94,   7,  -8 );
+       STEP(  15360, -1792,   7,  -8 );
+       STEP(   8534,  -341,   3,  -4 );
+       STEP(   9036, -1144,   3,  -4 );
+
+#      undef   STEP
+}
+
+void Gsm_LPC_Analysis P3((S, s,LARc),
+       struct gsm_state *S,
+       word             * s,           /* 0..159 signals       IN/OUT  */
+        word            * LARc)        /* 0..7   LARc's        OUT     */
+{
+       longword        L_ACF[9];
+
+#if defined(USE_FLOAT_MUL) && defined(FAST)
+       if (S->fast) Fast_Autocorrelation (s,     L_ACF );
+       else
+#endif
+       Autocorrelation                   (s,     L_ACF );
+       Reflection_coefficients           (L_ACF, LARc  );
+       Transformation_to_Log_Area_Ratios (LARc);
+       Quantization_and_coding           (LARc);
+}
diff --git a/gr-gsm-fr-vocoder/src/lib/gsm/preprocess.c b/gr-gsm-fr-vocoder/src/lib/gsm/preprocess.c
new file mode 100644 (file)
index 0000000..99c0709
--- /dev/null
@@ -0,0 +1,113 @@
+/*
+ * 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.
+ */
+
+/* $Header$ */
+
+#include       <stdio.h>
+#include       <assert.h>
+
+#include "private.h"
+
+#include       "gsm.h"
+#include       "proto.h"
+
+/*     4.2.0 .. 4.2.3  PREPROCESSING SECTION
+ *  
+ *     After A-law to linear conversion (or directly from the
+ *     Ato D converter) the following scaling is assumed for
+ *     input to the RPE-LTP algorithm:
+ *
+ *      in:  0.1.....................12
+ *          S.v.v.v.v.v.v.v.v.v.v.v.v.*.*.*
+ *
+ *     Where S is the sign bit, v a valid bit, and * a "don't care" bit.
+ *     The original signal is called sop[..]
+ *
+ *      out:   0.1................... 12 
+ *          S.S.v.v.v.v.v.v.v.v.v.v.v.v.0.0
+ */
+
+
+void Gsm_Preprocess P3((S, s, so),
+       struct gsm_state * S,
+       word             * s,
+       word             * so )         /* [0..159]     IN/OUT  */
+{
+
+       word       z1 = S->z1;
+       longword L_z2 = S->L_z2;
+       word       mp = S->mp;
+
+       word            s1;
+       longword      L_s2;
+
+       longword      L_temp;
+
+       word            msp, lsp;
+       word            SO;
+
+       longword        ltmp;           /* for   ADD */
+       ulongword       utmp;           /* for L_ADD */
+
+       register int            k = 160;
+
+       while (k--) {
+
+       /*  4.2.1   Downscaling of the input signal
+        */
+               SO = SASR( *s, 3 ) << 2;
+               s++;
+
+               assert (SO >= -0x4000); /* downscaled by     */
+               assert (SO <=  0x3FFC); /* previous routine. */
+
+
+       /*  4.2.2   Offset compensation
+        * 
+        *  This part implements a high-pass filter and requires extended
+        *  arithmetic precision for the recursive part of this filter.
+        *  The input of this procedure is the array so[0...159] and the
+        *  output the array sof[ 0...159 ].
+        */
+               /*   Compute the non-recursive part
+                */
+
+               s1 = SO - z1;                   /* s1 = gsm_sub( *so, z1 ); */
+               z1 = SO;
+
+               assert(s1 != MIN_WORD);
+
+               /*   Compute the recursive part
+                */
+               L_s2 = s1;
+               L_s2 <<= 15;
+
+               /*   Execution of a 31 bv 16 bits multiplication
+                */
+
+               msp = SASR( L_z2, 15 );
+               lsp = L_z2-((longword)msp<<15); /* gsm_L_sub(L_z2,(msp<<15)); */
+
+               L_s2  += GSM_MULT_R( lsp, 32735 );
+               L_temp = (longword)msp * 32735; /* GSM_L_MULT(msp,32735) >> 1;*/
+               L_z2   = GSM_L_ADD( L_temp, L_s2 );
+
+               /*    Compute sof[k] with rounding
+                */
+               L_temp = GSM_L_ADD( L_z2, 16384 );
+
+       /*   4.2.3  Preemphasis
+        */
+
+               msp   = GSM_MULT_R( mp, -28180 );
+               mp    = SASR( L_temp, 15 );
+               *so++ = GSM_ADD( mp, msp );
+       }
+
+       S->z1   = z1;
+       S->L_z2 = L_z2;
+       S->mp   = mp;
+}
diff --git a/gr-gsm-fr-vocoder/src/lib/gsm/private.h b/gr-gsm-fr-vocoder/src/lib/gsm/private.h
new file mode 100644 (file)
index 0000000..6b538cc
--- /dev/null
@@ -0,0 +1,268 @@
+/*
+ * 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.
+ */
+
+/*$Header$*/
+
+#ifndef        PRIVATE_H
+#define        PRIVATE_H
+
+typedef short                  word;           /* 16 bit signed int    */
+typedef long                   longword;       /* 32 bit signed int    */
+
+typedef unsigned short         uword;          /* unsigned word        */
+typedef unsigned long          ulongword;      /* unsigned longword    */
+
+struct gsm_state {
+
+       word            dp0[ 280 ];
+
+       word            z1;             /* preprocessing.c, Offset_com. */
+       longword        L_z2;           /*                  Offset_com. */
+       int             mp;             /*                  Preemphasis */
+
+       word            u[8];           /* short_term_aly_filter.c      */
+       word            LARpp[2][8];    /*                              */
+       word            j;              /*                              */
+
+       word            ltp_cut;        /* long_term.c, LTP crosscorr.  */
+       word            nrp; /* 40 */   /* long_term.c, synthesis       */
+       word            v[9];           /* short_term.c, synthesis      */
+       word            msr;            /* decoder.c,   Postprocessing  */
+
+       char            verbose;        /* only used if !NDEBUG         */
+       char            fast;           /* only used if FAST            */
+
+       char            wav_fmt;        /* only used if WAV49 defined   */
+       unsigned char   frame_index;    /*            odd/even chaining */
+       unsigned char   frame_chain;    /*   half-byte to carry forward */
+};
+
+
+#define        MIN_WORD        (-32767 - 1)
+#define        MAX_WORD          32767
+
+#define        MIN_LONGWORD    (-2147483647 - 1)
+#define        MAX_LONGWORD      2147483647
+
+#ifdef SASR            /* flag: >> is a signed arithmetic shift right */
+#undef SASR
+#define        SASR(x, by)     ((x) >> (by))
+#else
+#define        SASR(x, by)     ((x) >= 0 ? (x) >> (by) : (~(-((x) + 1) >> (by))))
+#endif /* SASR */
+
+#include "proto.h"
+
+/*
+ *     Prototypes from add.c
+ */
+extern word    gsm_mult        P((word a, word b));
+extern longword gsm_L_mult     P((word a, word b));
+extern word    gsm_mult_r      P((word a, word b));
+
+extern word    gsm_div         P((word num, word denum));
+
+extern word    gsm_add         P(( word a, word b ));
+extern longword gsm_L_add      P(( longword a, longword b ));
+
+extern word    gsm_sub         P((word a, word b));
+extern longword gsm_L_sub      P((longword a, longword b));
+
+extern word    gsm_abs         P((word a));
+
+extern word    gsm_norm        P(( longword a ));
+
+extern longword gsm_L_asl      P((longword a, int n));
+extern word    gsm_asl         P((word a, int n));
+
+extern longword gsm_L_asr      P((longword a, int n));
+extern word    gsm_asr         P((word a, int n));
+
+/*
+ *  Inlined functions from add.h 
+ */
+
+/* 
+ * #define GSM_MULT_R(a, b) (* word a, word b, !(a == b == MIN_WORD) *)        \
+ *     (0x0FFFF & SASR(((longword)(a) * (longword)(b) + 16384), 15))
+ */
+#define GSM_MULT_R(a, b) /* word a, word b, !(a == b == MIN_WORD) */   \
+       (SASR( ((longword)(a) * (longword)(b) + 16384), 15 ))
+
+# define GSM_MULT(a,b)  /* word a, word b, !(a == b == MIN_WORD) */    \
+       (SASR( ((longword)(a) * (longword)(b)), 15 ))
+
+# define GSM_L_MULT(a, b) /* word a, word b */ \
+       (((longword)(a) * (longword)(b)) << 1)
+
+# define GSM_L_ADD(a, b)       \
+       ( (a) <  0 ? ( (b) >= 0 ? (a) + (b)     \
+                : (utmp = (ulongword)-((a) + 1) + (ulongword)-((b) + 1)) \
+                  >= MAX_LONGWORD ? MIN_LONGWORD : -(longword)utmp-2 )   \
+       : ((b) <= 0 ? (a) + (b)   \
+                 : (utmp = (ulongword)(a) + (ulongword)(b)) >= MAX_LONGWORD \
+                   ? MAX_LONGWORD : utmp))
+
+/*
+ * # define GSM_ADD(a, b)      \
+ *     ((ltmp = (longword)(a) + (longword)(b)) >= MAX_WORD \
+ *     ? MAX_WORD : ltmp <= MIN_WORD ? MIN_WORD : ltmp)
+ */
+/* Nonportable, but faster: */
+
+#define        GSM_ADD(a, b)   \
+       ((ulongword)((ltmp = (longword)(a) + (longword)(b)) - MIN_WORD) > \
+               MAX_WORD - MIN_WORD ? (ltmp > 0 ? MAX_WORD : MIN_WORD) : ltmp)
+
+# define GSM_SUB(a, b) \
+       ((ltmp = (longword)(a) - (longword)(b)) >= MAX_WORD \
+       ? MAX_WORD : ltmp <= MIN_WORD ? MIN_WORD : ltmp)
+
+# define GSM_ABS(a)    ((a) < 0 ? ((a) == MIN_WORD ? MAX_WORD : -(a)) : (a))
+
+/* Use these if necessary:
+
+# define GSM_MULT_R(a, b)      gsm_mult_r(a, b)
+# define GSM_MULT(a, b)                gsm_mult(a, b)
+# define GSM_L_MULT(a, b)      gsm_L_mult(a, b)
+
+# define GSM_L_ADD(a, b)       gsm_L_add(a, b)
+# define GSM_ADD(a, b)         gsm_add(a, b)
+# define GSM_SUB(a, b)         gsm_sub(a, b)
+
+# define GSM_ABS(a)            gsm_abs(a)
+
+*/
+
+/*
+ *  More prototypes from implementations..
+ */
+extern void Gsm_Coder P((
+               struct gsm_state        * S,
+               word    * s,    /* [0..159] samples             IN      */
+               word    * LARc, /* [0..7] LAR coefficients      OUT     */
+               word    * Nc,   /* [0..3] LTP lag               OUT     */
+               word    * bc,   /* [0..3] coded LTP gain        OUT     */
+               word    * Mc,   /* [0..3] RPE grid selection    OUT     */
+               word    * xmaxc,/* [0..3] Coded maximum amplitude OUT   */
+               word    * xMc   /* [13*4] normalized RPE samples OUT    */));
+
+extern void Gsm_Long_Term_Predictor P((                /* 4x for 160 samples */
+               struct gsm_state * S,
+               word    * d,    /* [0..39]   residual signal    IN      */
+               word    * dp,   /* [-120..-1] d'                IN      */
+               word    * e,    /* [0..40]                      OUT     */
+               word    * dpp,  /* [0..40]                      OUT     */
+               word    * Nc,   /* correlation lag              OUT     */
+               word    * bc    /* gain factor                  OUT     */));
+
+extern void Gsm_LPC_Analysis P((
+               struct gsm_state * S,
+               word * s,        /* 0..159 signals      IN/OUT  */
+               word * LARc));   /* 0..7   LARc's       OUT     */
+
+extern void Gsm_Preprocess P((
+               struct gsm_state * S,
+               word * s, word * so));
+
+extern void Gsm_Encoding P((
+               struct gsm_state * S,
+               word    * e,    
+               word    * ep,   
+               word    * xmaxc,
+               word    * Mc,   
+               word    * xMc));
+
+extern void Gsm_Short_Term_Analysis_Filter P((
+               struct gsm_state * S,
+               word    * LARc, /* coded log area ratio [0..7]  IN      */
+               word    * d     /* st res. signal [0..159]      IN/OUT  */));
+
+extern void Gsm_Decoder P((
+               struct gsm_state * S,
+               word    * LARcr,        /* [0..7]               IN      */
+               word    * Ncr,          /* [0..3]               IN      */
+               word    * bcr,          /* [0..3]               IN      */
+               word    * Mcr,          /* [0..3]               IN      */
+               word    * xmaxcr,       /* [0..3]               IN      */
+               word    * xMcr,         /* [0..13*4]            IN      */
+               word    * s));          /* [0..159]             OUT     */
+
+extern void Gsm_Decoding P((
+               struct gsm_state * S,
+               word    xmaxcr,
+               word    Mcr,
+               word    * xMcr,         /* [0..12]              IN      */
+               word    * erp));        /* [0..39]              OUT     */
+
+extern void Gsm_Long_Term_Synthesis_Filtering P((
+               struct gsm_state* S,
+               word    Ncr,
+               word    bcr,
+               word    * erp,          /* [0..39]                IN    */
+               word    * drp));        /* [-120..-1] IN, [0..40] OUT   */
+
+void Gsm_RPE_Decoding P((
+       struct gsm_state *S,
+               word xmaxcr,
+               word Mcr,
+               word * xMcr,  /* [0..12], 3 bits             IN      */
+               word * erp)); /* [0..39]                     OUT     */
+
+void Gsm_RPE_Encoding P((
+               struct gsm_state * S,
+               word    * e,            /* -5..-1][0..39][40..44     IN/OUT  */
+               word    * xmaxc,        /*                              OUT */
+               word    * Mc,           /*                              OUT */
+               word    * xMc));        /* [0..12]                      OUT */
+
+extern void Gsm_Short_Term_Synthesis_Filter P((
+               struct gsm_state * S,
+               word    * LARcr,        /* log area ratios [0..7]  IN   */
+               word    * drp,          /* received d [0...39]     IN   */
+               word    * s));          /* signal   s [0..159]    OUT   */
+
+extern void Gsm_Update_of_reconstructed_short_time_residual_signal P((
+               word    * dpp,          /* [0...39]     IN      */
+               word    * ep,           /* [0...39]     IN      */
+               word    * dp));         /* [-120...-1]  IN/OUT  */
+
+/*
+ *  Tables from table.c
+ */
+#ifndef        GSM_TABLE_C
+
+extern word gsm_A[8], gsm_B[8], gsm_MIC[8], gsm_MAC[8];
+extern word gsm_INVA[8];
+extern word gsm_DLB[4], gsm_QLB[4];
+extern word gsm_H[11];
+extern word gsm_NRFAC[8];
+extern word gsm_FAC[8];
+
+#endif /* GSM_TABLE_C */
+
+/*
+ *  Debugging
+ */
+#ifdef NDEBUG
+
+#      define  gsm_debug_words(a, b, c, d)             /* nil */
+#      define  gsm_debug_longwords(a, b, c, d)         /* nil */
+#      define  gsm_debug_word(a, b)                    /* nil */
+#      define  gsm_debug_longword(a, b)                /* nil */
+
+#else  /* !NDEBUG => DEBUG */
+
+       extern void  gsm_debug_words     P((char * name, int, int, word *));
+       extern void  gsm_debug_longwords P((char * name, int, int, longword *));
+       extern void  gsm_debug_longword  P((char * name, longword));
+       extern void  gsm_debug_word      P((char * name, word));
+
+#endif /* !NDEBUG */
+
+#include "unproto.h"
+
+#endif /* PRIVATE_H */
diff --git a/gr-gsm-fr-vocoder/src/lib/gsm/proto.h b/gr-gsm-fr-vocoder/src/lib/gsm/proto.h
new file mode 100644 (file)
index 0000000..87cf05e
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * 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.
+ */
+
+/*$Header$*/
+
+#ifndef        PROTO_H
+#define        PROTO_H
+
+#if __cplusplus
+#      define  NeedFunctionPrototypes  1
+#endif
+
+#if __STDC__
+#      define  NeedFunctionPrototypes  1
+#endif
+
+#ifdef _NO_PROTO
+#      undef   NeedFunctionPrototypes
+#endif
+
+#undef P       /* gnu stdio.h actually defines this...         */
+#undef P0
+#undef P1
+#undef P2
+#undef P3
+#undef P4
+#undef P5
+#undef P6
+#undef P7
+#undef P8
+
+#if NeedFunctionPrototypes
+
+#      define  P( protos )     protos
+
+#      define  P0()                            (void)
+#      define  P1(x, a)                        (a)
+#      define  P2(x, a, b)                     (a, b)
+#      define  P3(x, a, b, c)                  (a, b, c)
+#      define  P4(x, a, b, c, d)               (a, b, c, d)    
+#      define  P5(x, a, b, c, d, e)            (a, b, c, d, e)
+#      define  P6(x, a, b, c, d, e, f)         (a, b, c, d, e, f)
+#      define  P7(x, a, b, c, d, e, f, g)      (a, b, c, d, e, f, g)
+#      define  P8(x, a, b, c, d, e, f, g, h)   (a, b, c, d, e, f, g, h)
+
+#else /* !NeedFunctionPrototypes */
+
+#      define  P( protos )     ( /* protos */ )
+
+#      define  P0()                            ()
+#      define  P1(x, a)                        x a;
+#      define  P2(x, a, b)                     x a; b;
+#      define  P3(x, a, b, c)                  x a; b; c;
+#      define  P4(x, a, b, c, d)               x a; b; c; d;
+#      define  P5(x, a, b, c, d, e)            x a; b; c; d; e;
+#      define  P6(x, a, b, c, d, e, f)         x a; b; c; d; e; f;
+#      define  P7(x, a, b, c, d, e, f, g)      x a; b; c; d; e; f; g;
+#      define  P8(x, a, b, c, d, e, f, g, h)   x a; b; c; d; e; f; g; h;
+
+#endif  /* !NeedFunctionPrototypes */
+
+#endif /* PROTO_H */
diff --git a/gr-gsm-fr-vocoder/src/lib/gsm/rpe.c b/gr-gsm-fr-vocoder/src/lib/gsm/rpe.c
new file mode 100644 (file)
index 0000000..8a6b81f
--- /dev/null
@@ -0,0 +1,488 @@
+/*
+ * 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.
+ */
+
+/* $Header$ */
+
+#include <stdio.h>
+#include <assert.h>
+
+#include "private.h"
+
+#include "gsm.h"
+#include "proto.h"
+
+/*  4.2.13 .. 4.2.17  RPE ENCODING SECTION
+ */
+
+/* 4.2.13 */
+
+static void Weighting_filter P2((e, x),
+       register word   * e,            /* signal [-5..0.39.44] IN  */
+       word            * x             /* signal [0..39]       OUT */
+)
+/*
+ *  The coefficients of the weighting filter are stored in a table
+ *  (see table 4.4).  The following scaling is used:
+ *
+ *     H[0..10] = integer( real_H[ 0..10] * 8192 ); 
+ */
+{
+       /* word                 wt[ 50 ]; */
+
+       register longword       L_result;
+       register int            k /* , i */ ;
+
+       /*  Initialization of a temporary working array wt[0...49]
+        */
+
+       /* for (k =  0; k <=  4; k++) wt[k] = 0;
+        * for (k =  5; k <= 44; k++) wt[k] = *e++;
+        * for (k = 45; k <= 49; k++) wt[k] = 0;
+        *
+        *  (e[-5..-1] and e[40..44] are allocated by the caller,
+        *  are initially zero and are not written anywhere.)
+        */
+       e -= 5;
+
+       /*  Compute the signal x[0..39]
+        */ 
+       for (k = 0; k <= 39; k++) {
+
+               L_result = 8192 >> 1;
+
+               /* for (i = 0; i <= 10; i++) {
+                *      L_temp   = GSM_L_MULT( wt[k+i], gsm_H[i] );
+                *      L_result = GSM_L_ADD( L_result, L_temp );
+                * }
+                */
+
+#undef STEP
+#define        STEP( i, H )    (e[ k + i ] * (longword)H)
+
+               /*  Every one of these multiplications is done twice --
+                *  but I don't see an elegant way to optimize this. 
+                *  Do you?
+                */
+
+#ifdef STUPID_COMPILER
+               L_result += STEP(       0,      -134 ) ;
+               L_result += STEP(       1,      -374 )  ;
+                      /* + STEP(       2,      0    )  */
+               L_result += STEP(       3,      2054 ) ;
+               L_result += STEP(       4,      5741 ) ;
+               L_result += STEP(       5,      8192 ) ;
+               L_result += STEP(       6,      5741 ) ;
+               L_result += STEP(       7,      2054 ) ;
+                      /* + STEP(       8,      0    )  */
+               L_result += STEP(       9,      -374 ) ;
+               L_result += STEP(       10,     -134 ) ;
+#else
+               L_result +=
+                 STEP( 0,      -134 ) 
+               + STEP( 1,      -374 ) 
+            /* + STEP( 2,      0    )  */
+               + STEP( 3,      2054 ) 
+               + STEP( 4,      5741 ) 
+               + STEP( 5,      8192 ) 
+               + STEP( 6,      5741 ) 
+               + STEP( 7,      2054 ) 
+            /* + STEP( 8,      0    )  */
+               + STEP( 9,      -374 ) 
+               + STEP(10,      -134 )
+               ;
+#endif
+
+               /* L_result = GSM_L_ADD( L_result, L_result ); (* scaling(x2) *)
+                * L_result = GSM_L_ADD( L_result, L_result ); (* scaling(x4) *)
+                *
+                * x[k] = SASR( L_result, 16 );
+                */
+
+               /* 2 adds vs. >>16 => 14, minus one shift to compensate for
+                * those we lost when replacing L_MULT by '*'.
+                */
+
+               L_result = SASR( L_result, 13 );
+               x[k] =  (  L_result < MIN_WORD ? MIN_WORD
+                       : (L_result > MAX_WORD ? MAX_WORD : L_result ));
+       }
+}
+
+/* 4.2.14 */
+
+static void RPE_grid_selection P3((x,xM,Mc_out),
+       word            * x,            /* [0..39]              IN  */ 
+       word            * xM,           /* [0..12]              OUT */
+       word            * Mc_out        /*                      OUT */
+)
+/*
+ *  The signal x[0..39] is used to select the RPE grid which is
+ *  represented by Mc.
+ */
+{
+       /* register word        temp1;  */
+       register int            /* m, */  i;
+       register longword       L_result, L_temp;
+       longword                EM;     /* xxx should be L_EM? */
+       word                    Mc;
+
+       longword                L_common_0_3;
+
+       EM = 0;
+       Mc = 0;
+
+       /* for (m = 0; m <= 3; m++) {
+        *      L_result = 0;
+        *
+        *
+        *      for (i = 0; i <= 12; i++) {
+        *
+        *              temp1    = SASR( x[m + 3*i], 2 );
+        *
+        *              assert(temp1 != MIN_WORD);
+        *
+        *              L_temp   = GSM_L_MULT( temp1, temp1 );
+        *              L_result = GSM_L_ADD( L_temp, L_result );
+        *      }
+        * 
+        *      if (L_result > EM) {
+        *              Mc = m;
+        *              EM = L_result;
+        *      }
+        * }
+        */
+
+#undef STEP
+#define        STEP( m, i )            L_temp = SASR( x[m + 3 * i], 2 );       \
+                               L_result += L_temp * L_temp;
+
+       /* common part of 0 and 3 */
+
+       L_result = 0;
+       STEP( 0, 1 ); STEP( 0, 2 ); STEP( 0, 3 ); STEP( 0, 4 );
+       STEP( 0, 5 ); STEP( 0, 6 ); STEP( 0, 7 ); STEP( 0, 8 );
+       STEP( 0, 9 ); STEP( 0, 10); STEP( 0, 11); STEP( 0, 12);
+       L_common_0_3 = L_result;
+
+       /* i = 0 */
+
+       STEP( 0, 0 );
+       L_result <<= 1; /* implicit in L_MULT */
+       EM = L_result;
+
+       /* i = 1 */
+
+       L_result = 0;
+       STEP( 1, 0 );
+       STEP( 1, 1 ); STEP( 1, 2 ); STEP( 1, 3 ); STEP( 1, 4 );
+       STEP( 1, 5 ); STEP( 1, 6 ); STEP( 1, 7 ); STEP( 1, 8 );
+       STEP( 1, 9 ); STEP( 1, 10); STEP( 1, 11); STEP( 1, 12);
+       L_result <<= 1;
+       if (L_result > EM) {
+               Mc = 1;
+               EM = L_result;
+       }
+
+       /* i = 2 */
+
+       L_result = 0;
+       STEP( 2, 0 );
+       STEP( 2, 1 ); STEP( 2, 2 ); STEP( 2, 3 ); STEP( 2, 4 );
+       STEP( 2, 5 ); STEP( 2, 6 ); STEP( 2, 7 ); STEP( 2, 8 );
+       STEP( 2, 9 ); STEP( 2, 10); STEP( 2, 11); STEP( 2, 12);
+       L_result <<= 1;
+       if (L_result > EM) {
+               Mc = 2;
+               EM = L_result;
+       }
+
+       /* i = 3 */
+
+       L_result = L_common_0_3;
+       STEP( 3, 12 );
+       L_result <<= 1;
+       if (L_result > EM) {
+               Mc = 3;
+               EM = L_result;
+       }
+
+       /**/
+
+       /*  Down-sampling by a factor 3 to get the selected xM[0..12]
+        *  RPE sequence.
+        */
+       for (i = 0; i <= 12; i ++) xM[i] = x[Mc + 3*i];
+       *Mc_out = Mc;
+}
+
+/* 4.12.15 */
+
+static void APCM_quantization_xmaxc_to_exp_mant P3((xmaxc,exp_out,mant_out),
+       word            xmaxc,          /* IN   */
+       word            * exp_out,      /* OUT  */
+       word            * mant_out )    /* OUT  */
+{
+       word    exp, mant;
+
+       /* Compute exponent and mantissa of the decoded version of xmaxc
+        */
+
+       exp = 0;
+       if (xmaxc > 15) exp = SASR(xmaxc, 3) - 1;
+       mant = xmaxc - (exp << 3);
+
+       if (mant == 0) {
+               exp  = -4;
+               mant = 7;
+       }
+       else {
+               while (mant <= 7) {
+                       mant = mant << 1 | 1;
+                       exp--;
+               }
+               mant -= 8;
+       }
+
+       assert( exp  >= -4 && exp <= 6 );
+       assert( mant >= 0 && mant <= 7 );
+
+       *exp_out  = exp;
+       *mant_out = mant;
+}
+
+static void APCM_quantization P5((xM,xMc,mant_out,exp_out,xmaxc_out),
+       word            * xM,           /* [0..12]              IN      */
+
+       word            * xMc,          /* [0..12]              OUT     */
+       word            * mant_out,     /*                      OUT     */
+       word            * exp_out,      /*                      OUT     */
+       word            * xmaxc_out     /*                      OUT     */
+)
+{
+       int     i, itest;
+
+       word    xmax, xmaxc, temp, temp1, temp2;
+       word    exp, mant;
+
+
+       /*  Find the maximum absolute value xmax of xM[0..12].
+        */
+
+       xmax = 0;
+       for (i = 0; i <= 12; i++) {
+               temp = xM[i];
+               temp = GSM_ABS(temp);
+               if (temp > xmax) xmax = temp;
+       }
+
+       /*  Qantizing and coding of xmax to get xmaxc.
+        */
+
+       exp   = 0;
+       temp  = SASR( xmax, 9 );
+       itest = 0;
+
+       for (i = 0; i <= 5; i++) {
+
+               itest |= (temp <= 0);
+               temp = SASR( temp, 1 );
+
+               assert(exp <= 5);
+               if (itest == 0) exp++;          /* exp = add (exp, 1) */
+       }
+
+       assert(exp <= 6 && exp >= 0);
+       temp = exp + 5;
+
+       assert(temp <= 11 && temp >= 0);
+       xmaxc = gsm_add( SASR(xmax, temp), exp << 3 );
+
+       /*   Quantizing and coding of the xM[0..12] RPE sequence
+        *   to get the xMc[0..12]
+        */
+
+       APCM_quantization_xmaxc_to_exp_mant( xmaxc, &exp, &mant );
+
+       /*  This computation uses the fact that the decoded version of xmaxc
+        *  can be calculated by using the exponent and the mantissa part of
+        *  xmaxc (logarithmic table).
+        *  So, this method avoids any division and uses only a scaling
+        *  of the RPE samples by a function of the exponent.  A direct 
+        *  multiplication by the inverse of the mantissa (NRFAC[0..7]
+        *  found in table 4.5) gives the 3 bit coded version xMc[0..12]
+        *  of the RPE samples.
+        */
+
+
+       /* Direct computation of xMc[0..12] using table 4.5
+        */
+
+       assert( exp <= 4096 && exp >= -4096);
+       assert( mant >= 0 && mant <= 7 ); 
+
+       temp1 = 6 - exp;                /* normalization by the exponent */
+       temp2 = gsm_NRFAC[ mant ];      /* inverse mantissa              */
+
+       for (i = 0; i <= 12; i++) {
+
+               assert(temp1 >= 0 && temp1 < 16);
+
+               temp = xM[i] << temp1;
+               temp = GSM_MULT( temp, temp2 );
+               temp = SASR(temp, 12);
+               xMc[i] = temp + 4;              /* see note below */
+       }
+
+       /*  NOTE: This equation is used to make all the xMc[i] positive.
+        */
+
+       *mant_out  = mant;
+       *exp_out   = exp;
+       *xmaxc_out = xmaxc;
+}
+
+/* 4.2.16 */
+
+static void APCM_inverse_quantization P4((xMc,mant,exp,xMp),
+       register word   * xMc,  /* [0..12]                      IN      */
+       word            mant,
+       word            exp,
+       register word   * xMp)  /* [0..12]                      OUT     */
+/* 
+ *  This part is for decoding the RPE sequence of coded xMc[0..12]
+ *  samples to obtain the xMp[0..12] array.  Table 4.6 is used to get
+ *  the mantissa of xmaxc (FAC[0..7]).
+ */
+{
+       int     i;
+       word    temp, temp1, temp2, temp3;
+       longword        ltmp;
+
+       assert( mant >= 0 && mant <= 7 ); 
+
+       temp1 = gsm_FAC[ mant ];        /* see 4.2-15 for mant */
+       temp2 = gsm_sub( 6, exp );      /* see 4.2-15 for exp  */
+       temp3 = gsm_asl( 1, gsm_sub( temp2, 1 ));
+
+       for (i = 13; i--;) {
+
+               assert( *xMc <= 7 && *xMc >= 0 );       /* 3 bit unsigned */
+
+               /* temp = gsm_sub( *xMc++ << 1, 7 ); */
+               temp = (*xMc++ << 1) - 7;               /* restore sign   */
+               assert( temp <= 7 && temp >= -7 );      /* 4 bit signed   */
+
+               temp <<= 12;                            /* 16 bit signed  */
+               temp = GSM_MULT_R( temp1, temp );
+               temp = GSM_ADD( temp, temp3 );
+               *xMp++ = gsm_asr( temp, temp2 );
+       }
+}
+
+/* 4.2.17 */
+
+static void RPE_grid_positioning P3((Mc,xMp,ep),
+       word            Mc,             /* grid position        IN      */
+       register word   * xMp,          /* [0..12]              IN      */
+       register word   * ep            /* [0..39]              OUT     */
+)
+/*
+ *  This procedure computes the reconstructed long term residual signal
+ *  ep[0..39] for the LTP analysis filter.  The inputs are the Mc
+ *  which is the grid position selection and the xMp[0..12] decoded
+ *  RPE samples which are upsampled by a factor of 3 by inserting zero
+ *  values.
+ */
+{
+       int     i = 13;
+
+       assert(0 <= Mc && Mc <= 3);
+
+        switch (Mc) {
+                case 3: *ep++ = 0;
+                case 2:  do {
+                                *ep++ = 0;
+                case 1:         *ep++ = 0;
+                case 0:         *ep++ = *xMp++;
+                         } while (--i);
+        }
+        while (++Mc < 4) *ep++ = 0;
+
+       /*
+
+       int i, k;
+       for (k = 0; k <= 39; k++) ep[k] = 0;
+       for (i = 0; i <= 12; i++) {
+               ep[ Mc + (3*i) ] = xMp[i];
+       }
+       */
+}
+
+/* 4.2.18 */
+
+/*  This procedure adds the reconstructed long term residual signal
+ *  ep[0..39] to the estimated signal dpp[0..39] from the long term
+ *  analysis filter to compute the reconstructed short term residual
+ *  signal dp[-40..-1]; also the reconstructed short term residual
+ *  array dp[-120..-41] is updated.
+ */
+
+#if 0  /* Has been inlined in code.c */
+void Gsm_Update_of_reconstructed_short_time_residual_signal P3((dpp, ep, dp),
+       word    * dpp,          /* [0...39]     IN      */
+       word    * ep,           /* [0...39]     IN      */
+       word    * dp)           /* [-120...-1]  IN/OUT  */
+{
+       int             k;
+
+       for (k = 0; k <= 79; k++) 
+               dp[ -120 + k ] = dp[ -80 + k ];
+
+       for (k = 0; k <= 39; k++)
+               dp[ -40 + k ] = gsm_add( ep[k], dpp[k] );
+}
+#endif /* Has been inlined in code.c */
+
+void Gsm_RPE_Encoding P5((S,e,xmaxc,Mc,xMc),
+
+       struct gsm_state * S,
+
+       word    * e,            /* -5..-1][0..39][40..44        IN/OUT  */
+       word    * xmaxc,        /*                              OUT */
+       word    * Mc,           /*                              OUT */
+       word    * xMc)          /* [0..12]                      OUT */
+{
+       word    x[40];
+       word    xM[13], xMp[13];
+       word    mant, exp;
+
+       Weighting_filter(e, x);
+       RPE_grid_selection(x, xM, Mc);
+
+       APCM_quantization(      xM, xMc, &mant, &exp, xmaxc);
+       APCM_inverse_quantization(  xMc,  mant,  exp, xMp);
+
+       RPE_grid_positioning( *Mc, xMp, e );
+
+}
+
+void Gsm_RPE_Decoding P5((S, xmaxcr, Mcr, xMcr, erp),
+       struct gsm_state        * S,
+
+       word            xmaxcr,
+       word            Mcr,
+       word            * xMcr,  /* [0..12], 3 bits             IN      */
+       word            * erp    /* [0..39]                     OUT     */
+)
+{
+       word    exp, mant;
+       word    xMp[ 13 ];
+
+       APCM_quantization_xmaxc_to_exp_mant( xmaxcr, &exp, &mant );
+       APCM_inverse_quantization( xMcr, mant, exp, xMp );
+       RPE_grid_positioning( Mcr, xMp, erp );
+
+}
diff --git a/gr-gsm-fr-vocoder/src/lib/gsm/short_term.c b/gr-gsm-fr-vocoder/src/lib/gsm/short_term.c
new file mode 100644 (file)
index 0000000..4f5fd7b
--- /dev/null
@@ -0,0 +1,429 @@
+/*
+ * 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.
+ */
+
+/* $Header$ */
+
+#include <stdio.h>
+#include <assert.h>
+
+#include "private.h"
+
+#include "gsm.h"
+#include "proto.h"
+
+/*
+ *  SHORT TERM ANALYSIS FILTERING SECTION
+ */
+
+/* 4.2.8 */
+
+static void Decoding_of_the_coded_Log_Area_Ratios P2((LARc,LARpp),
+       word    * LARc,         /* coded log area ratio [0..7]  IN      */
+       word    * LARpp)        /* out: decoded ..                      */
+{
+       register word   temp1 /* , temp2 */;
+       register long   ltmp;   /* for GSM_ADD */
+
+       /*  This procedure requires for efficient implementation
+        *  two tables.
+        *
+        *  INVA[1..8] = integer( (32768 * 8) / real_A[1..8])
+        *  MIC[1..8]  = minimum value of the LARc[1..8]
+        */
+
+       /*  Compute the LARpp[1..8]
+        */
+
+       /*      for (i = 1; i <= 8; i++, B++, MIC++, INVA++, LARc++, LARpp++) {
+        *
+        *              temp1  = GSM_ADD( *LARc, *MIC ) << 10;
+        *              temp2  = *B << 1;
+        *              temp1  = GSM_SUB( temp1, temp2 );
+        *
+        *              assert(*INVA != MIN_WORD);
+        *
+        *              temp1  = GSM_MULT_R( *INVA, temp1 );
+        *              *LARpp = GSM_ADD( temp1, temp1 );
+        *      }
+        */
+
+#undef STEP
+#define        STEP( B, MIC, INVA )    \
+               temp1    = GSM_ADD( *LARc++, MIC ) << 10;       \
+               temp1    = GSM_SUB( temp1, B << 1 );            \
+               temp1    = GSM_MULT_R( INVA, temp1 );           \
+               *LARpp++ = GSM_ADD( temp1, temp1 );
+
+       STEP(      0,  -32,  13107 );
+       STEP(      0,  -32,  13107 );
+       STEP(   2048,  -16,  13107 );
+       STEP(  -2560,  -16,  13107 );
+
+       STEP(     94,   -8,  19223 );
+       STEP(  -1792,   -8,  17476 );
+       STEP(   -341,   -4,  31454 );
+       STEP(  -1144,   -4,  29708 );
+
+       /* NOTE: the addition of *MIC is used to restore
+        *       the sign of *LARc.
+        */
+}
+
+/* 4.2.9 */
+/* Computation of the quantized reflection coefficients 
+ */
+
+/* 4.2.9.1  Interpolation of the LARpp[1..8] to get the LARp[1..8]
+ */
+
+/*
+ *  Within each frame of 160 analyzed speech samples the short term
+ *  analysis and synthesis filters operate with four different sets of
+ *  coefficients, derived from the previous set of decoded LARs(LARpp(j-1))
+ *  and the actual set of decoded LARs (LARpp(j))
+ *
+ * (Initial value: LARpp(j-1)[1..8] = 0.)
+ */
+
+static void Coefficients_0_12 P3((LARpp_j_1, LARpp_j, LARp),
+       register word * LARpp_j_1,
+       register word * LARpp_j,
+       register word * LARp)
+{
+       register int    i;
+       register longword ltmp;
+
+       for (i = 1; i <= 8; i++, LARp++, LARpp_j_1++, LARpp_j++) {
+               *LARp = GSM_ADD( SASR( *LARpp_j_1, 2 ), SASR( *LARpp_j, 2 ));
+               *LARp = GSM_ADD( *LARp,  SASR( *LARpp_j_1, 1));
+       }
+}
+
+static void Coefficients_13_26 P3((LARpp_j_1, LARpp_j, LARp),
+       register word * LARpp_j_1,
+       register word * LARpp_j,
+       register word * LARp)
+{
+       register int i;
+       register longword ltmp;
+       for (i = 1; i <= 8; i++, LARpp_j_1++, LARpp_j++, LARp++) {
+               *LARp = GSM_ADD( SASR( *LARpp_j_1, 1), SASR( *LARpp_j, 1 ));
+       }
+}
+
+static void Coefficients_27_39 P3((LARpp_j_1, LARpp_j, LARp),
+       register word * LARpp_j_1,
+       register word * LARpp_j,
+       register word * LARp)
+{
+       register int i;
+       register longword ltmp;
+
+       for (i = 1; i <= 8; i++, LARpp_j_1++, LARpp_j++, LARp++) {
+               *LARp = GSM_ADD( SASR( *LARpp_j_1, 2 ), SASR( *LARpp_j, 2 ));
+               *LARp = GSM_ADD( *LARp, SASR( *LARpp_j, 1 ));
+       }
+}
+
+
+static void Coefficients_40_159 P2((LARpp_j, LARp),
+       register word * LARpp_j,
+       register word * LARp)
+{
+       register int i;
+
+       for (i = 1; i <= 8; i++, LARp++, LARpp_j++)
+               *LARp = *LARpp_j;
+}
+
+/* 4.2.9.2 */
+
+static void LARp_to_rp P1((LARp),
+       register word * LARp)   /* [0..7] IN/OUT  */
+/*
+ *  The input of this procedure is the interpolated LARp[0..7] array.
+ *  The reflection coefficients, rp[i], are used in the analysis
+ *  filter and in the synthesis filter.
+ */
+{
+       register int            i;
+       register word           temp;
+       register longword       ltmp;
+
+       for (i = 1; i <= 8; i++, LARp++) {
+
+               /* temp = GSM_ABS( *LARp );
+                *
+                * if (temp < 11059) temp <<= 1;
+                * else if (temp < 20070) temp += 11059;
+                * else temp = GSM_ADD( temp >> 2, 26112 );
+                *
+                * *LARp = *LARp < 0 ? -temp : temp;
+                */
+
+               if (*LARp < 0) {
+                       temp = *LARp == MIN_WORD ? MAX_WORD : -(*LARp);
+                       *LARp = - ((temp < 11059) ? temp << 1
+                               : ((temp < 20070) ? temp + 11059
+                               :  GSM_ADD( temp >> 2, 26112 )));
+               } else {
+                       temp  = *LARp;
+                       *LARp =    (temp < 11059) ? temp << 1
+                               : ((temp < 20070) ? temp + 11059
+                               :  GSM_ADD( temp >> 2, 26112 ));
+               }
+       }
+}
+
+
+/* 4.2.10 */
+static void Short_term_analysis_filtering P4((S,rp,k_n,s),
+       struct gsm_state * S,
+       register word   * rp,   /* [0..7]       IN      */
+       register int    k_n,    /*   k_end - k_start    */
+       register word   * s     /* [0..n-1]     IN/OUT  */
+)
+/*
+ *  This procedure computes the short term residual signal d[..] to be fed
+ *  to the RPE-LTP loop from the s[..] signal and from the local rp[..]
+ *  array (quantized reflection coefficients).  As the call of this
+ *  procedure can be done in many ways (see the interpolation of the LAR
+ *  coefficient), it is assumed that the computation begins with index
+ *  k_start (for arrays d[..] and s[..]) and stops with index k_end
+ *  (k_start and k_end are defined in 4.2.9.1).  This procedure also
+ *  needs to keep the array u[0..7] in memory for each call.
+ */
+{
+       register word           * u = S->u;
+       register int            i;
+       register word           di, zzz, ui, sav, rpi;
+       register longword       ltmp;
+
+       for (; k_n--; s++) {
+
+               di = sav = *s;
+
+               for (i = 0; i < 8; i++) {               /* YYY */
+
+                       ui    = u[i];
+                       rpi   = rp[i];
+                       u[i]  = sav;
+
+                       zzz   = GSM_MULT_R(rpi, di);
+                       sav   = GSM_ADD(   ui,  zzz);
+
+                       zzz   = GSM_MULT_R(rpi, ui);
+                       di    = GSM_ADD(   di,  zzz );
+               }
+
+               *s = di;
+       }
+}
+
+#if defined(USE_FLOAT_MUL) && defined(FAST)
+
+static void Fast_Short_term_analysis_filtering P4((S,rp,k_n,s),
+       struct gsm_state * S,
+       register word   * rp,   /* [0..7]       IN      */
+       register int    k_n,    /*   k_end - k_start    */
+       register word   * s     /* [0..n-1]     IN/OUT  */
+)
+{
+       register word           * u = S->u;
+       register int            i;
+
+       float     uf[8],
+                rpf[8];
+
+       register float scalef = 3.0517578125e-5;
+       register float          sav, di, temp;
+
+       for (i = 0; i < 8; ++i) {
+               uf[i]  = u[i];
+               rpf[i] = rp[i] * scalef;
+       }
+       for (; k_n--; s++) {
+               sav = di = *s;
+               for (i = 0; i < 8; ++i) {
+                       register float rpfi = rpf[i];
+                       register float ufi  = uf[i];
+
+                       uf[i] = sav;
+                       temp  = rpfi * di + ufi;
+                       di   += rpfi * ufi;
+                       sav   = temp;
+               }
+               *s = di;
+       }
+       for (i = 0; i < 8; ++i) u[i] = uf[i];
+}
+#endif /* ! (defined (USE_FLOAT_MUL) && defined (FAST)) */
+
+static void Short_term_synthesis_filtering P5((S,rrp,k,wt,sr),
+       struct gsm_state * S,
+       register word   * rrp,  /* [0..7]       IN      */
+       register int    k,      /* k_end - k_start      */
+       register word   * wt,   /* [0..k-1]     IN      */
+       register word   * sr    /* [0..k-1]     OUT     */
+)
+{
+       register word           * v = S->v;
+       register int            i;
+       register word           sri, tmp1, tmp2;
+       register longword       ltmp;   /* for GSM_ADD  & GSM_SUB */
+
+       while (k--) {
+               sri = *wt++;
+               for (i = 8; i--;) {
+
+                       /* sri = GSM_SUB( sri, gsm_mult_r( rrp[i], v[i] ) );
+                        */
+                       tmp1 = rrp[i];
+                       tmp2 = v[i];
+                       tmp2 =  ( tmp1 == MIN_WORD && tmp2 == MIN_WORD
+                               ? MAX_WORD
+                               : 0x0FFFF & (( (longword)tmp1 * (longword)tmp2
+                                            + 16384) >> 15)) ;
+
+                       sri  = GSM_SUB( sri, tmp2 );
+
+                       /* v[i+1] = GSM_ADD( v[i], gsm_mult_r( rrp[i], sri ) );
+                        */
+                       tmp1  = ( tmp1 == MIN_WORD && sri == MIN_WORD
+                               ? MAX_WORD
+                               : 0x0FFFF & (( (longword)tmp1 * (longword)sri
+                                            + 16384) >> 15)) ;
+
+                       v[i+1] = GSM_ADD( v[i], tmp1);
+               }
+               *sr++ = v[0] = sri;
+       }
+}
+
+
+#if defined(FAST) && defined(USE_FLOAT_MUL)
+
+static void Fast_Short_term_synthesis_filtering P5((S,rrp,k,wt,sr),
+       struct gsm_state * S,
+       register word   * rrp,  /* [0..7]       IN      */
+       register int    k,      /* k_end - k_start      */
+       register word   * wt,   /* [0..k-1]     IN      */
+       register word   * sr    /* [0..k-1]     OUT     */
+)
+{
+       register word           * v = S->v;
+       register int            i;
+
+       float va[9], rrpa[8];
+       register float scalef = 3.0517578125e-5, temp;
+
+       for (i = 0; i < 8; ++i) {
+               va[i]   = v[i];
+               rrpa[i] = (float)rrp[i] * scalef;
+       }
+       while (k--) {
+               register float sri = *wt++;
+               for (i = 8; i--;) {
+                       sri -= rrpa[i] * va[i];
+                       if     (sri < -32768.) sri = -32768.;
+                       else if (sri > 32767.) sri =  32767.;
+
+                       temp = va[i] + rrpa[i] * sri;
+                       if     (temp < -32768.) temp = -32768.;
+                       else if (temp > 32767.) temp =  32767.;
+                       va[i+1] = temp;
+               }
+               *sr++ = va[0] = sri;
+       }
+       for (i = 0; i < 9; ++i) v[i] = va[i];
+}
+
+#endif /* defined(FAST) && defined(USE_FLOAT_MUL) */
+
+void Gsm_Short_Term_Analysis_Filter P3((S,LARc,s),
+
+       struct gsm_state * S,
+
+       word    * LARc,         /* coded log area ratio [0..7]  IN      */
+       word    * s             /* signal [0..159]              IN/OUT  */
+)
+{
+       word            * LARpp_j       = S->LARpp[ S->j      ];
+       word            * LARpp_j_1     = S->LARpp[ S->j ^= 1 ];
+
+       word            LARp[8];
+
+#undef FILTER
+#if    defined(FAST) && defined(USE_FLOAT_MUL)
+#      define  FILTER  (* (S->fast                     \
+                          ? Fast_Short_term_analysis_filtering \
+                          : Short_term_analysis_filtering      ))
+
+#else
+#      define  FILTER  Short_term_analysis_filtering
+#endif
+
+       Decoding_of_the_coded_Log_Area_Ratios( LARc, LARpp_j );
+
+       Coefficients_0_12(  LARpp_j_1, LARpp_j, LARp );
+       LARp_to_rp( LARp );
+       FILTER( S, LARp, 13, s);
+
+       Coefficients_13_26( LARpp_j_1, LARpp_j, LARp);
+       LARp_to_rp( LARp );
+       FILTER( S, LARp, 14, s + 13);
+
+       Coefficients_27_39( LARpp_j_1, LARpp_j, LARp);
+       LARp_to_rp( LARp );
+       FILTER( S, LARp, 13, s + 27);
+
+       Coefficients_40_159( LARpp_j, LARp);
+       LARp_to_rp( LARp );
+       FILTER( S, LARp, 120, s + 40);
+}
+
+void Gsm_Short_Term_Synthesis_Filter P4((S, LARcr, wt, s),
+       struct gsm_state * S,
+
+       word    * LARcr,        /* received log area ratios [0..7] IN  */
+       word    * wt,           /* received d [0..159]             IN  */
+
+       word    * s             /* signal   s [0..159]            OUT  */
+)
+{
+       word            * LARpp_j       = S->LARpp[ S->j     ];
+       word            * LARpp_j_1     = S->LARpp[ S->j ^=1 ];
+
+       word            LARp[8];
+
+#undef FILTER
+#if    defined(FAST) && defined(USE_FLOAT_MUL)
+
+#      define  FILTER  (* (S->fast                     \
+                          ? Fast_Short_term_synthesis_filtering        \
+                          : Short_term_synthesis_filtering     ))
+#else
+#      define  FILTER  Short_term_synthesis_filtering
+#endif
+
+       Decoding_of_the_coded_Log_Area_Ratios( LARcr, LARpp_j );
+
+       Coefficients_0_12( LARpp_j_1, LARpp_j, LARp );
+       LARp_to_rp( LARp );
+       FILTER( S, LARp, 13, wt, s );
+
+       Coefficients_13_26( LARpp_j_1, LARpp_j, LARp);
+       LARp_to_rp( LARp );
+       FILTER( S, LARp, 14, wt + 13, s + 13 );
+
+       Coefficients_27_39( LARpp_j_1, LARpp_j, LARp);
+       LARp_to_rp( LARp );
+       FILTER( S, LARp, 13, wt + 27, s + 27 );
+
+       Coefficients_40_159( LARpp_j, LARp );
+       LARp_to_rp( LARp );
+       FILTER(S, LARp, 120, wt + 40, s + 40);
+}
diff --git a/gr-gsm-fr-vocoder/src/lib/gsm/table.c b/gr-gsm-fr-vocoder/src/lib/gsm/table.c
new file mode 100644 (file)
index 0000000..16a0411
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * 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.
+ */
+
+/* $Header$ */
+
+/*  Most of these tables are inlined at their point of use.
+ */
+
+/*  4.4 TABLES USED IN THE FIXED POINT IMPLEMENTATION OF THE RPE-LTP
+ *      CODER AND DECODER
+ *
+ *     (Most of them inlined, so watch out.)
+ */
+
+#define        GSM_TABLE_C
+#include "private.h"
+#include       "gsm.h"
+
+/*  Table 4.1  Quantization of the Log.-Area Ratios
+ */
+/* i                1      2      3        4      5      6        7       8 */
+word gsm_A[8]   = {20480, 20480, 20480,  20480,  13964,  15360,   8534,  9036};
+word gsm_B[8]   = {    0,     0,  2048,  -2560,     94,  -1792,   -341, -1144};
+word gsm_MIC[8] = { -32,   -32,   -16,    -16,     -8,     -8,     -4,    -4 };
+word gsm_MAC[8] = {  31,    31,    15,     15,      7,      7,      3,     3 };
+
+
+/*  Table 4.2  Tabulation  of 1/A[1..8]
+ */
+word gsm_INVA[8]={ 13107, 13107,  13107, 13107,  19223, 17476,  31454, 29708 };
+
+
+/*   Table 4.3a  Decision level of the LTP gain quantizer
+ */
+/*  bc               0         1         2          3                  */
+word gsm_DLB[4] = {  6554,    16384,   26214,     32767        };
+
+
+/*   Table 4.3b   Quantization levels of the LTP gain quantizer
+ */
+/* bc                0          1        2          3                  */
+word gsm_QLB[4] = {  3277,    11469,   21299,     32767        };
+
+
+/*   Table 4.4  Coefficients of the weighting filter
+ */
+/* i               0      1   2    3   4      5      6     7   8   9    10  */
+word gsm_H[11] = {-134, -374, 0, 2054, 5741, 8192, 5741, 2054, 0, -374, -134 };
+
+
+/*   Table 4.5          Normalized inverse mantissa used to compute xM/xmax 
+ */
+/* i                   0        1    2      3      4      5     6      7   */
+word gsm_NRFAC[8] = { 29128, 26215, 23832, 21846, 20165, 18725, 17476, 16384 };
+
+
+/*   Table 4.6  Normalized direct mantissa used to compute xM/xmax
+ */
+/* i                  0      1       2      3      4      5      6      7   */
+word gsm_FAC[8]        = { 18431, 20479, 22527, 24575, 26623, 28671, 30719, 32767 };
diff --git a/gr-gsm-fr-vocoder/src/lib/gsm/unproto.h b/gr-gsm-fr-vocoder/src/lib/gsm/unproto.h
new file mode 100644 (file)
index 0000000..ccd5651
--- /dev/null
@@ -0,0 +1,23 @@
+/*
+ * 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.
+ */
+
+/*$Header$*/
+
+#ifdef PROTO_H         /* sic */
+#undef PROTO_H
+
+#undef P
+#undef P0
+#undef P1
+#undef P2
+#undef P3
+#undef P4
+#undef P5
+#undef P6
+#undef P7
+#undef P8
+
+#endif /* PROTO_H */
diff --git a/gr-gsm-fr-vocoder/src/lib/gsm_fr_decode_ps.cc b/gr-gsm-fr-vocoder/src/lib/gsm_fr_decode_ps.cc
new file mode 100644 (file)
index 0000000..59dcd3d
--- /dev/null
@@ -0,0 +1,72 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include "gsm_fr_decode_ps.h"
+extern "C"{
+#include "gsm/gsm.h"
+}
+#include <gr_io_signature.h>
+#include <stdexcept>
+#include <assert.h>
+
+gsm_fr_decode_ps_sptr
+gsm_fr_make_decode_ps ()
+{
+  return gsm_fr_decode_ps_sptr (new gsm_fr_decode_ps ());
+}
+
+gsm_fr_decode_ps::gsm_fr_decode_ps ()
+  : gr_sync_interpolator ("gsm_fr_decode_ps",
+                         gr_make_io_signature (1, 1, sizeof (gsm_frame)),
+                         gr_make_io_signature (1, 1, sizeof (short)),
+                         GSM_SAMPLES_PER_FRAME)
+{
+  if ((d_gsm = gsm_create ()) == 0)
+    throw std::runtime_error ("gsm_fr_decode_ps: gsm_create failed");
+}
+
+gsm_fr_decode_ps::~gsm_fr_decode_ps ()
+{
+  gsm_destroy (d_gsm);
+}
+
+int
+gsm_fr_decode_ps::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];
+  short *out = (short *) output_items[0];
+
+  assert ((noutput_items % GSM_SAMPLES_PER_FRAME) == 0);
+
+  for (int i = 0; i < noutput_items; i += GSM_SAMPLES_PER_FRAME){
+    gsm_decode (d_gsm, const_cast<unsigned char*>(in), out);
+    in += sizeof (gsm_frame);
+    out += GSM_SAMPLES_PER_FRAME;
+  }
+
+  return noutput_items;
+}
diff --git a/gr-gsm-fr-vocoder/src/lib/gsm_fr_decode_ps.h b/gr-gsm-fr-vocoder/src/lib/gsm_fr_decode_ps.h
new file mode 100644 (file)
index 0000000..4e1b212
--- /dev/null
@@ -0,0 +1,49 @@
+/* -*- 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 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.
+ */
+#ifndef INCLUDED_GSM_FR_DECODE_PS_H
+#define INCLUDED_GSM_FR_DECODE_PS_H
+
+#include <gr_sync_interpolator.h>
+
+class gsm_fr_decode_ps;
+typedef boost::shared_ptr<gsm_fr_decode_ps> gsm_fr_decode_ps_sptr;
+
+gsm_fr_decode_ps_sptr gsm_fr_make_decode_ps ();
+
+/*!
+ * \brief GSM 06.10 Full Rate Vocoder Decoder
+ */
+class gsm_fr_decode_ps : public gr_sync_interpolator {
+  struct gsm_state     *d_gsm;
+
+  friend gsm_fr_decode_ps_sptr gsm_fr_make_decode_ps ();
+  gsm_fr_decode_ps ();
+
+public:
+  ~gsm_fr_decode_ps ();
+
+  int work (int noutput_items,
+           gr_vector_const_void_star &input_items,
+           gr_vector_void_star &output_items);
+};
+
+#endif /* INCLUDED_GSM_FR_DECODE_PS_H */
diff --git a/gr-gsm-fr-vocoder/src/lib/gsm_fr_encode_sp.cc b/gr-gsm-fr-vocoder/src/lib/gsm_fr_encode_sp.cc
new file mode 100644 (file)
index 0000000..8f49280
--- /dev/null
@@ -0,0 +1,69 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include "gsm_fr_encode_sp.h"
+extern "C"{
+#include "gsm/gsm.h"
+}
+#include <gr_io_signature.h>
+#include <stdexcept>
+
+gsm_fr_encode_sp_sptr
+gsm_fr_make_encode_sp ()
+{
+  return gsm_fr_encode_sp_sptr (new gsm_fr_encode_sp ());
+}
+
+gsm_fr_encode_sp::gsm_fr_encode_sp ()
+  : gr_sync_decimator ("gsm_fr_encode_sp",
+                      gr_make_io_signature (1, 1, sizeof (short)),
+                      gr_make_io_signature (1, 1, sizeof (gsm_frame)),
+                      GSM_SAMPLES_PER_FRAME)
+{
+  if ((d_gsm = gsm_create ()) == 0)
+    throw std::runtime_error ("gsm_fr_encode_sp: gsm_create failed");
+}
+
+gsm_fr_encode_sp::~gsm_fr_encode_sp ()
+{
+  gsm_destroy (d_gsm);
+}
+
+int
+gsm_fr_encode_sp::work (int noutput_items,
+                       gr_vector_const_void_star &input_items,
+                       gr_vector_void_star &output_items)
+{
+  const short *in = (const short *) input_items[0];
+  unsigned char *out = (unsigned char *) output_items[0];
+
+  for (int i = 0; i < noutput_items; i++){
+    gsm_encode (d_gsm, const_cast<short*>(in), out);
+    in += GSM_SAMPLES_PER_FRAME;
+    out += sizeof (gsm_frame);
+  }
+
+  return noutput_items;
+}
diff --git a/gr-gsm-fr-vocoder/src/lib/gsm_fr_encode_sp.h b/gr-gsm-fr-vocoder/src/lib/gsm_fr_encode_sp.h
new file mode 100644 (file)
index 0000000..5cbc3ae
--- /dev/null
@@ -0,0 +1,52 @@
+/* -*- 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 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.
+ */
+#ifndef INCLUDED_GSM_FR_ENCODE_SP_H
+#define INCLUDED_GSM_FR_ENCODE_SP_H
+
+#include <gr_sync_decimator.h>
+
+class gsm_fr_encode_sp;
+typedef boost::shared_ptr<gsm_fr_encode_sp> gsm_fr_encode_sp_sptr;
+
+gsm_fr_encode_sp_sptr gsm_fr_make_encode_sp ();
+
+/*!
+ * \brief GSM 06.10 Full Rate Vocoder Encoder
+ * \ingroup block
+ *
+ * shorts in; 33 byte packets out
+ */
+class gsm_fr_encode_sp : public gr_sync_decimator {
+  struct gsm_state     *d_gsm;
+
+  friend gsm_fr_encode_sp_sptr gsm_fr_make_encode_sp ();
+  gsm_fr_encode_sp ();
+
+public:
+  ~gsm_fr_encode_sp ();
+
+  int work (int noutput_items,
+           gr_vector_const_void_star &input_items,
+           gr_vector_void_star &output_items);
+};
+
+#endif /* INCLUDED_GSM_FR_ENCODE_SP_H */
diff --git a/gr-gsm-fr-vocoder/src/lib/gsm_full_rate.i b/gr-gsm-fr-vocoder/src/lib/gsm_full_rate.i
new file mode 100644 (file)
index 0000000..80c5557
--- /dev/null
@@ -0,0 +1,52 @@
+/* -*- 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 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.
+ */
+
+%feature("autodoc","1");
+%include "exception.i"
+%import "gnuradio.i"
+
+%{
+#include "gnuradio_swig_bug_workaround.h"      // mandatory bug fix
+#include "gsm_fr_encode_sp.h"
+#include "gsm_fr_decode_ps.h"
+#include <stdexcept>
+%}
+
+GR_SWIG_BLOCK_MAGIC(gsm_fr,encode_sp);
+
+gsm_fr_encode_sp_sptr gsm_fr_make_encode_sp ();
+
+class gsm_fr_encode_sp : public gr_sync_decimator {
+public:
+  ~gsm_fr_encode_sp ();
+};
+
+// ----------------------------------------------------------------
+
+GR_SWIG_BLOCK_MAGIC(gsm_fr,decode_ps);
+
+gsm_fr_decode_ps_sptr gsm_fr_make_decode_ps ();
+
+class gsm_fr_decode_ps : public gr_sync_interpolator {
+public:
+  ~gsm_fr_decode_ps ();
+};
diff --git a/gr-gsm-fr-vocoder/src/python/Makefile.am b/gr-gsm-fr-vocoder/src/python/Makefile.am
new file mode 100644 (file)
index 0000000..4df9ca3
--- /dev/null
@@ -0,0 +1,33 @@
+#
+# 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.
+# 
+
+include $(top_srcdir)/Makefile.common
+
+EXTRA_DIST = run_tests.in
+
+
+TESTS =                                \
+       run_tests
+
+
+noinst_PYTHON =                        \
+       encdec.py                       \
+       qa_gsm_full_rate.py             
diff --git a/gr-gsm-fr-vocoder/src/python/encdec.py b/gr-gsm-fr-vocoder/src/python/encdec.py
new file mode 100755 (executable)
index 0000000..c8a4622
--- /dev/null
@@ -0,0 +1,44 @@
+#!/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 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.
+# 
+
+from gnuradio import gr
+from gnuradio import audio
+from gnuradio.vocoder import gsm_full_rate
+
+def build_graph():
+    fg = gr.flow_graph()
+    src = audio.source(8000)
+    src_scale = gr.multiply_const_ff(32767)
+    f2s = gr.float_to_short ()
+    enc = gsm_full_rate.encode_sp()
+    dec = gsm_full_rate.decode_ps()
+    s2f = gr.short_to_float ()
+    sink_scale = gr.multiply_const_ff(1.0/32767.)
+    sink = audio.sink(8000)
+    fg.connect(src, src_scale, f2s, enc, dec, s2f, sink_scale, sink)
+    return fg
+
+if __name__ == '__main__':
+    fg = build_graph()
+    fg.start()
+    raw_input ('Press Enter to exit: ')
+    fg.stop()
diff --git a/gr-gsm-fr-vocoder/src/python/qa_gsm_full_rate.py b/gr-gsm-fr-vocoder/src/python/qa_gsm_full_rate.py
new file mode 100755 (executable)
index 0000000..6b318d2
--- /dev/null
@@ -0,0 +1,35 @@
+#!/usr/bin/env 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.
+# 
+
+from gnuradio import gr, gr_unittest
+import gsm_full_rate
+
+class qa_howto (gr_unittest.TestCase):
+
+    def setUp (self):
+        self.fg = gr.flow_graph ()
+
+    def tearDown (self):
+        self.fg = None
+
+if __name__ == '__main__':
+    gr_unittest.main ()
diff --git a/gr-gsm-fr-vocoder/src/python/run_tests.in b/gr-gsm-fr-vocoder/src/python/run_tests.in
new file mode 100644 (file)
index 0000000..2c3be90
--- /dev/null
@@ -0,0 +1,47 @@
+#!/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@/gr-gsm-fr-vocoder/src/lib
+# Where to look in the src tree for swig generated python code
+libsrc=@abs_top_srcdir@/gr-gsm-fr-vocoder/src/lib
+# Where to look in the src tree for hand written python code
+py=@abs_top_srcdir@/gr-gsm-fr-vocoder/src/python
+
+# Where to look for GNU Radio python modules in current build tree
+# FIXME this is wrong on a distcheck.  We really need to ask gnuradio-core
+# where it put its python files.
+grpythonbld=@abs_top_builddir@/gnuradio-core/src/python/:@abs_top_builddir@/gnuradio-core/src/lib/swig/:@abs_top_builddir@/gnuradio-core/src/lib/swig/.libs
+
+PYTHONPATH="$grpythonbld:$libbld:$libbld/.libs:$libsrc:$py:$PYTHONPATH"
+export PYTHONPATH
+
+#
+# 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/.buildpri b/gr-howto-write-a-block/.buildpri
new file mode 100644 (file)
index 0000000..29ba0df
--- /dev/null
@@ -0,0 +1 @@
+450
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..2b7b643
--- /dev/null
@@ -0,0 +1,340 @@
+                   GNU GENERAL PUBLIC LICENSE
+                      Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+     59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                           Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.)  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
+this service 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 make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  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.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+\f
+                   GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute 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 and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+  2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+\f
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of Sections
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable.  However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+\f
+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+  5. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+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
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+\f
+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the 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 a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+                           NO WARRANTY
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, 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.
+
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE 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.
+
+                    END OF TERMS AND CONDITIONS
+\f
+           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
+convey 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) 19yy <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 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
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) 19yy name of author
+    Gnomovision 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, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+  `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+  <signature of Ty Coon>, 1 April 1989
+  Ty Coon, President of Vice
+
+This 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 Library General
+Public License instead of this License.
diff --git a/gr-howto-write-a-block/ChangeLog b/gr-howto-write-a-block/ChangeLog
new file mode 100644 (file)
index 0000000..fcb7af6
--- /dev/null
@@ -0,0 +1,46 @@
+2006-07-21  Eric Blossom  <eb@comsec.com>
+
+       * doc/howto-write-a-block.xml: clarified 1:1 i/o relationship
+       versus size of input and output items.  Thanks Jens!
+
+2005-07-02  Eric Blossom  <eb@comsec.com>
+
+       * config/gr_no_undefined.m4, config/gr_x86_64.m4: new, x86_64 support.
+       * config/gr_python.m4: backed out search for libpython, making
+       x86_64 work and breaking Cygwin/MinGW.
+       * configure.ac, src/lib/Makefile.am: mods for x86_64, $(NO_UNDEFINED)
+       
+2005-05-09  Stephane Fillod  <f8cfe@free.fr>
+
+        * config/gr_sysv_shm.m4: SysV shared memory not mandatory
+       * config/gr_pwin32.m4, config/gr_python.m4, config/lf_cxx.m4:
+         fixes for Cygwin, MinGW
+
+2005-01-29  Eric Blossom  <eb@comsec.com>
+
+       * src/lib/Makefile.am: mods for SWIG 1.3.24
+
+2005-01-20  Eric Blossom  <eb@comsec.com>
+
+       * doc/howto-write-a-block.xml: made release 0.1
+
+#
+# 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 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.
+# 
diff --git a/gr-howto-write-a-block/INSTALL b/gr-howto-write-a-block/INSTALL
new file mode 100644 (file)
index 0000000..54caf7c
--- /dev/null
@@ -0,0 +1,229 @@
+Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002 Free Software
+Foundation, Inc.
+
+   This file is free documentation; the Free Software Foundation gives
+unlimited permission to copy, distribute and modify it.
+
+Basic Installation
+==================
+
+   These are generic installation instructions.
+
+   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 only 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.  If you're
+     using `csh' on an old version of System V, you might need to type
+     `sh ./configure' instead to prevent `csh' from trying to execute
+     `configure' itself.
+
+     Running `configure' takes awhile.  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.
+
+  4. Type `make install' to install the programs and any data files and
+     documentation.
+
+  5. 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.
+
+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=c89 CFLAGS=-O2 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 must use a version of `make' that
+supports the `VPATH' variable, such as 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 `..'.
+
+   If you have to use a `make' that does not support the `VPATH'
+variable, you have 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.
+
+Installation Names
+==================
+
+   By default, `make install' will install the package's files in
+`/usr/local/bin', `/usr/local/man', etc.  You can specify an
+installation prefix other than `/usr/local' by giving `configure' the
+option `--prefix=PATH'.
+
+   You can specify separate installation prefixes for
+architecture-specific files and architecture-independent files.  If you
+give `configure' the option `--exec-prefix=PATH', the package will use
+PATH as the prefix for installing programs and libraries.
+Documentation and other data files will still use the regular prefix.
+
+   In addition, if you use an unusual directory layout you can give
+options like `--bindir=PATH' 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.
+
+   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'.
+
+Optional Features
+=================
+
+   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.
+
+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 `--target=TYPE' option 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
+
+will cause the specified gcc to be used as the C compiler (unless it is
+overridden in the site shell script).
+
+`configure' Invocation
+======================
+
+   `configure' recognizes the following options to control how it
+operates.
+
+`--help'
+`-h'
+     Print a summary of the options to `configure', and exit.
+
+`--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.
+
+`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..dcab912
--- /dev/null
@@ -0,0 +1,29 @@
+#
+# 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.
+# 
+
+include $(top_srcdir)/Makefile.common
+
+EXTRA_DIST = bootstrap configure config.h.in .buildpri
+SUBDIRS = config src
+DIST_SUBDIRS = config src doc
+
+pkgconfigdir = $(libdir)/pkgconfig
+pkgconfig_DATA =
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..261de50
--- /dev/null
@@ -0,0 +1,38 @@
+# -*- Makefile -*-
+#
+# 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 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.
+# 
+
+# includes
+grincludedir   = $(includedir)/gnuradio
+
+# swig includes 
+swigincludedir = $(grincludedir)/swig
+
+# Install this stuff in the appropriate subdirectory
+# This usually ends up at:
+#   ${prefix}/lib/python${python_version}/site-packages/gnuradio
+
+grpythondir = $(pythondir)/gnuradio
+grpyexecdir = $(pyexecdir)/gnuradio
+
+# swig flags
+SWIGPYTHONFLAGS = -fvirtual -python -modern
+SWIGGRFLAGS = -I$(GNURADIO_CORE_INCLUDEDIR)/swig -I$(GNURADIO_CORE_INCLUDEDIR)
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..2b5e9a5
--- /dev/null
@@ -0,0 +1,44 @@
+#
+# 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 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 tarball contains a build tree with examples, Makefiles, etc that
+demonstrate how to write signal processing blocks for the GNU Radio
+system.  
+
+To build the examples from the tarball use the normal recipe:
+
+  $ ./configure
+  $ make
+  $ make check
+
+If you're building from CVS, you'll need to use this sequence, since
+CVS doesn't contain configure or the generated Makefiles.
+
+  $ ./bootstrap
+  $ ./configure
+  $ make
+  $ make check
+
+
+The doc directory is not built by default.  This is to avoid spurious
+build problems on systems that don't have xmlto installed.  If you
+have xmlto and its dependencies installed, you can build the html
+version of the howto article by cd'ing to doc and invoking make.
diff --git a/gr-howto-write-a-block/bootstrap b/gr-howto-write-a-block/bootstrap
new file mode 100755 (executable)
index 0000000..7df375e
--- /dev/null
@@ -0,0 +1,29 @@
+#!/bin/sh
+
+# 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 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.
+
+
+rm -fr config.cache autom4te*.cache
+
+aclocal -I config
+autoconf
+autoheader
+libtoolize --automake
+automake --add-missing
diff --git a/gr-howto-write-a-block/config.guess b/gr-howto-write-a-block/config.guess
new file mode 100644 (file)
index 0000000..52c01be
--- /dev/null
@@ -0,0 +1,1465 @@
+#! /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 Free Software Foundation, Inc.
+
+timestamp='2005-11-11'
+
+# 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
+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 -q "$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 ;;
+           *) 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 ;;
+    macppc:MirBSD:*:*)
+       echo powerppc-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.*:*)
+       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:*:[45])
+       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:*:*)
+       echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
+       exit ;;
+    i*:CYGWIN*:*)
+       echo ${UNAME_MACHINE}-pc-cygwin
+       exit ;;
+    i*: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 ;;
+    x86:Interix*:[345]*)
+       echo i586-pc-interix${UNAME_RELEASE}|sed -e 's/\..*//'
+       exit ;;
+    [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:*:*)
+       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 | grep ^CPU=`
+       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 | grep ^CPU=`
+       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 ;;
+    x86_64:Linux:*:*)
+       echo x86_64-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
+       #ifdef __INTEL_COMPILER
+       LIBC=gnu
+       #else
+       LIBC=gnuaout
+       #endif
+       #endif
+       #ifdef __dietlibc__
+       LIBC=dietlibc
+       #endif
+EOF
+       eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=`
+       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 ;;
+    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 ;;
+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://savannah.gnu.org/cgi-bin/viewcvs/*checkout*/config/config/config.guess
+and
+  http://savannah.gnu.org/cgi-bin/viewcvs/*checkout*/config/config/config.sub
+
+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 100644 (file)
index 0000000..a4aba16
--- /dev/null
@@ -0,0 +1,1587 @@
+#! /bin/sh
+# Configuration validation subroutine script.
+#   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+#   2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+
+timestamp='2005-11-13'
+
+# 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
+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-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 \
+       | bfin \
+       | c4x | clipper \
+       | d10v | d30v | dlx | dsp16xx \
+       | fr30 | frv \
+       | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
+       | i370 | i860 | i960 | ia64 \
+       | ip2k | iq2000 \
+       | m32r | m32rle | m68000 | m68k | 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 \
+       | mn10200 | mn10300 \
+       | ms1 \
+       | msp430 \
+       | ns16k | ns32k \
+       | or32 \
+       | pdp10 | pdp11 | pj | pjl \
+       | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \
+       | pyramid \
+       | sh | sh[1234] | sh[24]a | sh[23]e | sh[34]eb | shbe | shle | sh[1234]le | sh3ele \
+       | sh64 | sh64le \
+       | sparc | sparc64 | sparc64b | sparc86x | sparclet | sparclite \
+       | sparcv8 | sparcv9 | sparcv9b \
+       | strongarm \
+       | tahoe | thumb | tic4x | tic80 | tron \
+       | v850 | v850e \
+       | we32k \
+       | x86 | xscale | xscalee[bl] | xstormy16 | xtensa \
+       | z8k)
+               basic_machine=$basic_machine-unknown
+               ;;
+       m32c)
+               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)
+               ;;
+
+       # 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-* \
+       | bfin-* | bs2000-* \
+       | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \
+       | clipper-* | craynv-* | cydra-* \
+       | d10v-* | d30v-* | dlx-* \
+       | elxsi-* \
+       | f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \
+       | h8300-* | h8500-* \
+       | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
+       | i*86-* | i860-* | i960-* | ia64-* \
+       | ip2k-* | iq2000-* \
+       | 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-* \
+       | ms1-* \
+       | msp430-* \
+       | 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-* | shbe-* \
+       | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
+       | sparc-* | sparc64-* | sparc64b-* | sparc86x-* | sparclet-* \
+       | sparclite-* \
+       | sparcv8-* | sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \
+       | tahoe-* | thumb-* \
+       | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
+       | tron-* \
+       | v850-* | v850e-* | vax-* \
+       | we32k-* \
+       | x86-* | x86_64-* | xps100-* | xscale-* | xscalee[bl]-* \
+       | xstormy16-* | xtensa-* \
+       | ymp-* \
+       | z8k-*)
+               ;;
+       m32c-*)
+               ;;
+       # 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
+               ;;
+       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
+               ;;
+       cr16c)
+               basic_machine=cr16c-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
+               ;;
+       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
+               ;;
+       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
+               ;;
+       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
+               ;;
+       pbd)
+               basic_machine=sparc-tti
+               ;;
+       pbb)
+               basic_machine=m68k-tti
+               ;;
+       pc532 | pc532-*)
+               basic_machine=ns32k-pc532
+               ;;
+       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
+               ;;
+       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
+               ;;
+       sei)
+               basic_machine=mips-sei
+               os=-seiux
+               ;;
+       sequent)
+               basic_machine=i386-sequent
+               ;;
+       sh)
+               basic_machine=sh-hitachi
+               os=-hms
+               ;;
+       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
+               ;;
+       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)
+               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* \
+             | -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-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*)
+       # 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
+       *-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
+               ;;
+       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/Makefile.am b/gr-howto-write-a-block/config/Makefile.am
new file mode 100644 (file)
index 0000000..2154a22
--- /dev/null
@@ -0,0 +1,66 @@
+#
+# 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 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.
+# 
+
+include $(top_srcdir)/Makefile.common
+
+# Install m4 macros in this directory
+m4datadir = $(datadir)/aclocal
+
+# List your m4 macros here
+m4macros =                     \
+       acx_pthread.m4          \
+       bnv_have_qt.m4          \
+       cppunit.m4              \
+       gr_as.m4                \
+       gr_boost.m4             \
+       gr_check_createfilemapping.m4 \
+       gr_check_usrp.m4        \
+       gr_check_mc4020.m4      \
+       gr_check_shm_open.m4    \
+       gr_doxygen.m4           \
+       gr_gprof.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_swig.m4              \
+       gr_sysv_shm.m4          \
+       gr_x86_64.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..d318ab0
--- /dev/null
@@ -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
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_as.m4 b/gr-howto-write-a-block/config/gr_as.m4
new file mode 100644 (file)
index 0000000..a069547
--- /dev/null
@@ -0,0 +1,34 @@
+# Figure out how to run the assembler.             -*- Autoconf -*-
+
+# serial 2
+
+# Copyright 2001 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, 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.
+
+# I just copy and renamed this from automake-1.6.3 so we should work 
+# under both 1.4-p6 and later.  -eb
+
+# GR_PROG_AS
+# ----------
+AC_DEFUN([GR_PROG_AS],
+[# By default we simply use the C compiler to build assembly code.
+AC_REQUIRE([AC_PROG_CC])
+: ${CCAS='$(CC)'}
+# Set ASFLAGS if not already set.
+: ${CCASFLAGS='$(CFLAGS)'}
+AC_SUBST(CCAS)
+AC_SUBST(CCASFLAGS)])
diff --git a/gr-howto-write-a-block/config/gr_boost.m4 b/gr-howto-write-a-block/config/gr_boost.m4
new file mode 100644 (file)
index 0000000..b1751c0
--- /dev/null
@@ -0,0 +1,111 @@
+dnl
+dnl Copyright 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 2, 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., 59 Temple Place - Suite 330,
+dnl Boston, MA 02111-1307, USA.
+dnl
+
+dnl This tries to do the "right thing" to locate the boost include files.
+dnl If the user explicitly specified --with-boost-include-dir=<foo>
+dnl we believe them and use it.  Otherwise,
+dnl
+dnl We look for boost/shared_ptr.hpp in the "normal places".  That is,
+dnl wherever AC_CHECK_HEADER looks.  If the boost includes are in /usr/local/include
+dnl this step will find them.
+dnl
+dnl Otherwise, we check to see if the boost stuff was installed in a version-specific
+dnl directory under /usr/local/include.  These look like: /usr/local/include/boost-1_33_1
+dnl If there's more than one version installed, we select the
+dnl lexicographically greatest one.
+dnl
+dnl If none of these work, we bail.
+
+AC_DEFUN([GR_REQUIRE_BOOST_INCLUDES],
+[
+  AC_LANG_PUSH(C++)
+  gr_boost_include_dir=
+  AC_ARG_WITH([boost-include-dir],
+    AC_HELP_STRING([--with-boost-include-dir=<path>],
+                  [path to boost c++ include files]),
+    [
+      # "yes" and "no" are bogus answers
+      if test x"$with_boost_include_dir" == xyes ||
+         test x"$with_boost_include_dir" == xno; then
+       gr_boost_include_dir=
+      else
+        gr_boost_include_dir=$with_boost_include_dir
+      fi
+    ])
+  echo "gr_boost_include_dir = $gr_boost_include_dir"
+  if test x$gr_boost_include_dir != x; then
+    #
+    # If the user specified a directory, then we use it
+    #
+    OLD_CPPFLAGS=$CPPFLAGS
+    CPPFLAGS="$CPPFLAGS -I$gr_boost_include_dir"
+    AC_CHECK_HEADER([boost/shared_ptr.hpp],
+      [BOOST_CFLAGS="-I$gr_boost_include_dir"],
+      [AC_MSG_ERROR(
+        [Failed to locate boost/shared_ptr.hpp.
+Try using --with-boost-include-dir=<path>, 
+E.g., --with-boost-include-dir=/usr/local/include/boost-1_33_1])])
+    CPPFLAGS=$OLD_CPPFLAGS
+  else
+    #
+    # Otherwise we check in the default places
+    # 
+    AC_CHECK_HEADER([boost/shared_ptr.hpp],
+      [BOOST_CFLAGS=""],
+      [ # Nope, look for latest version if any in $prefix/include/boost-*
+
+        # Wipe out cached value.  KLUDGE: AC should have API for this
+       unset AS_TR_SH([ac_cv_header_boost/shared_ptr.hpp])
+
+       boost_last_match(){
+         #echo "boost_last_match: [$]*"
+         pattern="[$]1"
+         shift
+         if test "[$]pattern" = "[$]1"
+         then
+           LM=''
+         else
+           shift `expr [$]# - 1`
+           LM=[$]1
+         fi
+         #echo "LM(1)='[$]LM'"
+       }
+
+       pattern="/usr/local/include/boost-*"
+       boost_last_match "$pattern" $pattern
+       #echo "LM(2)='$LM'"
+
+        OLD_CPPFLAGS=$CPP_FLAGS
+        CPPFLAGS="$CPPFLAGS -I$LM"
+        AC_CHECK_HEADER([boost/shared_ptr.hpp],
+          [BOOST_CFLAGS="-I$LM"],
+          [AC_MSG_ERROR(
+            [Failed to locate boost/shared_ptr.hpp.  
+Try using --with-boost-include-dir=<path>, 
+E.g., --with-boost-include-dir=/usr/local/include/boost-1_33_1])])
+        CPPFLAGS=$OLD_CPPFLAGS
+      ])
+
+   fi
+   unset boost_last_match LM
+   AC_LANG_POP
+   AC_SUBST(BOOST_CFLAGS)
+])
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..9cb94f5
--- /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 2, 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., 59 Temple Place - Suite 330,
+dnl Boston, MA 02111-1307, 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..0c4318e
--- /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 2, 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., 59 Temple Place - Suite 330,
+dnl Boston, MA 02111-1307, 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..27c9ee6
--- /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 2, 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., 59 Temple Place - Suite 330,
+dnl Boston, MA 02111-1307, 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..b818a69
--- /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 2, 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., 59 Temple Place - Suite 330,
+dnl Boston, MA 02111-1307, 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..82aea35
--- /dev/null
@@ -0,0 +1,59 @@
+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 2, 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., 59 Temple Place - Suite 330,
+dnl Boston, MA 02111-1307, USA.
+dnl 
+
+AC_DEFUN([GR_CHECK_DOXYGEN],[
+  AC_ARG_ENABLE(doxygen, [  --enable-doxygen        enable documentation generation with doxygen (no)])
+  AC_ARG_ENABLE(dot, [  --enable-dot            use 'dot' to generate graphs in doxygen (auto)])
+  AC_ARG_ENABLE(html-docs, [  --enable-html-docs      enable HTML generation with doxygen (yes)], [], [ enable_html_docs=yes])
+  AC_ARG_ENABLE(latex-docs, [  --enable-latex-docs     enable LaTeX doc generation with doxygen (no)], [], [ enable_latex_docs=no])
+
+  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_html_docs)
+  AC_SUBST(enable_latex_docs)
+  AC_SUBST(generate_docs)
+])
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..cc50508
--- /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 2, 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., 59 Temple Place - Suite 330,
+dnl Boston, MA 02111-1307, 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_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..491f7a0
--- /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 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.
+
+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..8780fab
--- /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 2, 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., 59 Temple Place - Suite 330,
+dnl Boston, MA 02111-1307, 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..7c3150b
--- /dev/null
@@ -0,0 +1,51 @@
+# Check for Omnithread (pthread/NT) thread 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 2, 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.
+
+AC_DEFUN([GR_OMNITHREAD],
+[
+  # Check first for POSIX
+  ACX_PTHREAD(
+  [ ot_posix="yes"
+    AC_DEFINE(OMNITHREAD_POSIX,[1],[Define to 1 to enable pthread])
+  ],[
+    # 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"
+       AC_DEFINE(OMNITHREAD_NT,[1],[Define to 1 to enable NT thread])
+      ],
+      [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..5f748af
--- /dev/null
@@ -0,0 +1,146 @@
+# 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 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.
+
+
+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
+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..760a0f7
--- /dev/null
@@ -0,0 +1,116 @@
+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 2, 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., 59 Temple Place - Suite 330,
+dnl Boston, MA 02111-1307, USA.
+dnl 
+
+# PYTHON_DEVEL()
+#
+# Checks for Python and tries to get the include path to 'Python.h'.
+# It provides the $(PYTHON_CPPFLAGS) and $(PYTHON_LDFLAGS) output variables.
+#
+AC_DEFUN([PYTHON_DEVEL],[
+       AC_REQUIRE([AM_PATH_PYTHON])
+       AC_REQUIRE([AC_CANONICAL_HOST])
+
+       # 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
+          AC_MSG_CHECKING([for pythondir])
+          pythondir=`echo $pythondir |sed 's,\\\\,/,g'`
+          AC_MSG_RESULT($pythondir)
+          AC_SUBST([pythondir])
+          AC_MSG_CHECKING([for pkgpythondir])
+          pkgpythondir=`echo $pkgpythondir |sed 's,\\\\,/,g'`
+          AC_MSG_RESULT($pkgpythondir)
+          AC_SUBST([pkgpythondir])
+          AC_MSG_CHECKING([for pyexecdir])
+          pyexecdir=`echo $pyexecdir |sed 's,\\\\,/,g'`
+          AC_MSG_RESULT($pyexecdir)
+          AC_SUBST([pyexecdir])
+          AC_MSG_CHECKING([for pkgpyexecdir])
+          pkgpyexecdir=`echo $pkgpyexecdir |sed 's,\\\\,/,g'`
+          AC_MSG_RESULT($pkgpyexecdir)
+          AC_SUBST([pkgpyexecdir])
+         ;;
+        esac
+
+       AC_SUBST([PYTHON_LDFLAGS])
+])
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..8a03eeb
--- /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 2, 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., 59 Temple Place - Suite 330,
+dnl Boston, MA 02111-1307, 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..7f3abde
--- /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 2, 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., 59 Temple Place - Suite 330,
+dnl Boston, MA 02111-1307, 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.23)
+  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..1bb2f34
--- /dev/null
@@ -0,0 +1,44 @@
+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 2, 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., 59 Temple Place - Suite 330,
+dnl Boston, MA 02111-1307, USA.
+dnl 
+
+AC_DEFUN([GR_SET_MD_CPU],[
+  AC_REQUIRE([AC_CANONICAL_HOST])
+  AC_ARG_WITH(md-cpu,
+       [  --with-md-cpu=ARCH      set machine dependent speedups (auto)],
+               [cf_with_md_cpu="$withval"],
+               [cf_with_md_cpu="$host_cpu"])
+
+  AC_MSG_CHECKING([for machine dependent speedups])
+  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        ;;
+#  sparc)       MD_CPU=sparc    ;;
+   *)           MD_CPU=generic   ;;
+  esac
+  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_generic, test $MD_CPU = generic)
+])
+
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..a587c6d
--- /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 2, 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., 59 Temple Place - Suite 330,
+dnl Boston, MA 02111-1307, 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..5e11e49
--- /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 2, 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.
+
+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_x86_64.m4 b/gr-howto-write-a-block/config/gr_x86_64.m4
new file mode 100644 (file)
index 0000000..3d6f5ea
--- /dev/null
@@ -0,0 +1,39 @@
+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 2, 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., 59 Temple Place - Suite 330,
+dnl Boston, MA 02111-1307, USA.
+dnl 
+
+# GR_X86_64()
+#
+# Checks to see if we're on a x86_64 machine, and if so, ensure
+# that libdir ends in "64"
+#
+AC_DEFUN([GR_X86_64],[
+  AC_REQUIRE([AC_CANONICAL_HOST])
+  if test "$host_cpu" = "x86_64"; then
+    AC_MSG_CHECKING([libdir for lib64 suffix])
+    t=${libdir##*/lib}
+    if test "$t" != 64 && test -d /lib64 && ! test -L /lib64; then
+      libdir=${libdir}64
+      AC_MSG_RESULT([no. Setting libdir to $libdir])
+    else
+      AC_MSG_RESULT([yes])
+    fi
+  fi
+])
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..f9bd715
--- /dev/null
@@ -0,0 +1,42 @@
+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 2 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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_MINIX])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..8ade1fb
--- /dev/null
@@ -0,0 +1,121 @@
+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 2 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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.
+# 1. Defines CXX_HAS_NO_BOOL if the compiler does not support the bool
+#    data type
+# 2. Defines CXX_HAS_BUGGY_FOR_LOOPS if the compiler has buggy
+#    scoping for the for-loop
+# 3. Defines USE_ASSERT if the user wants to use assertions
+# -----------------------------------------------------------------------
+
+
+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 Check whether we have bool
+  AC_MSG_CHECKING(whether C++ has bool)
+  AC_TRY_RUN([main() { bool b1=true; bool b2=false; }],
+             [ AC_MSG_RESULT(yes) ],
+             [ AC_MSG_RESULT(no)
+               AC_DEFINE(CXX_HAS_NO_BOOL,[],[Define if C++ is missing bool type]) ],
+             [ AC_MSG_WARN(Don't cross-compile)]
+            )
+
+  dnl Test whether C++ has buggy for-loops
+  AC_MSG_CHECKING(whether C++ has buggy scoping in for-loops)
+  AC_TRY_COMPILE([#include <iostream.h>], [
+   for (int i=0;i<10;i++) { }
+   for (int i=0;i<10;i++) { }
+], [ AC_MSG_RESULT(no) ],
+   [ AC_MSG_RESULT(yes)
+     AC_DEFINE(CXX_HAS_BUGGY_FOR_LOOPS,[],[Define if for loop scoping is broken]) ])
+
+  dnl Test whether the user wants to enable assertions
+  AC_MSG_CHECKING(whether user wants assertions)
+  AC_ARG_ENABLE(assert,
+                [  --disable-assert        don't use cpp.h assert],
+                [ AC_DEFINE(NDEBUG,[],[Define to disable asserts (don't doit!)])
+                  AC_MSG_RESULT(no)  ],
+                [ AC_MSG_RESULT(yes) ],
+               )
+
+  dnl Test whether C++ has std::isnan
+  AC_MSG_CHECKING(whether C++ has std::isnan)
+  AC_TRY_COMPILE([#include <math.h>], [
+   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
+])
+
+AH_BOTTOM([// Workaround for compilers with buggy for-loop scoping
+// That's quite a few compilers actually including recent versions of
+// Dec Alpha cxx, HP-UX CC and SGI CC.
+// The trivial "if" statement provides the correct scoping to the 
+// for loop
+
+#ifdef CXX_HAS_BUGGY_FOR_LOOPS
+#undef for
+#define for if(1) for
+#endif
+])
+
+AH_BOTTOM([// If the C++ compiler we use doesn't have bool, then
+// the following is a near-perfect work-around. 
+// You must make sure your code does not depend on "int" and "bool"
+// being two different types, in overloading for instance.
+
+#ifdef CXX_HAS_NO_BOOL
+#define bool int
+#define true 1
+#define false 0
+#endif
+])
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..0ebb97e
--- /dev/null
@@ -0,0 +1,128 @@
+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 2 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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 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
+      CXXFLAGS="${CXXFLAGS} $i"
+      AC_MSG_RESULT(yes)
+    else
+      AC_MSG_RESULT(no)
+    fi
+  done
+  rm -f conftest.cc conftest.o
+])
+
+# --------------------------------------------------------------------------
+# Check whether the C compiler accepts a certain flag
+# If it does it adds the flag to 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
+      CFLAGS="${CFLAGS} $i"
+      AC_MSG_RESULT(yes)
+    else
+      AC_MSG_RESULT(no)
+    fi
+  done
+  rm -f conftest.c conftest.o
+])
+
+# --------------------------------------------------------------------------
+# Check whether the Fortran compiler accepts a certain flag
+# If it does it adds the flag to 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
+      FFLAGS="${FFLAGS} $i"
+      AC_MSG_RESULT(yes)  
+    else
+      AC_MSG_RESULT(no)
+    fi
+  done
+  rm -f conftest.f conftest.o
+])
+
+# ----------------------------------------------------------------------
+# Provide the configure script with an --with-warnings option that
+# turns on warnings. Call this command AFTER you have configured ALL your
+# compilers. 
+# ----------------------------------------------------------------------
+
+AC_DEFUN([LF_SET_WARNINGS],[
+  dnl Check for --with-warnings
+  AC_MSG_CHECKING([whether user wants warnings])
+  AC_ARG_WITH(warnings,
+              [  --with-warnings         Turn on warnings],
+              [ lf_warnings=yes ], [ lf_warnings=no ])
+  lf_warnings=yes # hard code for now -eb
+  AC_MSG_RESULT($lf_warnings)
+  
+  dnl Warnings for the two main compilers
+  cc_warning_flags="-Wall"
+  cxx_warning_flags="-Wall -Woverloaded-virtual"
+  if test $lf_warnings = yes
+  then
+    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
+  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..3bd19f2
--- /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 2 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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..770f062
--- /dev/null
@@ -0,0 +1,68 @@
+dnl PKG_CHECK_MODULES(GSTUFF, gtk+-2.0 >= 1.3 glib = 1.3.4, action-if, action-not)
+dnl defines GSTUFF_LIBS, GSTUFF_CFLAGS, see pkg-config man page
+dnl also defines GSTUFF_PKG_ERRORS on error
+AC_DEFUN([PKG_CHECK_MODULES], [
+  succeeded=no
+
+  if test -z "$PKG_CONFIG"; then
+    AC_PATH_PROG(PKG_CONFIG, pkg-config, no)
+  fi
+
+  if test "$PKG_CONFIG" = "no" ; then
+     echo "*** The pkg-config script could not be found. Make sure it is"
+     echo "*** in your path, or set the PKG_CONFIG environment variable"
+     echo "*** to the full path to pkg-config."
+     echo "*** Or see http://www.freedesktop.org/software/pkgconfig to get pkg-config."
+  else
+     dnl If PKG_CONFIG_PATH is not already set, add /usr/local/lib/pkgconfig.
+     dnl If it's set, assume the user knows what they're doing.
+     dnl This should help avoid failures while looking for fftw3f
+     if test -z "$PKG_CONFIG_PATH"; then
+       export PKG_CONFIG_PATH="/usr/local/lib/pkgconfig"
+     fi
+
+     PKG_CONFIG_MIN_VERSION=0.9.0
+     if $PKG_CONFIG --atleast-pkgconfig-version $PKG_CONFIG_MIN_VERSION; then
+        AC_MSG_CHECKING(for $2)
+
+        if $PKG_CONFIG --exists "$2" ; then
+            AC_MSG_RESULT(yes)
+            succeeded=yes
+
+            AC_MSG_CHECKING($1_CFLAGS)
+            $1_CFLAGS=`$PKG_CONFIG --cflags "$2"`
+            AC_MSG_RESULT($$1_CFLAGS)
+
+            AC_MSG_CHECKING($1_LIBS)
+            $1_LIBS=`$PKG_CONFIG --libs "$2"`
+            AC_MSG_RESULT($$1_LIBS)
+
+            AC_MSG_CHECKING($1_INCLUDEDIR)
+            $1_INCLUDEDIR=`$PKG_CONFIG --variable=includedir "$2"`
+            AC_MSG_RESULT($$1_INCLUDEDIR)
+        else
+            $1_CFLAGS=""
+            $1_LIBS=""
+            ## If we have a custom action on failure, don't print errors, but 
+            ## do set a variable so people can do so.
+            $1_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "$2"`
+            ifelse([$4], ,echo $$1_PKG_ERRORS,)
+        fi
+
+        AC_SUBST($1_CFLAGS)
+        AC_SUBST($1_LIBS)
+        AC_SUBST($1_INCLUDEDIR)
+     else
+        echo "*** Your version of pkg-config is too old. You need version $PKG_CONFIG_MIN_VERSION or newer."
+        echo "*** See http://www.freedesktop.org/software/pkgconfig"
+     fi
+  fi
+
+  if test $succeeded = yes; then
+     ifelse([$3], , :, [$3])
+  else
+     ifelse([$4], , AC_MSG_ERROR([Library requirements ($2) not met; consider adjusting the PKG_CONFIG_PATH environment variable if your libraries are in a nonstandard prefix so pkg-config can find them.]), [$4])
+  fi
+])
+
+
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..8ebbd7c
--- /dev/null
@@ -0,0 +1,56 @@
+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 2, 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., 59 Temple Place - Suite 330,
+dnl Boston, MA 02111-1307, USA.
+dnl 
+
+AC_DEFUN([USRP_SET_FUSB_TECHNIQUE],[
+  AC_REQUIRE([AC_CANONICAL_HOST])
+  AC_ARG_WITH(fusb-tech,
+       [  --with-fusb-tech=OS     set fast usb technique (auto)],
+               [cf_with_fusb_tech="$withval"],
+               [cf_with_fusb_tech="$host_os"])
+       
+
+  AC_CHECK_HEADER([linux/usbdevice_fs.h],
+       [x_have_usbdevice_fs_h=yes],
+       [x_have_usbdevice_fs_h=no])
+
+  AC_MSG_CHECKING([for fast usb technique to use])
+  case "$cf_with_fusb_tech" in
+    linux*)    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         ;;
+    *)         FUSB_TECH=generic       ;;
+  esac 
+
+  AC_MSG_RESULT($FUSB_TECH)
+  AC_SUBST(FUSB_TECH)
+
+  AM_CONDITIONAL(FUSB_TECH_darwin,   test $FUSB_TECH = darwin)
+  AM_CONDITIONAL(FUSB_TECH_win32,    test $FUSB_TECH = win32)
+  AM_CONDITIONAL(FUSB_TECH_generic,  test $FUSB_TECH = generic)
+  AM_CONDITIONAL(FUSB_TECH_linux,    test $FUSB_TECH = linux)
+])
+
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..b1a554e
--- /dev/null
@@ -0,0 +1,43 @@
+# Check for libusb 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 2, 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.
+
+AC_DEFUN([USRP_LIBUSB],
+[
+       AC_REQUIRE([AC_CANONICAL_HOST])
+       AC_LANG_PUSH(C)
+
+       AC_CHECK_HEADERS([usb.h],
+         [],
+         [ AC_MSG_ERROR([USRP requires libusb. usb.h not found, stop. 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" ],
+         [ AC_MSG_ERROR([USRP requires libusb. usb_bulk_write not found, stop. See http://libusb.sf.net]) ]
+       )
+        LIBS="$save_LIBS"
+
+       AC_LANG_POP
+       AC_SUBST(USB_LIBS)
+])
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..81c255a
--- /dev/null
@@ -0,0 +1,67 @@
+# 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 2, 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.
+
+AC_DEFUN([USRP_SDCC],
+[
+       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_ERROR([USRP requires sdcc. sdcc not found, stop. See http://sdcc.sf.net])
+       fi
+
+       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
+               AC_MSG_ERROR([USRP requires sdcc >= $sdcc_version_min. sdcc not found, stop. See http://sdcc.sf.net])
+       fi
+
+       AC_SUBST(XCC)
+       AC_SUBST(XAS)
+
+])
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..7790c69
--- /dev/null
@@ -0,0 +1,104 @@
+dnl 
+dnl  Copyright 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 2, 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., 59 Temple Place - Suite 330,
+dnl  Boston, MA 02111-1307, USA.
+dnl 
+
+AC_INIT
+AC_PREREQ(2.57)
+AC_CONFIG_SRCDIR([src/lib/howto.i])
+AM_CONFIG_HEADER(config.h)
+AC_CANONICAL_TARGET([])
+AM_INIT_AUTOMAKE(gr-howto-write-a-block,0.6cvs)
+
+GR_X86_64
+dnl LF_CONFIGURE_CC
+LF_CONFIGURE_CXX
+LF_SET_WARNINGS
+GR_SET_GPROF
+GR_SET_PROF
+GR_PROG_AS
+AC_PROG_LN_S
+AC_PROG_MAKE_SET
+AC_PROG_INSTALL
+
+AC_LIBTOOL_WIN32_DLL
+AC_ENABLE_SHARED       dnl do build shared libraries
+AC_DISABLE_STATIC      dnl don't build static libraries
+AC_PROG_LIBTOOL
+
+dnl Locate python, SWIG, etc
+GR_NO_UNDEFINED
+GR_SCRIPTING
+
+dnl Checks for libraries.
+
+dnl check for threads (mandatory)
+GR_OMNITHREAD
+
+CFLAGS="${CFLAGS} $PTHREAD_CFLAGS"
+CXXFLAGS="${CXXFLAGS} $PTHREAD_CFLAGS"
+
+if test "x$CXX_FOR_BUILD" = x
+then
+  CXX_FOR_BUILD=${CXX}
+fi
+AC_SUBST(CXX_FOR_BUILD)
+
+dnl Checks for header files.
+AC_HEADER_STDC
+AC_HEADER_SYS_WAIT
+AC_CHECK_HEADERS(fcntl.h limits.h strings.h sys/ioctl.h sys/time.h unistd.h)
+AC_CHECK_HEADERS(sys/mman.h)
+
+dnl Checks for typedefs, structures, and compiler characteristics.
+AC_C_CONST
+AC_C_INLINE
+AC_TYPE_SIZE_T
+AC_HEADER_TIME
+
+dnl Checks for library functions.
+AC_CHECK_FUNCS([])
+
+dnl Check for Mingw support
+GR_PWIN32
+
+PKG_CHECK_MODULES(GNURADIO_CORE, gnuradio-core >= 2)
+LIBS="$LIBS $GNURADIO_CORE_LIBS"
+
+dnl Define where to find boost includes
+dnl defines BOOST_CFLAGS
+GR_REQUIRE_BOOST_INCLUDES
+
+STD_DEFINES_AND_INCLUDES="$GNURADIO_CORE_CFLAGS $BOOST_CFLAGS"
+AC_SUBST(STD_DEFINES_AND_INCLUDES)
+AC_CONFIG_FILES([\
+         Makefile \
+         config/Makefile \
+         doc/Makefile \
+         src/Makefile \
+         src/lib/Makefile \
+         src/python/Makefile \
+         src/python/run_tests \
+       ])
+
+dnl run_tests is created from run_tests.in.  Make it executable.
+AC_CONFIG_COMMANDS([run_tests], [chmod +x src/python/run_tests])
+
+AC_OUTPUT
diff --git a/gr-howto-write-a-block/doc/Makefile.am b/gr-howto-write-a-block/doc/Makefile.am
new file mode 100644 (file)
index 0000000..3326914
--- /dev/null
@@ -0,0 +1,81 @@
+#
+# 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 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.
+# 
+
+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 =                           \
+       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
+       ./make_numbered_listing.py $<
+
+howto_square_ff.cc.xml: $(top_srcdir)/src/lib/howto_square_ff.cc make_numbered_listing.py
+       ./make_numbered_listing.py $<
+
+howto_square_ff.h.xml: $(top_srcdir)/src/lib/howto_square_ff.h make_numbered_listing.py
+       ./make_numbered_listing.py $<
+
+howto_square2_ff.cc.xml: $(top_srcdir)/src/lib/howto_square2_ff.cc make_numbered_listing.py
+       ./make_numbered_listing.py $<
+
+howto_square2_ff.h.xml: $(top_srcdir)/src/lib/howto_square2_ff.h make_numbered_listing.py
+       ./make_numbered_listing.py $<
+
+
+# ----------------------------------------------------------------
+
+clean:
+       -rm -f $(TARGETS) $(BUILT_XML_FILES)
+
+%.html : %.xml
+       xmlto html-nochunks $<
+
+%.xml : % make_numbered_listing.py
+       ./make_numbered_listing.py $<
diff --git a/gr-howto-write-a-block/doc/howto-write-a-block.xml b/gr-howto-write-a-block/doc/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/gr-howto-write-a-block/doc/howto_1.i b/gr-howto-write-a-block/doc/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/gr-howto-write-a-block/doc/make_numbered_listing.py b/gr-howto-write-a-block/doc/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/gr-howto-write-a-block/doc/qa_howto_1.py b/gr-howto-write-a-block/doc/qa_howto_1.py
new file mode 100755 (executable)
index 0000000..aa84908
--- /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.fg = gr.flow_graph ()
+
+    def tearDown (self):
+        self.fg = 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.fg.connect (src, sqr)
+        self.fg.connect (sqr, dst)
+        self.fg.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/doc/src_lib_Makefile_1.am b/gr-howto-write-a-block/doc/src_lib_Makefile_1.am
new file mode 100644 (file)
index 0000000..846dd7c
--- /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)
+
+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/gr-howto-write-a-block/doc/src_lib_Makefile_2.am b/gr-howto-write-a-block/doc/src_lib_Makefile_2.am
new file mode 100644 (file)
index 0000000..a02b40c
--- /dev/null
@@ -0,0 +1,86 @@
+#
+# 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.
+# 
+
+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)
+
+SWIGCPPPYTHONARGS = -noruntime -c++ -python $(PYTHON_CPPFLAGS) \
+       -I$(swigincludedir) -I$(grincludedir)
+
+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/gr-howto-write-a-block/src/Makefile.am b/gr-howto-write-a-block/src/Makefile.am
new file mode 100644 (file)
index 0000000..122fc72
--- /dev/null
@@ -0,0 +1,22 @@
+#
+# 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.
+# 
+
+SUBDIRS = lib python
diff --git a/gr-howto-write-a-block/src/lib/Makefile.am b/gr-howto-write-a-block/src/lib/Makefile.am
new file mode 100644 (file)
index 0000000..d4c9d35
--- /dev/null
@@ -0,0 +1,94 @@
+#
+# Copyright 2004,2005,2006 Free Software Foundation, Inc.
+# 
+# This file is part of GNU Radio
+# 
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 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.
+# 
+
+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)
+
+SWIGPYTHONARGS = $(SWIGPYTHONFLAGS) $(SWIGGRFLAGS)
+
+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              \
+       howto_square2_ff.cc             
+
+# magic flags
+_howto_la_LDFLAGS = $(NO_UNDEFINED) -module -avoid-version
+
+# link the library against some comon swig runtime code and the 
+# c++ standard library
+_howto_la_LIBADD =                     \
+       $(PYTHON_LDFLAGS)               \
+       -lstdc++                        
+
+howto.cc howto.py: howto.i $(ALL_IFILES)
+       $(SWIG) $(SWIGPYTHONARGS) -module howto -o howto.cc $<
+
+# These headers get installed in ${prefix}/include/gnuradio
+grinclude_HEADERS =                    \
+       howto_square_ff.h               \
+       howto_square2_ff.h              
+
+
+# These swig headers get installed in ${prefix}/include/gnuradio/swig
+swiginclude_HEADERS =                  \
+       $(LOCAL_IFILES)
+
+
+MOSTLYCLEANFILES = $(BUILT_SOURCES) *.pyc
+
+# Don't distribute output of swig
+dist-hook:
+       @for file in $(BUILT_SOURCES); do echo $(RM) $(distdir)/$$file; done
+       @for file in $(BUILT_SOURCES); do $(RM) $(distdir)/$$file; done
diff --git a/gr-howto-write-a-block/src/lib/howto.i b/gr-howto-write-a-block/src/lib/howto.i
new file mode 100644 (file)
index 0000000..3d46ab4
--- /dev/null
@@ -0,0 +1,44 @@
+/* -*- c++ -*- */
+
+%feature("autodoc", "1");              // generate python docstrings
+
+%include "exception.i"
+%import "gnuradio.i"                   // the common stuff
+
+%{
+#include "gnuradio_swig_bug_workaround.h"      // mandatory bug fix
+#include "howto_square_ff.h"
+#include "howto_square2_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 ();
+};
+
+// ----------------------------------------------------------------
+
+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/src/lib/howto_square2_ff.cc b/gr-howto-write-a-block/src/lib/howto_square2_ff.cc
new file mode 100644 (file)
index 0000000..c6a5227
--- /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 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.
+ */
+
+/*
+ * 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/src/lib/howto_square2_ff.h b/gr-howto-write-a-block/src/lib/howto_square2_ff.h
new file mode 100644 (file)
index 0000000..2d5af20
--- /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 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.
+ */
+#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/src/lib/howto_square_ff.cc b/gr-howto-write-a-block/src/lib/howto_square_ff.cc
new file mode 100644 (file)
index 0000000..a580abc
--- /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 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.
+ */
+
+/*
+ * 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/src/lib/howto_square_ff.h b/gr-howto-write-a-block/src/lib/howto_square_ff.h
new file mode 100644 (file)
index 0000000..e370929
--- /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 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.
+ */
+#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/src/python/Makefile.am b/gr-howto-write-a-block/src/python/Makefile.am
new file mode 100644 (file)
index 0000000..c06f34e
--- /dev/null
@@ -0,0 +1,32 @@
+#
+# 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.
+# 
+
+include $(top_srcdir)/Makefile.common
+
+EXTRA_DIST = run_tests.in
+
+
+TESTS =                                \
+       run_tests
+
+
+noinst_PYTHON =                        \
+       qa_howto.py                     
diff --git a/gr-howto-write-a-block/src/python/qa_howto.py b/gr-howto-write-a-block/src/python/qa_howto.py
new file mode 100755 (executable)
index 0000000..7d96d31
--- /dev/null
@@ -0,0 +1,59 @@
+#!/usr/bin/env 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.
+# 
+
+from gnuradio import gr, gr_unittest
+import howto
+
+class qa_howto (gr_unittest.TestCase):
+
+    def setUp (self):
+        self.fg = gr.flow_graph ()
+
+    def tearDown (self):
+        self.fg = 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.fg.connect (src, sqr)
+        self.fg.connect (sqr, dst)
+        self.fg.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.square2_ff ()
+        dst = gr.vector_sink_f ()
+        self.fg.connect (src, sqr)
+        self.fg.connect (sqr, dst)
+        self.fg.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/src/python/run_tests.in b/gr-howto-write-a-block/src/python/run_tests.in
new file mode 100644 (file)
index 0000000..6e4b83e
--- /dev/null
@@ -0,0 +1,50 @@
+#!/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@/src/lib
+# Where to look in the src tree for swig generated python code
+libsrc=@abs_top_srcdir@/src/lib
+# Where to look in the src tree for hand written python code
+py=@abs_top_srcdir@/src/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:$libsrc:$py:$installed_pythondir:$installed_pyexecdir:$PYTHONPATH"
+#PYTHONPATH="$libbld:$libbld/.libs:$libsrc:$py:$installed_pythondir:$installed_pyexecdir"
+
+export PYTHONPATH
+
+#
+# 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-radar/AUTHORS b/gr-radar/AUTHORS
new file mode 100644 (file)
index 0000000..ee4560a
--- /dev/null
@@ -0,0 +1 @@
+Eric Blossom <eb@comsec.com>
diff --git a/gr-radar/ChangeLog b/gr-radar/ChangeLog
new file mode 100644 (file)
index 0000000..dde8414
--- /dev/null
@@ -0,0 +1,20 @@
+#
+# 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 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.
+# 
diff --git a/gr-radar/Makefile.am b/gr-radar/Makefile.am
new file mode 100644 (file)
index 0000000..9e88fe1
--- /dev/null
@@ -0,0 +1,25 @@
+#
+# 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 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.
+# 
+
+include $(top_srcdir)/Makefile.common
+
+SUBDIRS = src doc
+DIST_SUBDIRS = src doc
diff --git a/gr-radar/doc/Makefile.am b/gr-radar/doc/Makefile.am
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/gr-radar/src/Makefile.am b/gr-radar/src/Makefile.am
new file mode 100644 (file)
index 0000000..122fc72
--- /dev/null
@@ -0,0 +1,22 @@
+#
+# 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.
+# 
+
+SUBDIRS = lib python
diff --git a/gr-radar/src/lib/Makefile.am b/gr-radar/src/lib/Makefile.am
new file mode 100644 (file)
index 0000000..8ea52aa
--- /dev/null
@@ -0,0 +1,118 @@
+#
+# 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 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.
+# 
+
+include $(top_srcdir)/Makefile.common
+
+LIBS += $(GNURADIO_CORE_LIBS)
+
+# Install this stuff so that it ends up as the gnuradio.radar 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)
+
+SWIGPYTHONARGS = $(SWIGPYTHONFLAGS) $(STD_DEFINES_AND_INCLUDES)
+
+ALL_IFILES =                           \
+       $(LOCAL_IFILES)                 \
+       $(NON_LOCAL_IFILES)             
+
+NON_LOCAL_IFILES =                     \
+       $(top_srcdr)/gnuradio-core/src/lib/swig/gnuradio.i
+
+
+LOCAL_IFILES =                                 
+
+
+# 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 =                        
+
+lib_LTLIBRARIES = libradar.la
+
+libradar_la_SOURCES =                  \
+       time_series.h                   \
+       time_series.cc                  \
+       simulation.h                    \
+       simulation.cc                   
+
+bin_PROGRAMS =                                 \
+       xambi                           \
+       eb-xambi                        \
+       sim-airplane                    \
+       sim-airplane2                   
+
+xambi_SOURCES  = xambi.cc
+xambi_LDADD    = libradar.la
+
+eb_xambi_SOURCES = eb-xambi.cc
+eb_xambi_LDADD  = libradar.la
+
+sim_airplane_SOURCES = sim-airplane.cc
+sim_airplane_LDADD = libradar.la
+
+sim_airplane2_SOURCES = sim-airplane2.cc
+sim_airplane2_LDADD = libradar.la
+
+# This gets howto.py installed in the right place
+# ourpython_PYTHON =                   
+
+#ourlib_LTLIBRARIES = _howto.la
+
+# These are the source files that go into the shared library
+#_howto_la_SOURCES =                   \
+#      howto.cc                        \
+#      howto_square_ff.cc              \
+#      howto_square2_ff.cc             
+
+# magic flags
+#_howto_la_LDFLAGS = $(NO_UNDEFINED) -module -avoid-version
+
+# link the library against some comon swig runtime code and the 
+# c++ standard library
+#_howto_la_LIBADD =                    \
+#      $(PYTHON_LDFLAGS)               \
+#      -lstdc++                        
+
+#howto.cc howto.py: howto.i $(ALL_IFILES)
+#      $(SWIG) $(SWIGPYTHONARGS) -module howto -o howto.cc $<
+
+# These headers get installed in ${prefix}/include/gnuradio
+grinclude_HEADERS =                    
+
+
+# These swig headers get installed in ${prefix}/include/gnuradio/swig
+swiginclude_HEADERS =                  \
+       $(LOCAL_IFILES)
+
+
+MOSTLYCLEANFILES = $(BUILT_SOURCES) *.pyc
+
+
+# Don't distribute output of swig
+dist-hook:
+       @for file in $(BUILT_SOURCES); do echo $(RM) $(distdir)/$$file; done
+       @for file in $(BUILT_SOURCES); do $(RM) $(distdir)/$$file; done
diff --git a/gr-radar/src/lib/eb-xambi.cc b/gr-radar/src/lib/eb-xambi.cc
new file mode 100644 (file)
index 0000000..c3c0195
--- /dev/null
@@ -0,0 +1,291 @@
+/* -*- 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 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.
+ */
+
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+
+#include <iostream>
+#include <string>
+#include <fstream>
+#include <unistd.h>
+#include <stdlib.h>
+#include <getopt.h>
+#include <boost/scoped_array.hpp>
+#include <gr_complex.h>
+#include <gr_fxpt_nco.h>
+#include "time_series.h"
+
+
+gr_complex
+complex_conj_dotprod(const gr_complex *a, const gr_complex *b, unsigned n)
+{
+  gr_complex acc = 0;
+  for (unsigned i = 0; i < n; i++)
+    acc += a[i] * conj(b[i]);
+
+  return acc;
+}
+
+/*!
+ * \brief frequency translate src by normalized_freq
+ *
+ * \param dst                  destination
+ * \param src                  source
+ * \param n                    length of src and dst in samples
+ * \param normalized_freq      [-1/2, +1/2]
+ */
+void
+freq_xlate(gr_complex *dst, const gr_complex *src, unsigned n, float normalized_freq)
+{
+  gr_fxpt_nco  nco;
+  nco.set_freq(2 * M_PI * normalized_freq);
+
+  for (unsigned int i = 0; i < n; i++){
+    gr_complex phasor(nco.cos(), nco.sin());
+    dst[i] = src[i] * phasor;
+    nco.step();
+  }
+}
+
+inline void
+write_float(FILE *output, float x)
+{
+  fwrite(&x, sizeof(x), 1, output);
+}
+
+
+// write 8-float header
+static void
+write_header (FILE *output, float ndoppler_bins, float min_doppler, float max_doppler)
+{
+  write_float(output, ndoppler_bins);
+  write_float(output, min_doppler);
+  write_float(output, max_doppler);
+  write_float(output, 0);
+  write_float(output, 0);
+  write_float(output, 0);
+  write_float(output, 0);
+  write_float(output, 0);
+}
+
+
+void
+main_loop(FILE *output, time_series &ref_ts, time_series &scat0_ts,
+         unsigned nranges, unsigned correlation_window_size,
+         float min_doppler, float max_doppler, int ndoppler_bins)
+{
+  fprintf(stderr, "ndoppler_bins = %10d\n", ndoppler_bins);
+  fprintf(stderr, "min_doppler   = %10f\n", min_doppler);
+  fprintf(stderr, "max_doppler   = %10f\n", max_doppler);
+
+  // float scale_factor = 1.0/correlation_window_size; // FIXME, not sure this is right
+  float scale_factor = 1.0;                            // FIXME, not sure this is right
+
+  boost::scoped_array<gr_complex>  shifted(new gr_complex[correlation_window_size]);
+
+  // gr_complex shifted[correlation_window_size];              // doppler shifted reference
+
+  float doppler_incr = 0;
+  if (ndoppler_bins == 1){
+    min_doppler = 0;
+    max_doppler = 0;
+  }
+  else
+    doppler_incr = (max_doppler - min_doppler) / (ndoppler_bins - 1);
+
+  write_header(output, ndoppler_bins, min_doppler, max_doppler);
+
+  unsigned long long ro = 0;   // reference offset
+  unsigned long long so = 0;   // scatter offset
+
+  for (unsigned int n = 0; n < nranges; n++){
+    if (0){
+      fprintf(stdout, "n =  %6d\n", n);
+      fprintf(stdout, "ro = %6lld\n", ro);
+      fprintf(stdout, "so = %6lld\n", so);
+    }
+    const gr_complex *ref = (const gr_complex *) ref_ts.seek(ro, correlation_window_size);
+    const gr_complex *scat0 = (const gr_complex *) scat0_ts.seek(so, correlation_window_size);
+    if (ref == 0 || scat0 == 0)
+      return;
+
+    for (int nd = 0; nd < ndoppler_bins; nd++){
+      float fdop = min_doppler + doppler_incr * nd;
+      //fprintf(stderr, "fdop = %10g\n", fdop);
+      freq_xlate(&shifted[0], ref, correlation_window_size, fdop);     // generated doppler shifted reference
+
+      gr_complex ccor = complex_conj_dotprod(&shifted[0], scat0, correlation_window_size);
+      float out = norm(ccor) * scale_factor;
+
+      // fprintf(output, "%12g\n", out);
+      write_float(output, out);
+    }
+
+    so += 1;
+  }
+}
+
+static void
+usage(const char *argv0)
+{
+  const char *progname;
+  const char *t = std::strrchr(argv0, '/');
+  if (t != 0)
+    progname = t + 1;
+  else
+    progname = argv0;
+    
+  fprintf(stderr, "usage: %s [options] ref_file scatter_file\n", progname);
+  fprintf(stderr, "    -o OUTPUT_FILENAME [default=eb-xambi.out]\n");
+  fprintf(stderr, "    -m MIN_RANGE [default=0]\n");
+  fprintf(stderr, "    -M MAX_RANGE [default=300]\n");
+  fprintf(stderr, "    -w CORRELATION_WINDOW_SIZE [default=2500]\n");
+  fprintf(stderr, "    -s NSAMPLES_TO_SKIP [default=0]\n");
+  fprintf(stderr, "    -d max_doppler (normalized: [0, +1/2)) [default=.0012]\n");
+  fprintf(stderr, "    -n ndoppler_bins [default=31]\n");
+}
+
+int
+main(int argc, char **argv)
+{
+  int  ch;
+  int min_range =    0;
+  int max_range =  300;
+  const char *ref_filename = 0;
+  const char *scatter_filename = 0;
+  const char *output_filename = "eb-xambi.out";
+  unsigned int correlation_window_size = 2500;
+  long long int nsamples_to_skip = 0;
+  double max_doppler = 0.0012;
+  int ndoppler_bins = 31;
+
+
+  while ((ch = getopt(argc, argv, "m:M:ho:w:s:d:n:")) != -1){
+    switch (ch){
+    case 'm':
+      min_range = strtol(optarg, 0, 0);
+      break;
+
+    case 'M':
+      max_range = strtol(optarg, 0, 0);
+      break;
+
+    case 'w':
+      correlation_window_size = strtol(optarg, 0, 0);
+      if (correlation_window_size <= 1){
+       usage(argv[0]);
+       fprintf(stderr, "    correlation_window_size must be >= 1\n");
+       exit(1);
+      }
+      break;
+
+    case 'o':
+      output_filename = optarg;
+      break;
+      
+    case 's':
+      nsamples_to_skip = (long long) strtof(optarg, 0);
+      if (nsamples_to_skip < 0){
+       usage(argv[0]);
+       fprintf(stderr, "    nsamples_to_skip must be >= 0\n");
+       exit(1);
+      }
+      break;
+
+    case 'd':
+      max_doppler = strtof(optarg, 0);
+      if (max_doppler < 0 || max_doppler >= 0.5){
+       usage(argv[0]);
+       fprintf(stderr, "    max_doppler must be in [0, 0.5)\n");
+       exit(1);
+      }
+      break;
+
+    case 'n':
+      ndoppler_bins = strtol(optarg, 0, 0);
+      if (ndoppler_bins < 1){
+       usage(argv[0]);
+       fprintf(stderr, "    ndoppler_bins must >= 1\n");
+       exit(1);
+      }
+      break;
+
+    case '?':
+    case 'h':
+    default:
+      usage(argv[0]);
+      exit(1);
+    }
+  } // while getopt
+
+  if (argc - optind != 2){
+    usage(argv[0]);
+    exit(1);
+  }
+
+  if (max_range < min_range){
+    usage(argv[0]);
+    fprintf(stderr, "    max_range must be >= min_range\n");
+    exit(1);
+  }
+  unsigned int nranges = max_range - min_range + 1;
+
+  ref_filename = argv[optind++];
+  scatter_filename = argv[optind++];
+
+  FILE *output = fopen(output_filename, "wb");
+  if (output == 0){
+    perror(output_filename);
+    exit(1);
+  }
+
+  unsigned long long ref_starting_offset = 0;
+  unsigned long long scatter_starting_offset = 0;
+
+  if (min_range < 0){
+    ref_starting_offset = -min_range;
+    scatter_starting_offset = 0;
+  }
+  else {
+    ref_starting_offset = 0;
+    scatter_starting_offset = min_range;
+  }
+
+  ref_starting_offset += nsamples_to_skip;
+  scatter_starting_offset += nsamples_to_skip;
+
+  try {
+    time_series ref(sizeof(gr_complex), ref_filename, ref_starting_offset, 0);
+    time_series scat0(sizeof(gr_complex), scatter_filename, scatter_starting_offset, 0);
+
+    main_loop(output, ref, scat0, nranges, correlation_window_size,
+             -max_doppler, max_doppler, ndoppler_bins);
+  }
+  catch (std::string &s){
+    std::cerr << s << std::endl;
+    exit(1);
+  }
+
+  return 0;
+}
+
diff --git a/gr-radar/src/lib/gen_run b/gr-radar/src/lib/gen_run
new file mode 100755 (executable)
index 0000000..8b9549e
--- /dev/null
@@ -0,0 +1,26 @@
+#!/usr/bin/env python
+
+import sys
+
+def main():
+    window = 25000
+    #window = 250000
+    max_range = 99
+    gifs = []
+    for t in range(0, 241, 5):
+        sim_fn  = "sim.%04d" % (t,)
+        xref_fn = "xref.%04d" % (t,)
+        ppm_fn  = "i.%04d.ppm" % (t,)
+        gif_fn  = "i.%04d.gif" % (t,)
+        gifs.append(gif_fn)
+        
+        sys.stdout.write("./sim-airplane2 rfm -o %s -S %d\n" % (sim_fn, t))
+        sys.stdout.write("./eb-xambi -o %s -M %d -w %d -d 0.0002 rfm %s\n" % (
+            xref_fn, max_range, window, sim_fn))
+        sys.stdout.write("./plot_xambi_tool.m %s %s\n" % (xref_fn, ppm_fn))
+        sys.stdout.write("convert -resize 800%% %s %s\n" % (ppm_fn, gif_fn))
+
+    sys.stdout.write("gifsicle -d 50 %s >animated.gif\n" % (' '.join(gifs)))
+
+if __name__ == '__main__':
+    main()
diff --git a/gr-radar/src/lib/plot_rd.m b/gr-radar/src/lib/plot_rd.m
new file mode 100644 (file)
index 0000000..166da02
--- /dev/null
@@ -0,0 +1,38 @@
+filename="xambi.out"
+
+ambdata=read_float_binary(filename);
+
+fftsize=512
+nranges = prod(size(ambdata))/fftsize
+
+ambdata=reshape(ambdata,fftsize,nranges);
+% ambdata=fftshift(ambdata,1);
+
+% colormap(cool(256));
+colormap(rainbow(256));
+
+d = 10*log10(ambdata);
+min(min(d))
+max(max(d))
+imagesc(d, 2.0);
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/gr-radar/src/lib/plot_xambi.m b/gr-radar/src/lib/plot_xambi.m
new file mode 100755 (executable)
index 0000000..6208859
--- /dev/null
@@ -0,0 +1,15 @@
+function plot_xambi(amb)
+  [nr, nc] = size(amb);
+  ndoppler_bins = nr
+  nranges = nc
+
+  %colormap(cool(256));
+  %colormap(rainbow(256));
+  colormap(gray(1024));
+
+  %d = 10*log10(amb);
+  d = amb;
+  min(min(d))
+  max(max(d))
+  imagesc(d, 4.0);
+endfunction;
diff --git a/gr-radar/src/lib/plot_xambi_to_file.m b/gr-radar/src/lib/plot_xambi_to_file.m
new file mode 100755 (executable)
index 0000000..973d112
--- /dev/null
@@ -0,0 +1,17 @@
+function plot_xambi_to_file(amb, filename)
+  [nr, nc] = size(amb);
+  ndoppler_bins = nr
+  nranges = nc
+
+  %colormap(cool(256));
+  %colormap(rainbow(256));
+  colormap(gray(1024));
+
+  %d = 10*log10(amb);
+  d = amb;
+  min(min(d))
+  max(max(d))
+  b = imagesc(d, 4.0);
+  saveimage(filename, b, "ppm")
+
+endfunction;
diff --git a/gr-radar/src/lib/plot_xambi_tool.m b/gr-radar/src/lib/plot_xambi_tool.m
new file mode 100755 (executable)
index 0000000..508db28
--- /dev/null
@@ -0,0 +1,8 @@
+#!/usr/bin/env octave
+
+xambi_filename = argv{1};
+ppm_filename = argv{2};
+
+a = read_xambi(xambi_filename);
+plot_xambi_to_file(a, ppm_filename);
+
diff --git a/gr-radar/src/lib/sim-airplane.cc b/gr-radar/src/lib/sim-airplane.cc
new file mode 100644 (file)
index 0000000..9b27ff0
--- /dev/null
@@ -0,0 +1,296 @@
+/* -*- 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 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.
+ */
+
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+
+#include <iostream>
+#include <string>
+#include <fstream>
+#include <unistd.h>
+#include <stdlib.h>
+#include <gr_complex.h>
+#include <getopt.h>
+#include <gr_misc.h>
+#include <limits>
+#include <gr_fxpt_nco.h>
+#include "time_series.h"
+#include "simulation.h"
+
+static const double C = 3e8;   // sped of light, m/s
+
+
+// ------------------------------------------------------------------------
+
+class delay_line {
+  std::vector<gr_complex>      d_z;
+  const int                    d_mask;
+  int                          d_newest;
+public:
+  delay_line(unsigned int max_delay)
+    : d_z(gr_rounduppow2(max_delay)), d_mask(d_z.size()-1), d_newest(0)
+  {
+  }
+
+  void
+  push_item(gr_complex x)
+  {
+    d_newest = (d_newest - 1) & d_mask;
+    d_z[d_newest] = x;
+  }
+
+  gr_complex
+  ref_item(int delay) const 
+  {
+    return d_z[(d_newest + delay) & d_mask];
+  }
+};
+
+// ------------------------------------------------------------------------
+
+class my_sim : public simulation
+{
+  FILE                 *d_output;
+  time_series          &d_ref;
+  unsigned long long    d_pos;         // position in time series
+  delay_line            d_z;
+  dyn_object           *d_tx;          // transmitter (not moving)
+  dyn_object           *d_rx0;         // receiver (not moving)
+  dyn_object           *d_ac0;         // aircraft (linear motion)
+  gr_fxpt_nco           d_nco0;
+
+  double               d_baseline;             // length of baseline in meters
+  double               d_last_slant_range;
+  double               d_range_bin;            // meters/range_bin
+  float                        d_tx_lambda;            // wavelength of tx signals in meters
+  float                        d_sample_rate;
+  float                        d_gain;                 // linear scale factor
+
+public:
+  my_sim(FILE *output, time_series &ref, double timestep, float sample_rate,
+        double tx_freq, double gain_db);
+  ~my_sim();
+
+  bool update();
+  bool run(long long nsteps);
+
+  bool write_output(gr_complex x)
+  {
+    return fwrite(&x, sizeof(x), 1, d_output) == 1;
+  }
+};
+
+my_sim::my_sim(FILE *output, time_series &ref, double timestep,
+              float sample_rate, double tx_freq, double gain_db)
+  : simulation(timestep),
+    d_output(output), d_ref(ref), d_pos(0), d_z(1024),
+    d_range_bin(C * timestep), d_tx_lambda(C/tx_freq), 
+    d_sample_rate(sample_rate), d_gain(exp10(gain_db/10))
+{
+  d_tx = new dyn_object(point(0,0), point(0,0), "Tx");
+  d_rx0 = new dyn_object(point(45e3,0), point(0,0), "Rx0");
+
+  //float aircraft_speed =  135;         // meters/sec (~ 300 miles/hr)
+  float aircraft_speed =  350;         // meters/sec (~ 750 miles/hr)
+  float aircraft_angle =  250 * M_PI/180;
+  //point aircraft_pos = point(55e3, 20e3);
+  point aircraft_pos = point(55e3-5.54e3, 20e3-15.23e3);
+  d_ac0 = new dyn_object(aircraft_pos,
+                        point(aircraft_speed * cos(aircraft_angle),
+                              aircraft_speed * sin(aircraft_angle)),
+                        "Ac0");
+  add_object(d_tx);
+  add_object(d_rx0);
+  add_object(d_ac0);
+
+  d_baseline = dyn_object::distance(*d_tx, *d_rx0);
+  d_last_slant_range =
+    dyn_object::distance(*d_tx, *d_ac0) + dyn_object::distance(*d_ac0, *d_rx0);  
+}
+
+my_sim::~my_sim()
+{
+}
+
+bool
+my_sim::update()
+{
+  // std::cout << *d_ac0 << std::endl;
+
+  // compute slant_range and slant_range'
+  double slant_range =
+    dyn_object::distance(*d_tx, *d_ac0) + dyn_object::distance(*d_ac0, *d_rx0);        // meters
+  double delta_slant_range = slant_range - d_last_slant_range;
+  d_last_slant_range = slant_range;
+  double deriv_slant_range_wrt_time = delta_slant_range / timestep();          // m/sec
+
+  // fprintf(stdout, "%10.3f\t%10.3f\n", slant_range, deriv_slant_range_wrt_time);
+
+  // grab new item from input and insert it into delay line
+  const gr_complex *in = (const gr_complex *) d_ref.seek(d_pos++, 1);
+  if (in == 0)
+    return false;
+  d_z.push_item(*in);
+
+  // FIXME, may want to interpolate between two bins.
+  int int_delay = lrint((slant_range - d_baseline) / d_range_bin);
+
+  gr_complex x = d_z.ref_item(int_delay);
+
+  x = x * d_gain;              // scale amplitude (this includes everything: RCS, antenna gain, losses, etc...)
+
+  // compute doppler and apply it
+  float f_doppler = -deriv_slant_range_wrt_time / d_tx_lambda;
+  fprintf(stdout, "f_dop: %10.3f\n", f_doppler);
+
+  d_nco0.set_freq(f_doppler / d_sample_rate);
+  gr_complex phasor(d_nco0.cos(), d_nco0.sin());
+  // x = x * phasor;
+  d_nco0.step();
+
+  write_output(x);
+
+  return simulation::update();         // run generic update
+}
+
+bool
+my_sim::run(long long nsteps)
+{
+  //fprintf(stdout, "<%12.2f, %12.2f>\n", d_ac0->pos().x(), d_ac0->pos().y());
+  //std::cout << *d_ac0 << std::endl;
+  bool ok = simulation::run(nsteps);
+  //std::cout << *d_ac0 << std::endl;
+  //fprintf(stdout, "<%12.2f, %12.2f>\n", d_ac0->pos().x(), d_ac0->pos().y());
+  return ok;
+}
+
+// ------------------------------------------------------------------------
+
+static void
+usage(const char *argv0)
+{
+  const char *progname;
+  const char *t = std::strrchr(argv0, '/');
+  if (t != 0)
+    progname = t + 1;
+  else
+    progname = argv0;
+    
+  fprintf(stderr, "usage: %s [options] ref_file\n", progname);
+  fprintf(stderr, "    -o OUTPUT_FILENAME [default=sim.dat]\n");
+  fprintf(stderr, "    -n NSAMPLES_TO_PRODUCE [default=+inf]\n");
+  fprintf(stderr, "    -s NSAMPLES_TO_SKIP [default=0]\n");
+  fprintf(stderr, "    -g reflection gain in dB (should be <= 0) [default=0]\n");
+  fprintf(stderr, "    -f transmitter freq in Hz [default=100MHz]\n");
+  fprintf(stderr, "    -r sample rate in Hz [default=250kHz]\n");
+}
+
+int
+main(int argc, char **argv)
+{
+  int  ch;
+  const char *output_filename = "sim.dat";
+  const char *ref_filename = 0;
+  long long int nsamples_to_skip = 0;
+  long long int nsamples_to_produce = std::numeric_limits<long long int>::max();
+  double sample_rate = 250e3;
+  double gain_db = 0;
+  double tx_freq = 100e6;
+
+  while ((ch = getopt(argc, argv, "o:s:n:g:f:")) != -1){
+    switch (ch){
+    case 'o':
+      output_filename = optarg;
+      break;
+      
+    case 's':
+      nsamples_to_skip = (long long) strtof(optarg, 0);
+      if (nsamples_to_skip < 0){
+       usage(argv[0]);
+       fprintf(stderr, "    nsamples_to_skip must be >= 0\n");
+       exit(1);
+      }
+      break;
+
+    case 'n':
+      nsamples_to_produce = (long long) strtof(optarg, 0);
+      if (nsamples_to_produce < 0){
+       usage(argv[0]);
+       fprintf(stderr, "    nsamples_to_produce must be >= 0\n");
+       exit(1);
+      }
+      break;
+
+    case 'g':
+      gain_db = strtof(optarg, 0);
+      break;
+
+    case 'f':
+      tx_freq = strtof(optarg, 0);
+      break;
+
+    case 'r':
+      sample_rate = strtof(optarg, 0);
+      break;
+
+    case '?':
+    case 'h':
+    default:
+      usage(argv[0]);
+      exit(1);
+    }
+  } // while getopt
+
+  if (argc - optind != 1){
+    usage(argv[0]);
+    exit(1);
+  }
+
+  ref_filename = argv[optind++];
+
+  double timestep = 1.0/sample_rate;
+
+
+  FILE *output = fopen(output_filename, "wb");
+  if (output == 0){
+    perror(output_filename);
+    exit(1);
+  }
+
+  unsigned long long ref_starting_offset = 0;
+  ref_starting_offset += nsamples_to_skip;
+
+  try {
+    time_series ref(sizeof(gr_complex), ref_filename, ref_starting_offset, 0);
+
+    my_sim     simulator(output, ref, timestep, sample_rate, tx_freq, gain_db);
+    simulator.run(nsamples_to_produce);
+  }
+  catch (std::string &s){
+    std::cerr << s << std::endl;
+    exit(1);
+  }
+
+  return 0;
+}
+
diff --git a/gr-radar/src/lib/sim-airplane2.cc b/gr-radar/src/lib/sim-airplane2.cc
new file mode 100644 (file)
index 0000000..a8948a7
--- /dev/null
@@ -0,0 +1,372 @@
+/* -*- 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 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.
+ */
+
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+
+#include <iostream>
+#include <string>
+#include <fstream>
+#include <unistd.h>
+#include <stdlib.h>
+#include <gr_complex.h>
+#include <getopt.h>
+#include <gr_misc.h>
+#include <limits>
+#include <gr_fxpt_nco.h>
+#include "time_series.h"
+#include "simulation.h"
+
+static const double C = 3e8;   // sped of light, m/s
+
+
+// ------------------------------------------------------------------------
+
+class delay_line {
+  std::vector<gr_complex>      d_z;
+  const int                    d_mask;
+  int                          d_newest;
+public:
+  delay_line(unsigned int max_delay)
+    : d_z(gr_rounduppow2(max_delay)), d_mask(d_z.size()-1), d_newest(0)
+  {
+  }
+
+  void
+  push_item(gr_complex x)
+  {
+    d_newest = (d_newest - 1) & d_mask;
+    d_z[d_newest] = x;
+  }
+
+  gr_complex
+  ref_item(int delay) const 
+  {
+    return d_z[(d_newest + delay) & d_mask];
+  }
+};
+
+// ------------------------------------------------------------------------
+
+class aux_state {
+public:
+  dyn_object   *d_obj;
+  double        d_last_slant_range;
+  gr_fxpt_nco   d_nco;
+
+  aux_state(dyn_object *obj) : d_obj(obj) {}
+};
+
+// ------------------------------------------------------------------------
+
+class my_sim : public simulation
+{
+  FILE                  *d_output;
+  time_series           &d_ref;
+  unsigned long long     d_pos;                // position in time series
+  delay_line             d_z;
+  dyn_object            *d_tx;         // transmitter (not moving)
+  dyn_object            *d_rx0;                // receiver (not moving)
+  std::vector<aux_state*> d_target;
+
+  double                 d_baseline;           // length of baseline in meters
+  double                 d_range_bin;          // meters/range_bin
+  float                          d_tx_lambda;          // wavelength of tx signals in meters
+  float                          d_sample_rate;
+  float                          d_gain;               // linear scale factor
+
+  void adjust_for_start_time(double start_time);
+  
+  bool write_output(gr_complex x)
+  {
+    return fwrite(&x, sizeof(x), 1, d_output) == 1;
+  }
+
+public:
+  my_sim(FILE *output, time_series &ref, double timestep, float sample_rate,
+        double start_time, double tx_freq, double gain_db);
+  ~my_sim();
+
+  bool update();
+  bool run(long long nsteps);
+};
+
+
+my_sim::my_sim(FILE *output, time_series &ref, double timestep,
+              float sample_rate, double start_time,
+              double tx_freq, double gain_db)
+  : simulation(timestep),
+    d_output(output), d_ref(ref), d_pos(0), d_z(1024),
+    d_range_bin(C * timestep), d_tx_lambda(C/tx_freq), 
+    d_sample_rate(sample_rate), d_gain(exp10(gain_db/10))
+{
+  d_tx = new dyn_object(point(0,0), point(0,0), "Tx");
+  d_rx0 = new dyn_object(point(45e3,0), point(0,0), "Rx0");
+
+  add_object(d_tx);
+  add_object(d_rx0);
+  d_baseline = dyn_object::distance(*d_tx, *d_rx0);
+
+  {
+    // add targets
+    float aircraft_speed;
+    float aircraft_angle;
+    point aircraft_pos;
+    dyn_object *ac;
+
+    // target 1
+    aircraft_speed = 135;                      // m/s
+    aircraft_angle = 240 * M_PI/180;
+    aircraft_pos = point(55e3, 20e3);
+
+    ac = new dyn_object(aircraft_pos,
+                       point(aircraft_speed * cos(aircraft_angle),
+                             aircraft_speed * sin(aircraft_angle)),
+                       "Ac0");
+    add_object(ac);
+    d_target.push_back(new aux_state(ac));
+
+    // target 2 
+    aircraft_speed = 350;                      // m/s
+    aircraft_angle = 0 * M_PI/180;
+    aircraft_pos = point(-20e3, 60e3);
+
+    ac = new dyn_object(aircraft_pos,
+                       point(aircraft_speed * cos(aircraft_angle),
+                             aircraft_speed * sin(aircraft_angle)),
+                       "Ac1");
+    add_object(ac);
+    d_target.push_back(new aux_state(ac));
+  }
+
+  adjust_for_start_time(start_time);
+
+  for (unsigned i = 0; i < d_target.size(); i++)
+    d_target[i]->d_last_slant_range =
+      (dyn_object::distance(*d_tx, *d_target[i]->d_obj)
+       + dyn_object::distance(*d_target[i]->d_obj, *d_rx0));
+
+}
+
+my_sim::~my_sim()
+{
+}
+
+void
+my_sim::adjust_for_start_time(double start_time)
+{
+  for (unsigned i = 0; i < d_obj.size(); i++){
+    // Adjust initial starting positions depending on simulation
+    // start time.  FIXME Assumes velocity is constant
+    point p = d_obj[i]->pos();
+    point v = d_obj[i]->vel();
+    p.set_x(p.x() + v.x() * start_time);
+    p.set_y(p.y() + v.y() * start_time);
+    d_obj[i]->set_pos(p);
+  }
+}
+
+bool
+my_sim::update()
+{
+  // std::cout << *d_ac0 << std::endl;
+
+  // grab new item from input and insert it into delay line
+  const gr_complex *in = (const gr_complex *) d_ref.seek(d_pos++, 1);
+  if (in == 0)
+    return false;
+  d_z.push_item(*in);
+
+  gr_complex s = 0;    // output sample
+  // FIXME ought to add in attenuated direct path input
+
+
+  // for each target, compute slant_range and slant_range'
+
+  for (unsigned i = 0; i < d_target.size(); i++){
+    aux_state *t = d_target[i];
+    
+    double slant_range = 
+      (dyn_object::distance(*d_tx, *t->d_obj)
+       + dyn_object::distance(*t->d_obj, *d_rx0));                       // meters
+
+    double delta_slant_range = slant_range - t->d_last_slant_range;
+    t->d_last_slant_range = slant_range;
+    double deriv_slant_range_wrt_time = delta_slant_range / timestep();          // m/sec
+
+    //fprintf(stdout, "%10.3f\t%10.3f\n", slant_range, deriv_slant_range_wrt_time);
+
+    // FIXME, may want to interpolate between two bins.
+    int int_delay = lrint((slant_range - d_baseline) / d_range_bin);
+
+    gr_complex x = d_z.ref_item(int_delay);
+
+    // scale amplitude (this includes everything: RCS, antenna gain, losses, etc...)
+    x = x * d_gain;
+
+    if (1){
+      // compute doppler and apply it
+      float f_doppler = -deriv_slant_range_wrt_time / d_tx_lambda;
+
+      t->d_nco.set_freq(f_doppler / d_sample_rate);
+      gr_complex phasor(t->d_nco.cos(), t->d_nco.sin());
+      x = x * phasor;
+      t->d_nco.step();
+    }
+
+    s += x;            // add in this target's contribution
+  }
+
+  write_output(s);
+
+  return simulation::update();         // run generic update
+}
+
+bool
+my_sim::run(long long nsteps)
+{
+  //fprintf(stdout, "<%12.2f, %12.2f>\n", d_ac0->pos().x(), d_ac0->pos().y());
+  //std::cout << *d_ac0 << std::endl;
+  bool ok = simulation::run(nsteps);
+  //std::cout << *d_ac0 << std::endl;
+  //fprintf(stdout, "<%12.2f, %12.2f>\n", d_ac0->pos().x(), d_ac0->pos().y());
+  return ok;
+}
+
+// ------------------------------------------------------------------------
+
+static void
+usage(const char *argv0)
+{
+  const char *progname;
+  const char *t = std::strrchr(argv0, '/');
+  if (t != 0)
+    progname = t + 1;
+  else
+    progname = argv0;
+    
+  fprintf(stderr, "usage: %s [options] ref_file\n", progname);
+  fprintf(stderr, "    -o OUTPUT_FILENAME [default=sim.dat]\n");
+  fprintf(stderr, "    -n NSAMPLES_TO_PRODUCE [default=+inf]\n");
+  fprintf(stderr, "    -s NSAMPLES_TO_SKIP [default=0]\n");
+  fprintf(stderr, "    -g reflection gain in dB (should be <= 0) [default=0]\n");
+  fprintf(stderr, "    -f transmitter freq in Hz [default=100MHz]\n");
+  fprintf(stderr, "    -r sample rate in Hz [default=250kHz]\n");
+  fprintf(stderr, "    -S simulation start time in seconds [default=0]\n");
+}
+
+int
+main(int argc, char **argv)
+{
+  int  ch;
+  const char *output_filename = "sim.dat";
+  const char *ref_filename = 0;
+  long long int nsamples_to_skip = 0;
+  long long int nsamples_to_produce = std::numeric_limits<long long int>::max();
+  double sample_rate = 250e3;
+  double gain_db = 0;
+  double tx_freq = 100e6;
+  double start_time = 0;
+
+  while ((ch = getopt(argc, argv, "o:s:n:g:f:S:")) != -1){
+    switch (ch){
+    case 'o':
+      output_filename = optarg;
+      break;
+      
+    case 's':
+      nsamples_to_skip = (long long) strtof(optarg, 0);
+      if (nsamples_to_skip < 0){
+       usage(argv[0]);
+       fprintf(stderr, "    nsamples_to_skip must be >= 0\n");
+       exit(1);
+      }
+      break;
+
+    case 'n':
+      nsamples_to_produce = (long long) strtof(optarg, 0);
+      if (nsamples_to_produce < 0){
+       usage(argv[0]);
+       fprintf(stderr, "    nsamples_to_produce must be >= 0\n");
+       exit(1);
+      }
+      break;
+
+    case 'g':
+      gain_db = strtof(optarg, 0);
+      break;
+
+    case 'f':
+      tx_freq = strtof(optarg, 0);
+      break;
+
+    case 'r':
+      sample_rate = strtof(optarg, 0);
+      break;
+
+    case 'S':
+      start_time = strtof(optarg, 0);
+      break;
+
+    case '?':
+    case 'h':
+    default:
+      usage(argv[0]);
+      exit(1);
+    }
+  } // while getopt
+
+  if (argc - optind != 1){
+    usage(argv[0]);
+    exit(1);
+  }
+
+  ref_filename = argv[optind++];
+
+  double timestep = 1.0/sample_rate;
+
+
+  FILE *output = fopen(output_filename, "wb");
+  if (output == 0){
+    perror(output_filename);
+    exit(1);
+  }
+
+  unsigned long long ref_starting_offset = 0;
+  ref_starting_offset += nsamples_to_skip;
+
+  try {
+    time_series ref(sizeof(gr_complex), ref_filename, ref_starting_offset, 0);
+
+    my_sim     simulator(output, ref, timestep, sample_rate, start_time,
+                         tx_freq, gain_db);
+    simulator.run(nsamples_to_produce);
+  }
+  catch (std::string &s){
+    std::cerr << s << std::endl;
+    exit(1);
+  }
+
+  return 0;
+}
+
diff --git a/gr-radar/src/lib/simulation.cc b/gr-radar/src/lib/simulation.cc
new file mode 100644 (file)
index 0000000..4ebc7f1
--- /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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "simulation.h"
+
+bool
+dyn_object::update(double delta_t)
+{
+  double new_x = pos().x() + delta_t * vel().x();
+  double new_y = pos().y() + delta_t * vel().y();
+  set_pos(point(new_x, new_y));
+  return true;
+}
+
+simulation::~simulation()
+{
+  for (unsigned i = 0; i < d_obj.size(); i++){
+    delete d_obj[i];
+    d_obj[i] = 0;
+  }
+}
+
+bool
+simulation::update()
+{
+  bool ok = true;
+  for (unsigned i = 0; i < d_obj.size(); i++){
+    ok &= d_obj[i]->update(d_timestep);
+  }
+  d_now += d_timestep;
+  return ok;
+}
+
+bool
+simulation::run(long long nsteps)
+{
+  for (long long i = 0; i < nsteps; i++)
+    if (!update())
+      return false;
+
+  return true;
+}
+
+void
+simulation::add_object(dyn_object *obj)
+{
+  d_obj.push_back(obj);
+}
+
+// ----------------------------------------------------------------
+
+std::ostream& operator<<(std::ostream& out, const dyn_object& o)
+{
+  out << "<" << o.name()
+      << " pos: " << o.pos()
+      << " vel: " << o.vel()
+      << ">";
+  return out;
+}
+
+std::ostream& operator<<(std::ostream& out, const point& p)
+{
+  out << "(" << p.x() << ", " << p.y() << ")";
+  return out;
+}
+
diff --git a/gr-radar/src/lib/simulation.h b/gr-radar/src/lib/simulation.h
new file mode 100644 (file)
index 0000000..ff32484
--- /dev/null
@@ -0,0 +1,116 @@
+/* -*- 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 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.
+ */
+
+#ifndef INCLUDED_SIMULATION_H
+#define INCLUDED_SIMULATION_H
+
+#include <string>
+#include <cmath>
+#include <vector>
+#include <iostream>
+
+
+class point {
+  double       d_x, d_y;
+public:
+  point(double x = 0, double y = 0) : d_x(x), d_y(y) {}
+
+  double x() const { return d_x; }
+  double y() const { return d_y; }
+
+  void set_x(double x) { d_x = x; }
+  void set_y(double y) { d_y = y; }
+
+  static point
+  add(const point &p1, const point &p2)
+  {
+    return point(p1.x() + p2.x(),
+                p1.y() + p2.y());
+  }
+
+  static point
+  sub(const point &p1, const point &p2)
+  {
+    return point(p1.x() - p2.x(), p1.y() - p2.y());
+  }
+
+  static double
+  distance(const point &p1, const point &p2)
+  {
+    point d = point::sub(p1, p2);
+    return std::sqrt(d.x()*d.x() + d.y()*d.y());
+  }
+
+};
+
+
+class dyn_object {
+  point                d_pos;
+  point                d_vel;
+  std::string  d_name;
+public:
+  dyn_object(point pos=point(0,0), point vel=point(0,0), const std::string name="")
+    : d_pos(pos), d_vel(vel), d_name(name) {}
+
+  virtual ~dyn_object() {}
+
+  point pos() const { return d_pos; }
+  point vel() const { return d_vel; }
+  std::string name() const { return d_name; }
+
+  void set_pos(point pos) { d_pos = pos; }
+  void set_vel(point vel) { d_vel = vel; }
+
+  virtual bool update(double delta_t);
+
+  static double
+  distance(const dyn_object &o1, const dyn_object &o2)
+  {
+    return point::distance(o1.pos(), o2.pos());
+  }
+
+};
+
+
+class simulation {
+  double                       d_timestep;
+  double                       d_now;
+protected:
+  std::vector<dyn_object *>    d_obj;
+
+public:
+  simulation(double timestep = 1.0, double now = 0.0)
+    : d_timestep(timestep), d_now(now) {}
+  virtual ~simulation();
+  virtual bool update();
+  virtual bool run(long long nsteps);
+
+  void add_object(dyn_object *obj);
+  double now() const { return d_now; }
+  double timestep() const { return d_timestep; }
+};
+
+std::ostream& operator<<(std::ostream& out, const dyn_object& o);
+std::ostream& operator<<(std::ostream& out, const point& p);
+
+#endif /* INCLUDED_SIMULATION_H */
+
diff --git a/gr-radar/src/lib/time_series.cc b/gr-radar/src/lib/time_series.cc
new file mode 100644 (file)
index 0000000..2767165
--- /dev/null
@@ -0,0 +1,96 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "time_series.h"
+#include <sys/mman.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <iostream>
+
+
+time_series::time_series(size_t itemsize, const std::string filename,
+                        unsigned long long starting_offset,
+                        long long nsamples_to_process)
+  : d_itemsize(itemsize), d_filename(filename), d_fd(-1), 
+    d_start(starting_offset), d_buffer(0)
+{
+  if ((d_fd = open(d_filename.c_str(), O_RDONLY | O_LARGEFILE, 0660)) == -1){
+    perror(d_filename.c_str());
+    throw std::string("open failed: ") + d_filename;
+  }
+
+  struct stat statbuf;
+  if (fstat(d_fd, &statbuf) == -1){
+    perror(d_filename.c_str());
+    throw std::string("fstat failed: ") + d_filename;
+  }
+  d_filesize = statbuf.st_size;
+  d_limit = d_filesize / d_itemsize;
+
+  if (d_start > d_limit){
+    std::string s = std::string("d_start > filesize: ") + d_filename;
+    std::cerr << s
+             << " d_start " << d_start
+             << " d_limit " << d_limit << std::endl;
+    throw s;
+  }
+
+  if (nsamples_to_process > 0)
+    if ((d_start + nsamples_to_process) < d_limit)
+      d_limit = d_start + nsamples_to_process;
+
+  d_buffer = mmap(0, d_filesize, PROT_READ, MAP_SHARED, d_fd, 0);
+  if (d_buffer == MAP_FAILED){
+    perror("mmap");
+    throw std::string("mmap failed: ") + d_filename;
+  }
+}
+
+time_series::~time_series()
+{
+  munmap(d_buffer, d_filesize);
+  close(d_fd);
+}
+
+const void *
+time_series::seek(unsigned long long pos, unsigned long long blocksize) const
+{
+  if ((d_start + pos + blocksize) >= d_limit)
+    return 0;
+
+  return (const void *)((char *)d_buffer + ((d_start + pos) * d_itemsize));
+}
+
+long long
+time_series::nsamples_available(unsigned long long pos) const
+{
+  if ((d_start + pos) >= d_limit)
+    return 0;
+
+  return d_limit - (d_start + pos);
+}
diff --git a/gr-radar/src/lib/time_series.h b/gr-radar/src/lib/time_series.h
new file mode 100644 (file)
index 0000000..3764ba5
--- /dev/null
@@ -0,0 +1,73 @@
+/* -*- 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 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.
+ */
+#ifndef INCLUDED_TIME_SERIES_H
+#define INCLUDED_TIME_SERIES_H
+
+#include <string>
+
+/*!
+ * \brief Memory mapped input for complex time series data
+ *
+ * Inspired by "iqts" by John Sahr, Univ of Washington
+ */
+
+class time_series {
+  size_t               d_itemsize;         // user specified item size
+  std::string          d_filename;
+  int                  d_fd;               // file descriptor
+  unsigned long long   d_filesize;         // in bytes
+  unsigned long long   d_start;            // in items
+  unsigned long long   d_limit;            // in items
+  void                *d_buffer;           // points to base of file
+
+public:
+  /*!
+   * \brief Create read-only mapped file accessor.
+   * \param item_size           size of item in bytes
+   * \param filename            name of file to open
+   * \param starting_offset      offset in file in item_size units at which to start
+   * \param nsamples_to_process  maximum number of samples to map in starting at \p start.  -1 implies no limit.
+   *
+   * \throws string on error opening file, etc.
+   */
+  time_series(size_t item_size, const std::string filename,
+             unsigned long long starting_offset=0,
+             long long nsamples_to_process=-1);
+  ~time_series();
+
+  /*!
+   * \brief Return a pointer to a buffer of data at file offset pos.
+   *
+   * \param pos                offset from beginning of file in itemsize units.
+   * \param blocksize  minimum size of returned buffer in itemsize units.
+   *
+   * "Seek" to pos in file and return a pointer to the data at that
+   * location.  The returned pointer will have at least blocksize valid        
+   * elements.  Return 0 if pos is out of bounds, or if there isn't
+   * at least blocksize units available in the file.
+   */
+  const void *seek(unsigned long long pos, unsigned long long blocksize) const;
+
+  long long nsamples_available(unsigned long long pos) const;
+};
+
+#endif /* INCLUDED_TIME_SERIES_H */
diff --git a/gr-radar/src/lib/xambi.cc b/gr-radar/src/lib/xambi.cc
new file mode 100644 (file)
index 0000000..e5d4a9a
--- /dev/null
@@ -0,0 +1,259 @@
+/* -*- 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 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.
+ */
+
+#include <iostream>
+#include <string>
+#include <fstream>
+#include <unistd.h>
+
+#include <gr_complex.h>
+#include <gri_fft.h>
+#include "time_series.h"
+
+
+using namespace std;
+
+/*!
+ * \file xambi.cc driver for computation of cross ambiguity
+ *
+ * Based on ideas liberally lifted from a version of xambi.cc 
+ * obtained from John Sahr, that identified these people as authors:
+ *   John Sahr            jdsahr@u.washington.edu
+ *   Frank Lind           flind@haystack.mit.edu
+ *   Chucai "Cliff" Zhou
+ *   Melissa Meyer        mgmeyer@ee.washington.edu
+ *
+ * Extensively revised since then.
+ */
+
+static int default_decimation = 40;
+static int default_fftsize    = 256;
+static int default_naverages   = 1000000; // infinite
+
+/// usage for the xambi program
+
+static void usage(char *argv0)
+{
+  cerr << "usage:  xambi [opts] scatterfile"                << endl;
+  cerr << "  where [opts] are"                              << endl;
+  cerr << "  -x reffilename                  : Required"    << endl;
+  cerr << "  -o outputfilename[=xambi.out]   : create or overwrite" << endl;
+  cerr << "  -a averages[=100000]            : restart accumulation; 100000 = infinite" << endl;
+  cerr << "  -d decimationfactor[=40]"                      << endl;
+  cerr << "  -f fftsize[=256]"                              << endl;
+  cerr << "  -r range[=0]                    : first range" << endl;
+  cerr << "  -n nranges[=1]                  : range count" << endl;
+  cerr << "  -S start[=0]                    : starting offset in file" << endl;
+  cerr << "  -N nsamples[=inf]               : # of samples to process" << endl;
+  cerr << "  -v                              : increment verbosity" << endl;
+  cerr << "  -h                              : be helpful" << endl;
+  cerr << endl;
+  cerr << "The reffile and scatterfile are native-endian binary complex<float>" << endl;
+  cerr << "and must be sampled at the same rate." << endl;
+  exit(0);
+}
+
+gr_complex
+complex_dot_product(const gr_complex *xx, const gr_complex *yy, int nterms)
+{
+  gr_complex sum(0);
+
+  for (int i = 0; i < nterms; i++)
+    sum += xx[i] * yy[i];              // FIXME?   conj(yy[i])
+
+  return sum;
+}
+
+
+/// the main driver
+
+int 
+main(int argc, char *argv[])
+{
+  char *ref_fname = 0;    //< holds name of reference signal source
+  char *out_fname = 0;    //< holds name of processed output
+  int decimation  = default_decimation;
+  int range       = 0;    //< first range of range block
+  int nranges     = 1;    //< number of ranges of range block
+  int fftsize     = default_fftsize;
+  int naverages   = default_naverages;
+  int verbosity   = 0;    
+  int blocksize   = 0;
+  int offset      = 0;
+  unsigned long long starting_file_offset = 0;
+  unsigned long long nsamples_to_process = (unsigned long long) -1;
+
+  int f;
+
+  const gr_complex     *x,  *y;
+  const gr_complex     *xx, *yy;
+
+  int c;         // used to process the command line
+  int r;         // an index to count over ranges
+  int i;         // an index to count through the time series
+  int a;
+
+  while((c = getopt(argc,argv,"a:o:x:y:r:d:f:n:hvS:N:")) != EOF) {
+    switch(c) {
+    case 'x': ref_fname  = optarg;            break;
+    case 'o': out_fname  = optarg;            break;
+    case 'a': naverages   = atoi(optarg);     break;
+    case 'd': decimation = atoi(optarg);      break;
+    case 'r': range      = atoi(optarg);      break;
+    case 'n': nranges    = atoi(optarg);      break;
+    case 'f': fftsize    = atoi(optarg);      break;
+    case 'S': starting_file_offset = strtoll(optarg, 0, 0);  break;
+    case 'N': nsamples_to_process = strtoll(optarg, 0, 0);   break;
+    case 'v': verbosity++;                    break;
+    case 'h': usage(argv[0]);                 break;
+    default:  usage(argv[0]);                 break;
+    }
+  }
+
+  // Wrapper for FFTW 1d forward FFT.  N.B. output is not scaled by 1/fftsize
+  gri_fft_complex      fft(fftsize, true); 
+  gr_complex           *fft_input = fft.get_inbuf();
+  gr_complex           *fft_output = fft.get_outbuf();
+
+  if(range < 0) {
+    cerr << "you specified -r " << range << "; must be non-negative (exit)" << endl;
+    exit(1);
+  }
+
+  if(nranges < 1) {
+    cerr << "you specified -n " << nranges << "; must be positive (exit)" << endl;
+    exit(1);
+  }
+
+  if(decimation < 1) {
+    cerr << "you specified -d " << decimation << "; must be positive (exit)" << endl;
+    exit(1);
+  }
+
+  if(naverages < 1) {
+    cerr << "you specified -a " << naverages << "; must be positive (exit)" << endl;
+    exit(1);
+  }
+
+  if(ref_fname == 0) {
+    cerr << "you must specify a reference signal with the -x option" << endl;
+    usage(argv[0]);
+  }
+
+  if (optind >= argc) {
+    cerr << "you must specify a scattering signal after all other options" << endl;
+    usage(argv[0]);
+  }
+
+  time_series   X(sizeof(gr_complex), ref_fname,
+                 starting_file_offset, nsamples_to_process);
+
+  time_series   Y(sizeof(gr_complex), argv[optind],
+                 starting_file_offset, nsamples_to_process); // add more for interferometry ...
+
+  float  psd[fftsize*nranges];
+
+  if(out_fname == 0) {
+    char fname[200];
+    snprintf(fname, sizeof(fname), "%s.out", "xambi");
+    out_fname = fname;
+  }
+
+  ofstream Z(out_fname);
+
+  blocksize = fftsize*decimation + nranges;
+  offset    = 0;
+  a         = 0;
+
+  // the fftsize is squared because we're using norm, not abs, 
+  // when computing the psd
+  float scale_factor = 1.0 / (fftsize * fftsize);
+
+  for(i = 0; i < nranges*fftsize; i++)
+    psd[i] = 0.0;
+
+
+  while(1){             // loop over data until exhausted.
+    if(verbosity > 1) { 
+      cerr << " " << a;  // write out the number of completed averages
+      cerr.flush();
+    }
+
+    x = (const gr_complex *) X.seek(offset,         blocksize);
+    y = (const gr_complex *) Y.seek(offset + range, blocksize);
+
+    if(!x || !y)         // ran out of data; stop integrating
+      break;
+
+    for(r = 0; r < nranges; r++) {  // For Each Range ...
+      xx = x;
+      yy = y + r;
+
+      for(f = 0; f < fftsize; f++) {  // and for each Doppler bin ...
+
+       // cross correlate and do a boxcar decimation
+
+       fft_input[f] = complex_dot_product(xx, yy, decimation);
+       xx += decimation;
+       yy += decimation;
+      }
+
+      fft.execute();   // input: fft_input; output: fft_output
+
+      for(f = 0; f < fftsize; f++) {
+       psd[r*fftsize + f] += norm(fft_output[f]);
+      }
+    }  // end range
+
+    a++;
+    offset += fftsize * decimation; 
+
+    if(a >= naverages) {
+      if(verbosity > 0)
+       cerr << " dumping " << endl;
+      
+      for(i = 0; i < nranges*fftsize; i++)     // normalize
+       psd[i] *= scale_factor;
+
+      Z.write((const char *) psd, nranges*fftsize*sizeof(float)); 
+      for(i = 0; i < nranges*fftsize; i++)
+       psd[i] = 0.0;
+      
+      a = 0;
+    }
+  }
+
+  if(verbosity > 1)
+    printf("\n");
+
+  if(a > 0) {
+    for(i = 0; i < nranges*fftsize; i++)       // normalize
+      psd[i] *= scale_factor;
+
+    Z.write((const char *) psd, nranges*fftsize*sizeof(float));
+  }
+
+  return 0;
+}
+
diff --git a/gr-radar/src/python/Makefile.am b/gr-radar/src/python/Makefile.am
new file mode 100644 (file)
index 0000000..da81410
--- /dev/null
@@ -0,0 +1,33 @@
+#
+# 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.
+# 
+
+include $(top_srcdir)/Makefile.common
+
+EXTRA_DIST = run_tests.in
+
+
+TESTS =                                \
+       run_tests
+
+
+noinst_PYTHON =                        \
+       qa_nothing.py                   \
+       usrp_rx_radar.py                
diff --git a/gr-radar/src/python/complex_to_short.py b/gr-radar/src/python/complex_to_short.py
new file mode 100755 (executable)
index 0000000..9c229d8
--- /dev/null
@@ -0,0 +1,33 @@
+#!/usr/bin/env python
+
+from gnuradio import gr, gru, eng_notation, optfir
+from gnuradio.eng_option import eng_option
+from optparse import OptionParser
+import os.path
+import re
+
+class my_graph(gr.flow_graph):
+    def __init__(self):
+        gr.flow_graph.__init__(self)
+
+        usage="%prog: [options] input_file output_file"
+        parser = OptionParser (option_class=eng_option, usage=usage)
+        (options, args) = parser.parse_args()
+        if len(args) != 2:
+            parser.print_help()
+            raise SystemExit, 1
+
+        input_filename = args[0]
+        output_filename = args[1]
+
+        inf = gr.file_source(gr.sizeof_gr_complex, input_filename)
+        c2s = gr.complex_to_interleaved_short()
+        outf = gr.file_sink(gr.sizeof_short, output_filename)
+        self.connect(inf, c2s, outf)
+
+
+if __name__ == '__main__':
+    try:
+        my_graph().run()
+    except KeyboardInterrupt:
+        pass
diff --git a/gr-radar/src/python/fm_demod_file.py b/gr-radar/src/python/fm_demod_file.py
new file mode 100755 (executable)
index 0000000..9d430a8
--- /dev/null
@@ -0,0 +1,66 @@
+#!/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 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.
+# 
+
+"""
+Demod FM signal in data collected for radar.
+Input samples are complex baseband, 250kS/sec.
+"""
+
+from gnuradio import gr, gru, blks, eng_notation
+from gnuradio import audio
+from gnuradio.eng_option import eng_option
+from optparse import OptionParser
+import sys
+import math
+
+
+class my_graph(gr.flow_graph):
+    def __init__(self, input_filename, repeat):
+        gr.flow_graph.__init__(self)
+        
+        baseband_rate = 250e3
+        audio_decim = 8
+        audio_rate = int(baseband_rate // audio_decim) # output is at 31250 S/s
+
+        src = gr.file_source(gr.sizeof_gr_complex, input_filename, repeat)
+        guts = blks.wfm_rcv(self, baseband_rate, audio_decim)  
+        sink = audio.sink(audio_rate, "plughw:0,0")
+        self.connect(src, guts, sink)
+
+def main ():
+    usage = "usage: %prog [options] filename"
+    parser = OptionParser (option_class=eng_option, usage=usage)
+    parser.add_option ("-r", "--repeat", action="store_true", default=False)
+    (options, args) = parser.parse_args ()
+
+    if len (args) != 1:
+        parser.print_help ()
+        sys.exit (1)
+
+    try:
+        my_graph(args[0], options.repeat).run()
+    except KeyboardInterrupt:
+        pass
+    
+
+if __name__ == '__main__':
+    main ()
diff --git a/gr-radar/src/python/gen_fm_signal.py b/gr-radar/src/python/gen_fm_signal.py
new file mode 100755 (executable)
index 0000000..cd0834a
--- /dev/null
@@ -0,0 +1,66 @@
+#!/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 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.
+# 
+
+from gnuradio import gr, gru, blks, eng_notation
+from gnuradio import audio
+from gnuradio.eng_option import eng_option
+from optparse import OptionParser
+import sys
+import math
+
+
+class my_graph(gr.flow_graph):
+    def __init__(self, output_filename, tx_gain, nsamples):
+        gr.flow_graph.__init__(self)
+        
+        audio_rate = 31250
+        baseband_rate = 250e3
+
+        src = gr.noise_source_f(gr.GR_GAUSSIAN, 1.0)
+        #src = gr.noise_source_f(gr.GR_GAUSSIAN, 0.5)
+        guts = blks.wfm_tx(self, audio_rate, baseband_rate)
+        amp = gr.multiply_const_cc(tx_gain)
+        head = gr.head(gr.sizeof_gr_complex, nsamples)
+        sink = gr.file_sink(gr.sizeof_gr_complex, output_filename)
+        self.connect(src, guts, amp, head, sink)
+
+def main ():
+    usage = "usage: %prog [options] output_filename"
+    parser = OptionParser (option_class=eng_option, usage=usage)
+    parser.add_option("-N", "--nsamples", type="eng_float", default=250000,
+                      help="specify number of output samples to generate[=250000]")
+    parser.add_option("-g", "--tx-gain", type="eng_float", default=1.0,
+                      help="specify transmitter gain[=1]")
+    (options, args) = parser.parse_args ()
+
+    if len (args) != 1:
+        parser.print_help ()
+        sys.exit (1)
+
+    try:
+        my_graph(args[0], options.tx_gain, int(options.nsamples)).run()
+    except KeyboardInterrupt:
+        pass
+    
+
+if __name__ == '__main__':
+    main ()
diff --git a/gr-radar/src/python/gen_random_signal.py b/gr-radar/src/python/gen_random_signal.py
new file mode 100755 (executable)
index 0000000..87a531c
--- /dev/null
@@ -0,0 +1,66 @@
+#!/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 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.
+# 
+
+from gnuradio import gr, gru, blks, eng_notation
+from gnuradio import audio
+from gnuradio.eng_option import eng_option
+from optparse import OptionParser
+import sys
+import math
+
+
+class my_graph(gr.flow_graph):
+    def __init__(self, output_filename, tx_gain, nsamples):
+        gr.flow_graph.__init__(self)
+        
+        audio_rate = 31250
+        baseband_rate = 250e3
+
+        src = gr.noise_source_c(gr.GR_GAUSSIAN, 1.0)
+        #src = gr.noise_source_f(gr.GR_GAUSSIAN, 0.5)
+        #guts = blks.wfm_tx(self, audio_rate, baseband_rate)
+        amp = gr.multiply_const_cc(tx_gain)
+        head = gr.head(gr.sizeof_gr_complex, nsamples)
+        sink = gr.file_sink(gr.sizeof_gr_complex, output_filename)
+        self.connect(src, amp, head, sink)
+
+def main ():
+    usage = "usage: %prog [options] output_filename"
+    parser = OptionParser (option_class=eng_option, usage=usage)
+    parser.add_option("-N", "--nsamples", type="eng_float", default=250000,
+                      help="specify number of output samples to generate[=250000]")
+    parser.add_option("-g", "--tx-gain", type="eng_float", default=1.0,
+                      help="specify transmitter gain[=1]")
+    (options, args) = parser.parse_args ()
+
+    if len (args) != 1:
+        parser.print_help ()
+        sys.exit (1)
+
+    try:
+        my_graph(args[0], options.tx_gain, int(options.nsamples)).run()
+    except KeyboardInterrupt:
+        pass
+    
+
+if __name__ == '__main__':
+    main ()
diff --git a/gr-radar/src/python/qa_nothing.py b/gr-radar/src/python/qa_nothing.py
new file mode 100755 (executable)
index 0000000..e69de29
diff --git a/gr-radar/src/python/run_tests.in b/gr-radar/src/python/run_tests.in
new file mode 100644 (file)
index 0000000..fd0a43a
--- /dev/null
@@ -0,0 +1,47 @@
+#!/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@gr-radar/src/lib
+# Where to look in the src tree for swig generated python code
+libsrc=@abs_top_srcdir@/gr-radar/src/lib
+# Where to look in the src tree for hand written python code
+py=@abs_top_srcdir@/gr-radar/src/python
+
+# Where to look for GNU Radio python modules in current build tree
+# FIXME this is wrong on a distcheck.  We really need to ask gnuradio-core
+# where it put its python files.
+grpythonbld=@abs_top_builddir@/gnuradio-core/src/python/:@abs_top_builddir@/gnuradio-core/src/lib/swig/:@abs_top_builddir@/gnuradio-core/src/lib/swig/.libs
+
+PYTHONPATH="$grpythonbld:$libbld:$libbld/.libs:$libsrc:$py:$PYTHONPATH"
+export PYTHONPATH
+
+#
+# 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-radar/src/python/signal_levels.py b/gr-radar/src/python/signal_levels.py
new file mode 100755 (executable)
index 0000000..f21f7f8
--- /dev/null
@@ -0,0 +1,62 @@
+#!/usr/bin/env python
+
+import sys
+from math import pi, log10
+from gnuradio.eng_notation import num_to_str
+
+def power_density(transmitted_power, distance):
+    """
+    Estimate power density in Watts/meter.
+    Assume isotropic radiator (spherical radiation pattern).
+
+    @param transmitted_power: Watts
+    @param distance: distance from transmitter in meters
+
+    """
+    return transmitted_power / (4 * pi * distance * distance)
+
+
+def ratio_of_target_return_to_direct(Rl, Rt, Rr, rcs):
+    """
+    Estimate relative strength of signal levels for direct and reflected
+    path in bistatic radar.  Assume all antenna factors are constant,
+    and hence 'wash out'.  Also assume that the antennas are isotropic
+    radiators (spherical radiation pattern).
+
+    @param Rl:  distance between Tx and Rx in meters
+    @param Rt:  distance between Tx and target in meters
+    @param Rr:  distance between Rx and target in meters
+    @param rcs: radar cross section in meters^2
+
+    @returns: ratio of reflected to direct in decibels
+    """
+    Tx_power = 1
+    direct_path_power_density = power_density(Tx_power, Rl)
+    power_at_target = power_density(Tx_power, Rt) * rcs
+    reflected_path_power_density = power_density(power_at_target, Rr)
+    return 10*log10(reflected_path_power_density / direct_path_power_density)
+
+
+def print_header(f):
+    f.write("   Rl      Rt      Rr      rcs      dB\n")
+    f.write("-----------------------------------------\n")
+    
+def print_result(f, Rl, Rt, Rr, rcs, dB):
+    f.write("%6sm %6sm %6sm %6s  %6s\n" %  tuple([num_to_str(x) for x in [Rl, Rt, Rr, rcs, dB]]))
+
+def calc_print(f, Rl, Rt, Rr, rcs):
+    print_result(f, Rl, Rt, Rr, rcs, ratio_of_target_return_to_direct(Rl, Rt, Rr, rcs))
+    
+def main():
+    f = sys.stdout
+    print_header(f)
+    calc_print(f, 40e3, 100e3, 100e3, 10.0)
+    calc_print(f, 40e3,  80e3,  80e3, 10.0)
+    calc_print(f, 40e3,  40e3,  40e3, 10.0)
+    calc_print(f, 40e3,  40e3,   8e3, 10.0)
+    calc_print(f, 40e3,  60e3,  20e3, 10.0)
+    calc_print(f, 40e3,  20e3,  60e3, 10.0)
+
+    
+if __name__ == '__main__':
+    main()
diff --git a/gr-radar/src/python/split_files.py b/gr-radar/src/python/split_files.py
new file mode 100755 (executable)
index 0000000..a604c07
--- /dev/null
@@ -0,0 +1,93 @@
+#!/usr/bin/env python
+
+from gnuradio import gr, gru, eng_notation, optfir
+from gnuradio.eng_option import eng_option
+from optparse import OptionParser
+import os.path
+import re
+
+plot = None
+
+def split_filename(src_filename):
+    s = os.path.splitext(src_filename)[0]     # drop extension
+    date, time, freq, dec, nchan = s.split('-')
+    return (date, time, freq, int(dec), int(nchan))
+
+
+def make_filename(date, time, freq, n, short_output):
+    if short_output:
+        return '-'.join((date, time, freq)) + '.s%02d' % (n,)
+    else:
+        return '-'.join((date, time, freq)) + '.c%02d' % (n,)
+
+class my_graph(gr.flow_graph):
+
+    def __init__(self, src_filename, short_output):
+        """
+        Deinterleave file, filter and decimate by 4, and write out
+        a separate file for each input channel.
+
+        The input file is the raw output of nchannels of short USRP data.
+        That is, they are interleaved short I&Q for each channel.
+        """
+        global plot
+        
+        gr.flow_graph.__init__(self)
+
+        decim = 4
+
+        (date, time, freq, dec, nchan) = split_filename(src_filename)
+
+        src = gr.file_source(gr.sizeof_short, src_filename)
+
+        # convert stream of interleaved shorts to a stream of complex
+        s2c = gr.interleaved_short_to_complex()
+
+        # deinterleave complexes into separate streams
+        deint = gr.deinterleave(gr.sizeof_gr_complex)
+
+        self.connect(src, s2c, deint)
+
+        taps = optfir.low_pass(1,       # gain
+                               1,       # sampling rate
+                               0.100,   # passband cutoff
+                               0.125,   # stopband cutoff
+                               0.01,    # passband ripple (dB)
+                               70)      # stopband atten (dB)
+
+        print "len(taps) =", len(taps)
+                               
+        #plot = gru.gnuplot_freqz(gru.freqz(taps, 1), 1)
+        #raw_input('Press Enter to continue: ')
+        
+        for n in xrange(nchan):
+            #df = gr.fft_filter_ccc(decim, taps)
+            df = gr.fir_filter_ccf(decim, taps)
+            self.connect((deint, n), df)
+            dst_filename = make_filename(date, time, freq, n, short_output)
+            if short_output:
+                c2s = gr.complex_to_interleaved_short()
+                dst = gr.file_sink(gr.sizeof_short, dst_filename)
+                self.connect(df, c2s, dst)
+            else:
+                dst = gr.file_sink(gr.sizeof_gr_complex, dst_filename)
+                self.connect(df, dst)
+
+
+def split_1_file(filename, short_output):
+    my_graph(filename, short_output).run()
+
+
+def main():
+    usage="%prog: [options] file_to_split..."
+    parser = OptionParser (option_class=eng_option, usage=usage)
+    parser.add_option("-s", "--short", action="store_true", default=False,
+                      help="short output if set, else complex")
+    (options, args) = parser.parse_args()
+
+    for filename in args:
+        split_1_file(filename, options.short)
+
+
+if __name__ == '__main__':
+    main()
diff --git a/gr-radar/src/python/usrp_rx_radar.py b/gr-radar/src/python/usrp_rx_radar.py
new file mode 100755 (executable)
index 0000000..e7c2da2
--- /dev/null
@@ -0,0 +1,89 @@
+#!/usr/bin/env python
+
+from gnuradio import gr, gru, eng_notation
+from gnuradio import usrp
+from gnuradio.eng_option import eng_option
+from optparse import OptionParser
+import usrp_dbid
+import time
+import os.path
+
+
+def make_filename(dir, freq, decim, nchan, suffix):
+    t = time.strftime('%Y%m%d-%H%M%S')
+    f = 'R%s-%s-%d-%d.%s' % (
+        t, eng_notation.num_to_str(freq), decim, nchan, suffix)
+    return os.path.join(dir, f)
+
+class radar_graph(gr.flow_graph):
+
+    def __init__(self):
+        gr.flow_graph.__init__(self)
+
+        parser = OptionParser (option_class=eng_option)
+        #parser.add_option("-S", "--subdev", type="subdev", default=(0, None),
+        #                  help="select USRP Rx side A or B (default=A)")
+        parser.add_option("-d", "--decim", type="int", default=64,
+                          help="set fgpa decimation rate to DECIM (default=64)")
+        parser.add_option("-f", "--freq", type="eng_float", default=104.5e6,
+                          help="set frequency to FREQ (default=104.5M)", metavar="FREQ")
+        parser.add_option("", "--gain0", type="eng_float", default=0,
+                          help="set gain in dB (default 0)")
+        parser.add_option("", "--gain1", type="eng_float", default=11,
+                          help="set gain in dB (default 11)")
+        parser.add_option("-F", "--filename", default=None)
+        parser.add_option("-D", "--dir", default=None)
+        (options, args) = parser.parse_args()
+
+        if len(args) != 0:
+            parser.print_help()
+            sys.exit(1)
+
+        if options.filename is None and options.dir is None:
+            sys.stderr.write('Must specify either -F FILENAME or -D DIR\n')
+            parser.print_help()
+            sys.exit(1)
+
+        nchan = 2
+
+        # if filename was given, use it, otherwise build one.
+        if options.filename is None:
+            options.filename = make_filename(options.dir, options.freq,
+                                             options.decim, nchan, 'srd')
+
+        self.u = usrp.source_s(0, options.decim, nchan, 0, 0)
+        self.subdev = self.u.db[0]
+
+        if self.u.db[0][0].dbid() != usrp_dbid.BASIC_RX:
+            sys.stderr.write('This code requires a Basic Rx board on Side A\n')
+            sys.exit(1)
+
+        # self.u.set_mux(usrp.determine_rx_mux_value(self.u, options.subdev))
+        self.u.set_mux(gru.hexint(0xf0f0f1f0))
+
+        dst = gr.file_sink (gr.sizeof_short, options.filename)
+        self.connect (self.u, dst)
+
+        self.subdev[0].set_gain(options.gain0)
+        self.subdev[1].set_gain(options.gain1)
+        self.set_freq(options.freq)
+
+
+    def set_freq(self, target_freq):
+        ok = True
+        for i in range(len(self.subdev)):
+            r = usrp.tune(self.u, i, self.subdev[i], target_freq)
+            if not r:
+                ok = False
+                print "set_freq: failed to set subdev[%d] freq to %f" % (
+                    i, target_freq)
+
+        return ok
+
+
+if __name__ == '__main__':
+    fg = radar_graph()
+    try:
+        fg.run()
+    except KeyboardInterrupt:
+        pass
diff --git a/gr-radio-astronomy/AUTHORS b/gr-radio-astronomy/AUTHORS
new file mode 100644 (file)
index 0000000..b3ab414
--- /dev/null
@@ -0,0 +1,2 @@
+Marcus Leech <mleech@nortel.com>
+Eric Blossom <eb@comsec.com>
diff --git a/gr-radio-astronomy/ChangeLog b/gr-radio-astronomy/ChangeLog
new file mode 100644 (file)
index 0000000..4cc5ffa
--- /dev/null
@@ -0,0 +1,30 @@
+2006-06-29  Eric Blossom  <eb@comsec.com>
+
+       * src/python/Makefile.am: modfied to install part under gnuradio
+       and part under gnuradio/wxgui.
+
+2006-05-28  Eric Blossom  <eb@comsec.com>
+
+       * src/python/Makefile.am (bin_SCRIPTS): changed bin_PYTHON to
+       bin_SCRIPTS. 
+
+#
+# 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 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.
+# 
diff --git a/gr-radio-astronomy/Makefile.am b/gr-radio-astronomy/Makefile.am
new file mode 100644 (file)
index 0000000..ed5e752
--- /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 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.
+# 
+
+include $(top_srcdir)/Makefile.common
+
+SUBDIRS = src
diff --git a/gr-radio-astronomy/README b/gr-radio-astronomy/README
new file mode 100644 (file)
index 0000000..5abbac4
--- /dev/null
@@ -0,0 +1,38 @@
+#
+# 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 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 tarball contains a build tree with examples, Makefiles, etc 
+for radio astronomy related applications.
+
+To build the examples from the tarball use the normal recipe:
+
+  $ ./configure
+  $ make
+  $ make check
+
+If you're building from CVS, you'll need to use this sequence, since
+CVS doesn't contain configure or the generated Makefiles.
+
+  $ ./bootstrap
+  $ ./configure
+  $ make
+  $ make check
+
diff --git a/gr-radio-astronomy/src/Makefile.am b/gr-radio-astronomy/src/Makefile.am
new file mode 100644 (file)
index 0000000..122fc72
--- /dev/null
@@ -0,0 +1,22 @@
+#
+# 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.
+# 
+
+SUBDIRS = lib python
diff --git a/gr-radio-astronomy/src/lib/Makefile.am b/gr-radio-astronomy/src/lib/Makefile.am
new file mode 100644 (file)
index 0000000..b1d0173
--- /dev/null
@@ -0,0 +1,90 @@
+#
+# Copyright 2004,2005,2006 Free Software Foundation, Inc.
+# 
+# This file is part of GNU Radio
+# 
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 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.
+# 
+
+include $(top_srcdir)/Makefile.common
+
+# Install this stuff so that it ends up as the gnuradio.ra 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)
+
+SWIGPYTHONARGS = $(SWIGPYTHONFLAGS) $(STD_DEFINES_AND_INCLUDES)
+
+ALL_IFILES =                           \
+       $(LOCAL_IFILES)                 \
+       $(NON_LOCAL_IFILES)             
+
+NON_LOCAL_IFILES =                     \
+       $(top_srcdir)/gnuradio-core/src/lib/swig/gnuradio.i
+
+
+LOCAL_IFILES =                                 \
+       ra.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 =                \
+       ra.cc                   \
+       ra.py                           
+
+# This gets ra.py installed in the right place
+ourpython_PYTHON =                     \
+       ra.py
+
+ourlib_LTLIBRARIES = _ra.la
+
+# These are the source files that go into the shared library
+_ra_la_SOURCES =               \
+       ra.cc                   
+
+# magic flags
+_ra_la_LDFLAGS = $(NO_UNDEFINED) -module -avoid-version
+
+# link the library against some comon swig runtime code and the 
+# c++ standard library
+_ra_la_LIBADD =                        \
+       $(PYTHON_LDFLAGS)               \
+       $(GNURADIO_CORE_LIBS)           \
+       -lstdc++                        
+
+ra.cc ra.py: ra.i $(ALL_IFILES)
+       $(SWIG) $(SWIGPYTHONARGS) -module ra -o ra.cc $<
+
+# These headers get installed in ${prefix}/include/gnuradio
+grinclude_HEADERS =
+
+# These swig headers get installed in ${prefix}/include/gnuradio/swig
+swiginclude_HEADERS =                  \
+       $(LOCAL_IFILES)
+
+
+MOSTLYCLEANFILES = $(BUILT_SOURCES) *.pyc
+
+# Don't distribute output of swig
+dist-hook:
+       @for file in $(BUILT_SOURCES); do echo $(RM) $(distdir)/$$file; done
+       @for file in $(BUILT_SOURCES); do $(RM) $(distdir)/$$file; done
diff --git a/gr-radio-astronomy/src/lib/ra.i b/gr-radio-astronomy/src/lib/ra.i
new file mode 100644 (file)
index 0000000..15cfbfb
--- /dev/null
@@ -0,0 +1,45 @@
+/* -*- c++ -*- */
+
+%feature("autodoc", "1");              // generate python docstrings
+
+%include "exception.i"
+%import "gnuradio.i"                   // the common stuff
+
+%{
+#include "gnuradio_swig_bug_workaround.h"      // mandatory bug fix
+#include <stdexcept>
+%}
+
+// We'll need something like this if we add C++ blocks...
+// See the gr-howto-write-a-block tarball for examples
+
+// ----------------------------------------------------------------
+
+/*
+ * 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 ra_square_ff from python as ra.square_ff
+ */
+// GR_SWIG_BLOCK_MAGIC(ra,square_ff);
+
+// ra_square_ff_sptr ra_make_square_ff ();
+// 
+// class ra_square_ff : public gr_block
+// {
+// private:
+//   ra_square_ff ();
+// };
+// 
+// // ----------------------------------------------------------------
+// 
+// GR_SWIG_BLOCK_MAGIC(ra,square2_ff);
+// 
+// ra_square2_ff_sptr ra_make_square2_ff ();
+// 
+// class ra_square2_ff : public gr_sync_block
+// {
+// private:
+//   ra_square2_ff ();
+// };
diff --git a/gr-radio-astronomy/src/python/Makefile.am b/gr-radio-astronomy/src/python/Makefile.am
new file mode 100644 (file)
index 0000000..62706fc
--- /dev/null
@@ -0,0 +1,56 @@
+#
+# 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 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.
+# 
+
+include $(top_srcdir)/Makefile.common
+
+# Install this stuff so that it ends up as the gnuradio.ra module
+# This usually ends up at:
+#   ${prefix}/lib/python${python_version}/site-packages/gnuradio
+
+ourpythondir = $(grpythondir)
+ourlibdir    = $(grpyexecdir)
+
+# wxgui stuff here
+wxguipythondir  = $(grpythondir)/wxgui
+wxguilibdir     = $(grpyexecdir)/wxgui
+
+EXTRA_DIST = run_tests.in
+
+
+TESTS =                                \
+       run_tests
+
+
+noinst_PYTHON =                        \
+       qa_ra.py                        
+
+ourpython_PYTHON =                     \
+       local_calibrator.py
+
+wxguipython_PYTHON =                   \
+       ra_stripchartsink.py            \
+       ra_fftsink.py                   
+
+
+# and here for applications you want installed in prefix/bin
+bin_SCRIPTS =                          \
+       usrp_ra_receiver.py             \
+       usrp_psr_receiver.py
diff --git a/gr-radio-astronomy/src/python/local_calibrator.py b/gr-radio-astronomy/src/python/local_calibrator.py
new file mode 100755 (executable)
index 0000000..6c5fb4f
--- /dev/null
@@ -0,0 +1,149 @@
+#!/usr/bin/env python
+#
+# 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 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.
+# 
+
+import Numeric
+import math
+import ephem
+import time
+
+#
+# Simple class for allowing local definition of a calibration function
+#  for raw samples coming from the RA detector chain.  Each observatory
+#  is different, and rather than hacking up the main code in usrp_ra_receiver
+#  we define the appropriate function here.
+#
+# For example, one could calibrate the output in Janskys, rather than
+#  dB.
+#
+#
+
+def calib_default_total_power(data):
+    r = 10.0*math.log10(data)
+    return(r)
+
+def calib_numogate_ridge_observatory_total_power(data):
+
+    me = ephem.Observer()
+
+    #
+    # PyEphem wants lat/long as strings, rather than floats--took me quite
+    #  a long time to figure that out.  If they don't arrive as strings,
+    #  the calculations for sidereal time are complete garbage
+    #
+    me.long = str(-76.043)
+    me.lat = str(44.967)
+
+    me.date = ephem.now()
+    sidtime = me.sidereal_time()
+
+    foo = time.localtime()
+    if not "calib_prefix" in globals():
+        pfx = "./"
+    else:
+        pfx = globals()["calib_prefix"]
+    filenamestr = "%s/%04d%02d%02d%02d" % (pfx, foo.tm_year, 
+       foo.tm_mon, foo.tm_mday, foo.tm_hour)
+
+    rainbow_file = open (filenamestr+".tpdat","a")
+  
+    r = (math.sqrt(data) / 2048) * 1000.0
+    #r = calib_default_total_power(data)
+    inter = globals()["calib_decln"]
+    rainbow_file.write(str(ephem.hours(sidtime))+" "+str(r)+" "+str(inter)+"\n")
+    rainbow_file.close()
+    return(r)
+
+def calib_numogate_ridge_observatory_fft(data,l):
+
+    me = ephem.Observer()
+
+    #
+    # PyEphem wants lat/long as strings, rather than floats--took me quite
+    #  a long time to figure that out.  If they don't arrive as strings,
+    #  the calculations for sidereal time are complete garbage
+    #
+    me.long = str(-76.043)
+    me.lat = str(44.967)
+
+    me.date = ephem.now()
+    sidtime = me.sidereal_time()
+
+    foo = time.localtime()
+    
+    if not "calib_prefix" in globals():
+        pfx = "./"
+    else:
+        pfx = globals()["calib_prefix"]
+    filenamestr = "%s/%04d%02d%02d%02d" % (pfx, foo.tm_year, 
+       foo.tm_mon, foo.tm_mday, foo.tm_hour)
+
+    now = time.time()
+
+    if not "calib_then" in globals():
+        globals()["calib_then"] = now
+
+    delta = 5
+               
+    if (now - globals()["calib_then"]) >= delta:
+
+        globals()["calib_then"] = now
+        rainbow_file = open (filenamestr+".sdat","a")
+  
+        r = calib_default_fft(data,l)
+        inter = globals()["calib_decln"]
+        rainbow_file.write("data:"+str(ephem.hours(sidtime))+" "+str(inter)+" "+str(r)+"\n")
+        rainbow_file.close()
+        return(r)
+
+    return(data)
+
+def calib_default_fft(db,l):
+    return(db)
+
+#
+# We capture various parameters from the receive chain here, because
+#  they can affect the calibration equations.
+#
+#
+def calib_set_gain(gain):
+    globals()["calib_gain_setting"] = gain
+
+def calib_set_integ(integ):
+    globals()["calib_integ_setting"] = integ
+
+def calib_set_bw(bw):
+    globals()["calib_bw_setting"] = bw
+
+def calib_set_freq(freq):
+    globals()["calib_freq_setting"] = freq
+
+def calib_set_avg_alpha(alpha):
+    globals()["calib_avg_alpha"] = alpha
+
+def calib_set_interesting(inter):
+    globals()["calib_is_interesting"] = inter
+
+def calib_set_decln(dec):
+    globals()["calib_decln"] = dec
+
+def calib_set_prefix(pfx):
+    globals()["calib_prefix"] = pfx
diff --git a/gr-radio-astronomy/src/python/qa_ra.py b/gr-radio-astronomy/src/python/qa_ra.py
new file mode 100755 (executable)
index 0000000..4b24a1e
--- /dev/null
@@ -0,0 +1,38 @@
+#!/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 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.
+# 
+
+from gnuradio import gr, gr_unittest
+import ra
+
+class qa_ra (gr_unittest.TestCase):
+
+    def setUp (self):
+        self.fg = gr.flow_graph ()
+
+    def tearDown (self):
+        self.fg = None
+
+    def test_000_(self):          # ensure that we can load the module
+        pass
+        
+if __name__ == '__main__':
+    gr_unittest.main ()
diff --git a/gr-radio-astronomy/src/python/ra_fftsink.py b/gr-radio-astronomy/src/python/ra_fftsink.py
new file mode 100755 (executable)
index 0000000..213f4a7
--- /dev/null
@@ -0,0 +1,520 @@
+#!/usr/bin/env python
+#
+# 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 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.
+# 
+
+from gnuradio import gr, gru, window
+from gnuradio.wxgui import stdgui
+import wx
+import gnuradio.wxgui.plot as plot
+import Numeric
+import threading
+import math    
+import random
+
+default_ra_fftsink_size = (640,140)
+
+
+def default_cfunc(db,l):
+    return(db)
+
+
+class ra_fft_sink_base(object):
+    def __init__(self, input_is_real=False, baseband_freq=0, y_per_div=10, sc_y_per_div=0.5, ref_level=50, sc_ref_level=20,
+                 sample_rate=1, fft_size=512, fft_rate=15,
+                 average=False, avg_alpha=None, title='', peak_hold=False, cfunc=default_cfunc, xydfunc=None, interfunc=None):
+
+        # initialize common attributes
+        self.baseband_freq = baseband_freq
+        self.y_divs = 8
+        self.y_per_div=y_per_div
+        self.sc_y_per_div=sc_y_per_div
+        self.ref_level = ref_level
+        self.autoscale = False
+        self.sc_ref_level = sc_ref_level
+        self.sample_rate = sample_rate
+        self.fft_size = fft_size
+        self.fft_rate = fft_rate
+        self.binwidth = float(sample_rate/fft_size)
+        self.average = average
+        self.cfunc = cfunc
+        self.xydfunc = xydfunc
+        self.interfunc = interfunc
+        if avg_alpha is None:
+            self.avg_alpha = 2.0 / fft_rate
+        else:
+            self.avg_alpha = avg_alpha
+        self.title = title
+        self.peak_hold = peak_hold
+        self.input_is_real = input_is_real
+        self.msgq = gr.msg_queue(2)         # queue that holds a maximum of 2 messages
+
+    def set_y_per_div(self, y_per_div):
+        self.y_per_div = y_per_div
+
+
+    def set_ref_level(self, ref_level):
+        self.ref_level = ref_level
+
+    def set_average(self, average):
+        self.average = average
+        if average:
+            self.avg.set_taps(self.avg_alpha)
+            self.set_peak_hold(False)
+        else:
+            self.avg.set_taps(1.0)
+
+    def set_peak_hold(self, enable):
+        self.peak_hold = enable
+        if enable:
+            self.set_average(False)
+        self.win.set_peak_hold(enable)
+
+    def set_autoscale(self, auto):
+        self.autoscale = auto
+
+    def set_avg_alpha(self, avg_alpha):
+        self.avg_alpha = avg_alpha
+
+    def set_baseband_freq(self, baseband_freq):
+        self.baseband_freq = baseband_freq
+        
+
+class ra_fft_sink_f(gr.hier_block, ra_fft_sink_base):
+    def __init__(self, fg, parent, baseband_freq=0,
+                 y_per_div=10, sc_y_per_div=0.5, sc_ref_level=40, ref_level=50, sample_rate=1, fft_size=512,
+                 fft_rate=15, average=False, avg_alpha=None, title='',
+                 size=default_ra_fftsink_size, peak_hold=False, cfunc=default_cfunc, xydfunc=None, interfunc=None):
+
+        ra_fft_sink_base.__init__(self, input_is_real=True, baseband_freq=baseband_freq,
+                               y_per_div=y_per_div, sc_y_per_div=sc_y_per_div,
+                               sc_ref_level=sc_ref_level, ref_level=ref_level,
+                               sample_rate=sample_rate, fft_size=fft_size,
+                               fft_rate=fft_rate,
+                               average=average, avg_alpha=avg_alpha, title=title,
+                               peak_hold=peak_hold, cfunc=cfunc, 
+                               xydfunc=xydfunc, interfunc=interfunc)
+                               
+        self.binwidth = float(sample_rate/2.0)/float(fft_size)
+        s2p = gr.serial_to_parallel(gr.sizeof_float, fft_size)
+        one_in_n = gr.keep_one_in_n(gr.sizeof_float * fft_size,
+                                    max(1, int(sample_rate/fft_size/fft_rate)))
+        mywindow = window.blackmanharris(fft_size)
+        fft = gr.fft_vfc(fft_size, True, mywindow)
+        c2mag = gr.complex_to_mag(fft_size)
+        self.avg = gr.single_pole_iir_filter_ff(1.0, fft_size)
+        log = gr.nlog10_ff(20, fft_size, -20*math.log10(fft_size))
+        sink = gr.message_sink(gr.sizeof_float * fft_size, self.msgq, True)
+
+        fg.connect (s2p, one_in_n, fft, c2mag, self.avg, log, sink)
+        gr.hier_block.__init__(self, fg, s2p, sink)
+
+        self.win = fft_window(self, parent, size=size)
+        self.set_average(self.average)
+
+class ra_fft_sink_c(gr.hier_block, ra_fft_sink_base):
+    def __init__(self, fg, parent, baseband_freq=0,
+                 y_per_div=10, sc_y_per_div=0.5, sc_ref_level=40,
+                 ref_level=50, sample_rate=1, fft_size=512,
+                 fft_rate=15, average=False, avg_alpha=None, title='',
+                 size=default_ra_fftsink_size, peak_hold=False, cfunc=default_cfunc, xydfunc=None, interfunc=None):
+
+        ra_fft_sink_base.__init__(self, input_is_real=False, baseband_freq=baseband_freq,
+                               y_per_div=y_per_div, sc_y_per_div=sc_y_per_div,
+                               sc_ref_level=sc_ref_level, ref_level=ref_level,
+                               sample_rate=sample_rate, fft_size=fft_size,
+                               fft_rate=fft_rate,
+                               average=average, avg_alpha=avg_alpha, 
+                               title=title,
+                               peak_hold=peak_hold, cfunc=cfunc, 
+                               xydfunc=xydfunc, interfunc=interfunc)
+
+        s2p = gr.serial_to_parallel(gr.sizeof_gr_complex, fft_size)
+        one_in_n = gr.keep_one_in_n(gr.sizeof_gr_complex * fft_size,
+                                    max(1, int(sample_rate/fft_size/fft_rate)))
+        mywindow = window.blackmanharris(fft_size)
+        fft = gr.fft_vcc(fft_size, True, mywindow)
+        c2mag = gr.complex_to_mag(fft_size)
+        self.avg = gr.single_pole_iir_filter_ff(1.0, fft_size)
+        log = gr.nlog10_ff(20, fft_size, -20*math.log10(fft_size))
+        sink = gr.message_sink(gr.sizeof_float * fft_size, self.msgq, True)
+
+        fg.connect(s2p, one_in_n, fft, c2mag, self.avg, log, sink)
+        gr.hier_block.__init__(self, fg, s2p, sink)
+
+        self.win = fft_window(self, parent, size=size)
+        self.set_average(self.average)
+
+
+# ------------------------------------------------------------------------
+
+myDATA_EVENT = wx.NewEventType()
+EVT_DATA_EVENT = wx.PyEventBinder (myDATA_EVENT, 0)
+
+
+class DataEvent(wx.PyEvent):
+    def __init__(self, data):
+        wx.PyEvent.__init__(self)
+        self.SetEventType (myDATA_EVENT)
+        self.data = data
+
+    def Clone (self): 
+        self.__class__ (self.GetId())
+
+
+class input_watcher (threading.Thread):
+    def __init__ (self, msgq, fft_size, event_receiver, **kwds):
+        threading.Thread.__init__ (self, **kwds)
+        self.setDaemon (1)
+        self.msgq = msgq
+        self.fft_size = fft_size
+        self.event_receiver = event_receiver
+        self.keep_running = True
+        self.start ()
+
+    def run (self):
+        while (self.keep_running):
+            msg = self.msgq.delete_head()  # blocking read of message queue
+            itemsize = int(msg.arg1())
+            nitems = int(msg.arg2())
+
+            s = msg.to_string()            # get the body of the msg as a string
+
+            # There may be more than one FFT frame in the message.
+            # If so, we take only the last one
+            if nitems > 1:
+                start = itemsize * (nitems - 1)
+                s = s[start:start+itemsize]
+
+            complex_data = Numeric.fromstring (s, Numeric.Float32)
+            de = DataEvent (complex_data)
+            wx.PostEvent (self.event_receiver, de)
+            del de
+    
+
+class fft_window (plot.PlotCanvas):
+    def __init__ (self, ra_fftsink, parent, id = -1,
+                  pos = wx.DefaultPosition, size = wx.DefaultSize,
+                  style = wx.DEFAULT_FRAME_STYLE, name = ""):
+        plot.PlotCanvas.__init__ (self, parent, id, pos, size, style, name)
+
+        self.y_range = None
+        self.ra_fftsink = ra_fftsink
+        self.peak_hold = False
+        self.peak_vals = None
+
+        self.SetEnableGrid (True)
+        # self.SetEnableZoom (True)
+        # self.SetBackgroundColour ('black')
+        
+        self.build_popup_menu()
+        
+        EVT_DATA_EVENT (self, self.set_data)
+        wx.EVT_CLOSE (self, self.on_close_window)
+        self.Bind(wx.EVT_RIGHT_UP, self.on_right_click)
+        self.Bind(wx.EVT_MOTION, self.on_motion)
+        self.Bind(wx.EVT_LEFT_UP, self.on_left_click)
+
+        self.input_watcher = input_watcher(ra_fftsink.msgq, ra_fftsink.fft_size, self)
+
+
+    def on_close_window (self, event):
+        print "fft_window:on_close_window"
+        self.keep_running = False
+
+            
+    def set_data (self, evt):
+        calc_min = 99e10
+        calc_max = -99e10
+        dB = evt.data
+        L = len (dB)
+
+        calc_min = min(dB)
+        calc_max = max(dB)
+        
+        dB = self.ra_fftsink.cfunc(dB, L)
+
+        if self.peak_hold:
+            if self.peak_vals is None:
+                self.peak_vals = dB
+            else:
+                self.peak_vals = Numeric.maximum(dB, self.peak_vals)
+                dB = self.peak_vals
+
+        x = max(abs(self.ra_fftsink.sample_rate), abs(self.ra_fftsink.baseband_freq))
+        if x >= 1e9:
+            sf = 1e-9
+            units = "GHz"
+        elif x >= 1e6:
+            sf = 1e-6
+            units = "MHz"
+        elif x >= 1e3:
+            sf = 1e-3
+            units = "kHz"
+        else:
+            sf = 1.0
+            units = "Hz"
+
+        if self.ra_fftsink.input_is_real:     # only plot 1/2 the points
+            x_vals = ((Numeric.arrayrange (L/2)
+                       * (self.ra_fftsink.sample_rate * sf / L))
+                      + self.ra_fftsink.baseband_freq * sf)
+            points = Numeric.zeros((len(x_vals), 2), Numeric.Float64)
+            points[:,0] = x_vals
+            points[:,1] = dB[0:L/2]
+        else:
+            # the "negative freqs" are in the second half of the array
+            x_vals = ((Numeric.arrayrange (-L/2, L/2)
+                       * (self.ra_fftsink.sample_rate * sf / L))
+                      + self.ra_fftsink.baseband_freq * sf)
+            points = Numeric.zeros((len(x_vals), 2), Numeric.Float64)
+            points[:,0] = x_vals
+            points[:,1] = Numeric.concatenate ((dB[L/2:], dB[0:L/2]))
+
+        lines = plot.PolyLine (points, colour='BLUE')
+        graphics = plot.PlotGraphics ([lines],
+                                      title=self.ra_fftsink.title,
+                                      xLabel = units, yLabel = "dB")
+
+        self.Draw (graphics, xAxis=None, yAxis=self.y_range)
+        d = calc_max - calc_min
+        d *= 0.1
+        if self.ra_fftsink.autoscale == True:
+            self.y_range = self._axisInterval ('min', calc_min-d, calc_max+d)
+        else:
+            self.update_y_range ()
+
+    def set_peak_hold(self, enable):
+        self.peak_hold = enable
+        self.peak_vals = None
+
+    def update_y_range (self):
+        ymax = self.ra_fftsink.ref_level
+        ymin = self.ra_fftsink.ref_level - self.ra_fftsink.y_per_div * self.ra_fftsink.y_divs
+        self.y_range = self._axisInterval ('min', ymin, ymax)
+
+    def on_average(self, evt):
+        # print "on_average"
+        self.ra_fftsink.set_average(evt.IsChecked())
+
+    def on_peak_hold(self, evt):
+        # print "on_peak_hold"
+        self.ra_fftsink.set_peak_hold(evt.IsChecked())
+
+    def on_autoscale(self, evt):
+        self.ra_fftsink.set_autoscale(evt.IsChecked())
+
+    def on_incr_ref_level(self, evt):
+        # print "on_incr_ref_level"
+        self.ra_fftsink.set_ref_level(self.ra_fftsink.ref_level
+                                   + self.ra_fftsink.y_per_div)
+
+    def on_decr_ref_level(self, evt):
+        # print "on_decr_ref_level"
+        self.ra_fftsink.set_ref_level(self.ra_fftsink.ref_level
+                                   - self.ra_fftsink.y_per_div)
+
+    def on_incr_y_per_div(self, evt):
+        # print "on_incr_y_per_div"
+        self.ra_fftsink.set_y_per_div(next_up(self.ra_fftsink.y_per_div, (0.5,1,2,5,10)))
+
+    def on_decr_y_per_div(self, evt):
+        # print "on_decr_y_per_div"
+        self.ra_fftsink.set_y_per_div(next_down(self.ra_fftsink.y_per_div, (0.5,1,2,5,10)))
+
+    def on_y_per_div(self, evt):
+        # print "on_y_per_div"
+        Id = evt.GetId()
+        if Id == self.id_y_per_div_1:
+            self.ra_fftsink.set_y_per_div(0.5)
+        elif Id == self.id_y_per_div_2:
+            self.ra_fftsink.set_y_per_div(1.0)
+        elif Id == self.id_y_per_div_5:
+            self.ra_fftsink.set_y_per_div(2.0)
+        elif Id == self.id_y_per_div_10:
+            self.ra_fftsink.set_y_per_div(5.0)
+        elif Id == self.id_y_per_div_20:
+            self.ra_fftsink.set_y_per_div(10)
+
+        
+    def on_right_click(self, event):
+        menu = self.popup_menu
+        for id, pred in self.checkmarks.items():
+            item = menu.FindItemById(id)
+            item.Check(pred())
+        self.PopupMenu(menu, event.GetPosition())
+
+    def on_motion(self, event):
+        if not self.ra_fftsink.xydfunc == None:
+            xy = self.GetXY(event)
+            self.ra_fftsink.xydfunc (xy)
+
+    def on_left_click(self, event):
+        if not self.ra_fftsink.interfunc == None:
+            xy = self.GetXY(event)
+            self.ra_fftsink.interfunc (xy[0])
+
+    def build_popup_menu(self):
+        self.id_incr_ref_level = wx.NewId()
+        self.id_decr_ref_level = wx.NewId()
+        self.id_autoscale = wx.NewId()
+        self.id_incr_y_per_div = wx.NewId()
+        self.id_decr_y_per_div = wx.NewId()
+        self.id_y_per_div_1 = wx.NewId()
+        self.id_y_per_div_2 = wx.NewId()
+        self.id_y_per_div_5 = wx.NewId()
+        self.id_y_per_div_10 = wx.NewId()
+        self.id_y_per_div_20 = wx.NewId()
+        self.id_average = wx.NewId()
+        self.id_peak_hold = wx.NewId()
+
+        self.Bind(wx.EVT_MENU, self.on_average, id=self.id_average)
+        self.Bind(wx.EVT_MENU, self.on_peak_hold, id=self.id_peak_hold)
+        self.Bind(wx.EVT_MENU, self.on_autoscale, id=self.id_autoscale)
+        self.Bind(wx.EVT_MENU, self.on_incr_ref_level, id=self.id_incr_ref_level)
+        self.Bind(wx.EVT_MENU, self.on_decr_ref_level, id=self.id_decr_ref_level)
+        self.Bind(wx.EVT_MENU, self.on_incr_y_per_div, id=self.id_incr_y_per_div)
+        self.Bind(wx.EVT_MENU, self.on_decr_y_per_div, id=self.id_decr_y_per_div)
+        self.Bind(wx.EVT_MENU, self.on_y_per_div, id=self.id_y_per_div_1)
+        self.Bind(wx.EVT_MENU, self.on_y_per_div, id=self.id_y_per_div_2)
+        self.Bind(wx.EVT_MENU, self.on_y_per_div, id=self.id_y_per_div_5)
+        self.Bind(wx.EVT_MENU, self.on_y_per_div, id=self.id_y_per_div_10)
+        self.Bind(wx.EVT_MENU, self.on_y_per_div, id=self.id_y_per_div_20)
+
+
+        # make a menu
+        menu = wx.Menu()
+        self.popup_menu = menu
+        menu.AppendCheckItem(self.id_average, "Average")
+        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")
+        # menu.Append(self.id_incr_y_per_div, "Incr dB/div")
+        # menu.Append(self.id_decr_y_per_div, "Decr dB/div")
+        menu.AppendSeparator()
+        # we'd use RadioItems for these, but they're not supported on Mac
+        menu.AppendCheckItem(self.id_autoscale, "Autoscale")
+        menu.AppendCheckItem(self.id_y_per_div_1, "0.5 dB/div")
+        menu.AppendCheckItem(self.id_y_per_div_2, "1.0 dB/div")
+        menu.AppendCheckItem(self.id_y_per_div_5, "2.0 dB/div")
+        menu.AppendCheckItem(self.id_y_per_div_10, "5.0 dB/div")
+        menu.AppendCheckItem(self.id_y_per_div_20, "10.0 dB/div")
+
+        self.checkmarks = {
+            self.id_average : lambda : self.ra_fftsink.average,
+            self.id_peak_hold : lambda : self.ra_fftsink.peak_hold,
+            self.id_autoscale : lambda : self.ra_fftsink.autoscale,
+            self.id_y_per_div_1 : lambda : self.ra_fftsink.y_per_div == 0.5,
+            self.id_y_per_div_2 : lambda : self.ra_fftsink.y_per_div == 1.0,
+            self.id_y_per_div_5 : lambda : self.ra_fftsink.y_per_div == 2.0,
+            self.id_y_per_div_10 : lambda : self.ra_fftsink.y_per_div == 5.0,
+            self.id_y_per_div_20 : lambda : self.ra_fftsink.y_per_div == 10.0,
+            }
+
+
+def next_up(v, seq):
+    """
+    Return the first item in seq that is > v.
+    """
+    for s in seq:
+        if s > v:
+            return s
+    return v
+
+def next_down(v, seq):
+    """
+    Return the last item in seq that is < v.
+    """
+    rseq = list(seq[:])
+    rseq.reverse()
+
+    for s in rseq:
+        if s < v:
+            return s
+    return v
+
+
+# ----------------------------------------------------------------
+#                    Deprecated interfaces
+# ----------------------------------------------------------------
+
+# returns (block, win).
+#   block requires a single input stream of float
+#   win is a subclass of wxWindow
+
+def make_ra_fft_sink_f(fg, parent, title, fft_size, input_rate, ymin = 0, ymax=50):
+    
+    block = ra_fft_sink_f(fg, parent, title=title, fft_size=fft_size, sample_rate=input_rate,
+                       y_per_div=(ymax - ymin)/8, ref_level=ymax)
+    return (block, block.win)
+
+# returns (block, win).
+#   block requires a single input stream of gr_complex
+#   win is a subclass of wxWindow
+
+def make_ra_fft_sink_c(fg, parent, title, fft_size, input_rate, ymin=0, ymax=50):
+    block = ra_fft_sink_c(fg, parent, title=title, fft_size=fft_size, sample_rate=input_rate,
+                       y_per_div=(ymax - ymin)/8, ref_level=ymax)
+    return (block, block.win)
+
+
+# ----------------------------------------------------------------
+# Standalone test app
+# ----------------------------------------------------------------
+
+class test_app_flow_graph (stdgui.gui_flow_graph):
+    def __init__(self, frame, panel, vbox, argv):
+        stdgui.gui_flow_graph.__init__ (self, frame, panel, vbox, argv)
+
+        fft_size = 256
+
+        # build our flow graph
+        input_rate = 20.000e3
+
+        # Generate a complex sinusoid
+        src1 = gr.sig_source_c (input_rate, gr.GR_SIN_WAVE, 5.75e3, 1000)
+        #src1 = gr.sig_source_c (input_rate, gr.GR_CONST_WAVE, 5.75e3, 1000)
+
+        # We add these throttle blocks so that this demo doesn't
+        # suck down all the CPU available.  Normally you wouldn't use these.
+        thr1 = gr.throttle(gr.sizeof_gr_complex, input_rate)
+
+        sink1 = ra_fft_sink_c (self, panel, title="Complex Data", fft_size=fft_size,
+                            sample_rate=input_rate, baseband_freq=100e3,
+                            ref_level=60, y_per_div=10)
+        vbox.Add (sink1.win, 1, wx.EXPAND)
+        self.connect (src1, thr1, sink1)
+
+        src2 = gr.sig_source_f (input_rate, gr.GR_SIN_WAVE, 5.75e3, 1000)
+        #src2 = gr.sig_source_f (input_rate, gr.GR_CONST_WAVE, 5.75e3, 1000)
+        thr2 = gr.throttle(gr.sizeof_float, input_rate)
+        sink2 = ra_fft_sink_f (self, panel, title="Real Data", fft_size=fft_size*2,
+                            sample_rate=input_rate, baseband_freq=100e3,
+                            ref_level=60, y_per_div=10)
+        vbox.Add (sink2.win, 1, wx.EXPAND)
+        self.connect (src2, thr2, sink2)
+
+def main ():
+    app = stdgui.stdapp (test_app_flow_graph,
+                         "FFT Sink Test App")
+    app.MainLoop ()
+
+if __name__ == '__main__':
+    main ()
diff --git a/gr-radio-astronomy/src/python/ra_stripchartsink.py b/gr-radio-astronomy/src/python/ra_stripchartsink.py
new file mode 100755 (executable)
index 0000000..112a0d6
--- /dev/null
@@ -0,0 +1,399 @@
+#!/usr/bin/env python
+#
+# 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 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.
+# 
+
+from gnuradio import gr, gru
+from gnuradio.wxgui import stdgui
+import wx
+import gnuradio.wxgui.plot as plot
+import Numeric
+import threading
+import math    
+import ephem
+import time
+
+default_stripchartsink_size = (640,140)
+global_yvalues = []
+
+def default_cfunc(datum):
+    return(datum)
+
+class stripchart_sink_base(object):
+    def __init__(self, input_is_real=False, y_per_div=10, ref_level=50,
+                 sample_rate=1, stripsize=4,
+                 title='',xlabel="X", ylabel="Y", divbase=0.025,
+                 cfunc=default_cfunc, parallel=False, scaling=1.0, autoscale=False):
+
+        # initialize common attributes
+        self.y_divs = 8
+        self.y_per_div=y_per_div
+        self.ref_level = ref_level
+        self.autoscale = autoscale
+        self.sample_rate = sample_rate
+        self.parallel = parallel
+        self.title = title
+        self.xlabel = xlabel
+        self.ylabel = ylabel
+        self.divbase = divbase
+        self.scaling = scaling
+        self.cfunc = cfunc
+        self.input_is_real = input_is_real
+        self.msgq = gr.msg_queue(2)         # queue that holds a maximum of 2 messages
+        self.vector=Numeric.zeros(stripsize,Numeric.Float64)
+        self.wcnt = 0
+        self.timecnt = 0
+        self.stripsize=stripsize
+
+    def set_y_per_div(self, y_per_div):
+        self.y_per_div = y_per_div
+
+    def set_ref_level(self, ref_level):
+        self.ref_level = ref_level
+
+    def set_autoscale(self, auto):
+        self.autoscale = auto
+
+class stripchart_sink_f(gr.hier_block, stripchart_sink_base):
+    def __init__(self, fg, parent,
+                 y_per_div=10, ref_level=50, sample_rate=1,
+                 title='', stripsize=4,
+                 size=default_stripchartsink_size,xlabel="X", 
+                 ylabel="Y", divbase=0.025, cfunc=default_cfunc,
+                 parallel=False, scaling=1.0, autoscale=False):
+
+        stripchart_sink_base.__init__(self, input_is_real=True,
+                               y_per_div=y_per_div, ref_level=ref_level,
+                               sample_rate=sample_rate,
+                               stripsize=stripsize,
+                               xlabel=xlabel, ylabel=ylabel, 
+                               divbase=divbase, title=title,
+                               cfunc=cfunc, parallel=parallel, 
+                               scaling=scaling, autoscale=autoscale)
+                               
+        if (parallel == True):
+            one = gr.keep_one_in_n (gr.sizeof_float*stripsize, 1)
+            sink = gr.message_sink(gr.sizeof_float*stripsize, self.msgq, True)
+        else:
+            one = gr.keep_one_in_n (gr.sizeof_float, 1)
+            sink = gr.message_sink(gr.sizeof_float, self.msgq, True)
+        fg.connect (one, sink)
+
+        gr.hier_block.__init__(self, fg, one, sink)
+
+        self.win = stripchart_window(self, parent, size=size)
+
+
+
+# ------------------------------------------------------------------------
+
+myDATA_EVENT = wx.NewEventType()
+EVT_DATA_EVENT = wx.PyEventBinder (myDATA_EVENT, 0)
+
+
+class DataEvent(wx.PyEvent):
+    def __init__(self, data):
+        wx.PyEvent.__init__(self)
+        self.SetEventType (myDATA_EVENT)
+        self.data = data
+
+    def Clone (self): 
+        self.__class__ (self.GetId())
+
+
+class input_watcher (threading.Thread):
+    def __init__ (self, msgq, evsize, event_receiver, **kwds):
+        threading.Thread.__init__ (self, **kwds)
+        self.setDaemon (1)
+        self.msgq = msgq
+        self.evsize = evsize
+        self.event_receiver = event_receiver
+        self.keep_running = True
+        self.start ()
+
+    def run (self):
+        while (self.keep_running):
+            msg = self.msgq.delete_head()  # blocking read of message queue
+            itemsize = int(msg.arg1())
+            nitems = int(msg.arg2())
+
+            s = msg.to_string()            # get the body of the msg as a string
+
+            # There may be more than one frame in the message.
+            # If so, we take only the last one
+            if nitems > 1:
+                start = itemsize * (nitems - 1)
+                s = s[start:start+itemsize]
+
+            complex_data = Numeric.fromstring (s, Numeric.Float32)
+            de = DataEvent (complex_data)
+            wx.PostEvent (self.event_receiver, de)
+            del de
+
+class stripchart_window(plot.PlotCanvas):
+    def __init__ (self, stripchartsink, parent, id = -1,
+                  pos = wx.DefaultPosition, size = wx.DefaultSize,
+                  style = wx.DEFAULT_FRAME_STYLE, name = ""):
+        plot.PlotCanvas.__init__ (self, parent, id, pos, size, style, name)
+
+        self.y_range = None
+        self.stripchartsink = stripchartsink
+
+        self.SetEnableGrid (True)
+        # self.SetEnableZoom (True)
+        # self.SetBackgroundColour ('black')
+        
+        self.build_popup_menu()
+        
+        EVT_DATA_EVENT (self, self.set_data)
+
+        wx.EVT_CLOSE (self, self.on_close_window)
+        self.Bind(wx.EVT_RIGHT_UP, self.on_right_click)
+
+        self.input_watcher = input_watcher(stripchartsink.msgq, 1, self)
+
+
+    def on_close_window (self, event):
+        print "stripchart_window:on_close_window"
+        self.keep_running = False
+
+
+    def set_data (self, evt):
+        indata = evt.data
+        L = len (indata)
+
+        calc_min = min(indata)
+        calc_max = max(indata)
+        d = calc_max - calc_min
+        d *= 0.1
+        if self.stripchartsink.autoscale == True and self.stripchartsink.parallel == True:
+            self.y_range = self._axisInterval ('min', calc_min-d, calc_max+d)
+
+        if (self.stripchartsink.parallel != True):
+            indata = self.stripchartsink.cfunc(indata)
+
+        N = self.stripchartsink.stripsize
+        if self.stripchartsink.parallel != True:
+           for i in range(1,N):
+                pooey = N-i
+                self.stripchartsink.vector[pooey] = self.stripchartsink.vector[pooey-1]
+    
+            self.stripchartsink.vector[0] = indata
+
+        else:
+            self.stripchartsink.vector = indata
+
+        if self.stripchartsink.parallel == True:
+            avg = 0
+            for i in range(0,self.stripchartsink.stripsize):
+                if self.stripchartsink.vector[i] > 0:
+                    avg += self.stripchartsink.vector[i]
+                if self.stripchartsink.vector[i] < calc_min:
+                    calc_min = self.stripchartsink.vector[i]
+                if self.stripchartsink.vector[i] > calc_max:
+                    calc_max = self.stripchartsink.vector[i]
+
+            avg /= self.stripchartsink.stripsize
+            markers = []
+            placedmarkers = 0
+            for i in range(0,self.stripchartsink.stripsize):
+                if (self.stripchartsink.vector[i] > 0 and
+                    self.stripchartsink.vector[i] > (avg*5)):
+                       markers.append((i*self.stripchartsink.scaling,
+                       self.stripchartsink.vector[i]))
+                       placedmarkers += 1
+            
+        points = Numeric.zeros((N,2), Numeric.Float64)
+        for i in range(0,N):
+            if self.stripchartsink.scaling == 1.0:
+                points[i,0] = i
+            else:
+                points[i,0] = i * self.stripchartsink.scaling
+            points[i,1] = self.stripchartsink.vector[i]
+
+        if self.stripchartsink.parallel == True and placedmarkers > 1:
+            for i in range(0,N):
+                self.stripchartsink.vector[i] = 0
+
+            marks = plot.PolyMarker(markers, colour='BLACK', marker='triangle_down')
+
+        lines = plot.PolyLine (points, colour='RED')
+
+        # Temporary--I'm find the markers distracting
+        placedmarkers = 0
+        xlab = self.stripchartsink.xlabel
+        ylab = self.stripchartsink.ylabel
+        if (self.stripchartsink.parallel == False) or (placedmarkers <= 1):
+            graphics = plot.PlotGraphics ([lines],
+                                      title=self.stripchartsink.title,
+                                      xLabel = xlab, yLabel = ylab)
+
+        else:
+            graphics = plot.PlotGraphics ([lines,marks],
+                                      title=self.stripchartsink.title,
+                                      xLabel = xlab, yLabel = ylab)
+
+        self.Draw (graphics, xAxis=None, yAxis=self.y_range)
+
+        if self.stripchartsink.autoscale == False or self.stripchartsink.parallel == False:
+            self.update_y_range ()
+
+
+    def update_y_range (self):
+        ymax = self.stripchartsink.ref_level
+        ymin = self.stripchartsink.ref_level - self.stripchartsink.y_per_div * self.stripchartsink.y_divs
+        self.y_range = self._axisInterval ('min', ymin, ymax)
+
+    def on_incr_ref_level(self, evt):
+        # print "on_incr_ref_level"
+        self.stripchartsink.set_ref_level(self.stripchartsink.ref_level
+                                   + self.stripchartsink.y_per_div)
+
+    def on_decr_ref_level(self, evt):
+        # print "on_decr_ref_level"
+        self.stripchartsink.set_ref_level(self.stripchartsink.ref_level
+                                   - self.stripchartsink.y_per_div)
+
+    def on_autoscale(self, evt):
+        self.stripchartsink.set_autoscale(evt.IsChecked())
+
+    def on_incr_y_per_div(self, evt):
+        divbase = self.stripchartsink.divbase
+        x1 = 1 * divbase
+        x2 = 2 * divbase
+        x4 = 4 * divbase
+        x10 = 10 * divbase
+        x20 = 20 * divbase
+        # print "on_incr_y_per_div"
+        self.stripchartsink.set_y_per_div(next_up(self.stripchartsink.y_per_div, (x1,x2,x4,x10,x20)))
+
+    def on_decr_y_per_div(self, evt):
+        # print "on_decr_y_per_div"
+        divbase = self.stripchartsink.divbase
+        x1 = 1 * divbase
+        x2 = 2 * divbase
+        x4 = 4 * divbase
+        x10 = 10 * divbase
+        x20 = 20 * divbase
+        self.stripchartsink.set_y_per_div(next_down(self.stripchartsink.y_per_div, (x1,x2,x4,x10,x20)))
+
+    def on_y_per_div(self, evt):
+        # print "on_y_per_div"
+        divbase=self.stripchartsink.divbase
+        Id = evt.GetId()
+        if Id == self.id_y_per_div_1:
+            self.stripchartsink.set_y_per_div(1*divbase)
+        elif Id == self.id_y_per_div_2:
+            self.stripchartsink.set_y_per_div(2*divbase)
+        elif Id == self.id_y_per_div_5:
+            self.stripchartsink.set_y_per_div(4*divbase)
+        elif Id == self.id_y_per_div_10:
+            self.stripchartsink.set_y_per_div(10*divbase)
+        elif Id == self.id_y_per_div_20:
+            self.stripchartsink.set_y_per_div(20*divbase)
+
+        
+    def on_right_click(self, event):
+        menu = self.popup_menu
+        for id, pred in self.checkmarks.items():
+            item = menu.FindItemById(id)
+            item.Check(pred())
+        self.PopupMenu(menu, event.GetPosition())
+
+
+    def build_popup_menu(self):
+        divbase=self.stripchartsink.divbase
+        self.id_incr_ref_level = wx.NewId()
+        self.id_decr_ref_level = wx.NewId()
+        self.id_autoscale = wx.NewId()
+        self.id_incr_y_per_div = wx.NewId()
+        self.id_decr_y_per_div = wx.NewId()
+        self.id_y_per_div_1 = wx.NewId()
+        self.id_y_per_div_2 = wx.NewId()
+        self.id_y_per_div_5 = wx.NewId()
+        self.id_y_per_div_10 = wx.NewId()
+        self.id_y_per_div_20 = wx.NewId()
+
+        self.Bind(wx.EVT_MENU, self.on_incr_ref_level, id=self.id_incr_ref_level)
+        self.Bind(wx.EVT_MENU, self.on_decr_ref_level, id=self.id_decr_ref_level)
+        self.Bind(wx.EVT_MENU, self.on_autoscale, id=self.id_autoscale)
+        self.Bind(wx.EVT_MENU, self.on_incr_y_per_div, id=self.id_incr_y_per_div)
+        self.Bind(wx.EVT_MENU, self.on_decr_y_per_div, id=self.id_decr_y_per_div)
+        self.Bind(wx.EVT_MENU, self.on_y_per_div, id=self.id_y_per_div_1)
+        self.Bind(wx.EVT_MENU, self.on_y_per_div, id=self.id_y_per_div_2)
+        self.Bind(wx.EVT_MENU, self.on_y_per_div, id=self.id_y_per_div_5)
+        self.Bind(wx.EVT_MENU, self.on_y_per_div, id=self.id_y_per_div_10)
+        self.Bind(wx.EVT_MENU, self.on_y_per_div, id=self.id_y_per_div_20)
+
+
+        # make a menu
+        menu = wx.Menu()
+        self.popup_menu = menu
+        menu.Append(self.id_incr_ref_level, "Incr Ref Level")
+        menu.Append(self.id_decr_ref_level, "Decr Ref Level")
+        menu.AppendSeparator()
+        menu.AppendCheckItem(self.id_autoscale, "Auto Scale")
+        # we'd use RadioItems for these, but they're not supported on Mac
+        v = 1.0*divbase
+        s = "%.3f" % v
+        menu.AppendCheckItem(self.id_y_per_div_1, s)
+        v = 2.0*divbase
+        s = "%.3f" % v
+        menu.AppendCheckItem(self.id_y_per_div_2, s)
+        v = 4.0*divbase
+        s = "%.3f" % v
+        menu.AppendCheckItem(self.id_y_per_div_5, s)
+        v = 10*divbase
+        s = "%.3f" % v
+        menu.AppendCheckItem(self.id_y_per_div_10, s)
+        v = 20*divbase
+        s = "%.3f" % v
+        menu.AppendCheckItem(self.id_y_per_div_20, s)
+
+        self.checkmarks = {
+            self.id_autoscale : lambda : self.stripchartsink.autoscale,
+            self.id_y_per_div_1 : lambda : self.stripchartsink.y_per_div == 1*divbase,
+            self.id_y_per_div_2 : lambda : self.stripchartsink.y_per_div == 2*divbase,
+            self.id_y_per_div_5 : lambda : self.stripchartsink.y_per_div == 4*divbase,
+            self.id_y_per_div_10 : lambda : self.stripchartsink.y_per_div == 10*divbase,
+            self.id_y_per_div_20 : lambda : self.stripchartsink.y_per_div == 20*divbase,
+            }
+
+
+def next_up(v, seq):
+    """
+    Return the first item in seq that is > v.
+    """
+    for s in seq:
+        if s > v:
+            return s
+    return v
+
+def next_down(v, seq):
+    """
+    Return the last item in seq that is < v.
+    """
+    rseq = list(seq[:])
+    rseq.reverse()
+
+    for s in rseq:
+        if s < v:
+            return s
+    return v
diff --git a/gr-radio-astronomy/src/python/run_tests.in b/gr-radio-astronomy/src/python/run_tests.in
new file mode 100644 (file)
index 0000000..5156882
--- /dev/null
@@ -0,0 +1,47 @@
+#!/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@/gr-radio-astronomy/src/lib
+# Where to look in the src tree for swig generated python code
+libsrc=@abs_top_srcdir@/gr-radio-astronomy/src/lib
+# Where to look in the src tree for hand written python code
+py=@abs_top_srcdir@/gr-radio-astronomy/src/python
+
+# Where to look for GNU Radio python modules in current build tree
+# FIXME this is wrong on a distcheck.  We really need to ask gnuradio-core
+# where it put its python files.
+grpythonbld=@abs_top_builddir@/gnuradio-core/src/python/:@abs_top_builddir@/gnuradio-core/src/lib/swig/:@abs_top_builddir@/gnuradio-core/src/lib/swig/.libs
+
+PYTHONPATH="$grpythonbld:$libbld:$libbld/.libs:$libsrc:$py:$PYTHONPATH"
+export PYTHONPATH
+
+#
+# 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-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.
diff --git a/gr-radio-astronomy/src/python/usrp_psr_receiver.py b/gr-radio-astronomy/src/python/usrp_psr_receiver.py
new file mode 100755 (executable)
index 0000000..8a55937
--- /dev/null
@@ -0,0 +1,1101 @@
+#!/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 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.
+# 
+
+
+#
+#
+# Pulsar receiver application
+#
+# Performs both harmonic folding analysis
+#  and epoch folding analysis
+#
+#
+from gnuradio import gr, gru, blks, audio
+from gnuradio import usrp, optfir
+from gnuradio import eng_notation
+from gnuradio.eng_option import eng_option
+from gnuradio.wxgui import stdgui, ra_fftsink, ra_stripchartsink, form, slider
+from optparse import OptionParser
+import wx
+import sys
+import Numeric
+import FFT
+import ephem
+import time
+import os
+import math
+
+
+class app_flow_graph(stdgui.gui_flow_graph):
+    def __init__(self, frame, panel, vbox, argv):
+        stdgui.gui_flow_graph.__init__(self)
+
+        self.frame = frame
+        self.panel = panel
+        
+        parser = OptionParser(option_class=eng_option)
+        parser.add_option("-R", "--rx-subdev-spec", type="subdev", default=(0, 0),
+                          help="select USRP Rx side A or B (default=A)")
+        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("-Q", "--observing", type="eng_float", default=0.0,
+                          help="set observing frequency to FREQ")
+        parser.add_option("-a", "--avg", type="eng_float", default=1.0,
+               help="set spectral averaging alpha")
+        parser.add_option("-V", "--favg", type="eng_float", default=2.0,
+                help="set folder averaging alpha")
+        parser.add_option("-g", "--gain", type="eng_float", default=None,
+                          help="set gain in dB (default is midpoint)")
+        parser.add_option("-l", "--reflevel", type="eng_float", default=30.0,
+                          help="Set pulse display reference level")
+        parser.add_option("-L", "--lowest", type="eng_float", default=1.5,
+                          help="Lowest valid frequency bin")
+        parser.add_option("-e", "--longitude", type="eng_float", default=-76.02,                          help="Set Observer Longitude")
+        parser.add_option("-c", "--latitude", type="eng_float", default=44.85,                          help="Set Observer Latitude")
+        parser.add_option("-F", "--fft_size", type="eng_float", default=1024, help="Size of FFT")
+
+        parser.add_option ("-t", "--threshold", type="eng_float", default=2.5, help="pulsar threshold")
+        parser.add_option("-p", "--lowpass", type="eng_float", default=100, help="Pulse spectra cutoff freq")
+        parser.add_option("-P", "--prefix", default="./", help="File prefix")
+        parser.add_option("-u", "--pulsefreq", type="eng_float", default=0.748, help="Observation pulse rate")
+        parser.add_option("-D", "--dm", type="eng_float", default=1.0e-5, help="Dispersion Measure")
+        parser.add_option("-O", "--doppler", type="eng_float", default=1.0, help="Doppler ratio")
+        parser.add_option("-B", "--divbase", type="eng_float", default=20, help="Y/Div menu base")
+        parser.add_option("-I", "--division", type="eng_float", default=100, help="Y/Div")
+        (options, args) = parser.parse_args()
+        if len(args) != 0:
+            parser.print_help()
+            sys.exit(1)
+
+        self.show_debug_info = True
+
+        self.reflevel = options.reflevel
+        self.divbase = options.divbase
+        self.division = options.division
+
+        # Low-pass cutoff for post-detector filter
+        # Set to 100Hz usually, since lots of pulsars fit in this
+        #   range
+        self.lowpass = options.lowpass
+
+        # What is lowest valid frequency bin in post-detector FFT?
+        # There's some pollution very close to DC
+        self.lowest_freq = options.lowest
+
+        # What (dB) threshold to use in determining spectral candidates
+        self.threshold = options.threshold
+
+        # Filename prefix for recording file
+        self.prefix = options.prefix
+
+        # Dispersion Measure (DM)
+        self.dm = options.dm
+
+        # Doppler shift, as a ratio
+        #  1.0 == no doppler shift
+        #  1.005 == a little negative shift
+        #  0.995 == a little positive shift
+        self.doppler = options.doppler
+
+        #
+        # Input frequency and observing frequency--not necessarily the
+        #   same thing, if we're looking at the IF of some downconverter
+        #   that's ahead of the USRP and daughtercard.  This distinction
+        #   is important in computing the correct de-dispersion filter.
+        #
+        self.frequency = options.freq
+        if options.observing <= 0:
+            self.observing_freq = options.freq
+        else:
+            self.observing_freq = options.observing
+        
+        # build the graph
+        self.u = usrp.source_c(decim_rate=options.decim)
+        self.u.set_mux(usrp.determine_rx_mux_value(self.u, options.rx_subdev_spec))
+
+        #
+        # Recording file, in case we ever need to record baseband data
+        #
+        self.recording = gr.file_sink(gr.sizeof_char, "/dev/null")
+        self.recording_state = False
+
+        self.pulse_recording = gr.file_sink(gr.sizeof_short, "/dev/null")
+        self.pulse_recording_state = False
+
+        #
+        # We come up with recording turned off, but the user may
+        #  request recording later on
+        self.recording.close()
+        self.pulse_recording.close()
+
+        #
+        # Need these two for converting 12-bit baseband signals to 8-bit
+        #
+        self.tofloat = gr.complex_to_float()
+        self.tochar = gr.float_to_char()
+
+        # Need this for recording pulses (post-detector)
+        self.toshort = gr.float_to_short()
+
+
+        #
+        # The spectral measurer sets this when it has a valid
+        #   average spectral peak-to-peak distance
+        # We can then use this to program the parameters for the epoch folder
+        #
+        # We set a sentimental value here
+        self.pulse_freq = options.pulsefreq
+
+        # Folder runs at this raw sample rate
+        self.folder_input_rate = 20000
+
+        # Each pulse in the epoch folder is sampled at 128 times the nominal
+        #  pulse rate
+        self.folding = 128
+
+        #
+        # Try to find candidate parameters for rational resampler
+        #
+        save_i = 0
+        candidates = []
+        for i in range(20,300):
+            input_rate = self.folder_input_rate
+            output_rate = int(self.pulse_freq * i)
+            interp = gru.lcm(input_rate, output_rate) / input_rate
+            decim = gru.lcm(input_rate, output_rate) / output_rate
+            if (interp < 500 and decim < 250000):
+                 candidates.append(i)
+
+        # We didn't find anything, bail!
+        if (len(candidates) < 1):
+            print "Couldn't converge on resampler parameters"
+            sys.exit(1)
+
+        #
+        # Now try to find candidate with the least sampling error
+        #
+        mindiff = 999.999
+        for i in candidates:
+            diff = self.pulse_freq * i
+            diff = diff - int(diff)
+            if (diff < mindiff):
+                mindiff = diff
+                save_i = i
+
+        # Recompute rates
+        input_rate = self.folder_input_rate
+        output_rate = int(self.pulse_freq * save_i)
+
+        # Compute new interp and decim, based on best candidate
+        interp = gru.lcm(input_rate, output_rate) / input_rate
+        decim = gru.lcm(input_rate, output_rate) / output_rate
+
+        # Save optimized folding parameters, used later
+        self.folding = save_i
+        self.interp = int(interp)
+        self.decim = int(decim)
+
+        # So that we can view 4 pulses in the pulse viewer window
+        FOLD_MULT=4
+
+        # determine the daughterboard subdevice we're using
+        self.subdev = usrp.selected_subdev(self.u, options.rx_subdev_spec)
+
+        # Compute raw input rate
+        input_rate = self.u.adc_freq() / self.u.decim_rate()
+
+        # BW==input_rate for complex data
+        self.bw = input_rate
+
+        #
+        # We use this as a crude volume control for the audio output
+        #
+        self.volume = gr.multiply_const_ff(10**(-1))
+        
+
+        #
+        # Create location data for ephem package
+        #
+        self.locality = ephem.Observer()
+        self.locality.long = str(options.longitude)
+        self.locality.lat = str(options.latitude)
+
+        #
+        # What is the post-detector LPF cutoff for the FFT?
+        #
+        PULSAR_MAX_FREQ=int(options.lowpass)
+
+        # First low-pass filters down to input_rate/FIRST_FACTOR
+        #   and decimates appropriately
+        FIRST_FACTOR=int(input_rate/(self.folder_input_rate/2))
+        first_filter = gr.firdes.low_pass (1.0,
+                                          input_rate,
+                                          input_rate/FIRST_FACTOR,
+                                          input_rate/(FIRST_FACTOR*20),         
+                                          gr.firdes.WIN_HAMMING)
+
+        # Second filter runs at the output rate of the first filter,
+        #  And low-pass filters down to PULSAR_MAX_FREQ*10
+        #
+        second_input_rate =  int(input_rate/(FIRST_FACTOR/2))
+        second_filter = gr.firdes.band_pass(1.0, second_input_rate,
+                                          0.10,
+                                          PULSAR_MAX_FREQ*10,
+                                          PULSAR_MAX_FREQ*1.5,
+                                          gr.firdes.WIN_HAMMING)
+
+        # Third filter runs at PULSAR_MAX_FREQ*20
+        #   and filters down to PULSAR_MAX_FREQ
+        #
+        third_input_rate = PULSAR_MAX_FREQ*20
+        third_filter = gr.firdes_band_pass(1.0, third_input_rate,
+                                           0.10, PULSAR_MAX_FREQ,
+                                           PULSAR_MAX_FREQ/10.0,
+                                           gr.firdes.WIN_HAMMING)
+
+
+        #
+        # Create the appropriate FFT scope
+        #
+        self.scope = ra_fftsink.ra_fft_sink_f (self, panel, 
+           fft_size=int(options.fft_size), sample_rate=PULSAR_MAX_FREQ*2,
+           title="Post-detector spectrum",  
+           cfunc=self.pulsarfunc, xydfunc=self.xydfunc, fft_rate=200)
+
+        #
+        # Tell scope we're looking from DC to PULSAR_MAX_FREQ
+        #
+        self.scope.set_baseband_freq (0.0)
+
+
+        #
+        # Setup stripchart for showing pulse profiles
+        #
+        hz = "%5.3fHz " % self.pulse_freq
+        per = "(%5.3f sec)" % (1.0/self.pulse_freq)
+        sr = "%d sps" % (int(self.pulse_freq*self.folding))
+        self.chart = ra_stripchartsink.stripchart_sink_f (self, panel,
+               sample_rate=1,
+               stripsize=self.folding*FOLD_MULT, parallel=True, title="Pulse Profiles: "+hz+per, 
+               xlabel="Seconds @ "+sr, ylabel="Level", autoscale=True,
+               divbase=self.divbase, scaling=1.0/(self.folding*self.pulse_freq))
+        self.chart.set_ref_level(self.reflevel)
+        self.chart.set_y_per_div(self.division)
+
+        # De-dispersion filter setup
+        #
+        # Do this here, just before creating the filter
+        #  that will use the taps.
+        #
+        ntaps = self.compute_disp_ntaps(self.dm,self.bw,self.observing_freq)
+
+        # Taps for the de-dispersion filter
+        self.disp_taps = Numeric.zeros(ntaps,Numeric.Complex64)
+
+        # Compute the de-dispersion filter now
+        self.compute_dispfilter(self.dm,self.doppler,
+            self.bw,self.observing_freq)
+
+        #
+        # Call constructors for receive chains
+        #
+
+        #
+        # Now create the FFT filter using the computed taps
+        self.dispfilt = gr.fft_filter_ccc(1, self.disp_taps)
+
+        #
+        # Audio sink
+        #
+        self.audio = audio.sink(second_input_rate, "plughw:0,0")
+
+        #
+        # The three post-detector filters
+        # Done this way to allow an audio path (up to 10Khz)
+        # ...and also because going from xMhz down to ~100Hz
+        # In a single filter doesn't seem to work.
+        #
+        self.first = gr.fir_filter_fff (FIRST_FACTOR/2, first_filter)
+
+        p = second_input_rate / (PULSAR_MAX_FREQ*20)
+        self.second = gr.fir_filter_fff (int(p), second_filter)
+        self.third = gr.fir_filter_fff (10, third_filter)
+
+        # Split complex USRP stream into a pair of floats
+        self.splitter = gr.complex_to_float (1);
+
+        # I squarer (detector)
+        self.multI = gr.multiply_ff();
+
+        # Q squarer (detector)
+        self.multQ = gr.multiply_ff();
+
+        # Adding squared I and Q to produce instantaneous signal power
+        self.adder = gr.add_ff();
+
+        self.enable_comb_filter = False
+        # Epoch folder comb filter
+        if self.enable_comb_filter == True:
+            bogtaps = Numeric.zeros(512, Numeric.Float64)
+            self.folder_comb = gr.fft_filter_ccc(1,bogtaps)
+
+        # Rational resampler
+        self.folder_rr = blks.rational_resampler_fff(self, self.interp, self.decim)
+
+        # Epoch folder bandpass
+        bogtaps = Numeric.zeros(1, Numeric.Float64)
+        self.folder_bandpass = gr.fir_filter_fff (1, bogtaps)
+
+        # Epoch folder F2C/C2F
+        self.folder_f2c = gr.float_to_complex()
+        self.folder_c2f = gr.complex_to_float()
+
+        # Epoch folder S2P
+        self.folder_s2p = gr.serial_to_parallel (gr.sizeof_float, 
+             self.folding*FOLD_MULT)
+
+        # Epoch folder IIR Filter (produces average pulse profiles)
+        self.folder_iir = gr.single_pole_iir_filter_ff(1.0/options.favg,
+             self.folding*FOLD_MULT)
+
+        #
+        # Set all the epoch-folder goop up
+        #
+        self.set_folding_params()
+
+        # 
+        # Start connecting configured modules in the receive chain
+        #
+
+        # Connect raw USRP to de-dispersion filter, complex->float splitter
+        self.connect(self.u, self.dispfilt, self.splitter)
+
+        # Connect splitter outputs to multipliers
+        # First do I^2
+        self.connect((self.splitter, 0), (self.multI,0))
+        self.connect((self.splitter, 0), (self.multI,1))
+
+        # Then do Q^2
+        self.connect((self.splitter, 1), (self.multQ,0))
+        self.connect((self.splitter, 1), (self.multQ,1))
+
+        # Then sum the squares
+        self.connect(self.multI, (self.adder,0))
+        self.connect(self.multQ, (self.adder,1))
+
+        # Connect detector/adder output to FIR LPF
+        #  in two stages, followed by the FFT scope
+        self.connect(self.adder, self.first,
+            self.second, self.third, self.scope)
+
+        # Connect audio output
+        self.connect(self.first, self.volume)
+        self.connect(self.volume, (self.audio, 0))
+        self.connect(self.volume, (self.audio, 1))
+
+        # Connect epoch folder
+        if self.enable_comb_filter == True:
+            self.connect (self.first, self.folder_bandpass, self.folder_rr,
+                self.folder_f2c,
+                self.folder_comb, self.folder_c2f,
+                self.folder_s2p, self.folder_iir,
+                self.chart)
+
+        else:
+            self.connect (self.first, self.folder_bandpass, self.folder_rr,
+                self.folder_s2p, self.folder_iir, self.chart)
+
+        # Connect baseband recording file (initially /dev/null)
+        self.connect(self.u, self.tofloat, self.tochar, self.recording)
+
+        # Connect pulse recording file (initially /dev/null)
+        self.connect(self.first, self.toshort, self.pulse_recording)
+
+        #
+        # Build the GUI elements
+        #
+        self._build_gui(vbox)
+
+        # Make GUI agree with command-line
+        self.myform['average'].set_value(int(options.avg))
+        self.myform['foldavg'].set_value(int(options.favg))
+
+
+        # Make spectral averager agree with command line
+        if options.avg != 1.0:
+            self.scope.set_avg_alpha(float(1.0/options.avg))
+            self.scope.set_average(True)
+
+
+        # set initial values
+
+        if options.gain is None:
+            # if no gain was specified, use the mid-point in dB
+            g = self.subdev.gain_range()
+            options.gain = float(g[0]+g[1])/2
+
+        if options.freq is None:
+            # if no freq was specified, use the mid-point
+            r = self.subdev.freq_range()
+            options.freq = float(r[0]+r[1])/2
+
+        self.set_gain(options.gain)
+        self.set_volume(-10.0)
+
+        if not(self.set_freq(options.freq)):
+            self._set_status_msg("Failed to set initial frequency")
+
+        self.myform['decim'].set_value(self.u.decim_rate())
+        self.myform['fs@usb'].set_value(self.u.adc_freq() / self.u.decim_rate())
+        self.myform['dbname'].set_value(self.subdev.name())
+        self.myform['DM'].set_value(self.dm)
+        self.myform['Doppler'].set_value(self.doppler)
+
+        #
+        # Start the timer that shows current LMST on the GUI
+        #
+        self.lmst_timer.Start(1000)
+
+
+    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'])
+
+        def _form_set_dm(kv):
+            return self.set_dm(kv['DM'])
+
+        def _form_set_doppler(kv):
+            return self.set_doppler(kv['Doppler'])
+
+        # Position the FFT or Waterfall
+        vbox.Add(self.scope.win, 5, wx.EXPAND)
+        vbox.Add(self.chart.win, 5, wx.EXPAND)
+
+        # add control area at the bottom
+        self.myform = myform = form.form()
+        hbox = wx.BoxSizer(wx.HORIZONTAL)
+        hbox.Add((7,0), 0, wx.EXPAND)
+        vbox1 = wx.BoxSizer(wx.VERTICAL)
+        myform['freq'] = form.float_field(
+            parent=self.panel, sizer=vbox1, label="Center freq", weight=1,
+            callback=myform.check_input_and_call(_form_set_freq, self._set_status_msg))
+
+        vbox1.Add((3,0), 0, 0)
+
+        # To show current Local Mean Sidereal Time
+        myform['lmst_high'] = form.static_text_field(
+            parent=self.panel, sizer=vbox1, label="Current LMST", weight=1)
+        vbox1.Add((3,0), 0, 0)
+
+        # To show current spectral cursor data
+        myform['spec_data'] = form.static_text_field(
+            parent=self.panel, sizer=vbox1, label="Pulse Freq", weight=1)
+        vbox1.Add((3,0), 0, 0)
+
+        # To show best pulses found in FFT output
+        myform['best_pulse'] = form.static_text_field(
+            parent=self.panel, sizer=vbox1, label="Best freq", weight=1)
+        vbox1.Add((3,0), 0, 0)
+
+        vboxBogus = wx.BoxSizer(wx.VERTICAL)
+        vboxBogus.Add ((2,0), 0, wx.EXPAND)
+        vbox2 = wx.BoxSizer(wx.VERTICAL)
+        g = self.subdev.gain_range()
+        myform['gain'] = form.slider_field(parent=self.panel, sizer=vbox2, label="RF Gain",
+                                           weight=1,
+                                           min=int(g[0]), max=int(g[1]),
+                                           callback=self.set_gain)
+
+        vbox2.Add((6,0), 0, 0)
+        myform['average'] = form.slider_field(parent=self.panel, sizer=vbox2, 
+                    label="Spectral Averaging", weight=1, min=1, max=200, callback=self.set_averaging)
+        vbox2.Add((6,0), 0, 0)
+        myform['foldavg'] = form.slider_field(parent=self.panel, sizer=vbox2,
+                    label="Folder Averaging", weight=1, min=1, max=20, callback=self.set_folder_averaging)
+        vbox2.Add((6,0), 0, 0)
+        myform['volume'] = form.quantized_slider_field(parent=self.panel, sizer=vbox2,
+                    label="Audio Volume", weight=1, range=(-20, 0, 0.5), callback=self.set_volume)
+        vbox2.Add((6,0), 0, 0)
+        myform['DM'] = form.float_field(
+            parent=self.panel, sizer=vbox2, label="DM", weight=1,
+            callback=myform.check_input_and_call(_form_set_dm))
+        vbox2.Add((6,0), 0, 0)
+        myform['Doppler'] = form.float_field(
+            parent=self.panel, sizer=vbox2, label="Doppler", weight=1,
+            callback=myform.check_input_and_call(_form_set_doppler))
+        vbox2.Add((6,0), 0, 0)
+
+
+        # Baseband recording control
+        buttonbox = wx.BoxSizer(wx.HORIZONTAL)
+        self.record_control = form.button_with_callback(self.panel,
+              label="Recording baseband: Off                           ",
+              callback=self.toggle_recording)
+        self.record_pulse_control = form.button_with_callback(self.panel,
+              label="Recording pulses: Off                              ",
+              callback=self.toggle_pulse_recording)
+
+        buttonbox.Add(self.record_control, 0, wx.CENTER)
+        buttonbox.Add(self.record_pulse_control, 0, wx.CENTER)
+        vbox.Add(buttonbox, 0, wx.CENTER)
+        hbox.Add(vbox1, 0, 0)
+        hbox.Add(vboxBogus, 0, 0)
+       hbox.Add(vbox2, wx.ALIGN_RIGHT, 0)
+        vbox.Add(hbox, 0, wx.EXPAND)
+
+        self._build_subpanel(vbox)
+
+        self.lmst_timer = wx.PyTimer(self.lmst_timeout)
+        self.lmst_timeout()
+
+
+    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)
+        
+        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.static_float_field(
+            parent=panel, sizer=hbox, label="Decim")
+
+        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 = usrp.tune(self.u, 0, self.subdev, target_freq)
+
+        if r:
+            self.myform['freq'].set_value(target_freq)     # update displayed value
+            self.myform['baseband'].set_value(r.baseband_freq)
+            self.myform['ddc'].set_value(r.dxc_freq)
+            # Adjust self.frequency, and self.observing_freq
+            # We pick up the difference between the current self.frequency
+            #   and the just-programmed one, and use this to adjust
+            #   self.observing_freq.  We have to do it this way to
+            #   make the dedispersion filtering work out properly.
+            delta = target_freq - self.frequency
+            self.frequency = target_freq
+            self.observing_freq += delta
+
+            # Now that we're adjusted, compute a new dispfilter, and
+            #   set the taps for the FFT filter.
+            ntaps = self.compute_disp_ntaps(self.dm, self.bw, self.observing_freq)
+            self.disp_taps = Numeric.zeros(ntaps, Numeric.Complex64)
+            self.compute_dispfilter(self.dm,self.doppler,self.bw,
+                self.observing_freq)
+            self.dispfilt.set_taps(self.disp_taps)
+
+            return True
+
+        return False
+
+    # Callback for gain-setting slider
+    def set_gain(self, gain):
+        self.myform['gain'].set_value(gain)     # update displayed value
+        self.subdev.set_gain(gain)
+
+
+    def set_volume(self, vol):
+        self.myform['volume'].set_value(vol)
+        self.volume.set_k((10**(vol/10))/8192)
+
+    # Callback for spectral-averaging slider
+    def set_averaging(self, avval):
+        self.myform['average'].set_value(avval)
+        self.scope.set_avg_alpha(1.0/(avval))
+        self.scope.set_average(True)
+
+    def set_folder_averaging(self, avval):
+        self.myform['foldavg'].set_value(avval)
+        self.folder_iir.set_taps(1.0/avval)
+
+    # Timer callback to update LMST display
+    def lmst_timeout(self):
+         self.locality.date = ephem.now()
+         sidtime = self.locality.sidereal_time()
+         self.myform['lmst_high'].set_value(str(ephem.hours(sidtime)))
+
+    #
+    # Turn recording on/off
+    # Called-back by "Recording" button
+    #
+    def toggle_recording(self):
+        # Pick up current LMST
+        self.locality.date = ephem.now()
+        sidtime = self.locality.sidereal_time()
+
+        # Pick up localtime, for generating filenames
+        foo = time.localtime()
+
+        # Generate filenames for both data and header file
+        filename = "%04d%02d%02d%02d%02d.pdat" % (foo.tm_year, foo.tm_mon,
+           foo.tm_mday, foo.tm_hour, foo.tm_min)
+        hdrfilename = "%04d%02d%02d%02d%02d.phdr" % (foo.tm_year, foo.tm_mon,
+           foo.tm_mday, foo.tm_hour, foo.tm_min)
+
+        # Current recording?  Flip state
+        if (self.recording_state == True):
+          self.recording_state = False
+          self.record_control.SetLabel("Recording baseband: Off                           ")
+          self.recording.close()
+        # Not recording?
+        else:
+          self.recording_state = True
+          self.record_control.SetLabel("Recording baseband to: "+filename)
+
+          # Cause gr_file_sink object to accept new filename
+          #   note use of self.prefix--filename prefix from
+          #   command line (defaults to ./)
+          #
+          self.recording.open (self.prefix+filename)
+
+          #
+          # We open the header file as a regular file, write header data,
+          #   then close
+          hdrf = open(self.prefix+hdrfilename, "w")
+          hdrf.write("receiver center frequency: "+str(self.frequency)+"\n")
+          hdrf.write("observing frequency: "+str(self.observing_freq)+"\n")
+          hdrf.write("DM: "+str(self.dm)+"\n")
+          hdrf.write("doppler: "+str(self.doppler)+"\n")
+
+          hdrf.write("sidereal: "+str(ephem.hours(sidtime))+"\n")
+          hdrf.write("bandwidth: "+str(self.u.adc_freq() / self.u.decim_rate())+"\n")
+          hdrf.write("sample type: complex_char\n")
+          hdrf.write("sample size: "+str(gr.sizeof_char*2)+"\n")
+          hdrf.close()
+    #
+    # Turn recording on/off
+    # Called-back by "Recording" button
+    #
+    def toggle_pulse_recording(self):
+        # Pick up current LMST
+        self.locality.date = ephem.now()
+        sidtime = self.locality.sidereal_time()
+
+        # Pick up localtime, for generating filenames
+        foo = time.localtime()
+
+        # Generate filenames for both data and header file
+        filename = "%04d%02d%02d%02d%02d.padat" % (foo.tm_year, foo.tm_mon,
+           foo.tm_mday, foo.tm_hour, foo.tm_min)
+        hdrfilename = "%04d%02d%02d%02d%02d.pahdr" % (foo.tm_year, foo.tm_mon,
+           foo.tm_mday, foo.tm_hour, foo.tm_min)
+
+        # Current recording?  Flip state
+        if (self.pulse_recording_state == True):
+          self.pulse_recording_state = False
+          self.record_pulse_control.SetLabel("Recording pulses: Off                           ")
+          self.pulse_recording.close()
+        # Not recording?
+        else:
+          self.pulse_recording_state = True
+          self.record_pulse_control.SetLabel("Recording pulses to: "+filename)
+
+          # Cause gr_file_sink object to accept new filename
+          #   note use of self.prefix--filename prefix from
+          #   command line (defaults to ./)
+          #
+          self.pulse_recording.open (self.prefix+filename)
+
+          #
+          # We open the header file as a regular file, write header data,
+          #   then close
+          hdrf = open(self.prefix+hdrfilename, "w")
+          hdrf.write("receiver center frequency: "+str(self.frequency)+"\n")
+          hdrf.write("observing frequency: "+str(self.observing_freq)+"\n")
+          hdrf.write("DM: "+str(self.dm)+"\n")
+          hdrf.write("doppler: "+str(self.doppler)+"\n")
+          hdrf.write("pulse rate: "+str(self.pulse_freq)+"\n")
+          hdrf.write("pulse sps: "+str(self.pulse_freq*self.folding)+"\n")
+          hdrf.write("file sps: "+str(self.folder_input_rate)+"\n")
+
+          hdrf.write("sidereal: "+str(ephem.hours(sidtime))+"\n")
+          hdrf.write("bandwidth: "+str(self.u.adc_freq() / self.u.decim_rate())+"\n")
+          hdrf.write("sample type: short\n")
+          hdrf.write("sample size: 1\n")
+          hdrf.close()
+
+    # We get called at startup, and whenever the GUI "Set Folding params"
+    #   button is pressed
+    #
+    def set_folding_params(self):
+        if (self.pulse_freq <= 0):
+            return
+
+        # Compute required sample rate
+        self.sample_rate = int(self.pulse_freq*self.folding)
+
+        # And the implied decimation rate
+        required_decimation = int(self.folder_input_rate / self.sample_rate)
+
+        # We also compute a new FFT comb filter, based on the expected
+        #  spectral profile of our pulse parameters
+        #
+        # FFT-based comb filter
+        #
+        N_COMB_TAPS=int(self.sample_rate*4)
+        if N_COMB_TAPS > 2000:
+            N_COMB_TAPS = 2000
+        self.folder_comb_taps = Numeric.zeros(N_COMB_TAPS,Numeric.Complex64)
+        fincr = (self.sample_rate)/float(N_COMB_TAPS)
+        for i in range(0,len(self.folder_comb_taps)):
+            self.folder_comb_taps[i] = complex(0.0, 0.0)
+
+        freq = 0.0
+        harmonics = [1.0,2.0,3.0,4.0,5.0,6.0,7.0]
+        for i in range(0,len(self.folder_comb_taps)/2):
+            for j in range(0,len(harmonics)):
+                 if abs(freq - harmonics[j]*self.pulse_freq) <= fincr:
+                     self.folder_comb_taps[i] = complex(4.0, 0.0)
+                     if harmonics[j] == 1.0:
+                         self.folder_comb_taps[i] = complex(8.0, 0.0)
+            freq += fincr
+
+        if self.enable_comb_filter == True:
+            # Set the just-computed FFT comb filter taps
+            self.folder_comb.set_taps(self.folder_comb_taps)
+
+        # And compute a new decimated bandpass filter, to go in front
+        #   of the comb.  Primary function is to decimate and filter down
+        #   to an exact-ish multiple of the target pulse rate
+        #
+        self.folding_taps = gr.firdes_band_pass (1.0, self.folder_input_rate,
+            0.10, self.sample_rate/2, 10, 
+            gr.firdes.WIN_HAMMING)
+
+        # Set the computed taps for the bandpass/decimate filter
+        self.folder_bandpass.set_taps (self.folding_taps)
+    #
+    # Record a spectral "hit" of a possible pulsar spectral profile
+    #
+    def record_hit(self,hits, hcavg, hcmax):
+        # Pick up current LMST
+        self.locality.date = ephem.now()
+        sidtime = self.locality.sidereal_time()
+
+        # Pick up localtime, for generating filenames
+        foo = time.localtime()
+
+        # Generate filenames for both data and header file
+        hitfilename = "%04d%02d%02d%02d.phit" % (foo.tm_year, foo.tm_mon,
+           foo.tm_mday, foo.tm_hour)
+
+        hitf = open(self.prefix+hitfilename, "a")
+        hitf.write("receiver center frequency: "+str(self.frequency)+"\n")
+        hitf.write("observing frequency: "+str(self.observing_freq)+"\n")
+        hitf.write("DM: "+str(self.dm)+"\n")
+        hitf.write("doppler: "+str(self.doppler)+"\n")
+
+        hitf.write("sidereal: "+str(ephem.hours(sidtime))+"\n")
+        hitf.write("bandwidth: "+str(self.u.adc_freq() / self.u.decim_rate())+"\n")
+        hitf.write("spectral peaks: "+str(hits)+"\n")
+        hitf.write("HCM: "+str(hcavg)+" "+str(hcmax)+"\n")
+        hitf.close()
+
+    # This is a callback used by ra_fftsink.py (passed on creation of
+    #   ra_fftsink)
+    # Whenever the user moves the cursor within the FFT display, this
+    #   shows the coordinate data
+    #
+    def xydfunc(self,xyv):
+        s = "%.6fHz\n%.3fdB" % (xyv[0], xyv[1])
+        if self.lowpass >= 500:
+            s = "%.6fHz\n%.3fdB" % (xyv[0]*1000, xyv[1])
+        
+        self.myform['spec_data'].set_value(s)
+
+    # This is another callback used by ra_fftsink.py (passed on creation
+    #   of ra_fftsink).  We pass this as our "calibrator" function, but
+    #   we create interesting side-effects in the GUI.
+    #
+    # This function finds peaks in the FFT output data, and reports
+    #  on them through the "Best" text object in the GUI
+    #  It also computes the Harmonic Compliance Measure (HCM), and displays
+    #  that also.
+    #
+    def pulsarfunc(self,d,l):
+       x = range(0,l)
+       incr = float(self.lowpass)/float(l)
+       incr = incr * 2.0
+       bestdb = -50.0
+       bestfreq = 0.0
+       avg = 0
+       dcnt = 0
+       #
+       # First, we need to find the average signal level
+       #
+       for i in x:
+           if (i * incr) > self.lowest_freq and (i*incr) < (self.lowpass-2):
+               avg += d[i]
+               dcnt += 1
+       # Set average signal level
+       avg /= dcnt
+       s2=" "
+       findcnt = 0
+       #
+       # Then we find candidates that are greater than the user-supplied
+       #   threshold.
+       #
+       # We try to cluster "hits" whose whole-number frequency is the
+       #   same, and compute an average "hit" frequency.
+       #
+       lastint = 0
+       hits=[]
+       intcnt = 0
+       freqavg = 0
+       for i in x:
+           freq = i*incr
+           # If frequency within bounds, and the (dB-avg) value is above our
+           #   threshold
+           if freq > self.lowest_freq and freq < self.lowpass-2 and (d[i] - avg) > self.threshold:
+               # If we're finding a new whole-number frequency
+               if lastint != int(freq):
+                   # Record "center" of this hit, if this is a new hit
+                   if lastint != 0:
+                       s2 += "%5.3fHz " % (freqavg/intcnt)
+                       hits.append(freqavg/intcnt)
+                       findcnt += 1
+                   lastint = int(freq)
+                   intcnt = 1
+                   freqavg = freq
+               else:
+                   intcnt += 1
+                   freqavg += freq
+           if (findcnt >= 14):
+               break
+
+       if intcnt > 1:
+           s2 += "%5.3fHz " % (freqavg/intcnt)
+           hits.append(freqavg/intcnt)
+
+       #
+       # Compute the HCM, by dividing each of the "hits" by each of the
+       #   other hits, and comparing the difference between a "perfect"
+       #   harmonic, and the observed frequency ratio.
+       #
+       measure = 0
+       max_measure=0
+       mcnt = 0
+       avg_dist = 0
+       acnt = 0
+       for i in range(1,len(hits)):
+           meas = hits[i]/hits[0] - int(hits[i]/hits[0])
+           if abs((hits[i]-hits[i-1])-hits[0]) < 0.1:
+               avg_dist += hits[i]-hits[i-1]
+               acnt += 1
+           if meas > 0.98 and meas < 1.0:
+               meas = 1.0 - meas
+           meas *= hits[0]
+           if meas >= max_measure:
+               max_measure = meas
+           measure += meas
+           mcnt += 1
+       if mcnt > 0:
+           measure /= mcnt
+           if acnt > 0:
+               avg_dist /= acnt
+       if len(hits) > 1:
+           measure /= mcnt
+           s3="\nHCM: Avg %5.3fHz(%d) Max %5.3fHz Dist %5.3fHz(%d)" % (measure,mcnt,max_measure, avg_dist, acnt)
+           if max_measure < 0.5 and len(hits) >= 2:
+               self.record_hit(hits, measure, max_measure)
+               self.avg_dist = avg_dist
+       else:
+           s3="\nHCM: --"
+       s4="\nAvg dB: %4.2f" % avg
+       self.myform['best_pulse'].set_value("("+s2+")"+s3+s4)
+
+       # Since we are nominally a calibrator function for ra_fftsink, we
+       #  simply return what they sent us, untouched.  A "real" calibrator
+       #  function could monkey with the data before returning it to the
+       #  FFT display function.
+       return(d)
+
+    #
+    # Callback for the "DM" gui object
+    #
+    # We call compute_dispfilter() as appropriate to compute a new filter,
+    #   and then set that new filter into self.dispfilt.
+    #
+    def set_dm(self,dm):
+       self.dm = dm
+
+       ntaps = self.compute_disp_ntaps (self.dm, self.bw, self.observing_freq)
+       self.disp_taps = Numeric.zeros(ntaps, Numeric.Complex64)
+       self.compute_dispfilter(self.dm,self.doppler,self.bw,self.observing_freq)
+       self.dispfilt.set_taps(self.disp_taps)
+       self.myform['DM'].set_value(dm)
+       return(dm)
+
+    #
+    # Callback for the "Doppler" gui object
+    #
+    # We call compute_dispfilter() as appropriate to compute a new filter,
+    #   and then set that new filter into self.dispfilt.
+    #
+    def set_doppler(self,doppler):
+       self.doppler = doppler
+
+       ntaps = self.compute_disp_ntaps (self.dm, self.bw, self.observing_freq)
+       self.disp_taps = Numeric.zeros(ntaps, Numeric.Complex64)
+       self.compute_dispfilter(self.dm,self.doppler,self.bw,self.observing_freq)
+       self.dispfilt.set_taps(self.disp_taps)
+       self.myform['Doppler'].set_value(doppler)
+       return(doppler)
+
+    #
+    # Compute a de-dispersion filter
+    #  From Hankins, et al, 1975
+    #
+    # This code translated from dedisp_filter.c from Swinburne
+    #   pulsar software repository
+    #
+    def compute_dispfilter(self,dm,doppler,bw,centerfreq):
+        npts = len(self.disp_taps)
+        tmp = Numeric.zeros(npts, Numeric.Complex64)
+        M_PI = 3.14159265358
+        DM = dm/2.41e-10
+
+        #
+        # Because astronomers are a crazy bunch, the "standard" calcultion
+        #   is in Mhz, rather than Hz
+        #
+        centerfreq = centerfreq / 1.0e6
+        bw = bw / 1.0e6
+        
+        isign = int(bw / abs (bw))
+        
+        # Center frequency may be doppler shifted
+        cfreq     = centerfreq / doppler
+
+        # As well as the bandwidth..
+        bandwidth = bw / doppler
+
+        # Bandwidth divided among bins
+        binwidth  = bandwidth / npts
+
+        # Delay is an "extra" parameter, in usecs, and largely
+        #  untested in the Swinburne code.
+        delay = 0.0
+        
+        # This determines the coefficient of the frequency response curve
+        # Linear in DM, but quadratic in center frequency
+        coeff = isign * 2.0*M_PI * DM / (cfreq*cfreq)
+        
+        # DC to nyquist/2
+        n = 0
+        for i in range(0,int(npts/2)):
+            freq = (n + 0.5) * binwidth
+            phi = coeff*freq*freq/(cfreq+freq) + (2.0*M_PI*freq*delay)
+            tmp[i] = complex(math.cos(phi), math.sin(phi))
+            n += 1
+
+        # -nyquist/2 to DC
+        n = int(npts/2)
+        n *= -1
+        for i in range(int(npts/2),npts):
+            freq = (n + 0.5) * binwidth
+            phi = coeff*freq*freq/(cfreq+freq) + (2.0*M_PI*freq*delay)
+            tmp[i] = complex(math.cos(phi), math.sin(phi))
+            n += 1
+        
+        self.disp_taps = FFT.inverse_fft(tmp)
+        return(self.disp_taps)
+
+    #
+    # Compute minimum number of taps required in de-dispersion FFT filter
+    #
+    def compute_disp_ntaps(self,dm,bw,freq):
+        #
+        # Dt calculations are in Mhz, rather than Hz
+        #    crazy astronomers....
+        mbw = bw/1.0e6
+        mfreq = freq/1.0e6
+
+        f_lower = mfreq-(mbw/2)
+        f_upper = mfreq+(mbw/2)
+
+        # Compute smear time
+        Dt = dm/2.41e-4 * (1.0/(f_lower*f_lower)-1.0/(f_upper*f_upper))
+
+        # ntaps is now bandwidth*smeartime
+        # Should be bandwidth*smeartime*2, but the Gnu Radio FFT filter
+        #   already expands it by a factor of 2
+        ntaps = bw*Dt
+        if ntaps < 64:
+            ntaps = 64
+        return(int(ntaps))
+
+def main ():
+    app = stdgui.stdapp(app_flow_graph, "RADIO ASTRONOMY PULSAR RECEIVER: $Revision$", nstatus=1)
+    app.MainLoop()
+
+if __name__ == '__main__':
+    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
diff --git a/gr-radio-astronomy/src/python/usrp_ra_receiver.py b/gr-radio-astronomy/src/python/usrp_ra_receiver.py
new file mode 100755 (executable)
index 0000000..37a1ebf
--- /dev/null
@@ -0,0 +1,584 @@
+#!/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 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.
+# 
+
+from gnuradio import gr, gru
+from gnuradio import usrp
+import usrp_dbid
+from gnuradio import eng_notation
+from gnuradio.eng_option import eng_option
+from gnuradio.wxgui import stdgui, ra_fftsink, ra_stripchartsink, waterfallsink, form, slider
+from optparse import OptionParser
+import wx
+import sys
+from Numeric import *
+import FFT
+import ephem
+from gnuradio.local_calibrator import *
+
+class app_flow_graph(stdgui.gui_flow_graph):
+    def __init__(self, frame, panel, vbox, argv):
+        stdgui.gui_flow_graph.__init__(self)
+
+        self.frame = frame
+        self.panel = panel
+        
+        parser = OptionParser(option_class=eng_option)
+        parser.add_option("-R", "--rx-subdev-spec", type="subdev", default=(0, 0),
+                          help="select USRP Rx side A or B (default=A)")
+        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("-a", "--avg", type="eng_float", default=1.0,
+               help="set spectral averaging alpha")
+       parser.add_option("-i", "--integ", type="eng_float", default=1.0,
+               help="set integration time")
+        parser.add_option("-g", "--gain", type="eng_float", default=None,
+                          help="set gain in dB (default is midpoint)")
+        parser.add_option("-l", "--reflevel", type="eng_float", default=30.0,
+                          help="Set Total power reference level")
+        parser.add_option("-y", "--division", type="eng_float", default=0.5,
+                          help="Set Total power Y division size")
+        parser.add_option("-e", "--longitude", type="eng_float", default=-76.02,                          help="Set Observer Longitude")
+        parser.add_option("-c", "--latitude", type="eng_float", default=44.85,                          help="Set Observer Latitude")
+        parser.add_option("-o", "--observing", type="eng_float", default=0.0,
+                        help="Set observing frequency")
+        parser.add_option("-x", "--ylabel", default="dB", help="Y axis label") 
+        parser.add_option("-C", "--cfunc", default="default", help="Calibration function name") 
+        parser.add_option("-z", "--divbase", type="eng_float", default=0.025, help="Y Division increment base") 
+        parser.add_option("-v", "--stripsize", type="eng_float", default=2400, help="Size of stripchart, in 2Hz samples") 
+        parser.add_option("-F", "--fft_size", type="eng_float", default=1024, help="Size of FFT")
+
+        parser.add_option("-N", "--decln", type="eng_float", default=999.99, help="Observing declination")
+        parser.add_option("-I", "--interfilt", action="store_true", default=False)
+        parser.add_option("-X", "--prefix", default="./")
+        (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 = usrp.source_c(decim_rate=options.decim)
+        self.u.set_mux(usrp.determine_rx_mux_value(self.u, options.rx_subdev_spec))
+        self.cardtype = self.u.daughterboard_id(0)
+        # Set initial declination
+        self.decln = options.decln
+
+        # Turn off interference filter by default
+        self.use_interfilt = options.interfilt
+
+        # determine the daughterboard subdevice we're using
+        self.subdev = usrp.selected_subdev(self.u, options.rx_subdev_spec)
+
+        input_rate = self.u.adc_freq() / self.u.decim_rate()
+
+        tpstr="calib_"+options.cfunc+"_total_power"
+        sstr="calib_"+options.cfunc+"_fft"
+        self.tpcfunc=eval(tpstr)
+        self.scfunc=eval(sstr)
+
+        #
+        # Set prefix for data files
+        #
+        self.prefix = options.prefix
+        calib_set_prefix(self.prefix)
+
+        # Set up FFT display
+        self.scope = ra_fftsink.ra_fft_sink_c (self, panel, 
+           fft_size=int(options.fft_size), sample_rate=input_rate,
+           fft_rate=8, title="Spectral",  
+           cfunc=self.scfunc, xydfunc=self.xydfunc, interfunc=self.interference)
+
+        # Set up ephemeris data
+        self.locality = ephem.Observer()
+        self.locality.long = str(options.longitude)
+        self.locality.lat = str(options.latitude)
+
+        # Set up stripchart display
+        self.stripsize = int(options.stripsize)
+        self.chart = ra_stripchartsink.stripchart_sink_f (self, panel,
+            stripsize=self.stripsize,
+            title="Continuum",
+            xlabel="LMST Offset (Seconds)",
+            scaling=1.0, ylabel=options.ylabel,
+            divbase=options.divbase, cfunc=self.tpcfunc)
+
+        # Set center frequency
+        self.centerfreq = options.freq
+
+        # Set observing frequency (might be different from actual programmed
+        #    RF frequency)
+        if options.observing == 0.0:
+            self.observing = options.freq
+        else:
+            self.observing = options.observing
+
+        self.bw = input_rate
+
+        #
+        # Produce a default interference map
+        #  May not actually get used, unless --interfilt was specified
+        #
+        self.intmap = Numeric.zeros(256,Numeric.Complex64)
+        for i in range(0,len(self.intmap)):
+            self.intmap[i] = complex(1.0, 0.0)
+
+        # We setup the first two integrators to produce a fixed integration
+        # Down to 1Hz, with output at 1 samples/sec
+        N = input_rate/5000
+
+        # Second stage runs on decimated output of first
+        M = (input_rate/N)
+
+        # Create taps for first integrator
+        t = range(0,N-1)
+        tapsN = []
+        for i in t:
+             tapsN.append(1.0/N)
+
+        # Create taps for second integrator
+        t = range(0,M-1)
+        tapsM = []
+        for i in t:
+            tapsM.append(1.0/M)
+
+        #
+        # The 3rd integrator is variable, and user selectable at runtime
+        # This integrator doesn't decimate, but is used to set the
+        #  final integration time based on the constant 1Hz input samples
+        # The strip chart is fed at a constant 1Hz rate as a result
+        #
+
+        #
+        # Call constructors for receive chains
+        #
+
+        #
+        # This is the interference-zapping filter
+        #
+        # The GUI is used to set/clear inteference zones in
+        #   the filter.  The non-interfering zones are set to
+        #   1.0.
+        #
+        if 0:
+            self.interfilt = gr.fft_filter_ccc(1,self.intmap)
+            tmp = FFT.inverse_fft(self.intmap)
+            self.interfilt.set_taps(tmp)
+
+        # The three integrators--two FIR filters, and an IIR final filter
+        self.integrator1 = gr.fir_filter_fff (N, tapsN)
+        self.integrator2 = gr.fir_filter_fff (M, tapsM)
+        self.integrator3 = gr.single_pole_iir_filter_ff(1.0)
+
+        # Split complex USRP stream into a pair of floats
+        self.splitter = gr.complex_to_float (1);
+        self.toshort = gr.float_to_short();
+
+        # I squarer (detector)
+        self.multI = gr.multiply_ff();
+
+        # Q squarer (detector)
+        self.multQ = gr.multiply_ff();
+
+        # Adding squared I and Q to produce instantaneous signal power
+        self.adder = gr.add_ff();
+
+        #
+        # Start connecting configured modules in the receive chain
+        #
+
+        # Connect interference-filtered USRP input to selected scope function
+        if self.use_interfilt == True:
+            self.connect(self.u, self.interfilt, self.scope)
+
+            # Connect interference-filtered USRP to a complex->float splitter
+            self.connect(self.interfilt, self.splitter)
+
+        else:
+            self.connect(self.u, self.scope)
+            self.connect(self.u, self.splitter)
+
+        # Connect splitter outputs to multipliers
+        # First do I^2
+        self.connect((self.splitter, 0), (self.multI,0))
+        self.connect((self.splitter, 0), (self.multI,1))
+
+        # Then do Q^2
+        self.connect((self.splitter, 1), (self.multQ,0))
+        self.connect((self.splitter, 1), (self.multQ,1))
+
+        # Then sum the squares
+        self.connect(self.multI, (self.adder,0))
+        self.connect(self.multQ, (self.adder,1))
+
+        # Connect adder output to three-stages of FIR integrator
+        self.connect(self.adder, self.integrator1, 
+           self.integrator2, self.integrator3, self.chart)
+
+
+        self._build_gui(vbox)
+
+        # Make GUI agree with command-line
+        self.myform['integration'].set_value(int(options.integ))
+        self.myform['average'].set_value(int(options.avg))
+
+        # Make integrator agree with command line
+        self.set_integration(int(options.integ))
+
+        # Make spectral averager agree with command line
+        if options.avg != 1.0:
+            self.scope.set_avg_alpha(float(1.0/options.avg))
+            calib_set_avg_alpha(float(options.avg))
+            self.scope.set_average(True)
+
+
+        # Set division size
+        self.chart.set_y_per_div(options.division)
+
+        # Set reference(MAX) level
+        self.chart.set_ref_level(options.reflevel)
+
+        # set initial values
+
+        if options.gain is None:
+            # if no gain was specified, use the mid-point in dB
+            g = self.subdev.gain_range()
+            options.gain = float(g[0]+g[1])/2
+
+        if options.freq is None:
+            # if no freq was specified, use the mid-point
+            r = self.subdev.freq_range()
+            options.freq = float(r[0]+r[1])/2
+
+        # Set the initial gain control
+        self.set_gain(options.gain)
+
+        if not(self.set_freq(options.freq)):
+            self._set_status_msg("Failed to set initial frequency")
+
+        self.set_decln (self.decln)
+        calib_set_bw(self.decln)
+
+        self.myform['decim'].set_value(self.u.decim_rate())
+        self.myform['fs@usb'].set_value(self.u.adc_freq() / self.u.decim_rate())
+        self.myform['dbname'].set_value(self.subdev.name())
+
+        # Make sure calibrator knows what our bandwidth is
+        calib_set_bw(self.u.adc_freq() / self.u.decim_rate())
+
+        # Tell calibrator our declination as well
+        calib_set_decln(self.decln)
+
+        # Start the timer for the LMST display
+        self.lmst_timer.Start(1000)
+
+
+    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'])
+
+        def _form_set_decln(kv):
+            return self.set_decln(kv['decln'])
+
+        # Position the FFT display
+        vbox.Add(self.scope.win, 15, wx.EXPAND)
+
+        # Position the Total-power stripchart
+        vbox.Add(self.chart.win, 15, wx.EXPAND)
+        
+        # add control area at the bottom
+        self.myform = myform = form.form()
+        hbox = wx.BoxSizer(wx.HORIZONTAL)
+        hbox.Add((7,0), 0, wx.EXPAND)
+        vbox1 = wx.BoxSizer(wx.VERTICAL)
+        myform['freq'] = form.float_field(
+            parent=self.panel, sizer=vbox1, label="Center freq", weight=1,
+            callback=myform.check_input_and_call(_form_set_freq, self._set_status_msg))
+
+        vbox1.Add((4,0), 0, 0)
+
+        myform['lmst_high'] = form.static_text_field(
+            parent=self.panel, sizer=vbox1, label="Current LMST", weight=1)
+        vbox1.Add((4,0), 0, 0)
+
+        myform['spec_data'] = form.static_text_field(
+            parent=self.panel, sizer=vbox1, label="Spectral Cursor", weight=1)
+        vbox1.Add((4,0), 0, 0)
+
+        vbox2 = wx.BoxSizer(wx.VERTICAL)
+        g = self.subdev.gain_range()
+        myform['gain'] = form.slider_field(parent=self.panel, sizer=vbox2, label="RF Gain",
+                                           weight=1,
+                                           min=int(g[0]), max=int(g[1]),
+                                           callback=self.set_gain)
+
+        vbox2.Add((4,0), 0, 0)
+        myform['average'] = form.slider_field(parent=self.panel, sizer=vbox2, 
+                    label="Spectral Averaging (FFT frames)", weight=1, min=1, max=2000, callback=self.set_averaging)
+
+        vbox2.Add((4,0), 0, 0)
+
+        myform['integration'] = form.slider_field(parent=self.panel, sizer=vbox2,
+               label="Continuum Integration Time (sec)", weight=1, min=1, max=180, callback=self.set_integration)
+
+        vbox2.Add((4,0), 0, 0)
+        myform['decln'] = form.float_field(
+            parent=self.panel, sizer=vbox2, label="Current Declination", weight=1,
+            callback=myform.check_input_and_call(_form_set_decln))
+        vbox2.Add((4,0), 0, 0)
+
+        buttonbox = wx.BoxSizer(wx.HORIZONTAL)
+        if self.use_interfilt == True:
+            self.doit = form.button_with_callback(self.panel,
+                  label="Clear Interference List", 
+                  callback=self.clear_interferers)
+        if self.use_interfilt == True:
+            buttonbox.Add(self.doit, 0, wx.CENTER)
+        vbox.Add(buttonbox, 0, wx.CENTER)
+        hbox.Add(vbox1, 0, 0)
+       hbox.Add(vbox2, wx.ALIGN_RIGHT, 0)
+        vbox.Add(hbox, 0, wx.EXPAND)
+
+        self._build_subpanel(vbox)
+
+        self.lmst_timer = wx.PyTimer(self.lmst_timeout)
+        self.lmst_timeout()
+
+
+    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)
+        
+        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.static_float_field(
+            parent=panel, sizer=hbox, label="Decim")
+
+        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.
+        """
+        #
+        # Everything except BASIC_RX should support usrp.tune()
+        #
+        if not (self.cardtype == usrp_dbid.BASIC_RX):
+            r = usrp.tune(self.u, 0, self.subdev, target_freq)
+        else:
+            r = self.u.set_rx_freq(0, target_freq)
+            f = self.u.rx_freq(0)
+            if abs(f-target_freq) > 2.0e3:
+                r = 0
+        if r:
+            self.myform['freq'].set_value(target_freq)     # update displayed value
+            #
+            # Make sure calibrator knows our target freq
+            #
+
+            # Remember centerfreq---used for doppler calcs
+            delta = self.centerfreq - target_freq
+            self.centerfreq = target_freq
+            self.observing -= delta
+            self.scope.set_baseband_freq (self.observing)
+            calib_set_freq(self.observing)
+
+            # Clear interference list
+            self.clear_interferers()
+
+            self.myform['baseband'].set_value(r.baseband_freq)
+            self.myform['ddc'].set_value(r.dxc_freq)
+
+            return True
+
+        return False
+
+    def set_decln(self, dec):
+        self.decln = dec
+        self.myform['decln'].set_value(dec)     # update displayed value
+        calib_set_decln(dec)
+
+    def set_gain(self, gain):
+        self.myform['gain'].set_value(gain)     # update displayed value
+        self.subdev.set_gain(gain)
+
+        #
+        # Make sure calibrator knows our gain setting
+        #
+        calib_set_gain(gain)
+
+    def set_averaging(self, avval):
+        self.myform['average'].set_value(avval)
+        self.scope.set_avg_alpha(1.0/(avval))
+        calib_set_avg_alpha(avval)
+        self.scope.set_average(True)
+
+    def set_integration(self, integval):
+        self.integrator3.set_taps(1.0/integval)
+        self.myform['integration'].set_value(integval)
+
+        #
+        # Make sure calibrator knows our integration time
+        #
+        calib_set_integ(integval)
+
+    def lmst_timeout(self):
+         self.locality.date = ephem.now()
+         sidtime = self.locality.sidereal_time()
+         self.myform['lmst_high'].set_value(str(ephem.hours(sidtime)))
+
+    def xydfunc(self,xyv):
+        magn = int(log10(self.observing))
+        if (magn == 6 or magn == 7 or magn == 8):
+            magn = 6
+        dfreq = xyv[0] * pow(10.0,magn)
+        ratio = self.observing / dfreq
+        vs = 1.0 - ratio
+        vs *= 299792.0
+        if magn >= 9:
+           xhz = "Ghz"
+        elif magn >= 6:
+           xhz = "Mhz"
+        elif magn <= 5:
+           xhz =  "Khz"
+        s = "%.6f%s\n%.3fdB" % (xyv[0], xhz, xyv[1])
+        s2 = "\n%.3fkm/s" % vs
+        self.myform['spec_data'].set_value(s+s2)
+
+    def interference(self,x):
+        if self.use_interfilt == False:
+            return
+        magn = int(log10(self.observing))
+        dfreq = x * pow(10.0,magn)
+        delta = dfreq - self.observing
+        fincr = self.bw / len(self.intmap)
+        l = len(self.intmap)
+        if delta > 0:
+            offset = delta/fincr
+        else:
+            offset = (l) - int((abs(delta)/fincr))
+
+        offset = int(offset)
+
+        if offset >= len(self.intmap) or offset < 0:
+            print "interference offset is invalid--", offset
+            return
+
+        #
+        # Zero out the region around the selected interferer
+        #
+        self.intmap[offset-2] = complex (0.5, 0.0)
+        self.intmap[offset-1] = complex (0.25, 0.0)
+        self.intmap[offset] = complex (0.0, 0.0)
+        self.intmap[offset+1] = complex(0.25, 0.0)
+        self.intmap[offset+2] = complex(0.5, 0.0)
+
+        #
+        # Set new taps
+        #
+        tmp = FFT.inverse_fft(self.intmap)
+        self.interfilt.set_taps(tmp)
+
+    def clear_interf(self):
+         self.clear_interferers()
+
+    def clear_interferers(self):
+         for i in range(0,len(self.intmap)):
+             self.intmap[i] = complex(1.0,0.0)
+         tmp = FFT.inverse_fft(self.intmap)
+         if self.use_interfilt == True:
+             self.interfilt.set_taps(tmp)
+   
+
+
+    def toggle_cal(self):
+        if (self.calstate == True):
+          self.calstate = False
+          self.u.write_io(0,0,(1<<15))
+          self.calibrator.SetLabel("Calibration Source: Off")
+        else:
+          self.calstate = True
+          self.u.write_io(0,(1<<15),(1<<15))
+          self.calibrator.SetLabel("Calibration Source: On")
+
+    def toggle_annotation(self):
+        if (self.annotate_state == True):
+          self.annotate_state = False
+          self.annotation.SetLabel("Annotation: Off")
+        else:
+          self.annotate_state = True
+          self.annotation.SetLabel("Annotation: On")
+        calib_set_interesting(self.annotate_state)
+        
+
+def main ():
+    app = stdgui.stdapp(app_flow_graph, "RADIO ASTRONOMY SPECTRAL/CONTINUUM RECEIVER: $Revision$", nstatus=1)
+    app.MainLoop()
+
+if __name__ == '__main__':
+    main ()
diff --git a/gr-usrp/AUTHORS b/gr-usrp/AUTHORS
new file mode 100644 (file)
index 0000000..ee4560a
--- /dev/null
@@ -0,0 +1 @@
+Eric Blossom <eb@comsec.com>
diff --git a/gr-usrp/ChangeLog b/gr-usrp/ChangeLog
new file mode 100644 (file)
index 0000000..9744d39
--- /dev/null
@@ -0,0 +1,374 @@
+2006-06-17  Eric Blossom  <eb@comsec.com>
+
+       * src/usrp.py, src/usrp1.i, src/usrp1_sink_base.cc, src/usrp1_sink_base.h,
+       src/usrp1_sink_c.cc, src/usrp1_sink_c.h, src/usrp1_sink_s.cc,
+       src/usrp1_sink_s.h, src/usrp1_source_base.cc, src/usrp1_source_base.h,
+       src/usrp1_source_c.cc, src/usrp1_source_c.h, src/usrp1_source_s.cc,
+       src/usrp1_source_s.h: changed constructor args to add
+       fusb_block_size and fusb_nblocks so that the application can
+       adjust the amount of buffering being done.  [This was an awful lot
+       of files to have to touch to make this change.  There must be an
+       easier way?]
+
+
+2006-05-11  Martin Dudok van Heel <nldudok1 at olifantasia dot com>
+       Added synchronised multi_usrp support. 
+       This work was funded by Toby Oliver at Sensus Analytics / Path Intelligence.
+
+       See README_MULTI_USRP.txt and the multi_usrp examples on how to use.
+        In short:  
+        Connect the 64MHz clocks between the boards with a short sma coax cable.
+       (See the wiki on how to enable clock-out and clock-in 
+         http://comsec.com/wiki?USRPClockingNotes )
+       Connect io15 on the RXA daughterboards of both usrps
+        instantiate multi=usrp_multi.multi_source_align([args])
+        The 4 aligned channels become available as:
+        (multi.get_master_source_c(),1) (multi.get_master_source_c(),2)
+        (multi.get_slave_source(),1) (multi.get_slave_source(),2)
+        call multi.sync() at least once AFTER the flowgraph has started running
+
+       * READMU_MULTI_USRP.txt: new
+       * configure.ac: added missing newline at end of file
+       * src/Makefile.am: added usrp_multi.py
+       * src/usrp1.i: added _write_fpga_reg_masked
+       * src/usrp1_source_base.[cc,h]: added _write_fpga_reg_masked
+       * src/usrp_multi.py: new Instantiate a usrp_multi.multi_source_align to
+                                get aligned streams from two usrps. 
+
+2006-03-11  Matt Ettus  <matt@ettus.com>
+
+       * src/Makefile.am, src/db_flexrf_mimo.py, src/usrp.py:  New skeleton 
+       file for mimo mode with the flexrf boards
+
+       * src/db_base.py:  added standard code to control refclock and
+       adc buffer bypass so all dboards can do it the same way.  Taken from
+       db_dbs_rx.py
+
+       * src/db_tv_rx.py:  Use standard method for adc buffer bypass
+
+       * src/db_flexrf.py:  Use standard method for adc buffer bypass
+
+       * src/db_dbs_rx.py:  Use standard methods for adc buffer bypass and
+       refclock control
+
+       * src/db_basic.py:  Use standard method for adc buffer bypass,
+       and instantiate a BasicTX when the unknown or missing board is on
+       the TX side
+
+2006-03-10  Eric Blossom  <eb@comsec.com>
+
+       * src/db_dbs_rx.py (db_dbs_rx._refclk_freq): replaced 64e6 with
+       call to fpga_master_clock_freq().
+
+2006-02-18  Eric Blossom  <eb@comsec.com>
+
+       * src/usrp1_{sink,source}_{base,c,s}.{h,cc}, src/usrp1.i,
+       src/usrp.py: added support for specifying the firmware and fpga
+       files that are to be loaded.
+
+2006-02-17  Eric Blossom  <eb@comsec.com>
+
+       * src/usrp1.i, src/usrp1_{sink,source}_base.{h,cc}: added serial_number()
+
+2006-01-30  Eric Blossom  <eb@comsec.com>
+
+       * src/db_base.py, src/db_flexrf.py: revised to use new auto t/r
+       switching strategy.  FR_ATR_CTL no longer exists.  We control auto
+       t/r via the FR_ATR_MASK* registers.
+
+2006-01-25  Eric Blossom  <eb@comsec.com>
+
+       * src/usrp.py (usrp_common): added code to read FPGA capability register.
+       (determine_tx_mux_value): new utility.
+
+2006-01-22  Eric Blossom  <eb@comsec.com>
+
+       * src/usrp.py (pick_rx_subdevice): added latest d'board revs to list.
+
+2006-01-04  Eric Blossom  <eb@comsec.com>
+
+       * src/usrp1_{sink,source}_{s,c}.cc: added usrp_bytesex.h include and
+       use usrp_to_host_short or host_to_usrp_short as appropriate to
+       handle usrp to host endianness differences.
+       
+       * configure.ac: added AC_C_BIGENDIAN and header check for byteswap.h
+
+2005-12-20  Matt Ettus  <matt@ettus.com>
+
+       * src/db_base.py (db_base.spectrum_inverted): Base function
+       defaults to no spectrum inversion, so we can handle daughterboards
+       which have analog spectra which are inverted (currently only tvrx2)
+       
+       * src/db_tv_rx.py (db_tv_rx.spectrum_inverted): Report that the
+       tvrx2 has inverted spectrum, the tvrx does not
+
+       * src/usrp.py (tune): Handle daughterboards which have analog
+       spectra which are inverted (currently only tvrx2)
+       
+
+2005-12-08  Eric Blossom  <eb@comsec.com>
+
+       * src/usrp1_sink_s.cc (usrp1_sink_s): call set_output_multiple so
+       we ensure 512 byte writes across USB.
+
+2005-12-07  Eric Blossom  <eb@comsec.com>
+
+       * src/usrp.py: revised sink_c, sink_s, source_c and source_s to
+       properly fire daughterboard destructors.  Without this, we had the
+       nasty habit of leaving the transmitter running if the user didn't
+       explicitly disable it.
+
+2005-12-05  Eric Blossom  <eb@comsec.com>
+
+       * src/db_base.py, src/db_flexrf.py: refactored to use new
+       Auto T/R switching.
+
+       * src/db_flexrf.py (flexrf_base.set_freq): Offset the LO by 4 MHz.
+       Helps initial lock-up time with discontinuous transmission.
+
+2005-11-22  Eric Blossom  <eb@comsec.com>
+
+       * src/db_base.py, src/db_flexrf.py: renamed set_auto_tx to set_auto_tr.
+
+2005-11-17  Eric Blossom  <eb@comsec.com>
+
+       * src/usrp1_sink_base.cc: reduced amount of USB Tx buffering.
+
+2005-11-13  Eric Blossom  <eb@comsec.com>
+
+       * src/db_base.py (db_base.set_auto_tx): new stub method.
+
+2005-11-11  Eric Blossom  <eb@comsec.com>
+
+       * src/usrp.py (pick_rx_subdevice): moved to library.
+
+2005-11-10  Matt Ettus  <matt@ettus.com>
+
+       * src/db_flexrf.py (flexrf_base_tx.set_enable): fixed definition.
+
+2005-10-27  Eric Blossom  <eb@comsec.com>
+
+       * src/db_base.py, src/db_flexrf.py: new method: set_enable
+
+2005-10-20  Eric Blossom  <eb@comsec.com>
+
+       * src/usrp1_source_s.{h,cc}, src/usrp1_source_c.{h,cc}: support
+       both 8 and 16-bit samples across the USB.
+       * src/usrp1.i, src/usrp1_source_base.{h,cc}: new methods for
+       setting and getting rx format.
+
+2005-10-11  Eric Blossom  <eb@comsec.com>
+
+       * src/usrp.py: removed dispatch on usrp revision (no longer
+       support rev0 boards).  Constructors now take keyword args, thus
+       all args are optional.  This will allow us to get rid of the 64e6's
+       and 128e6's that are scattered throughout the example code.
+       * src/usrp1.i: removed default values from constructors.  They are
+       now provided by keyword args in usrp.py
+
+2005-09-29  Eric Blossom  <eb@comsec.com>
+
+       * src/db_dbs_rx.py (db_dbs_rx.freq_range): set freq step size to 1M
+
+2005-09-27  Eric Blossom  <eb@comsec.com>
+
+       * src/db_base.py (db_base.i_and_q_swapped): new method for 
+       Flex 400 Rx and other boards that route I into ADC 1 instead of 0.
+
+       * src/usrp.py (tune): added tune fct.  Reworked subdev_spec.  No
+       longer accepts (0|1, None).  Check for and handle i_and_q_swapped.
+
+2005-09-21  Eric Blossom  <eb@comsec.com>
+
+       * src/db_basic.py: new.
+       * src/db_instantiator.py, src/usrp.py:  added framework for
+       automatically instantiating daughterboard subclasses.
+       
+       * src/usrp1.i, src/usrp1_sink_base.{h,cc},
+       src/usrp1_source_base.{h,cc}: deprecated adc_freq(), dac_freq(),
+       recommend converter_rate().
+       
+2005-09-17  Eric Blossom  <eb@comsec.com>
+
+       * src/db_dbs_rx.py: renamed from dbs_rx.py
+       * src/db_flexrf.py: renamed from flexrf.py
+       * src/db_tv_rx.py: renamed from tv_rx.py
+       * src/db_base.py: renamed from daughterboard_base.py
+
+2005-08-28  Eric Blossom  <eb@comsec.com>
+
+       * src/flexrf.py: added hook to invoke debugging gui.
+       * src/flexrf_debug_gui.py: new debugging tool.
+
+2005-07-19  Eric Blossom  <eb@comsec.com>
+
+       * src/usrp1_source_base.{h,cc}, src/usrp1.i: new method: set_ddc_phase.
+
+2005-07-02  Eric Blossom  <eb@comsec.com>
+
+       * config/gr_no_undefined.m4, config/gr_x86_64.m4: new, x86_64 support.
+       * config/gr_python.m4: backed out search for libpython, making
+       x86_64 work and breaking Cygwin/MinGW.
+       * configure.ac, src/Makefile.am: mods for x86_64, $(NO_UNDEFINED)
+       
+2005-06-09  Eric Blossom  <eb@comsec.com>
+
+       * src/gen_usrp_dbids.py: new.  Generate usrp_dbids.py from
+       usrp_daughterboards.h.  This file contains symbolic names for for
+       daughterboard ID's.
+
+2005-05-18  Eric Blossom  <eb@comsec.com>
+
+       * src/usrp1_sink_base.{h,cc}, src/usrp1_source_base.{h,cc}: use
+       new start/stop methods.
+
+2005-05-09  Stephane Fillod  <f8cfe@free.fr>
+
+        * config/gr_sysv_shm.m4: SysV shared memory not mandatory
+       * config/gr_pwin32.m4, config/gr_python.m4, config/lf_cxx.m4:
+         fixes for Cygwin, MinGW
+
+2005-03-29  Eric Blossom  <eb@comsec.com>
+
+       * src/usrp.py: now check for usrp version at open time, not import
+       time.
+
+2005-03-15  Eric Blossom  <eb@comsec.com>
+
+       * src/usrp1_sink_base.{h,cc}, src/usrp1_source_base.{h,cc}:
+       read_aux_dac and write_aux_dac now take which_dboard instead of slot.
+
+2005-03-13  Matt Ettus <matt@ettus.com>
+
+       * src/Makefile.am, src/tv_rx.py: first cut at TV RX dboard
+       * src/dbs_rx.py: minor fixes
+
+2005-03-11  Eric Blossom  <eb@comsec.com>
+
+       * src/usrp1_sink_base.{h,cc},src/usrp1_source_base.{h,cc}: new
+       methods: set_adc_offset, set_dac_offset, set_adc_buffer_bypass.
+
+2005-02-18  Eric Blossom  <eb@comsec.com>
+
+       * src/usrp1_sink_base.cc (_write_oe): fix delegation.
+       * src/usrp1_source_base.cc (_write_oe): fix delegation.
+
+2005-02-16  Eric Blossom  <eb@comsec.com>
+
+       * src/dbs_rx.py: new. control DBS_RX daughterboard.
+       * src/usrp1_{sink,source}_base.{h,cc}: add read_i2c and write_i2c.
+       
+2005-02-06  Eric Blossom  <eb@comsec.com>
+
+       * configure.ac: upped rev to 0.4 for release.
+       * src/Makefile.am: backed out dependency on libpython
+
+2005-01-28  Stephane Fillod <f8cfe@free.fr>
+
+       * src/Makefile.am: fixes for MinGW.
+       
+2005-01-12  Eric Blossom  <eb@comsec.com>
+
+       * src/usrp1_sink_base.cc,src/usrp1_source_base.cc: changed
+       under/overrun diagnostic indicator to "uU" and "uO" to reduce
+       amount of diagnostic output.
+
+2005-01-10  Eric Blossom  <eb@comsec.com>
+
+       * src/usrp1.i,src/usrp1_sink_base.{h,cc},
+       src/usrp1_source_base.{h,cc}: new methods to control all knobs.
+
+2005-01-04  Eric Blossom  <eb@comsec.com>
+
+       * src/usrp1.i,src/usrp1_source_base.{h,cc}: new methods for
+       messing with Rx PGA. 
+
+2004-11-14  Eric Blossom  <eb@comsec.com>
+
+       * src/usrp1_sink_base.cc (work): corrected increment of obi.
+
+2004-10-13  Eric Blossom  <eb@comsec.com>
+
+       * configure.ac: upped rev to 0.2cvs
+
+2004-10-11  Eric Blossom  <eb@comsec.com>
+
+       * configure.ac: bumped rev to 0.2, make release.
+       * Makefile.am (EXTRA_DIST): added config.h.in
+
+2004-09-30  Eric Blossom  <eb@comsec.com>
+
+       * src/usrp1_sink_base.{h,cc}, src/usrp1_source_base.{h,cc},
+       src/usrp1.i: new methods for reading and writing aux dac and adc,
+       eeproms, and fpga registers.
+
+2004-09-23  Eric Blossom  <eb@comsec.com>
+
+       * config/usrp_fusb_tech.m4, config/bnv_have_qt.m4, config/cppunit.m4,
+       config/gr_check_mc4020.m4, config/gr_check_usrp.m4, config/gr_doxygen.m4,
+       config/gr_gprof.m4, config/gr_scripting.m4, config/gr_set_md_cpu.m4,
+       config/pkg.m4, config/usrp_fusb_tech.m4: added additional quoting
+       to first arg of AC_DEFUN to silence automake warning.
+
+2004-08-19  Eric Blossom  <eb@comsec.com>
+
+       * src/usrp1_{sink,source}_base.{h,cc}, src/usrp1.i: new method: set_verbose.
+
+2004-08-03  Eric Blossom  <eb@comsec.com>
+
+       * src/usrp1_source_base.{h,cc}, src/usrp1_sink_base.{h,cc}:
+       extracted base class that handles everything but the packing and
+       unpacking of data into the usrp buffer.
+       * src/usrp1_source_c.{h,cc}, src/usrp1_sink_c.{h,cc}: revised to
+       use new base class.
+       * src/usrp1_source_s.{h,cc}, src/usrp1_sink_s.{h,cc}: new.
+       
+
+2004-07-31  Eric Blossom  <eb@comsec.com>
+
+       * src/usrp1_{sink,source}_c.{h,cc}: new method: set_loopback
+       * src/usrp1.i: new method: set_loopback
+
+2004-07-30  Eric Blossom  <eb@comsec.com>
+
+       * src/usrp1_source_c.{h,cc}: renamed from usrp_source_c.{h,cc}
+       * src/usrp1_sink_c.{h,cc}: renamed from usrp_sink_c.{h,cc}
+       * src/usrp1.i: renamed from usrp.i
+       * src/usrp.py: new.  Binds proper class depending on hardware found.
+       
+
+2004-07-29  Eric Blossom  <eb@comsec.com>
+
+       * src/usrp_{sink,source}_c.h: doc fix.
+       * src/usrp0.i: new
+       * src/usrp0_source_c.{h,cc}: new
+       * src/usrp0_sink_c.{h,cc}: new
+
+2004-07-12  Eric Blossom  <eb@comsec.com>
+
+       * configure.ac: upped rev to 0.1cvs
+
+2004-07-08  Eric Blossom  <eb@comsec.com>
+
+       * src/usrp_source_c.{h,cc}: new.
+
+#
+# Copyright 2004,2005,2006 Free Software Foundation, Inc.
+# 
+# This file is part of GNU Radio
+# 
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 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.
+# 
diff --git a/gr-usrp/Makefile.am b/gr-usrp/Makefile.am
new file mode 100644 (file)
index 0000000..e500700
--- /dev/null
@@ -0,0 +1,25 @@
+#
+# 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.
+# 
+
+include $(top_srcdir)/Makefile.common
+
+EXTRA_DIST = README_MULTI_USRP.txt
+SUBDIRS = src
diff --git a/gr-usrp/README_MULTI_USRP.txt b/gr-usrp/README_MULTI_USRP.txt
new file mode 100644 (file)
index 0000000..4ed7a15
--- /dev/null
@@ -0,0 +1,251 @@
+Multi usrp
+
+With this code you can connect two or more usrps (with a locked clock) and get synchronised samples.
+You must connect a (flat)cable between a dboard on the master in RXA and a dboard on the slave in RXA.
+You then put one usrp in master mode, put the other in slave mode.
+
+For a quick start using the examples look at gnuradio-examples/python/multi_usrp/README
+
+Use the usrp_multi block which is installed by gr-usrp.
+instantiate in the following way:
+
+        self.multi=usrp_multi.multi_source_align( fg=self, master_serialno=options.master_serialno, decim=options.decim, nchan=options.nchan )
+
+nchan should be 2 or 4.
+
+You determine which is the master by master_serialno (this is a text string a hexadecimal number).
+If you enter a serial number which is not found it will print the serial numbers which are available.
+If you give no serial number  (master_serialno=None), the code will pick a Master for you.
+
+You can get a reference to the master and the slave usrp in the following way:
+
+        self.um=self.multi.get_master_usrp()
+        self.us=self.multi.get_slave_usrp()
+
+You only need these references for setting freqs/gains or getting info about daughterboards.
+Don't use the output directly but use the aligned output from multi.get_master_source_c() and multi.get_slave_source_c()
+
+You get references to the aligned output samples in the following way:
+aligned_master_source_c=self.multi.get_master_source_c()
+aligned_slave_source_c=self.multi.get_slave_source_c()
+
+These blocks have multiple outputs.
+output 0 is the sample counter (high bits in I, low bits in Q)
+You normally don't need the samplecounters so you can ignore output 0
+
+output 1 is the first aligend output channel (if you enable 2 or 4 channels)
+output 2 is the second output channel (only if you enable 4 channels)
+
+so the usefull 4 channels are:
+self.aligned_master_chan1=(self.multi.get_master_source_c(),1)
+self.aligned_master_chan2=(self.multi.get_master_source_c(),2)
+self.aligned_slave_chan1=(self.multi.get_slave_source_c(),1)
+self.aligned_slave_chan2=(self.multi.get_slave_source_c(),2)
+
+The two samplecounters are:
+self.aligned_master_samplecounter=(self.multi.get_master_source_c(),0)
+self.aligned_slave_samplecounter=(self.multi.get_slave_source_c(),0)
+
+You can set the gain or tune the frequency for all 4 receive daughetrboards at once:
+        self.multi.set_gain_all_rx(options.gain)
+        result,r1,r2,r3,r4 = self.multi.tune_all_rx(options.freq)
+
+This will only work reliably when you have all the same daughterboards.
+Otherwise set all freqs and gains individually.
+
+You must call self.multi.sync() at least once AFTER the flowgraph has started running.
+(This will synchronise the streams of the two usrps)
+
+This work was funded by Toby Oliver at Sensus Analytics / Path Intelligence.
+Many Thanks for making this possible.
+
+It was written by Martin Dudok van Heel at Olifantasia.
+
+Quick start multi-usrp:
+Unpack, build and install usrp, gnuradio-core and gr-usrp
+Versions need to be more recent then 2.7cvs/svn 11 may 2006
+
+Make sure usrp/fpga/rbf/rev2/multi*.rbf is installed in /usr/local/share/usrp/rev2/
+Make sure usrp/fpga/rbf/rev4/multi*.rbf is installed in /usr/local/share/usrp/rev4/
+(If in doubt, copy manually)
+build and install gr-wxgui gr-audio-xxx  and so on.
+
+unpack gnuradio-examples.
+
+There is a gnuradio-examples/python/multi_usrp directory which contains examples and a README
+
+
+Put at least a basic RX or dbsrx board in RXA of the master and RXA of the slave board.
+Make sure that the usrps have a serial or unique identifier programmed in their eeprom.
+(All new rev 4.1 boards have this)
+You can do without a serial but then you never know which usrp is the master and which is the slave.
+
+
+CONNECTING THE CABLES
+Now connect the 64MHz clocks between the boards with a short sma coax cable.
+(See the wiki on how to enable clock-out and clock-in 
+http://comsec.com/wiki?USRPClockingNotes )
+
+You need one board with a clock out and one board with a clock in.
+
+You can choose any of the two boards as master or slave, this is not dependant on which board has the clock-out or in.
+In my experiments I had fewer problems when the board that has the clock-in will be the master board.
+
+You can use a standard 16-pole flatcable to connect tvrx, basic-rx or dbsrx boards.
+Of this 16pin flatcable only two pins are used (io15 and ground)
+For all new daughterboards which use up a lot of io pins you have to use a cable with fewer connections.
+The savest is using a 2pin headercable connected to io15,gnd (a cable like the ones used to connect frontpanel leds to the mainboard of a PC)
+
+If using basic rx board:
+  Connect a 16-pole flatcable from J25 on basicrx/dbs_rx in rxa of the master usrp to J25 on basicrx/dbsrx in RXA of the slave usrp
+  Don't twist the cable (Make sure the pin1 marker (red line on the flatcable) is on the same side of the connector (at io-8 on the master and at io8 on the slave.))
+  For basic_rx this means the marker should be on the side of the dboard with the sma connectors. 
+  For dbs_rx this means the marker should be on the side of the dboard with the two little chips.
+  In other words, don't twist the cable, you will burn your board if you do.
+
+You can also connect a flatcable with multiple connectors from master-J25 to slave1-J25 to slave2-J25 to ...
+You will however have to think of something to create a common 64Mhz clock for more then two usrps.
+
+For all other daughterboards, connect a 2wire cable from masterRXA J25 io15,gnd to slaveRXA J25 io15,gnd 
+
+
+So now the hardware is setup, software is setup. Lets do some tests.
+
+Connect power to both usrps.
+unpack the gnuradio_examples somewhere (cvs version later then 11 may 2006) 
+go to the gnuradio-examples/python/multi_usrp folder.
+
+Now run 
+ ./multi_usrp_oscope.py -x 12345678
+
+It should tell you that usrp 12345678 is not found and tell you which serials are available.
+
+Now run  ./multi_usrp_oscope.py -x actualserialnum 
+You should now get an oscope with two channels, one is from the master and one is from the slave
+It will which show the I-signal from channel 0 of the master usrp and I-signal from channel 0 of the slave usrp.
+(For testing connect the same signal source to the inputs of both boards)
+The signals should be aligned.
+If you click the sync button, it will resync the master and slave (should never be needed)
+
+Now run
+./multi_usrp_oscope.py --help
+To see all available options.
+
+
+Now you are ready to do phase-locked aligned signal processing.
+
+You can also capture to file with:
+./multi_usrp_rx_cfile.py 
+
+run ./multi_usrp_rx_cfile.py --help to see all available options.
+
+
+Here follows a brief of the new blocks and (changes)functionality for multi-usrp.
+You can also look at the generated documentation in  
+/usr/local/share/doc/gnuradio-core-X.X
+/usr/local/share/doc/usrp-X.X
+(Make sure to build and install the documentation, go to the doc directory of the sourcetree and issue make doc; make install)
+
+gnuradio-examples:
+new/changed files:
+multi_usrp/multi_usrp_oscope.py
+multi_usrp/multi_usrp_rx_cfile.py
+
+
+gnuradio-core:
+gr.align_on_samplenumbers_ss (int nchan,int align_interval) 
+
+align several complex short (interleaved short) input channels with corresponding unsigned 32 bit sample_counters (provided as interleaved 16 bit values)
+
+Parameters:
+       nchan   number of complex_short input channels (including the 32 bit counting channel)
+       align_interval  interval at which the samples are aligned, ignored for now.
+
+Pay attention on how you connect this block It expects a minimum of 2 usrp_source_s with nchan number of channels and as mode  usrp_prims.bmFR_MODE_RX_COUNTING_32BIT enabled. This means that the first complex_short channel is an interleaved 32 bit counter. The samples are aligned by dropping samples untill the samplenumbers match.
+
+files:
+gnuradio-core/src/lib/general/gr_align_on_samplenumbers_ss.cc
+gnuradio-core/src/lib/general/gr_align_on_samplenumbers_ss.h
+gnuradio-core/src/lib/general/gr_align_on_samplenumbers_ss.i
+
+
+gr-usrp
+   added _write_fpga_reg_masked
+   added usrp_multi.py
+  new usrp_multi block which can instantiate two linked usrps as master and slave and alignes their output.
+  It has a sync() function which should be called AFTER the flowgraph has started running.
+  bool sync();
+     \brief Call this on a master usrp to sync master and slave by outputing a sync pulse on rx_a_io[15].
+        The 32 bit samplecounter of master and slave will be reset to zero and all phase and buffer related things in the usrps are reset.
+        Call this only after the flowgraph has been started, otherwise there will be no effect since everything is kept in reset state as long as the flowgraph is not running.
+     \returns true if successfull.
+
+files:
+configure.ac
+src/Makefile.am
+src/usrp1.i
+src/usrp1_source_base.cc
+src/usrp1_source_base.h
+src/usrp_multi.py
+
+usrp-0.11cvsmulti:
+usrp:
+   new constant bmFR_MODE_RX_COUNTING_32BIT    (could also be added as extra mode like FPGA_MODE_COUNTING_32BIT)
+   Use this for the mode parameter when creating a usrp when you want to use the master/slave setup or if you want to use the 32 bit counter for other things, like testing with gr.check_counting_s(True)
+
+  added register FR_RX_MASTER_SLAVE
+  added bitno and bitmaskes:
+   bmFR_MODE_RX_COUNTING_32BIT
+
+   bitnoFR_RX_SYNC 
+   bitnoFR_RX_SYNC_MASTER
+   bitnoFR_RX_SYNC_SLAVE
+
+   bitnoFR_RX_SYNC_INPUT_IOPIN 15
+   bmFR_RX_SYNC_INPUT_IOPIN  (1<<bitnoFR_RX_SYNC_INPUT_IOPIN)
+   bitnoFR_RX_SYNC_OUTPUT_IOPIN 15
+   bmFR_RX_SYNC_OUTPUT_IOPIN (1<<bitnoFR_RX_SYNC_OUTPUT_IOPIN)
+   added _write_fpga_reg_masked()
+   added new toplevel folder usrp_multi
+   added usrp_multi.v and master_control_multi.v
+   added new MULTI_ON and COUNTER_32BIT_ON defines
+      If these are turned off usrp_multi.v will behave exactly as usrp_std.v
+
+   added setting_reg_masked.v
+   changed reset behaviour of phase_acc.v and rx_buffer.v
+
+   changed generate_regs.py to handle bm and bitno defines
+
+
+files:
+firmware/include/fpga_regs_standard.v
+firmware/include/fpga_regs_common.h
+firmware/include/generate_regs.py
+firmware/include/fpga_regs_standard.h
+host/lib/usrp_basic.h
+host/lib/usrp_basic.cc
+host/lib/usrp_standard.h
+fpga/rbf/Makefile.am
+fpga/toplevel/usrp_std/usrp_std.v
+fpga/toplevel/usrp_multi/usrp_multi.esf
+fpga/toplevel/usrp_multi/usrp_multi.vh
+fpga/toplevel/usrp_multi/usrp_std.vh
+fpga/toplevel/usrp_multi/usrp_multi_config_2rxhb_0tx.vh
+fpga/toplevel/usrp_multi/usrp_multi_config_2rxhb_2tx.vh
+fpga/toplevel/usrp_multi/usrp_multi.v
+fpga/toplevel/usrp_multi/usrp_multi.qpf
+fpga/toplevel/usrp_multi/usrp_multi.psf
+fpga/toplevel/usrp_multi/usrp_multi_config_2rx_0tx.vh
+fpga/toplevel/usrp_multi/usrp_multi.qsf
+fpga/toplevel/usrp_multi/usrp_multi_config_4rx_0tx.vh
+fpga/toplevel/usrp_multi/usrp_multi.csf
+fpga/toplevel/usrp_multi/.cvsignore
+fpga/sdr_lib/rx_buffer.v
+fpga/sdr_lib/master_control_multi.v
+fpga/sdr_lib/phase_acc.v
+fpga/sdr_lib/setting_reg_masked.v
+
+
diff --git a/gr-usrp/src/Makefile.am b/gr-usrp/src/Makefile.am
new file mode 100644 (file)
index 0000000..0bcd6c4
--- /dev/null
@@ -0,0 +1,120 @@
+#
+# Copyright 2004,2005,2006 Free Software Foundation, Inc.
+# 
+# This file is part of GNU Radio
+# 
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 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.
+# 
+
+include $(top_srcdir)/Makefile.common
+
+# Install this stuff so that it ends up as the gnuradio.usrp module
+# This usually ends up at:
+#   ${prefix}/lib/python${python_version}/site-packages/gnuradio
+
+ourpythondir = $(grpythondir)
+ourlibdir    = $(grpyexecdir)
+
+EXTRA_DIST = run_tests.in
+TESTS = run_tests
+
+LOCAL_IFILES =                                 \
+       usrp1.i                         
+
+NON_LOCAL_IFILES =                     \
+       $(top_srcdir)/gnuradio-core/src/lib/swig/gnuradio.i
+
+ALL_IFILES =                           \
+       $(LOCAL_IFILES)                 \
+       $(NON_LOCAL_IFILES)             
+
+BUILT_SOURCES =                        \
+       usrp1.cc                        \
+       usrp1.py                        
+
+ourpython_PYTHON =                     \
+       db_base.py                      \
+       db_basic.py                     \
+       db_dbs_rx.py                    \
+       db_flexrf.py                    \
+       db_flexrf_mimo.py               \
+       db_instantiator.py              \
+       db_tv_rx.py                     \
+       flexrf_debug_gui.py             \
+       tx_debug_gui.py                 \
+       usrp.py                         \
+       usrp1.py                        \
+        usrp_multi.py                  
+
+
+USRP_INCLUDES = -I$(top_srcdir)/usrp/host/lib -I$(top_srcdir)/usrp/firmware/include
+USRP_LIBS = -L$(top_srcdir)/usrp/host/lib/.libs -lusrp
+
+INCLUDES = $(STD_DEFINES_AND_INCLUDES) $(PYTHON_CPPFLAGS) 
+
+SWIGPYTHONARGS = $(SWIGPYTHONFLAGS) $(STD_DEFINES_AND_INCLUDES) $(USRP_INCLUDES)
+
+grinclude_HEADERS =                    \
+       usrp1_sink_base.h               \
+       usrp1_sink_c.h                  \
+       usrp1_sink_s.h                  \
+       usrp1_source_base.h             \
+       usrp1_source_c.h                \
+       usrp1_source_s.h                
+
+swiginclude_HEADERS =                  \
+       $(LOCAL_IFILES)
+
+
+ourlib_LTLIBRARIES = _usrp1.la
+
+
+_usrp1_la_SOURCES =                    \
+       usrp1.cc                        \
+       usrp1_sink_base.cc              \
+       usrp1_sink_c.cc                 \
+       usrp1_sink_s.cc                 \
+       usrp1_source_base.cc            \
+       usrp1_source_c.cc               \
+       usrp1_source_s.cc               
+
+
+_usrp1_la_LIBADD =                     \
+       $(PYTHON_LDFLAGS)               \
+       $(GNURADIO_CORE_LIBS)           \
+       $(USRP_LIBS)                    \
+       -lstdc++
+
+
+_usrp1_la_LDFLAGS = $(NO_UNDEFINED) -module -avoid-version
+
+
+usrp1.cc usrp1.py: usrp1.i $(NON_LOCAL_IFILES)
+       $(SWIG) $(SWIGPYTHONARGS) -module usrp1 -o usrp1.cc $<
+
+
+noinst_PYTHON =                                \
+       qa_usrp.py                      
+
+MOSTLYCLEANFILES = \
+       $(BUILT_SOURCES) *~ *.pyc
+
+
+# Don't distribute output of swig
+dist-hook:
+       @for file in $(BUILT_SOURCES); do echo $(RM) $(distdir)/$$file; done
+       @for file in $(BUILT_SOURCES); do $(RM) $(distdir)/$$file; done
+
diff --git a/gr-usrp/src/db_base.py b/gr-usrp/src/db_base.py
new file mode 100644 (file)
index 0000000..4f4db38
--- /dev/null
@@ -0,0 +1,234 @@
+#
+# 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 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.
+# 
+
+import usrp_prims
+import weakref
+from usrp_fpga_regs import *
+
+class db_base(object):
+    """
+    Abstract base class for all daughterboards.
+
+    This defines the required operations and interfaces for all d'boards.
+    """
+    def __init__(self, usrp, which):
+        """
+        Initialize daughterboard interface.
+
+        @param usrp: instance of usrp
+        @param which: which daughterboard side: A = 0, B = 1
+        @type which: int
+        """
+
+        if not (which in (0, 1)):
+            raise ValueError, "Invalid value of which: %s" % (which,)
+
+        self._u = weakref.proxy(usrp)
+
+        self._which = which
+        if hasattr(self._u, 'tx_freq'):   # is this a tx or rx daughterboard?
+            self._tx = True
+            self._slot = which * 2
+        else:
+            self._tx = False
+            self._slot = which * 2 + 1
+
+        FR_TX_A_REFCLK = 40
+        FR_RX_A_REFCLK = 41
+        FR_TX_B_REFCLK = 42
+        FR_RX_B_REFCLK = 43
+
+        self._refclk_reg = (FR_TX_A_REFCLK,FR_RX_A_REFCLK,FR_TX_B_REFCLK,FR_RX_B_REFCLK)[self._slot]
+
+
+    def dbid(self):
+        return self._u.daughterboard_id(self._which)
+
+    def name(self):
+        return usrp_prims.usrp_dbid_to_string(self.dbid())
+
+    def side_and_name(self):
+        return "AB"[self._which] + ': ' + self.name()
+
+    # Function to bypass ADC buffers.  Any board which is DC-coupled should bypass the buffers
+    def bypass_adc_buffers(self,bypass):
+        if self._tx:
+            raise RuntimeError, "TX Board has no adc buffers"
+        if self._which==0:
+            self._u.set_adc_buffer_bypass(0, bypass)
+            self._u.set_adc_buffer_bypass(1, bypass)
+        else:
+            self._u.set_adc_buffer_bypass(2, bypass)
+            self._u.set_adc_buffer_bypass(3, bypass)
+        
+    # ------------------------------------------------------------------------
+    # 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
+    #
+    # FIXME get these from the fpga_regs_standard.h
+    
+    def _refclk_freq(self):
+        return self._u.fpga_master_clock_freq()/self._refclk_divisor()
+    
+    def _enable_refclk(self,enable):
+        CLOCK_OUT = 1   # Clock is on lowest bit
+        REFCLK_ENABLE = 0x80
+        REFCLK_DIVISOR_MASK = 0x7f
+        if enable:
+            self._u._write_oe(self._which, CLOCK_OUT, CLOCK_OUT)  # output enable
+            self._u._write_fpga_reg(self._refclk_reg,
+                                   ((self._refclk_divisor() & REFCLK_DIVISOR_MASK)
+                                    | REFCLK_ENABLE))
+        else:
+            self._u._write_fpga_reg(self._refclk_reg, 0)
+            
+    def _refclk_divisor(self):
+        """
+        Return value to stick in REFCLK_DIVISOR register
+        """
+        raise NotImplementedError
+
+    # ------------------------------------------------------------------------
+    # Automatic Transmit/Receive switching
+    #
+    # 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.
+
+    def set_atr_mask(self, v):
+        """
+        Set Auto T/R mask.
+        """
+        return self._u._write_fpga_reg(FR_ATR_MASK_0 + 3 * self._slot, v)
+
+    def set_atr_txval(self, v):
+        """
+        Set Auto T/R register value to be used when transmitting.
+        """
+        return self._u._write_fpga_reg(FR_ATR_TXVAL_0 + 3 * self._slot, v)
+
+    def set_atr_rxval(self, v):
+        """
+        Set Auto T/R register value to be used when receiving.
+        """
+        return self._u._write_fpga_reg(FR_ATR_RXVAL_0 + 3 * self._slot, v)
+
+    # derived classes should override the following methods
+
+    def freq_range(self):
+        """
+        Return range of frequencies in Hz that can be tuned by this d'board.
+
+        @returns (min_freq, max_freq, step_size)
+        @rtype tuple
+        """
+        raise NotImplementedError
+
+    def set_freq(self, target_freq):
+        """
+        Set the frequency.
+
+        @param freq:  target RF frequency in Hz
+        @type freq:   float
+
+        @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.
+        """
+        raise NotImplementedError
+
+    def gain_range(self):
+        """
+        Return range of gain that can be set by this d'board.
+
+        @returns (min_gain, max_gain, step_size)
+        Where gains are expressed in decibels (your mileage may vary)
+        """
+        raise NotImplementedError
+
+    def set_gain(self, gain):
+        """
+        Set the gain.
+
+        @param gain:  gain in decibels
+        @returns True/False
+        """
+        raise NotImplementedError
+
+    def is_quadrature(self):
+        """
+        Return True if this daughterboard does quadrature up or down conversion.
+        That is, 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.
+        """
+        raise NotImplementedError
+
+    def i_and_q_swapped(self):
+        """
+        Return True if this is a quadrature device and ADC 0 is Q.
+        """
+        return False
+
+    def spectrum_inverted(self):
+        """
+        Return True if the dboard gives an inverted spectrum
+        """
+        return False
+    
+    def set_enable(self, on):
+        """
+        For tx daughterboards, this controls the transmitter enable.
+        """
+        pass
+    
+    def set_auto_tr(self,on):
+        """
+        Enable automatic Transmit/Receive switching (ATR).
+
+        Should be overridden in subclasses that care.  This will typically
+        set the atr_mask, txval and rxval.
+        """
+        pass
+
diff --git a/gr-usrp/src/db_basic.py b/gr-usrp/src/db_basic.py
new file mode 100644 (file)
index 0000000..e913946
--- /dev/null
@@ -0,0 +1,252 @@
+#
+# 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 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.
+# 
+
+import sys
+import usrp_dbid
+import db_base
+import db_instantiator
+
+class db_basic_tx(db_base.db_base):
+    def __init__(self, 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
+        """
+        # sets _u and _which
+        db_base.db_base.__init__(self, usrp, which)
+
+        if 0:        # Doing this would give us a different default than the historical values...
+            g = self.gain_range()                  # initialize gain
+            self.set_gain(float(g[0]+g[1]) / 2)
+
+
+    def freq_range(self):
+        """
+        Return range of frequencies in Hz that can be tuned by this d'board.
+
+        @returns (min_freq, max_freq, step_size)
+        @rtype tuple
+
+        We say we can do pretty much anything...
+        """
+        return (-90e9, 90e9, 1e-6)
+
+    def set_freq(self, target_freq):
+        """
+        Set the frequency.
+
+        @param freq:  target RF frequency in Hz
+        @type freq:   float
+
+        @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 (True, 0)
+
+    def gain_range(self):
+        """
+        Return range of gain that can be set by this d'board.
+
+        @returns (min_gain, max_gain, step_size)
+        Where gains are expressed in decibels (your mileage may vary)
+        """
+        return (self._u.pga_min(), self._u.pga_max(), self._u.pga_db_per_step())
+
+    def set_gain(self, gain):
+        """
+        Set the gain.
+
+        @param gain:  gain in decibels
+        @returns True/False
+        """
+        ok = self._u.set_pga(self._which * 2 + 0, gain)
+        ok = ok and self._u.set_pga(self._which * 2 + 1, gain)
+        return ok
+
+    def is_quadrature(self):
+        """
+        Return True if this board requires both I & Q analog channels.
+        """
+        return True
+    
+
+class db_basic_rx(db_base.db_base):
+    def __init__(self, usrp, which, subdev):
+        """
+        Handler for Basic 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
+        """
+        # sets _u and _which
+        db_base.db_base.__init__(self, usrp, which)
+        self._subdev = subdev
+
+        self.bypass_adc_buffers(True)
+
+        if 0:        # Doing this would give us a different default than the historical values...
+            g = self.gain_range()                  # initialize gain
+            self.set_gain(float(g[0]+g[1]) / 2)
+
+
+    def freq_range(self):
+        """
+        Return range of frequencies in Hz that can be tuned by this d'board.
+
+        @returns (min_freq, max_freq, step_size)
+        @rtype tuple
+
+        We say we can do pretty much anything...
+        """
+        return (0, 90e9, 1e-6)
+
+    def set_freq(self, target_freq):
+        """
+        Set the frequency.
+
+        @param freq:  target RF frequency in Hz
+        @type freq:   float
+
+        @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 (True, 0)
+        
+
+    def gain_range(self):
+        """
+        Return range of gain that can be set by this d'board.
+
+        @returns (min_gain, max_gain, step_size)
+        Where gains are expressed in decibels (your mileage may vary)
+        """
+        return (self._u.pga_min(), self._u.pga_max(), self._u.pga_db_per_step())
+
+    def set_gain(self, gain):
+        """
+        Set the gain.
+
+        @param gain:  gain in decibels
+        @returns True/False
+        """
+        return self._u.set_pga(self._which * 2 + self._subdev, gain)
+
+    def is_quadrature(self):
+        """
+        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
+    
+class db_lf_rx(db_basic_rx):
+    def __init__(self, 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
+        """
+        # sets _u and _which
+        db_basic_rx.__init__(self, usrp, which, subdev)
+
+    def freq_range(self):
+        """
+        Return range of frequencies in Hz that can be tuned by this d'board.
+
+        @returns (min_freq, max_freq, step_size)
+        @rtype tuple
+
+        We cover the first nyquist zone only
+        """
+        return (0, 32e6, 1e-6)
+
+class db_lf_tx(db_basic_tx):
+    def __init__(self, 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
+        """
+        # sets _u and _which
+        db_basic_tx.__init__(self, usrp, which)
+
+    def freq_range(self):
+        """
+        Return range of frequencies in Hz that can be tuned by this d'board.
+
+        @returns (min_freq, max_freq, step_size)
+        @rtype tuple
+
+        We cover the first nyquist zone only
+        """
+        return (-32e6, 32e6, 1e-6)
+
+
+# hook these daughterboard classes into the auto-instantiation framework
+
+def _basic_rx_instantiator(usrp, which):
+    # two single channel subdevices
+    return (db_basic_rx(usrp, which, 0), db_basic_rx(usrp, which, 1))
+
+def _lf_rx_instantiator(usrp, which):
+    # two single channel subdevices
+    return (db_lf_rx(usrp, which, 0), db_lf_rx(usrp, which, 1))
+
+def _basic_tx_instantiator(usrp, which):
+    # one quadrature subdevice
+    return (db_basic_tx(usrp, which),)
+
+def _lf_tx_instantiator(usrp, which):
+    # one quadrature subdevice
+    return (db_lf_tx(usrp, which),)
+
+def _no_db_instantiator(usrp, which):
+    if hasattr(usrp, 'tx_freq'):   # is this a tx or rx daughterboard?
+        return (_basic_tx_instantiator(usrp, which))
+    else:
+        return (_basic_rx_instantiator(usrp, which))
+    
+def _invalid_instantiator(usrp, which):
+    if hasattr(usrp, 'tx_freq'):   # is this a tx or rx daughterboard?
+        sys.stderr.write('\n\aWarning: Treating daughterboard with invalid EEPROM contents as if it were a "Basic Tx."\n')
+        sys.stderr.write('Warning: This is almost certainly wrong...  Use appropriate burn-*-eeprom utility.\n\n')
+        return _basic_tx_instantiator(usrp, which)
+    else:
+        sys.stderr.write('\n\aWarning: Treating daughterboard with invalid EEPROM contents as if it were a "Basic Rx."\n')
+        sys.stderr.write('Warning: This is almost certainly wrong...  Use appropriate burn-*-eeprom utility.\n\n')
+        return _basic_rx_instantiator(usrp, which)
+
+db_instantiator.add(-1, _no_db_instantiator)                  # no daughterboard
+db_instantiator.add(-2, _invalid_instantiator)                # invalid eeprom contents
+db_instantiator.add(usrp_dbid.BASIC_TX, _basic_tx_instantiator)
+db_instantiator.add(usrp_dbid.BASIC_RX, _basic_rx_instantiator)
+db_instantiator.add(usrp_dbid.LF_TX, _lf_tx_instantiator)
+db_instantiator.add(usrp_dbid.LF_RX, _lf_rx_instantiator)
diff --git a/gr-usrp/src/db_dbs_rx.py b/gr-usrp/src/db_dbs_rx.py
new file mode 100644 (file)
index 0000000..24e8d7d
--- /dev/null
@@ -0,0 +1,345 @@
+#
+# 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 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.
+# 
+
+import math
+import usrp_dbid
+import db_base
+import db_instantiator
+
+def int_seq_to_str (seq):
+    """convert a sequence of integers into a string"""
+    return ''.join (map (chr, seq))
+
+def str_to_int_seq (str):
+    """convert a string to a list of integers"""
+    return map (ord, str)
+
+class db_dbs_rx (db_base.db_base):
+    def __init__ (self, usrp, which):
+        """
+        Control DBS receiver based USRP 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
+        """
+        # sets _u and _which
+        db_base.db_base.__init__(self, usrp, which)
+
+        self._u._write_oe(self._which,0x0001,0x0001)
+        self.i2c_addr = (0x67, 0x65)[self._which]
+        # set basic parameters
+        # set default values
+        self.n = 950
+        self.div2 = 0
+        self.osc = 5
+        self.cp = 3
+        self.r = 4
+        self.r_int = 1
+        self.fdac = 127
+        self.m = 2
+        self.dl = 0
+        self.ade = 0
+        self.adl = 0
+        self.gc2 = 31
+        self.diag = 0
+
+        # FIXME this should be in the core dboard class
+        self.refclk_divisor = 16
+        self._enable_refclk(True)
+
+        g = self.gain_range()
+        self.set_gain(float(g[0]+g[1]) / 2)
+        self.bypass_adc_buffers(True)
+        
+    def __del__(self):
+        if self._u:
+            self._enable_refclk(False)
+
+    def _write_reg (self, regno, v):
+        """regno is in [0,5], v is value to write to register"""
+        assert (0 <= regno and regno <= 5)
+        self._u.write_i2c (self.i2c_addr, int_seq_to_str ((regno, v)))
+        
+    def _write_regs (self, starting_regno, vals):
+        """starting_regno is in [0,5],
+        vals is a seq of integers to write to consecutive registers"""
+        self._u.write_i2c (self.i2c_addr,
+                          int_seq_to_str ((starting_regno,) + tuple (vals)))
+        
+    def _read_status (self):
+        """If successful, return list of two ints: [status_info, filter_DAC]"""
+        s = self._u.read_i2c (self.i2c_addr, 2)
+        if len (s) != 2:
+            return None
+        return str_to_int_seq (s)
+
+    def _send_reg(self,regno):
+        assert (0 <= regno and regno <= 5)
+        if regno == 0:
+            self._write_reg(0,(self.div2<<7) + (self.n>>8))
+        if regno == 1:
+            self._write_reg(1,self.n & 255)
+        if regno == 2:
+            self._write_reg(2,self.osc + (self.cp<<3) + (self.r_int<<5))
+        if regno == 3:
+            self._write_reg(3,self.fdac)
+        if regno == 4:
+            self._write_reg(4,self.m + (self.dl<<5) + (self.ade<<6) + (self.adl<<7))
+        if regno == 5:
+            self._write_reg(5,self.gc2 + (self.diag<<5))
+
+    # BW setting
+    def _set_m(self,m):
+        assert m>0 and m<32
+        self.m = m
+        self._send_reg(4)
+    
+    def _set_fdac(self,fdac):
+        assert fdac>=0 and fdac<128
+        self.fdac = fdac
+        self._send_reg(3)
+        
+    def set_bw (self, bw):
+        #assert (bw>=4e6 and bw<=33e6)
+        assert (bw>=1e6 and bw<=33e6)
+        if bw >= 4e6:
+            m_max = int(min(31,math.floor(self._refclk_freq()/1e6)))
+        elif bw >= 2e6:      # Outside of Specs!
+            m_max = int(min(31,math.floor(self._refclk_freq()/.5e6)))
+        else:      # Way outside of Specs!
+            m_max = int(min(31,math.floor(self._refclk_freq()/.25e6)))
+        
+        m_min = int(math.ceil(self._refclk_freq()/2.5e6))
+        m_test = m_max
+        while m_test >= m_min:
+            fdac_test = int(round(((bw * m_test / self._refclk_freq())-4)/.145))
+            if fdac_test>127:
+                m_test = m_test - 1
+            else:
+                break
+        if (m_test>=m_min and fdac_test >=0):
+            self._set_m(m_test)
+            self._set_fdac(fdac_test)
+            return (self.m,self.fdac,self._refclk_freq()/self.m*(4+0.145*self.fdac))
+        else:
+            print "Failed to set bw"
+
+    # Gain setting
+    def _set_dl(self,dl):
+        assert dl == 0 or dl == 1
+        self.dl = dl
+        self._send_reg(4)
+        
+    def _set_gc2(self,gc2):
+        assert gc2<32 and gc2>=0
+        self.gc2 = gc2
+        self._send_reg(5)
+
+    def _set_gc1(self,gc1):
+        assert gc1>=0 and gc1<4096
+        self.gc1 = gc1
+        self._u.write_aux_dac(self._which,0,int(gc1))
+
+    def _set_pga(self, pga_gain):
+        assert pga_gain >=0 and pga_gain <=20
+        if(self._which == 0):
+            self._u.set_pga (0, pga_gain)
+            self._u.set_pga (1, pga_gain)
+        else:
+            self._u.set_pga (2, pga_gain)
+            self._u.set_pga (3, pga_gain)
+            
+    def gain_range(self):
+        return (0, 104, 1)
+    
+    def set_gain(self,gain):
+        if not (gain>=0 and gain<105):
+            raise ValueError, "gain out of range"
+        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 = gain - 56
+        if gain < 24:
+            gc2 = int(round(31.0 * (1-gain/24.0)))
+            gain = 0
+        else:
+            gc2 = 0
+            gain = gain - 24
+        if gain >= 4.58:
+            dl = 1
+            gain = gain - 4.58
+        pga = gain
+        self._set_gc1(gc1)
+        self._set_gc2(gc2)
+        self._set_dl(dl)
+        self._set_pga(pga)
+        
+    # Frequency setting
+    def _set_osc(self,osc):
+        assert osc>=0 and osc<8
+        self.osc = osc
+        self._send_reg(2)
+
+    def _set_cp(self,cp):
+        assert cp>=0 and cp<4
+        self.cp = cp
+        self._send_reg(2)
+
+    def _set_n(self,n):
+        assert n>256 and n<32768
+        self.n = n
+        self._send_reg(0)
+        self._send_reg(1)
+
+    def _set_div2(self,div2):
+        assert div2 == 0 or div2 == 1
+        self.div2 = div2
+        self._send_reg(0)
+
+    def _set_r(self,r):
+        assert r>=0 and r<128
+        self.r = r
+        self.r_int = int(round(math.log10(r)/math.log10(2)) - 1)
+        self._send_reg(2)
+        
+    # FIXME  How do we handle ADE and ADL properly?
+    def _set_ade(self,ade):
+        assert ade == 0 or ade == 1
+        self.ade = ade
+        self._send_reg(4)
+        
+    def freq_range(self):
+        return (500e6, 2.6e9, 1e6)
+
+    def _refclk_divisor(self):
+        """
+        Return value to stick in REFCLK_DIVISOR register
+        """
+        return 16
+    
+    def set_freq(self, freq):
+        """
+        Set the frequency.
+
+        @param freq:  target frequency in Hz
+        @type freq:   float
+
+        @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.
+        """
+        if not (freq>=500e6 and freq<=2.6e9):
+            return (False, 0)
+        
+        if(freq<1150e6):
+            self._set_div2(0)
+            vcofreq = 4 * freq
+        else:
+            self._set_div2(1)
+            vcofreq = 2 * freq
+        self._set_ade(1)
+        rmin=max(2,self._refclk_freq()/2e6)
+        rmax=min(128,self._refclk_freq()/150e3)
+        r = 2
+        n=0
+        best_r = 2
+        best_n =0
+        best_delta = 10e6
+        while r <= rmax:
+            n = round(freq/(self._refclk_freq()/r))
+            if r<rmin or n<256:
+                r = r * 2
+                continue
+            delta = abs(n*self._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
+        self._set_r(int(best_r))
+
+        self._set_n(int(round(best_n)))
+        if vcofreq < 2433e6:
+            vco = 0
+        elif vcofreq < 2711e6:
+            vco=1
+        elif vcofreq < 3025e6:
+            vco=2
+        elif vcofreq < 3341e6:
+            vco=3
+        elif vcofreq < 3727e6:
+            vco=4
+        elif vcofreq < 4143e6:
+            vco=5
+        elif vcofreq < 4493e6:
+            vco=6
+        else:
+            vco=7
+
+        self._set_osc(vco)
+
+        # Set CP current
+        adc_val = 0
+        while adc_val == 0 or adc_val == 7:
+            (byte1,byte2) = self._read_status()
+            adc_val = byte1 >> 2
+            if(adc_val == 0):
+                if vco <= 0:
+                    return (False, 0)
+                else:
+                    vco = vco - 1
+            elif(adc_val == 7):
+                if(vco >= 7):
+                    return (False, 0)
+                else:
+                    vco = vco + 1
+            self._set_osc(vco)
+        if adc_val == 1 or adc_val == 2:
+            self._set_cp(1)
+        elif adc_val == 3 or adc_val == 4:
+            self._set_cp(2)
+        else:
+            self._set_cp(3)
+                    
+        return (True, self.n * self._refclk_freq() / self.r)
+
+    def is_quadrature(self):
+        """
+        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
+
+# hook this daughterboard class into the auto-instantiation framework
+db_instantiator.add(usrp_dbid.DBS_RX, lambda usrp, which : (db_dbs_rx(usrp, which),))
diff --git a/gr-usrp/src/db_flexrf.py b/gr-usrp/src/db_flexrf.py
new file mode 100644 (file)
index 0000000..a00cfe8
--- /dev/null
@@ -0,0 +1,680 @@
+#
+# 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 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.
+# 
+
+from gnuradio import usrp1
+import time,math
+
+import usrp_dbid
+import db_base
+import db_instantiator
+from usrp_fpga_regs import *
+
+#debug_using_gui = True                  # Must be set to True or False
+debug_using_gui = False                  # Must be set to True or False
+
+if debug_using_gui:
+    import flexrf_debug_gui
+
+# d'board i/o pin defs
+# Tx and Rx have shared defs, but different i/o regs
+AUX_RXAGC = (1 << 8)
+POWER_UP = (1 << 7)         # enables power supply
+RX_TXN = (1 << 6)           # Tx only: T/R antenna switch for TX/RX port
+RX2_RX1N = (1 << 6)         # Rx only: antenna switch between RX2 and TX/RX port
+ENABLE = (1 << 5)           # enables mixer
+AUX_SEN = (1 << 4)
+AUX_SCLK = (1 << 3)
+PLL_LOCK_DETECT = (1 << 2)
+AUX_SDO = (1 << 1)
+CLOCK_OUT = (1 << 0)
+
+SPI_ENABLE_TX_A = usrp1.SPI_ENABLE_TX_A
+SPI_ENABLE_TX_B = usrp1.SPI_ENABLE_TX_B
+SPI_ENABLE_RX_A = usrp1.SPI_ENABLE_RX_A
+SPI_ENABLE_RX_B = usrp1.SPI_ENABLE_RX_B
+
+class flexrf_base(db_base.db_base):
+    """
+    Abstract base class for all flexrf boards.
+
+    Derive board specific subclasses from db_flexrf_base_{tx,rx}
+    """
+    def __init__(self, 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
+        """
+        # sets _u  _which _tx and _slot
+        db_base.db_base.__init__(self, usrp, which)
+
+        self.first = True
+        self.spi_format = usrp1.SPI_FMT_MSB | usrp1.SPI_FMT_HDR_0
+
+        self._u._write_oe(self._which, 0, 0xffff)   # turn off all outputs
+        self._enable_refclk(False)                      # disable refclk
+
+        g = self.gain_range()                       # initialize gain
+        self.set_gain(float(g[0]+g[1]) / 2)
+
+        self.set_auto_tr(False)
+        
+        if debug_using_gui:
+            title = "FlexRF Debug Rx"
+            if self._tx:
+                title = "FlexRF Debug Tx"
+            self.gui = flexrf_debug_gui.flexrf_debug_gui(self, title)
+            self.gui.Show(True)
+
+
+    def __del__(self):
+        #print "flexrf_base.__del__"
+        self._u.write_io(self._which, self.power_off, POWER_UP)   # turn off power to board
+        self._enable_refclk(False)                       # turn off refclk
+        self.set_auto_tr(False)
+
+    def _write_all(self, R, control, 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 $: 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
+        """
+        self._write_R(R)
+        self._write_control( control)
+        if self.first:
+            time.sleep(0.010)
+            self.first = False
+        self._write_N(N)
+
+    def _write_control(self, control):
+        self._write_it((control & ~0x3) | 0)
+
+    def _write_R(self, R):
+        self._write_it((R & ~0x3) | 1)
+
+    def _write_N(self, N):
+        self._write_it((N & ~0x3) | 2)
+
+    def _write_it(self, v):
+        s = ''.join((chr((v >> 16) & 0xff),
+                     chr((v >>  8) & 0xff),
+                     chr(v & 0xff)))
+        self._u._write_spi(0, self.spi_enable, self.spi_format, s)
+        
+    def _lock_detect(self):
+        """
+        @returns: the value of the VCO/PLL lock detect bit.
+        @rtype: 0 or 1
+        """
+        if self._u.read_io(self._which) & PLL_LOCK_DETECT:
+            return True
+        else:      # Give it a second chance
+            if self._u.read_io(self._which) & PLL_LOCK_DETECT:
+                return True
+            else:
+                return False
+        
+    def _compute_regs(self, freq):
+        """
+        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
+
+    def _refclk_freq(self):
+        # return float(self._u.fpga_master_clock_freq())/self._refclk_divisor()
+        return 64e6/self._refclk_divisor()
+
+    def set_freq(self, 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.
+        """
+
+        # 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 += self.lo_offset
+        
+        R, control, N, actual_freq = self._compute_regs(freq)
+        if R==0:
+            return(False,0)
+        self._write_all(R, control, N)
+        return (self._lock_detect(), actual_freq)
+
+    def gain_range(self):
+        """
+        Return range of gain that can be set by this d'board.
+
+        @returns (min_gain, max_gain, step_size)
+        Where gains are expressed in decibels (your mileage may vary)
+        """
+        return (self._u.pga_min(), self._u.pga_max(), self._u.pga_db_per_step())
+
+    def set_gain(self, gain):
+        """
+        Set the gain.
+
+        @param gain:  gain in decibels
+        @returns True/False
+        """
+        return self._set_pga(gain)
+
+    def _set_pga(self, pga_gain):
+        if(self._which == 0):
+            self._u.set_pga (0, pga_gain)
+            self._u.set_pga (1, pga_gain)
+        else:
+            self._u.set_pga (2, pga_gain)
+            self._u.set_pga (3, pga_gain)
+
+    def is_quadrature(self):
+        """
+        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
+
+# ----------------------------------------------------------------
+
+class flexrf_base_tx(flexrf_base):
+    def __init__(self, usrp, which):
+        """
+        @param usrp: instance of usrp.sink_c
+        @param which: 0 or 1 corresponding to side TX_A or TX_B respectively.
+        """
+        flexrf_base.__init__(self, usrp, which)
+        self.spi_enable = (SPI_ENABLE_TX_A, SPI_ENABLE_TX_B)[which]
+
+        # power up the transmit side, but don't enable the mixer
+        self._u._write_oe(self._which,(POWER_UP|RX_TXN|ENABLE), 0xffff)
+        self._u.write_io(self._which, (self.power_on|RX_TXN), (POWER_UP|RX_TXN|ENABLE))
+        self.lo_offset = 4e6             # FIXME may want to be a function of d'board
+
+    def __del__(self):
+        #print "flexrf_base_tx.__del__"
+        # Power down and leave the T/R switch in the R position
+        self._u.write_io(self._which, (self.power_off|RX_TXN), (POWER_UP|RX_TXN|ENABLE))
+        flexrf_base.__del__(self)
+
+    def set_auto_tr(self, on):
+        if on:
+            self.set_atr_mask (RX_TXN | ENABLE)
+            self.set_atr_txval(0      | ENABLE)
+            self.set_atr_rxval(RX_TXN | 0)
+        else:
+            self.set_atr_mask (0)
+            self.set_atr_txval(0)
+            self.set_atr_rxval(0)
+
+    def set_enable(self, on):
+        """
+        Enable transmitter if on is True
+        """
+        mask = RX_TXN | ENABLE
+        if on:
+            v = ENABLE
+        else:
+            v = RX_TXN
+        self._u.write_io(self._which, v, mask)
+
+    def gain_range(self):
+        """
+        Return range of gain that can be set by this d'board.
+
+        @returns (min_gain, max_gain, step_size)
+        Where gains are expressed in decibels (your mileage may vary)
+
+        Flex Tx boards require that the PGA be maxed out to properly bias their circuitry.
+        """
+        g = self._u.pga_max()
+        return (g, g, 1.0)
+
+    def set_gain(self, gain):
+        """
+        Set the gain.
+
+        @param gain:  gain in decibels
+        @returns True/False
+        """
+        return self._set_pga(self._u.pga_max())
+
+
+class flexrf_base_rx(flexrf_base):
+    def __init__(self, usrp, which):
+        """
+        @param usrp: instance of usrp.source_c
+        @param which: 0 or 1 corresponding to side RX_A or RX_B respectively.
+        """
+        flexrf_base.__init__(self, usrp, which)
+        self.spi_enable = (SPI_ENABLE_RX_A, SPI_ENABLE_RX_B)[which]
+        
+        self._u._write_oe(self._which, (POWER_UP|RX2_RX1N|ENABLE), 0xffff)
+        self._u.write_io(self._which,  (self.power_on|RX2_RX1N|ENABLE), (POWER_UP|RX2_RX1N|ENABLE))
+
+        # set up for RX on TX/RX port
+        self.select_rx_antenna('TX/RX')
+
+        self.bypass_adc_buffers(True)
+
+        self.lo_offset = -4e6             # FIXME may want to be a function of d'board
+
+    def __del__(self):
+        # print "flexrf_base_rx.__del__"
+        # Power down
+        self._u.write_io(self._which, self.power_off, (POWER_UP|ENABLE))
+        flexrf_base.__del__(self)
+    
+    def set_auto_tr(self, on):
+        if on:
+            self.set_atr_mask (ENABLE)
+            self.set_atr_txval(     0)
+            self.set_atr_rxval(ENABLE)
+        else:
+            self.set_atr_mask (0)
+            self.set_atr_txval(0)
+            self.set_atr_rxval(0)
+
+    def select_rx_antenna(self, which_antenna):
+        """
+        Specify which antenna port to use for reception.
+        @param which_antenna: either 'TX/RX' or 'RX2'
+        """
+        if which_antenna in (0, 'TX/RX'):
+            self._u.write_io(self._which, 0,        RX2_RX1N)
+        elif which_antenna in (1, 'RX2'):
+            self._u.write_io(self._which, RX2_RX1N, RX2_RX1N)
+        else:
+            raise ValueError, "which_antenna must be either 'TX/RX' or 'RX2'"
+
+    def set_gain(self, gain):
+        """
+        Set the gain.
+
+        @param gain:  gain in decibels
+        @returns True/False
+        """
+        maxgain = self.gain_range()[1] - self._u.pga_max()
+        if gain > maxgain:
+            pga_gain = gain-maxgain
+            assert pga_gain <= self._u.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 + V_mingain)*4096/V_fullscale
+        assert dac_value>=0 and dac_value<4096
+        return self._u.write_aux_dac(self._which, 0, int(dac_value)) and \
+               self._set_pga(int(pga_gain))
+
+
+# ----------------------------------------------------------------
+
+class _AD4360_common(object):
+    def __init__(self):
+        # R-Register Common Values
+        self.R_RSV = 0   # bits 23,22
+        self.BSC = 3   # bits 21,20 Div by 8 to be safe
+        self.TEST = 0  # bit 19
+        self.LDP = 1   # bit 18
+        self.ABP = 0   # bit 17,16   3ns
+
+        # N-Register Common Values
+        self.N_RSV = 0      # bit 7
+        
+        # Control Register Common Values
+        self.PD = 0       # bits 21,20   Normal operation
+        self.PL = 0       # bits 13,12   11mA
+        self.MTLD = 1     # bit 11       enabled
+        self.CPG = 0      # bit 10       CP setting 1
+        self.CP3S = 0     # bit 9        Normal
+        self.PDP = 1      # bit 8        Positive
+        self.MUXOUT = 1   # bits 7:5     Digital Lock Detect
+        self.CR = 0       # bit 4        Normal
+        self.PC = 1       # bits 3,2     Core power 10mA
+
+    def _compute_regs(self, freq):
+        """
+        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
+        phdet_freq = self._refclk_freq()/self.R_DIV
+        desired_n = round(freq*self.freq_mult/phdet_freq)
+        actual_freq = desired_n * phdet_freq
+        B = math.floor(desired_n/self._prescaler())
+        A = desired_n - self._prescaler()*B
+        self.B_DIV = int(B)    # bits 20:8
+        self.A_DIV = int(A)    # bit 6:2
+        #assert self.B_DIV >= self.A_DIV
+        if self.B_DIV < self.A_DIV:
+            return (0,0,0,0)
+        R = (self.R_RSV<<22) | (self.BSC<<20) | (self.TEST<<19) | (self.LDP<<18) \
+            | (self.ABP<<16) | (self.R_DIV<<2)
+        
+        control = (self.P<<22) | (self.PD<<20) | (self.CP2<<17) | (self.CP1<<14) | (self.PL<<12) \
+                  | (self.MTLD<<11) | (self.CPG<<10) | (self.CP3S<<9) | (self.PDP<<8) | \
+                  (self.MUXOUT<<5) | (self.CR<<4) | (self.PC<<2)
+
+        N = (self.DIVSEL<<23) | (self.DIV2<<22) | (self.CPGAIN<<21) | (self.B_DIV<<8) | \
+            (self.N_RSV<<7) | (self.A_DIV<<2)
+
+        return (R,control,N,actual_freq/self.freq_mult)
+
+    def _refclk_divisor(self):
+        """
+        Return value to stick in REFCLK_DIVISOR register
+        """
+        return 1
+    
+    def _prescaler(self):
+        if self.P == 0:
+            return 8
+        elif self.P == 1:
+            return 16
+        else:
+            return 32
+
+#----------------------------------------------------------------------
+class _2400_common(_AD4360_common):
+    def __init__(self):
+        _AD4360_common.__init__(self)
+
+        # Band-specific R-Register Values
+        self.R_DIV = 16  # bits 15:2
+   
+        # Band-specific C-Register values
+        self.P = 1        # bits 23,22   Div by 16/17
+        self.CP2 = 7      # bits 19:17
+        self.CP1 = 7      # bits 16:14
+
+        # Band specifc N-Register Values
+        self.DIVSEL = 0   # bit 23
+        self.DIV2 = 0     # bit 22
+        self.CPGAIN = 0   # bit 21
+        self.freq_mult = 1
+
+    def freq_range(self):           # FIXME
+        return (2300e6, 2700e6, 4e6)
+
+#----------------------------------------------------------------------
+class _1200_common(_AD4360_common):
+    def __init__(self):
+        _AD4360_common.__init__(self)
+
+        # Band-specific R-Register Values
+        self.R_DIV = 16  # bits 15:2  DIV by 16 for a 1 MHz phase detector freq
+   
+        # Band-specific C-Register values
+        self.P = 1        # bits 23,22   Div by 16/17
+        self.CP2 = 7      # bits 19:17   1.25 mA
+        self.CP1 = 7      # bits 16:14   1.25 mA
+
+        # Band specifc N-Register Values
+        self.DIVSEL = 0   # bit 23
+        self.DIV2 = 1     # bit 22
+        self.CPGAIN = 0   # bit 21
+        self.freq_mult = 2
+
+    def freq_range(self):           # FIXME
+        return (1150e6, 1350e6, 4e6)
+
+#-------------------------------------------------------------------------
+class _1800_common(_AD4360_common):
+    def __init__(self):
+        _AD4360_common.__init__(self)
+
+        # Band-specific R-Register Values
+        self.R_DIV = 16  # bits 15:2  DIV by 16 for a 1 MHz phase detector freq
+   
+        # Band-specific C-Register values
+        self.P = 1        # bits 23,22   Div by 16/17
+        self.CP2 = 7      # bits 19:17   1.25 mA
+        self.CP1 = 7      # bits 16:14   1.25 mA
+
+        # Band specifc N-Register Values
+        self.DIVSEL = 0   # bit 23
+        self.DIV2 = 0     # bit 22
+        self.freq_mult = 1
+        self.CPGAIN = 0   # bit 21
+
+    def freq_range(self):           # FIXME
+        return (1600e6, 2000e6, 4e6)
+
+#-------------------------------------------------------------------------
+class _900_common(_AD4360_common):
+    def __init__(self):
+        _AD4360_common.__init__(self)
+
+        # Band-specific R-Register Values
+        self.R_DIV = 16  # bits 15:2  DIV by 16 for a 1 MHz phase detector freq
+   
+        # Band-specific C-Register values
+        self.P = 1        # bits 23,22   Div by 16/17
+        self.CP2 = 7      # bits 19:17   1.25 mA
+        self.CP1 = 7      # bits 16:14   1.25 mA
+
+        # Band specifc N-Register Values
+        self.DIVSEL = 0   # bit 23
+        self.DIV2 = 1     # bit 22
+        self.freq_mult = 2
+        self.CPGAIN = 0   # bit 21
+
+    def freq_range(self):           # FIXME
+        return (800e6, 1000e6, 4e6)
+
+#-------------------------------------------------------------------------
+class _400_common(_AD4360_common):
+    def __init__(self):
+        _AD4360_common.__init__(self)
+
+        # Band-specific R-Register Values
+        self.R_DIV = 16  # bits 15:2 
+   
+        # Band-specific C-Register values
+        self.P = 0        # bits 23,22   Div by 8/9
+        self.CP2 = 7      # bits 19:17   1.25 mA
+        self.CP1 = 7      # bits 16:14   1.25 mA
+
+        # Band specifc N-Register Values  These are different for TX/RX
+        self.DIVSEL = 0   # bit 23
+        if self._tx:
+            self.DIV2 = 1 # bit 22
+        else:
+            self.DIV2 = 0 # bit 22   # RX side has built-in DIV2 in AD8348
+        self.freq_mult = 2
+
+        self.CPGAIN = 0   # bit 21
+
+    def freq_range(self):           
+        #return (350e6, 465e6, 1e6)    # FIXME prototype
+        return (400e6, 500e6, 1e6)     # final version
+    
+
+#------------------------------------------------------------    
+class db_flexrf_2400_tx(_2400_common, flexrf_base_tx):
+    def __init__(self, usrp, which):
+        self.power_on = ~POWER_UP
+        self.power_off = ~POWER_UP    # powering it off kills the serial bus
+        flexrf_base_tx.__init__(self, usrp, which)
+        _2400_common.__init__(self)
+        
+class db_flexrf_2400_rx(_2400_common, flexrf_base_rx):
+    def __init__(self, usrp, which):
+        self.power_on = ~POWER_UP
+        self.power_off = ~POWER_UP   # Powering it off kills the serial bus
+        flexrf_base_rx.__init__(self, usrp, which)
+        _2400_common.__init__(self)
+
+    def gain_range(self):
+        """
+        Return range of gain that can be set by this d'board.
+        
+        @returns (min_gain, max_gain, step_size)
+        Where gains are expressed in decibels (your mileage may vary)
+        """
+        return (self._u.pga_min(), self._u.pga_max() + 70, 0.05)
+
+    def i_and_q_swapped(self):
+        return True
+
+class db_flexrf_1200_tx(_1200_common, flexrf_base_tx):
+    def __init__(self, usrp, which):
+        self.power_on = ~POWER_UP
+        self.power_off = ~POWER_UP    # powering it off kills the serial bus
+        flexrf_base_tx.__init__(self, usrp, which)
+        _1200_common.__init__(self)
+        
+class db_flexrf_1200_rx(_1200_common, flexrf_base_rx):
+    def __init__(self, usrp, which):
+        self.power_on = ~POWER_UP
+        self.power_off = ~POWER_UP    # powering it off kills the serial bus
+        flexrf_base_rx.__init__(self, usrp, which)
+        _1200_common.__init__(self)
+
+    def gain_range(self):
+        """
+        Return range of gain that can be set by this d'board.
+        
+        @returns (min_gain, max_gain, step_size)
+        Where gains are expressed in decibels (your mileage may vary)
+        """
+        return (self._u.pga_min(), self._u.pga_max() + 70, 0.05)
+
+    def i_and_q_swapped(self):
+        return True
+
+class db_flexrf_1800_tx(_1800_common, flexrf_base_tx):
+    def __init__(self, usrp, which):
+        self.power_on = ~POWER_UP
+        self.power_off = ~POWER_UP    # powering it off kills the serial bus
+        flexrf_base_tx.__init__(self, usrp, which)
+        _1800_common.__init__(self)
+        
+class db_flexrf_1800_rx(_1800_common, flexrf_base_rx):
+    def __init__(self, usrp, which):
+        self.power_on = ~POWER_UP
+        self.power_off = ~POWER_UP    # powering it off kills the serial bus
+        flexrf_base_rx.__init__(self, usrp, which)
+        _1800_common.__init__(self)
+
+    def gain_range(self):
+        """
+        Return range of gain that can be set by this d'board.
+        
+        @returns (min_gain, max_gain, step_size)
+        Where gains are expressed in decibels (your mileage may vary)
+        """
+        return (self._u.pga_min(), self._u.pga_max() + 70, 0.05)
+
+    def i_and_q_swapped(self):
+        return True
+
+class db_flexrf_900_tx(_900_common, flexrf_base_tx):
+    def __init__(self, usrp, which):
+        self.power_on = ~POWER_UP
+        self.power_off = ~POWER_UP    # powering it off kills the serial bus
+        flexrf_base_tx.__init__(self, usrp, which)
+        _900_common.__init__(self)
+        
+class db_flexrf_900_rx(_900_common, flexrf_base_rx):
+    def __init__(self, usrp, which):
+        self.power_on = ~POWER_UP
+        self.power_off = ~POWER_UP    # powering it off kills the serial bus
+        flexrf_base_rx.__init__(self, usrp, which)
+        _900_common.__init__(self)
+
+    def gain_range(self):
+        """
+        Return range of gain that can be set by this d'board.
+        
+        @returns (min_gain, max_gain, step_size)
+        Where gains are expressed in decibels (your mileage may vary)
+        """
+        return (self._u.pga_min(), self._u.pga_max() + 70, 0.05)
+
+    def i_and_q_swapped(self):
+        return True
+
+class db_flexrf_400_tx(_400_common, flexrf_base_tx):
+    def __init__(self, usrp, which):
+        self.power_on = POWER_UP
+        self.power_off = ~POWER_UP
+        flexrf_base_tx.__init__(self, usrp, which)
+        _400_common.__init__(self)
+        
+class db_flexrf_400_rx(_400_common, flexrf_base_rx):
+    def __init__(self, usrp, which):
+        self.power_on = POWER_UP
+        self.power_off = ~POWER_UP
+        flexrf_base_rx.__init__(self, usrp, which)
+        _400_common.__init__(self)
+
+    def gain_range(self):
+        """
+        Return range of gain that can be set by this d'board.
+        
+        @returns (min_gain, max_gain, step_size)
+        Where gains are expressed in decibels (your mileage may vary)
+        """
+        return (self._u.pga_min(), self._u.pga_max() + 45, 0.035)
+
+    def i_and_q_swapped(self):
+        return True
+    
+# hook these daughterboard classes into the auto-instantiation framework
+
+db_instantiator.add(usrp_dbid.FLEX_2400_TX, lambda usrp, which : (db_flexrf_2400_tx(usrp, which),))
+db_instantiator.add(usrp_dbid.FLEX_2400_RX, lambda usrp, which : (db_flexrf_2400_rx(usrp, which),))
+db_instantiator.add(usrp_dbid.FLEX_1200_TX, lambda usrp, which : (db_flexrf_1200_tx(usrp, which),))
+db_instantiator.add(usrp_dbid.FLEX_1200_RX, lambda usrp, which : (db_flexrf_1200_rx(usrp, which),))
+db_instantiator.add(usrp_dbid.FLEX_1800_TX, lambda usrp, which : (db_flexrf_1800_tx(usrp, which),))
+db_instantiator.add(usrp_dbid.FLEX_1800_RX, lambda usrp, which : (db_flexrf_1800_rx(usrp, which),))
+db_instantiator.add(usrp_dbid.FLEX_900_TX,  lambda usrp, which : (db_flexrf_900_tx(usrp, which),))
+db_instantiator.add(usrp_dbid.FLEX_900_RX,  lambda usrp, which : (db_flexrf_900_rx(usrp, which),))
+db_instantiator.add(usrp_dbid.FLEX_400_TX,  lambda usrp, which : (db_flexrf_400_tx(usrp, which),))
+db_instantiator.add(usrp_dbid.FLEX_400_RX,  lambda usrp, which : (db_flexrf_400_rx(usrp, which),))
diff --git a/gr-usrp/src/db_flexrf_mimo.py b/gr-usrp/src/db_flexrf_mimo.py
new file mode 100644 (file)
index 0000000..71c49a8
--- /dev/null
@@ -0,0 +1,286 @@
+#
+# 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 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.
+# 
+
+from gnuradio import usrp1
+import time,math
+
+import usrp_dbid
+import db_base
+import db_instantiator
+from usrp_fpga_regs import *
+from db_flexrf import *
+
+# self._u.fpga_master_clock_freq()
+
+# MIMO Classes
+class db_flexrf_2400_tx_mimo_a(db_flexrf_2400_tx):
+    def __init__(self, usrp, which):
+        db_flexrf_2400_tx.__init__(self, usrp, which)
+        self._enable_refclk(True)
+        self.R_DIV = 1
+
+    def _refclk_divisor(self):
+        """
+        Return value to stick in REFCLK_DIVISOR register
+        """
+        return 16
+
+class db_flexrf_2400_rx_mimo_a(db_flexrf_2400_rx):
+    def __init__(self, usrp, which):
+        db_flexrf_2400_rx.__init__(self, usrp, which)
+        self._enable_refclk(True)
+        self.R_DIV = 1
+
+    def _refclk_divisor(self):
+        """
+        Return value to stick in REFCLK_DIVISOR register
+        """
+        return 16
+    
+class db_flexrf_2400_tx_mimo_b(db_flexrf_2400_tx):
+    def __init__(self, usrp, which):
+        db_flexrf_2400_tx.__init__(self, usrp, which)
+        self.R_DIV = 16
+
+    def _refclk_divisor(self):
+        """
+        Return value to stick in REFCLK_DIVISOR register
+        """
+        return 1
+
+class db_flexrf_2400_rx_mimo_b(db_flexrf_2400_rx):
+    def __init__(self, usrp, which):
+        db_flexrf_2400_rx.__init__(self, usrp, which)
+        self.R_DIV = 16
+
+    def _refclk_divisor(self):
+        """
+        Return value to stick in REFCLK_DIVISOR register
+        """
+        return 1
+    
+class db_flexrf_1800_tx_mimo_a(db_flexrf_1800_tx):
+    def __init__(self, usrp, which):
+        db_flexrf_1800_tx.__init__(self, usrp, which)
+        self._enable_refclk(True)
+        self.R_DIV = 1
+
+    def _refclk_divisor(self):
+        """
+        Return value to stick in REFCLK_DIVISOR register
+        """
+        return 16
+
+class db_flexrf_1800_rx_mimo_a(db_flexrf_1800_rx):
+    def __init__(self, usrp, which):
+        db_flexrf_1800_rx.__init__(self, usrp, which)
+        self._enable_refclk(True)
+        self.R_DIV = 1
+
+    def _refclk_divisor(self):
+        """
+        Return value to stick in REFCLK_DIVISOR register
+        """
+        return 16
+    
+class db_flexrf_1800_tx_mimo_b(db_flexrf_1800_tx):
+    def __init__(self, usrp, which):
+        db_flexrf_1800_tx.__init__(self, usrp, which)
+        self.R_DIV = 16
+
+    def _refclk_divisor(self):
+        """
+        Return value to stick in REFCLK_DIVISOR register
+        """
+        return 1
+
+class db_flexrf_1800_rx_mimo_b(db_flexrf_1800_rx):
+    def __init__(self, usrp, which):
+        db_flexrf_1800_rx.__init__(self, usrp, which)
+        self.R_DIV = 16
+
+    def _refclk_divisor(self):
+        """
+        Return value to stick in REFCLK_DIVISOR register
+        """
+        return 1
+
+class db_flexrf_1200_tx_mimo_a(db_flexrf_1200_tx):
+    def __init__(self, usrp, which):
+        db_flexrf_1200_tx.__init__(self, usrp, which)
+        self._enable_refclk(True)
+        self.R_DIV = 1
+
+    def _refclk_divisor(self):
+        """
+        Return value to stick in REFCLK_DIVISOR register
+        """
+        return 16
+
+class db_flexrf_1200_rx_mimo_a(db_flexrf_1200_rx):
+    def __init__(self, usrp, which):
+        db_flexrf_1200_rx.__init__(self, usrp, which)
+        self._enable_refclk(True)
+        self.R_DIV = 1
+
+    def _refclk_divisor(self):
+        """
+        Return value to stick in REFCLK_DIVISOR register
+        """
+        return 16
+    
+class db_flexrf_1200_tx_mimo_b(db_flexrf_1200_tx):
+    def __init__(self, usrp, which):
+        db_flexrf_1200_tx.__init__(self, usrp, which)
+        self.R_DIV = 16
+
+    def _refclk_divisor(self):
+        """
+        Return value to stick in REFCLK_DIVISOR register
+        """
+        return 1
+
+class db_flexrf_1200_rx_mimo_b(db_flexrf_1200_rx):
+    def __init__(self, usrp, which):
+        db_flexrf_1200_rx.__init__(self, usrp, which)
+        self.R_DIV = 16
+
+    def _refclk_divisor(self):
+        """
+        Return value to stick in REFCLK_DIVISOR register
+        """
+        return 1
+
+class db_flexrf_900_tx_mimo_a(db_flexrf_900_tx):
+    def __init__(self, usrp, which):
+        db_flexrf_900_tx.__init__(self, usrp, which)
+        self._enable_refclk(True)
+        self.R_DIV = 1
+
+    def _refclk_divisor(self):
+        """
+        Return value to stick in REFCLK_DIVISOR register
+        """
+        return 16
+    
+class db_flexrf_900_rx_mimo_a(db_flexrf_900_rx):
+    def __init__(self, usrp, which):
+        db_flexrf_900_rx.__init__(self, usrp, which)
+        self._enable_refclk(True)
+        self.R_DIV = 1
+
+    def _refclk_divisor(self):
+        """
+        Return value to stick in REFCLK_DIVISOR register
+        """
+        return 16
+    
+class db_flexrf_900_tx_mimo_b(db_flexrf_900_tx):
+    def __init__(self, usrp, which):
+        db_flexrf_900_tx.__init__(self, usrp, which)
+        self.R_DIV = 16
+
+    def _refclk_divisor(self):
+        """
+        Return value to stick in REFCLK_DIVISOR register
+        """
+        return 1
+    
+class db_flexrf_900_rx_mimo_b(db_flexrf_900_rx):
+    def __init__(self, usrp, which):
+        db_flexrf_900_rx.__init__(self, usrp, which)
+        self.R_DIV = 16
+
+    def _refclk_divisor(self):
+        """
+        Return value to stick in REFCLK_DIVISOR register
+        """
+        return 1
+
+class db_flexrf_400_tx_mimo_a(db_flexrf_400_tx):
+    def __init__(self, usrp, which):
+        db_flexrf_400_tx.__init__(self, usrp, which)
+        self._enable_refclk(True)
+        self.R_DIV = 1
+
+    def _refclk_divisor(self):
+        """
+        Return value to stick in REFCLK_DIVISOR register
+        """
+        return 16
+    
+class db_flexrf_400_rx_mimo_a(db_flexrf_400_rx):
+    def __init__(self, usrp, which):
+        db_flexrf_400_rx.__init__(self, usrp, which)
+        self._enable_refclk(True)
+        self.R_DIV = 1
+
+    def _refclk_divisor(self):
+        """
+        Return value to stick in REFCLK_DIVISOR register
+        """
+        return 16
+    
+class db_flexrf_400_tx_mimo_b(db_flexrf_400_tx):
+    def __init__(self, usrp, which):
+        db_flexrf_400_tx.__init__(self, usrp, which)
+        self.R_DIV = 16
+
+    def _refclk_divisor(self):
+        """
+        Return value to stick in REFCLK_DIVISOR register
+        """
+        return 1
+    
+class db_flexrf_400_rx_mimo_b(db_flexrf_400_rx):
+    def __init__(self, usrp, which):
+        db_flexrf_400_rx.__init__(self, usrp, which)
+        self.R_DIV = 16
+
+    def _refclk_divisor(self):
+        """
+        Return value to stick in REFCLK_DIVISOR register
+        """
+        return 1
+    
+# hook these daughterboard classes into the auto-instantiation framework
+db_instantiator.add(usrp_dbid.FLEX_2400_TX_MIMO_A, lambda usrp, which : (db_flexrf_2400_tx_mimo_a(usrp, which),))
+db_instantiator.add(usrp_dbid.FLEX_2400_RX_MIMO_A, lambda usrp, which : (db_flexrf_2400_rx_mimo_a(usrp, which),))
+db_instantiator.add(usrp_dbid.FLEX_1800_TX_MIMO_A, lambda usrp, which : (db_flexrf_1800_tx_mimo_a(usrp, which),))
+db_instantiator.add(usrp_dbid.FLEX_1800_RX_MIMO_A, lambda usrp, which : (db_flexrf_1800_rx_mimo_a(usrp, which),))
+db_instantiator.add(usrp_dbid.FLEX_1200_TX_MIMO_A, lambda usrp, which : (db_flexrf_1200_tx_mimo_a(usrp, which),))
+db_instantiator.add(usrp_dbid.FLEX_1200_RX_MIMO_A, lambda usrp, which : (db_flexrf_1200_rx_mimo_a(usrp, which),))
+db_instantiator.add(usrp_dbid.FLEX_900_TX_MIMO_A,  lambda usrp, which : (db_flexrf_900_tx_mimo_a(usrp, which),))
+db_instantiator.add(usrp_dbid.FLEX_900_RX_MIMO_A,  lambda usrp, which : (db_flexrf_900_rx_mimo_a(usrp, which),))
+db_instantiator.add(usrp_dbid.FLEX_400_TX_MIMO_A,  lambda usrp, which : (db_flexrf_400_tx_mimo_a(usrp, which),))
+db_instantiator.add(usrp_dbid.FLEX_400_RX_MIMO_A,  lambda usrp, which : (db_flexrf_400_rx_mimo_a(usrp, which),))
+
+db_instantiator.add(usrp_dbid.FLEX_2400_TX_MIMO_B, lambda usrp, which : (db_flexrf_2400_tx_mimo_b(usrp, which),))
+db_instantiator.add(usrp_dbid.FLEX_2400_RX_MIMO_B, lambda usrp, which : (db_flexrf_2400_rx_mimo_b(usrp, which),))
+db_instantiator.add(usrp_dbid.FLEX_1800_TX_MIMO_B, lambda usrp, which : (db_flexrf_1800_tx_mimo_b(usrp, which),))
+db_instantiator.add(usrp_dbid.FLEX_1800_RX_MIMO_B, lambda usrp, which : (db_flexrf_1800_rx_mimo_b(usrp, which),))
+db_instantiator.add(usrp_dbid.FLEX_1200_TX_MIMO_B, lambda usrp, which : (db_flexrf_1200_tx_mimo_b(usrp, which),))
+db_instantiator.add(usrp_dbid.FLEX_1200_RX_MIMO_B, lambda usrp, which : (db_flexrf_1200_rx_mimo_b(usrp, which),))
+db_instantiator.add(usrp_dbid.FLEX_900_TX_MIMO_B,  lambda usrp, which : (db_flexrf_900_tx_mimo_b(usrp, which),))
+db_instantiator.add(usrp_dbid.FLEX_900_RX_MIMO_B,  lambda usrp, which : (db_flexrf_900_rx_mimo_b(usrp, which),))
+db_instantiator.add(usrp_dbid.FLEX_400_TX_MIMO_B,  lambda usrp, which : (db_flexrf_400_tx_mimo_b(usrp, which),))
+db_instantiator.add(usrp_dbid.FLEX_400_RX_MIMO_B,  lambda usrp, which : (db_flexrf_400_rx_mimo_b(usrp, which),))
+
diff --git a/gr-usrp/src/db_instantiator.py b/gr-usrp/src/db_instantiator.py
new file mode 100644 (file)
index 0000000..db10de4
--- /dev/null
@@ -0,0 +1,31 @@
+#
+# 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 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.
+# 
+
+_instantiator_map = {}
+
+def add(dbid, instantiator):
+    _instantiator_map[dbid] = instantiator
+
+def instantiate(usrp, which):
+    dbid = usrp.daughterboard_id(which)
+    if _instantiator_map.has_key(dbid):
+        return _instantiator_map[dbid](usrp, which)
+    raise ValueError, "No class defined to handle daughterboard (dbid = %d)" % (dbid,)
diff --git a/gr-usrp/src/db_tv_rx.py b/gr-usrp/src/db_tv_rx.py
new file mode 100644 (file)
index 0000000..0550455
--- /dev/null
@@ -0,0 +1,198 @@
+#
+# 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 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.
+# 
+
+__all__ = ['tv_rx']
+
+import math
+import usrp_dbid
+import db_base
+import db_instantiator
+
+def int_seq_to_str(seq):
+    """convert a sequence of integers into a string"""
+    return ''.join (map (chr, seq))
+
+def str_to_int_seq(str):
+    """convert a string to a list of integers"""
+    return map (ord, str)
+
+def control_byte_1(fast_tuning_p, reference_divisor):
+    c = 0x88
+    if fast_tuning_p:
+        c |= 0x40
+    if reference_divisor == 512:
+        c |= 0x3 << 1
+    elif reference_divisor == 640:
+        c |= 0x0 << 1
+    elif reference_divisor == 1024:
+        c |= 0x1 << 1
+    else:
+        assert 0
+    return c
+
+def control_byte_2(target_freq, shutdown_tx_PGA):
+    if target_freq < 158e6:        # VHF low
+        c = 0xa0
+    elif target_freq < 464e6:      # VHF high
+        c = 0x90
+    else:                          # UHF
+        c = 0x30
+    if shutdown_tx_PGA:
+        c |= 0x08
+    return c
+
+class db_tv_rx(db_base.db_base):
+    def __init__(self, usrp, which, first_IF, second_IF):
+        """
+        Control Microtune 4937 based USRP 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
+        """
+        # sets _u and _which
+        db_base.db_base.__init__(self, usrp, which)
+
+        self._i2c_addr = (0x60, 0x61)[which]
+
+        self._first_IF = first_IF
+        self._second_IF = second_IF
+        self._reference_divisor = 640
+        self._fast_tuning = False
+        self._inverted = False      # FIXME get rid of this
+        
+        g = self.gain_range()                  # initialize gain
+        self.set_gain(float(g[0]+g[1]) / 2)
+
+        self.bypass_adc_buffers(False)
+        
+    # Gain setting
+    def _set_rfagc(self,gain):
+        assert gain <= 60 and 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
+        dacword = int(4096*voltage/1.22/3.3)    # 1.22 = opamp gain
+
+        assert dacword>=0 and dacword<4096
+        self._u.write_aux_dac(self._which, 1, dacword)
+
+    def _set_ifagc(self,gain):
+        assert gain <= 35 and gain >= 0
+        voltage = gain/35.0 * 2.1 + 1.4
+        dacword = int(4096*voltage/1.22/3.3)    # 1.22 = opamp gain
+
+        assert dacword>=0 and dacword<4096
+        self._u.write_aux_dac(self._which, 0, dacword)
+
+    def _set_pga(self,pga_gain):
+        assert pga_gain >=0 and pga_gain <=20
+        if(self._which == 0):
+            self._u.set_pga (0, pga_gain)
+        else:
+            self._u.set_pga (2, pga_gain)
+            
+    def gain_range(self):
+        return (0, 115, 1)
+    
+    def set_gain(self,gain):
+        assert gain>=0 and 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
+        self._set_rfagc(rfgain)
+        self._set_ifagc(ifgain)
+        self._set_pga(pgagain)
+        
+    def freq_range(self):
+        return (50e6, 860e6, 10e3)
+
+    def set_freq(self, 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.
+        """
+        r = self.freq_range()
+        if target_freq < r[0] or target_freq > r[1]:
+            return (False, 0)
+        
+        target_lo_freq = target_freq + self._first_IF;  # High side mixing
+        f_ref = 4e6 / self._reference_divisor   # frequency steps
+
+        divisor = int((target_lo_freq + (f_ref * 4)) / (f_ref * 8))  
+        actual_lo_freq = (f_ref * 8 * divisor)
+        actual_freq = actual_lo_freq - self._first_IF;
+
+        if (divisor & ~0x7fff) != 0:           # must be 15-bits or less
+            return (False, 0)
+        
+        # build i2c command string
+        buf = [0] * 4
+        buf[0] = (divisor >> 8) & 0xff          # DB1
+        buf[1] = divisor & 0xff                 # DB2
+        buf[2] = control_byte_1(self._fast_tuning, self._reference_divisor)
+        buf[3] = control_byte_2(actual_freq, True)  
+
+        ok = self._u.write_i2c(self._i2c_addr, int_seq_to_str (buf))
+
+        return (ok, actual_freq - self._second_IF)
+
+    def is_quadrature(self):
+        """
+        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
+
+    def spectrum_inverted(self):
+        """
+        The 43.75 MHz version is inverted
+        """
+        return self._inverted
+
+# hook this daughterboard class into the auto-instantiation framework
+
+# With MT4937DI5-3x7702 with second downconversion
+db_instantiator.add(usrp_dbid.TV_RX,
+                    lambda usrp, which : (db_tv_rx(usrp, which, 43.75e6, 5.75e6),))
+
+# With MT4937DI5-3x8680, and 3x8769 without second downconversion
+db_instantiator.add(usrp_dbid.TV_RX_REV_2,
+                    lambda usrp, which : (db_tv_rx(usrp, which, 44e6, 20e6),))
+
+# With MT4937DI5-3x7901 without second downconversion, basically the same as tvrx2
+db_instantiator.add(usrp_dbid.TV_RX_REV_3,
+                    lambda usrp, which : (db_tv_rx(usrp, which, 44e6, 20e6),))
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..173d48a
--- /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 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.
+# 
+
+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()
+
diff --git a/gr-usrp/src/qa_usrp.py b/gr-usrp/src/qa_usrp.py
new file mode 100755 (executable)
index 0000000..eb68c64
--- /dev/null
@@ -0,0 +1,40 @@
+#!/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 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.
+# 
+
+from gnuradio import gr, gr_unittest
+import usrp1
+
+class qa_usrp (gr_unittest.TestCase):
+
+    def setUp (self):
+        self.fg = gr.flow_graph ()
+
+    def tearDown (self):
+        self.fg = None
+
+    def test_000_nop (self):
+        """Just see if we can import the module...
+        They may not have a USRP connected, etc.  Don't try to run anything"""
+        pass
+    
+if __name__ == '__main__':
+    gr_unittest.main ()
diff --git a/gr-usrp/src/run_tests.in b/gr-usrp/src/run_tests.in
new file mode 100644 (file)
index 0000000..793cb24
--- /dev/null
@@ -0,0 +1,47 @@
+#!/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@/gr-usrp/src
+# Where to look in the src tree for swig generated python code
+libsrc=@abs_top_srcdir@/gr-usrp/src
+# Where to look in the src tree for hand written python code
+py=@abs_top_srcdir@/gr-usrp/src
+
+# Where to look for GNU Radio python modules in current build tree
+# FIXME this is wrong on a distcheck.  We really need to ask gnuradio-core
+# where it put its python files.
+grpythonbld=@abs_top_builddir@/gnuradio-core/src/python/:@abs_top_builddir@/gnuradio-core/src/lib/swig/:@abs_top_builddir@/gnuradio-core/src/lib/swig/.libs
+
+PYTHONPATH="$grpythonbld:$libbld:$libbld/.libs:$libsrc:$py:$PYTHONPATH"
+export PYTHONPATH
+
+#
+# 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-usrp/src/tx_debug_gui.py b/gr-usrp/src/tx_debug_gui.py
new file mode 100755 (executable)
index 0000000..6988f98
--- /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 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.
+# 
+
+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()
diff --git a/gr-usrp/src/usrp.py b/gr-usrp/src/usrp.py
new file mode 100644 (file)
index 0000000..6e19c1b
--- /dev/null
@@ -0,0 +1,474 @@
+#
+# 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 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.
+# 
+
+
+
+import usrp_prims
+import usrp_dbid
+from gnuradio import usrp1              # usrp Rev 1 and later
+from gnuradio import gru
+from usrp_fpga_regs import *
+
+FPGA_MODE_NORMAL   = usrp1.FPGA_MODE_NORMAL
+FPGA_MODE_LOOPBACK = usrp1.FPGA_MODE_LOOPBACK
+FPGA_MODE_COUNTING = usrp1.FPGA_MODE_COUNTING
+
+SPI_FMT_xSB_MASK = usrp1.SPI_FMT_xSB_MASK
+SPI_FMT_LSB      = usrp1.SPI_FMT_LSB
+SPI_FMT_MSB      = usrp1.SPI_FMT_MSB
+SPI_FMT_HDR_MASK = usrp1.SPI_FMT_HDR_MASK
+SPI_FMT_HDR_0    = usrp1.SPI_FMT_HDR_0
+SPI_FMT_HDR_1    = usrp1.SPI_FMT_HDR_1
+SPI_FMT_HDR_2    = usrp1.SPI_FMT_HDR_2
+
+SPI_ENABLE_FPGA     = usrp1.SPI_ENABLE_FPGA
+SPI_ENABLE_CODEC_A  = usrp1.SPI_ENABLE_CODEC_A
+SPI_ENABLE_CODEC_B  = usrp1.SPI_ENABLE_CODEC_B
+SPI_ENABLE_reserved = usrp1.SPI_ENABLE_reserved
+SPI_ENABLE_TX_A     = usrp1.SPI_ENABLE_TX_A
+SPI_ENABLE_RX_A     = usrp1.SPI_ENABLE_RX_A
+SPI_ENABLE_TX_B     = usrp1.SPI_ENABLE_TX_B
+SPI_ENABLE_RX_B     = usrp1.SPI_ENABLE_RX_B
+
+
+# Import all the daughterboard classes we know about.
+# This hooks them into the auto-instantiation framework.
+
+import db_instantiator
+
+import db_basic
+import db_dbs_rx
+import db_flexrf
+import db_flexrf_mimo
+import db_tv_rx
+
+
+def _look_for_usrp(which):
+    """
+    Try to open the specified usrp.
+
+    @param which: int >= 0 specifying which USRP to open
+    @type which: int
+    
+    @return: Returns version number, or raises RuntimeError
+    @rtype: int
+    """
+    d = usrp_prims.usrp_find_device(which)
+    if not d:
+        raise RuntimeError, "Unable to find USRP #%d" % (which,)
+
+    return usrp_prims.usrp_hw_rev(d)
+
+
+def _ensure_rev2(which):
+    v = _look_for_usrp(which)
+    if not v in (2, 4):
+        raise RuntimeError, "Sorry, unsupported USRP revision (rev=%d)" % (v,)
+
+
+class tune_result(object):
+    """
+    Container for intermediate tuning information.
+    """
+    def __init__(self, baseband_freq, dxc_freq, residual_freq, inverted):
+        self.baseband_freq = baseband_freq
+        self.dxc_freq = dxc_freq
+        self.residual_freq = residual_freq
+        self.inverted = inverted
+
+
+def tune(u, chan, subdev, target_freq):
+    """
+    Set the center frequency we're interested in.
+
+    @param u: instance of usrp.source_* or usrp.sink_*
+    @param chan: DDC/DUC channel
+    @type  chan: int
+    @param subdev: daughterboard subdevice
+    @param target_freq: frequency in Hz
+    @returns False if failure else tune_result
+    
+    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.
+    """
+
+    # Does this usrp instance do Tx or Rx?
+    rx_p = True
+    try:
+        u.rx_freq
+    except AttributeError:
+        rx_p = False
+
+    ok, baseband_freq = subdev.set_freq(target_freq)
+    dxc_freq, inverted = calc_dxc_freq(target_freq, baseband_freq, u.converter_rate())
+
+    # 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 subdev.spectrum_inverted():
+        inverted = not(inverted)
+    
+    if inverted and not(subdev.is_quadrature()):
+        dxc_freq = -dxc_freq
+        inverted = not(inverted)
+
+    if rx_p:
+        ok = ok and u.set_rx_freq(chan, dxc_freq)
+    else:
+        dxc_freq = -dxc_freq
+        ok = ok and u.set_tx_freq(chan, dxc_freq)
+        
+    if not(ok):
+        return False
+
+    # residual_freq is the offset left over because of dxc tuning step size
+    if rx_p:
+        residual_freq = dxc_freq - u.rx_freq(chan)
+    else:
+        # FIXME 50-50 chance this has the wrong sign...
+        residual_freq = dxc_freq - u.tx_freq(chan)
+
+    return tune_result(baseband_freq, dxc_freq, residual_freq, inverted)
+    
+    
+# ------------------------------------------------------------------------
+# Build subclasses of raw usrp1.* class that add the db attribute
+# by automatically instantiating the appropriate daughterboard classes.
+# [Also provides keyword args.]
+# ------------------------------------------------------------------------
+
+class usrp_common(object):
+    def __init__(self):
+        # read capability register
+        r = self._u._read_fpga_reg(FR_RB_CAPS)
+        if r < 0:
+            r += 2**32
+        if r == 0xaa55ff77:    # value of this reg prior to being defined as cap reg
+            r = ((2 << bmFR_RB_CAPS_NDUC_SHIFT)
+                 | (2 << bmFR_RB_CAPS_NDDC_SHIFT)
+                 | bmFR_RB_CAPS_RX_HAS_HALFBAND)
+        self._fpga_caps = r
+
+        if False:
+            print "FR_RB_CAPS      = %#08x" % (self._fpga_caps,)
+            print "has_rx_halfband =", self.has_rx_halfband()
+            print "nDDCs           =", self.nddc()
+            print "has_tx_halfband =", self.has_tx_halfband()
+            print "nDUCs           =", self.nduc()
+    
+    def __getattr__(self, name):
+        return getattr(self._u, name)
+
+    def tune(self, chan, subdev, target_freq):
+        return tune(self, chan, subdev, target_freq)
+
+    def has_rx_halfband(self):
+        return self._fpga_caps & bmFR_RB_CAPS_RX_HAS_HALFBAND != 0
+
+    def has_tx_halfband(self):
+        return self._fpga_caps & bmFR_RB_CAPS_TX_HAS_HALFBAND != 0
+
+    def nddc(self):
+        """
+        Number of Digital Down Converters implemented in FPGA
+        """
+        return (self._fpga_caps & bmFR_RB_CAPS_NDDC_MASK) >> bmFR_RB_CAPS_NDDC_SHIFT
+
+    def nduc(self):
+        """
+        Number of Digital Up Converters implemented in FPGA
+        """
+        return (self._fpga_caps & bmFR_RB_CAPS_NDUC_MASK) >> bmFR_RB_CAPS_NDUC_SHIFT
+
+
+class sink_c(usrp_common):
+    def __init__(self, which=0, interp_rate=128, nchan=1, mux=0x98,
+                 fusb_block_size=0, fusb_nblocks=0,
+                 fpga_filename="", firmware_filename=""):
+        _ensure_rev2(which)
+        self._u = usrp1.sink_c(which, interp_rate, nchan, mux,
+                               fusb_block_size, fusb_nblocks,
+                               fpga_filename, firmware_filename)
+        # Add the db attribute, which contains a 2-tuple of tuples of daughterboard classes
+        self.db = (db_instantiator.instantiate(self._u, 0),
+                   db_instantiator.instantiate(self._u, 1))
+        usrp_common.__init__(self)
+
+    def __del__(self):
+        self.db = None          # will fire d'board destructors
+        self._u = None          # will fire usrp1.* destructor
+
+
+class sink_s(usrp_common):
+    def __init__(self, which=0, interp_rate=128, nchan=1, mux=0x98,
+                 fusb_block_size=0, fusb_nblocks=0,
+                 fpga_filename="", firmware_filename=""):
+        _ensure_rev2(which)
+        self._u = usrp1.sink_s(which, interp_rate, nchan, mux,
+                               fusb_block_size, fusb_nblocks,
+                               fpga_filename, firmware_filename)
+        # Add the db attribute, which contains a 2-tuple of tuples of daughterboard classes
+        self.db = (db_instantiator.instantiate(self._u, 0),
+                   db_instantiator.instantiate(self._u, 1))
+        usrp_common.__init__(self)
+
+    def __del__(self):
+        self.db = None          # will fire d'board destructors
+        self._u = None          # will fire usrp1.* destructor
+        
+
+class source_c(usrp_common):
+    def __init__(self, which=0, decim_rate=64, nchan=1, mux=0x32103210, mode=0,
+                 fusb_block_size=0, fusb_nblocks=0,
+                 fpga_filename="", firmware_filename=""):
+        _ensure_rev2(which)
+        self._u = usrp1.source_c(which, decim_rate, nchan, mux, mode,
+                                 fusb_block_size, fusb_nblocks,
+                                 fpga_filename, firmware_filename)
+        # Add the db attribute, which contains a 2-tuple of tuples of daughterboard classes
+        self.db = (db_instantiator.instantiate(self._u, 0),
+                   db_instantiator.instantiate(self._u, 1))
+        usrp_common.__init__(self)
+
+    def __del__(self):
+        self.db = None          # will fire d'board destructors
+        self._u = None          # will fire usrp1.* destructor
+
+
+class source_s(usrp_common):
+    def __init__(self, which=0, decim_rate=64, nchan=1, mux=0x32103210, mode=0,
+                 fusb_block_size=0, fusb_nblocks=0,
+                 fpga_filename="", firmware_filename=""):
+        _ensure_rev2(which)
+        self._u = usrp1.source_s(which, decim_rate, nchan, mux, mode,
+                                 fusb_block_size, fusb_nblocks,
+                                 fpga_filename, firmware_filename)
+        # Add the db attribute, which contains a 2-tuple of tuples of daughterboard classes
+        self.db = (db_instantiator.instantiate(self._u, 0),
+                   db_instantiator.instantiate(self._u, 1))
+        usrp_common.__init__(self)
+
+    def __del__(self):
+        self.db = None          # will fire d'board destructors
+        self._u = None          # will fire usrp1.* destructor
+        
+
+# ------------------------------------------------------------------------
+#                               utilities
+# ------------------------------------------------------------------------
+
+def determine_rx_mux_value(u, subdev_spec):
+    """
+    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.
+    #
+
+    side = subdev_spec[0]  # side A = 0, side B = 1
+
+    if not(side in (0, 1)):
+        raise ValueError, "Invalid subdev_spec: %r:" % (subdev_spec,)
+
+    db = u.db[side]        # This is a tuple of length 1 or 2 containing the subdevice
+                           #   classes for the selected side.
+    
+    # compute bitmasks of used A/D's
+    
+    if db[0].is_quadrature():
+        subdev0_uses = 0x3              # uses A/D 0 and 1
+    else:
+        subdev0_uses = 0x1              # uses A/D 0 only
+
+    if len(db) > 1:
+        subdev1_uses = 0x2              # uses A/D 1 only
+    else:
+        subdev1_uses = 0x0              # uses no A/D (doesn't exist)
+
+    if subdev_spec[1] == 0:
+        uses = subdev0_uses
+    elif subdev_spec[1] == 1:
+        uses = subdev1_uses
+    else:
+        raise ValueError, "Invalid subdev_spec: %r: " % (subdev_spec,)
+    
+    if uses == 0:
+        raise RuntimeError, "Daughterboard doesn't have a subdevice 1: %r: " % (subdev_spec,)
+
+    swap_iq = db[0].i_and_q_swapped()
+    
+    truth_table = {
+        # (side, uses, swap_iq) : mux_val
+        (0, 0x1, False) : 0xf0f0f0f0,
+        (0, 0x2, False) : 0xf0f0f0f1,
+        (0, 0x3, False) : 0x00000010,
+        (0, 0x3, True)  : 0x00000001,
+        (1, 0x1, False) : 0xf0f0f0f2,
+        (1, 0x2, False) : 0xf0f0f0f3,
+        (1, 0x3, False) : 0x00000032,
+        (1, 0x3, True)  : 0x00000023
+        }
+
+    return gru.hexint(truth_table[(side, uses, swap_iq)])
+
+
+def determine_tx_mux_value(u, subdev_spec):
+    """
+    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.
+
+    side = subdev_spec[0]  # side A = 0, side B = 1
+
+    if not(side in (0, 1)):
+        raise ValueError, "Invalid subdev_spec: %r:" % (subdev_spec,)
+
+    return gru.hexint([0x0098, 0x9800][side])
+
+
+def selected_subdev(u, subdev_spec):
+    """
+    Return the user specified daughterboard subdevice.
+
+    @param u: an instance of usrp.source_* or usrp.sink_*
+    @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: an instance derived from db_base
+    """
+    side, subdev = subdev_spec
+    return u.db[side][subdev]
+
+
+def calc_dxc_freq(target_freq, baseband_freq, fs):
+    """
+    Calculate the frequency to use for setting the digital up or down converter.
+    
+    @param target_freq: desired RF frequency (Hz)
+    @type  target_freq: number
+    @param baseband_freq: the RF frequency that corresponds to DC in the IF.
+    @type  baseband_freq: number
+    @param fs: converter sample rate
+    @type  fs: number
+    
+    @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.
+    """
+
+    delta = target_freq - baseband_freq
+
+    if delta >= 0:
+        while delta > fs:
+            delta -= fs
+        if delta <= fs/2:
+            return (-delta, False)        # non-inverted region
+        else:
+            return (delta - fs, True)     # inverted region
+    else:
+        while delta < -fs:
+            delta += fs
+        if delta >= -fs/2:
+            return (-delta, False)        # non-inverted region
+        else:
+            return (delta + fs, True)     # inverted region
+    
+    
+# ------------------------------------------------------------------------
+#                              Utilities
+# ------------------------------------------------------------------------
+
+def pick_tx_subdevice(u):
+    """
+    The user didn't specify a tx subdevice on the command line.
+    Try for one of these, in order: FLEX_400, FLEX_900, FLEX_1200, FLEX_2400,
+    BASIC_TX, whatever's on side A.
+
+    @return a subdev_spec
+    """
+    return pick_subdev(u, (usrp_dbid.FLEX_400_TX,
+                           usrp_dbid.FLEX_900_TX,
+                           usrp_dbid.FLEX_1200_TX,
+                           usrp_dbid.FLEX_2400_TX,
+                           usrp_dbid.BASIC_TX))
+
+def pick_rx_subdevice(u):
+    """
+    The user didn't specify an rx subdevice on the command line.
+    Try for one of these, in order: FLEX_400, FLEX_900, FLEX_1200, FLEX_2400,
+    TV_RX, DBS_RX, BASIC_RX, whatever's on side A.
+
+    @return a subdev_spec
+    """
+    return pick_subdev(u, (usrp_dbid.FLEX_400_RX,
+                           usrp_dbid.FLEX_900_RX,
+                           usrp_dbid.FLEX_1200_RX,
+                           usrp_dbid.FLEX_2400_RX,
+                           usrp_dbid.TV_RX,
+                           usrp_dbid.TV_RX_REV_2,
+                           usrp_dbid.DBS_RX,
+                           usrp_dbid.DBS_RX_REV_2_1,
+                           usrp_dbid.BASIC_RX))
+
+def pick_subdev(u, candidates):
+    """
+    @param u:          usrp instance
+    @param candidates: list of dbids
+    @returns: subdev specification
+    """
+    db0 = u.db[0][0].dbid()
+    db1 = u.db[1][0].dbid()
+    for c in candidates:
+        if c == db0: return (0, 0)
+        if c == db1: return (1, 0)
+    if db0 >= 0:
+        return (0, 0)
+    if db1 >= 0:
+        return (1, 0)
+    raise RuntimeError, "No suitable daughterboard found!"
+
diff --git a/gr-usrp/src/usrp1.i b/gr-usrp/src/usrp1.i
new file mode 100644 (file)
index 0000000..b73abcd
--- /dev/null
@@ -0,0 +1,657 @@
+/* -*- 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 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.
+ */
+
+%feature("autodoc", "1");              // generate python docstrings
+
+%include "exception.i"
+%import "gnuradio.i"                           // the common stuff
+
+%{
+
+#include "gnuradio_swig_bug_workaround.h"      // mandatory bug fix
+#include "usrp1_sink_c.h"
+#include "usrp1_sink_s.h"
+#include "usrp1_source_c.h"
+#include "usrp1_source_s.h"
+#include <stdexcept>
+#include <usrp_standard.h>
+#include <usrp_spi_defs.h>
+%}
+
+%include <usrp_spi_defs.h>
+
+%constant int FPGA_MODE_NORMAL   = usrp_standard_rx::FPGA_MODE_NORMAL;
+%constant int FPGA_MODE_LOOPBACK = usrp_standard_rx::FPGA_MODE_LOOPBACK;
+%constant int FPGA_MODE_COUNTING = usrp_standard_rx::FPGA_MODE_COUNTING;
+
+// ================================================================
+//                        abstract classes
+// ================================================================
+
+class usrp1_sink_base : public gr_sync_block {
+protected:
+  usrp1_sink_base (const std::string &name,
+                  gr_io_signature_sptr input_signature,
+                  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
+                  ) throw (std::runtime_error);
+
+  virtual void copy_to_usrp_buffer (gr_vector_const_void_star &input_items,
+                                   int  input_index,
+                                   int  input_items_available,
+                                   int  &input_items_consumed,
+                                   void *usrp_buffer,
+                                   int  usrp_buffer_length,
+                                   int  &bytes_written) = 0;
+ public:
+  ~usrp1_sink_base ();
+
+  /*!
+   * \brief Set interpolator rate.  \p rate must be in [4, 1024] and a multiple of 4.
+   *
+   * The final complex sample rate across the USB is
+   *   dac_freq () * nchannels () / interp_rate ()
+   */
+  bool set_interp_rate (unsigned int rate);
+  bool set_nchannels (int nchan);
+  bool set_mux (int mux);
+
+  /*!
+   * \brief set the frequency of the digital up converter.
+   *
+   * \p channel must be 0 or 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.
+   */
+  bool set_tx_freq (int channel, double freq);
+
+  void set_verbose (bool verbose);
+
+  // ACCESSORS
+
+  long fpga_master_clock_freq() const;
+  long converter_rate() const;      // D/A sample rate
+  long dac_rate() const;            // alias
+  long dac_freq () const;           // deprecated name.  Use converter_rate() or dac_rate().
+
+  unsigned int interp_rate () const;
+  double tx_freq (int channel) const;
+  int nunderruns () const { return d_nunderruns; }
+
+  /*!
+   * \brief Set Programmable Gain Amplifier (PGA)
+   *
+   * \param which      which D/A [0,3]
+   * \param gain_in_db gain value (linear in dB)
+   *
+   * gain is rounded to closest setting supported by hardware.
+   * Note that DAC 0 and DAC 1 share a gain setting as do DAC 2 and DAC 3.
+   * Setting DAC 0 affects DAC 1 and vice versa.  Same with DAC 2 and DAC 3.
+   *
+   * \returns true iff sucessful.
+   *
+   * \sa pga_min(), pga_max(), pga_db_per_step()
+   */
+  bool set_pga (int which, double gain_in_db);
+
+  /*!
+   * \brief Return programmable gain amplifier gain in dB.
+   *
+   * \param which      which D/A [0,3]
+   */
+  double pga (int which) const;
+
+  /*!
+   * \brief Return minimum legal PGA gain in dB.
+   */
+  double pga_min () const;
+
+  /*!
+   * \brief Return maximum legal PGA gain in dB.
+   */
+  double pga_max () const;
+
+  /*!
+   * \brief Return hardware step size of PGA (linear in dB).
+   */
+  double pga_db_per_step () const;
+
+  /*!
+   * \brief Return daughterboard ID for given Tx daughterboard slot [0,1].
+   *
+   * \return daughterboard id >= 0 if successful
+   * \return -1 if no daugherboard
+   * \return -2 if invalid EEPROM on daughterboard
+   */
+  int daughterboard_id (int which_dboard) const;
+
+  /*!
+   * \brief Set ADC offset correction
+   * \param which      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, int offset);
+
+  /*!
+   * \brief Set DAC offset correction
+   * \param which      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, int offset, int offset_pin);
+
+  /*!
+   * \brief Control ADC input buffer
+   * \param which      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, bool bypass);
+
+  /*!
+   * \brief return the usrp's serial number.
+   *
+   * \returns non-zero length string iff successful.
+   */
+  std::string serial_number();
+
+  /*!
+   * \brief Write direction register (output enables) for pins that go to daughterboard.
+   *
+   * \param which_dboard       [0,1] which d'board
+   * \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 _write_oe (int which_dboard, int value, int mask);
+
+  /*!
+   * \brief Write daughterboard i/o pin value
+   *
+   * \param which_dboard       [0,1] which d'board
+   * \param value              value to write into register
+   * \param mask               which bits of value to write into reg
+   */
+  bool write_io (int which_dboard, int value, int mask);
+
+  /*!
+   * \brief Read daughterboard i/o pin value
+   *
+   * \param which_dboard       [0,1] which d'board
+   * \returns register value if successful, else READ_FAILED
+   */
+  int read_io (int which_dboard);
+
+  bool write_aux_dac (int which_dboard, int which_dac, int value);
+  int read_aux_adc (int which_dboard, int which_adc);
+  bool write_eeprom (int i2c_addr, int eeprom_offset, const std::string buf);
+  std::string read_eeprom (int i2c_addr, int eeprom_offset, int len);
+  bool write_i2c (int i2c_addr, const std::string buf);
+  std::string read_i2c (int i2c_addr, int len);
+
+  bool _write_fpga_reg (int regno, int value); //< 7-bit regno, 32-bit value
+  int  _read_fpga_reg (int regno);
+  bool _write_9862 (int which_codec, int regno, unsigned char value);
+  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);
+};
+
+// ----------------------------------------------------------------
+
+class usrp1_source_base : public gr_sync_block {
+ protected:
+
+  usrp1_sink_base (const std::string &name,
+                  gr_io_signature_sptr input_signature,
+                  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
+                  ) throw (std::runtime_error);
+
+  virtual int ninput_bytes_reqd_for_noutput_items (int noutput_items) = 0;
+
+  virtual void copy_from_usrp_buffer (gr_vector_void_star &output_items,
+                                     int output_index,
+                                     int output_items_available,
+                                     int &output_items_produced,
+                                     const void *usrp_buffer,
+                                     int usrp_buffer_length,
+                                     int &bytes_read) = 0;
+ public:
+  ~usrp1_source_base ();
+
+
+  /*!
+   * \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 ()
+   */
+  bool set_decim_rate (unsigned int rate);
+  bool set_nchannels (int nchan);
+  bool set_mux (int mux);
+
+  /*!
+   * \brief set the center frequency of the digital down converter.
+   *
+   * \p channel must be 0.  \p freq is the center frequency in Hz.
+   * It must be in the range [-FIXME, FIXME].  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 special modes
+   */
+  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);
+
+
+  void set_verbose (bool verbose);
+
+  // ACCESSORS
+
+  long fpga_master_clock_freq() const;
+  long converter_rate() const;  // A/D sample rate
+  long adc_rate() const;        // alias
+  long adc_freq() const;        // Deprecated name.  Use converter_rate() or adc_rate().
+
+  unsigned int decim_rate () const;
+  double rx_freq (int channel) const;
+  int noverruns () const { return d_noverruns; }
+
+
+  // PGA stuff
+  /*!
+   * \brief Set Programmable Gain Amplifier (PGA)
+   *
+   * \param which      which A/D [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 set_pga (int which, double gain_in_db);
+
+  /*!
+   * \brief Return programmable gain amplifier gain setting in dB.
+   *
+   * \param which      which A/D [0,3]
+   */
+  double pga (int which) const;
+
+  /*!
+   * \brief Return minimum legal PGA setting in dB.
+   */
+  double pga_min () const;
+
+  /*!
+   * \brief Return maximum legal PGA setting in dB.
+   */
+  double pga_max () const;
+
+  /*!
+   * \brief Return hardware step size of PGA (linear in dB).
+   */
+  double pga_db_per_step () const;
+
+  /*!
+   * \brief Return daughterboard ID for given Rx daughterboard slot [0,1].
+   *
+   * \return daughterboard id >= 0 if successful
+   * \return -1 if no daugherboard
+   * \return -2 if invalid EEPROM on daughterboard
+   */
+  int daughterboard_id (int which_dboard) const;
+
+  /*!
+   * \brief Set ADC offset correction
+   * \param which      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, int offset);
+
+  /*!
+   * \brief Set DAC offset correction
+   * \param which      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, int offset, int offset_pin);
+
+  /*!
+   * \brief Control ADC input buffer
+   * \param which      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, bool bypass);
+
+  /*!
+   * \brief return the usrp's serial number.
+   *
+   * \returns non-zero length string iff successful.
+   */
+  std::string serial_number();
+
+  /*!
+   * \brief Write direction register (output enables) for pins that go to daughterboard.
+   *
+   * \param which_dboard       [0,1] which d'board
+   * \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 _write_oe (int which_dboard, int value, int mask);
+
+  /*!
+   * \brief Write daughterboard i/o pin value
+   *
+   * \param which_dboard       [0,1] which d'board
+   * \param value              value to write into register
+   * \param mask               which bits of value to write into reg
+   */
+  bool write_io (int which_dboard, int value, int mask);
+
+  /*!
+   * \brief Read daughterboard i/o pin value
+   *
+   * \param which_dboard       [0,1] which d'board
+   * \returns register value if successful, else READ_FAILED
+   */
+  int read_io (int which_dboard);
+
+  /*!
+   * \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 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);
+
+  /*!
+   * \brief return current format
+   */
+  unsigned int format () const;
+
+  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);
+
+
+
+
+  bool write_aux_dac (int which_dboard, int which_dac, int value);
+  int read_aux_adc (int which_dboard, int which_adc);
+  bool write_eeprom (int i2c_addr, int eeprom_offset, const std::string buf);
+  std::string read_eeprom (int i2c_addr, int eeprom_offset, int len);
+  bool write_i2c (int i2c_addr, const std::string buf);
+  std::string read_i2c (int i2c_addr, int len);
+  bool _write_fpga_reg (int regno, int value); //< 7-bit regno, 32-bit value
+  bool _write_fpga_reg_masked (int regno, int value, int mask); //< 7-bit regno, 16-bit value, 16-bit mask
+  int  _read_fpga_reg (int regno);
+  bool _write_9862 (int which_codec, int regno, unsigned char value);
+  int  _read_9862 (int which_codec, int regno) const;
+
+  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);
+};
+
+
+// ================================================================
+//                     concrete sinks
+// ================================================================
+
+
+GR_SWIG_BLOCK_MAGIC(usrp1,sink_c)
+
+usrp1_sink_c_sptr
+usrp1_make_sink_c (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
+                  ) throw (std::runtime_error);
+
+
+class usrp1_sink_c : public usrp1_sink_base {
+ protected:
+  usrp1_sink_c (int which_board, unsigned int interp_rate,
+               int nchan, int mux);
+
+ public:
+  ~usrp1_sink_c ();
+};
+
+// ----------------------------------------------------------------
+
+GR_SWIG_BLOCK_MAGIC(usrp1,sink_s)
+
+usrp1_sink_s_sptr
+usrp1_make_sink_s (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
+                  ) throw (std::runtime_error);
+
+
+class usrp1_sink_s : public usrp1_sink_base {
+ protected:
+  usrp1_sink_s (int which_board, unsigned int interp_rate,
+               int nchan, int mux);
+
+ public:
+  ~usrp1_sink_s ();
+};
+
+// ================================================================
+//                     concrete sources
+// ================================================================
+
+GR_SWIG_BLOCK_MAGIC(usrp1,source_c)
+
+
+usrp1_source_c_sptr
+usrp1_make_source_c (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
+                    ) throw (std::runtime_error);
+
+class usrp1_source_c : public usrp1_source_base {
+ protected:
+  usrp1_source_c (int which_board, unsigned int decim_rate,
+                 int nchan, int mux, int mode);
+
+ public:
+  ~usrp1_source_c ();
+};
+
+// ----------------------------------------------------------------
+
+GR_SWIG_BLOCK_MAGIC(usrp1,source_s)
+
+usrp1_source_s_sptr
+usrp1_make_source_s (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
+                    ) throw (std::runtime_error);
+
+
+class usrp1_source_s : public usrp1_source_base {
+ protected:
+  usrp1_source_s (int which_board, unsigned int decim_rate,
+                 int nchan, int mux, int mode);
+
+ public:
+  ~usrp1_source_s ();
+};
+
diff --git a/gr-usrp/src/usrp1_sink_base.cc b/gr-usrp/src/usrp1_sink_base.cc
new file mode 100644 (file)
index 0000000..19e0b23
--- /dev/null
@@ -0,0 +1,359 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <usrp1_sink_base.h>
+#include <gr_io_signature.h>
+#include <usrp_standard.h>
+#include <assert.h>
+
+static const int OUTPUT_MULTIPLE_SAMPLES = 128;                // DON'T CHANGE THIS VALUE!
+
+usrp1_sink_base::usrp1_sink_base (const std::string &name,
+                                 gr_io_signature_sptr input_signature,
+                                 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
+                                 ) throw (std::runtime_error)
+  : gr_sync_block (name,
+                  input_signature,
+                  gr_make_io_signature (0, 0, 0)),
+    d_nunderruns (0)
+{
+  d_usrp = usrp_standard_tx::make (which_board,
+                                  interp_rate,
+                                  nchan, mux,
+                                  fusb_block_size,
+                                  fusb_nblocks,
+                                  fpga_filename,
+                                  firmware_filename
+                                  );
+  if (d_usrp == 0)
+    throw std::runtime_error ("can't open usrp1");
+
+  // All calls to d_usrp->write must be multiples of 512 bytes.
+
+  set_output_multiple (OUTPUT_MULTIPLE_SAMPLES);
+}
+
+usrp1_sink_base::~usrp1_sink_base ()
+{
+  delete d_usrp;
+}
+
+bool 
+usrp1_sink_base::start()
+{
+  return d_usrp->start();
+}
+
+bool 
+usrp1_sink_base::stop()
+{
+  return d_usrp->stop();
+}
+
+int
+usrp1_sink_base::work (int noutput_items,
+                      gr_vector_const_void_star &input_items,
+                      gr_vector_void_star &output_items)
+{
+  static const int BUFSIZE = 16 * (1L << 10);  // 16kB
+  unsigned char outbuf[BUFSIZE];
+  int          obi = 0;
+  int          input_index = 0;
+  int          input_items_consumed;
+  int          bytes_written;
+  bool         underrun;
+  
+
+  while (input_index < noutput_items){
+  
+    copy_to_usrp_buffer (input_items,
+                        input_index,
+                        noutput_items - input_index,   // input_items_available
+                        input_items_consumed,          // [out]
+                        &outbuf[obi],                  // [out] usrp_buffer
+                        BUFSIZE - obi,                 // usrp_buffer_length
+                        bytes_written);                // [out]
+
+    assert (input_index + input_items_consumed <= noutput_items);
+    assert (obi + bytes_written <= BUFSIZE);
+    
+    input_index += input_items_consumed;
+    obi += bytes_written;
+
+    if (obi >= BUFSIZE){       // flush
+      if (d_usrp->write (outbuf, obi, &underrun) != obi)
+       return -1;              // indicate we're done
+
+      if (underrun){
+       d_nunderruns++;
+       // fprintf (stderr, "usrp1_sink: underrun\n");
+       fputs ("uU", stderr);
+      }
+      obi = 0;
+    }
+  }
+
+  if (obi != 0){
+    assert (obi % 512 == 0);
+    if (d_usrp->write (outbuf, obi, &underrun) != obi)
+      return -1;       // indicate we're done
+
+    if (underrun){
+      d_nunderruns++;
+      // fprintf (stderr, "usrp1_sink: underrun\n");
+      fputs ("uU", stderr);
+    }
+  }
+
+  return noutput_items;
+}
+
+bool
+usrp1_sink_base::set_interp_rate (unsigned int rate)
+{
+  return d_usrp->set_interp_rate (rate);
+}
+
+bool
+usrp1_sink_base::set_nchannels (int nchan)
+{
+  return d_usrp->set_nchannels (nchan);
+}
+
+bool
+usrp1_sink_base::set_mux (int mux)
+{
+  return d_usrp->set_mux (mux);
+}
+
+bool
+usrp1_sink_base::set_tx_freq (int channel, double freq)
+{
+  return d_usrp->set_tx_freq (channel, freq);
+}
+
+long
+usrp1_sink_base::fpga_master_clock_freq() const
+{
+  return d_usrp->fpga_master_clock_freq();
+}
+
+long
+usrp1_sink_base::converter_rate () const
+{
+  return d_usrp->converter_rate ();
+}
+
+unsigned int
+usrp1_sink_base::interp_rate () const
+{
+  return d_usrp->interp_rate ();
+}
+
+int
+usrp1_sink_base::nchannels () const
+{
+  return d_usrp->nchannels ();
+}
+
+int
+usrp1_sink_base::mux () const
+{
+  return d_usrp->mux ();
+}
+
+
+double
+usrp1_sink_base::tx_freq (int channel) const
+{
+  return d_usrp->tx_freq (channel);
+}
+
+void
+usrp1_sink_base::set_verbose (bool verbose)
+{  
+  d_usrp->set_verbose (verbose);
+}
+
+bool
+usrp1_sink_base::write_aux_dac (int which_dboard, int which_dac, int value)
+{
+  return d_usrp->write_aux_dac (which_dboard, which_dac, value);
+}
+
+int
+usrp1_sink_base::read_aux_adc (int which_dboard, int which_adc)
+{
+  return d_usrp->read_aux_adc (which_dboard, which_adc);
+}
+
+bool
+usrp1_sink_base::write_eeprom (int i2c_addr, int eeprom_offset, const std::string buf)
+{
+  return d_usrp->write_eeprom (i2c_addr, eeprom_offset, buf);
+}
+
+std::string
+usrp1_sink_base::read_eeprom (int i2c_addr, int eeprom_offset, int len)
+{
+  return d_usrp->read_eeprom (i2c_addr, eeprom_offset, len);
+}
+
+bool
+usrp1_sink_base::write_i2c (int i2c_addr, const std::string buf)
+{
+  return d_usrp->write_i2c (i2c_addr, buf);
+}
+
+std::string
+usrp1_sink_base::read_i2c (int i2c_addr, int len)
+{
+  return d_usrp->read_i2c (i2c_addr, len);
+}
+
+bool
+usrp1_sink_base::set_pga (int which, double gain)
+{
+  return d_usrp->set_pga (which, gain);
+}
+
+double
+usrp1_sink_base::pga (int which) const
+{
+  return d_usrp->pga (which);
+}
+
+double
+usrp1_sink_base::pga_min () const
+{
+  return d_usrp->pga_min ();
+}
+
+double
+usrp1_sink_base::pga_max () const
+{
+  return d_usrp->pga_max ();
+}
+
+double
+usrp1_sink_base::pga_db_per_step () const
+{
+  return d_usrp->pga_db_per_step ();
+}
+
+int
+usrp1_sink_base::daughterboard_id (int which) const
+{
+  return d_usrp->daughterboard_id (which);
+}
+
+bool
+usrp1_sink_base::set_adc_offset (int which, int offset)
+{
+  return d_usrp->set_adc_offset (which, offset);
+}
+
+bool
+usrp1_sink_base::set_dac_offset (int which, int offset, int offset_pin)
+{
+  return d_usrp->set_dac_offset (which, offset, offset_pin);
+}
+
+bool
+usrp1_sink_base::set_adc_buffer_bypass (int which, bool bypass)
+{
+  return d_usrp->set_adc_buffer_bypass (which, bypass);
+}
+
+std::string
+usrp1_sink_base::serial_number()
+{
+  return d_usrp->serial_number();
+}
+
+bool
+usrp1_sink_base::_write_oe (int which_dboard, int value, int mask)
+{
+  return d_usrp->_write_oe (which_dboard, value, mask);
+}
+
+bool
+usrp1_sink_base::write_io (int which_dboard, int value, int mask)
+{
+  return d_usrp->write_io (which_dboard, value, mask);
+}
+
+int
+usrp1_sink_base::read_io (int which_dboard)
+{
+  return d_usrp->read_io (which_dboard);
+}
+
+// internal routines...
+
+bool
+usrp1_sink_base::_write_fpga_reg (int regno, int value)
+{
+  return d_usrp->_write_fpga_reg (regno, value);
+}
+
+int
+usrp1_sink_base::_read_fpga_reg (int regno)
+{
+  return d_usrp->_read_fpga_reg (regno);
+}
+
+bool
+usrp1_sink_base::_write_9862 (int which_codec, int regno, unsigned char value)
+{
+  return d_usrp->_write_9862 (which_codec, regno, value);
+}
+
+int
+usrp1_sink_base::_read_9862 (int which_codec, int regno) const
+{
+  return d_usrp->_read_9862 (which_codec, regno);
+}
+
+bool
+usrp1_sink_base::_write_spi (int optional_header, int enables,
+                            int format, std::string buf)
+{
+  return d_usrp->_write_spi (optional_header, enables, format, buf);
+}
+
+std::string
+usrp1_sink_base::_read_spi (int optional_header, int enables, int format, int len)
+{
+  return d_usrp->_read_spi (optional_header, enables, format, len);
+}
diff --git a/gr-usrp/src/usrp1_sink_base.h b/gr-usrp/src/usrp1_sink_base.h
new file mode 100644 (file)
index 0000000..d577537
--- /dev/null
@@ -0,0 +1,359 @@
+/* -*- 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 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.
+ */
+
+#ifndef INCLUDED_USRP1_SINK_BASE_H
+#define INCLUDED_USRP1_SINK_BASE_H
+
+#include <gr_sync_block.h>
+#include <stdexcept>
+
+class usrp_standard_tx;
+
+
+/*!
+ * \brief abstract interface to Universal Software Radio Peripheral Tx path (Rev 1)
+ */
+class usrp1_sink_base : public gr_sync_block {
+ private:
+  usrp_standard_tx     *d_usrp;
+  int                   d_nunderruns;
+  
+ protected:
+  usrp1_sink_base (const std::string &name,
+                  gr_io_signature_sptr input_signature,
+                  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
+                  ) throw (std::runtime_error);
+
+  /*!
+   * \brief convert between input item format and usrp native format
+   *
+   * \param input_items[in]            stream(s) of input items
+   * \param input_index[in]            starting index in input_items
+   * \param input_items_available[in]  number of items available starting at item[index]
+   * \param input_items_consumed[out]          number of input items consumed by copy
+   * \param usrp_buffer[out]           destination buffer
+   * \param usrp_buffer_length[in]     \p usrp_buffer length in bytes
+   * \param bytes_written[out]         number of bytes written into \p usrp_buffer
+   */
+  virtual void copy_to_usrp_buffer (gr_vector_const_void_star &input_items,
+                                   int  input_index,
+                                   int  input_items_available,
+                                   int  &input_items_consumed,
+                                   void *usrp_buffer,
+                                   int  usrp_buffer_length,
+                                   int  &bytes_written) = 0;
+
+ public:
+  //! magic value used on alternate register read interfaces
+  static const int READ_FAILED = -99999;
+
+
+  ~usrp1_sink_base ();
+
+  int work (int noutput_items,
+           gr_vector_const_void_star &input_items,
+           gr_vector_void_star &output_items);
+
+  bool start();
+  bool stop();
+
+  /*!
+   * \brief Set interpolator rate.  \p rate must be in [4, 1024] and a multiple of 4.
+   *
+   * The final complex sample rate across the USB is
+   *   dac_freq () / interp_rate () * nchannels ()
+   */
+  bool set_interp_rate (unsigned int rate);
+  bool set_nchannels (int nchan);
+  bool set_mux (int mux);
+
+  /*!
+   * \brief set the frequency of the digital up converter.
+   *
+   * \p channel must be 0.  \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.
+   */
+  bool set_tx_freq (int channel, double freq);
+
+  void set_verbose (bool verbose);
+
+  /*!
+   * \brief Set Programmable Gain Amplifier (PGA)
+   *
+   * \param which      which D/A [0,3]
+   * \param gain_in_db gain value (linear in dB)
+   *
+   * gain is rounded to closest setting supported by hardware.
+   * Note that DAC 0 and DAC 1 share a gain setting as do DAC 2 and DAC 3.
+   * Setting DAC 0 affects DAC 1 and vice versa.  Same with DAC 2 and DAC 3.
+   *
+   * \returns true iff sucessful.
+   *
+   * \sa pga_min(), pga_max(), pga_db_per_step()
+   */
+  bool set_pga (int which, double gain_in_db);
+
+  /*!
+   * \brief Return programmable gain amplifier gain in dB.
+   *
+   * \param which      which D/A [0,3]
+   */
+  double pga (int which) const;
+
+  /*!
+   * \brief Return minimum legal PGA gain in dB.
+   */
+  double pga_min () const;
+
+  /*!
+   * \brief Return maximum legal PGA gain in dB.
+   */
+  double pga_max () const;
+
+  /*!
+   * \brief Return hardware step size of PGA (linear in dB).
+   */
+  double pga_db_per_step () const;
+
+
+  // ACCESSORS
+
+  long fpga_master_clock_freq() const;
+  long converter_rate() const;
+  long dac_rate() const { return converter_rate(); }   // alias
+  long dac_freq() const { return converter_rate(); }   // deprecated alias
+
+  unsigned int interp_rate () const;
+  int nchannels () const;
+  int mux () const;
+  double tx_freq (int channel) const;
+  int nunderruns () const { return d_nunderruns; }
+
+  /*!
+   * \brief Return daughterboard ID for given Rx daughterboard slot [0,1].
+   *
+   * \return daughterboard id >= 0 if successful
+   * \return -1 if no daugherboard
+   * \return -2 if invalid EEPROM on daughterboard
+   */
+  int daughterboard_id (int which_dboard) const;
+
+  /*!
+   * \brief Write auxiliary digital to analog converter.
+   *
+   * \param which_dboard       [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 write_aux_dac (int which_board, int which_dac, int value);
+
+  /*!
+   * \brief Read auxiliary analog to digital converter.
+   *
+   * \param which_dboard       [0,1] which d'board
+   * \param which_adc          [0,1]
+   * \returns value in the range [0,4095] if successful, else READ_FAILED.
+   */
+  int read_aux_adc (int which_dboard, int which_adc);
+
+  /*!
+   * \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 Write 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 of 64 bytes.
+   */
+  std::string read_i2c (int i2c_addr, int len);
+
+  /*!
+   * \brief Set ADC offset correction
+   * \param which      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, int offset);
+
+  /*!
+   * \brief Set DAC offset correction
+   * \param which      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, int offset, int offset_pin);
+
+  /*!
+   * \brief Control ADC input buffer
+   * \param which      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, bool bypass);
+
+  /*!
+   * \brief return the usrp's serial number.
+   *
+   * \returns non-zero length string iff successful.
+   */
+  std::string serial_number();
+
+  /*!
+   * \brief Write direction register (output enables) for pins that go to daughterboard.
+   *
+   * \param which_dboard       [0,1] which d'board
+   * \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 _write_oe (int which_dboard, int value, int mask);
+
+  /*!
+   * \brief Write daughterboard i/o pin value
+   *
+   * \param which_dboard       [0,1] which d'board
+   * \param value              value to write into register
+   * \param mask               which bits of value to write into reg
+   */
+  bool write_io (int which_dboard, int value, int mask);
+
+  /*!
+   * \brief Read daughterboard i/o pin value
+   *
+   * \param which_dboard       [0,1] which d'board
+   * \returns register value if successful, else READ_FAILED
+   */
+  int read_io (int which_dboard);
+
+  //
+  // internal routines...
+  // You probably shouldn't be using these...
+  //
+  /*!
+   * \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
+   * \returns register value if successful, else READ_FAILED
+   */
+  int  _read_fpga_reg (int regno);
+
+  /*!
+   * \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
+   * \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);
+};
+
+#endif /* INCLUDED_USRP1_SINK_BASE_H */
diff --git a/gr-usrp/src/usrp1_sink_c.cc b/gr-usrp/src/usrp1_sink_c.cc
new file mode 100644 (file)
index 0000000..16296cf
--- /dev/null
@@ -0,0 +1,106 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <usrp1_sink_c.h>
+#include <gr_io_signature.h>
+#include <usrp_standard.h>
+#include <usrp_bytesex.h>
+
+usrp1_sink_c_sptr
+usrp1_make_sink_c (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
+                  ) throw (std::runtime_error)
+{
+  return usrp1_sink_c_sptr (new usrp1_sink_c (which_board,
+                                             interp_rate,
+                                             nchan,
+                                             mux,
+                                             fusb_block_size,
+                                             fusb_nblocks,
+                                             fpga_filename,
+                                             firmware_filename
+                                             ));
+}
+
+
+usrp1_sink_c::usrp1_sink_c (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
+                           ) throw (std::runtime_error)
+  : usrp1_sink_base ("usrp1_sink_c",
+                    gr_make_io_signature (1, 1, sizeof (gr_complex)),
+                    which_board, interp_rate, nchan, mux,
+                    fusb_block_size, fusb_nblocks,
+                    fpga_filename, firmware_filename)
+{
+}
+
+usrp1_sink_c::~usrp1_sink_c ()
+{
+  // NOP
+}
+
+/*
+ * Take one complex input stream and format it into interleaved short I & Q
+ * for the usrp.
+ */
+void
+usrp1_sink_c::copy_to_usrp_buffer (gr_vector_const_void_star &input_items,
+                                  int  input_index,
+                                  int  input_items_available,
+                                  int  &input_items_consumed,  // out
+                                  void *usrp_buffer,
+                                  int  usrp_buffer_length,
+                                  int  &bytes_written)         // out
+{
+  gr_complex *in = &((gr_complex *) input_items[0])[input_index];
+  short *dst = (short *) usrp_buffer;
+
+  static const int usrp_bytes_per_input_item = 2 * sizeof (short); // I & Q
+
+  int nitems = std::min (input_items_available,
+                        usrp_buffer_length / usrp_bytes_per_input_item);
+
+  for (int i = 0; i < nitems; i++){
+    dst[2*i + 0] = host_to_usrp_short((short) real(in[i]));    // FIXME saturate?
+    dst[2*i + 1] = host_to_usrp_short((short) imag(in[i]));    // FIXME saturate?
+  }
+
+  input_items_consumed = nitems;
+  bytes_written = nitems * usrp_bytes_per_input_item;
+}
+
diff --git a/gr-usrp/src/usrp1_sink_c.h b/gr-usrp/src/usrp1_sink_c.h
new file mode 100644 (file)
index 0000000..15d92a9
--- /dev/null
@@ -0,0 +1,87 @@
+/* -*- 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 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.
+ */
+
+#ifndef INCLUDED_USRP1_SINK_C_H
+#define INCLUDED_USRP1_SINK_C_H
+
+#include <usrp1_sink_base.h>
+
+class usrp1_sink_c;
+typedef boost::shared_ptr<usrp1_sink_c> usrp1_sink_c_sptr;
+
+
+// public shared_ptr constructor
+
+usrp1_sink_c_sptr
+usrp1_make_sink_c (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
+                  ) throw (std::runtime_error);
+
+
+/*!
+ * \brief interface to Universal Software Radio Peripheral Tx path (Rev 1)
+ *
+ * input: gr_complex
+ */
+class usrp1_sink_c : public usrp1_sink_base {
+ private:
+
+  friend usrp1_sink_c_sptr
+  usrp1_make_sink_c (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
+                    ) throw (std::runtime_error);
+
+ protected:
+  usrp1_sink_c (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
+               ) throw (std::runtime_error);
+
+  virtual void copy_to_usrp_buffer (gr_vector_const_void_star &input_items,
+                                   int  input_index,
+                                   int  input_items_available,
+                                   int  &input_items_consumed,
+                                   void *usrp_buffer,
+                                   int  usrp_buffer_length,
+                                   int  &bytes_written);
+ public:
+  ~usrp1_sink_c ();
+};
+
+#endif /* INCLUDED_USRP1_SINK_C_H */
diff --git a/gr-usrp/src/usrp1_sink_s.cc b/gr-usrp/src/usrp1_sink_s.cc
new file mode 100644 (file)
index 0000000..634eb5a
--- /dev/null
@@ -0,0 +1,106 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <usrp1_sink_s.h>
+#include <gr_io_signature.h>
+#include <usrp_standard.h>
+#include <usrp_bytesex.h>
+
+usrp1_sink_s_sptr
+usrp1_make_sink_s (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
+                  ) throw (std::runtime_error)
+{
+  return usrp1_sink_s_sptr (new usrp1_sink_s (which_board,
+                                             interp_rate,
+                                             nchan,
+                                             mux,
+                                             fusb_block_size,
+                                             fusb_nblocks,
+                                             fpga_filename,
+                                             firmware_filename
+                                             ));
+}
+
+
+usrp1_sink_s::usrp1_sink_s (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
+                           ) throw (std::runtime_error)
+  : usrp1_sink_base ("usrp1_sink_s",
+                    gr_make_io_signature (1, 1, sizeof (short)),
+                    which_board, interp_rate, nchan, mux,
+                    fusb_block_size, fusb_nblocks,
+                    fpga_filename, firmware_filename)
+{
+  set_output_multiple (512 / sizeof(short));   // don't change
+}
+
+usrp1_sink_s::~usrp1_sink_s ()
+{
+  // NOP
+}
+
+/*
+ * Take one short input stream and format it into interleaved short I & Q
+ * for the usrp.
+ */
+void
+usrp1_sink_s::copy_to_usrp_buffer (gr_vector_const_void_star &input_items,
+                                  int  input_index,
+                                  int  input_items_available,
+                                  int  &input_items_consumed,  // out
+                                  void *usrp_buffer,
+                                  int  usrp_buffer_length,
+                                  int  &bytes_written)         // out
+{
+  short *in = &((short *) input_items[0])[input_index];
+  short *dst = (short *) usrp_buffer;
+
+  static const int usrp_bytes_per_input_item = sizeof (short);
+
+  int nitems = std::min (input_items_available,
+                        usrp_buffer_length / usrp_bytes_per_input_item);
+
+  for (int i = 0; i < nitems; i++){    // FIXME unroll
+    dst[i] = host_to_usrp_short(in[i]);
+  }
+
+  input_items_consumed = nitems;
+  bytes_written = nitems * usrp_bytes_per_input_item;
+}
+
diff --git a/gr-usrp/src/usrp1_sink_s.h b/gr-usrp/src/usrp1_sink_s.h
new file mode 100644 (file)
index 0000000..a2e086c
--- /dev/null
@@ -0,0 +1,86 @@
+/* -*- 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 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.
+ */
+
+#ifndef INCLUDED_USRP1_SINK_S_H
+#define INCLUDED_USRP1_SINK_S_H
+
+#include <usrp1_sink_base.h>
+
+class usrp1_sink_s;
+typedef boost::shared_ptr<usrp1_sink_s> usrp1_sink_s_sptr;
+
+
+// public shared_ptr constructor
+
+usrp1_sink_s_sptr
+usrp1_make_sink_s (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
+                  ) throw (std::runtime_error);
+
+/*!
+ * \brief interface to Universal Software Radio Peripheral Tx path (Rev 1)
+ *
+ * input: short
+ */
+class usrp1_sink_s : public usrp1_sink_base {
+ private:
+
+  friend usrp1_sink_s_sptr
+  usrp1_make_sink_s (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
+                    ) throw (std::runtime_error);
+
+ protected:
+  usrp1_sink_s (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
+               ) throw (std::runtime_error);
+
+  virtual void copy_to_usrp_buffer (gr_vector_const_void_star &input_items,
+                                   int  input_index,
+                                   int  input_items_available,
+                                   int  &input_items_consumed,
+                                   void *usrp_buffer,
+                                   int  usrp_buffer_length,
+                                   int  &bytes_written);
+ public:
+  ~usrp1_sink_s ();
+};
+
+#endif /* INCLUDED_USRP1_SINK_S_H */
diff --git a/gr-usrp/src/usrp1_source_base.cc b/gr-usrp/src/usrp1_source_base.cc
new file mode 100644 (file)
index 0000000..9f5cb25
--- /dev/null
@@ -0,0 +1,425 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <usrp1_source_base.h>
+#include <gr_io_signature.h>
+#include <usrp_standard.h>
+#include <assert.h>
+
+static const int OUTPUT_MULTIPLE_BYTES = 4 * 1024;
+
+usrp1_source_base::usrp1_source_base (const std::string &name,
+                                     gr_io_signature_sptr output_signature,
+                                     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
+                                     ) throw (std::runtime_error)
+  : gr_sync_block (name,
+                  gr_make_io_signature (0, 0, 0),
+                  output_signature),
+    d_noverruns (0)
+{
+  d_usrp = usrp_standard_rx::make (which_board, decim_rate,
+                                  nchan, mux, mode,
+                                  fusb_block_size,
+                                  fusb_nblocks,
+                                  fpga_filename,
+                                  firmware_filename);
+  if (d_usrp == 0)
+    throw std::runtime_error ("can't open usrp1");
+
+  // All calls to d_usrp->read must be multiples of 512 bytes.
+  // We jack this up to 4k to reduce overhead.
+
+  set_output_multiple (OUTPUT_MULTIPLE_BYTES / output_signature->sizeof_stream_item (0));
+}
+
+usrp1_source_base::~usrp1_source_base ()
+{
+  delete d_usrp;
+}
+
+unsigned int
+usrp1_source_base::sizeof_basic_sample() const
+{
+  return usrp_standard_rx::format_width(d_usrp->format()) / 8;
+}
+
+bool
+usrp1_source_base::start()
+{
+  return d_usrp->start();
+}
+
+bool
+usrp1_source_base::stop()
+{
+  return d_usrp->stop();
+}
+
+int
+usrp1_source_base::work (int noutput_items,
+                        gr_vector_const_void_star &input_items,
+                        gr_vector_void_star &output_items)
+{
+  static const int BUFSIZE = 4 * OUTPUT_MULTIPLE_BYTES;
+  unsigned char buf[BUFSIZE];
+  int output_index = 0;
+  int output_items_produced;
+  int bytes_read;
+  bool overrun;
+
+  while (output_index < noutput_items){
+    int nbytes = ninput_bytes_reqd_for_noutput_items (noutput_items - output_index);
+    nbytes = std::min (nbytes, BUFSIZE);
+
+    int result_nbytes = d_usrp->read (buf, nbytes, &overrun);
+    if (overrun){
+      // fprintf (stderr, "usrp1_source: overrun\n");
+      fputs ("uO", stderr);
+      d_noverruns++;
+    }
+
+    if (result_nbytes < 0)     // We've got a problem.  Usually board unplugged or powered down.
+      return -1;               // Indicate we're done.
+
+    if (result_nbytes != nbytes){      // not really an error, but unexpected
+      fprintf (stderr, "usrp1_source: short read.  Expected %d, got %d\n",
+              nbytes, result_nbytes);
+    }
+
+    copy_from_usrp_buffer (output_items,
+                          output_index,
+                          noutput_items - output_index,   // output_items_available
+                          output_items_produced,          // [out]
+                          buf,                            // usrp_buffer
+                          result_nbytes,                  // usrp_buffer_length
+                          bytes_read);                    // [out]
+
+    assert (output_index + output_items_produced <= noutput_items);
+    assert (bytes_read == result_nbytes);
+
+    output_index += output_items_produced;
+  }
+
+  return noutput_items;
+}
+
+
+bool
+usrp1_source_base::set_decim_rate (unsigned int rate)
+{
+  return d_usrp->set_decim_rate (rate);
+}
+
+bool
+usrp1_source_base::set_nchannels (int nchan)
+{
+  return d_usrp->set_nchannels (nchan);
+}
+
+bool
+usrp1_source_base::set_mux (int mux)
+{
+  return d_usrp->set_mux (mux);
+}
+
+bool
+usrp1_source_base::set_rx_freq (int channel, double freq)
+{
+  return d_usrp->set_rx_freq (channel, freq);
+}
+
+long
+usrp1_source_base::fpga_master_clock_freq() const
+{
+  return d_usrp->fpga_master_clock_freq();
+}
+
+long
+usrp1_source_base::converter_rate() const
+{
+  return d_usrp->converter_rate();
+}
+
+unsigned int
+usrp1_source_base::decim_rate () const
+{
+  return d_usrp->decim_rate ();
+}
+
+int
+usrp1_source_base::nchannels () const
+{
+  return d_usrp->nchannels ();
+}
+
+int
+usrp1_source_base::mux () const
+{
+  return d_usrp->mux ();
+}
+
+double
+usrp1_source_base::rx_freq (int channel) const
+{
+  return d_usrp->rx_freq (channel);
+}
+
+bool
+usrp1_source_base::set_fpga_mode (int mode)
+{
+  return d_usrp->set_fpga_mode (mode);
+}
+
+bool
+usrp1_source_base::set_ddc_phase (int channel, int phase)
+{
+  return d_usrp->set_ddc_phase(channel, phase);
+}
+
+bool
+usrp1_source_base::set_dc_offset_cl_enable(int bits, int mask)
+{
+  return d_usrp->set_dc_offset_cl_enable(bits, mask);
+}
+
+void
+usrp1_source_base::set_verbose (bool verbose)
+{  
+  d_usrp->set_verbose (verbose);
+}
+
+bool
+usrp1_source_base::write_aux_dac (int which_dboard, int which_dac, int value)
+{
+  return d_usrp->write_aux_dac (which_dboard, which_dac, value);
+}
+
+int
+usrp1_source_base::read_aux_adc (int which_dboard, int which_adc)
+{
+  return d_usrp->read_aux_adc (which_dboard, which_adc);
+}
+
+bool
+usrp1_source_base::write_eeprom (int i2c_addr, int eeprom_offset, const std::string buf)
+{
+  return d_usrp->write_eeprom (i2c_addr, eeprom_offset, buf);
+}
+
+std::string
+usrp1_source_base::read_eeprom (int i2c_addr, int eeprom_offset, int len)
+{
+  return d_usrp->read_eeprom (i2c_addr, eeprom_offset, len);
+}
+
+bool
+usrp1_source_base::write_i2c (int i2c_addr, const std::string buf)
+{
+  return d_usrp->write_i2c (i2c_addr, buf);
+}
+
+std::string
+usrp1_source_base::read_i2c (int i2c_addr, int len)
+{
+  return d_usrp->read_i2c (i2c_addr, len);
+}
+
+bool
+usrp1_source_base::set_pga (int which, double gain)
+{
+  return d_usrp->set_pga (which, gain);
+}
+
+double
+usrp1_source_base::pga (int which) const
+{
+  return d_usrp->pga (which);
+}
+
+double
+usrp1_source_base::pga_min () const
+{
+  return d_usrp->pga_min ();
+}
+
+double
+usrp1_source_base::pga_max () const
+{
+  return d_usrp->pga_max ();
+}
+
+double
+usrp1_source_base::pga_db_per_step () const
+{
+  return d_usrp->pga_db_per_step ();
+}
+
+int
+usrp1_source_base::daughterboard_id (int which) const
+{
+  return d_usrp->daughterboard_id (which);
+}
+
+
+bool
+usrp1_source_base::set_adc_offset (int which, int offset)
+{
+  return d_usrp->set_adc_offset (which, offset);
+}
+
+bool
+usrp1_source_base::set_dac_offset (int which, int offset, int offset_pin)
+{
+  return d_usrp->set_dac_offset (which, offset, offset_pin);
+}
+
+bool
+usrp1_source_base::set_adc_buffer_bypass (int which, bool bypass)
+{
+  return d_usrp->set_adc_buffer_bypass (which, bypass);
+}
+
+std::string
+usrp1_source_base::serial_number()
+{
+  return d_usrp->serial_number();
+}
+
+bool
+usrp1_source_base::_write_oe (int which_dboard, int value, int mask)
+{
+  return d_usrp->_write_oe (which_dboard, value, mask);
+}
+
+bool
+usrp1_source_base::write_io (int which_dboard, int value, int mask)
+{
+  return d_usrp->write_io (which_dboard, value, mask);
+}
+
+int
+usrp1_source_base::read_io (int which_dboard)
+{
+  return d_usrp->read_io (which_dboard);
+}
+
+
+
+
+// internal routines...
+
+bool
+usrp1_source_base::_write_fpga_reg (int regno, int value)
+{
+  return d_usrp->_write_fpga_reg (regno, value);
+}
+
+bool
+usrp1_source_base::_write_fpga_reg_masked (int regno, int value, int mask)
+{
+  return d_usrp->_write_fpga_reg_masked (regno, value, mask);
+}
+
+int
+usrp1_source_base::_read_fpga_reg (int regno)
+{
+  return d_usrp->_read_fpga_reg (regno);
+}
+
+bool
+usrp1_source_base::_write_9862 (int which_codec, int regno, unsigned char value)
+{
+  return d_usrp->_write_9862 (which_codec, regno, value);
+}
+
+int
+usrp1_source_base::_read_9862 (int which_codec, int regno) const
+{
+  return d_usrp->_read_9862 (which_codec, regno);
+}
+
+bool
+usrp1_source_base::_write_spi (int optional_header, int enables,
+                              int format, std::string buf)
+{
+  return d_usrp->_write_spi (optional_header, enables, format, buf);
+}
+
+std::string
+usrp1_source_base::_read_spi (int optional_header, int enables, int format, int len)
+{
+  return d_usrp->_read_spi (optional_header, enables, format, len);
+}
+
+bool
+usrp1_source_base::set_format(unsigned int format)
+{
+  return d_usrp->set_format(format);
+}
+
+unsigned int
+usrp1_source_base::format() const
+{
+  return d_usrp->format();
+}
+
+unsigned int
+usrp1_source_base::make_format(int width, int shift, bool want_q, bool bypass_halfband)
+{
+  return usrp_standard_rx::make_format(width, shift, want_q, bypass_halfband);
+}
+
+int
+usrp1_source_base::format_width(unsigned int format)
+{
+  return usrp_standard_rx::format_width(format);
+}
+
+int
+usrp1_source_base::format_shift(unsigned int format)
+{
+  return usrp_standard_rx::format_shift(format);
+}
+
+bool
+usrp1_source_base::format_want_q(unsigned int format)
+{
+  return usrp_standard_rx::format_want_q(format);
+}
+
+bool
+usrp1_source_base::format_bypass_halfband(unsigned int format)
+{
+  return usrp_standard_rx::format_bypass_halfband(format);
+}
diff --git a/gr-usrp/src/usrp1_source_base.h b/gr-usrp/src/usrp1_source_base.h
new file mode 100644 (file)
index 0000000..a04eadf
--- /dev/null
@@ -0,0 +1,455 @@
+/* -*- 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 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.
+ */
+
+#ifndef INCLUDED_USRP1_SOURCE_BASE_H
+#define INCLUDED_USRP1_SOURCE_BASE_H
+
+#include <gr_sync_block.h>
+#include <stdexcept>
+
+class usrp_standard_rx;
+
+/*!
+ * \brief abstract interface to Universal Software Radio Peripheral Rx path (Rev 1)
+ */
+class usrp1_source_base : public gr_sync_block {
+ private:
+  usrp_standard_rx     *d_usrp;
+  int                   d_noverruns;
+  
+ protected:
+  usrp1_source_base (const std::string &name,
+                    gr_io_signature_sptr output_signature,
+                    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
+                    ) throw (std::runtime_error);
+
+  /*!
+   * \brief return number of usrp input bytes required to produce noutput items.
+   */
+  virtual int ninput_bytes_reqd_for_noutput_items (int noutput_items) = 0;
+
+  /*!
+   * \brief number of bytes in a low-level sample
+   */
+  unsigned int sizeof_basic_sample() const;
+
+  /*!
+   * \brief convert between native usrp format and output item format
+   *
+   * \param output_items[out]          stream(s) of output items
+   * \param output_index[in]           starting index in output_items
+   * \param output_items_available[in] number of empty items available at item[index]
+   * \param output_items_produced[out] number of items produced by copy
+   * \param usrp_buffer[in]            source buffer
+   * \param usrp_buffer_length[in]     number of bytes available in \p usrp_buffer
+   * \param bytes_read[out]            number of bytes read from \p usrp_buffer
+   *
+   * The copy must consume all bytes available.  That is, \p bytes_read must equal
+   * \p usrp_buffer_length.
+   */
+  virtual void copy_from_usrp_buffer (gr_vector_void_star &output_items,
+                                     int output_index,
+                                     int output_items_available,
+                                     int &output_items_produced,
+                                     const void *usrp_buffer,
+                                     int usrp_buffer_length,
+                                     int &bytes_read) = 0;
+
+ public:
+  //! magic value used on alternate register read interfaces
+  static const int READ_FAILED = -99999;
+
+  ~usrp1_source_base ();
+
+  int work (int noutput_items,
+           gr_vector_const_void_star &input_items,
+           gr_vector_void_star &output_items);
+
+  bool start();
+  bool stop();
+
+  /*!
+   * \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 ()
+   */
+  bool set_decim_rate (unsigned int rate);
+  bool set_nchannels (int nchan);
+  bool set_mux (int mux);
+
+  /*!
+   * \brief set the center frequency of the digital down converter.
+   *
+   * \p channel must be 0.  \p freq is the center frequency in Hz.
+   * It must be in the range [-FIXME, FIXME].  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 special modes
+   */
+  bool set_fpga_mode (int mode);
+
+  void set_verbose (bool verbose);
+
+  /*!
+   * \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 Set Programmable Gain Amplifier (PGA)
+   *
+   * \param which      which A/D [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 set_pga (int which, double gain_in_db);
+
+  /*!
+   * \brief Return programmable gain amplifier gain setting in dB.
+   *
+   * \param which      which A/D [0,3]
+   */
+  double pga (int which) const;
+
+  /*!
+   * \brief Return minimum legal PGA setting in dB.
+   */
+  double pga_min () const;
+
+  /*!
+   * \brief Return maximum legal PGA setting in dB.
+   */
+  double pga_max () const;
+
+  /*!
+   * \brief Return hardware step size of PGA (linear in dB).
+   */
+  double pga_db_per_step () const;
+
+  // ACCESSORS
+
+  long fpga_master_clock_freq() const;
+  long converter_rate() const;
+  long adc_rate() const { return converter_rate(); }   // alias
+  long adc_freq() const { return converter_rate(); }   // deprecated alias
+
+  unsigned int decim_rate () const;
+  int nchannels () const;
+  int mux () const;
+  double rx_freq (int channel) const;
+  int noverruns () const { return d_noverruns; }
+
+  /*!
+   * \brief Return daughterboard ID for given Rx daughterboard slot [0,1].
+   *
+   * \return daughterboard id >= 0 if successful
+   * \return -1 if no daugherboard
+   * \return -2 if invalid EEPROM on daughterboard
+   */
+  int daughterboard_id (int which_dboard) const;
+
+  /*!
+   * \brief Write auxiliary digital to analog converter.
+   *
+   * \param which_dboard       [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 write_aux_dac (int which_board, int which_dac, int value);
+
+  /*!
+   * \brief Read auxiliary analog to digital converter.
+   *
+   * \param which_dboard       [0,1] which d'board
+   * \param which_adc          [0,1]
+   * \returns value in the range [0,4095] if successful, else READ_FAILED.
+   */
+  int read_aux_adc (int which_dboard, int which_adc);
+
+  /*!
+   * \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 Write 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 of 64 bytes.
+   */
+  std::string read_i2c (int i2c_addr, int len);
+
+  /*!
+   * \brief Set ADC offset correction
+   * \param which      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, int offset);
+
+  /*!
+   * \brief Set DAC offset correction
+   * \param which      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, int offset, int offset_pin);
+
+  /*!
+   * \brief Control ADC input buffer
+   * \param which      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, bool bypass);
+
+  /*!
+   * \brief return the usrp's serial number.
+   *
+   * \returns non-zero length string iff successful.
+   */
+  std::string serial_number();
+
+  /*!
+   * \brief Write direction register (output enables) for pins that go to daughterboard.
+   *
+   * \param which_dboard       [0,1] which d'board
+   * \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 _write_oe (int which_dboard, int value, int mask);
+
+  /*!
+   * \brief Write daughterboard i/o pin value
+   *
+   * \param which_dboard       [0,1] which d'board
+   * \param value              value to write into register
+   * \param mask               which bits of value to write into reg
+   */
+  bool write_io (int which_dboard, int value, int mask);
+
+  /*!
+   * \brief Read daughterboard i/o pin value
+   *
+   * \param which_dboard       [0,1] which d'board
+   * \returns register value if successful, else READ_FAILED
+   */
+  int read_io (int which_dboard);
+
+  /*!
+   * \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 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);
+
+  /*!
+   * \brief return current format
+   */
+  unsigned int format () const;
+
+  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);
+
+  // ----------------------------------------------------------------
+  // internal routines...  
+  // You probably shouldn't be using these...
+  // ----------------------------------------------------------------
+
+  /*!
+   * \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 Write FPGA register masked.
+   * \param regno      7-bit register number
+   * \param value      16-bit value
+   * \param mask               16-bit mask
+   * \returns true iff successful
+   */
+  bool _write_fpga_reg_masked (int regno, int value, int mask);        //< 7-bit regno, 16-bit value, 16-bit mask
+
+  /*!
+   * \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 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
+   * \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);
+};
+
+#endif /* INCLUDED_USRP1_SOURCE_BASE_H */
diff --git a/gr-usrp/src/usrp1_source_c.cc b/gr-usrp/src/usrp1_source_c.cc
new file mode 100644 (file)
index 0000000..e614370
--- /dev/null
@@ -0,0 +1,131 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <usrp1_source_c.h>
+#include <gr_io_signature.h>
+#include <usrp_standard.h>
+#include <usrp_bytesex.h>
+
+static const int NBASIC_SAMPLES_PER_ITEM = 2;  // I & Q
+
+usrp1_source_c_sptr
+usrp1_make_source_c (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
+                    ) throw (std::runtime_error)
+{
+  return usrp1_source_c_sptr (new usrp1_source_c (which_board,
+                                                 decim_rate,
+                                                 nchan,
+                                                 mux,
+                                                 mode,
+                                                 fusb_block_size,
+                                                 fusb_nblocks,
+                                                 fpga_filename,
+                                                 firmware_filename
+                                                 ));
+}
+
+
+usrp1_source_c::usrp1_source_c (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
+                               ) throw (std::runtime_error)
+  : usrp1_source_base ("usrp1_source_c",
+                      gr_make_io_signature (1, 1, sizeof (gr_complex)),
+                      which_board, decim_rate, nchan, mux, mode,
+                      fusb_block_size, fusb_nblocks,
+                      fpga_filename, firmware_filename)
+{
+}
+
+usrp1_source_c::~usrp1_source_c ()
+{
+  // NOP
+}
+
+int
+usrp1_source_c::ninput_bytes_reqd_for_noutput_items (int noutput_items)
+{
+  return noutput_items * NBASIC_SAMPLES_PER_ITEM * sizeof_basic_sample();
+}
+
+/*
+ * Convert interleaved 8 or 16-bit I & Q from usrp buffer into a single
+ * complex output stream.
+ */
+void
+usrp1_source_c::copy_from_usrp_buffer (gr_vector_void_star &output_items,
+                                      int output_index,
+                                      int output_items_available,
+                                      int &output_items_produced,
+                                      const void *usrp_buffer,
+                                      int usrp_buffer_length,
+                                      int &bytes_read)
+{
+  gr_complex *out = &((gr_complex *) output_items[0])[output_index];
+  unsigned sbs = sizeof_basic_sample();
+  unsigned nusrp_bytes_per_item = NBASIC_SAMPLES_PER_ITEM * sbs;
+
+  int nitems = std::min (output_items_available,
+                        (int)(usrp_buffer_length / nusrp_bytes_per_item));
+
+  signed char *s8 = (signed char *) usrp_buffer;
+  short *s16 = (short *) usrp_buffer;
+
+  switch (sbs){
+  case 1:
+    for (int i = 0; i < nitems; i++){
+      out[i] = gr_complex ((float)(s8[2*i+0] << 8), (float)(s8[2*i+1] << 8));
+    }
+    break;
+
+  case 2:
+    for (int i = 0; i < nitems; i++){
+      out[i] = gr_complex ((float) usrp_to_host_short(s16[2*i+0]),
+                          (float) usrp_to_host_short(s16[2*i+1]));
+    }
+    break;
+
+  default:
+    assert(0);
+  }
+
+  output_items_produced = nitems;
+  bytes_read = nitems * nusrp_bytes_per_item;
+}
diff --git a/gr-usrp/src/usrp1_source_c.h b/gr-usrp/src/usrp1_source_c.h
new file mode 100644 (file)
index 0000000..4b87493
--- /dev/null
@@ -0,0 +1,93 @@
+/* -*- 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 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.
+ */
+
+#ifndef INCLUDED_USRP1_SOURCE_C_H
+#define INCLUDED_USRP1_SOURCE_C_H
+
+#include <usrp1_source_base.h>
+#include <stdexcept>
+
+class usrp_standard_rx;
+
+
+class usrp1_source_c;
+typedef boost::shared_ptr<usrp1_source_c> usrp1_source_c_sptr;
+
+
+// public shared_ptr constructor
+
+usrp1_source_c_sptr
+usrp1_make_source_c (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
+                    ) throw (std::runtime_error);
+
+/*!
+ * \brief interface to Universal Software Radio Peripheral Rx path (Rev 1)
+ */
+class usrp1_source_c : public usrp1_source_base {
+ private:
+  friend usrp1_source_c_sptr
+  usrp1_make_source_c (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
+                      ) throw (std::runtime_error);
+
+ protected:
+  usrp1_source_c (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
+                 ) throw (std::runtime_error);
+
+  virtual int ninput_bytes_reqd_for_noutput_items (int noutput_items);
+
+  virtual void copy_from_usrp_buffer (gr_vector_void_star &output_items,
+                                     int output_index,
+                                     int output_items_available,
+                                     int &output_items_produced,
+                                     const void *usrp_buffer,
+                                     int usrp_buffer_length,
+                                     int &bytes_read);
+
+ public:
+  ~usrp1_source_c ();
+};
+
+#endif /* INCLUDED_USRP1_SOURCE_C_H */
diff --git a/gr-usrp/src/usrp1_source_s.cc b/gr-usrp/src/usrp1_source_s.cc
new file mode 100644 (file)
index 0000000..c2c105b
--- /dev/null
@@ -0,0 +1,131 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <usrp1_source_s.h>
+#include <gr_io_signature.h>
+#include <usrp_standard.h>
+#include <usrp_bytesex.h>
+
+static const int NBASIC_SAMPLES_PER_ITEM = 1;
+
+usrp1_source_s_sptr
+usrp1_make_source_s (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
+                    ) throw (std::runtime_error)
+{
+  return usrp1_source_s_sptr (new usrp1_source_s (which_board,
+                                                 decim_rate, 
+                                                 nchan,
+                                                 mux,
+                                                 mode,
+                                                 fusb_block_size,
+                                                 fusb_nblocks,
+                                                 fpga_filename,
+                                                 firmware_filename
+                                                 ));
+}
+
+
+usrp1_source_s::usrp1_source_s (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
+                               ) throw (std::runtime_error)
+  : usrp1_source_base ("usrp1_source_s",
+                      gr_make_io_signature (1, 1, sizeof (short)),
+                      which_board, decim_rate, nchan, mux, mode,
+                      fusb_block_size,
+                      fusb_nblocks,
+                      fpga_filename, firmware_filename)
+{
+}
+
+usrp1_source_s::~usrp1_source_s ()
+{
+  // NOP
+}
+
+int
+usrp1_source_s::ninput_bytes_reqd_for_noutput_items (int noutput_items)
+{
+  return noutput_items * NBASIC_SAMPLES_PER_ITEM * sizeof_basic_sample();
+}
+
+/*
+ * Convert interleaved 8 or 16-bit I & Q from usrp buffer into a single
+ * short output stream.
+ */
+void
+usrp1_source_s::copy_from_usrp_buffer (gr_vector_void_star &output_items,
+                                      int output_index,
+                                      int output_items_available,
+                                      int &output_items_produced,
+                                      const void *usrp_buffer,
+                                      int usrp_buffer_length,
+                                      int &bytes_read)
+{
+  short *out = &((short *) output_items[0])[output_index];
+  unsigned sbs = sizeof_basic_sample();
+  unsigned nusrp_bytes_per_item = NBASIC_SAMPLES_PER_ITEM * sbs;
+
+  int nitems = std::min (output_items_available,
+                        (int)(usrp_buffer_length / nusrp_bytes_per_item));
+
+  signed char *s8 = (signed char *) usrp_buffer;
+  short *s16 = (short *) usrp_buffer;
+
+  switch(sbs){
+  case 1:
+    for (int i = 0; i < nitems; i++){
+      out[i] = s8[i] << 8;
+    }
+    break;
+
+  case 2:
+    for (int i = 0; i < nitems; i++){
+      out[i] = usrp_to_host_short(s16[i]);
+    }
+    break;
+    
+  default:
+    assert(0);
+  }
+
+  output_items_produced = nitems;
+  bytes_read = nitems * nusrp_bytes_per_item;
+}
diff --git a/gr-usrp/src/usrp1_source_s.h b/gr-usrp/src/usrp1_source_s.h
new file mode 100644 (file)
index 0000000..a3a3e74
--- /dev/null
@@ -0,0 +1,94 @@
+/* -*- 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 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.
+ */
+
+#ifndef INCLUDED_USRP1_SOURCE_S_H
+#define INCLUDED_USRP1_SOURCE_S_H
+
+#include <usrp1_source_base.h>
+#include <stdexcept>
+
+class usrp_standard_rx;
+
+
+class usrp1_source_s;
+typedef boost::shared_ptr<usrp1_source_s> usrp1_source_s_sptr;
+
+
+// public shared_ptr constructor
+
+usrp1_source_s_sptr
+usrp1_make_source_s (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
+                    ) throw (std::runtime_error);
+
+/*!
+ * \brief interface to Universal Software Radio Peripheral Rx path (Rev 1)
+ *
+ * output: 1 stream of short
+ */
+class usrp1_source_s : public usrp1_source_base {
+ private:
+  friend usrp1_source_s_sptr
+  usrp1_make_source_s (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
+                      ) throw (std::runtime_error);
+
+ protected:
+  usrp1_source_s (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
+                 ) throw (std::runtime_error);
+
+  virtual int ninput_bytes_reqd_for_noutput_items (int noutput_items);
+
+  virtual void copy_from_usrp_buffer (gr_vector_void_star &output_items,
+                                     int output_index,
+                                     int output_items_available,
+                                     int &output_items_produced,
+                                     const void *usrp_buffer,
+                                     int usrp_buffer_length,
+                                     int &bytes_read);
+ public:
+  ~usrp1_source_s ();
+};
+
+#endif /* INCLUDED_USRP1_SOURCE_S_H */
diff --git a/gr-usrp/src/usrp_multi.py b/gr-usrp/src/usrp_multi.py
new file mode 100644 (file)
index 0000000..865e42f
--- /dev/null
@@ -0,0 +1,233 @@
+#
+# 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 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.
+# 
+
+import math
+from gnuradio import gr, gru
+from gnuradio.gr import hier_block_base
+from gnuradio import usrp
+from gnuradio import usrp1              # usrp Rev 1 and later
+from gnuradio import blks
+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):
+        """
+        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="multi_2rxhb_2tx.rbf" )
+        u0 = usrp.source_s (0, decim, nchan, gru.hexint(mux), mode,fpga_filename="multi_2rxhb_2tx.rbf" )
+        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=0
+            um=u0
+            us_index=1
+            us=u1
+
+        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)
diff --git a/gr-video-sdl/AUTHORS b/gr-video-sdl/AUTHORS
new file mode 100644 (file)
index 0000000..3e57f56
--- /dev/null
@@ -0,0 +1 @@
+Martin Dudok van Heel <nldudok1 at olifantasia.com>
diff --git a/gr-video-sdl/ChangeLog b/gr-video-sdl/ChangeLog
new file mode 100644 (file)
index 0000000..f142ef8
--- /dev/null
@@ -0,0 +1,25 @@
+2006-02-21  Martin Dudok van Heel  <nldudok1 at olifantasia.com>
+        
+        Initial release
+        * src/video_sdl_sink.{h,cc,i}: new.
+
+#
+# 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 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.
+# 
diff --git a/gr-video-sdl/Makefile.am b/gr-video-sdl/Makefile.am
new file mode 100644 (file)
index 0000000..12d751e
--- /dev/null
@@ -0,0 +1,24 @@
+#
+# 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 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.
+# 
+
+include $(top_srcdir)/Makefile.common
+
+SUBDIRS = src
diff --git a/gr-video-sdl/src/Makefile.am b/gr-video-sdl/src/Makefile.am
new file mode 100644 (file)
index 0000000..0a28e0c
--- /dev/null
@@ -0,0 +1,86 @@
+#
+# Copyright 2004,2005,2006 Free Software Foundation, Inc.
+# 
+# This file is part of GNU Radio
+# 
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 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.
+# 
+
+include $(top_srcdir)/Makefile.common
+
+# Install this stuff so that it ends up as the gnuradio.video_sdl module
+# This usually ends up at:
+#   ${prefix}/lib/python${python_version}/site-packages/gnuradio
+
+ourpythondir = $(grpythondir)
+ourlibdir    = $(grpyexecdir)
+
+EXTRA_DIST = run_tests.in
+TESTS = run_tests
+
+LOCAL_IFILES =                                 \
+       video_sdl.i                             
+
+NON_LOCAL_IFILES =                     \
+       $(top_srcdir)/gnuradio-core/src/lib/swig/gnuradio.i
+
+ALL_IFILES =                           \
+       $(LOCAL_IFILES)                 \
+       $(NON_LOCAL_IFILES)             
+
+BUILT_SOURCES =                        \
+       video_sdl.cc                    \
+       video_sdl.py                            
+
+ourpython_PYTHON =                     \
+       video_sdl.py
+
+INCLUDES = $(STD_DEFINES_AND_INCLUDES) $(PYTHON_CPPFLAGS) $(SDL_CFLAGS)
+
+SWIGCPPPYTHONARGS = -fvirtual -python -modern $(PYTHON_CPPFLAGS) $(STD_DEFINES_AND_INCLUDES)
+
+ourlib_LTLIBRARIES = _video_sdl.la
+
+_video_sdl_la_SOURCES =                \
+       video_sdl.cc                    \
+       video_sdl_sink_uc.cc            \
+       video_sdl_sink_s.cc
+
+
+grinclude_HEADERS =                    \
+       video_sdl_sink_uc.h             \
+       video_sdl_sink_s.h
+
+swiginclude_HEADERS =                  \
+       $(LOCAL_IFILES)
+
+_video_sdl_la_LIBADD =                         \
+       $(PYTHON_LDFLAGS)               \
+       $(GNURADIO_CORE_LIBS)           \
+        $(SDL_LIBS)                    \
+       -lstdc++                                
+
+_video_sdl_la_LDFLAGS = $(NO_UNDEFINED) -module -avoid-version
+
+video_sdl.cc video_sdl.py: video_sdl.i
+       $(SWIG) $(SWIGCPPPYTHONARGS) -module video_sdl -o video_sdl.cc $<
+
+
+noinst_PYTHON = qa_video_sdl.py
+
+MOSTLYCLEANFILES = \
+       $(BUILT_SOURCES) *~ *.pyc
+
diff --git a/gr-video-sdl/src/qa_video_sdl.py b/gr-video-sdl/src/qa_video_sdl.py
new file mode 100755 (executable)
index 0000000..905b287
--- /dev/null
@@ -0,0 +1,40 @@
+#!/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 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.
+# 
+
+from gnuradio import gr, gr_unittest
+import video_sdl
+
+class qa_video_sdl (gr_unittest.TestCase):
+
+    def setUp (self):
+        self.fg = gr.flow_graph ()
+
+    def tearDown (self):
+        self.fg = None
+
+    def test_000_nop (self):
+        """Just see if we can import the module...
+        They may not have video drivers, etc.  Don't try to run anything"""
+        pass
+    
+if __name__ == '__main__':
+    gr_unittest.main ()
diff --git a/gr-video-sdl/src/run_tests.in b/gr-video-sdl/src/run_tests.in
new file mode 100644 (file)
index 0000000..2f84c37
--- /dev/null
@@ -0,0 +1,47 @@
+#!/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@/gr-video-sdl/src
+# Where to look in the src tree for swig generated python code
+libsrc=@abs_top_srcdir@/gr-video-sdl/src
+# Where to look in the src tree for hand written python code
+py=@abs_top_srcdir@/gr-video-sdl/src
+
+# Where to look for GNU Radio python modules in current build tree
+# FIXME this is wrong on a distcheck.  We really need to ask gnuradio-core
+# where it put its python files.
+grpythonbld=@abs_top_builddir@/gnuradio-core/src/python/:@abs_top_builddir@/gnuradio-core/src/lib/swig/:@abs_top_builddir@/gnuradio-core/src/lib/swig/.libs
+
+PYTHONPATH="$grpythonbld:$libbld:$libbld/.libs:$libsrc:$py:$PYTHONPATH"
+export PYTHONPATH
+
+#
+# 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-video-sdl/src/video_sdl.i b/gr-video-sdl/src/video_sdl.i
new file mode 100644 (file)
index 0000000..e70d123
--- /dev/null
@@ -0,0 +1,67 @@
+/* -*- 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 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.
+ */
+
+%feature("autodoc","1");
+
+%include "exception.i"
+%import "gnuradio.i"                           // the common stuff
+
+%{
+#include "gnuradio_swig_bug_workaround.h"      // mandatory bug fix
+#include "video_sdl_sink_uc.h"
+#include "video_sdl_sink_s.h"
+#include <stdexcept>
+%}
+
+// ----------------------------------------------------------------
+
+GR_SWIG_BLOCK_MAGIC(video_sdl,sink_uc)
+
+video_sdl_sink_uc_sptr
+video_sdl_make_sink_uc ( double framerate,int width=640, int height=480,unsigned int format=0,int dst_width=-1,int dst_height=-1
+                    ) throw (std::runtime_error);
+
+
+class video_sdl_sink_uc : public gr_sync_block {
+ protected:
+  video_sdl_sink_uc (double framerate,int width, int height,gr_uint32 format,int dst_width,int dst_height);
+
+ public:
+  ~video_sdl_sink_uc ();
+};
+
+// ----------------------------------------------------------------
+
+GR_SWIG_BLOCK_MAGIC(video_sdl,sink_s)
+
+video_sdl_sink_s_sptr
+video_sdl_make_sink_s ( double framerate,int width=640, int height=480,unsigned int format=0,int dst_width=-1,int dst_height=-1
+                    ) throw (std::runtime_error);
+
+
+class video_sdl_sink_s : public gr_sync_block {
+ protected:
+  video_sdl_sink_s (double framerate,int width, int height,gr_uint32 format,int dst_width,int dst_height);
+
+ public:
+  ~video_sdl_sink_s ();
+};
diff --git a/gr-video-sdl/src/video_sdl_sink_s.cc b/gr-video-sdl/src/video_sdl_sink_s.cc
new file mode 100644 (file)
index 0000000..50e730d
--- /dev/null
@@ -0,0 +1,301 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <SDL.h>
+
+#include <video_sdl_sink_s.h>
+#include <gr_io_signature.h>
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <iostream>
+#include <stdexcept>
+
+
+
+video_sdl_sink_s::video_sdl_sink_s (double framerate,int width, int height,unsigned int format,int dst_width,int dst_height)
+  : gr_sync_block ("video_sdl_sink_s",
+                  gr_make_io_signature (1, 3, sizeof (short)),
+                  gr_make_io_signature (0, 0, 0)),
+    d_chunk_size (width*height),
+    d_framerate(framerate),
+    d_wanted_frametime_ms(0),
+    d_width(width),
+    d_height (height),
+    d_dst_width(dst_width),
+    d_dst_height(dst_height),
+    d_format(format), 
+    d_current_line(0),
+    d_screen(NULL),
+    d_image(NULL),
+    d_avg_delay(0.0),
+    d_wanted_ticks(0)
+{
+  if(framerate<=0.0) 
+    d_wanted_frametime_ms=0;//Go as fast as possible
+  else
+    d_wanted_frametime_ms=(int)(1000.0/framerate);
+  if(dst_width<0) d_dst_width=d_width;
+  if(dst_height<0) d_dst_height=d_height;
+  if(0==format) d_format=IMGFMT_YV12;
+  
+  atexit(SDL_Quit);//check if this is the way to do this
+  if ( SDL_Init(SDL_INIT_VIDEO) < 0 ) {
+    std::cerr << "video_sdl_sink_s: Couldn't initialize SDL:" << SDL_GetError() << " \n SDL_Init(SDL_INIT_VIDEO) failed\n";
+    throw std::runtime_error ("video_sdl_sink_s");
+  };
+
+  /* accept any depth */
+  d_screen = SDL_SetVideoMode(dst_width, dst_height, 0, SDL_SWSURFACE|SDL_RESIZABLE|SDL_ANYFORMAT);//SDL_DOUBLEBUF |SDL_SWSURFACE| SDL_HWSURFACE||SDL_FULLSCREEN
+  if ( d_screen == NULL ) {
+    std::cerr << "Unable to set SDL video mode: " << SDL_GetError() <<"\n SDL_SetVideoMode() Failed \n";
+    exit(1);
+  }
+  if ( d_image ) {
+      SDL_FreeYUVOverlay(d_image);
+    }
+  /* Initialize and create the YUV Overlay used for video out */
+  if (!(d_image = SDL_CreateYUVOverlay (d_width, d_height, SDL_YV12_OVERLAY, d_screen))) {
+    std::cerr << "SDL: Couldn't create a YUV overlay: \n"<< SDL_GetError() <<"\n";
+    throw std::runtime_error ("video_sdl_sink_s");
+  }
+
+  printf("SDL screen_mode %d bits-per-pixel\n",
+        d_screen->format->BitsPerPixel);
+  printf("SDL overlay_mode %i \n",
+        d_image->format);
+  d_chunk_size = std::min(1,16384/width); //width*16;
+  d_chunk_size = d_chunk_size*width;
+  //d_chunk_size = (int) (width);
+  set_output_multiple (d_chunk_size);
+  /* Set the default playback area */
+  d_dst_rect.x = 0;
+  d_dst_rect.y = 0;
+  d_dst_rect.w = d_dst_width;
+  d_dst_rect.h = d_dst_height;
+  //clear the surface to grey
+  if ( SDL_LockYUVOverlay( d_image ) ) {
+    std::cerr << "SDL: Couldn't lock YUV overlay: \n"<< SDL_GetError() <<"\n";
+    throw std::runtime_error ("video_sdl_sink_s");
+  }
+  memset(d_image->pixels[0], 128, d_image->pitches[0]*d_height);  
+  memset(d_image->pixels[1], 128, d_image->pitches[1]*d_height/2);  
+  memset(d_image->pixels[2], 128, d_image->pitches[2]*d_height/2);  
+  SDL_UnlockYUVOverlay( d_image );
+}
+
+video_sdl_sink_s::~video_sdl_sink_s ()
+{
+  SDL_Quit();
+}
+
+video_sdl_sink_s_sptr
+video_sdl_make_sink_s (double framerate,int width, int height,unsigned int format,int dst_width,int dst_height)
+{
+  return video_sdl_sink_s_sptr (new video_sdl_sink_s (framerate, width, height,format,dst_width,dst_height));
+}
+
+void
+video_sdl_sink_s::copy_line_pixel_interleaved(unsigned char *dst_pixels_u,unsigned char *dst_pixels_v,const short * src_pixels,int src_width)
+{
+  for(int i=0;i<src_width;i++)
+  {
+    dst_pixels_u[i]=(unsigned char)src_pixels[i*2];
+    dst_pixels_v[i]=(unsigned char)src_pixels[i*2+1];
+  }
+  return;
+}
+
+void
+video_sdl_sink_s::copy_line_line_interleaved(unsigned char *dst_pixels_u,unsigned char *dst_pixels_v,const short * src_pixels,int src_width)
+{
+  for(int i=0;i<src_width;i++)
+  {
+    dst_pixels_u[i]=(unsigned char)src_pixels[i];
+    dst_pixels_v[i]=(unsigned char)src_pixels[i+src_width];
+  }
+  for(int i=src_width;i<src_width*2;i++)
+  {
+    dst_pixels_v[i]=(unsigned char)src_pixels[i];
+  }
+  return;
+}
+void
+video_sdl_sink_s::copy_line_single_plane(unsigned char *dst_pixels,const short * src_pixels,int src_width)
+{
+  for(int i=0;i<src_width;i++)
+  {
+    dst_pixels[i]=(unsigned char)src_pixels[i];
+  }
+  return;
+}
+
+void
+video_sdl_sink_s::copy_line_single_plane_dec2(unsigned char *dst_pixels,const short * src_pixels,int src_width)
+{
+  for(int i=0,j=0;i<src_width;i+=2,j++)
+  {
+    dst_pixels[j]=(unsigned char)src_pixels[i];
+  }
+  return;
+}
+
+int
+video_sdl_sink_s::copy_plane_to_surface (int plane,int noutput_items,
+                     const short * src_pixels)
+{
+    const int first_dst_plane=(12==plane ||1122==plane)?1:plane;
+    const int second_dst_plane=(12==plane ||1122==plane)?2:plane;
+    int current_line=(0==plane)?d_current_line:d_current_line/2;
+    unsigned char * dst_pixels = (unsigned char *)d_image->pixels[first_dst_plane];
+    dst_pixels=&dst_pixels[current_line*d_image->pitches[first_dst_plane]];
+    unsigned char * dst_pixels_2 = (unsigned char *)d_image->pixels[second_dst_plane];
+    dst_pixels_2=&dst_pixels_2[current_line*d_image->pitches[second_dst_plane]];
+    int src_width=(0==plane || 12==plane || 1122==plane)?d_width:d_width/2;
+    int noutput_items_produced=0;
+    int max_height=(0==plane)?d_height-1:d_height/2-1;
+    for (int i = 0; i < noutput_items; i += src_width){
+        //output one line at a time
+        if(12==plane)
+        {
+          copy_line_pixel_interleaved(dst_pixels,dst_pixels_2,src_pixels,src_width);
+          dst_pixels_2 += d_image->pitches[second_dst_plane];
+        }
+        else if (1122==plane)
+          {
+            copy_line_line_interleaved(dst_pixels,dst_pixels_2,src_pixels,src_width);
+            dst_pixels_2 += d_image->pitches[second_dst_plane];
+            src_pixels += src_width;
+          }
+        else if (0==plane)
+          copy_line_single_plane(dst_pixels,src_pixels,src_width);
+        else /* 1==plane || 2==plane*/
+          copy_line_single_plane_dec2(dst_pixels,src_pixels,src_width);//decimate by two horizontally
+
+        src_pixels += src_width;
+        dst_pixels += d_image->pitches[first_dst_plane];
+        noutput_items_produced+=src_width;
+        current_line++;
+        if (current_line>max_height)
+        {
+          //Start new frame
+          //TODO, do this all in a seperate thread
+          current_line=0;
+          dst_pixels=d_image->pixels[first_dst_plane];
+          dst_pixels_2=d_image->pixels[second_dst_plane];
+          if(0==plane)
+          {
+            SDL_DisplayYUVOverlay(d_image, &d_dst_rect);
+            //SDL_Flip(d_screen);
+            unsigned int ticks=SDL_GetTicks();//milliseconds
+            d_wanted_ticks+=d_wanted_frametime_ms;
+            float avg_alpha=0.1;
+            int time_diff=d_wanted_ticks-ticks;
+            d_avg_delay=time_diff*avg_alpha +d_avg_delay*(1.0-avg_alpha);
+          }
+        }
+      }
+    if(0==plane) d_current_line=current_line;
+  return noutput_items_produced;
+}
+
+int
+video_sdl_sink_s::work (int noutput_items,
+                     gr_vector_const_void_star &input_items,
+                     gr_vector_void_star &output_items)
+{
+  short *src_pixels_0,*src_pixels_1,*src_pixels_2;
+  int noutput_items_produced=0;
+  int plane;
+  int delay=(int)d_avg_delay;
+  if(0==d_wanted_ticks)
+    d_wanted_ticks=SDL_GetTicks();
+  if(delay>0)
+    SDL_Delay((unsigned int)delay);//compensate if running too fast
+
+  if ( SDL_LockYUVOverlay( d_image ) ) {
+    return 0;
+  } 
+  switch (input_items.size ()){
+  case 3:              // first channel=Y, second channel is  U , third channel is V
+    src_pixels_0 = (short *) input_items[0];
+    src_pixels_1 = (short *) input_items[1];
+    src_pixels_2 = (short *) input_items[2];
+    for (int i = 0; i < noutput_items; i += d_chunk_size){
+      copy_plane_to_surface (1,d_chunk_size, src_pixels_1);
+      copy_plane_to_surface (2,d_chunk_size, src_pixels_2);
+      noutput_items_produced+=copy_plane_to_surface (0,d_chunk_size, src_pixels_0);
+      src_pixels_0 += d_chunk_size;
+      src_pixels_1 += d_chunk_size;
+      src_pixels_2 += d_chunk_size;      
+    }
+    break;
+  case 2:
+    if(1) //if(pixel_interleaved_uv)
+    {
+      // first channel=Y, second channel is alternating pixels U and V
+      src_pixels_0 = (short *) input_items[0];
+      src_pixels_1 = (short *) input_items[1];
+      for (int i = 0; i < noutput_items; i += d_chunk_size){
+        copy_plane_to_surface (12,d_chunk_size/2, src_pixels_1);
+        noutput_items_produced+=copy_plane_to_surface (0,d_chunk_size, src_pixels_0);
+        src_pixels_0 += d_chunk_size;
+        src_pixels_1 += d_chunk_size;     
+      }
+    } else
+    {
+      // first channel=Y, second channel is alternating lines U and V
+      src_pixels_0 = (short *) input_items[0];
+      src_pixels_1 = (short *) input_items[1];
+      for (int i = 0; i < noutput_items; i += d_chunk_size){
+        copy_plane_to_surface (1222,d_chunk_size/2, src_pixels_1);
+        noutput_items_produced+=copy_plane_to_surface (0,d_chunk_size, src_pixels_0);
+        src_pixels_0 += d_chunk_size;
+        src_pixels_1 += d_chunk_size;     
+      }
+    }
+    break;
+  case 1:              // grey (Y) input
+    /* Y component */
+    plane=0;
+    src_pixels_0 = (short *) input_items[plane];
+    for (int i = 0; i < noutput_items; i += d_chunk_size){
+      noutput_items_produced+=copy_plane_to_surface (plane,d_chunk_size, src_pixels_0);
+      src_pixels_0 += d_chunk_size;
+    }
+    break;
+  default: //0 or more then 3 channels
+     std::cerr << "video_sdl_sink_s: Wrong number of channels: ";
+     std::cerr <<"1, 2 or 3 channels are supported.\n  Requested number of channels is "<< input_items.size () <<"\n";
+    throw std::runtime_error ("video_sdl_sink_s");
+  }
+
+  SDL_UnlockYUVOverlay( d_image );
+  return noutput_items_produced;
+}
diff --git a/gr-video-sdl/src/video_sdl_sink_s.h b/gr-video-sdl/src/video_sdl_sink_s.h
new file mode 100644 (file)
index 0000000..662c52b
--- /dev/null
@@ -0,0 +1,90 @@
+/* -*- 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 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.
+ */
+
+#ifndef INCLUDED_VIDEO_SDL_SINK_S_H
+#define INCLUDED_VIDEO_SDL_SINK_S_H
+
+#include <gr_sync_block.h>
+#include <string>
+#include <SDL.h>
+
+/*  fourcc (four character code) */
+#define vid_fourcc(a,b,c,d) (((unsigned)(a)<<0) | ((unsigned)(b)<<8) | ((unsigned)(c)<<16) | ((unsigned)(d)<<24))
+#define IMGFMT_YV12  vid_fourcc('Y','V','1','2') /* 12  YVU 4:2:0 */
+
+class video_sdl_sink_s;
+typedef boost::shared_ptr<video_sdl_sink_s> video_sdl_sink_s_sptr;
+
+video_sdl_sink_s_sptr
+video_sdl_make_sink_s (double framerate,int width=640, int height=480,unsigned int format=IMGFMT_YV12,int dst_width=-1,int dst_height=-1);
+
+/*!
+ * \brief video sink using SDL
+ *
+ * input signature is one, two or three streams of signed short.
+ * One stream: stream is grey (Y)
+ * two streems: first is grey (Y), second is alternating U and V
+ * Three streams: first is grey (Y), second is U, third is V
+ * Input samples must be in the range [0,255].
+ */
+
+class video_sdl_sink_s : public gr_sync_block {
+  friend video_sdl_sink_s_sptr
+  video_sdl_make_sink_s (double framerate,int width, int height,unsigned int format,int dst_width,int dst_height);
+
+  int          d_chunk_size;
+
+ protected:
+  video_sdl_sink_s (double framerate,int width, int height,unsigned int format,
+                      int dst_width,int dst_height);
+  void copy_line_pixel_interleaved(unsigned char *dst_pixels_u,unsigned char *dst_pixels_v,
+                          const short * src_pixels,int src_width);
+  void copy_line_line_interleaved(unsigned char *dst_pixels_u,unsigned char *dst_pixels_v,
+                          const short * src_pixels,int src_width);
+  void copy_line_single_plane(unsigned char *dst_pixels,const short * src_pixels,int src_width);
+  void copy_line_single_plane_dec2(unsigned char *dst_pixels,const short * src_pixels,int src_width);
+  int copy_plane_to_surface (int plane,int noutput_items,
+                     const short * src_pixels);
+  float d_framerate;
+  int d_wanted_frametime_ms;
+  int d_width;
+  int d_height;
+  int d_dst_width;
+  int d_dst_height;
+  int d_format;
+  int d_current_line;
+  SDL_Surface *d_screen;
+  SDL_Overlay *d_image;
+  SDL_Rect d_dst_rect;
+  float d_avg_delay;
+  unsigned int d_wanted_ticks;
+
+
+ public:
+  ~video_sdl_sink_s ();
+  
+  int work (int noutput_items,
+                 gr_vector_const_void_star &input_items,
+                 gr_vector_void_star &output_items);
+};
+
+#endif /* INCLUDED_VIDEO_SDL_SINK_S_H */
diff --git a/gr-video-sdl/src/video_sdl_sink_uc.cc b/gr-video-sdl/src/video_sdl_sink_uc.cc
new file mode 100644 (file)
index 0000000..1462d72
--- /dev/null
@@ -0,0 +1,291 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <SDL.h>
+
+#include <video_sdl_sink_uc.h>
+#include <gr_io_signature.h>
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <iostream>
+#include <stdexcept>
+
+
+
+video_sdl_sink_uc::video_sdl_sink_uc (double framerate,int width, int height,unsigned int format,int dst_width,int dst_height)
+  : gr_sync_block ("video_sdl_sink_uc",
+                  gr_make_io_signature (1, 3, sizeof (unsigned char)),
+                  gr_make_io_signature (0, 0, 0)),
+    d_chunk_size (width*height),
+    d_framerate(framerate),
+    d_wanted_frametime_ms(0),
+    d_width(width),
+    d_height (height),
+    d_dst_width(dst_width),
+    d_dst_height(dst_height),
+    d_format(format), 
+    d_current_line(0),
+    d_screen(NULL),
+    d_image(NULL),
+    d_avg_delay(0.0),
+    d_wanted_ticks(0)
+{
+  if(framerate<=0.0) 
+    d_wanted_frametime_ms=0;//Go as fast as possible
+  else
+    d_wanted_frametime_ms=(int)(1000.0/framerate);
+  if(dst_width<0) d_dst_width=d_width;
+  if(dst_height<0) d_dst_height=d_height;
+  if(0==format) d_format=IMGFMT_YV12;
+  
+  atexit(SDL_Quit);//check if this is the way to do this
+  if ( SDL_Init(SDL_INIT_VIDEO) < 0 ) {
+    std::cerr << "video_sdl_sink_uc: Couldn't initialize SDL:" << SDL_GetError() << " \n SDL_Init(SDL_INIT_VIDEO) failed\n";
+    throw std::runtime_error ("video_sdl_sink_uc");
+  };
+
+  /* accept any depth */
+  d_screen = SDL_SetVideoMode(dst_width, dst_height, 0, SDL_SWSURFACE|SDL_RESIZABLE|SDL_ANYFORMAT);//SDL_DOUBLEBUF |SDL_SWSURFACE| SDL_HWSURFACE||SDL_FULLSCREEN
+  if ( d_screen == NULL ) {
+    std::cerr << "Unable to set SDL video mode: " << SDL_GetError() <<"\n SDL_SetVideoMode() Failed \n";
+    exit(1);
+  }
+  if ( d_image ) {
+      SDL_FreeYUVOverlay(d_image);
+    }
+  /* Initialize and create the YUV Overlay used for video out */
+  if (!(d_image = SDL_CreateYUVOverlay (d_width, d_height, SDL_YV12_OVERLAY, d_screen))) {
+    std::cerr << "SDL: Couldn't create a YUV overlay: \n"<< SDL_GetError() <<"\n";
+    throw std::runtime_error ("video_sdl_sink_uc");
+  }
+
+  printf("SDL screen_mode %d bits-per-pixel\n",
+        d_screen->format->BitsPerPixel);
+  printf("SDL overlay_mode %i \n",
+        d_image->format);
+  d_chunk_size = std::min(1,16384/width); //width*16;
+  d_chunk_size = d_chunk_size*width;
+  //d_chunk_size = (int) (width);
+  set_output_multiple (d_chunk_size);
+  /* Set the default playback area */
+  d_dst_rect.x = 0;
+  d_dst_rect.y = 0;
+  d_dst_rect.w = d_dst_width;
+  d_dst_rect.h = d_dst_height;
+  //clear the surface to grey
+  if ( SDL_LockYUVOverlay( d_image ) ) {
+    std::cerr << "SDL: Couldn't lock YUV overlay: \n"<< SDL_GetError() <<"\n";
+    throw std::runtime_error ("video_sdl_sink_uc");
+  }
+  memset(d_image->pixels[0], 128, d_image->pitches[0]*d_height);  
+  memset(d_image->pixels[1], 128, d_image->pitches[1]*d_height/2);  
+  memset(d_image->pixels[2], 128, d_image->pitches[2]*d_height/2);  
+  SDL_UnlockYUVOverlay( d_image );
+}
+
+video_sdl_sink_uc::~video_sdl_sink_uc ()
+{
+  SDL_Quit();
+}
+
+video_sdl_sink_uc_sptr
+video_sdl_make_sink_uc (double framerate,int width, int height,unsigned int format,int dst_width,int dst_height)
+{
+  return video_sdl_sink_uc_sptr (new video_sdl_sink_uc (framerate, width, height,format,dst_width,dst_height));
+}
+
+void
+video_sdl_sink_uc::copy_line_pixel_interleaved(unsigned char *dst_pixels_u,unsigned char *dst_pixels_v,const unsigned char * src_pixels,int src_width)
+{
+  for(int i=0;i<src_width;i++)
+  {
+    dst_pixels_u[i]=src_pixels[i*2];
+    dst_pixels_v[i]=src_pixels[i*2+1];
+  }
+  return;
+}
+
+void
+video_sdl_sink_uc::copy_line_line_interleaved(unsigned char *dst_pixels_u,unsigned char *dst_pixels_v,const unsigned char * src_pixels,int src_width)
+{
+  memcpy(dst_pixels_u, src_pixels, src_width); 
+  memcpy(dst_pixels_v, src_pixels+src_width, src_width); 
+  return;
+}
+
+void
+video_sdl_sink_uc::copy_line_single_plane(unsigned char *dst_pixels,const unsigned char * src_pixels,int src_width)
+{
+  memcpy(dst_pixels, src_pixels, src_width); 
+  return;
+}
+
+void
+video_sdl_sink_uc::copy_line_single_plane_dec2(unsigned char *dst_pixels,const unsigned char * src_pixels,int src_width)
+{
+  for(int i=0,j=0;i<src_width;i+=2,j++)
+  {
+    dst_pixels[j]=(unsigned char)src_pixels[i];
+  }
+  return;
+}
+
+int
+video_sdl_sink_uc::copy_plane_to_surface (int plane,int noutput_items,
+                     const unsigned char * src_pixels)
+{
+    const int first_dst_plane=(12==plane ||1122==plane)?1:plane;
+    const int second_dst_plane=(12==plane ||1122==plane)?2:plane;
+    int current_line=(0==plane)?d_current_line:d_current_line/2;
+    unsigned char * dst_pixels = (unsigned char *)d_image->pixels[first_dst_plane];
+    dst_pixels=&dst_pixels[current_line*d_image->pitches[first_dst_plane]];
+    unsigned char * dst_pixels_2 = (unsigned char *)d_image->pixels[second_dst_plane];
+    dst_pixels_2=&dst_pixels_2[current_line*d_image->pitches[second_dst_plane]];
+    int src_width=(0==plane || 12==plane || 1122==plane)?d_width:d_width/2;
+    int noutput_items_produced=0;
+    int max_height=(0==plane)?d_height-1:d_height/2-1;
+    for (int i = 0; i < noutput_items; i += src_width){
+        //output one line at a time
+        if(12==plane)
+        {
+          copy_line_pixel_interleaved(dst_pixels,dst_pixels_2,src_pixels,src_width);
+          dst_pixels_2 += d_image->pitches[second_dst_plane];
+        }
+        else if (1122==plane)
+          {
+            copy_line_line_interleaved(dst_pixels,dst_pixels_2,src_pixels,src_width);
+            dst_pixels_2 += d_image->pitches[second_dst_plane];
+            src_pixels += src_width;
+          }
+        else if (0==plane)
+          copy_line_single_plane(dst_pixels,src_pixels,src_width);
+        else /* 1==plane || 2==plane*/
+          copy_line_single_plane_dec2(dst_pixels,src_pixels,src_width);//decimate by two horizontally
+        src_pixels += src_width;
+        dst_pixels += d_image->pitches[first_dst_plane];
+        noutput_items_produced+=src_width;
+        current_line++;
+        if (current_line>max_height)
+        {
+          //Start new frame
+          //TODO, do this all in a seperate thread
+          current_line=0;
+          dst_pixels=d_image->pixels[first_dst_plane];
+          dst_pixels_2=d_image->pixels[second_dst_plane];
+          if(0==plane)
+          {
+            SDL_DisplayYUVOverlay(d_image, &d_dst_rect);
+            //SDL_Flip(d_screen);
+            unsigned int ticks=SDL_GetTicks();//milliseconds
+            d_wanted_ticks+=d_wanted_frametime_ms;
+            float avg_alpha=0.1;
+            int time_diff=d_wanted_ticks-ticks;
+            d_avg_delay=time_diff*avg_alpha +d_avg_delay*(1.0-avg_alpha);
+          }
+        }
+      }
+    if(0==plane) d_current_line=current_line;
+  return noutput_items_produced;
+}
+
+int
+video_sdl_sink_uc::work (int noutput_items,
+                     gr_vector_const_void_star &input_items,
+                     gr_vector_void_star &output_items)
+{
+  unsigned char *src_pixels_0,*src_pixels_1,*src_pixels_2;
+  int noutput_items_produced=0;
+  int plane;
+  int delay=(int)d_avg_delay;
+  if(0==d_wanted_ticks)
+    d_wanted_ticks=SDL_GetTicks();
+  if(delay>0)
+    SDL_Delay((unsigned int)delay);//compensate if running too fast
+
+  if ( SDL_LockYUVOverlay( d_image ) ) {
+    return 0;
+  } 
+  switch (input_items.size ()){
+  case 3:              // first channel=Y, second channel is  U , third channel is V
+    src_pixels_0 = (unsigned char *) input_items[0];
+    src_pixels_1 = (unsigned char *) input_items[1];
+    src_pixels_2 = (unsigned char *) input_items[2];
+    for (int i = 0; i < noutput_items; i += d_chunk_size){
+      copy_plane_to_surface (1,d_chunk_size, src_pixels_1);
+      copy_plane_to_surface (2,d_chunk_size, src_pixels_2);
+      noutput_items_produced+=copy_plane_to_surface (0,d_chunk_size, src_pixels_0);
+      src_pixels_0 += d_chunk_size;
+      src_pixels_1 += d_chunk_size;
+      src_pixels_2 += d_chunk_size;      
+    }
+    break;
+  case 2:
+    if(1) //if(pixel_interleaved_uv)
+    {
+      // first channel=Y, second channel is alternating pixels U and V
+      src_pixels_0 = (unsigned char *) input_items[0];
+      src_pixels_1 = (unsigned char *) input_items[1];
+      for (int i = 0; i < noutput_items; i += d_chunk_size){
+        copy_plane_to_surface (12,d_chunk_size/2, src_pixels_1);
+        noutput_items_produced+=copy_plane_to_surface (0,d_chunk_size, src_pixels_0);
+        src_pixels_0 += d_chunk_size;
+        src_pixels_1 += d_chunk_size;     
+      }
+    } else
+    {
+      // first channel=Y, second channel is alternating lines U and V
+      src_pixels_0 = (unsigned char *) input_items[0];
+      src_pixels_1 = (unsigned char *) input_items[1];
+      for (int i = 0; i < noutput_items; i += d_chunk_size){
+        copy_plane_to_surface (1222,d_chunk_size/2, src_pixels_1);
+        noutput_items_produced+=copy_plane_to_surface (0,d_chunk_size, src_pixels_0);
+        src_pixels_0 += d_chunk_size;
+        src_pixels_1 += d_chunk_size;     
+      }
+    }
+    break;
+  case 1:              // grey (Y) input
+    /* Y component */
+    plane=0;
+    src_pixels_0 = (unsigned char *) input_items[plane];
+    for (int i = 0; i < noutput_items; i += d_chunk_size){
+      noutput_items_produced+=copy_plane_to_surface (plane,d_chunk_size, src_pixels_0);
+      src_pixels_0 += d_chunk_size;
+    }
+    break;
+  default: //0 or more then 3 channels
+     std::cerr << "video_sdl_sink_uc: Wrong number of channels: ";
+     std::cerr <<"1, 2 or 3 channels are supported.\n  Requested number of channels is "<< input_items.size () <<"\n";
+    throw std::runtime_error ("video_sdl_sink_uc");
+  }
+
+  SDL_UnlockYUVOverlay( d_image );
+  return noutput_items_produced;
+}
diff --git a/gr-video-sdl/src/video_sdl_sink_uc.h b/gr-video-sdl/src/video_sdl_sink_uc.h
new file mode 100644 (file)
index 0000000..3f380f3
--- /dev/null
@@ -0,0 +1,90 @@
+/* -*- 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 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.
+ */
+
+#ifndef INCLUDED_VIDEO_SDL_SINK_UC_H
+#define INCLUDED_VIDEO_SDL_SINK_UC_H
+
+#include <gr_sync_block.h>
+#include <string>
+#include <SDL.h>
+
+/*  fourcc (four character code) */
+#define vid_fourcc(a,b,c,d) (((unsigned)(a)<<0) | ((unsigned)(b)<<8) | ((unsigned)(c)<<16) | ((unsigned)(d)<<24))
+#define IMGFMT_YV12  vid_fourcc('Y','V','1','2') /* 12  YVU 4:2:0 */
+
+class video_sdl_sink_uc;
+typedef boost::shared_ptr<video_sdl_sink_uc> video_sdl_sink_uc_sptr;
+
+video_sdl_sink_uc_sptr
+video_sdl_make_sink_uc (double framerate,int width=640, int height=480,unsigned int format=IMGFMT_YV12,int dst_width=-1,int dst_height=-1);
+
+/*!
+ * \brief video sink using SDL
+ *
+ * input signature is one, two or three streams of uchar.
+ * One stream: stream is grey (Y)
+ * two streems: first is grey (Y), second is alternating U and V
+ * Three streams: first is grey (Y), second is U, third is V
+ * Input samples must be in the range [0,255].
+ */
+
+class video_sdl_sink_uc : public gr_sync_block {
+  friend video_sdl_sink_uc_sptr
+  video_sdl_make_sink_uc (double framerate,int width, int height,unsigned int format,int dst_width,int dst_height);
+
+  int          d_chunk_size;
+
+ protected:
+  video_sdl_sink_uc (double framerate,int width, int height,unsigned int format,
+                      int dst_width,int dst_height);
+  void copy_line_pixel_interleaved(unsigned char *dst_pixels_u,unsigned char *dst_pixels_v,
+                          const unsigned char * src_pixels,int src_width);
+  void copy_line_line_interleaved(unsigned char *dst_pixels_u,unsigned char *dst_pixels_v,
+                          const unsigned char * src_pixels,int src_width);
+  void copy_line_single_plane(unsigned char *dst_pixels,const unsigned char * src_pixels,int src_width);
+  void copy_line_single_plane_dec2(unsigned char *dst_pixels,const unsigned char * src_pixels,int src_width);
+  int copy_plane_to_surface (int plane,int noutput_items,
+                     const unsigned char * src_pixels);
+  float d_framerate;
+  int d_wanted_frametime_ms;
+  int d_width;
+  int d_height;
+  int d_dst_width;
+  int d_dst_height;
+  int d_format;
+  int d_current_line;
+  SDL_Surface *d_screen;
+  SDL_Overlay *d_image;
+  SDL_Rect d_dst_rect;
+  float d_avg_delay;
+  unsigned int d_wanted_ticks;
+
+
+ public:
+  ~video_sdl_sink_uc ();
+  
+  int work (int noutput_items,
+                 gr_vector_const_void_star &input_items,
+                 gr_vector_void_star &output_items);
+};
+
+#endif /* INCLUDED_VIDEO_SDL_SINK_UC_H */
diff --git a/gr-wxgui/ChangeLog b/gr-wxgui/ChangeLog
new file mode 100644 (file)
index 0000000..ed4e5ad
--- /dev/null
@@ -0,0 +1,171 @@
+2006-07-24  Eric Blossom  <eb@comsec.com>
+
+       * src/python/powermate.py (powermate._open_device): added additional
+       name for ID_SHUTTLE_XPRESS per Kwan Hong Lee <kwan@media.mit.edu>
+
+2006-06-15  Eric Blossom  <eb@comsec.com>
+
+       * src/python/fftsink.py, src/python/waterfallsink.py,
+       src/python/scopesink.py: added set_sample_rate method.
+
+2006-04-02  Eric Blossom  <eb@comsec.com>
+
+       * src/python/fftsink.py (default_fft_rate): query prefs for default.
+       * src/python/waterfallsink.py (default_fft_rate): query prefs for default.
+       * src/python/scopesink (default_frame_decim): query prefs for default.
+       
+2006-03-29  Eric Blossom  <eb@comsec.com>
+
+       * src/python/fftsink.py: updated to use renamed stream_to_vector
+       instead of serial_to_parallel.  Updated ref_level and y_per_div in
+       builtin test case.
+
+2006-02-02  Eric Blossom  <eb@comsec.com>
+
+       * src/python/scopesink.py: now supports manual as well as
+       autoscaling of the y-axis.  Thank to Jon Jacky.
+
+2005-12-08  Eric Blossom  <eb@comsec.com>
+
+       * src/python/stdgui.py (stdapp.__init__): added redirect=False arg
+       to wx.App.__init__ for Mac users.  Thanks to Jon Jacky.
+
+2005-11-15  Eric Blossom  <eb@comsec.com>
+
+       * src/python/fftsink.py, src/python/scopesink.py: refactored to
+       use messages and message queues instead of pipes to communicate
+       with the C++ side.  A side benefit is that the C++ side now will
+       not block when sending data to the gui.
+
+2005-10-25  Eric Blossom  <eb@comsec.com>
+
+       * src/python/fftsink.py: added peak_hold function and menu item.
+
+2005-10-14  Eric Blossom  <eb@comsec.com>
+
+       * src/python/form.py (quantized_slider_field): new field type,
+       very nice for quantized floats such as frequency, gain, etc.
+
+2005-08-28  Eric Blossom  <eb@comsec.com>
+
+       * src/python/form.py: new.  tools for building forms based GUIs.
+
+2005-08-15  Eric Blossom  <eb@comsec.com>
+
+       * src/python/waterfallsink.py: fftshift data so it comes out as
+       expected -- -ve freqs on the left, 0 in the middle, +ve freqs on
+       right.  Thanks to James Smith.
+
+2005-08-15  Krzysztof Kamieniecki <krys@kamieniecki.com>
+
+       * src/python/powermate.py: on GNU/Linux get exclusive access to knob.
+
+2005-07-02  Eric Blossom  <eb@comsec.com>
+
+       * config/gr_no_undefined.m4, config/gr_x86_64.m4: new, x86_64 support.
+       * config/gr_python.m4: backed out search for libpython, making
+       x86_64 work and breaking Cygwin/MinGW.
+       * configure.ac: mods for x86_64, $(NO_UNDEFINED)
+       
+2005-06-19  Eric Blossom  <eb@comsec.com>
+
+       * src/python/waterfallsink.py:  reworked to use latest FFT sink stuff.
+       * src/python/fftsink.py (fft_sink_f.__init__): added missing call
+       to set_average.
+
+2005-06-11  Eric Blossom  <eb@comsec.com>
+
+       * src/python/fftsink.py: normalized FFT by number of points.
+
+2005-06-08  Krzysztof Kamieniecki <krys@kamieniecki.com>
+
+       * src/python/powermate.py: added support for ShuttlePRO v2.
+
+2005-05-15  Eric Blossom  <eb@comsec.com>
+
+       * src/python/powermate.py: new.  Support the Griffin PowerMate and
+       Countour Shuttle/Jog usb knobs.  (Revised version of what I got
+       from Matt.)
+
+2005-05-11  Eric Blossom  <eb@comsec.com>
+
+       * src/python/fftsink.py, src/python/scopesink.py: Use
+       gru.os_read_exactly instead of os.read to avoid problems with
+       short reads [thanks to Jon Jacky for troubleshooting].
+       Added throttle block to demo to keep it from sucking down all CPU.
+
+2005-05-09  Stephane Fillod  <f8cfe@free.fr>
+
+        * config/gr_sysv_shm.m4: SysV shared memory not mandatory
+       * config/gr_pwin32.m4, config/gr_python.m4, config/lf_cxx.m4:
+         fixes for Cygwin, MinGW
+
+2005-03-16  Eric Blossom  <eb@comsec.com>
+
+       * src/python/scopesink.py (graph_window.format_data): enabled legend.
+
+2005-03-13  David Carr <dc@dcarr.org>
+
+       * src/python/waterfallsink.py: New faster, in color
+
+2005-03-04  Eric Blossom  <eb@comsec.com>
+
+       * src/python/slider.py: high level interface to wx.Slider
+
+2005-02-25  Eric Blossom  <eb@comsec.com>
+
+       Moved everything from src/python/gnuradio/wxgui to src/python and
+       removed the unnecessary hierarchy.
+
+2004-11-15  Matt Ettus    <matt@ettus.com>
+
+       * src/python/gnuradio/wxgui/waterfallsink.py: new, from David Carr <dc@dcarr.org>
+
+2004-10-13  Eric Blossom  <eb@comsec.com>
+
+       * configure.ac: upped rev to 0.1cvs
+
+2004-10-11  Eric Blossom  <eb@comsec.com>
+
+       * configure.ac: bumped rev to 0.1, make release
+       * Makefile.am (EXTRA_DIST): added config.h.in
+
+2004-09-23  Eric Blossom  <eb@comsec.com>
+
+       * config/usrp_fusb_tech.m4, config/bnv_have_qt.m4, config/cppunit.m4,
+       config/gr_check_mc4020.m4, config/gr_check_usrp.m4, config/gr_doxygen.m4,
+       config/gr_gprof.m4, config/gr_scripting.m4, config/gr_set_md_cpu.m4,
+       config/pkg.m4, config/usrp_fusb_tech.m4: added additional quoting
+       to first arg of AC_DEFUN to silence automake warning.
+
+2004-09-19  Eric Blossom  <eb@comsec.com>
+
+       * src/python/gnuradio/wxgui/stdgui.py: reworked to really subclass
+       wx.App
+
+2004-09-18  Eric Blossom  <eb@comsec.com>
+
+       * src/python/gnuradio/wxgui/stdgui.py: new.
+       * src/python/gnuradio/wxgui/fftsink.py: new.
+       * src/python/gnuradio/wxgui/scopesink.py: new.  Needs work
+
+#
+# Copyright 2004,2005,2006 Free Software Foundation, Inc.
+# 
+# This file is part of GNU Radio
+# 
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 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.
+# 
diff --git a/gr-wxgui/Makefile.am b/gr-wxgui/Makefile.am
new file mode 100644 (file)
index 0000000..2a0b4b4
--- /dev/null
@@ -0,0 +1,28 @@
+#
+# 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 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.
+# 
+
+include $(top_srcdir)/Makefile.common
+
+EXTRA_DIST = gr-wxgui.conf
+SUBDIRS = src
+
+etcdir = $(sysconfdir)/gnuradio/conf.d
+etc_DATA = gr-wxgui.conf
diff --git a/gr-wxgui/README b/gr-wxgui/README
new file mode 100644 (file)
index 0000000..ebd0d23
--- /dev/null
@@ -0,0 +1 @@
+This requires wxPython 2.5.2.7 or later.  See http://www.wxpython.org
diff --git a/gr-wxgui/gr-wxgui.conf b/gr-wxgui/gr-wxgui.conf
new file mode 100644 (file)
index 0000000..f6b128c
--- /dev/null
@@ -0,0 +1,7 @@
+# This file contains system wide configuration data for GNU Radio.
+# You may override any setting on a per-user basis by editing
+# ~/.gnuradio/config.conf
+
+[wxgui]
+fft_rate = 15    # fftsink and waterfallsink
+frame_decim = 1   # scopesink
diff --git a/gr-wxgui/src/Makefile.am b/gr-wxgui/src/Makefile.am
new file mode 100644 (file)
index 0000000..5da68b9
--- /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 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.
+# 
+
+include $(top_srcdir)/Makefile.common
+
+SUBDIRS = python
diff --git a/gr-wxgui/src/python/Makefile.am b/gr-wxgui/src/python/Makefile.am
new file mode 100644 (file)
index 0000000..2d25de0
--- /dev/null
@@ -0,0 +1,40 @@
+#
+# 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 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.
+# 
+
+include $(top_srcdir)/Makefile.common
+
+# Install this stuff so that it ends up as the gnuradio.wxgui module
+# This usually ends up at:
+#   ${prefix}/lib/python${python_version}/site-packages/gnuradio/wxgui
+
+ourpythondir = $(grpythondir)/wxgui
+ourlibdir    = $(grpyexecdir)/wxgui
+
+ourpython_PYTHON =                     \
+       __init__.py                     \
+       form.py                         \
+       fftsink.py                      \
+       plot.py                         \
+       powermate.py                    \
+       scopesink.py                    \
+       waterfallsink.py                \
+       slider.py                       \
+       stdgui.py                       
diff --git a/gr-wxgui/src/python/__init__.py b/gr-wxgui/src/python/__init__.py
new file mode 100644 (file)
index 0000000..027150d
--- /dev/null
@@ -0,0 +1 @@
+# make this directory a package
diff --git a/gr-wxgui/src/python/fftsink.py b/gr-wxgui/src/python/fftsink.py
new file mode 100755 (executable)
index 0000000..8796a1b
--- /dev/null
@@ -0,0 +1,488 @@
+#!/usr/bin/env python
+#
+# Copyright 2003,2004,2005,2006 Free Software Foundation, Inc.
+# 
+# This file is part of GNU Radio
+# 
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 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.
+# 
+
+from gnuradio import gr, gru, window
+from gnuradio.wxgui import stdgui
+import wx
+import gnuradio.wxgui.plot as plot
+import Numeric
+import threading
+import math    
+
+default_fftsink_size = (640,240)
+default_fft_rate = gr.prefs().get_long('wxgui', 'fft_rate', 15)
+
+class fft_sink_base(object):
+    def __init__(self, input_is_real=False, 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='', peak_hold=False):
+
+        # initialize common attributes
+        self.baseband_freq = baseband_freq
+        self.y_divs = 8
+        self.y_per_div=y_per_div
+        self.ref_level = ref_level
+        self.sample_rate = sample_rate
+        self.fft_size = fft_size
+        self.fft_rate = fft_rate
+        self.average = average
+        if avg_alpha is None:
+            self.avg_alpha = 2.0 / fft_rate
+        else:
+            self.avg_alpha = avg_alpha
+        self.title = title
+        self.peak_hold = peak_hold
+        self.input_is_real = input_is_real
+        self.msgq = gr.msg_queue(2)         # queue that holds a maximum of 2 messages
+
+    def set_y_per_div(self, y_per_div):
+        self.y_per_div = y_per_div
+
+    def set_ref_level(self, ref_level):
+        self.ref_level = ref_level
+
+    def set_average(self, average):
+        self.average = average
+        if average:
+            self.avg.set_taps(self.avg_alpha)
+            self.set_peak_hold(False)
+        else:
+            self.avg.set_taps(1.0)
+
+    def set_peak_hold(self, enable):
+        self.peak_hold = enable
+        if enable:
+            self.set_average(False)
+        self.win.set_peak_hold(enable)
+
+    def set_avg_alpha(self, avg_alpha):
+        self.avg_alpha = avg_alpha
+
+    def set_baseband_freq(self, baseband_freq):
+        self.baseband_freq = baseband_freq
+
+    def set_sample_rate(self, sample_rate):
+        self.sample_rate = sample_rate
+        self._set_n()
+
+    def _set_n(self):
+        self.one_in_n.set_n(max(1, int(self.sample_rate/self.fft_size/self.fft_rate)))
+        
+
+class fft_sink_f(gr.hier_block, fft_sink_base):
+    def __init__(self, fg, 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, peak_hold=False):
+
+        fft_sink_base.__init__(self, input_is_real=True, baseband_freq=baseband_freq,
+                               y_per_div=y_per_div, ref_level=ref_level,
+                               sample_rate=sample_rate, fft_size=fft_size,
+                               fft_rate=fft_rate,
+                               average=average, avg_alpha=avg_alpha, title=title,
+                               peak_hold=peak_hold)
+                               
+        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,
+                                         max(1, int(self.sample_rate/self.fft_size/self.fft_rate)))
+
+        mywindow = window.blackmanharris(self.fft_size)
+        fft = gr.fft_vfc(self.fft_size, True, mywindow)
+        power = 0
+        for tap in mywindow:
+            power += tap*tap
+            
+        c2mag = gr.complex_to_mag(self.fft_size)
+        self.avg = gr.single_pole_iir_filter_ff(1.0, self.fft_size)
+
+        # FIXME  We need to add 3dB to all bins but the DC bin
+        log = gr.nlog10_ff(20, self.fft_size,
+                           -20*math.log10(self.fft_size)-10*math.log10(power/self.fft_size))
+        sink = gr.message_sink(gr.sizeof_float * self.fft_size, self.msgq, True)
+
+        fg.connect (s2p, self.one_in_n, fft, c2mag, self.avg, log, sink)
+        gr.hier_block.__init__(self, fg, s2p, sink)
+
+        self.win = fft_window(self, parent, size=size)
+        self.set_average(self.average)
+
+
+class fft_sink_c(gr.hier_block, fft_sink_base):
+    def __init__(self, fg, 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, peak_hold=False):
+
+        fft_sink_base.__init__(self, input_is_real=False, baseband_freq=baseband_freq,
+                               y_per_div=y_per_div, ref_level=ref_level,
+                               sample_rate=sample_rate, fft_size=fft_size,
+                               fft_rate=fft_rate,
+                               average=average, avg_alpha=avg_alpha, title=title,
+                               peak_hold=peak_hold)
+
+        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,
+                                         max(1, int(self.sample_rate/self.fft_size/self.fft_rate)))
+        mywindow = window.blackmanharris(self.fft_size)
+        power = 0
+        for tap in mywindow:
+            power += tap*tap
+            
+        fft = gr.fft_vcc(self.fft_size, True, mywindow)
+        c2mag = gr.complex_to_mag(fft_size)
+        self.avg = gr.single_pole_iir_filter_ff(1.0, fft_size)
+        log = gr.nlog10_ff(20, self.fft_size,
+                           -20*math.log10(self.fft_size)-10*math.log10(power/self.fft_size))
+        sink = gr.message_sink(gr.sizeof_float * fft_size, self.msgq, True)
+
+        fg.connect(s2p, self.one_in_n, fft, c2mag, self.avg, log, sink)
+        gr.hier_block.__init__(self, fg, s2p, sink)
+
+        self.win = fft_window(self, parent, size=size)
+        self.set_average(self.average)
+
+
+# ------------------------------------------------------------------------
+
+myDATA_EVENT = wx.NewEventType()
+EVT_DATA_EVENT = wx.PyEventBinder (myDATA_EVENT, 0)
+
+
+class DataEvent(wx.PyEvent):
+    def __init__(self, data):
+        wx.PyEvent.__init__(self)
+        self.SetEventType (myDATA_EVENT)
+        self.data = data
+
+    def Clone (self): 
+        self.__class__ (self.GetId())
+
+
+class input_watcher (threading.Thread):
+    def __init__ (self, msgq, fft_size, event_receiver, **kwds):
+        threading.Thread.__init__ (self, **kwds)
+        self.setDaemon (1)
+        self.msgq = msgq
+        self.fft_size = fft_size
+        self.event_receiver = event_receiver
+        self.keep_running = True
+        self.start ()
+
+    def run (self):
+        while (self.keep_running):
+            msg = self.msgq.delete_head()  # blocking read of message queue
+            itemsize = int(msg.arg1())
+            nitems = int(msg.arg2())
+
+            s = msg.to_string()            # get the body of the msg as a string
+
+            # There may be more than one FFT frame in the message.
+            # If so, we take only the last one
+            if nitems > 1:
+                start = itemsize * (nitems - 1)
+                s = s[start:start+itemsize]
+
+            complex_data = Numeric.fromstring (s, Numeric.Float32)
+            de = DataEvent (complex_data)
+            wx.PostEvent (self.event_receiver, de)
+            del de
+    
+
+class fft_window (plot.PlotCanvas):
+    def __init__ (self, fftsink, parent, id = -1,
+                  pos = wx.DefaultPosition, size = wx.DefaultSize,
+                  style = wx.DEFAULT_FRAME_STYLE, name = ""):
+        plot.PlotCanvas.__init__ (self, parent, id, pos, size, style, name)
+
+        self.y_range = None
+        self.fftsink = fftsink
+        self.peak_hold = False
+        self.peak_vals = None
+
+        self.SetEnableGrid (True)
+        # self.SetEnableZoom (True)
+        # self.SetBackgroundColour ('black')
+        
+        self.build_popup_menu()
+        
+        EVT_DATA_EVENT (self, self.set_data)
+        wx.EVT_CLOSE (self, self.on_close_window)
+        self.Bind(wx.EVT_RIGHT_UP, self.on_right_click)
+
+        self.input_watcher = input_watcher(fftsink.msgq, fftsink.fft_size, self)
+
+
+    def on_close_window (self, event):
+        print "fft_window:on_close_window"
+        self.keep_running = False
+
+
+    def set_data (self, evt):
+        dB = evt.data
+        L = len (dB)
+
+        if self.peak_hold:
+            if self.peak_vals is None:
+                self.peak_vals = dB
+            else:
+                self.peak_vals = Numeric.maximum(dB, self.peak_vals)
+                dB = self.peak_vals
+
+        x = max(abs(self.fftsink.sample_rate), abs(self.fftsink.baseband_freq))
+        if x >= 1e9:
+            sf = 1e-9
+            units = "GHz"
+        elif x >= 1e6:
+            sf = 1e-6
+            units = "MHz"
+        else:
+            sf = 1e-3
+            units = "kHz"
+
+        if self.fftsink.input_is_real:     # only plot 1/2 the points
+            x_vals = ((Numeric.arrayrange (L/2)
+                       * (self.fftsink.sample_rate * sf / L))
+                      + self.fftsink.baseband_freq * sf)
+            points = Numeric.zeros((len(x_vals), 2), Numeric.Float64)
+            points[:,0] = x_vals
+            points[:,1] = dB[0:L/2]
+        else:
+            # the "negative freqs" are in the second half of the array
+            x_vals = ((Numeric.arrayrange (-L/2, L/2)
+                       * (self.fftsink.sample_rate * sf / L))
+                      + self.fftsink.baseband_freq * sf)
+            points = Numeric.zeros((len(x_vals), 2), Numeric.Float64)
+            points[:,0] = x_vals
+            points[:,1] = Numeric.concatenate ((dB[L/2:], dB[0:L/2]))
+
+
+        lines = plot.PolyLine (points, colour='BLUE')
+
+        graphics = plot.PlotGraphics ([lines],
+                                      title=self.fftsink.title,
+                                      xLabel = units, yLabel = "dB")
+
+        self.Draw (graphics, xAxis=None, yAxis=self.y_range)
+        self.update_y_range ()
+
+    def set_peak_hold(self, enable):
+        self.peak_hold = enable
+        self.peak_vals = None
+
+    def update_y_range (self):
+        ymax = self.fftsink.ref_level
+        ymin = self.fftsink.ref_level - self.fftsink.y_per_div * self.fftsink.y_divs
+        self.y_range = self._axisInterval ('min', ymin, ymax)
+
+    def on_average(self, evt):
+        # print "on_average"
+        self.fftsink.set_average(evt.IsChecked())
+
+    def on_peak_hold(self, evt):
+        # print "on_peak_hold"
+        self.fftsink.set_peak_hold(evt.IsChecked())
+
+    def on_incr_ref_level(self, evt):
+        # print "on_incr_ref_level"
+        self.fftsink.set_ref_level(self.fftsink.ref_level
+                                   + self.fftsink.y_per_div)
+
+    def on_decr_ref_level(self, evt):
+        # print "on_decr_ref_level"
+        self.fftsink.set_ref_level(self.fftsink.ref_level
+                                   - self.fftsink.y_per_div)
+
+    def on_incr_y_per_div(self, evt):
+        # print "on_incr_y_per_div"
+        self.fftsink.set_y_per_div(next_up(self.fftsink.y_per_div, (1,2,5,10,20)))
+
+    def on_decr_y_per_div(self, evt):
+        # print "on_decr_y_per_div"
+        self.fftsink.set_y_per_div(next_down(self.fftsink.y_per_div, (1,2,5,10,20)))
+
+    def on_y_per_div(self, evt):
+        # print "on_y_per_div"
+        Id = evt.GetId()
+        if Id == self.id_y_per_div_1:
+            self.fftsink.set_y_per_div(1)
+        elif Id == self.id_y_per_div_2:
+            self.fftsink.set_y_per_div(2)
+        elif Id == self.id_y_per_div_5:
+            self.fftsink.set_y_per_div(5)
+        elif Id == self.id_y_per_div_10:
+            self.fftsink.set_y_per_div(10)
+        elif Id == self.id_y_per_div_20:
+            self.fftsink.set_y_per_div(20)
+
+        
+    def on_right_click(self, event):
+        menu = self.popup_menu
+        for id, pred in self.checkmarks.items():
+            item = menu.FindItemById(id)
+            item.Check(pred())
+        self.PopupMenu(menu, event.GetPosition())
+
+
+    def build_popup_menu(self):
+        self.id_incr_ref_level = wx.NewId()
+        self.id_decr_ref_level = wx.NewId()
+        self.id_incr_y_per_div = wx.NewId()
+        self.id_decr_y_per_div = wx.NewId()
+        self.id_y_per_div_1 = wx.NewId()
+        self.id_y_per_div_2 = wx.NewId()
+        self.id_y_per_div_5 = wx.NewId()
+        self.id_y_per_div_10 = wx.NewId()
+        self.id_y_per_div_20 = wx.NewId()
+        self.id_average = wx.NewId()
+        self.id_peak_hold = wx.NewId()
+
+        self.Bind(wx.EVT_MENU, self.on_average, id=self.id_average)
+        self.Bind(wx.EVT_MENU, self.on_peak_hold, id=self.id_peak_hold)
+        self.Bind(wx.EVT_MENU, self.on_incr_ref_level, id=self.id_incr_ref_level)
+        self.Bind(wx.EVT_MENU, self.on_decr_ref_level, id=self.id_decr_ref_level)
+        self.Bind(wx.EVT_MENU, self.on_incr_y_per_div, id=self.id_incr_y_per_div)
+        self.Bind(wx.EVT_MENU, self.on_decr_y_per_div, id=self.id_decr_y_per_div)
+        self.Bind(wx.EVT_MENU, self.on_y_per_div, id=self.id_y_per_div_1)
+        self.Bind(wx.EVT_MENU, self.on_y_per_div, id=self.id_y_per_div_2)
+        self.Bind(wx.EVT_MENU, self.on_y_per_div, id=self.id_y_per_div_5)
+        self.Bind(wx.EVT_MENU, self.on_y_per_div, id=self.id_y_per_div_10)
+        self.Bind(wx.EVT_MENU, self.on_y_per_div, id=self.id_y_per_div_20)
+
+
+        # make a menu
+        menu = wx.Menu()
+        self.popup_menu = menu
+        menu.AppendCheckItem(self.id_average, "Average")
+        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")
+        # menu.Append(self.id_incr_y_per_div, "Incr dB/div")
+        # menu.Append(self.id_decr_y_per_div, "Decr dB/div")
+        menu.AppendSeparator()
+        # we'd use RadioItems for these, but they're not supported on Mac
+        menu.AppendCheckItem(self.id_y_per_div_1, "1 dB/div")
+        menu.AppendCheckItem(self.id_y_per_div_2, "2 dB/div")
+        menu.AppendCheckItem(self.id_y_per_div_5, "5 dB/div")
+        menu.AppendCheckItem(self.id_y_per_div_10, "10 dB/div")
+        menu.AppendCheckItem(self.id_y_per_div_20, "20 dB/div")
+
+        self.checkmarks = {
+            self.id_average : lambda : self.fftsink.average,
+            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,
+            self.id_y_per_div_5 : lambda : self.fftsink.y_per_div == 5,
+            self.id_y_per_div_10 : lambda : self.fftsink.y_per_div == 10,
+            self.id_y_per_div_20 : lambda : self.fftsink.y_per_div == 20,
+            }
+
+
+def next_up(v, seq):
+    """
+    Return the first item in seq that is > v.
+    """
+    for s in seq:
+        if s > v:
+            return s
+    return v
+
+def next_down(v, seq):
+    """
+    Return the last item in seq that is < v.
+    """
+    rseq = list(seq[:])
+    rseq.reverse()
+
+    for s in rseq:
+        if s < v:
+            return s
+    return v
+
+
+# ----------------------------------------------------------------
+#                    Deprecated interfaces
+# ----------------------------------------------------------------
+
+# returns (block, win).
+#   block requires a single input stream of float
+#   win is a subclass of wxWindow
+
+def make_fft_sink_f(fg, parent, title, fft_size, input_rate, ymin = 0, ymax=50):
+    
+    block = fft_sink_f(fg, parent, title=title, fft_size=fft_size, sample_rate=input_rate,
+                       y_per_div=(ymax - ymin)/8, ref_level=ymax)
+    return (block, block.win)
+
+# returns (block, win).
+#   block requires a single input stream of gr_complex
+#   win is a subclass of wxWindow
+
+def make_fft_sink_c(fg, parent, title, fft_size, input_rate, ymin=0, ymax=50):
+    block = fft_sink_c(fg, parent, title=title, fft_size=fft_size, sample_rate=input_rate,
+                       y_per_div=(ymax - ymin)/8, ref_level=ymax)
+    return (block, block.win)
+
+
+# ----------------------------------------------------------------
+# Standalone test app
+# ----------------------------------------------------------------
+
+class test_app_flow_graph (stdgui.gui_flow_graph):
+    def __init__(self, frame, panel, vbox, argv):
+        stdgui.gui_flow_graph.__init__ (self, frame, panel, vbox, argv)
+
+        fft_size = 256
+
+        # build our flow graph
+        input_rate = 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)
+
+        # We add these throttle blocks so that this demo doesn't
+        # suck down all the CPU available.  Normally you wouldn't use these.
+        thr1 = gr.throttle(gr.sizeof_gr_complex, input_rate)
+
+        sink1 = fft_sink_c (self, panel, title="Complex Data", fft_size=fft_size,
+                            sample_rate=input_rate, baseband_freq=100e3,
+                            ref_level=0, y_per_div=20)
+        vbox.Add (sink1.win, 1, wx.EXPAND)
+        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)
+        thr2 = gr.throttle(gr.sizeof_float, input_rate)
+        sink2 = fft_sink_f (self, panel, title="Real Data", fft_size=fft_size*2,
+                            sample_rate=input_rate, baseband_freq=100e3,
+                            ref_level=0, y_per_div=20)
+        vbox.Add (sink2.win, 1, wx.EXPAND)
+        self.connect (src2, thr2, sink2)
+
+def main ():
+    app = stdgui.stdapp (test_app_flow_graph,
+                         "FFT Sink Test App")
+    app.MainLoop ()
+
+if __name__ == '__main__':
+    main ()
diff --git a/gr-wxgui/src/python/form.py b/gr-wxgui/src/python/form.py
new file mode 100755 (executable)
index 0000000..bb41817
--- /dev/null
@@ -0,0 +1,391 @@
+#!/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 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.
+# 
+
+import wx
+from gnuradio import eng_notation
+
+# ----------------------------------------------------------------
+#                   Wrappers for certain widgets
+# ----------------------------------------------------------------
+
+def button_with_callback(parent, label, callback):
+    new_id = wx.NewId()
+    btn = wx.Button(parent, new_id, label)
+    wx.EVT_BUTTON(parent, new_id, lambda evt: callback())
+    return btn
+    
+
+# ----------------------------------------------------------------
+#                        Format converters
+# ----------------------------------------------------------------
+
+class abstract_converter(object):
+    def value_to_prim(self, v):
+        """
+        Convert from user specified value to value acceptable to underlying primitive.
+        The underlying primitive usually expects strings.
+        """
+        raise NotImplementedError
+    def prim_to_value(self, s):
+        """
+        Convert from underlying primitive value to user specified value.
+        The underlying primitive usually expects strings.
+        """
+        raise NotImplementedError
+    def help(self):
+        return "Any string is acceptable"
+
+class identity_converter(abstract_converter):
+    def value_to_prim(self,v):
+        return v
+    def prim_to_value(self, s):
+        return s
+
+class int_converter(abstract_converter):
+    def value_to_prim(self, v):
+        return str(v)
+    def prim_to_value(self, s):
+        return int(s, 0)
+    def help(self):
+        return "Enter an integer.  Leading 0x indicates hex"
+
+class float_converter(abstract_converter):
+    def value_to_prim(self, v):
+        return eng_notation.num_to_str(v)
+    def prim_to_value(self, s):
+        return eng_notation.str_to_num(s)
+    def help(self):
+        return "Enter a float with optional scale suffix.  E.g., 100.1M"
+
+
+# ----------------------------------------------------------------
+#               Various types of data entry fields
+# ----------------------------------------------------------------
+
+class field(object):
+    """
+    A field in a form.
+    """
+    def __init__(self, converter, value):
+        self.converter = converter
+        if value is not None:
+            self.set_value(value)
+
+    def set_value(self, v):
+        self._set_prim_value(self.converter.value_to_prim(v))
+
+    def get_value(self):
+        return self.converter.prim_to_value(self._get_prim_value())
+
+    def get_value_with_check(self):
+        """
+        Returns (value, error_msg), where error_msg is not None if there was problem
+        """
+        try:
+            return (self.get_value(), None)
+        except:
+            return (None, self._error_msg())
+
+    def _set_prim_value(self, v):
+        raise NotImplementedError
+
+    def _get_prim_value(self):
+        raise NotImplementedError
+
+    def _pair_with_label(self, widget, parent=None, sizer=None, label=None, weight=1):
+        self.label = label
+        if label is None:
+            sizer.Add (widget, weight, wx.EXPAND)
+            return widget
+        elif 0:
+            hbox = wx.BoxSizer(wx.HORIZONTAL)
+            label_widget = wx.StaticText(parent, -1, label + ': ')
+            hbox.Add(label_widget, 0, wx.EXPAND)
+            hbox.Add(widget, 1, wx.EXPAND)
+            sizer.Add(hbox, weight, wx.EXPAND)
+            return widget
+        else:
+            label_widget = wx.StaticText(parent, -1, label + ': ')
+            sizer.Add(label_widget, 0, wx.EXPAND)
+            sizer.Add(widget, weight, wx.EXPAND)
+            return widget
+    
+    def _error_msg(self):
+        prefix = ''
+        if self.label:
+            prefix = self.label + ': '
+        return "%s%s is invalid. %s" % (prefix, self._get_prim_value(),
+                                        self.converter.help())
+
+# static (display-only) text fields
+
+class static_text_field(field):
+    def __init__(self, parent=None, sizer=None, label=None, value=None,
+                 converter=identity_converter(), weight=0):
+        self.f = self._pair_with_label(wx.StaticText(parent, -1, ""),
+                                       parent=parent, sizer=sizer, label=label, weight=weight)
+        field.__init__(self, converter, value)
+
+    def _get_prim_value(self):
+        return self.f.GetLabel()
+
+    def _set_prim_value(self, v):
+        self.f.SetLabel(v)
+
+
+class static_int_field(static_text_field):
+    def __init__(self, parent=None, sizer=None, label=None, value=None, weight=0):
+        static_text_field.__init__(self, parent, sizer, label, value, int_converter(), weight)
+
+class static_float_field(static_text_field):
+    def __init__(self, parent=None, sizer=None, label=None, value=None, weight=0):
+        static_text_field.__init__(self, parent, sizer, label, value, float_converter(), weight)
+
+
+# editable text fields
+
+class text_field(field):
+    def __init__(self, parent=None, sizer=None, label=None, value=None,
+                 converter=identity_converter(), callback=None, weight=1):
+        style = 0
+        if callback:
+            style = wx.TE_PROCESS_ENTER
+
+        new_id = wx.NewId()
+        w = wx.TextCtrl(parent, new_id, "", style=style)
+        self.f = self._pair_with_label(w, parent=parent, sizer=sizer, label=label, weight=weight)
+        if callback:
+            wx.EVT_TEXT_ENTER(w, new_id, lambda evt: callback())
+        field.__init__(self, converter, value)
+
+    def _get_prim_value(self):
+        return self.f.GetValue()
+
+    def _set_prim_value(self, v):
+        self.f.SetValue(v)
+
+
+class int_field(text_field):
+    def __init__(self, parent=None, sizer=None, label=None, value=None,
+                 callback=None, weight=1):
+        text_field.__init__(self, parent, sizer, label, value, int_converter(), callback, weight)
+
+class float_field(text_field):
+    def __init__(self, parent=None, sizer=None, label=None, value=None,
+                 callback=None, weight=1):
+        text_field.__init__(self, parent, sizer, label, value, float_converter(), callback, weight)
+
+# other fields
+
+class slider_field(field):
+    def __init__(self, parent=None, sizer=None, label=None, value=None,
+                 converter=identity_converter(), callback=None, min=0, max=100, weight=1):
+        new_id = wx.NewId()
+        w = wx.Slider(parent, new_id, (max+min)/2, min, max,
+                      size=wx.Size(250, -1), style=wx.SL_HORIZONTAL | wx.SL_LABELS)
+        self.f = self._pair_with_label(w, parent=parent, sizer=sizer, label=label, weight=weight)
+        if callback:
+            wx.EVT_COMMAND_SCROLL(w, new_id, lambda evt: callback(evt.GetInt()))
+        field.__init__(self, converter, value)
+
+    def _get_prim_value(self):
+        return self.f.GetValue()
+
+    def _set_prim_value(self, v):
+        self.f.SetValue(int(v))
+
+class quantized_slider_field(field):
+    def __init__(self, parent=None, sizer=None, label=None, value=None,
+                 converter=identity_converter(), callback=None, range=None, weight=1):
+        if not isinstance(range, (tuple, list)) or len(range) != 3:
+            raise ValueError, range
+
+        self.min = range[0]
+        self.max = range[1]
+        self.step_size = float(range[2])
+        nsteps = int((self.max-self.min)/self.step_size)
+        
+        new_id = wx.NewId()
+        w = wx.Slider(parent, new_id, 0, 0, nsteps,
+                      size=wx.Size(250, -1), style=wx.SL_HORIZONTAL)
+        self.f = self._pair_with_label(w, parent=parent, sizer=sizer, label=label, weight=weight)
+        if callback:
+            wx.EVT_COMMAND_SCROLL(w, new_id,
+                                  lambda evt: callback(self._map_out(evt.GetInt())))
+        field.__init__(self, converter, value)
+
+    def _get_prim_value(self):
+        return self._map_out(self.f.GetValue())
+
+    def _set_prim_value(self, v):
+        self.f.SetValue(self._map_in(v))
+
+    def _map_in(self, x):
+        return int((x-self.min) / self.step_size)
+
+    def _map_out(self, x):
+        return x * self.step_size + self.min
+
+class checkbox_field(field):
+    def __init__(self, parent=None, sizer=None, label=None, value=None,
+                 converter=identity_converter(), callback=None, weight=1):
+        new_id = wx.NewId()
+        w = wx.CheckBox(parent, new_id, label, style=wx.CHK_2STATE)
+        self.f = self._pair_with_label(w, parent=parent, sizer=sizer, label=None, weight=weight)
+        if callback:
+            wx.EVT_CHECKBOX(w, new_id, lambda evt: callback(evt.GetInt()))
+        field.__init__(self, converter, value)
+
+    def _get_prim_value(self):
+        return self.f.GetValue()
+
+    def _set_prim_value(self, v):
+        self.f.SetValue(int(v))
+
+
+class radiobox_field(field):
+    def __init__(self, parent=None, sizer=None, label="", value=None,
+                 converter=identity_converter(), callback=None, weight=1,
+                 choices=None, major_dimension=1, specify_rows=False):
+        new_id = wx.NewId()
+
+        if specify_rows:
+            style=wx.RA_SPECIFY_ROWS | wx.RA_HORIZONTAL
+        else:
+            style=wx.RA_SPECIFY_COLS | wx.RA_HORIZONTAL
+            
+        w = wx.RadioBox(parent, new_id, label, style=style, majorDimension=major_dimension,
+                        choices=choices)
+        self.f = self._pair_with_label(w, parent=parent, sizer=sizer, label=label, weight=weight)
+        if callback:
+            wx.EVT_RADIOBOX(w, new_id, lambda evt: callback(evt.GetString()))
+        field.__init__(self, converter, value)
+
+    def _get_prim_value(self):
+        return self.f.GetStringSelection()
+
+    def _set_prim_value(self, v):
+        self.f.SetStringSelection(str(v))
+
+# ----------------------------------------------------------------
+#                         the form class
+# ----------------------------------------------------------------
+
+class form(dict):
+    def __init__(self):
+        dict.__init__(self)
+
+    def check_input_for_errors(self):
+        """
+        Returns list of error messages if there's trouble,
+        else empty list.
+        """
+        vals = [f.get_value_with_check() for f in self.values()]
+        return [t[1] for t in vals if t[1] is not None]
+        
+    def get_key_vals(self):
+        d = {}
+        for (key, f) in self.items():
+            d[key] = f.get_value()
+        return d
+
+
+    def _nop(*args): pass
+    
+    def check_input_and_call(self, callback, status_handler=_nop):
+        """
+        Return a function that checks the form for errors, and then if it's OK,
+        invokes the user specified callback, passing it the form key/value dictionary.
+        status_handler is called with a string indicating results.
+        """
+        def doit_callback(*ignore):
+            errors = self.check_input_for_errors()
+            if errors:
+                status_handler(errors[0])
+                #print '\n'.join(tuple(errors))
+            else:
+                kv = self.get_key_vals()
+                if callback(kv):
+                    status_handler("OK")
+                else:
+                    status_handler("Failed")
+
+        return doit_callback
+
+
+
+# ----------------------------------------------------------------
+#                    Stand-alone example code
+# ----------------------------------------------------------------
+
+import sys
+from gnuradio.wxgui import stdgui
+
+class demo_app_flow_graph (stdgui.gui_flow_graph):
+    def __init__(self, frame, panel, vbox, argv):
+        stdgui.gui_flow_graph.__init__ (self, frame, panel, vbox, argv)
+
+        self.frame = frame
+        self.panel = panel
+
+        def _print_kv(kv):
+            print "kv =", kv
+            return True
+
+        self.form = form()
+        
+        self.form['static1'] = \
+            static_text_field(parent=panel, sizer=vbox,
+                              label="Static Text",
+                              value="The Static Value")
+
+        self.form['text1'] = \
+            text_field(parent=panel, sizer=vbox,
+                       label="TextCtrl",
+                       value="The Editable Value")
+
+        self.form['int1'] = \
+            int_field(parent=panel, sizer=vbox,
+                      label="Int Field",
+                      value=1234)
+
+        self.form['float1'] = \
+            float_field(parent=panel, sizer=vbox,
+                      label="Float Field",
+                      value=3.14159)
+
+        self.doit = button_with_callback(
+            panel, "Do It!",
+            self.form.check_input_and_call(_print_kv, self._set_status_msg))
+
+        vbox.Add(self.doit, 0, wx.CENTER)
+
+    def _set_status_msg(self, msg):
+        self.frame.GetStatusBar().SetStatusText(msg, 0)
+
+            
+def main ():
+    app = stdgui.stdapp (demo_app_flow_graph, "wxgui form demo", nstatus=1)
+    app.MainLoop ()
+
+if __name__ == '__main__':
+    main ()
diff --git a/gr-wxgui/src/python/plot.py b/gr-wxgui/src/python/plot.py
new file mode 100644 (file)
index 0000000..d902d41
--- /dev/null
@@ -0,0 +1,1744 @@
+#-----------------------------------------------------------------------------
+# Name:        wx.lib.plot.py
+# Purpose:     Line, Bar and Scatter Graphs
+#
+# Author:      Gordon Williams
+#
+# Created:     2003/11/03
+# RCS-ID:      $Id$
+# Copyright:   (c) 2002
+# Licence:     Use as you wish.
+#-----------------------------------------------------------------------------
+# 12/15/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o 2.5 compatability update.
+# o Renamed to plot.py in the wx.lib directory.
+# o Reworked test frame to work with wx demo framework. This saves a bit
+#   of tedious cut and paste, and the test app is excellent.
+#
+# 12/18/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o wxScrolledMessageDialog -> ScrolledMessageDialog
+#
+# Oct 6, 2004  Gordon Williams (g_will@cyberus.ca)
+#   - Added bar graph demo
+#   - Modified line end shape from round to square.
+#   - Removed FloatDCWrapper for conversion to ints and ints in arguments
+#
+# Oct 15, 2004  Gordon Williams (g_will@cyberus.ca)
+#   - Imported modules given leading underscore to name.
+#   - Added Cursor Line Tracking and User Point Labels. 
+#   - Demo for Cursor Line Tracking and Point Labels.
+#   - Size of plot preview frame adjusted to show page better.
+#   - Added helper functions PositionUserToScreen and PositionScreenToUser in PlotCanvas.
+#   - Added functions GetClosestPoints (all curves) and GetClosestPoint (only closest curve)
+#       can be in either user coords or screen coords.
+#   
+#
+
+"""
+This is a simple light weight plotting module that can be used with
+Boa or easily integrated into your own wxPython application.  The
+emphasis is on small size and fast plotting for large data sets.  It
+has a reasonable number of features to do line and scatter graphs
+easily as well as simple bar graphs.  It is not as sophisticated or 
+as powerful as SciPy Plt or Chaco.  Both of these are great packages 
+but consume huge amounts of computer resources for simple plots.
+They can be found at http://scipy.com
+
+This file contains two parts; first the re-usable library stuff, then,
+after a "if __name__=='__main__'" test, a simple frame and a few default
+plots for examples and testing.
+
+Based on wxPlotCanvas
+Written by K.Hinsen, R. Srinivasan;
+Ported to wxPython Harm van der Heijden, feb 1999
+
+Major Additions Gordon Williams Feb. 2003 (g_will@cyberus.ca)
+    -More style options
+    -Zooming using mouse 'rubber band'
+    -Scroll left, right
+    -Grid(graticule)
+    -Printing, preview, and page set up (margins)
+    -Axis and title labels
+    -Cursor xy axis values
+    -Doc strings and lots of comments
+    -Optimizations for large number of points
+    -Legends
+    
+Did a lot of work here to speed markers up. Only a factor of 4
+improvement though. Lines are much faster than markers, especially
+filled markers.  Stay away from circles and triangles unless you
+only have a few thousand points.
+
+Times for 25,000 points
+Line - 0.078 sec
+Markers
+Square -                   0.22 sec
+dot -                      0.10
+circle -                   0.87
+cross,plus -               0.28
+triangle, triangle_down -  0.90
+
+Thanks to Chris Barker for getting this version working on Linux.
+
+Zooming controls with mouse (when enabled):
+    Left mouse drag - Zoom box.
+    Left mouse double click - reset zoom.
+    Right mouse click - zoom out centred on click location.
+"""
+
+import  string as _string
+import  time as _time
+import  wx
+
+# Needs Numeric or numarray
+try:
+    import Numeric as _Numeric
+except:
+    try:
+        import numarray as _Numeric  #if numarray is used it is renamed Numeric
+    except:
+        msg= """
+        This module requires the Numeric or numarray module,
+        which could not be imported.  It probably is not installed
+        (it's not part of the standard Python distribution). See the
+        Python site (http://www.python.org) for information on
+        downloading source or binaries."""
+        raise ImportError, "Numeric or numarray not found. \n" + msg
+
+
+
+#
+# Plotting classes...
+#
+class PolyPoints:
+    """Base Class for lines and markers
+        - All methods are private.
+    """
+
+    def __init__(self, points, attr):
+        self.points = _Numeric.array(points)
+        self.currentScale= (1,1)
+        self.currentShift= (0,0)
+        self.scaled = self.points
+        self.attributes = {}
+        self.attributes.update(self._attributes)
+        for name, value in attr.items():   
+            if name not in self._attributes.keys():
+                raise KeyError, "Style attribute incorrect. Should be one of %s" % self._attributes.keys()
+            self.attributes[name] = value
+        
+    def boundingBox(self):
+        if len(self.points) == 0:
+            # no curves to draw
+            # defaults to (-1,-1) and (1,1) but axis can be set in Draw
+            minXY= _Numeric.array([-1,-1])
+            maxXY= _Numeric.array([ 1, 1])
+        else:
+            minXY= _Numeric.minimum.reduce(self.points)
+            maxXY= _Numeric.maximum.reduce(self.points)
+        return minXY, maxXY
+
+    def scaleAndShift(self, scale=(1,1), shift=(0,0)):
+        if len(self.points) == 0:
+            # no curves to draw
+            return
+        if (scale is not self.currentScale) or (shift is not self.currentShift):
+            # update point scaling
+            self.scaled = scale*self.points+shift
+            self.currentScale= scale
+            self.currentShift= shift
+        # else unchanged use the current scaling
+        
+    def getLegend(self):
+        return self.attributes['legend']
+
+    def getClosestPoint(self, pntXY, pointScaled= True):
+        """Returns the index of closest point on the curve, pointXY, scaledXY, distance
+            x, y in user coords
+            if pointScaled == True based on screen coords
+            if pointScaled == False based on user coords
+        """
+        if pointScaled == True:
+            #Using screen coords
+            p = self.scaled
+            pxy = self.currentScale * _Numeric.array(pntXY)+ self.currentShift
+        else:
+            #Using user coords
+            p = self.points
+            pxy = _Numeric.array(pntXY)
+        #determine distance for each point
+        d= _Numeric.sqrt(_Numeric.add.reduce((p-pxy)**2,1)) #sqrt(dx^2+dy^2)
+        pntIndex = _Numeric.argmin(d)
+        dist = d[pntIndex]
+        return [pntIndex, self.points[pntIndex], self.scaled[pntIndex], dist]
+        
+        
+class PolyLine(PolyPoints):
+    """Class to define line type and style
+        - All methods except __init__ are private.
+    """
+    
+    _attributes = {'colour': 'black',
+                   'width': 1,
+                   'style': wx.SOLID,
+                   'legend': ''}
+
+    def __init__(self, points, **attr):
+        """Creates PolyLine object
+            points - sequence (array, tuple or list) of (x,y) points making up line
+            **attr - key word attributes
+                Defaults:
+                    'colour'= 'black',          - wx.Pen Colour any wx.NamedColour
+                    'width'= 1,                 - Pen width
+                    'style'= wx.SOLID,          - wx.Pen style
+                    'legend'= ''                - Line Legend to display
+        """
+        PolyPoints.__init__(self, points, attr)
+
+    def draw(self, dc, printerScale, coord= None):
+        colour = self.attributes['colour']
+        width = self.attributes['width'] * printerScale
+        style= self.attributes['style']
+        pen = wx.Pen(wx.NamedColour(colour), width, style)
+        pen.SetCap(wx.CAP_BUTT)
+        dc.SetPen(pen)
+        if coord == None:
+            dc.DrawLines(self.scaled)
+        else:
+            dc.DrawLines(coord) # draw legend line
+
+    def getSymExtent(self, printerScale):
+        """Width and Height of Marker"""
+        h= self.attributes['width'] * printerScale
+        w= 5 * h
+        return (w,h)
+
+
+class PolyMarker(PolyPoints):
+    """Class to define marker type and style
+        - All methods except __init__ are private.
+    """
+  
+    _attributes = {'colour': 'black',
+                   'width': 1,
+                   'size': 2,
+                   'fillcolour': None,
+                   'fillstyle': wx.SOLID,
+                   'marker': 'circle',
+                   'legend': ''}
+
+    def __init__(self, points, **attr):
+        """Creates PolyMarker object
+        points - sequence (array, tuple or list) of (x,y) points
+        **attr - key word attributes
+            Defaults:
+                'colour'= 'black',          - wx.Pen Colour any wx.NamedColour
+                'width'= 1,                 - Pen width
+                'size'= 2,                  - Marker size
+                'fillcolour'= same as colour,      - wx.Brush Colour any wx.NamedColour
+                'fillstyle'= wx.SOLID,      - wx.Brush fill style (use wx.TRANSPARENT for no fill)
+                'marker'= 'circle'          - Marker shape
+                'legend'= ''                - Marker Legend to display
+              
+            Marker Shapes:
+                - 'circle'
+                - 'dot'
+                - 'square'
+                - 'triangle'
+                - 'triangle_down'
+                - 'cross'
+                - 'plus'
+        """
+      
+        PolyPoints.__init__(self, points, attr)
+
+    def draw(self, dc, printerScale, coord= None):
+        colour = self.attributes['colour']
+        width = self.attributes['width'] * printerScale
+        size = self.attributes['size'] * printerScale
+        fillcolour = self.attributes['fillcolour']
+        fillstyle = self.attributes['fillstyle']
+        marker = self.attributes['marker']
+
+        dc.SetPen(wx.Pen(wx.NamedColour(colour), width))
+        if fillcolour:
+            dc.SetBrush(wx.Brush(wx.NamedColour(fillcolour),fillstyle))
+        else:
+            dc.SetBrush(wx.Brush(wx.NamedColour(colour), fillstyle))
+        if coord == None:
+            self._drawmarkers(dc, self.scaled, marker, size)
+        else:
+            self._drawmarkers(dc, coord, marker, size) # draw legend marker
+
+    def getSymExtent(self, printerScale):
+        """Width and Height of Marker"""
+        s= 5*self.attributes['size'] * printerScale
+        return (s,s)
+
+    def _drawmarkers(self, dc, coords, marker,size=1):
+        f = eval('self._' +marker)
+        f(dc, coords, size)
+
+    def _circle(self, dc, coords, size=1):
+        fact= 2.5*size
+        wh= 5.0*size
+        rect= _Numeric.zeros((len(coords),4),_Numeric.Float)+[0.0,0.0,wh,wh]
+        rect[:,0:2]= coords-[fact,fact]
+        dc.DrawEllipseList(rect.astype(_Numeric.Int32))
+
+    def _dot(self, dc, coords, size=1):
+        dc.DrawPointList(coords)
+
+    def _square(self, dc, coords, size=1):
+        fact= 2.5*size
+        wh= 5.0*size
+        rect= _Numeric.zeros((len(coords),4),_Numeric.Float)+[0.0,0.0,wh,wh]
+        rect[:,0:2]= coords-[fact,fact]
+        dc.DrawRectangleList(rect.astype(_Numeric.Int32))
+
+    def _triangle(self, dc, coords, size=1):
+        shape= [(-2.5*size,1.44*size), (2.5*size,1.44*size), (0.0,-2.88*size)]
+        poly= _Numeric.repeat(coords,3)
+        poly.shape= (len(coords),3,2)
+        poly += shape
+        dc.DrawPolygonList(poly.astype(_Numeric.Int32))
+
+    def _triangle_down(self, dc, coords, size=1):
+        shape= [(-2.5*size,-1.44*size), (2.5*size,-1.44*size), (0.0,2.88*size)]
+        poly= _Numeric.repeat(coords,3)
+        poly.shape= (len(coords),3,2)
+        poly += shape
+        dc.DrawPolygonList(poly.astype(_Numeric.Int32))
+      
+    def _cross(self, dc, coords, size=1):
+        fact= 2.5*size
+        for f in [[-fact,-fact,fact,fact],[-fact,fact,fact,-fact]]:
+            lines= _Numeric.concatenate((coords,coords),axis=1)+f
+            dc.DrawLineList(lines.astype(_Numeric.Int32))
+
+    def _plus(self, dc, coords, size=1):
+        fact= 2.5*size
+        for f in [[-fact,0,fact,0],[0,-fact,0,fact]]:
+            lines= _Numeric.concatenate((coords,coords),axis=1)+f
+            dc.DrawLineList(lines.astype(_Numeric.Int32))
+
+class PlotGraphics:
+    """Container to hold PolyXXX objects and graph labels
+        - All methods except __init__ are private.
+    """
+
+    def __init__(self, objects, title='', xLabel='', yLabel= ''):
+        """Creates PlotGraphics object
+        objects - list of PolyXXX objects to make graph
+        title - title shown at top of graph
+        xLabel - label shown on x-axis
+        yLabel - label shown on y-axis
+        """
+        if type(objects) not in [list,tuple]:
+            raise TypeError, "objects argument should be list or tuple"
+        self.objects = objects
+        self.title= title
+        self.xLabel= xLabel
+        self.yLabel= yLabel
+
+    def boundingBox(self):
+        p1, p2 = self.objects[0].boundingBox()
+        for o in self.objects[1:]:
+            p1o, p2o = o.boundingBox()
+            p1 = _Numeric.minimum(p1, p1o)
+            p2 = _Numeric.maximum(p2, p2o)
+        return p1, p2
+
+    def scaleAndShift(self, scale=(1,1), shift=(0,0)):
+        for o in self.objects:
+            o.scaleAndShift(scale, shift)
+
+    def setPrinterScale(self, scale):
+        """Thickens up lines and markers only for printing"""
+        self.printerScale= scale
+
+    def setXLabel(self, xLabel= ''):
+        """Set the X axis label on the graph"""
+        self.xLabel= xLabel
+
+    def setYLabel(self, yLabel= ''):
+        """Set the Y axis label on the graph"""
+        self.yLabel= yLabel
+        
+    def setTitle(self, title= ''):
+        """Set the title at the top of graph"""
+        self.title= title
+
+    def getXLabel(self):
+        """Get x axis label string"""
+        return self.xLabel
+
+    def getYLabel(self):
+        """Get y axis label string"""
+        return self.yLabel
+
+    def getTitle(self, title= ''):
+        """Get the title at the top of graph"""
+        return self.title
+
+    def draw(self, dc):
+        for o in self.objects:
+            #t=_time.clock()          # profile info
+            o.draw(dc, self.printerScale)
+            #dt= _time.clock()-t
+            #print o, "time=", dt
+
+    def getSymExtent(self, printerScale):
+        """Get max width and height of lines and markers symbols for legend"""
+        symExt = self.objects[0].getSymExtent(printerScale)
+        for o in self.objects[1:]:
+            oSymExt = o.getSymExtent(printerScale)
+            symExt = _Numeric.maximum(symExt, oSymExt)
+        return symExt
+    
+    def getLegendNames(self):
+        """Returns list of legend names"""
+        lst = [None]*len(self)
+        for i in range(len(self)):
+            lst[i]= self.objects[i].getLegend()
+        return lst
+            
+    def __len__(self):
+        return len(self.objects)
+
+    def __getitem__(self, item):
+        return self.objects[item]
+
+
+#-------------------------------------------------------------------------------
+# Main window that you will want to import into your application.
+
+class PlotCanvas(wx.Window):
+    """Subclass of a wx.Window to allow simple general plotting
+    of data with zoom, labels, and automatic axis scaling."""
+
+    def __init__(self, parent, id = -1, pos=wx.DefaultPosition,
+            size=wx.DefaultSize, style= wx.DEFAULT_FRAME_STYLE, name= ""):
+        """Constucts a window, which can be a child of a frame, dialog or
+        any other non-control window"""
+    
+        wx.Window.__init__(self, parent, id, pos, size, style, name)
+        self.border = (1,1)
+
+        self.SetBackgroundColour("white")
+        
+        # Create some mouse events for zooming
+        self.Bind(wx.EVT_LEFT_DOWN, self.OnMouseLeftDown)
+        self.Bind(wx.EVT_LEFT_UP, self.OnMouseLeftUp)
+        self.Bind(wx.EVT_MOTION, self.OnMotion)
+        self.Bind(wx.EVT_LEFT_DCLICK, self.OnMouseDoubleClick)
+        self.Bind(wx.EVT_RIGHT_DOWN, self.OnMouseRightDown)
+
+        # set curser as cross-hairs
+        self.SetCursor(wx.CROSS_CURSOR)
+
+        # Things for printing
+        self.print_data = wx.PrintData()
+        self.print_data.SetPaperId(wx.PAPER_LETTER)
+        self.print_data.SetOrientation(wx.LANDSCAPE)
+        self.pageSetupData= wx.PageSetupDialogData()
+        self.pageSetupData.SetMarginBottomRight((25,25))
+        self.pageSetupData.SetMarginTopLeft((25,25))
+        self.pageSetupData.SetPrintData(self.print_data)
+        self.printerScale = 1
+        self.parent= parent
+
+        # Zooming variables
+        self._zoomInFactor =  0.5
+        self._zoomOutFactor = 2
+        self._zoomCorner1= _Numeric.array([0.0, 0.0]) # left mouse down corner
+        self._zoomCorner2= _Numeric.array([0.0, 0.0])   # left mouse up corner
+        self._zoomEnabled= False
+        self._hasDragged= False
+        
+        # Drawing Variables
+        self.last_draw = None
+        self._pointScale= 1
+        self._pointShift= 0
+        self._xSpec= 'auto'
+        self._ySpec= 'auto'
+        self._gridEnabled= False
+        self._legendEnabled= False
+        self._xUseScopeTicks= False
+        
+        # Fonts
+        self._fontCache = {}
+        self._fontSizeAxis= 10
+        self._fontSizeTitle= 15
+        self._fontSizeLegend= 7
+
+        # pointLabels
+        self._pointLabelEnabled= False
+        self.last_PointLabel= None
+        self._pointLabelFunc= None
+        self.Bind(wx.EVT_LEAVE_WINDOW, self.OnLeave)
+
+        self.Bind(wx.EVT_PAINT, self.OnPaint)
+        self.Bind(wx.EVT_SIZE, self.OnSize)
+        # OnSize called to make sure the buffer is initialized.
+        # This might result in OnSize getting called twice on some
+        # platforms at initialization, but little harm done.
+        self.OnSize(None) # sets the initial size based on client size
+                          # UNCONDITIONAL, needed to create self._Buffer
+        
+    # SaveFile
+    def SaveFile(self, fileName= ''):
+        """Saves the file to the type specified in the extension. If no file
+        name is specified a dialog box is provided.  Returns True if sucessful,
+        otherwise False.
+        
+        .bmp  Save a Windows bitmap file.
+        .xbm  Save an X bitmap file.
+        .xpm  Save an XPM bitmap file.
+        .png  Save a Portable Network Graphics file.
+        .jpg  Save a Joint Photographic Experts Group file.
+        """
+        if _string.lower(fileName[-3:]) not in ['bmp','xbm','xpm','png','jpg']:
+            dlg1 = wx.FileDialog(
+                    self, 
+                    "Choose a file with extension bmp, gif, xbm, xpm, png, or jpg", ".", "",
+                    "BMP files (*.bmp)|*.bmp|XBM files (*.xbm)|*.xbm|XPM file (*.xpm)|*.xpm|PNG files (*.png)|*.png|JPG files (*.jpg)|*.jpg",
+                    wx.SAVE|wx.OVERWRITE_PROMPT
+                    )
+            try:
+                while 1:
+                    if dlg1.ShowModal() == wx.ID_OK:
+                        fileName = dlg1.GetPath()
+                        # Check for proper exension
+                        if _string.lower(fileName[-3:]) not in ['bmp','xbm','xpm','png','jpg']:
+                            dlg2 = wx.MessageDialog(self, 'File name extension\n'
+                            'must be one of\n'
+                            'bmp, xbm, xpm, png, or jpg',
+                              'File Name Error', wx.OK | wx.ICON_ERROR)
+                            try:
+                                dlg2.ShowModal()
+                            finally:
+                                dlg2.Destroy()
+                        else:
+                            break # now save file
+                    else: # exit without saving
+                        return False
+            finally:
+                dlg1.Destroy()
+
+        # File name has required extension
+        fType = _string.lower(fileName[-3:])
+        if fType == "bmp":
+            tp= wx.BITMAP_TYPE_BMP       # Save a Windows bitmap file.
+        elif fType == "xbm":
+            tp= wx.BITMAP_TYPE_XBM       # Save an X bitmap file.
+        elif fType == "xpm":
+            tp= wx.BITMAP_TYPE_XPM       # Save an XPM bitmap file.
+        elif fType == "jpg":
+            tp= wx.BITMAP_TYPE_JPEG      # Save a JPG file.
+        else:
+            tp= wx.BITMAP_TYPE_PNG       # Save a PNG file.
+        # Save Bitmap
+        res= self._Buffer.SaveFile(fileName, tp)
+        return res
+
+    def PageSetup(self):
+        """Brings up the page setup dialog"""
+        data = self.pageSetupData
+        data.SetPrintData(self.print_data)
+        dlg = wx.PageSetupDialog(self.parent, data)
+        try:
+            if dlg.ShowModal() == wx.ID_OK:
+                data = dlg.GetPageSetupData() # returns wx.PageSetupDialogData
+                # updates page parameters from dialog
+                self.pageSetupData.SetMarginBottomRight(data.GetMarginBottomRight())
+                self.pageSetupData.SetMarginTopLeft(data.GetMarginTopLeft())
+                self.pageSetupData.SetPrintData(data.GetPrintData())
+                self.print_data=data.GetPrintData() # updates print_data
+        finally:
+            dlg.Destroy()
+                
+    def Printout(self, paper=None):
+        """Print current plot."""
+        if paper != None:
+            self.print_data.SetPaperId(paper)
+        pdd = wx.PrintDialogData()
+        pdd.SetPrintData(self.print_data)
+        printer = wx.Printer(pdd)
+        out = PlotPrintout(self)
+        print_ok = printer.Print(self.parent, out)
+        if print_ok:
+            self.print_data = printer.GetPrintDialogData().GetPrintData()
+        out.Destroy()
+
+    def PrintPreview(self):
+        """Print-preview current plot."""
+        printout = PlotPrintout(self)
+        printout2 = PlotPrintout(self)
+        self.preview = wx.PrintPreview(printout, printout2, self.print_data)
+        if not self.preview.Ok():
+            wx.MessageDialog(self, "Print Preview failed.\n" \
+                               "Check that default printer is configured\n", \
+                               "Print error", wx.OK|wx.CENTRE).ShowModal()
+        self.preview.SetZoom(40)
+        # search up tree to find frame instance
+        frameInst= self
+        while not isinstance(frameInst, wx.Frame):
+            frameInst= frameInst.GetParent()
+        frame = wx.PreviewFrame(self.preview, frameInst, "Preview")
+        frame.Initialize()
+        frame.SetPosition(self.GetPosition())
+        frame.SetSize((600,550))
+        frame.Centre(wx.BOTH)
+        frame.Show(True)
+
+    def SetFontSizeAxis(self, point= 10):
+        """Set the tick and axis label font size (default is 10 point)"""
+        self._fontSizeAxis= point
+        
+    def GetFontSizeAxis(self):
+        """Get current tick and axis label font size in points"""
+        return self._fontSizeAxis
+    
+    def SetFontSizeTitle(self, point= 15):
+        """Set Title font size (default is 15 point)"""
+        self._fontSizeTitle= point
+
+    def GetFontSizeTitle(self):
+        """Get current Title font size in points"""
+        return self._fontSizeTitle
+    
+    def SetFontSizeLegend(self, point= 7):
+        """Set Legend font size (default is 7 point)"""
+        self._fontSizeLegend= point
+        
+    def GetFontSizeLegend(self):
+        """Get current Legend font size in points"""
+        return self._fontSizeLegend
+
+    def SetEnableZoom(self, value):
+        """Set True to enable zooming."""
+        if value not in [True,False]:
+            raise TypeError, "Value should be True or False"
+        self._zoomEnabled= value
+
+    def GetEnableZoom(self):
+        """True if zooming enabled."""
+        return self._zoomEnabled
+
+    def SetEnableGrid(self, value):
+        """Set True to enable grid."""
+        if value not in [True,False]:
+            raise TypeError, "Value should be True or False"
+        self._gridEnabled= value
+        self.Redraw()
+
+    def GetEnableGrid(self):
+        """True if grid enabled."""
+        return self._gridEnabled
+
+    def SetEnableLegend(self, value):
+        """Set True to enable legend."""
+        if value not in [True,False]:
+            raise TypeError, "Value should be True or False"
+        self._legendEnabled= value 
+        self.Redraw()
+
+    def GetEnableLegend(self):
+        """True if Legend enabled."""
+        return self._legendEnabled
+
+    def SetEnablePointLabel(self, value):
+        """Set True to enable pointLabel."""
+        if value not in [True,False]:
+            raise TypeError, "Value should be True or False"
+        self._pointLabelEnabled= value 
+        self.Redraw()  #will erase existing pointLabel if present
+        self.last_PointLabel = None
+
+    def GetEnablePointLabel(self):
+        """True if pointLabel enabled."""
+        return self._pointLabelEnabled
+
+    def SetPointLabelFunc(self, func):
+        """Sets the function with custom code for pointLabel drawing
+            ******** more info needed ***************
+        """
+        self._pointLabelFunc= func
+
+    def GetPointLabelFunc(self):
+        """Returns pointLabel Drawing Function"""
+        return self._pointLabelFunc
+
+    def Reset(self):
+        """Unzoom the plot."""
+        self.last_PointLabel = None        #reset pointLabel
+        if self.last_draw is not None:
+            self.Draw(self.last_draw[0])
+        
+    def ScrollRight(self, units):          
+        """Move view right number of axis units."""
+        self.last_PointLabel = None        #reset pointLabel
+        if self.last_draw is not None:
+            graphics, xAxis, yAxis= self.last_draw
+            xAxis= (xAxis[0]+units, xAxis[1]+units)
+            self.Draw(graphics,xAxis,yAxis)
+
+    def ScrollUp(self, units):
+        """Move view up number of axis units."""
+        self.last_PointLabel = None        #reset pointLabel
+        if self.last_draw is not None:
+            graphics, xAxis, yAxis= self.last_draw
+            yAxis= (yAxis[0]+units, yAxis[1]+units)
+            self.Draw(graphics,xAxis,yAxis)
+        
+    def GetXY(self,event):
+        """Takes a mouse event and returns the XY user axis values."""
+        x,y= self.PositionScreenToUser(event.GetPosition())
+        return x,y
+
+    def PositionUserToScreen(self, pntXY):
+        """Converts User position to Screen Coordinates"""
+        userPos= _Numeric.array(pntXY)
+        x,y= userPos * self._pointScale + self._pointShift
+        return x,y
+        
+    def PositionScreenToUser(self, pntXY):
+        """Converts Screen position to User Coordinates"""
+        screenPos= _Numeric.array(pntXY)
+        x,y= (screenPos-self._pointShift)/self._pointScale
+        return x,y
+        
+    def SetXSpec(self, type= 'auto'):
+        """xSpec- defines x axis type. Can be 'none', 'min' or 'auto'
+        where:
+            'none' - shows no axis or tick mark values
+            'min' - shows min bounding box values
+            'auto' - rounds axis range to sensible values
+        """
+        self._xSpec= type
+        
+    def SetYSpec(self, type= 'auto'):
+        """ySpec- defines x axis type. Can be 'none', 'min' or 'auto'
+        where:
+            'none' - shows no axis or tick mark values
+            'min' - shows min bounding box values
+            'auto' - rounds axis range to sensible values
+        """
+        self._ySpec= type
+
+    def GetXSpec(self):
+        """Returns current XSpec for axis"""
+        return self._xSpec
+    
+    def GetYSpec(self):
+        """Returns current YSpec for axis"""
+        return self._ySpec
+    
+    def GetXMaxRange(self):
+        """Returns (minX, maxX) x-axis range for displayed graph"""
+        graphics= self.last_draw[0]
+        p1, p2 = graphics.boundingBox()     # min, max points of graphics
+        xAxis = self._axisInterval(self._xSpec, p1[0], p2[0]) # in user units
+        return xAxis
+
+    def GetYMaxRange(self):
+        """Returns (minY, maxY) y-axis range for displayed graph"""
+        graphics= self.last_draw[0]
+        p1, p2 = graphics.boundingBox()     # min, max points of graphics
+        yAxis = self._axisInterval(self._ySpec, p1[1], p2[1])
+        return yAxis
+
+    def GetXCurrentRange(self):
+        """Returns (minX, maxX) x-axis for currently displayed portion of graph"""
+        return self.last_draw[1]
+    
+    def GetYCurrentRange(self):
+        """Returns (minY, maxY) y-axis for currently displayed portion of graph"""
+        return self.last_draw[2]
+        
+    def SetXUseScopeTicks(self, v=False):
+        """Always 10 divisions, no labels"""
+        self._xUseScopeTicks = v
+        
+    def GetXUseScopeTicks(self):
+        return self._xUseScopeTicks
+
+    def Draw(self, graphics, xAxis = None, yAxis = None, dc = None):
+        """Draw objects in graphics with specified x and y axis.
+        graphics- instance of PlotGraphics with list of PolyXXX objects
+        xAxis - tuple with (min, max) axis range to view
+        yAxis - same as xAxis
+        dc - drawing context - doesn't have to be specified.    
+        If it's not, the offscreen buffer is used
+        """
+        # check Axis is either tuple or none
+        if type(xAxis) not in [type(None),tuple]:
+            raise TypeError, "xAxis should be None or (minX,maxX)"
+        if type(yAxis) not in [type(None),tuple]:
+            raise TypeError, "yAxis should be None or (minY,maxY)"
+             
+        # check case for axis = (a,b) where a==b caused by improper zooms
+        if xAxis != None:
+            if xAxis[0] == xAxis[1]:
+                return
+        if yAxis != None:
+            if yAxis[0] == yAxis[1]:
+                return
+            
+        if dc == None:
+            # sets new dc and clears it 
+            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))
+
+        # sizes axis to axis type, create lower left and upper right corners of plot
+        if xAxis == None or yAxis == None:
+            # One or both axis not specified in Draw
+            p1, p2 = graphics.boundingBox()     # min, max points of graphics
+            if xAxis == None:
+                xAxis = self._axisInterval(self._xSpec, p1[0], p2[0]) # in user units
+            if yAxis == None:
+                yAxis = self._axisInterval(self._ySpec, p1[1], p2[1])
+            # Adjust bounding box for axis spec
+            p1[0],p1[1] = xAxis[0], yAxis[0]     # lower left corner user scale (xmin,ymin)
+            p2[0],p2[1] = xAxis[1], yAxis[1]     # upper right corner user scale (xmax,ymax)
+        else:
+            # Both axis specified in Draw
+            p1= _Numeric.array([xAxis[0], yAxis[0]])    # lower left corner user scale (xmin,ymin)
+            p2= _Numeric.array([xAxis[1], yAxis[1]])     # upper right corner user scale (xmax,ymax)
+
+        self.last_draw = (graphics, xAxis, yAxis)       # saves most recient values
+
+        # Get ticks and textExtents for axis if required
+        if self._xSpec is not 'none':
+            if self._xUseScopeTicks:
+                xticks = self._scope_ticks(xAxis[0], xAxis[1])
+            else:
+                xticks = self._ticks(xAxis[0], xAxis[1])
+            xTextExtent = dc.GetTextExtent(xticks[-1][1])# w h of x axis text last number on axis
+        else:
+            xticks = None
+            xTextExtent= (0,0) # No text for ticks
+        if self._ySpec is not 'none':
+            yticks = self._ticks(yAxis[0], yAxis[1])
+            yTextExtentBottom= dc.GetTextExtent(yticks[0][1])
+            yTextExtentTop   = dc.GetTextExtent(yticks[-1][1])
+            yTextExtent= (max(yTextExtentBottom[0],yTextExtentTop[0]),
+                          max(yTextExtentBottom[1],yTextExtentTop[1]))
+        else:
+            yticks = None
+            yTextExtent= (0,0) # No text for ticks
+
+        # TextExtents for Title and Axis Labels
+        titleWH, xLabelWH, yLabelWH= self._titleLablesWH(dc, graphics)
+
+        # TextExtents for Legend
+        legendBoxWH, legendSymExt, legendTextExt = self._legendWH(dc, graphics)
+
+        # room around graph area
+        rhsW= max(xTextExtent[0], legendBoxWH[0]) # use larger of number width or legend width
+        lhsW= yTextExtent[0]+ yLabelWH[1]
+        bottomH= max(xTextExtent[1], yTextExtent[1]/2.)+ xLabelWH[1]
+        topH= yTextExtent[1]/2. + titleWH[1]
+        textSize_scale= _Numeric.array([rhsW+lhsW,bottomH+topH]) # make plot area smaller by text size
+        textSize_shift= _Numeric.array([lhsW, bottomH])          # shift plot area by this amount
+
+        # drawing title and labels text
+        dc.SetFont(self._getFont(self._fontSizeTitle))
+        titlePos= (self.plotbox_origin[0]+ lhsW + (self.plotbox_size[0]-lhsW-rhsW)/2.- titleWH[0]/2.,
+                 self.plotbox_origin[1]- self.plotbox_size[1])
+        dc.DrawText(graphics.getTitle(),titlePos[0],titlePos[1])
+        dc.SetFont(self._getFont(self._fontSizeAxis))
+        xLabelPos= (self.plotbox_origin[0]+ lhsW + (self.plotbox_size[0]-lhsW-rhsW)/2.- xLabelWH[0]/2.,
+                 self.plotbox_origin[1]- xLabelWH[1])
+        dc.DrawText(graphics.getXLabel(),xLabelPos[0],xLabelPos[1])
+        yLabelPos= (self.plotbox_origin[0],
+                 self.plotbox_origin[1]- bottomH- (self.plotbox_size[1]-bottomH-topH)/2.+ yLabelWH[0]/2.)
+        if graphics.getYLabel():  # bug fix for Linux
+            dc.DrawRotatedText(graphics.getYLabel(),yLabelPos[0],yLabelPos[1],90)
+
+        # drawing legend makers and text
+        if self._legendEnabled:
+            self._drawLegend(dc,graphics,rhsW,topH,legendBoxWH, legendSymExt, legendTextExt)
+
+        # allow for scaling and shifting plotted points
+        scale = (self.plotbox_size-textSize_scale) / (p2-p1)* _Numeric.array((1,-1))
+        shift = -p1*scale + self.plotbox_origin + textSize_shift * _Numeric.array((1,-1))
+        self._pointScale= scale  # make available for mouse events
+        self._pointShift= shift        
+        self._drawAxes(dc, p1, p2, scale, shift, xticks, yticks)
+        
+        graphics.scaleAndShift(scale, shift)
+        graphics.setPrinterScale(self.printerScale)  # thicken up lines and markers if printing
+        
+        # set clipping area so drawing does not occur outside axis box
+        ptx,pty,rectWidth,rectHeight= self._point2ClientCoord(p1, p2)
+        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()
+        
+    def Redraw(self, dc= None):
+        """Redraw the existing plot."""
+        if self.last_draw is not None:
+            graphics, xAxis, yAxis= self.last_draw
+            self.Draw(graphics,xAxis,yAxis,dc)
+
+    def Clear(self):
+        """Erase the window."""
+        self.last_PointLabel = None        #reset pointLabel
+        dc = wx.BufferedDC(wx.ClientDC(self), self._Buffer)
+        dc.Clear()
+        self.last_draw = None
+
+    def Zoom(self, Center, Ratio):
+        """ Zoom on the plot
+            Centers on the X,Y coords given in Center
+            Zooms by the Ratio = (Xratio, Yratio) given
+        """
+        self.last_PointLabel = None   #reset maker
+        x,y = Center
+        if self.last_draw != None:
+            (graphics, xAxis, yAxis) = self.last_draw
+            w = (xAxis[1] - xAxis[0]) * Ratio[0]
+            h = (yAxis[1] - yAxis[0]) * Ratio[1]
+            xAxis = ( x - w/2, x + w/2 )
+            yAxis = ( y - h/2, y + h/2 )
+            self.Draw(graphics, xAxis, yAxis)
+        
+    def GetClosestPoints(self, pntXY, pointScaled= True):
+        """Returns list with
+            [curveNumber, legend, index of closest point, pointXY, scaledXY, distance]
+            list for each curve.
+            Returns [] if no curves are being plotted.
+            
+            x, y in user coords
+            if pointScaled == True based on screen coords
+            if pointScaled == False based on user coords
+        """
+        if self.last_draw == None:
+            #no graph available
+            return []
+        graphics, xAxis, yAxis= self.last_draw
+        l = []
+        for curveNum,obj in enumerate(graphics):
+            #check there are points in the curve
+            if len(obj.points) == 0:
+                continue  #go to next obj
+            #[curveNumber, legend, index of closest point, pointXY, scaledXY, distance]
+            cn = [curveNum]+ [obj.getLegend()]+ obj.getClosestPoint( pntXY, pointScaled)
+            l.append(cn)
+        return l
+
+    def GetClosetPoint(self, pntXY, pointScaled= True):
+        """Returns list with
+            [curveNumber, legend, index of closest point, pointXY, scaledXY, distance]
+            list for only the closest curve.
+            Returns [] if no curves are being plotted.
+            
+            x, y in user coords
+            if pointScaled == True based on screen coords
+            if pointScaled == False based on user coords
+        """
+        #closest points on screen based on screen scaling (pointScaled= True)
+        #list [curveNumber, index, pointXY, scaledXY, distance] for each curve
+        closestPts= self.GetClosestPoints(pntXY, pointScaled)
+        if closestPts == []:
+            return []  #no graph present
+        #find one with least distance
+        dists = [c[-1] for c in closestPts]
+        mdist = min(dists)  #Min dist
+        i = dists.index(mdist)  #index for min dist
+        return closestPts[i]  #this is the closest point on closest curve
+
+    def UpdatePointLabel(self, mDataDict):
+        """Updates the pointLabel point on screen with data contained in
+            mDataDict.
+
+            mDataDict will be passed to your function set by
+            SetPointLabelFunc.  It can contain anything you
+            want to display on the screen at the scaledXY point
+            you specify.
+
+            This function can be called from parent window with onClick,
+            onMotion events etc.            
+        """
+        if self.last_PointLabel != None:
+            #compare pointXY
+            if mDataDict["pointXY"] != self.last_PointLabel["pointXY"]:
+                #closest changed
+                self._drawPointLabel(self.last_PointLabel) #erase old
+                self._drawPointLabel(mDataDict) #plot new
+        else:
+            #just plot new with no erase
+            self._drawPointLabel(mDataDict) #plot new
+        #save for next erase
+        self.last_PointLabel = mDataDict
+
+    # event handlers **********************************
+    def OnMotion(self, event):
+        if self._zoomEnabled and event.LeftIsDown():
+            if self._hasDragged:
+                self._drawRubberBand(self._zoomCorner1, self._zoomCorner2) # remove old
+            else:
+                self._hasDragged= True
+            self._zoomCorner2[0], self._zoomCorner2[1] = self.GetXY(event)
+            self._drawRubberBand(self._zoomCorner1, self._zoomCorner2) # add new
+
+    def OnMouseLeftDown(self,event):
+        self._zoomCorner1[0], self._zoomCorner1[1]= self.GetXY(event)
+
+    def OnMouseLeftUp(self, event):
+        if self._zoomEnabled:
+            if self._hasDragged == True:
+                self._drawRubberBand(self._zoomCorner1, self._zoomCorner2) # remove old
+                self._zoomCorner2[0], self._zoomCorner2[1]= self.GetXY(event)
+                self._hasDragged = False  # reset flag
+                minX, minY= _Numeric.minimum( self._zoomCorner1, self._zoomCorner2)
+                maxX, maxY= _Numeric.maximum( self._zoomCorner1, self._zoomCorner2)
+                self.last_PointLabel = None        #reset pointLabel
+                if self.last_draw != None:
+                    self.Draw(self.last_draw[0], xAxis = (minX,maxX), yAxis = (minY,maxY), dc = None)
+            #else: # A box has not been drawn, zoom in on a point
+            ## this interfered with the double click, so I've disables it.
+            #    X,Y = self.GetXY(event)
+            #    self.Zoom( (X,Y), (self._zoomInFactor,self._zoomInFactor) )
+
+    def OnMouseDoubleClick(self,event):
+        if self._zoomEnabled:
+            self.Reset()
+        
+    def OnMouseRightDown(self,event):
+        if self._zoomEnabled:
+            X,Y = self.GetXY(event)
+            self.Zoom( (X,Y), (self._zoomOutFactor, self._zoomOutFactor) )
+
+    def OnPaint(self, event):
+        # All that is needed here is to draw the buffer to screen
+        if self.last_PointLabel != None:
+            self._drawPointLabel(self.last_PointLabel) #erase old
+            self.last_PointLabel = None
+        dc = wx.BufferedPaintDC(self, self._Buffer)
+
+    def OnSize(self,event):
+        # The Buffer init is done here, to make sure the buffer is always
+        # the same size as the Window
+        Size  = self.GetClientSize()
+
+        # 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._setSize()
+
+        self.last_PointLabel = None        #reset pointLabel
+
+        if self.last_draw is None:
+            self.Clear()
+        else:
+            graphics, xSpec, ySpec = self.last_draw
+            self.Draw(graphics,xSpec,ySpec)
+
+    def OnLeave(self, event):
+        """Used to erase pointLabel when mouse outside window"""
+        if self.last_PointLabel != None:
+            self._drawPointLabel(self.last_PointLabel) #erase old
+            self.last_PointLabel = None
+
+        
+    # Private Methods **************************************************
+    def _setSize(self, width=None, height=None):
+        """DC width and height."""
+        if width == None:
+            (self.width,self.height) = self.GetClientSize()
+        else:
+            self.width, self.height= width,height    
+        self.plotbox_size = 0.97*_Numeric.array([self.width, self.height])
+        xo = 0.5*(self.width-self.plotbox_size[0])
+        yo = self.height-0.5*(self.height-self.plotbox_size[1])
+        self.plotbox_origin = _Numeric.array([xo, yo])
+    
+    def _setPrinterScale(self, scale):
+        """Used to thicken lines and increase marker size for print out."""
+        # line thickness on printer is very thin at 600 dot/in. Markers small
+        self.printerScale= scale
+     
+    def _printDraw(self, printDC):
+        """Used for printing."""
+        if self.last_draw != None:
+            graphics, xSpec, ySpec= self.last_draw
+            self.Draw(graphics,xSpec,ySpec,printDC)
+
+    def _drawPointLabel(self, mDataDict):
+        """Draws and erases pointLabels"""
+        width = self._Buffer.GetWidth()
+        height = self._Buffer.GetHeight()
+        tmp_Buffer = wx.EmptyBitmap(width,height)
+        dcs = wx.MemoryDC()
+        dcs.SelectObject(tmp_Buffer)
+        dcs.Clear()
+        dcs.BeginDrawing()
+        self._pointLabelFunc(dcs,mDataDict)  #custom user pointLabel function
+        dcs.EndDrawing()
+
+        dc = wx.ClientDC( self )
+        #this will erase if called twice
+        dc.Blit(0, 0, width, height, dcs, 0, 0, wx.EQUIV)  #(NOT src) XOR dst
+        
+
+    def _drawLegend(self,dc,graphics,rhsW,topH,legendBoxWH, legendSymExt, legendTextExt):
+        """Draws legend symbols and text"""
+        # top right hand corner of graph box is ref corner
+        trhc= self.plotbox_origin+ (self.plotbox_size-[rhsW,topH])*[1,-1]
+        legendLHS= .091* legendBoxWH[0]  # border space between legend sym and graph box
+        lineHeight= max(legendSymExt[1], legendTextExt[1]) * 1.1 #1.1 used as space between lines
+        dc.SetFont(self._getFont(self._fontSizeLegend))
+        for i in range(len(graphics)):
+            o = graphics[i]
+            s= i*lineHeight
+            if isinstance(o,PolyMarker):
+                # draw marker with legend
+                pnt= (trhc[0]+legendLHS+legendSymExt[0]/2., trhc[1]+s+lineHeight/2.)
+                o.draw(dc, self.printerScale, coord= _Numeric.array([pnt]))
+            elif isinstance(o,PolyLine):
+                # draw line with legend
+                pnt1= (trhc[0]+legendLHS, trhc[1]+s+lineHeight/2.)
+                pnt2= (trhc[0]+legendLHS+legendSymExt[0], trhc[1]+s+lineHeight/2.)
+                o.draw(dc, self.printerScale, coord= _Numeric.array([pnt1,pnt2]))
+            else:
+                raise TypeError, "object is neither PolyMarker or PolyLine instance"
+            # draw legend txt
+            pnt= (trhc[0]+legendLHS+legendSymExt[0], trhc[1]+s+lineHeight/2.-legendTextExt[1]/2)
+            dc.DrawText(o.getLegend(),pnt[0],pnt[1])
+        dc.SetFont(self._getFont(self._fontSizeAxis)) # reset
+
+    def _titleLablesWH(self, dc, graphics):
+        """Draws Title and labels and returns width and height for each"""
+        # TextExtents for Title and Axis Labels
+        dc.SetFont(self._getFont(self._fontSizeTitle))
+        title= graphics.getTitle()
+        titleWH= dc.GetTextExtent(title)
+        dc.SetFont(self._getFont(self._fontSizeAxis))
+        xLabel, yLabel= graphics.getXLabel(),graphics.getYLabel()
+        xLabelWH= dc.GetTextExtent(xLabel)
+        yLabelWH= dc.GetTextExtent(yLabel)
+        return titleWH, xLabelWH, yLabelWH
+    
+    def _legendWH(self, dc, graphics):
+        """Returns the size in screen units for legend box"""
+        if self._legendEnabled != True:
+            legendBoxWH= symExt= txtExt= (0,0)
+        else:
+            # find max symbol size
+            symExt= graphics.getSymExtent(self.printerScale)
+            # find max legend text extent
+            dc.SetFont(self._getFont(self._fontSizeLegend))
+            txtList= graphics.getLegendNames()
+            txtExt= dc.GetTextExtent(txtList[0])
+            for txt in graphics.getLegendNames()[1:]:
+                txtExt= _Numeric.maximum(txtExt,dc.GetTextExtent(txt))
+            maxW= symExt[0]+txtExt[0]    
+            maxH= max(symExt[1],txtExt[1])
+            # padding .1 for lhs of legend box and space between lines
+            maxW= maxW* 1.1
+            maxH= maxH* 1.1 * len(txtList)
+            dc.SetFont(self._getFont(self._fontSizeAxis))
+            legendBoxWH= (maxW,maxH)
+        return (legendBoxWH, symExt, txtExt)
+
+    def _drawRubberBand(self, corner1, corner2):
+        """Draws/erases rect box from corner1 to corner2"""
+        ptx,pty,rectWidth,rectHeight= self._point2ClientCoord(corner1, corner2)
+        # draw rectangle
+        dc = wx.ClientDC( self )
+        dc.BeginDrawing()                 
+        dc.SetPen(wx.Pen(wx.BLACK))
+        dc.SetBrush(wx.Brush( wx.WHITE, wx.TRANSPARENT ) )
+        dc.SetLogicalFunction(wx.INVERT)
+        dc.DrawRectangle( ptx,pty, rectWidth,rectHeight)
+        dc.SetLogicalFunction(wx.COPY)
+        dc.EndDrawing()
+
+    def _getFont(self,size):
+        """Take font size, adjusts if printing and returns wx.Font"""
+        s = size*self.printerScale
+        of = self.GetFont()
+        # Linux speed up to get font from cache rather than X font server
+        key = (int(s), of.GetFamily (), of.GetStyle (), of.GetWeight ())
+        font = self._fontCache.get (key, None)
+        if font:
+            return font                 # yeah! cache hit
+        else:
+            font =  wx.Font(int(s), of.GetFamily(), of.GetStyle(), of.GetWeight())
+            self._fontCache[key] = font
+            return font
+
+
+    def _point2ClientCoord(self, corner1, corner2):
+        """Converts user point coords to client screen int coords x,y,width,height"""
+        c1= _Numeric.array(corner1)
+        c2= _Numeric.array(corner2)
+        # convert to screen coords
+        pt1= c1*self._pointScale+self._pointShift
+        pt2= c2*self._pointScale+self._pointShift
+        # make height and width positive
+        pul= _Numeric.minimum(pt1,pt2) # Upper left corner
+        plr= _Numeric.maximum(pt1,pt2) # Lower right corner
+        rectWidth, rectHeight= plr-pul
+        ptx,pty= pul
+        return ptx, pty, rectWidth, rectHeight 
+    
+    def _axisInterval(self, spec, lower, upper):
+        """Returns sensible axis range for given spec"""
+        if spec == 'none' or spec == 'min':
+            if lower == upper:
+                return lower-0.5, upper+0.5
+            else:
+                return lower, upper
+        elif spec == 'auto':
+            range = upper-lower
+            # if range == 0.:
+            if abs(range) < 1e-36:
+                return lower-0.5, upper+0.5
+            log = _Numeric.log10(range)
+            power = _Numeric.floor(log)
+            fraction = log-power
+            if fraction <= 0.05:
+                power = power-1
+            grid = 10.**power
+            lower = lower - lower % grid
+            mod = upper % grid
+            if mod != 0:
+                upper = upper - mod + grid
+            return lower, upper
+        elif type(spec) == type(()):
+            lower, upper = spec
+            if lower <= upper:
+                return lower, upper
+            else:
+                return upper, lower
+        else:
+            raise ValueError, str(spec) + ': illegal axis specification'
+
+    def _drawAxes(self, dc, p1, p2, scale, shift, xticks, yticks):
+        
+        penWidth= self.printerScale        # increases thickness for printing only
+        dc.SetPen(wx.Pen(wx.NamedColour('BLACK'), penWidth))
+        
+        # set length of tick marks--long ones make grid
+        if self._gridEnabled:
+            x,y,width,height= self._point2ClientCoord(p1,p2)
+            yTickLength= width/2.0 +1
+            xTickLength= height/2.0 +1
+        else:
+            yTickLength= 3 * self.printerScale  # lengthens lines for printing
+            xTickLength= 3 * self.printerScale
+        
+        if self._xSpec is not 'none':
+            lower, upper = p1[0],p2[0]
+            text = 1
+            for y, d in [(p1[1], -xTickLength), (p2[1], xTickLength)]:   # miny, maxy and tick lengths
+                a1 = scale*_Numeric.array([lower, y])+shift
+                a2 = scale*_Numeric.array([upper, y])+shift
+                dc.DrawLine(a1[0],a1[1],a2[0],a2[1])  # draws upper and lower axis line
+                for x, label in xticks:
+                    pt = scale*_Numeric.array([x, y])+shift
+                    dc.DrawLine(pt[0],pt[1],pt[0],pt[1] + d) # draws tick mark d units
+                    if text:
+                        dc.DrawText(label,pt[0],pt[1])
+                text = 0  # axis values not drawn on top side
+
+        if self._ySpec is not 'none':
+            lower, upper = p1[1],p2[1]
+            text = 1
+            h = dc.GetCharHeight()
+            for x, d in [(p1[0], -yTickLength), (p2[0], yTickLength)]:
+                a1 = scale*_Numeric.array([x, lower])+shift
+                a2 = scale*_Numeric.array([x, upper])+shift
+                dc.DrawLine(a1[0],a1[1],a2[0],a2[1])
+                for y, label in yticks:
+                    pt = scale*_Numeric.array([x, y])+shift
+                    dc.DrawLine(pt[0],pt[1],pt[0]-d,pt[1])
+                    if text:
+                        dc.DrawText(label,pt[0]-dc.GetTextExtent(label)[0],
+                                    pt[1]-0.5*h)
+                text = 0    # axis values not drawn on right side
+
+    def _ticks(self, lower, upper):
+        ideal = (upper-lower)/7.
+        log = _Numeric.log10(ideal)
+        power = _Numeric.floor(log)
+        fraction = log-power
+        factor = 1.
+        error = fraction
+        for f, lf in self._multiples:
+            e = _Numeric.fabs(fraction-lf)
+            if e < error:
+                error = e
+                factor = f
+        grid = factor * 10.**power
+        if power > 4 or power < -4:
+            format = '%+7.1e'        
+        elif power >= 0:
+            digits = max(1, int(power))
+            format = '%' + `digits`+'.0f'
+        else:
+            digits = -int(power)
+            format = '%'+`digits+2`+'.'+`digits`+'f'
+        ticks = []
+        t = -grid*_Numeric.floor(-lower/grid)
+        while t <= upper:
+            ticks.append( (t, format % (t,)) )
+            t = t + grid
+        return ticks
+
+    def _scope_ticks (self, lower, upper):
+        '''Always 10 divisions, no labels'''
+        grid = (upper - lower) / 10.0
+        ticks = []
+        t = lower
+        while t <= upper:
+            ticks.append( (t, ""))
+            t = t + grid
+        return ticks
+
+    _multiples = [(2., _Numeric.log10(2.)), (5., _Numeric.log10(5.))]
+
+
+#-------------------------------------------------------------------------------
+# Used to layout the printer page
+
+class PlotPrintout(wx.Printout):
+    """Controls how the plot is made in printing and previewing"""
+    # Do not change method names in this class,
+    # we have to override wx.Printout methods here!
+    def __init__(self, graph):
+        """graph is instance of plotCanvas to be printed or previewed"""
+        wx.Printout.__init__(self)
+        self.graph = graph
+
+    def HasPage(self, page):
+        if page == 1:
+            return True
+        else:
+            return False
+
+    def GetPageInfo(self):
+        return (1, 1, 1, 1)  # disable page numbers
+
+    def OnPrintPage(self, page):
+        dc = self.GetDC()  # allows using floats for certain functions
+##        print "PPI Printer",self.GetPPIPrinter()
+##        print "PPI Screen", self.GetPPIScreen()
+##        print "DC GetSize", dc.GetSize()
+##        print "GetPageSizePixels", self.GetPageSizePixels()
+        # Note PPIScreen does not give the correct number
+        # Calulate everything for printer and then scale for preview
+        PPIPrinter= self.GetPPIPrinter()        # printer dots/inch (w,h)
+        #PPIScreen= self.GetPPIScreen()          # screen dots/inch (w,h)
+        dcSize= dc.GetSize()                    # DC size
+        pageSize= self.GetPageSizePixels() # page size in terms of pixcels
+        clientDcSize= self.graph.GetClientSize()
+        
+        # find what the margins are (mm)
+        margLeftSize,margTopSize= self.graph.pageSetupData.GetMarginTopLeft()
+        margRightSize, margBottomSize= self.graph.pageSetupData.GetMarginBottomRight()
+
+        # calculate offset and scale for dc
+        pixLeft= margLeftSize*PPIPrinter[0]/25.4  # mm*(dots/in)/(mm/in)
+        pixRight= margRightSize*PPIPrinter[0]/25.4    
+        pixTop= margTopSize*PPIPrinter[1]/25.4
+        pixBottom= margBottomSize*PPIPrinter[1]/25.4
+
+        plotAreaW= pageSize[0]-(pixLeft+pixRight)
+        plotAreaH= pageSize[1]-(pixTop+pixBottom)
+
+        # ratio offset and scale to screen size if preview
+        if self.IsPreview():
+            ratioW= float(dcSize[0])/pageSize[0]
+            ratioH= float(dcSize[1])/pageSize[1]
+            pixLeft *= ratioW
+            pixTop *= ratioH
+            plotAreaW *= ratioW
+            plotAreaH *= ratioH
+        
+        # rescale plot to page or preview plot area
+        self.graph._setSize(plotAreaW,plotAreaH)
+        
+        # Set offset and scale
+        dc.SetDeviceOrigin(pixLeft,pixTop)
+
+        # Thicken up pens and increase marker size for printing
+        ratioW= float(plotAreaW)/clientDcSize[0]
+        ratioH= float(plotAreaH)/clientDcSize[1]
+        aveScale= (ratioW+ratioH)/2
+        self.graph._setPrinterScale(aveScale)  # tickens up pens for printing
+
+        self.graph._printDraw(dc)
+        # rescale back to original
+        self.graph._setSize()
+        self.graph._setPrinterScale(1)
+        self.graph.Redraw()     #to get point label scale and shift correct
+
+        return True
+
+
+
+
+#---------------------------------------------------------------------------
+# if running standalone...
+#
+#     ...a sample implementation using the above
+#
+
+def _draw1Objects():
+    # 100 points sin function, plotted as green circles
+    data1 = 2.*_Numeric.pi*_Numeric.arange(200)/200.
+    data1.shape = (100, 2)
+    data1[:,1] = _Numeric.sin(data1[:,0])
+    markers1 = PolyMarker(data1, legend='Green Markers', colour='green', marker='circle',size=1)
+
+    # 50 points cos function, plotted as red line
+    data1 = 2.*_Numeric.pi*_Numeric.arange(100)/100.
+    data1.shape = (50,2)
+    data1[:,1] = _Numeric.cos(data1[:,0])
+    lines = PolyLine(data1, legend= 'Red Line', colour='red')
+
+    # A few more points...
+    pi = _Numeric.pi
+    markers2 = PolyMarker([(0., 0.), (pi/4., 1.), (pi/2, 0.),
+                          (3.*pi/4., -1)], legend='Cross Legend', colour='blue',
+                          marker='cross')
+    
+    return PlotGraphics([markers1, lines, markers2],"Graph Title", "X Axis", "Y Axis")
+
+def _draw2Objects():
+    # 100 points sin function, plotted as green dots
+    data1 = 2.*_Numeric.pi*_Numeric.arange(200)/200.
+    data1.shape = (100, 2)
+    data1[:,1] = _Numeric.sin(data1[:,0])
+    line1 = PolyLine(data1, legend='Green Line', colour='green', width=6, style=wx.DOT)
+
+    # 50 points cos function, plotted as red dot-dash
+    data1 = 2.*_Numeric.pi*_Numeric.arange(100)/100.
+    data1.shape = (50,2)
+    data1[:,1] = _Numeric.cos(data1[:,0])
+    line2 = PolyLine(data1, legend='Red Line', colour='red', width=3, style= wx.DOT_DASH)
+
+    # A few more points...
+    pi = _Numeric.pi
+    markers1 = PolyMarker([(0., 0.), (pi/4., 1.), (pi/2, 0.),
+                          (3.*pi/4., -1)], legend='Cross Hatch Square', colour='blue', width= 3, size= 6,
+                          fillcolour= 'red', fillstyle= wx.CROSSDIAG_HATCH,
+                          marker='square')
+
+    return PlotGraphics([markers1, line1, line2], "Big Markers with Different Line Styles")
+
+def _draw3Objects():
+    markerList= ['circle', 'dot', 'square', 'triangle', 'triangle_down',
+                'cross', 'plus', 'circle']
+    m=[]
+    for i in range(len(markerList)):
+        m.append(PolyMarker([(2*i+.5,i+.5)], legend=markerList[i], colour='blue',
+                          marker=markerList[i]))
+    return PlotGraphics(m, "Selection of Markers", "Minimal Axis", "No Axis")
+
+def _draw4Objects():
+    # 25,000 point line
+    data1 = _Numeric.arange(5e5,1e6,10)
+    data1.shape = (25000, 2)
+    line1 = PolyLine(data1, legend='Wide Line', colour='green', width=5)
+
+    # A few more points...
+    markers2 = PolyMarker(data1, legend='Square', colour='blue',
+                          marker='square')
+    return PlotGraphics([line1, markers2], "25,000 Points", "Value X", "")
+
+def _draw5Objects():
+    # Empty graph with axis defined but no points/lines
+    points=[]
+    line1 = PolyLine(points, legend='Wide Line', colour='green', width=5)
+    return PlotGraphics([line1], "Empty Plot With Just Axes", "Value X", "Value Y")
+
+def _draw6Objects():
+    # Bar graph
+    points1=[(1,0), (1,10)]
+    line1 = PolyLine(points1, colour='green', legend='Feb.', width=10)
+    points1g=[(2,0), (2,4)]
+    line1g = PolyLine(points1g, colour='red', legend='Mar.', width=10)
+    points1b=[(3,0), (3,6)]
+    line1b = PolyLine(points1b, colour='blue', legend='Apr.', width=10)
+
+    points2=[(4,0), (4,12)]
+    line2 = PolyLine(points2, colour='Yellow', legend='May', width=10)
+    points2g=[(5,0), (5,8)]
+    line2g = PolyLine(points2g, colour='orange', legend='June', width=10)
+    points2b=[(6,0), (6,4)]
+    line2b = PolyLine(points2b, colour='brown', legend='July', width=10)
+
+    return PlotGraphics([line1, line1g, line1b, line2, line2g, line2b],
+                        "Bar Graph - (Turn on Grid, Legend)", "Months", "Number of Students")
+
+
+class TestFrame(wx.Frame):
+    def __init__(self, parent, id, title):
+        wx.Frame.__init__(self, parent, id, title,
+                          wx.DefaultPosition, (600, 400))
+
+        # Now Create the menu bar and items
+        self.mainmenu = wx.MenuBar()
+
+        menu = wx.Menu()
+        menu.Append(200, 'Page Setup...', 'Setup the printer page')
+        self.Bind(wx.EVT_MENU, self.OnFilePageSetup, id=200)
+        
+        menu.Append(201, 'Print Preview...', 'Show the current plot on page')
+        self.Bind(wx.EVT_MENU, self.OnFilePrintPreview, id=201)
+        
+        menu.Append(202, 'Print...', 'Print the current plot')
+        self.Bind(wx.EVT_MENU, self.OnFilePrint, id=202)
+        
+        menu.Append(203, 'Save Plot...', 'Save current plot')
+        self.Bind(wx.EVT_MENU, self.OnSaveFile, id=203)
+        
+        menu.Append(205, 'E&xit', 'Enough of this already!')
+        self.Bind(wx.EVT_MENU, self.OnFileExit, id=205)
+        self.mainmenu.Append(menu, '&File')
+
+        menu = wx.Menu()
+        menu.Append(206, 'Draw1', 'Draw plots1')
+        self.Bind(wx.EVT_MENU,self.OnPlotDraw1, id=206)
+        menu.Append(207, 'Draw2', 'Draw plots2')
+        self.Bind(wx.EVT_MENU,self.OnPlotDraw2, id=207)
+        menu.Append(208, 'Draw3', 'Draw plots3')
+        self.Bind(wx.EVT_MENU,self.OnPlotDraw3, id=208)
+        menu.Append(209, 'Draw4', 'Draw plots4')
+        self.Bind(wx.EVT_MENU,self.OnPlotDraw4, id=209)
+        menu.Append(210, 'Draw5', 'Draw plots5')
+        self.Bind(wx.EVT_MENU,self.OnPlotDraw5, id=210)
+        menu.Append(260, 'Draw6', 'Draw plots6')
+        self.Bind(wx.EVT_MENU,self.OnPlotDraw6, id=260)
+       
+
+        menu.Append(211, '&Redraw', 'Redraw plots')
+        self.Bind(wx.EVT_MENU,self.OnPlotRedraw, id=211)
+        menu.Append(212, '&Clear', 'Clear canvas')
+        self.Bind(wx.EVT_MENU,self.OnPlotClear, id=212)
+        menu.Append(213, '&Scale', 'Scale canvas')
+        self.Bind(wx.EVT_MENU,self.OnPlotScale, id=213) 
+        menu.Append(214, 'Enable &Zoom', 'Enable Mouse Zoom', kind=wx.ITEM_CHECK)
+        self.Bind(wx.EVT_MENU,self.OnEnableZoom, id=214) 
+        menu.Append(215, 'Enable &Grid', 'Turn on Grid', kind=wx.ITEM_CHECK)
+        self.Bind(wx.EVT_MENU,self.OnEnableGrid, id=215)
+        menu.Append(220, 'Enable &Legend', 'Turn on Legend', kind=wx.ITEM_CHECK)
+        self.Bind(wx.EVT_MENU,self.OnEnableLegend, id=220)
+        menu.Append(222, 'Enable &Point Label', 'Show Closest Point', kind=wx.ITEM_CHECK)
+        self.Bind(wx.EVT_MENU,self.OnEnablePointLabel, id=222)
+       
+        menu.Append(225, 'Scroll Up 1', 'Move View Up 1 Unit')
+        self.Bind(wx.EVT_MENU,self.OnScrUp, id=225) 
+        menu.Append(230, 'Scroll Rt 2', 'Move View Right 2 Units')
+        self.Bind(wx.EVT_MENU,self.OnScrRt, id=230)
+        menu.Append(235, '&Plot Reset', 'Reset to original plot')
+        self.Bind(wx.EVT_MENU,self.OnReset, id=235)
+
+        self.mainmenu.Append(menu, '&Plot')
+
+        menu = wx.Menu()
+        menu.Append(300, '&About', 'About this thing...')
+        self.Bind(wx.EVT_MENU, self.OnHelpAbout, id=300)
+        self.mainmenu.Append(menu, '&Help')
+
+        self.SetMenuBar(self.mainmenu)
+
+        # A status bar to tell people what's happening
+        self.CreateStatusBar(1)
+        
+        self.client = PlotCanvas(self)
+        #define the function for drawing pointLabels
+        self.client.SetPointLabelFunc(self.DrawPointLabel)
+        # Create mouse event for showing cursor coords in status bar
+        self.client.Bind(wx.EVT_LEFT_DOWN, self.OnMouseLeftDown)
+        # Show closest point when enabled
+        self.client.Bind(wx.EVT_MOTION, self.OnMotion)
+
+        self.Show(True)
+
+    def DrawPointLabel(self, dc, mDataDict):
+        """This is the fuction that defines how the pointLabels are plotted
+            dc - DC that will be passed
+            mDataDict - Dictionary of data that you want to use for the pointLabel
+
+            As an example I have decided I want a box at the curve point
+            with some text information about the curve plotted below.
+            Any wxDC method can be used.
+        """
+        # ----------
+        dc.SetPen(wx.Pen(wx.BLACK))
+        dc.SetBrush(wx.Brush( wx.BLACK, wx.SOLID ) )
+        
+        sx, sy = mDataDict["scaledXY"] #scaled x,y of closest point
+        dc.DrawRectangle( sx-5,sy-5, 10, 10)  #10by10 square centered on point
+        px,py = mDataDict["pointXY"]
+        cNum = mDataDict["curveNum"]
+        pntIn = mDataDict["pIndex"]
+        legend = mDataDict["legend"]
+        #make a string to display
+        s = "Crv# %i, '%s', Pt. (%.2f,%.2f), PtInd %i" %(cNum, legend, px, py, pntIn)
+        dc.DrawText(s, sx , sy+1)
+        # -----------
+
+    def OnMouseLeftDown(self,event):
+        s= "Left Mouse Down at Point: (%.4f, %.4f)" % self.client.GetXY(event)
+        self.SetStatusText(s)
+        event.Skip()            #allows plotCanvas OnMouseLeftDown to be called
+
+    def OnMotion(self, event):
+        #show closest point (when enbled)
+        if self.client.GetEnablePointLabel() == True:
+            #make up dict with info for the pointLabel
+            #I've decided to mark the closest point on the closest curve
+            dlst= self.client.GetClosetPoint( self.client.GetXY(event), pointScaled= True)
+            if dlst != []:    #returns [] if none
+                curveNum, legend, pIndex, pointXY, scaledXY, distance = dlst
+                #make up dictionary to pass to my user function (see DrawPointLabel) 
+                mDataDict= {"curveNum":curveNum, "legend":legend, "pIndex":pIndex,\
+                            "pointXY":pointXY, "scaledXY":scaledXY}
+                #pass dict to update the pointLabel
+                self.client.UpdatePointLabel(mDataDict)
+        event.Skip()           #go to next handler
+
+    def OnFilePageSetup(self, event):
+        self.client.PageSetup()
+        
+    def OnFilePrintPreview(self, event):
+        self.client.PrintPreview()
+        
+    def OnFilePrint(self, event):
+        self.client.Printout()
+        
+    def OnSaveFile(self, event):
+        self.client.SaveFile()
+
+    def OnFileExit(self, event):
+        self.Close()
+
+    def OnPlotDraw1(self, event):
+        self.resetDefaults()
+        self.client.Draw(_draw1Objects())
+    
+    def OnPlotDraw2(self, event):
+        self.resetDefaults()
+        self.client.Draw(_draw2Objects())
+    
+    def OnPlotDraw3(self, event):
+        self.resetDefaults()
+        self.client.SetFont(wx.Font(10,wx.SCRIPT,wx.NORMAL,wx.NORMAL))
+        self.client.SetFontSizeAxis(20)
+        self.client.SetFontSizeLegend(12)
+        self.client.SetXSpec('min')
+        self.client.SetYSpec('none')
+        self.client.Draw(_draw3Objects())
+
+    def OnPlotDraw4(self, event):
+        self.resetDefaults()
+        drawObj= _draw4Objects()
+        self.client.Draw(drawObj)
+##        # profile
+##        start = _time.clock()            
+##        for x in range(10):
+##            self.client.Draw(drawObj)
+##        print "10 plots of Draw4 took: %f sec."%(_time.clock() - start)
+##        # profile end
+
+    def OnPlotDraw5(self, event):
+        # Empty plot with just axes
+        self.resetDefaults()
+        drawObj= _draw5Objects()
+        # make the axis X= (0,5), Y=(0,10)
+        # (default with None is X= (-1,1), Y= (-1,1))
+        self.client.Draw(drawObj, xAxis= (0,5), yAxis= (0,10))
+
+    def OnPlotDraw6(self, event):
+        #Bar Graph Example
+        self.resetDefaults()
+        #self.client.SetEnableLegend(True)   #turn on Legend
+        #self.client.SetEnableGrid(True)     #turn on Grid
+        self.client.SetXSpec('none')        #turns off x-axis scale
+        self.client.SetYSpec('auto')
+        self.client.Draw(_draw6Objects(), xAxis= (0,7))
+
+    def OnPlotRedraw(self,event):
+        self.client.Redraw()
+
+    def OnPlotClear(self,event):
+        self.client.Clear()
+        
+    def OnPlotScale(self, event):
+        if self.client.last_draw != None:
+            graphics, xAxis, yAxis= self.client.last_draw
+            self.client.Draw(graphics,(1,3.05),(0,1))
+
+    def OnEnableZoom(self, event):
+        self.client.SetEnableZoom(event.IsChecked())
+        
+    def OnEnableGrid(self, event):
+        self.client.SetEnableGrid(event.IsChecked())
+        
+    def OnEnableLegend(self, event):
+        self.client.SetEnableLegend(event.IsChecked())
+
+    def OnEnablePointLabel(self, event):
+        self.client.SetEnablePointLabel(event.IsChecked())
+
+    def OnScrUp(self, event):
+        self.client.ScrollUp(1)
+        
+    def OnScrRt(self,event):
+        self.client.ScrollRight(2)
+
+    def OnReset(self,event):
+        self.client.Reset()
+
+    def OnHelpAbout(self, event):
+        from wx.lib.dialogs import ScrolledMessageDialog
+        about = ScrolledMessageDialog(self, __doc__, "About...")
+        about.ShowModal()
+
+    def resetDefaults(self):
+        """Just to reset the fonts back to the PlotCanvas defaults"""
+        self.client.SetFont(wx.Font(10,wx.SWISS,wx.NORMAL,wx.NORMAL))
+        self.client.SetFontSizeAxis(10)
+        self.client.SetFontSizeLegend(7)
+        self.client.SetXSpec('auto')
+        self.client.SetYSpec('auto')
+        
+
+def __test():
+
+    class MyApp(wx.App):
+        def OnInit(self):
+            wx.InitAllImageHandlers()
+            frame = TestFrame(None, -1, "PlotCanvas")
+            #frame.Show(True)
+            self.SetTopWindow(frame)
+            return True
+
+
+    app = MyApp(0)
+    app.MainLoop()
+
+if __name__ == '__main__':
+    __test()
diff --git a/gr-wxgui/src/python/powermate.py b/gr-wxgui/src/python/powermate.py
new file mode 100755 (executable)
index 0000000..36be408
--- /dev/null
@@ -0,0 +1,437 @@
+#!/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 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.
+# 
+
+"""
+Handler for Griffin PowerMate, Contour ShuttlePro & ShuttleXpress USB knobs
+
+This is Linux and wxPython specific.
+"""
+import select
+import os
+import fcntl
+import struct
+import exceptions
+import threading
+import sys
+import wx
+from gnuradio import gru
+
+# First a little bit of background:
+#
+# The Griffin PowerMate has
+#  * a single knob which rotates
+#  * a single button (pressing the knob)
+#
+# The Contour ShuttleXpress (aka SpaceShuttle) has
+#  * "Jog Wheel"  -- the knob (rotary encoder) on the inside
+#  * "Shuttle Ring" -- the spring loaded rubber covered ring
+#  * 5 buttons
+#
+# The Contour ShuttlePro has
+#  * "Jog Wheel" -- the knob (rotary encoder) on the inside
+#  * "Shuttle Ring" -- the spring loaded rubber covered ring
+#  * 13 buttons
+#
+# The Contour ShuttlePro V2 has
+#  *"Jog Wheel" -- the knob (rotary encoder) on the inside
+#  * "Shuttle Ring" -- the spring loaded rubber covered ring
+#  * 15 buttons
+
+# We remap all the buttons on the devices so that they start at zero.
+
+# For the ShuttleXpress the buttons are 0 to 4 (left to right)
+
+# For the ShuttlePro, we number the buttons immediately above
+# the ring 0 to 4 (left to right) so that they match our numbering
+# on the ShuttleXpress.  The top row is 5, 6, 7, 8.  The first row below
+# the ring is 9, 10, and the bottom row is 11, 12.
+
+# For the ShuttlePro V2, buttons 13 & 14 are to the
+# left and right of the wheel respectively.
+
+# We generate 3 kinds of events:
+#
+#   button press/release (button_number, press/release)
+#   knob rotation (relative_clicks)       # typically -1, +1
+#   shuttle position (absolute_position)  # -7,-6,...,0,...,6,7
+
+# ----------------------------------------------------------------
+# Our ID's for the devices:
+# Not to be confused with anything related to magic hardware numbers.
+
+ID_POWERMATE         = 'powermate'
+ID_SHUTTLE_XPRESS    = 'shuttle xpress'
+ID_SHUTTLE_PRO       = 'shuttle pro'
+ID_SHUTTLE_PRO_V2    = 'shuttle pro v2'
+
+# ------------------------------------------------------------------------
+# format of messages that we read from /dev/input/event*
+# See /usr/include/linux/input.h for more info
+#
+#struct input_event {
+#        struct timeval time; = {long seconds, long microseconds}
+#        unsigned short type;
+#        unsigned short code;
+#        unsigned int value;
+#};
+
+input_event_struct = "@llHHi"
+input_event_size = struct.calcsize(input_event_struct)
+
+# ------------------------------------------------------------------------
+# input_event types
+# ------------------------------------------------------------------------
+
+IET_SYN                  = 0x00   # aka RESET
+IET_KEY                  = 0x01   # key or button press/release
+IET_REL                  = 0x02   # relative movement (knob rotation)
+IET_ABS                  = 0x03   # absolute position (graphics pad, etc)
+IET_MSC                  = 0x04
+IET_LED                  = 0x11
+IET_SND                  = 0x12
+IET_REP                  = 0x14
+IET_FF           = 0x15
+IET_PWR                  = 0x16
+IET_FF_STATUS    = 0x17
+IET_MAX                  = 0x1f
+
+# ------------------------------------------------------------------------
+# input_event codes (there are a zillion of them, we only define a few)
+# ------------------------------------------------------------------------
+
+# these are valid for IET_KEY
+
+IEC_BTN_0         = 0x100
+IEC_BTN_1         = 0x101
+IEC_BTN_2         = 0x102
+IEC_BTN_3         = 0x103
+IEC_BTN_4         = 0x104
+IEC_BTN_5         = 0x105
+IEC_BTN_6         = 0x106
+IEC_BTN_7         = 0x107
+IEC_BTN_8         = 0x108
+IEC_BTN_9         = 0x109
+IEC_BTN_10        = 0x10a
+IEC_BTN_11        = 0x10b
+IEC_BTN_12        = 0x10c
+IEC_BTN_13        = 0x10d
+IEC_BTN_14        = 0x10e
+IEC_BTN_15        = 0x10f
+
+# these are valid for IET_REL (Relative axes)
+
+IEC_REL_X         = 0x00
+IEC_REL_Y         = 0x01
+IEC_REL_Z         = 0x02
+IEC_REL_HWHEEL    = 0x06
+IEC_REL_DIAL      = 0x07   # rotating the knob
+IEC_REL_WHEEL     = 0x08   # moving the shuttle ring
+IEC_REL_MISC      = 0x09
+IEC_REL_MAX       = 0x0f
+
+# ------------------------------------------------------------------------
+
+class powermate(threading.Thread):
+    """
+    Interface to Griffin PowerMate and Contour Shuttles
+    """
+    def __init__(self, event_receiver=None, filename=None, **kwargs):
+        self.event_receiver = event_receiver
+        self.handle = -1
+        if filename:
+            if not self._open_device(filename):
+                raise exceptions.RuntimeError, 'Unable to find powermate'
+        else:
+            ok = False
+            for d in range(0, 16):
+                if self._open_device("/dev/input/event%d" % d):
+                    ok = True
+                    break
+            if not ok:
+                raise exceptions.RuntimeError, 'Unable to find powermate'
+
+        threading.Thread.__init__(self, **kwargs)
+        self.setDaemon (1)
+        self.keep_running = True
+        self.start ()
+        
+    def __del__(self):
+        self.keep_running = False
+        if self.handle >= 0:
+            os.close(self.handle)
+            self.handle = -1
+
+    def _open_device(self, filename):
+        try:
+            self.handle = os.open(filename, os.O_RDWR)
+            if self.handle < 0:
+                return False
+
+            # read event device name
+            name = fcntl.ioctl(self.handle, gru.hexint(0x80ff4506), chr(0) * 256)
+            name = name.replace(chr(0), '')
+
+            # do we see anything we recognize?
+            if name == 'Griffin PowerMate' or name == 'Griffin SoundKnob':
+                self.id = ID_POWERMATE
+                self.mapper = _powermate_remapper()
+            elif name == 'CAVS SpaceShuttle A/V' or name == 'Contour Design ShuttleXpress':
+                self.id = ID_SHUTTLE_XPRESS
+                self.mapper = _contour_remapper()
+            elif name == 'Contour Design ShuttlePRO':
+                self.id = ID_SHUTTLE_PRO
+                self.mapper = _contour_remapper()
+            elif name == 'Contour Design ShuttlePRO v2':
+                self.id = ID_SHUTTLE_PRO_V2
+                self.mapper = _contour_remapper()
+            else:
+                os.close(self.handle)
+                self.handle = -1
+                return False
+
+            # get exclusive control of the device, using ioctl EVIOCGRAB
+           # there may be an issue with this on non x86 platforms and if
+           # the _IOW,_IOC,... macros in <asm/ioctl.h> are changed
+            fcntl.ioctl(self.handle,gru.hexint(0x40044590), 1)
+            return True
+        except exceptions.OSError:
+            return False
+
+    
+    def set_event_receiver(self, obj):
+        self.event_receiver = obj
+
+
+    def set_led_state(self, static_brightness, pulse_speed=0,
+                      pulse_table=0, pulse_on_sleep=0, pulse_on_wake=0):
+        """
+        What do these magic values mean...
+        """
+        if self.id != ID_POWERMATE:
+            return False
+        
+        static_brightness &= 0xff;
+        if pulse_speed < 0:
+            pulse_speed = 0
+        if pulse_speed > 510:
+            pulse_speed = 510
+        if pulse_table < 0:
+            pulse_table = 0
+        if pulse_table > 2:
+            pulse_table = 2
+        pulse_on_sleep = not not pulse_on_sleep # not not = convert to 0/1
+        pulse_on_wake  = not not pulse_on_wake
+        magic = (static_brightness
+                 | (pulse_speed << 8)
+                 | (pulse_table << 17)
+                 | (pulse_on_sleep << 19)
+                 | (pulse_on_wake << 20))
+        data = struct.pack(input_event_struct, 0, 0, 0x04, 0x01, magic)
+        os.write(self.handle, data)
+        return True
+
+    def run (self):
+        while (self.keep_running):
+            s = os.read (self.handle, input_event_size)
+            if not s:
+                self.keep_running = False
+                break
+
+            raw_input_event = struct.unpack(input_event_struct,s)
+            sec, usec, type, code, val = self.mapper(raw_input_event)
+            
+            if self.event_receiver is None:
+                continue
+            
+            if type == IET_SYN:    # ignore
+                pass
+            elif type == IET_MSC:  # ignore (seems to be PowerMate reporting led brightness)
+                pass                     
+            elif type == IET_REL and code == IEC_REL_DIAL:
+                #print "Dial: %d" % (val,)
+                wx.PostEvent(self.event_receiver, PMRotateEvent(val))
+            elif type == IET_REL and code == IEC_REL_WHEEL:
+                #print "Shuttle: %d" % (val,)
+                wx.PostEvent(self.event_receiver, PMShuttleEvent(val))
+            elif type == IET_KEY:
+                #print "Key: Btn%d %d" % (code - IEC_BTN_0, val)
+                wx.PostEvent(self.event_receiver,
+                             PMButtonEvent(code - IEC_BTN_0, val))
+            else:
+                print "powermate: unrecognized event: type = 0x%x  code = 0x%x  val = %d" % (type, code, val)
+
+
+class _powermate_remapper(object):
+    def __init__(self):
+        pass
+    def __call__(self, event):
+        """
+        Notice how nice and simple this is...
+        """
+        return event
+
+class _contour_remapper(object):
+    def __init__(self):
+        self.prev = None
+    def __call__(self, event):
+        """
+        ...and how screwed up this is
+        """
+        sec, usec, type, code, val = event
+        if type == IET_REL and code == IEC_REL_WHEEL:
+            # === Shuttle ring ===
+            # First off, this really ought to be IET_ABS, not IET_REL!
+            # They never generate a zero value so you can't
+            # tell when the shuttle ring is back in the center.
+            # We kludge around this by calling both -1 and 1 zero.
+            if val == -1 or val == 1:
+                return (sec, usec, type, code, 0)
+            return event
+
+        if type == IET_REL and code == IEC_REL_DIAL:
+            # === Jog knob (rotary encoder) ===
+            # Dim wits got it wrong again!  This one should return a
+            # a relative value, e.g., -1, +1.  Instead they return
+            # a total that runs modulo 256 (almost!).   For some
+            # reason they count like this 253, 254, 255, 1, 2, 3
+
+            if self.prev is None:                  # first time call
+                self.prev = val
+                return (sec, usec, IET_SYN, 0, 0)  # will be ignored above
+
+            diff = val - self.prev
+            if diff == 0:                          # sometimes it just sends stuff...
+                return (sec, usec, IET_SYN, 0, 0)  # will be ignored above
+
+            if abs(diff) > 100:      # crossed into the twilight zone
+                if self.prev > val:  # we've wrapped going forward
+                    self.prev = val
+                    return (sec, usec, type, code, +1)
+                else:                # we've wrapped going backward
+                    self.prev = val
+                    return (sec, usec, type, code, -1)
+
+            self.prev = val
+            return (sec, usec, type, code, diff)
+
+        if type == IET_KEY:
+            # remap keys so that all 3 gadgets have buttons 0 to 4 in common
+            return (sec, usec, type, 
+                    (IEC_BTN_5, IEC_BTN_6, IEC_BTN_7, IEC_BTN_8,
+                     IEC_BTN_0, IEC_BTN_1, IEC_BTN_2, IEC_BTN_3, IEC_BTN_4,
+                     IEC_BTN_9,  IEC_BTN_10,
+                     IEC_BTN_11, IEC_BTN_12,
+                     IEC_BTN_13, IEC_BTN_14)[code - IEC_BTN_0], val)
+            
+        return event
+
+# ------------------------------------------------------------------------
+# new wxPython event classes
+# ------------------------------------------------------------------------
+
+grEVT_POWERMATE_BUTTON  = wx.NewEventType()
+grEVT_POWERMATE_ROTATE  = wx.NewEventType()
+grEVT_POWERMATE_SHUTTLE = wx.NewEventType()
+
+EVT_POWERMATE_BUTTON = wx.PyEventBinder(grEVT_POWERMATE_BUTTON, 0)
+EVT_POWERMATE_ROTATE = wx.PyEventBinder(grEVT_POWERMATE_ROTATE, 0)
+EVT_POWERMATE_SHUTTLE = wx.PyEventBinder(grEVT_POWERMATE_SHUTTLE, 0)
+
+class PMButtonEvent(wx.PyEvent):
+    def __init__(self, button, value):
+        wx.PyEvent.__init__(self)
+        self.SetEventType(grEVT_POWERMATE_BUTTON)
+        self.button = button
+        self.value = value
+
+    def Clone (self): 
+        self.__class__(self.GetId())
+        
+
+class PMRotateEvent(wx.PyEvent):
+    def __init__(self, delta):
+        wx.PyEvent.__init__(self)
+        self.SetEventType (grEVT_POWERMATE_ROTATE)
+        self.delta = delta
+
+    def Clone (self): 
+        self.__class__(self.GetId())
+
+
+class PMShuttleEvent(wx.PyEvent):
+    def __init__(self, position):
+        wx.PyEvent.__init__(self)
+        self.SetEventType (grEVT_POWERMATE_SHUTTLE)
+        self.position = position
+
+    def Clone (self): 
+        self.__class__(self.GetId())
+        
+# ------------------------------------------------------------------------
+#  Example usage
+# ------------------------------------------------------------------------
+
+if __name__ == '__main__':
+    class Frame(wx.Frame):
+        def __init__(self,parent=None,id=-1,title='Title',
+                     pos=wx.DefaultPosition, size=(400,200)):
+            wx.Frame.__init__(self,parent,id,title,pos,size)
+            EVT_POWERMATE_BUTTON(self, self.on_button)
+            EVT_POWERMATE_ROTATE(self, self.on_rotate)
+            EVT_POWERMATE_SHUTTLE(self, self.on_shuttle)
+            self.brightness = 128
+            self.pulse_speed = 0
+            
+            try:
+                self.pm = powermate(self)
+            except:
+                sys.stderr.write("Unable to find PowerMate or Contour Shuttle\n")
+                sys.exit(1)
+
+            self.pm.set_led_state(self.brightness, self.pulse_speed) 
+
+
+        def on_button(self, evt):
+            print "Button %d %s" % (evt.button,
+                                    ("Released", "Pressed")[evt.value])
+
+        def on_rotate(self, evt):
+            print "Rotated %d" % (evt.delta,)
+            if 0:
+                new = max(0, min(255, self.brightness + evt.delta))
+                if new != self.brightness:
+                    self.brightness = new
+                    self.pm.set_led_state(self.brightness, self.pulse_speed) 
+        
+        def on_shuttle(self, evt):
+            print "Shuttle %d" % (evt.position,)
+        
+    class App(wx.App):
+        def OnInit(self):
+            title='PowerMate Demo'
+            self.frame = Frame(parent=None,id=-1,title=title)
+            self.frame.Show()
+            self.SetTopWindow(self.frame)
+            return True
+
+    app = App()
+    app.MainLoop ()
diff --git a/gr-wxgui/src/python/scopesink.py b/gr-wxgui/src/python/scopesink.py
new file mode 100755 (executable)
index 0000000..f231b3b
--- /dev/null
@@ -0,0 +1,650 @@
+#!/usr/bin/env python
+#
+# Copyright 2003,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 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.
+# 
+
+from gnuradio import gr, gru, eng_notation
+from gnuradio.wxgui import stdgui
+import wx
+import gnuradio.wxgui.plot as plot
+import Numeric
+import threading
+import struct
+
+default_scopesink_size = (640, 240)
+default_v_scale = 1000
+default_frame_decim = gr.prefs().get_long('wxgui', 'frame_decim', 1)
+
+class scope_sink_f(gr.hier_block):
+    def __init__(self, fg, parent, title='', sample_rate=1,
+                 size=default_scopesink_size, frame_decim=default_frame_decim,
+                 v_scale=default_v_scale, t_scale=None):
+        msgq = gr.msg_queue(2)         # message queue that holds at most 2 messages
+        self.guts = gr.oscope_sink_f(sample_rate, msgq)
+        gr.hier_block.__init__(self, fg, self.guts, self.guts)
+        self.win = scope_window(win_info (msgq, sample_rate, frame_decim,
+                                          v_scale, t_scale, self.guts, title), parent)
+
+    def set_sample_rate(self, sample_rate):
+        self.guts.set_sample_rate(sample_rate)
+        self.win.info.set_sample_rate(sample_rate)
+
+class scope_sink_c(gr.hier_block):
+    def __init__(self, fg, parent, title='', sample_rate=1,
+                 size=default_scopesink_size, frame_decim=default_frame_decim,
+                 v_scale=default_v_scale, t_scale=None):
+        msgq = gr.msg_queue(2)         # message queue that holds at most 2 messages
+        c2f = gr.complex_to_float()
+        self.guts = gr.oscope_sink_f(sample_rate, msgq)
+        fg.connect((c2f, 0), (self.guts, 0))
+        fg.connect((c2f, 1), (self.guts, 1))
+        gr.hier_block.__init__(self, fg, c2f, self.guts)
+        self.win = scope_window(win_info(msgq, sample_rate, frame_decim,
+                                         v_scale, t_scale, self.guts, title), parent)
+        
+    def set_sample_rate(self, sample_rate):
+        self.guts.set_sample_rate(sample_rate)
+        self.win.info.set_sample_rate(sample_rate)
+
+# ========================================================================
+# This is the deprecated interface, retained for compatibility...
+#
+# returns (block, win).
+#   block requires a N input stream of float
+#   win is a subclass of wxWindow
+
+def make_scope_sink_f (fg, parent, label, input_rate):
+    block = scope_sink_f(fg, parent, title=label, sample_rate=input_rate)
+    return (block, block.win)
+
+# ========================================================================
+
+
+time_base_list = [                      # time / division
+    1.0e-7,   # 100ns / div
+    2.5e-7,
+    5.0e-7,
+    1.0e-6,   #   1us / div
+    2.5e-6,
+    5.0e-6,
+    1.0e-5,   #  10us / div
+    2.5e-5,
+    5.0e-5,
+    1.0e-4,   # 100us / div
+    2.5e-4,
+    5.0e-4,
+    1.0e-3,   #   1ms / div
+    2.5e-3,
+    5.0e-3,
+    1.0e-2,   #  10ms / div
+    2.5e-2,
+    5.0e-2
+    ]
+
+v_scale_list = [ # counts / div, LARGER gains are SMALLER /div, appear EARLIER
+    2.0e-3,   # 2m / div, don't call it V/div it's actually counts/div
+    5.0e-3,
+    1.0e-2,
+    2.0e-2,
+    5.0e-2,
+    1.0e-1,
+    2.0e-1,
+    5.0e-1,
+    1.0e+0,
+    2.0e+0,
+    5.0e+0,
+    1.0e+1,
+    2.0e+1,
+    5.0e+1,
+    1.0e+2,
+    2.0e+2,
+    5.0e+2,
+    1.0e+3,
+    2.0e+3,
+    5.0e+3,
+    1.0e+4 # 10000 /div, USRP full scale is -/+ 32767
+    ]
+
+    
+wxDATA_EVENT = wx.NewEventType()
+
+def EVT_DATA_EVENT(win, func):
+    win.Connect(-1, -1, wxDATA_EVENT, func)
+
+class DataEvent(wx.PyEvent):
+    def __init__(self, data):
+        wx.PyEvent.__init__(self)
+        self.SetEventType (wxDATA_EVENT)
+        self.data = data
+
+    def Clone (self): 
+        self.__class__ (self.GetId())
+
+
+class win_info (object):
+    __slots__ = ['msgq', 'sample_rate', 'frame_decim', 'v_scale', 
+                 'scopesink', 'title',
+                 'time_scale_cursor', 'v_scale_cursor', 'marker', 'xy',
+                 'autorange', 'running']
+
+    def __init__ (self, msgq, sample_rate, frame_decim, v_scale, t_scale,
+                  scopesink, title = "Oscilloscope"):
+        self.msgq = msgq
+        self.sample_rate = sample_rate
+        self.frame_decim = frame_decim
+        self.scopesink = scopesink
+        self.title = title;
+
+        self.time_scale_cursor = gru.seq_with_cursor(time_base_list, initial_value = t_scale)
+        self.v_scale_cursor = gru.seq_with_cursor(v_scale_list, initial_value = v_scale)
+
+        self.marker = 'line'
+        self.xy = False
+        if v_scale == None:        # 0 and None are both False, but 0 != None
+            self.autorange = True
+        else:
+            self.autorange = False # 0 is a valid v_scale            
+        self.running = True
+
+    def get_time_per_div (self):
+        return self.time_scale_cursor.current ()
+
+    def get_volts_per_div (self):
+        return self.v_scale_cursor.current ()
+
+    def set_sample_rate(self, sample_rate):
+        self.sample_rate = sample_rate
+        
+    def get_sample_rate (self):
+        return self.sample_rate
+
+    def get_decimation_rate (self):
+        return 1.0
+
+    def set_marker (self, s):
+        self.marker = s
+
+    def get_marker (self):
+        return self.marker
+
+
+class input_watcher (threading.Thread):
+    def __init__ (self, msgq, event_receiver, frame_decim, **kwds):
+        threading.Thread.__init__ (self, **kwds)
+        self.setDaemon (1)
+        self.msgq = msgq
+        self.event_receiver = event_receiver
+        self.frame_decim = frame_decim
+        self.iscan = 0
+        self.keep_running = True
+        self.start ()
+
+    def run (self):
+        # print "input_watcher: pid = ", os.getpid ()
+        while (self.keep_running):
+            msg = self.msgq.delete_head()   # blocking read of message queue
+            if self.iscan == 0:            # only display at frame_decim
+                self.iscan = self.frame_decim
+                                
+                nchan = int(msg.arg1())    # number of channels of data in msg
+                nsamples = int(msg.arg2()) # number of samples in each channel
+
+                s = msg.to_string()      # get the body of the msg as a string
+
+                bytes_per_chan = nsamples * gr.sizeof_float
+
+                records = []
+                for ch in range (nchan):
+
+                    start = ch * bytes_per_chan
+                    chan_data = s[start:start+bytes_per_chan]
+                    rec = Numeric.fromstring (chan_data, Numeric.Float32)
+                    records.append (rec)
+
+                # print "nrecords = %d, reclen = %d" % (len (records),nsamples)
+
+                de = DataEvent (records)
+                wx.PostEvent (self.event_receiver, de)
+                records = []
+                del de
+
+            # end if iscan == 0
+            self.iscan -= 1
+    
+
+class scope_window (wx.Panel):
+
+    def __init__ (self, info, parent, id = -1,
+                  pos = wx.DefaultPosition, size = wx.DefaultSize, name = ""):
+        wx.Panel.__init__ (self, parent, -1)
+        self.info = info
+
+        vbox = wx.BoxSizer (wx.VERTICAL)
+
+        self.graph = graph_window (info, self, -1)
+
+        vbox.Add (self.graph, 1, wx.EXPAND)
+        vbox.Add (self.make_control_box(), 0, wx.EXPAND)
+        vbox.Add (self.make_control2_box(), 0, wx.EXPAND)
+
+        self.sizer = vbox
+        self.SetSizer (self.sizer)
+        self.SetAutoLayout (True)
+        self.sizer.Fit (self)
+        self.set_autorange(self.info.autorange)
+        
+
+    # second row of control buttons etc. appears BELOW control_box
+    def make_control2_box (self):
+        ctrlbox = wx.BoxSizer (wx.HORIZONTAL)
+
+        self.inc_v_button = wx.Button (self, 1101, " < ", style=wx.BU_EXACTFIT)
+        self.inc_v_button.SetToolTipString ("Increase vertical range")
+        wx.EVT_BUTTON (self, 1101, self.incr_v_scale) # ID matches button ID above
+
+        self.dec_v_button  = wx.Button (self, 1100, " > ", style=wx.BU_EXACTFIT)
+        self.dec_v_button.SetToolTipString ("Decrease vertical range")
+        wx.EVT_BUTTON (self, 1100, self.decr_v_scale)
+
+        self.v_scale_label = wx.StaticText (self, 1002, "None") # vertical /div
+        self.update_v_scale_label ()
+
+        self.autorange_checkbox = wx.CheckBox (self, 1102, "Autorange")
+        self.autorange_checkbox.SetToolTipString ("Select autorange on/off")
+        wx.EVT_CHECKBOX(self, 1102, self.autorange_checkbox_event)
+
+        ctrlbox.Add ((5,0) ,0) # left margin space
+        ctrlbox.Add (self.inc_v_button, 0, wx.EXPAND)
+        ctrlbox.Add (self.dec_v_button, 0, wx.EXPAND)
+        ctrlbox.Add (self.v_scale_label, 0, wx.ALIGN_CENTER)
+        ctrlbox.Add ((20,0) ,0) # spacer
+        ctrlbox.Add (self.autorange_checkbox, 0, wx.ALIGN_CENTER)
+
+        return ctrlbox
+
+    def make_control_box (self):
+        ctrlbox = wx.BoxSizer (wx.HORIZONTAL)
+
+        tb_left = wx.Button (self, 1001, " < ", style=wx.BU_EXACTFIT)
+        tb_left.SetToolTipString ("Increase time base")
+        wx.EVT_BUTTON (self, 1001, self.incr_timebase)
+
+
+        tb_right  = wx.Button (self, 1000, " > ", style=wx.BU_EXACTFIT)
+        tb_right.SetToolTipString ("Decrease time base")
+        wx.EVT_BUTTON (self, 1000, self.decr_timebase)
+
+        self.time_base_label = wx.StaticText (self, 1002, "")
+        self.update_timebase_label ()
+
+        ctrlbox.Add ((5,0) ,0)
+        # ctrlbox.Add (wx.StaticText (self, -1, "Horiz Scale: "), 0, wx.ALIGN_CENTER)
+        ctrlbox.Add (tb_left, 0, wx.EXPAND)
+        ctrlbox.Add (tb_right, 0, wx.EXPAND)
+        ctrlbox.Add (self.time_base_label, 0, wx.ALIGN_CENTER)
+
+        ctrlbox.Add ((10,0) ,1)            # stretchy space
+
+        ctrlbox.Add (wx.StaticText (self, -1, "Trig: "), 0, wx.ALIGN_CENTER)
+        self.trig_chan_choice = wx.Choice (self, 1004,
+                                           choices = ['Ch1', 'Ch2', 'Ch3', 'Ch4'])
+        self.trig_chan_choice.SetToolTipString ("Select channel for trigger")
+        wx.EVT_CHOICE (self, 1004, self.trig_chan_choice_event)
+        ctrlbox.Add (self.trig_chan_choice, 0, wx.ALIGN_CENTER)
+
+        self.trig_mode_choice = wx.Choice (self, 1005,
+                                           choices = ['Pos', 'Neg', 'Auto'])
+        self.trig_mode_choice.SetToolTipString ("Select trigger slope or Auto (untriggered roll)")
+        wx.EVT_CHOICE (self, 1005, self.trig_mode_choice_event)
+        ctrlbox.Add (self.trig_mode_choice, 0, wx.ALIGN_CENTER)
+
+        trig_level50 = wx.Button (self, 1006, "50%")
+        trig_level50.SetToolTipString ("Set trigger level to 50%")
+        wx.EVT_BUTTON (self, 1006, self.set_trig_level50)
+        ctrlbox.Add (trig_level50, 0, wx.EXPAND)
+
+        run_stop = wx.Button (self, 1007, "Run/Stop")
+        run_stop.SetToolTipString ("Toggle Run/Stop mode")
+        wx.EVT_BUTTON (self, 1007, self.run_stop)
+        ctrlbox.Add (run_stop, 0, wx.EXPAND)
+
+        ctrlbox.Add ((10, 0) ,1)            # stretchy space
+
+        ctrlbox.Add (wx.StaticText (self, -1, "Fmt: "), 0, wx.ALIGN_CENTER)
+        self.marker_choice = wx.Choice (self, 1002, choices = self._marker_choices)
+        self.marker_choice.SetToolTipString ("Select plotting with lines, pluses or dots")
+        wx.EVT_CHOICE (self, 1002, self.marker_choice_event)
+        ctrlbox.Add (self.marker_choice, 0, wx.ALIGN_CENTER)
+
+        self.xy_choice = wx.Choice (self, 1003, choices = ['X:t', 'X:Y'])
+        self.xy_choice.SetToolTipString ("Select X vs time or X vs Y display")
+        wx.EVT_CHOICE (self, 1003, self.xy_choice_event)
+        ctrlbox.Add (self.xy_choice, 0, wx.ALIGN_CENTER)
+
+        return ctrlbox
+    
+    _marker_choices = ['line', 'plus', 'dot']
+
+    def update_timebase_label (self):
+        time_per_div = self.info.get_time_per_div ()
+        s = ' ' + eng_notation.num_to_str (time_per_div) + 's/div'
+        self.time_base_label.SetLabel (s)
+        
+    def decr_timebase (self, evt):
+        self.info.time_scale_cursor.prev ()
+        self.update_timebase_label ()
+
+    def incr_timebase (self, evt):
+        self.info.time_scale_cursor.next ()
+        self.update_timebase_label ()
+
+    def update_v_scale_label (self):
+        volts_per_div = self.info.get_volts_per_div ()
+        s = ' ' + eng_notation.num_to_str (volts_per_div) + '/div' # Not V/div
+        self.v_scale_label.SetLabel (s)
+        
+    def decr_v_scale (self, evt):
+        self.info.v_scale_cursor.prev ()
+        self.update_v_scale_label ()
+
+    def incr_v_scale (self, evt):
+        self.info.v_scale_cursor.next ()
+        self.update_v_scale_label ()
+        
+    def marker_choice_event (self, evt):
+        s = evt.GetString ()
+        self.set_marker (s)
+
+    def set_autorange(self, on):
+        if on:
+            self.v_scale_label.SetLabel(" (auto)")
+            self.info.autorange = True
+            self.autorange_checkbox.SetValue(True)
+            self.inc_v_button.Enable(False)
+            self.dec_v_button.Enable(False)
+        else:
+            if self.graph.y_range:
+                (l,u) = self.graph.y_range # found by autorange
+                self.info.v_scale_cursor.set_index_by_value((u-l)/8.0)
+            self.update_v_scale_label()
+            self.info.autorange = False
+            self.autorange_checkbox.SetValue(False)
+            self.inc_v_button.Enable(True)
+            self.dec_v_button.Enable(True)
+            
+    def autorange_checkbox_event(self, evt):
+        if evt.Checked():
+            self.set_autorange(True)
+        else:
+            self.set_autorange(False)
+            
+    def set_marker (self, s):
+        self.info.set_marker (s)        # set info for drawing routines
+        i = self.marker_choice.FindString (s)
+        assert i >= 0, "Hmmm, set_marker problem"
+        self.marker_choice.SetSelection (i)
+
+    def set_format_line (self):
+        self.set_marker ('line')
+
+    def set_format_dot (self):
+        self.set_marker ('dot')
+
+    def set_format_plus (self):
+        self.set_marker ('plus')
+        
+    def xy_choice_event (self, evt):
+        s = evt.GetString ()
+        self.info.xy = s == 'X:Y'
+
+    def trig_chan_choice_event (self, evt):
+        s = evt.GetString ()
+        ch = int (s[-1]) - 1
+        self.info.scopesink.set_trigger_channel (ch)
+
+    def trig_mode_choice_event (self, evt):
+        sink = self.info.scopesink
+        s = evt.GetString ()
+        if s == 'Pos':
+            sink.set_trigger_mode (gr.gr_TRIG_POS_SLOPE)
+        elif s == 'Neg':
+            sink.set_trigger_mode (gr.gr_TRIG_NEG_SLOPE)
+        elif s == 'Auto':
+            sink.set_trigger_mode (gr.gr_TRIG_AUTO)
+        else:
+            assert 0, "Bad trig_mode_choice string"
+    
+    def set_trig_level50 (self, evt):
+        self.info.scopesink.set_trigger_level_auto ()
+
+    def run_stop (self, evt):
+        self.info.running = not self.info.running
+        
+
+class graph_window (plot.PlotCanvas):
+
+    channel_colors = ['BLUE', 'RED',
+                      'CYAN', 'MAGENTA', 'GREEN', 'YELLOW']
+    
+    def __init__ (self, info, parent, id = -1,
+                  pos = wx.DefaultPosition, size = (640, 240),
+                  style = wx.DEFAULT_FRAME_STYLE, name = ""):
+        plot.PlotCanvas.__init__ (self, parent, id, pos, size, style, name)
+
+        self.SetXUseScopeTicks (True)
+        self.SetEnableGrid (True)
+        self.SetEnableZoom (True)
+        self.SetEnableLegend(True)
+        # self.SetBackgroundColour ('black')
+        
+        self.info = info;
+        self.y_range = None
+        self.x_range = None
+        self.avg_y_min = None
+        self.avg_y_max = None
+        self.avg_x_min = None
+        self.avg_x_max = None
+
+        EVT_DATA_EVENT (self, self.format_data)
+
+        self.input_watcher = input_watcher (info.msgq, self, info.frame_decim)
+
+    def channel_color (self, ch):
+        return self.channel_colors[ch % len(self.channel_colors)]
+       
+    def format_data (self, evt):
+        if not self.info.running:
+            return
+        
+        if self.info.xy:
+            self.format_xy_data (evt)
+            return
+
+        info = self.info
+        records = evt.data
+        nchannels = len (records)
+        npoints = len (records[0])
+
+        objects = []
+
+        Ts = 1.0 / (info.get_sample_rate () / info.get_decimation_rate ())
+        x_vals = Ts * Numeric.arrayrange (-npoints/2, npoints/2)
+
+        # preliminary clipping based on time axis here, instead of in graphics code
+        time_per_window = self.info.get_time_per_div () * 10
+        n = int (time_per_window / Ts + 0.5)
+        n = n & ~0x1                    # make even
+        n = max (2, min (n, npoints))
+
+        self.SetXUseScopeTicks (True)   # use 10 divisions, no labels
+
+        for ch in range(nchannels):
+            r = records[ch]
+
+            # plot middle n points of record
+
+            lb = npoints/2 - n/2
+            ub = npoints/2 + n/2
+            # points = zip (x_vals[lb:ub], r[lb:ub])
+            points = Numeric.zeros ((ub-lb, 2), Numeric.Float64)
+            points[:,0] = x_vals[lb:ub]
+            points[:,1] = r[lb:ub]
+
+            m = info.get_marker ()
+            if m == 'line':
+                objects.append (plot.PolyLine (points,
+                                               colour=self.channel_color (ch),
+                                               legend=('Ch%d' % (ch+1,))))
+            else:
+                objects.append (plot.PolyMarker (points,
+                                                 marker=m,
+                                                 colour=self.channel_color (ch),
+                                                 legend=('Ch%d' % (ch+1,))))
+
+        graphics = plot.PlotGraphics (objects,
+                                      title=self.info.title,
+                                      xLabel = '', yLabel = '')
+
+        time_per_div = info.get_time_per_div ()
+        x_range = (-5.0 * time_per_div, 5.0 * time_per_div) # ranges are tuples!
+        volts_per_div = info.get_volts_per_div ()
+        if not self.info.autorange:
+            self.y_range = (-4.0 * volts_per_div, 4.0 * volts_per_div)
+        self.Draw (graphics, xAxis=x_range, yAxis=self.y_range)
+        self.update_y_range () # autorange to self.y_range
+
+
+    def format_xy_data (self, evt):
+        info = self.info
+        records = evt.data
+        nchannels = len (records)
+        npoints = len (records[0])
+
+        if nchannels < 2:
+            return
+
+        objects = []
+        # points = zip (records[0], records[1])
+        points = Numeric.zeros ((len(records[0]), 2), Numeric.Float32)
+        points[:,0] = records[0]
+        points[:,1] = records[1]
+        
+        self.SetXUseScopeTicks (False)
+
+        m = info.get_marker ()
+        if m == 'line':
+            objects.append (plot.PolyLine (points,
+                                           colour=self.channel_color (0)))
+        else:
+            objects.append (plot.PolyMarker (points,
+                                             marker=m,
+                                             colour=self.channel_color (0)))
+
+        graphics = plot.PlotGraphics (objects,
+                                      title=self.info.title,
+                                      xLabel = 'I', yLabel = 'Q')
+
+        self.Draw (graphics, xAxis=self.x_range, yAxis=self.y_range)
+        self.update_y_range ()
+        self.update_x_range ()
+
+
+    def update_y_range (self):
+        alpha = 1.0/25
+        graphics = self.last_draw[0]
+        p1, p2 = graphics.boundingBox ()     # min, max points of graphics
+
+        if self.avg_y_min: # prevent vertical scale from jumping abruptly --?
+            self.avg_y_min = p1[1] * alpha + self.avg_y_min * (1 - alpha)
+            self.avg_y_max = p2[1] * alpha + self.avg_y_max * (1 - alpha)
+        else: # initial guess
+            self.avg_y_min = p1[1] # -500.0 workaround, sometimes p1 is ~ 10^35
+            self.avg_y_max = p2[1] # 500.0
+
+        self.y_range = self._axisInterval ('auto', self.avg_y_min, self.avg_y_max)
+        # print "p1 %s  p2 %s  y_min %s  y_max %s  y_range %s" \
+        #        % (p1, p2, self.avg_y_min, self.avg_y_max, self.y_range)
+
+
+    def update_x_range (self):
+        alpha = 1.0/25
+        graphics = self.last_draw[0]
+        p1, p2 = graphics.boundingBox ()     # min, max points of graphics
+
+        if self.avg_x_min:
+            self.avg_x_min = p1[0] * alpha + self.avg_x_min * (1 - alpha)
+            self.avg_x_max = p2[0] * alpha + self.avg_x_max * (1 - alpha)
+        else:
+            self.avg_x_min = p1[0]
+            self.avg_x_max = p2[0]
+
+        self.x_range = self._axisInterval ('auto', self.avg_x_min, self.avg_x_max)
+
+
+# ----------------------------------------------------------------
+# Stand-alone test application
+# ----------------------------------------------------------------
+
+class test_app_flow_graph (stdgui.gui_flow_graph):
+    def __init__(self, frame, panel, vbox, argv):
+        stdgui.gui_flow_graph.__init__ (self, frame, panel, vbox, argv)
+
+        if len(argv) > 1:
+            frame_decim = int(argv[1]) 
+        else:
+            frame_decim = 1
+
+        if len(argv) > 2:
+            v_scale = float(argv[2])  # start up at this v_scale value
+        else:
+            v_scale = None  # start up in autorange mode, default
+
+        if len(argv) > 3:
+            t_scale = float(argv[3])  # start up at this t_scale value
+        else:
+            t_scale = None  # old behavior
+
+        print "frame decim %s  v_scale %s  t_scale %s" % (frame_decim,v_scale,t_scale)
+            
+        input_rate = 1e6
+
+        # Generate a complex sinusoid
+        src0 = gr.sig_source_c (input_rate, gr.GR_SIN_WAVE, 25.1e3, 1e3)
+
+        # We add this throttle block so that this demo doesn't suck down
+        # all the CPU available.  You normally wouldn't use it...
+        throttle = gr.throttle(gr.sizeof_gr_complex, input_rate)
+
+        scope = scope_sink_c (self, panel,"Secret Data",sample_rate=input_rate,
+                              frame_decim=frame_decim,
+                              v_scale=v_scale, t_scale=t_scale)
+        vbox.Add (scope.win, 1, wx.EXPAND)
+
+        # wire the blocks together
+        self.connect (src0, throttle, scope)
+
+def main ():
+    app = stdgui.stdapp (test_app_flow_graph, "O'Scope Test App")
+    app.MainLoop ()
+
+if __name__ == '__main__':
+    main ()
+
+# ----------------------------------------------------------------
diff --git a/gr-wxgui/src/python/slider.py b/gr-wxgui/src/python/slider.py
new file mode 100755 (executable)
index 0000000..e8cdcfc
--- /dev/null
@@ -0,0 +1,49 @@
+#!/usr/bin/env python
+
+import wx
+
+def slider(parent, min, max, callback):
+    """
+    Return a wx.Slider object.
+
+    @param min: minimum slider value
+    @type min: float
+    @param max: maximum slider value
+    @type max: float
+    @param callback: function of one arg invoked when slider moves.
+    @rtype: wx.Slider
+    """
+    new_id = wx.NewId()
+    s = wx.Slider(parent, new_id, (max+min)/2, min, max, wx.DefaultPosition,
+                  wx.Size(250,-1), wx.SL_HORIZONTAL | wx.SL_LABELS)
+    wx.EVT_COMMAND_SCROLL(parent, new_id,
+                          lambda evt : callback(evt.GetInt()))
+    return s
+
+
+# ----------------------------------------------------------------
+#                           Demo app
+# ----------------------------------------------------------------
+if __name__ == '__main__':
+
+    from gnuradio.wxgui import stdgui
+
+    class demo_graph(stdgui.gui_flow_graph):
+
+        def __init__(self, frame, panel, vbox, argv):
+            stdgui.gui_flow_graph.__init__ (self, frame, panel, vbox, argv)
+
+            vbox.Add(slider(panel, 23, 47, self.my_callback1), 1, wx.ALIGN_CENTER)
+            vbox.Add(slider(panel, -100, 100, self.my_callback2), 1, wx.ALIGN_CENTER)
+
+        def my_callback1(self, val):
+            print "cb1 = ", val
+
+        def my_callback2(self, val):
+            print "cb2 = ", val
+
+    def main ():
+        app = stdgui.stdapp (demo_graph, "Slider Demo")
+        app.MainLoop ()
+
+    main ()
diff --git a/gr-wxgui/src/python/stdgui.py b/gr-wxgui/src/python/stdgui.py
new file mode 100644 (file)
index 0000000..76cc177
--- /dev/null
@@ -0,0 +1,90 @@
+#
+# 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.
+# 
+
+'''A simple wx gui for GNU Radio applications'''
+
+import wx
+import sys
+from gnuradio import gr
+
+
+class stdapp (wx.App):
+    def __init__ (self, flow_graph_maker, title="GNU Radio", nstatus=2):
+        self.flow_graph_maker = flow_graph_maker
+        self.title = title
+        self._nstatus = nstatus
+        # All our initialization must come before calling wx.App.__init__.
+        # OnInit is called from somewhere in the guts of __init__.
+        wx.App.__init__ (self, redirect=False)
+
+    def OnInit (self):
+        frame = stdframe (self.flow_graph_maker, self.title, self._nstatus)
+        frame.Show (True)
+        self.SetTopWindow (frame)
+        return True
+
+
+class stdframe (wx.Frame):
+    def __init__ (self, flow_graph_maker, title="GNU Radio", nstatus=2):
+        # print "stdframe.__init__"
+        wx.Frame.__init__(self, None, -1, title)
+
+        self.CreateStatusBar (nstatus)
+        mainmenu = wx.MenuBar ()
+
+        menu = wx.Menu ()
+        item = menu.Append (200, 'E&xit', 'Exit')
+        self.Bind (wx.EVT_MENU, self.OnCloseWindow, item)
+        mainmenu.Append (menu, "&File")
+        self.SetMenuBar (mainmenu)
+
+        self.Bind (wx.EVT_CLOSE, self.OnCloseWindow)
+        self.panel = stdpanel (self, self, flow_graph_maker)
+        vbox = wx.BoxSizer(wx.VERTICAL)
+        vbox.Add(self.panel, 1, wx.EXPAND)
+        self.SetSizer(vbox)
+        self.SetAutoLayout(True)
+        vbox.Fit(self)
+
+    def OnCloseWindow (self, event):
+        self.flow_graph().stop()
+        self.Destroy ()
+
+    def flow_graph (self):
+        return self.panel.fg
+    
+class stdpanel (wx.Panel):
+    def __init__ (self, parent, frame, flow_graph_maker):
+        # print "stdpanel.__init__"
+        wx.Panel.__init__ (self, parent, -1)
+        self.frame = frame
+
+        vbox = wx.BoxSizer (wx.VERTICAL)
+        self.fg = flow_graph_maker (frame, self, vbox, sys.argv)
+        self.SetSizer (vbox)
+        self.SetAutoLayout (True)
+        vbox.Fit (self)
+
+        self.fg.start ()
+
+class gui_flow_graph (gr.flow_graph):
+    def __init__ (self, *ignore):
+        gr.flow_graph.__init__ (self)
diff --git a/gr-wxgui/src/python/waterfallsink.py b/gr-wxgui/src/python/waterfallsink.py
new file mode 100755 (executable)
index 0000000..f5a6d24
--- /dev/null
@@ -0,0 +1,469 @@
+#!/usr/bin/env python
+#
+# 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 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.
+# 
+
+from gnuradio import gr, gru, window
+from gnuradio.wxgui import stdgui
+import wx
+import gnuradio.wxgui.plot as plot
+import Numeric
+import os
+import threading
+import math    
+
+default_fftsink_size = (640,240)
+default_fft_rate = gr.prefs().get_long('wxgui', 'fft_rate', 15)
+
+class waterfall_sink_base(object):
+    def __init__(self, input_is_real=False, baseband_freq=0,
+                 sample_rate=1, fft_size=512,
+                 fft_rate=default_fft_rate,
+                 average=False, avg_alpha=None, title=''):
+
+        # initialize common attributes
+        self.baseband_freq = baseband_freq
+        self.sample_rate = sample_rate
+        self.fft_size = fft_size
+        self.fft_rate = fft_rate
+        self.average = average
+        if avg_alpha is None:
+            self.avg_alpha = 2.0 / fft_rate
+        else:
+            self.avg_alpha = avg_alpha
+        self.title = title
+        self.input_is_real = input_is_real
+        (self.r_fd, self.w_fd) = os.pipe()
+
+    def set_average(self, average):
+        self.average = average
+        if average:
+            self.avg.set_taps(self.avg_alpha)
+        else:
+            self.avg.set_taps(1.0)
+
+    def set_avg_alpha(self, avg_alpha):
+        self.avg_alpha = avg_alpha
+
+    def set_baseband_freq(self, baseband_freq):
+        self.baseband_freq = baseband_freq
+
+    def set_sample_rate(self, sample_rate):
+        self.sample_rate = sample_rate
+        self._set_n()
+
+    def _set_n(self):
+        self.one_in_n.set_n(max(1, int(self.sample_rate/self.fft_size/self.fft_rate)))
+        
+class waterfall_sink_f(gr.hier_block, waterfall_sink_base):
+    def __init__(self, fg, 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):
+
+        waterfall_sink_base.__init__(self, input_is_real=True, baseband_freq=baseband_freq,
+                               sample_rate=sample_rate, fft_size=fft_size,
+                               fft_rate=fft_rate,
+                               average=average, avg_alpha=avg_alpha, title=title)
+                               
+        s2p = gr.serial_to_parallel(gr.sizeof_float, self.fft_size)
+        self.one_in_n = gr.keep_one_in_n(gr.sizeof_float * self.fft_size,
+                                         max(1, int(self.sample_rate/self.fft_size/self.fft_rate)))
+        mywindow = window.blackmanharris(self.fft_size)
+        fft = gr.fft_vfc(self.fft_size, True, mywindow)
+        c2mag = gr.complex_to_mag(self.fft_size)
+        self.avg = gr.single_pole_iir_filter_ff(1.0, self.fft_size)
+        log = gr.nlog10_ff(20, self.fft_size, -20*math.log10(self.fft_size))
+        sink = gr.file_descriptor_sink(gr.sizeof_float * self.fft_size, self.w_fd)
+
+        fg.connect (s2p, self.one_in_n, fft, c2mag, self.avg, log, sink)
+        gr.hier_block.__init__(self, fg, s2p, sink)
+
+        self.win = waterfall_window(self, parent, size=size)
+        self.set_average(self.average)
+
+
+class waterfall_sink_c(gr.hier_block, waterfall_sink_base):
+    def __init__(self, fg, 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):
+
+        waterfall_sink_base.__init__(self, input_is_real=False, baseband_freq=baseband_freq,
+                                     sample_rate=sample_rate, fft_size=fft_size,
+                                     fft_rate=fft_rate,
+                                     average=average, avg_alpha=avg_alpha, title=title)
+
+        s2p = gr.serial_to_parallel(gr.sizeof_gr_complex, self.fft_size)
+        self.one_in_n = gr.keep_one_in_n(gr.sizeof_gr_complex * self.fft_size,
+                                         max(1, int(self.sample_rate/self.fft_size/self.fft_rate)))
+
+        mywindow = window.blackmanharris(self.fft_size)
+        fft = gr.fft_vcc(self.fft_size, True, mywindow)
+        c2mag = gr.complex_to_mag(self.fft_size)
+        self.avg = gr.single_pole_iir_filter_ff(1.0, self.fft_size)
+        log = gr.nlog10_ff(20, self.fft_size, -20*math.log10(self.fft_size))
+        sink = gr.file_descriptor_sink(gr.sizeof_float * self.fft_size, self.w_fd)
+
+        fg.connect(s2p, self.one_in_n, fft, c2mag, self.avg, log, sink)
+        gr.hier_block.__init__(self, fg, s2p, sink)
+
+        self.win = waterfall_window(self, parent, size=size)
+        self.set_average(self.average)
+
+
+# ------------------------------------------------------------------------
+
+myDATA_EVENT = wx.NewEventType()
+EVT_DATA_EVENT = wx.PyEventBinder (myDATA_EVENT, 0)
+
+
+class DataEvent(wx.PyEvent):
+    def __init__(self, data):
+        wx.PyEvent.__init__(self)
+        self.SetEventType (myDATA_EVENT)
+        self.data = data
+
+    def Clone (self): 
+        self.__class__ (self.GetId())
+
+
+class input_watcher (threading.Thread):
+    def __init__ (self, file_descriptor, fft_size, event_receiver, **kwds):
+        threading.Thread.__init__ (self, **kwds)
+        self.setDaemon (1)
+        self.file_descriptor = file_descriptor
+        self.fft_size = fft_size
+        self.event_receiver = event_receiver
+        self.keep_running = True
+        self.start ()
+
+    def run (self):
+        while (self.keep_running):
+            s = gru.os_read_exactly (self.file_descriptor,
+                                     gr.sizeof_float * self.fft_size)
+            if not s:
+                self.keep_running = False
+                break
+
+            complex_data = Numeric.fromstring (s, Numeric.Float32)
+            de = DataEvent (complex_data)
+            wx.PostEvent (self.event_receiver, de)
+            del de
+    
+
+class waterfall_window (wx.Panel):
+    def __init__ (self, fftsink, parent, id = -1,
+                  pos = wx.DefaultPosition, size = wx.DefaultSize,
+                  style = wx.DEFAULT_FRAME_STYLE, name = ""):
+        wx.Panel.__init__(self, parent, id, pos, size, style, name)
+
+        self.fftsink = fftsink
+        self.bm = wx.EmptyBitmap(self.fftsink.fft_size, 300, -1)
+
+        self.scale_factor = 5.0           # FIXME should autoscale, or set this
+        
+        dc1 = wx.MemoryDC()
+        dc1.SelectObject(self.bm)
+        dc1.Clear()
+
+        self.pens = self.make_pens()
+
+        wx.EVT_PAINT( self, self.OnPaint )
+        wx.EVT_CLOSE (self, self.on_close_window)
+        EVT_DATA_EVENT (self, self.set_data)
+        
+        self.build_popup_menu()
+        
+        wx.EVT_CLOSE (self, self.on_close_window)
+        self.Bind(wx.EVT_RIGHT_UP, self.on_right_click)
+
+        self.input_watcher = input_watcher(fftsink.r_fd, fftsink.fft_size, self)
+
+
+    def on_close_window (self, event):
+        print "waterfall_window: on_close_window"
+        self.keep_running = False
+
+    def const_list(self,const,len):
+        return [const] * len
+
+    def make_colormap(self):
+        r = []
+        r.extend(self.const_list(0,96))
+        r.extend(range(0,255,4))
+        r.extend(self.const_list(255,64))
+        r.extend(range(255,128,-4))
+        
+        g = []
+        g.extend(self.const_list(0,32))
+        g.extend(range(0,255,4))
+        g.extend(self.const_list(255,64))
+        g.extend(range(255,0,-4))
+        g.extend(self.const_list(0,32))
+        
+        b = range(128,255,4)
+        b.extend(self.const_list(255,64))
+        b.extend(range(255,0,-4))
+        b.extend(self.const_list(0,96))
+        return (r,g,b)
+
+    def make_pens(self):
+        (r,g,b) = self.make_colormap()
+        pens = []
+        for i in range(0,256):
+            colour = wx.Colour(r[i], g[i], b[i])
+            pens.append( wx.Pen(colour, 2, wx.SOLID))
+        return pens
+        
+    def OnPaint(self, event):
+        dc = wx.PaintDC(self)
+        self.DoDrawing(dc)
+
+    def DoDrawing(self, dc=None):
+        if dc is None:
+            dc = wx.ClientDC(self)
+        dc.DrawBitmap(self.bm, 0, 0, False )
+    
+
+    def const_list(self,const,len):
+        a = [const]
+        for i in range(1,len):
+            a.append(const)
+        return a
+
+    def make_colormap(self):
+        r = []
+        r.extend(self.const_list(0,96))
+        r.extend(range(0,255,4))
+        r.extend(self.const_list(255,64))
+        r.extend(range(255,128,-4))
+        
+        g = []
+        g.extend(self.const_list(0,32))
+        g.extend(range(0,255,4))
+        g.extend(self.const_list(255,64))
+        g.extend(range(255,0,-4))
+        g.extend(self.const_list(0,32))
+        
+        b = range(128,255,4)
+        b.extend(self.const_list(255,64))
+        b.extend(range(255,0,-4))
+        b.extend(self.const_list(0,96))
+        return (r,g,b)
+
+    def set_data (self, evt):
+        dB = evt.data
+        L = len (dB)
+
+        dc1 = wx.MemoryDC()
+        dc1.SelectObject(self.bm)
+        dc1.Blit(0,1,self.fftsink.fft_size,300,dc1,0,0,wx.COPY,False,-1,-1)
+
+        x = max(abs(self.fftsink.sample_rate), abs(self.fftsink.baseband_freq))
+        if x >= 1e9:
+            sf = 1e-9
+            units = "GHz"
+        elif x >= 1e6:
+            sf = 1e-6
+            units = "MHz"
+        else:
+            sf = 1e-3
+            units = "kHz"
+
+
+        if self.fftsink.input_is_real:     # only plot 1/2 the points
+            d_max = L/2
+            p_width = 2
+        else:
+            d_max = L/2
+            p_width = 1
+
+        scale_factor = self.scale_factor
+        if self.fftsink.input_is_real:     # real fft
+           for x_pos in range(0, d_max):
+               value = int(dB[x_pos] * scale_factor)
+               value = min(255, max(0, value))
+               dc1.SetPen(self.pens[value])
+               dc1.DrawRectangle(x_pos*p_width, 0, p_width, 1) 
+        else:                               # complex fft
+           for x_pos in range(0, d_max):    # positive freqs
+               value = int(dB[x_pos] * scale_factor)
+               value = min(255, max(0, value))
+               dc1.SetPen(self.pens[value])
+               dc1.DrawRectangle(x_pos*p_width + d_max, 0, p_width, 1) 
+           for x_pos in range(0 , d_max):   # negative freqs
+               value = int(dB[x_pos+d_max] * scale_factor)
+               value = min(255, max(0, value))
+               dc1.SetPen(self.pens[value])
+               dc1.DrawRectangle(x_pos*p_width, 0, p_width, 1) 
+
+        self.DoDrawing (None)
+
+    def on_average(self, evt):
+        # print "on_average"
+        self.fftsink.set_average(evt.IsChecked())
+
+    def on_right_click(self, event):
+        menu = self.popup_menu
+        for id, pred in self.checkmarks.items():
+            item = menu.FindItemById(id)
+            item.Check(pred())
+        self.PopupMenu(menu, event.GetPosition())
+
+
+    def build_popup_menu(self):
+        self.id_incr_ref_level = wx.NewId()
+        self.id_decr_ref_level = wx.NewId()
+        self.id_incr_y_per_div = wx.NewId()
+        self.id_decr_y_per_div = wx.NewId()
+        self.id_y_per_div_1 = wx.NewId()
+        self.id_y_per_div_2 = wx.NewId()
+        self.id_y_per_div_5 = wx.NewId()
+        self.id_y_per_div_10 = wx.NewId()
+        self.id_y_per_div_20 = wx.NewId()
+        self.id_average = wx.NewId()
+
+        self.Bind(wx.EVT_MENU, self.on_average, id=self.id_average)
+        #self.Bind(wx.EVT_MENU, self.on_incr_ref_level, id=self.id_incr_ref_level)
+        #self.Bind(wx.EVT_MENU, self.on_decr_ref_level, id=self.id_decr_ref_level)
+        #self.Bind(wx.EVT_MENU, self.on_incr_y_per_div, id=self.id_incr_y_per_div)
+        #self.Bind(wx.EVT_MENU, self.on_decr_y_per_div, id=self.id_decr_y_per_div)
+        #self.Bind(wx.EVT_MENU, self.on_y_per_div, id=self.id_y_per_div_1)
+        #self.Bind(wx.EVT_MENU, self.on_y_per_div, id=self.id_y_per_div_2)
+        #self.Bind(wx.EVT_MENU, self.on_y_per_div, id=self.id_y_per_div_5)
+        #self.Bind(wx.EVT_MENU, self.on_y_per_div, id=self.id_y_per_div_10)
+        #self.Bind(wx.EVT_MENU, self.on_y_per_div, id=self.id_y_per_div_20)
+
+
+        # make a menu
+        menu = wx.Menu()
+        self.popup_menu = menu
+        menu.AppendCheckItem(self.id_average, "Average")
+        # menu.Append(self.id_incr_ref_level, "Incr Ref Level")
+        # menu.Append(self.id_decr_ref_level, "Decr Ref Level")
+        # menu.Append(self.id_incr_y_per_div, "Incr dB/div")
+        # menu.Append(self.id_decr_y_per_div, "Decr dB/div")
+        # menu.AppendSeparator()
+        # we'd use RadioItems for these, but they're not supported on Mac
+        #menu.AppendCheckItem(self.id_y_per_div_1, "1 dB/div")
+        #menu.AppendCheckItem(self.id_y_per_div_2, "2 dB/div")
+        #menu.AppendCheckItem(self.id_y_per_div_5, "5 dB/div")
+        #menu.AppendCheckItem(self.id_y_per_div_10, "10 dB/div")
+        #menu.AppendCheckItem(self.id_y_per_div_20, "20 dB/div")
+
+        self.checkmarks = {
+            self.id_average : lambda : self.fftsink.average
+            #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,
+            #self.id_y_per_div_5 : lambda : self.fftsink.y_per_div == 5,
+            #self.id_y_per_div_10 : lambda : self.fftsink.y_per_div == 10,
+            #self.id_y_per_div_20 : lambda : self.fftsink.y_per_div == 20,
+            }
+
+
+def next_up(v, seq):
+    """
+    Return the first item in seq that is > v.
+    """
+    for s in seq:
+        if s > v:
+            return s
+    return v
+
+def next_down(v, seq):
+    """
+    Return the last item in seq that is < v.
+    """
+    rseq = list(seq[:])
+    rseq.reverse()
+
+    for s in rseq:
+        if s < v:
+            return s
+    return v
+
+
+# ----------------------------------------------------------------
+#                    Deprecated interfaces
+# ----------------------------------------------------------------
+
+# returns (block, win).
+#   block requires a single input stream of float
+#   win is a subclass of wxWindow
+
+def make_waterfall_sink_f(fg, parent, title, fft_size, input_rate):
+    
+    block = waterfall_sink_f(fg, parent, title=title, fft_size=fft_size,
+                             sample_rate=input_rate)
+    return (block, block.win)
+
+# returns (block, win).
+#   block requires a single input stream of gr_complex
+#   win is a subclass of wxWindow
+
+def make_waterfall_sink_c(fg, parent, title, fft_size, input_rate):
+    block = waterfall_sink_c(fg, parent, title=title, fft_size=fft_size,
+                             sample_rate=input_rate)
+    return (block, block.win)
+
+
+# ----------------------------------------------------------------
+# Standalone test app
+# ----------------------------------------------------------------
+
+class test_app_flow_graph (stdgui.gui_flow_graph):
+    def __init__(self, frame, panel, vbox, argv):
+        stdgui.gui_flow_graph.__init__ (self, frame, panel, vbox, argv)
+
+        fft_size = 512
+
+        # build our flow graph
+        input_rate = 20.000e3
+
+        # Generate a complex sinusoid
+        src1 = gr.sig_source_c (input_rate, gr.GR_SIN_WAVE, 5.75e3, 1000)
+        #src1 = gr.sig_source_c (input_rate, gr.GR_CONST_WAVE, 5.75e3, 1000)
+
+        # We add these throttle blocks so that this demo doesn't
+        # suck down all the CPU available.  Normally you wouldn't use these.
+        thr1 = gr.throttle(gr.sizeof_gr_complex, input_rate)
+
+        sink1 = waterfall_sink_c (self, panel, title="Complex Data", fft_size=fft_size,
+                                  sample_rate=input_rate, baseband_freq=100e3)
+        vbox.Add (sink1.win, 1, wx.EXPAND)
+        self.connect (src1, thr1, sink1)
+
+        # generate a real sinusoid
+        src2 = gr.sig_source_f (input_rate, gr.GR_SIN_WAVE, 5.75e3, 1000)
+        #src2 = gr.sig_source_f (input_rate, gr.GR_CONST_WAVE, 5.75e3, 1000)
+        thr2 = gr.throttle(gr.sizeof_float, input_rate)
+        sink2 = waterfall_sink_f (self, panel, title="Real Data", fft_size=fft_size,
+                                  sample_rate=input_rate, baseband_freq=100e3)
+        vbox.Add (sink2.win, 1, wx.EXPAND)
+        self.connect (src2, thr2, sink2)
+
+def main ():
+    app = stdgui.stdapp (test_app_flow_graph,
+                         "Waterfall Sink Test App")
+    app.MainLoop ()
+
+if __name__ == '__main__':
+    main ()
diff --git a/pmt/AUTHORS b/pmt/AUTHORS
new file mode 100644 (file)
index 0000000..ee4560a
--- /dev/null
@@ -0,0 +1 @@
+Eric Blossom <eb@comsec.com>
diff --git a/pmt/ChangeLog b/pmt/ChangeLog
new file mode 100644 (file)
index 0000000..385dbc6
--- /dev/null
@@ -0,0 +1,20 @@
+#
+# 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 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.
+# 
diff --git a/pmt/Makefile.am b/pmt/Makefile.am
new file mode 100644 (file)
index 0000000..d16c469
--- /dev/null
@@ -0,0 +1,25 @@
+#
+# 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.
+# 
+
+include $(top_srcdir)/Makefile.common
+
+SUBDIRS = src
+DIST_SUBDIRS = src doc
diff --git a/pmt/README b/pmt/README
new file mode 100644 (file)
index 0000000..a578506
--- /dev/null
@@ -0,0 +1,45 @@
+#
+# 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 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 directory hierarchy contains an implementation of 
+polymorphic types.  These are similar to lisp or python data objects,
+and implement transparent reference counting using the boost shared_ptr
+templates.
+
+To build the examples from the tarball use the normal recipe:
+
+  $ ./configure
+  $ make
+  $ make check
+
+If you're building from CVS, you'll need to use this sequence, since
+CVS doesn't contain configure or the generated Makefiles.
+
+  $ ./bootstrap
+  $ ./configure
+  $ make
+  $ make check
+
+
+The doc directory is not built by default.  This is to avoid spurious
+build problems on systems that don't have xmlto installed.  If you
+have xmlto and its dependencies installed, you can build the html
+version of the howto article by cd'ing to doc and invoking make.
diff --git a/pmt/doc/Makefile.am b/pmt/doc/Makefile.am
new file mode 100644 (file)
index 0000000..2774a84
--- /dev/null
@@ -0,0 +1,43 @@
+#
+# Copyright 2004,2005,2006 Free Software Foundation, Inc.
+# 
+# This file is part of GNU Radio
+# 
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 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.
+# 
+
+TARGETS = 
+
+
+# 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 =                           
+
+BUILT_XML_FILES =                      
+
+
+# ----------------------------------------------------------------
+
+clean:
+       -rm -f $(TARGETS) $(BUILT_XML_FILES)
+
+%.html : %.xml
+       xmlto html-nochunks $<
diff --git a/pmt/src/Makefile.am b/pmt/src/Makefile.am
new file mode 100644 (file)
index 0000000..8b32a22
--- /dev/null
@@ -0,0 +1,22 @@
+#
+# 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 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.
+# 
+
+SUBDIRS = lib
diff --git a/pmt/src/lib/Makefile.am b/pmt/src/lib/Makefile.am
new file mode 100644 (file)
index 0000000..2f3eab7
--- /dev/null
@@ -0,0 +1,71 @@
+#
+# 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 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.
+# 
+
+include $(top_srcdir)/Makefile.common
+
+TESTS = test_pmt
+
+lib_LTLIBRARIES = libpmt.la libpmt-qa.la
+
+# These are the source files that go into the pmt shared library
+libpmt_la_SOURCES =                    \
+       pmt.cc
+
+# magic flags
+libpmt_la_LDFLAGS = $(NO_UNDEFINED) -avoid-version
+
+# link the library against the c++ standard library
+libpmt_la_LIBADD =                     \
+       -lstdc++                        
+
+include_HEADERS =                      \
+       pmt.h
+
+noinst_HEADERS =                       \
+       pmt_int.h                       \
+       qa_pmt.h                        \
+       qa_pmt_prims.h                  
+
+
+# Build the qa code into its own library
+
+libpmt_qa_la_SOURCES =                 \
+       qa_pmt.cc                       \
+       qa_pmt_prims.cc                 
+
+# magic flags
+libpmt_qa_la_LDFLAGS = $(NO_UNDEFINED) -avoid-version
+
+# link the library against the c++ standard library
+libpmt_qa_la_LIBADD =                  \
+       $(CPPUNIT_LIBS)                 \
+       -lstdc++                        
+
+
+noinst_PROGRAMS        =                       \
+       test_pmt
+
+
+LIBPMT   = libpmt.la
+LIBPMTQA = libpmt-qa.la $(LIBPMT)
+
+test_pmt_SOURCES = test_pmt.cc
+test_pmt_LDADD   = $(LIBPMTQA)
diff --git a/pmt/src/lib/pmt.cc b/pmt/src/lib/pmt.cc
new file mode 100644 (file)
index 0000000..a1569e4
--- /dev/null
@@ -0,0 +1,705 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <vector>
+#include <pmt.h>
+#include "pmt_int.h"
+
+pmt_base::~pmt_base()
+{
+  // nop -- out of line virtual destructor
+}
+
+////////////////////////////////////////////////////////////////////////////
+//                         Exceptions
+////////////////////////////////////////////////////////////////////////////
+
+pmt_exception::pmt_exception(const char *msg, pmt_t obj)
+  : d_msg(msg), d_obj(obj)
+{
+}
+
+pmt_wrong_type::pmt_wrong_type(const char *msg, pmt_t obj)
+  : pmt_exception(msg, obj)
+{
+}
+
+pmt_out_of_range::pmt_out_of_range(const char *msg, pmt_t obj)
+  : pmt_exception(msg, 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_dict *
+_dict(pmt_t x)
+{
+  return dynamic_cast<pmt_dict*>(x.get());
+}
+
+////////////////////////////////////////////////////////////////////////////
+//                           Booleans
+////////////////////////////////////////////////////////////////////////////
+
+const pmt_t PMT_BOOL_T = pmt_t(new pmt_bool());                // singleton
+const pmt_t PMT_BOOL_F = pmt_t(new pmt_bool());                // singleton
+
+pmt_bool::pmt_bool(){}
+
+bool
+pmt_is_true(pmt_t obj)
+{
+  return obj != PMT_BOOL_F;
+}
+
+bool
+pmt_is_false(pmt_t obj)
+{
+  return obj == PMT_BOOL_F;
+}
+
+bool
+pmt_is_bool(pmt_t obj)
+{
+  return obj->is_bool();
+}
+
+pmt_t
+pmt_from_bool(bool val)
+{
+  return val ? PMT_BOOL_T : PMT_BOOL_F;
+}
+
+bool
+pmt_to_bool(pmt_t val)
+{
+  if (val == PMT_BOOL_T)
+    return true;
+  if (val == PMT_BOOL_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(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;
+}
+
+const std::string
+pmt_symbol_to_string(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)
+{
+  if (x->is_integer())
+    return _integer(x)->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
+////////////////////////////////////////////////////////////////////////////
+
+const pmt_t PMT_NIL = pmt_t(new pmt_null());           // singleton
+
+pmt_null::pmt_null() {}
+pmt_pair::pmt_pair(pmt_t car, pmt_t cdr) : d_car(car), d_cdr(cdr) {}
+
+bool
+pmt_is_null(pmt_t x)
+{
+  return x == PMT_NIL;
+}
+
+bool
+pmt_is_pair(pmt_t obj)
+{
+  return obj->is_pair();
+}
+
+pmt_t
+pmt_cons(pmt_t x, pmt_t y)
+{
+  return pmt_t(new pmt_pair(x, y));
+}
+
+pmt_t
+pmt_car(pmt_t pair)
+{
+  if (pair->is_pair())
+    return _pair(pair)->car();
+  
+  throw pmt_wrong_type("pmt_car", pair);
+}
+
+pmt_t
+pmt_cdr(pmt_t pair)
+{
+  if (pair->is_pair())
+    return _pair(pair)->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);
+}
+
+////////////////////////////////////////////////////////////////////////////
+//                            Dictionaries
+////////////////////////////////////////////////////////////////////////////
+
+pmt_dict::pmt_dict()
+  : d_alist(PMT_NIL)
+{
+}
+
+void
+pmt_dict::set(pmt_t key, pmt_t value)
+{
+  pmt_t        p = pmt_assv(key, d_alist);     // look for (key . value) pair
+  if (pmt_is_pair(p)){                 // found existing pair...
+    pmt_set_cdr(p, value);             // overrwrite cdr with new value
+  }
+  else {                               // not in the dict
+    d_alist = pmt_cons(pmt_cons(key, value), d_alist); // add new (key . value) pair
+  }
+}
+
+pmt_t
+pmt_dict::ref(pmt_t key, pmt_t not_found) const
+{
+  pmt_t        p = pmt_assv(key, d_alist);     // look for (key . value) pair
+  if (pmt_is_pair(p))
+    return pmt_cdr(p);
+  else
+    return not_found;
+}
+
+bool
+pmt_dict::has_key(pmt_t key) const
+{
+  return pmt_is_pair(pmt_assv(key, d_alist));
+}
+
+pmt_t
+pmt_dict::items() const
+{
+  return d_alist;
+}
+
+pmt_t
+pmt_dict::keys() const
+{
+  return pmt_map(pmt_car, d_alist);
+}
+
+pmt_t
+pmt_dict::values() const
+{
+  return pmt_map(pmt_cdr, d_alist);
+}
+
+bool
+pmt_is_dict(pmt_t obj)
+{
+  return obj->is_dict();
+}
+
+pmt_t
+pmt_make_dict()
+{
+  return pmt_t(new pmt_dict());
+}
+
+void
+pmt_dict_set(pmt_t dict, pmt_t key, pmt_t value)
+{
+  if (!dict->is_dict())
+    throw pmt_wrong_type("pmt_dict_set", dict);
+
+  _dict(dict)->set(key, value);
+}
+
+bool
+pmt_dict_has_key(pmt_t dict, pmt_t key)
+{
+  if (!dict->is_dict())
+    throw pmt_wrong_type("pmt_dict_has_key", dict);
+
+  return _dict(dict)->has_key(key);
+}
+
+pmt_t
+pmt_dict_ref(pmt_t dict, pmt_t key, pmt_t not_found)
+{
+  if (!dict->is_dict())
+    throw pmt_wrong_type("pmt_dict_ref", dict);
+
+  return _dict(dict)->ref(key, not_found);
+}
+
+pmt_t
+pmt_dict_items(pmt_t dict)
+{
+  if (!dict->is_dict())
+    throw pmt_wrong_type("pmt_dict_items", dict);
+
+  return _dict(dict)->items();
+}
+
+pmt_t
+pmt_dict_keys(pmt_t dict)
+{
+  if (!dict->is_dict())
+    throw pmt_wrong_type("pmt_dict_keys", dict);
+
+  return _dict(dict)->keys();
+}
+
+pmt_t
+pmt_dict_values(pmt_t dict)
+{
+  if (!dict->is_dict())
+    throw pmt_wrong_type("pmt_dict_values", dict);
+
+  return _dict(dict)->values();
+}
+
+////////////////////////////////////////////////////////////////////////////
+//                          General Functions
+////////////////////////////////////////////////////////////////////////////
+
+bool
+pmt_eq(pmt_t x, pmt_t y)
+{
+  return x == y;
+}
+
+bool
+pmt_eqv(pmt_t x, 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_equal(pmt_t x, 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;
+  }
+
+  // FIXME add other cases here...
+
+  return false;
+}
+
+size_t
+pmt_length(pmt_t x)
+{
+  if (x->is_vector())
+    return _vector(x)->length();
+
+  // FIXME list length
+  // FIXME uniform vector length
+  // 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_BOOL_F;
+
+    if (pmt_eq(obj, pmt_car(p)))
+      return p;
+
+    alist = pmt_cdr(alist);
+  }
+  return PMT_BOOL_F;
+}
+
+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_BOOL_F;
+
+    if (pmt_eqv(obj, pmt_car(p)))
+      return p;
+
+    alist = pmt_cdr(alist);
+  }
+  return PMT_BOOL_F;
+}
+
+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_BOOL_F;
+
+    if (pmt_equal(obj, pmt_car(p)))
+      return p;
+
+    alist = pmt_cdr(alist);
+  }
+  return PMT_BOOL_F;
+}
+
+pmt_t
+pmt_map(pmt_t proc(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);
+}
diff --git a/pmt/src/lib/pmt.h b/pmt/src/lib/pmt.h
new file mode 100644 (file)
index 0000000..b27b7ce
--- /dev/null
@@ -0,0 +1,554 @@
+/* -*- 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 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.
+ */
+
+#ifndef INCLUDED_PMT_H
+#define INCLUDED_PMT_H
+
+#include <boost/shared_ptr.hpp>
+#include <complex>
+#include <string>
+#include <stdint.h>
+#include <iostream>
+
+/*!
+ * 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.
+ */
+
+/*!
+ * \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::shared_ptr<pmt_base> pmt_t;
+
+
+class pmt_exception
+{
+  const char *d_msg;
+  pmt_t              d_obj;
+
+public:
+  pmt_exception(const char *msg, pmt_t obj);
+  const char *msg() { return d_msg; }
+  pmt_t obj() { return d_obj; }
+};
+
+class pmt_wrong_type : public pmt_exception
+{
+public:
+  pmt_wrong_type(const char *msg, pmt_t obj);
+};
+
+class pmt_out_of_range : public pmt_exception
+{
+public:
+  pmt_out_of_range(const char *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_BOOL_T; //< #t : boolean true constant
+extern const pmt_t PMT_BOOL_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_BOOL_T, return false when val is PMT_BOOL_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(pmt_t obj);
+
+//! Return the symbol whose name is \p s.
+pmt_t pmt_string_to_symbol(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(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(pmt_t x);
+
+//! Return true if \p obj is a pair, else false.
+bool pmt_is_pair(pmt_t obj);
+
+//! Return a newly allocated pair whose car is \p x and whose cdr is \p y.
+pmt_t pmt_cons(pmt_t x, pmt_t y);
+
+//! If \p pair is a pair, return the car of the \p pair, otherwise raise wrong_type.
+pmt_t pmt_car(pmt_t pair);
+
+//! If \p pair is a pair, return the cdr of the \p pair, otherwise raise wrong_type.
+pmt_t pmt_cdr(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);
+
+/*
+ * ------------------------------------------------------------------------
+ *                            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);
+
+/*!
+ * <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, uint8_t *data);
+pmt_t pmt_init_s8vector(size_t k, int8_t *data);
+pmt_t pmt_init_u16vector(size_t k, uint16_t *data);
+pmt_t pmt_init_s16vector(size_t k, int16_t *data);
+pmt_t pmt_init_u32vector(size_t k, uint32_t *data);
+pmt_t pmt_init_s32vector(size_t k, int32_t *data);
+pmt_t pmt_init_u64vector(size_t k, uint64_t *data);
+pmt_t pmt_init_s64vector(size_t k, int64_t *data);
+pmt_t pmt_init_f32vector(size_t k, float *data);
+pmt_t pmt_init_f64vector(size_t k, double *data);
+pmt_t pmt_init_c32vector(size_t k, std::complex<float> *data);
+pmt_t pmt_init_c64vector(size_t k, 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_writeable_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)
+ * ------------------------------------------------------------------------
+ */
+
+//! Return true if \p obj is a dictionary
+bool pmt_is_dict(pmt_t obj);
+
+//! make an empty dictionary
+pmt_t pmt_make_dict();
+
+//! dict[key] = value
+void  pmt_dict_set(pmt_t dict, pmt_t key, pmt_t value);
+
+//! Return true if \p key exists in \p dict
+bool  pmt_dict_has_key(pmt_t dict, pmt_t key);
+
+//! If \p key exists in \p dict, return associated value; otherwise return \p not_found.
+pmt_t pmt_dict_ref(pmt_t dict, pmt_t key, 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);
+
+/*
+ * ------------------------------------------------------------------------
+ *                       General functions
+ * ------------------------------------------------------------------------
+ */
+
+//! Return true if x and y are the same object; otherwise return false.
+bool pmt_eq(pmt_t x, 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(pmt_t x, 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(pmt_t x, pmt_t y);
+
+
+//! Return the number of elements in v
+size_t pmt_length(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(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);
+}
+
+/*
+ * ------------------------------------------------------------------------
+ *                          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);
+
+/*
+ * ------------------------------------------------------------------------
+ *                   portable byte stream representation
+ * ------------------------------------------------------------------------
+ */
+/*!
+ * \brief Write portable byte-serial representation of \p obj to \p sink
+ */
+void pmt_serialize(pmt_t obj, std::ostream &sink);
+
+/*!
+ * \brief Create obj from portable byte-serial representation
+ */
+pmt_t pmt_deserialize(std::istream &source);
+
+#endif /* INCLUDED_PMT_H */
diff --git a/pmt/src/lib/pmt_int.h b/pmt/src/lib/pmt_int.h
new file mode 100644 (file)
index 0000000..7335464
--- /dev/null
@@ -0,0 +1,178 @@
+/* -*- 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 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.
+ */
+#ifndef INCLUDED_PMT_INT_H
+#define INCLUDED_PMT_INT_H
+
+#include <pmt.h>
+
+/*
+ * EVERYTHING IN THIS FILE IS PRIVATE TO THE IMPLEMENTATION!
+ *
+ * See pmt.h for the public interface
+ */
+
+class pmt_base {
+protected:
+  pmt_base(){};
+  virtual ~pmt_base();
+
+private:
+  pmt_base(const pmt_base& rhs);               // NOT IMPLEMENTED
+  pmt_base& operator=(const pmt_base& rhs);    // NOT IMPLEMENTED
+  
+
+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_vector()  const { return false; }
+  virtual bool is_dict()    const { return false; }
+};
+
+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
+{
+  long         d_value;
+
+public:
+  pmt_integer(long value);
+  //~pmt_integer(){}
+
+  bool is_integer() const { return true; }
+  long value() const { return d_value; }
+};
+
+class pmt_real : public pmt_base
+{
+  double       d_value;
+
+public:
+  pmt_real(double value);
+  //~pmt_real(){}
+
+  bool is_real() const { return true; }
+  double value() const { return d_value; }
+};
+
+class pmt_complex : public pmt_base
+{
+  std::complex<double> d_value;
+
+public:
+  pmt_complex(std::complex<double> value);
+  //~pmt_complex(){}
+
+  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
+{
+  pmt_t                d_car;
+  pmt_t                d_cdr;
+
+public:
+  pmt_pair(pmt_t car, 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_dict : public pmt_base
+{
+  pmt_t                d_alist;        // list of (key . value) pairs
+
+public:
+  pmt_dict();
+  //~pmt_dict();
+
+  bool  is_dict() const { return true; }
+  void  set(pmt_t key, pmt_t value);
+  pmt_t ref(pmt_t key, pmt_t default_value) const;
+  bool  has_key(pmt_t key) const;
+  pmt_t items() const;
+  pmt_t keys() const;
+  pmt_t values() const;
+};
+
+#endif /* INCLUDED_PMT_INT_H */
diff --git a/pmt/src/lib/qa_pmt.cc b/pmt/src/lib/qa_pmt.cc
new file mode 100644 (file)
index 0000000..6ed681a
--- /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 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 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>
+
+CppUnit::TestSuite *
+qa_pmt::suite ()
+{
+  CppUnit::TestSuite   *s = new CppUnit::TestSuite ("pmt");
+
+  s->addTest (qa_pmt_prims::suite ());
+  //s->addTest (qa_gr_circular_file::suite ());
+  //s->addTest (qa_gr_fxpt::suite ());
+  
+  return s;
+}
diff --git a/pmt/src/lib/qa_pmt.h b/pmt/src/lib/qa_pmt.h
new file mode 100644 (file)
index 0000000..166e7f8
--- /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 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.
+ */
+
+#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/pmt/src/lib/qa_pmt_prims.cc b/pmt/src/lib/qa_pmt_prims.cc
new file mode 100644 (file)
index 0000000..3c81a65
--- /dev/null
@@ -0,0 +1,284 @@
+/* -*- 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 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.
+ */
+
+#include <qa_pmt_prims.h>
+#include <cppunit/TestAssert.h>
+#include <pmt.h>
+#include <stdio.h>
+
+void
+qa_pmt_prims::test_symbols()
+{
+  CPPUNIT_ASSERT(!pmt_is_symbol(PMT_BOOL_T));
+  CPPUNIT_ASSERT(!pmt_is_symbol(PMT_BOOL_F));
+  CPPUNIT_ASSERT_THROW(pmt_symbol_to_string(PMT_BOOL_F), pmt_wrong_type);
+
+  pmt_t sym1 = pmt_string_to_symbol("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 = pmt_string_to_symbol("foo");
+  pmt_t sym3 = pmt_string_to_symbol("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] = pmt_string_to_symbol(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] = pmt_string_to_symbol(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 = pmt_string_to_symbol("test");
+  CPPUNIT_ASSERT(pmt_is_bool(PMT_BOOL_T));
+  CPPUNIT_ASSERT(pmt_is_bool(PMT_BOOL_F));
+  CPPUNIT_ASSERT(!pmt_is_bool(sym));
+  CPPUNIT_ASSERT_EQUAL(pmt_from_bool(false), PMT_BOOL_F);
+  CPPUNIT_ASSERT_EQUAL(pmt_from_bool(true), PMT_BOOL_T);
+  CPPUNIT_ASSERT_EQUAL(false, pmt_to_bool(PMT_BOOL_F));
+  CPPUNIT_ASSERT_EQUAL(true, pmt_to_bool(PMT_BOOL_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_BOOL_T));
+  CPPUNIT_ASSERT(pmt_is_integer(p1));
+  CPPUNIT_ASSERT(pmt_is_integer(m1));
+  CPPUNIT_ASSERT_THROW(pmt_to_long(PMT_BOOL_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_BOOL_T));
+  CPPUNIT_ASSERT(pmt_is_real(p1));
+  CPPUNIT_ASSERT(pmt_is_real(m1));
+  CPPUNIT_ASSERT_THROW(pmt_to_double(PMT_BOOL_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_BOOL_T));
+  CPPUNIT_ASSERT(pmt_is_complex(p1));
+  CPPUNIT_ASSERT(pmt_is_complex(m1));
+  CPPUNIT_ASSERT_THROW(pmt_to_complex(PMT_BOOL_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 = pmt_string_to_symbol("s1");
+  pmt_t s2 = pmt_string_to_symbol("s2");
+  pmt_t s3 = pmt_string_to_symbol("s3");
+
+  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));
+
+  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_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 = pmt_string_to_symbol("s0");
+  pmt_t s1 = pmt_string_to_symbol("s1");
+  pmt_t s2 = pmt_string_to_symbol("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));
+}
+
+void
+qa_pmt_prims::test_equivalence()
+{
+  pmt_t s0 = pmt_string_to_symbol("s0");
+  pmt_t s1 = pmt_string_to_symbol("s1");
+  pmt_t s2 = pmt_string_to_symbol("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()
+{
+  CPPUNIT_ASSERT_THROW(pmt_length(PMT_NIL), pmt_wrong_type);
+
+  pmt_t k0 = pmt_string_to_symbol("k0");
+  pmt_t k1 = pmt_string_to_symbol("k1");
+  pmt_t k2 = pmt_string_to_symbol("k2");
+  pmt_t k3 = pmt_string_to_symbol("k3");
+  pmt_t v0 = pmt_string_to_symbol("v0");
+  pmt_t v1 = pmt_string_to_symbol("v1");
+  pmt_t v2 = pmt_string_to_symbol("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_BOOL_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 = pmt_string_to_symbol("k0");
+  pmt_t k1 = pmt_string_to_symbol("k1");
+  pmt_t k2 = pmt_string_to_symbol("k2");
+  pmt_t k3 = pmt_string_to_symbol("k3");
+  pmt_t v0 = pmt_string_to_symbol("v0");
+  pmt_t v1 = pmt_string_to_symbol("v1");
+  pmt_t v2 = pmt_string_to_symbol("v2");
+  pmt_t v3 = pmt_string_to_symbol("v3");
+  pmt_t not_found = pmt_cons(PMT_NIL, PMT_NIL);
+  
+  CPPUNIT_ASSERT(!pmt_dict_has_key(dict, k0));
+  pmt_dict_set(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));
+  pmt_dict_set(dict, k1, v1);
+  pmt_dict_set(dict, k2, v2);
+  CPPUNIT_ASSERT(pmt_eqv(pmt_dict_ref(dict, k1, not_found), v1));
+  pmt_dict_set(dict, k1, v3);
+  CPPUNIT_ASSERT(pmt_eqv(pmt_dict_ref(dict, k1, not_found), v3));
+
+  pmt_t keys = pmt_cons(k2, pmt_cons(k1, pmt_cons(k0, PMT_NIL)));
+  pmt_t vals = pmt_cons(v2, pmt_cons(v3, pmt_cons(v0, PMT_NIL)));
+  CPPUNIT_ASSERT(pmt_equal(keys, pmt_dict_keys(dict)));
+  CPPUNIT_ASSERT(pmt_equal(vals, pmt_dict_values(dict)));
+}
diff --git a/pmt/src/lib/qa_pmt_prims.h b/pmt/src/lib/qa_pmt_prims.h
new file mode 100644 (file)
index 0000000..334ee65
--- /dev/null
@@ -0,0 +1,57 @@
+/* -*- 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 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.
+ */
+#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_equivalence);
+  CPPUNIT_TEST(test_misc);
+  CPPUNIT_TEST(test_dict);
+  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_equivalence();
+  void test_misc();
+  void test_dict();
+};
+
+#endif /* INCLUDED_QA_PMT_PRIMS_H */
+
diff --git a/pmt/src/lib/test_pmt.cc b/pmt/src/lib/test_pmt.cc
new file mode 100644 (file)
index 0000000..41cdc63
--- /dev/null
@@ -0,0 +1,37 @@
+/* -*- 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 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.
+ */
+
+#include <cppunit/TextTestRunner.h>
+#include <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/usrp/AUTHORS b/usrp/AUTHORS
new file mode 100644 (file)
index 0000000..bdfe42d
--- /dev/null
@@ -0,0 +1,4 @@
+Matt Ettus <matt@ettus.com> 
+Eric Blossom <eb@comsec.com>
+Michael Dickens  <mdickens@nd.edu> Fast USB support for OS/X
+Martin Dudok van Heel <nldudok1 at olifantasia dot com> Multi usrp synchronisation, 8 bit support
diff --git a/usrp/ChangeLog b/usrp/ChangeLog
new file mode 100644 (file)
index 0000000..e5acb6a
--- /dev/null
@@ -0,0 +1,1055 @@
+2006-06-25  Eric Blossom  <eb@comsec.com>
+
+       * firmware/include/fpga_regs_standard.h: doc fix to reflect current reality.
+
+2006-06-10  Eric Blossom  <eb@comsec.com>
+
+       * host/apps/usrper.cc: removed dead (#if 0'd) code, that's no longer applicable.
+
+2006-05-11  Martin Dudok van Heel <nldudok1 at olifantasia dot com>
+       Added synchronised multi_usrp support using a new fpga firmware build in a new toplevel usrp_multi.
+       A few changes were needed in the mainline code, but they shouldn't affect anyone
+       (No functionality changes in the existing code, just a few API additions)
+
+       * firmware/include/fpga_regs_standard.v: added Master/slave control register FR_RX_MASTER_SLAVE
+       * firmware/include/fpga_regs_common.h: added 32 bit counter support bmFR_MODE_RX_COUNTING_32BIT
+       * firmware/include/generate_regs.py: added support for bitno and bm defines
+       * firmware/include/fpga_regs_standard.h: added Master/slave control register FR_RX_MASTER_SLAVE
+       * host/lib/usrp_basic.h: added _write_fpga_reg_masked
+       * host/lib/usrp_basic.cc: added _write_fpga_reg_masked
+       * host/lib/usrp_standard.h: added FPGA_MODE_COUNTING_32BIT
+       * fpga/Makefile.extra: regenerated to add new usrp_multi files
+       * fpga/rbf/rev4/multi_2rxhb_2tx.rbf: new (fpga firmware for synchronised multi_usrp support)
+       * fpga/rbf/rev4/multi_4rx_0tx.rbf: new (fpga firmware for synchronised multi_usrp support)
+       * fpga/rbf/Makefile.am: added commented out rev2/multi_2rxhb_2tx.rbf and        rev4/multi_2rxhb_2tx.rbf        
+       * fpga/rbf/rev2/multi_2rxhb_2tx.rbf: new (fpga firmware for synchronised multi_usrp support)
+       * fpga/rbf/rev2/multi_4rx_0tx.rbf: new (fpga firmware for synchronised multi_usrp support)
+       * fpga/toplevel/usrp_std/usrp_std.v: split rx_buffer reset into dsp reset and reset_regs 
+       * fpga/toplevel/usrp_multi: new fpga toplevel for synchronised multi_usrp support
+       * fpga/toplevel/usrp_multi/usrp_multi.esf: new
+       * fpga/toplevel/usrp_multi/usrp_multi.vh: new toplevel verilog include, 
+           to turn on/off multi usrp support and number of rx/tx channels and halfband
+       * fpga/toplevel/usrp_multi/usrp_std.vh: new wrapper for usrp_multi.vh
+       * fpga/toplevel/usrp_multi/usrp_multi_config_2rxhb_0tx.vh: new
+       * fpga/toplevel/usrp_multi/usrp_multi_config_2rxhb_2tx.vh: new
+       * fpga/toplevel/usrp_multi/usrp_multi.v: new toplevel verilog file for multi_usrp support.
+           The multi_usrp support can be turned on and off in usrp_multi.vh.
+           If it is turned off this file will generate exactly the same as usrp_std.v
+           (just do a diff between usrp_std.v and usrp_multi.v to see how this is done) 
+       * fpga/toplevel/usrp_multi/usrp_multi.qpf: new
+       * fpga/toplevel/usrp_multi/usrp_multi.psf: new
+       * fpga/toplevel/usrp_multi/usrp_multi_config_2rx_0tx.vh: new
+       * fpga/toplevel/usrp_multi/usrp_multi.qsf: new
+       * fpga/toplevel/usrp_multi/usrp_multi_config_4rx_0tx.vh: new
+       * fpga/toplevel/usrp_multi/usrp_multi.csf: new
+       * fpga/toplevel/usrp_multi/.cvsignore: new
+       * fpga/sdr_lib/rx_buffer.v: split reset into dsp reset and reset registers
+       * fpga/sdr_lib/master_control_multi.v: new wrapper for master_control.v which adds multi_usrp support
+       * fpga/sdr_lib/phase_acc.v: set reset of FREQADDR register to 1'b0
+           This way reset can be used to reset phase_acc without resetting the frequency
+           (this reset was not used untill now)
+       * fpga/sdr_lib/setting_reg_masked.v: new masked 16 bit register
+
+2006-05-01  Michael Dickens  <mdickens@nd.edu>
+
+       * host/lib/Makefile.am, host/lib/fusb_darwin.{h,cc}: mods for
+       higher speed OS/X support.
+       * host/lib/darwin_libusb.h, host/lib/mld_threads.h,
+       host/lib/circular_buffer.h, host/lib/circular_linked_list.h,
+       README_OSX: new files for higher speed OS/X support.
+
+
+2006-03-29  Eric Blossom  <eb@comsec.com>
+
+       * fpga/Makefile.am: regenerated Makefile.extra so that make distcheck
+       passes.
+       * fpga/rbf/Makefile.am: simplified installation of FPGA rbf
+       files.  It actually works again ;)
+
+2006-03-09  Eric Blossom  <eb@comsec.com>
+
+       * fpga/gen_makefile_extra.py, fpga/Makefile.am,
+       fpga/Makefile.extra:  based on an idea by Martin, we now machine
+       generate the list of FPGA related files that should go into the
+       tarball distribution.  After adding or removing fpga files from
+       CVS, you must run gen_makefile_extra.py to regenerate the Makefile
+       fragment.
+
+2006-03-09  Martin Dudok van Heel <nldudok1@olifantasia.com>
+
+       * firmware/src/usrp2/Makefile.am, usrp/rbf/Makefile.am: fixed 
+       make distcheck failures.
+
+2006-03-06  Eric Blossom  <eb@comsec.com>
+
+       * host/lib/usrp_standard.cc (compute_freq_control_word_fpga):
+       Removed host-side truncation of frequency control word.  
+       Tuning resolution is now approximately 0.03 Hz.
+
+2006-02-18  Eric Blossom  <eb@comsec.com>
+
+       * host/lib/usrp_prims.{h,cc}, host/lib/usrp_basic.{h,cc},
+       host/lib/usrp_standard.{h,cc}: added support for specifying the
+       firmware and fpga files that is to be loaded.  Also provided
+       default override via USRP_FPGA and USRP_FIRMWARE environment
+       variables.
+
+2006-02-17  Eric Blossom  <eb@comsec.com>
+
+       * host/lib/usrp_basic.{h,cc}, host/lib/usrp_prims.{h,cc}: added
+       methods to retrieve serial number from usrp motherboard.
+       * host/apps/burn-serial-number: burn a serial number into usrp motherboard.
+       * firmware/src/usrp2/eeprom_io.{h,c}: routines to read and write eeprom.
+       * firmware/src/usrp2/usrp_main.c (patch_usb_descriptors): read h/w
+       rev and serial number out of boot eeprom and patch into returned
+       usb descriptors.
+
+       * host/apps/test_usrp0.cc, host/lib/usrp0.{h,cc}: removed usrp0
+       host code.
+       * firmware/src/Makefile.am: removed all rev0 and rev1 usrp firmware.
+
+2006-02-09  Eric Blossom  <eb@comsec.com>
+
+       * fpga/toplevel/usrp_std/usrp_std.vh: refactored condition compilation.
+       * fpga/toplevel/usrp_std/usrp_std_config_2rxhb_2tx.vh: new
+       * fpga/toplevel/usrp_std/usrp_std_config_4rx_0tx.vh: new
+
+       * firmware/include/fpga_regs_common.{h,v}, host/lib/usrp_basic.cc:
+       removed reference to FR_ATR_CTL.
+       * fpga/sdr_lib/rx_chain_hb.v: deleted.  Capability was folded into rx_chain.v
+
+2006-02-01  Eric Blossom  <eb@comsec.com>
+
+       * host/lib/usrp_prims.cc (usrp_open_interface): reenabled
+       usb_set_configuration for WIN32 platform.  Thanks Martin!
+
+2006-01-30  Eric Blossom  <eb@comsec.com>
+
+       * fpga/sdr_lib/master_control.v: modified code so that it appears
+       that atr_ctl is always asserted.  This allows us to simplify the
+       daughterboard and applications code.  They can control everything
+       via the other three ATR_* regs.
+       * fpga/rbf/usrp_fpga_rev2.rbf: updated with new binary.
+
+       * host/lib/usrp_prims.cc (_usrp_load_fpga): manually reset fpga
+       regs by writing zero to them.
+
+2006-01-25  Eric Blossom  <eb@comsec.com>
+
+       * host/lib/usrp_standard.{h,cc}: new methods for reporting on FPGA
+       capabilities.
+       * firmware/include/fpga_regs_standard.h (FR_RB_CAPS): new reg that
+       describes FPGA capabilities.
+
+2005-12-15  Eric Blossom  <eb@comsec.com>
+
+       * fpga/Makefile.am: Added missing files to EXTRA_DIST.
+
+2005-12-08  Martin Dudok van Heel <nldudok1@olifantasia.com>
+       
+       tagged RBF_2005_12_08
+       
+       * fpga/rbf/usrp_fpga_rev2.rbf: updated. 
+       * fpga/toplevel/usrp_std/usrp_std.v: fixed counter mode bug
+       related to half-band filter.
+
+2005-12-07  Eric Blossom  <eb@comsec.com>
+
+       Tagged all files: RBF_2005_12_07
+       
+       * fpga/rbf/usrp_fpga_rev2.rbf: updated with new Auto T/R switching code.
+
+2005-12-06  Eric Blossom  <eb@comsec.com>
+
+       * host/swig/Makefile.am (prims.cc usrp_prims.py): added new dependencies.
+       * host/lib/usrp_basic.cc: disabled printing of daughterboard types.
+
+2005-12-05  Eric Blossom  <eb@comsec.com>
+
+       * firmware/include/fpga_regs_standard.h: renumbed
+       FR_TX_FORMAT and FR_RX_FORMAT to remove gap.
+       * firmware/include/fpga_regs_common.h: moved FR_ATR regs here from
+       fpga_regs_standard.h.
+       * host/lib/usrp_basic.cc: zero Auto T/R regs at init time.
+
+2005-12-01  Eric Blossom  <eb@comsec.com>
+
+       * host/swig/usrp_fpga_regs.py: define all fpga register names and
+       bit masks.  This is effectively a python binding for the contents
+       of firmware/include/fpga_regs_{common,standard}.h
+       * host/swig/prims.i: swigged fpga_regs_{common,standard}.h
+
+2005-11-30  Eric Blossom  <eb@comsec.com>
+
+       * firmware/include/fpga_regs_standard.h: fixed typo in FR_ATR_*
+       series.  Renumbered to start after the 16 registers reserved for
+       custom user definition.
+       * firmware/include/generate_regs.py (generate_fpga_regs): changed
+       generated register const width to 7 bits.
+
+2005-11-19  Martin Dudok van Heel <nldudok1@olifantasia.com>
+
+        * host/apps/Makefile.am: make make-dist work again by
+          added new burn-db-eeprom and removing burn-dbs-eeprom
+          and burn-tvrx-eeprom from noinst_PYTHON.
+        * fpga/Makefile.am: make make-dist work again by making
+          EXTRA_DIST consistant with latest cleanup of old files.
+
+2005-11-18  Eric Blossom  <eb@comsec.com>
+
+       * firmware/include/fpga_regs_standard.h: redefined auto
+       transmit/receive control registers.
+
+2005-11-17  Eric Blossom  <eb@comsec.com>
+
+       * host/lib/fusb_linux.cc (write): added code to minimize transmit
+       buffering.  This allows the higher level code to control buffering
+       of USB transfers.
+
+2005-11-15  Eric Blossom  <eb@comsec.com>
+
+       * host/lib/usrp_basic.cc: zero the daughterboard i/o registers on open.
+       * fpga/rbf/usrp_fgpa_rev2.rbf: new RBF_2005_11_15
+       
+2005-11-15  Matt Ettus  <matt@ettus.com>
+       
+       * fpga/sdr_lib/master_control.v, fpga/sdr_lib/io_pins.v:
+       Refactored resets to fix problem where starting Rx side was
+       killing Tx side.
+
+2005-11-13  Eric Blossom  <eb@comsec.com>
+
+       * host/lib/usrp_prims.cc (usrp_open_interface): removed call to usb_set_configuration.
+       
+2005-11-02  Eric Blossom  <eb@comsec.com>
+
+       * host/lib/usrp_basic.h (class usrp_basic_tx): fixed pga_db_per_step.
+
+2005-10-31  Eric Blossom  <eb@comsec.com>
+
+       * host/lib/usrp_prims.cc (usrp_open_interface): ignore error on
+       usb_set_configuration.
+
+2005-10-28  Eric Blossom  <eb@comsec.com>
+
+       * fpga/rbf/Makefile.am (install-data-local): conditionally install
+       fpga .rbf files.  If a file named DONT_INSTALL_RBF exists in the
+       install directory, the install will not be done.
+
+2005-10-24  Eric Blossom  <eb@comsec.com>
+
+       * host/lib/usrp_standard.{h,cc}: mods to use halfband decimator
+       in FPGA.
+
+       * fpga/sdr_lib/hb/halfband_decim.v: added documentation.
+
+2005-10-20  Eric Blossom  <eb@comsec.com>
+
+       * host/lib/usrp_standard.{h,cc} (class usrp_standard_rx): support
+       setting and getting rx format (8-bit values, etc).
+       * host/lib/usrp_basic.cc (usrp_basic): disable FPGA DEBUG_EN in ctor.
+       * host/lib/gen_usrp_dbid.py, host/lib/usrp_prims.h: handle <none> and
+       <unknown> cases.
+       * host/apps/test_usrp_standard_rx.cc (main): added support for 8-bit samples.
+       
+       * fpga/sdr_lib/rx_buffer.v: fixed misspelled netname.
+       * fpga/toplevel/usrp_std/usrp_std.v: added additional ../ to includes.
+       * fpga/sdr_lib/master_control.v: put FR_DEBUG_EN back to single reg.
+
+2005-10-17  Eric Blossom  <eb@comsec.com>
+
+       * firmware/include/fpga_regs_standard.h: redefined RX_FORMAT register.
+       * firmware/include/fpga_regs_common.h: split FR_DEBUG_EN into a TX
+       and an RX register.
+
+2005-10-13  Eric Blossom  <eb@comsec.com>
+
+       * host/lib/usrp_standard.cc: initialize nchannels before interp/decim
+       rate.  Fixed problem computing polling iterval.
+       * host/apps/test_usrp_standard_tx.cc (main): added -M megabytes option.
+
+2005-09-21  Eric Blossom  <eb@comsec.com>
+
+       * host/lib/usrp_basic.h: adc_freq() -> adc_rate(); dac_freq() ->
+       dac_rate().  Also added converter_rate() which is defined on both
+       Tx and Rx sides.
+
+2005-09-20  Eric Blossom  <eb@comsec.com>
+
+       * host/apps/burn-db-eeprom: new.  Burns eeproms on all kinds of
+       daughterboards. 
+
+2005-09-17  Eric Blossom  <eb@comsec.com>
+
+       * host/swig/prims.i: added interface for usrp_dbid_to_string.
+
+2005-09-09  Larry Doolittle <ldoolitt@recycle.lbl.gov>
+
+       * host/apps/test_usrp_standard_rx.cc: Added -M option to specify
+       how many megabytes to transfer.
+
+2005-09-06  Martin Dudok van Heel <nldudok1 at olifantasia.com>
+
+        * host/lib/fusb_win32.cc: Solved missing samples bug in usb code.
+        (Which you could see by running test_counting.py example)
+       
+2005-08-26  Eric Blossom  <eb@comsec.com>
+
+       * firmware/include/fpga_regs_standard.{h,v}: Added defs for new
+       FR_TX_FORMAT and FR_RX_FORMAT registers.
+
+2005-08-19  Eric Blossom  <eb@comsec.com>
+
+       * doc/Makefile.am: clean-local now uses $(RM) -fr
+
+2005-07-29  Martin Dvh <nldudok1 at olifantasia.com>, Stephane Fillod
+
+        * host/lib/fusb_win32.{cc,h}: WTH made win32 fast usb buffer work 
+       * host/lib/usrp_prims.cc: Get usrp basepath for firmware from
+       environment variable USRP_PATH.  Needed for win32 binary installer
+
+2005-07-24  Stephane Fillod  <f8cfe@free.fr>
+
+        * config/usrp_fusb_tech.m4: select win32 fusb for Cygwin
+       
+2005-07-19  Eric Blossom  <eb@comsec.com>
+
+       * host/apps/usrp_cal_dc_offset.cc: new.  control system for
+       determining ADC DC offset correction.  Works, but really ought to
+       be reimplemented in FPGA and run constantly.  Part of the problem
+       is that the offset correction varies with temperature, pga gain,
+       and daughterboard.
+
+       * firmware/src/common/build_eeprom.py (build_shell_script): added
+       sleep 1 after each command.
+
+       * host/lib/usrp_standard.h (class usrp_standard_rx): new method:
+       set_ddc_phase.
+
+       * host/lib/usrp_basic.{h,cc}, host/lib/usrp_standard.{h,cc}: added
+       fusb_block_size and fusb_nblocks args to constructors so that
+       application code can control "fast usb" buffer.
+
+2005-07-11  Eric Blossom  <eb@comsec.com>
+
+       * host/lib/gen_usrp_dbid.py: new.  Generate usrp_dbid.h,
+       usrp_dbid.py and usrp_dbid.cc using usrp_dbid.dat as the input file.
+       * host/apps/burn-basic-eeprom, host/apps/burn-dbs-eeprom,
+       host/apps/burn-tvrx-eeprom: import usrp_dbid
+       
+2005-07-02  Eric Blossom  <eb@comsec.com>
+
+       * config/gr_no_undefined.m4, config/gr_x86_64.m4: new, x86_64 support.
+       * config/gr_python.m4: backed out search for libpython, making
+       x86_64 work and breaking Cygwin/MinGW.
+       * configure.ac, host/lib/Makefile.am, host/swig/Makefile.am: mods
+       for x86_64, $(NO_UNDEFINED)
+       
+2005-05-18  Eric Blossom  <eb@comsec.com>
+
+       * host/lib/usrp_standard.{h,cc}, host/lib/usrp_basic.{h,cc}: new
+       start and stop methods to kick off data xfer.  (Useful for
+       minimizing latency).
+       * host/apps/test_usrp_standard_{tx,rx}.cc: modified to use new
+       start method.
+       
+2005-05-09  Stephane Fillod  <f8cfe@free.fr>
+
+        * config/gr_sysv_shm.m4: SysV shared memory not mandatory
+       * config/gr_pwin32.m4, config/gr_python.m4, config/lf_cxx.m4:
+         fixes for Cygwin, MinGW
+       * usrp.inf, usrp.iss.in: new for windows installer
+
+2005-05-01  Stephane Fillod  <f8cfe@free.fr>
+
+        * config/usrp_fusb_tech.m4,host/lib/Makefile.am: added win32
+        fusb support.
+        * host/lib/fusb_sysconfig_win32.cc, host/lib/fusb_win32.{h,cc}:
+        new files
+        * host/apps/test_usrp0.cc, host/apps/test_usrp_standard_rx.cc,
+        host/apps/test_usrp_standard_tx.cc, host/lib/fusb.h,
+        host/lib/fusb_linux.cc, host/lib/fusb_sysconfig_darwin.cc,
+        host/lib/fusb_sysconfig_generic.cc, host/lib/fusb_sysconfig_linux.cc,
+        host/lib/usrp0.cc, host/lib/usrp0.h, host/lib/usrp_basic.cc,
+        host/lib/usrp_basic.h: do not hardcode the usb driver block_size.
+        * host/lib/fusb_darwin.cc, host/lib/fusb_generic.cc: typo and read
+        endpoint fix.
+       
+2005-03-31  Eric Blossom  <eb@comsec.com>
+
+       * firmware/include/usrp_spi_defs.h,firmware/include/Makefile.am:
+       renamed from spi_defs.h to usrp_spi_defs.h.  It's now installed.
+
+2005-03-26  Eric Blossom  <eb@comsec.com>
+
+       * host/lib/fusb_linux.cc (read): fix for x86_64 compile.
+
+2005-03-15  Eric Blossom  <eb@comsec.com>
+
+       * host/lib/usrp_basic.{h,cc}: hoisted write_aux_dac and read_aux_dac
+       methods out of usrp_basic and into usrp_basic_rx and usrp_basic_tx.
+
+2005-03-11  Eric Blossom  <eb@comsec.com>
+
+       * host/lib/usrp_basic.{h,cc}: new methods: set_adc_offset,
+       set_dac_offset, set_adc_buffer_bypass.
+
+2005-03-03  Eric Blossom  <eb@comsec.com>
+
+       * host/lib/usrp_standard.cc (set_decim_rate): added warning about rates > 128.
+
+2005-02-22  Eric Blossom  <eb@comsec.com>
+
+       * firmware/src/usrp1/spi.c (read_byte_msb): rewritten to work
+       around SDCC 2.4.0 bug.
+
+2005-02-20  Eric Blossom  <eb@comsec.com>
+
+       * firmware/include/usrp_ids.h (USB_PID_FSF_SSRP_reserved): added
+       PID for SSRP.
+
+2005-02-18  Eric Blossom  <eb@comsec.com>
+
+       * host/lib/usrp_standard.cc (set_interp_rate,set_decim_rate): added range check.
+       * host/lib/usrp_standard.h: doc fix.
+
+2005-02-16  Eric Blossom  <eb@comsec.com>
+
+       * host/lib/usrp_dbid.cc: new ID.
+       * host/lib/usrp_daughterboards.h (USRP_DBID_DBS_RX): new ID.
+       * host/lib/usrp_basic.{h,cc}: added read_i2c and write_i2c methods.
+       * host/apps/burn-dbs-eeprom: init eeprom on DBS Rx daughterboard.
+
+2005-02-11  Eric Blossom  <eb@comsec.com>
+
+       * doc/Makefile.am: fixes for distcheck.
+       * src/host/apps/Makefile.am: add burn-basic-eeprom to tarball.
+
+2005-02-10  Eric Blossom  <eb@comsec.com>
+
+       * configure.ac, doc/Makefile.am: build html from DocBook if
+       they've got xmlto installed.
+       
+2005-02-09  Eric Blossom  <eb@comsec.com>
+
+       * host/lib/std_paths.h.in (std_paths): new.  Use prefix to locate
+       fpga and firmware binaries.
+
+       * host/lib/usrp_prims.cc (compute_hash): rewritten to use embedded
+       md5 code instead of calling out to program.
+       * host/lib/md5.{h,c}: new. imported from core-utils.
+
+2005-02-08  Eric Blossom  <eb@comsec.com>
+
+       * host/apps/usrper.cc (usage): added missing parameter.
+
+2005-02-06  Eric Blossom  <eb@comsec.com>
+
+       * configure.ac: upped rev to 0.7 for release.
+       * host/swig/Makefile.am: backed out dependency on libpython
+       * host/apps/Makefile.am, host/apps/test_fusb.cc: removed test_fusb.cc
+       * doc/Makefile.am: new.  Generate doxygen docs.
+
+2005-02-05  Eric Blossom  <eb@comsec.com>
+
+       * fpga/Makefile.am: new. distribute verilog with tarball.
+       * fpga/rbf/Makefile.am: new.  distribute rbf's with tarball
+       * host/apps/test_usrp_standard_rx.cc (main): fixed calling sequence.
+
+2005-02-02  Eric Blossom  <eb@comsec.com>
+
+       * fpga/toplevel/usrp_basic/usrp_basic.v: Removed
+       ch?tx_freq from list of signals passed to serial_io in order to
+       get it to compile.
+
+2005-01-28  Stephane Fillod <f8cfe@free.fr>
+
+       * src/Makefile.am: fixes for MinGW.
+       
+2005-01-10  Eric Blossom  <eb@comsec.com>
+
+       * host/lib/usrp_standard.{h,cc}: changed default strategy on mux values. 
+
+       * host/lib/usrp_basic.{h,cc}: probe d'boards and initialize
+       fpga adc_offset and oe regs.  Add methods to control all knobs.
+       Includes d'board i/o pins, PGA's, query daugherboard ids.
+
+       * host/lib/usrp_prims.{h,cc},host/lib/usrp_dbid.cc: new code to
+       read, parse and write d'board EEPROMs.
+
+2005-01-08  Eric Blossom  <eb@comsec.com>
+
+       * firmware/include/usrp_i2c_addr.h: doc fix on d'board EEPROM contents
+
+2005-01-05  Eric Blossom  <eb@comsec.com>
+
+       * host/lib/usrp_basic.cc (set_pga): fixed incorrect upper limit.
+
+2005-01-04  Eric Blossom  <eb@comsec.com>
+
+       * host/lib/usrp_basic.{h,cc} (class usrp_basic_rx): new methods
+       for controlling Rx PGA.
+
+2004-12-20  Eric Blossom  <eb@comsec.com>
+
+       * firmware/src/common/build_eeprom.py: new.  builds shell script
+       to burn low-power code into usrp motherboard EEPROM.
+
+2004-12-19  Eric Blossom  <eb@comsec.com>
+
+       * firmware/src/usrp1/{eeprom_boot.a51,eeprom_init.c}: new.  Mimimum
+       code that will put board in low-power state at boot time.
+
+       * firmware/src/usrp2/Makefile.am: reorg to remove duplicate code
+       between rev1 and rev2.
+       * firmware/src/usrp2/{fpga.h,fpga_load.h,fpga_rev2.c,fpga_rev2,usrp_common.h,
+       usrp_globals.h,usrp_rev2_regs.h}: removed.
+       * firmware/src/usrp2/fpga_rev1.c: new
+
+2004-12-08  Eric Blossom  <eb@comsec.com>
+
+       * host/lib/usrp_prims.{h,cc}, host/lib/usrp_basic.cc: minor tweaks for rev2 h/w.
+
+       * firmware/src/usrp2/.cvsignore,Makefile.am,_startup.a51,blink_leds.c,
+       board_specific.c,check_mdelay.c,check_udelay.c,edit-gpif,fpga.h,
+       fpga_load.c,fpga_load.h,fpga_rev2.c,fpga_rev2.h,gpif.c,gpif.gpf,init_gpif.c,
+       spi.c,spi.h,usb_descriptors.a51,usrp_common.c,usrp_common.h,usrp_globals.h,
+       usrp_main.c,usrp_rev2_regs.h,vectors.a51: new. copied from usrp1.
+       Should remerge this after we're sorted out.
+
+2004-11-29  Berndt Josef Wulf <wulf@ping.net.au>
+
+       * configure.ac, config/usrp_sdcc.m4: new. check for proper version
+       of SDCC 8051 compiler and assembler.
+       * config/usrp_libusb.m4: fixed check for usb.h
+       
+2004-11-14  Eric Blossom  <eb@comsec.com>
+
+       * firmware/src/usrp1/usrp_rev1_regs.h (bmMISC_OUTPUTS): removed
+       unused define.
+       (bmPORT_E_OUTPUTS): made bmPE_FPGA_CLR_STATUS an output (as it
+       should have been all along).
+
+2004-10-20  Stephane Fillod <f8cfe@free.fr>
+
+        * configure.ac, config/Makefile.am, config/gr_pwin32.m4,
+        host/Makefile.am, host/apps/Makefile.am,
+        host/apps/time_stuff.c, host/lib/Makefile.am,
+        host/swig/Makefile.am: detect missing functions under Win32.
+
+        * config/mkstemp.m4, config/onceonly.m4,
+        host/misc/bug_work_around_8.cc, host/misc/getopt.c,
+        host/misc/getopt.h, host/misc/gettimeofday.c,
+        host/misc/Makefile.am, host/misc/mkstemp.c,
+        host/misc/tempname.c, host/misc/usleep.c,
+        host/misc/.cvsignore: new files, replacements for win32 support
+
+        * host/lib/usrp_prims.cc: fix libusb init on systems not as
+        clever as Linux (no easy shared global variable, and no
+        auto set_configuration).
+       
+2004-10-20  Eric Blossom  <eb@comsec.com>
+
+       * firmware/src/common/Makefile.am, firmware/lib/Makefile.am,
+       firmware/src/common/Makefile.am, firmware/src/usrp0/Makefile.am,
+       firmware/src/usrp1/Makefile.am: make distcheck now works!
+
+2004-10-20  Stephane Fillod <f8cfe@free.fr>
+       
+        * firmware/src/common/Makefile.am,
+        firmware/src/common/edit-gpif, firmware/src/usrp0/Makefile.am,
+        firmware/src/usrp1/Makefile.am, firmware/src/usrp1/edit-gpif:
+        allow VPATH building.
+
+2004-10-18  Eric Blossom  <eb@comsec.com>
+
+       * fpga/sdr_lib/serial_io.v: removed dac_offset stuff.
+       * fpga/toplevel/usrp_basic/usrp_basic.v: removed dac_offset stuff.
+       Conditionalized debug output.
+       * host/swig/util.py: fixed import
+
+       * fpga/toplevel/usrp_basic/usrp_basic.v,fpga/sdr_lib/serial_io.v:
+       modified to use 0-based naming on frequencies.
+       
+       * firmware/include/generate_all.py (generate_fpga_regs): new.
+       Generate fpga_regs.v from fpga_regs.h
+       * fpga/sdr_lib/serial_io.v: now use symbolic defines for register numbers.
+
+2004-10-13  Eric Blossom  <eb@comsec.com>
+
+       * configure.ac: upped rev to 0.5cvs
+
+2004-10-11  Eric Blossom  <eb@comsec.com>
+
+       * configure.ac: bumped rev to 0.5, made release
+       * Makefile.am (EXTRA_DIST): added config.h.in
+
+2004-09-30  Eric Blossom  <eb@comsec.com>
+
+       * firmware/include/usrp_i2c_addr.h: renamed from i2c_addr.h.
+       Now installed.
+
+       * host/lib/usrp_basic.{h,cc}: added methods for writing/reading
+       aux dac/adc and eeproms.
+
+2004-09-29  Eric Blossom  <eb@comsec.com>
+
+       * host/lib/usrp_prims.{h,cc} (usrp_read_aux_adc, usrp_write_aux_dac):
+       Redefined the interface such that aux i/o values are 12-bit.
+       This buys us a bit of independence from the AD9862.
+
+2004-09-24  Eric Blossom  <eb@comsec.com>
+
+       * fpga/toplevel/usrp_basic/usrp_basic.v: subtract adc offset from
+       buffered input values.
+
+2004-09-23  Eric Blossom  <eb@comsec.com>
+
+       * config/usrp_fusb_tech.m4, config/bnv_have_qt.m4, config/cppunit.m4,
+       config/gr_check_mc4020.m4, config/gr_check_usrp.m4, config/gr_doxygen.m4,
+       config/gr_gprof.m4, config/gr_scripting.m4, config/gr_set_md_cpu.m4,
+       config/pkg.m4, config/usrp_fusb_tech.m4: added additional quoting
+       to first arg of AC_DEFUN to silence automake warning.
+
+2004-08-19  Eric Blossom  <eb@comsec.com>
+
+       * host/lib/usrp_basic.{h,cc}, host/lib/usrp_standard.cc: make
+       verbose output conditional.
+
+2004-08-14  Matt Ettus  <matt@ettus.com>
+
+       Rx timing problem fixed!
+       
+       * fpga/sdr_lib/rx_buffer.v: revised to use extended RD assertion
+       timing.
+
+2004-08-14  Eric Blossom  <eb@comsec.com>
+
+       * firmware/src/usrp1/{edit-gpif,gpif.gpf}: copied for common and
+       modified.  For the time being we've got a different gpif program
+       for the usrp0 and usrp1, though the usrp0 should get updated to
+       use the new organization.
+       * firmware/src/usrp1/{usrp_gpif.c,usrp_gpif_inline.h}: removed
+       links to common.  Now generated in usrp1 from usrp1 specific gpif.c
+
+2004-08-06  Eric Blossom  <eb@comsec.com>
+
+       * host/lib/fusb_linux.cc (write): failure of submit_urb is now
+       propagated upward as an error.
+
+2004-08-04  Eric Blossom  <eb@comsec.com>
+
+       Rx counting and Rx/Tx digital loopback are now working, modulo the
+       problem at the beginning of the packet.  The good news is that it
+       is completely reproducible, and there's no PLL being used in the FPGA.
+       
+       * host/lib/usrp_basic.{h,cc} (set_usb_data_rate,usb_data_rate): new methods.
+       * host/lib/usrp_standard.{h,cc}: polling rate is now
+       f(usb_data_rate).  Moved fpga_mode into rx only, and changed
+       constructor to take optional mode.
+       * host/apps/test_usrp_standard_rx.cc (main): changes to match new
+       constructor.
+       * host/apps/test_usrp_standard_tx.cc (main): -c generates counting
+       sequence.
+       * fpga/toplevel/usrp_basic/usrp_basic.v: Fixed race.  Changed
+       strobe_decim to strobe_interp in loopback setup.
+       * fpga/sdr_lib/tx_buffer.v: Removed unnecessary zero assignment.
+
+2004-07-31  Eric Blossom  <eb@comsec.com>
+
+       * host/apps/test_usrp_standard_tx.cc (main): added -l (loopback) option
+       * host/apps/test_usrp_standard_tx.cc (main): added -l (loopback) option
+
+       * firmware/include/fpga_regs.h (FR_MODE): added new mode register.
+       * host/lib/usrp_basic.cc (usrp_basic): init to non-loopback mode
+       
+       * host/apps/test_usrp_standard_tx.cc (main): changed default
+       interp rate to 16 (=> 32MB/sec).
+
+       * host/lib/usrp_bytesex.h (host_to_usrp_short): New.  Conditional
+       byte swapping between host and usrp.
+       * host/app/test_usrp0.cc: added conditional byte swapping.
+       * host/app/test_usrp_standard_{rx,tx}.cc: added conditional byte swapping.
+
+2004-07-30  Eric Blossom  <eb@comsec.com>
+
+       * host/swig/Makefile.am: now installs usrp_prims.* directly in site-packages.
+       One could argue that this isn't particularly pretty, but it does
+       get it into the namespace where we want it.     
+
+2004-07-29  Eric Blossom  <eb@comsec.com>
+
+       * host/apps/test_usrp0.cc (main): added code to set tx frequency.
+
+2004-07-12  Eric Blossom  <eb@comsec.com>
+
+       * configure.ac: upped rev to 0.4cvs
+
+2004-07-11  Eric Blossom  <eb@comsec.com>
+
+       * host/lib/usrp_basic.cc: invert TX_SYNC
+
+       * host/lib/usrp_basic.{h,cc},usrp_standard.cc: now temporarily
+       disable tx and rx paths when changing interpolation or decimation
+       rate.  Didn't fix the problem, but shouldn't hurt either.
+
+2004-07-07  Eric Blossom  <eb@comsec.com>
+
+       * firmware/src/common/_startup.a51 (__sdcc_external_startup):
+       Rewritten to avoid fragile kludge.  Now requires that all firmware
+       be compiled with --no-xinit-opt.
+
+       * firmware/src/usrp{0,1}/Makefile.am: pass in linker option to
+       place usb descriptors at 0xE000 absolute.  This works around the
+       fact that the assembler and linker don't really implement the
+       .even directive.
+       * firmware/src/usrp{0,1}/usb_descriptors.a51: now place
+       descriptors in USBDESCSEG, which we force to 0xE000.
+       
+       * firmware/src/usrp1/board_specific.c (power_down_9862s):
+       Power down the 9862's when the firmware is loaded to keep from
+       burning up the board.  Note to Analog Devices: put a power pad
+       on these or some other way to get the heat out of them.
+
+       * host/lib/usrp_prims.cc (_usrp_load_fpga): Since loading the FPGA
+       wiggles the shared reset line with the 9862s, we now once again
+       power down the 9862's.
+
+2004-07-06  Eric Blossom  <eb@comsec.com>
+
+       * firmware/src/common/_startup.a51 (__sdcc_external_startup):
+       picked up bug fixes from 2.4.0 release, and added a fragile kludge
+       that ensures that our variables are all initialized properly.
+       
+       * firmware/src/usrp0/usrp_main.c, firmware/src/usrp1/usrp_main.c,
+       firmware/src/common/usb_common.c: removed deprecated use of 
+       pragma NOIV.
+
+2004-07-05  Eric Blossom  <eb@comsec.com>
+
+       * host/lib/fusb_linux.cc (alloc_urb): removed
+       USBDEVFS_URB_QUEUE_BULK flag.
+
+2004-07-02  Eric Blossom  <eb@comsec.com>
+
+       * host/lib/usrp_basic.h: added adc_freq and dac_freq
+       to disambiguate the interpretation of interpolation and decimation
+       ratios.
+
+2004-07-01  Eric Blossom  <eb@comsec.com>
+
+       * host/swig/prims.i: renamed from usrp_prims.i  Module is now
+       installed as usrp.prims
+       * host/lib/usrp_basic.cc (usrp_basic_tx, usrp_basic_rx): power
+       down 9862 tx or rx path in destructor.
+       * host/lib/usrp_standard.cc: now control coarse and fine
+       modulators transparently, based on user provided center freq.
+       * fpga/sdr_lib/gen_cordic_consts.py: new. generate magic constants for cordic.
+       * fpga/sdr_lib/cordic.v: `define constants.  integer c00 = <foo>
+       wasn't being synthesized correctly by Quartus II 4.0    
+
+2004-05-28  Eric Blossom  <eb@comsec.com>
+
+       * host/lib/usrp_standard.{h,cc}: Now uses 4x interpolator and
+       9862 cordic.  Tx path looks great up to +/- 44 MHz!
+       This code still twiddles the coarse modulator manually.
+
+2004-05-27  Eric Blossom  <eb@comsec.com>
+
+       * Tagged everything with BEFORE_CLOCK_REVAMP_2004_05_27.
+       We're about to rework the boards, host code and the verilog to
+       directly feed the 64 MHz oscillator to the 9862's and the FPGA.
+       With any luck, life will drastically improve...
+       
+
+2004-05-25  Eric Blossom  <eb@comsec.com>
+
+       * host/lib/usrp_standard.{h,cc} (class usrp_standard_tx_use_nco):
+       new.  Class that utilizes the AD9862's built-in NCO for up conversion.
+       There's still something slightly flaky going on.
+       
+       * host/lib/usrp_basic.cc: initialize 9862 Tx FTW
+
+2004-05-21  Eric Blossom  <eb@comsec.com>
+
+       * firmware/src/usrp1/usrp_main.c (main): work around compiler
+       data initialization bug.
+
+       * firmware/src/usrp1/fpga_rev1.{h,c}: added support for {TX,RX}_RESET
+
+2004-05-10  Eric Blossom  <eb@comsec.com>
+
+       * host/lib/usrp_basic.cc (~usrp_basic_rx): turn off rx_enable.
+
+       * firmware/src/usrp1/usrp_main.c: removed unneeded global
+       g_fpga_reset.
+
+2004-05-08  Eric Blossom  <eb@comsec.com>
+
+       * firmware/src/usrp1/usrp_main.c (main): enabled GSTATE output.
+
+2004-05-07  Eric Blossom  <eb@comsec.com>
+
+       * host/lib/usrp_standard.cc (make): changed constructors and make
+       to pass the interp/decim rate.  This ensures that the rate is set
+       to something the user wants when the rx and tx paths are first
+       enabled.
+
+       * host/lib/usrp_basic.cc (initialize): enabled xrun status polling.
+       (set_fpga_rx_sample_rate_divisor,set_fpga_rx_sample_rate_divisor):
+       set FPGA register to N-1.
+
+       * host/lib/usrp_standard.cc (set_interp_rate, set_decim_rate): now
+       set FPGA register to N-1.
+
+2004-04-18  Eric Blossom  <eb@comsec.com>
+
+       * firmware/src/usrp1/spi.c (spi_read, spi_write): removed extra
+       clocks.  FPGA is now doing the right thing.
+
+       * host/lib/ad9862.h: new.  register defs for AD962 codec.
+
+       * firmware/src/usrp1/spi.c (spi_write,spi_read): clock once w/o 
+       enables for the FPGA's benefit.  We're also clocking one extra
+       cycle at the end with enables again for the FPGA.  I think we
+       should remove the extra clocking at the end.
+
+2004-04-17  Eric Blossom  <eb@comsec.com>
+
+       * host/lib/usrp_prims.{h,cc} (usrp_read_aux_adc,usrp_write_aux_dac): new.
+       * host/lib/usrp_prims.{h,cc} (usrp_eeprom_write,usrp_eeprom_read): new.
+
+2004-04-16  Eric Blossom  <eb@comsec.com>
+
+       * firmware/include/i2c_addr.h: new.  I2C addresses.
+
+2004-04-12  Eric Blossom  <eb@comsec.com>
+
+       * host/apps/test_usrp0.cc: renamed from test_usrp.cc
+       * firmware/include/fpga_regs.h: corrected to match latest control_bus.v
+
+2004-04-11  Eric Blossom  <eb@comsec.com>
+
+       * host/lib/usrp0.{h,cc}: new.  copies of original usrp.{h,cc}
+       * host/lib/usrp_basic.{h,cc}: new.  reflect rev1 hardware.
+
+2004-04-10  Eric Blossom  <eb@comsec.com>
+
+       * host/swig/usrp_prims.i: new.  SWIG'd usrp_prims.
+       * host/lib/usrp_prims.cc: added usrp_rescan; dispatch on hardware revision
+       when appropriate; added usrp_read_fpga_reg
+       * firmware/src/usrp1/fpga_rev1.h: added declarations
+       * firmware/src/usrp1/fpga_rev.c: added implementations for
+       fpga_write_reg, fpga_set_reset, fpga_set_tx_enable, fpga_set_rx_enable.
+       * firmware/include/fpga_regs0.h: renamed prev fpga_regs.h to fpga_regs0.h
+       * firmware/include/fpga_regs.h: new for usrp rev1.  Needs checking
+       against verilog.
+       
+
+2004-03-01  Eric Blossom  <eb@comsec.com>
+
+       * host/lib/rate_to_regval.h: new. mapping table.
+       * host/lib/usrp.cc (map_rate_to_regval): now support all 97 legal
+       values. 
+
+2004-01-11  Eric Blossom  <eb@comsec.com>
+
+       * configure.ac: configure fast usb technique as f(os)
+       * config/usrp_fusb_tech.m4: new autoconf macro
+       * host/lib/fusb.{h,cc}: refactored in to abstract class
+       * host/lib/fusb_{darwin,generic,linux}.{h,cc}: new concrete classes
+       * host/lib/fusb_sysconfig_{darwin,generic,linux}.cc: new
+
+       * config/usrp_libusb.m4: new. check for libusb.
+       * configure.ac: check for libusb
+       
+       * firmware/src/Makefile.am: fixed dependencies
+       * firmware/src/fpga.{h,c}, firmware/src/usrp_main.c: cleanup to
+       make board with no FPGA usable again.
+       * firmware/include/usrp_config.h: doc fix.
+
+2003-12-30  Eric Blossom  <eb@comsec.com>
+
+       * host/lib/fusb.cc (alloc_urb): fixes for linux 2.5/2.6
+
+2003-12-12  Eric Blossom  <eb@comsec.com>
+
+       * firmware/lib/i2c.c (i2c_read): worked around sdcc compiler bug.
+
+2003-12-07  Eric Blossom  <eb@comsec.com>
+
+       * configure.ac: autoconfiscated the firmware directory.  It now
+       builds from the top along with the host code.
+
+       * I've touched just about every file in the tree, both
+       firmware and host side.  The combo is now working well.  It is
+       capable of half duplex reading or writing at 31.25 MB/sec and
+       (pseudo) full duplex reading and writing at 15.625 MS/sec in each
+       direction.
+
+       In addition, the receive side is decoupled from the transmit side
+       so that separate processes can open each side.
+       
+       
+2003-11-27  Eric Blossom  <eb@comsec.com>
+
+       * firmware/src/fpga.c (clock_out_config_byte): assembly speedup
+       for loading fpga.
+
+       basic support for interrupts is now working.
+       
+       * firmware/lib/{isr.c,timer.c}: new
+       * firmware/include/{isr.h,timer.h}: new
+       * firmware/src/command_loop.c (isr_tick): blink led
+
+2003-11-21  Eric Blossom  <eb@comsec.com>
+
+       * firmware/src/edit-gpif (edit_gpif): now leave xdata alone
+       * firmware/src/init_gpif.c: added xdata storage qualifer
+       * firmware/Makefile: added linker opts to get xdata located properly
+
+       Rearranged the firmware directory.
+       firmware/basic_fw/include --> firmware/include
+       firmware/basic_fw/src     --> firmware/src
+       All older firmware stuff was removed
+
+2003-11-15  Eric Blossom  <eb@comsec.com>
+
+       * host/lib/fusb.cc (fusb_devhandle, _cancel_pending_rqsts): now
+       use reverse_iterator to cancel pending requests from the back to
+       the front.  This removes the mystery of more than one cancelled
+       urb having a non-zero transfer count.
+
+       * host/lib/test_fusb.cc (test_output): fixed defective test case
+       that was having me think the tx code wasn't working.
+
+2003-11-13  Eric Blossom  <eb@comsec.com>
+
+       * host/lib/fusb.{h,cc}:  work in progress on the Rx path.
+
+2003-11-11  Eric Blossom  <eb@comsec.com>
+
+       * host/lib/fusb.{h,cc}: halved net Tx memory requirement by using
+       a single user mode buffer.
+
+2003-11-10  Eric Blossom  <eb@comsec.com>
+
+       System is now sustaining 31MB/sec on the TX path, no underruns ;-)
+       
+       * firmware/basic_fw/src/edit-gpif: now machine generate inline
+       definitions for setup_flowstate_common, setup_flowstate_read and
+       setup_flowstate_write. 
+
+       * firmware/basic_fw/src/usrp_common.c: clear_usrp_error now clears
+       over and underrun flags from status word.
+       * firmware/basic_fw/src/usrp_comands.c: added bit defs for overrun
+       and underrun status indicators.
+       * firmware/basic_fw/src/command_loop.c (poll_gpif): now checks for
+       over and underruns and clears fpga status.
+       
+       * firmware/basic_fw/include/usrp_regs.h (bmFCB_CLR_STATUS): moved
+       FPGA clear_status line to the previous location of SDO.  This
+       means that firmware from here out will only work with the latest
+       FPGA bitstreams that have this pin configurd as an input.
+
+       * host/lib/fusb.{h,cc}: fast streaming usb library built on top of libusb.
+       This version uses linux specific magic.
+
+       * host/lib/test_fusb.cc: test and benchmarking code for fusb.
+       
+2003-11-08  Eric Blossom  <eb@comsec.com>
+
+       * firmware/basic_fw/src/gpif.gpf: moved BOGUS ctl line to CTL5.
+       Added clear_status as CTL3.
+       * firmware/basic_fw/src/usrp_common.c (init_usrp): removed
+       obsolete ENABLE_FIFO ifdef.  Disabled RX pump priming.
+       * firmware/basic_fw/src/command_loop.c (main): enable both RX and TX.
+
+2003-10-22  Eric Blossom  <eb@comsec.com>
+
+       * host/lib/Usrp.{h,cc}: added accessors for get_rx_freq, get_tx_freq
+
+2003-10-17  Eric Blossom  <eb@comsec.com>
+
+       * host/usrper/test_input.cc (main): new program to exercise USRP
+       input path.
+
+       * host/lib/Usrp.{h,cc} (read): changed return value from bool to int
+
+2003-09-30  Eric Blossom  <eb@comsec.com>
+
+       * host/lib/Usrp.{h,cc}: handle new format interp and decim regs.
+       * firmware/basic_fw/src/command_loop.c (g_enable_read): disabled
+       read for the time being.
+
+2003-09-17  Eric Blossom  <eb@comsec.com>
+
+       * host/lib/Usrp.cc (find_file): changed load path for firmware and
+       fpga bits to to /usr/local/share/usrp.
+       (Usrp): now set gstate, sleep, fpga_reset and tx_enable per Matt's
+       script.
+
+2003-09-16  Eric Blossom  <eb@comsec.com>
+
+       * AUTHORS, NEWS, README: new & empty
+       * bootstrap, configure.ac, Makefile.am: new for autoconfiscation
+       * host/Makefile.am, host/lib/Makefile.am, host/usrper/Makefile.am: new
+       * host/lib/{Makefile.am,Usrp.{h,cc}}: new class to interface to USRP.
+       * host/usrper/usrper2.cc: new code to exercise Usrp.{h,cc}
+
+       * host/usrper/usrper.cc: removed uneeded includes
+
+2003-09-04  Eric Blossom  <eb@comsec.com>
+
+       * firmware/basic_fw/src/usrp_commands.h,
+       firmware/basic_fw/src/command_loop.c (do_set_sleep_bits),
+       host/usrper/usrper.cc (usrp_set_sleep_bits): added command to slam
+       the A/D and D/A sleep control lines.
+
+
+2003-08-30  Eric Blossom  <eb@comsec.com>
+
+       * firmware/basic_fw/src/usrp_commands.h: removed obsolete
+       foo_CLR_bar commands.  Added UCMD_SET_GSTATE_OUTPUT_ENABLE to
+       enable the output of the GPIF state on the low 3 bits of Port E.
+
+       * host/usrper/usrper.cc (usrper_load_firmware): now implements
+       "load_firmware" command.
+
+2003-08-17  Eric Blossom  <eb@comsec.com>
+
+       * host/usrper/usrper.cc (usrper_load_fpga),
+       firmware/basic_fw/src/fpga.c: changed load_fpga to expect a byte
+       count, not a bit count in the xfer packet.
+
+       * firmware/basic_fw/src/fpga.c (do_fpga_config_start): cleanup,
+       add appropriate delay.
+
+       * firmware/basic_fw/src/usrp_common.c (udelay1, udelay): new delay functions
+
+2003-07-30  Eric Blossom  <eb@comsec.com>
+
+       * firmware/basic_fw/include/fx2regs.h: changed sfr and sbit syntax
+       to match what SDCC expects.  Now the SFR's are really allocated
+       where they are supposed to be ;-)
+       
+#
+# 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 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.
+# 
diff --git a/usrp/Makefile.am b/usrp/Makefile.am
new file mode 100644 (file)
index 0000000..cd908c8
--- /dev/null
@@ -0,0 +1,25 @@
+#
+# 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 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.
+# 
+
+EXTRA_DIST = usrp.pc.in usrp.iss.in usrp.inf
+
+SUBDIRS = host firmware fpga doc
+
diff --git a/usrp/README b/usrp/README
new file mode 100644 (file)
index 0000000..63ff4a2
--- /dev/null
@@ -0,0 +1,37 @@
+#
+# README -- the short version
+#
+
+The top level makefile handles the host code and FX2 firmware.
+
+Besides the normal gcc suite and all the auto tools, you'll need
+the SDCC free C compiler to build the firmware.  You MUST
+USE VERSION 2.4.0 or VERSION 2.5.0 due to some problems with variable
+initialization.  http://sdcc.sourceforge.net
+
+
+# To get started...
+
+./bootstrap    # if you're building from CVS
+
+./configure
+make && make check && make install
+
+
+The high level interface to the USRP using our standard FPGA bitstram
+is contained in usrp/host/lib/usrp_standard.h
+
+If you've got doxygen installed, there are html docs in
+usrp/doc/html/index.html
+
+
+# Compiling the verilog (not required unless you're modifying it)
+
+If you want to build the FPGA .rbf file from source (not required; we
+provide pre-compiled .rbf files in usrp/fpga/rbf directory), you'll
+need Altera's no cost Quartus II development tools.  We're currently
+building with Quartus II 5.1sp1 Web Edition.  The project file is
+usrp/fpga/toplevel/usrp_std/usrp_std.qpf.  The toplevel verilog file
+is usrp/fpga/toplevel/usrp_std/usrp_std.v.  The bulk of the verilog
+modules are contained in usrp/fpga/sdr_lib
+
diff --git a/usrp/doc/Doxyfile.in b/usrp/doc/Doxyfile.in
new file mode 100644 (file)
index 0000000..e0533e5
--- /dev/null
@@ -0,0 +1,1167 @@
+#
+# Copyright 2001,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 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.
+# 
+
+# Doxyfile 1.3.7
+
+# This file describes the settings to be used by the documentation system
+# doxygen (www.doxygen.org) for a project
+#
+# All text after a hash (#) is considered a comment and will be ignored
+# The format is:
+#       TAG = value [value, ...]
+# For lists items can also be appended using:
+#       TAG += value [value, ...]
+# Values that contain spaces should be placed between quotes (" ")
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+
+# The PROJECT_NAME tag is a single word (or a sequence of words surrounded 
+# by quotes) that should identify the project.
+
+PROJECT_NAME           = "Universal Software Radio Peripheral"
+
+# The PROJECT_NUMBER tag can be used to enter a project or revision number. 
+# This could be handy for archiving the generated documentation or 
+# if some version control system is used.
+
+PROJECT_NUMBER         = 
+
+# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) 
+# base path where the generated documentation will be put. 
+# If a relative path is entered, it will be relative to the location 
+# where doxygen was started. If left blank the current directory will be used.
+
+OUTPUT_DIRECTORY       = 
+
+# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create 
+# 2 levels of 10 sub-directories under the output directory of each output 
+# format and will distribute the generated files over these directories. 
+# Enabling this option can be useful when feeding doxygen a huge amount of source 
+# files, where putting all generated files in the same directory would otherwise 
+# cause performance problems for the file system.
+
+CREATE_SUBDIRS         = NO
+
+# The OUTPUT_LANGUAGE tag is used to specify the language in which all 
+# documentation generated by doxygen is written. Doxygen will use this 
+# information to generate all constant output in the proper language. 
+# The default language is English, other supported languages are: 
+# Brazilian, Catalan, Chinese, Chinese-Traditional, Croatian, Czech, Danish, Dutch, 
+# Finnish, French, German, Greek, Hungarian, Italian, Japanese, Japanese-en 
+# (Japanese with English messages), Korean, Korean-en, Norwegian, Polish, Portuguese, 
+# Romanian, Russian, Serbian, Slovak, Slovene, Spanish, Swedish, and Ukrainian.
+
+OUTPUT_LANGUAGE        = English
+
+# This tag can be used to specify the encoding used in the generated output. 
+# The encoding is not always determined by the language that is chosen, 
+# but also whether or not the output is meant for Windows or non-Windows users. 
+# In case there is a difference, setting the USE_WINDOWS_ENCODING tag to YES 
+# forces the Windows encoding (this is the default for the Windows binary), 
+# whereas setting the tag to NO uses a Unix-style encoding (the default for 
+# all platforms other than Windows).
+
+USE_WINDOWS_ENCODING   = NO
+
+# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will 
+# include brief member descriptions after the members that are listed in 
+# the file and class documentation (similar to JavaDoc). 
+# Set to NO to disable this.
+
+BRIEF_MEMBER_DESC      = YES
+
+# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend 
+# the brief description of a member or function before the detailed description. 
+# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the 
+# brief descriptions will be completely suppressed.
+
+REPEAT_BRIEF           = YES
+
+# This tag implements a quasi-intelligent brief description abbreviator 
+# that is used to form the text in various listings. Each string 
+# in this list, if found as the leading text of the brief description, will be 
+# stripped from the text and the result after processing the whole list, is used 
+# as the annotated text. Otherwise, the brief description is used as-is. If left 
+# blank, the following values are used ("$name" is automatically replaced with the 
+# name of the entity): "The $name class" "The $name widget" "The $name file" 
+# "is" "provides" "specifies" "contains" "represents" "a" "an" "the"
+
+ABBREVIATE_BRIEF       = 
+
+# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then 
+# Doxygen will generate a detailed section even if there is only a brief 
+# description.
+
+ALWAYS_DETAILED_SEC    = NO
+
+# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all inherited 
+# members of a class in the documentation of that class as if those members were 
+# ordinary class members. Constructors, destructors and assignment operators of 
+# the base classes will not be shown.
+
+INLINE_INHERITED_MEMB  = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full 
+# path before files name in the file list and in the header files. If set 
+# to NO the shortest path that makes the file name unique will be used.
+
+FULL_PATH_NAMES        = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag 
+# can be used to strip a user-defined part of the path. Stripping is 
+# only done if one of the specified strings matches the left-hand part of 
+# the path. The tag can be used to show relative paths in the file list. 
+# If left blank the directory from which doxygen is run is used as the 
+# path to strip.
+
+STRIP_FROM_PATH        = 
+
+# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of 
+# the path mentioned in the documentation of a class, which tells 
+# the reader which header file to include in order to use a class. 
+# If left blank only the name of the header file containing the class 
+# definition is used. Otherwise one should specify the include paths that 
+# are normally passed to the compiler using the -I flag.
+
+STRIP_FROM_INC_PATH    = 
+
+# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter 
+# (but less readable) file names. This can be useful is your file systems 
+# doesn't support long names like on DOS, Mac, or CD-ROM.
+
+SHORT_NAMES            = NO
+
+# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen 
+# will interpret the first line (until the first dot) of a JavaDoc-style 
+# comment as the brief description. If set to NO, the JavaDoc 
+# comments will behave just like the Qt-style comments (thus requiring an 
+# explicit @brief command for a brief description.
+
+JAVADOC_AUTOBRIEF      = NO
+
+# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen 
+# treat a multi-line C++ special comment block (i.e. a block of //! or /// 
+# comments) as a brief description. This used to be the default behaviour. 
+# The new default is to treat a multi-line C++ comment block as a detailed 
+# description. Set this tag to YES if you prefer the old behaviour instead.
+
+MULTILINE_CPP_IS_BRIEF = NO
+
+# If the DETAILS_AT_TOP tag is set to YES then Doxygen 
+# will output the detailed description near the top, like JavaDoc.
+# If set to NO, the detailed description appears after the member 
+# documentation.
+
+DETAILS_AT_TOP         = YES
+
+# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented 
+# member inherits the documentation from any documented member that it 
+# re-implements.
+
+INHERIT_DOCS           = YES
+
+# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC 
+# tag is set to YES, then doxygen will reuse the documentation of the first 
+# member in the group (if any) for the other members of the group. By default 
+# all members of a group must be documented explicitly.
+
+DISTRIBUTE_GROUP_DOC   = NO
+
+# The TAB_SIZE tag can be used to set the number of spaces in a tab. 
+# Doxygen uses this value to replace tabs by spaces in code fragments.
+
+TAB_SIZE               = 8
+
+# This tag can be used to specify a number of aliases that acts 
+# as commands in the documentation. An alias has the form "name=value". 
+# For example adding "sideeffect=\par Side Effects:\n" will allow you to 
+# put the command \sideeffect (or @sideeffect) in the documentation, which 
+# will result in a user-defined paragraph with heading "Side Effects:". 
+# You can put \n's in the value part of an alias to insert newlines.
+
+ALIASES                = 
+
+# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources 
+# only. Doxygen will then generate output that is more tailored for C. 
+# For instance, some of the names that are used will be different. The list 
+# of all members will be omitted, etc.
+
+OPTIMIZE_OUTPUT_FOR_C  = NO
+
+# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java sources 
+# only. Doxygen will then generate output that is more tailored for Java. 
+# For instance, namespaces will be presented as packages, qualified scopes 
+# will look different, etc.
+
+OPTIMIZE_OUTPUT_JAVA   = NO
+
+# Set the SUBGROUPING tag to YES (the default) to allow class member groups of 
+# the same type (for instance a group of public functions) to be put as a 
+# subgroup of that type (e.g. under the Public Functions section). Set it to 
+# NO to prevent subgrouping. Alternatively, this can be done per class using 
+# the \nosubgrouping command.
+
+SUBGROUPING            = YES
+
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+
+# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in 
+# documentation are documented, even if no documentation was available. 
+# Private class members and static file members will be hidden unless 
+# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
+
+EXTRACT_ALL            = YES
+
+# If the EXTRACT_PRIVATE tag is set to YES all private members of a class 
+# will be included in the documentation.
+
+EXTRACT_PRIVATE        = NO
+
+# If the EXTRACT_STATIC tag is set to YES all static members of a file 
+# will be included in the documentation.
+
+EXTRACT_STATIC         = NO
+
+# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) 
+# defined locally in source files will be included in the documentation. 
+# If set to NO only classes defined in header files are included.
+
+EXTRACT_LOCAL_CLASSES  = YES
+
+# This flag is only useful for Objective-C code. When set to YES local 
+# methods, which are defined in the implementation section but not in 
+# the interface are included in the documentation. 
+# If set to NO (the default) only methods in the interface are included.
+
+EXTRACT_LOCAL_METHODS  = NO
+
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all 
+# undocumented members of documented classes, files or namespaces. 
+# If set to NO (the default) these members will be included in the 
+# various overviews, but no documentation section is generated. 
+# This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_MEMBERS     = NO
+
+# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all 
+# undocumented classes that are normally visible in the class hierarchy. 
+# If set to NO (the default) these classes will be included in the various 
+# overviews. This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_CLASSES     = NO
+
+# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all 
+# friend (class|struct|union) declarations. 
+# If set to NO (the default) these declarations will be included in the 
+# documentation.
+
+HIDE_FRIEND_COMPOUNDS  = NO
+
+# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any 
+# documentation blocks found inside the body of a function. 
+# If set to NO (the default) these blocks will be appended to the 
+# function's detailed documentation block.
+
+HIDE_IN_BODY_DOCS      = NO
+
+# The INTERNAL_DOCS tag determines if documentation 
+# that is typed after a \internal command is included. If the tag is set 
+# to NO (the default) then the documentation will be excluded. 
+# Set it to YES to include the internal documentation.
+
+INTERNAL_DOCS          = NO
+
+# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate 
+# file names in lower-case letters. If set to YES upper-case letters are also 
+# allowed. This is useful if you have classes or files whose names only differ 
+# in case and if your file system supports case sensitive file names. Windows 
+# users are advised to set this option to NO.
+
+CASE_SENSE_NAMES       = YES
+
+# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen 
+# will show members with their full class and namespace scopes in the 
+# documentation. If set to YES the scope will be hidden.
+
+HIDE_SCOPE_NAMES       = NO
+
+# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen 
+# will put a list of the files that are included by a file in the documentation 
+# of that file.
+
+SHOW_INCLUDE_FILES     = YES
+
+# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] 
+# is inserted in the documentation for inline members.
+
+INLINE_INFO            = YES
+
+# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen 
+# will sort the (detailed) documentation of file and class members 
+# alphabetically by member name. If set to NO the members will appear in 
+# declaration order.
+
+SORT_MEMBER_DOCS       = YES
+
+# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the 
+# brief documentation of file, namespace and class members alphabetically 
+# by member name. If set to NO (the default) the members will appear in 
+# declaration order.
+
+SORT_BRIEF_DOCS        = NO
+
+# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be 
+# sorted by fully-qualified names, including namespaces. If set to 
+# NO (the default), the class list will be sorted only by class name, 
+# not including the namespace part. 
+# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
+# Note: This option applies only to the class list, not to the 
+# alphabetical list.
+
+SORT_BY_SCOPE_NAME     = NO
+
+# The GENERATE_TODOLIST tag can be used to enable (YES) or 
+# disable (NO) the todo list. This list is created by putting \todo 
+# commands in the documentation.
+
+GENERATE_TODOLIST      = YES
+
+# The GENERATE_TESTLIST tag can be used to enable (YES) or 
+# disable (NO) the test list. This list is created by putting \test 
+# commands in the documentation.
+
+GENERATE_TESTLIST      = YES
+
+# The GENERATE_BUGLIST tag can be used to enable (YES) or 
+# disable (NO) the bug list. This list is created by putting \bug 
+# commands in the documentation.
+
+GENERATE_BUGLIST       = YES
+
+# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or 
+# disable (NO) the deprecated list. This list is created by putting 
+# \deprecated commands in the documentation.
+
+GENERATE_DEPRECATEDLIST= YES
+
+# The ENABLED_SECTIONS tag can be used to enable conditional 
+# documentation sections, marked by \if sectionname ... \endif.
+
+ENABLED_SECTIONS       = 
+
+# The MAX_INITIALIZER_LINES tag determines the maximum number of lines 
+# the initial value of a variable or define consists of for it to appear in 
+# the documentation. If the initializer consists of more lines than specified 
+# here it will be hidden. Use a value of 0 to hide initializers completely. 
+# The appearance of the initializer of individual variables and defines in the 
+# documentation can be controlled using \showinitializer or \hideinitializer 
+# command in the documentation regardless of this setting.
+
+MAX_INITIALIZER_LINES  = 30
+
+# Set the SHOW_USED_FILES tag to NO to disable the list of files generated 
+# at the bottom of the documentation of classes and structs. If set to YES the 
+# list will mention the files that were used to generate the documentation.
+
+SHOW_USED_FILES        = YES
+
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+
+# The QUIET tag can be used to turn on/off the messages that are generated 
+# by doxygen. Possible values are YES and NO. If left blank NO is used.
+
+QUIET                  = NO
+
+# The WARNINGS tag can be used to turn on/off the warning messages that are 
+# generated by doxygen. Possible values are YES and NO. If left blank 
+# NO is used.
+
+WARNINGS               = YES
+
+# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings 
+# for undocumented members. If EXTRACT_ALL is set to YES then this flag will 
+# automatically be disabled.
+
+WARN_IF_UNDOCUMENTED   = YES
+
+# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for 
+# potential errors in the documentation, such as not documenting some 
+# parameters in a documented function, or documenting parameters that 
+# don't exist or using markup commands wrongly.
+
+WARN_IF_DOC_ERROR      = YES
+
+# The WARN_FORMAT tag determines the format of the warning messages that 
+# doxygen can produce. The string should contain the $file, $line, and $text 
+# tags, which will be replaced by the file and line number from which the 
+# warning originated and the warning text.
+
+WARN_FORMAT            = "$file:$line: $text"
+
+# The WARN_LOGFILE tag can be used to specify a file to which warning 
+# and error messages should be written. If left blank the output is written 
+# to stderr.
+
+WARN_LOGFILE           = 
+
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+
+# The INPUT tag can be used to specify the files and/or directories that contain 
+# documented source files. You may enter file names like "myfile.cpp" or 
+# directories like "/usr/src/myproject". Separate the files or directories 
+# with spaces.
+
+INPUT                  = @top_srcdir@/host \
+                         @top_srcdir@/doc/other
+
+# If the value of the INPUT tag contains directories, you can use the 
+# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp 
+# and *.h) to filter out the source-files in the directories. If left 
+# blank the following patterns are tested: 
+# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx *.hpp 
+# *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm
+
+FILE_PATTERNS          = *.h \
+                         *.cc \
+                         *.dox
+
+# The RECURSIVE tag can be used to turn specify whether or not subdirectories 
+# should be searched for input files as well. Possible values are YES and NO. 
+# If left blank NO is used.
+
+RECURSIVE              = YES
+
+# The EXCLUDE tag can be used to specify files and/or directories that should 
+# excluded from the INPUT source files. This way you can easily exclude a 
+# subdirectory from a directory tree whose root is specified with the INPUT tag.
+
+EXCLUDE                = CVS \
+                         @top_srcdir@/host/swig
+
+# The EXCLUDE_SYMLINKS tag can be used select whether or not files or directories 
+# that are symbolic links (a Unix filesystem feature) are excluded from the input.
+
+EXCLUDE_SYMLINKS       = NO
+
+# If the value of the INPUT tag contains directories, you can use the 
+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude 
+# certain files from those directories.
+
+EXCLUDE_PATTERNS       = moc_*.cc
+
+# The EXAMPLE_PATH tag can be used to specify one or more files or 
+# directories that contain example code fragments that are included (see 
+# the \include command).
+
+EXAMPLE_PATH           = 
+
+# If the value of the EXAMPLE_PATH tag contains directories, you can use the 
+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp 
+# and *.h) to filter out the source-files in the directories. If left 
+# blank all files are included.
+
+EXAMPLE_PATTERNS       = 
+
+# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be 
+# searched for input files to be used with the \include or \dontinclude 
+# commands irrespective of the value of the RECURSIVE tag. 
+# Possible values are YES and NO. If left blank NO is used.
+
+EXAMPLE_RECURSIVE      = NO
+
+# The IMAGE_PATH tag can be used to specify one or more files or 
+# directories that contain image that are included in the documentation (see 
+# the \image command).
+
+IMAGE_PATH             = 
+
+# The INPUT_FILTER tag can be used to specify a program that doxygen should 
+# invoke to filter for each input file. Doxygen will invoke the filter program 
+# by executing (via popen()) the command <filter> <input-file>, where <filter> 
+# is the value of the INPUT_FILTER tag, and <input-file> is the name of an 
+# input file. Doxygen will then use the output that the filter program writes 
+# to standard output.
+
+INPUT_FILTER           = 
+
+# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using 
+# INPUT_FILTER) will be used to filter the input files when producing source 
+# files to browse (i.e. when SOURCE_BROWSER is set to YES).
+
+FILTER_SOURCE_FILES    = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+
+# If the SOURCE_BROWSER tag is set to YES then a list of source files will 
+# be generated. Documented entities will be cross-referenced with these sources. 
+# Note: To get rid of all source code in the generated output, make sure also 
+# VERBATIM_HEADERS is set to NO.
+
+SOURCE_BROWSER         = NO
+
+# Setting the INLINE_SOURCES tag to YES will include the body 
+# of functions and classes directly in the documentation.
+
+INLINE_SOURCES         = NO
+
+# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct 
+# doxygen to hide any special comment blocks from generated source code 
+# fragments. Normal C and C++ comments will always remain visible.
+
+STRIP_CODE_COMMENTS    = YES
+
+# If the REFERENCED_BY_RELATION tag is set to YES (the default) 
+# then for each documented function all documented 
+# functions referencing it will be listed.
+
+REFERENCED_BY_RELATION = YES
+
+# If the REFERENCES_RELATION tag is set to YES (the default) 
+# then for each documented function all documented entities 
+# called/used by that function will be listed.
+
+REFERENCES_RELATION    = YES
+
+# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen 
+# will generate a verbatim copy of the header file for each class for 
+# which an include is specified. Set to NO to disable this.
+
+VERBATIM_HEADERS       = YES
+
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+
+# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index 
+# of all compounds will be generated. Enable this if the project 
+# contains a lot of classes, structs, unions or interfaces.
+
+ALPHABETICAL_INDEX     = NO
+
+# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then 
+# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns 
+# in which this list will be split (can be a number in the range [1..20])
+
+COLS_IN_ALPHA_INDEX    = 5
+
+# In case all classes in a project start with a common prefix, all 
+# classes will be put under the same header in the alphabetical index. 
+# The IGNORE_PREFIX tag can be used to specify one or more prefixes that 
+# should be ignored while generating the index headers.
+
+IGNORE_PREFIX          = 
+
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_HTML tag is set to YES (the default) Doxygen will 
+# generate HTML output.
+
+GENERATE_HTML          = YES
+
+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `html' will be used as the default path.
+
+HTML_OUTPUT            = html
+
+# The HTML_FILE_EXTENSION tag can be used to specify the file extension for 
+# each generated HTML page (for example: .htm,.php,.asp). If it is left blank 
+# doxygen will generate files with .html extension.
+
+HTML_FILE_EXTENSION    = .html
+
+# The HTML_HEADER tag can be used to specify a personal HTML header for 
+# each generated HTML page. If it is left blank doxygen will generate a 
+# standard header.
+
+HTML_HEADER            = 
+
+# The HTML_FOOTER tag can be used to specify a personal HTML footer for 
+# each generated HTML page. If it is left blank doxygen will generate a 
+# standard footer.
+
+HTML_FOOTER            = 
+
+# The HTML_STYLESHEET tag can be used to specify a user-defined cascading 
+# style sheet that is used by each HTML page. It can be used to 
+# fine-tune the look of the HTML output. If the tag is left blank doxygen 
+# will generate a default style sheet. Note that doxygen will try to copy 
+# the style sheet file to the HTML output directory, so don't put your own 
+# stylesheet in the HTML output directory as well, or it will be erased!
+
+HTML_STYLESHEET        = 
+
+# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, 
+# files or namespaces will be aligned in HTML using tables. If set to 
+# NO a bullet list will be used.
+
+HTML_ALIGN_MEMBERS     = YES
+
+# If the GENERATE_HTMLHELP tag is set to YES, additional index files 
+# will be generated that can be used as input for tools like the 
+# Microsoft HTML help workshop to generate a compressed HTML help file (.chm) 
+# of the generated HTML documentation.
+
+GENERATE_HTMLHELP      = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can 
+# be used to specify the file name of the resulting .chm file. You 
+# can add a path in front of the file if the result should not be 
+# written to the html output directory.
+
+CHM_FILE               = 
+
+# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can 
+# be used to specify the location (absolute path including file name) of 
+# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run 
+# the HTML help compiler on the generated index.hhp.
+
+HHC_LOCATION           = 
+
+# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag 
+# controls if a separate .chi index file is generated (YES) or that 
+# it should be included in the master .chm file (NO).
+
+GENERATE_CHI           = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag 
+# controls whether a binary table of contents is generated (YES) or a 
+# normal table of contents (NO) in the .chm file.
+
+BINARY_TOC             = NO
+
+# The TOC_EXPAND flag can be set to YES to add extra items for group members 
+# to the contents of the HTML help documentation and to the tree view.
+
+TOC_EXPAND             = NO
+
+# The DISABLE_INDEX tag can be used to turn on/off the condensed index at 
+# top of each HTML page. The value NO (the default) enables the index and 
+# the value YES disables it.
+
+DISABLE_INDEX          = NO
+
+# This tag can be used to set the number of enum values (range [1..20]) 
+# that doxygen will group on one line in the generated HTML documentation.
+
+ENUM_VALUES_PER_LINE   = 4
+
+# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be
+# generated containing a tree-like index structure (just like the one that 
+# is generated for HTML Help). For this to work a browser that supports 
+# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, 
+# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are 
+# probably better off using the HTML help feature.
+
+GENERATE_TREEVIEW      = NO
+
+# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be 
+# used to set the initial width (in pixels) of the frame in which the tree 
+# is shown.
+
+TREEVIEW_WIDTH         = 250
+
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will 
+# generate Latex output.
+
+GENERATE_LATEX         = NO
+
+# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `latex' will be used as the default path.
+
+LATEX_OUTPUT           = latex
+
+# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be 
+# invoked. If left blank `latex' will be used as the default command name.
+
+LATEX_CMD_NAME         = latex
+
+# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to 
+# generate index for LaTeX. If left blank `makeindex' will be used as the 
+# default command name.
+
+MAKEINDEX_CMD_NAME     = makeindex
+
+# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact 
+# LaTeX documents. This may be useful for small projects and may help to 
+# save some trees in general.
+
+COMPACT_LATEX          = NO
+
+# The PAPER_TYPE tag can be used to set the paper type that is used 
+# by the printer. Possible values are: a4, a4wide, letter, legal and 
+# executive. If left blank a4wide will be used.
+
+PAPER_TYPE             = letter
+
+# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX 
+# packages that should be included in the LaTeX output.
+
+EXTRA_PACKAGES         = 
+
+# The LATEX_HEADER tag can be used to specify a personal LaTeX header for 
+# the generated latex document. The header should contain everything until 
+# the first chapter. If it is left blank doxygen will generate a 
+# standard header. Notice: only use this tag if you know what you are doing!
+
+LATEX_HEADER           = 
+
+# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated 
+# is prepared for conversion to pdf (using ps2pdf). The pdf file will 
+# contain links (just like the HTML output) instead of page references 
+# This makes the output suitable for online browsing using a pdf viewer.
+
+PDF_HYPERLINKS         = YES
+
+# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of 
+# plain latex in the generated Makefile. Set this option to YES to get a 
+# higher quality PDF documentation.
+
+USE_PDFLATEX           = NO
+
+# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. 
+# command to the generated LaTeX files. This will instruct LaTeX to keep 
+# running if errors occur, instead of asking the user for help. 
+# This option is also used when generating formulas in HTML.
+
+LATEX_BATCHMODE        = NO
+
+# If LATEX_HIDE_INDICES is set to YES then doxygen will not 
+# include the index chapters (such as File Index, Compound Index, etc.) 
+# in the output.
+
+LATEX_HIDE_INDICES     = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output 
+# The RTF output is optimized for Word 97 and may not look very pretty with 
+# other RTF readers or editors.
+
+GENERATE_RTF           = NO
+
+# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `rtf' will be used as the default path.
+
+RTF_OUTPUT             = rtf
+
+# If the COMPACT_RTF tag is set to YES Doxygen generates more compact 
+# RTF documents. This may be useful for small projects and may help to 
+# save some trees in general.
+
+COMPACT_RTF            = NO
+
+# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated 
+# will contain hyperlink fields. The RTF file will 
+# contain links (just like the HTML output) instead of page references. 
+# This makes the output suitable for online browsing using WORD or other 
+# programs which support those fields. 
+# Note: wordpad (write) and others do not support links.
+
+RTF_HYPERLINKS         = NO
+
+# Load stylesheet definitions from file. Syntax is similar to doxygen's 
+# config file, i.e. a series of assignments. You only have to provide 
+# replacements, missing definitions are set to their default value.
+
+RTF_STYLESHEET_FILE    = 
+
+# Set optional variables used in the generation of an rtf document. 
+# Syntax is similar to doxygen's config file.
+
+RTF_EXTENSIONS_FILE    = 
+
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_MAN tag is set to YES (the default) Doxygen will 
+# generate man pages
+
+GENERATE_MAN           = NO
+
+# The MAN_OUTPUT tag is used to specify where the man pages will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `man' will be used as the default path.
+
+MAN_OUTPUT             = man
+
+# The MAN_EXTENSION tag determines the extension that is added to 
+# the generated man pages (default is the subroutine's section .3)
+
+MAN_EXTENSION          = .3
+
+# If the MAN_LINKS tag is set to YES and Doxygen generates man output, 
+# then it will generate one additional man file for each entity 
+# documented in the real man page(s). These additional files 
+# only source the real man page, but without them the man command 
+# would be unable to find the correct page. The default is NO.
+
+MAN_LINKS              = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_XML tag is set to YES Doxygen will 
+# generate an XML file that captures the structure of 
+# the code including all documentation.
+
+GENERATE_XML           = YES
+
+# The XML_OUTPUT tag is used to specify where the XML pages will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `xml' will be used as the default path.
+
+XML_OUTPUT             = xml
+
+# The XML_SCHEMA tag can be used to specify an XML schema, 
+# which can be used by a validating XML parser to check the 
+# syntax of the XML files.
+
+XML_SCHEMA             = 
+
+# The XML_DTD tag can be used to specify an XML DTD, 
+# which can be used by a validating XML parser to check the 
+# syntax of the XML files.
+
+XML_DTD                = 
+
+# If the XML_PROGRAMLISTING tag is set to YES Doxygen will 
+# dump the program listings (including syntax highlighting 
+# and cross-referencing information) to the XML output. Note that 
+# enabling this will significantly increase the size of the XML output.
+
+XML_PROGRAMLISTING     = YES
+
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will 
+# generate an AutoGen Definitions (see autogen.sf.net) file 
+# that captures the structure of the code including all 
+# documentation. Note that this feature is still experimental 
+# and incomplete at the moment.
+
+GENERATE_AUTOGEN_DEF   = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_PERLMOD tag is set to YES Doxygen will 
+# generate a Perl module file that captures the structure of 
+# the code including all documentation. Note that this 
+# feature is still experimental and incomplete at the 
+# moment.
+
+GENERATE_PERLMOD       = NO
+
+# If the PERLMOD_LATEX tag is set to YES Doxygen will generate 
+# the necessary Makefile rules, Perl scripts and LaTeX code to be able 
+# to generate PDF and DVI output from the Perl module output.
+
+PERLMOD_LATEX          = NO
+
+# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be 
+# nicely formatted so it can be parsed by a human reader.  This is useful 
+# if you want to understand what is going on.  On the other hand, if this 
+# tag is set to NO the size of the Perl module output will be much smaller 
+# and Perl will parse it just the same.
+
+PERLMOD_PRETTY         = YES
+
+# The names of the make variables in the generated doxyrules.make file 
+# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. 
+# This is useful so different doxyrules.make files included by the same 
+# Makefile don't overwrite each other's variables.
+
+PERLMOD_MAKEVAR_PREFIX = 
+
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor   
+#---------------------------------------------------------------------------
+
+# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will 
+# evaluate all C-preprocessor directives found in the sources and include 
+# files.
+
+ENABLE_PREPROCESSING   = YES
+
+# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro 
+# names in the source code. If set to NO (the default) only conditional 
+# compilation will be performed. Macro expansion can be done in a controlled 
+# way by setting EXPAND_ONLY_PREDEF to YES.
+
+MACRO_EXPANSION        = NO
+
+# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES 
+# then the macro expansion is limited to the macros specified with the 
+# PREDEFINED and EXPAND_AS_PREDEFINED tags.
+
+EXPAND_ONLY_PREDEF     = NO
+
+# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files 
+# in the INCLUDE_PATH (see below) will be search if a #include is found.
+
+SEARCH_INCLUDES        = YES
+
+# The INCLUDE_PATH tag can be used to specify one or more directories that 
+# contain include files that are not input files but should be processed by 
+# the preprocessor.
+
+INCLUDE_PATH           = 
+
+# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard 
+# patterns (like *.h and *.hpp) to filter out the header-files in the 
+# directories. If left blank, the patterns specified with FILE_PATTERNS will 
+# be used.
+
+INCLUDE_FILE_PATTERNS  = 
+
+# The PREDEFINED tag can be used to specify one or more macro names that 
+# are defined before the preprocessor is started (similar to the -D option of 
+# gcc). The argument of the tag is a list of macros of the form: name 
+# or name=definition (no spaces). If the definition and the = are 
+# omitted =1 is assumed.
+
+PREDEFINED             = 
+
+# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then 
+# this tag can be used to specify a list of macro names that should be expanded. 
+# The macro definition that is found in the sources will be used. 
+# Use the PREDEFINED tag if you want to use a different macro definition.
+
+EXPAND_AS_DEFINED      = 
+
+# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then 
+# doxygen's preprocessor will remove all function-like macros that are alone 
+# on a line, have an all uppercase name, and do not end with a semicolon. Such 
+# function macros are typically used for boiler-plate code, and will confuse the 
+# parser if not removed.
+
+SKIP_FUNCTION_MACROS   = YES
+
+#---------------------------------------------------------------------------
+# Configuration::additions related to external references   
+#---------------------------------------------------------------------------
+
+# The TAGFILES option can be used to specify one or more tagfiles. 
+# Optionally an initial location of the external documentation 
+# can be added for each tagfile. The format of a tag file without 
+# this location is as follows: 
+#   TAGFILES = file1 file2 ... 
+# Adding location for the tag files is done as follows: 
+#   TAGFILES = file1=loc1 "file2 = loc2" ... 
+# where "loc1" and "loc2" can be relative or absolute paths or 
+# URLs. If a location is present for each tag, the installdox tool 
+# does not have to be run to correct the links.
+# Note that each tag file must have a unique name
+# (where the name does NOT include the path)
+# If a tag file is not located in the directory in which doxygen 
+# is run, you must also specify the path to the tagfile here.
+
+TAGFILES               = 
+
+# When a file name is specified after GENERATE_TAGFILE, doxygen will create 
+# a tag file that is based on the input files it reads.
+
+GENERATE_TAGFILE       = 
+
+# If the ALLEXTERNALS tag is set to YES all external classes will be listed 
+# in the class index. If set to NO only the inherited external classes 
+# will be listed.
+
+ALLEXTERNALS           = NO
+
+# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed 
+# in the modules index. If set to NO, only the current project's groups will 
+# be listed.
+
+EXTERNAL_GROUPS        = YES
+
+# The PERL_PATH should be the absolute path and name of the perl script 
+# interpreter (i.e. the result of `which perl').
+
+PERL_PATH              = /usr/bin/perl
+
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool   
+#---------------------------------------------------------------------------
+
+# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will 
+# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base or 
+# super classes. Setting the tag to NO turns the diagrams off. Note that this 
+# option is superseded by the HAVE_DOT option below. This is only a fallback. It is 
+# recommended to install and use dot, since it yields more powerful graphs.
+
+CLASS_DIAGRAMS         = YES
+
+# If set to YES, the inheritance and collaboration graphs will hide 
+# inheritance and usage relations if the target is undocumented 
+# or is not a class.
+
+HIDE_UNDOC_RELATIONS   = YES
+
+# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is 
+# available from the path. This tool is part of Graphviz, a graph visualization 
+# toolkit from AT&T and Lucent Bell Labs. The other options in this section 
+# have no effect if this option is set to NO (the default)
+
+HAVE_DOT               = @HAVE_DOT@
+
+# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen 
+# will generate a graph for each documented class showing the direct and 
+# indirect inheritance relations. Setting this tag to YES will force the 
+# the CLASS_DIAGRAMS tag to NO.
+
+CLASS_GRAPH            = YES
+
+# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen 
+# will generate a graph for each documented class showing the direct and 
+# indirect implementation dependencies (inheritance, containment, and 
+# class references variables) of the class with other documented classes.
+
+COLLABORATION_GRAPH    = YES
+
+# If the UML_LOOK tag is set to YES doxygen will generate inheritance and 
+# collaboration diagrams in a style similar to the OMG's Unified Modeling 
+# Language.
+
+UML_LOOK               = NO
+
+# If set to YES, the inheritance and collaboration graphs will show the 
+# relations between templates and their instances.
+
+TEMPLATE_RELATIONS     = NO
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT 
+# tags are set to YES then doxygen will generate a graph for each documented 
+# file showing the direct and indirect include dependencies of the file with 
+# other documented files.
+
+INCLUDE_GRAPH          = YES
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and 
+# HAVE_DOT tags are set to YES then doxygen will generate a graph for each 
+# documented header file showing the documented files that directly or 
+# indirectly include this file.
+
+INCLUDED_BY_GRAPH      = YES
+
+# If the CALL_GRAPH and HAVE_DOT tags are set to YES then doxygen will 
+# generate a call dependency graph for every global function or class method. 
+# Note that enabling this option will significantly increase the time of a run. 
+# So in most cases it will be better to enable call graphs for selected 
+# functions only using the \callgraph command.
+
+CALL_GRAPH             = NO
+
+# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen 
+# will graphical hierarchy of all classes instead of a textual one.
+
+GRAPHICAL_HIERARCHY    = YES
+
+# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images 
+# generated by dot. Possible values are png, jpg, or gif
+# If left blank png will be used.
+
+DOT_IMAGE_FORMAT       = png
+
+# The tag DOT_PATH can be used to specify the path where the dot tool can be 
+# found. If left blank, it is assumed the dot tool can be found on the path.
+
+DOT_PATH               = 
+
+# The DOTFILE_DIRS tag can be used to specify one or more directories that 
+# contain dot files that are included in the documentation (see the 
+# \dotfile command).
+
+DOTFILE_DIRS           = 
+
+# The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width 
+# (in pixels) of the graphs generated by dot. If a graph becomes larger than 
+# this value, doxygen will try to truncate the graph, so that it fits within 
+# the specified constraint. Beware that most browsers cannot cope with very 
+# large images.
+
+MAX_DOT_GRAPH_WIDTH    = 1024
+
+# The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height 
+# (in pixels) of the graphs generated by dot. If a graph becomes larger than 
+# this value, doxygen will try to truncate the graph, so that it fits within 
+# the specified constraint. Beware that most browsers cannot cope with very 
+# large images.
+
+MAX_DOT_GRAPH_HEIGHT   = 1024
+
+# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the 
+# graphs generated by dot. A depth value of 3 means that only nodes reachable 
+# from the root by following a path via at most 3 edges will be shown. Nodes that 
+# lay further from the root node will be omitted. Note that setting this option to 
+# 1 or 2 may greatly reduce the computation time needed for large code bases. Also 
+# note that a graph may be further truncated if the graph's image dimensions are 
+# not sufficient to fit the graph (see MAX_DOT_GRAPH_WIDTH and MAX_DOT_GRAPH_HEIGHT). 
+# If 0 is used for the depth value (the default), the graph is not depth-constrained.
+
+MAX_DOT_GRAPH_DEPTH    = 0
+
+# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will 
+# generate a legend page explaining the meaning of the various boxes and 
+# arrows in the dot generated graphs.
+
+GENERATE_LEGEND        = YES
+
+# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will 
+# remove the intermediate dot files that are used to generate 
+# the various graphs.
+
+DOT_CLEANUP            = YES
+
+#---------------------------------------------------------------------------
+# Configuration::additions related to the search engine   
+#---------------------------------------------------------------------------
+
+# The SEARCHENGINE tag specifies whether or not a search engine should be 
+# used. If set to NO the values of all tags below this one will be ignored.
+
+SEARCHENGINE           = NO
diff --git a/usrp/doc/Makefile.am b/usrp/doc/Makefile.am
new file mode 100644 (file)
index 0000000..563fa92
--- /dev/null
@@ -0,0 +1,79 @@
+#
+# 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 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.
+# 
+
+include $(top_srcdir)/Makefile.common
+
+
+SUBDIRS = other
+
+man3dir = $(mandir)/man3
+docdir  = $(prefix)/share/doc/@PACKAGE@-@VERSION@
+
+EXTRA_DIST =                   \
+       Doxyfile.in             \
+       ddc.eps                 \
+       ddc.png                 \
+       usrp-block-diagram.eps  \
+       usrp-block-diagram.png  \
+       usrp.jpg                \
+       usrp_guide.xml          
+
+if HAS_XMLTO
+DOCBOOK_HTML_FILES=usrp_guide.html
+all-local: dox docbook-html
+else
+DOCBOOK_HTML_FILES=
+all-local: dox
+endif
+
+dox: html/index.html
+html/index.html:
+       mkdir -p html
+       @DOXYGEN@
+
+docbook-html: usrp_guide.html
+
+usrp_guide.html: usrp_guide.xml
+       xmlto html-nochunks $<
+
+install-data-local:
+       $(mkinstalldirs) $(DESTDIR)$(docdir)
+       @for i in $(top_srcdir)/usrp/README $(top_srcdir)/usrp/ChangeLog; do \
+               echo "$(INSTALL_DATA) $$i $(DESTDIR)$(docdir)"; \
+               $(INSTALL_DATA) $$i $(DESTDIR)$(docdir); \
+       done
+
+       mkdir -p $(DESTDIR)$(docdir)/html
+       @for i in $(DOCBOOK_HTML_FILES); do \
+               echo "$(INSTALL_DATA) $$i $(DESTDIR)$(docdir)/html"; \
+               $(INSTALL_DATA) $$i $(DESTDIR)$(docdir)/html; \
+       done
+       cp -r html $(DESTDIR)$(docdir)
+
+uninstall-local:
+       @for i in README ChangeLog; do \
+               echo "$(RM) $(DESTDIR)$(docdir)/$$i;"; \
+               $(RM) $(DESTDIR)$(docdir)/$$i; \
+       done
+       $(RM) -fr $(DESTDIR)$(docdir)/html
+
+clean-local:
+       $(RM) -fr latex html man xml $(DOCBOOK_HTML_FILES)
diff --git a/usrp/doc/ddc.eps b/usrp/doc/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/usrp/doc/ddc.png b/usrp/doc/ddc.png
new file mode 100644 (file)
index 0000000..ce35bc2
Binary files /dev/null and b/usrp/doc/ddc.png differ
diff --git a/usrp/doc/other/Makefile.am b/usrp/doc/other/Makefile.am
new file mode 100644 (file)
index 0000000..c10311e
--- /dev/null
@@ -0,0 +1,25 @@
+#
+# 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 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.
+# 
+
+include $(top_srcdir)/Makefile.common
+
+EXTRA_DIST =                   \
+       mainpage.dox            
diff --git a/usrp/doc/other/mainpage.dox b/usrp/doc/other/mainpage.dox
new file mode 100644 (file)
index 0000000..56068cc
--- /dev/null
@@ -0,0 +1,9 @@
+/*! \mainpage
+
+The top level interfaces to the USRP are usrp_standard_rx and
+usrp_standard_tx.  Also take a look at their base classes,
+usrp_basic_rx, usrp_basic_tx and usrp_basic.
+
+See also <a href="usrp_guide.html">USRP User's and Developer's Guide</a>
+
+*/
diff --git a/usrp/doc/usrp-block-diagram.eps b/usrp/doc/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/usrp/doc/usrp-block-diagram.png b/usrp/doc/usrp-block-diagram.png
new file mode 100644 (file)
index 0000000..55a0f0b
Binary files /dev/null and b/usrp/doc/usrp-block-diagram.png differ
diff --git a/usrp/doc/usrp.jpg b/usrp/doc/usrp.jpg
new file mode 100644 (file)
index 0000000..0ddb592
Binary files /dev/null and b/usrp/doc/usrp.jpg differ
diff --git a/usrp/doc/usrp_guide.xml b/usrp/doc/usrp_guide.xml
new file mode 100644 (file)
index 0000000..7c4d5d5
--- /dev/null
@@ -0,0 +1,399 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+          "docbookx.dtd" [
+]>
+
+<article>
+  <articleinfo>
+  <title>USRP User's and Developer's Guide</title>
+    <author>
+      <firstname>Matt</firstname>
+      <surname>Ettus</surname>
+      <affiliation>
+       <orgname>Ettus Research LLC</orgname>
+       <address>
+         Ettus Research LLC
+         <street>604 Mariposa Ave</street>
+         <city>Mountain View</city>, <state>CA</state> <postcode>94041</postcode>
+         <country>USA</country>
+         <email>matt@ettus.com</email>
+       </address>
+      </affiliation>
+    </author>
+    
+    <abstract>
+      <para>
+       This guide explains both basic usage of the USRP as well as how to expand it.
+      </para>
+    </abstract>
+    
+  </articleinfo>
+  
+  <sect1 id="intro">
+    <title>Introduction</title>
+    <para>
+      The Universal Software Radio Peripheral, or USRP (pronounced "usurp") 
+      is designed to allow general purpose computers to function as high 
+      bandwidth software radios.  In essence, it serves as a digital 
+      baseband and IF section of a radio communication system.  In addition, 
+      it has a well-defined electrical and mechanical interface to RF 
+      front-ends (daughterboards) which can translate between that IF or 
+      baseband and the RF bands of interest
+    </para>
+    <para>
+      The basic design philosophy behind the USRP has been to do all of the
+      waveform-specific processing, like modulation and demodulation, on the
+      host CPU.  All of the high-speed general purpose operations like
+      digital up- and downconversion, decimation and interpolation are done
+      on the FPGA. 
+    </para>
+    <para>
+      It is anticipated that the majority of USRP users will never need to
+      use anything other than the standard FPGA configuration.  However, for
+      those users that wish to, the FPGA design may be changed or replaced.
+      All of the interfaces are well defined and documented.
+    </para>
+    <figure id="usrp-board">
+      <title>USRP with Daughterboards</title>
+      <mediaobject>
+       <imageobject><imagedata fileref="usrp.jpg" format="JPG"/></imageobject>
+       <caption><para>
+         This USRP has 2 BasicTX and 2 BasicRX boards mounted on it.  
+         Notice that the boards on the left are rotated 180 degrees.
+       </para></caption>
+      </mediaobject>
+    </figure>
+    
+    <sect2 id="requirements">
+      <title>System Requirements</title>
+      <para>
+       The USRP requires a PC or Mac with a USB2 interface.
+      </para>
+    </sect2>
+    
+  <sect2 id="capabilities">
+    <title>Capabilities</title>
+    <para>
+      The USRP has 4 high-speed analog to digital converters (ADCs), each at 
+      12 bits per sample, 64 million samples per second.  There are also 
+      4 high-speed digital to analog converters (DACs), each at 14 bits per 
+      sample, 128 million samples per second.  These 4 input and 4 output 
+      channels are connected to an Altera Cyclone EP1C12 FPGA.  The FPGA, in 
+      turn, connects to a USB2 interface chip, the Cypress FX2, and on to the 
+      computer.  The USRP connects to the computer via a high speed USB2 
+      interface only, and will not work with USB1.1.  
+    </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>
+  </sect2>
+  </sect1>
+  <sect1 id="getting-started">
+    <title>Getting Started</title>
+    <sect2 id="the-code">
+      <title>Getting all the Software</title>
+      <para>
+       The first step in using your USRP system is to get all of GNU Radio installed.  This can 
+       sometimes be a daunting process, as there are several other libraries which will need to be
+       installed first.
+      </para>
+      <sect3 id="dependencies">
+       <title>Library Dependencies</title>
+       <itemizedlist>
+         <listitem>
+           <para>SWIG</para>
+           <para>
+             We use SWIG (Simple Wrapper Interface Generator) to tie together the C++ and Python code 
+             in the GNU Radio system.  We require that you have version 1.3.24 or newer.  You'll
+             probably have to compile it from source, which you can find here: <ulink url="http://www.swig.org">SWIG</ulink>
+           </para>
+         </listitem>
+         <listitem>
+           <para>FFTW</para>
+           <para>
+             FFTW is the library which GNU Radio uses for FFTs.  GNU Radio requires version 3.0.1 or
+             newer, and it must be compiled for single precision.  You can get it from the 
+             <ulink url="http://www.fftw.org">FFTW Homepage</ulink>
+           </para>
+         </listitem>
+         <listitem>
+           <para>Boost Library</para>
+           <para>
+             Boost provides several low-level structures used in our C++ code.  If it is not included in
+             your OS distribution, you can get it here:  <ulink url="http://boost.org">Boost</ulink>
+           </para>
+         </listitem>
+         <listitem>
+           <para>CPP Unit</para>
+           <para>
+             CPPUnit provides our unit-testing framework.  This creates automated tests to insure that 
+             code does not break when changes are made.  Get it at the <ulink url="http://cppunit.sf.net">
+             CPP Unit Homepage</ulink>
+           </para>
+         </listitem>
+       </itemizedlist>
+      </sect3>
+      <sect3 id="getting-gradio">
+       <title>Getting GNU Radio and the USRP code</title>
+       <para>
+         There are several packages of software which make up GNU Radio and the USRP support software.
+         Links to the latest versions of each can be found on the GNU Radio Wiki at
+         <ulink url="http://comsec.com/wiki?GnuRadio2.X">Download Links</ulink>.  Gr-build 
+         can greatly simplify the installation process, and its use it highly recommended.
+       </para>
+      </sect3>
+      <sect3 id="cvs">
+       <title>Following CVS Development</title>
+       <para>
+         Development for the USRP proceeds very quickly at times, so some users may want to keep up with
+         the latest by following the CVS trees.  There are three separate software repositories 
+         which contain various parts of the USRP system.
+         <itemizedlist>
+           <listitem>
+             <para>
+               USRP-HW, containing the hardware and FPGA designs.
+             </para>
+             <para>
+               All of the schematics in this repository were created in 
+               <ulink url="http://www.geda.seul.org">gEDA</ulink>.  The board 
+               layouts were created in <ulink url="http://pcb.sf.net">PCB</ulink>.  
+               Verilog designs are compiled in Quartus II Web Edition from 
+               <ulink url="http://www.altera.com">Altera</ulink>.
+             </para>
+           </listitem>
+           <listitem>
+             <para>
+               <ulink url="https://sourceforge.net/cvs/?group_id=22397">USRP-SW</ulink>, 
+               USRP-SW, containing firmware and host drivers for the USRP
+             </para>
+             <para>
+               Host side drivers and firmware which runs in the USB2 interface chip on the board.
+             </para>
+           </listitem>
+           <listitem>
+             <para>
+               <ulink url="http://comsec.com/wiki?CvsAccess">GNU Radio/gr-usrp</ulink>
+               which contains the GNU Radio interface to the USRP
+             </para>
+           </listitem>
+         </itemizedlist>
+       </para>
+      </sect3>
+    </sect2>
+    <sect2 id="usrp-start">
+      <title>Using your USRP</title>
+      <sect3 id="physical">
+       <title>Mechanical Connection</title>
+       <para>
+         The USRP ships with a complete set of standoffs, nuts and bolts.  There are 20 standoffs, 
+         M3x10mm M-F, of which 4 are intended to be used as "feet" for the USRP.  Place them in the 4
+         corner holes on the main board, inserting the male part from below.  The remaining 16 
+         are used to hold the daughterboards in place.  Four of them should be connected to the male 
+         portion of the 4 standoffs already inserted from below.  The remaining 12 should be
+         connected to the board with the 12 M3x6mm screws from below.  At this point there should be
+         16 standoffs on the board with the male ends up to serve as a guide for the daughterboards.  
+         The 16 M3 nuts are used to fasten the daughterboards down to the main board.
+       </para>
+       <para>
+         The USRP accomodates 2 TX and 2 RX daughterboards.  The placement of the standoffs is designed
+         to prevent the accidental incorrect connection of daughterboards.  The 2 sides of the USRP have 
+         their daughterboard slots rotated 180 degrees.  The USRP should not be operated without 
+         standoffs, and daughterboards should never be connected or removed while power is applied.
+       </para>
+      </sect3>
+      <sect3 id="electrical">
+       <title>Electrical Connections</title>
+       <para>
+         The USRP is powered by a 6V 4A power converter included in the kit.  The converter is
+         capable of 90-260 Vac, 50/60 Hz operation, and so should work in any country.
+         If there is a need to use another power supply, the connector is a standard 2.1mm/5.5mm 
+         DC power connector.  The USRP itself only needs 5V at 2A, but a 6V supply was chosen to 
+         accomodate future daughterboards.  Extra power supplies are available from Ettus Research.
+       </para>
+       <para>
+         The included USB cable should be connected to a USB2-capable socket on a computer.  The USRP
+         does not support USB 1.1 operation at this time.
+       </para>
+      </sect3>
+      <sect3 id="diagnostics">
+       <title>Troubleshooting</title>
+       <para>
+         When first powered up, an LED on the USRP should be flashing at about 3-4x per second.
+         This indicates that the processor is running, and has put the device in a low power mode.
+         Once firmware has been downloaded to the USRP, the LED will blink at a slower rate.
+         If there is no blinking LED, check all power connections, and check for continuity
+         in the power fuse (F501, near the power connector).  If the fuse needs replacement, it
+         is size 0603, 3 amps.
+       </para>
+      </sect3>
+    </sect2>
+  </sect1>
+  <sect1 id="fpga">
+    <title>FPGA</title>
+    <sect2 id="fpga-std">
+      <title>Standard FPGA Configuration</title>
+      <para>
+       In the standard fpga configuration, usrp_std, all samples sent over
+       the USB interface are in 16-bit signed integers in IQ format.  When
+       there are multiple channels (up to 4), the channels are interleaved.
+       For example, with 4 channels, the sequence would be I0 Q0 I1 Q1 I2 Q2
+       I3 Q3 I0 Q0, etc.
+      </para>  
+      <para>
+       The USRP can operate in full duplex mode.  When in this mode, the
+       transmit and receive sides are completely independent of one another.
+       The only consideration is that the combined data rate over the bus
+       must be 32 Megabytes per second or less.  The multiple RX channels
+       (1,2, or 4) must all be the same data rate (i.e. same decimation
+       ratio).  The same applies to the 1,2, or TX channels, which each must
+       be at the same data rate (which may be different from the RX rate).
+      </para>
+      <para>
+       On the RX side, each of the 4 ADCs can be routed to either of I or the
+       Q input of any of the 4 downconverters.  This allows for having
+       multiple channels selected out of the same ADC sample stream.
+      </para>
+      <para>
+       The digital upconverters (DUCs) on the transmit side are actually
+       contained in the AD9862 CODEC chips, not in the FPGA.  The only
+       transmit signal processing blocks in the FPGA are the interpolators.
+       The interpolator outputs can be routed to any of the 4 CODEC inputs.
+      </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>
+      
+    </sect2>
+  </sect1>
+  <sect1 id="dboard-int">
+    <title>Daughterboard Interface</title>
+    <sect2 id="power-int">
+      <title>Power</title>
+      <para>
+       Daughterboards are provided with clean regulated 3.3V for the analog
+       and digital sections.  Additionally there is a 6V connection straight from
+       the wall supply which is intended to supply a 5V LDO regulator.  All daughterboards
+       may draw a combined total of 1.5 A.
+      </para>
+    </sect2>
+      <sect2 id="logical-int">
+      <title>Logical Interface</title>
+      <para>
+       There are slots for 2 TX daughterboards, labeled TXA and TXB, and 2 
+       corresponding RX daughterboards, RXA and RXB.  Each daughterboard slot has 
+       access to 2 of the 4 high-speed data converter analog signals (DAC outputs
+       for TX, ADC inputs for RX).  This allows each daughterboard which uses real 
+       (not IQ) sampling to have 2 independent RF sections, and 2 antennas 
+       (4 total for the system).  If IQ sampling is used, each board can support 
+       a single RF section, for a total of 2 for the whole system.
+      </para>
+      <para>
+       No antialias or reconstruction filtering is provided on the USRP motherboard.
+       This allows for maximum flexibility in frequency planning for the 
+       daughterboards.  The analog input bandwidth of the ADCs is over 200 MHz, so
+       IF frequencies up to that high may be chosen.  If several decibels of loss
+       is tolerable, and IF frequency as high as 500 MHz can be used.
+      </para>
+      <para>
+       Every daughterboard has an I2C EEPROM (24LC024 or 24LC025) onboard 
+       which identifies the board to the system.  This allows the host 
+       software to automatically set up the system properly based on the 
+       installed daughterboard.  The EEPROM may also store calibration values
+       like DC offsets or IQ imbalances.  If this EEPROM is not programmed, a
+       warning message is printed every time USRP software is run.
+      </para>
+    </sect2>
+    <sect2 id="analog-int">
+      <title>Analog Interface</title>
+      <para>
+       Each RX daughterboard has 2 differential analog inputs 
+       (VINP_A/VINN_A and VINP_B/VINN_B) which are sampled at a rate of 64 MS/s.
+       The input impedance is approximately 1Kohm.
+       The motherboard has a software-controllable programmable gain amplifier 
+       on these inputs, with 0 to 20 dB of gain.  With gain set to zero, full 
+       scale inputs are 2 Volts peak-to-peak differential.  When set to 20 dB, 
+       only .2 V pk-pk differential is needed to reach full scale. 
+      </para>
+      <para>
+       If signals are AC-coupled, there is no need to provide DC bias as long as the
+       internal buffer is turned on.  It will provide an approximately 2V bias.
+       If signals are DC-couple, a DC bias of Vdd/2 (1.65V) should be provided to
+       both the positive and negative inputs, and the internal buffer should be turned off.
+       VREF provides a clean 1 V reference.
+      </para>
+      <para>
+       Each TX daughterboard has a pair of differential analog outputs which are 
+       updated at 128 MS/s.  The signals (IOUTP_A/IOUTN_A and IOUTP_B/IOUTN_B) are 
+       current-output, each varying between 0 and 20 mA.  Since they are high-impedance,
+       they can be converted into differential voltages with a resistor.
+      </para>
+      <para>
+       In addition to the high-speed signals, each daughterboard has exclusive access to 2 low-speed ADC inputs 
+       (labeled AUX_ADC_A and AUX_ADC_B) which can be read from software.  
+       These are useful for sensing RSSI signal levels, temperatures, bias 
+       levels, etc.  Additionally, each board has shared access to 4 low-speed DAC
+       signals, labeled AUX_DAC_A through AUX_DAC_D.  RXA and TXA share one set
+       of these 4 lines, and RXB and TXB share their own independent set.  These
+       signals are useful for controlling gain of variable-gain amplifiers, for example.
+       AUX_ADC_REF provides a reference level for gain setting if it is necessary.
+      </para>
+      
+    </sect2>
+    <sect2 id="dig-int">
+      <title>Digital Interface</title>
+      <para></para>
+    </sect2>
+    <sect2 id="mech-int">
+      <title>Connector Pinouts</title>
+      
+      <table frame='all'><title>RX DBoard Connector</title>
+      <tgroup cols='3' align='left' colsep='1' rowsep='1'>
+       <thead>
+         <row>
+           <entry>Pin #</entry>
+           <entry>Name</entry>
+           <entry>Description</entry>
+         </row>
+       </thead>
+       <tbody>
+         <row>
+           <entry>1</entry>
+           <entry>power</entry>
+           <entry>This is power</entry>
+         </row>
+         <row>
+           <entry>c1</entry>
+           <entry>c4</entry>
+         </row>
+         <row>
+           <entry>d1</entry>
+           <entry>d4</entry>
+           <entry>d5</entry>
+         </row>
+       </tbody>
+      </tgroup>
+      </table>
+    </sect2>
+  </sect1>
+  <sect1 id="dboards">
+    <title>Available Daughterboards</title>
+    <sect2 id="basicrx">
+      <title>BasicRX</title>
+      <para>
+      </para>
+    </sect2>
+    <sect2 id="basictx">
+      <title>BasicTX</title>
+      <para>
+      </para>
+    </sect2>
+  </sect1>
+</article>
diff --git a/usrp/firmware/Makefile.am b/usrp/firmware/Makefile.am
new file mode 100644 (file)
index 0000000..16a03cc
--- /dev/null
@@ -0,0 +1,22 @@
+#
+# 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 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.
+# 
+
+SUBDIRS = include lib src
diff --git a/usrp/firmware/include/Makefile.am b/usrp/firmware/include/Makefile.am
new file mode 100644 (file)
index 0000000..7f58d19
--- /dev/null
@@ -0,0 +1,59 @@
+#
+# 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 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.
+# 
+
+include_HEADERS =              \
+       usrp_i2c_addr.h         \
+       usrp_spi_defs.h         
+
+
+noinst_HEADERS =               \
+       delay.h                 \
+       fpga_regs_common.h      \
+       fpga_regs_common.v      \
+       fpga_regs_standard.h    \
+       fpga_regs_standard.v    \
+       fpga_regs0.h            \
+       fx2regs.h               \
+       fx2utils.h              \
+       i2c.h                   \
+       isr.h                   \
+       syncdelay.h             \
+       timer.h                 \
+       usb_common.h            \
+       usb_descriptors.h       \
+       usb_requests.h          \
+       usrp_commands.h         \
+       usrp_config.h           \
+       usrp_ids.h              \
+       usrp_interfaces.h       
+
+
+CODE_GENERATOR =               \
+       generate_regs.py        
+
+EXTRA_DIST =                   \
+       $(CODE_GENERATOR)
+
+fpga_regs_common.v: fpga_regs_common.h generate_regs.py 
+       PYTHONPATH=$(top_srcdir)/usrp/firmware/include $(srcdir)/generate_regs.py $< $@
+
+fpga_regs_standard.v: fpga_regs_standard.h generate_regs.py
+       PYTHONPATH=$(top_srcdir)/usrp/firmware/include $(srcdir)/generate_regs.py $< $@
diff --git a/usrp/firmware/include/delay.h b/usrp/firmware/include/delay.h
new file mode 100644 (file)
index 0000000..c0ef19a
--- /dev/null
@@ -0,0 +1,38 @@
+/* -*- 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 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.
+ */
+
+#ifndef _DELAY_H_
+#define _DELAY_H_
+
+/*
+ * delay for approximately usecs microseconds
+ * Note limit of 255 usecs.
+ */
+void udelay (unsigned char usecs);
+
+/*
+ * delay for approximately msecs milliseconds
+ */
+void mdelay (unsigned short msecs);
+
+
+#endif /* _DELAY_H_ */
diff --git a/usrp/firmware/include/fpga_regs0.h b/usrp/firmware/include/fpga_regs0.h
new file mode 100644 (file)
index 0000000..fd591dd
--- /dev/null
@@ -0,0 +1,42 @@
+/* -*- 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 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.
+ */
+
+#ifndef _FPGA_REGS0_H_
+#define _FPGA_REGS0_H_
+
+#define FR_RX_FREQ_0      0
+#define FR_RX_FREQ_1      1
+#define FR_RX_FREQ_2      2
+#define FR_RX_FREQ_3      3
+#define FR_TX_FREQ_0      4
+#define FR_TX_FREQ_1      5
+#define FR_TX_FREQ_2      6
+#define FR_TX_FREQ_3      7
+#define FR_COMBO          8
+
+
+#define FR_ADC_CLK_DIV   128   // pseudo regs mapped to FR_COMBO by f/w
+#define FR_EXT_CLK_DIV  129    
+#define FR_INTERP       130
+#define FR_DECIM        131
+
+#endif
diff --git a/usrp/firmware/include/fpga_regs_common.h b/usrp/firmware/include/fpga_regs_common.h
new file mode 100644 (file)
index 0000000..3272fdf
--- /dev/null
@@ -0,0 +1,147 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003,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.
+ */
+#ifndef INCLUDED_FPGA_REGS_COMMON_H
+#define INCLUDED_FPGA_REGS_COMMON_H
+
+// This file defines registers common to all FPGA configurations.
+// Registers 0 to 31 are reserved for use in this file.
+
+
+// The FPGA needs to know the rate that samples are coming from and
+// going to the A/D's and D/A's.  div = 128e6 / sample_rate
+
+#define        FR_TX_SAMPLE_RATE_DIV    0
+#define        FR_RX_SAMPLE_RATE_DIV    1
+
+// 2 is available.
+// 3 is available.
+
+#define        FR_MASTER_CTRL           4      // master enable and reset controls
+#  define  bmFR_MC_ENABLE_TX           (1 << 0)
+#  define  bmFR_MC_ENABLE_RX           (1 << 1)
+#  define  bmFR_MC_RESET_TX            (1 << 2)
+#  define  bmFR_MC_RESET_RX            (1 << 3)
+
+// i/o direction registers for pins that go to daughterboards.
+// Setting the bit makes it an output from the FPGA to the d'board.
+// top 16 is mask, low 16 is value
+
+#define        FR_OE_0                  5      // slot 0
+#define        FR_OE_1                  6
+#define        FR_OE_2                  7
+#define        FR_OE_3                  8
+
+// i/o registers for pins that go to daughterboards.
+// top 16 is a mask, low 16 is value
+
+#define        FR_IO_0                  9      // slot 0
+#define        FR_IO_1                 10
+#define        FR_IO_2                 11
+#define        FR_IO_3                 12
+
+#define        FR_MODE                 13
+#  define  bmFR_MODE_NORMAL                  0
+#  define  bmFR_MODE_LOOPBACK          (1 << 0)        // enable digital loopback
+#  define  bmFR_MODE_RX_COUNTING       (1 << 1)        // Rx is counting
+#  define  bmFR_MODE_RX_COUNTING_32BIT (1 << 2)        // Rx is counting with a 32 bit counter
+                                                    // low and high 16 bits are multiplexed across channel I and Q
+
+
+// If the corresponding bit is set, internal FPGA debug circuitry
+// controls the i/o pins for the associated bank of daughterboard
+// i/o pins.  Typically used for debugging FPGA designs.
+
+#define FR_DEBUG_EN             14
+#  define bmFR_DEBUG_EN_TX_A           (1 << 0)        // debug controls TX_A i/o
+#  define bmFR_DEBUG_EN_RX_A           (1 << 1)        // debug controls RX_A i/o
+#  define bmFR_DEBUG_EN_TX_B           (1 << 2)        // debug controls TX_B i/o
+#  define bmFR_DEBUG_EN_RX_B           (1 << 3)        // debug controls RX_B i/o
+
+
+// If the corresponding bit is set, enable the automatic DC
+// offset correction control loop.
+//
+// The 4 low bits are significant:
+//
+//   ADC0 = (1 << 0)
+//   ADC1 = (1 << 1)
+//   ADC2 = (1 << 2)
+//   ADC3 = (1 << 3)
+//
+// This control loop works if the attached daugherboard blocks DC.
+// Currently all daughterboards do block DC.  This includes:
+// basic rx, dbs_rx, tv_rx, flex_xxx_rx.
+
+#define FR_DC_OFFSET_CL_EN     15                      // DC Offset Control Loop Enable
+
+
+// offset corrections for ADC's and DAC's (2's complement)
+
+#define        FR_ADC_OFFSET_0         16
+#define        FR_ADC_OFFSET_1         17
+#define        FR_ADC_OFFSET_2         18
+#define        FR_ADC_OFFSET_3         19
+
+
+// ------------------------------------------------------------------------
+// Automatic Transmit/Receive switching
+//
+// 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.
+                      
+#define FR_ATR_MASK_0          20      // slot 0
+#define        FR_ATR_TXVAL_0          21
+#define FR_ATR_RXVAL_0         22
+
+#define FR_ATR_MASK_1          23      // slot 1
+#define        FR_ATR_TXVAL_1          24
+#define FR_ATR_RXVAL_1         25
+
+#define FR_ATR_MASK_2          26      // slot 2
+#define        FR_ATR_TXVAL_2          27
+#define FR_ATR_RXVAL_2         28
+
+#define FR_ATR_MASK_3          29      // slot 3
+#define        FR_ATR_TXVAL_3          30
+#define FR_ATR_RXVAL_3         31
+
+#endif /* INCLUDED_FPGA_REGS_COMMON_H */
diff --git a/usrp/firmware/include/fpga_regs_common.v b/usrp/firmware/include/fpga_regs_common.v
new file mode 100644 (file)
index 0000000..ee87ac0
--- /dev/null
@@ -0,0 +1,114 @@
+//
+// This file is machine generated from fpga_regs_common.h
+// Do not edit by hand; your edits will be overwritten.
+//
+
+// This file defines registers common to all FPGA configurations.
+// Registers 0 to 31 are reserved for use in this file.
+
+
+// The FPGA needs to know the rate that samples are coming from and
+// going to the A/D's and D/A's.  div = 128e6 / sample_rate
+
+`define FR_TX_SAMPLE_RATE_DIV     7'd0
+`define FR_RX_SAMPLE_RATE_DIV     7'd1
+
+// 2 is available.
+// 3 is available.
+
+`define FR_MASTER_CTRL            7'd4 // master enable and reset controls
+
+// i/o direction registers for pins that go to daughterboards.
+// Setting the bit makes it an output from the FPGA to the d'board.
+// top 16 is mask, low 16 is value
+
+`define FR_OE_0                   7'd5 // slot 0
+`define FR_OE_1                   7'd6
+`define FR_OE_2                   7'd7
+`define FR_OE_3                   7'd8
+
+// i/o registers for pins that go to daughterboards.
+// top 16 is a mask, low 16 is value
+
+`define FR_IO_0                   7'd9 // slot 0
+`define FR_IO_1                   7'd10
+`define FR_IO_2                   7'd11
+`define FR_IO_3                   7'd12
+
+`define FR_MODE                   7'd13
+
+
+// If the corresponding bit is set, internal FPGA debug circuitry
+// controls the i/o pins for the associated bank of daughterboard
+// i/o pins.  Typically used for debugging FPGA designs.
+
+`define FR_DEBUG_EN               7'd14
+
+
+// If the corresponding bit is set, enable the automatic DC
+// offset correction control loop.
+//
+// The 4 low bits are significant:
+//
+//   ADC0 = (1 << 0)
+//   ADC1 = (1 << 1)
+//   ADC2 = (1 << 2)
+//   ADC3 = (1 << 3)
+//
+// This control loop works if the attached daugherboard blocks DC.
+// Currently all daughterboards do block DC.  This includes:
+// basic rx, dbs_rx, tv_rx, flex_xxx_rx.
+
+`define FR_DC_OFFSET_CL_EN        7'd15                        // DC Offset Control Loop Enable
+
+
+// offset corrections for ADC's and DAC's (2's complement)
+
+`define FR_ADC_OFFSET_0           7'd16
+`define FR_ADC_OFFSET_1           7'd17
+`define FR_ADC_OFFSET_2           7'd18
+`define FR_ADC_OFFSET_3           7'd19
+
+
+// ------------------------------------------------------------------------
+// Automatic Transmit/Receive switching
+//
+// 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.
+                      
+`define FR_ATR_MASK_0             7'd20        // slot 0
+`define FR_ATR_TXVAL_0            7'd21
+`define FR_ATR_RXVAL_0            7'd22
+
+`define FR_ATR_MASK_1             7'd23        // slot 1
+`define FR_ATR_TXVAL_1            7'd24
+`define FR_ATR_RXVAL_1            7'd25
+
+`define FR_ATR_MASK_2             7'd26        // slot 2
+`define FR_ATR_TXVAL_2            7'd27
+`define FR_ATR_RXVAL_2            7'd28
+
+`define FR_ATR_MASK_3             7'd29        // slot 3
+`define FR_ATR_TXVAL_3            7'd30
+`define FR_ATR_RXVAL_3            7'd31
+
diff --git a/usrp/firmware/include/fpga_regs_standard.h b/usrp/firmware/include/fpga_regs_standard.h
new file mode 100644 (file)
index 0000000..3c46422
--- /dev/null
@@ -0,0 +1,284 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003,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 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.
+ */
+#ifndef INCLUDED_FPGA_REGS_STANDARD_H
+#define INCLUDED_FPGA_REGS_STANDARD_H
+
+// Register numbers 0 to 31 are reserved for use in fpga_regs_common.h.
+// Registers 64 to 79 are available for custom FPGA builds.
+
+
+// DDC / DUC
+
+#define        FR_INTERP_RATE          32      // [1,1024]
+#define        FR_DECIM_RATE           33      // [1,256]
+
+// DDC center freq
+
+#define FR_RX_FREQ_0           34
+#define FR_RX_FREQ_1           35
+#define FR_RX_FREQ_2           36
+#define FR_RX_FREQ_3           37
+
+// See below for DDC Starting Phase
+
+// ------------------------------------------------------------------------
+//  configure FPGA Rx mux
+//
+//    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 |
+// +-----------------------+-------+-------+-------+-------+-+-----+
+//
+// There are a maximum of 4 digital downconverters in the the FPGA.
+// Each DDC has two 16-bit inputs, I and Q, and two 16-bit outputs, I & Q.
+//
+// DDC I inputs are specified by the two bit fields I3, I2, I1 & I0
+//
+//   0 = DDC input is from ADC 0
+//   1 = DDC input is from ADC 1
+//   2 = DDC input is from ADC 2
+//   3 = DDC input is from ADC 3
+//
+// If Z == 1, all DDC Q inputs are set to zero
+// If Z == 0, DDC Q inputs are specified by the two bit fields Q3, Q2, Q1 & Q0
+//
+// NCH specifies the number of complex channels that are sent across
+// the USB.  The legal values are 1, 2 or 4, corresponding to 2, 4 or
+// 8 16-bit values.
+
+#define        FR_RX_MUX               38
+
+// ------------------------------------------------------------------------
+//  configure FPGA Tx Mux.
+//
+//    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 |0| NCH |
+// +-----------------------------------------------+-------+-+-----+
+//
+// NCH specifies the number of complex channels that are sent across
+// the USB.  The legal values are 1 or 2, corresponding to 2 or 4
+// 16-bit values.
+//
+// There are two interpolators with complex inputs and outputs.
+// There are four DACs.  (We use the DUC in each AD9862.)
+//
+// 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
+
+#define        FR_TX_MUX               39
+
+// ------------------------------------------------------------------------
+// REFCLK control
+//
+// 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
+
+#define FR_TX_A_REFCLK          40
+#define FR_RX_A_REFCLK          41
+#define FR_TX_B_REFCLK          42
+#define FR_RX_B_REFCLK          43
+
+#  define bmFR_REFCLK_EN          0x80
+#  define bmFR_REFCLK_DIVISOR_MASK 0x7f
+
+// ------------------------------------------------------------------------
+// DDC Starting Phase
+
+#define FR_RX_PHASE_0          44
+#define FR_RX_PHASE_1          45
+#define FR_RX_PHASE_2          46
+#define FR_RX_PHASE_3          47
+
+// ------------------------------------------------------------------------
+// Tx 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)            |  FMT  |
+// +-------------------------------------------------------+-------+
+//
+//  FMT values:
+
+#define FR_TX_FORMAT           48
+#  define bmFR_TX_FORMAT_16_IQ         0       // 16-bit I, 16-bit Q
+
+// ------------------------------------------------------------------------
+// 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 |
+// +-----------------------------------------+-+-+---------+-------+
+//
+//  FMT values:
+
+#define FR_RX_FORMAT           49
+
+#  define bmFR_RX_FORMAT_SHIFT_MASK    (0x0f <<  0)    // arithmetic right shift [0, 15]
+#  define bmFR_RX_FORMAT_SHIFT_SHIFT   0
+#  define bmFR_RX_FORMAT_WIDTH_MASK    (0x1f <<  4)    // data width in bits [1, 16] (not all valid)
+#  define bmFR_RX_FORMAT_WIDTH_SHIFT    4
+#  define bmFR_RX_FORMAT_WANT_Q                (0x1  <<  9)    // deliver both I & Q, else just I
+#  define bmFR_RX_FORMAT_BYPASS_HB     (0x1  << 10)    // bypass half-band filter
+
+// The valid combinations currently are:
+//
+//   B  Q  WIDTH  SHIFT
+//   0  1    16     0
+//   0  1     8     8
+
+
+// Possible future values of WIDTH = {4, 2, 1}
+// 12 takes a bit more work, since we need to know packet alignment.
+
+// ------------------------------------------------------------------------
+// FIXME register numbers 50 to 63 are available
+
+// ------------------------------------------------------------------------
+// Registers 64 to 79 are reserved for user custom FPGA builds.
+// The standard USRP software will not touch these.
+
+#define FR_USER_0      64
+#define FR_USER_1      65
+#define FR_USER_2      66
+#define FR_USER_3      67
+#define FR_USER_4      68
+#define FR_USER_5      69
+#define FR_USER_6      70
+#define FR_USER_7      71
+#define FR_USER_8      72
+#define FR_USER_9      73
+#define FR_USER_10     74
+#define FR_USER_11     75
+#define FR_USER_12     76
+#define FR_USER_13     77
+#define FR_USER_14     78
+#define FR_USER_15     79
+
+//Registers needed for multi usrp master/slave configuration
+//
+//Rx Master/slave control register (FR_RX_MASTER_SLAVE = FR_USER_0)
+//
+#define FR_RX_MASTER_SLAVE             64
+#define bitnoFR_RX_SYNC                        0
+#define bitnoFR_RX_SYNC_MASTER         1
+#define bitnoFR_RX_SYNC_SLAVE          2
+#  define bmFR_RX_SYNC          (1 <<bitnoFR_RX_SYNC) //1 If this is a master "sync now" and send sync to slave.
+                                                      //  If this is a slave "sync now" (testing purpose only)
+                                                      //  Sync is allmost the same as reset (clear all counters and buffers) 
+                                                      //  except that the io outputs and settings don't get reset (otherwise it couldn't send the sync to the slave)
+                                                      //0 Normal operation
+
+#  define bmFR_RX_SYNC_MASTER (1 <<bitnoFR_RX_SYNC_MASTER) //1 This is a rx sync master, output sync_rx on rx_a_io[15]
+                                                           //0 This is not a rx sync master
+#  define bmFR_RX_SYNC_SLAVE  (1 <<bitnoFR_RX_SYNC_SLAVE) //1 This is a rx sync slave, follow sync_rx on rx_a_io[bitnoFR_RX_SYNC_INPUT_IOPIN]
+                                                          //0 This is not an rx sync slave.
+
+//Caution The master settings will output values on the io lines.
+//They inheritely enable these lines as output. If you have a daughtercard which uses these lines also as output then you will burn your usrp and daughtercard.
+//If you set the slave bits then your usrp won't do anything if you don't connect a master.
+// Rx Master/slave control register
+//
+// The way this is supposed to be used is connecting a (short) 16pin flatcable from an rx daughterboard in RXA master io_rx[8..15] to slave io_rx[8..15] on RXA of slave usrp
+// This can be done with basic_rx boards or dbsrx boards
+//dbsrx: connect master-J25 to slave-J25
+//basic rx: connect J25 to slave-J25
+//CAUTION: pay attention to the lineup of your connector.
+//The red line (pin1) should be at the same side of the daughterboards on master and slave.
+//If you turnaround the cable on one end you will burn your usrp.
+
+//You cannot use a 16pin flatcable if you are using FLEX400 or FLEX2400 daughterboards, since these use a lot of the io pins.
+//You can still link them but you must use only a 2pin or 1pin cable
+//You can also use a 2-wire link. put a 2pin header on io[15],gnd of the master RXA daughterboard and connect it to io15,gnd of the slave RXA db.
+//You can use a cable like the ones found with the leds on the mainbord of a PC.
+//Make sure you don't twist the cable, otherwise you connect the sync output to ground.
+//To be save you could also just use a single wire from master io[15] to slave io[15], but this is not optimal for signal integrity.
+
+
+// Since rx_io[0] can normally be used as a refclk and is not exported on all daughterboards this line
+// still has the refclk function if you use the master/slave setup (it is not touched by the master/slave settings).
+// The master/slave circuitry will only use io pin 15 and does not touch any of the other io pins.
+#define bitnoFR_RX_SYNC_INPUT_IOPIN            15
+#define bmFR_RX_SYNC_INPUT_IOPIN               (1<<bitnoFR_RX_SYNC_INPUT_IOPIN)
+//TODO the output pin is still hardcoded in the verilog code, make it listen to the following define
+#define bitnoFR_RX_SYNC_OUTPUT_IOPIN   15
+#define bmFR_RX_SYNC_OUTPUT_IOPIN      (1<<bitnoFR_RX_SYNC_OUTPUT_IOPIN)
+// =======================================================================
+// READBACK Registers
+// =======================================================================
+
+#define FR_RB_IO_RX_A_IO_TX_A  1       // read back a-side i/o pins
+#define        FR_RB_IO_RX_B_IO_TX_B   2       // read back b-side i/o pins
+
+// ------------------------------------------------------------------------
+// FPGA Capability 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)    |T|NDUC |R|NDDC |
+// +-----------------------------------------------+-+-----+-+-----+
+//
+// Bottom 4-bits are Rx capabilities
+// Next   4-bits are Tx capabilities
+
+#define        FR_RB_CAPS      3
+#  define bmFR_RB_CAPS_NDDC_MASK       (0x7 << 0)   // # of digital down converters 0,1,2,4
+#  define bmFR_RB_CAPS_NDDC_SHIFT      0
+#  define bmFR_RB_CAPS_RX_HAS_HALFBAND (0x1 << 3)
+#  define bmFR_RB_CAPS_NDUC_MASK        (0x7 << 4)   // # of digital up converters 0,1,2
+#  define bmFR_RB_CAPS_NDUC_SHIFT      4
+#  define bmFR_RB_CAPS_TX_HAS_HALFBAND (0x1 << 7)
+
+
+#endif /* INCLUDED_FPGA_REGS_STANDARD_H */
diff --git a/usrp/firmware/include/fpga_regs_standard.v b/usrp/firmware/include/fpga_regs_standard.v
new file mode 100644 (file)
index 0000000..cc67be2
--- /dev/null
@@ -0,0 +1,240 @@
+//
+// This file is machine generated from fpga_regs_standard.h
+// Do not edit by hand; your edits will be overwritten.
+//
+
+// Register numbers 0 to 31 are reserved for use in fpga_regs_common.h.
+// Registers 64 to 79 are available for custom FPGA builds.
+
+
+// DDC / DUC
+
+`define FR_INTERP_RATE            7'd32        // [1,1024]
+`define FR_DECIM_RATE             7'd33        // [1,256]
+
+// DDC center freq
+
+`define FR_RX_FREQ_0              7'd34
+`define FR_RX_FREQ_1              7'd35
+`define FR_RX_FREQ_2              7'd36
+`define FR_RX_FREQ_3              7'd37
+
+// See below for DDC Starting Phase
+
+// ------------------------------------------------------------------------
+//  configure FPGA Rx mux
+//
+//    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 |
+// +-----------------------+-------+-------+-------+-------+-+-----+
+//
+// There are a maximum of 4 digital downconverters in the the FPGA.
+// Each DDC has two 16-bit inputs, I and Q, and two 16-bit outputs, I & Q.
+//
+// DDC I inputs are specified by the two bit fields I3, I2, I1 & I0
+//
+//   0 = DDC input is from ADC 0
+//   1 = DDC input is from ADC 1
+//   2 = DDC input is from ADC 2
+//   3 = DDC input is from ADC 3
+//
+// If Z == 1, all DDC Q inputs are set to zero
+// If Z == 0, DDC Q inputs are specified by the two bit fields Q3, Q2, Q1 & Q0
+//
+// NCH specifies the number of complex channels that are sent across
+// the USB.  The legal values are 1, 2 or 4, corresponding to 2, 4 or
+// 8 16-bit values.
+
+`define FR_RX_MUX                 7'd38
+
+// ------------------------------------------------------------------------
+//  configure FPGA Tx Mux.
+//
+//    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 |0| NCH |
+// +-----------------------------------------------+-------+-+-----+
+//
+// NCH specifies the number of complex channels that are sent across
+// the USB.  The legal values are 1 or 2, corresponding to 2 or 4
+// 16-bit values.
+//
+// There are two interpolators with complex inputs and outputs.
+// There are four DACs.  (We use the DUC in each AD9862.)
+//
+// 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
+
+`define FR_TX_MUX                 7'd39
+
+// ------------------------------------------------------------------------
+// REFCLK control
+//
+// 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
+
+`define FR_TX_A_REFCLK            7'd40
+`define FR_RX_A_REFCLK            7'd41
+`define FR_TX_B_REFCLK            7'd42
+`define FR_RX_B_REFCLK            7'd43
+
+
+// ------------------------------------------------------------------------
+// DDC Starting Phase
+
+`define FR_RX_PHASE_0             7'd44
+`define FR_RX_PHASE_1             7'd45
+`define FR_RX_PHASE_2             7'd46
+`define FR_RX_PHASE_3             7'd47
+
+// ------------------------------------------------------------------------
+// Tx 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)            |  FMT  |
+// +-------------------------------------------------------+-------+
+//
+//  FMT values:
+
+`define FR_TX_FORMAT              7'd48
+
+// ------------------------------------------------------------------------
+// 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 |
+// +-----------------------------------------+-+-+---------+-------+
+//
+//  FMT values:
+
+`define FR_RX_FORMAT              7'd49
+
+
+// The valid combinations currently are:
+//
+//   B  Q  WIDTH  SHIFT
+//   0  1    16     0
+//   0  1     8     8
+
+
+// Possible future values of WIDTH = {4, 2, 1}
+// 12 takes a bit more work, since we need to know packet alignment.
+
+// ------------------------------------------------------------------------
+// FIXME register numbers 50 to 63 are available
+
+// ------------------------------------------------------------------------
+// Registers 64 to 79 are reserved for user custom FPGA builds.
+// The standard USRP software will not touch these.
+
+`define FR_USER_0                 7'd64
+`define FR_USER_1                 7'd65
+`define FR_USER_2                 7'd66
+`define FR_USER_3                 7'd67
+`define FR_USER_4                 7'd68
+`define FR_USER_5                 7'd69
+`define FR_USER_6                 7'd70
+`define FR_USER_7                 7'd71
+`define FR_USER_8                 7'd72
+`define FR_USER_9                 7'd73
+`define FR_USER_10                7'd74
+`define FR_USER_11                7'd75
+`define FR_USER_12                7'd76
+`define FR_USER_13                7'd77
+`define FR_USER_14                7'd78
+`define FR_USER_15                7'd79
+
+//Registers needed for multi usrp master/slave configuration
+//
+//Rx Master/slave control register (FR_RX_MASTER_SLAVE = FR_USER_0)
+//
+`define FR_RX_MASTER_SLAVE        7'd64
+`define bitnoFR_RX_SYNC           0
+`define bitnoFR_RX_SYNC_MASTER    1
+`define bitnoFR_RX_SYNC_SLAVE     2
+
+
+//Caution The master settings will output values on the io lines.
+//They inheritely enable these lines as output. If you have a daughtercard which uses these lines also as output then you will burn your usrp and daughtercard.
+//If you set the slave bits then your usrp won't do anything if you don't connect a master.
+// Rx Master/slave control register
+//
+// The way this is supposed to be used is connecting a (short) 16pin flatcable from an rx daughterboard in RXA master io_rx[8..15] to slave io_rx[8..15] on RXA of slave usrp
+// This can be done with basic_rx boards or dbsrx boards
+//dbsrx: connect master-J25 to slave-J25
+//basic rx: connect J25 to slave-J25
+//CAUTION: pay attention to the lineup of your connector.
+//The red line (pin1) should be at the same side of the daughterboards on master and slave.
+//If you turnaround the cable on one end you will burn your usrp.
+
+//You cannot use a 16pin flatcable if you are using FLEX400 or FLEX2400 daughterboards, since these use a lot of the io pins.
+//You can still link them but you must use only a 2pin or 1pin cable
+//You can also use a 2-wire link. put a 2pin header on io[15],gnd of the master RXA daughterboard and connect it to io15,gnd of the slave RXA db.
+//You can use a cable like the ones found with the leds on the mainbord of a PC.
+//Make sure you don't twist the cable, otherwise you connect the sync output to ground.
+//To be save you could also just use a single wire from master io[15] to slave io[15], but this is not optimal for signal integrity.
+
+
+// Since rx_io[0] can normally be used as a refclk and is not exported on all daughterboards this line
+// still has the refclk function if you use the master/slave setup (it is not touched by the master/slave settings).
+// The master/slave circuitry will only use io pin 15 and does not touch any of the other io pins.
+`define bitnoFR_RX_SYNC_INPUT_IOPIN 15
+`define bmFR_RX_SYNC_INPUT_IOPIN  (1<<bitnoFR_RX_SYNC_INPUT_IOPIN)
+//TODO the output pin is still hardcoded in the verilog code, make it listen to the following define
+`define bitnoFR_RX_SYNC_OUTPUT_IOPIN 15
+`define bmFR_RX_SYNC_OUTPUT_IOPIN (1<<bitnoFR_RX_SYNC_OUTPUT_IOPIN)
+// =======================================================================
+// READBACK Registers
+// =======================================================================
+
+`define FR_RB_IO_RX_A_IO_TX_A     7'd1 // read back a-side i/o pins
+`define FR_RB_IO_RX_B_IO_TX_B     7'd2 // read back b-side i/o pins
+
+// ------------------------------------------------------------------------
+// FPGA Capability 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)    |T|NDUC |R|NDDC |
+// +-----------------------------------------------+-+-----+-+-----+
+//
+// Bottom 4-bits are Rx capabilities
+// Next   4-bits are Tx capabilities
+
+`define FR_RB_CAPS                7'd3
+
+
diff --git a/usrp/firmware/include/fx2regs.h b/usrp/firmware/include/fx2regs.h
new file mode 100644 (file)
index 0000000..efe0f99
--- /dev/null
@@ -0,0 +1,716 @@
+/* -*- 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 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.
+ */
+
+/*
+//-----------------------------------------------------------------------------
+//   File:      FX2regs.h
+//   Contents:   EZ-USB FX2 register declarations and bit mask definitions.
+//
+// $Archive: /USB/Target/Inc/fx2regs.h $
+// $Date$
+// $Revision$
+//
+//
+//   Copyright (c) 2000 Cypress Semiconductor, All rights reserved
+//-----------------------------------------------------------------------------
+*/
+
+
+#ifndef FX2REGS_H   /* Header Sentry */
+#define FX2REGS_H
+
+#define ALLOCATE_EXTERN                // required for "right thing to happen" with fx2regs.h
+
+/*
+//-----------------------------------------------------------------------------
+// FX2 Related Register Assignments
+//-----------------------------------------------------------------------------
+
+// The Ez-USB FX2 registers are defined here. We use FX2regs.h for register 
+// address allocation by using "#define ALLOCATE_EXTERN". 
+// When using "#define ALLOCATE_EXTERN", you get (for instance): 
+// xdata volatile BYTE OUT7BUF[64]   _at_   0x7B40;
+// Such lines are created from FX2.h by using the preprocessor. 
+// Incidently, these lines will not generate any space in the resulting hex 
+// file; they just bind the symbols to the addresses for compilation. 
+// You just need to put "#define ALLOCATE_EXTERN" in your main program file; 
+// i.e. fw.c or a stand-alone C source file. 
+// Without "#define ALLOCATE_EXTERN", you just get the external reference: 
+// extern xdata volatile BYTE OUT7BUF[64]   ;//   0x7B40;
+// This uses the concatenation operator "##" to insert a comment "//" 
+// to cut off the end of the line, "_at_   0x7B40;", which is not wanted.
+*/
+
+
+#ifdef ALLOCATE_EXTERN
+#define EXTERN
+#define _AT_(a) at a
+#else
+#define EXTERN extern
+#define _AT_ ;/ ## /
+#endif
+
+typedef unsigned char BYTE;
+typedef unsigned short WORD;
+
+EXTERN xdata _AT_(0xE400) volatile BYTE GPIF_WAVE_DATA[128];
+EXTERN xdata _AT_(0xE480) volatile BYTE RES_WAVEDATA_END  ;
+
+// General Configuration
+
+EXTERN xdata _AT_(0xE600) volatile BYTE CPUCS             ;  // Control & Status
+EXTERN xdata _AT_(0xE601) volatile BYTE IFCONFIG          ;  // Interface Configuration
+EXTERN xdata _AT_(0xE602) volatile BYTE PINFLAGSAB        ;  // FIFO FLAGA and FLAGB Assignments
+EXTERN xdata _AT_(0xE603) volatile BYTE PINFLAGSCD        ;  // FIFO FLAGC and FLAGD Assignments
+EXTERN xdata _AT_(0xE604) volatile BYTE FIFORESET         ;  // Restore FIFOS to default state
+EXTERN xdata _AT_(0xE605) volatile BYTE BREAKPT           ;  // Breakpoint
+EXTERN xdata _AT_(0xE606) volatile BYTE BPADDRH           ;  // Breakpoint Address H
+EXTERN xdata _AT_(0xE607) volatile BYTE BPADDRL           ;  // Breakpoint Address L
+EXTERN xdata _AT_(0xE608) volatile BYTE UART230           ;  // 230 Kbaud clock for T0,T1,T2
+EXTERN xdata _AT_(0xE609) volatile BYTE FIFOPINPOLAR      ;  // FIFO polarities
+EXTERN xdata _AT_(0xE60A) volatile BYTE REVID             ;  // Chip Revision
+EXTERN xdata _AT_(0xE60B) volatile BYTE REVCTL            ;  // Chip Revision Control
+
+// Endpoint Configuration
+
+EXTERN xdata _AT_(0xE610) volatile BYTE EP1OUTCFG         ;  // Endpoint 1-OUT Configuration
+EXTERN xdata _AT_(0xE611) volatile BYTE EP1INCFG          ;  // Endpoint 1-IN Configuration
+EXTERN xdata _AT_(0xE612) volatile BYTE EP2CFG            ;  // Endpoint 2 Configuration
+EXTERN xdata _AT_(0xE613) volatile BYTE EP4CFG            ;  // Endpoint 4 Configuration
+EXTERN xdata _AT_(0xE614) volatile BYTE EP6CFG            ;  // Endpoint 6 Configuration
+EXTERN xdata _AT_(0xE615) volatile BYTE EP8CFG            ;  // Endpoint 8 Configuration
+EXTERN xdata _AT_(0xE618) volatile BYTE EP2FIFOCFG        ;  // Endpoint 2 FIFO configuration
+EXTERN xdata _AT_(0xE619) volatile BYTE EP4FIFOCFG        ;  // Endpoint 4 FIFO configuration
+EXTERN xdata _AT_(0xE61A) volatile BYTE EP6FIFOCFG        ;  // Endpoint 6 FIFO configuration
+EXTERN xdata _AT_(0xE61B) volatile BYTE EP8FIFOCFG        ;  // Endpoint 8 FIFO configuration
+EXTERN xdata _AT_(0xE620) volatile BYTE EP2AUTOINLENH     ;  // Endpoint 2 Packet Length H (IN only)
+EXTERN xdata _AT_(0xE621) volatile BYTE EP2AUTOINLENL     ;  // Endpoint 2 Packet Length L (IN only)
+EXTERN xdata _AT_(0xE622) volatile BYTE EP4AUTOINLENH     ;  // Endpoint 4 Packet Length H (IN only)
+EXTERN xdata _AT_(0xE623) volatile BYTE EP4AUTOINLENL     ;  // Endpoint 4 Packet Length L (IN only)
+EXTERN xdata _AT_(0xE624) volatile BYTE EP6AUTOINLENH     ;  // Endpoint 6 Packet Length H (IN only)
+EXTERN xdata _AT_(0xE625) volatile BYTE EP6AUTOINLENL     ;  // Endpoint 6 Packet Length L (IN only)
+EXTERN xdata _AT_(0xE626) volatile BYTE EP8AUTOINLENH     ;  // Endpoint 8 Packet Length H (IN only)
+EXTERN xdata _AT_(0xE627) volatile BYTE EP8AUTOINLENL     ;  // Endpoint 8 Packet Length L (IN only)
+EXTERN xdata _AT_(0xE630) volatile BYTE EP2FIFOPFH        ;  // EP2 Programmable Flag trigger H
+EXTERN xdata _AT_(0xE631) volatile BYTE EP2FIFOPFL        ;  // EP2 Programmable Flag trigger L
+EXTERN xdata _AT_(0xE632) volatile BYTE EP4FIFOPFH        ;  // EP4 Programmable Flag trigger H
+EXTERN xdata _AT_(0xE633) volatile BYTE EP4FIFOPFL        ;  // EP4 Programmable Flag trigger L
+EXTERN xdata _AT_(0xE634) volatile BYTE EP6FIFOPFH        ;  // EP6 Programmable Flag trigger H
+EXTERN xdata _AT_(0xE635) volatile BYTE EP6FIFOPFL        ;  // EP6 Programmable Flag trigger L
+EXTERN xdata _AT_(0xE636) volatile BYTE EP8FIFOPFH        ;  // EP8 Programmable Flag trigger H
+EXTERN xdata _AT_(0xE637) volatile BYTE EP8FIFOPFL        ;  // EP8 Programmable Flag trigger L
+EXTERN xdata _AT_(0xE640) volatile BYTE EP2ISOINPKTS      ;  // EP2 (if ISO) IN Packets per frame (1-3)
+EXTERN xdata _AT_(0xE641) volatile BYTE EP4ISOINPKTS      ;  // EP4 (if ISO) IN Packets per frame (1-3)
+EXTERN xdata _AT_(0xE642) volatile BYTE EP6ISOINPKTS      ;  // EP6 (if ISO) IN Packets per frame (1-3)
+EXTERN xdata _AT_(0xE643) volatile BYTE EP8ISOINPKTS      ;  // EP8 (if ISO) IN Packets per frame (1-3)
+EXTERN xdata _AT_(0xE648) volatile BYTE INPKTEND          ;  // Force IN Packet End
+EXTERN xdata _AT_(0xE649) volatile BYTE OUTPKTEND         ;  // Force OUT Packet End
+
+// Interrupts
+
+EXTERN xdata _AT_(0xE650) volatile BYTE EP2FIFOIE         ;  // Endpoint 2 Flag Interrupt Enable
+EXTERN xdata _AT_(0xE651) volatile BYTE EP2FIFOIRQ        ;  // Endpoint 2 Flag Interrupt Request
+EXTERN xdata _AT_(0xE652) volatile BYTE EP4FIFOIE         ;  // Endpoint 4 Flag Interrupt Enable
+EXTERN xdata _AT_(0xE653) volatile BYTE EP4FIFOIRQ        ;  // Endpoint 4 Flag Interrupt Request
+EXTERN xdata _AT_(0xE654) volatile BYTE EP6FIFOIE         ;  // Endpoint 6 Flag Interrupt Enable
+EXTERN xdata _AT_(0xE655) volatile BYTE EP6FIFOIRQ        ;  // Endpoint 6 Flag Interrupt Request
+EXTERN xdata _AT_(0xE656) volatile BYTE EP8FIFOIE         ;  // Endpoint 8 Flag Interrupt Enable
+EXTERN xdata _AT_(0xE657) volatile BYTE EP8FIFOIRQ        ;  // Endpoint 8 Flag Interrupt Request
+EXTERN xdata _AT_(0xE658) volatile BYTE IBNIE             ;  // IN-BULK-NAK Interrupt Enable
+EXTERN xdata _AT_(0xE659) volatile BYTE IBNIRQ            ;  // IN-BULK-NAK interrupt Request
+EXTERN xdata _AT_(0xE65A) volatile BYTE NAKIE             ;  // Endpoint Ping NAK interrupt Enable
+EXTERN xdata _AT_(0xE65B) volatile BYTE NAKIRQ            ;  // Endpoint Ping NAK interrupt Request
+EXTERN xdata _AT_(0xE65C) volatile BYTE USBIE             ;  // USB Int Enables
+EXTERN xdata _AT_(0xE65D) volatile BYTE USBIRQ            ;  // USB Interrupt Requests
+EXTERN xdata _AT_(0xE65E) volatile BYTE EPIE              ;  // Endpoint Interrupt Enables
+EXTERN xdata _AT_(0xE65F) volatile BYTE EPIRQ             ;  // Endpoint Interrupt Requests
+EXTERN xdata _AT_(0xE660) volatile BYTE GPIFIE            ;  // GPIF Interrupt Enable
+EXTERN xdata _AT_(0xE661) volatile BYTE GPIFIRQ           ;  // GPIF Interrupt Request
+EXTERN xdata _AT_(0xE662) volatile BYTE USBERRIE          ;  // USB Error Interrupt Enables
+EXTERN xdata _AT_(0xE663) volatile BYTE USBERRIRQ         ;  // USB Error Interrupt Requests
+EXTERN xdata _AT_(0xE664) volatile BYTE ERRCNTLIM         ;  // USB Error counter and limit
+EXTERN xdata _AT_(0xE665) volatile BYTE CLRERRCNT         ;  // Clear Error Counter EC[3..0]
+EXTERN xdata _AT_(0xE666) volatile BYTE INT2IVEC          ;  // Interupt 2 (USB) Autovector
+EXTERN xdata _AT_(0xE667) volatile BYTE INT4IVEC          ;  // Interupt 4 (FIFOS & GPIF) Autovector
+EXTERN xdata _AT_(0xE668) volatile BYTE INTSETUP          ;  // Interrupt 2&4 Setup
+
+// Input/Output
+
+EXTERN xdata _AT_(0xE670) volatile BYTE PORTACFG          ;  // I/O PORTA Alternate Configuration
+EXTERN xdata _AT_(0xE671) volatile BYTE PORTCCFG          ;  // I/O PORTC Alternate Configuration
+EXTERN xdata _AT_(0xE672) volatile BYTE PORTECFG          ;  // I/O PORTE Alternate Configuration
+EXTERN xdata _AT_(0xE678) volatile BYTE I2CS              ;  // Control & Status
+EXTERN xdata _AT_(0xE679) volatile BYTE I2DAT             ;  // Data
+EXTERN xdata _AT_(0xE67A) volatile BYTE I2CTL             ;  // I2C Control
+EXTERN xdata _AT_(0xE67B) volatile BYTE XAUTODAT1         ;  // Autoptr1 MOVX access
+EXTERN xdata _AT_(0xE67C) volatile BYTE XAUTODAT2         ;  // Autoptr2 MOVX access
+
+#define EXTAUTODAT1 XAUTODAT1
+#define EXTAUTODAT2 XAUTODAT2
+
+// USB Control
+
+EXTERN xdata _AT_(0xE680) volatile BYTE USBCS             ;  // USB Control & Status
+EXTERN xdata _AT_(0xE681) volatile BYTE SUSPEND           ;  // Put chip into suspend
+EXTERN xdata _AT_(0xE682) volatile BYTE WAKEUPCS          ;  // Wakeup source and polarity
+EXTERN xdata _AT_(0xE683) volatile BYTE TOGCTL            ;  // Toggle Control
+EXTERN xdata _AT_(0xE684) volatile BYTE USBFRAMEH         ;  // USB Frame count H
+EXTERN xdata _AT_(0xE685) volatile BYTE USBFRAMEL         ;  // USB Frame count L
+EXTERN xdata _AT_(0xE686) volatile BYTE MICROFRAME        ;  // Microframe count, 0-7
+EXTERN xdata _AT_(0xE687) volatile BYTE FNADDR            ;  // USB Function address
+
+// Endpoints
+
+EXTERN xdata _AT_(0xE68A) volatile BYTE EP0BCH            ;  // Endpoint 0 Byte Count H
+EXTERN xdata _AT_(0xE68B) volatile BYTE EP0BCL            ;  // Endpoint 0 Byte Count L
+EXTERN xdata _AT_(0xE68D) volatile BYTE EP1OUTBC          ;  // Endpoint 1 OUT Byte Count
+EXTERN xdata _AT_(0xE68F) volatile BYTE EP1INBC           ;  // Endpoint 1 IN Byte Count
+EXTERN xdata _AT_(0xE690) volatile BYTE EP2BCH            ;  // Endpoint 2 Byte Count H
+EXTERN xdata _AT_(0xE691) volatile BYTE EP2BCL            ;  // Endpoint 2 Byte Count L
+EXTERN xdata _AT_(0xE694) volatile BYTE EP4BCH            ;  // Endpoint 4 Byte Count H
+EXTERN xdata _AT_(0xE695) volatile BYTE EP4BCL            ;  // Endpoint 4 Byte Count L
+EXTERN xdata _AT_(0xE698) volatile BYTE EP6BCH            ;  // Endpoint 6 Byte Count H
+EXTERN xdata _AT_(0xE699) volatile BYTE EP6BCL            ;  // Endpoint 6 Byte Count L
+EXTERN xdata _AT_(0xE69C) volatile BYTE EP8BCH            ;  // Endpoint 8 Byte Count H
+EXTERN xdata _AT_(0xE69D) volatile BYTE EP8BCL            ;  // Endpoint 8 Byte Count L
+EXTERN xdata _AT_(0xE6A0) volatile BYTE EP0CS             ;  // Endpoint  Control and Status
+EXTERN xdata _AT_(0xE6A1) volatile BYTE EP1OUTCS          ;  // Endpoint 1 OUT Control and Status
+EXTERN xdata _AT_(0xE6A2) volatile BYTE EP1INCS           ;  // Endpoint 1 IN Control and Status
+EXTERN xdata _AT_(0xE6A3) volatile BYTE EP2CS             ;  // Endpoint 2 Control and Status
+EXTERN xdata _AT_(0xE6A4) volatile BYTE EP4CS             ;  // Endpoint 4 Control and Status
+EXTERN xdata _AT_(0xE6A5) volatile BYTE EP6CS             ;  // Endpoint 6 Control and Status
+EXTERN xdata _AT_(0xE6A6) volatile BYTE EP8CS             ;  // Endpoint 8 Control and Status
+EXTERN xdata _AT_(0xE6A7) volatile BYTE EP2FIFOFLGS       ;  // Endpoint 2 Flags
+EXTERN xdata _AT_(0xE6A8) volatile BYTE EP4FIFOFLGS       ;  // Endpoint 4 Flags
+EXTERN xdata _AT_(0xE6A9) volatile BYTE EP6FIFOFLGS       ;  // Endpoint 6 Flags
+EXTERN xdata _AT_(0xE6AA) volatile BYTE EP8FIFOFLGS       ;  // Endpoint 8 Flags
+EXTERN xdata _AT_(0xE6AB) volatile BYTE EP2FIFOBCH        ;  // EP2 FIFO total byte count H
+EXTERN xdata _AT_(0xE6AC) volatile BYTE EP2FIFOBCL        ;  // EP2 FIFO total byte count L
+EXTERN xdata _AT_(0xE6AD) volatile BYTE EP4FIFOBCH        ;  // EP4 FIFO total byte count H
+EXTERN xdata _AT_(0xE6AE) volatile BYTE EP4FIFOBCL        ;  // EP4 FIFO total byte count L
+EXTERN xdata _AT_(0xE6AF) volatile BYTE EP6FIFOBCH        ;  // EP6 FIFO total byte count H
+EXTERN xdata _AT_(0xE6B0) volatile BYTE EP6FIFOBCL        ;  // EP6 FIFO total byte count L
+EXTERN xdata _AT_(0xE6B1) volatile BYTE EP8FIFOBCH        ;  // EP8 FIFO total byte count H
+EXTERN xdata _AT_(0xE6B2) volatile BYTE EP8FIFOBCL        ;  // EP8 FIFO total byte count L
+EXTERN xdata _AT_(0xE6B3) volatile BYTE SUDPTRH           ;  // Setup Data Pointer high address byte
+EXTERN xdata _AT_(0xE6B4) volatile BYTE SUDPTRL           ;  // Setup Data Pointer low address byte
+EXTERN xdata _AT_(0xE6B5) volatile BYTE SUDPTRCTL         ;  // Setup Data Pointer Auto Mode
+EXTERN xdata _AT_(0xE6B8) volatile BYTE SETUPDAT[8]       ;  // 8 bytes of SETUP data
+
+// GPIF
+
+EXTERN xdata _AT_(0xE6C0) volatile BYTE GPIFWFSELECT      ;  // Waveform Selector
+EXTERN xdata _AT_(0xE6C1) volatile BYTE GPIFIDLECS        ;  // GPIF Done, GPIF IDLE drive mode
+EXTERN xdata _AT_(0xE6C2) volatile BYTE GPIFIDLECTL       ;  // Inactive Bus, CTL states
+EXTERN xdata _AT_(0xE6C3) volatile BYTE GPIFCTLCFG        ;  // CTL OUT pin drive
+EXTERN xdata _AT_(0xE6C4) volatile BYTE GPIFADRH          ;  // GPIF Address H
+EXTERN xdata _AT_(0xE6C5) volatile BYTE GPIFADRL          ;  // GPIF Address L
+
+EXTERN xdata _AT_(0xE6CE) volatile BYTE GPIFTCB3          ;  // GPIF Transaction Count Byte 3
+EXTERN xdata _AT_(0xE6CF) volatile BYTE GPIFTCB2          ;  // GPIF Transaction Count Byte 2
+EXTERN xdata _AT_(0xE6D0) volatile BYTE GPIFTCB1          ;  // GPIF Transaction Count Byte 1
+EXTERN xdata _AT_(0xE6D1) volatile BYTE GPIFTCB0          ;  // GPIF Transaction Count Byte 0
+
+#define EP2GPIFTCH GPIFTCB1   // these are here for backwards compatibility
+#define EP2GPIFTCL GPIFTCB0   // before REVE silicon (ie. REVB and REVD)
+#define EP4GPIFTCH GPIFTCB1   // these are here for backwards compatibility
+#define EP4GPIFTCL GPIFTCB0   // before REVE silicon (ie. REVB and REVD)
+#define EP6GPIFTCH GPIFTCB1   // these are here for backwards compatibility
+#define EP6GPIFTCL GPIFTCB0   // before REVE silicon (ie. REVB and REVD)
+#define EP8GPIFTCH GPIFTCB1   // these are here for backwards compatibility
+#define EP8GPIFTCL GPIFTCB0   // before REVE silicon (ie. REVB and REVD)
+
+// EXTERN xdata volatile BYTE EP2GPIFTCH     _AT_ 0xE6D0;  // EP2 GPIF Transaction Count High
+// EXTERN xdata volatile BYTE EP2GPIFTCL     _AT_ 0xE6D1;  // EP2 GPIF Transaction Count Low
+EXTERN xdata _AT_(0xE6D2) volatile BYTE EP2GPIFFLGSEL     ;  // EP2 GPIF Flag select
+EXTERN xdata _AT_(0xE6D3) volatile BYTE EP2GPIFPFSTOP     ;  // Stop GPIF EP2 transaction on prog. flag
+EXTERN xdata _AT_(0xE6D4) volatile BYTE EP2GPIFTRIG       ;  // EP2 FIFO Trigger
+// EXTERN xdata volatile BYTE EP4GPIFTCH     _AT_ 0xE6D8;  // EP4 GPIF Transaction Count High
+// EXTERN xdata volatile BYTE EP4GPIFTCL     _AT_ 0xE6D9;  // EP4 GPIF Transactionr Count Low
+EXTERN xdata _AT_(0xE6DA) volatile BYTE EP4GPIFFLGSEL     ;  // EP4 GPIF Flag select
+EXTERN xdata _AT_(0xE6DB) volatile BYTE EP4GPIFPFSTOP     ;  // Stop GPIF EP4 transaction on prog. flag
+EXTERN xdata _AT_(0xE6DC) volatile BYTE EP4GPIFTRIG       ;  // EP4 FIFO Trigger
+// EXTERN xdata volatile BYTE EP6GPIFTCH     _AT_ 0xE6E0;  // EP6 GPIF Transaction Count High
+// EXTERN xdata volatile BYTE EP6GPIFTCL     _AT_ 0xE6E1;  // EP6 GPIF Transaction Count Low
+EXTERN xdata _AT_(0xE6E2) volatile BYTE EP6GPIFFLGSEL     ;  // EP6 GPIF Flag select
+EXTERN xdata _AT_(0xE6E3) volatile BYTE EP6GPIFPFSTOP     ;  // Stop GPIF EP6 transaction on prog. flag
+EXTERN xdata _AT_(0xE6E4) volatile BYTE EP6GPIFTRIG       ;  // EP6 FIFO Trigger
+// EXTERN xdata volatile BYTE EP8GPIFTCH     _AT_ 0xE6E8;  // EP8 GPIF Transaction Count High
+// EXTERN xdata volatile BYTE EP8GPIFTCL     _AT_ 0xE6E9;  // EP8GPIF Transaction Count Low
+EXTERN xdata _AT_(0xE6EA) volatile BYTE EP8GPIFFLGSEL     ;  // EP8 GPIF Flag select
+EXTERN xdata _AT_(0xE6EB) volatile BYTE EP8GPIFPFSTOP     ;  // Stop GPIF EP8 transaction on prog. flag
+EXTERN xdata _AT_(0xE6EC) volatile BYTE EP8GPIFTRIG       ;  // EP8 FIFO Trigger
+EXTERN xdata _AT_(0xE6F0) volatile BYTE XGPIFSGLDATH      ;  // GPIF Data H (16-bit mode only)
+EXTERN xdata _AT_(0xE6F1) volatile BYTE XGPIFSGLDATLX     ;  // Read/Write GPIF Data L & trigger transac
+EXTERN xdata _AT_(0xE6F2) volatile BYTE XGPIFSGLDATLNOX   ;  // Read GPIF Data L, no transac trigger
+EXTERN xdata _AT_(0xE6F3) volatile BYTE GPIFREADYCFG      ;  // Internal RDY,Sync/Async, RDY5CFG
+EXTERN xdata _AT_(0xE6F4) volatile BYTE GPIFREADYSTAT     ;  // RDY pin states
+EXTERN xdata _AT_(0xE6F5) volatile BYTE GPIFABORT         ;  // Abort GPIF cycles
+
+// UDMA
+
+EXTERN xdata _AT_(0xE6C6) volatile BYTE FLOWSTATE         ; //Defines GPIF flow state
+EXTERN xdata _AT_(0xE6C7) volatile BYTE FLOWLOGIC         ; //Defines flow/hold decision criteria
+EXTERN xdata _AT_(0xE6C8) volatile BYTE FLOWEQ0CTL        ; //CTL states during active flow state
+EXTERN xdata _AT_(0xE6C9) volatile BYTE FLOWEQ1CTL        ; //CTL states during hold flow state
+EXTERN xdata _AT_(0xE6CA) volatile BYTE FLOWHOLDOFF       ;
+EXTERN xdata _AT_(0xE6CB) volatile BYTE FLOWSTB           ; //CTL/RDY Signal to use as master data strobe 
+EXTERN xdata _AT_(0xE6CC) volatile BYTE FLOWSTBEDGE       ; //Defines active master strobe edge
+EXTERN xdata _AT_(0xE6CD) volatile BYTE FLOWSTBHPERIOD    ; //Half Period of output master strobe
+EXTERN xdata _AT_(0xE60C) volatile BYTE GPIFHOLDAMOUNT    ; //Data delay shift 
+EXTERN xdata _AT_(0xE67D) volatile BYTE UDMACRCH          ; //CRC Upper byte
+EXTERN xdata _AT_(0xE67E) volatile BYTE UDMACRCL          ; //CRC Lower byte
+EXTERN xdata _AT_(0xE67F) volatile BYTE UDMACRCQUAL       ; //UDMA In only, host terminated use only
+
+
+// Debug/Test
+
+EXTERN xdata _AT_(0xE6F8) volatile BYTE DBUG              ;  // Debug
+EXTERN xdata _AT_(0xE6F9) volatile BYTE TESTCFG           ;  // Test configuration
+EXTERN xdata _AT_(0xE6FA) volatile BYTE USBTEST           ;  // USB Test Modes
+EXTERN xdata _AT_(0xE6FB) volatile BYTE CT1               ;  // Chirp Test--Override
+EXTERN xdata _AT_(0xE6FC) volatile BYTE CT2               ;  // Chirp Test--FSM
+EXTERN xdata _AT_(0xE6FD) volatile BYTE CT3               ;  // Chirp Test--Control Signals
+EXTERN xdata _AT_(0xE6FE) volatile BYTE CT4               ;  // Chirp Test--Inputs
+
+// Endpoint Buffers
+
+EXTERN xdata _AT_(0xE740) volatile BYTE EP0BUF[64]        ;  // EP0 IN-OUT buffer
+EXTERN xdata _AT_(0xE780) volatile BYTE EP1OUTBUF[64]     ;  // EP1-OUT buffer
+EXTERN xdata _AT_(0xE7C0) volatile BYTE EP1INBUF[64]      ;  // EP1-IN buffer
+EXTERN xdata _AT_(0xF000) volatile BYTE EP2FIFOBUF[1024]  ;  // 512/1024-byte EP2 buffer (IN or OUT)
+EXTERN xdata _AT_(0xF400) volatile BYTE EP4FIFOBUF[1024]  ;  // 512 byte EP4 buffer (IN or OUT)
+EXTERN xdata _AT_(0xF800) volatile BYTE EP6FIFOBUF[1024]  ;  // 512/1024-byte EP6 buffer (IN or OUT)
+EXTERN xdata _AT_(0xFC00) volatile BYTE EP8FIFOBUF[1024]  ;  // 512 byte EP8 buffer (IN or OUT)
+
+#undef EXTERN
+#undef _AT_
+
+/*-----------------------------------------------------------------------------
+   Special Function Registers (SFRs)
+   The byte registers and bits defined in the following list are based
+   on the Synopsis definition of the 8051 Special Function Registers for EZ-USB. 
+    If you modify the register definitions below, please regenerate the file 
+    "ezregs.inc" which includes the same basic information for assembly inclusion.
+-----------------------------------------------------------------------------*/
+
+sfr at 0x80 IOA;
+sfr at 0x81 SP;
+sfr at 0x82 DPL;
+sfr at 0x83 DPH;
+sfr at 0x84 DPL1;
+sfr at 0x85 DPH1;
+sfr at 0x86 DPS;
+         /*  DPS  */
+         sbit at 0x86+0 SEL;
+sfr at 0x87 PCON;   /*  PCON  */
+         //sbit IDLE   = 0x87+0;
+         //sbit STOP   = 0x87+1;
+         //sbit GF0    = 0x87+2;
+         //sbit GF1    = 0x87+3;
+         //sbit SMOD0  = 0x87+7;
+sfr at 0x88 TCON;
+         /*  TCON  */
+         sbit at 0x88+0 IT0;
+         sbit at 0x88+1 IE0;
+         sbit at 0x88+2 IT1;
+         sbit at 0x88+3 IE1;
+         sbit at 0x88+4 TR0;
+         sbit at 0x88+5 TF0;
+         sbit at 0x88+6 TR1;
+         sbit at 0x88+7 TF1;
+sfr at 0x89 TMOD;
+         /*  TMOD  */
+         //sbit M00    = 0x89+0;
+         //sbit M10    = 0x89+1;
+         //sbit CT0    = 0x89+2;
+         //sbit GATE0  = 0x89+3;
+         //sbit M01    = 0x89+4;
+         //sbit M11    = 0x89+5;
+         //sbit CT1    = 0x89+6;
+         //sbit GATE1  = 0x89+7;
+sfr at 0x8A TL0;
+sfr at 0x8B TL1;
+sfr at 0x8C TH0;
+sfr at 0x8D TH1;
+sfr at 0x8E CKCON;
+         /*  CKCON  */
+         //sbit MD0    = 0x89+0;
+         //sbit MD1    = 0x89+1;
+         //sbit MD2    = 0x89+2;
+         //sbit T0M    = 0x89+3;
+         //sbit T1M    = 0x89+4;
+         //sbit T2M    = 0x89+5;
+// sfr at 0x8F SPC_FNC; // Was WRS in Reg320
+         /*  CKCON  */
+         //sbit WRS    = 0x8F+0;
+sfr at 0x90 IOB;
+sfr at 0x91 EXIF; // EXIF Bit Values differ from Reg320
+         /*  EXIF  */
+         //sbit USBINT = 0x91+4;
+         //sbit I2CINT = 0x91+5;
+         //sbit IE4    = 0x91+6;
+         //sbit IE5    = 0x91+7;
+sfr at 0x92 MPAGE;
+sfr at 0x98 SCON0;
+         /*  SCON0  */
+         sbit at 0x98+0 RI;
+         sbit at 0x98+1 TI;
+         sbit at 0x98+2 RB8;
+         sbit at 0x98+3 TB8;
+         sbit at 0x98+4 REN;
+         sbit at 0x98+5 SM2;
+         sbit at 0x98+6 SM1;
+         sbit at 0x98+7 SM0;
+sfr at 0x99 SBUF0;
+
+sfr at 0x9A APTR1H;
+sfr at 0x9B APTR1L;
+sfr at 0x9C AUTODAT1; 
+sfr at 0x9D AUTOPTRH2;
+sfr at 0x9E AUTOPTRL2; 
+sfr at 0x9F AUTODAT2;
+sfr at 0xA0 IOC;
+sfr at 0xA1 INT2CLR;
+sfr at 0xA2 INT4CLR;
+
+#define        AUTOPTRH1       APTR1H
+#define        AUTOPTRL1       APTR1L
+
+sfr at 0xA8 IE;
+         /*  IE  */
+         sbit at 0xA8+0 EX0;
+         sbit at 0xA8+1 ET0;
+         sbit at 0xA8+2 EX1;
+         sbit at 0xA8+3 ET1;
+         sbit at 0xA8+4 ES0;
+         sbit at 0xA8+5 ET2;
+         sbit at 0xA8+6 ES1;
+         sbit at 0xA8+7 EA;
+
+sfr at 0xAA EP2468STAT;
+         /* EP2468STAT */
+         //sbit EP2E   = 0xAA+0;
+         //sbit EP2F   = 0xAA+1;
+         //sbit EP4E   = 0xAA+2;
+         //sbit EP4F   = 0xAA+3;
+         //sbit EP6E   = 0xAA+4;
+         //sbit EP6F   = 0xAA+5;
+         //sbit EP8E   = 0xAA+6;
+         //sbit EP8F   = 0xAA+7;
+
+sfr at 0xAB EP24FIFOFLGS;
+sfr at 0xAC EP68FIFOFLGS;
+sfr at 0xAF AUTOPTRSETUP;
+            /* AUTOPTRSETUP */
+            // sbit EXTACC  = 0xAF+0;
+            // sbit APTR1FZ = 0xAF+1;
+            // sbit APTR2FZ = 0xAF+2;
+
+sfr at 0xB0 IOD;
+sfr at 0xB1 IOE;
+sfr at 0xB2 OEA;
+sfr at 0xB3 OEB;
+sfr at 0xB4 OEC;
+sfr at 0xB5 OED;
+sfr at 0xB6 OEE;
+
+sfr at 0xB8 IP;
+         /*  IP  */
+         sbit at 0xB8+0 PX0;
+         sbit at 0xB8+1 PT0;
+         sbit at 0xB8+2 PX1;
+         sbit at 0xB8+3 PT1;
+         sbit at 0xB8+4 PS0;
+         sbit at 0xB8+5 PT2;
+         sbit at 0xB8+6 PS1;
+
+sfr at 0xBA EP01STAT;
+sfr at 0xBB GPIFTRIG;
+                
+sfr at 0xBD GPIFSGLDATH;
+sfr at 0xBE GPIFSGLDATLX;
+sfr at 0xBF GPIFSGLDATLNOX;
+
+sfr at 0xC0 SCON1;
+         /*  SCON1  */
+         sbit at 0xC0+0 RI1;
+         sbit at 0xC0+1 TI1;
+         sbit at 0xC0+2 RB81;
+         sbit at 0xC0+3 TB81;
+         sbit at 0xC0+4 REN1;
+         sbit at 0xC0+5 SM21;
+         sbit at 0xC0+6 SM11;
+         sbit at 0xC0+7 SM01;
+sfr at 0xC1 SBUF1;
+sfr at 0xC8 T2CON;
+         /*  T2CON  */
+        sbit at 0xC8+0 CP_RL2;
+        sbit at 0xC8+1 C_T2;
+         sbit at 0xC8+2 TR2;
+         sbit at 0xC8+3 EXEN2;
+         sbit at 0xC8+4 TCLK;
+         sbit at 0xC8+5 RCLK;
+         sbit at 0xC8+6 EXF2;
+         sbit at 0xC8+7 TF2;
+sfr at 0xCA RCAP2L;
+sfr at 0xCB RCAP2H;
+sfr at 0xCC TL2;
+sfr at 0xCD TH2;
+sfr at 0xD0 PSW;
+         /*  PSW  */
+         sbit at 0xD0+0 P;
+         sbit at 0xD0+1 FL;
+         sbit at 0xD0+2 OV;
+         sbit at 0xD0+3 RS0;
+         sbit at 0xD0+4 RS1;
+         sbit at 0xD0+5 F0;
+         sbit at 0xD0+6 AC;
+         sbit at 0xD0+7 CY;
+sfr at 0xD8 EICON; // Was WDCON in DS80C320 EICON; Bit Values differ from Reg320
+         /*  EICON  */
+         sbit at 0xD8+3 INT6;
+         sbit at 0xD8+4 RESI;
+         sbit at 0xD8+5 ERESI;
+         sbit at 0xD8+7 SMOD1;
+sfr at 0xE0 ACC;
+sfr at 0xE8 EIE; // EIE Bit Values differ from Reg320
+                        /*  EIE  */
+         sbit at 0xE8+0 EIUSB;
+         sbit at 0xE8+1 EI2C;
+         sbit at 0xE8+2 EIEX4;
+         sbit at 0xE8+3 EIEX5;
+         sbit at 0xE8+4 EIEX6;
+sfr at 0xF0 B;
+sfr at 0xF8 EIP; // EIP Bit Values differ from Reg320
+                        /*  EIP  */
+         sbit at 0xF8+0 PUSB;
+         sbit at 0xF8+1 PI2C;
+         sbit at 0xF8+2 EIPX4;
+         sbit at 0xF8+3 EIPX5;
+         sbit at 0xF8+4 EIPX6;
+
+/*-----------------------------------------------------------------------------
+   Bit Masks
+-----------------------------------------------------------------------------*/
+
+#define bmBIT0 1
+#define bmBIT1 2
+#define bmBIT2 4
+#define bmBIT3 8
+#define bmBIT4 16
+#define bmBIT5 32
+#define bmBIT6 64
+#define bmBIT7 128
+
+/* CPU Control & Status Register (CPUCS) */
+#define bmPRTCSTB    bmBIT5
+#define bmCLKSPD     (bmBIT4 | bmBIT3)
+#define bmCLKSPD1    bmBIT4
+#define bmCLKSPD0    bmBIT3
+#define bmCLKINV     bmBIT2
+#define bmCLKOE      bmBIT1
+#define bm8051RES    bmBIT0
+/* Port Alternate Configuration Registers */
+/* Port A (PORTACFG) */
+#define bmFLAGD      bmBIT7
+#define bmINT1       bmBIT1
+#define bmINT0       bmBIT0
+/* Port C (PORTCCFG) */
+#define bmGPIFA7     bmBIT7
+#define bmGPIFA6     bmBIT6
+#define bmGPIFA5     bmBIT5
+#define bmGPIFA4     bmBIT4
+#define bmGPIFA3     bmBIT3
+#define bmGPIFA2     bmBIT2
+#define bmGPIFA1     bmBIT1
+#define bmGPIFA0     bmBIT0
+/* Port E (PORTECFG) */
+#define bmGPIFA8     bmBIT7
+#define bmT2EX       bmBIT6
+#define bmINT6       bmBIT5
+#define bmRXD1OUT    bmBIT4
+#define bmRXD0OUT    bmBIT3
+#define bmT2OUT      bmBIT2
+#define bmT1OUT      bmBIT1
+#define bmT0OUT      bmBIT0
+
+/* I2C Control & Status Register (I2CS) */
+#define bmSTART      bmBIT7
+#define bmSTOP       bmBIT6
+#define bmLASTRD     bmBIT5
+#define bmID         (bmBIT4 | bmBIT3)
+#define bmBERR       bmBIT2
+#define bmACK        bmBIT1
+#define bmDONE       bmBIT0
+/* I2C Control Register (I2CTL) */
+#define bmSTOPIE     bmBIT1
+#define bm400KHZ     bmBIT0
+/* Interrupt 2 (USB) Autovector Register (INT2IVEC) */
+#define bmIV4        bmBIT6
+#define bmIV3        bmBIT5
+#define bmIV2        bmBIT4
+#define bmIV1        bmBIT3
+#define bmIV0        bmBIT2
+/* USB Interrupt Request & Enable Registers (USBIE/USBIRQ) */
+#define bmEP0ACK     bmBIT6
+#define bmHSGRANT    bmBIT5
+#define bmURES       bmBIT4
+#define bmSUSP       bmBIT3
+#define bmSUTOK      bmBIT2
+#define bmSOF        bmBIT1
+#define bmSUDAV      bmBIT0
+/* Breakpoint register (BREAKPT) */
+#define bmBREAK      bmBIT3
+#define bmBPPULSE    bmBIT2
+#define bmBPEN       bmBIT1
+/* Interrupt 2 & 4 Setup (INTSETUP) */
+#define bmAV2EN      bmBIT3
+#define bmINT4IN     bmBIT1
+#define bmAV4EN      bmBIT0
+/* USB Control & Status Register (USBCS) */
+#define bmHSM        bmBIT7
+#define bmDISCON     bmBIT3
+#define bmNOSYNSOF   bmBIT2
+#define bmRENUM      bmBIT1
+#define bmSIGRESUME  bmBIT0
+/* Wakeup Control and Status Register (WAKEUPCS) */
+#define bmWU2        bmBIT7
+#define bmWU         bmBIT6
+#define bmWU2POL     bmBIT5
+#define bmWUPOL      bmBIT4
+#define bmDPEN       bmBIT2
+#define bmWU2EN      bmBIT1
+#define bmWUEN       bmBIT0
+/* End Point 0 Control & Status Register (EP0CS) */
+#define bmHSNAK      bmBIT7
+/* End Point 0-1 Control & Status Registers (EP0CS/EP1OUTCS/EP1INCS) */
+#define bmEPBUSY     bmBIT1
+#define bmEPSTALL    bmBIT0
+/* End Point 2-8 Control & Status Registers (EP2CS/EP4CS/EP6CS/EP8CS) */
+#define bmNPAK       (bmBIT6 | bmBIT5 | bmBIT4)
+#define bmEPFULL     bmBIT3
+#define bmEPEMPTY    bmBIT2
+/* Endpoint Status (EP2468STAT) SFR bits */
+#define bmEP8FULL    bmBIT7
+#define bmEP8EMPTY   bmBIT6
+#define bmEP6FULL    bmBIT5
+#define bmEP6EMPTY   bmBIT4
+#define bmEP4FULL    bmBIT3
+#define bmEP4EMPTY   bmBIT2
+#define bmEP2FULL    bmBIT1
+#define bmEP2EMPTY   bmBIT0
+/* SETUP Data Pointer Auto Mode (SUDPTRCTL) */
+#define bmSDPAUTO    bmBIT0
+/* Endpoint Data Toggle Control (TOGCTL) */
+#define bmQUERYTOGGLE  bmBIT7
+#define bmSETTOGGLE    bmBIT6
+#define bmRESETTOGGLE  bmBIT5
+#define bmTOGCTLEPMASK bmBIT3 | bmBIT2 | bmBIT1 | bmBIT0
+/* IBN (In Bulk Nak) enable and request bits (IBNIE/IBNIRQ) */
+#define bmEP8IBN     bmBIT5
+#define bmEP6IBN     bmBIT4
+#define bmEP4IBN     bmBIT3
+#define bmEP2IBN     bmBIT2
+#define bmEP1IBN     bmBIT1
+#define bmEP0IBN     bmBIT0
+
+/* PING-NAK enable and request bits (NAKIE/NAKIRQ) */
+#define bmEP8PING     bmBIT7
+#define bmEP6PING     bmBIT6
+#define bmEP4PING     bmBIT5
+#define bmEP2PING     bmBIT4
+#define bmEP1PING     bmBIT3
+#define bmEP0PING     bmBIT2
+#define bmIBN         bmBIT0
+
+/* Interface Configuration bits (IFCONFIG) */
+#define bmIFCLKSRC    bmBIT7           // set == INTERNAL
+#define bm3048MHZ     bmBIT6           // set == 48 MHz
+#define bmIFCLKOE     bmBIT5
+#define bmIFCLKPOL    bmBIT4
+#define bmASYNC       bmBIT3
+#define bmGSTATE      bmBIT2
+#define bmIFCFG1      bmBIT1
+#define bmIFCFG0      bmBIT0
+#define bmIFCFGMASK   (bmIFCFG0 | bmIFCFG1)
+#define bmIFGPIF      bmIFCFG1
+
+/* EP 2468 FIFO Configuration bits (EP2FIFOCFG,EP4FIFOCFG,EP6FIFOCFG,EP8FIFOCFG) */
+#define bmINFM       bmBIT6
+#define bmOEP        bmBIT5
+#define bmAUTOOUT    bmBIT4
+#define bmAUTOIN     bmBIT3
+#define bmZEROLENIN  bmBIT2
+//   must be zero    bmBIT1
+#define bmWORDWIDE   bmBIT0
+
+/*
+ * Chip Revision Control Bits (REVCTL) - used to ebable/disable revision specific features
+ */ 
+#define bmNOAUTOARM    bmBIT1  // these don't match the docs
+#define bmSKIPCOMMIT   bmBIT0  // these don't match the docs
+
+#define        bmDYN_OUT      bmBIT1   // these do...
+#define        bmENH_PKT      bmBIT0
+
+
+/* Fifo Reset bits (FIFORESET) */
+#define bmNAKALL       bmBIT7
+
+/* Endpoint Configuration (EPxCFG) */
+#define        bmVALID         bmBIT7
+#define        bmIN            bmBIT6
+#define        bmTYPE1         bmBIT5
+#define        bmTYPE0         bmBIT4
+#define          bmISOCHRONOUS         bmTYPE0
+#define          bmBULK                bmTYPE1
+#define          bmINTERRUPT          (bmTYPE1 | bmTYPE0)
+#define        bm1KBUF         bmBIT3
+#define        bmBUF1          bmBIT1
+#define        bmBUF0          bmBIT0
+#define          bmQUADBUF             0
+#define          bmINVALIDBUF          bmBUF0
+#define          bmDOUBLEBUF           bmBUF1
+#define          bmTRIPLEBUF           (bmBUF1 | bmBUF0)
+
+/* OUTPKTEND */
+#define        bmSKIP          bmBIT7  // low 4 bits specify which end point
+
+/* GPIFTRIG defs */
+#define        bmGPIF_IDLE             bmBIT7          // status bit
+
+#define        bmGPIF_EP2_START             0
+#define        bmGPIF_EP4_START             1
+#define        bmGPIF_EP6_START             2
+#define        bmGPIF_EP8_START             3
+#define        bmGPIF_READ             bmBIT2
+#define        bmGPIF_WRITE                 0
+
+/* EXIF bits */
+#define        bmEXIF_USBINT           bmBIT4
+#define        bmEXIF_I2CINT           bmBIT5
+#define        bmEXIF_IE4              bmBIT6
+#define        bmEXIF_IE5              bmBIT7
+
+
+#endif   /* FX2REGS_H */
diff --git a/usrp/firmware/include/fx2utils.h b/usrp/firmware/include/fx2utils.h
new file mode 100644 (file)
index 0000000..9c2e99d
--- /dev/null
@@ -0,0 +1,31 @@
+/* -*- 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 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.
+ */
+#ifndef _FX2UTILS_H_
+#define _FX2UTILS_H_
+
+void fx2_stall_ep0 (void);
+void fx2_reset_data_toggle (unsigned char ep);
+void fx2_renumerate (void);
+
+
+
+#endif /* _FX2UTILS_H_ */
diff --git a/usrp/firmware/include/generate_regs.py b/usrp/firmware/include/generate_regs.py
new file mode 100755 (executable)
index 0000000..656cd5e
--- /dev/null
@@ -0,0 +1,57 @@
+#!/usr/bin/env python
+
+import os, os.path
+import re
+import sys
+
+
+# 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 generate_fpga_regs (h_filename, v_filename):
+    const_width = 7                  # bit width of constants
+    
+    h_file = open_src (h_filename, 'r')
+    v_file = open (v_filename, 'w')
+    v_file.write (
+    '''//
+// This file is machine generated from %s
+// Do not edit by hand; your edits will be overwritten.
+//
+''' % (h_filename,))
+
+    pat = re.compile (r'^#define\s*(FR_\w*)\s*(\w*)(.*)$')
+    pat_bitno = re.compile (r'^#define\s*(bitno\w*)\s*(\w*)(.*)$')
+    pat_bm = re.compile (r'^#define\s*(bm\w*)\s*(\w*)(.*)$')
+    for line in h_file:
+        if re.match ('//|\s*$', line):  # comment or blank line
+            v_file.write (line)
+        mo = pat.search (line)
+        mo_bitno =pat_bitno.search (line)
+        mo_bm =pat_bm.search (line)
+        if mo:
+            v_file.write ('`define %-25s %d\'d%s%s\n' % (
+                mo.group (1), const_width, mo.group (2), mo.group (3)))
+        elif mo_bitno:
+            v_file.write ('`define %-25s %s%s\n' % (
+                mo_bitno.group (1), mo_bitno.group (2), mo_bitno.group (3)))
+        elif mo_bm:
+            v_file.write ('`define %-25s %s%s\n' % (
+                mo_bm.group (1), mo_bm.group (2), mo_bm.group (3)))
+    
+
+if __name__ == '__main__':
+    if len (sys.argv) != 3:
+        sys.stderr.write ('usage: %s file.h file.v\n' % (sys.argv[0]))
+        sys.exit (1)
+    generate_fpga_regs (sys.argv[1], sys.argv[2])
+    
diff --git a/usrp/firmware/include/i2c.h b/usrp/firmware/include/i2c.h
new file mode 100644 (file)
index 0000000..58b7a34
--- /dev/null
@@ -0,0 +1,32 @@
+/* -*- 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 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.
+ */
+
+#ifndef _I2C_H_
+#define _I2C_H_
+
+// returns non-zero if successful, else 0
+unsigned char i2c_read (unsigned char addr, xdata unsigned char *buf, unsigned char len);
+
+// returns non-zero if successful, else 0
+unsigned char i2c_write (unsigned char addr, xdata const unsigned char *buf, unsigned char len);
+
+#endif /* _I2C_H_ */
diff --git a/usrp/firmware/include/isr.h b/usrp/firmware/include/isr.h
new file mode 100644 (file)
index 0000000..2081175
--- /dev/null
@@ -0,0 +1,172 @@
+/* -*- 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 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.
+ */
+
+#ifndef _ISR_H_
+#define _ISR_H_
+
+/*
+ * ----------------------------------------------------------------
+ *     routines for managing interrupt services routines
+ * ----------------------------------------------------------------
+ */
+
+/*
+ * The FX2 has three discrete sets of interrupt vectors.
+ * The first set is the standard 8051 vector (13 8-byte entries).
+ * The second set is USB interrupt autovector (32 4-byte entries).
+ * The third set is the FIFO/GPIF autovector (14 4-byte entries).
+ *
+ * Since all the code we're running in the FX2 is ram based, we
+ * forego the typical "initialize the interrupt vectors at link time"
+ * strategy, in favor of calls at run time that install the correct
+ * pointers to functions.
+ */
+
+/*
+ * Standard Vector numbers
+ */
+
+#define        SV_INT_0                0x03
+#define        SV_TIMER_0              0x0b
+#define        SV_INT_1                0x13
+#define        SV_TIMER_1              0x1b
+#define        SV_SERIAL_0             0x23
+#define        SV_TIMER_2              0x2b
+#define        SV_RESUME               0x33
+#define        SV_SERIAL_1             0x3b
+#define        SV_INT_2                0x43            // (INT_2) points at USB autovector
+#define        SV_I2C                  0x4b
+#define        SV_INT_4                0x53            // (INT_4) points at FIFO/GPIF autovector
+#define        SV_INT_5                0x5b
+#define        SV_INT_6                0x63
+
+#define        SV_MIN                  SV_INT_0
+#define        SV_MAX                  SV_INT_6
+
+/*
+ * USB Auto Vector numbers
+ */
+
+#define        UV_SUDAV                0x00
+#define        UV_SOF                  0x04
+#define        UV_SUTOK                0x08
+#define        UV_SUSPEND              0x0c
+#define        UV_USBRESET             0x10
+#define        UV_HIGHSPEED            0x14
+#define        UV_EP0ACK               0x18
+#define        UV_SPARE_1C             0x1c
+#define        UV_EP0IN                0x20
+#define        UV_EP0OUT               0x24
+#define        UV_EP1IN                0x28
+#define        UV_EP1OUT               0x2c
+#define        UV_EP2                  0x30
+#define        UV_EP4                  0x34
+#define        UV_EP6                  0x38
+#define        UV_EP8                  0x3c
+#define        UV_IBN                  0x40
+#define        UV_SPARE_44             0x44
+#define        UV_EP0PINGNAK           0x48
+#define        UV_EP1PINGNAK           0x4c
+#define        UV_EP2PINGNAK           0x50
+#define        UV_EP4PINGNAK           0x54
+#define        UV_EP6PINGNAK           0x58
+#define        UV_EP8PINGNAK           0x5c
+#define        UV_ERRLIMIT             0x60
+#define        UV_SPARE_64             0x64
+#define        UV_SPARE_68             0x68
+#define        UV_SPARE_6C             0x6c
+#define        UV_EP2ISOERR            0x70
+#define        UV_EP4ISOERR            0x74
+#define        UV_EP6ISOERR            0x78
+#define        UV_EP8ISOERR            0x7c
+
+#define        UV_MIN                  UV_SUDAV
+#define        UV_MAX                  UV_EP8ISOERR
+
+/*
+ * FIFO/GPIF Auto Vector numbers
+ */
+
+#define        FGV_EP2PF               0x80
+#define        FGV_EP4PF               0x84
+#define        FGV_EP6PF               0x88
+#define        FGV_EP8PF               0x8c
+#define        FGV_EP2EF               0x90
+#define        FGV_EP4EF               0x94
+#define        FGV_EP6EF               0x98
+#define        FGV_EP8EF               0x9c
+#define        FGV_EP2FF               0xa0
+#define        FGV_EP4FF               0xa4
+#define        FGV_EP6FF               0xa8
+#define        FGV_EP8FF               0xac
+#define        FGV_GPIFDONE            0xb0
+#define        FGV_GPIFWF              0xb4
+
+#define        FGV_MIN                 FGV_EP2PF
+#define        FGV_MAX                 FGV_GPIFWF
+
+
+/*
+ * Hook standard interrupt vector.
+ *
+ * vector_number is from the SV_<foo> list above.
+ * addr is the address of the interrupt service routine.
+ */
+void hook_sv (unsigned char vector_number, unsigned short addr);
+
+/*
+ * Hook usb interrupt vector.
+ *
+ * vector_number is from the UV_<foo> list above.
+ * addr is the address of the interrupt service routine.
+ */
+void hook_uv (unsigned char vector_number, unsigned short addr);
+
+/*
+ * Hook fifo/gpif interrupt vector.
+ *
+ * vector_number is from the FGV_<foo> list above.
+ * addr is the address of the interrupt service routine.
+ */
+void hook_fgv (unsigned char vector_number, unsigned short addr);
+
+/*
+ * One time call to enable autovectoring for both USB and FIFO/GPIF
+ */
+void setup_autovectors (void);
+
+
+/*
+ * Must be called in each usb interrupt handler
+ */
+#define        clear_usb_irq()                 \
+       EXIF &= ~bmEXIF_USBINT;         \
+       INT2CLR = 0
+
+/*
+ * Must be calledin each fifo/gpif interrupt handler
+ */
+#define        clear_fifo_gpif_irq()           \
+       EXIF &= ~bmEXIF_IE4;            \
+       INT4CLR = 0
+
+#endif /* _ISR_H_ */
diff --git a/usrp/firmware/include/syncdelay.h b/usrp/firmware/include/syncdelay.h
new file mode 100644 (file)
index 0000000..fa67338
--- /dev/null
@@ -0,0 +1,65 @@
+/* -*- 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 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.
+ */
+#ifndef _SYNCDELAY_H_
+#define _SYNCDELAY_H_
+
+/*
+ * Magic delay required between access to certain xdata registers (TRM page 15-106).
+ * For our configuration, 48 MHz FX2 / 48 MHz IFCLK, we need three cycles.  Each
+ * NOP is a single cycle....
+ *
+ * From TRM page 15-105:
+ *
+ * Under certain conditions, some read and write access to the FX2 registers must
+ * be separated by a "synchronization delay".  The delay is necessary only under the
+ * following conditions:
+ *
+ *   - between a write to any register in the 0xE600 - 0xE6FF range and a write to one
+ *     of the registers listed below.
+ *
+ *   - between a write to one of the registers listed below and a read from any register
+ *     in the 0xE600 - 0xE6FF range.
+ *
+ *   Registers which require a synchronization delay:
+ *
+ *     FIFORESET                       FIFOPINPOLAR
+ *     INPKTEND                        EPxBCH:L
+ *     EPxFIFOPFH:L                    EPxAUTOINLENH:L
+ *     EPxFIFOCFG                      EPxGPIFFLGSEL
+ *     PINFLAGSAB                      PINFLAGSCD
+ *     EPxFIFOIE                       EPxFIFOIRQ
+ *     GPIFIE                          GPIFIRQ
+ *     UDMACRCH:L                      GPIFADRH:L
+ *     GPIFTRIG                        EPxGPIFTRIG
+ *     OUTPKTEND                       REVCTL
+ *     GPIFTCB3                        GPIFTCB2
+ *     GPIFTCB1                        GPIFTCB0
+ */
+
+/*
+ * FIXME ensure that the peep hole optimizer isn't screwing us
+ */
+#define        SYNCDELAY       _asm nop; nop; nop; _endasm
+#define        NOP             _asm nop; _endasm
+
+
+#endif /* _SYNCDELAY_H_ */
diff --git a/usrp/firmware/include/timer.h b/usrp/firmware/include/timer.h
new file mode 100644 (file)
index 0000000..7bb640e
--- /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 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.
+ */
+
+#ifndef _TIMER_H_
+#define _TIMER_H_
+
+/*
+ * Arrange to have isr_tick_handler called at 100 Hz
+ */
+void hook_timer_tick (unsigned short isr_tick_handler);
+
+#define clear_timer_irq()                              \
+       TF2 = 0         /* clear overflow flag */
+
+
+#endif /* _TIMER_H_ */
diff --git a/usrp/firmware/include/usb_common.h b/usrp/firmware/include/usb_common.h
new file mode 100644 (file)
index 0000000..f8e26be
--- /dev/null
@@ -0,0 +1,37 @@
+/* -*- 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 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.
+ */
+
+#ifndef _USB_COMMON_H_
+#define _USB_COMMON_H_
+
+extern volatile bit _usb_got_SUDAV;
+
+// Provided by user application to handle VENDOR commands.
+// returns non-zero if it handled the command.
+unsigned char app_vendor_cmd (void);
+
+void usb_install_handlers (void);
+void usb_handle_setup_packet (void);
+
+#define usb_setup_packet_avail()       _usb_got_SUDAV
+
+#endif /* _USB_COMMON_H_ */
diff --git a/usrp/firmware/include/usb_descriptors.h b/usrp/firmware/include/usb_descriptors.h
new file mode 100644 (file)
index 0000000..68390d7
--- /dev/null
@@ -0,0 +1,40 @@
+/* -*- 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 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.
+ */
+
+extern xdata const char high_speed_device_descr[];
+extern xdata const char high_speed_devqual_descr[];
+extern xdata const char high_speed_config_descr[];
+
+extern xdata const char full_speed_device_descr[];
+extern xdata const char full_speed_devqual_descr[];
+extern xdata const char full_speed_config_descr[];
+
+extern xdata unsigned char nstring_descriptors;
+extern xdata char * xdata string_descriptors[];
+
+/*
+ * We patch these locations with info read from the usrp config eeprom
+ */
+extern xdata char usb_desc_hw_rev_binary_patch_location_0[];
+extern xdata char usb_desc_hw_rev_binary_patch_location_1[];
+extern xdata char usb_desc_hw_rev_ascii_patch_location_0[];
+extern xdata char usb_desc_serial_number_ascii[];
diff --git a/usrp/firmware/include/usb_requests.h b/usrp/firmware/include/usb_requests.h
new file mode 100644 (file)
index 0000000..c4680b0
--- /dev/null
@@ -0,0 +1,88 @@
+/* -*- 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 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.
+ */
+
+// Standard USB requests.
+// These are contained in end point 0 setup packets
+
+
+#ifndef _USB_REQUESTS_H_
+#define _USB_REQUESTS_H_
+
+// format of bmRequestType byte
+
+#define        bmRT_DIR_MASK           (0x1 << 7)
+#define        bmRT_DIR_IN             (1 << 7)
+#define        bmRT_DIR_OUT            (0 << 7)
+
+#define        bmRT_TYPE_MASK          (0x3 << 5)
+#define        bmRT_TYPE_STD           (0 << 5)
+#define        bmRT_TYPE_CLASS         (1 << 5)
+#define        bmRT_TYPE_VENDOR        (2 << 5)
+#define        bmRT_TYPE_RESERVED      (3 << 5)
+
+#define        bmRT_RECIP_MASK         (0x1f << 0)
+#define        bmRT_RECIP_DEVICE       (0 << 0)
+#define        bmRT_RECIP_INTERFACE    (1 << 0)
+#define        bmRT_RECIP_ENDPOINT     (2 << 0)
+#define        bmRT_RECIP_OTHER        (3 << 0)
+
+
+// standard request codes (bRequest)
+
+#define        RQ_GET_STATUS           0
+#define        RQ_CLEAR_FEATURE        1
+#define        RQ_RESERVED_2           2
+#define        RQ_SET_FEATURE          3
+#define        RQ_RESERVED_4           4
+#define        RQ_SET_ADDRESS          5
+#define        RQ_GET_DESCR            6
+#define        RQ_SET_DESCR            7
+#define        RQ_GET_CONFIG           8
+#define        RQ_SET_CONFIG           9
+#define        RQ_GET_INTERFACE       10
+#define        RQ_SET_INTERFACE       11
+#define        RQ_SYNCH_FRAME         12
+
+// standard descriptor types
+
+#define        DT_DEVICE               1
+#define        DT_CONFIG               2
+#define        DT_STRING               3
+#define        DT_INTERFACE            4
+#define        DT_ENDPOINT             5
+#define        DT_DEVQUAL              6
+#define        DT_OTHER_SPEED          7
+#define        DT_INTERFACE_POWER      8
+
+// standard feature selectors
+
+#define        FS_ENDPOINT_HALT        0       // recip: endpoint
+#define        FS_DEV_REMOTE_WAKEUP    1       // recip: device
+#define        FS_TEST_MODE            2       // recip: device
+
+// Get Status device attributes
+
+#define        bmGSDA_SELF_POWERED     0x01
+#define        bmGSDA_REM_WAKEUP       0x02
+
+
+#endif /* _USB_REQUESTS_H_ */
diff --git a/usrp/firmware/include/usrp_commands.h b/usrp/firmware/include/usrp_commands.h
new file mode 100644 (file)
index 0000000..2487892
--- /dev/null
@@ -0,0 +1,99 @@
+/* 
+ * USRP - Universal Software Radio Peripheral
+ *
+ * Copyright (C) 2003,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 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
+ */
+
+#ifndef _USRP_COMMANDS_H_
+#define _USRP_COMMANDS_H_
+
+#include <usrp_interfaces.h>
+#include <usrp_spi_defs.h>
+
+#define        MAX_EP0_PKTSIZE                64       // max size of EP0 packet on FX2
+
+// ----------------------------------------------------------------
+//                     Vendor bmRequestType's
+// ----------------------------------------------------------------
+
+#define        VRT_VENDOR_IN                   0xC0
+#define        VRT_VENDOR_OUT                  0x40
+
+// ----------------------------------------------------------------
+//                       USRP Vendor Requests
+//
+// Note that Cypress reserves [0xA0,0xAF].
+// 0xA0 is the firmware load function.
+// ----------------------------------------------------------------
+
+
+// IN commands
+
+#define        VRQ_GET_STATUS                  0x80
+#define                GS_TX_UNDERRUN                  0       // wIndexL      // returns 1 byte
+#define                GS_RX_OVERRUN                   1       // wIndexL      // returns 1 byte
+
+#define        VRQ_I2C_READ                    0x81            // wValueL: i2c address; length: how much to read
+
+#define        VRQ_SPI_READ                    0x82            // wValue: optional header bytes
+                                                       // wIndexH:     enables
+                                                       // wIndexL:     format
+                                                       // len: how much to read
+
+// OUT commands
+
+#define        VRQ_SET_LED                     0x01            // wValueL off/on {0,1}; wIndexL: which {0,1}
+
+#define        VRQ_FPGA_LOAD                   0x02
+#  define      FL_BEGIN                        0       // wIndexL: begin fpga programming cycle.  stalls if trouble.
+#  define      FL_XFER                         1       // wIndexL: xfer up to 64 bytes of data
+#  define      FL_END                          2       // wIndexL: end programming cycle, check for success.
+                                                       //          stalls endpoint if trouble.
+
+#define        VRQ_FPGA_WRITE_REG              0x03            // wIndexL: regno; data: 32-bit regval MSB first
+#define        VRQ_FPGA_SET_RESET              0x04            // wValueL: {0,1}
+#define        VRQ_FPGA_SET_TX_ENABLE          0x05            // wValueL: {0,1}
+#define        VRQ_FPGA_SET_RX_ENABLE          0x06            // wValueL: {0,1}
+// see below VRQ_FPGA_SET_{TX,RX}_RESET
+
+#define        VRQ_SET_SLEEP_BITS              0x07            // wValueH: mask; wValueL: bits.  set bits given by mask to bits
+
+#  define      SLEEP_ADC0                      0x01
+#  define      SLEEP_ADC1                      0x02
+#  define      SLEEP_DAC0                      0x04
+#  define      SLEEP_DAC1                      0x08
+
+#define        VRQ_I2C_WRITE                   0x08            // wValueL: i2c address; data: data
+
+#define        VRQ_SPI_WRITE                   0x09            // wValue: optional header bytes
+                                                       // wIndexH:     enables
+                                                       // wIndexL:     format
+                                                       // len: how much to write
+
+#define        VRQ_FPGA_SET_TX_RESET           0x0a            // wValueL: {0, 1}
+#define        VRQ_FPGA_SET_RX_RESET           0x0b            // wValueL: {0, 1}
+
+
+// -------------------------------------------------------------------
+// we store the hashes at fixed addresses in the FX2 internal memory
+
+#define          USRP_HASH_SLOT_0_ADDR                 0xe1e0
+#define          USRP_HASH_SLOT_1_ADDR                 0xe1f0
+
+
+
+#endif /* _USRP_COMMANDS_H_ */
diff --git a/usrp/firmware/include/usrp_config.h b/usrp/firmware/include/usrp_config.h
new file mode 100644 (file)
index 0000000..6d87665
--- /dev/null
@@ -0,0 +1,44 @@
+/* 
+ * USRP - Universal Software Radio Peripheral
+ *
+ * Copyright (C) 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 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
+ */
+
+/*
+ * configuration stuff for debugging
+ */
+
+/*
+ * Define to 0 for normal use of port A, i.e., FPGA control bus.
+ * Define to 1 to write trace to port A for scoping with logic analyzer.
+ */
+#define        UC_TRACE_USING_PORT_A                   0
+
+
+/*
+ * Define to 0 for normal use of low 3 bits of port E, i.e., A/D, D/A SLEEP bits.
+ * Define to 1 to enable by default driving the GPIF state to the
+ * low three bits of port E.
+ */
+#define UC_START_WITH_GSTATE_OUTPUT_ENABLED    0
+
+
+/*
+ * Define to 1 for normal use (the board really has an FPGA on it).
+ * Define to 0 for debug use on board without FPGA.
+ */
+#define UC_BOARD_HAS_FPGA                      1
diff --git a/usrp/firmware/include/usrp_i2c_addr.h b/usrp/firmware/include/usrp_i2c_addr.h
new file mode 100644 (file)
index 0000000..738bf2e
--- /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 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.
+ */
+#ifndef INCLUDED_USRP_I2C_ADDR_H
+#define INCLUDED_USRP_I2C_ADDR_H
+
+// I2C addresses
+
+#define I2C_DEV_EEPROM 0x50            // 24LC02[45]:  7-bits 1010xxx
+
+#define        I2C_ADDR_BOOT   (I2C_DEV_EEPROM | 0x0)
+#define        I2C_ADDR_TX_A   (I2C_DEV_EEPROM | 0x4)
+#define        I2C_ADDR_RX_A   (I2C_DEV_EEPROM | 0x5)
+#define        I2C_ADDR_TX_B   (I2C_DEV_EEPROM | 0x6)
+#define        I2C_ADDR_RX_B   (I2C_DEV_EEPROM | 0x7)
+
+
+// format of FX2 BOOT EEPROM
+//     00: 0xC0        code for ``Read IDs from EEPROM''
+//     01: 0xFE        USB Vendor ID (LSB)
+//     02: 0xFF        USB Vendor ID (MSB)
+//     03: 0x02        USB Product ID (LSB)
+//     04: 0x00        USB Product ID (MSB)
+//     05: 0x01        USB Device ID (LSB)     // rev1
+//     06: 0x00        USB Device ID (MSB)     // 0 = unconfig'd (no firmware)
+//     07: 0x00        option byte
+
+
+// format of daughterboard EEPROM
+//     00: 0xDB        code for ``I'm a daughterboard''
+//     01:   ..        Daughterboard ID (LSB)
+//     02:   ..        Daughterboard ID (MSB)
+//     03:   ..        io bits  7-0 direction (bit set if it's an output from m'board)
+//     04:   ..        io bits 15-8 direction (bit set if it's an output from m'board)
+//     05:   ..        ADC0 DC offset correction (LSB)
+//     06:   ..        ADC0 DC offset correction (MSB)
+//     07:   ..        ADC1 DC offset correction (LSB)
+//     08:   ..        ADC1 DC offset correction (MSB)
+//     ...
+//     1f:   ..        negative of the sum of bytes [0x00, 0x1e]
+
+#define        DB_EEPROM_MAGIC         0x00
+#define          DB_EEPROM_MAGIC_VALUE                 0xDB
+#define        DB_EEPROM_ID_LSB                0x01
+#define        DB_EEPROM_ID_MSB                0x02
+#define        DB_EEPROM_OE_LSB                0x03
+#define        DB_EEPROM_OE_MSB                0x04
+#define        DB_EEPROM_OFFSET_0_LSB          0x05    // offset correction for ADC or DAC 0
+#define        DB_EEPROM_OFFSET_0_MSB          0x06
+#define        DB_EEPROM_OFFSET_1_LSB          0x07    // offset correction for ADC or DAC 1
+#define        DB_EEPROM_OFFSET_1_MSB          0x08
+#define        DB_EEPROM_CHKSUM                0x1f
+
+#define        DB_EEPROM_CLEN                  0x20    // length of common portion of eeprom
+
+#define        DB_EEPROM_CUSTOM_BASE           DB_EEPROM_CLEN  // first avail offset for
+                                                       //   daughterboard specific use
+
+#endif /* INCLUDED_USRP_I2C_ADDR_H */
+
diff --git a/usrp/firmware/include/usrp_ids.h b/usrp/firmware/include/usrp_ids.h
new file mode 100644 (file)
index 0000000..65c4755
--- /dev/null
@@ -0,0 +1,53 @@
+/* -*- 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 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.
+ */
+
+/*
+ * USB Vendor and Product IDs that we use
+ *
+ * (keep in sync with usb_descriptors.a51)
+ */
+
+#ifndef _USRP_IDS_H_
+#define _USRP_IDS_H_
+
+#define        USB_VID_CYPRESS                 0x04b4
+#define        USB_PID_CYPRESS_FX2             0x8613
+
+
+#define        USB_VID_FSF                     0xfffe    // Free Software Folks
+#define        USB_PID_FSF_EXP_0               0x0000    // Experimental 0
+#define        USB_PID_FSF_EXP_1               0x0001    // Experimental 1
+#define        USB_PID_FSF_USRP                0x0002    // Universal Software Radio Peripheral
+#define        USB_PID_FSF_USRP_reserved       0x0003    // Universal Software Radio Peripheral
+#define        USB_PID_FSF_SSRP                0x0004    // Simple Software Radio Peripheral
+#define        USB_PID_FSF_SSRP_reserved       0x0005    // Simple Software Radio Peripheral
+#define USB_PID_FSF_HPSDR               0x0006    // High Performance Software Defined Radio (Internal Boot)
+#define USB_PID_FSF_HPSDR_HA           0x0007    // High Performance Software Defined Radio (Host Assisted Boot)
+
+#define USB_PID_FSF_LBNL_UXO            0x0018    // http://recycle.lbl.gov/~ldoolitt/uxo/
+
+
+#define        USB_DID_USRP_0                  0x0000    // unconfigured rev 0 USRP
+#define        USB_DID_USRP_1                  0x0001    // unconfigured rev 1 USRP
+#define        USB_DID_USRP_2                  0x0002    // unconfigured rev 2 USRP
+
+#endif /* _USRP_IDS_H_ */
diff --git a/usrp/firmware/include/usrp_interfaces.h b/usrp/firmware/include/usrp_interfaces.h
new file mode 100644 (file)
index 0000000..98432d1
--- /dev/null
@@ -0,0 +1,47 @@
+/* -*- 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 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.
+ */
+
+#ifndef _USRP_INTERFACES_H_
+#define _USRP_INTERFACES_H_
+
+/*
+ * We've now split the USRP into 3 separate interfaces.
+ *
+ * Interface 0 contains only ep0 and is used for command and status.
+ * Interface 1 is the Tx path and it uses ep2 OUT BULK.
+ * Interface 2 is the Rx path and it uses ep6 IN BULK.
+ */
+#define        USRP_CMD_INTERFACE              0
+#define        USRP_CMD_ALTINTERFACE           0
+#define        USRP_CMD_ENDPOINT               0
+
+#define        USRP_TX_INTERFACE               1
+#define        USRP_TX_ALTINTERFACE            0
+#define        USRP_TX_ENDPOINT                2       // streaming data from host to FPGA
+
+#define        USRP_RX_INTERFACE               2
+#define        USRP_RX_ALTINTERFACE            0
+#define        USRP_RX_ENDPOINT                6       // streaming data from FPGA to host
+
+
+#endif /* _USRP_INTERFACES_H_ */
diff --git a/usrp/firmware/include/usrp_spi_defs.h b/usrp/firmware/include/usrp_spi_defs.h
new file mode 100644 (file)
index 0000000..8404d7c
--- /dev/null
@@ -0,0 +1,86 @@
+/* -*- 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 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.
+ */
+
+#ifndef INCLUDED_USRP_SPI_DEFS_H
+#define INCLUDED_USRP_SPI_DEFS_H
+
+/*
+ * defines for the VRQ_SPI_READ and VRQ_SPI_WRITE commands
+ *
+ * SPI == "Serial Port Interface".  SPI is a 3 wire bus plus a
+ * separate enable for each peripheral.  The common lines are SCLK,
+ * SDI and SDO.  The FX2 always drives SCLK and SDI, the clock and
+ * data lines from the FX2 to the peripheral.  When enabled, a
+ * peripheral may drive SDO, the data line from the peripheral to the
+ * FX2.
+ *
+ * The SPI_READ and SPI_WRITE commands are formatted identically.
+ * Each specifies which peripherals to enable, whether the bits should
+ * be transmistted Most Significant Bit first or Least Significant Bit
+ * first, the number of bytes in the optional header, and the number
+ * of bytes to read or write in the body.
+ *
+ * The body is limited to 64 bytes.  The optional header may contain
+ * 0, 1 or 2 bytes.  For an SPI_WRITE, the header bytes are
+ * transmitted to the peripheral followed by the the body bytes.  For
+ * an SPI_READ, the header bytes are transmitted to the peripheral,
+ * then len bytes are read back from the peripheral.
+ */
+
+/*
+ * SPI_FMT_* goes in wIndexL
+ */
+#define SPI_FMT_xSB_MASK       (1 << 7)
+#  define      SPI_FMT_LSB     (1 << 7)        // least signficant bit first
+#  define      SPI_FMT_MSB     (0 << 7)        // most significant bit first
+#define        SPI_FMT_HDR_MASK        (3 << 5)
+#  define      SPI_FMT_HDR_0   (0 << 5)        // 0 header bytes
+#  define      SPI_FMT_HDR_1   (1 << 5)        // 1 header byte
+#  define      SPI_FMT_HDR_2   (2 << 5)        // 2 header bytes
+
+/*
+ * SPI_ENABLE_*  goes in wIndexH
+ *
+ * For the software interface, the enables are active high.
+ * For reads, it's an error to have more than one enable set.
+ *
+ * [FWIW, the hardware implements them as active low.  Don't change the
+ * definitions of these.  They are related to usrp_rev1_regs.h]
+ */
+#define        SPI_ENABLE_FPGA         0x01    // select FPGA
+#define        SPI_ENABLE_CODEC_A      0x02    // select AD9862 A
+#define        SPI_ENABLE_CODEC_B      0x04    // select AD9862 B
+#define        SPI_ENABLE_reserved     0x08
+#define        SPI_ENABLE_TX_A         0x10    // select d'board TX A
+#define        SPI_ENABLE_RX_A         0x20    // select d'board RX A
+#define        SPI_ENABLE_TX_B         0x40    // select d'board TX B
+#define        SPI_ENABLE_RX_B         0x80    // select d'board RX B
+
+/*
+ * If there's one header byte, it goes in wValueL.
+ *
+ * If there are two header bytes, they go in wValueH | wValueL.
+ * The transmit order of the bytes (and bits within them) is 
+ * determined by SPI_FMT_*SB
+ */
+#endif /* INCLUDED_USRP_SPI_DEFS_H */
diff --git a/usrp/firmware/lib/Makefile.am b/usrp/firmware/lib/Makefile.am
new file mode 100644 (file)
index 0000000..3ddafcf
--- /dev/null
@@ -0,0 +1,83 @@
+#
+# 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 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.
+# 
+
+EXTRA_DIST =           \
+       delay.c         \
+       fx2utils.c      \
+       i2c.c           \
+       isr.c           \
+       timer.c         \
+       usb_common.c
+
+
+
+DEFINES=
+INCLUDES=-I$(top_srcdir)/usrp/firmware/include
+
+# with EA = 0, the FX2 implements a portion of the 8051 "external memory"
+# on chip.  This memory is mapped like this:
+#
+# The bottom 8K of memory (0x0000 - 0x1fff) is used for both data and
+# code accesses.  There's also 512 bytes for data only from 0xe000 - 0xe1ff.
+#
+# We tell the linker to start the xdata segment at 0x1800, 6K up from
+# the bottom.
+
+LINKOPTS = --code-loc 0x0000 --code-size 0x1800 --xram-loc 0x1800 --xram-size 0x0800
+
+LIBRARY = libfx2.lib
+
+LIBOBJS =              \
+       delay.rel       \
+       fx2utils.rel    \
+       i2c.rel         \
+       isr.rel         \
+       timer.rel       \
+       usb_common.rel
+
+
+
+all: libfx2.lib
+
+%.rel : %.c
+       $(XCC) $(INCLUDES) $(DEFINES) -c $< -o $@
+
+%.rel : %.a51
+       $(XAS) $<
+
+
+$(LIBRARY): $(LIBOBJS)
+       -rm -f $(LIBRARY)
+       touch $(LIBRARY)
+       for obj in $(LIBOBJS); do basename $$obj .rel >> $(LIBRARY) ; done
+
+
+CLEANFILES = \
+       *.ihx *.lnk *.lst *.map *.mem *.rel *.rst *.sym *.asm *.lib
+
+DISTCLEANFILES = \
+       *.ihx *.lnk *.lst *.map *.mem *.rel *.rst *.sym *.asm *.lib
+
+install: all
+
+
+# dependencies
+
diff --git a/usrp/firmware/lib/delay.c b/usrp/firmware/lib/delay.c
new file mode 100644 (file)
index 0000000..c8bad7f
--- /dev/null
@@ -0,0 +1,76 @@
+/* -*- 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 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.
+ */
+
+/*
+ * Delay approximately 1 microsecond (including overhead in udelay).
+ */
+static void
+udelay1 (void) _naked
+{
+  _asm                         ; lcall that got us here took 4 bus cycles
+       ret                     ; 4 bus cycles
+  _endasm;
+}
+
+/*
+ * delay for approximately usecs microseconds
+ */
+void
+udelay (unsigned char usecs)
+{
+  do {
+    udelay1 ();
+  } while (--usecs != 0);
+}
+
+
+/*
+ * Delay approximately 1 millisecond.
+ * We're running at 48 MHz, so we need 48,000 clock cycles.
+ *
+ * Note however, that each bus cycle takes 4 clock cycles (not obvious,
+ * but explains the factor of 4 problem below).
+ */
+static void
+mdelay1 (void) _naked
+{
+  _asm
+       mov     dptr,#(-1200 & 0xffff)
+002$:  
+       inc     dptr            ; 3 bus cycles
+       mov     a, dpl          ; 2 bus cycles
+       orl     a, dph          ; 2 bus cycles
+       jnz     002$            ; 3 bus cycles
+
+       ret
+  _endasm;
+}
+
+void
+mdelay (unsigned int msecs)
+{
+  do {
+    mdelay1 ();
+  } while (--msecs != 0);
+}
+
+       
diff --git a/usrp/firmware/lib/fx2utils.c b/usrp/firmware/lib/fx2utils.c
new file mode 100644 (file)
index 0000000..544302e
--- /dev/null
@@ -0,0 +1,54 @@
+/* -*- 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 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.
+ */
+
+#include "fx2utils.h"
+#include "fx2regs.h"
+#include "delay.h"
+
+void
+fx2_stall_ep0 (void)
+{
+  EP0CS |= bmEPSTALL;
+}
+
+void
+fx2_reset_data_toggle (unsigned char ep)
+{
+  TOGCTL = ((ep & 0x80) >> 3 | (ep & 0x0f));
+  TOGCTL |= bmRESETTOGGLE;
+}
+
+void
+fx2_renumerate (void)
+{
+  USBCS |= bmDISCON | bmRENUM;
+
+  // mdelay (1500);            // FIXME why 1.5 seconds?
+  mdelay (250);                        // FIXME why 1.5 seconds?
+  
+  USBIRQ = 0xff;               // clear any pending USB irqs...
+  EPIRQ =  0xff;               //   they're from before the renumeration
+
+  EXIF &= ~bmEXIF_USBINT;
+
+  USBCS &= ~bmDISCON;          // reconnect USB
+}
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..ae97f1a
--- /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 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.
+ */
+
+#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/lib/i2c.c b/usrp/firmware/lib/i2c.c
new file mode 100644 (file)
index 0000000..08a09cf
--- /dev/null
@@ -0,0 +1,123 @@
+/* -*- 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 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.
+ */
+
+#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;
+  
+  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
+
+  while (--len != 0){
+    while ((I2CS & bmDONE) == 0)
+      ;
+
+    if (I2CS & bmBERR)
+      goto fail;
+
+    if (len == 1)
+      I2CS |= bmLASTRD;
+    
+    *buf++ = I2DAT;            // get data, trigger another read
+  }
+
+  // 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/lib/isr.c b/usrp/firmware/lib/isr.c
new file mode 100644 (file)
index 0000000..7a20107
--- /dev/null
@@ -0,0 +1,167 @@
+/* -*- 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 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.
+ */
+
+#include "isr.h"
+#include "fx2regs.h"
+#include "syncdelay.h"
+
+extern xdata unsigned char _standard_interrupt_vector[];
+extern xdata unsigned char _usb_autovector[];
+extern xdata unsigned char _fifo_gpif_autovector[];
+
+#define LJMP_OPCODE    0x02
+
+/*
+ * Hook standard interrupt vector.
+ *
+ * vector_number is from the SV_<foo> list.
+ * addr is the address of the interrupt service routine.
+ */
+void 
+hook_sv (unsigned char vector_number, unsigned short addr)
+{
+  bit  t;
+  
+  // sanity checks
+
+  if (vector_number < SV_MIN || vector_number > SV_MAX)
+    return;
+
+  if ((vector_number & 0x0f) != 0x03 && (vector_number & 0x0f) != 0x0b)
+    return;
+
+  t = EA;
+  EA = 0;
+  _standard_interrupt_vector[vector_number] = LJMP_OPCODE;
+  _standard_interrupt_vector[vector_number + 1] = addr >> 8;
+  _standard_interrupt_vector[vector_number + 2] = addr & 0xff;
+  EA = t;
+}
+
+/*
+ * Hook usb interrupt vector.
+ *
+ * vector_number is from the UV_<foo> list.
+ * addr is the address of the interrupt service routine.
+ */
+void 
+hook_uv (unsigned char vector_number, unsigned short addr)
+{
+  bit  t;
+  
+  // sanity checks
+
+  if (vector_number < UV_MIN || vector_number > UV_MAX)
+    return;
+
+  if ((vector_number & 0x3) != 0)
+    return;
+
+  t = EA;
+  EA = 0;
+  _usb_autovector[vector_number] = LJMP_OPCODE;
+  _usb_autovector[vector_number + 1] = addr >> 8;
+  _usb_autovector[vector_number + 2] = addr & 0xff;
+  EA = t;
+}
+
+/*
+ * Hook fifo/gpif interrupt vector.
+ *
+ * vector_number is from the FGV_<foo> list.
+ * addr is the address of the interrupt service routine.
+ */
+void 
+hook_fgv (unsigned char vector_number, unsigned short addr)
+{
+  bit  t;
+  
+  // sanity checks
+
+  if (vector_number < FGV_MIN || vector_number > FGV_MAX)
+    return;
+
+  if ((vector_number & 0x3) != 0)
+    return;
+
+  t = EA;
+  EA = 0;
+  _fifo_gpif_autovector[vector_number] = LJMP_OPCODE;
+  _fifo_gpif_autovector[vector_number + 1] = addr >> 8;
+  _fifo_gpif_autovector[vector_number + 2] = addr & 0xff;
+  EA = t;
+}
+
+/*
+ * One time call to enable autovectoring for both USB and FIFO/GPIF.
+ *
+ * This disables all USB and FIFO/GPIF interrupts and clears
+ * any pending interrupts too.  It leaves the master USB and FIFO/GPIF
+ * interrupts enabled.
+ */
+void
+setup_autovectors (void)
+{
+  // disable master usb and fifo/gpif interrupt enables
+  EIUSB = 0;
+  EIEX4 = 0;
+
+  hook_sv (SV_INT_2, (unsigned short) _usb_autovector);
+  hook_sv (SV_INT_4, (unsigned short) _fifo_gpif_autovector);
+
+  // disable all fifo interrupt enables
+  SYNCDELAY;
+  EP2FIFOIE = 0;       SYNCDELAY;
+  EP4FIFOIE = 0;       SYNCDELAY;
+  EP6FIFOIE = 0;       SYNCDELAY;
+  EP8FIFOIE = 0;       SYNCDELAY;
+
+  // clear all pending fifo irqs       
+  EP2FIFOIRQ = 0xff;   SYNCDELAY;
+  EP4FIFOIRQ = 0xff;   SYNCDELAY;
+  EP6FIFOIRQ = 0xff;   SYNCDELAY;
+  EP8FIFOIRQ = 0xff;   SYNCDELAY;
+
+  IBNIE  = 0;
+  IBNIRQ = 0xff;
+  NAKIE  = 0;
+  NAKIRQ = 0xff;
+  USBIE  = 0;
+  USBIRQ = 0xff;
+  EPIE   = 0;
+  EPIRQ  = 0xff;
+  SYNCDELAY;   GPIFIE = 0;             
+  SYNCDELAY;   GPIFIRQ = 0xff;
+  USBERRIE = 0;
+  USBERRIRQ = 0xff;
+  CLRERRCNT = 0;
+  
+  INTSETUP = bmAV2EN | bmAV4EN | bmINT4IN;
+
+  // clear master irq's for usb and fifo/gpif
+  EXIF &= ~bmEXIF_USBINT;
+  EXIF &= ~bmEXIF_IE4;
+  
+  // enable master usb and fifo/gpif interrrupts
+  EIUSB = 1;
+  EIEX4 = 1;
+}
diff --git a/usrp/firmware/lib/timer.c b/usrp/firmware/lib/timer.c
new file mode 100644 (file)
index 0000000..9e396f4
--- /dev/null
@@ -0,0 +1,49 @@
+/* -*- 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 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.
+ */
+
+#include "timer.h"
+#include "fx2regs.h"
+#include "isr.h"
+
+/*
+ * Arrange to have isr_tick_handler called at 100 Hz.
+ *
+ * The cpu clock is running at 48e6.  The input to the timer
+ * is 48e6 / 12 = 4e6.
+ *
+ * We arrange to have the timer overflow every 40000 clocks == 100 Hz
+ */
+
+#define        RELOAD_VALUE    ((unsigned short) -40000)
+
+void 
+hook_timer_tick (unsigned short isr_tick_handler)
+{
+  ET2 = 0;                     // disable timer 2 interrupts
+  hook_sv (SV_TIMER_2, isr_tick_handler);
+  
+  RCAP2H = RELOAD_VALUE >> 8;  // setup the auto reload value
+  RCAP2L = RELOAD_VALUE;
+
+  T2CON = 0x04;                        // interrupt on overflow; reload; run
+  ET2 = 1;                     // enable timer 2 interrupts
+}
diff --git a/usrp/firmware/lib/usb_common.c b/usrp/firmware/lib/usb_common.c
new file mode 100644 (file)
index 0000000..731fd68
--- /dev/null
@@ -0,0 +1,385 @@
+/* -*- 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 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.
+ */
+
+#include "usb_common.h"
+#include "fx2regs.h"
+#include "syncdelay.h"
+#include "fx2utils.h"
+#include "isr.h"
+#include "usb_descriptors.h"
+#include "usb_requests.h"
+
+extern xdata char str0[];
+extern xdata char str1[];
+extern xdata char str2[];
+extern xdata char str3[];
+extern xdata char str4[];
+extern xdata char str5[];
+
+
+#define        bRequestType    SETUPDAT[0]
+#define        bRequest        SETUPDAT[1]
+#define        wValueL         SETUPDAT[2]
+#define        wValueH         SETUPDAT[3]
+#define        wIndexL         SETUPDAT[4]
+#define        wIndexH         SETUPDAT[5]
+#define        wLengthL        SETUPDAT[6]
+#define        wLengthH        SETUPDAT[7]
+
+#define MSB(x) (((unsigned short) x) >> 8)
+#define LSB(x) (((unsigned short) x) & 0xff)
+
+volatile bit _usb_got_SUDAV;
+
+unsigned char  _usb_config = 0;
+unsigned char  _usb_alt_setting = 0;   // FIXME really 1/interface
+
+xdata unsigned char *current_device_descr;
+xdata unsigned char *current_devqual_descr;
+xdata unsigned char *current_config_descr;
+xdata unsigned char *other_config_descr;
+
+static void
+setup_descriptors (void)
+{
+  if (USBCS & bmHSM){          // high speed mode
+    current_device_descr  = high_speed_device_descr;
+    current_devqual_descr = high_speed_devqual_descr;
+    current_config_descr  = high_speed_config_descr;
+    other_config_descr    = full_speed_config_descr;
+  }
+  else {
+    current_device_descr  = full_speed_device_descr;
+    current_devqual_descr = full_speed_devqual_descr;
+    current_config_descr  = full_speed_config_descr;
+    other_config_descr    = high_speed_config_descr;
+  }
+
+  // whack the type fields
+  // FIXME, may not be required.
+  // current_config_descr[1] = DT_CONFIG;
+  // other_config_descr[1]   = DT_OTHER_SPEED;
+}
+
+static void
+isr_SUDAV (void) interrupt
+{
+  clear_usb_irq ();
+  _usb_got_SUDAV = 1;
+}
+
+static void
+isr_USBRESET (void) interrupt
+{
+  clear_usb_irq ();
+  setup_descriptors ();
+}
+
+static void
+isr_HIGHSPEED (void) interrupt
+{
+  clear_usb_irq ();
+  setup_descriptors ();
+}
+
+void
+usb_install_handlers (void)
+{
+  setup_descriptors ();            // ensure that they're set before use
+
+  hook_uv (UV_SUDAV,     (unsigned short) isr_SUDAV);
+  hook_uv (UV_USBRESET,  (unsigned short) isr_USBRESET);
+  hook_uv (UV_HIGHSPEED, (unsigned short) isr_HIGHSPEED);
+
+  USBIE = bmSUDAV | bmURES | bmHSGRANT;
+}
+
+// On the FX2 the only plausible endpoints are 0, 1, 2, 4, 6, 8
+// This doesn't check to see that they're enabled
+
+unsigned char
+plausible_endpoint (unsigned char ep)
+{
+  ep &= ~0x80; // ignore direction bit
+
+  if (ep > 8)
+    return 0;
+
+  if (ep == 1)
+    return 1;
+
+  return (ep & 0x1) == 0;      // must be even
+}
+
+// return pointer to control and status register for endpoint.
+// only called with plausible_endpoints
+
+xdata volatile unsigned char *
+epcs (unsigned char ep)
+{
+  if (ep == 0x01)              // ep1 has different in and out CS regs
+    return EP1OUTCS;
+
+  if (ep == 0x81)
+    return EP1INCS;
+
+  ep &= ~0x80;                 // ignore direction bit
+
+  if (ep == 0x00)              // ep0
+    return EP0CS;
+
+  return EP2CS + (ep >> 1);    // 2, 4, 6, 8 are consecutive
+}
+
+void
+usb_handle_setup_packet (void)
+{
+  _usb_got_SUDAV = 0;
+
+  // handle the standard requests...
+
+  switch (bRequestType & bmRT_TYPE_MASK){
+
+  case bmRT_TYPE_CLASS:
+  case bmRT_TYPE_RESERVED:
+    fx2_stall_ep0 ();          // we don't handle these.  indicate error
+    break;
+    
+  case bmRT_TYPE_VENDOR:
+    // call the application code.
+    // If it handles the command it returns non-zero
+
+    if (!app_vendor_cmd ())    
+      fx2_stall_ep0 ();
+    break;
+
+  case bmRT_TYPE_STD:
+    // these are the standard requests...
+
+    if ((bRequestType & bmRT_DIR_MASK) == bmRT_DIR_IN){
+
+      ////////////////////////////////////
+      //    handle the IN requests
+      ////////////////////////////////////
+
+      switch (bRequest){
+
+      case RQ_GET_CONFIG:
+       EP0BUF[0] = _usb_config;        // FIXME app should handle
+       EP0BCH = 0;
+       EP0BCL = 1;
+       break;
+       
+      // --------------------------------
+
+      case RQ_GET_INTERFACE:
+       EP0BUF[0] = _usb_alt_setting;   // FIXME app should handle
+       EP0BCH = 0;
+       EP0BCL = 1;
+       break;
+
+      // --------------------------------
+
+      case RQ_GET_DESCR:
+       switch (wValueH){
+
+       case DT_DEVICE:
+         SUDPTRH = MSB (current_device_descr);
+         SUDPTRL = LSB (current_device_descr);
+         break;
+         
+       case DT_DEVQUAL:
+         SUDPTRH = MSB (current_devqual_descr);
+         SUDPTRL = LSB (current_devqual_descr);
+         break;
+
+       case DT_CONFIG:
+         if (0 && wValueL != 1)        // FIXME only a single configuration
+           fx2_stall_ep0 ();
+         else {
+           SUDPTRH = MSB (current_config_descr);
+           SUDPTRL = LSB (current_config_descr);
+         }
+         break;
+
+       case DT_OTHER_SPEED:
+         if (0 && wValueL != 1)        // FIXME only a single configuration
+           fx2_stall_ep0 ();
+         else {
+           SUDPTRH = MSB (other_config_descr);
+           SUDPTRL = LSB (other_config_descr);
+         }
+         break;
+
+       case DT_STRING:
+         if (wValueL >= nstring_descriptors)
+           fx2_stall_ep0 ();
+         else {
+           xdata char *p = string_descriptors[wValueL];
+           SUDPTRH = MSB (p);
+           SUDPTRL = LSB (p);
+         }
+         break;
+
+       default:
+         fx2_stall_ep0 ();     // invalid request
+         break;
+       }
+       break;
+       
+      // --------------------------------
+
+      case RQ_GET_STATUS:
+       switch (bRequestType & bmRT_RECIP_MASK){
+       case bmRT_RECIP_DEVICE:
+         EP0BUF[0] = bmGSDA_SELF_POWERED;      // FIXME app should handle
+         EP0BUF[1] = 0;
+         EP0BCH = 0;
+         EP0BCL = 2;
+         break;
+
+       case bmRT_RECIP_INTERFACE:
+         EP0BUF[0] = 0;
+         EP0BUF[1] = 0;
+         EP0BCH = 0;
+         EP0BCL = 2;
+         break;
+
+       case bmRT_RECIP_ENDPOINT:
+         if (plausible_endpoint (wIndexL)){
+           EP0BUF[0] = *epcs (wIndexL) & bmEPSTALL;
+           EP0BUF[1] = 0;
+           EP0BCH = 0;
+           EP0BCL = 2;
+         }
+         else
+           fx2_stall_ep0 ();
+         break;
+
+       default:
+         fx2_stall_ep0 ();
+         break;
+       }
+
+      // --------------------------------
+
+      case RQ_SYNCH_FRAME:     // not implemented
+      default:
+       fx2_stall_ep0 ();
+       break;
+      }
+    }
+
+    else {
+
+      ////////////////////////////////////
+      //    handle the OUT requests
+      ////////////////////////////////////
+
+      switch (bRequest){
+
+      case RQ_SET_CONFIG:
+       _usb_config = wValueL;          // FIXME app should handle
+       break;
+
+      case RQ_SET_INTERFACE:
+       _usb_alt_setting = wValueL;     // FIXME app should handle
+       break;
+
+      // --------------------------------
+
+      case RQ_CLEAR_FEATURE:
+       switch (bRequestType & bmRT_RECIP_MASK){
+
+       case bmRT_RECIP_DEVICE:
+         switch (wValueL){
+         case FS_DEV_REMOTE_WAKEUP:
+         default:
+           fx2_stall_ep0 ();
+         }
+         break;
+
+       case bmRT_RECIP_ENDPOINT:
+         if (wValueL == FS_ENDPOINT_HALT && plausible_endpoint (wIndexL)){
+           *epcs (wIndexL) &= ~bmEPSTALL;
+           fx2_reset_data_toggle (wIndexL);
+         }
+         else
+           fx2_stall_ep0 ();
+         break;
+
+       default:
+         fx2_stall_ep0 ();
+         break;
+       }
+       break;
+
+      // --------------------------------
+
+      case RQ_SET_FEATURE:
+       switch (bRequestType & bmRT_RECIP_MASK){
+
+       case bmRT_RECIP_DEVICE:
+         switch (wValueL){
+         case FS_TEST_MODE:
+           // hardware handles this after we complete SETUP phase handshake
+           break;
+
+         case FS_DEV_REMOTE_WAKEUP:
+         default:
+           fx2_stall_ep0 ();
+           break;
+         }
+       }
+       break;
+
+      case bmRT_RECIP_ENDPOINT:
+       switch (wValueL){
+       case FS_ENDPOINT_HALT:
+         if (plausible_endpoint (wIndexL))
+           *epcs (wIndexL) |= bmEPSTALL;
+         else
+           fx2_stall_ep0 ();
+         break;
+
+       default:
+         fx2_stall_ep0 ();
+         break;
+       }
+       break;
+
+      // --------------------------------
+
+      case RQ_SET_ADDRESS:     // handled by fx2 hardware
+      case RQ_SET_DESCR:       // not implemented
+      default:
+       fx2_stall_ep0 ();
+      }
+
+    }
+    break;
+
+  }    // bmRT_TYPE_MASK
+
+  // ack handshake phase of device request
+  EP0CS |= bmHSNAK;
+}
diff --git a/usrp/firmware/src/Makefile.am b/usrp/firmware/src/Makefile.am
new file mode 100644 (file)
index 0000000..e480137
--- /dev/null
@@ -0,0 +1,22 @@
+#
+# 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.
+# 
+
+SUBDIRS = common usrp2
diff --git a/usrp/firmware/src/common/Makefile.am b/usrp/firmware/src/common/Makefile.am
new file mode 100644 (file)
index 0000000..ba3c0e4
--- /dev/null
@@ -0,0 +1,50 @@
+#
+# 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.
+# 
+
+EXTRA_DIST =                   \
+       _startup.a51            \
+       blink_leds.c            \
+       check_mdelay.c          \
+       check_udelay.c          \
+       edit-gpif               \
+       fpga.h                  \
+       fpga_load.h             \
+       fpga_load.c             \
+       gpif.c                  \
+       gpif.gpf                \
+       init_gpif.c             \
+       usrp_common.c           \
+       usrp_globals.h          \
+       vectors.a51             \
+       build_eeprom.py         
+
+all: usrp_gpif.c
+
+usrp_gpif.c usrp_gpif_inline.h : gpif.c
+       srcdir=$(srcdir) $(srcdir)/edit-gpif $(srcdir)/gpif.c usrp_gpif.c usrp_gpif_inline.h
+
+CLEANFILES = \
+       *.ihx *.lnk *.lst *.map *.mem *.rel *.rst *.sym *.asm *.lib \
+       usrp_gpif.c usrp_gpif_inline.h
+
+DISTCLEANFILES = \
+       *.ihx *.lnk *.lst *.map *.mem *.rel *.rst *.sym *.asm *.lib \
+       usrp_gpif.c usrp_gpif_inline.h 
diff --git a/usrp/firmware/src/common/_startup.a51 b/usrp/firmware/src/common/_startup.a51
new file mode 100644 (file)
index 0000000..0bffbbe
--- /dev/null
@@ -0,0 +1,80 @@
+;;; -*- asm -*-
+;;;
+;;; Copyright 2003,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.
+
+    
+;;; 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
+
+       
+       .area CSEG    (CODE)
+
+       ;; sfr that sets upper address byte of MOVX using @r0 or @r1
+       _MPAGE  =       0x0092
+
+__sdcc_external_startup::
+       ;; This system is now compiled with the --no-xinit-opt 
+       ;; which means that any initialized XDATA is handled
+       ;; inline by code in the GSINIT segs emitted for each file.
+       ;; 
+       ;; We zero XSEG and all of the internal ram to ensure 
+       ;; a known good state for uninitialized variables.
+
+;      _mcs51_genRAMCLEAR() start
+       mov     r0,#l_XSEG
+       mov     a,r0
+       orl     a,#(l_XSEG >> 8)
+       jz      00002$
+       mov     r1,#((l_XSEG + 255) >> 8)
+       mov     dptr,#s_XSEG
+       clr     a
+       
+00001$:        movx    @dptr,a
+       inc     dptr
+       djnz    r0,00001$
+       djnz    r1,00001$
+       
+       ;; We're about to clear internal memory.  This will overwrite
+       ;; the stack which contains our return address.
+       ;; Pop our return address into DPH, DPL
+00002$:        pop     dph
+       pop     dpl
+       
+       ;; R0 and A contain 0.  This loop will execute 256 times.
+       ;; 
+       ;; FWIW the first iteration writes direct address 0x00,
+       ;; which is the location of r0.  We get lucky, we're 
+       ;; writing the correct value (0)
+       
+00003$:        mov     @r0,a
+       djnz    r0,00003$
+
+       push    dpl             ; restore our return address
+       push    dph
+
+       mov     dpl,#0          ; indicate that data init is still required
+       ret
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..1238f3d
--- /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 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.
+
+    
+;;; 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
diff --git a/usrp/firmware/src/common/blink_leds.c b/usrp/firmware/src/common/blink_leds.c
new file mode 100644 (file)
index 0000000..4654e73
--- /dev/null
@@ -0,0 +1,36 @@
+/* 
+ * USRP - Universal Software Radio Peripheral
+ *
+ * Copyright (C) 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 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
+ */
+
+#include "usrp_common.h"
+
+void
+main (void)
+{
+  unsigned short       counter = 0;
+
+  init_usrp ();
+
+  while (1){
+    unsigned char counter_high = counter >> 8;
+    set_led_0 (counter_high & 0x40);
+    set_led_1 (counter_high & 0x80);
+    counter++;
+  }
+}
diff --git a/usrp/firmware/src/common/build_eeprom.py b/usrp/firmware/src/common/build_eeprom.py
new file mode 100755 (executable)
index 0000000..6612059
--- /dev/null
@@ -0,0 +1,182 @@
+#!/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 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.
+# 
+
+import re
+import sys
+import os, os.path
+from optparse import OptionParser
+
+# USB Vendor and Product ID's
+
+VID = 0xfffe                            # Free Software Folks
+PID = 0x0002                            # Universal Software Radio Peripheral
+
+
+def hex_to_bytes (s):
+    if len (s) & 0x1:
+        raise ValueError, "Length must be even"
+    r = []
+    for i in range (0, len(s), 2):
+        r.append (int (s[i:i+2], 16))
+    return r
+    
+def msb (x):
+    return (x >> 8) & 0xff
+
+def lsb (x):
+    return x & 0xff
+
+class ihx_rec (object):
+    def __init__ (self, addr, type, data):
+        self.addr = addr
+        self.type = type
+        self.data = data
+
+class ihx_file (object):
+    def __init__ (self):
+        self.pat = re.compile (r':[0-9A-F]{10,}')
+    def read (self, file):
+        r = []
+        for line in file:
+            line = line.strip().upper ()
+            if not self.pat.match (line):
+                raise ValueError, "Invalid hex record format"
+            bytes = hex_to_bytes (line[1:])
+            sum = reduce (lambda x, y: x + y, bytes, 0) % 256
+            if sum != 0:
+                raise ValueError, "Bad hex checksum"
+            lenx = bytes[0]
+            addr = (bytes[1] << 8) + bytes[2]
+            type = bytes[3]
+            data = bytes[4:-1]
+            if lenx != len (data):
+                raise ValueError, "Invalid hex record (bad length)"
+            if type != 0:
+                break;
+            r.append (ihx_rec (addr, type, data))
+
+        return r
+
+def get_code (filename):
+    """Read the intel hex format file FILENAME and return a tuple
+    of the code starting address and a list of bytes to load there.
+    """
+    f = open (filename, 'r')
+    ifx = ihx_file ()
+    r = ifx.read (f)
+    r.sort (lambda a,b: a.addr - b.addr)
+    code_start = r[0].addr
+    code_end = r[-1].addr + len (r[-1].data)
+    code_len = code_end - code_start
+    code = [0] * code_len
+    for x in r:
+        a = x.addr
+        l = len (x.data)
+        code[a-code_start:a-code_start+l] = x.data
+    return (code_start, code)
+        
+
+def build_eeprom_image (filename, rev):
+    """Build a ``C2 Load'' EEPROM image.
+
+    For details on this format, see section 3.4.3 of
+    the EZ-USB FX2 Technical Reference Manual
+    """
+    # get the code we want to run
+    (start_addr, bytes) = get_code (filename)
+
+    devid = rev
+
+    rom_header = [
+        0xC2,                           # boot from EEPROM
+        lsb (VID),
+        msb (VID),
+        lsb (PID),
+        msb (PID),
+        lsb (devid),
+        msb (devid),
+        0                               # configuration byte
+        ]
+    
+    # 4 byte header that indicates where to load
+    # the immediately follow code bytes.
+    code_header = [
+        msb (len (bytes)),
+        lsb (len (bytes)),
+        msb (start_addr),
+        lsb (start_addr)
+        ]
+
+    # writes 0 to CPUCS reg (brings FX2 out of reset)
+    trailer = [
+        0x80,
+        0x01,
+        0xe6,
+        0x00,
+        0x00
+        ]
+
+    image = rom_header + code_header + bytes + trailer
+
+    assert (len (image) <= 256)
+    return image
+
+def build_shell_script (out, ihx_filename, rev):
+
+    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')
+    
+    # print "len(image) =", len(image)
+    
+    i2c_addr = 0x50
+    rom_addr = 0x00
+
+    hex_image = map (lambda x : "%02x" % (x,), image)
+
+    while (len (hex_image) > 0):
+        l = min (len (hex_image), 16)
+        out.write ('usrper i2c_write 0x%02x %02x%s\n' %
+                   (i2c_addr, rom_addr, ''.join (hex_image[0:l])))
+        hex_image = hex_image[l:]
+        rom_addr = rom_addr + l
+        out.write ('sleep 1\n')
+
+if __name__ == '__main__':
+    usage = "usage: %prog -r REV [options] bootfile.ihx"
+    parser = OptionParser (usage=usage)
+    parser.add_option ("-r", "--rev", type="int", default=-1,
+                       help="Specify USRP revision number REV (2 or 4)")
+    (options, args) = parser.parse_args ()
+    if len (args) != 1:
+        parser.print_help ()
+        sys.exit (1)
+    if options.rev < 0:
+        sys.stderr.write (
+            "You must specify the USRP revision number (2 or 4) with -r REV\n")
+        sys.exit (1)
+
+    ihx_filename = args[0]
+
+    build_shell_script (sys.stdout, ihx_filename, options.rev)
diff --git a/usrp/firmware/src/common/check_mdelay.c b/usrp/firmware/src/common/check_mdelay.c
new file mode 100644 (file)
index 0000000..8cdadab
--- /dev/null
@@ -0,0 +1,37 @@
+/* 
+ * USRP - Universal Software Radio Peripheral
+ *
+ * Copyright (C) 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 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
+ */
+
+#include "usrp_common.h"
+#include "delay.h"
+
+void
+main (void)
+{
+  init_usrp ();
+
+  // CPUCS = 0;                // 12 MHz
+  // CPUCS = bmCLKSPD0;        // 24 MHz
+  CPUCS = bmCLKSPD1;   // 48 MHz
+  
+  while (1){
+    USRP_LED_REG ^= bmLED0;
+    mdelay (10);
+  }
+}
diff --git a/usrp/firmware/src/common/check_udelay.c b/usrp/firmware/src/common/check_udelay.c
new file mode 100644 (file)
index 0000000..6e1c840
--- /dev/null
@@ -0,0 +1,37 @@
+/* 
+ * USRP - Universal Software Radio Peripheral
+ *
+ * Copyright (C) 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 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
+ */
+
+#include "usrp_common.h"
+#include "delay.h"
+
+void
+main (void)
+{
+  init_usrp ();
+
+  // CPUCS = 0;                // 12 MHz
+  // CPUCS = bmCLKSPD0;        // 24 MHz
+  CPUCS = bmCLKSPD1;   // 48 MHz
+  
+  while (1){
+    USRP_LED_REG ^= bmLED0;
+    udelay (250);
+  }
+}
diff --git a/usrp/firmware/src/common/edit-gpif b/usrp/firmware/src/common/edit-gpif
new file mode 100755 (executable)
index 0000000..c507f50
--- /dev/null
@@ -0,0 +1,114 @@
+#!/usr/bin/env python
+# -*- 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 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.
+# 
+
+
+# Edit the gpif.c file generated by the Cypress GPIF Designer Tool and
+# produce usrp_gpif.c, and usrp_gpif_inline.h, files suitable for our
+# uses.
+
+import re
+import string
+import sys
+
+def check_flow_state (line, flow_state_dict):
+    mo = re.match (r'/\* Wave (\d) FlowStates \*/ (.*),', line)
+    if mo:
+        wave = int (mo.group (1))
+        data = mo.group (2)
+        split = data.split (',', 8)
+        v = map (lambda x : int (x, 16), split)
+        # print "%s, %s" % (wave, data)
+        # print "split: ", split
+        # print "v    : ", v
+        flow_state_dict[wave] = v
+
+
+def delta (xseq, yseq):
+    # set subtraction
+    z = []
+    for x in xseq:
+        if x not in yseq:
+            z.append (x)
+    return z
+    
+
+def write_define (output, name, pairs):
+    output.write ('#define %s()\t\\\n' % name)
+    output.write ('do {\t\t\t\t\t\\\n')
+    for reg, val in pairs:
+        output.write ('%14s = 0x%02x;\t\t\t\\\n' % (reg, val))
+    output.write ('} while (0)\n\n')
+    
+def write_inlines (output, dict):
+    regs = ['FLOWSTATE', 'FLOWLOGIC', 'FLOWEQ0CTL', 'FLOWEQ1CTL', 'FLOWHOLDOFF',
+            'FLOWSTB', 'FLOWSTBEDGE', 'FLOWSTBHPERIOD', 'GPIFHOLDAMOUNT']
+
+    READ_FLOW_STATE = 2
+    WRITE_FLOW_STATE = 3
+
+    read_info = zip (regs, dict[READ_FLOW_STATE])
+    write_info = zip (regs, dict[WRITE_FLOW_STATE])
+    
+    output.write ('''/*
+ * Machine generated by "edit-gpif".  Do not edit by hand.
+ */
+
+''')
+    write_define (output, 'setup_flowstate_common', read_info)
+    write_define (output, 'setup_flowstate_read', delta (read_info, write_info))
+    write_define (output, 'setup_flowstate_write', delta (write_info, read_info))
+    
+
+def edit_gpif (input_name, output_name, inline_name):
+    input = open (input_name, 'r')
+    output = open (output_name, 'w')
+    inline = open (inline_name, 'w')
+    flow_state_dict = {}
+
+    output.write ('''/*
+ * Machine generated by "edit-gpif".  Do not edit by hand.
+ */
+
+''')
+    
+    while 1:
+        line = input.readline ()
+        line = string.replace (line, '\r','')
+        line = re.sub (r' *$', r'', line)
+
+        check_flow_state (line, flow_state_dict)
+
+        line = re.sub (r'#include', r'// #include', line)
+        line = re.sub (r'xdata ', r'', line)
+        if re.search (r'GpifInit', line):
+            break
+        
+        output.write (line)
+
+    output.close ()
+    write_inlines (inline, flow_state_dict)
+    inline.close ()
+
+
+# gpif.c usrp_gpif.c usrp_gpif_inline.h
+edit_gpif (sys.argv[1], sys.argv[2], sys.argv[3])
diff --git a/usrp/firmware/src/common/fpga.h b/usrp/firmware/src/common/fpga.h
new file mode 100644 (file)
index 0000000..d95db33
--- /dev/null
@@ -0,0 +1,31 @@
+/* -*- 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 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.
+ */
+#ifndef INCLUDED_FPGA_H
+#define INCLUDED_FPGA_H
+
+#include "fpga_load.h"
+
+#if defined(HAVE_USRP2)
+#include "fpga_rev2.h"
+#endif
+
+#endif /* INCLUDED_FPGA_H */
diff --git a/usrp/firmware/src/common/fpga_load.c b/usrp/firmware/src/common/fpga_load.c
new file mode 100644 (file)
index 0000000..1c2792d
--- /dev/null
@@ -0,0 +1,193 @@
+/* 
+ * USRP - Universal Software Radio Peripheral
+ *
+ * Copyright (C) 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 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
+ */
+
+#include "usrp_common.h"
+#include "fpga_load.h"
+#include "delay.h"
+
+/*
+ * setup altera FPGA serial load (PS).
+ *
+ * On entry:
+ *     don't care
+ *
+ * On exit:
+ *     ALTERA_DCLK    = 0
+ *     ALTERA_NCONFIG = 1
+ *     ALTERA_NSTATUS = 1 (input)
+ */
+unsigned char
+fpga_load_begin (void)
+{
+  USRP_ALTERA_CONFIG &= ~bmALTERA_BITS;                // clear all bits (NCONFIG low)
+  udelay (40);                                 // wait 40 us
+  USRP_ALTERA_CONFIG |= bmALTERA_NCONFIG;      // set NCONFIG high
+
+  if (UC_BOARD_HAS_FPGA){
+    // FIXME should really cap this loop with a counter so we
+    //   don't hang forever on a hardware failure.
+    while ((USRP_ALTERA_CONFIG & bmALTERA_NSTATUS) == 0) // wait for NSTATUS to go high
+      ;
+  }
+
+  // ready to xfer now
+
+  return 1;
+}
+
+/*
+ * clock out the low bit of bits.
+ *
+ * On entry:
+ *     ALTERA_DCLK    = 0
+ *     ALTERA_NCONFIG = 1
+ *     ALTERA_NSTATUS = 1 (input)
+ *
+ * On exit:
+ *     ALTERA_DCLK    = 0
+ *     ALTERA_NCONFIG = 1
+ *     ALTERA_NSTATUS = 1 (input)
+ */
+
+
+#if 0
+
+static void
+clock_out_config_byte (unsigned char bits)
+{
+  unsigned char i;
+
+  // clock out configuration byte, least significant bit first
+
+  for (i = 0; i < 8; i++){
+
+    USRP_ALTERA_CONFIG = ((USRP_ALTERA_CONFIG & ~bmALTERA_DATA0) | ((bits & 1) ? bmALTERA_DATA0 : 0));
+    USRP_ALTERA_CONFIG |= bmALTERA_DCLK;               /* set DCLK to 1 */
+    USRP_ALTERA_CONFIG &= ~bmALTERA_DCLK;              /* set DCLK to 0 */
+
+    bits = bits >> 1;
+  }
+}
+       
+#else
+
+static void 
+clock_out_config_byte (unsigned char bits) _naked
+{
+    _asm
+       mov     a, dpl
+       
+       rrc     a
+       mov     _bitALTERA_DATA0,c
+       setb    _bitALTERA_DCLK
+       clr     _bitALTERA_DCLK
+       
+       rrc     a
+       mov     _bitALTERA_DATA0,c
+       setb    _bitALTERA_DCLK
+       clr     _bitALTERA_DCLK
+       
+       rrc     a
+       mov     _bitALTERA_DATA0,c
+       setb    _bitALTERA_DCLK
+       clr     _bitALTERA_DCLK
+       
+       rrc     a
+       mov     _bitALTERA_DATA0,c
+       setb    _bitALTERA_DCLK
+       clr     _bitALTERA_DCLK
+       
+       rrc     a
+       mov     _bitALTERA_DATA0,c
+       setb    _bitALTERA_DCLK
+       clr     _bitALTERA_DCLK
+       
+       rrc     a
+       mov     _bitALTERA_DATA0,c
+       setb    _bitALTERA_DCLK
+       clr     _bitALTERA_DCLK
+       
+       rrc     a
+       mov     _bitALTERA_DATA0,c
+       setb    _bitALTERA_DCLK
+       clr     _bitALTERA_DCLK
+       
+       rrc     a
+       mov     _bitALTERA_DATA0,c
+       setb    _bitALTERA_DCLK
+       clr     _bitALTERA_DCLK
+       
+       ret     
+
+    _endasm;
+}
+
+#endif
+
+static void
+clock_out_bytes (unsigned char bytecount,
+                unsigned char xdata *p)
+{
+  while (bytecount-- > 0)
+    clock_out_config_byte (*p++);
+}
+
+/*
+ * Transfer block of bytes from packet to FPGA serial configuration port
+ *
+ * On entry:
+ *     ALTERA_DCLK    = 0
+ *     ALTERA_NCONFIG = 1
+ *     ALTERA_NSTATUS = 1 (input)
+ *
+ * On exit:
+ *     ALTERA_DCLK    = 0
+ *     ALTERA_NCONFIG = 1
+ *     ALTERA_NSTATUS = 1 (input)
+ */
+unsigned char
+fpga_load_xfer (xdata unsigned char *p, unsigned char bytecount)
+{
+  clock_out_bytes (bytecount, p);
+  return 1;
+}
+
+/*
+ * check for successful load...
+ */
+unsigned char
+fpga_load_end (void)
+{
+  unsigned char status = USRP_ALTERA_CONFIG;
+
+  if (!UC_BOARD_HAS_FPGA)                      // always true if we don't have FPGA
+    return 1;
+
+  if ((status & bmALTERA_NSTATUS) == 0)                // failed to program
+    return 0;
+
+  if ((status & bmALTERA_CONF_DONE) == bmALTERA_CONF_DONE)
+    return 1;                                  // everything's cool
+
+  // I don't think this should happen.  It indicates that
+  // programming is still in progress.
+
+  return 0;
+}
diff --git a/usrp/firmware/src/common/fpga_load.h b/usrp/firmware/src/common/fpga_load.h
new file mode 100644 (file)
index 0000000..baf22de
--- /dev/null
@@ -0,0 +1,28 @@
+/* 
+ * USRP - Universal Software Radio Peripheral
+ *
+ * Copyright (C) 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 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
+ */
+
+#ifndef INCLUDED_FPGA_LOAD_H
+#define INCLUDED_FPGA_LOAD_H
+
+unsigned char fpga_load_begin (void);
+unsigned char fpga_load_xfer (xdata unsigned char *p, unsigned char len);
+unsigned char fpga_load_end (void);
+
+#endif /* INCLUDED_FPGA_LOAD_H */
diff --git a/usrp/firmware/src/common/gpif.c b/usrp/firmware/src/common/gpif.c
new file mode 100755 (executable)
index 0000000..489e6e8
--- /dev/null
@@ -0,0 +1,292 @@
+// This program configures the General Programmable Interface (GPIF) for FX2.     
+// Please do not modify sections of text which are marked as "DO NOT EDIT ...". 
+//                                                                                
+// DO NOT EDIT ...                  
+// GPIF Initialization              
+// Interface Timing      Async        
+// Internal Ready Init   IntRdy=1     
+// CTL Out Tristate-able Binary       
+// SingleWrite WF Select     1     
+// SingleRead WF Select      0     
+// FifoWrite WF Select       3     
+// FifoRead WF Select        2     
+// Data Bus Idle Drive   Tristate     
+// END DO NOT EDIT                  
+                                    
+// DO NOT EDIT ...       
+// GPIF Wave Names       
+// Wave 0   = singlerd     
+// Wave 1   = singlewr     
+// Wave 2   = FIFORd       
+// Wave 3   = FIFOWr       
+                         
+// GPIF Ctrl Outputs   Level   
+// CTL 0    = WEN#     CMOS        
+// CTL 1    = REN#     CMOS        
+// CTL 2    = OE#      CMOS        
+// CTL 3    = CLRST    CMOS        
+// CTL 4    = unused   CMOS        
+// CTL 5    = BOGUS    CMOS        
+                               
+// GPIF Rdy Inputs         
+// RDY0     = EF#            
+// RDY1     = FF#            
+// RDY2     = unused         
+// RDY3     = unused         
+// RDY4     = unused         
+// RDY5     = TCXpire        
+// FIFOFlag = FIFOFlag       
+// IntReady = IntReady       
+// END DO NOT EDIT         
+// DO NOT EDIT ...                                                                         
+//                                                                                         
+// GPIF Waveform 0: singlerd                                                                
+//                                                                                         
+// Interval     0         1         2         3         4         5         6     Idle (7) 
+//          _________ _________ _________ _________ _________ _________ _________ _________
+//                                                                                         
+// AddrMode Same Val  Same Val  Same Val  Same Val  Same Val  Same Val  Same Val           
+// DataMode NO Data   NO Data   NO Data   NO Data   NO Data   NO Data   NO Data            
+// NextData SameData  SameData  SameData  SameData  SameData  SameData  SameData           
+// Int Trig No Int    No Int    No Int    No Int    No Int    No Int    No Int             
+// IF/Wait  Wait 1    Wait 1    Wait 1    Wait 1    Wait 1    Wait 1    Wait 1             
+//   Term A                                                                                
+//   LFunc                                                                                 
+//   Term B                                                                                
+// Branch1                                                                                 
+// Branch0                                                                                 
+// Re-Exec                                                                                 
+// Sngl/CRC Default   Default   Default   Default   Default   Default   Default            
+// WEN#         0         0         0         0         0         0         0         0    
+// REN#         0         0         0         0         0         0         0         0    
+// OE#          0         0         0         0         0         0         0         0    
+// CLRST        0         0         0         0         0         0         0         0    
+// unused       0         0         0         0         0         0         0         0    
+// BOGUS        0         0         0         0         0         0         0         0    
+//                     
+// END DO NOT EDIT     
+// DO NOT EDIT ...                                                                         
+//                                                                                         
+// GPIF Waveform 1: singlewr                                                                
+//                                                                                         
+// Interval     0         1         2         3         4         5         6     Idle (7) 
+//          _________ _________ _________ _________ _________ _________ _________ _________
+//                                                                                         
+// AddrMode Same Val  Same Val  Same Val  Same Val  Same Val  Same Val  Same Val           
+// DataMode Activate  Activate  Activate  Activate  Activate  Activate  Activate           
+// NextData SameData  SameData  SameData  SameData  SameData  SameData  SameData           
+// Int Trig No Int    No Int    No Int    No Int    No Int    No Int    No Int             
+// IF/Wait  Wait 1    IF        Wait 1    Wait 1    Wait 1    Wait 1    Wait 1             
+//   Term A           EF#                                                                  
+//   LFunc            AND                                                                  
+//   Term B           EF#                                                                  
+// Branch1            ThenIdle                                                             
+// Branch0            ElseIdle                                                             
+// Re-Exec            No                                                                   
+// Sngl/CRC Default   Default   Default   Default   Default   Default   Default            
+// WEN#         0         1         1         1         1         1         1         0    
+// REN#         0         0         0         0         0         0         0         0    
+// OE#          0         0         0         0         0         0         0         0    
+// CLRST        0         0         0         0         0         0         0         0    
+// unused       0         0         0         0         0         0         0         0    
+// BOGUS        0         0         0         0         0         0         0         0    
+//                     
+// END DO NOT EDIT     
+// DO NOT EDIT ...                                                                         
+//                                                                                         
+// GPIF Waveform 2: FIFORd                                                                  
+//                                                                                         
+// Interval     0         1         2         3         4         5         6     Idle (7) 
+//          _________ _________ _________ _________ _________ _________ _________ _________
+//                                                                                         
+// AddrMode Same Val  Same Val  Same Val  Same Val  Same Val  Same Val  Same Val           
+// DataMode NO Data   Activate  NO Data   NO Data   NO Data   NO Data   NO Data            
+// NextData SameData  SameData  SameData  SameData  SameData  SameData  SameData           
+// Int Trig No Int    No Int    No Int    No Int    No Int    No Int    No Int             
+// IF/Wait  Wait 1    IF        Wait 1    IF        Wait 1    Wait 1    Wait 1             
+//   Term A           TCXpire             TCXpire                                          
+//   LFunc            AND                 AND                                              
+//   Term B           TCXpire             TCXpire                                          
+// Branch1            Then 2              ThenIdle                                         
+// Branch0            Else 1              ElseIdle                                         
+// Re-Exec            No                  No                                               
+// Sngl/CRC Default   Default   Default   Default   Default   Default   Default            
+// WEN#         0         0         0         0         0         0         0         0    
+// REN#         0         0         0         0         0         0         0         0    
+// OE#          1         1         1         0         0         0         0         0    
+// CLRST        0         0         0         0         0         0         0         0    
+// unused       0         0         0         0         0         0         0         0    
+// BOGUS        0         0         0         0         0         0         0         0    
+//                     
+// END DO NOT EDIT     
+// DO NOT EDIT ...                                                                         
+//                                                                                         
+// GPIF Waveform 3: FIFOWr                                                                  
+//                                                                                         
+// Interval     0         1         2         3         4         5         6     Idle (7) 
+//          _________ _________ _________ _________ _________ _________ _________ _________
+//                                                                                         
+// AddrMode Same Val  Same Val  Same Val  Same Val  Same Val  Same Val  Same Val           
+// DataMode NO Data   Activate  Activate  Activate  Activate  Activate  Activate           
+// NextData SameData  SameData  SameData  SameData  SameData  SameData  SameData           
+// Int Trig No Int    No Int    No Int    No Int    No Int    No Int    No Int             
+// IF/Wait  Wait 1    IF        Wait 1    Wait 1    Wait 1    Wait 1    Wait 1             
+//   Term A           TCXpire                                                              
+//   LFunc            AND                                                                  
+//   Term B           TCXpire                                                              
+// Branch1            ThenIdle                                                             
+// Branch0            Else 1                                                               
+// Re-Exec            No                                                                   
+// Sngl/CRC Default   Default   Default   Default   Default   Default   Default            
+// WEN#         0         0         0         0         0         0         0         0    
+// REN#         0         0         0         0         0         0         0         0    
+// OE#          0         0         0         0         0         0         0         0    
+// CLRST        0         0         0         0         0         0         0         0    
+// unused       0         0         0         0         0         0         0         0    
+// BOGUS        0         0         0         0         0         0         0         0    
+//                     
+// END DO NOT EDIT     
+                                              
+// GPIF Program Code                          
+                                              
+// DO NOT EDIT ...                            
+#include "fx2.h"                            
+#include "fx2regs.h"                        
+#include "fx2sdly.h"     // SYNCDELAY macro 
+// END DO NOT EDIT                            
+                                              
+// DO NOT EDIT ...                     
+const char xdata WaveData[128] =     
+{                                      
+// Wave 0 
+/* LenBr */ 0x01,     0x01,     0x01,     0x01,     0x01,     0x01,     0x01,     0x07,
+/* Opcode*/ 0x00,     0x00,     0x00,     0x00,     0x00,     0x00,     0x00,     0x00,
+/* Output*/ 0x00,     0x00,     0x00,     0x00,     0x00,     0x00,     0x00,     0x00,
+/* LFun  */ 0x00,     0x00,     0x00,     0x00,     0x00,     0x00,     0x00,     0x3F,
+// Wave 1 
+/* LenBr */ 0x01,     0x3F,     0x01,     0x01,     0x01,     0x01,     0x01,     0x07,
+/* Opcode*/ 0x22,     0x03,     0x02,     0x02,     0x02,     0x02,     0x02,     0x00,
+/* Output*/ 0x00,     0x01,     0x01,     0x01,     0x01,     0x01,     0x01,     0x00,
+/* LFun  */ 0x00,     0x00,     0x00,     0x00,     0x00,     0x00,     0x00,     0x3F,
+// Wave 2 
+/* LenBr */ 0x01,     0x11,     0x01,     0x3F,     0x01,     0x01,     0x01,     0x07,
+/* Opcode*/ 0x00,     0x03,     0x00,     0x01,     0x00,     0x00,     0x00,     0x00,
+/* Output*/ 0x04,     0x04,     0x04,     0x00,     0x00,     0x00,     0x00,     0x00,
+/* LFun  */ 0x00,     0x2D,     0x00,     0x2D,     0x00,     0x00,     0x00,     0x3F,
+// Wave 3 
+/* LenBr */ 0x01,     0x39,     0x01,     0x01,     0x01,     0x01,     0x01,     0x07,
+/* Opcode*/ 0x00,     0x03,     0x02,     0x02,     0x02,     0x02,     0x02,     0x00,
+/* Output*/ 0x00,     0x00,     0x00,     0x00,     0x00,     0x00,     0x00,     0x00,
+/* LFun  */ 0x00,     0x2D,     0x00,     0x00,     0x00,     0x00,     0x00,     0x3F,
+};                     
+// END DO NOT EDIT     
+                       
+// DO NOT EDIT ...                     
+const char xdata FlowStates[36] =   
+{                                      
+/* Wave 0 FlowStates */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+/* Wave 1 FlowStates */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+/* Wave 2 FlowStates */ 0x81,0x2D,0x26,0x00,0x04,0x04,0x03,0x02,0x00,
+/* Wave 3 FlowStates */ 0x81,0x2D,0x21,0x00,0x04,0x04,0x03,0x02,0x00,
+};                     
+// END DO NOT EDIT     
+                       
+// DO NOT EDIT ...                                               
+const char xdata InitData[7] =                                   
+{                                                                
+/* Regs  */ 0xA0,0x00,0x00,0x00,0xEE,0x4E,0x00     
+};                                                               
+// END DO NOT EDIT                                               
+                                                                 
+// TO DO: You may add additional code below.
+
+void GpifInit( void )
+{
+  BYTE i;
+  // Registers which require a synchronization delay, see section 15.14
+  // FIFORESET        FIFOPINPOLAR
+  // INPKTEND         OUTPKTEND
+  // EPxBCH:L         REVCTL
+  // GPIFTCB3         GPIFTCB2
+  // GPIFTCB1         GPIFTCB0
+  // EPxFIFOPFH:L     EPxAUTOINLENH:L
+  // EPxFIFOCFG       EPxGPIFFLGSEL
+  // PINFLAGSxx       EPxFIFOIRQ
+  // EPxFIFOIE        GPIFIRQ
+  // GPIFIE           GPIFADRH:L
+  // UDMACRCH:L       EPxGPIFTRIG
+  // GPIFTRIG
+  
+  // Note: The pre-REVE EPxGPIFTCH/L register are affected, as well...
+  //      ...these have been replaced by GPIFTC[B3:B0] registers
+  // 8051 doesn't have access to waveform memories 'til
+  // the part is in GPIF mode.
+  IFCONFIG = 0xEE;
+  // IFCLKSRC=1   , FIFOs executes on internal clk source
+  // xMHz=1       , 48MHz internal clk rate
+  // IFCLKOE=0    , Don't drive IFCLK pin signal at 48MHz
+  // IFCLKPOL=0   , Don't invert IFCLK pin signal from internal clk
+  // ASYNC=1      , master samples asynchronous
+  // GSTATE=1     , Drive GPIF states out on PORTE[2:0], debug WF
+  // IFCFG[1:0]=10, FX2 in GPIF master mode
+  GPIFABORT = 0xFF;  // abort any waveforms pending
+  GPIFREADYCFG = InitData[ 0 ];
+  GPIFCTLCFG = InitData[ 1 ];
+  GPIFIDLECS = InitData[ 2 ];
+  GPIFIDLECTL = InitData[ 3 ];
+  GPIFWFSELECT = InitData[ 5 ];
+  GPIFREADYSTAT = InitData[ 6 ];
+  // use dual autopointer feature... 
+  AUTOPTRSETUP = 0x07;          // inc both pointers, 
+                                // ...warning: this introduces pdata hole(s)
+                                // ...at E67B (XAUTODAT1) and E67C (XAUTODAT2)
+  
+  // source
+  AUTOPTRH1 = MSB( &WaveData );
+  AUTOPTRL1 = LSB( &WaveData );
+  
+  // destination
+  AUTOPTRH2 = 0xE4;
+  AUTOPTRL2 = 0x00;
+  // transfer
+  for ( i = 0x00; i < 128; i++ )
+  {
+    EXTAUTODAT2 = EXTAUTODAT1;
+  }
+// Configure GPIF Address pins, output initial value,
+  PORTCCFG = 0xFF;    // [7:0] as alt. func. GPIFADR[7:0]
+  OEC = 0xFF;         // and as outputs
+  PORTECFG |= 0x80;   // [8] as alt. func. GPIFADR[8]
+  OEE |= 0x80;        // and as output
+// ...OR... tri-state GPIFADR[8:0] pins
+//  PORTCCFG = 0x00;  // [7:0] as port I/O
+//  OEC = 0x00;       // and as inputs
+//  PORTECFG &= 0x7F; // [8] as port I/O
+//  OEE &= 0x7F;      // and as input
+// GPIF address pins update when GPIFADRH/L written
+  SYNCDELAY;                    // 
+  GPIFADRH = 0x00;    // bits[7:1] always 0
+  SYNCDELAY;                    // 
+  GPIFADRL = 0x00;    // point to PERIPHERAL address 0x0000
+// Configure GPIF FlowStates registers for Wave 0 of WaveData
+  FLOWSTATE = FlowStates[ 0 ];
+  FLOWLOGIC = FlowStates[ 1 ];
+  FLOWEQ0CTL = FlowStates[ 2 ];
+  FLOWEQ1CTL = FlowStates[ 3 ];
+  FLOWHOLDOFF = FlowStates[ 4 ];
+  FLOWSTB = FlowStates[ 5 ];
+  FLOWSTBEDGE = FlowStates[ 6 ];
+  FLOWSTBHPERIOD = FlowStates[ 7 ];
+}
diff --git a/usrp/firmware/src/common/gpif.gpf b/usrp/firmware/src/common/gpif.gpf
new file mode 100755 (executable)
index 0000000..a954ac1
Binary files /dev/null and b/usrp/firmware/src/common/gpif.gpf differ
diff --git a/usrp/firmware/src/common/init_gpif.c b/usrp/firmware/src/common/init_gpif.c
new file mode 100644 (file)
index 0000000..40336e6
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * USRP - Universal Software Radio Peripheral
+ *
+ * Copyright (C) 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 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
+ */
+
+#include "usrp_common.h"
+
+// These are the tables generated by the Cypress GPIF Designer
+
+extern const char WaveData[128];
+extern const char FlowStates[36];
+extern const char InitData[7];
+
+// The tool is kind of screwed up, in that it doesn't configure some
+// of the ports correctly.  We just use their tables and handle the
+// initialization ourselves.  They also declare that their static
+// initialized data is in xdata, which screws us too.
+
+void
+init_gpif (void)
+{
+  // we've already setup IFCONFIG before calling this...
+
+  GPIFABORT = 0xFF;  // abort any waveforms pending
+  SYNCDELAY;
+  GPIFREADYCFG = InitData[ 0 ];
+  GPIFCTLCFG = InitData[ 1 ];
+  GPIFIDLECS = InitData[ 2 ];
+  GPIFIDLECTL = InitData[ 3 ];
+  // Hmmm, what's InitData[ 4 ] ...
+  GPIFWFSELECT = InitData[ 5 ];
+  // GPIFREADYSTAT = InitData[ 6 ];    // I think this register is read only...
+  {
+    BYTE i;
+    
+    for (i = 0; i < 128; i++){
+      GPIF_WAVE_DATA[i] = WaveData[i];
+    }
+  }
+  FLOWSTATE = 0;               /* ensure it's off */
+}
diff --git a/usrp/firmware/src/common/usrp_common.c b/usrp/firmware/src/common/usrp_common.c
new file mode 100644 (file)
index 0000000..5daa8df
--- /dev/null
@@ -0,0 +1,109 @@
+/*
+ * USRP - Universal Software Radio Peripheral
+ *
+ * Copyright (C) 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 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
+ */
+
+/* 
+ * common code for USRP
+ */
+
+#include "usrp_common.h"
+
+void init_board (void);
+
+void
+init_usrp (void)
+{
+  CPUCS = bmCLKSPD1;   // CPU runs @ 48 MHz
+  CKCON = 0;           // MOVX takes 2 cycles
+
+  // IFCLK is generated internally and runs at 48 MHz; GPIF "master mode"
+
+  IFCONFIG = bmIFCLKSRC | bm3048MHZ | bmIFCLKOE | bmIFCLKPOL | bmIFGPIF;
+  SYNCDELAY;
+
+  // configure IO ports (B and D are used by GPIF)
+
+  IOA = bmPORT_A_INITIAL;      // Port A initial state
+  OEA = bmPORT_A_OUTPUTS;      // Port A direction register
+
+  IOC = bmPORT_C_INITIAL;      // Port C initial state
+  OEC = bmPORT_C_OUTPUTS;      // Port C direction register
+
+  IOE = bmPORT_E_INITIAL;      // Port E initial state
+  OEE = bmPORT_E_OUTPUTS;      // Port E direction register
+
+
+  // REVCTL = bmDYN_OUT | bmENH_PKT;                   // highly recommended by docs
+  // SYNCDELAY;
+  
+  // configure end points
+
+  EP1OUTCFG = bmVALID | bmBULK;                                SYNCDELAY;
+  EP1INCFG  = bmVALID | bmBULK | bmIN;                 SYNCDELAY;
+
+  EP2CFG    = bmVALID | bmBULK | bmQUADBUF;            SYNCDELAY;      // 512 quad bulk OUT
+  EP4CFG    = 0;                                       SYNCDELAY;      // disabled
+  EP6CFG    = bmVALID | bmBULK | bmQUADBUF | bmIN;     SYNCDELAY;      // 512 quad bulk IN
+  EP8CFG    = 0;                                       SYNCDELAY;      // disabled
+
+  // reset FIFOs
+
+  FIFORESET = bmNAKALL;                                        SYNCDELAY;
+  FIFORESET = 2;                                       SYNCDELAY;
+  // FIFORESET = 4;                                    SYNCDELAY;
+  FIFORESET = 6;                                       SYNCDELAY;
+  // FIFORESET = 8;                                    SYNCDELAY;
+  FIFORESET = 0;                                       SYNCDELAY;
+  
+  // configure end point FIFOs
+
+  // let core see 0 to 1 transistion of autoout bit
+
+  EP2FIFOCFG =             bmWORDWIDE;                 SYNCDELAY;
+  EP2FIFOCFG = bmAUTOOUT | bmWORDWIDE;                 SYNCDELAY;
+  EP6FIFOCFG = bmAUTOIN  | bmWORDWIDE;                 SYNCDELAY;
+
+
+  // prime the pump 
+
+#if 0
+  EP2BCL  = 0x80;              SYNCDELAY;
+  EP2BCL  = 0x80;              SYNCDELAY;
+  EP2BCL  = 0x80;              SYNCDELAY;
+  EP2BCL  = 0x80;              SYNCDELAY;
+#endif
+
+  EP0BCH = 0;                  SYNCDELAY;
+
+  // arm EP1OUT so we can receive "out" packets (TRM pg 8-8)
+
+  EP1OUTBC = 0;                        SYNCDELAY;
+
+  EP2GPIFFLGSEL = 0x01;                SYNCDELAY; // For EP2OUT, GPIF uses EF flag
+  EP6GPIFFLGSEL = 0x02;                SYNCDELAY; // For EP6IN,  GPIF uses FF flag
+
+  // set autoin length for EP6
+  // FIXME should be f(enumeration)
+
+  EP6AUTOINLENH = (512) >> 8;  SYNCDELAY;  // this is the length for high speed
+  EP6AUTOINLENL = (512) & 0xff; SYNCDELAY;
+
+  init_board ();
+}
+
diff --git a/usrp/firmware/src/common/usrp_globals.h b/usrp/firmware/src/common/usrp_globals.h
new file mode 100644 (file)
index 0000000..6caa234
--- /dev/null
@@ -0,0 +1,32 @@
+/* -*- 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 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.
+ */
+#ifndef _USRP_GLOBALS_H_
+#define _USRP_GLOBALS_H_
+
+extern unsigned char g_tx_enable;
+extern unsigned char g_rx_enable;
+extern unsigned char g_fpga_reset;
+extern unsigned char g_rx_overrun;
+extern unsigned char g_tx_underrun;
+
+
+#endif /* _USRP_GLOBALS_H_ */
diff --git a/usrp/firmware/src/common/vectors.a51 b/usrp/firmware/src/common/vectors.a51
new file mode 100644 (file)
index 0000000..7fd5f95
--- /dev/null
@@ -0,0 +1,180 @@
+;;; -*- 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 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.
+;;; 
+
+;;; Interrupt vectors.
+
+;;; N.B. This object module must come first in the list of modules
+
+       .module vectors
+
+;;; ----------------------------------------------------------------
+;;;              standard FX2 interrupt vectors
+;;; ----------------------------------------------------------------
+
+       .area CSEG (CODE)
+       .area GSINIT (CODE)
+       .area CSEG (CODE)
+__standard_interrupt_vector::
+__reset_vector::
+       ljmp    s_GSINIT
+       
+       ;; 13 8-byte entries.  We point them all at __isr_nop
+       ljmp    __isr_nop       ; 3 bytes
+       .ds     5               ; + 5 = 8 bytes for vector slot
+       ljmp    __isr_nop
+       .ds     5
+       ljmp    __isr_nop
+       .ds     5
+       ljmp    __isr_nop
+       .ds     5
+       ljmp    __isr_nop
+       .ds     5
+       ljmp    __isr_nop
+       .ds     5
+       ljmp    __isr_nop
+       .ds     5
+       ljmp    __isr_nop
+       .ds     5
+       ljmp    __isr_nop
+       .ds     5
+       ljmp    __isr_nop
+       .ds     5
+       ljmp    __isr_nop
+       .ds     5
+       ljmp    __isr_nop
+       .ds     5
+       ljmp    __isr_nop
+       .ds     5
+
+__isr_nop::
+       reti
+
+;;; ----------------------------------------------------------------
+;;; the FIFO/GPIF autovector.  14 4-byte entries.
+;;; must start on a 128 byte boundary.
+;;; ----------------------------------------------------------------
+       
+       . = __reset_vector + 0x0080
+               
+__fifo_gpif_autovector::
+       ljmp    __isr_nop
+       nop     
+       ljmp    __isr_nop
+       nop     
+       ljmp    __isr_nop
+       nop     
+       ljmp    __isr_nop
+       nop     
+       ljmp    __isr_nop
+       nop     
+       ljmp    __isr_nop
+       nop     
+       ljmp    __isr_nop
+       nop     
+       ljmp    __isr_nop
+       nop     
+       ljmp    __isr_nop
+       nop     
+       ljmp    __isr_nop
+       nop     
+       ljmp    __isr_nop
+       nop     
+       ljmp    __isr_nop
+       nop     
+       ljmp    __isr_nop
+       nop     
+       ljmp    __isr_nop
+       nop     
+
+       
+;;; ----------------------------------------------------------------
+;;; the USB autovector.  32 4-byte entries.
+;;; must start on a 256 byte boundary.
+;;; ----------------------------------------------------------------
+
+       . = __reset_vector + 0x0100
+       
+__usb_autovector::
+       ljmp    __isr_nop
+       nop
+       ljmp    __isr_nop
+       nop
+       ljmp    __isr_nop
+       nop
+       ljmp    __isr_nop
+       nop
+       ljmp    __isr_nop
+       nop
+       ljmp    __isr_nop
+       nop
+       ljmp    __isr_nop
+       nop
+       ljmp    __isr_nop
+       nop
+       ljmp    __isr_nop
+       nop
+       ljmp    __isr_nop
+       nop
+       ljmp    __isr_nop
+       nop
+       ljmp    __isr_nop
+       nop
+       ljmp    __isr_nop
+       nop
+       ljmp    __isr_nop
+       nop
+       ljmp    __isr_nop
+       nop
+       ljmp    __isr_nop
+       nop
+       ljmp    __isr_nop
+       nop
+       ljmp    __isr_nop
+       nop
+       ljmp    __isr_nop
+       nop
+       ljmp    __isr_nop
+       nop
+       ljmp    __isr_nop
+       nop
+       ljmp    __isr_nop
+       nop
+       ljmp    __isr_nop
+       nop
+       ljmp    __isr_nop
+       nop
+       ljmp    __isr_nop
+       nop
+       ljmp    __isr_nop
+       nop
+       ljmp    __isr_nop
+       nop
+       ljmp    __isr_nop
+       nop
+       ljmp    __isr_nop
+       nop
+       ljmp    __isr_nop
+       nop
+       ljmp    __isr_nop
+       nop
+       ljmp    __isr_nop
+       nop
diff --git a/usrp/firmware/src/usrp2/Makefile.am b/usrp/firmware/src/usrp2/Makefile.am
new file mode 100644 (file)
index 0000000..e708312
--- /dev/null
@@ -0,0 +1,168 @@
+#
+# 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 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.
+# 
+
+firmware2dir = $(prefix)/share/usrp/rev2
+firmware2_DATA = std.ihx
+
+# we put the same stuff in the rev4 directory
+firmware4dir = $(prefix)/share/usrp/rev4
+firmware4_DATA = std.ihx
+
+EXTRA_DIST =                   \
+       edit-gpif               \
+       _startup.a51            \
+       blink_leds.c            \
+       board_specific.c        \
+       check_mdelay.c          \
+       check_udelay.c          \
+       eeprom_boot.a51         \
+       eeprom_init.c           \
+       eeprom_io.c             \
+       eeprom_io.h             \
+       fpga_load.c             \
+       fpga_rev2.c             \
+       fpga_rev2.h             \
+       gpif.c                  \
+       init_gpif.c             \
+       spi.c                   \
+       spi.h                   \
+       usb_descriptors.a51     \
+       usrp_common.c           \
+       usrp_common.h           \
+       usrp_gpif.c             \
+       usrp_main.c             \
+       usrp_rev2_regs.h        \
+       vectors.a51             
+
+
+DEFINES=-DHAVE_USRP2
+INCLUDES=-I$(top_srcdir)/usrp/firmware/include -I$(top_srcdir)/usrp/firmware/src/usrp2 -I$(top_srcdir)/usrp/firmware/src/common -I./ -I../common
+
+# with EA = 0, the FX2 implements a portion of the 8051 "external memory"
+# on chip.  This memory is mapped like this:
+#
+# The bottom 8K of memory (0x0000 - 0x1fff) is used for both data and
+# code accesses.  There's also 512 bytes for data only from 0xe000 - 0xe1ff.
+#
+# We tell the linker to start the xdata segment at 0x1800, 6K up from
+# the bottom.
+
+MEMOPTS = --code-loc 0x0000 --code-size 0x1800 --xram-loc 0x1800 --xram-size 0x0800 \
+ -Wl '-b USBDESCSEG = 0xE000'
+
+LIBOPTS = -L ../../lib libfx2.lib
+LIBDEP = ../../lib/libfx2.lib
+
+LINKOPTS = $(MEMOPTS) $(LIBOPTS)
+
+EXECUTABLES =                  \
+       std.ihx                 \
+       blink_leds.ihx          \
+       check_mdelay.ihx        \
+       check_udelay.ihx        \
+       eeprom_boot.ihx         
+
+STARTUP = _startup.rel
+
+noinst_SCRIPTS =               \
+       burn-usrp2-eeprom       \
+       burn-usrp4-eeprom
+
+
+%.rel : %.c
+       $(XCC) $(INCLUDES) $(DEFINES) \
+               -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<
+
+%.rel : %.a51
+       test -f `basename '$<'` || ln -s '$<' .
+       test -f ../common/`basename '$<'` -o \
+               \! -f `dirname '$<'`/../common/`basename '$<'` \
+               || ln -s `dirname '$<'`/../common/`basename '$<'` ../common/.
+       $(XAS) `basename '$<'`
+
+
+EEPROM_BOOT_OBJS = eeprom_boot.rel eeprom_init.rel $(STARTUP)
+
+eeprom_boot.ihx: $(EEPROM_BOOT_OBJS) $(LIBDEP)
+       $(XCC) $(LINKOPTS) -o $@ $(EEPROM_BOOT_OBJS)
+
+burn-usrp2-eeprom: eeprom_boot.ihx
+       $(srcdir)/../common/build_eeprom.py -r2 $< > $@
+       chmod +x $@
+
+burn-usrp4-eeprom: eeprom_boot.ihx
+       $(srcdir)/../common/build_eeprom.py -r4 $< > $@
+       chmod +x $@
+
+
+BLINK_LEDS_OBJS = blink_leds.rel usrp_common.rel board_specific.rel spi.rel $(STARTUP)
+
+blink_leds.ihx: $(BLINK_LEDS_OBJS) $(LIBDEP)
+       $(XCC) $(LINKOPTS) -o $@ $(BLINK_LEDS_OBJS)
+
+
+CHECK_MDELAY_OBJS = check_mdelay.rel usrp_common.rel board_specific.rel spi.rel $(STARTUP)
+
+check_mdelay.ihx: $(CHECK_MDELAY_OBJS) $(LIBDEP)
+       $(XCC) $(LINKOPTS) -o $@ $(CHECK_MDELAY_OBJS)
+
+
+
+CHECK_UDELAY_OBJS = check_udelay.rel usrp_common.rel board_specific.rel spi.rel $(STARTUP)
+
+check_udelay.ihx: $(CHECK_UDELAY_OBJS) $(LIBDEP)
+       $(XCC) $(LINKOPTS) -o $@ $(CHECK_UDELAY_OBJS)
+
+
+
+USRP_OBJS = \
+       vectors.rel                                             \
+       usrp_main.rel usrp_common.rel board_specific.rel        \
+       fpga_load.rel fpga_rev2.rel init_gpif.rel usrp_gpif.rel \
+       usb_descriptors.rel spi.rel eeprom_io.rel $(STARTUP)
+
+std.ihx: $(USRP_OBJS) $(LIBDEP)
+       $(XCC) $(LINKOPTS) -o $@ $(USRP_OBJS)
+
+CLEANFILES =           \
+       *.ihx *.lnk *.lst *.map *.mem *.rel *.rst *.sym *.asm *.lib     \
+       usrp_gpif.c usrp_gpif_inline.h \
+       burn-usrp2-eeprom       \
+       burn-usrp4-eeprom
+
+DISTCLEANFILES =       \
+       *.ihx *.lnk *.lst *.map *.mem *.rel *.rst *.sym *.asm *.lib
+
+# build gpif stuff
+
+all: usrp_gpif.c
+
+usrp_gpif.c usrp_gpif_inline.h : gpif.c
+       srcdir=$(srcdir) $(srcdir)/edit-gpif $(srcdir)/gpif.c usrp_gpif.c usrp_gpif_inline.h
+
+
+# dependencies
+
+usrp_main.rel: usrp_gpif_inline.h
+#usrp_main.rel: fpga.h usrp_common.h ../../include/usrp_commands.h usrp_gpif_inline.h  ../../include/usrp_config.h usrp_rev2_regs.h ../../include/fx2regs.h
+#usrp_common.rel: usrp_common.h ../../include/usrp_commands.h ../../include/usrp_config.h usrp_rev2_regs.h ../../include/fx2regs.h
+#fpga.rel: usrp_common.h ../../include/usrp_commands.h fpga.h ../../include/usrp_config.h usrp_rev2_regs.h ../../include/fx2regs.h
+#init_gpif.rel: usrp_common.h ../../include/usrp_config.h usrp_rev2_regs.h ../../include/fx2regs.h
diff --git a/usrp/firmware/src/usrp2/_startup.a51 b/usrp/firmware/src/usrp2/_startup.a51
new file mode 100644 (file)
index 0000000..4f53099
--- /dev/null
@@ -0,0 +1 @@
+       .include "../common/_startup.a51"
diff --git a/usrp/firmware/src/usrp2/blink_leds.c b/usrp/firmware/src/usrp2/blink_leds.c
new file mode 100644 (file)
index 0000000..c633d5d
--- /dev/null
@@ -0,0 +1 @@
+#include "../common/blink_leds.c"
diff --git a/usrp/firmware/src/usrp2/board_specific.c b/usrp/firmware/src/usrp2/board_specific.c
new file mode 100644 (file)
index 0000000..a4ff45c
--- /dev/null
@@ -0,0 +1,113 @@
+/* -*- 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 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.
+ */
+
+#include "usrp_common.h"
+#include "spi.h"
+
+void
+set_led_0 (unsigned char on)
+{
+  if (!on)                     // active low
+    USRP_PC |= bmPC_LED0;
+  else
+    USRP_PC &= ~bmPC_LED0;
+}
+
+void 
+set_led_1 (unsigned char on)
+{
+  if (!on)                     // active low
+    USRP_PC |= bmPC_LED1;
+  else
+    USRP_PC &= ~bmPC_LED1;
+}
+
+void
+toggle_led_0 (void)
+{
+  USRP_PC ^= bmPC_LED0;
+}
+
+void
+toggle_led_1 (void)
+{
+  USRP_PC ^= bmPC_LED1;
+}
+
+void
+la_trace_init (void)
+{
+}
+
+void
+set_sleep_bits (unsigned char bits, unsigned char mask)
+{
+  // NOP on usrp1
+}
+
+static xdata unsigned char xbuf[1];
+
+void
+write_9862 (unsigned char which, unsigned char regno, unsigned char value)
+{
+  xbuf[0] = value;
+  
+  spi_write (0, regno & 0x3f,
+            which == 0 ? SPI_ENABLE_CODEC_A : SPI_ENABLE_CODEC_B,
+            SPI_FMT_MSB | SPI_FMT_HDR_1,
+            xbuf, 1);
+}
+
+void
+write_both_9862s (unsigned char regno, unsigned char value)
+{
+  xbuf[0] = value;
+  
+  spi_write (0, regno & 0x3f,
+            SPI_ENABLE_CODEC_A | SPI_ENABLE_CODEC_B,
+            SPI_FMT_MSB | SPI_FMT_HDR_1,
+            xbuf, 1);
+}
+
+#define REG_RX_PWR_DN           1
+#define        REG_TX_PWR_DN            8
+#define        REG_TX_MODULATOR        20
+
+static void
+power_down_9862s (void)
+{
+  write_both_9862s (REG_RX_PWR_DN,    0x01);
+  write_both_9862s (REG_TX_PWR_DN,    0x0f);   // pwr dn digital and analog_both
+  write_both_9862s (REG_TX_MODULATOR, 0x00);   // coarse & fine modulators disabled
+}
+
+void
+init_board (void)
+{
+  la_trace_init ();
+  init_spi ();
+
+  USRP_PC &= ~bmPC_nRESET;     // active low reset
+  USRP_PC |= bmPC_nRESET;
+
+  power_down_9862s ();
+}
diff --git a/usrp/firmware/src/usrp2/check_mdelay.c b/usrp/firmware/src/usrp2/check_mdelay.c
new file mode 100644 (file)
index 0000000..ea4ccdb
--- /dev/null
@@ -0,0 +1 @@
+#include "../common/check_mdelay.c"
diff --git a/usrp/firmware/src/usrp2/check_udelay.c b/usrp/firmware/src/usrp2/check_udelay.c
new file mode 100644 (file)
index 0000000..d01622e
--- /dev/null
@@ -0,0 +1 @@
+#include "../common/check_udelay.c"
diff --git a/usrp/firmware/src/usrp2/edit-gpif b/usrp/firmware/src/usrp2/edit-gpif
new file mode 100755 (executable)
index 0000000..c507f50
--- /dev/null
@@ -0,0 +1,114 @@
+#!/usr/bin/env python
+# -*- 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 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.
+# 
+
+
+# Edit the gpif.c file generated by the Cypress GPIF Designer Tool and
+# produce usrp_gpif.c, and usrp_gpif_inline.h, files suitable for our
+# uses.
+
+import re
+import string
+import sys
+
+def check_flow_state (line, flow_state_dict):
+    mo = re.match (r'/\* Wave (\d) FlowStates \*/ (.*),', line)
+    if mo:
+        wave = int (mo.group (1))
+        data = mo.group (2)
+        split = data.split (',', 8)
+        v = map (lambda x : int (x, 16), split)
+        # print "%s, %s" % (wave, data)
+        # print "split: ", split
+        # print "v    : ", v
+        flow_state_dict[wave] = v
+
+
+def delta (xseq, yseq):
+    # set subtraction
+    z = []
+    for x in xseq:
+        if x not in yseq:
+            z.append (x)
+    return z
+    
+
+def write_define (output, name, pairs):
+    output.write ('#define %s()\t\\\n' % name)
+    output.write ('do {\t\t\t\t\t\\\n')
+    for reg, val in pairs:
+        output.write ('%14s = 0x%02x;\t\t\t\\\n' % (reg, val))
+    output.write ('} while (0)\n\n')
+    
+def write_inlines (output, dict):
+    regs = ['FLOWSTATE', 'FLOWLOGIC', 'FLOWEQ0CTL', 'FLOWEQ1CTL', 'FLOWHOLDOFF',
+            'FLOWSTB', 'FLOWSTBEDGE', 'FLOWSTBHPERIOD', 'GPIFHOLDAMOUNT']
+
+    READ_FLOW_STATE = 2
+    WRITE_FLOW_STATE = 3
+
+    read_info = zip (regs, dict[READ_FLOW_STATE])
+    write_info = zip (regs, dict[WRITE_FLOW_STATE])
+    
+    output.write ('''/*
+ * Machine generated by "edit-gpif".  Do not edit by hand.
+ */
+
+''')
+    write_define (output, 'setup_flowstate_common', read_info)
+    write_define (output, 'setup_flowstate_read', delta (read_info, write_info))
+    write_define (output, 'setup_flowstate_write', delta (write_info, read_info))
+    
+
+def edit_gpif (input_name, output_name, inline_name):
+    input = open (input_name, 'r')
+    output = open (output_name, 'w')
+    inline = open (inline_name, 'w')
+    flow_state_dict = {}
+
+    output.write ('''/*
+ * Machine generated by "edit-gpif".  Do not edit by hand.
+ */
+
+''')
+    
+    while 1:
+        line = input.readline ()
+        line = string.replace (line, '\r','')
+        line = re.sub (r' *$', r'', line)
+
+        check_flow_state (line, flow_state_dict)
+
+        line = re.sub (r'#include', r'// #include', line)
+        line = re.sub (r'xdata ', r'', line)
+        if re.search (r'GpifInit', line):
+            break
+        
+        output.write (line)
+
+    output.close ()
+    write_inlines (inline, flow_state_dict)
+    inline.close ()
+
+
+# gpif.c usrp_gpif.c usrp_gpif_inline.h
+edit_gpif (sys.argv[1], sys.argv[2], sys.argv[3])
diff --git a/usrp/firmware/src/usrp2/eeprom_boot.a51 b/usrp/firmware/src/usrp2/eeprom_boot.a51
new file mode 100644 (file)
index 0000000..65e4526
--- /dev/null
@@ -0,0 +1,573 @@
+;--------------------------------------------------------
+; Hand tweaked minimal eeprom boot code
+;--------------------------------------------------------
+       .module eeprom_boot
+       .optsdcc -mmcs51 --model-small
+       
+;--------------------------------------------------------
+; Public variables in this module
+;--------------------------------------------------------
+       .globl _eeprom_init
+       .globl _EP8FIFOBUF
+       .globl _EP6FIFOBUF
+       .globl _EP4FIFOBUF
+       .globl _EP2FIFOBUF
+       .globl _EP1INBUF
+       .globl _EP1OUTBUF
+       .globl _EP0BUF
+       .globl _CT4
+       .globl _CT3
+       .globl _CT2
+       .globl _CT1
+       .globl _USBTEST
+       .globl _TESTCFG
+       .globl _DBUG
+       .globl _UDMACRCQUAL
+       .globl _UDMACRCL
+       .globl _UDMACRCH
+       .globl _GPIFHOLDAMOUNT
+       .globl _FLOWSTBHPERIOD
+       .globl _FLOWSTBEDGE
+       .globl _FLOWSTB
+       .globl _FLOWHOLDOFF
+       .globl _FLOWEQ1CTL
+       .globl _FLOWEQ0CTL
+       .globl _FLOWLOGIC
+       .globl _FLOWSTATE
+       .globl _GPIFABORT
+       .globl _GPIFREADYSTAT
+       .globl _GPIFREADYCFG
+       .globl _XGPIFSGLDATLNOX
+       .globl _XGPIFSGLDATLX
+       .globl _XGPIFSGLDATH
+       .globl _EP8GPIFTRIG
+       .globl _EP8GPIFPFSTOP
+       .globl _EP8GPIFFLGSEL
+       .globl _EP6GPIFTRIG
+       .globl _EP6GPIFPFSTOP
+       .globl _EP6GPIFFLGSEL
+       .globl _EP4GPIFTRIG
+       .globl _EP4GPIFPFSTOP
+       .globl _EP4GPIFFLGSEL
+       .globl _EP2GPIFTRIG
+       .globl _EP2GPIFPFSTOP
+       .globl _EP2GPIFFLGSEL
+       .globl _GPIFTCB0
+       .globl _GPIFTCB1
+       .globl _GPIFTCB2
+       .globl _GPIFTCB3
+       .globl _GPIFADRL
+       .globl _GPIFADRH
+       .globl _GPIFCTLCFG
+       .globl _GPIFIDLECTL
+       .globl _GPIFIDLECS
+       .globl _GPIFWFSELECT
+       .globl _SETUPDAT
+       .globl _SUDPTRCTL
+       .globl _SUDPTRL
+       .globl _SUDPTRH
+       .globl _EP8FIFOBCL
+       .globl _EP8FIFOBCH
+       .globl _EP6FIFOBCL
+       .globl _EP6FIFOBCH
+       .globl _EP4FIFOBCL
+       .globl _EP4FIFOBCH
+       .globl _EP2FIFOBCL
+       .globl _EP2FIFOBCH
+       .globl _EP8FIFOFLGS
+       .globl _EP6FIFOFLGS
+       .globl _EP4FIFOFLGS
+       .globl _EP2FIFOFLGS
+       .globl _EP8CS
+       .globl _EP6CS
+       .globl _EP4CS
+       .globl _EP2CS
+       .globl _EP1INCS
+       .globl _EP1OUTCS
+       .globl _EP0CS
+       .globl _EP8BCL
+       .globl _EP8BCH
+       .globl _EP6BCL
+       .globl _EP6BCH
+       .globl _EP4BCL
+       .globl _EP4BCH
+       .globl _EP2BCL
+       .globl _EP2BCH
+       .globl _EP1INBC
+       .globl _EP1OUTBC
+       .globl _EP0BCL
+       .globl _EP0BCH
+       .globl _FNADDR
+       .globl _MICROFRAME
+       .globl _USBFRAMEL
+       .globl _USBFRAMEH
+       .globl _TOGCTL
+       .globl _WAKEUPCS
+       .globl _SUSPEND
+       .globl _USBCS
+       .globl _XAUTODAT2
+       .globl _XAUTODAT1
+       .globl _I2CTL
+       .globl _I2DAT
+       .globl _I2CS
+       .globl _PORTECFG
+       .globl _PORTCCFG
+       .globl _PORTACFG
+       .globl _INTSETUP
+       .globl _INT4IVEC
+       .globl _INT2IVEC
+       .globl _CLRERRCNT
+       .globl _ERRCNTLIM
+       .globl _USBERRIRQ
+       .globl _USBERRIE
+       .globl _GPIFIRQ
+       .globl _GPIFIE
+       .globl _EPIRQ
+       .globl _EPIE
+       .globl _USBIRQ
+       .globl _USBIE
+       .globl _NAKIRQ
+       .globl _NAKIE
+       .globl _IBNIRQ
+       .globl _IBNIE
+       .globl _EP8FIFOIRQ
+       .globl _EP8FIFOIE
+       .globl _EP6FIFOIRQ
+       .globl _EP6FIFOIE
+       .globl _EP4FIFOIRQ
+       .globl _EP4FIFOIE
+       .globl _EP2FIFOIRQ
+       .globl _EP2FIFOIE
+       .globl _OUTPKTEND
+       .globl _INPKTEND
+       .globl _EP8ISOINPKTS
+       .globl _EP6ISOINPKTS
+       .globl _EP4ISOINPKTS
+       .globl _EP2ISOINPKTS
+       .globl _EP8FIFOPFL
+       .globl _EP8FIFOPFH
+       .globl _EP6FIFOPFL
+       .globl _EP6FIFOPFH
+       .globl _EP4FIFOPFL
+       .globl _EP4FIFOPFH
+       .globl _EP2FIFOPFL
+       .globl _EP2FIFOPFH
+       .globl _EP8AUTOINLENL
+       .globl _EP8AUTOINLENH
+       .globl _EP6AUTOINLENL
+       .globl _EP6AUTOINLENH
+       .globl _EP4AUTOINLENL
+       .globl _EP4AUTOINLENH
+       .globl _EP2AUTOINLENL
+       .globl _EP2AUTOINLENH
+       .globl _EP8FIFOCFG
+       .globl _EP6FIFOCFG
+       .globl _EP4FIFOCFG
+       .globl _EP2FIFOCFG
+       .globl _EP8CFG
+       .globl _EP6CFG
+       .globl _EP4CFG
+       .globl _EP2CFG
+       .globl _EP1INCFG
+       .globl _EP1OUTCFG
+       .globl _REVCTL
+       .globl _REVID
+       .globl _FIFOPINPOLAR
+       .globl _UART230
+       .globl _BPADDRL
+       .globl _BPADDRH
+       .globl _BREAKPT
+       .globl _FIFORESET
+       .globl _PINFLAGSCD
+       .globl _PINFLAGSAB
+       .globl _IFCONFIG
+       .globl _CPUCS
+       .globl _RES_WAVEDATA_END
+       .globl _GPIF_WAVE_DATA
+;--------------------------------------------------------
+; special function registers
+;--------------------------------------------------------
+_IOA   =       0x0080
+_SP    =       0x0081
+_DPL   =       0x0082
+_DPH   =       0x0083
+_DPL1  =       0x0084
+_DPH1  =       0x0085
+_DPS   =       0x0086
+_PCON  =       0x0087
+_TCON  =       0x0088
+_TMOD  =       0x0089
+_TL0   =       0x008a
+_TL1   =       0x008b
+_TH0   =       0x008c
+_TH1   =       0x008d
+_CKCON =       0x008e
+_IOB   =       0x0090
+_EXIF  =       0x0091
+_MPAGE =       0x0092
+_SCON0 =       0x0098
+_SBUF0 =       0x0099
+_APTR1H        =       0x009a
+_APTR1L        =       0x009b
+_AUTODAT1      =       0x009c
+_AUTOPTRH2     =       0x009d
+_AUTOPTRL2     =       0x009e
+_AUTODAT2      =       0x009f
+_IOC   =       0x00a0
+_INT2CLR       =       0x00a1
+_INT4CLR       =       0x00a2
+_IE    =       0x00a8
+_EP2468STAT    =       0x00aa
+_EP24FIFOFLGS  =       0x00ab
+_EP68FIFOFLGS  =       0x00ac
+_AUTOPTRSETUP  =       0x00af
+_IOD   =       0x00b0
+_IOE   =       0x00b1
+_OEA   =       0x00b2
+_OEB   =       0x00b3
+_OEC   =       0x00b4
+_OED   =       0x00b5
+_OEE   =       0x00b6
+_IP    =       0x00b8
+_EP01STAT      =       0x00ba
+_GPIFTRIG      =       0x00bb
+_GPIFSGLDATH   =       0x00bd
+_GPIFSGLDATLX  =       0x00be
+_GPIFSGLDATLNOX        =       0x00bf
+_SCON1 =       0x00c0
+_SBUF1 =       0x00c1
+_T2CON =       0x00c8
+_RCAP2L        =       0x00ca
+_RCAP2H        =       0x00cb
+_TL2   =       0x00cc
+_TH2   =       0x00cd
+_PSW   =       0x00d0
+_EICON =       0x00d8
+_ACC   =       0x00e0
+_EIE   =       0x00e8
+_B     =       0x00f0
+_EIP   =       0x00f8
+;--------------------------------------------------------
+; special function bits 
+;--------------------------------------------------------
+_SEL   =       0x0086
+_IT0   =       0x0088
+_IE0   =       0x0089
+_IT1   =       0x008a
+_IE1   =       0x008b
+_TR0   =       0x008c
+_TF0   =       0x008d
+_TR1   =       0x008e
+_TF1   =       0x008f
+_RI    =       0x0098
+_TI    =       0x0099
+_RB8   =       0x009a
+_TB8   =       0x009b
+_REN   =       0x009c
+_SM2   =       0x009d
+_SM1   =       0x009e
+_SM0   =       0x009f
+_EX0   =       0x00a8
+_ET0   =       0x00a9
+_EX1   =       0x00aa
+_ET1   =       0x00ab
+_ES0   =       0x00ac
+_ET2   =       0x00ad
+_ES1   =       0x00ae
+_EA    =       0x00af
+_PX0   =       0x00b8
+_PT0   =       0x00b9
+_PX1   =       0x00ba
+_PT1   =       0x00bb
+_PS0   =       0x00bc
+_PT2   =       0x00bd
+_PS1   =       0x00be
+_RI1   =       0x00c0
+_TI1   =       0x00c1
+_RB81  =       0x00c2
+_TB81  =       0x00c3
+_REN1  =       0x00c4
+_SM21  =       0x00c5
+_SM11  =       0x00c6
+_SM01  =       0x00c7
+_CP_RL2        =       0x00c8
+_C_T2  =       0x00c9
+_TR2   =       0x00ca
+_EXEN2 =       0x00cb
+_TCLK  =       0x00cc
+_RCLK  =       0x00cd
+_EXF2  =       0x00ce
+_TF2   =       0x00cf
+_P     =       0x00d0
+_FL    =       0x00d1
+_OV    =       0x00d2
+_RS0   =       0x00d3
+_RS1   =       0x00d4
+_F0    =       0x00d5
+_AC    =       0x00d6
+_CY    =       0x00d7
+_INT6  =       0x00db
+_RESI  =       0x00dc
+_ERESI =       0x00dd
+_SMOD1 =       0x00df
+_EIUSB =       0x00e8
+_EI2C  =       0x00e9
+_EIEX4 =       0x00ea
+_EIEX5 =       0x00eb
+_EIEX6 =       0x00ec
+_PUSB  =       0x00f8
+_PI2C  =       0x00f9
+_EIPX4 =       0x00fa
+_EIPX5 =       0x00fb
+_EIPX6 =       0x00fc
+_bitS_CLK      =       0x0080
+_bitS_OUT      =       0x0081
+_bitS_IN       =       0x0082
+_bitALTERA_DATA0       =       0x00a1
+_bitALTERA_DCLK        =       0x00a3
+;--------------------------------------------------------
+; overlayable register banks 
+;--------------------------------------------------------
+       .area REG_BANK_0        (REL,OVR,DATA)
+       .ds 8
+;--------------------------------------------------------
+; internal ram data
+;--------------------------------------------------------
+       .area DSEG    (DATA)
+;--------------------------------------------------------
+; overlayable items in internal ram 
+;--------------------------------------------------------
+       .area OSEG    (OVR,DATA)
+;--------------------------------------------------------
+; Stack segment in internal ram 
+;--------------------------------------------------------
+       .area   SSEG    (DATA)
+__start__stack:
+       .ds     1
+
+;--------------------------------------------------------
+; indirectly addressable internal ram data
+;--------------------------------------------------------
+       .area ISEG    (DATA)
+;--------------------------------------------------------
+; bit data
+;--------------------------------------------------------
+       .area BSEG    (BIT)
+;--------------------------------------------------------
+; external ram data
+;--------------------------------------------------------
+       .area XSEG    (XDATA)
+_GPIF_WAVE_DATA        =       0xe400
+_RES_WAVEDATA_END      =       0xe480
+_CPUCS =       0xe600
+_IFCONFIG      =       0xe601
+_PINFLAGSAB    =       0xe602
+_PINFLAGSCD    =       0xe603
+_FIFORESET     =       0xe604
+_BREAKPT       =       0xe605
+_BPADDRH       =       0xe606
+_BPADDRL       =       0xe607
+_UART230       =       0xe608
+_FIFOPINPOLAR  =       0xe609
+_REVID =       0xe60a
+_REVCTL        =       0xe60b
+_EP1OUTCFG     =       0xe610
+_EP1INCFG      =       0xe611
+_EP2CFG        =       0xe612
+_EP4CFG        =       0xe613
+_EP6CFG        =       0xe614
+_EP8CFG        =       0xe615
+_EP2FIFOCFG    =       0xe618
+_EP4FIFOCFG    =       0xe619
+_EP6FIFOCFG    =       0xe61a
+_EP8FIFOCFG    =       0xe61b
+_EP2AUTOINLENH =       0xe620
+_EP2AUTOINLENL =       0xe621
+_EP4AUTOINLENH =       0xe622
+_EP4AUTOINLENL =       0xe623
+_EP6AUTOINLENH =       0xe624
+_EP6AUTOINLENL =       0xe625
+_EP8AUTOINLENH =       0xe626
+_EP8AUTOINLENL =       0xe627
+_EP2FIFOPFH    =       0xe630
+_EP2FIFOPFL    =       0xe631
+_EP4FIFOPFH    =       0xe632
+_EP4FIFOPFL    =       0xe633
+_EP6FIFOPFH    =       0xe634
+_EP6FIFOPFL    =       0xe635
+_EP8FIFOPFH    =       0xe636
+_EP8FIFOPFL    =       0xe637
+_EP2ISOINPKTS  =       0xe640
+_EP4ISOINPKTS  =       0xe641
+_EP6ISOINPKTS  =       0xe642
+_EP8ISOINPKTS  =       0xe643
+_INPKTEND      =       0xe648
+_OUTPKTEND     =       0xe649
+_EP2FIFOIE     =       0xe650
+_EP2FIFOIRQ    =       0xe651
+_EP4FIFOIE     =       0xe652
+_EP4FIFOIRQ    =       0xe653
+_EP6FIFOIE     =       0xe654
+_EP6FIFOIRQ    =       0xe655
+_EP8FIFOIE     =       0xe656
+_EP8FIFOIRQ    =       0xe657
+_IBNIE =       0xe658
+_IBNIRQ        =       0xe659
+_NAKIE =       0xe65a
+_NAKIRQ        =       0xe65b
+_USBIE =       0xe65c
+_USBIRQ        =       0xe65d
+_EPIE  =       0xe65e
+_EPIRQ =       0xe65f
+_GPIFIE        =       0xe660
+_GPIFIRQ       =       0xe661
+_USBERRIE      =       0xe662
+_USBERRIRQ     =       0xe663
+_ERRCNTLIM     =       0xe664
+_CLRERRCNT     =       0xe665
+_INT2IVEC      =       0xe666
+_INT4IVEC      =       0xe667
+_INTSETUP      =       0xe668
+_PORTACFG      =       0xe670
+_PORTCCFG      =       0xe671
+_PORTECFG      =       0xe672
+_I2CS  =       0xe678
+_I2DAT =       0xe679
+_I2CTL =       0xe67a
+_XAUTODAT1     =       0xe67b
+_XAUTODAT2     =       0xe67c
+_USBCS =       0xe680
+_SUSPEND       =       0xe681
+_WAKEUPCS      =       0xe682
+_TOGCTL        =       0xe683
+_USBFRAMEH     =       0xe684
+_USBFRAMEL     =       0xe685
+_MICROFRAME    =       0xe686
+_FNADDR        =       0xe687
+_EP0BCH        =       0xe68a
+_EP0BCL        =       0xe68b
+_EP1OUTBC      =       0xe68d
+_EP1INBC       =       0xe68f
+_EP2BCH        =       0xe690
+_EP2BCL        =       0xe691
+_EP4BCH        =       0xe694
+_EP4BCL        =       0xe695
+_EP6BCH        =       0xe698
+_EP6BCL        =       0xe699
+_EP8BCH        =       0xe69c
+_EP8BCL        =       0xe69d
+_EP0CS =       0xe6a0
+_EP1OUTCS      =       0xe6a1
+_EP1INCS       =       0xe6a2
+_EP2CS =       0xe6a3
+_EP4CS =       0xe6a4
+_EP6CS =       0xe6a5
+_EP8CS =       0xe6a6
+_EP2FIFOFLGS   =       0xe6a7
+_EP4FIFOFLGS   =       0xe6a8
+_EP6FIFOFLGS   =       0xe6a9
+_EP8FIFOFLGS   =       0xe6aa
+_EP2FIFOBCH    =       0xe6ab
+_EP2FIFOBCL    =       0xe6ac
+_EP4FIFOBCH    =       0xe6ad
+_EP4FIFOBCL    =       0xe6ae
+_EP6FIFOBCH    =       0xe6af
+_EP6FIFOBCL    =       0xe6b0
+_EP8FIFOBCH    =       0xe6b1
+_EP8FIFOBCL    =       0xe6b2
+_SUDPTRH       =       0xe6b3
+_SUDPTRL       =       0xe6b4
+_SUDPTRCTL     =       0xe6b5
+_SETUPDAT      =       0xe6b8
+_GPIFWFSELECT  =       0xe6c0
+_GPIFIDLECS    =       0xe6c1
+_GPIFIDLECTL   =       0xe6c2
+_GPIFCTLCFG    =       0xe6c3
+_GPIFADRH      =       0xe6c4
+_GPIFADRL      =       0xe6c5
+_GPIFTCB3      =       0xe6ce
+_GPIFTCB2      =       0xe6cf
+_GPIFTCB1      =       0xe6d0
+_GPIFTCB0      =       0xe6d1
+_EP2GPIFFLGSEL =       0xe6d2
+_EP2GPIFPFSTOP =       0xe6d3
+_EP2GPIFTRIG   =       0xe6d4
+_EP4GPIFFLGSEL =       0xe6da
+_EP4GPIFPFSTOP =       0xe6db
+_EP4GPIFTRIG   =       0xe6dc
+_EP6GPIFFLGSEL =       0xe6e2
+_EP6GPIFPFSTOP =       0xe6e3
+_EP6GPIFTRIG   =       0xe6e4
+_EP8GPIFFLGSEL =       0xe6ea
+_EP8GPIFPFSTOP =       0xe6eb
+_EP8GPIFTRIG   =       0xe6ec
+_XGPIFSGLDATH  =       0xe6f0
+_XGPIFSGLDATLX =       0xe6f1
+_XGPIFSGLDATLNOX       =       0xe6f2
+_GPIFREADYCFG  =       0xe6f3
+_GPIFREADYSTAT =       0xe6f4
+_GPIFABORT     =       0xe6f5
+_FLOWSTATE     =       0xe6c6
+_FLOWLOGIC     =       0xe6c7
+_FLOWEQ0CTL    =       0xe6c8
+_FLOWEQ1CTL    =       0xe6c9
+_FLOWHOLDOFF   =       0xe6ca
+_FLOWSTB       =       0xe6cb
+_FLOWSTBEDGE   =       0xe6cc
+_FLOWSTBHPERIOD        =       0xe6cd
+_GPIFHOLDAMOUNT        =       0xe60c
+_UDMACRCH      =       0xe67d
+_UDMACRCL      =       0xe67e
+_UDMACRCQUAL   =       0xe67f
+_DBUG  =       0xe6f8
+_TESTCFG       =       0xe6f9
+_USBTEST       =       0xe6fa
+_CT1   =       0xe6fb
+_CT2   =       0xe6fc
+_CT3   =       0xe6fd
+_CT4   =       0xe6fe
+_EP0BUF        =       0xe740
+_EP1OUTBUF     =       0xe780
+_EP1INBUF      =       0xe7c0
+_EP2FIFOBUF    =       0xf000
+_EP4FIFOBUF    =       0xf400
+_EP6FIFOBUF    =       0xf800
+_EP8FIFOBUF    =       0xfc00
+;--------------------------------------------------------
+; external initialized ram data
+;--------------------------------------------------------
+;--------------------------------------------------------
+; interrupt vector 
+;--------------------------------------------------------
+       .area CSEG    (CODE)
+__interrupt_vect:
+       ljmp    __sdcc_gsinit_startup
+;--------------------------------------------------------
+; global & static initialisations
+;--------------------------------------------------------
+       .area GSINIT  (CODE)
+       .area GSFINAL (CODE)
+       .area GSINIT  (CODE)
+__sdcc_gsinit_startup:
+       mov     sp,#__start__stack - 1
+       lcall   __sdcc_external_startup
+       mov     a,dpl
+       jz      __sdcc_init_data
+       ljmp    __sdcc_program_startup
+__sdcc_init_data:
+       .area GSFINAL (CODE)
+       ljmp    __sdcc_program_startup
+;--------------------------------------------------------
+; Home
+;--------------------------------------------------------
+       .area HOME    (CODE)
+       .area CSEG    (CODE)
+;--------------------------------------------------------
+; code
+;--------------------------------------------------------
+       .area CSEG    (CODE)
+__sdcc_program_startup:
+       lcall   _eeprom_init
+;      return from _eeprom_init will spin here
+       sjmp .
+       .area CSEG    (CODE)
diff --git a/usrp/firmware/src/usrp2/eeprom_init.c b/usrp/firmware/src/usrp2/eeprom_init.c
new file mode 100644 (file)
index 0000000..fb949bc
--- /dev/null
@@ -0,0 +1,116 @@
+/* -*- 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 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.
+ */
+
+#include "usrp_common.h"
+#include "usrp_commands.h"
+#include "spi.h"
+
+/*
+ * the host side fpga loader code pushes an MD5 hash of the bitstream
+ * into hash1.
+ */
+#define          USRP_HASH_SIZE      16
+xdata at USRP_HASH_SLOT_0_ADDR unsigned char hash0[USRP_HASH_SIZE];
+
+
+#define enable_codecs() USRP_PA &= ~(bmPA_SEN_CODEC_A | bmPA_SEN_CODEC_B)
+#define disable_all()  USRP_PA |=  (bmPA_SEN_CODEC_A | bmPA_SEN_CODEC_B)
+
+static void
+write_byte_msb (unsigned char v);
+
+void
+write_both_9862s (unsigned char header_lo, unsigned char v)
+{
+  enable_codecs ();
+
+  write_byte_msb (header_lo);
+  write_byte_msb (v);
+
+  disable_all ();
+}
+
+// ----------------------------------------------------------------
+
+static void
+write_byte_msb (unsigned char v)
+{
+  unsigned char n = 8;
+  do {
+    v = (v << 1) | (v >> 7);   // rotate left (MSB into bottom bit)
+    bitS_OUT = v & 0x1;
+    bitS_CLK = 1;
+    bitS_CLK = 0;
+  } while (--n != 0);
+}
+
+// ----------------------------------------------------------------
+
+#define REG_RX_PWR_DN           1
+#define        REG_TX_PWR_DN            8
+#define        REG_TX_MODULATOR        20
+
+void eeprom_init (void)
+{
+  unsigned short counter;
+  unsigned char         i;
+
+  // configure IO ports (B and D are used by GPIF)
+
+  IOA = bmPORT_A_INITIAL;      // Port A initial state
+  OEA = bmPORT_A_OUTPUTS;      // Port A direction register
+
+  IOC = bmPORT_C_INITIAL;      // Port C initial state
+  OEC = bmPORT_C_OUTPUTS;      // Port C direction register
+
+  IOE = bmPORT_E_INITIAL;      // Port E initial state
+  OEE = bmPORT_E_OUTPUTS;      // Port E direction register
+
+  EP0BCH = 0;                  SYNCDELAY;
+
+  // USBCS &= ~bmRENUM;                // chip firmware handles commands
+  USBCS = 0;                   // chip firmware handles commands
+
+  USRP_PC &= ~bmPC_nRESET;     // active low reset
+  USRP_PC |=  bmPC_nRESET;
+
+  // init_spi ();
+  bitS_OUT = 0;                        /* idle state has CLK = 0 */
+
+  write_both_9862s (REG_RX_PWR_DN,    0x01);
+  write_both_9862s (REG_TX_PWR_DN,    0x0f);   // pwr dn digital and analog_both
+  write_both_9862s (REG_TX_MODULATOR, 0x00);   // coarse & fine modulators disabled
+
+  // zero firmware hash slot
+  i = 0;
+  do {
+    hash0[i] = 0;
+    i++;
+  } while (i != USRP_HASH_SIZE);
+
+  counter = 0;
+  while (1){
+    counter++;
+    if (counter & 0x8000)
+      IOC ^= bmPC_LED0;
+  }
+}
diff --git a/usrp/firmware/src/usrp2/eeprom_io.c b/usrp/firmware/src/usrp2/eeprom_io.c
new file mode 100644 (file)
index 0000000..1aa51a0
--- /dev/null
@@ -0,0 +1,65 @@
+/* -*- 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 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.
+ */
+
+#include "eeprom_io.h"
+#include "i2c.h"
+#include "delay.h"
+
+// returns non-zero if successful, else 0
+unsigned char
+eeprom_read (unsigned char i2c_addr, unsigned char eeprom_offset,
+            xdata unsigned char *buf, unsigned char len)
+{
+  // We setup a random read by first doing a "zero byte write".
+  // Writes carry an address.  Reads use an implicit address.
+
+  static xdata unsigned char cmd[1];
+  cmd[0] = eeprom_offset;
+  if (!i2c_write(i2c_addr, cmd, 1))
+    return 0;
+
+  return i2c_read(i2c_addr, buf, len);
+}
+
+
+#if 0
+
+// returns non-zero if successful, else 0
+unsigned char
+eeprom_write (unsigned char i2c_addr, unsigned char eeprom_offset,
+             const xdata unsigned char *buf, unsigned char len)
+{
+  static xdata unsigned char cmd[2];
+  unsigned char ok;
+
+  while (len-- > 0){
+    cmd[0] = eeprom_offset++;
+    cmd[1] = *buf++;
+    ok = i2c_write(i2c_addr, cmd, 2);
+    mdelay(10);                // delay 10ms worst case write time
+    if (!ok)
+      return 0;
+  }
+  return 1;
+}
+
+#endif
diff --git a/usrp/firmware/src/usrp2/eeprom_io.h b/usrp/firmware/src/usrp2/eeprom_io.h
new file mode 100644 (file)
index 0000000..ece8036
--- /dev/null
@@ -0,0 +1,38 @@
+/* -*- 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 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.
+ */
+
+#ifndef INCLUDED_EEPROM_IO_H
+#define INCLUDED_EEPROM_IO_H
+
+
+// returns non-zero if successful, else 0
+unsigned char
+eeprom_read (unsigned char i2c_addr, unsigned char eeprom_offset,
+            xdata unsigned char *buf, unsigned char len);
+
+// returns non-zero if successful, else 0
+unsigned char
+eeprom_write (unsigned char i2c_addr, unsigned char eeprom_offset,
+             const xdata unsigned char *buf, unsigned char len);
+
+
+#endif /* INCLUDED_EEPROM_IO_H */
diff --git a/usrp/firmware/src/usrp2/fpga_load.c b/usrp/firmware/src/usrp2/fpga_load.c
new file mode 100644 (file)
index 0000000..b0256e9
--- /dev/null
@@ -0,0 +1 @@
+#include "../common/fpga_load.c"
diff --git a/usrp/firmware/src/usrp2/fpga_rev2.c b/usrp/firmware/src/usrp2/fpga_rev2.c
new file mode 100644 (file)
index 0000000..cd282d6
--- /dev/null
@@ -0,0 +1,122 @@
+/* -*- 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 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.
+ */
+
+#include "fpga.h"
+#include "fpga_regs_common.h"
+#include "usrp_common.h"
+#include "usrp_globals.h"
+#include "spi.h"
+
+unsigned char g_tx_reset = 0;
+unsigned char g_rx_reset = 0;
+
+void
+fpga_write_reg (unsigned char regno, const xdata unsigned char *regval)
+{
+  spi_write (0, 0x00 | (regno & 0x7f),
+            SPI_ENABLE_FPGA,
+            SPI_FMT_MSB | SPI_FMT_HDR_1,
+            regval, 4);
+}
+
+
+static xdata unsigned char regval[4] = {0, 0, 0, 0};
+
+static void
+write_fpga_master_ctrl (void)
+{
+  unsigned char v = 0;
+  if (g_tx_enable)
+    v |= bmFR_MC_ENABLE_TX;
+  if (g_rx_enable)
+    v |= bmFR_MC_ENABLE_RX;
+  if (g_tx_reset)
+    v |= bmFR_MC_RESET_TX;
+  if (g_rx_reset)
+    v |= bmFR_MC_RESET_RX;
+  regval[3] = v;
+
+  fpga_write_reg (FR_MASTER_CTRL, regval);
+}
+
+// Resets both AD9862's and the FPGA serial bus interface.
+
+void
+fpga_set_reset (unsigned char on)
+{
+  on &= 0x1;
+
+  if (on){
+    USRP_PC &= ~bmPC_nRESET;           // active low
+    g_tx_enable = 0;
+    g_rx_enable = 0;
+    g_tx_reset = 0;
+    g_rx_reset = 0;
+  }
+  else
+    USRP_PC |= bmPC_nRESET;
+}
+
+void
+fpga_set_tx_enable (unsigned char on)
+{
+  on &= 0x1;
+  g_tx_enable = on;
+
+  write_fpga_master_ctrl ();
+
+  if (on){
+    g_tx_underrun = 0;
+    fpga_clear_flags ();
+  }
+}
+
+void
+fpga_set_rx_enable (unsigned char on)
+{
+  on &= 0x1;
+  g_rx_enable = on;
+  
+  write_fpga_master_ctrl ();
+  if (on){
+    g_rx_overrun = 0;
+    fpga_clear_flags ();
+  }
+}
+
+void
+fpga_set_tx_reset (unsigned char on)
+{
+  on &= 0x1;
+  g_tx_reset = on;
+
+  write_fpga_master_ctrl ();
+}
+
+void
+fpga_set_rx_reset (unsigned char on)
+{
+  on &= 0x1;
+  g_rx_reset = on;
+  
+  write_fpga_master_ctrl ();
+}
diff --git a/usrp/firmware/src/usrp2/fpga_rev2.h b/usrp/firmware/src/usrp2/fpga_rev2.h
new file mode 100644 (file)
index 0000000..6c04271
--- /dev/null
@@ -0,0 +1,58 @@
+/* 
+ * USRP - Universal Software Radio Peripheral
+ *
+ * Copyright (C) 2003,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 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
+ */
+
+#ifndef INCLUDED_FPGA_REV1_H
+#define INCLUDED_FPGA_REV1_H
+
+void fpga_set_reset (unsigned char v);
+void fpga_set_tx_enable (unsigned char v);
+void fpga_set_rx_enable (unsigned char v);
+void fpga_set_tx_reset (unsigned char v);
+void fpga_set_rx_reset (unsigned char v);
+
+unsigned char fpga_has_room_for_packet (void);
+unsigned char fpga_has_packet_avail (void);
+
+#if (UC_BOARD_HAS_FPGA)
+/*
+ * return TRUE iff FPGA internal fifo has room for 512 bytes.
+ */
+#define fpga_has_room_for_packet()     (GPIFREADYSTAT & bmFPGA_HAS_SPACE)
+
+/*
+ * return TRUE iff FPGA internal fifo has at least 512 bytes available.
+ */
+#define fpga_has_packet_avail()                (GPIFREADYSTAT & bmFPGA_PKT_AVAIL)
+
+#else  /* no FPGA on board.  fake it. */
+
+#define fpga_has_room_for_packet()     TRUE
+#define        fpga_has_packet_avail()         TRUE
+
+#endif
+
+#define        fpga_clear_flags()                              \
+       do {                                            \
+         USRP_PE |= bmPE_FPGA_CLR_STATUS;              \
+         USRP_PE &= ~bmPE_FPGA_CLR_STATUS;             \
+        } while (0)
+
+
+#endif /* INCLUDED_FPGA_REV1_H */
diff --git a/usrp/firmware/src/usrp2/gpif.c b/usrp/firmware/src/usrp2/gpif.c
new file mode 100644 (file)
index 0000000..f6745a4
--- /dev/null
@@ -0,0 +1,292 @@
+// This program configures the General Programmable Interface (GPIF) for FX2.     
+// Please do not modify sections of text which are marked as "DO NOT EDIT ...". 
+//                                                                                
+// DO NOT EDIT ...                  
+// GPIF Initialization              
+// Interface Timing      Async        
+// Internal Ready Init   IntRdy=1     
+// CTL Out Tristate-able Binary       
+// SingleWrite WF Select     1     
+// SingleRead WF Select      0     
+// FifoWrite WF Select       3     
+// FifoRead WF Select        2     
+// Data Bus Idle Drive   Tristate     
+// END DO NOT EDIT                  
+                                    
+// DO NOT EDIT ...       
+// GPIF Wave Names       
+// Wave 0   = singlerd     
+// Wave 1   = singlewr     
+// Wave 2   = FIFORd       
+// Wave 3   = FIFOWr       
+                         
+// GPIF Ctrl Outputs   Level   
+// CTL 0    = WEN#     CMOS        
+// CTL 1    = REN#     CMOS        
+// CTL 2    = OE#      CMOS        
+// CTL 3    = CLRST    CMOS        
+// CTL 4    = unused   CMOS        
+// CTL 5    = BOGUS    CMOS        
+                               
+// GPIF Rdy Inputs         
+// RDY0     = EF#            
+// RDY1     = FF#            
+// RDY2     = unused         
+// RDY3     = unused         
+// RDY4     = unused         
+// RDY5     = TCXpire        
+// FIFOFlag = FIFOFlag       
+// IntReady = IntReady       
+// END DO NOT EDIT         
+// DO NOT EDIT ...                                                                         
+//                                                                                         
+// GPIF Waveform 0: singlerd                                                                
+//                                                                                         
+// Interval     0         1         2         3         4         5         6     Idle (7) 
+//          _________ _________ _________ _________ _________ _________ _________ _________
+//                                                                                         
+// AddrMode Same Val  Same Val  Same Val  Same Val  Same Val  Same Val  Same Val           
+// DataMode NO Data   NO Data   NO Data   NO Data   NO Data   NO Data   NO Data            
+// NextData SameData  SameData  SameData  SameData  SameData  SameData  SameData           
+// Int Trig No Int    No Int    No Int    No Int    No Int    No Int    No Int             
+// IF/Wait  Wait 1    Wait 1    Wait 1    Wait 1    Wait 1    Wait 1    Wait 1             
+//   Term A                                                                                
+//   LFunc                                                                                 
+//   Term B                                                                                
+// Branch1                                                                                 
+// Branch0                                                                                 
+// Re-Exec                                                                                 
+// Sngl/CRC Default   Default   Default   Default   Default   Default   Default            
+// WEN#         0         0         0         0         0         0         0         0    
+// REN#         0         0         0         0         0         0         0         0    
+// OE#          0         0         0         0         0         0         0         0    
+// CLRST        0         0         0         0         0         0         0         0    
+// unused       0         0         0         0         0         0         0         0    
+// BOGUS        0         0         0         0         0         0         0         0    
+//                     
+// END DO NOT EDIT     
+// DO NOT EDIT ...                                                                         
+//                                                                                         
+// GPIF Waveform 1: singlewr                                                                
+//                                                                                         
+// Interval     0         1         2         3         4         5         6     Idle (7) 
+//          _________ _________ _________ _________ _________ _________ _________ _________
+//                                                                                         
+// AddrMode Same Val  Same Val  Same Val  Same Val  Same Val  Same Val  Same Val           
+// DataMode Activate  Activate  Activate  Activate  Activate  Activate  Activate           
+// NextData SameData  SameData  SameData  SameData  SameData  SameData  SameData           
+// Int Trig No Int    No Int    No Int    No Int    No Int    No Int    No Int             
+// IF/Wait  Wait 1    IF        Wait 1    Wait 1    Wait 1    Wait 1    Wait 1             
+//   Term A           EF#                                                                  
+//   LFunc            AND                                                                  
+//   Term B           EF#                                                                  
+// Branch1            ThenIdle                                                             
+// Branch0            ElseIdle                                                             
+// Re-Exec            No                                                                   
+// Sngl/CRC Default   Default   Default   Default   Default   Default   Default            
+// WEN#         0         1         1         1         1         1         1         0    
+// REN#         0         0         0         0         0         0         0         0    
+// OE#          0         0         0         0         0         0         0         0    
+// CLRST        0         0         0         0         0         0         0         0    
+// unused       0         0         0         0         0         0         0         0    
+// BOGUS        0         0         0         0         0         0         0         0    
+//                     
+// END DO NOT EDIT     
+// DO NOT EDIT ...                                                                         
+//                                                                                         
+// GPIF Waveform 2: FIFORd                                                                  
+//                                                                                         
+// Interval     0         1         2         3         4         5         6     Idle (7) 
+//          _________ _________ _________ _________ _________ _________ _________ _________
+//                                                                                         
+// AddrMode Same Val  Same Val  Same Val  Same Val  Same Val  Same Val  Same Val           
+// DataMode NO Data   Activate  NO Data   NO Data   NO Data   NO Data   NO Data            
+// NextData SameData  SameData  SameData  SameData  SameData  SameData  SameData           
+// Int Trig No Int    No Int    No Int    No Int    No Int    No Int    No Int             
+// IF/Wait  Wait 1    IF        Wait 1    IF        Wait 1    Wait 1    Wait 1             
+//   Term A           TCXpire             TCXpire                                          
+//   LFunc            AND                 AND                                              
+//   Term B           TCXpire             TCXpire                                          
+// Branch1            Then 2              ThenIdle                                         
+// Branch0            Else 1              ElseIdle                                         
+// Re-Exec            No                  No                                               
+// Sngl/CRC Default   Default   Default   Default   Default   Default   Default            
+// WEN#         0         0         0         0         0         0         0         0    
+// REN#         1         0         0         0         0         0         0         0    
+// OE#          1         1         1         0         0         0         0         0    
+// CLRST        0         0         0         0         0         0         0         0    
+// unused       0         0         0         0         0         0         0         0    
+// BOGUS        0         0         0         0         0         0         0         0    
+//                     
+// END DO NOT EDIT     
+// DO NOT EDIT ...                                                                         
+//                                                                                         
+// GPIF Waveform 3: FIFOWr                                                                  
+//                                                                                         
+// Interval     0         1         2         3         4         5         6     Idle (7) 
+//          _________ _________ _________ _________ _________ _________ _________ _________
+//                                                                                         
+// AddrMode Same Val  Same Val  Same Val  Same Val  Same Val  Same Val  Same Val           
+// DataMode NO Data   Activate  Activate  Activate  Activate  Activate  Activate           
+// NextData SameData  SameData  SameData  SameData  SameData  SameData  SameData           
+// Int Trig No Int    No Int    No Int    No Int    No Int    No Int    No Int             
+// IF/Wait  Wait 1    IF        Wait 1    Wait 1    Wait 1    Wait 1    Wait 1             
+//   Term A           TCXpire                                                              
+//   LFunc            AND                                                                  
+//   Term B           TCXpire                                                              
+// Branch1            ThenIdle                                                             
+// Branch0            Else 1                                                               
+// Re-Exec            No                                                                   
+// Sngl/CRC Default   Default   Default   Default   Default   Default   Default            
+// WEN#         0         0         0         0         0         0         0         0    
+// REN#         0         0         0         0         0         0         0         0    
+// OE#          0         0         0         0         0         0         0         0    
+// CLRST        0         0         0         0         0         0         0         0    
+// unused       0         0         0         0         0         0         0         0    
+// BOGUS        0         0         0         0         0         0         0         0    
+//                     
+// END DO NOT EDIT     
+                                              
+// GPIF Program Code                          
+                                              
+// DO NOT EDIT ...                            
+#include "fx2.h"                            
+#include "fx2regs.h"                        
+#include "fx2sdly.h"     // SYNCDELAY macro 
+// END DO NOT EDIT                            
+                                              
+// DO NOT EDIT ...                     
+const char xdata WaveData[128] =     
+{                                      
+// Wave 0 
+/* LenBr */ 0x01,     0x01,     0x01,     0x01,     0x01,     0x01,     0x01,     0x07,
+/* Opcode*/ 0x00,     0x00,     0x00,     0x00,     0x00,     0x00,     0x00,     0x00,
+/* Output*/ 0x00,     0x00,     0x00,     0x00,     0x00,     0x00,     0x00,     0x00,
+/* LFun  */ 0x00,     0x00,     0x00,     0x00,     0x00,     0x00,     0x00,     0x3F,
+// Wave 1 
+/* LenBr */ 0x01,     0x3F,     0x01,     0x01,     0x01,     0x01,     0x01,     0x07,
+/* Opcode*/ 0x22,     0x03,     0x02,     0x02,     0x02,     0x02,     0x02,     0x00,
+/* Output*/ 0x00,     0x01,     0x01,     0x01,     0x01,     0x01,     0x01,     0x00,
+/* LFun  */ 0x00,     0x00,     0x00,     0x00,     0x00,     0x00,     0x00,     0x3F,
+// Wave 2 
+/* LenBr */ 0x01,     0x11,     0x01,     0x3F,     0x01,     0x01,     0x01,     0x07,
+/* Opcode*/ 0x00,     0x03,     0x00,     0x01,     0x00,     0x00,     0x00,     0x00,
+/* Output*/ 0x06,     0x04,     0x04,     0x00,     0x00,     0x00,     0x00,     0x00,
+/* LFun  */ 0x00,     0x2D,     0x00,     0x2D,     0x00,     0x00,     0x00,     0x3F,
+// Wave 3 
+/* LenBr */ 0x01,     0x39,     0x01,     0x01,     0x01,     0x01,     0x01,     0x07,
+/* Opcode*/ 0x00,     0x03,     0x02,     0x02,     0x02,     0x02,     0x02,     0x00,
+/* Output*/ 0x00,     0x00,     0x00,     0x00,     0x00,     0x00,     0x00,     0x00,
+/* LFun  */ 0x00,     0x2D,     0x00,     0x00,     0x00,     0x00,     0x00,     0x3F,
+};                     
+// END DO NOT EDIT     
+                       
+// DO NOT EDIT ...                     
+const char xdata FlowStates[36] =   
+{                                      
+/* Wave 0 FlowStates */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+/* Wave 1 FlowStates */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+/* Wave 2 FlowStates */ 0x81,0x2D,0x26,0x00,0x04,0x04,0x03,0x02,0x00,
+/* Wave 3 FlowStates */ 0x81,0x2D,0x21,0x00,0x04,0x04,0x03,0x02,0x00,
+};                     
+// END DO NOT EDIT     
+                       
+// DO NOT EDIT ...                                               
+const char xdata InitData[7] =                                   
+{                                                                
+/* Regs  */ 0xA0,0x00,0x00,0x00,0xEE,0x4E,0x00     
+};                                                               
+// END DO NOT EDIT                                               
+                                                                 
+// TO DO: You may add additional code below.
+
+void GpifInit( void )
+{
+  BYTE i;
+  // Registers which require a synchronization delay, see section 15.14
+  // FIFORESET        FIFOPINPOLAR
+  // INPKTEND         OUTPKTEND
+  // EPxBCH:L         REVCTL
+  // GPIFTCB3         GPIFTCB2
+  // GPIFTCB1         GPIFTCB0
+  // EPxFIFOPFH:L     EPxAUTOINLENH:L
+  // EPxFIFOCFG       EPxGPIFFLGSEL
+  // PINFLAGSxx       EPxFIFOIRQ
+  // EPxFIFOIE        GPIFIRQ
+  // GPIFIE           GPIFADRH:L
+  // UDMACRCH:L       EPxGPIFTRIG
+  // GPIFTRIG
+  
+  // Note: The pre-REVE EPxGPIFTCH/L register are affected, as well...
+  //      ...these have been replaced by GPIFTC[B3:B0] registers
+  // 8051 doesn't have access to waveform memories 'til
+  // the part is in GPIF mode.
+  IFCONFIG = 0xEE;
+  // IFCLKSRC=1   , FIFOs executes on internal clk source
+  // xMHz=1       , 48MHz internal clk rate
+  // IFCLKOE=0    , Don't drive IFCLK pin signal at 48MHz
+  // IFCLKPOL=0   , Don't invert IFCLK pin signal from internal clk
+  // ASYNC=1      , master samples asynchronous
+  // GSTATE=1     , Drive GPIF states out on PORTE[2:0], debug WF
+  // IFCFG[1:0]=10, FX2 in GPIF master mode
+  GPIFABORT = 0xFF;  // abort any waveforms pending
+  GPIFREADYCFG = InitData[ 0 ];
+  GPIFCTLCFG = InitData[ 1 ];
+  GPIFIDLECS = InitData[ 2 ];
+  GPIFIDLECTL = InitData[ 3 ];
+  GPIFWFSELECT = InitData[ 5 ];
+  GPIFREADYSTAT = InitData[ 6 ];
+  // use dual autopointer feature... 
+  AUTOPTRSETUP = 0x07;          // inc both pointers, 
+                                // ...warning: this introduces pdata hole(s)
+                                // ...at E67B (XAUTODAT1) and E67C (XAUTODAT2)
+  
+  // source
+  AUTOPTRH1 = MSB( &WaveData );
+  AUTOPTRL1 = LSB( &WaveData );
+  
+  // destination
+  AUTOPTRH2 = 0xE4;
+  AUTOPTRL2 = 0x00;
+  // transfer
+  for ( i = 0x00; i < 128; i++ )
+  {
+    EXTAUTODAT2 = EXTAUTODAT1;
+  }
+// Configure GPIF Address pins, output initial value,
+  PORTCCFG = 0xFF;    // [7:0] as alt. func. GPIFADR[7:0]
+  OEC = 0xFF;         // and as outputs
+  PORTECFG |= 0x80;   // [8] as alt. func. GPIFADR[8]
+  OEE |= 0x80;        // and as output
+// ...OR... tri-state GPIFADR[8:0] pins
+//  PORTCCFG = 0x00;  // [7:0] as port I/O
+//  OEC = 0x00;       // and as inputs
+//  PORTECFG &= 0x7F; // [8] as port I/O
+//  OEE &= 0x7F;      // and as input
+// GPIF address pins update when GPIFADRH/L written
+  SYNCDELAY;                    // 
+  GPIFADRH = 0x00;    // bits[7:1] always 0
+  SYNCDELAY;                    // 
+  GPIFADRL = 0x00;    // point to PERIPHERAL address 0x0000
+// Configure GPIF FlowStates registers for Wave 0 of WaveData
+  FLOWSTATE = FlowStates[ 0 ];
+  FLOWLOGIC = FlowStates[ 1 ];
+  FLOWEQ0CTL = FlowStates[ 2 ];
+  FLOWEQ1CTL = FlowStates[ 3 ];
+  FLOWHOLDOFF = FlowStates[ 4 ];
+  FLOWSTB = FlowStates[ 5 ];
+  FLOWSTBEDGE = FlowStates[ 6 ];
+  FLOWSTBHPERIOD = FlowStates[ 7 ];
+}
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/firmware/src/usrp2/init_gpif.c b/usrp/firmware/src/usrp2/init_gpif.c
new file mode 100644 (file)
index 0000000..0f5944b
--- /dev/null
@@ -0,0 +1 @@
+#include "../common/init_gpif.c"
diff --git a/usrp/firmware/src/usrp2/spi.c b/usrp/firmware/src/usrp2/spi.c
new file mode 100644 (file)
index 0000000..0c6abb4
--- /dev/null
@@ -0,0 +1,381 @@
+/* -*- 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 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.
+ */
+
+#include "spi.h"
+#include "usrp_rev2_regs.h"
+
+static void
+setup_enables (unsigned char enables)
+{
+  // Software eanbles are active high.
+  // Hardware enables are active low.
+
+  // Uhh, the CODECs are active low, but the FPGA is active high...
+  enables ^= SPI_ENABLE_FPGA;
+
+  // KLUDGE: This code is fragile, but reasonably fast...
+  // low three bits of enables go into port A
+  USRP_PA = USRP_PA | (0x7 << 3);      // disable FPGA, CODEC_A, CODEC_B
+  USRP_PA ^= (enables & 0x7) << 3;     // enable specified devs
+
+  // high four bits of enables go into port E
+  USRP_PE = USRP_PE | (0xf << 4);      // disable TX_A, RX_A, TX_B, RX_B
+  USRP_PE ^= (enables & 0xf0);         // enable specified devs
+}
+
+#define disable_all()  setup_enables (0)
+
+void
+init_spi (void)
+{
+  disable_all ();              /* disable all devs       */
+  bitS_OUT = 0;                        /* idle state has CLK = 0 */
+}
+
+#if 0
+static unsigned char
+count_bits8 (unsigned char v)
+{
+  static unsigned char count4[16] = {
+    0, // 0
+    1, // 1
+    1, // 2
+    2, // 3
+    1, // 4
+    2, // 5
+    2, // 6
+    3, // 7
+    1, // 8
+    2, // 9
+    2, // a
+    3, // b
+    2, // c
+    3, // d
+    3, // e
+    4  // f
+  };
+  return count4[v & 0xf] + count4[(v >> 4) & 0xf];
+}
+
+#else
+
+static unsigned char
+count_bits8 (unsigned char v)
+{
+  unsigned char count = 0;
+  if (v & (1 << 0)) count++;
+  if (v & (1 << 1)) count++;
+  if (v & (1 << 2)) count++;
+  if (v & (1 << 3)) count++;
+  if (v & (1 << 4)) count++;
+  if (v & (1 << 5)) count++;
+  if (v & (1 << 6)) count++;
+  if (v & (1 << 7)) count++;
+  return count;
+}
+#endif
+
+static void
+write_byte_msb (unsigned char v);
+
+static void
+write_bytes_msb (const xdata unsigned char *buf, unsigned char len);
+
+static void
+read_bytes_msb (xdata unsigned char *buf, unsigned char len);
+
+  
+// returns non-zero if successful, else 0
+unsigned char
+spi_read (unsigned char header_hi, unsigned char header_lo,
+         unsigned char enables, unsigned char format,
+         xdata unsigned char *buf, unsigned char len)
+{
+  if (count_bits8 (enables) > 1)
+    return 0;          // error, too many enables set
+
+  setup_enables (enables);
+
+  if (format & SPI_FMT_LSB){           // order: LSB
+#if 1
+    return 0;          // error, not implemented
+#else
+    switch (format & SPI_FMR_HDR_MASK){
+    case SPI_FMT_HDR_0:
+      break;
+    case SPI_FMT_HDR_1:
+      write_byte_lsb (header_lo);
+      break;
+    case SPI_FMT_HDR_2:
+      write_byte_lsb (header_lo);
+      write_byte_lsb (header_hi);
+      break;
+    default:
+      return 0;                // error
+    }
+    if (len != 0)
+      read_bytes_lsb (buf, len);
+#endif
+  }
+
+  else {               // order: MSB
+
+    switch (format & SPI_FMT_HDR_MASK){
+    case SPI_FMT_HDR_0:
+      break;
+    case SPI_FMT_HDR_1:
+      write_byte_msb (header_lo);
+      break;
+    case SPI_FMT_HDR_2:
+      write_byte_msb (header_hi);
+      write_byte_msb (header_lo);
+      break;
+    default:
+      return 0;                // error
+    }
+    if (len != 0)
+      read_bytes_msb (buf, len);
+  }
+
+  disable_all ();
+  return 1;            // success
+}
+
+
+// returns non-zero if successful, else 0
+unsigned char
+spi_write (unsigned char header_hi, unsigned char header_lo,
+          unsigned char enables, unsigned char format,
+          const xdata unsigned char *buf, unsigned char len)
+{
+  setup_enables (enables);
+
+  if (format & SPI_FMT_LSB){           // order: LSB
+#if 1
+    return 0;          // error, not implemented
+#else
+    switch (format & SPI_FMR_HDR_MASK){
+    case SPI_FMT_HDR_0:
+      break;
+    case SPI_FMT_HDR_1:
+      write_byte_lsb (header_lo);
+      break;
+    case SPI_FMT_HDR_2:
+      write_byte_lsb (header_lo);
+      write_byte_lsb (header_hi);
+      break;
+    default:
+      return 0;                // error
+    }
+    if (len != 0)
+      write_bytes_lsb (buf, len);
+#endif
+  }
+
+  else {               // order: MSB
+
+    switch (format & SPI_FMT_HDR_MASK){
+    case SPI_FMT_HDR_0:
+      break;
+    case SPI_FMT_HDR_1:
+      write_byte_msb (header_lo);
+      break;
+    case SPI_FMT_HDR_2:
+      write_byte_msb (header_hi);
+      write_byte_msb (header_lo);
+      break;
+    default:
+      return 0;                // error
+    }
+    if (len != 0)
+      write_bytes_msb (buf, len);
+  }
+
+  disable_all ();
+  return 1;            // success
+}
+
+// ----------------------------------------------------------------
+
+static void
+write_byte_msb (unsigned char v)
+{
+  v = (v << 1) | (v >> 7);     // rotate left (MSB into bottom bit)
+  bitS_OUT = v & 0x1;
+  bitS_CLK = 1;
+  bitS_CLK = 0;
+
+  v = (v << 1) | (v >> 7);     // rotate left (MSB into bottom bit)
+  bitS_OUT = v & 0x1;
+  bitS_CLK = 1;
+  bitS_CLK = 0;
+
+  v = (v << 1) | (v >> 7);     // rotate left (MSB into bottom bit)
+  bitS_OUT = v & 0x1;
+  bitS_CLK = 1;
+  bitS_CLK = 0;
+
+  v = (v << 1) | (v >> 7);     // rotate left (MSB into bottom bit)
+  bitS_OUT = v & 0x1;
+  bitS_CLK = 1;
+  bitS_CLK = 0;
+
+  v = (v << 1) | (v >> 7);     // rotate left (MSB into bottom bit)
+  bitS_OUT = v & 0x1;
+  bitS_CLK = 1;
+  bitS_CLK = 0;
+
+  v = (v << 1) | (v >> 7);     // rotate left (MSB into bottom bit)
+  bitS_OUT = v & 0x1;
+  bitS_CLK = 1;
+  bitS_CLK = 0;
+
+  v = (v << 1) | (v >> 7);     // rotate left (MSB into bottom bit)
+  bitS_OUT = v & 0x1;
+  bitS_CLK = 1;
+  bitS_CLK = 0;
+
+  v = (v << 1) | (v >> 7);     // rotate left (MSB into bottom bit)
+  bitS_OUT = v & 0x1;
+  bitS_CLK = 1;
+  bitS_CLK = 0;
+}
+
+static void
+write_bytes_msb (const xdata unsigned char *buf, unsigned char len)
+{
+  while (len-- != 0){
+    write_byte_msb (*buf++);
+  }
+}
+
+#if 0
+/*
+ * This is incorrectly compiled by SDCC 2.4.0
+ */
+static unsigned char
+read_byte_msb (void)
+{
+  unsigned char v = 0;
+
+  bitS_CLK = 1;
+  v |= bitS_IN;
+  bitS_CLK = 0;
+
+  v = v << 1;
+  bitS_CLK = 1;
+  v |= bitS_IN;
+  bitS_CLK = 0;
+
+  v = v << 1;
+  bitS_CLK = 1;
+  v |= bitS_IN;
+  bitS_CLK = 0;
+
+  v = v << 1;
+  bitS_CLK = 1;
+  v |= bitS_IN;
+  bitS_CLK = 0;
+
+  v = v << 1;
+  bitS_CLK = 1;
+  v |= bitS_IN;
+  bitS_CLK = 0;
+
+  v = v << 1;
+  bitS_CLK = 1;
+  v |= bitS_IN;
+  bitS_CLK = 0;
+
+  v = v << 1;
+  bitS_CLK = 1;
+  v |= bitS_IN;
+  bitS_CLK = 0;
+
+  v = v << 1;
+  bitS_CLK = 1;
+  v |= bitS_IN;
+  bitS_CLK = 0;
+
+  return v;
+}
+#else
+static unsigned char
+read_byte_msb (void) _naked
+{
+  _asm
+       clr     a
+
+       setb    _bitS_CLK
+        mov    c, _bitS_IN
+       rlc     a
+       clr     _bitS_CLK
+
+       setb    _bitS_CLK
+        mov    c, _bitS_IN
+       rlc     a
+       clr     _bitS_CLK
+
+       setb    _bitS_CLK
+        mov    c, _bitS_IN
+       rlc     a
+       clr     _bitS_CLK
+
+       setb    _bitS_CLK
+        mov    c, _bitS_IN
+       rlc     a
+       clr     _bitS_CLK
+
+       setb    _bitS_CLK
+        mov    c, _bitS_IN
+       rlc     a
+       clr     _bitS_CLK
+
+       setb    _bitS_CLK
+        mov    c, _bitS_IN
+       rlc     a
+       clr     _bitS_CLK
+
+       setb    _bitS_CLK
+        mov    c, _bitS_IN
+       rlc     a
+       clr     _bitS_CLK
+
+       setb    _bitS_CLK
+        mov    c, _bitS_IN
+       rlc     a
+       clr     _bitS_CLK
+
+       mov     dpl,a
+       ret
+  _endasm;
+}
+#endif
+
+static void
+read_bytes_msb (xdata unsigned char *buf, unsigned char len)
+{
+  while (len-- != 0){
+    *buf++ = read_byte_msb ();
+  }
+}
+
diff --git a/usrp/firmware/src/usrp2/spi.h b/usrp/firmware/src/usrp2/spi.h
new file mode 100644 (file)
index 0000000..b17126d
--- /dev/null
@@ -0,0 +1,43 @@
+/* -*- 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 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.
+ */
+
+#ifndef INCLUDED_SPI_H
+#define INCLUDED_SPI_H
+
+#include "usrp_spi_defs.h"
+
+void init_spi (void);          // one time call to init
+
+// returns non-zero if successful, else 0
+unsigned char
+spi_read (unsigned char header_hi, unsigned char header_lo,
+         unsigned char enables, unsigned char format,
+         xdata unsigned char *buf, unsigned char len);
+
+// returns non-zero if successful, else 0
+unsigned char
+spi_write (unsigned char header_hi, unsigned char header_lo,
+          unsigned char enables, unsigned char format,
+          const xdata unsigned char *buf, unsigned char len);
+
+
+#endif /* INCLUDED_SPI_H */
diff --git a/usrp/firmware/src/usrp2/usb_descriptors.a51 b/usrp/firmware/src/usrp2/usb_descriptors.a51
new file mode 100644 (file)
index 0000000..06a92f5
--- /dev/null
@@ -0,0 +1,404 @@
+;;; -*- 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 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.
+;;;
+       
+;;; USB Descriptor table for the USRP
+;;; 
+;;; We're a high-speed only device (480 Mb/sec) with 1 configuration
+;;; and 3 interfaces.  
+;;; 
+;;;    interface 0:    command and status (ep0 COMMAND)
+;;;    interface 1:    Transmit path (ep2 OUT BULK)
+;;;    interface 2:    Receive path (ep6 IN BULK)
+
+       .module usb_descriptors
+       
+       VID_FREE         = 0xfffe       ; Free Software Folks
+       PID_USRP         = 0x0002       ; USRP
+
+       ;; We distinguish configured from unconfigured USRPs using the Device ID.
+       ;; If the MSB of the DID is 0, the device is unconfigured.
+       ;; The LSB of the DID is reserved for hardware revs.
+       
+       DID_USRP         = 0x0100       ; Device ID (bcd)
+
+       
+       DSCR_DEVICE      =   1  ; Descriptor type: Device
+       DSCR_CONFIG      =   2  ; Descriptor type: Configuration
+       DSCR_STRING      =   3  ; Descriptor type: String
+       DSCR_INTRFC      =   4  ; Descriptor type: Interface
+       DSCR_ENDPNT      =   5  ; Descriptor type: Endpoint
+       DSCR_DEVQUAL     =   6  ; Descriptor type: Device Qualifier
+       
+       DSCR_DEVICE_LEN  =  18
+       DSCR_CONFIG_LEN  =   9
+       DSCR_INTRFC_LEN  =   9
+       DSCR_ENDPNT_LEN  =   7
+       DSCR_DEVQUAL_LEN =  10
+       
+       ET_CONTROL       =   0  ; Endpoint type: Control
+       ET_ISO           =   1  ; Endpoint type: Isochronous
+       ET_BULK          =   2  ; Endpoint type: Bulk
+       ET_INT           =   3  ; Endpoint type: Interrupt
+       
+       
+       ;; configuration attributes
+       bmSELF_POWERED  =       1 << 6
+
+;;; --------------------------------------------------------
+;;;    external ram data
+;;;--------------------------------------------------------
+       
+       .area USBDESCSEG    (XDATA)
+       
+;;; ----------------------------------------------------------------
+;;; descriptors used when operating at high speed (480Mb/sec)
+;;; ----------------------------------------------------------------
+       
+       .even   ; descriptors must be 2-byte aligned for SUDPTR{H,L} to work
+
+       ;; The .even directive isn't really honored by the linker.  Bummer!
+       ;; (There's no way to specify an alignment requirement for a given area,
+       ;; hence when they're concatenated together, even doesn't work.)
+       ;; 
+       ;; We work around this by telling the linker to put USBDESCSEG
+       ;; at 0xE000 absolute.  This means that the maximimum length of this
+       ;; segment is 480 bytes, leaving room for the two hash slots 
+       ;; at 0xE1EO to 0xE1FF.  
+       ;; 
+       ;; As of July 7, 2004, this segment is 326 bytes long
+       
+_high_speed_device_descr::
+       .db     DSCR_DEVICE_LEN
+       .db     DSCR_DEVICE
+       .db     <0x0200         ; Specification version (LSB)
+       .db     >0x0200         ; Specification version (MSB)
+       .db     0xff            ; device class (vendor specific)
+       .db     0xff            ; device subclass (vendor specific)
+       .db     0xff            ; device protocol (vendor specific)
+       .db     64              ; bMaxPacketSize0 for endpoint 0
+       .db     <VID_FREE       ; idVendor
+       .db     >VID_FREE       ; idVendor
+       .db     <PID_USRP       ; idProduct
+       .db     >PID_USRP       ; idProduct
+_usb_desc_hw_rev_binary_patch_location_0::
+       .db     <DID_USRP       ; bcdDevice
+       .db     >DID_USRP       ; bcdDevice
+       .db     SI_VENDOR       ; iManufacturer (string index)
+       .db     SI_PRODUCT      ; iProduct (string index)
+       .db     SI_SERIAL       ; iSerial number (string index)
+       .db     1               ; bNumConfigurations
+       
+;;; describes the other speed (12Mb/sec)
+       .even
+_high_speed_devqual_descr::
+       .db     DSCR_DEVQUAL_LEN
+       .db     DSCR_DEVQUAL
+       .db     <0x0200         ; bcdUSB (LSB)
+       .db     >0x0200         ; bcdUSB (MSB)
+       .db     0xff            ; bDeviceClass
+       .db     0xff            ; bDeviceSubClass
+       .db     0xff            ; bDeviceProtocol
+       .db     64              ; bMaxPacketSize0
+       .db     1               ; bNumConfigurations (one config at 12Mb/sec)
+       .db     0               ; bReserved
+       
+       .even
+_high_speed_config_descr::     
+       .db     DSCR_CONFIG_LEN
+       .db     DSCR_CONFIG
+       .db     <(_high_speed_config_descr_end - _high_speed_config_descr) ; LSB
+       .db     >(_high_speed_config_descr_end - _high_speed_config_descr) ; MSB
+       .db     3               ; bNumInterfaces
+       .db     1               ; bConfigurationValue
+       .db     0               ; iConfiguration
+       .db     0x80 | bmSELF_POWERED ; bmAttributes
+       .db     0               ; bMaxPower
+
+       ;; interface descriptor 0 (command & status, ep0 COMMAND)
+       
+       .db     DSCR_INTRFC_LEN
+       .db     DSCR_INTRFC
+       .db     0               ; bInterfaceNumber (zero based)
+       .db     0               ; bAlternateSetting
+       .db     0               ; bNumEndpoints
+       .db     0xff            ; bInterfaceClass (vendor specific)
+       .db     0xff            ; bInterfaceSubClass (vendor specific)
+       .db     0xff            ; bInterfaceProtocol (vendor specific)
+       .db     SI_COMMAND_AND_STATUS   ; iInterface (description)
+
+       ;; interface descriptor 1 (transmit path, ep2 OUT BULK)
+       
+       .db     DSCR_INTRFC_LEN
+       .db     DSCR_INTRFC
+       .db     1               ; bInterfaceNumber (zero based)
+       .db     0               ; bAlternateSetting
+       .db     1               ; bNumEndpoints
+       .db     0xff            ; bInterfaceClass (vendor specific)
+       .db     0xff            ; bInterfaceSubClass (vendor specific)
+       .db     0xff            ; bInterfaceProtocol (vendor specific)
+       .db     SI_TX_PATH      ; iInterface (description)
+
+       ;; interface 1's end point
+
+       .db     DSCR_ENDPNT_LEN
+       .db     DSCR_ENDPNT
+       .db     0x02            ; bEndpointAddress (ep 2 OUT)
+       .db     ET_BULK         ; bmAttributes
+       .db     <512            ; wMaxPacketSize (LSB)
+       .db     >512            ; wMaxPacketSize (MSB)
+       .db     0               ; bInterval (iso only)
+
+       ;; interface descriptor 2 (receive path, ep6 IN BULK)
+       
+       .db     DSCR_INTRFC_LEN
+       .db     DSCR_INTRFC
+       .db     2               ; bInterfaceNumber (zero based)
+       .db     0               ; bAlternateSetting
+       .db     1               ; bNumEndpoints
+       .db     0xff            ; bInterfaceClass (vendor specific)
+       .db     0xff            ; bInterfaceSubClass (vendor specific)
+       .db     0xff            ; bInterfaceProtocol (vendor specific)
+       .db     SI_RX_PATH      ; iInterface (description)
+
+       ;; interface 2's end point
+
+       .db     DSCR_ENDPNT_LEN
+       .db     DSCR_ENDPNT
+       .db     0x86            ; bEndpointAddress (ep 6 IN)
+       .db     ET_BULK         ; bmAttributes
+       .db     <512            ; wMaxPacketSize (LSB)
+       .db     >512            ; wMaxPacketSize (MSB)
+       .db     0               ; bInterval (iso only)
+
+_high_speed_config_descr_end:          
+
+;;; ----------------------------------------------------------------
+;;; descriptors used when operating at full speed (12Mb/sec)
+;;; ----------------------------------------------------------------
+
+       .even
+_full_speed_device_descr::     
+       .db     DSCR_DEVICE_LEN
+       .db     DSCR_DEVICE
+       .db     <0x0200         ; Specification version (LSB)
+       .db     >0x0200         ; Specification version (MSB)
+       .db     0xff            ; device class (vendor specific)
+       .db     0xff            ; device subclass (vendor specific)
+       .db     0xff            ; device protocol (vendor specific)
+       .db     64              ; bMaxPacketSize0 for endpoint 0
+       .db     <VID_FREE       ; idVendor
+       .db     >VID_FREE       ; idVendor
+       .db     <PID_USRP       ; idProduct
+       .db     >PID_USRP       ; idProduct
+_usb_desc_hw_rev_binary_patch_location_1::
+       .db     <DID_USRP       ; bcdDevice
+       .db     >DID_USRP       ; bcdDevice
+       .db     SI_VENDOR       ; iManufacturer (string index)
+       .db     SI_PRODUCT      ; iProduct (string index)
+       .db     SI_NONE         ; iSerial number (None)
+       .db     1               ; bNumConfigurations
+       
+       
+;;; describes the other speed (480Mb/sec)
+       .even
+_full_speed_devqual_descr::
+       .db     DSCR_DEVQUAL_LEN
+       .db     DSCR_DEVQUAL
+       .db     <0x0200         ; bcdUSB
+       .db     >0x0200         ; bcdUSB
+       .db     0xff            ; bDeviceClass
+       .db     0xff            ; bDeviceSubClass
+       .db     0xff            ; bDeviceProtocol
+       .db     64              ; bMaxPacketSize0
+       .db     1               ; bNumConfigurations (one config at 480Mb/sec)
+       .db     0               ; bReserved
+       
+       .even
+_full_speed_config_descr::     
+       .db     DSCR_CONFIG_LEN
+       .db     DSCR_CONFIG
+       .db     <(_full_speed_config_descr_end - _full_speed_config_descr) ; LSB
+       .db     >(_full_speed_config_descr_end - _full_speed_config_descr) ; MSB
+       .db     1               ; bNumInterfaces
+       .db     1               ; bConfigurationValue
+       .db     0               ; iConfiguration
+       .db     0x80 | bmSELF_POWERED ; bmAttributes
+       .db     0               ; bMaxPower
+
+       ;; interface descriptor 0 (command & status, ep0 COMMAND)
+       
+       .db     DSCR_INTRFC_LEN
+       .db     DSCR_INTRFC
+       .db     0               ; bInterfaceNumber (zero based)
+       .db     0               ; bAlternateSetting
+       .db     0               ; bNumEndpoints
+       .db     0xff            ; bInterfaceClass (vendor specific)
+       .db     0xff            ; bInterfaceSubClass (vendor specific)
+       .db     0xff            ; bInterfaceProtocol (vendor specific)
+       .db     SI_COMMAND_AND_STATUS   ; iInterface (description)
+       
+_full_speed_config_descr_end:  
+       
+;;; ----------------------------------------------------------------
+;;;                    string descriptors
+;;; ----------------------------------------------------------------
+
+_nstring_descriptors::
+       .db     (_string_descriptors_end - _string_descriptors) / 2
+
+_string_descriptors::
+       .db     <str0, >str0
+       .db     <str1, >str1
+       .db     <str2, >str2
+       .db     <str3, >str3
+       .db     <str4, >str4
+       .db     <str5, >str5
+       .db     <str6, >str6
+_string_descriptors_end:
+
+       SI_NONE = 0
+       ;; str0 contains the language ID's.
+       .even
+str0:  .db     str0_end - str0
+       .db     DSCR_STRING
+       .db     0
+       .db     0
+       .db     <0x0409         ; magic code for US English (LSB)
+       .db     >0x0409         ; magic code for US English (MSB)
+str0_end:
+
+       SI_VENDOR = 1
+       .even
+str1:  .db     str1_end - str1
+       .db     DSCR_STRING
+       .db     'F, 0           ; 16-bit unicode
+       .db     'r, 0
+       .db     'e, 0
+       .db     'e, 0
+       .db     ' , 0
+       .db     'S, 0
+       .db     'o, 0
+       .db     'f, 0
+       .db     't, 0
+       .db     'w, 0
+       .db     'a, 0
+       .db     'r, 0
+       .db     'e, 0
+       .db     ' , 0
+       .db     'F, 0
+       .db     'o, 0
+       .db     'l, 0
+       .db     'k, 0
+       .db     's, 0
+str1_end:
+
+       SI_PRODUCT = 2
+       .even
+str2:  .db     str2_end - str2
+       .db     DSCR_STRING
+       .db     'U, 0
+       .db     'S, 0
+       .db     'R, 0
+       .db     'P, 0
+       .db     ' , 0
+       .db     'R, 0
+       .db     'e, 0
+       .db     'v, 0
+       .db     ' , 0
+_usb_desc_hw_rev_ascii_patch_location_0::
+       .db     '?, 0
+str2_end:
+
+       SI_COMMAND_AND_STATUS = 3
+       .even
+str3:  .db     str3_end - str3
+       .db     DSCR_STRING
+       .db     'C, 0
+       .db     'o, 0
+       .db     'm, 0
+       .db     'm, 0
+       .db     'a, 0
+       .db     'n, 0
+       .db     'd, 0
+       .db     ' , 0
+       .db     '&, 0
+       .db     ' , 0
+       .db     'S, 0
+       .db     't, 0
+       .db     'a, 0
+       .db     't, 0
+       .db     'u, 0
+       .db     's, 0
+str3_end:
+
+       SI_TX_PATH = 4
+       .even
+str4:  .db     str4_end - str4
+       .db     DSCR_STRING
+       .db     'T, 0
+       .db     'r, 0
+       .db     'a, 0
+       .db     'n, 0
+       .db     's, 0
+       .db     'm, 0
+       .db     'i, 0
+       .db     't, 0
+       .db     ' , 0
+       .db     'P, 0
+       .db     'a, 0
+       .db     't, 0
+       .db     'h, 0
+str4_end:
+
+       SI_RX_PATH = 5
+       .even
+str5:  .db     str5_end - str5
+       .db     DSCR_STRING
+       .db     'R, 0
+       .db     'e, 0
+       .db     'c, 0
+       .db     'e, 0
+       .db     'i, 0
+       .db     'v, 0
+       .db     'e, 0
+       .db     ' , 0
+       .db     'P, 0
+       .db     'a, 0
+       .db     't, 0
+       .db     'h, 0
+str5_end:
+
+       SI_SERIAL = 6
+       .even
+str6:  .db     str6_end - str6
+       .db     DSCR_STRING
+_usb_desc_serial_number_ascii::
+       .db     '3, 0
+       .db     '., 0
+       .db     '1, 0
+       .db     '4, 0
+       .db     '1, 0
+       .db     '5, 0
+       .db     '9, 0
+       .db     '3, 0
+str6_end:
+
diff --git a/usrp/firmware/src/usrp2/usrp_common.c b/usrp/firmware/src/usrp2/usrp_common.c
new file mode 100644 (file)
index 0000000..f389d92
--- /dev/null
@@ -0,0 +1 @@
+#include "../common/usrp_common.c"
diff --git a/usrp/firmware/src/usrp2/usrp_common.h b/usrp/firmware/src/usrp2/usrp_common.h
new file mode 100644 (file)
index 0000000..5625b42
--- /dev/null
@@ -0,0 +1,77 @@
+/* 
+ * USRP - Universal Software Radio Peripheral
+ *
+ * Copyright (C) 2003,2006 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
+ */
+
+/*
+ * common defines and prototypes for USRP
+ *
+ * In comments below "TRM" refers to the EZ-USB FX2 Technical Reference Manual
+ */
+
+#ifndef _USRPCOMMON_H_
+#define _USRPCOMMON_H_
+
+#include <usrp_config.h>
+#include <usrp_rev2_regs.h>
+#include <syncdelay.h>
+
+/*
+ * From TRM page 15-105:
+ *
+ * Under certain conditions, some read and write access to the FX2
+ * registers must be separated by a "synchronization delay".  The
+ * delay is necessary only under the following conditions:
+ *
+ *   - between a write to any register in the 0xE600 - 0xE6FF range 
+ *     and a write to one of the registers listed below.
+ *
+ *   - between a write to one of the registers listed below and a read 
+ *     from any register in the 0xE600 - 0xE6FF range.
+ *
+ *   Registers which require a synchronization delay:
+ *
+ *     FIFORESET                       FIFOPINPOLAR
+ *     INPKTEND                        EPxBCH:L
+ *     EPxFIFOPFH:L                    EPxAUTOINLENH:L
+ *     EPxFIFOCFG                      EPxGPIFFLGSEL
+ *     PINFLAGSAB                      PINFLAGSCD
+ *     EPxFIFOIE                       EPxFIFOIRQ
+ *     GPIFIE                          GPIFIRQ
+ *     UDMACRCH:L                      GPIFADRH:L
+ *     GPIFTRIG                        EPxGPIFTRIG
+ *     OUTPKTEND                       REVCTL
+ *     GPIFTCB3                        GPIFTCB2
+ *     GPIFTCB1                        GPIFTCB0
+ */
+
+#define        TRUE            1
+#define        FALSE           0
+
+
+void init_usrp (void);
+void init_gpif (void);
+
+void set_led_0 (unsigned char on);
+void set_led_1 (unsigned char on);
+void toggle_led_0 (void);
+void toggle_led_1 (void);
+
+#define la_trace(v)
+
+#endif /* _USRPCOMMON_H_ */
diff --git a/usrp/firmware/src/usrp2/usrp_main.c b/usrp/firmware/src/usrp2/usrp_main.c
new file mode 100644 (file)
index 0000000..0dbba8e
--- /dev/null
@@ -0,0 +1,380 @@
+/* 
+ * USRP - Universal Software Radio Peripheral
+ *
+ * Copyright (C) 2003,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 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
+ */
+
+#include "usrp_common.h"
+#include "usrp_commands.h"
+#include "fpga.h"
+#include "usrp_gpif_inline.h"
+#include "timer.h"
+#include "i2c.h"
+#include "isr.h"
+#include "usb_common.h"
+#include "fx2utils.h"
+#include "usrp_globals.h"
+#include "usrp_i2c_addr.h"
+#include <string.h>
+#include "spi.h"
+#include "eeprom_io.h"
+#include "usb_descriptors.h"
+
+/*
+ * offsets into boot eeprom for configuration values
+ */
+#define        HW_REV_OFFSET             5
+#define SERIAL_NO_OFFSET       248
+#define SERIAL_NO_LEN            8
+
+
+#define        bRequestType    SETUPDAT[0]
+#define        bRequest        SETUPDAT[1]
+#define        wValueL         SETUPDAT[2]
+#define        wValueH         SETUPDAT[3]
+#define        wIndexL         SETUPDAT[4]
+#define        wIndexH         SETUPDAT[5]
+#define        wLengthL        SETUPDAT[6]
+#define        wLengthH        SETUPDAT[7]
+
+
+unsigned char g_tx_enable = 0;
+unsigned char g_rx_enable = 0;
+unsigned char g_rx_overrun = 0;
+unsigned char g_tx_underrun = 0;
+
+/*
+ * the host side fpga loader code pushes an MD5 hash of the bitstream
+ * into hash1.
+ */
+#define          USRP_HASH_SIZE      16
+xdata at USRP_HASH_SLOT_1_ADDR unsigned char hash1[USRP_HASH_SIZE];
+
+static void
+get_ep0_data (void)
+{
+  EP0BCL = 0;                  // arm EP0 for OUT xfer.  This sets the busy bit
+
+  while (EP0CS & bmEPBUSY)     // wait for busy to clear
+    ;
+}
+
+/*
+ * Handle our "Vendor Extension" commands on endpoint 0.
+ * If we handle this one, return non-zero.
+ */
+unsigned char
+app_vendor_cmd (void)
+{
+  if (bRequestType == VRT_VENDOR_IN){
+
+    /////////////////////////////////
+    //    handle the IN requests
+    /////////////////////////////////
+
+    switch (bRequest){
+
+    case VRQ_GET_STATUS:
+      switch (wIndexL){
+
+      case GS_TX_UNDERRUN:
+       EP0BUF[0] = g_tx_underrun;
+       g_tx_underrun = 0;
+       EP0BCH = 0;
+       EP0BCL = 1;
+       break;
+
+      case GS_RX_OVERRUN:
+       EP0BUF[0] = g_rx_overrun;
+       g_rx_overrun = 0;
+       EP0BCH = 0;
+       EP0BCL = 1;
+       break;
+
+      default:
+       return 0;
+      }
+      break;
+
+    case VRQ_I2C_READ:
+      if (!i2c_read (wValueL, EP0BUF, wLengthL))
+       return 0;
+
+      EP0BCH = 0;
+      EP0BCL = wLengthL;
+      break;
+      
+    case VRQ_SPI_READ:
+      if (!spi_read (wValueH, wValueL, wIndexH, wIndexL, EP0BUF, wLengthL))
+       return 0;
+
+      EP0BCH = 0;
+      EP0BCL = wLengthL;
+      break;
+
+    default:
+      return 0;
+    }
+  }
+
+  else if (bRequestType == VRT_VENDOR_OUT){
+
+    /////////////////////////////////
+    //    handle the OUT requests
+    /////////////////////////////////
+
+    switch (bRequest){
+
+    case VRQ_SET_LED:
+      switch (wIndexL){
+      case 0:
+       set_led_0 (wValueL);
+       break;
+       
+      case 1:
+       set_led_1 (wValueL);
+       break;
+       
+      default:
+       return 0;
+      }
+      break;
+      
+    case VRQ_FPGA_LOAD:
+      switch (wIndexL){                        // sub-command
+      case FL_BEGIN:
+       return fpga_load_begin ();
+       
+      case FL_XFER:
+       get_ep0_data ();
+       return fpga_load_xfer (EP0BUF, EP0BCL);
+       
+      case FL_END:
+       return fpga_load_end ();
+       
+      default:
+       return 0;
+      }
+      break;
+      
+
+    case VRQ_FPGA_SET_RESET:
+      fpga_set_reset (wValueL);
+      break;
+      
+    case VRQ_FPGA_SET_TX_ENABLE:
+      fpga_set_tx_enable (wValueL);
+      break;
+      
+    case VRQ_FPGA_SET_RX_ENABLE:
+      fpga_set_rx_enable (wValueL);
+      break;
+
+    case VRQ_FPGA_SET_TX_RESET:
+      fpga_set_tx_reset (wValueL);
+      break;
+      
+    case VRQ_FPGA_SET_RX_RESET:
+      fpga_set_rx_reset (wValueL);
+      break;
+
+    case VRQ_I2C_WRITE:
+      get_ep0_data ();
+      if (!i2c_write (wValueL, EP0BUF, EP0BCL))
+       return 0;
+      break;
+
+    case VRQ_SPI_WRITE:
+      get_ep0_data ();
+      if (!spi_write (wValueH, wValueL, wIndexH, wIndexL, EP0BUF, EP0BCL))
+       return 0;
+      break;
+
+    default:
+      return 0;
+    }
+
+  }
+  else
+    return 0;    // invalid bRequestType
+
+  return 1;
+}
+
+
+
+static void
+main_loop (void)
+{
+  setup_flowstate_common ();
+
+  while (1){
+
+    if (usb_setup_packet_avail ())
+      usb_handle_setup_packet ();
+    
+  
+    if (GPIFTRIG & bmGPIF_IDLE){
+
+      // OK, GPIF is idle.  Let's try to give it some work.
+
+      // First check for underruns and overruns
+
+      if (UC_BOARD_HAS_FPGA && (USRP_PA & (bmPA_TX_UNDERRUN | bmPA_RX_OVERRUN))){
+      
+       // record the under/over run
+       if (USRP_PA & bmPA_TX_UNDERRUN)
+         g_tx_underrun = 1;
+
+       if (USRP_PA & bmPA_RX_OVERRUN)
+         g_rx_overrun = 1;
+
+       // tell the FPGA to clear the flags
+       fpga_clear_flags ();
+      }
+
+      // Next see if there are any "OUT" packets waiting for our attention,
+      // and if so, if there's room in the FPGA's FIFO for them.
+
+      if (g_tx_enable && !(EP24FIFOFLGS & 0x02)){  // USB end point fifo is not empty...
+
+       if (fpga_has_room_for_packet ()){          // ... and FPGA has room for packet
+
+         GPIFTCB1 = 0x01;      SYNCDELAY;
+         GPIFTCB0 = 0x00;      SYNCDELAY;
+
+         setup_flowstate_write ();
+
+         SYNCDELAY;
+         GPIFTRIG = bmGPIF_EP2_START | bmGPIF_WRITE;   // start the xfer
+         SYNCDELAY;
+
+         while (!(GPIFTRIG & bmGPIF_IDLE)){
+           // wait for the transaction to complete
+         }
+       }
+      }
+
+      // See if there are any requests for "IN" packets, and if so
+      // whether the FPGA's got any packets for us.
+
+      if (g_rx_enable && !(EP6CS & bmEPFULL)){ // USB end point fifo is not full...
+
+       if (fpga_has_packet_avail ()){          // ... and FPGA has packet available
+
+         GPIFTCB1 = 0x01;      SYNCDELAY;
+         GPIFTCB0 = 0x00;      SYNCDELAY;
+
+         setup_flowstate_read ();
+
+         SYNCDELAY;
+         GPIFTRIG = bmGPIF_EP6_START | bmGPIF_READ;    // start the xfer
+         SYNCDELAY;
+
+         while (!(GPIFTRIG & bmGPIF_IDLE)){
+           // wait for the transaction to complete
+         }
+
+         SYNCDELAY;
+         INPKTEND = 6; // tell USB we filled buffer (6 is our endpoint num)
+       }
+      }
+    }
+  }
+}
+
+
+/*
+ * called at 100 Hz from timer2 interrupt
+ *
+ * Toggle led 0
+ */
+void
+isr_tick (void) interrupt
+{
+  static unsigned char count = 1;
+  
+  if (--count == 0){
+    count = 50;
+    USRP_LED_REG ^= bmLED0;
+  }
+
+  clear_timer_irq ();
+}
+
+/*
+ * Read h/w rev code and serial number out of boot eeprom and
+ * patch the usb descriptors with the values.
+ */
+void
+patch_usb_descriptors(void)
+{
+  static xdata unsigned char hw_rev;
+  static xdata unsigned char serial_no[8];
+  unsigned char i;
+
+  eeprom_read(I2C_ADDR_BOOT, HW_REV_OFFSET, &hw_rev, 1);       // LSB of device id
+  usb_desc_hw_rev_binary_patch_location_0[0] = hw_rev;
+  usb_desc_hw_rev_binary_patch_location_1[0] = hw_rev;
+  usb_desc_hw_rev_ascii_patch_location_0[0] = hw_rev + '0';     // FIXME if we get > 9
+
+  eeprom_read(I2C_ADDR_BOOT, SERIAL_NO_OFFSET, serial_no, SERIAL_NO_LEN);
+
+  for (i = 0; i < SERIAL_NO_LEN; i++){
+    unsigned char ch = serial_no[i];
+    if (ch == 0xff)    // make unprogrammed EEPROM default to '0'
+      ch = '0';
+    usb_desc_serial_number_ascii[i << 1] = ch;
+  }
+}
+
+void
+main (void)
+{
+#if 0
+  g_rx_enable = 0;     // FIXME (work around initialization bug)
+  g_tx_enable = 0;
+  g_rx_overrun = 0;
+  g_tx_underrun = 0;
+#endif
+
+  memset (hash1, 0, USRP_HASH_SIZE);   // zero fpga bitstream hash.  This forces reload
+  
+  init_usrp ();
+  init_gpif ();
+  
+  // if (UC_START_WITH_GSTATE_OUTPUT_ENABLED)
+  IFCONFIG |= bmGSTATE;                        // no conflict, start with it on
+
+  set_led_0 (0);
+  set_led_1 (0);
+  
+  EA = 0;              // disable all interrupts
+
+  patch_usb_descriptors();
+
+  setup_autovectors ();
+  usb_install_handlers ();
+  hook_timer_tick ((unsigned short) isr_tick);
+
+  EIEX4 = 1;           // disable INT4 FIXME
+  EA = 1;              // global interrupt enable
+
+  fx2_renumerate ();   // simulates disconnect / reconnect
+
+  main_loop ();
+}
diff --git a/usrp/firmware/src/usrp2/usrp_rev2_regs.h b/usrp/firmware/src/usrp2/usrp_rev2_regs.h
new file mode 100644 (file)
index 0000000..e18003f
--- /dev/null
@@ -0,0 +1,163 @@
+/*
+ * USRP - Universal Software Radio Peripheral
+ *
+ * Copyright (C) 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 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
+ */
+
+/*
+ * These are the register definitions for the Rev 1 USRP prototype
+ * The Rev 1 is the version with the AD9862's and daughterboards
+ */
+
+#ifndef _USRP_REV1_REGS_H_
+#define _USRP_REV1_REGS_H_
+
+#include "fx2regs.h"
+
+/*
+ * Port A (bit addressable):
+ */
+
+#define USRP_PA                        IOA             // Port A
+#define        USRP_PA_OE              OEA             // Port A direction register
+
+#define bmPA_S_CLK             bmBIT0          // SPI serial clock
+#define        bmPA_S_DATA_TO_PERIPH   bmBIT1          // SPI SDI (peripheral rel name)
+#define bmPA_S_DATA_FROM_PERIPH        bmBIT2          // SPI SDO (peripheral rel name)
+#define bmPA_SEN_FPGA          bmBIT3          // serial enable for FPGA (active low)
+#define        bmPA_SEN_CODEC_A        bmBIT4          // serial enable AD9862 A (active low)
+#define        bmPA_SEN_CODEC_B        bmBIT5          // serial enable AD9862 B (active low)
+//#define bmPA_FX2_2           bmBIT6          // misc pin to FPGA (overflow)
+//#define bmPA_FX2_3           bmBIT7          // misc pin to FPGA (underflow)
+#define        bmPA_RX_OVERRUN         bmBIT6          // misc pin to FPGA (overflow)
+#define        bmPA_TX_UNDERRUN        bmBIT7          // misc pin to FPGA (underflow)
+
+
+sbit at 0x80+0 bitS_CLK;               // 0x80 is the bit address of PORT A
+sbit at 0x80+1 bitS_OUT;               // out from FX2 point of view
+sbit at 0x80+2 bitS_IN;                        // in from FX2 point of view
+
+
+/* all outputs except S_DATA_FROM_PERIPH, FX2_2, FX2_3 */
+
+#define        bmPORT_A_OUTPUTS  (bmPA_S_CLK                   \
+                          | bmPA_S_DATA_TO_PERIPH      \
+                          | bmPA_SEN_FPGA              \
+                          | bmPA_SEN_CODEC_A           \
+                          | bmPA_SEN_CODEC_B           \
+                          )
+
+#define        bmPORT_A_INITIAL   (bmPA_SEN_FPGA | bmPA_SEN_CODEC_A | bmPA_SEN_CODEC_B)
+
+
+/* Port B: GPIF        FD[7:0]                 */
+
+/*
+ * Port C (bit addressable):
+ *    5:1 FPGA configuration
+ */
+
+#define        USRP_PC                 IOC             // Port C
+#define        USRP_PC_OE              OEC             // Port C direction register
+
+#define        USRP_ALTERA_CONFIG      USRP_PC
+
+#define        bmPC_nRESET             bmBIT0          // reset line to codecs (active low)
+#define bmALTERA_DATA0         bmBIT1
+#define bmALTERA_NCONFIG       bmBIT2
+#define bmALTERA_DCLK          bmBIT3
+#define bmALTERA_CONF_DONE     bmBIT4
+#define bmALTERA_NSTATUS       bmBIT5
+#define        bmPC_LED0               bmBIT6          // active low
+#define        bmPC_LED1               bmBIT7          // active low
+
+sbit at 0xA0+1 bitALTERA_DATA0;                // 0xA0 is the bit address of PORT C
+sbit at 0xA0+3 bitALTERA_DCLK;
+
+
+#define        bmALTERA_BITS           (bmALTERA_DATA0                 \
+                                | bmALTERA_NCONFIG             \
+                                | bmALTERA_DCLK                \
+                                | bmALTERA_CONF_DONE           \
+                                | bmALTERA_NSTATUS)
+
+#define        bmPORT_C_OUTPUTS        (bmPC_nRESET                    \
+                                | bmALTERA_DATA0               \
+                                | bmALTERA_NCONFIG             \
+                                | bmALTERA_DCLK                \
+                                | bmPC_LED0                    \
+                                | bmPC_LED1                    \
+                                )
+
+#define        bmPORT_C_INITIAL        (bmPC_LED0 | bmPC_LED1)
+
+
+#define        USRP_LED_REG            USRP_PC
+#define        bmLED0                  bmPC_LED0
+#define        bmLED1                  bmPC_LED1
+
+
+/* Port D: GPIF        FD[15:8]                */
+
+/* Port E: not bit addressible         */
+
+#define        USRP_PE                 IOE             // Port E
+#define        USRP_PE_OE              OEE             // Port E direction register
+
+#define bmPE_PE0               bmBIT0          // GPIF debug output
+#define        bmPE_PE1                bmBIT1          // GPIF debug output
+#define        bmPE_PE2                bmBIT2          // GPIF debug output
+#define        bmPE_FPGA_CLR_STATUS    bmBIT3          // misc pin to FPGA (clear status)
+#define        bmPE_SEN_TX_A           bmBIT4          // serial enable d'board TX A (active low)
+#define        bmPE_SEN_RX_A           bmBIT5          // serial enable d'board RX A (active low)
+#define        bmPE_SEN_TX_B           bmBIT6          // serial enable d'board TX B (active low)
+#define bmPE_SEN_RX_B          bmBIT7          // serial enable d'board RX B (active low)
+
+
+#define        bmPORT_E_OUTPUTS        (bmPE_FPGA_CLR_STATUS   \
+                                | bmPE_SEN_TX_A        \
+                                | bmPE_SEN_RX_A        \
+                                | bmPE_SEN_TX_B        \
+                                | bmPE_SEN_RX_B        \
+                                )
+
+
+#define        bmPORT_E_INITIAL        (bmPE_SEN_TX_A          \
+                                | bmPE_SEN_RX_A        \
+                                | bmPE_SEN_TX_B        \
+                                | bmPE_SEN_RX_B        \
+                                )
+
+/*
+ * FPGA output lines that are tied to FX2 RDYx inputs.
+ * These are readable using GPIFREADYSTAT.
+ */
+#define        bmFPGA_HAS_SPACE                bmBIT0  // usbrdy[0] has room for 512 byte packet
+#define        bmFPGA_PKT_AVAIL                bmBIT1  // usbrdy[1] has >= 512 bytes available
+// #define     bmTX_UNDERRUN                   bmBIT2  // usbrdy[2] D/A ran out of data
+// #define     bmRX_OVERRUN                    bmBIT3  // usbrdy[3] A/D ran out of buffer
+
+/*
+ * FPGA input lines that are tied to the FX2 CTLx outputs.
+ *
+ * These are controlled by the GPIF microprogram...
+ */
+// WR                                  bmBIT0  // usbctl[0]
+// RD                                  bmBIT1  // usbctl[1]
+// OE                                  bmBIT2  // usbctl[2]
+
+#endif /* _USRP_REV1_REGS_H_ */
diff --git a/usrp/firmware/src/usrp2/vectors.a51 b/usrp/firmware/src/usrp2/vectors.a51
new file mode 100644 (file)
index 0000000..fa579ba
--- /dev/null
@@ -0,0 +1 @@
+       .include "../common/vectors.a51"
diff --git a/usrp/fpga/Makefile.am b/usrp/fpga/Makefile.am
new file mode 100644 (file)
index 0000000..61227f0
--- /dev/null
@@ -0,0 +1,24 @@
+#
+# Copyright 2004,2005,2006 Free Software Foundation, Inc.
+# 
+# This file is part of GNU Radio
+# 
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 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.
+# 
+
+SUBDIRS = rbf
+
+include Makefile.extra
diff --git a/usrp/fpga/Makefile.extra b/usrp/fpga/Makefile.extra
new file mode 100644 (file)
index 0000000..c3ccaa0
--- /dev/null
@@ -0,0 +1,150 @@
+EXTRA_DIST =                                           \
+       gen_makefile_extra.py                          \
+       megacells/accum32.bsf                          \
+       megacells/accum32.cmp                          \
+       megacells/accum32.inc                          \
+       megacells/accum32.v                            \
+       megacells/accum32_bb.v                         \
+       megacells/accum32_inst.v                       \
+       megacells/add32.bsf                            \
+       megacells/add32.cmp                            \
+       megacells/add32.inc                            \
+       megacells/add32.v                              \
+       megacells/add32_bb.v                           \
+       megacells/add32_inst.v                         \
+       megacells/addsub16.bsf                         \
+       megacells/addsub16.cmp                         \
+       megacells/addsub16.inc                         \
+       megacells/addsub16.v                           \
+       megacells/addsub16_bb.v                        \
+       megacells/addsub16_inst.v                      \
+       megacells/bustri.bsf                           \
+       megacells/bustri.cmp                           \
+       megacells/bustri.inc                           \
+       megacells/bustri.v                             \
+       megacells/bustri_bb.v                          \
+       megacells/bustri_inst.v                        \
+       megacells/clk_doubler.v                        \
+       megacells/clk_doubler_bb.v                     \
+       megacells/dspclkpll.v                          \
+       megacells/dspclkpll_bb.v                       \
+       megacells/fifo_2k.v                            \
+       megacells/fifo_2k_bb.v                         \
+       megacells/fifo_4k.v                            \
+       megacells/fifo_4k_bb.v                         \
+       megacells/mylpm_addsub.bsf                     \
+       megacells/mylpm_addsub.cmp                     \
+       megacells/mylpm_addsub.inc                     \
+       megacells/mylpm_addsub.v                       \
+       megacells/mylpm_addsub_bb.v                    \
+       megacells/mylpm_addsub_inst.v                  \
+       megacells/pll.v                                \
+       megacells/pll_bb.v                             \
+       megacells/pll_inst.v                           \
+       megacells/sub32.bsf                            \
+       megacells/sub32.cmp                            \
+       megacells/sub32.inc                            \
+       megacells/sub32.v                              \
+       megacells/sub32_bb.v                           \
+       megacells/sub32_inst.v                         \
+       models/bustri.v                                \
+       models/fifo.v                                  \
+       models/fifo_1c_1k.v                            \
+       models/fifo_1c_2k.v                            \
+       models/fifo_1c_4k.v                            \
+       models/fifo_1k.v                               \
+       models/fifo_2k.v                               \
+       models/fifo_4k.v                               \
+       models/pll.v                                   \
+       models/ssram.v                                 \
+       sdr_lib/adc_interface.v                        \
+       sdr_lib/bidir_reg.v                            \
+       sdr_lib/bus_interface.v                        \
+       sdr_lib/cic_decim.v                            \
+       sdr_lib/cic_int_shifter.v                      \
+       sdr_lib/cic_interp.v                           \
+       sdr_lib/clk_divider.v                          \
+       sdr_lib/cordic.v                               \
+       sdr_lib/cordic_stage.v                         \
+       sdr_lib/ddc.v                                  \
+       sdr_lib/dpram.v                                \
+       sdr_lib/duc.v                                  \
+       sdr_lib/ext_fifo.v                             \
+       sdr_lib/gen_cordic_consts.py                   \
+       sdr_lib/gen_sync.v                             \
+       sdr_lib/hb/acc.v                               \
+       sdr_lib/hb/coeff_ram.v                         \
+       sdr_lib/hb/coeff_rom.v                         \
+       sdr_lib/hb/halfband_decim.v                    \
+       sdr_lib/hb/halfband_interp.v                   \
+       sdr_lib/hb/hbd_tb/test_hbd.v                   \
+       sdr_lib/hb/mac.v                               \
+       sdr_lib/hb/mult.v                              \
+       sdr_lib/hb/ram16_2port.v                       \
+       sdr_lib/hb/ram16_2sum.v                        \
+       sdr_lib/hb/ram32_2sum.v                        \
+       sdr_lib/io_pins.v                              \
+       sdr_lib/master_control.v                       \
+       sdr_lib/master_control_multi.v                 \
+       sdr_lib/phase_acc.v                            \
+       sdr_lib/ram.v                                  \
+       sdr_lib/ram16.v                                \
+       sdr_lib/ram32.v                                \
+       sdr_lib/ram64.v                                \
+       sdr_lib/rx_buffer.v                            \
+       sdr_lib/rx_chain.v                             \
+       sdr_lib/rx_chain_dual.v                        \
+       sdr_lib/rx_dcoffset.v                          \
+       sdr_lib/serial_io.v                            \
+       sdr_lib/setting_reg.v                          \
+       sdr_lib/setting_reg_masked.v                   \
+       sdr_lib/sign_extend.v                          \
+       sdr_lib/strobe_gen.v                           \
+       sdr_lib/tx_buffer.v                            \
+       sdr_lib/tx_chain.v                             \
+       sdr_lib/tx_chain_hb.v                          \
+       tb/cbus_tb.v                                   \
+       tb/cordic_tb.v                                 \
+       tb/decim_tb.v                                  \
+       tb/fullchip_tb.v                               \
+       tb/interp_tb.v                                 \
+       tb/justinterp_tb.v                             \
+       tb/usrp_tasks.v                                \
+       toplevel/mrfm/biquad_2stage.v                  \
+       toplevel/mrfm/biquad_6stage.v                  \
+       toplevel/mrfm/mrfm.csf                         \
+       toplevel/mrfm/mrfm.esf                         \
+       toplevel/mrfm/mrfm.psf                         \
+       toplevel/mrfm/mrfm.py                          \
+       toplevel/mrfm/mrfm.qpf                         \
+       toplevel/mrfm/mrfm.qsf                         \
+       toplevel/mrfm/mrfm.v                           \
+       toplevel/mrfm/mrfm.vh                          \
+       toplevel/mrfm/mrfm_compensator.v               \
+       toplevel/mrfm/mrfm_fft.py                      \
+       toplevel/mrfm/mrfm_proc.v                      \
+       toplevel/mrfm/shifter.v                        \
+       toplevel/sizetest/sizetest.csf                 \
+       toplevel/sizetest/sizetest.psf                 \
+       toplevel/sizetest/sizetest.v                   \
+       toplevel/usrp_multi/usrp_multi.csf             \
+       toplevel/usrp_multi/usrp_multi.esf             \
+       toplevel/usrp_multi/usrp_multi.psf             \
+       toplevel/usrp_multi/usrp_multi.qpf             \
+       toplevel/usrp_multi/usrp_multi.qsf             \
+       toplevel/usrp_multi/usrp_multi.v               \
+       toplevel/usrp_multi/usrp_multi.vh              \
+       toplevel/usrp_multi/usrp_multi_config_2rx_0tx.vh   \
+       toplevel/usrp_multi/usrp_multi_config_2rxhb_0tx.vh \
+       toplevel/usrp_multi/usrp_multi_config_2rxhb_2tx.vh \
+       toplevel/usrp_multi/usrp_multi_config_4rx_0tx.vh   \
+       toplevel/usrp_multi/usrp_std.vh                \
+       toplevel/usrp_std/usrp_std.csf                 \
+       toplevel/usrp_std/usrp_std.esf                 \
+       toplevel/usrp_std/usrp_std.psf                 \
+       toplevel/usrp_std/usrp_std.qpf                 \
+       toplevel/usrp_std/usrp_std.qsf                 \
+       toplevel/usrp_std/usrp_std.v                   \
+       toplevel/usrp_std/usrp_std.vh                  \
+       toplevel/usrp_std/usrp_std_config_2rxhb_2tx.vh \
+       toplevel/usrp_std/usrp_std_config_4rx_0tx.vh
diff --git a/usrp/fpga/TODO b/usrp/fpga/TODO
new file mode 100644 (file)
index 0000000..76287c3
--- /dev/null
@@ -0,0 +1,23 @@
+
+
+Area Reduction
+==============
+Reduce one or both stages of dec/interp to max rate of 8 instead of 16
+Optimize CICs to minimize registers
+Reduce width of RX CORDIC
+Fix CORDIC wasted logic cells from bad synthesis
+Progressively narrow x,y,z on CORDIC
+16-bit wide FIFOs, split IQ/channels on other side (?)
+
+Enhancements
+============
+Halfband filter in Spartan 3
+Muxing of inputs
+Switch over to newfc
+RAM interface?
+
+Other
+=====
+Capture/Transmit straight samples (no DUC/DDC)
+
+
diff --git a/usrp/fpga/gen_makefile_extra.py b/usrp/fpga/gen_makefile_extra.py
new file mode 100755 (executable)
index 0000000..165a849
--- /dev/null
@@ -0,0 +1,67 @@
+#!/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 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.
+# 
+
+"""
+Generate Makefile.extra
+"""
+
+import sys
+import os.path
+
+extensions_we_like = (
+    '.v', '.vh',
+    '.csf', '.esf', '.psf', '.qpf', '.qsf', 
+    '.inc', '.cmp', '.bsf',
+    '.py')
+
+def visit(keepers, dirname, names):
+    if 'rbf' in names:
+        names.remove('rbf')
+    if 'CVS' in names:
+        names.remove('CVS')
+    
+    if dirname == '.':
+        dirname = ''
+    if dirname.startswith('./'):
+        dirname = dirname[2:]
+    
+    for n in names:
+        base, ext = os.path.splitext(n)
+        if ext in extensions_we_like:
+            keepers.append(os.path.join(dirname, n))
+
+def generate(f):
+    keepers = []
+    os.path.walk('.', visit, keepers)
+    keepers.sort()
+    write_keepers(keepers, f)
+
+def write_keepers(files, outf):
+    m = reduce(max, map(len, files), 0)
+    e = 'EXTRA_DIST ='
+    outf.write('%s%s \\\n' % (e, (m-len(e)+8) * ' '))
+    for f in files[:-1]:
+        outf.write('\t%s%s \\\n' % (f, (m-len(f)) * ' '))
+    outf.write('\t%s\n' % (files[-1],))
+
+if __name__ == '__main__':
+    generate(open('Makefile.extra','w'))
diff --git a/usrp/fpga/megacells/accum32.bsf b/usrp/fpga/megacells/accum32.bsf
new file mode 100755 (executable)
index 0000000..494a820
--- /dev/null
@@ -0,0 +1,86 @@
+/*
+WARNING: Do NOT edit the input and output ports in this file in a text
+editor if you plan to continue editing the block that represents it in
+the Block Editor! File corruption is VERY likely to occur.
+*/
+/*
+Copyright (C) 1991-2003 Altera Corporation
+Any  megafunction  design,  and related netlist (encrypted  or  decrypted),
+support information,  device programming or simulation file,  and any other
+associated  documentation or information  provided by  Altera  or a partner
+under  Altera's   Megafunction   Partnership   Program  may  be  used  only
+to program  PLD  devices (but not masked  PLD  devices) from  Altera.   Any
+other  use  of such  megafunction  design,  netlist,  support  information,
+device programming or simulation file,  or any other  related documentation
+or information  is prohibited  for  any  other purpose,  including, but not
+limited to  modification,  reverse engineering,  de-compiling, or use  with
+any other  silicon devices,  unless such use is  explicitly  licensed under
+a separate agreement with  Altera  or a megafunction partner.  Title to the
+intellectual property,  including patents,  copyrights,  trademarks,  trade
+secrets,  or maskworks,  embodied in any such megafunction design, netlist,
+support  information,  device programming or simulation file,  or any other
+related documentation or information provided by  Altera  or a megafunction
+partner, remains with Altera, the megafunction partner, or their respective
+licensors. No other licenses, including any licenses needed under any third
+party's intellectual property, are provided herein.
+*/
+(header "symbol" (version "1.1"))
+(symbol
+       (rect 0 0 240 120)
+       (text "accum32" (rect 87 2 166 21)(font "Arial" (font_size 10)))
+       (text "inst" (rect 8 101 31 116)(font "Arial" ))
+       (port
+               (pt 0 40)
+               (input)
+               (text "data[31..0]" (rect 0 0 73 16)(font "Arial" (font_size 8)))
+               (text "data[31..0]" (rect 20 24 82 40)(font "Arial" (font_size 8)))
+               (line (pt 0 40)(pt 16 40)(line_width 3))
+       )
+       (port
+               (pt 0 56)
+               (input)
+               (text "clock" (rect 0 0 36 16)(font "Arial" (font_size 8)))
+               (text "clock" (rect 20 40 51 56)(font "Arial" (font_size 8)))
+               (line (pt 0 56)(pt 16 56)(line_width 1))
+       )
+       (port
+               (pt 0 72)
+               (input)
+               (text "clken" (rect 0 0 36 16)(font "Arial" (font_size 8)))
+               (text "clken" (rect 20 56 51 72)(font "Arial" (font_size 8)))
+               (line (pt 0 72)(pt 16 72)(line_width 1))
+       )
+       (port
+               (pt 0 96)
+               (input)
+               (text "aclr" (rect 0 0 24 16)(font "Arial" (font_size 8)))
+               (text "aclr" (rect 20 80 41 96)(font "Arial" (font_size 8)))
+               (line (pt 0 96)(pt 16 96)(line_width 1))
+       )
+       (port
+               (pt 240 56)
+               (output)
+               (text "result[31..0]" (rect 0 0 81 16)(font "Arial" (font_size 8)))
+               (text "result[31..0]" (rect 152 40 221 56)(font "Arial" (font_size 8)))
+               (line (pt 240 56)(pt 224 56)(line_width 3))
+       )
+       (drawing
+               (text "acc" (rect 102 48 123 64)(font "Arial" (font_size 8)))
+               (text "SIGNED" (rect 177 18 214 32)(font "Arial" ))
+               (line (pt 16 16)(pt 224 16)(line_width 1))
+               (line (pt 16 16)(pt 16 104)(line_width 1))
+               (line (pt 16 104)(pt 224 104)(line_width 1))
+               (line (pt 224 16)(pt 224 104)(line_width 1))
+               (line (pt 88 24)(pt 136 48)(line_width 1))
+               (line (pt 136 64)(pt 136 48)(line_width 1))
+               (line (pt 88 88)(pt 136 64)(line_width 1))
+               (line (pt 88 24)(pt 88 88)(line_width 1))
+               (line (pt 16 40)(pt 88 40)(line_width 1))
+               (line (pt 16 56)(pt 88 56)(line_width 1))
+               (line (pt 136 56)(pt 224 56)(line_width 1))
+               (line (pt 16 72)(pt 88 72)(line_width 1))
+               (line (pt 16 72)(pt 88 72)(line_width 1))
+               (line (pt 16 96)(pt 104 96)(line_width 1))
+               (line (pt 104 96)(pt 104 80)(line_width 1))
+       )
+)
diff --git a/usrp/fpga/megacells/accum32.cmp b/usrp/fpga/megacells/accum32.cmp
new file mode 100755 (executable)
index 0000000..55b5fdc
--- /dev/null
@@ -0,0 +1,31 @@
+--Copyright (C) 1991-2003 Altera Corporation
+--Any  megafunction  design,  and related netlist (encrypted  or  decrypted),
+--support information,  device programming or simulation file,  and any other
+--associated  documentation or information  provided by  Altera  or a partner
+--under  Altera's   Megafunction   Partnership   Program  may  be  used  only
+--to program  PLD  devices (but not masked  PLD  devices) from  Altera.   Any
+--other  use  of such  megafunction  design,  netlist,  support  information,
+--device programming or simulation file,  or any other  related documentation
+--or information  is prohibited  for  any  other purpose,  including, but not
+--limited to  modification,  reverse engineering,  de-compiling, or use  with
+--any other  silicon devices,  unless such use is  explicitly  licensed under
+--a separate agreement with  Altera  or a megafunction partner.  Title to the
+--intellectual property,  including patents,  copyrights,  trademarks,  trade
+--secrets,  or maskworks,  embodied in any such megafunction design, netlist,
+--support  information,  device programming or simulation file,  or any other
+--related documentation or information provided by  Altera  or a megafunction
+--partner, remains with Altera, the megafunction partner, or their respective
+--licensors. No other licenses, including any licenses needed under any third
+--party's intellectual property, are provided herein.
+
+
+component accum32
+       PORT
+       (
+               data            : IN STD_LOGIC_VECTOR (31 DOWNTO 0);
+               clock           : IN STD_LOGIC  := '0';
+               clken           : IN STD_LOGIC  := '1';
+               aclr            : IN STD_LOGIC  := '0';
+               result          : OUT STD_LOGIC_VECTOR (31 DOWNTO 0)
+       );
+end component;
diff --git a/usrp/fpga/megacells/accum32.inc b/usrp/fpga/megacells/accum32.inc
new file mode 100755 (executable)
index 0000000..6c66900
--- /dev/null
@@ -0,0 +1,32 @@
+--Copyright (C) 1991-2003 Altera Corporation
+--Any  megafunction  design,  and related netlist (encrypted  or  decrypted),
+--support information,  device programming or simulation file,  and any other
+--associated  documentation or information  provided by  Altera  or a partner
+--under  Altera's   Megafunction   Partnership   Program  may  be  used  only
+--to program  PLD  devices (but not masked  PLD  devices) from  Altera.   Any
+--other  use  of such  megafunction  design,  netlist,  support  information,
+--device programming or simulation file,  or any other  related documentation
+--or information  is prohibited  for  any  other purpose,  including, but not
+--limited to  modification,  reverse engineering,  de-compiling, or use  with
+--any other  silicon devices,  unless such use is  explicitly  licensed under
+--a separate agreement with  Altera  or a megafunction partner.  Title to the
+--intellectual property,  including patents,  copyrights,  trademarks,  trade
+--secrets,  or maskworks,  embodied in any such megafunction design, netlist,
+--support  information,  device programming or simulation file,  or any other
+--related documentation or information provided by  Altera  or a megafunction
+--partner, remains with Altera, the megafunction partner, or their respective
+--licensors. No other licenses, including any licenses needed under any third
+--party's intellectual property, are provided herein.
+
+
+FUNCTION accum32 
+(
+       data[31..0],
+       clock,
+       clken,
+       aclr
+)
+
+RETURNS (
+       result[31..0]
+);
diff --git a/usrp/fpga/megacells/accum32.v b/usrp/fpga/megacells/accum32.v
new file mode 100755 (executable)
index 0000000..ce50cbb
--- /dev/null
@@ -0,0 +1,765 @@
+// megafunction wizard: %ALTACCUMULATE%CBX%
+// GENERATION: STANDARD
+// VERSION: WM1.0
+// MODULE: altaccumulate 
+
+// ============================================================
+// File Name: accum32.v
+// Megafunction Name(s):
+//                     altaccumulate
+// ============================================================
+// ************************************************************
+// THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE!
+// ************************************************************
+
+
+//Copyright (C) 1991-2003 Altera Corporation
+//Any  megafunction  design,  and related netlist (encrypted  or  decrypted),
+//support information,  device programming or simulation file,  and any other
+//associated  documentation or information  provided by  Altera  or a partner
+//under  Altera's   Megafunction   Partnership   Program  may  be  used  only
+//to program  PLD  devices (but not masked  PLD  devices) from  Altera.   Any
+//other  use  of such  megafunction  design,  netlist,  support  information,
+//device programming or simulation file,  or any other  related documentation
+//or information  is prohibited  for  any  other purpose,  including, but not
+//limited to  modification,  reverse engineering,  de-compiling, or use  with
+//any other  silicon devices,  unless such use is  explicitly  licensed under
+//a separate agreement with  Altera  or a megafunction partner.  Title to the
+//intellectual property,  including patents,  copyrights,  trademarks,  trade
+//secrets,  or maskworks,  embodied in any such megafunction design, netlist,
+//support  information,  device programming or simulation file,  or any other
+//related documentation or information provided by  Altera  or a megafunction
+//partner, remains with Altera, the megafunction partner, or their respective
+//licensors. No other licenses, including any licenses needed under any third
+//party's intellectual property, are provided herein.
+
+
+//altaccumulate DEVICE_FAMILY=Cyclone LPM_REPRESENTATION=SIGNED WIDTH_IN=32 WIDTH_OUT=32 aclr clken clock data result
+//VERSION_BEGIN 3.0 cbx_altaccumulate 2003:04:08:16:04:48:SJ cbx_mgl 2003:06:11:11:00:44:SJ cbx_stratix 2003:05:16:10:26:50:SJ  VERSION_END
+
+//synthesis_resources = lut 32 
+module  accum32_accum_nta
+       ( 
+       aclr,
+       clken,
+       clock,
+       data,
+       result) /* synthesis synthesis_clearbox=1 */;
+       input   aclr;
+       input   clken;
+       input   clock;
+       input   [31:0]  data;
+       output   [31:0]  result;
+
+       wire  [0:0]   wire_acc_cella_0cout;
+       wire  [0:0]   wire_acc_cella_1cout;
+       wire  [0:0]   wire_acc_cella_2cout;
+       wire  [0:0]   wire_acc_cella_3cout;
+       wire  [0:0]   wire_acc_cella_4cout;
+       wire  [0:0]   wire_acc_cella_5cout;
+       wire  [0:0]   wire_acc_cella_6cout;
+       wire  [0:0]   wire_acc_cella_7cout;
+       wire  [0:0]   wire_acc_cella_8cout;
+       wire  [0:0]   wire_acc_cella_9cout;
+       wire  [0:0]   wire_acc_cella_10cout;
+       wire  [0:0]   wire_acc_cella_11cout;
+       wire  [0:0]   wire_acc_cella_12cout;
+       wire  [0:0]   wire_acc_cella_13cout;
+       wire  [0:0]   wire_acc_cella_14cout;
+       wire  [0:0]   wire_acc_cella_15cout;
+       wire  [0:0]   wire_acc_cella_16cout;
+       wire  [0:0]   wire_acc_cella_17cout;
+       wire  [0:0]   wire_acc_cella_18cout;
+       wire  [0:0]   wire_acc_cella_19cout;
+       wire  [0:0]   wire_acc_cella_20cout;
+       wire  [0:0]   wire_acc_cella_21cout;
+       wire  [0:0]   wire_acc_cella_22cout;
+       wire  [0:0]   wire_acc_cella_23cout;
+       wire  [0:0]   wire_acc_cella_24cout;
+       wire  [0:0]   wire_acc_cella_25cout;
+       wire  [0:0]   wire_acc_cella_26cout;
+       wire  [0:0]   wire_acc_cella_27cout;
+       wire  [0:0]   wire_acc_cella_28cout;
+       wire  [0:0]   wire_acc_cella_29cout;
+       wire  [0:0]   wire_acc_cella_30cout;
+       wire  [31:0]   wire_acc_cella_dataa;
+       wire  [31:0]   wire_acc_cella_datab;
+       wire  [31:0]   wire_acc_cella_datac;
+       wire  [31:0]   wire_acc_cella_regout;
+       wire sload;
+
+       stratix_lcell   acc_cella_0
+       ( 
+       .aclr(aclr),
+       .cin(1'b0),
+       .clk(clock),
+       .cout(wire_acc_cella_0cout[0:0]),
+       .dataa(wire_acc_cella_dataa[0:0]),
+       .datab(wire_acc_cella_datab[0:0]),
+       .datac(wire_acc_cella_datac[0:0]),
+       .ena(clken),
+       .regout(wire_acc_cella_regout[0:0]),
+       .sload(sload));
+       defparam
+               acc_cella_0.cin_used = "true",
+               acc_cella_0.lut_mask = "96e8",
+               acc_cella_0.operation_mode = "arithmetic",
+               acc_cella_0.sum_lutc_input = "cin",
+               acc_cella_0.synch_mode = "on",
+               acc_cella_0.lpm_type = "stratix_lcell";
+       stratix_lcell   acc_cella_1
+       ( 
+       .aclr(aclr),
+       .cin(wire_acc_cella_0cout[0:0]),
+       .clk(clock),
+       .cout(wire_acc_cella_1cout[0:0]),
+       .dataa(wire_acc_cella_dataa[1:1]),
+       .datab(wire_acc_cella_datab[1:1]),
+       .datac(wire_acc_cella_datac[1:1]),
+       .ena(clken),
+       .regout(wire_acc_cella_regout[1:1]),
+       .sload(sload));
+       defparam
+               acc_cella_1.cin_used = "true",
+               acc_cella_1.lut_mask = "96e8",
+               acc_cella_1.operation_mode = "arithmetic",
+               acc_cella_1.sum_lutc_input = "cin",
+               acc_cella_1.synch_mode = "on",
+               acc_cella_1.lpm_type = "stratix_lcell";
+       stratix_lcell   acc_cella_2
+       ( 
+       .aclr(aclr),
+       .cin(wire_acc_cella_1cout[0:0]),
+       .clk(clock),
+       .cout(wire_acc_cella_2cout[0:0]),
+       .dataa(wire_acc_cella_dataa[2:2]),
+       .datab(wire_acc_cella_datab[2:2]),
+       .datac(wire_acc_cella_datac[2:2]),
+       .ena(clken),
+       .regout(wire_acc_cella_regout[2:2]),
+       .sload(sload));
+       defparam
+               acc_cella_2.cin_used = "true",
+               acc_cella_2.lut_mask = "96e8",
+               acc_cella_2.operation_mode = "arithmetic",
+               acc_cella_2.sum_lutc_input = "cin",
+               acc_cella_2.synch_mode = "on",
+               acc_cella_2.lpm_type = "stratix_lcell";
+       stratix_lcell   acc_cella_3
+       ( 
+       .aclr(aclr),
+       .cin(wire_acc_cella_2cout[0:0]),
+       .clk(clock),
+       .cout(wire_acc_cella_3cout[0:0]),
+       .dataa(wire_acc_cella_dataa[3:3]),
+       .datab(wire_acc_cella_datab[3:3]),
+       .datac(wire_acc_cella_datac[3:3]),
+       .ena(clken),
+       .regout(wire_acc_cella_regout[3:3]),
+       .sload(sload));
+       defparam
+               acc_cella_3.cin_used = "true",
+               acc_cella_3.lut_mask = "96e8",
+               acc_cella_3.operation_mode = "arithmetic",
+               acc_cella_3.sum_lutc_input = "cin",
+               acc_cella_3.synch_mode = "on",
+               acc_cella_3.lpm_type = "stratix_lcell";
+       stratix_lcell   acc_cella_4
+       ( 
+       .aclr(aclr),
+       .cin(wire_acc_cella_3cout[0:0]),
+       .clk(clock),
+       .cout(wire_acc_cella_4cout[0:0]),
+       .dataa(wire_acc_cella_dataa[4:4]),
+       .datab(wire_acc_cella_datab[4:4]),
+       .datac(wire_acc_cella_datac[4:4]),
+       .ena(clken),
+       .regout(wire_acc_cella_regout[4:4]),
+       .sload(sload));
+       defparam
+               acc_cella_4.cin_used = "true",
+               acc_cella_4.lut_mask = "96e8",
+               acc_cella_4.operation_mode = "arithmetic",
+               acc_cella_4.sum_lutc_input = "cin",
+               acc_cella_4.synch_mode = "on",
+               acc_cella_4.lpm_type = "stratix_lcell";
+       stratix_lcell   acc_cella_5
+       ( 
+       .aclr(aclr),
+       .cin(wire_acc_cella_4cout[0:0]),
+       .clk(clock),
+       .cout(wire_acc_cella_5cout[0:0]),
+       .dataa(wire_acc_cella_dataa[5:5]),
+       .datab(wire_acc_cella_datab[5:5]),
+       .datac(wire_acc_cella_datac[5:5]),
+       .ena(clken),
+       .regout(wire_acc_cella_regout[5:5]),
+       .sload(sload));
+       defparam
+               acc_cella_5.cin_used = "true",
+               acc_cella_5.lut_mask = "96e8",
+               acc_cella_5.operation_mode = "arithmetic",
+               acc_cella_5.sum_lutc_input = "cin",
+               acc_cella_5.synch_mode = "on",
+               acc_cella_5.lpm_type = "stratix_lcell";
+       stratix_lcell   acc_cella_6
+       ( 
+       .aclr(aclr),
+       .cin(wire_acc_cella_5cout[0:0]),
+       .clk(clock),
+       .cout(wire_acc_cella_6cout[0:0]),
+       .dataa(wire_acc_cella_dataa[6:6]),
+       .datab(wire_acc_cella_datab[6:6]),
+       .datac(wire_acc_cella_datac[6:6]),
+       .ena(clken),
+       .regout(wire_acc_cella_regout[6:6]),
+       .sload(sload));
+       defparam
+               acc_cella_6.cin_used = "true",
+               acc_cella_6.lut_mask = "96e8",
+               acc_cella_6.operation_mode = "arithmetic",
+               acc_cella_6.sum_lutc_input = "cin",
+               acc_cella_6.synch_mode = "on",
+               acc_cella_6.lpm_type = "stratix_lcell";
+       stratix_lcell   acc_cella_7
+       ( 
+       .aclr(aclr),
+       .cin(wire_acc_cella_6cout[0:0]),
+       .clk(clock),
+       .cout(wire_acc_cella_7cout[0:0]),
+       .dataa(wire_acc_cella_dataa[7:7]),
+       .datab(wire_acc_cella_datab[7:7]),
+       .datac(wire_acc_cella_datac[7:7]),
+       .ena(clken),
+       .regout(wire_acc_cella_regout[7:7]),
+       .sload(sload));
+       defparam
+               acc_cella_7.cin_used = "true",
+               acc_cella_7.lut_mask = "96e8",
+               acc_cella_7.operation_mode = "arithmetic",
+               acc_cella_7.sum_lutc_input = "cin",
+               acc_cella_7.synch_mode = "on",
+               acc_cella_7.lpm_type = "stratix_lcell";
+       stratix_lcell   acc_cella_8
+       ( 
+       .aclr(aclr),
+       .cin(wire_acc_cella_7cout[0:0]),
+       .clk(clock),
+       .cout(wire_acc_cella_8cout[0:0]),
+       .dataa(wire_acc_cella_dataa[8:8]),
+       .datab(wire_acc_cella_datab[8:8]),
+       .datac(wire_acc_cella_datac[8:8]),
+       .ena(clken),
+       .regout(wire_acc_cella_regout[8:8]),
+       .sload(sload));
+       defparam
+               acc_cella_8.cin_used = "true",
+               acc_cella_8.lut_mask = "96e8",
+               acc_cella_8.operation_mode = "arithmetic",
+               acc_cella_8.sum_lutc_input = "cin",
+               acc_cella_8.synch_mode = "on",
+               acc_cella_8.lpm_type = "stratix_lcell";
+       stratix_lcell   acc_cella_9
+       ( 
+       .aclr(aclr),
+       .cin(wire_acc_cella_8cout[0:0]),
+       .clk(clock),
+       .cout(wire_acc_cella_9cout[0:0]),
+       .dataa(wire_acc_cella_dataa[9:9]),
+       .datab(wire_acc_cella_datab[9:9]),
+       .datac(wire_acc_cella_datac[9:9]),
+       .ena(clken),
+       .regout(wire_acc_cella_regout[9:9]),
+       .sload(sload));
+       defparam
+               acc_cella_9.cin_used = "true",
+               acc_cella_9.lut_mask = "96e8",
+               acc_cella_9.operation_mode = "arithmetic",
+               acc_cella_9.sum_lutc_input = "cin",
+               acc_cella_9.synch_mode = "on",
+               acc_cella_9.lpm_type = "stratix_lcell";
+       stratix_lcell   acc_cella_10
+       ( 
+       .aclr(aclr),
+       .cin(wire_acc_cella_9cout[0:0]),
+       .clk(clock),
+       .cout(wire_acc_cella_10cout[0:0]),
+       .dataa(wire_acc_cella_dataa[10:10]),
+       .datab(wire_acc_cella_datab[10:10]),
+       .datac(wire_acc_cella_datac[10:10]),
+       .ena(clken),
+       .regout(wire_acc_cella_regout[10:10]),
+       .sload(sload));
+       defparam
+               acc_cella_10.cin_used = "true",
+               acc_cella_10.lut_mask = "96e8",
+               acc_cella_10.operation_mode = "arithmetic",
+               acc_cella_10.sum_lutc_input = "cin",
+               acc_cella_10.synch_mode = "on",
+               acc_cella_10.lpm_type = "stratix_lcell";
+       stratix_lcell   acc_cella_11
+       ( 
+       .aclr(aclr),
+       .cin(wire_acc_cella_10cout[0:0]),
+       .clk(clock),
+       .cout(wire_acc_cella_11cout[0:0]),
+       .dataa(wire_acc_cella_dataa[11:11]),
+       .datab(wire_acc_cella_datab[11:11]),
+       .datac(wire_acc_cella_datac[11:11]),
+       .ena(clken),
+       .regout(wire_acc_cella_regout[11:11]),
+       .sload(sload));
+       defparam
+               acc_cella_11.cin_used = "true",
+               acc_cella_11.lut_mask = "96e8",
+               acc_cella_11.operation_mode = "arithmetic",
+               acc_cella_11.sum_lutc_input = "cin",
+               acc_cella_11.synch_mode = "on",
+               acc_cella_11.lpm_type = "stratix_lcell";
+       stratix_lcell   acc_cella_12
+       ( 
+       .aclr(aclr),
+       .cin(wire_acc_cella_11cout[0:0]),
+       .clk(clock),
+       .cout(wire_acc_cella_12cout[0:0]),
+       .dataa(wire_acc_cella_dataa[12:12]),
+       .datab(wire_acc_cella_datab[12:12]),
+       .datac(wire_acc_cella_datac[12:12]),
+       .ena(clken),
+       .regout(wire_acc_cella_regout[12:12]),
+       .sload(sload));
+       defparam
+               acc_cella_12.cin_used = "true",
+               acc_cella_12.lut_mask = "96e8",
+               acc_cella_12.operation_mode = "arithmetic",
+               acc_cella_12.sum_lutc_input = "cin",
+               acc_cella_12.synch_mode = "on",
+               acc_cella_12.lpm_type = "stratix_lcell";
+       stratix_lcell   acc_cella_13
+       ( 
+       .aclr(aclr),
+       .cin(wire_acc_cella_12cout[0:0]),
+       .clk(clock),
+       .cout(wire_acc_cella_13cout[0:0]),
+       .dataa(wire_acc_cella_dataa[13:13]),
+       .datab(wire_acc_cella_datab[13:13]),
+       .datac(wire_acc_cella_datac[13:13]),
+       .ena(clken),
+       .regout(wire_acc_cella_regout[13:13]),
+       .sload(sload));
+       defparam
+               acc_cella_13.cin_used = "true",
+               acc_cella_13.lut_mask = "96e8",
+               acc_cella_13.operation_mode = "arithmetic",
+               acc_cella_13.sum_lutc_input = "cin",
+               acc_cella_13.synch_mode = "on",
+               acc_cella_13.lpm_type = "stratix_lcell";
+       stratix_lcell   acc_cella_14
+       ( 
+       .aclr(aclr),
+       .cin(wire_acc_cella_13cout[0:0]),
+       .clk(clock),
+       .cout(wire_acc_cella_14cout[0:0]),
+       .dataa(wire_acc_cella_dataa[14:14]),
+       .datab(wire_acc_cella_datab[14:14]),
+       .datac(wire_acc_cella_datac[14:14]),
+       .ena(clken),
+       .regout(wire_acc_cella_regout[14:14]),
+       .sload(sload));
+       defparam
+               acc_cella_14.cin_used = "true",
+               acc_cella_14.lut_mask = "96e8",
+               acc_cella_14.operation_mode = "arithmetic",
+               acc_cella_14.sum_lutc_input = "cin",
+               acc_cella_14.synch_mode = "on",
+               acc_cella_14.lpm_type = "stratix_lcell";
+       stratix_lcell   acc_cella_15
+       ( 
+       .aclr(aclr),
+       .cin(wire_acc_cella_14cout[0:0]),
+       .clk(clock),
+       .cout(wire_acc_cella_15cout[0:0]),
+       .dataa(wire_acc_cella_dataa[15:15]),
+       .datab(wire_acc_cella_datab[15:15]),
+       .datac(wire_acc_cella_datac[15:15]),
+       .ena(clken),
+       .regout(wire_acc_cella_regout[15:15]),
+       .sload(sload));
+       defparam
+               acc_cella_15.cin_used = "true",
+               acc_cella_15.lut_mask = "96e8",
+               acc_cella_15.operation_mode = "arithmetic",
+               acc_cella_15.sum_lutc_input = "cin",
+               acc_cella_15.synch_mode = "on",
+               acc_cella_15.lpm_type = "stratix_lcell";
+       stratix_lcell   acc_cella_16
+       ( 
+       .aclr(aclr),
+       .cin(wire_acc_cella_15cout[0:0]),
+       .clk(clock),
+       .cout(wire_acc_cella_16cout[0:0]),
+       .dataa(wire_acc_cella_dataa[16:16]),
+       .datab(wire_acc_cella_datab[16:16]),
+       .datac(wire_acc_cella_datac[16:16]),
+       .ena(clken),
+       .regout(wire_acc_cella_regout[16:16]),
+       .sload(sload));
+       defparam
+               acc_cella_16.cin_used = "true",
+               acc_cella_16.lut_mask = "96e8",
+               acc_cella_16.operation_mode = "arithmetic",
+               acc_cella_16.sum_lutc_input = "cin",
+               acc_cella_16.synch_mode = "on",
+               acc_cella_16.lpm_type = "stratix_lcell";
+       stratix_lcell   acc_cella_17
+       ( 
+       .aclr(aclr),
+       .cin(wire_acc_cella_16cout[0:0]),
+       .clk(clock),
+       .cout(wire_acc_cella_17cout[0:0]),
+       .dataa(wire_acc_cella_dataa[17:17]),
+       .datab(wire_acc_cella_datab[17:17]),
+       .datac(wire_acc_cella_datac[17:17]),
+       .ena(clken),
+       .regout(wire_acc_cella_regout[17:17]),
+       .sload(sload));
+       defparam
+               acc_cella_17.cin_used = "true",
+               acc_cella_17.lut_mask = "96e8",
+               acc_cella_17.operation_mode = "arithmetic",
+               acc_cella_17.sum_lutc_input = "cin",
+               acc_cella_17.synch_mode = "on",
+               acc_cella_17.lpm_type = "stratix_lcell";
+       stratix_lcell   acc_cella_18
+       ( 
+       .aclr(aclr),
+       .cin(wire_acc_cella_17cout[0:0]),
+       .clk(clock),
+       .cout(wire_acc_cella_18cout[0:0]),
+       .dataa(wire_acc_cella_dataa[18:18]),
+       .datab(wire_acc_cella_datab[18:18]),
+       .datac(wire_acc_cella_datac[18:18]),
+       .ena(clken),
+       .regout(wire_acc_cella_regout[18:18]),
+       .sload(sload));
+       defparam
+               acc_cella_18.cin_used = "true",
+               acc_cella_18.lut_mask = "96e8",
+               acc_cella_18.operation_mode = "arithmetic",
+               acc_cella_18.sum_lutc_input = "cin",
+               acc_cella_18.synch_mode = "on",
+               acc_cella_18.lpm_type = "stratix_lcell";
+       stratix_lcell   acc_cella_19
+       ( 
+       .aclr(aclr),
+       .cin(wire_acc_cella_18cout[0:0]),
+       .clk(clock),
+       .cout(wire_acc_cella_19cout[0:0]),
+       .dataa(wire_acc_cella_dataa[19:19]),
+       .datab(wire_acc_cella_datab[19:19]),
+       .datac(wire_acc_cella_datac[19:19]),
+       .ena(clken),
+       .regout(wire_acc_cella_regout[19:19]),
+       .sload(sload));
+       defparam
+               acc_cella_19.cin_used = "true",
+               acc_cella_19.lut_mask = "96e8",
+               acc_cella_19.operation_mode = "arithmetic",
+               acc_cella_19.sum_lutc_input = "cin",
+               acc_cella_19.synch_mode = "on",
+               acc_cella_19.lpm_type = "stratix_lcell";
+       stratix_lcell   acc_cella_20
+       ( 
+       .aclr(aclr),
+       .cin(wire_acc_cella_19cout[0:0]),
+       .clk(clock),
+       .cout(wire_acc_cella_20cout[0:0]),
+       .dataa(wire_acc_cella_dataa[20:20]),
+       .datab(wire_acc_cella_datab[20:20]),
+       .datac(wire_acc_cella_datac[20:20]),
+       .ena(clken),
+       .regout(wire_acc_cella_regout[20:20]),
+       .sload(sload));
+       defparam
+               acc_cella_20.cin_used = "true",
+               acc_cella_20.lut_mask = "96e8",
+               acc_cella_20.operation_mode = "arithmetic",
+               acc_cella_20.sum_lutc_input = "cin",
+               acc_cella_20.synch_mode = "on",
+               acc_cella_20.lpm_type = "stratix_lcell";
+       stratix_lcell   acc_cella_21
+       ( 
+       .aclr(aclr),
+       .cin(wire_acc_cella_20cout[0:0]),
+       .clk(clock),
+       .cout(wire_acc_cella_21cout[0:0]),
+       .dataa(wire_acc_cella_dataa[21:21]),
+       .datab(wire_acc_cella_datab[21:21]),
+       .datac(wire_acc_cella_datac[21:21]),
+       .ena(clken),
+       .regout(wire_acc_cella_regout[21:21]),
+       .sload(sload));
+       defparam
+               acc_cella_21.cin_used = "true",
+               acc_cella_21.lut_mask = "96e8",
+               acc_cella_21.operation_mode = "arithmetic",
+               acc_cella_21.sum_lutc_input = "cin",
+               acc_cella_21.synch_mode = "on",
+               acc_cella_21.lpm_type = "stratix_lcell";
+       stratix_lcell   acc_cella_22
+       ( 
+       .aclr(aclr),
+       .cin(wire_acc_cella_21cout[0:0]),
+       .clk(clock),
+       .cout(wire_acc_cella_22cout[0:0]),
+       .dataa(wire_acc_cella_dataa[22:22]),
+       .datab(wire_acc_cella_datab[22:22]),
+       .datac(wire_acc_cella_datac[22:22]),
+       .ena(clken),
+       .regout(wire_acc_cella_regout[22:22]),
+       .sload(sload));
+       defparam
+               acc_cella_22.cin_used = "true",
+               acc_cella_22.lut_mask = "96e8",
+               acc_cella_22.operation_mode = "arithmetic",
+               acc_cella_22.sum_lutc_input = "cin",
+               acc_cella_22.synch_mode = "on",
+               acc_cella_22.lpm_type = "stratix_lcell";
+       stratix_lcell   acc_cella_23
+       ( 
+       .aclr(aclr),
+       .cin(wire_acc_cella_22cout[0:0]),
+       .clk(clock),
+       .cout(wire_acc_cella_23cout[0:0]),
+       .dataa(wire_acc_cella_dataa[23:23]),
+       .datab(wire_acc_cella_datab[23:23]),
+       .datac(wire_acc_cella_datac[23:23]),
+       .ena(clken),
+       .regout(wire_acc_cella_regout[23:23]),
+       .sload(sload));
+       defparam
+               acc_cella_23.cin_used = "true",
+               acc_cella_23.lut_mask = "96e8",
+               acc_cella_23.operation_mode = "arithmetic",
+               acc_cella_23.sum_lutc_input = "cin",
+               acc_cella_23.synch_mode = "on",
+               acc_cella_23.lpm_type = "stratix_lcell";
+       stratix_lcell   acc_cella_24
+       ( 
+       .aclr(aclr),
+       .cin(wire_acc_cella_23cout[0:0]),
+       .clk(clock),
+       .cout(wire_acc_cella_24cout[0:0]),
+       .dataa(wire_acc_cella_dataa[24:24]),
+       .datab(wire_acc_cella_datab[24:24]),
+       .datac(wire_acc_cella_datac[24:24]),
+       .ena(clken),
+       .regout(wire_acc_cella_regout[24:24]),
+       .sload(sload));
+       defparam
+               acc_cella_24.cin_used = "true",
+               acc_cella_24.lut_mask = "96e8",
+               acc_cella_24.operation_mode = "arithmetic",
+               acc_cella_24.sum_lutc_input = "cin",
+               acc_cella_24.synch_mode = "on",
+               acc_cella_24.lpm_type = "stratix_lcell";
+       stratix_lcell   acc_cella_25
+       ( 
+       .aclr(aclr),
+       .cin(wire_acc_cella_24cout[0:0]),
+       .clk(clock),
+       .cout(wire_acc_cella_25cout[0:0]),
+       .dataa(wire_acc_cella_dataa[25:25]),
+       .datab(wire_acc_cella_datab[25:25]),
+       .datac(wire_acc_cella_datac[25:25]),
+       .ena(clken),
+       .regout(wire_acc_cella_regout[25:25]),
+       .sload(sload));
+       defparam
+               acc_cella_25.cin_used = "true",
+               acc_cella_25.lut_mask = "96e8",
+               acc_cella_25.operation_mode = "arithmetic",
+               acc_cella_25.sum_lutc_input = "cin",
+               acc_cella_25.synch_mode = "on",
+               acc_cella_25.lpm_type = "stratix_lcell";
+       stratix_lcell   acc_cella_26
+       ( 
+       .aclr(aclr),
+       .cin(wire_acc_cella_25cout[0:0]),
+       .clk(clock),
+       .cout(wire_acc_cella_26cout[0:0]),
+       .dataa(wire_acc_cella_dataa[26:26]),
+       .datab(wire_acc_cella_datab[26:26]),
+       .datac(wire_acc_cella_datac[26:26]),
+       .ena(clken),
+       .regout(wire_acc_cella_regout[26:26]),
+       .sload(sload));
+       defparam
+               acc_cella_26.cin_used = "true",
+               acc_cella_26.lut_mask = "96e8",
+               acc_cella_26.operation_mode = "arithmetic",
+               acc_cella_26.sum_lutc_input = "cin",
+               acc_cella_26.synch_mode = "on",
+               acc_cella_26.lpm_type = "stratix_lcell";
+       stratix_lcell   acc_cella_27
+       ( 
+       .aclr(aclr),
+       .cin(wire_acc_cella_26cout[0:0]),
+       .clk(clock),
+       .cout(wire_acc_cella_27cout[0:0]),
+       .dataa(wire_acc_cella_dataa[27:27]),
+       .datab(wire_acc_cella_datab[27:27]),
+       .datac(wire_acc_cella_datac[27:27]),
+       .ena(clken),
+       .regout(wire_acc_cella_regout[27:27]),
+       .sload(sload));
+       defparam
+               acc_cella_27.cin_used = "true",
+               acc_cella_27.lut_mask = "96e8",
+               acc_cella_27.operation_mode = "arithmetic",
+               acc_cella_27.sum_lutc_input = "cin",
+               acc_cella_27.synch_mode = "on",
+               acc_cella_27.lpm_type = "stratix_lcell";
+       stratix_lcell   acc_cella_28
+       ( 
+       .aclr(aclr),
+       .cin(wire_acc_cella_27cout[0:0]),
+       .clk(clock),
+       .cout(wire_acc_cella_28cout[0:0]),
+       .dataa(wire_acc_cella_dataa[28:28]),
+       .datab(wire_acc_cella_datab[28:28]),
+       .datac(wire_acc_cella_datac[28:28]),
+       .ena(clken),
+       .regout(wire_acc_cella_regout[28:28]),
+       .sload(sload));
+       defparam
+               acc_cella_28.cin_used = "true",
+               acc_cella_28.lut_mask = "96e8",
+               acc_cella_28.operation_mode = "arithmetic",
+               acc_cella_28.sum_lutc_input = "cin",
+               acc_cella_28.synch_mode = "on",
+               acc_cella_28.lpm_type = "stratix_lcell";
+       stratix_lcell   acc_cella_29
+       ( 
+       .aclr(aclr),
+       .cin(wire_acc_cella_28cout[0:0]),
+       .clk(clock),
+       .cout(wire_acc_cella_29cout[0:0]),
+       .dataa(wire_acc_cella_dataa[29:29]),
+       .datab(wire_acc_cella_datab[29:29]),
+       .datac(wire_acc_cella_datac[29:29]),
+       .ena(clken),
+       .regout(wire_acc_cella_regout[29:29]),
+       .sload(sload));
+       defparam
+               acc_cella_29.cin_used = "true",
+               acc_cella_29.lut_mask = "96e8",
+               acc_cella_29.operation_mode = "arithmetic",
+               acc_cella_29.sum_lutc_input = "cin",
+               acc_cella_29.synch_mode = "on",
+               acc_cella_29.lpm_type = "stratix_lcell";
+       stratix_lcell   acc_cella_30
+       ( 
+       .aclr(aclr),
+       .cin(wire_acc_cella_29cout[0:0]),
+       .clk(clock),
+       .cout(wire_acc_cella_30cout[0:0]),
+       .dataa(wire_acc_cella_dataa[30:30]),
+       .datab(wire_acc_cella_datab[30:30]),
+       .datac(wire_acc_cella_datac[30:30]),
+       .ena(clken),
+       .regout(wire_acc_cella_regout[30:30]),
+       .sload(sload));
+       defparam
+               acc_cella_30.cin_used = "true",
+               acc_cella_30.lut_mask = "96e8",
+               acc_cella_30.operation_mode = "arithmetic",
+               acc_cella_30.sum_lutc_input = "cin",
+               acc_cella_30.synch_mode = "on",
+               acc_cella_30.lpm_type = "stratix_lcell";
+       stratix_lcell   acc_cella_31
+       ( 
+       .aclr(aclr),
+       .cin(wire_acc_cella_30cout[0:0]),
+       .clk(clock),
+       .dataa(wire_acc_cella_dataa[31:31]),
+       .datab(wire_acc_cella_datab[31:31]),
+       .datac(wire_acc_cella_datac[31:31]),
+       .ena(clken),
+       .regout(wire_acc_cella_regout[31:31]),
+       .sload(sload));
+       defparam
+               acc_cella_31.cin_used = "true",
+               acc_cella_31.lut_mask = "9696",
+               acc_cella_31.operation_mode = "normal",
+               acc_cella_31.sum_lutc_input = "cin",
+               acc_cella_31.synch_mode = "on",
+               acc_cella_31.lpm_type = "stratix_lcell";
+       assign
+               wire_acc_cella_dataa = data,
+               wire_acc_cella_datab = wire_acc_cella_regout,
+               wire_acc_cella_datac = data;
+       assign
+               result = wire_acc_cella_regout,
+               sload = 1'b0;
+endmodule //accum32_accum_nta
+//VALID FILE
+
+
+module accum32 (
+       data,
+       clock,
+       clken,
+       aclr,
+       result)/* synthesis synthesis_clearbox = 1 */;
+
+       input   [31:0]  data;
+       input     clock;
+       input     clken;
+       input     aclr;
+       output  [31:0]  result;
+
+       wire [31:0] sub_wire0;
+       wire [31:0] result = sub_wire0[31:0];
+
+       accum32_accum_nta       accum32_accum_nta_component (
+                               .clken (clken),
+                               .aclr (aclr),
+                               .clock (clock),
+                               .data (data),
+                               .result (sub_wire0));
+
+endmodule
+
+// ============================================================
+// CNX file retrieval info
+// ============================================================
+// Retrieval info: PRIVATE: WIDTH_IN NUMERIC "32"
+// Retrieval info: PRIVATE: WIDTH_OUT NUMERIC "32"
+// Retrieval info: PRIVATE: LPM_REPRESENTATION NUMERIC "0"
+// Retrieval info: PRIVATE: SLOAD NUMERIC "0"
+// Retrieval info: PRIVATE: ADD_SUB NUMERIC "0"
+// Retrieval info: PRIVATE: CIN NUMERIC "0"
+// Retrieval info: PRIVATE: CLKEN NUMERIC "1"
+// Retrieval info: PRIVATE: ACLR NUMERIC "1"
+// Retrieval info: PRIVATE: COUT NUMERIC "0"
+// Retrieval info: PRIVATE: OVERFLOW NUMERIC "0"
+// Retrieval info: PRIVATE: LATENCY NUMERIC "0"
+// Retrieval info: PRIVATE: EXTRA_LATENCY NUMERIC "0"
+// Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING "Cyclone"
+// Retrieval info: CONSTANT: WIDTH_IN NUMERIC "32"
+// Retrieval info: CONSTANT: WIDTH_OUT NUMERIC "32"
+// Retrieval info: CONSTANT: LPM_REPRESENTATION STRING "SIGNED"
+// Retrieval info: CONSTANT: LPM_TYPE STRING "altaccumulate"
+// Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone"
+// Retrieval info: USED_PORT: data 0 0 32 0 INPUT NODEFVAL data[31..0]
+// Retrieval info: USED_PORT: result 0 0 32 0 OUTPUT NODEFVAL result[31..0]
+// Retrieval info: USED_PORT: clock 0 0 0 0 INPUT GND clock
+// Retrieval info: USED_PORT: clken 0 0 0 0 INPUT VCC clken
+// Retrieval info: USED_PORT: aclr 0 0 0 0 INPUT GND aclr
+// Retrieval info: CONNECT: @data 0 0 32 0 data 0 0 32 0
+// Retrieval info: CONNECT: result 0 0 32 0 @result 0 0 32 0
+// Retrieval info: CONNECT: @clock 0 0 0 0 clock 0 0 0 0
+// Retrieval info: CONNECT: @clken 0 0 0 0 clken 0 0 0 0
+// Retrieval info: CONNECT: @aclr 0 0 0 0 aclr 0 0 0 0
+// Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all
diff --git a/usrp/fpga/megacells/accum32_bb.v b/usrp/fpga/megacells/accum32_bb.v
new file mode 100755 (executable)
index 0000000..142bde8
--- /dev/null
@@ -0,0 +1,35 @@
+//Copyright (C) 1991-2003 Altera Corporation
+//Any  megafunction  design,  and related netlist (encrypted  or  decrypted),
+//support information,  device programming or simulation file,  and any other
+//associated  documentation or information  provided by  Altera  or a partner
+//under  Altera's   Megafunction   Partnership   Program  may  be  used  only
+//to program  PLD  devices (but not masked  PLD  devices) from  Altera.   Any
+//other  use  of such  megafunction  design,  netlist,  support  information,
+//device programming or simulation file,  or any other  related documentation
+//or information  is prohibited  for  any  other purpose,  including, but not
+//limited to  modification,  reverse engineering,  de-compiling, or use  with
+//any other  silicon devices,  unless such use is  explicitly  licensed under
+//a separate agreement with  Altera  or a megafunction partner.  Title to the
+//intellectual property,  including patents,  copyrights,  trademarks,  trade
+//secrets,  or maskworks,  embodied in any such megafunction design, netlist,
+//support  information,  device programming or simulation file,  or any other
+//related documentation or information provided by  Altera  or a megafunction
+//partner, remains with Altera, the megafunction partner, or their respective
+//licensors. No other licenses, including any licenses needed under any third
+//party's intellectual property, are provided herein.
+
+module accum32 (
+       data,
+       clock,
+       clken,
+       aclr,
+       result)/* synthesis synthesis_clearbox = 1 */;
+
+       input   [31:0]  data;
+       input     clock;
+       input     clken;
+       input     aclr;
+       output  [31:0]  result;
+
+endmodule
+
diff --git a/usrp/fpga/megacells/accum32_inst.v b/usrp/fpga/megacells/accum32_inst.v
new file mode 100755 (executable)
index 0000000..c354acc
--- /dev/null
@@ -0,0 +1,7 @@
+accum32        accum32_inst (
+       .data ( data_sig ),
+       .clock ( clock_sig ),
+       .clken ( clken_sig ),
+       .aclr ( aclr_sig ),
+       .result ( result_sig )
+       );
diff --git a/usrp/fpga/megacells/add32.bsf b/usrp/fpga/megacells/add32.bsf
new file mode 100755 (executable)
index 0000000..b2da9fc
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+WARNING: Do NOT edit the input and output ports in this file in a text
+editor if you plan to continue editing the block that represents it in
+the Block Editor! File corruption is VERY likely to occur.
+*/
+/*
+Copyright (C) 1991-2003 Altera Corporation
+Any  megafunction  design,  and related netlist (encrypted  or  decrypted),
+support information,  device programming or simulation file,  and any other
+associated  documentation or information  provided by  Altera  or a partner
+under  Altera's   Megafunction   Partnership   Program  may  be  used  only
+to program  PLD  devices (but not masked  PLD  devices) from  Altera.   Any
+other  use  of such  megafunction  design,  netlist,  support  information,
+device programming or simulation file,  or any other  related documentation
+or information  is prohibited  for  any  other purpose,  including, but not
+limited to  modification,  reverse engineering,  de-compiling, or use  with
+any other  silicon devices,  unless such use is  explicitly  licensed under
+a separate agreement with  Altera  or a megafunction partner.  Title to the
+intellectual property,  including patents,  copyrights,  trademarks,  trade
+secrets,  or maskworks,  embodied in any such megafunction design, netlist,
+support  information,  device programming or simulation file,  or any other
+related documentation or information provided by  Altera  or a megafunction
+partner, remains with Altera, the megafunction partner, or their respective
+licensors. No other licenses, including any licenses needed under any third
+party's intellectual property, are provided herein.
+*/
+(header "symbol" (version "1.1"))
+(symbol
+       (rect 0 0 160 96)
+       (text "add32" (rect 58 2 111 21)(font "Arial" (font_size 10)))
+       (text "inst" (rect 8 77 31 92)(font "Arial" ))
+       (port
+               (pt 0 40)
+               (input)
+               (text "dataa[7..0]" (rect 0 0 73 16)(font "Arial" (font_size 8)))
+               (text "dataa[7..0]" (rect 4 24 66 40)(font "Arial" (font_size 8)))
+               (line (pt 0 40)(pt 64 40)(line_width 3))
+       )
+       (port
+               (pt 0 72)
+               (input)
+               (text "datab[7..0]" (rect 0 0 73 16)(font "Arial" (font_size 8)))
+               (text "datab[7..0]" (rect 4 56 66 72)(font "Arial" (font_size 8)))
+               (line (pt 0 72)(pt 64 72)(line_width 3))
+       )
+       (port
+               (pt 160 56)
+               (output)
+               (text "result[7..0]" (rect 0 0 73 16)(font "Arial" (font_size 8)))
+               (text "result[7..0]" (rect 95 40 157 56)(font "Arial" (font_size 8)))
+               (line (pt 160 56)(pt 96 56)(line_width 3))
+       )
+       (drawing
+               (text "A" (rect 66 32 75 48)(font "Arial" (font_size 8)))
+               (text "B" (rect 66 64 75 80)(font "Arial" (font_size 8)))
+               (text "A+B" (rect 68 48 94 64)(font "Arial" (font_size 8)))
+               (line (pt 64 32)(pt 96 40)(line_width 1))
+               (line (pt 96 40)(pt 96 72)(line_width 1))
+               (line (pt 96 72)(pt 64 80)(line_width 1))
+               (line (pt 64 80)(pt 64 32)(line_width 1))
+       )
+)
diff --git a/usrp/fpga/megacells/add32.cmp b/usrp/fpga/megacells/add32.cmp
new file mode 100755 (executable)
index 0000000..3b12017
--- /dev/null
@@ -0,0 +1,29 @@
+--Copyright (C) 1991-2003 Altera Corporation
+--Any  megafunction  design,  and related netlist (encrypted  or  decrypted),
+--support information,  device programming or simulation file,  and any other
+--associated  documentation or information  provided by  Altera  or a partner
+--under  Altera's   Megafunction   Partnership   Program  may  be  used  only
+--to program  PLD  devices (but not masked  PLD  devices) from  Altera.   Any
+--other  use  of such  megafunction  design,  netlist,  support  information,
+--device programming or simulation file,  or any other  related documentation
+--or information  is prohibited  for  any  other purpose,  including, but not
+--limited to  modification,  reverse engineering,  de-compiling, or use  with
+--any other  silicon devices,  unless such use is  explicitly  licensed under
+--a separate agreement with  Altera  or a megafunction partner.  Title to the
+--intellectual property,  including patents,  copyrights,  trademarks,  trade
+--secrets,  or maskworks,  embodied in any such megafunction design, netlist,
+--support  information,  device programming or simulation file,  or any other
+--related documentation or information provided by  Altera  or a megafunction
+--partner, remains with Altera, the megafunction partner, or their respective
+--licensors. No other licenses, including any licenses needed under any third
+--party's intellectual property, are provided herein.
+
+
+component add32
+       PORT
+       (
+               dataa           : IN STD_LOGIC_VECTOR (7 DOWNTO 0);
+               datab           : IN STD_LOGIC_VECTOR (7 DOWNTO 0);
+               result          : OUT STD_LOGIC_VECTOR (7 DOWNTO 0)
+       );
+end component;
diff --git a/usrp/fpga/megacells/add32.inc b/usrp/fpga/megacells/add32.inc
new file mode 100755 (executable)
index 0000000..6755257
--- /dev/null
@@ -0,0 +1,30 @@
+--Copyright (C) 1991-2003 Altera Corporation
+--Any  megafunction  design,  and related netlist (encrypted  or  decrypted),
+--support information,  device programming or simulation file,  and any other
+--associated  documentation or information  provided by  Altera  or a partner
+--under  Altera's   Megafunction   Partnership   Program  may  be  used  only
+--to program  PLD  devices (but not masked  PLD  devices) from  Altera.   Any
+--other  use  of such  megafunction  design,  netlist,  support  information,
+--device programming or simulation file,  or any other  related documentation
+--or information  is prohibited  for  any  other purpose,  including, but not
+--limited to  modification,  reverse engineering,  de-compiling, or use  with
+--any other  silicon devices,  unless such use is  explicitly  licensed under
+--a separate agreement with  Altera  or a megafunction partner.  Title to the
+--intellectual property,  including patents,  copyrights,  trademarks,  trade
+--secrets,  or maskworks,  embodied in any such megafunction design, netlist,
+--support  information,  device programming or simulation file,  or any other
+--related documentation or information provided by  Altera  or a megafunction
+--partner, remains with Altera, the megafunction partner, or their respective
+--licensors. No other licenses, including any licenses needed under any third
+--party's intellectual property, are provided herein.
+
+
+FUNCTION add32 
+(
+       dataa[7..0],
+       datab[7..0]
+)
+
+RETURNS (
+       result[7..0]
+);
diff --git a/usrp/fpga/megacells/add32.v b/usrp/fpga/megacells/add32.v
new file mode 100755 (executable)
index 0000000..d809061
--- /dev/null
@@ -0,0 +1,221 @@
+// megafunction wizard: %LPM_ADD_SUB%CBX%
+// GENERATION: STANDARD
+// VERSION: WM1.0
+// MODULE: lpm_add_sub 
+
+// ============================================================
+// File Name: add32.v
+// Megafunction Name(s):
+//                     lpm_add_sub
+// ============================================================
+// ************************************************************
+// THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE!
+// ************************************************************
+
+
+//Copyright (C) 1991-2003 Altera Corporation
+//Any  megafunction  design,  and related netlist (encrypted  or  decrypted),
+//support information,  device programming or simulation file,  and any other
+//associated  documentation or information  provided by  Altera  or a partner
+//under  Altera's   Megafunction   Partnership   Program  may  be  used  only
+//to program  PLD  devices (but not masked  PLD  devices) from  Altera.   Any
+//other  use  of such  megafunction  design,  netlist,  support  information,
+//device programming or simulation file,  or any other  related documentation
+//or information  is prohibited  for  any  other purpose,  including, but not
+//limited to  modification,  reverse engineering,  de-compiling, or use  with
+//any other  silicon devices,  unless such use is  explicitly  licensed under
+//a separate agreement with  Altera  or a megafunction partner.  Title to the
+//intellectual property,  including patents,  copyrights,  trademarks,  trade
+//secrets,  or maskworks,  embodied in any such megafunction design, netlist,
+//support  information,  device programming or simulation file,  or any other
+//related documentation or information provided by  Altera  or a megafunction
+//partner, remains with Altera, the megafunction partner, or their respective
+//licensors. No other licenses, including any licenses needed under any third
+//party's intellectual property, are provided herein.
+
+
+//lpm_add_sub DEVICE_FAMILY=Cyclone LPM_DIRECTION=ADD LPM_WIDTH=8 dataa datab result
+//VERSION_BEGIN 3.0 cbx_lpm_add_sub 2003:04:10:18:28:42:SJ cbx_mgl 2003:06:11:11:00:44:SJ cbx_stratix 2003:05:16:10:26:50:SJ  VERSION_END
+
+//synthesis_resources = lut 8 
+module  add32_add_sub_nq7
+       ( 
+       dataa,
+       datab,
+       result) /* synthesis synthesis_clearbox=1 */;
+       input   [7:0]  dataa;
+       input   [7:0]  datab;
+       output   [7:0]  result;
+
+       wire  [7:0]   wire_add_sub_cella_combout;
+       wire  [0:0]   wire_add_sub_cella_0cout;
+       wire  [0:0]   wire_add_sub_cella_1cout;
+       wire  [0:0]   wire_add_sub_cella_2cout;
+       wire  [0:0]   wire_add_sub_cella_3cout;
+       wire  [0:0]   wire_add_sub_cella_4cout;
+       wire  [0:0]   wire_add_sub_cella_5cout;
+       wire  [0:0]   wire_add_sub_cella_6cout;
+       wire  [7:0]   wire_add_sub_cella_dataa;
+       wire  [7:0]   wire_add_sub_cella_datab;
+
+       stratix_lcell   add_sub_cella_0
+       ( 
+       .cin(1'b0),
+       .combout(wire_add_sub_cella_combout[0:0]),
+       .cout(wire_add_sub_cella_0cout[0:0]),
+       .dataa(wire_add_sub_cella_dataa[0:0]),
+       .datab(wire_add_sub_cella_datab[0:0]));
+       defparam
+               add_sub_cella_0.cin_used = "true",
+               add_sub_cella_0.lut_mask = "96e8",
+               add_sub_cella_0.operation_mode = "arithmetic",
+               add_sub_cella_0.sum_lutc_input = "cin",
+               add_sub_cella_0.lpm_type = "stratix_lcell";
+       stratix_lcell   add_sub_cella_1
+       ( 
+       .cin(wire_add_sub_cella_0cout[0:0]),
+       .combout(wire_add_sub_cella_combout[1:1]),
+       .cout(wire_add_sub_cella_1cout[0:0]),
+       .dataa(wire_add_sub_cella_dataa[1:1]),
+       .datab(wire_add_sub_cella_datab[1:1]));
+       defparam
+               add_sub_cella_1.cin_used = "true",
+               add_sub_cella_1.lut_mask = "96e8",
+               add_sub_cella_1.operation_mode = "arithmetic",
+               add_sub_cella_1.sum_lutc_input = "cin",
+               add_sub_cella_1.lpm_type = "stratix_lcell";
+       stratix_lcell   add_sub_cella_2
+       ( 
+       .cin(wire_add_sub_cella_1cout[0:0]),
+       .combout(wire_add_sub_cella_combout[2:2]),
+       .cout(wire_add_sub_cella_2cout[0:0]),
+       .dataa(wire_add_sub_cella_dataa[2:2]),
+       .datab(wire_add_sub_cella_datab[2:2]));
+       defparam
+               add_sub_cella_2.cin_used = "true",
+               add_sub_cella_2.lut_mask = "96e8",
+               add_sub_cella_2.operation_mode = "arithmetic",
+               add_sub_cella_2.sum_lutc_input = "cin",
+               add_sub_cella_2.lpm_type = "stratix_lcell";
+       stratix_lcell   add_sub_cella_3
+       ( 
+       .cin(wire_add_sub_cella_2cout[0:0]),
+       .combout(wire_add_sub_cella_combout[3:3]),
+       .cout(wire_add_sub_cella_3cout[0:0]),
+       .dataa(wire_add_sub_cella_dataa[3:3]),
+       .datab(wire_add_sub_cella_datab[3:3]));
+       defparam
+               add_sub_cella_3.cin_used = "true",
+               add_sub_cella_3.lut_mask = "96e8",
+               add_sub_cella_3.operation_mode = "arithmetic",
+               add_sub_cella_3.sum_lutc_input = "cin",
+               add_sub_cella_3.lpm_type = "stratix_lcell";
+       stratix_lcell   add_sub_cella_4
+       ( 
+       .cin(wire_add_sub_cella_3cout[0:0]),
+       .combout(wire_add_sub_cella_combout[4:4]),
+       .cout(wire_add_sub_cella_4cout[0:0]),
+       .dataa(wire_add_sub_cella_dataa[4:4]),
+       .datab(wire_add_sub_cella_datab[4:4]));
+       defparam
+               add_sub_cella_4.cin_used = "true",
+               add_sub_cella_4.lut_mask = "96e8",
+               add_sub_cella_4.operation_mode = "arithmetic",
+               add_sub_cella_4.sum_lutc_input = "cin",
+               add_sub_cella_4.lpm_type = "stratix_lcell";
+       stratix_lcell   add_sub_cella_5
+       ( 
+       .cin(wire_add_sub_cella_4cout[0:0]),
+       .combout(wire_add_sub_cella_combout[5:5]),
+       .cout(wire_add_sub_cella_5cout[0:0]),
+       .dataa(wire_add_sub_cella_dataa[5:5]),
+       .datab(wire_add_sub_cella_datab[5:5]));
+       defparam
+               add_sub_cella_5.cin_used = "true",
+               add_sub_cella_5.lut_mask = "96e8",
+               add_sub_cella_5.operation_mode = "arithmetic",
+               add_sub_cella_5.sum_lutc_input = "cin",
+               add_sub_cella_5.lpm_type = "stratix_lcell";
+       stratix_lcell   add_sub_cella_6
+       ( 
+       .cin(wire_add_sub_cella_5cout[0:0]),
+       .combout(wire_add_sub_cella_combout[6:6]),
+       .cout(wire_add_sub_cella_6cout[0:0]),
+       .dataa(wire_add_sub_cella_dataa[6:6]),
+       .datab(wire_add_sub_cella_datab[6:6]));
+       defparam
+               add_sub_cella_6.cin_used = "true",
+               add_sub_cella_6.lut_mask = "96e8",
+               add_sub_cella_6.operation_mode = "arithmetic",
+               add_sub_cella_6.sum_lutc_input = "cin",
+               add_sub_cella_6.lpm_type = "stratix_lcell";
+       stratix_lcell   add_sub_cella_7
+       ( 
+       .cin(wire_add_sub_cella_6cout[0:0]),
+       .combout(wire_add_sub_cella_combout[7:7]),
+       .dataa(wire_add_sub_cella_dataa[7:7]),
+       .datab(wire_add_sub_cella_datab[7:7]));
+       defparam
+               add_sub_cella_7.cin_used = "true",
+               add_sub_cella_7.lut_mask = "9696",
+               add_sub_cella_7.operation_mode = "normal",
+               add_sub_cella_7.sum_lutc_input = "cin",
+               add_sub_cella_7.lpm_type = "stratix_lcell";
+       assign
+               wire_add_sub_cella_dataa = dataa,
+               wire_add_sub_cella_datab = datab;
+       assign
+               result = wire_add_sub_cella_combout;
+endmodule //add32_add_sub_nq7
+//VALID FILE
+
+
+module add32 (
+       dataa,
+       datab,
+       result)/* synthesis synthesis_clearbox = 1 */;
+
+       input   [7:0]  dataa;
+       input   [7:0]  datab;
+       output  [7:0]  result;
+
+       wire [7:0] sub_wire0;
+       wire [7:0] result = sub_wire0[7:0];
+
+       add32_add_sub_nq7       add32_add_sub_nq7_component (
+                               .dataa (dataa),
+                               .datab (datab),
+                               .result (sub_wire0));
+
+endmodule
+
+// ============================================================
+// CNX file retrieval info
+// ============================================================
+// Retrieval info: PRIVATE: nBit NUMERIC "8"
+// Retrieval info: PRIVATE: Function NUMERIC "0"
+// Retrieval info: PRIVATE: WhichConstant NUMERIC "0"
+// Retrieval info: PRIVATE: ConstantA NUMERIC "0"
+// Retrieval info: PRIVATE: ConstantB NUMERIC "0"
+// Retrieval info: PRIVATE: ValidCtA NUMERIC "0"
+// Retrieval info: PRIVATE: ValidCtB NUMERIC "0"
+// Retrieval info: PRIVATE: CarryIn NUMERIC "0"
+// Retrieval info: PRIVATE: CarryOut NUMERIC "0"
+// Retrieval info: PRIVATE: Overflow NUMERIC "0"
+// Retrieval info: PRIVATE: Latency NUMERIC "0"
+// Retrieval info: PRIVATE: aclr NUMERIC "0"
+// Retrieval info: PRIVATE: clken NUMERIC "0"
+// Retrieval info: PRIVATE: LPM_PIPELINE NUMERIC "0"
+// Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING "Cyclone"
+// Retrieval info: CONSTANT: LPM_WIDTH NUMERIC "8"
+// Retrieval info: CONSTANT: LPM_DIRECTION STRING "ADD"
+// Retrieval info: CONSTANT: LPM_TYPE STRING "LPM_ADD_SUB"
+// Retrieval info: CONSTANT: LPM_HINT STRING "ONE_INPUT_IS_CONSTANT=NO"
+// Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone"
+// Retrieval info: USED_PORT: result 0 0 8 0 OUTPUT NODEFVAL result[7..0]
+// Retrieval info: USED_PORT: dataa 0 0 8 0 INPUT NODEFVAL dataa[7..0]
+// Retrieval info: USED_PORT: datab 0 0 8 0 INPUT NODEFVAL datab[7..0]
+// Retrieval info: CONNECT: result 0 0 8 0 @result 0 0 8 0
+// Retrieval info: CONNECT: @dataa 0 0 8 0 dataa 0 0 8 0
+// Retrieval info: CONNECT: @datab 0 0 8 0 datab 0 0 8 0
+// Retrieval info: LIBRARY: lpm lpm.lpm_components.all
diff --git a/usrp/fpga/megacells/add32_bb.v b/usrp/fpga/megacells/add32_bb.v
new file mode 100755 (executable)
index 0000000..8d1588c
--- /dev/null
@@ -0,0 +1,31 @@
+//Copyright (C) 1991-2003 Altera Corporation
+//Any  megafunction  design,  and related netlist (encrypted  or  decrypted),
+//support information,  device programming or simulation file,  and any other
+//associated  documentation or information  provided by  Altera  or a partner
+//under  Altera's   Megafunction   Partnership   Program  may  be  used  only
+//to program  PLD  devices (but not masked  PLD  devices) from  Altera.   Any
+//other  use  of such  megafunction  design,  netlist,  support  information,
+//device programming or simulation file,  or any other  related documentation
+//or information  is prohibited  for  any  other purpose,  including, but not
+//limited to  modification,  reverse engineering,  de-compiling, or use  with
+//any other  silicon devices,  unless such use is  explicitly  licensed under
+//a separate agreement with  Altera  or a megafunction partner.  Title to the
+//intellectual property,  including patents,  copyrights,  trademarks,  trade
+//secrets,  or maskworks,  embodied in any such megafunction design, netlist,
+//support  information,  device programming or simulation file,  or any other
+//related documentation or information provided by  Altera  or a megafunction
+//partner, remains with Altera, the megafunction partner, or their respective
+//licensors. No other licenses, including any licenses needed under any third
+//party's intellectual property, are provided herein.
+
+module add32 (
+       dataa,
+       datab,
+       result)/* synthesis synthesis_clearbox = 1 */;
+
+       input   [7:0]  dataa;
+       input   [7:0]  datab;
+       output  [7:0]  result;
+
+endmodule
+
diff --git a/usrp/fpga/megacells/add32_inst.v b/usrp/fpga/megacells/add32_inst.v
new file mode 100755 (executable)
index 0000000..bc7e6d4
--- /dev/null
@@ -0,0 +1,5 @@
+add32  add32_inst (
+       .dataa ( dataa_sig ),
+       .datab ( datab_sig ),
+       .result ( result_sig )
+       );
diff --git a/usrp/fpga/megacells/addsub16.bsf b/usrp/fpga/megacells/addsub16.bsf
new file mode 100755 (executable)
index 0000000..9ed6b72
--- /dev/null
@@ -0,0 +1,96 @@
+/*
+WARNING: Do NOT edit the input and output ports in this file in a text
+editor if you plan to continue editing the block that represents it in
+the Block Editor! File corruption is VERY likely to occur.
+*/
+/*
+Copyright (C) 1991-2003 Altera Corporation
+Any  megafunction  design,  and related netlist (encrypted  or  decrypted),
+support information,  device programming or simulation file,  and any other
+associated  documentation or information  provided by  Altera  or a partner
+under  Altera's   Megafunction   Partnership   Program  may  be  used  only
+to program  PLD  devices (but not masked  PLD  devices) from  Altera.   Any
+other  use  of such  megafunction  design,  netlist,  support  information,
+device programming or simulation file,  or any other  related documentation
+or information  is prohibited  for  any  other purpose,  including, but not
+limited to  modification,  reverse engineering,  de-compiling, or use  with
+any other  silicon devices,  unless such use is  explicitly  licensed under
+a separate agreement with  Altera  or a megafunction partner.  Title to the
+intellectual property,  including patents,  copyrights,  trademarks,  trade
+secrets,  or maskworks,  embodied in any such megafunction design, netlist,
+support  information,  device programming or simulation file,  or any other
+related documentation or information provided by  Altera  or a megafunction
+partner, remains with Altera, the megafunction partner, or their respective
+licensors. No other licenses, including any licenses needed under any third
+party's intellectual property, are provided herein.
+*/
+(header "symbol" (version "1.1"))
+(symbol
+       (rect 0 0 160 144)
+       (text "addsub16" (rect 45 2 128 21)(font "Arial" (font_size 10)))
+       (text "inst" (rect 8 125 31 140)(font "Arial" ))
+       (port
+               (pt 0 56)
+               (input)
+               (text "dataa[15..0]" (rect 0 0 81 16)(font "Arial" (font_size 8)))
+               (text "dataa[15..0]" (rect 4 40 73 56)(font "Arial" (font_size 8)))
+               (line (pt 0 56)(pt 64 56)(line_width 3))
+       )
+       (port
+               (pt 0 88)
+               (input)
+               (text "datab[15..0]" (rect 0 0 81 16)(font "Arial" (font_size 8)))
+               (text "datab[15..0]" (rect 4 72 73 88)(font "Arial" (font_size 8)))
+               (line (pt 0 88)(pt 64 88)(line_width 3))
+       )
+       (port
+               (pt 0 72)
+               (input)
+               (text "clock" (rect 0 0 36 16)(font "Arial" (font_size 8)))
+               (text "clock" (rect 4 56 35 72)(font "Arial" (font_size 8)))
+               (line (pt 0 72)(pt 64 72)(line_width 1))
+       )
+       (port
+               (pt 0 32)
+               (input)
+               (text "add_sub" (rect 0 0 57 16)(font "Arial" (font_size 8)))
+               (text "add_sub" (rect 4 16 53 32)(font "Arial" (font_size 8)))
+               (line (pt 0 32)(pt 80 32)(line_width 1))
+       )
+       (port
+               (pt 0 112)
+               (input)
+               (text "clken" (rect 0 0 36 16)(font "Arial" (font_size 8)))
+               (text "clken" (rect 4 96 35 112)(font "Arial" (font_size 8)))
+               (line (pt 0 112)(pt 74 112)(line_width 1))
+       )
+       (port
+               (pt 0 128)
+               (input)
+               (text "aclr" (rect 0 0 24 16)(font "Arial" (font_size 8)))
+               (text "aclr" (rect 4 112 25 128)(font "Arial" (font_size 8)))
+               (line (pt 0 128)(pt 85 128)(line_width 1))
+       )
+       (port
+               (pt 160 72)
+               (output)
+               (text "result[15..0]" (rect 0 0 81 16)(font "Arial" (font_size 8)))
+               (text "result[15..0]" (rect 88 56 157 72)(font "Arial" (font_size 8)))
+               (line (pt 160 72)(pt 96 72)(line_width 3))
+       )
+       (drawing
+               (text "A" (rect 66 48 75 64)(font "Arial" (font_size 8)))
+               (text "B" (rect 66 80 75 96)(font "Arial" (font_size 8)))
+               (text "A+B/A-B" (rect 82 37 134 53)(font "Arial" (font_size 8)))
+               (line (pt 64 48)(pt 96 56)(line_width 1))
+               (line (pt 96 56)(pt 96 88)(line_width 1))
+               (line (pt 96 88)(pt 64 96)(line_width 1))
+               (line (pt 64 96)(pt 64 48)(line_width 1))
+               (line (pt 80 32)(pt 80 52)(line_width 1))
+               (line (pt 106 40)(pt 125 40)(line_width 1))
+               (line (pt 74 112)(pt 74 93)(line_width 1))
+               (line (pt 85 128)(pt 85 90)(line_width 1))
+               (line (pt 64 66)(pt 70 72)(line_width 1))
+               (line (pt 70 72)(pt 64 78)(line_width 1))
+       )
+)
diff --git a/usrp/fpga/megacells/addsub16.cmp b/usrp/fpga/megacells/addsub16.cmp
new file mode 100755 (executable)
index 0000000..e32e01b
--- /dev/null
@@ -0,0 +1,33 @@
+--Copyright (C) 1991-2003 Altera Corporation
+--Any  megafunction  design,  and related netlist (encrypted  or  decrypted),
+--support information,  device programming or simulation file,  and any other
+--associated  documentation or information  provided by  Altera  or a partner
+--under  Altera's   Megafunction   Partnership   Program  may  be  used  only
+--to program  PLD  devices (but not masked  PLD  devices) from  Altera.   Any
+--other  use  of such  megafunction  design,  netlist,  support  information,
+--device programming or simulation file,  or any other  related documentation
+--or information  is prohibited  for  any  other purpose,  including, but not
+--limited to  modification,  reverse engineering,  de-compiling, or use  with
+--any other  silicon devices,  unless such use is  explicitly  licensed under
+--a separate agreement with  Altera  or a megafunction partner.  Title to the
+--intellectual property,  including patents,  copyrights,  trademarks,  trade
+--secrets,  or maskworks,  embodied in any such megafunction design, netlist,
+--support  information,  device programming or simulation file,  or any other
+--related documentation or information provided by  Altera  or a megafunction
+--partner, remains with Altera, the megafunction partner, or their respective
+--licensors. No other licenses, including any licenses needed under any third
+--party's intellectual property, are provided herein.
+
+
+component addsub16
+       PORT
+       (
+               add_sub         : IN STD_LOGIC ;
+               dataa           : IN STD_LOGIC_VECTOR (15 DOWNTO 0);
+               datab           : IN STD_LOGIC_VECTOR (15 DOWNTO 0);
+               clock           : IN STD_LOGIC ;
+               aclr            : IN STD_LOGIC ;
+               clken           : IN STD_LOGIC ;
+               result          : OUT STD_LOGIC_VECTOR (15 DOWNTO 0)
+       );
+end component;
diff --git a/usrp/fpga/megacells/addsub16.inc b/usrp/fpga/megacells/addsub16.inc
new file mode 100755 (executable)
index 0000000..846f301
--- /dev/null
@@ -0,0 +1,34 @@
+--Copyright (C) 1991-2003 Altera Corporation
+--Any  megafunction  design,  and related netlist (encrypted  or  decrypted),
+--support information,  device programming or simulation file,  and any other
+--associated  documentation or information  provided by  Altera  or a partner
+--under  Altera's   Megafunction   Partnership   Program  may  be  used  only
+--to program  PLD  devices (but not masked  PLD  devices) from  Altera.   Any
+--other  use  of such  megafunction  design,  netlist,  support  information,
+--device programming or simulation file,  or any other  related documentation
+--or information  is prohibited  for  any  other purpose,  including, but not
+--limited to  modification,  reverse engineering,  de-compiling, or use  with
+--any other  silicon devices,  unless such use is  explicitly  licensed under
+--a separate agreement with  Altera  or a megafunction partner.  Title to the
+--intellectual property,  including patents,  copyrights,  trademarks,  trade
+--secrets,  or maskworks,  embodied in any such megafunction design, netlist,
+--support  information,  device programming or simulation file,  or any other
+--related documentation or information provided by  Altera  or a megafunction
+--partner, remains with Altera, the megafunction partner, or their respective
+--licensors. No other licenses, including any licenses needed under any third
+--party's intellectual property, are provided herein.
+
+
+FUNCTION addsub16 
+(
+       add_sub,
+       dataa[15..0],
+       datab[15..0],
+       clock,
+       aclr,
+       clken
+)
+
+RETURNS (
+       result[15..0]
+);
diff --git a/usrp/fpga/megacells/addsub16.v b/usrp/fpga/megacells/addsub16.v
new file mode 100755 (executable)
index 0000000..431af3e
--- /dev/null
@@ -0,0 +1,438 @@
+// megafunction wizard: %LPM_ADD_SUB%CBX%
+// GENERATION: STANDARD
+// VERSION: WM1.0
+// MODULE: lpm_add_sub 
+
+// ============================================================
+// File Name: addsub16.v
+// Megafunction Name(s):
+//                     lpm_add_sub
+// ============================================================
+// ************************************************************
+// THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE!
+// ************************************************************
+
+
+//Copyright (C) 1991-2003 Altera Corporation
+//Any  megafunction  design,  and related netlist (encrypted  or  decrypted),
+//support information,  device programming or simulation file,  and any other
+//associated  documentation or information  provided by  Altera  or a partner
+//under  Altera's   Megafunction   Partnership   Program  may  be  used  only
+//to program  PLD  devices (but not masked  PLD  devices) from  Altera.   Any
+//other  use  of such  megafunction  design,  netlist,  support  information,
+//device programming or simulation file,  or any other  related documentation
+//or information  is prohibited  for  any  other purpose,  including, but not
+//limited to  modification,  reverse engineering,  de-compiling, or use  with
+//any other  silicon devices,  unless such use is  explicitly  licensed under
+//a separate agreement with  Altera  or a megafunction partner.  Title to the
+//intellectual property,  including patents,  copyrights,  trademarks,  trade
+//secrets,  or maskworks,  embodied in any such megafunction design, netlist,
+//support  information,  device programming or simulation file,  or any other
+//related documentation or information provided by  Altera  or a megafunction
+//partner, remains with Altera, the megafunction partner, or their respective
+//licensors. No other licenses, including any licenses needed under any third
+//party's intellectual property, are provided herein.
+
+
+//lpm_add_sub DEVICE_FAMILY=Cyclone LPM_PIPELINE=1 LPM_WIDTH=16 aclr add_sub clken clock dataa datab result
+//VERSION_BEGIN 3.0 cbx_lpm_add_sub 2003:04:10:18:28:42:SJ cbx_mgl 2003:06:11:11:00:44:SJ cbx_stratix 2003:05:16:10:26:50:SJ  VERSION_END
+
+//synthesis_resources = lut 17 
+module  addsub16_add_sub_gp9
+       ( 
+       aclr,
+       add_sub,
+       clken,
+       clock,
+       dataa,
+       datab,
+       result) /* synthesis synthesis_clearbox=1 */;
+       input   aclr;
+       input   add_sub;
+       input   clken;
+       input   clock;
+       input   [15:0]  dataa;
+       input   [15:0]  datab;
+       output   [15:0]  result;
+
+       wire  [0:0]   wire_add_sub_cella_0cout;
+       wire  [0:0]   wire_add_sub_cella_1cout;
+       wire  [0:0]   wire_add_sub_cella_2cout;
+       wire  [0:0]   wire_add_sub_cella_3cout;
+       wire  [0:0]   wire_add_sub_cella_4cout;
+       wire  [0:0]   wire_add_sub_cella_5cout;
+       wire  [0:0]   wire_add_sub_cella_6cout;
+       wire  [0:0]   wire_add_sub_cella_7cout;
+       wire  [0:0]   wire_add_sub_cella_8cout;
+       wire  [0:0]   wire_add_sub_cella_9cout;
+       wire  [0:0]   wire_add_sub_cella_10cout;
+       wire  [0:0]   wire_add_sub_cella_11cout;
+       wire  [0:0]   wire_add_sub_cella_12cout;
+       wire  [0:0]   wire_add_sub_cella_13cout;
+       wire  [0:0]   wire_add_sub_cella_14cout;
+       wire  [15:0]   wire_add_sub_cella_dataa;
+       wire  [15:0]   wire_add_sub_cella_datab;
+       wire  [15:0]   wire_add_sub_cella_regout;
+       wire  wire_strx_lcell1_cout;
+
+       stratix_lcell   add_sub_cella_0
+       ( 
+       .aclr(aclr),
+       .cin(wire_strx_lcell1_cout),
+       .clk(clock),
+       .cout(wire_add_sub_cella_0cout[0:0]),
+       .dataa(wire_add_sub_cella_dataa[0:0]),
+       .datab(wire_add_sub_cella_datab[0:0]),
+       .ena(clken),
+       .inverta((~ add_sub)),
+       .regout(wire_add_sub_cella_regout[0:0]));
+       defparam
+               add_sub_cella_0.cin_used = "true",
+               add_sub_cella_0.lut_mask = "96e8",
+               add_sub_cella_0.operation_mode = "arithmetic",
+               add_sub_cella_0.sum_lutc_input = "cin",
+               add_sub_cella_0.lpm_type = "stratix_lcell";
+       stratix_lcell   add_sub_cella_1
+       ( 
+       .aclr(aclr),
+       .cin(wire_add_sub_cella_0cout[0:0]),
+       .clk(clock),
+       .cout(wire_add_sub_cella_1cout[0:0]),
+       .dataa(wire_add_sub_cella_dataa[1:1]),
+       .datab(wire_add_sub_cella_datab[1:1]),
+       .ena(clken),
+       .inverta((~ add_sub)),
+       .regout(wire_add_sub_cella_regout[1:1]));
+       defparam
+               add_sub_cella_1.cin_used = "true",
+               add_sub_cella_1.lut_mask = "96e8",
+               add_sub_cella_1.operation_mode = "arithmetic",
+               add_sub_cella_1.sum_lutc_input = "cin",
+               add_sub_cella_1.lpm_type = "stratix_lcell";
+       stratix_lcell   add_sub_cella_2
+       ( 
+       .aclr(aclr),
+       .cin(wire_add_sub_cella_1cout[0:0]),
+       .clk(clock),
+       .cout(wire_add_sub_cella_2cout[0:0]),
+       .dataa(wire_add_sub_cella_dataa[2:2]),
+       .datab(wire_add_sub_cella_datab[2:2]),
+       .ena(clken),
+       .inverta((~ add_sub)),
+       .regout(wire_add_sub_cella_regout[2:2]));
+       defparam
+               add_sub_cella_2.cin_used = "true",
+               add_sub_cella_2.lut_mask = "96e8",
+               add_sub_cella_2.operation_mode = "arithmetic",
+               add_sub_cella_2.sum_lutc_input = "cin",
+               add_sub_cella_2.lpm_type = "stratix_lcell";
+       stratix_lcell   add_sub_cella_3
+       ( 
+       .aclr(aclr),
+       .cin(wire_add_sub_cella_2cout[0:0]),
+       .clk(clock),
+       .cout(wire_add_sub_cella_3cout[0:0]),
+       .dataa(wire_add_sub_cella_dataa[3:3]),
+       .datab(wire_add_sub_cella_datab[3:3]),
+       .ena(clken),
+       .inverta((~ add_sub)),
+       .regout(wire_add_sub_cella_regout[3:3]));
+       defparam
+               add_sub_cella_3.cin_used = "true",
+               add_sub_cella_3.lut_mask = "96e8",
+               add_sub_cella_3.operation_mode = "arithmetic",
+               add_sub_cella_3.sum_lutc_input = "cin",
+               add_sub_cella_3.lpm_type = "stratix_lcell";
+       stratix_lcell   add_sub_cella_4
+       ( 
+       .aclr(aclr),
+       .cin(wire_add_sub_cella_3cout[0:0]),
+       .clk(clock),
+       .cout(wire_add_sub_cella_4cout[0:0]),
+       .dataa(wire_add_sub_cella_dataa[4:4]),
+       .datab(wire_add_sub_cella_datab[4:4]),
+       .ena(clken),
+       .inverta((~ add_sub)),
+       .regout(wire_add_sub_cella_regout[4:4]));
+       defparam
+               add_sub_cella_4.cin_used = "true",
+               add_sub_cella_4.lut_mask = "96e8",
+               add_sub_cella_4.operation_mode = "arithmetic",
+               add_sub_cella_4.sum_lutc_input = "cin",
+               add_sub_cella_4.lpm_type = "stratix_lcell";
+       stratix_lcell   add_sub_cella_5
+       ( 
+       .aclr(aclr),
+       .cin(wire_add_sub_cella_4cout[0:0]),
+       .clk(clock),
+       .cout(wire_add_sub_cella_5cout[0:0]),
+       .dataa(wire_add_sub_cella_dataa[5:5]),
+       .datab(wire_add_sub_cella_datab[5:5]),
+       .ena(clken),
+       .inverta((~ add_sub)),
+       .regout(wire_add_sub_cella_regout[5:5]));
+       defparam
+               add_sub_cella_5.cin_used = "true",
+               add_sub_cella_5.lut_mask = "96e8",
+               add_sub_cella_5.operation_mode = "arithmetic",
+               add_sub_cella_5.sum_lutc_input = "cin",
+               add_sub_cella_5.lpm_type = "stratix_lcell";
+       stratix_lcell   add_sub_cella_6
+       ( 
+       .aclr(aclr),
+       .cin(wire_add_sub_cella_5cout[0:0]),
+       .clk(clock),
+       .cout(wire_add_sub_cella_6cout[0:0]),
+       .dataa(wire_add_sub_cella_dataa[6:6]),
+       .datab(wire_add_sub_cella_datab[6:6]),
+       .ena(clken),
+       .inverta((~ add_sub)),
+       .regout(wire_add_sub_cella_regout[6:6]));
+       defparam
+               add_sub_cella_6.cin_used = "true",
+               add_sub_cella_6.lut_mask = "96e8",
+               add_sub_cella_6.operation_mode = "arithmetic",
+               add_sub_cella_6.sum_lutc_input = "cin",
+               add_sub_cella_6.lpm_type = "stratix_lcell";
+       stratix_lcell   add_sub_cella_7
+       ( 
+       .aclr(aclr),
+       .cin(wire_add_sub_cella_6cout[0:0]),
+       .clk(clock),
+       .cout(wire_add_sub_cella_7cout[0:0]),
+       .dataa(wire_add_sub_cella_dataa[7:7]),
+       .datab(wire_add_sub_cella_datab[7:7]),
+       .ena(clken),
+       .inverta((~ add_sub)),
+       .regout(wire_add_sub_cella_regout[7:7]));
+       defparam
+               add_sub_cella_7.cin_used = "true",
+               add_sub_cella_7.lut_mask = "96e8",
+               add_sub_cella_7.operation_mode = "arithmetic",
+               add_sub_cella_7.sum_lutc_input = "cin",
+               add_sub_cella_7.lpm_type = "stratix_lcell";
+       stratix_lcell   add_sub_cella_8
+       ( 
+       .aclr(aclr),
+       .cin(wire_add_sub_cella_7cout[0:0]),
+       .clk(clock),
+       .cout(wire_add_sub_cella_8cout[0:0]),
+       .dataa(wire_add_sub_cella_dataa[8:8]),
+       .datab(wire_add_sub_cella_datab[8:8]),
+       .ena(clken),
+       .inverta((~ add_sub)),
+       .regout(wire_add_sub_cella_regout[8:8]));
+       defparam
+               add_sub_cella_8.cin_used = "true",
+               add_sub_cella_8.lut_mask = "96e8",
+               add_sub_cella_8.operation_mode = "arithmetic",
+               add_sub_cella_8.sum_lutc_input = "cin",
+               add_sub_cella_8.lpm_type = "stratix_lcell";
+       stratix_lcell   add_sub_cella_9
+       ( 
+       .aclr(aclr),
+       .cin(wire_add_sub_cella_8cout[0:0]),
+       .clk(clock),
+       .cout(wire_add_sub_cella_9cout[0:0]),
+       .dataa(wire_add_sub_cella_dataa[9:9]),
+       .datab(wire_add_sub_cella_datab[9:9]),
+       .ena(clken),
+       .inverta((~ add_sub)),
+       .regout(wire_add_sub_cella_regout[9:9]));
+       defparam
+               add_sub_cella_9.cin_used = "true",
+               add_sub_cella_9.lut_mask = "96e8",
+               add_sub_cella_9.operation_mode = "arithmetic",
+               add_sub_cella_9.sum_lutc_input = "cin",
+               add_sub_cella_9.lpm_type = "stratix_lcell";
+       stratix_lcell   add_sub_cella_10
+       ( 
+       .aclr(aclr),
+       .cin(wire_add_sub_cella_9cout[0:0]),
+       .clk(clock),
+       .cout(wire_add_sub_cella_10cout[0:0]),
+       .dataa(wire_add_sub_cella_dataa[10:10]),
+       .datab(wire_add_sub_cella_datab[10:10]),
+       .ena(clken),
+       .inverta((~ add_sub)),
+       .regout(wire_add_sub_cella_regout[10:10]));
+       defparam
+               add_sub_cella_10.cin_used = "true",
+               add_sub_cella_10.lut_mask = "96e8",
+               add_sub_cella_10.operation_mode = "arithmetic",
+               add_sub_cella_10.sum_lutc_input = "cin",
+               add_sub_cella_10.lpm_type = "stratix_lcell";
+       stratix_lcell   add_sub_cella_11
+       ( 
+       .aclr(aclr),
+       .cin(wire_add_sub_cella_10cout[0:0]),
+       .clk(clock),
+       .cout(wire_add_sub_cella_11cout[0:0]),
+       .dataa(wire_add_sub_cella_dataa[11:11]),
+       .datab(wire_add_sub_cella_datab[11:11]),
+       .ena(clken),
+       .inverta((~ add_sub)),
+       .regout(wire_add_sub_cella_regout[11:11]));
+       defparam
+               add_sub_cella_11.cin_used = "true",
+               add_sub_cella_11.lut_mask = "96e8",
+               add_sub_cella_11.operation_mode = "arithmetic",
+               add_sub_cella_11.sum_lutc_input = "cin",
+               add_sub_cella_11.lpm_type = "stratix_lcell";
+       stratix_lcell   add_sub_cella_12
+       ( 
+       .aclr(aclr),
+       .cin(wire_add_sub_cella_11cout[0:0]),
+       .clk(clock),
+       .cout(wire_add_sub_cella_12cout[0:0]),
+       .dataa(wire_add_sub_cella_dataa[12:12]),
+       .datab(wire_add_sub_cella_datab[12:12]),
+       .ena(clken),
+       .inverta((~ add_sub)),
+       .regout(wire_add_sub_cella_regout[12:12]));
+       defparam
+               add_sub_cella_12.cin_used = "true",
+               add_sub_cella_12.lut_mask = "96e8",
+               add_sub_cella_12.operation_mode = "arithmetic",
+               add_sub_cella_12.sum_lutc_input = "cin",
+               add_sub_cella_12.lpm_type = "stratix_lcell";
+       stratix_lcell   add_sub_cella_13
+       ( 
+       .aclr(aclr),
+       .cin(wire_add_sub_cella_12cout[0:0]),
+       .clk(clock),
+       .cout(wire_add_sub_cella_13cout[0:0]),
+       .dataa(wire_add_sub_cella_dataa[13:13]),
+       .datab(wire_add_sub_cella_datab[13:13]),
+       .ena(clken),
+       .inverta((~ add_sub)),
+       .regout(wire_add_sub_cella_regout[13:13]));
+       defparam
+               add_sub_cella_13.cin_used = "true",
+               add_sub_cella_13.lut_mask = "96e8",
+               add_sub_cella_13.operation_mode = "arithmetic",
+               add_sub_cella_13.sum_lutc_input = "cin",
+               add_sub_cella_13.lpm_type = "stratix_lcell";
+       stratix_lcell   add_sub_cella_14
+       ( 
+       .aclr(aclr),
+       .cin(wire_add_sub_cella_13cout[0:0]),
+       .clk(clock),
+       .cout(wire_add_sub_cella_14cout[0:0]),
+       .dataa(wire_add_sub_cella_dataa[14:14]),
+       .datab(wire_add_sub_cella_datab[14:14]),
+       .ena(clken),
+       .inverta((~ add_sub)),
+       .regout(wire_add_sub_cella_regout[14:14]));
+       defparam
+               add_sub_cella_14.cin_used = "true",
+               add_sub_cella_14.lut_mask = "96e8",
+               add_sub_cella_14.operation_mode = "arithmetic",
+               add_sub_cella_14.sum_lutc_input = "cin",
+               add_sub_cella_14.lpm_type = "stratix_lcell";
+       stratix_lcell   add_sub_cella_15
+       ( 
+       .aclr(aclr),
+       .cin(wire_add_sub_cella_14cout[0:0]),
+       .clk(clock),
+       .dataa(wire_add_sub_cella_dataa[15:15]),
+       .datab(wire_add_sub_cella_datab[15:15]),
+       .ena(clken),
+       .inverta((~ add_sub)),
+       .regout(wire_add_sub_cella_regout[15:15]));
+       defparam
+               add_sub_cella_15.cin_used = "true",
+               add_sub_cella_15.lut_mask = "9696",
+               add_sub_cella_15.operation_mode = "normal",
+               add_sub_cella_15.sum_lutc_input = "cin",
+               add_sub_cella_15.lpm_type = "stratix_lcell";
+       assign
+               wire_add_sub_cella_dataa = datab,
+               wire_add_sub_cella_datab = dataa;
+       stratix_lcell   strx_lcell1
+       ( 
+       .cout(wire_strx_lcell1_cout),
+       .dataa(1'b0),
+       .datab((~ add_sub)),
+       .inverta((~ add_sub)));
+       defparam
+               strx_lcell1.cin_used = "false",
+               strx_lcell1.lut_mask = "00cc",
+               strx_lcell1.operation_mode = "arithmetic",
+               strx_lcell1.lpm_type = "stratix_lcell";
+       assign
+               result = wire_add_sub_cella_regout;
+endmodule //addsub16_add_sub_gp9
+//VALID FILE
+
+
+module addsub16 (
+       add_sub,
+       dataa,
+       datab,
+       clock,
+       aclr,
+       clken,
+       result)/* synthesis synthesis_clearbox = 1 */;
+
+       input     add_sub;
+       input   [15:0]  dataa;
+       input   [15:0]  datab;
+       input     clock;
+       input     aclr;
+       input     clken;
+       output  [15:0]  result;
+
+       wire [15:0] sub_wire0;
+       wire [15:0] result = sub_wire0[15:0];
+
+       addsub16_add_sub_gp9    addsub16_add_sub_gp9_component (
+                               .dataa (dataa),
+                               .add_sub (add_sub),
+                               .datab (datab),
+                               .clken (clken),
+                               .aclr (aclr),
+                               .clock (clock),
+                               .result (sub_wire0));
+
+endmodule
+
+// ============================================================
+// CNX file retrieval info
+// ============================================================
+// Retrieval info: PRIVATE: nBit NUMERIC "16"
+// Retrieval info: PRIVATE: Function NUMERIC "2"
+// Retrieval info: PRIVATE: WhichConstant NUMERIC "0"
+// Retrieval info: PRIVATE: ConstantA NUMERIC "0"
+// Retrieval info: PRIVATE: ConstantB NUMERIC "0"
+// Retrieval info: PRIVATE: ValidCtA NUMERIC "0"
+// Retrieval info: PRIVATE: ValidCtB NUMERIC "0"
+// Retrieval info: PRIVATE: CarryIn NUMERIC "0"
+// Retrieval info: PRIVATE: CarryOut NUMERIC "0"
+// Retrieval info: PRIVATE: Overflow NUMERIC "0"
+// Retrieval info: PRIVATE: Latency NUMERIC "1"
+// Retrieval info: PRIVATE: aclr NUMERIC "1"
+// Retrieval info: PRIVATE: clken NUMERIC "1"
+// Retrieval info: PRIVATE: LPM_PIPELINE NUMERIC "1"
+// Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING "Cyclone"
+// Retrieval info: CONSTANT: LPM_WIDTH NUMERIC "16"
+// Retrieval info: CONSTANT: LPM_DIRECTION STRING "UNUSED"
+// Retrieval info: CONSTANT: LPM_TYPE STRING "LPM_ADD_SUB"
+// Retrieval info: CONSTANT: LPM_HINT STRING "ONE_INPUT_IS_CONSTANT=NO"
+// Retrieval info: CONSTANT: LPM_PIPELINE NUMERIC "1"
+// Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone"
+// Retrieval info: USED_PORT: add_sub 0 0 0 0 INPUT NODEFVAL add_sub
+// Retrieval info: USED_PORT: result 0 0 16 0 OUTPUT NODEFVAL result[15..0]
+// Retrieval info: USED_PORT: dataa 0 0 16 0 INPUT NODEFVAL dataa[15..0]
+// Retrieval info: USED_PORT: datab 0 0 16 0 INPUT NODEFVAL datab[15..0]
+// Retrieval info: USED_PORT: clock 0 0 0 0 INPUT NODEFVAL clock
+// Retrieval info: USED_PORT: aclr 0 0 0 0 INPUT NODEFVAL aclr
+// Retrieval info: USED_PORT: clken 0 0 0 0 INPUT NODEFVAL clken
+// Retrieval info: CONNECT: @add_sub 0 0 0 0 add_sub 0 0 0 0
+// Retrieval info: CONNECT: result 0 0 16 0 @result 0 0 16 0
+// Retrieval info: CONNECT: @dataa 0 0 16 0 dataa 0 0 16 0
+// Retrieval info: CONNECT: @datab 0 0 16 0 datab 0 0 16 0
+// Retrieval info: CONNECT: @clock 0 0 0 0 clock 0 0 0 0
+// Retrieval info: CONNECT: @aclr 0 0 0 0 aclr 0 0 0 0
+// Retrieval info: CONNECT: @clken 0 0 0 0 clken 0 0 0 0
+// Retrieval info: LIBRARY: lpm lpm.lpm_components.all
diff --git a/usrp/fpga/megacells/addsub16_bb.v b/usrp/fpga/megacells/addsub16_bb.v
new file mode 100755 (executable)
index 0000000..8e1e7c6
--- /dev/null
@@ -0,0 +1,39 @@
+//Copyright (C) 1991-2003 Altera Corporation
+//Any  megafunction  design,  and related netlist (encrypted  or  decrypted),
+//support information,  device programming or simulation file,  and any other
+//associated  documentation or information  provided by  Altera  or a partner
+//under  Altera's   Megafunction   Partnership   Program  may  be  used  only
+//to program  PLD  devices (but not masked  PLD  devices) from  Altera.   Any
+//other  use  of such  megafunction  design,  netlist,  support  information,
+//device programming or simulation file,  or any other  related documentation
+//or information  is prohibited  for  any  other purpose,  including, but not
+//limited to  modification,  reverse engineering,  de-compiling, or use  with
+//any other  silicon devices,  unless such use is  explicitly  licensed under
+//a separate agreement with  Altera  or a megafunction partner.  Title to the
+//intellectual property,  including patents,  copyrights,  trademarks,  trade
+//secrets,  or maskworks,  embodied in any such megafunction design, netlist,
+//support  information,  device programming or simulation file,  or any other
+//related documentation or information provided by  Altera  or a megafunction
+//partner, remains with Altera, the megafunction partner, or their respective
+//licensors. No other licenses, including any licenses needed under any third
+//party's intellectual property, are provided herein.
+
+module addsub16 (
+       add_sub,
+       dataa,
+       datab,
+       clock,
+       aclr,
+       clken,
+       result)/* synthesis synthesis_clearbox = 1 */;
+
+       input     add_sub;
+       input   [15:0]  dataa;
+       input   [15:0]  datab;
+       input     clock;
+       input     aclr;
+       input     clken;
+       output  [15:0]  result;
+
+endmodule
+
diff --git a/usrp/fpga/megacells/addsub16_inst.v b/usrp/fpga/megacells/addsub16_inst.v
new file mode 100755 (executable)
index 0000000..4a81ff2
--- /dev/null
@@ -0,0 +1,9 @@
+addsub16       addsub16_inst (
+       .add_sub ( add_sub_sig ),
+       .dataa ( dataa_sig ),
+       .datab ( datab_sig ),
+       .clock ( clock_sig ),
+       .aclr ( aclr_sig ),
+       .clken ( clken_sig ),
+       .result ( result_sig )
+       );
diff --git a/usrp/fpga/megacells/bustri.bsf b/usrp/fpga/megacells/bustri.bsf
new file mode 100755 (executable)
index 0000000..f1bc3ca
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+WARNING: Do NOT edit the input and output ports in this file in a text
+editor if you plan to continue editing the block that represents it in
+the Block Editor! File corruption is VERY likely to occur.
+*/
+/*
+Copyright (C) 1991-2003 Altera Corporation
+Any  megafunction  design,  and related netlist (encrypted  or  decrypted),
+support information,  device programming or simulation file,  and any other
+associated  documentation or information  provided by  Altera  or a partner
+under  Altera's   Megafunction   Partnership   Program  may  be  used  only
+to program  PLD  devices (but not masked  PLD  devices) from  Altera.   Any
+other  use  of such  megafunction  design,  netlist,  support  information,
+device programming or simulation file,  or any other  related documentation
+or information  is prohibited  for  any  other purpose,  including, but not
+limited to  modification,  reverse engineering,  de-compiling, or use  with
+any other  silicon devices,  unless such use is  explicitly  licensed under
+a separate agreement with  Altera  or a megafunction partner.  Title to the
+intellectual property,  including patents,  copyrights,  trademarks,  trade
+secrets,  or maskworks,  embodied in any such megafunction design, netlist,
+support  information,  device programming or simulation file,  or any other
+related documentation or information provided by  Altera  or a megafunction
+partner, remains with Altera, the megafunction partner, or their respective
+licensors. No other licenses, including any licenses needed under any third
+party's intellectual property, are provided herein.
+*/
+(header "symbol" (version "1.1"))
+(symbol
+       (rect 0 0 80 40)
+       (text "bustri" (rect 24 1 61 17)(font "Arial" (font_size 10)))
+       (text "inst" (rect 8 24 25 36)(font "Arial" ))
+       (port
+               (pt 40 40)
+               (input)
+               (text "enabledt" (rect 0 0 48 14)(font "Arial" (font_size 8)))
+               (text "enabledt" (rect 40 -6 53 36)(font "Arial" (font_size 8))(invisible))
+               (line (pt 40 40)(pt 40 28)(line_width 1))
+       )
+       (port
+               (pt 0 24)
+               (input)
+               (text "data[15..0]" (rect 0 0 60 14)(font "Arial" (font_size 8)))
+               (text "data[15..0]" (rect -3 -27 10 24)(font "Arial" (font_size 8))(invisible))
+               (line (pt 0 24)(pt 32 24)(line_width 3))
+       )
+       (port
+               (pt 80 24)
+               (bidir)
+               (text "tridata[15..0]" (rect 0 0 70 14)(font "Arial" (font_size 8)))
+               (text "tridata[15..0]" (rect 84 -36 97 24)(font "Arial" (font_size 8))(invisible))
+               (line (pt 80 24)(pt 48 24)(line_width 3))
+       )
+       (drawing
+               (text "16" (rect 61 25 71 37)(font "Arial" ))
+               (text "16" (rect 13 25 23 37)(font "Arial" ))
+               (line (pt 32 16)(pt 48 24)(line_width 1))
+               (line (pt 48 24)(pt 32 32)(line_width 1))
+               (line (pt 32 32)(pt 32 16)(line_width 1))
+               (line (pt 56 28)(pt 64 20)(line_width 1))
+               (line (pt 8 28)(pt 16 20)(line_width 1))
+       )
+)
diff --git a/usrp/fpga/megacells/bustri.cmp b/usrp/fpga/megacells/bustri.cmp
new file mode 100755 (executable)
index 0000000..87599ca
--- /dev/null
@@ -0,0 +1,29 @@
+--Copyright (C) 1991-2003 Altera Corporation
+--Any  megafunction  design,  and related netlist (encrypted  or  decrypted),
+--support information,  device programming or simulation file,  and any other
+--associated  documentation or information  provided by  Altera  or a partner
+--under  Altera's   Megafunction   Partnership   Program  may  be  used  only
+--to program  PLD  devices (but not masked  PLD  devices) from  Altera.   Any
+--other  use  of such  megafunction  design,  netlist,  support  information,
+--device programming or simulation file,  or any other  related documentation
+--or information  is prohibited  for  any  other purpose,  including, but not
+--limited to  modification,  reverse engineering,  de-compiling, or use  with
+--any other  silicon devices,  unless such use is  explicitly  licensed under
+--a separate agreement with  Altera  or a megafunction partner.  Title to the
+--intellectual property,  including patents,  copyrights,  trademarks,  trade
+--secrets,  or maskworks,  embodied in any such megafunction design, netlist,
+--support  information,  device programming or simulation file,  or any other
+--related documentation or information provided by  Altera  or a megafunction
+--partner, remains with Altera, the megafunction partner, or their respective
+--licensors. No other licenses, including any licenses needed under any third
+--party's intellectual property, are provided herein.
+
+
+component bustri
+       PORT
+       (
+               data            : IN STD_LOGIC_VECTOR (15 DOWNTO 0);
+               enabledt                : IN STD_LOGIC ;
+               tridata         : INOUT STD_LOGIC_VECTOR (15 DOWNTO 0)
+       );
+end component;
diff --git a/usrp/fpga/megacells/bustri.inc b/usrp/fpga/megacells/bustri.inc
new file mode 100755 (executable)
index 0000000..3999503
--- /dev/null
@@ -0,0 +1,30 @@
+--Copyright (C) 1991-2003 Altera Corporation
+--Any  megafunction  design,  and related netlist (encrypted  or  decrypted),
+--support information,  device programming or simulation file,  and any other
+--associated  documentation or information  provided by  Altera  or a partner
+--under  Altera's   Megafunction   Partnership   Program  may  be  used  only
+--to program  PLD  devices (but not masked  PLD  devices) from  Altera.   Any
+--other  use  of such  megafunction  design,  netlist,  support  information,
+--device programming or simulation file,  or any other  related documentation
+--or information  is prohibited  for  any  other purpose,  including, but not
+--limited to  modification,  reverse engineering,  de-compiling, or use  with
+--any other  silicon devices,  unless such use is  explicitly  licensed under
+--a separate agreement with  Altera  or a megafunction partner.  Title to the
+--intellectual property,  including patents,  copyrights,  trademarks,  trade
+--secrets,  or maskworks,  embodied in any such megafunction design, netlist,
+--support  information,  device programming or simulation file,  or any other
+--related documentation or information provided by  Altera  or a megafunction
+--partner, remains with Altera, the megafunction partner, or their respective
+--licensors. No other licenses, including any licenses needed under any third
+--party's intellectual property, are provided herein.
+
+
+FUNCTION bustri 
+(
+       data[15..0],
+       enabledt
+)
+
+RETURNS (
+       tridata[15..0]
+);
diff --git a/usrp/fpga/megacells/bustri.v b/usrp/fpga/megacells/bustri.v
new file mode 100755 (executable)
index 0000000..e40c694
--- /dev/null
@@ -0,0 +1,71 @@
+// megafunction wizard: %LPM_BUSTRI%
+// GENERATION: STANDARD
+// VERSION: WM1.0
+// MODULE: lpm_bustri 
+
+// ============================================================
+// File Name: bustri.v
+// Megafunction Name(s):
+//                     lpm_bustri
+// ============================================================
+// ************************************************************
+// THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE!
+// ************************************************************
+
+
+//Copyright (C) 1991-2003 Altera Corporation
+//Any  megafunction  design,  and related netlist (encrypted  or  decrypted),
+//support information,  device programming or simulation file,  and any other
+//associated  documentation or information  provided by  Altera  or a partner
+//under  Altera's   Megafunction   Partnership   Program  may  be  used  only
+//to program  PLD  devices (but not masked  PLD  devices) from  Altera.   Any
+//other  use  of such  megafunction  design,  netlist,  support  information,
+//device programming or simulation file,  or any other  related documentation
+//or information  is prohibited  for  any  other purpose,  including, but not
+//limited to  modification,  reverse engineering,  de-compiling, or use  with
+//any other  silicon devices,  unless such use is  explicitly  licensed under
+//a separate agreement with  Altera  or a megafunction partner.  Title to the
+//intellectual property,  including patents,  copyrights,  trademarks,  trade
+//secrets,  or maskworks,  embodied in any such megafunction design, netlist,
+//support  information,  device programming or simulation file,  or any other
+//related documentation or information provided by  Altera  or a megafunction
+//partner, remains with Altera, the megafunction partner, or their respective
+//licensors. No other licenses, including any licenses needed under any third
+//party's intellectual property, are provided herein.
+
+
+module bustri (
+       data,
+       enabledt,
+       tridata);
+
+       input   [15:0]  data;
+       input     enabledt;
+       inout   [15:0]  tridata;
+
+
+       lpm_bustri      lpm_bustri_component (
+                               .tridata (tridata),
+                               .enabledt (enabledt),
+                               .data (data));
+       defparam
+               lpm_bustri_component.lpm_width = 16,
+               lpm_bustri_component.lpm_type = "LPM_BUSTRI";
+
+
+endmodule
+
+// ============================================================
+// CNX file retrieval info
+// ============================================================
+// Retrieval info: PRIVATE: nBit NUMERIC "16"
+// Retrieval info: PRIVATE: BiDir NUMERIC "0"
+// Retrieval info: CONSTANT: LPM_WIDTH NUMERIC "16"
+// Retrieval info: CONSTANT: LPM_TYPE STRING "LPM_BUSTRI"
+// Retrieval info: USED_PORT: tridata 0 0 16 0 BIDIR NODEFVAL tridata[15..0]
+// Retrieval info: USED_PORT: data 0 0 16 0 INPUT NODEFVAL data[15..0]
+// Retrieval info: USED_PORT: enabledt 0 0 0 0 INPUT NODEFVAL enabledt
+// Retrieval info: CONNECT: tridata 0 0 16 0 @tridata 0 0 16 0
+// Retrieval info: CONNECT: @data 0 0 16 0 data 0 0 16 0
+// Retrieval info: CONNECT: @enabledt 0 0 0 0 enabledt 0 0 0 0
+// Retrieval info: LIBRARY: lpm lpm.lpm_components.all
diff --git a/usrp/fpga/megacells/bustri_bb.v b/usrp/fpga/megacells/bustri_bb.v
new file mode 100755 (executable)
index 0000000..4cbc160
--- /dev/null
@@ -0,0 +1,31 @@
+//Copyright (C) 1991-2003 Altera Corporation
+//Any  megafunction  design,  and related netlist (encrypted  or  decrypted),
+//support information,  device programming or simulation file,  and any other
+//associated  documentation or information  provided by  Altera  or a partner
+//under  Altera's   Megafunction   Partnership   Program  may  be  used  only
+//to program  PLD  devices (but not masked  PLD  devices) from  Altera.   Any
+//other  use  of such  megafunction  design,  netlist,  support  information,
+//device programming or simulation file,  or any other  related documentation
+//or information  is prohibited  for  any  other purpose,  including, but not
+//limited to  modification,  reverse engineering,  de-compiling, or use  with
+//any other  silicon devices,  unless such use is  explicitly  licensed under
+//a separate agreement with  Altera  or a megafunction partner.  Title to the
+//intellectual property,  including patents,  copyrights,  trademarks,  trade
+//secrets,  or maskworks,  embodied in any such megafunction design, netlist,
+//support  information,  device programming or simulation file,  or any other
+//related documentation or information provided by  Altera  or a megafunction
+//partner, remains with Altera, the megafunction partner, or their respective
+//licensors. No other licenses, including any licenses needed under any third
+//party's intellectual property, are provided herein.
+
+module bustri (
+       data,
+       enabledt,
+       tridata);
+
+       input   [15:0]  data;
+       input     enabledt;
+       inout   [15:0]  tridata;
+
+endmodule
+
diff --git a/usrp/fpga/megacells/bustri_inst.v b/usrp/fpga/megacells/bustri_inst.v
new file mode 100755 (executable)
index 0000000..2b4e496
--- /dev/null
@@ -0,0 +1,5 @@
+bustri bustri_inst (
+       .data ( data_sig ),
+       .enabledt ( enabledt_sig ),
+       .tridata ( tridata_sig )
+       );
diff --git a/usrp/fpga/megacells/clk_doubler.v b/usrp/fpga/megacells/clk_doubler.v
new file mode 100644 (file)
index 0000000..b3762a9
--- /dev/null
@@ -0,0 +1,198 @@
+// megafunction wizard: %ALTPLL%
+// GENERATION: STANDARD
+// VERSION: WM1.0
+// MODULE: altpll 
+
+// ============================================================
+// File Name: clk_doubler.v
+// Megafunction Name(s):
+//                     altpll
+// ============================================================
+// ************************************************************
+// THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE!
+//
+// 4.2 Build 156 11/29/2004 SJ Web Edition
+// ************************************************************
+
+
+//Copyright (C) 1991-2004 Altera Corporation
+//Any  megafunction  design,  and related netlist (encrypted  or  decrypted),
+//support information,  device programming or simulation file,  and any other
+//associated  documentation or information  provided by  Altera  or a partner
+//under  Altera's   Megafunction   Partnership   Program  may  be  used  only
+//to program  PLD  devices (but not masked  PLD  devices) from  Altera.   Any
+//other  use  of such  megafunction  design,  netlist,  support  information,
+//device programming or simulation file,  or any other  related documentation
+//or information  is prohibited  for  any  other purpose,  including, but not
+//limited to  modification,  reverse engineering,  de-compiling, or use  with
+//any other  silicon devices,  unless such use is  explicitly  licensed under
+//a separate agreement with  Altera  or a megafunction partner.  Title to the
+//intellectual property,  including patents,  copyrights,  trademarks,  trade
+//secrets,  or maskworks,  embodied in any such megafunction design, netlist,
+//support  information,  device programming or simulation file,  or any other
+//related documentation or information provided by  Altera  or a megafunction
+//partner, remains with Altera, the megafunction partner, or their respective
+//licensors. No other licenses, including any licenses needed under any third
+//party's intellectual property, are provided herein.
+
+
+// synopsys translate_off
+`timescale 1 ps / 1 ps
+// synopsys translate_on
+module clk_doubler (
+       inclk0,
+       c0);
+
+       input     inclk0;
+       output    c0;
+
+       wire [5:0] sub_wire0;
+       wire [0:0] sub_wire4 = 1'h0;
+       wire [0:0] sub_wire1 = sub_wire0[0:0];
+       wire  c0 = sub_wire1;
+       wire  sub_wire2 = inclk0;
+       wire [1:0] sub_wire3 = {sub_wire4, sub_wire2};
+
+       altpll  altpll_component (
+                               .inclk (sub_wire3),
+                               .clk (sub_wire0)
+                               // synopsys translate_off
+                               ,
+                               .activeclock (),
+                               .areset (),
+                               .clkbad (),
+                               .clkena (),
+                               .clkloss (),
+                               .clkswitch (),
+                               .enable0 (),
+                               .enable1 (),
+                               .extclk (),
+                               .extclkena (),
+                               .fbin (),
+                               .locked (),
+                               .pfdena (),
+                               .pllena (),
+                               .scanaclr (),
+                               .scanclk (),
+                               .scandata (),
+                               .scandataout (),
+                               .scandone (),
+                               .scanread (),
+                               .scanwrite (),
+                               .sclkout0 (),
+                               .sclkout1 ()
+                               // synopsys translate_on
+                               );
+       defparam
+               altpll_component.clk0_duty_cycle = 50,
+               altpll_component.lpm_type = "altpll",
+               altpll_component.clk0_multiply_by = 2,
+               altpll_component.inclk0_input_frequency = 15625,
+               altpll_component.clk0_divide_by = 1,
+               altpll_component.pll_type = "AUTO",
+               altpll_component.intended_device_family = "Cyclone",
+               altpll_component.operation_mode = "NORMAL",
+               altpll_component.compensate_clock = "CLK0",
+               altpll_component.clk0_phase_shift = "0";
+
+
+endmodule
+
+// ============================================================
+// CNX file retrieval info
+// ============================================================
+// Retrieval info: PRIVATE: MIRROR_CLK0 STRING "0"
+// Retrieval info: PRIVATE: PHASE_SHIFT_UNIT0 STRING "deg"
+// Retrieval info: PRIVATE: OUTPUT_FREQ_UNIT0 STRING "MHz"
+// Retrieval info: PRIVATE: INCLK1_FREQ_UNIT_COMBO STRING "MHz"
+// Retrieval info: PRIVATE: SPREAD_USE STRING "0"
+// Retrieval info: PRIVATE: SPREAD_FEATURE_ENABLED STRING "0"
+// Retrieval info: PRIVATE: GLOCKED_COUNTER_EDIT_CHANGED STRING "1"
+// Retrieval info: PRIVATE: GLOCK_COUNTER_EDIT NUMERIC "1048575"
+// Retrieval info: PRIVATE: SRC_SYNCH_COMP_RADIO STRING "0"
+// Retrieval info: PRIVATE: DUTY_CYCLE0 STRING "50.00000000"
+// Retrieval info: PRIVATE: PHASE_SHIFT0 STRING "0.00000000"
+// Retrieval info: PRIVATE: MULT_FACTOR0 NUMERIC "2"
+// Retrieval info: PRIVATE: OUTPUT_FREQ_MODE0 STRING "0"
+// Retrieval info: PRIVATE: SPREAD_PERCENT STRING "0.500"
+// Retrieval info: PRIVATE: LOCKED_OUTPUT_CHECK STRING "0"
+// Retrieval info: PRIVATE: PLL_ARESET_CHECK STRING "0"
+// Retrieval info: PRIVATE: STICKY_CLK0 STRING "1"
+// Retrieval info: PRIVATE: BANDWIDTH STRING "1.000"
+// Retrieval info: PRIVATE: BANDWIDTH_USE_CUSTOM STRING "0"
+// Retrieval info: PRIVATE: DEVICE_SPEED_GRADE STRING "8"
+// Retrieval info: PRIVATE: SPREAD_FREQ STRING "50.000"
+// Retrieval info: PRIVATE: BANDWIDTH_FEATURE_ENABLED STRING "0"
+// Retrieval info: PRIVATE: LONG_SCAN_RADIO STRING "1"
+// Retrieval info: PRIVATE: PLL_ENHPLL_CHECK NUMERIC "0"
+// Retrieval info: PRIVATE: LVDS_MODE_DATA_RATE_DIRTY NUMERIC "0"
+// Retrieval info: PRIVATE: USE_CLK0 STRING "1"
+// Retrieval info: PRIVATE: INCLK1_FREQ_EDIT_CHANGED STRING "1"
+// Retrieval info: PRIVATE: SCAN_FEATURE_ENABLED STRING "0"
+// Retrieval info: PRIVATE: ZERO_DELAY_RADIO STRING "0"
+// Retrieval info: PRIVATE: PLL_PFDENA_CHECK STRING "0"
+// Retrieval info: PRIVATE: CREATE_CLKBAD_CHECK STRING "0"
+// Retrieval info: PRIVATE: INCLK1_FREQ_EDIT STRING "100.000"
+// Retrieval info: PRIVATE: CUR_DEDICATED_CLK STRING "c0"
+// Retrieval info: PRIVATE: PLL_FASTPLL_CHECK NUMERIC "0"
+// Retrieval info: PRIVATE: ACTIVECLK_CHECK STRING "0"
+// Retrieval info: PRIVATE: BANDWIDTH_FREQ_UNIT STRING "MHz"
+// Retrieval info: PRIVATE: INCLK0_FREQ_UNIT_COMBO STRING "MHz"
+// Retrieval info: PRIVATE: GLOCKED_MODE_CHECK STRING "0"
+// Retrieval info: PRIVATE: NORMAL_MODE_RADIO STRING "1"
+// Retrieval info: PRIVATE: CUR_FBIN_CLK STRING "e0"
+// Retrieval info: PRIVATE: DIV_FACTOR0 NUMERIC "1"
+// Retrieval info: PRIVATE: INCLK1_FREQ_UNIT_CHANGED STRING "1"
+// Retrieval info: PRIVATE: HAS_MANUAL_SWITCHOVER STRING "1"
+// Retrieval info: PRIVATE: EXT_FEEDBACK_RADIO STRING "0"
+// Retrieval info: PRIVATE: PLL_AUTOPLL_CHECK NUMERIC "1"
+// Retrieval info: PRIVATE: CLKLOSS_CHECK STRING "0"
+// Retrieval info: PRIVATE: BANDWIDTH_USE_AUTO STRING "1"
+// Retrieval info: PRIVATE: SHORT_SCAN_RADIO STRING "0"
+// Retrieval info: PRIVATE: LVDS_MODE_DATA_RATE STRING "512.000"
+// Retrieval info: PRIVATE: CLKSWITCH_CHECK STRING "0"
+// Retrieval info: PRIVATE: SPREAD_FREQ_UNIT STRING "KHz"
+// Retrieval info: PRIVATE: PLL_ENA_CHECK STRING "0"
+// Retrieval info: PRIVATE: INCLK0_FREQ_EDIT STRING "64.000"
+// Retrieval info: PRIVATE: CNX_NO_COMPENSATE_RADIO STRING "0"
+// Retrieval info: PRIVATE: INT_FEEDBACK__MODE_RADIO STRING "1"
+// Retrieval info: PRIVATE: OUTPUT_FREQ0 STRING "100.000"
+// Retrieval info: PRIVATE: PRIMARY_CLK_COMBO STRING "inclk0"
+// Retrieval info: PRIVATE: CREATE_INCLK1_CHECK STRING "0"
+// Retrieval info: PRIVATE: SACN_INPUTS_CHECK STRING "0"
+// Retrieval info: PRIVATE: DEV_FAMILY STRING "Cyclone"
+// Retrieval info: PRIVATE: LOCK_LOSS_SWITCHOVER_CHECK STRING "0"
+// Retrieval info: PRIVATE: SWITCHOVER_COUNT_EDIT NUMERIC "1"
+// Retrieval info: PRIVATE: SWITCHOVER_FEATURE_ENABLED STRING "0"
+// Retrieval info: PRIVATE: BANDWIDTH_PRESET STRING "Low"
+// Retrieval info: PRIVATE: GLOCKED_FEATURE_ENABLED STRING "0"
+// Retrieval info: PRIVATE: USE_CLKENA0 STRING "0"
+// Retrieval info: PRIVATE: LVDS_PHASE_SHIFT_UNIT0 STRING "deg"
+// Retrieval info: PRIVATE: CLKBAD_SWITCHOVER_CHECK STRING "0"
+// Retrieval info: PRIVATE: BANDWIDTH_USE_PRESET STRING "0"
+// Retrieval info: PRIVATE: PLL_LVDS_PLL_CHECK NUMERIC "0"
+// Retrieval info: PRIVATE: DEVICE_FAMILY NUMERIC "11"
+// Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all
+// Retrieval info: CONSTANT: CLK0_DUTY_CYCLE NUMERIC "50"
+// Retrieval info: CONSTANT: LPM_TYPE STRING "altpll"
+// Retrieval info: CONSTANT: CLK0_MULTIPLY_BY NUMERIC "2"
+// Retrieval info: CONSTANT: INCLK0_INPUT_FREQUENCY NUMERIC "15625"
+// Retrieval info: CONSTANT: CLK0_DIVIDE_BY NUMERIC "1"
+// Retrieval info: CONSTANT: PLL_TYPE STRING "AUTO"
+// Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone"
+// Retrieval info: CONSTANT: OPERATION_MODE STRING "NORMAL"
+// Retrieval info: CONSTANT: COMPENSATE_CLOCK STRING "CLK0"
+// Retrieval info: CONSTANT: CLK0_PHASE_SHIFT STRING "0"
+// Retrieval info: USED_PORT: c0 0 0 0 0 OUTPUT VCC "c0"
+// Retrieval info: USED_PORT: @clk 0 0 6 0 OUTPUT VCC "@clk[5..0]"
+// Retrieval info: USED_PORT: inclk0 0 0 0 0 INPUT GND "inclk0"
+// Retrieval info: USED_PORT: @extclk 0 0 4 0 OUTPUT VCC "@extclk[3..0]"
+// Retrieval info: CONNECT: @inclk 0 0 1 0 inclk0 0 0 0 0
+// Retrieval info: CONNECT: c0 0 0 0 0 @clk 0 0 1 0
+// Retrieval info: CONNECT: @inclk 0 0 1 1 GND 0 0 0 0
+// Retrieval info: GEN_FILE: TYPE_NORMAL clk_doubler.v TRUE FALSE
+// Retrieval info: GEN_FILE: TYPE_NORMAL clk_doubler.inc FALSE FALSE
+// Retrieval info: GEN_FILE: TYPE_NORMAL clk_doubler.cmp FALSE FALSE
+// Retrieval info: GEN_FILE: TYPE_NORMAL clk_doubler.bsf FALSE FALSE
+// Retrieval info: GEN_FILE: TYPE_NORMAL clk_doubler_inst.v FALSE FALSE
+// Retrieval info: GEN_FILE: TYPE_NORMAL clk_doubler_bb.v TRUE FALSE
diff --git a/usrp/fpga/megacells/clk_doubler_bb.v b/usrp/fpga/megacells/clk_doubler_bb.v
new file mode 100644 (file)
index 0000000..48c52e7
--- /dev/null
@@ -0,0 +1,143 @@
+// megafunction wizard: %ALTPLL%VBB%
+// GENERATION: STANDARD
+// VERSION: WM1.0
+// MODULE: altpll 
+
+// ============================================================
+// File Name: clk_doubler.v
+// Megafunction Name(s):
+//                     altpll
+// ============================================================
+// ************************************************************
+// THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE!
+//
+// 4.2 Build 156 11/29/2004 SJ Web Edition
+// ************************************************************
+
+//Copyright (C) 1991-2004 Altera Corporation
+//Any  megafunction  design,  and related netlist (encrypted  or  decrypted),
+//support information,  device programming or simulation file,  and any other
+//associated  documentation or information  provided by  Altera  or a partner
+//under  Altera's   Megafunction   Partnership   Program  may  be  used  only
+//to program  PLD  devices (but not masked  PLD  devices) from  Altera.   Any
+//other  use  of such  megafunction  design,  netlist,  support  information,
+//device programming or simulation file,  or any other  related documentation
+//or information  is prohibited  for  any  other purpose,  including, but not
+//limited to  modification,  reverse engineering,  de-compiling, or use  with
+//any other  silicon devices,  unless such use is  explicitly  licensed under
+//a separate agreement with  Altera  or a megafunction partner.  Title to the
+//intellectual property,  including patents,  copyrights,  trademarks,  trade
+//secrets,  or maskworks,  embodied in any such megafunction design, netlist,
+//support  information,  device programming or simulation file,  or any other
+//related documentation or information provided by  Altera  or a megafunction
+//partner, remains with Altera, the megafunction partner, or their respective
+//licensors. No other licenses, including any licenses needed under any third
+//party's intellectual property, are provided herein.
+
+module clk_doubler (
+       inclk0,
+       c0);
+
+       input     inclk0;
+       output    c0;
+
+endmodule
+
+// ============================================================
+// CNX file retrieval info
+// ============================================================
+// Retrieval info: PRIVATE: MIRROR_CLK0 STRING "0"
+// Retrieval info: PRIVATE: PHASE_SHIFT_UNIT0 STRING "deg"
+// Retrieval info: PRIVATE: OUTPUT_FREQ_UNIT0 STRING "MHz"
+// Retrieval info: PRIVATE: INCLK1_FREQ_UNIT_COMBO STRING "MHz"
+// Retrieval info: PRIVATE: SPREAD_USE STRING "0"
+// Retrieval info: PRIVATE: SPREAD_FEATURE_ENABLED STRING "0"
+// Retrieval info: PRIVATE: GLOCKED_COUNTER_EDIT_CHANGED STRING "1"
+// Retrieval info: PRIVATE: GLOCK_COUNTER_EDIT NUMERIC "1048575"
+// Retrieval info: PRIVATE: SRC_SYNCH_COMP_RADIO STRING "0"
+// Retrieval info: PRIVATE: DUTY_CYCLE0 STRING "50.00000000"
+// Retrieval info: PRIVATE: PHASE_SHIFT0 STRING "0.00000000"
+// Retrieval info: PRIVATE: MULT_FACTOR0 NUMERIC "2"
+// Retrieval info: PRIVATE: OUTPUT_FREQ_MODE0 STRING "0"
+// Retrieval info: PRIVATE: SPREAD_PERCENT STRING "0.500"
+// Retrieval info: PRIVATE: LOCKED_OUTPUT_CHECK STRING "0"
+// Retrieval info: PRIVATE: PLL_ARESET_CHECK STRING "0"
+// Retrieval info: PRIVATE: STICKY_CLK0 STRING "1"
+// Retrieval info: PRIVATE: BANDWIDTH STRING "1.000"
+// Retrieval info: PRIVATE: BANDWIDTH_USE_CUSTOM STRING "0"
+// Retrieval info: PRIVATE: DEVICE_SPEED_GRADE STRING "8"
+// Retrieval info: PRIVATE: SPREAD_FREQ STRING "50.000"
+// Retrieval info: PRIVATE: BANDWIDTH_FEATURE_ENABLED STRING "0"
+// Retrieval info: PRIVATE: LONG_SCAN_RADIO STRING "1"
+// Retrieval info: PRIVATE: PLL_ENHPLL_CHECK NUMERIC "0"
+// Retrieval info: PRIVATE: LVDS_MODE_DATA_RATE_DIRTY NUMERIC "0"
+// Retrieval info: PRIVATE: USE_CLK0 STRING "1"
+// Retrieval info: PRIVATE: INCLK1_FREQ_EDIT_CHANGED STRING "1"
+// Retrieval info: PRIVATE: SCAN_FEATURE_ENABLED STRING "0"
+// Retrieval info: PRIVATE: ZERO_DELAY_RADIO STRING "0"
+// Retrieval info: PRIVATE: PLL_PFDENA_CHECK STRING "0"
+// Retrieval info: PRIVATE: CREATE_CLKBAD_CHECK STRING "0"
+// Retrieval info: PRIVATE: INCLK1_FREQ_EDIT STRING "100.000"
+// Retrieval info: PRIVATE: CUR_DEDICATED_CLK STRING "c0"
+// Retrieval info: PRIVATE: PLL_FASTPLL_CHECK NUMERIC "0"
+// Retrieval info: PRIVATE: ACTIVECLK_CHECK STRING "0"
+// Retrieval info: PRIVATE: BANDWIDTH_FREQ_UNIT STRING "MHz"
+// Retrieval info: PRIVATE: INCLK0_FREQ_UNIT_COMBO STRING "MHz"
+// Retrieval info: PRIVATE: GLOCKED_MODE_CHECK STRING "0"
+// Retrieval info: PRIVATE: NORMAL_MODE_RADIO STRING "1"
+// Retrieval info: PRIVATE: CUR_FBIN_CLK STRING "e0"
+// Retrieval info: PRIVATE: DIV_FACTOR0 NUMERIC "1"
+// Retrieval info: PRIVATE: INCLK1_FREQ_UNIT_CHANGED STRING "1"
+// Retrieval info: PRIVATE: HAS_MANUAL_SWITCHOVER STRING "1"
+// Retrieval info: PRIVATE: EXT_FEEDBACK_RADIO STRING "0"
+// Retrieval info: PRIVATE: PLL_AUTOPLL_CHECK NUMERIC "1"
+// Retrieval info: PRIVATE: CLKLOSS_CHECK STRING "0"
+// Retrieval info: PRIVATE: BANDWIDTH_USE_AUTO STRING "1"
+// Retrieval info: PRIVATE: SHORT_SCAN_RADIO STRING "0"
+// Retrieval info: PRIVATE: LVDS_MODE_DATA_RATE STRING "512.000"
+// Retrieval info: PRIVATE: CLKSWITCH_CHECK STRING "0"
+// Retrieval info: PRIVATE: SPREAD_FREQ_UNIT STRING "KHz"
+// Retrieval info: PRIVATE: PLL_ENA_CHECK STRING "0"
+// Retrieval info: PRIVATE: INCLK0_FREQ_EDIT STRING "64.000"
+// Retrieval info: PRIVATE: CNX_NO_COMPENSATE_RADIO STRING "0"
+// Retrieval info: PRIVATE: INT_FEEDBACK__MODE_RADIO STRING "1"
+// Retrieval info: PRIVATE: OUTPUT_FREQ0 STRING "100.000"
+// Retrieval info: PRIVATE: PRIMARY_CLK_COMBO STRING "inclk0"
+// Retrieval info: PRIVATE: CREATE_INCLK1_CHECK STRING "0"
+// Retrieval info: PRIVATE: SACN_INPUTS_CHECK STRING "0"
+// Retrieval info: PRIVATE: DEV_FAMILY STRING "Cyclone"
+// Retrieval info: PRIVATE: LOCK_LOSS_SWITCHOVER_CHECK STRING "0"
+// Retrieval info: PRIVATE: SWITCHOVER_COUNT_EDIT NUMERIC "1"
+// Retrieval info: PRIVATE: SWITCHOVER_FEATURE_ENABLED STRING "0"
+// Retrieval info: PRIVATE: BANDWIDTH_PRESET STRING "Low"
+// Retrieval info: PRIVATE: GLOCKED_FEATURE_ENABLED STRING "0"
+// Retrieval info: PRIVATE: USE_CLKENA0 STRING "0"
+// Retrieval info: PRIVATE: LVDS_PHASE_SHIFT_UNIT0 STRING "deg"
+// Retrieval info: PRIVATE: CLKBAD_SWITCHOVER_CHECK STRING "0"
+// Retrieval info: PRIVATE: BANDWIDTH_USE_PRESET STRING "0"
+// Retrieval info: PRIVATE: PLL_LVDS_PLL_CHECK NUMERIC "0"
+// Retrieval info: PRIVATE: DEVICE_FAMILY NUMERIC "11"
+// Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all
+// Retrieval info: CONSTANT: CLK0_DUTY_CYCLE NUMERIC "50"
+// Retrieval info: CONSTANT: LPM_TYPE STRING "altpll"
+// Retrieval info: CONSTANT: CLK0_MULTIPLY_BY NUMERIC "2"
+// Retrieval info: CONSTANT: INCLK0_INPUT_FREQUENCY NUMERIC "15625"
+// Retrieval info: CONSTANT: CLK0_DIVIDE_BY NUMERIC "1"
+// Retrieval info: CONSTANT: PLL_TYPE STRING "AUTO"
+// Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone"
+// Retrieval info: CONSTANT: OPERATION_MODE STRING "NORMAL"
+// Retrieval info: CONSTANT: COMPENSATE_CLOCK STRING "CLK0"
+// Retrieval info: CONSTANT: CLK0_PHASE_SHIFT STRING "0"
+// Retrieval info: USED_PORT: c0 0 0 0 0 OUTPUT VCC "c0"
+// Retrieval info: USED_PORT: @clk 0 0 6 0 OUTPUT VCC "@clk[5..0]"
+// Retrieval info: USED_PORT: inclk0 0 0 0 0 INPUT GND "inclk0"
+// Retrieval info: USED_PORT: @extclk 0 0 4 0 OUTPUT VCC "@extclk[3..0]"
+// Retrieval info: CONNECT: @inclk 0 0 1 0 inclk0 0 0 0 0
+// Retrieval info: CONNECT: c0 0 0 0 0 @clk 0 0 1 0
+// Retrieval info: CONNECT: @inclk 0 0 1 1 GND 0 0 0 0
+// Retrieval info: GEN_FILE: TYPE_NORMAL clk_doubler.v TRUE FALSE
+// Retrieval info: GEN_FILE: TYPE_NORMAL clk_doubler.inc FALSE FALSE
+// Retrieval info: GEN_FILE: TYPE_NORMAL clk_doubler.cmp FALSE FALSE
+// Retrieval info: GEN_FILE: TYPE_NORMAL clk_doubler.bsf FALSE FALSE
+// Retrieval info: GEN_FILE: TYPE_NORMAL clk_doubler_inst.v FALSE FALSE
+// Retrieval info: GEN_FILE: TYPE_NORMAL clk_doubler_bb.v TRUE FALSE
diff --git a/usrp/fpga/megacells/dspclkpll.v b/usrp/fpga/megacells/dspclkpll.v
new file mode 100644 (file)
index 0000000..81e6221
--- /dev/null
@@ -0,0 +1,237 @@
+// megafunction wizard: %ALTPLL%
+// GENERATION: STANDARD
+// VERSION: WM1.0
+// MODULE: altpll 
+
+// ============================================================
+// File Name: dspclkpll.v
+// Megafunction Name(s):
+//                     altpll
+// ============================================================
+// ************************************************************
+// THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE!
+//
+// 4.0 Build 214 3/25/2004 SP 1 SJ Web Edition
+// ************************************************************
+
+
+//Copyright (C) 1991-2004 Altera Corporation
+//Any  megafunction  design,  and related netlist (encrypted  or  decrypted),
+//support information,  device programming or simulation file,  and any other
+//associated  documentation or information  provided by  Altera  or a partner
+//under  Altera's   Megafunction   Partnership   Program  may  be  used  only
+//to program  PLD  devices (but not masked  PLD  devices) from  Altera.   Any
+//other  use  of such  megafunction  design,  netlist,  support  information,
+//device programming or simulation file,  or any other  related documentation
+//or information  is prohibited  for  any  other purpose,  including, but not
+//limited to  modification,  reverse engineering,  de-compiling, or use  with
+//any other  silicon devices,  unless such use is  explicitly  licensed under
+//a separate agreement with  Altera  or a megafunction partner.  Title to the
+//intellectual property,  including patents,  copyrights,  trademarks,  trade
+//secrets,  or maskworks,  embodied in any such megafunction design, netlist,
+//support  information,  device programming or simulation file,  or any other
+//related documentation or information provided by  Altera  or a megafunction
+//partner, remains with Altera, the megafunction partner, or their respective
+//licensors. No other licenses, including any licenses needed under any third
+//party's intellectual property, are provided herein.
+
+
+// synopsys translate_off
+`timescale 1 ps / 1 ps
+// synopsys translate_on
+module dspclkpll (
+       inclk0,
+       c0,
+       c1);
+
+       input     inclk0;
+       output    c0;
+       output    c1;
+
+       wire [5:0] sub_wire0;
+       wire [0:0] sub_wire5 = 1'h0;
+       wire [1:1] sub_wire2 = sub_wire0[1:1];
+       wire [0:0] sub_wire1 = sub_wire0[0:0];
+       wire  c0 = sub_wire1;
+       wire  c1 = sub_wire2;
+       wire  sub_wire3 = inclk0;
+       wire [1:0] sub_wire4 = {sub_wire5, sub_wire3};
+
+       altpll  altpll_component (
+                               .inclk (sub_wire4),
+                               .clk (sub_wire0)
+                               // synopsys translate_off
+,
+                               .fbin (),
+                               .pllena (),
+                               .clkswitch (),
+                               .areset (),
+                               .pfdena (),
+                               .clkena (),
+                               .extclkena (),
+                               .scanclk (),
+                               .scanaclr (),
+                               .scandata (),
+                               .scanread (),
+                               .scanwrite (),
+                               .extclk (),
+                               .clkbad (),
+                               .activeclock (),
+                               .locked (),
+                               .clkloss (),
+                               .scandataout (),
+                               .scandone (),
+                               .sclkout1 (),
+                               .sclkout0 (),
+                               .enable0 (),
+                               .enable1 ()
+                               // synopsys translate_on
+
+);
+       defparam
+               altpll_component.clk1_divide_by = 1,
+               altpll_component.clk1_phase_shift = "0",
+               altpll_component.clk0_duty_cycle = 50,
+               altpll_component.lpm_type = "altpll",
+               altpll_component.clk0_multiply_by = 1,
+               altpll_component.inclk0_input_frequency = 15625,
+               altpll_component.clk0_divide_by = 1,
+               altpll_component.clk1_duty_cycle = 50,
+               altpll_component.pll_type = "AUTO",
+               altpll_component.clk1_multiply_by = 2,
+               altpll_component.clk0_time_delay = "0",
+               altpll_component.intended_device_family = "Cyclone",
+               altpll_component.operation_mode = "NORMAL",
+               altpll_component.compensate_clock = "CLK0",
+               altpll_component.clk1_time_delay = "0",
+               altpll_component.clk0_phase_shift = "0";
+
+
+endmodule
+
+// ============================================================
+// CNX file retrieval info
+// ============================================================
+// Retrieval info: PRIVATE: MIRROR_CLK0 STRING "0"
+// Retrieval info: PRIVATE: PHASE_SHIFT_UNIT0 STRING "deg"
+// Retrieval info: PRIVATE: OUTPUT_FREQ_UNIT0 STRING "MHz"
+// Retrieval info: PRIVATE: INCLK1_FREQ_UNIT_COMBO STRING "MHz"
+// Retrieval info: PRIVATE: SPREAD_USE STRING "0"
+// Retrieval info: PRIVATE: SPREAD_FEATURE_ENABLED STRING "0"
+// Retrieval info: PRIVATE: GLOCKED_COUNTER_EDIT_CHANGED STRING "1"
+// Retrieval info: PRIVATE: GLOCK_COUNTER_EDIT NUMERIC "1048575"
+// Retrieval info: PRIVATE: SRC_SYNCH_COMP_RADIO STRING "0"
+// Retrieval info: PRIVATE: MIRROR_CLK1 STRING "0"
+// Retrieval info: PRIVATE: PHASE_SHIFT_UNIT1 STRING "deg"
+// Retrieval info: PRIVATE: OUTPUT_FREQ_UNIT1 STRING "MHz"
+// Retrieval info: PRIVATE: DUTY_CYCLE0 STRING "50.00000000"
+// Retrieval info: PRIVATE: PHASE_SHIFT0 STRING "0.00000000"
+// Retrieval info: PRIVATE: MULT_FACTOR0 NUMERIC "1"
+// Retrieval info: PRIVATE: OUTPUT_FREQ_MODE0 STRING "0"
+// Retrieval info: PRIVATE: SPREAD_PERCENT STRING "0.500"
+// Retrieval info: PRIVATE: LOCKED_OUTPUT_CHECK STRING "0"
+// Retrieval info: PRIVATE: PLL_ARESET_CHECK STRING "0"
+// Retrieval info: PRIVATE: DUTY_CYCLE1 STRING "50.00000000"
+// Retrieval info: PRIVATE: PHASE_SHIFT1 STRING "0.00000000"
+// Retrieval info: PRIVATE: MULT_FACTOR1 NUMERIC "2"
+// Retrieval info: PRIVATE: OUTPUT_FREQ_MODE1 STRING "0"
+// Retrieval info: PRIVATE: TIME_SHIFT0 STRING "0.00000000"
+// Retrieval info: PRIVATE: STICKY_CLK0 STRING "1"
+// Retrieval info: PRIVATE: BANDWIDTH STRING "1.000"
+// Retrieval info: PRIVATE: BANDWIDTH_USE_CUSTOM STRING "0"
+// Retrieval info: PRIVATE: DEVICE_SPEED_GRADE STRING "8"
+// Retrieval info: PRIVATE: TIME_SHIFT1 STRING "0.00000000"
+// Retrieval info: PRIVATE: STICKY_CLK1 STRING "1"
+// Retrieval info: PRIVATE: SPREAD_FREQ STRING "50.000"
+// Retrieval info: PRIVATE: BANDWIDTH_FEATURE_ENABLED STRING "0"
+// Retrieval info: PRIVATE: LONG_SCAN_RADIO STRING "1"
+// Retrieval info: PRIVATE: PLL_ENHPLL_CHECK NUMERIC "0"
+// Retrieval info: PRIVATE: LVDS_MODE_DATA_RATE_DIRTY NUMERIC "0"
+// Retrieval info: PRIVATE: USE_CLK0 STRING "1"
+// Retrieval info: PRIVATE: INCLK1_FREQ_EDIT_CHANGED STRING "1"
+// Retrieval info: PRIVATE: SCAN_FEATURE_ENABLED STRING "0"
+// Retrieval info: PRIVATE: ZERO_DELAY_RADIO STRING "0"
+// Retrieval info: PRIVATE: PLL_PFDENA_CHECK STRING "0"
+// Retrieval info: PRIVATE: USE_CLK1 STRING "1"
+// Retrieval info: PRIVATE: CREATE_CLKBAD_CHECK STRING "0"
+// Retrieval info: PRIVATE: INCLK1_FREQ_EDIT STRING "100.000"
+// Retrieval info: PRIVATE: CUR_DEDICATED_CLK STRING "c0"
+// Retrieval info: PRIVATE: PLL_FASTPLL_CHECK NUMERIC "0"
+// Retrieval info: PRIVATE: ACTIVECLK_CHECK STRING "0"
+// Retrieval info: PRIVATE: BANDWIDTH_FREQ_UNIT STRING "MHz"
+// Retrieval info: PRIVATE: INCLK0_FREQ_UNIT_COMBO STRING "MHz"
+// Retrieval info: PRIVATE: MEGAFN_PORT_INFO_0 STRING "inclk;fbin;pllena;clkswitch;areset"
+// Retrieval info: PRIVATE: GLOCKED_MODE_CHECK STRING "0"
+// Retrieval info: PRIVATE: NORMAL_MODE_RADIO STRING "1"
+// Retrieval info: PRIVATE: CUR_FBIN_CLK STRING "e0"
+// Retrieval info: PRIVATE: MEGAFN_PORT_INFO_1 STRING "pfdena;clkena;extclkena;scanclk;scanaclr"
+// Retrieval info: PRIVATE: DIV_FACTOR0 NUMERIC "1"
+// Retrieval info: PRIVATE: INCLK1_FREQ_UNIT_CHANGED STRING "1"
+// Retrieval info: PRIVATE: HAS_MANUAL_SWITCHOVER STRING "1"
+// Retrieval info: PRIVATE: EXT_FEEDBACK_RADIO STRING "0"
+// Retrieval info: PRIVATE: PLL_AUTOPLL_CHECK NUMERIC "1"
+// Retrieval info: PRIVATE: MEGAFN_PORT_INFO_2 STRING "scandata;scanread;scanwrite;clk;extclk"
+// Retrieval info: PRIVATE: DIV_FACTOR1 NUMERIC "1"
+// Retrieval info: PRIVATE: CLKLOSS_CHECK STRING "0"
+// Retrieval info: PRIVATE: BANDWIDTH_USE_AUTO STRING "1"
+// Retrieval info: PRIVATE: SHORT_SCAN_RADIO STRING "0"
+// Retrieval info: PRIVATE: LVDS_MODE_DATA_RATE STRING "512.000"
+// Retrieval info: PRIVATE: MEGAFN_PORT_INFO_3 STRING "clkbad;activeclock;locked;clkloss;scandataout"
+// Retrieval info: PRIVATE: CLKSWITCH_CHECK STRING "0"
+// Retrieval info: PRIVATE: SPREAD_FREQ_UNIT STRING "KHz"
+// Retrieval info: PRIVATE: PLL_ENA_CHECK STRING "0"
+// Retrieval info: PRIVATE: INCLK0_FREQ_EDIT STRING "64.000"
+// Retrieval info: PRIVATE: MEGAFN_PORT_INFO_4 STRING "scandone;sclkout1;sclkout0;enable0;enable1"
+// Retrieval info: PRIVATE: CNX_NO_COMPENSATE_RADIO STRING "0"
+// Retrieval info: PRIVATE: INT_FEEDBACK__MODE_RADIO STRING "1"
+// Retrieval info: PRIVATE: OUTPUT_FREQ0 STRING "100.000"
+// Retrieval info: PRIVATE: PRIMARY_CLK_COMBO STRING "inclk0"
+// Retrieval info: PRIVATE: CREATE_INCLK1_CHECK STRING "0"
+// Retrieval info: PRIVATE: SACN_INPUTS_CHECK STRING "0"
+// Retrieval info: PRIVATE: DEV_FAMILY STRING "Cyclone"
+// Retrieval info: PRIVATE: OUTPUT_FREQ1 STRING "100.000"
+// Retrieval info: PRIVATE: LOCK_LOSS_SWITCHOVER_CHECK STRING "0"
+// Retrieval info: PRIVATE: SWITCHOVER_COUNT_EDIT NUMERIC "1"
+// Retrieval info: PRIVATE: SWITCHOVER_FEATURE_ENABLED STRING "0"
+// Retrieval info: PRIVATE: BANDWIDTH_PRESET STRING "Low"
+// Retrieval info: PRIVATE: GLOCKED_FEATURE_ENABLED STRING "0"
+// Retrieval info: PRIVATE: USE_CLKENA0 STRING "0"
+// Retrieval info: PRIVATE: LVDS_PHASE_SHIFT_UNIT0 STRING "deg"
+// Retrieval info: PRIVATE: USE_CLKENA1 STRING "0"
+// Retrieval info: PRIVATE: LVDS_PHASE_SHIFT_UNIT1 STRING "deg"
+// Retrieval info: PRIVATE: CLKBAD_SWITCHOVER_CHECK STRING "0"
+// Retrieval info: PRIVATE: BANDWIDTH_USE_PRESET STRING "0"
+// Retrieval info: PRIVATE: PLL_LVDS_PLL_CHECK NUMERIC "0"
+// Retrieval info: PRIVATE: DEVICE_FAMILY NUMERIC "11"
+// Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all
+// Retrieval info: CONSTANT: CLK1_DIVIDE_BY NUMERIC "1"
+// Retrieval info: CONSTANT: CLK1_PHASE_SHIFT STRING "0"
+// Retrieval info: CONSTANT: CLK0_DUTY_CYCLE NUMERIC "50"
+// Retrieval info: CONSTANT: LPM_TYPE STRING "altpll"
+// Retrieval info: CONSTANT: CLK0_MULTIPLY_BY NUMERIC "1"
+// Retrieval info: CONSTANT: INCLK0_INPUT_FREQUENCY NUMERIC "15625"
+// Retrieval info: CONSTANT: CLK0_DIVIDE_BY NUMERIC "1"
+// Retrieval info: CONSTANT: CLK1_DUTY_CYCLE NUMERIC "50"
+// Retrieval info: CONSTANT: PLL_TYPE STRING "AUTO"
+// Retrieval info: CONSTANT: CLK1_MULTIPLY_BY NUMERIC "2"
+// Retrieval info: CONSTANT: CLK0_TIME_DELAY STRING "0"
+// Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone"
+// Retrieval info: CONSTANT: OPERATION_MODE STRING "NORMAL"
+// Retrieval info: CONSTANT: COMPENSATE_CLOCK STRING "CLK0"
+// Retrieval info: CONSTANT: CLK1_TIME_DELAY STRING "0"
+// Retrieval info: CONSTANT: CLK0_PHASE_SHIFT STRING "0"
+// Retrieval info: USED_PORT: c0 0 0 0 0 OUTPUT VCC "c0"
+// Retrieval info: USED_PORT: @clk 0 0 6 0 OUTPUT VCC "@clk[5..0]"
+// Retrieval info: USED_PORT: c1 0 0 0 0 OUTPUT VCC "c1"
+// Retrieval info: USED_PORT: inclk0 0 0 0 0 INPUT GND "inclk0"
+// Retrieval info: USED_PORT: @extclk 0 0 4 0 OUTPUT VCC "@extclk[3..0]"
+// Retrieval info: CONNECT: @inclk 0 0 1 0 inclk0 0 0 0 0
+// Retrieval info: CONNECT: c0 0 0 0 0 @clk 0 0 1 0
+// Retrieval info: CONNECT: c1 0 0 0 0 @clk 0 0 1 1
+// Retrieval info: CONNECT: @inclk 0 0 1 1 GND 0 0 0 0
+// Retrieval info: GEN_FILE: TYPE_NORMAL dspclkpll.v TRUE FALSE
+// Retrieval info: GEN_FILE: TYPE_NORMAL dspclkpll.inc FALSE FALSE
+// Retrieval info: GEN_FILE: TYPE_NORMAL dspclkpll.cmp FALSE FALSE
+// Retrieval info: GEN_FILE: TYPE_NORMAL dspclkpll.bsf FALSE FALSE
+// Retrieval info: GEN_FILE: TYPE_NORMAL dspclkpll_inst.v FALSE FALSE
+// Retrieval info: GEN_FILE: TYPE_NORMAL dspclkpll_bb.v TRUE FALSE
diff --git a/usrp/fpga/megacells/dspclkpll_bb.v b/usrp/fpga/megacells/dspclkpll_bb.v
new file mode 100644 (file)
index 0000000..489be7b
--- /dev/null
@@ -0,0 +1,31 @@
+//Copyright (C) 1991-2004 Altera Corporation
+//Any  megafunction  design,  and related netlist (encrypted  or  decrypted),
+//support information,  device programming or simulation file,  and any other
+//associated  documentation or information  provided by  Altera  or a partner
+//under  Altera's   Megafunction   Partnership   Program  may  be  used  only
+//to program  PLD  devices (but not masked  PLD  devices) from  Altera.   Any
+//other  use  of such  megafunction  design,  netlist,  support  information,
+//device programming or simulation file,  or any other  related documentation
+//or information  is prohibited  for  any  other purpose,  including, but not
+//limited to  modification,  reverse engineering,  de-compiling, or use  with
+//any other  silicon devices,  unless such use is  explicitly  licensed under
+//a separate agreement with  Altera  or a megafunction partner.  Title to the
+//intellectual property,  including patents,  copyrights,  trademarks,  trade
+//secrets,  or maskworks,  embodied in any such megafunction design, netlist,
+//support  information,  device programming or simulation file,  or any other
+//related documentation or information provided by  Altera  or a megafunction
+//partner, remains with Altera, the megafunction partner, or their respective
+//licensors. No other licenses, including any licenses needed under any third
+//party's intellectual property, are provided herein.
+
+module dspclkpll (
+       inclk0,
+       c0,
+       c1);
+
+       input     inclk0;
+       output    c0;
+       output    c1;
+
+endmodule
+
diff --git a/usrp/fpga/megacells/fifo_2k.v b/usrp/fpga/megacells/fifo_2k.v
new file mode 100644 (file)
index 0000000..5e2a385
--- /dev/null
@@ -0,0 +1,3343 @@
+// megafunction wizard: %FIFO%CBX%
+// GENERATION: STANDARD
+// VERSION: WM1.0
+// MODULE: dcfifo 
+
+// ============================================================
+// File Name: fifo_2k.v
+// Megafunction Name(s):
+//                     dcfifo
+// ============================================================
+// ************************************************************
+// THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE!
+//
+// 5.0 Build 168 06/22/2005 SP 1 SJ Web Edition
+// ************************************************************
+
+
+//Copyright (C) 1991-2005 Altera Corporation
+//Your use of Altera Corporation's design tools, logic functions 
+//and other software and tools, and its AMPP partner logic       
+//functions, and any output files any of the foregoing           
+//(including device programming or simulation files), and any    
+//associated documentation or information are expressly subject  
+//to the terms and conditions of the Altera Program License      
+//Subscription Agreement, Altera MegaCore Function License       
+//Agreement, or other applicable license agreement, including,   
+//without limitation, that your use is for the sole purpose of   
+//programming logic devices manufactured by Altera and sold by   
+//Altera or its authorized distributors.  Please refer to the    
+//applicable agreement for further details.
+
+
+//dcfifo ADD_RAM_OUTPUT_REGISTER="OFF" CLOCKS_ARE_SYNCHRONIZED="FALSE" DEVICE_FAMILY="Cyclone" LPM_NUMWORDS=2048 LPM_SHOWAHEAD="ON" LPM_WIDTH=16 LPM_WIDTHU=11 OVERFLOW_CHECKING="OFF" UNDERFLOW_CHECKING="OFF" USE_EAB="ON" aclr data q rdclk rdempty rdreq rdusedw wrclk wrfull wrreq wrusedw
+//VERSION_BEGIN 5.0 cbx_a_gray2bin 2004:03:06:00:52:20:SJ cbx_a_graycounter 2004:10:01:12:13:16:SJ cbx_altdpram 2004:11:30:11:29:56:SJ cbx_altsyncram 2005:03:24:13:58:56:SJ cbx_cycloneii 2004:12:20:14:28:52:SJ cbx_dcfifo 2005:03:07:17:11:14:SJ cbx_fifo_common 2004:12:13:14:26:24:SJ cbx_flex10ke 2002:10:18:16:54:38:SJ cbx_lpm_add_sub 2005:04:12:13:30:42:SJ cbx_lpm_compare 2004:11:30:11:30:40:SJ cbx_lpm_counter 2005:02:02:04:37:10:SJ cbx_lpm_decode 2004:12:13:14:19:12:SJ cbx_lpm_mux 2004:12:13:14:16:38:SJ cbx_mgl 2005:05:19:13:51:58:SJ cbx_scfifo 2005:03:10:10:52:20:SJ cbx_stratix 2005:06:02:09:53:04:SJ cbx_stratixii 2004:12:22:13:27:12:SJ cbx_util_mgl 2005:04:04:13:50:06:SJ  VERSION_END
+
+
+//a_gray2bin device_family="Cyclone" WIDTH=11 bin gray
+//VERSION_BEGIN 5.0 cbx_a_gray2bin 2004:03:06:00:52:20:SJ cbx_mgl 2005:05:19:13:51:58:SJ  VERSION_END
+
+//synthesis_resources = 
+//synopsys translate_off
+`timescale 1 ps / 1 ps
+//synopsys translate_on
+module  fifo_2k_a_gray2bin_8m4
+       ( 
+       bin,
+       gray) /* synthesis synthesis_clearbox=1 */;
+       output   [10:0]  bin;
+       input   [10:0]  gray;
+
+       wire  xor0;
+       wire  xor1;
+       wire  xor2;
+       wire  xor3;
+       wire  xor4;
+       wire  xor5;
+       wire  xor6;
+       wire  xor7;
+       wire  xor8;
+       wire  xor9;
+
+       assign
+               bin = {gray[10], xor9, xor8, xor7, xor6, xor5, xor4, xor3, xor2, xor1, xor0},
+               xor0 = (gray[0] ^ xor1),
+               xor1 = (gray[1] ^ xor2),
+               xor2 = (gray[2] ^ xor3),
+               xor3 = (gray[3] ^ xor4),
+               xor4 = (gray[4] ^ xor5),
+               xor5 = (gray[5] ^ xor6),
+               xor6 = (gray[6] ^ xor7),
+               xor7 = (gray[7] ^ xor8),
+               xor8 = (gray[8] ^ xor9),
+               xor9 = (gray[10] ^ gray[9]);
+endmodule //fifo_2k_a_gray2bin_8m4
+
+
+//a_graycounter DEVICE_FAMILY="Cyclone" WIDTH=11 aclr clock cnt_en q
+//VERSION_BEGIN 5.0 cbx_a_gray2bin 2004:03:06:00:52:20:SJ cbx_a_graycounter 2004:10:01:12:13:16:SJ cbx_cycloneii 2004:12:20:14:28:52:SJ cbx_flex10ke 2002:10:18:16:54:38:SJ cbx_mgl 2005:05:19:13:51:58:SJ cbx_stratix 2005:06:02:09:53:04:SJ cbx_stratixii 2004:12:22:13:27:12:SJ  VERSION_END
+
+//synthesis_resources = lut 12 
+//synopsys translate_off
+`timescale 1 ps / 1 ps
+//synopsys translate_on
+module  fifo_2k_a_graycounter_726
+       ( 
+       aclr,
+       clock,
+       cnt_en,
+       q) /* synthesis synthesis_clearbox=1 */;
+       input   aclr;
+       input   clock;
+       input   cnt_en;
+       output   [10:0]  q;
+
+       wire  [0:0]   wire_countera_0cout;
+       wire  [0:0]   wire_countera_1cout;
+       wire  [0:0]   wire_countera_2cout;
+       wire  [0:0]   wire_countera_3cout;
+       wire  [0:0]   wire_countera_4cout;
+       wire  [0:0]   wire_countera_5cout;
+       wire  [0:0]   wire_countera_6cout;
+       wire  [0:0]   wire_countera_7cout;
+       wire  [0:0]   wire_countera_8cout;
+       wire  [0:0]   wire_countera_9cout;
+       wire  [10:0]   wire_countera_regout;
+       wire  wire_parity_cout;
+       wire  wire_parity_regout;
+       wire  [10:0]  power_modified_counter_values;
+       wire sclr;
+       wire updown;
+
+       cyclone_lcell   countera_0
+       ( 
+       .aclr(aclr),
+       .cin(wire_parity_cout),
+       .clk(clock),
+       .combout(),
+       .cout(wire_countera_0cout[0:0]),
+       .dataa(cnt_en),
+       .datab(wire_countera_regout[0:0]),
+       .ena(1'b1),
+       .regout(wire_countera_regout[0:0]),
+       .sclr(sclr)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_off
+       `endif
+       ,
+       .aload(1'b0),
+       .datac(1'b1),
+       .datad(1'b1),
+       .inverta(1'b0),
+       .regcascin(1'b0),
+       .sload(1'b0)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_on
+       `endif
+       // synopsys translate_off
+       ,
+       .cin0(),
+       .cin1(),
+       .cout0(),
+       .cout1(),
+       .devclrn(),
+       .devpor()
+       // synopsys translate_on
+       );
+       defparam
+               countera_0.cin_used = "true",
+               countera_0.lut_mask = "c6a0",
+               countera_0.operation_mode = "arithmetic",
+               countera_0.sum_lutc_input = "cin",
+               countera_0.synch_mode = "on",
+               countera_0.lpm_type = "cyclone_lcell";
+       cyclone_lcell   countera_1
+       ( 
+       .aclr(aclr),
+       .cin(wire_countera_0cout[0:0]),
+       .clk(clock),
+       .combout(),
+       .cout(wire_countera_1cout[0:0]),
+       .dataa(power_modified_counter_values[0]),
+       .datab(power_modified_counter_values[1]),
+       .ena(1'b1),
+       .regout(wire_countera_regout[1:1]),
+       .sclr(sclr)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_off
+       `endif
+       ,
+       .aload(1'b0),
+       .datac(1'b1),
+       .datad(1'b1),
+       .inverta(1'b0),
+       .regcascin(1'b0),
+       .sload(1'b0)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_on
+       `endif
+       // synopsys translate_off
+       ,
+       .cin0(),
+       .cin1(),
+       .cout0(),
+       .cout1(),
+       .devclrn(),
+       .devpor()
+       // synopsys translate_on
+       );
+       defparam
+               countera_1.cin_used = "true",
+               countera_1.lut_mask = "6c50",
+               countera_1.operation_mode = "arithmetic",
+               countera_1.sum_lutc_input = "cin",
+               countera_1.synch_mode = "on",
+               countera_1.lpm_type = "cyclone_lcell";
+       cyclone_lcell   countera_2
+       ( 
+       .aclr(aclr),
+       .cin(wire_countera_1cout[0:0]),
+       .clk(clock),
+       .combout(),
+       .cout(wire_countera_2cout[0:0]),
+       .dataa(power_modified_counter_values[1]),
+       .datab(power_modified_counter_values[2]),
+       .ena(1'b1),
+       .regout(wire_countera_regout[2:2]),
+       .sclr(sclr)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_off
+       `endif
+       ,
+       .aload(1'b0),
+       .datac(1'b1),
+       .datad(1'b1),
+       .inverta(1'b0),
+       .regcascin(1'b0),
+       .sload(1'b0)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_on
+       `endif
+       // synopsys translate_off
+       ,
+       .cin0(),
+       .cin1(),
+       .cout0(),
+       .cout1(),
+       .devclrn(),
+       .devpor()
+       // synopsys translate_on
+       );
+       defparam
+               countera_2.cin_used = "true",
+               countera_2.lut_mask = "6c50",
+               countera_2.operation_mode = "arithmetic",
+               countera_2.sum_lutc_input = "cin",
+               countera_2.synch_mode = "on",
+               countera_2.lpm_type = "cyclone_lcell";
+       cyclone_lcell   countera_3
+       ( 
+       .aclr(aclr),
+       .cin(wire_countera_2cout[0:0]),
+       .clk(clock),
+       .combout(),
+       .cout(wire_countera_3cout[0:0]),
+       .dataa(power_modified_counter_values[2]),
+       .datab(power_modified_counter_values[3]),
+       .ena(1'b1),
+       .regout(wire_countera_regout[3:3]),
+       .sclr(sclr)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_off
+       `endif
+       ,
+       .aload(1'b0),
+       .datac(1'b1),
+       .datad(1'b1),
+       .inverta(1'b0),
+       .regcascin(1'b0),
+       .sload(1'b0)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_on
+       `endif
+       // synopsys translate_off
+       ,
+       .cin0(),
+       .cin1(),
+       .cout0(),
+       .cout1(),
+       .devclrn(),
+       .devpor()
+       // synopsys translate_on
+       );
+       defparam
+               countera_3.cin_used = "true",
+               countera_3.lut_mask = "6c50",
+               countera_3.operation_mode = "arithmetic",
+               countera_3.sum_lutc_input = "cin",
+               countera_3.synch_mode = "on",
+               countera_3.lpm_type = "cyclone_lcell";
+       cyclone_lcell   countera_4
+       ( 
+       .aclr(aclr),
+       .cin(wire_countera_3cout[0:0]),
+       .clk(clock),
+       .combout(),
+       .cout(wire_countera_4cout[0:0]),
+       .dataa(power_modified_counter_values[3]),
+       .datab(power_modified_counter_values[4]),
+       .ena(1'b1),
+       .regout(wire_countera_regout[4:4]),
+       .sclr(sclr)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_off
+       `endif
+       ,
+       .aload(1'b0),
+       .datac(1'b1),
+       .datad(1'b1),
+       .inverta(1'b0),
+       .regcascin(1'b0),
+       .sload(1'b0)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_on
+       `endif
+       // synopsys translate_off
+       ,
+       .cin0(),
+       .cin1(),
+       .cout0(),
+       .cout1(),
+       .devclrn(),
+       .devpor()
+       // synopsys translate_on
+       );
+       defparam
+               countera_4.cin_used = "true",
+               countera_4.lut_mask = "6c50",
+               countera_4.operation_mode = "arithmetic",
+               countera_4.sum_lutc_input = "cin",
+               countera_4.synch_mode = "on",
+               countera_4.lpm_type = "cyclone_lcell";
+       cyclone_lcell   countera_5
+       ( 
+       .aclr(aclr),
+       .cin(wire_countera_4cout[0:0]),
+       .clk(clock),
+       .combout(),
+       .cout(wire_countera_5cout[0:0]),
+       .dataa(power_modified_counter_values[4]),
+       .datab(power_modified_counter_values[5]),
+       .ena(1'b1),
+       .regout(wire_countera_regout[5:5]),
+       .sclr(sclr)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_off
+       `endif
+       ,
+       .aload(1'b0),
+       .datac(1'b1),
+       .datad(1'b1),
+       .inverta(1'b0),
+       .regcascin(1'b0),
+       .sload(1'b0)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_on
+       `endif
+       // synopsys translate_off
+       ,
+       .cin0(),
+       .cin1(),
+       .cout0(),
+       .cout1(),
+       .devclrn(),
+       .devpor()
+       // synopsys translate_on
+       );
+       defparam
+               countera_5.cin_used = "true",
+               countera_5.lut_mask = "6c50",
+               countera_5.operation_mode = "arithmetic",
+               countera_5.sum_lutc_input = "cin",
+               countera_5.synch_mode = "on",
+               countera_5.lpm_type = "cyclone_lcell";
+       cyclone_lcell   countera_6
+       ( 
+       .aclr(aclr),
+       .cin(wire_countera_5cout[0:0]),
+       .clk(clock),
+       .combout(),
+       .cout(wire_countera_6cout[0:0]),
+       .dataa(power_modified_counter_values[5]),
+       .datab(power_modified_counter_values[6]),
+       .ena(1'b1),
+       .regout(wire_countera_regout[6:6]),
+       .sclr(sclr)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_off
+       `endif
+       ,
+       .aload(1'b0),
+       .datac(1'b1),
+       .datad(1'b1),
+       .inverta(1'b0),
+       .regcascin(1'b0),
+       .sload(1'b0)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_on
+       `endif
+       // synopsys translate_off
+       ,
+       .cin0(),
+       .cin1(),
+       .cout0(),
+       .cout1(),
+       .devclrn(),
+       .devpor()
+       // synopsys translate_on
+       );
+       defparam
+               countera_6.cin_used = "true",
+               countera_6.lut_mask = "6c50",
+               countera_6.operation_mode = "arithmetic",
+               countera_6.sum_lutc_input = "cin",
+               countera_6.synch_mode = "on",
+               countera_6.lpm_type = "cyclone_lcell";
+       cyclone_lcell   countera_7
+       ( 
+       .aclr(aclr),
+       .cin(wire_countera_6cout[0:0]),
+       .clk(clock),
+       .combout(),
+       .cout(wire_countera_7cout[0:0]),
+       .dataa(power_modified_counter_values[6]),
+       .datab(power_modified_counter_values[7]),
+       .ena(1'b1),
+       .regout(wire_countera_regout[7:7]),
+       .sclr(sclr)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_off
+       `endif
+       ,
+       .aload(1'b0),
+       .datac(1'b1),
+       .datad(1'b1),
+       .inverta(1'b0),
+       .regcascin(1'b0),
+       .sload(1'b0)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_on
+       `endif
+       // synopsys translate_off
+       ,
+       .cin0(),
+       .cin1(),
+       .cout0(),
+       .cout1(),
+       .devclrn(),
+       .devpor()
+       // synopsys translate_on
+       );
+       defparam
+               countera_7.cin_used = "true",
+               countera_7.lut_mask = "6c50",
+               countera_7.operation_mode = "arithmetic",
+               countera_7.sum_lutc_input = "cin",
+               countera_7.synch_mode = "on",
+               countera_7.lpm_type = "cyclone_lcell";
+       cyclone_lcell   countera_8
+       ( 
+       .aclr(aclr),
+       .cin(wire_countera_7cout[0:0]),
+       .clk(clock),
+       .combout(),
+       .cout(wire_countera_8cout[0:0]),
+       .dataa(power_modified_counter_values[7]),
+       .datab(power_modified_counter_values[8]),
+       .ena(1'b1),
+       .regout(wire_countera_regout[8:8]),
+       .sclr(sclr)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_off
+       `endif
+       ,
+       .aload(1'b0),
+       .datac(1'b1),
+       .datad(1'b1),
+       .inverta(1'b0),
+       .regcascin(1'b0),
+       .sload(1'b0)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_on
+       `endif
+       // synopsys translate_off
+       ,
+       .cin0(),
+       .cin1(),
+       .cout0(),
+       .cout1(),
+       .devclrn(),
+       .devpor()
+       // synopsys translate_on
+       );
+       defparam
+               countera_8.cin_used = "true",
+               countera_8.lut_mask = "6c50",
+               countera_8.operation_mode = "arithmetic",
+               countera_8.sum_lutc_input = "cin",
+               countera_8.synch_mode = "on",
+               countera_8.lpm_type = "cyclone_lcell";
+       cyclone_lcell   countera_9
+       ( 
+       .aclr(aclr),
+       .cin(wire_countera_8cout[0:0]),
+       .clk(clock),
+       .combout(),
+       .cout(wire_countera_9cout[0:0]),
+       .dataa(power_modified_counter_values[8]),
+       .datab(power_modified_counter_values[9]),
+       .ena(1'b1),
+       .regout(wire_countera_regout[9:9]),
+       .sclr(sclr)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_off
+       `endif
+       ,
+       .aload(1'b0),
+       .datac(1'b1),
+       .datad(1'b1),
+       .inverta(1'b0),
+       .regcascin(1'b0),
+       .sload(1'b0)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_on
+       `endif
+       // synopsys translate_off
+       ,
+       .cin0(),
+       .cin1(),
+       .cout0(),
+       .cout1(),
+       .devclrn(),
+       .devpor()
+       // synopsys translate_on
+       );
+       defparam
+               countera_9.cin_used = "true",
+               countera_9.lut_mask = "6c50",
+               countera_9.operation_mode = "arithmetic",
+               countera_9.sum_lutc_input = "cin",
+               countera_9.synch_mode = "on",
+               countera_9.lpm_type = "cyclone_lcell";
+       cyclone_lcell   countera_10
+       ( 
+       .aclr(aclr),
+       .cin(wire_countera_9cout[0:0]),
+       .clk(clock),
+       .combout(),
+       .cout(),
+       .dataa(power_modified_counter_values[10]),
+       .ena(1'b1),
+       .regout(wire_countera_regout[10:10]),
+       .sclr(sclr)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_off
+       `endif
+       ,
+       .aload(1'b0),
+       .datab(1'b1),
+       .datac(1'b1),
+       .datad(1'b1),
+       .inverta(1'b0),
+       .regcascin(1'b0),
+       .sload(1'b0)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_on
+       `endif
+       // synopsys translate_off
+       ,
+       .cin0(),
+       .cin1(),
+       .cout0(),
+       .cout1(),
+       .devclrn(),
+       .devpor()
+       // synopsys translate_on
+       );
+       defparam
+               countera_10.cin_used = "true",
+               countera_10.lut_mask = "5a5a",
+               countera_10.operation_mode = "normal",
+               countera_10.sum_lutc_input = "cin",
+               countera_10.synch_mode = "on",
+               countera_10.lpm_type = "cyclone_lcell";
+       cyclone_lcell   parity
+       ( 
+       .aclr(aclr),
+       .cin(updown),
+       .clk(clock),
+       .combout(),
+       .cout(wire_parity_cout),
+       .dataa(cnt_en),
+       .datab(wire_parity_regout),
+       .ena(1'b1),
+       .regout(wire_parity_regout),
+       .sclr(sclr)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_off
+       `endif
+       ,
+       .aload(1'b0),
+       .datac(1'b1),
+       .datad(1'b1),
+       .inverta(1'b0),
+       .regcascin(1'b0),
+       .sload(1'b0)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_on
+       `endif
+       // synopsys translate_off
+       ,
+       .cin0(),
+       .cin1(),
+       .cout0(),
+       .cout1(),
+       .devclrn(),
+       .devpor()
+       // synopsys translate_on
+       );
+       defparam
+               parity.cin_used = "true",
+               parity.lut_mask = "6682",
+               parity.operation_mode = "arithmetic",
+               parity.synch_mode = "on",
+               parity.lpm_type = "cyclone_lcell";
+       assign
+               power_modified_counter_values = {wire_countera_regout[10:0]},
+               q = power_modified_counter_values,
+               sclr = 1'b0,
+               updown = 1'b1;
+endmodule //fifo_2k_a_graycounter_726
+
+
+//a_graycounter DEVICE_FAMILY="Cyclone" PVALUE=1 WIDTH=11 aclr clock cnt_en q
+//VERSION_BEGIN 5.0 cbx_a_gray2bin 2004:03:06:00:52:20:SJ cbx_a_graycounter 2004:10:01:12:13:16:SJ cbx_cycloneii 2004:12:20:14:28:52:SJ cbx_flex10ke 2002:10:18:16:54:38:SJ cbx_mgl 2005:05:19:13:51:58:SJ cbx_stratix 2005:06:02:09:53:04:SJ cbx_stratixii 2004:12:22:13:27:12:SJ  VERSION_END
+
+//synthesis_resources = lut 12 
+//synopsys translate_off
+`timescale 1 ps / 1 ps
+//synopsys translate_on
+module  fifo_2k_a_graycounter_2r6
+       ( 
+       aclr,
+       clock,
+       cnt_en,
+       q) /* synthesis synthesis_clearbox=1 */;
+       input   aclr;
+       input   clock;
+       input   cnt_en;
+       output   [10:0]  q;
+
+       wire  [0:0]   wire_countera_0cout;
+       wire  [0:0]   wire_countera_1cout;
+       wire  [0:0]   wire_countera_2cout;
+       wire  [0:0]   wire_countera_3cout;
+       wire  [0:0]   wire_countera_4cout;
+       wire  [0:0]   wire_countera_5cout;
+       wire  [0:0]   wire_countera_6cout;
+       wire  [0:0]   wire_countera_7cout;
+       wire  [0:0]   wire_countera_8cout;
+       wire  [0:0]   wire_countera_9cout;
+       wire  [10:0]   wire_countera_regout;
+       wire  wire_parity_cout;
+       wire  wire_parity_regout;
+       wire  [10:0]  power_modified_counter_values;
+       wire sclr;
+       wire updown;
+
+       cyclone_lcell   countera_0
+       ( 
+       .aclr(aclr),
+       .cin(wire_parity_cout),
+       .clk(clock),
+       .combout(),
+       .cout(wire_countera_0cout[0:0]),
+       .dataa(cnt_en),
+       .datab(wire_countera_regout[0:0]),
+       .ena(1'b1),
+       .regout(wire_countera_regout[0:0]),
+       .sclr(sclr)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_off
+       `endif
+       ,
+       .aload(1'b0),
+       .datac(1'b1),
+       .datad(1'b1),
+       .inverta(1'b0),
+       .regcascin(1'b0),
+       .sload(1'b0)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_on
+       `endif
+       // synopsys translate_off
+       ,
+       .cin0(),
+       .cin1(),
+       .cout0(),
+       .cout1(),
+       .devclrn(),
+       .devpor()
+       // synopsys translate_on
+       );
+       defparam
+               countera_0.cin_used = "true",
+               countera_0.lut_mask = "c6a0",
+               countera_0.operation_mode = "arithmetic",
+               countera_0.sum_lutc_input = "cin",
+               countera_0.synch_mode = "on",
+               countera_0.lpm_type = "cyclone_lcell";
+       cyclone_lcell   countera_1
+       ( 
+       .aclr(aclr),
+       .cin(wire_countera_0cout[0:0]),
+       .clk(clock),
+       .combout(),
+       .cout(wire_countera_1cout[0:0]),
+       .dataa(power_modified_counter_values[0]),
+       .datab(power_modified_counter_values[1]),
+       .ena(1'b1),
+       .regout(wire_countera_regout[1:1]),
+       .sclr(sclr)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_off
+       `endif
+       ,
+       .aload(1'b0),
+       .datac(1'b1),
+       .datad(1'b1),
+       .inverta(1'b0),
+       .regcascin(1'b0),
+       .sload(1'b0)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_on
+       `endif
+       // synopsys translate_off
+       ,
+       .cin0(),
+       .cin1(),
+       .cout0(),
+       .cout1(),
+       .devclrn(),
+       .devpor()
+       // synopsys translate_on
+       );
+       defparam
+               countera_1.cin_used = "true",
+               countera_1.lut_mask = "6c50",
+               countera_1.operation_mode = "arithmetic",
+               countera_1.sum_lutc_input = "cin",
+               countera_1.synch_mode = "on",
+               countera_1.lpm_type = "cyclone_lcell";
+       cyclone_lcell   countera_2
+       ( 
+       .aclr(aclr),
+       .cin(wire_countera_1cout[0:0]),
+       .clk(clock),
+       .combout(),
+       .cout(wire_countera_2cout[0:0]),
+       .dataa(power_modified_counter_values[1]),
+       .datab(power_modified_counter_values[2]),
+       .ena(1'b1),
+       .regout(wire_countera_regout[2:2]),
+       .sclr(sclr)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_off
+       `endif
+       ,
+       .aload(1'b0),
+       .datac(1'b1),
+       .datad(1'b1),
+       .inverta(1'b0),
+       .regcascin(1'b0),
+       .sload(1'b0)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_on
+       `endif
+       // synopsys translate_off
+       ,
+       .cin0(),
+       .cin1(),
+       .cout0(),
+       .cout1(),
+       .devclrn(),
+       .devpor()
+       // synopsys translate_on
+       );
+       defparam
+               countera_2.cin_used = "true",
+               countera_2.lut_mask = "6c50",
+               countera_2.operation_mode = "arithmetic",
+               countera_2.sum_lutc_input = "cin",
+               countera_2.synch_mode = "on",
+               countera_2.lpm_type = "cyclone_lcell";
+       cyclone_lcell   countera_3
+       ( 
+       .aclr(aclr),
+       .cin(wire_countera_2cout[0:0]),
+       .clk(clock),
+       .combout(),
+       .cout(wire_countera_3cout[0:0]),
+       .dataa(power_modified_counter_values[2]),
+       .datab(power_modified_counter_values[3]),
+       .ena(1'b1),
+       .regout(wire_countera_regout[3:3]),
+       .sclr(sclr)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_off
+       `endif
+       ,
+       .aload(1'b0),
+       .datac(1'b1),
+       .datad(1'b1),
+       .inverta(1'b0),
+       .regcascin(1'b0),
+       .sload(1'b0)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_on
+       `endif
+       // synopsys translate_off
+       ,
+       .cin0(),
+       .cin1(),
+       .cout0(),
+       .cout1(),
+       .devclrn(),
+       .devpor()
+       // synopsys translate_on
+       );
+       defparam
+               countera_3.cin_used = "true",
+               countera_3.lut_mask = "6c50",
+               countera_3.operation_mode = "arithmetic",
+               countera_3.sum_lutc_input = "cin",
+               countera_3.synch_mode = "on",
+               countera_3.lpm_type = "cyclone_lcell";
+       cyclone_lcell   countera_4
+       ( 
+       .aclr(aclr),
+       .cin(wire_countera_3cout[0:0]),
+       .clk(clock),
+       .combout(),
+       .cout(wire_countera_4cout[0:0]),
+       .dataa(power_modified_counter_values[3]),
+       .datab(power_modified_counter_values[4]),
+       .ena(1'b1),
+       .regout(wire_countera_regout[4:4]),
+       .sclr(sclr)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_off
+       `endif
+       ,
+       .aload(1'b0),
+       .datac(1'b1),
+       .datad(1'b1),
+       .inverta(1'b0),
+       .regcascin(1'b0),
+       .sload(1'b0)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_on
+       `endif
+       // synopsys translate_off
+       ,
+       .cin0(),
+       .cin1(),
+       .cout0(),
+       .cout1(),
+       .devclrn(),
+       .devpor()
+       // synopsys translate_on
+       );
+       defparam
+               countera_4.cin_used = "true",
+               countera_4.lut_mask = "6c50",
+               countera_4.operation_mode = "arithmetic",
+               countera_4.sum_lutc_input = "cin",
+               countera_4.synch_mode = "on",
+               countera_4.lpm_type = "cyclone_lcell";
+       cyclone_lcell   countera_5
+       ( 
+       .aclr(aclr),
+       .cin(wire_countera_4cout[0:0]),
+       .clk(clock),
+       .combout(),
+       .cout(wire_countera_5cout[0:0]),
+       .dataa(power_modified_counter_values[4]),
+       .datab(power_modified_counter_values[5]),
+       .ena(1'b1),
+       .regout(wire_countera_regout[5:5]),
+       .sclr(sclr)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_off
+       `endif
+       ,
+       .aload(1'b0),
+       .datac(1'b1),
+       .datad(1'b1),
+       .inverta(1'b0),
+       .regcascin(1'b0),
+       .sload(1'b0)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_on
+       `endif
+       // synopsys translate_off
+       ,
+       .cin0(),
+       .cin1(),
+       .cout0(),
+       .cout1(),
+       .devclrn(),
+       .devpor()
+       // synopsys translate_on
+       );
+       defparam
+               countera_5.cin_used = "true",
+               countera_5.lut_mask = "6c50",
+               countera_5.operation_mode = "arithmetic",
+               countera_5.sum_lutc_input = "cin",
+               countera_5.synch_mode = "on",
+               countera_5.lpm_type = "cyclone_lcell";
+       cyclone_lcell   countera_6
+       ( 
+       .aclr(aclr),
+       .cin(wire_countera_5cout[0:0]),
+       .clk(clock),
+       .combout(),
+       .cout(wire_countera_6cout[0:0]),
+       .dataa(power_modified_counter_values[5]),
+       .datab(power_modified_counter_values[6]),
+       .ena(1'b1),
+       .regout(wire_countera_regout[6:6]),
+       .sclr(sclr)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_off
+       `endif
+       ,
+       .aload(1'b0),
+       .datac(1'b1),
+       .datad(1'b1),
+       .inverta(1'b0),
+       .regcascin(1'b0),
+       .sload(1'b0)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_on
+       `endif
+       // synopsys translate_off
+       ,
+       .cin0(),
+       .cin1(),
+       .cout0(),
+       .cout1(),
+       .devclrn(),
+       .devpor()
+       // synopsys translate_on
+       );
+       defparam
+               countera_6.cin_used = "true",
+               countera_6.lut_mask = "6c50",
+               countera_6.operation_mode = "arithmetic",
+               countera_6.sum_lutc_input = "cin",
+               countera_6.synch_mode = "on",
+               countera_6.lpm_type = "cyclone_lcell";
+       cyclone_lcell   countera_7
+       ( 
+       .aclr(aclr),
+       .cin(wire_countera_6cout[0:0]),
+       .clk(clock),
+       .combout(),
+       .cout(wire_countera_7cout[0:0]),
+       .dataa(power_modified_counter_values[6]),
+       .datab(power_modified_counter_values[7]),
+       .ena(1'b1),
+       .regout(wire_countera_regout[7:7]),
+       .sclr(sclr)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_off
+       `endif
+       ,
+       .aload(1'b0),
+       .datac(1'b1),
+       .datad(1'b1),
+       .inverta(1'b0),
+       .regcascin(1'b0),
+       .sload(1'b0)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_on
+       `endif
+       // synopsys translate_off
+       ,
+       .cin0(),
+       .cin1(),
+       .cout0(),
+       .cout1(),
+       .devclrn(),
+       .devpor()
+       // synopsys translate_on
+       );
+       defparam
+               countera_7.cin_used = "true",
+               countera_7.lut_mask = "6c50",
+               countera_7.operation_mode = "arithmetic",
+               countera_7.sum_lutc_input = "cin",
+               countera_7.synch_mode = "on",
+               countera_7.lpm_type = "cyclone_lcell";
+       cyclone_lcell   countera_8
+       ( 
+       .aclr(aclr),
+       .cin(wire_countera_7cout[0:0]),
+       .clk(clock),
+       .combout(),
+       .cout(wire_countera_8cout[0:0]),
+       .dataa(power_modified_counter_values[7]),
+       .datab(power_modified_counter_values[8]),
+       .ena(1'b1),
+       .regout(wire_countera_regout[8:8]),
+       .sclr(sclr)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_off
+       `endif
+       ,
+       .aload(1'b0),
+       .datac(1'b1),
+       .datad(1'b1),
+       .inverta(1'b0),
+       .regcascin(1'b0),
+       .sload(1'b0)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_on
+       `endif
+       // synopsys translate_off
+       ,
+       .cin0(),
+       .cin1(),
+       .cout0(),
+       .cout1(),
+       .devclrn(),
+       .devpor()
+       // synopsys translate_on
+       );
+       defparam
+               countera_8.cin_used = "true",
+               countera_8.lut_mask = "6c50",
+               countera_8.operation_mode = "arithmetic",
+               countera_8.sum_lutc_input = "cin",
+               countera_8.synch_mode = "on",
+               countera_8.lpm_type = "cyclone_lcell";
+       cyclone_lcell   countera_9
+       ( 
+       .aclr(aclr),
+       .cin(wire_countera_8cout[0:0]),
+       .clk(clock),
+       .combout(),
+       .cout(wire_countera_9cout[0:0]),
+       .dataa(power_modified_counter_values[8]),
+       .datab(power_modified_counter_values[9]),
+       .ena(1'b1),
+       .regout(wire_countera_regout[9:9]),
+       .sclr(sclr)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_off
+       `endif
+       ,
+       .aload(1'b0),
+       .datac(1'b1),
+       .datad(1'b1),
+       .inverta(1'b0),
+       .regcascin(1'b0),
+       .sload(1'b0)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_on
+       `endif
+       // synopsys translate_off
+       ,
+       .cin0(),
+       .cin1(),
+       .cout0(),
+       .cout1(),
+       .devclrn(),
+       .devpor()
+       // synopsys translate_on
+       );
+       defparam
+               countera_9.cin_used = "true",
+               countera_9.lut_mask = "6c50",
+               countera_9.operation_mode = "arithmetic",
+               countera_9.sum_lutc_input = "cin",
+               countera_9.synch_mode = "on",
+               countera_9.lpm_type = "cyclone_lcell";
+       cyclone_lcell   countera_10
+       ( 
+       .aclr(aclr),
+       .cin(wire_countera_9cout[0:0]),
+       .clk(clock),
+       .combout(),
+       .cout(),
+       .dataa(power_modified_counter_values[10]),
+       .ena(1'b1),
+       .regout(wire_countera_regout[10:10]),
+       .sclr(sclr)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_off
+       `endif
+       ,
+       .aload(1'b0),
+       .datab(1'b1),
+       .datac(1'b1),
+       .datad(1'b1),
+       .inverta(1'b0),
+       .regcascin(1'b0),
+       .sload(1'b0)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_on
+       `endif
+       // synopsys translate_off
+       ,
+       .cin0(),
+       .cin1(),
+       .cout0(),
+       .cout1(),
+       .devclrn(),
+       .devpor()
+       // synopsys translate_on
+       );
+       defparam
+               countera_10.cin_used = "true",
+               countera_10.lut_mask = "5a5a",
+               countera_10.operation_mode = "normal",
+               countera_10.sum_lutc_input = "cin",
+               countera_10.synch_mode = "on",
+               countera_10.lpm_type = "cyclone_lcell";
+       cyclone_lcell   parity
+       ( 
+       .aclr(aclr),
+       .cin(updown),
+       .clk(clock),
+       .combout(),
+       .cout(wire_parity_cout),
+       .dataa(cnt_en),
+       .datab((~ wire_parity_regout)),
+       .ena(1'b1),
+       .regout(wire_parity_regout),
+       .sclr(sclr)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_off
+       `endif
+       ,
+       .aload(1'b0),
+       .datac(1'b1),
+       .datad(1'b1),
+       .inverta(1'b0),
+       .regcascin(1'b0),
+       .sload(1'b0)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_on
+       `endif
+       // synopsys translate_off
+       ,
+       .cin0(),
+       .cin1(),
+       .cout0(),
+       .cout1(),
+       .devclrn(),
+       .devpor()
+       // synopsys translate_on
+       );
+       defparam
+               parity.cin_used = "true",
+               parity.lut_mask = "9982",
+               parity.operation_mode = "arithmetic",
+               parity.synch_mode = "on",
+               parity.lpm_type = "cyclone_lcell";
+       assign
+               power_modified_counter_values = {wire_countera_regout[10:1], (~ wire_countera_regout[0])},
+               q = power_modified_counter_values,
+               sclr = 1'b0,
+               updown = 1'b1;
+endmodule //fifo_2k_a_graycounter_2r6
+
+
+//altsyncram ADDRESS_REG_B="CLOCK1" DEVICE_FAMILY="Cyclone" OPERATION_MODE="DUAL_PORT" OUTDATA_REG_B="UNREGISTERED" WIDTH_A=16 WIDTH_B=16 WIDTH_BYTEENA_A=1 WIDTHAD_A=11 WIDTHAD_B=11 address_a address_b clock0 clock1 clocken1 data_a q_b wren_a
+//VERSION_BEGIN 5.0 cbx_altsyncram 2005:03:24:13:58:56:SJ cbx_cycloneii 2004:12:20:14:28:52:SJ cbx_lpm_add_sub 2005:04:12:13:30:42:SJ cbx_lpm_compare 2004:11:30:11:30:40:SJ cbx_lpm_decode 2004:12:13:14:19:12:SJ cbx_lpm_mux 2004:12:13:14:16:38:SJ cbx_mgl 2005:05:19:13:51:58:SJ cbx_stratix 2005:06:02:09:53:04:SJ cbx_stratixii 2004:12:22:13:27:12:SJ cbx_util_mgl 2005:04:04:13:50:06:SJ  VERSION_END
+
+//synthesis_resources = M4K 8 
+//synopsys translate_off
+`timescale 1 ps / 1 ps
+//synopsys translate_on
+module  fifo_2k_altsyncram_6pl
+       ( 
+       address_a,
+       address_b,
+       clock0,
+       clock1,
+       clocken1,
+       data_a,
+       q_b,
+       wren_a) /* synthesis synthesis_clearbox=1 */;
+       input   [10:0]  address_a;
+       input   [10:0]  address_b;
+       input   clock0;
+       input   clock1;
+       input   clocken1;
+       input   [15:0]  data_a;
+       output   [15:0]  q_b;
+       input   wren_a;
+
+       wire  [0:0]   wire_ram_block3a_0portbdataout;
+       wire  [0:0]   wire_ram_block3a_1portbdataout;
+       wire  [0:0]   wire_ram_block3a_2portbdataout;
+       wire  [0:0]   wire_ram_block3a_3portbdataout;
+       wire  [0:0]   wire_ram_block3a_4portbdataout;
+       wire  [0:0]   wire_ram_block3a_5portbdataout;
+       wire  [0:0]   wire_ram_block3a_6portbdataout;
+       wire  [0:0]   wire_ram_block3a_7portbdataout;
+       wire  [0:0]   wire_ram_block3a_8portbdataout;
+       wire  [0:0]   wire_ram_block3a_9portbdataout;
+       wire  [0:0]   wire_ram_block3a_10portbdataout;
+       wire  [0:0]   wire_ram_block3a_11portbdataout;
+       wire  [0:0]   wire_ram_block3a_12portbdataout;
+       wire  [0:0]   wire_ram_block3a_13portbdataout;
+       wire  [0:0]   wire_ram_block3a_14portbdataout;
+       wire  [0:0]   wire_ram_block3a_15portbdataout;
+       wire  [10:0]  address_a_wire;
+       wire  [10:0]  address_b_wire;
+
+       cyclone_ram_block   ram_block3a_0
+       ( 
+       .clk0(clock0),
+       .clk1(clock1),
+       .ena0(wren_a),
+       .ena1(clocken1),
+       .portaaddr({address_a_wire[10:0]}),
+       .portadatain({data_a[0]}),
+       .portadataout(),
+       .portawe(1'b1),
+       .portbaddr({address_b_wire[10:0]}),
+       .portbdataout(wire_ram_block3a_0portbdataout[0:0]),
+       .portbrewe(1'b1)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_off
+       `endif
+       ,
+       .clr0(1'b0),
+       .clr1(1'b0),
+       .portabyteenamasks(1'b1),
+       .portbbyteenamasks(1'b1),
+       .portbdatain(1'b0)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_on
+       `endif
+       // synopsys translate_off
+       ,
+       .devclrn(),
+       .devpor()
+       // synopsys translate_on
+       );
+       defparam
+               ram_block3a_0.connectivity_checking = "OFF",
+               ram_block3a_0.logical_ram_name = "ALTSYNCRAM",
+               ram_block3a_0.mixed_port_feed_through_mode = "dont_care",
+               ram_block3a_0.operation_mode = "dual_port",
+               ram_block3a_0.port_a_address_width = 11,
+               ram_block3a_0.port_a_data_width = 1,
+               ram_block3a_0.port_a_first_address = 0,
+               ram_block3a_0.port_a_first_bit_number = 0,
+               ram_block3a_0.port_a_last_address = 2047,
+               ram_block3a_0.port_a_logical_ram_depth = 2048,
+               ram_block3a_0.port_a_logical_ram_width = 16,
+               ram_block3a_0.port_b_address_clear = "none",
+               ram_block3a_0.port_b_address_clock = "clock1",
+               ram_block3a_0.port_b_address_width = 11,
+               ram_block3a_0.port_b_data_out_clear = "none",
+               ram_block3a_0.port_b_data_out_clock = "none",
+               ram_block3a_0.port_b_data_width = 1,
+               ram_block3a_0.port_b_first_address = 0,
+               ram_block3a_0.port_b_first_bit_number = 0,
+               ram_block3a_0.port_b_last_address = 2047,
+               ram_block3a_0.port_b_logical_ram_depth = 2048,
+               ram_block3a_0.port_b_logical_ram_width = 16,
+               ram_block3a_0.port_b_read_enable_write_enable_clock = "clock1",
+               ram_block3a_0.ram_block_type = "auto",
+               ram_block3a_0.lpm_type = "cyclone_ram_block";
+       cyclone_ram_block   ram_block3a_1
+       ( 
+       .clk0(clock0),
+       .clk1(clock1),
+       .ena0(wren_a),
+       .ena1(clocken1),
+       .portaaddr({address_a_wire[10:0]}),
+       .portadatain({data_a[1]}),
+       .portadataout(),
+       .portawe(1'b1),
+       .portbaddr({address_b_wire[10:0]}),
+       .portbdataout(wire_ram_block3a_1portbdataout[0:0]),
+       .portbrewe(1'b1)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_off
+       `endif
+       ,
+       .clr0(1'b0),
+       .clr1(1'b0),
+       .portabyteenamasks(1'b1),
+       .portbbyteenamasks(1'b1),
+       .portbdatain(1'b0)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_on
+       `endif
+       // synopsys translate_off
+       ,
+       .devclrn(),
+       .devpor()
+       // synopsys translate_on
+       );
+       defparam
+               ram_block3a_1.connectivity_checking = "OFF",
+               ram_block3a_1.logical_ram_name = "ALTSYNCRAM",
+               ram_block3a_1.mixed_port_feed_through_mode = "dont_care",
+               ram_block3a_1.operation_mode = "dual_port",
+               ram_block3a_1.port_a_address_width = 11,
+               ram_block3a_1.port_a_data_width = 1,
+               ram_block3a_1.port_a_first_address = 0,
+               ram_block3a_1.port_a_first_bit_number = 1,
+               ram_block3a_1.port_a_last_address = 2047,
+               ram_block3a_1.port_a_logical_ram_depth = 2048,
+               ram_block3a_1.port_a_logical_ram_width = 16,
+               ram_block3a_1.port_b_address_clear = "none",
+               ram_block3a_1.port_b_address_clock = "clock1",
+               ram_block3a_1.port_b_address_width = 11,
+               ram_block3a_1.port_b_data_out_clear = "none",
+               ram_block3a_1.port_b_data_out_clock = "none",
+               ram_block3a_1.port_b_data_width = 1,
+               ram_block3a_1.port_b_first_address = 0,
+               ram_block3a_1.port_b_first_bit_number = 1,
+               ram_block3a_1.port_b_last_address = 2047,
+               ram_block3a_1.port_b_logical_ram_depth = 2048,
+               ram_block3a_1.port_b_logical_ram_width = 16,
+               ram_block3a_1.port_b_read_enable_write_enable_clock = "clock1",
+               ram_block3a_1.ram_block_type = "auto",
+               ram_block3a_1.lpm_type = "cyclone_ram_block";
+       cyclone_ram_block   ram_block3a_2
+       ( 
+       .clk0(clock0),
+       .clk1(clock1),
+       .ena0(wren_a),
+       .ena1(clocken1),
+       .portaaddr({address_a_wire[10:0]}),
+       .portadatain({data_a[2]}),
+       .portadataout(),
+       .portawe(1'b1),
+       .portbaddr({address_b_wire[10:0]}),
+       .portbdataout(wire_ram_block3a_2portbdataout[0:0]),
+       .portbrewe(1'b1)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_off
+       `endif
+       ,
+       .clr0(1'b0),
+       .clr1(1'b0),
+       .portabyteenamasks(1'b1),
+       .portbbyteenamasks(1'b1),
+       .portbdatain(1'b0)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_on
+       `endif
+       // synopsys translate_off
+       ,
+       .devclrn(),
+       .devpor()
+       // synopsys translate_on
+       );
+       defparam
+               ram_block3a_2.connectivity_checking = "OFF",
+               ram_block3a_2.logical_ram_name = "ALTSYNCRAM",
+               ram_block3a_2.mixed_port_feed_through_mode = "dont_care",
+               ram_block3a_2.operation_mode = "dual_port",
+               ram_block3a_2.port_a_address_width = 11,
+               ram_block3a_2.port_a_data_width = 1,
+               ram_block3a_2.port_a_first_address = 0,
+               ram_block3a_2.port_a_first_bit_number = 2,
+               ram_block3a_2.port_a_last_address = 2047,
+               ram_block3a_2.port_a_logical_ram_depth = 2048,
+               ram_block3a_2.port_a_logical_ram_width = 16,
+               ram_block3a_2.port_b_address_clear = "none",
+               ram_block3a_2.port_b_address_clock = "clock1",
+               ram_block3a_2.port_b_address_width = 11,
+               ram_block3a_2.port_b_data_out_clear = "none",
+               ram_block3a_2.port_b_data_out_clock = "none",
+               ram_block3a_2.port_b_data_width = 1,
+               ram_block3a_2.port_b_first_address = 0,
+               ram_block3a_2.port_b_first_bit_number = 2,
+               ram_block3a_2.port_b_last_address = 2047,
+               ram_block3a_2.port_b_logical_ram_depth = 2048,
+               ram_block3a_2.port_b_logical_ram_width = 16,
+               ram_block3a_2.port_b_read_enable_write_enable_clock = "clock1",
+               ram_block3a_2.ram_block_type = "auto",
+               ram_block3a_2.lpm_type = "cyclone_ram_block";
+       cyclone_ram_block   ram_block3a_3
+       ( 
+       .clk0(clock0),
+       .clk1(clock1),
+       .ena0(wren_a),
+       .ena1(clocken1),
+       .portaaddr({address_a_wire[10:0]}),
+       .portadatain({data_a[3]}),
+       .portadataout(),
+       .portawe(1'b1),
+       .portbaddr({address_b_wire[10:0]}),
+       .portbdataout(wire_ram_block3a_3portbdataout[0:0]),
+       .portbrewe(1'b1)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_off
+       `endif
+       ,
+       .clr0(1'b0),
+       .clr1(1'b0),
+       .portabyteenamasks(1'b1),
+       .portbbyteenamasks(1'b1),
+       .portbdatain(1'b0)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_on
+       `endif
+       // synopsys translate_off
+       ,
+       .devclrn(),
+       .devpor()
+       // synopsys translate_on
+       );
+       defparam
+               ram_block3a_3.connectivity_checking = "OFF",
+               ram_block3a_3.logical_ram_name = "ALTSYNCRAM",
+               ram_block3a_3.mixed_port_feed_through_mode = "dont_care",
+               ram_block3a_3.operation_mode = "dual_port",
+               ram_block3a_3.port_a_address_width = 11,
+               ram_block3a_3.port_a_data_width = 1,
+               ram_block3a_3.port_a_first_address = 0,
+               ram_block3a_3.port_a_first_bit_number = 3,
+               ram_block3a_3.port_a_last_address = 2047,
+               ram_block3a_3.port_a_logical_ram_depth = 2048,
+               ram_block3a_3.port_a_logical_ram_width = 16,
+               ram_block3a_3.port_b_address_clear = "none",
+               ram_block3a_3.port_b_address_clock = "clock1",
+               ram_block3a_3.port_b_address_width = 11,
+               ram_block3a_3.port_b_data_out_clear = "none",
+               ram_block3a_3.port_b_data_out_clock = "none",
+               ram_block3a_3.port_b_data_width = 1,
+               ram_block3a_3.port_b_first_address = 0,
+               ram_block3a_3.port_b_first_bit_number = 3,
+               ram_block3a_3.port_b_last_address = 2047,
+               ram_block3a_3.port_b_logical_ram_depth = 2048,
+               ram_block3a_3.port_b_logical_ram_width = 16,
+               ram_block3a_3.port_b_read_enable_write_enable_clock = "clock1",
+               ram_block3a_3.ram_block_type = "auto",
+               ram_block3a_3.lpm_type = "cyclone_ram_block";
+       cyclone_ram_block   ram_block3a_4
+       ( 
+       .clk0(clock0),
+       .clk1(clock1),
+       .ena0(wren_a),
+       .ena1(clocken1),
+       .portaaddr({address_a_wire[10:0]}),
+       .portadatain({data_a[4]}),
+       .portadataout(),
+       .portawe(1'b1),
+       .portbaddr({address_b_wire[10:0]}),
+       .portbdataout(wire_ram_block3a_4portbdataout[0:0]),
+       .portbrewe(1'b1)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_off
+       `endif
+       ,
+       .clr0(1'b0),
+       .clr1(1'b0),
+       .portabyteenamasks(1'b1),
+       .portbbyteenamasks(1'b1),
+       .portbdatain(1'b0)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_on
+       `endif
+       // synopsys translate_off
+       ,
+       .devclrn(),
+       .devpor()
+       // synopsys translate_on
+       );
+       defparam
+               ram_block3a_4.connectivity_checking = "OFF",
+               ram_block3a_4.logical_ram_name = "ALTSYNCRAM",
+               ram_block3a_4.mixed_port_feed_through_mode = "dont_care",
+               ram_block3a_4.operation_mode = "dual_port",
+               ram_block3a_4.port_a_address_width = 11,
+               ram_block3a_4.port_a_data_width = 1,
+               ram_block3a_4.port_a_first_address = 0,
+               ram_block3a_4.port_a_first_bit_number = 4,
+               ram_block3a_4.port_a_last_address = 2047,
+               ram_block3a_4.port_a_logical_ram_depth = 2048,
+               ram_block3a_4.port_a_logical_ram_width = 16,
+               ram_block3a_4.port_b_address_clear = "none",
+               ram_block3a_4.port_b_address_clock = "clock1",
+               ram_block3a_4.port_b_address_width = 11,
+               ram_block3a_4.port_b_data_out_clear = "none",
+               ram_block3a_4.port_b_data_out_clock = "none",
+               ram_block3a_4.port_b_data_width = 1,
+               ram_block3a_4.port_b_first_address = 0,
+               ram_block3a_4.port_b_first_bit_number = 4,
+               ram_block3a_4.port_b_last_address = 2047,
+               ram_block3a_4.port_b_logical_ram_depth = 2048,
+               ram_block3a_4.port_b_logical_ram_width = 16,
+               ram_block3a_4.port_b_read_enable_write_enable_clock = "clock1",
+               ram_block3a_4.ram_block_type = "auto",
+               ram_block3a_4.lpm_type = "cyclone_ram_block";
+       cyclone_ram_block   ram_block3a_5
+       ( 
+       .clk0(clock0),
+       .clk1(clock1),
+       .ena0(wren_a),
+       .ena1(clocken1),
+       .portaaddr({address_a_wire[10:0]}),
+       .portadatain({data_a[5]}),
+       .portadataout(),
+       .portawe(1'b1),
+       .portbaddr({address_b_wire[10:0]}),
+       .portbdataout(wire_ram_block3a_5portbdataout[0:0]),
+       .portbrewe(1'b1)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_off
+       `endif
+       ,
+       .clr0(1'b0),
+       .clr1(1'b0),
+       .portabyteenamasks(1'b1),
+       .portbbyteenamasks(1'b1),
+       .portbdatain(1'b0)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_on
+       `endif
+       // synopsys translate_off
+       ,
+       .devclrn(),
+       .devpor()
+       // synopsys translate_on
+       );
+       defparam
+               ram_block3a_5.connectivity_checking = "OFF",
+               ram_block3a_5.logical_ram_name = "ALTSYNCRAM",
+               ram_block3a_5.mixed_port_feed_through_mode = "dont_care",
+               ram_block3a_5.operation_mode = "dual_port",
+               ram_block3a_5.port_a_address_width = 11,
+               ram_block3a_5.port_a_data_width = 1,
+               ram_block3a_5.port_a_first_address = 0,
+               ram_block3a_5.port_a_first_bit_number = 5,
+               ram_block3a_5.port_a_last_address = 2047,
+               ram_block3a_5.port_a_logical_ram_depth = 2048,
+               ram_block3a_5.port_a_logical_ram_width = 16,
+               ram_block3a_5.port_b_address_clear = "none",
+               ram_block3a_5.port_b_address_clock = "clock1",
+               ram_block3a_5.port_b_address_width = 11,
+               ram_block3a_5.port_b_data_out_clear = "none",
+               ram_block3a_5.port_b_data_out_clock = "none",
+               ram_block3a_5.port_b_data_width = 1,
+               ram_block3a_5.port_b_first_address = 0,
+               ram_block3a_5.port_b_first_bit_number = 5,
+               ram_block3a_5.port_b_last_address = 2047,
+               ram_block3a_5.port_b_logical_ram_depth = 2048,
+               ram_block3a_5.port_b_logical_ram_width = 16,
+               ram_block3a_5.port_b_read_enable_write_enable_clock = "clock1",
+               ram_block3a_5.ram_block_type = "auto",
+               ram_block3a_5.lpm_type = "cyclone_ram_block";
+       cyclone_ram_block   ram_block3a_6
+       ( 
+       .clk0(clock0),
+       .clk1(clock1),
+       .ena0(wren_a),
+       .ena1(clocken1),
+       .portaaddr({address_a_wire[10:0]}),
+       .portadatain({data_a[6]}),
+       .portadataout(),
+       .portawe(1'b1),
+       .portbaddr({address_b_wire[10:0]}),
+       .portbdataout(wire_ram_block3a_6portbdataout[0:0]),
+       .portbrewe(1'b1)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_off
+       `endif
+       ,
+       .clr0(1'b0),
+       .clr1(1'b0),
+       .portabyteenamasks(1'b1),
+       .portbbyteenamasks(1'b1),
+       .portbdatain(1'b0)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_on
+       `endif
+       // synopsys translate_off
+       ,
+       .devclrn(),
+       .devpor()
+       // synopsys translate_on
+       );
+       defparam
+               ram_block3a_6.connectivity_checking = "OFF",
+               ram_block3a_6.logical_ram_name = "ALTSYNCRAM",
+               ram_block3a_6.mixed_port_feed_through_mode = "dont_care",
+               ram_block3a_6.operation_mode = "dual_port",
+               ram_block3a_6.port_a_address_width = 11,
+               ram_block3a_6.port_a_data_width = 1,
+               ram_block3a_6.port_a_first_address = 0,
+               ram_block3a_6.port_a_first_bit_number = 6,
+               ram_block3a_6.port_a_last_address = 2047,
+               ram_block3a_6.port_a_logical_ram_depth = 2048,
+               ram_block3a_6.port_a_logical_ram_width = 16,
+               ram_block3a_6.port_b_address_clear = "none",
+               ram_block3a_6.port_b_address_clock = "clock1",
+               ram_block3a_6.port_b_address_width = 11,
+               ram_block3a_6.port_b_data_out_clear = "none",
+               ram_block3a_6.port_b_data_out_clock = "none",
+               ram_block3a_6.port_b_data_width = 1,
+               ram_block3a_6.port_b_first_address = 0,
+               ram_block3a_6.port_b_first_bit_number = 6,
+               ram_block3a_6.port_b_last_address = 2047,
+               ram_block3a_6.port_b_logical_ram_depth = 2048,
+               ram_block3a_6.port_b_logical_ram_width = 16,
+               ram_block3a_6.port_b_read_enable_write_enable_clock = "clock1",
+               ram_block3a_6.ram_block_type = "auto",
+               ram_block3a_6.lpm_type = "cyclone_ram_block";
+       cyclone_ram_block   ram_block3a_7
+       ( 
+       .clk0(clock0),
+       .clk1(clock1),
+       .ena0(wren_a),
+       .ena1(clocken1),
+       .portaaddr({address_a_wire[10:0]}),
+       .portadatain({data_a[7]}),
+       .portadataout(),
+       .portawe(1'b1),
+       .portbaddr({address_b_wire[10:0]}),
+       .portbdataout(wire_ram_block3a_7portbdataout[0:0]),
+       .portbrewe(1'b1)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_off
+       `endif
+       ,
+       .clr0(1'b0),
+       .clr1(1'b0),
+       .portabyteenamasks(1'b1),
+       .portbbyteenamasks(1'b1),
+       .portbdatain(1'b0)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_on
+       `endif
+       // synopsys translate_off
+       ,
+       .devclrn(),
+       .devpor()
+       // synopsys translate_on
+       );
+       defparam
+               ram_block3a_7.connectivity_checking = "OFF",
+               ram_block3a_7.logical_ram_name = "ALTSYNCRAM",
+               ram_block3a_7.mixed_port_feed_through_mode = "dont_care",
+               ram_block3a_7.operation_mode = "dual_port",
+               ram_block3a_7.port_a_address_width = 11,
+               ram_block3a_7.port_a_data_width = 1,
+               ram_block3a_7.port_a_first_address = 0,
+               ram_block3a_7.port_a_first_bit_number = 7,
+               ram_block3a_7.port_a_last_address = 2047,
+               ram_block3a_7.port_a_logical_ram_depth = 2048,
+               ram_block3a_7.port_a_logical_ram_width = 16,
+               ram_block3a_7.port_b_address_clear = "none",
+               ram_block3a_7.port_b_address_clock = "clock1",
+               ram_block3a_7.port_b_address_width = 11,
+               ram_block3a_7.port_b_data_out_clear = "none",
+               ram_block3a_7.port_b_data_out_clock = "none",
+               ram_block3a_7.port_b_data_width = 1,
+               ram_block3a_7.port_b_first_address = 0,
+               ram_block3a_7.port_b_first_bit_number = 7,
+               ram_block3a_7.port_b_last_address = 2047,
+               ram_block3a_7.port_b_logical_ram_depth = 2048,
+               ram_block3a_7.port_b_logical_ram_width = 16,
+               ram_block3a_7.port_b_read_enable_write_enable_clock = "clock1",
+               ram_block3a_7.ram_block_type = "auto",
+               ram_block3a_7.lpm_type = "cyclone_ram_block";
+       cyclone_ram_block   ram_block3a_8
+       ( 
+       .clk0(clock0),
+       .clk1(clock1),
+       .ena0(wren_a),
+       .ena1(clocken1),
+       .portaaddr({address_a_wire[10:0]}),
+       .portadatain({data_a[8]}),
+       .portadataout(),
+       .portawe(1'b1),
+       .portbaddr({address_b_wire[10:0]}),
+       .portbdataout(wire_ram_block3a_8portbdataout[0:0]),
+       .portbrewe(1'b1)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_off
+       `endif
+       ,
+       .clr0(1'b0),
+       .clr1(1'b0),
+       .portabyteenamasks(1'b1),
+       .portbbyteenamasks(1'b1),
+       .portbdatain(1'b0)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_on
+       `endif
+       // synopsys translate_off
+       ,
+       .devclrn(),
+       .devpor()
+       // synopsys translate_on
+       );
+       defparam
+               ram_block3a_8.connectivity_checking = "OFF",
+               ram_block3a_8.logical_ram_name = "ALTSYNCRAM",
+               ram_block3a_8.mixed_port_feed_through_mode = "dont_care",
+               ram_block3a_8.operation_mode = "dual_port",
+               ram_block3a_8.port_a_address_width = 11,
+               ram_block3a_8.port_a_data_width = 1,
+               ram_block3a_8.port_a_first_address = 0,
+               ram_block3a_8.port_a_first_bit_number = 8,
+               ram_block3a_8.port_a_last_address = 2047,
+               ram_block3a_8.port_a_logical_ram_depth = 2048,
+               ram_block3a_8.port_a_logical_ram_width = 16,
+               ram_block3a_8.port_b_address_clear = "none",
+               ram_block3a_8.port_b_address_clock = "clock1",
+               ram_block3a_8.port_b_address_width = 11,
+               ram_block3a_8.port_b_data_out_clear = "none",
+               ram_block3a_8.port_b_data_out_clock = "none",
+               ram_block3a_8.port_b_data_width = 1,
+               ram_block3a_8.port_b_first_address = 0,
+               ram_block3a_8.port_b_first_bit_number = 8,
+               ram_block3a_8.port_b_last_address = 2047,
+               ram_block3a_8.port_b_logical_ram_depth = 2048,
+               ram_block3a_8.port_b_logical_ram_width = 16,
+               ram_block3a_8.port_b_read_enable_write_enable_clock = "clock1",
+               ram_block3a_8.ram_block_type = "auto",
+               ram_block3a_8.lpm_type = "cyclone_ram_block";
+       cyclone_ram_block   ram_block3a_9
+       ( 
+       .clk0(clock0),
+       .clk1(clock1),
+       .ena0(wren_a),
+       .ena1(clocken1),
+       .portaaddr({address_a_wire[10:0]}),
+       .portadatain({data_a[9]}),
+       .portadataout(),
+       .portawe(1'b1),
+       .portbaddr({address_b_wire[10:0]}),
+       .portbdataout(wire_ram_block3a_9portbdataout[0:0]),
+       .portbrewe(1'b1)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_off
+       `endif
+       ,
+       .clr0(1'b0),
+       .clr1(1'b0),
+       .portabyteenamasks(1'b1),
+       .portbbyteenamasks(1'b1),
+       .portbdatain(1'b0)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_on
+       `endif
+       // synopsys translate_off
+       ,
+       .devclrn(),
+       .devpor()
+       // synopsys translate_on
+       );
+       defparam
+               ram_block3a_9.connectivity_checking = "OFF",
+               ram_block3a_9.logical_ram_name = "ALTSYNCRAM",
+               ram_block3a_9.mixed_port_feed_through_mode = "dont_care",
+               ram_block3a_9.operation_mode = "dual_port",
+               ram_block3a_9.port_a_address_width = 11,
+               ram_block3a_9.port_a_data_width = 1,
+               ram_block3a_9.port_a_first_address = 0,
+               ram_block3a_9.port_a_first_bit_number = 9,
+               ram_block3a_9.port_a_last_address = 2047,
+               ram_block3a_9.port_a_logical_ram_depth = 2048,
+               ram_block3a_9.port_a_logical_ram_width = 16,
+               ram_block3a_9.port_b_address_clear = "none",
+               ram_block3a_9.port_b_address_clock = "clock1",
+               ram_block3a_9.port_b_address_width = 11,
+               ram_block3a_9.port_b_data_out_clear = "none",
+               ram_block3a_9.port_b_data_out_clock = "none",
+               ram_block3a_9.port_b_data_width = 1,
+               ram_block3a_9.port_b_first_address = 0,
+               ram_block3a_9.port_b_first_bit_number = 9,
+               ram_block3a_9.port_b_last_address = 2047,
+               ram_block3a_9.port_b_logical_ram_depth = 2048,
+               ram_block3a_9.port_b_logical_ram_width = 16,
+               ram_block3a_9.port_b_read_enable_write_enable_clock = "clock1",
+               ram_block3a_9.ram_block_type = "auto",
+               ram_block3a_9.lpm_type = "cyclone_ram_block";
+       cyclone_ram_block   ram_block3a_10
+       ( 
+       .clk0(clock0),
+       .clk1(clock1),
+       .ena0(wren_a),
+       .ena1(clocken1),
+       .portaaddr({address_a_wire[10:0]}),
+       .portadatain({data_a[10]}),
+       .portadataout(),
+       .portawe(1'b1),
+       .portbaddr({address_b_wire[10:0]}),
+       .portbdataout(wire_ram_block3a_10portbdataout[0:0]),
+       .portbrewe(1'b1)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_off
+       `endif
+       ,
+       .clr0(1'b0),
+       .clr1(1'b0),
+       .portabyteenamasks(1'b1),
+       .portbbyteenamasks(1'b1),
+       .portbdatain(1'b0)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_on
+       `endif
+       // synopsys translate_off
+       ,
+       .devclrn(),
+       .devpor()
+       // synopsys translate_on
+       );
+       defparam
+               ram_block3a_10.connectivity_checking = "OFF",
+               ram_block3a_10.logical_ram_name = "ALTSYNCRAM",
+               ram_block3a_10.mixed_port_feed_through_mode = "dont_care",
+               ram_block3a_10.operation_mode = "dual_port",
+               ram_block3a_10.port_a_address_width = 11,
+               ram_block3a_10.port_a_data_width = 1,
+               ram_block3a_10.port_a_first_address = 0,
+               ram_block3a_10.port_a_first_bit_number = 10,
+               ram_block3a_10.port_a_last_address = 2047,
+               ram_block3a_10.port_a_logical_ram_depth = 2048,
+               ram_block3a_10.port_a_logical_ram_width = 16,
+               ram_block3a_10.port_b_address_clear = "none",
+               ram_block3a_10.port_b_address_clock = "clock1",
+               ram_block3a_10.port_b_address_width = 11,
+               ram_block3a_10.port_b_data_out_clear = "none",
+               ram_block3a_10.port_b_data_out_clock = "none",
+               ram_block3a_10.port_b_data_width = 1,
+               ram_block3a_10.port_b_first_address = 0,
+               ram_block3a_10.port_b_first_bit_number = 10,
+               ram_block3a_10.port_b_last_address = 2047,
+               ram_block3a_10.port_b_logical_ram_depth = 2048,
+               ram_block3a_10.port_b_logical_ram_width = 16,
+               ram_block3a_10.port_b_read_enable_write_enable_clock = "clock1",
+               ram_block3a_10.ram_block_type = "auto",
+               ram_block3a_10.lpm_type = "cyclone_ram_block";
+       cyclone_ram_block   ram_block3a_11
+       ( 
+       .clk0(clock0),
+       .clk1(clock1),
+       .ena0(wren_a),
+       .ena1(clocken1),
+       .portaaddr({address_a_wire[10:0]}),
+       .portadatain({data_a[11]}),
+       .portadataout(),
+       .portawe(1'b1),
+       .portbaddr({address_b_wire[10:0]}),
+       .portbdataout(wire_ram_block3a_11portbdataout[0:0]),
+       .portbrewe(1'b1)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_off
+       `endif
+       ,
+       .clr0(1'b0),
+       .clr1(1'b0),
+       .portabyteenamasks(1'b1),
+       .portbbyteenamasks(1'b1),
+       .portbdatain(1'b0)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_on
+       `endif
+       // synopsys translate_off
+       ,
+       .devclrn(),
+       .devpor()
+       // synopsys translate_on
+       );
+       defparam
+               ram_block3a_11.connectivity_checking = "OFF",
+               ram_block3a_11.logical_ram_name = "ALTSYNCRAM",
+               ram_block3a_11.mixed_port_feed_through_mode = "dont_care",
+               ram_block3a_11.operation_mode = "dual_port",
+               ram_block3a_11.port_a_address_width = 11,
+               ram_block3a_11.port_a_data_width = 1,
+               ram_block3a_11.port_a_first_address = 0,
+               ram_block3a_11.port_a_first_bit_number = 11,
+               ram_block3a_11.port_a_last_address = 2047,
+               ram_block3a_11.port_a_logical_ram_depth = 2048,
+               ram_block3a_11.port_a_logical_ram_width = 16,
+               ram_block3a_11.port_b_address_clear = "none",
+               ram_block3a_11.port_b_address_clock = "clock1",
+               ram_block3a_11.port_b_address_width = 11,
+               ram_block3a_11.port_b_data_out_clear = "none",
+               ram_block3a_11.port_b_data_out_clock = "none",
+               ram_block3a_11.port_b_data_width = 1,
+               ram_block3a_11.port_b_first_address = 0,
+               ram_block3a_11.port_b_first_bit_number = 11,
+               ram_block3a_11.port_b_last_address = 2047,
+               ram_block3a_11.port_b_logical_ram_depth = 2048,
+               ram_block3a_11.port_b_logical_ram_width = 16,
+               ram_block3a_11.port_b_read_enable_write_enable_clock = "clock1",
+               ram_block3a_11.ram_block_type = "auto",
+               ram_block3a_11.lpm_type = "cyclone_ram_block";
+       cyclone_ram_block   ram_block3a_12
+       ( 
+       .clk0(clock0),
+       .clk1(clock1),
+       .ena0(wren_a),
+       .ena1(clocken1),
+       .portaaddr({address_a_wire[10:0]}),
+       .portadatain({data_a[12]}),
+       .portadataout(),
+       .portawe(1'b1),
+       .portbaddr({address_b_wire[10:0]}),
+       .portbdataout(wire_ram_block3a_12portbdataout[0:0]),
+       .portbrewe(1'b1)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_off
+       `endif
+       ,
+       .clr0(1'b0),
+       .clr1(1'b0),
+       .portabyteenamasks(1'b1),
+       .portbbyteenamasks(1'b1),
+       .portbdatain(1'b0)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_on
+       `endif
+       // synopsys translate_off
+       ,
+       .devclrn(),
+       .devpor()
+       // synopsys translate_on
+       );
+       defparam
+               ram_block3a_12.connectivity_checking = "OFF",
+               ram_block3a_12.logical_ram_name = "ALTSYNCRAM",
+               ram_block3a_12.mixed_port_feed_through_mode = "dont_care",
+               ram_block3a_12.operation_mode = "dual_port",
+               ram_block3a_12.port_a_address_width = 11,
+               ram_block3a_12.port_a_data_width = 1,
+               ram_block3a_12.port_a_first_address = 0,
+               ram_block3a_12.port_a_first_bit_number = 12,
+               ram_block3a_12.port_a_last_address = 2047,
+               ram_block3a_12.port_a_logical_ram_depth = 2048,
+               ram_block3a_12.port_a_logical_ram_width = 16,
+               ram_block3a_12.port_b_address_clear = "none",
+               ram_block3a_12.port_b_address_clock = "clock1",
+               ram_block3a_12.port_b_address_width = 11,
+               ram_block3a_12.port_b_data_out_clear = "none",
+               ram_block3a_12.port_b_data_out_clock = "none",
+               ram_block3a_12.port_b_data_width = 1,
+               ram_block3a_12.port_b_first_address = 0,
+               ram_block3a_12.port_b_first_bit_number = 12,
+               ram_block3a_12.port_b_last_address = 2047,
+               ram_block3a_12.port_b_logical_ram_depth = 2048,
+               ram_block3a_12.port_b_logical_ram_width = 16,
+               ram_block3a_12.port_b_read_enable_write_enable_clock = "clock1",
+               ram_block3a_12.ram_block_type = "auto",
+               ram_block3a_12.lpm_type = "cyclone_ram_block";
+       cyclone_ram_block   ram_block3a_13
+       ( 
+       .clk0(clock0),
+       .clk1(clock1),
+       .ena0(wren_a),
+       .ena1(clocken1),
+       .portaaddr({address_a_wire[10:0]}),
+       .portadatain({data_a[13]}),
+       .portadataout(),
+       .portawe(1'b1),
+       .portbaddr({address_b_wire[10:0]}),
+       .portbdataout(wire_ram_block3a_13portbdataout[0:0]),
+       .portbrewe(1'b1)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_off
+       `endif
+       ,
+       .clr0(1'b0),
+       .clr1(1'b0),
+       .portabyteenamasks(1'b1),
+       .portbbyteenamasks(1'b1),
+       .portbdatain(1'b0)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_on
+       `endif
+       // synopsys translate_off
+       ,
+       .devclrn(),
+       .devpor()
+       // synopsys translate_on
+       );
+       defparam
+               ram_block3a_13.connectivity_checking = "OFF",
+               ram_block3a_13.logical_ram_name = "ALTSYNCRAM",
+               ram_block3a_13.mixed_port_feed_through_mode = "dont_care",
+               ram_block3a_13.operation_mode = "dual_port",
+               ram_block3a_13.port_a_address_width = 11,
+               ram_block3a_13.port_a_data_width = 1,
+               ram_block3a_13.port_a_first_address = 0,
+               ram_block3a_13.port_a_first_bit_number = 13,
+               ram_block3a_13.port_a_last_address = 2047,
+               ram_block3a_13.port_a_logical_ram_depth = 2048,
+               ram_block3a_13.port_a_logical_ram_width = 16,
+               ram_block3a_13.port_b_address_clear = "none",
+               ram_block3a_13.port_b_address_clock = "clock1",
+               ram_block3a_13.port_b_address_width = 11,
+               ram_block3a_13.port_b_data_out_clear = "none",
+               ram_block3a_13.port_b_data_out_clock = "none",
+               ram_block3a_13.port_b_data_width = 1,
+               ram_block3a_13.port_b_first_address = 0,
+               ram_block3a_13.port_b_first_bit_number = 13,
+               ram_block3a_13.port_b_last_address = 2047,
+               ram_block3a_13.port_b_logical_ram_depth = 2048,
+               ram_block3a_13.port_b_logical_ram_width = 16,
+               ram_block3a_13.port_b_read_enable_write_enable_clock = "clock1",
+               ram_block3a_13.ram_block_type = "auto",
+               ram_block3a_13.lpm_type = "cyclone_ram_block";
+       cyclone_ram_block   ram_block3a_14
+       ( 
+       .clk0(clock0),
+       .clk1(clock1),
+       .ena0(wren_a),
+       .ena1(clocken1),
+       .portaaddr({address_a_wire[10:0]}),
+       .portadatain({data_a[14]}),
+       .portadataout(),
+       .portawe(1'b1),
+       .portbaddr({address_b_wire[10:0]}),
+       .portbdataout(wire_ram_block3a_14portbdataout[0:0]),
+       .portbrewe(1'b1)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_off
+       `endif
+       ,
+       .clr0(1'b0),
+       .clr1(1'b0),
+       .portabyteenamasks(1'b1),
+       .portbbyteenamasks(1'b1),
+       .portbdatain(1'b0)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_on
+       `endif
+       // synopsys translate_off
+       ,
+       .devclrn(),
+       .devpor()
+       // synopsys translate_on
+       );
+       defparam
+               ram_block3a_14.connectivity_checking = "OFF",
+               ram_block3a_14.logical_ram_name = "ALTSYNCRAM",
+               ram_block3a_14.mixed_port_feed_through_mode = "dont_care",
+               ram_block3a_14.operation_mode = "dual_port",
+               ram_block3a_14.port_a_address_width = 11,
+               ram_block3a_14.port_a_data_width = 1,
+               ram_block3a_14.port_a_first_address = 0,
+               ram_block3a_14.port_a_first_bit_number = 14,
+               ram_block3a_14.port_a_last_address = 2047,
+               ram_block3a_14.port_a_logical_ram_depth = 2048,
+               ram_block3a_14.port_a_logical_ram_width = 16,
+               ram_block3a_14.port_b_address_clear = "none",
+               ram_block3a_14.port_b_address_clock = "clock1",
+               ram_block3a_14.port_b_address_width = 11,
+               ram_block3a_14.port_b_data_out_clear = "none",
+               ram_block3a_14.port_b_data_out_clock = "none",
+               ram_block3a_14.port_b_data_width = 1,
+               ram_block3a_14.port_b_first_address = 0,
+               ram_block3a_14.port_b_first_bit_number = 14,
+               ram_block3a_14.port_b_last_address = 2047,
+               ram_block3a_14.port_b_logical_ram_depth = 2048,
+               ram_block3a_14.port_b_logical_ram_width = 16,
+               ram_block3a_14.port_b_read_enable_write_enable_clock = "clock1",
+               ram_block3a_14.ram_block_type = "auto",
+               ram_block3a_14.lpm_type = "cyclone_ram_block";
+       cyclone_ram_block   ram_block3a_15
+       ( 
+       .clk0(clock0),
+       .clk1(clock1),
+       .ena0(wren_a),
+       .ena1(clocken1),
+       .portaaddr({address_a_wire[10:0]}),
+       .portadatain({data_a[15]}),
+       .portadataout(),
+       .portawe(1'b1),
+       .portbaddr({address_b_wire[10:0]}),
+       .portbdataout(wire_ram_block3a_15portbdataout[0:0]),
+       .portbrewe(1'b1)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_off
+       `endif
+       ,
+       .clr0(1'b0),
+       .clr1(1'b0),
+       .portabyteenamasks(1'b1),
+       .portbbyteenamasks(1'b1),
+       .portbdatain(1'b0)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_on
+       `endif
+       // synopsys translate_off
+       ,
+       .devclrn(),
+       .devpor()
+       // synopsys translate_on
+       );
+       defparam
+               ram_block3a_15.connectivity_checking = "OFF",
+               ram_block3a_15.logical_ram_name = "ALTSYNCRAM",
+               ram_block3a_15.mixed_port_feed_through_mode = "dont_care",
+               ram_block3a_15.operation_mode = "dual_port",
+               ram_block3a_15.port_a_address_width = 11,
+               ram_block3a_15.port_a_data_width = 1,
+               ram_block3a_15.port_a_first_address = 0,
+               ram_block3a_15.port_a_first_bit_number = 15,
+               ram_block3a_15.port_a_last_address = 2047,
+               ram_block3a_15.port_a_logical_ram_depth = 2048,
+               ram_block3a_15.port_a_logical_ram_width = 16,
+               ram_block3a_15.port_b_address_clear = "none",
+               ram_block3a_15.port_b_address_clock = "clock1",
+               ram_block3a_15.port_b_address_width = 11,
+               ram_block3a_15.port_b_data_out_clear = "none",
+               ram_block3a_15.port_b_data_out_clock = "none",
+               ram_block3a_15.port_b_data_width = 1,
+               ram_block3a_15.port_b_first_address = 0,
+               ram_block3a_15.port_b_first_bit_number = 15,
+               ram_block3a_15.port_b_last_address = 2047,
+               ram_block3a_15.port_b_logical_ram_depth = 2048,
+               ram_block3a_15.port_b_logical_ram_width = 16,
+               ram_block3a_15.port_b_read_enable_write_enable_clock = "clock1",
+               ram_block3a_15.ram_block_type = "auto",
+               ram_block3a_15.lpm_type = "cyclone_ram_block";
+       assign
+               address_a_wire = address_a,
+               address_b_wire = address_b,
+               q_b = {wire_ram_block3a_15portbdataout[0], wire_ram_block3a_14portbdataout[0], wire_ram_block3a_13portbdataout[0], wire_ram_block3a_12portbdataout[0], wire_ram_block3a_11portbdataout[0], wire_ram_block3a_10portbdataout[0], wire_ram_block3a_9portbdataout[0], wire_ram_block3a_8portbdataout[0], wire_ram_block3a_7portbdataout[0], wire_ram_block3a_6portbdataout[0], wire_ram_block3a_5portbdataout[0], wire_ram_block3a_4portbdataout[0], wire_ram_block3a_3portbdataout[0], wire_ram_block3a_2portbdataout[0], wire_ram_block3a_1portbdataout[0], wire_ram_block3a_0portbdataout[0]};
+endmodule //fifo_2k_altsyncram_6pl
+
+
+//dffpipe DELAY=1 WIDTH=11 clock clrn d q
+//VERSION_BEGIN 5.0 cbx_mgl 2005:05:19:13:51:58:SJ cbx_stratixii 2004:12:22:13:27:12:SJ cbx_util_mgl 2005:04:04:13:50:06:SJ  VERSION_END
+
+//synthesis_resources = lut 11 
+//synopsys translate_off
+`timescale 1 ps / 1 ps
+//synopsys translate_on
+module  fifo_2k_dffpipe_ab3
+       ( 
+       clock,
+       clrn,
+       d,
+       q) /* synthesis synthesis_clearbox=1 */
+               /* synthesis ALTERA_ATTRIBUTE="AUTO_SHIFT_REGISTER_RECOGNITION=OFF" */;
+       input   clock;
+       input   clrn;
+       input   [10:0]  d;
+       output   [10:0]  q;
+
+       wire    [10:0]  wire_dffe4a_D;
+       reg     [10:0]  dffe4a;
+       wire ena;
+       wire prn;
+       wire sclr;
+
+       // synopsys translate_off
+       initial
+               dffe4a[0:0] = 0;
+       // synopsys translate_on
+       always @ ( posedge clock or  negedge prn or  negedge clrn)
+               if (prn == 1'b0) dffe4a[0:0] <= 1'b1;
+               else if (clrn == 1'b0) dffe4a[0:0] <= 1'b0;
+               else if  (ena == 1'b1)   dffe4a[0:0] <= wire_dffe4a_D[0:0];
+       // synopsys translate_off
+       initial
+               dffe4a[1:1] = 0;
+       // synopsys translate_on
+       always @ ( posedge clock or  negedge prn or  negedge clrn)
+               if (prn == 1'b0) dffe4a[1:1] <= 1'b1;
+               else if (clrn == 1'b0) dffe4a[1:1] <= 1'b0;
+               else if  (ena == 1'b1)   dffe4a[1:1] <= wire_dffe4a_D[1:1];
+       // synopsys translate_off
+       initial
+               dffe4a[2:2] = 0;
+       // synopsys translate_on
+       always @ ( posedge clock or  negedge prn or  negedge clrn)
+               if (prn == 1'b0) dffe4a[2:2] <= 1'b1;
+               else if (clrn == 1'b0) dffe4a[2:2] <= 1'b0;
+               else if  (ena == 1'b1)   dffe4a[2:2] <= wire_dffe4a_D[2:2];
+       // synopsys translate_off
+       initial
+               dffe4a[3:3] = 0;
+       // synopsys translate_on
+       always @ ( posedge clock or  negedge prn or  negedge clrn)
+               if (prn == 1'b0) dffe4a[3:3] <= 1'b1;
+               else if (clrn == 1'b0) dffe4a[3:3] <= 1'b0;
+               else if  (ena == 1'b1)   dffe4a[3:3] <= wire_dffe4a_D[3:3];
+       // synopsys translate_off
+       initial
+               dffe4a[4:4] = 0;
+       // synopsys translate_on
+       always @ ( posedge clock or  negedge prn or  negedge clrn)
+               if (prn == 1'b0) dffe4a[4:4] <= 1'b1;
+               else if (clrn == 1'b0) dffe4a[4:4] <= 1'b0;
+               else if  (ena == 1'b1)   dffe4a[4:4] <= wire_dffe4a_D[4:4];
+       // synopsys translate_off
+       initial
+               dffe4a[5:5] = 0;
+       // synopsys translate_on
+       always @ ( posedge clock or  negedge prn or  negedge clrn)
+               if (prn == 1'b0) dffe4a[5:5] <= 1'b1;
+               else if (clrn == 1'b0) dffe4a[5:5] <= 1'b0;
+               else if  (ena == 1'b1)   dffe4a[5:5] <= wire_dffe4a_D[5:5];
+       // synopsys translate_off
+       initial
+               dffe4a[6:6] = 0;
+       // synopsys translate_on
+       always @ ( posedge clock or  negedge prn or  negedge clrn)
+               if (prn == 1'b0) dffe4a[6:6] <= 1'b1;
+               else if (clrn == 1'b0) dffe4a[6:6] <= 1'b0;
+               else if  (ena == 1'b1)   dffe4a[6:6] <= wire_dffe4a_D[6:6];
+       // synopsys translate_off
+       initial
+               dffe4a[7:7] = 0;
+       // synopsys translate_on
+       always @ ( posedge clock or  negedge prn or  negedge clrn)
+               if (prn == 1'b0) dffe4a[7:7] <= 1'b1;
+               else if (clrn == 1'b0) dffe4a[7:7] <= 1'b0;
+               else if  (ena == 1'b1)   dffe4a[7:7] <= wire_dffe4a_D[7:7];
+       // synopsys translate_off
+       initial
+               dffe4a[8:8] = 0;
+       // synopsys translate_on
+       always @ ( posedge clock or  negedge prn or  negedge clrn)
+               if (prn == 1'b0) dffe4a[8:8] <= 1'b1;
+               else if (clrn == 1'b0) dffe4a[8:8] <= 1'b0;
+               else if  (ena == 1'b1)   dffe4a[8:8] <= wire_dffe4a_D[8:8];
+       // synopsys translate_off
+       initial
+               dffe4a[9:9] = 0;
+       // synopsys translate_on
+       always @ ( posedge clock or  negedge prn or  negedge clrn)
+               if (prn == 1'b0) dffe4a[9:9] <= 1'b1;
+               else if (clrn == 1'b0) dffe4a[9:9] <= 1'b0;
+               else if  (ena == 1'b1)   dffe4a[9:9] <= wire_dffe4a_D[9:9];
+       // synopsys translate_off
+       initial
+               dffe4a[10:10] = 0;
+       // synopsys translate_on
+       always @ ( posedge clock or  negedge prn or  negedge clrn)
+               if (prn == 1'b0) dffe4a[10:10] <= 1'b1;
+               else if (clrn == 1'b0) dffe4a[10:10] <= 1'b0;
+               else if  (ena == 1'b1)   dffe4a[10:10] <= wire_dffe4a_D[10:10];
+       assign
+               wire_dffe4a_D = (d & {11{(~ sclr)}});
+       assign
+               ena = 1'b1,
+               prn = 1'b1,
+               q = dffe4a,
+               sclr = 1'b0;
+endmodule //fifo_2k_dffpipe_ab3
+
+
+//dffpipe WIDTH=11 clock clrn d q
+//VERSION_BEGIN 5.0 cbx_a_gray2bin 2004:03:06:00:52:20:SJ cbx_a_graycounter 2004:10:01:12:13:16:SJ cbx_altdpram 2004:11:30:11:29:56:SJ cbx_altsyncram 2005:03:24:13:58:56:SJ cbx_cycloneii 2004:12:20:14:28:52:SJ cbx_dcfifo 2005:03:07:17:11:14:SJ cbx_fifo_common 2004:12:13:14:26:24:SJ cbx_flex10ke 2002:10:18:16:54:38:SJ cbx_lpm_add_sub 2005:04:12:13:30:42:SJ cbx_lpm_compare 2004:11:30:11:30:40:SJ cbx_lpm_counter 2005:02:02:04:37:10:SJ cbx_lpm_decode 2004:12:13:14:19:12:SJ cbx_lpm_mux 2004:12:13:14:16:38:SJ cbx_mgl 2005:05:19:13:51:58:SJ cbx_scfifo 2005:03:10:10:52:20:SJ cbx_stratix 2005:06:02:09:53:04:SJ cbx_stratixii 2004:12:22:13:27:12:SJ cbx_util_mgl 2005:04:04:13:50:06:SJ  VERSION_END
+
+
+//dffpipe WIDTH=11 clock clrn d q
+//VERSION_BEGIN 5.0 cbx_mgl 2005:05:19:13:51:58:SJ cbx_stratixii 2004:12:22:13:27:12:SJ cbx_util_mgl 2005:04:04:13:50:06:SJ  VERSION_END
+
+//synthesis_resources = lut 11 
+//synopsys translate_off
+`timescale 1 ps / 1 ps
+//synopsys translate_on
+module  fifo_2k_dffpipe_dm2
+       ( 
+       clock,
+       clrn,
+       d,
+       q) /* synthesis synthesis_clearbox=1 */
+               /* synthesis ALTERA_ATTRIBUTE="AUTO_SHIFT_REGISTER_RECOGNITION=OFF" */;
+       input   clock;
+       input   clrn;
+       input   [10:0]  d;
+       output   [10:0]  q;
+
+       wire    [10:0]  wire_dffe6a_D;
+       reg     [10:0]  dffe6a;
+       wire ena;
+       wire prn;
+       wire sclr;
+
+       // synopsys translate_off
+       initial
+               dffe6a[0:0] = 0;
+       // synopsys translate_on
+       always @ ( posedge clock or  negedge prn or  negedge clrn)
+               if (prn == 1'b0) dffe6a[0:0] <= 1'b1;
+               else if (clrn == 1'b0) dffe6a[0:0] <= 1'b0;
+               else if  (ena == 1'b1)   dffe6a[0:0] <= wire_dffe6a_D[0:0];
+       // synopsys translate_off
+       initial
+               dffe6a[1:1] = 0;
+       // synopsys translate_on
+       always @ ( posedge clock or  negedge prn or  negedge clrn)
+               if (prn == 1'b0) dffe6a[1:1] <= 1'b1;
+               else if (clrn == 1'b0) dffe6a[1:1] <= 1'b0;
+               else if  (ena == 1'b1)   dffe6a[1:1] <= wire_dffe6a_D[1:1];
+       // synopsys translate_off
+       initial
+               dffe6a[2:2] = 0;
+       // synopsys translate_on
+       always @ ( posedge clock or  negedge prn or  negedge clrn)
+               if (prn == 1'b0) dffe6a[2:2] <= 1'b1;
+               else if (clrn == 1'b0) dffe6a[2:2] <= 1'b0;
+               else if  (ena == 1'b1)   dffe6a[2:2] <= wire_dffe6a_D[2:2];
+       // synopsys translate_off
+       initial
+               dffe6a[3:3] = 0;
+       // synopsys translate_on
+       always @ ( posedge clock or  negedge prn or  negedge clrn)
+               if (prn == 1'b0) dffe6a[3:3] <= 1'b1;
+               else if (clrn == 1'b0) dffe6a[3:3] <= 1'b0;
+               else if  (ena == 1'b1)   dffe6a[3:3] <= wire_dffe6a_D[3:3];
+       // synopsys translate_off
+       initial
+               dffe6a[4:4] = 0;
+       // synopsys translate_on
+       always @ ( posedge clock or  negedge prn or  negedge clrn)
+               if (prn == 1'b0) dffe6a[4:4] <= 1'b1;
+               else if (clrn == 1'b0) dffe6a[4:4] <= 1'b0;
+               else if  (ena == 1'b1)   dffe6a[4:4] <= wire_dffe6a_D[4:4];
+       // synopsys translate_off
+       initial
+               dffe6a[5:5] = 0;
+       // synopsys translate_on
+       always @ ( posedge clock or  negedge prn or  negedge clrn)
+               if (prn == 1'b0) dffe6a[5:5] <= 1'b1;
+               else if (clrn == 1'b0) dffe6a[5:5] <= 1'b0;
+               else if  (ena == 1'b1)   dffe6a[5:5] <= wire_dffe6a_D[5:5];
+       // synopsys translate_off
+       initial
+               dffe6a[6:6] = 0;
+       // synopsys translate_on
+       always @ ( posedge clock or  negedge prn or  negedge clrn)
+               if (prn == 1'b0) dffe6a[6:6] <= 1'b1;
+               else if (clrn == 1'b0) dffe6a[6:6] <= 1'b0;
+               else if  (ena == 1'b1)   dffe6a[6:6] <= wire_dffe6a_D[6:6];
+       // synopsys translate_off
+       initial
+               dffe6a[7:7] = 0;
+       // synopsys translate_on
+       always @ ( posedge clock or  negedge prn or  negedge clrn)
+               if (prn == 1'b0) dffe6a[7:7] <= 1'b1;
+               else if (clrn == 1'b0) dffe6a[7:7] <= 1'b0;
+               else if  (ena == 1'b1)   dffe6a[7:7] <= wire_dffe6a_D[7:7];
+       // synopsys translate_off
+       initial
+               dffe6a[8:8] = 0;
+       // synopsys translate_on
+       always @ ( posedge clock or  negedge prn or  negedge clrn)
+               if (prn == 1'b0) dffe6a[8:8] <= 1'b1;
+               else if (clrn == 1'b0) dffe6a[8:8] <= 1'b0;
+               else if  (ena == 1'b1)   dffe6a[8:8] <= wire_dffe6a_D[8:8];
+       // synopsys translate_off
+       initial
+               dffe6a[9:9] = 0;
+       // synopsys translate_on
+       always @ ( posedge clock or  negedge prn or  negedge clrn)
+               if (prn == 1'b0) dffe6a[9:9] <= 1'b1;
+               else if (clrn == 1'b0) dffe6a[9:9] <= 1'b0;
+               else if  (ena == 1'b1)   dffe6a[9:9] <= wire_dffe6a_D[9:9];
+       // synopsys translate_off
+       initial
+               dffe6a[10:10] = 0;
+       // synopsys translate_on
+       always @ ( posedge clock or  negedge prn or  negedge clrn)
+               if (prn == 1'b0) dffe6a[10:10] <= 1'b1;
+               else if (clrn == 1'b0) dffe6a[10:10] <= 1'b0;
+               else if  (ena == 1'b1)   dffe6a[10:10] <= wire_dffe6a_D[10:10];
+       assign
+               wire_dffe6a_D = (d & {11{(~ sclr)}});
+       assign
+               ena = 1'b1,
+               prn = 1'b1,
+               q = dffe6a,
+               sclr = 1'b0;
+endmodule //fifo_2k_dffpipe_dm2
+
+//synthesis_resources = lut 11 
+//synopsys translate_off
+`timescale 1 ps / 1 ps
+//synopsys translate_on
+module  fifo_2k_alt_synch_pipe_dm2
+       ( 
+       clock,
+       clrn,
+       d,
+       q) /* synthesis synthesis_clearbox=1 */
+               /* synthesis ALTERA_ATTRIBUTE="X_ON_VIOLATION_OPTION=OFF" */;
+       input   clock;
+       input   clrn;
+       input   [10:0]  d;
+       output   [10:0]  q;
+
+       wire  [10:0]   wire_dffpipe5_q;
+
+       fifo_2k_dffpipe_dm2   dffpipe5
+       ( 
+       .clock(clock),
+       .clrn(clrn),
+       .d(d),
+       .q(wire_dffpipe5_q));
+       assign
+               q = wire_dffpipe5_q;
+endmodule //fifo_2k_alt_synch_pipe_dm2
+
+
+//lpm_add_sub DEVICE_FAMILY="Cyclone" LPM_DIRECTION="SUB" LPM_WIDTH=11 dataa datab result
+//VERSION_BEGIN 5.0 cbx_cycloneii 2004:12:20:14:28:52:SJ cbx_lpm_add_sub 2005:04:12:13:30:42:SJ cbx_mgl 2005:05:19:13:51:58:SJ cbx_stratix 2005:06:02:09:53:04:SJ cbx_stratixii 2004:12:22:13:27:12:SJ  VERSION_END
+
+//synthesis_resources = lut 11 
+//synopsys translate_off
+`timescale 1 ps / 1 ps
+//synopsys translate_on
+module  fifo_2k_add_sub_a18
+       ( 
+       dataa,
+       datab,
+       result) /* synthesis synthesis_clearbox=1 */;
+       input   [10:0]  dataa;
+       input   [10:0]  datab;
+       output   [10:0]  result;
+
+       wire  [10:0]   wire_add_sub_cella_combout;
+       wire  [0:0]   wire_add_sub_cella_0cout;
+       wire  [0:0]   wire_add_sub_cella_1cout;
+       wire  [0:0]   wire_add_sub_cella_2cout;
+       wire  [0:0]   wire_add_sub_cella_3cout;
+       wire  [0:0]   wire_add_sub_cella_4cout;
+       wire  [0:0]   wire_add_sub_cella_5cout;
+       wire  [0:0]   wire_add_sub_cella_6cout;
+       wire  [0:0]   wire_add_sub_cella_7cout;
+       wire  [0:0]   wire_add_sub_cella_8cout;
+       wire  [0:0]   wire_add_sub_cella_9cout;
+       wire  [10:0]   wire_add_sub_cella_dataa;
+       wire  [10:0]   wire_add_sub_cella_datab;
+
+       cyclone_lcell   add_sub_cella_0
+       ( 
+       .cin(1'b1),
+       .combout(wire_add_sub_cella_combout[0:0]),
+       .cout(wire_add_sub_cella_0cout[0:0]),
+       .dataa(wire_add_sub_cella_dataa[0:0]),
+       .datab(wire_add_sub_cella_datab[0:0]),
+       .regout()
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_off
+       `endif
+       ,
+       .aclr(1'b0),
+       .aload(1'b0),
+       .clk(1'b1),
+       .datac(1'b1),
+       .datad(1'b1),
+       .ena(1'b1),
+       .inverta(1'b0),
+       .regcascin(1'b0),
+       .sclr(1'b0),
+       .sload(1'b0)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_on
+       `endif
+       // synopsys translate_off
+       ,
+       .cin0(),
+       .cin1(),
+       .cout0(),
+       .cout1(),
+       .devclrn(),
+       .devpor()
+       // synopsys translate_on
+       );
+       defparam
+               add_sub_cella_0.cin_used = "true",
+               add_sub_cella_0.lut_mask = "69b2",
+               add_sub_cella_0.operation_mode = "arithmetic",
+               add_sub_cella_0.sum_lutc_input = "cin",
+               add_sub_cella_0.lpm_type = "cyclone_lcell";
+       cyclone_lcell   add_sub_cella_1
+       ( 
+       .cin(wire_add_sub_cella_0cout[0:0]),
+       .combout(wire_add_sub_cella_combout[1:1]),
+       .cout(wire_add_sub_cella_1cout[0:0]),
+       .dataa(wire_add_sub_cella_dataa[1:1]),
+       .datab(wire_add_sub_cella_datab[1:1]),
+       .regout()
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_off
+       `endif
+       ,
+       .aclr(1'b0),
+       .aload(1'b0),
+       .clk(1'b1),
+       .datac(1'b1),
+       .datad(1'b1),
+       .ena(1'b1),
+       .inverta(1'b0),
+       .regcascin(1'b0),
+       .sclr(1'b0),
+       .sload(1'b0)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_on
+       `endif
+       // synopsys translate_off
+       ,
+       .cin0(),
+       .cin1(),
+       .cout0(),
+       .cout1(),
+       .devclrn(),
+       .devpor()
+       // synopsys translate_on
+       );
+       defparam
+               add_sub_cella_1.cin_used = "true",
+               add_sub_cella_1.lut_mask = "69b2",
+               add_sub_cella_1.operation_mode = "arithmetic",
+               add_sub_cella_1.sum_lutc_input = "cin",
+               add_sub_cella_1.lpm_type = "cyclone_lcell";
+       cyclone_lcell   add_sub_cella_2
+       ( 
+       .cin(wire_add_sub_cella_1cout[0:0]),
+       .combout(wire_add_sub_cella_combout[2:2]),
+       .cout(wire_add_sub_cella_2cout[0:0]),
+       .dataa(wire_add_sub_cella_dataa[2:2]),
+       .datab(wire_add_sub_cella_datab[2:2]),
+       .regout()
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_off
+       `endif
+       ,
+       .aclr(1'b0),
+       .aload(1'b0),
+       .clk(1'b1),
+       .datac(1'b1),
+       .datad(1'b1),
+       .ena(1'b1),
+       .inverta(1'b0),
+       .regcascin(1'b0),
+       .sclr(1'b0),
+       .sload(1'b0)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_on
+       `endif
+       // synopsys translate_off
+       ,
+       .cin0(),
+       .cin1(),
+       .cout0(),
+       .cout1(),
+       .devclrn(),
+       .devpor()
+       // synopsys translate_on
+       );
+       defparam
+               add_sub_cella_2.cin_used = "true",
+               add_sub_cella_2.lut_mask = "69b2",
+               add_sub_cella_2.operation_mode = "arithmetic",
+               add_sub_cella_2.sum_lutc_input = "cin",
+               add_sub_cella_2.lpm_type = "cyclone_lcell";
+       cyclone_lcell   add_sub_cella_3
+       ( 
+       .cin(wire_add_sub_cella_2cout[0:0]),
+       .combout(wire_add_sub_cella_combout[3:3]),
+       .cout(wire_add_sub_cella_3cout[0:0]),
+       .dataa(wire_add_sub_cella_dataa[3:3]),
+       .datab(wire_add_sub_cella_datab[3:3]),
+       .regout()
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_off
+       `endif
+       ,
+       .aclr(1'b0),
+       .aload(1'b0),
+       .clk(1'b1),
+       .datac(1'b1),
+       .datad(1'b1),
+       .ena(1'b1),
+       .inverta(1'b0),
+       .regcascin(1'b0),
+       .sclr(1'b0),
+       .sload(1'b0)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_on
+       `endif
+       // synopsys translate_off
+       ,
+       .cin0(),
+       .cin1(),
+       .cout0(),
+       .cout1(),
+       .devclrn(),
+       .devpor()
+       // synopsys translate_on
+       );
+       defparam
+               add_sub_cella_3.cin_used = "true",
+               add_sub_cella_3.lut_mask = "69b2",
+               add_sub_cella_3.operation_mode = "arithmetic",
+               add_sub_cella_3.sum_lutc_input = "cin",
+               add_sub_cella_3.lpm_type = "cyclone_lcell";
+       cyclone_lcell   add_sub_cella_4
+       ( 
+       .cin(wire_add_sub_cella_3cout[0:0]),
+       .combout(wire_add_sub_cella_combout[4:4]),
+       .cout(wire_add_sub_cella_4cout[0:0]),
+       .dataa(wire_add_sub_cella_dataa[4:4]),
+       .datab(wire_add_sub_cella_datab[4:4]),
+       .regout()
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_off
+       `endif
+       ,
+       .aclr(1'b0),
+       .aload(1'b0),
+       .clk(1'b1),
+       .datac(1'b1),
+       .datad(1'b1),
+       .ena(1'b1),
+       .inverta(1'b0),
+       .regcascin(1'b0),
+       .sclr(1'b0),
+       .sload(1'b0)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_on
+       `endif
+       // synopsys translate_off
+       ,
+       .cin0(),
+       .cin1(),
+       .cout0(),
+       .cout1(),
+       .devclrn(),
+       .devpor()
+       // synopsys translate_on
+       );
+       defparam
+               add_sub_cella_4.cin_used = "true",
+               add_sub_cella_4.lut_mask = "69b2",
+               add_sub_cella_4.operation_mode = "arithmetic",
+               add_sub_cella_4.sum_lutc_input = "cin",
+               add_sub_cella_4.lpm_type = "cyclone_lcell";
+       cyclone_lcell   add_sub_cella_5
+       ( 
+       .cin(wire_add_sub_cella_4cout[0:0]),
+       .combout(wire_add_sub_cella_combout[5:5]),
+       .cout(wire_add_sub_cella_5cout[0:0]),
+       .dataa(wire_add_sub_cella_dataa[5:5]),
+       .datab(wire_add_sub_cella_datab[5:5]),
+       .regout()
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_off
+       `endif
+       ,
+       .aclr(1'b0),
+       .aload(1'b0),
+       .clk(1'b1),
+       .datac(1'b1),
+       .datad(1'b1),
+       .ena(1'b1),
+       .inverta(1'b0),
+       .regcascin(1'b0),
+       .sclr(1'b0),
+       .sload(1'b0)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_on
+       `endif
+       // synopsys translate_off
+       ,
+       .cin0(),
+       .cin1(),
+       .cout0(),
+       .cout1(),
+       .devclrn(),
+       .devpor()
+       // synopsys translate_on
+       );
+       defparam
+               add_sub_cella_5.cin_used = "true",
+               add_sub_cella_5.lut_mask = "69b2",
+               add_sub_cella_5.operation_mode = "arithmetic",
+               add_sub_cella_5.sum_lutc_input = "cin",
+               add_sub_cella_5.lpm_type = "cyclone_lcell";
+       cyclone_lcell   add_sub_cella_6
+       ( 
+       .cin(wire_add_sub_cella_5cout[0:0]),
+       .combout(wire_add_sub_cella_combout[6:6]),
+       .cout(wire_add_sub_cella_6cout[0:0]),
+       .dataa(wire_add_sub_cella_dataa[6:6]),
+       .datab(wire_add_sub_cella_datab[6:6]),
+       .regout()
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_off
+       `endif
+       ,
+       .aclr(1'b0),
+       .aload(1'b0),
+       .clk(1'b1),
+       .datac(1'b1),
+       .datad(1'b1),
+       .ena(1'b1),
+       .inverta(1'b0),
+       .regcascin(1'b0),
+       .sclr(1'b0),
+       .sload(1'b0)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_on
+       `endif
+       // synopsys translate_off
+       ,
+       .cin0(),
+       .cin1(),
+       .cout0(),
+       .cout1(),
+       .devclrn(),
+       .devpor()
+       // synopsys translate_on
+       );
+       defparam
+               add_sub_cella_6.cin_used = "true",
+               add_sub_cella_6.lut_mask = "69b2",
+               add_sub_cella_6.operation_mode = "arithmetic",
+               add_sub_cella_6.sum_lutc_input = "cin",
+               add_sub_cella_6.lpm_type = "cyclone_lcell";
+       cyclone_lcell   add_sub_cella_7
+       ( 
+       .cin(wire_add_sub_cella_6cout[0:0]),
+       .combout(wire_add_sub_cella_combout[7:7]),
+       .cout(wire_add_sub_cella_7cout[0:0]),
+       .dataa(wire_add_sub_cella_dataa[7:7]),
+       .datab(wire_add_sub_cella_datab[7:7]),
+       .regout()
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_off
+       `endif
+       ,
+       .aclr(1'b0),
+       .aload(1'b0),
+       .clk(1'b1),
+       .datac(1'b1),
+       .datad(1'b1),
+       .ena(1'b1),
+       .inverta(1'b0),
+       .regcascin(1'b0),
+       .sclr(1'b0),
+       .sload(1'b0)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_on
+       `endif
+       // synopsys translate_off
+       ,
+       .cin0(),
+       .cin1(),
+       .cout0(),
+       .cout1(),
+       .devclrn(),
+       .devpor()
+       // synopsys translate_on
+       );
+       defparam
+               add_sub_cella_7.cin_used = "true",
+               add_sub_cella_7.lut_mask = "69b2",
+               add_sub_cella_7.operation_mode = "arithmetic",
+               add_sub_cella_7.sum_lutc_input = "cin",
+               add_sub_cella_7.lpm_type = "cyclone_lcell";
+       cyclone_lcell   add_sub_cella_8
+       ( 
+       .cin(wire_add_sub_cella_7cout[0:0]),
+       .combout(wire_add_sub_cella_combout[8:8]),
+       .cout(wire_add_sub_cella_8cout[0:0]),
+       .dataa(wire_add_sub_cella_dataa[8:8]),
+       .datab(wire_add_sub_cella_datab[8:8]),
+       .regout()
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_off
+       `endif
+       ,
+       .aclr(1'b0),
+       .aload(1'b0),
+       .clk(1'b1),
+       .datac(1'b1),
+       .datad(1'b1),
+       .ena(1'b1),
+       .inverta(1'b0),
+       .regcascin(1'b0),
+       .sclr(1'b0),
+       .sload(1'b0)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_on
+       `endif
+       // synopsys translate_off
+       ,
+       .cin0(),
+       .cin1(),
+       .cout0(),
+       .cout1(),
+       .devclrn(),
+       .devpor()
+       // synopsys translate_on
+       );
+       defparam
+               add_sub_cella_8.cin_used = "true",
+               add_sub_cella_8.lut_mask = "69b2",
+               add_sub_cella_8.operation_mode = "arithmetic",
+               add_sub_cella_8.sum_lutc_input = "cin",
+               add_sub_cella_8.lpm_type = "cyclone_lcell";
+       cyclone_lcell   add_sub_cella_9
+       ( 
+       .cin(wire_add_sub_cella_8cout[0:0]),
+       .combout(wire_add_sub_cella_combout[9:9]),
+       .cout(wire_add_sub_cella_9cout[0:0]),
+       .dataa(wire_add_sub_cella_dataa[9:9]),
+       .datab(wire_add_sub_cella_datab[9:9]),
+       .regout()
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_off
+       `endif
+       ,
+       .aclr(1'b0),
+       .aload(1'b0),
+       .clk(1'b1),
+       .datac(1'b1),
+       .datad(1'b1),
+       .ena(1'b1),
+       .inverta(1'b0),
+       .regcascin(1'b0),
+       .sclr(1'b0),
+       .sload(1'b0)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_on
+       `endif
+       // synopsys translate_off
+       ,
+       .cin0(),
+       .cin1(),
+       .cout0(),
+       .cout1(),
+       .devclrn(),
+       .devpor()
+       // synopsys translate_on
+       );
+       defparam
+               add_sub_cella_9.cin_used = "true",
+               add_sub_cella_9.lut_mask = "69b2",
+               add_sub_cella_9.operation_mode = "arithmetic",
+               add_sub_cella_9.sum_lutc_input = "cin",
+               add_sub_cella_9.lpm_type = "cyclone_lcell";
+       cyclone_lcell   add_sub_cella_10
+       ( 
+       .cin(wire_add_sub_cella_9cout[0:0]),
+       .combout(wire_add_sub_cella_combout[10:10]),
+       .cout(),
+       .dataa(wire_add_sub_cella_dataa[10:10]),
+       .datab(wire_add_sub_cella_datab[10:10]),
+       .regout()
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_off
+       `endif
+       ,
+       .aclr(1'b0),
+       .aload(1'b0),
+       .clk(1'b1),
+       .datac(1'b1),
+       .datad(1'b1),
+       .ena(1'b1),
+       .inverta(1'b0),
+       .regcascin(1'b0),
+       .sclr(1'b0),
+       .sload(1'b0)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_on
+       `endif
+       // synopsys translate_off
+       ,
+       .cin0(),
+       .cin1(),
+       .cout0(),
+       .cout1(),
+       .devclrn(),
+       .devpor()
+       // synopsys translate_on
+       );
+       defparam
+               add_sub_cella_10.cin_used = "true",
+               add_sub_cella_10.lut_mask = "6969",
+               add_sub_cella_10.operation_mode = "normal",
+               add_sub_cella_10.sum_lutc_input = "cin",
+               add_sub_cella_10.lpm_type = "cyclone_lcell";
+       assign
+               wire_add_sub_cella_dataa = dataa,
+               wire_add_sub_cella_datab = datab;
+       assign
+               result = wire_add_sub_cella_combout;
+endmodule //fifo_2k_add_sub_a18
+
+
+//lpm_compare DEVICE_FAMILY="Cyclone" LPM_WIDTH=11 aeb dataa datab
+//VERSION_BEGIN 5.0 cbx_cycloneii 2004:12:20:14:28:52:SJ cbx_lpm_add_sub 2005:04:12:13:30:42:SJ cbx_lpm_compare 2004:11:30:11:30:40:SJ cbx_mgl 2005:05:19:13:51:58:SJ cbx_stratix 2005:06:02:09:53:04:SJ cbx_stratixii 2004:12:22:13:27:12:SJ  VERSION_END
+
+
+//lpm_compare DEVICE_FAMILY="Cyclone" LPM_WIDTH=11 aeb dataa datab
+//VERSION_BEGIN 5.0 cbx_cycloneii 2004:12:20:14:28:52:SJ cbx_lpm_add_sub 2005:04:12:13:30:42:SJ cbx_lpm_compare 2004:11:30:11:30:40:SJ cbx_mgl 2005:05:19:13:51:58:SJ cbx_stratix 2005:06:02:09:53:04:SJ cbx_stratixii 2004:12:22:13:27:12:SJ  VERSION_END
+
+//synthesis_resources = lut 97 M4K 8 
+//synopsys translate_off
+`timescale 1 ps / 1 ps
+//synopsys translate_on
+module  fifo_2k_dcfifo_0cq
+       ( 
+       aclr,
+       data,
+       q,
+       rdclk,
+       rdempty,
+       rdreq,
+       rdusedw,
+       wrclk,
+       wrfull,
+       wrreq,
+       wrusedw) /* synthesis synthesis_clearbox=1 */
+               /* synthesis ALTERA_ATTRIBUTE="AUTO_SHIFT_REGISTER_RECOGNITION=OFF;{ -from \"rdptr_g|power_modified_counter_values\" -to \"ws_dgrp|dffpipe5|dffe6a\" }CUT=ON;{ -from \"delayed_wrptr_g\" -to \"rs_dgwp|dffpipe5|dffe6a\" }CUT=ON" */;
+       input   aclr;
+       input   [15:0]  data;
+       output   [15:0]  q;
+       input   rdclk;
+       output   rdempty;
+       input   rdreq;
+       output   [10:0]  rdusedw;
+       input   wrclk;
+       output   wrfull;
+       input   wrreq;
+       output   [10:0]  wrusedw;
+
+       wire  [10:0]   wire_rdptr_g_gray2bin_bin;
+       wire  [10:0]   wire_rs_dgwp_gray2bin_bin;
+       wire  [10:0]   wire_wrptr_g_gray2bin_bin;
+       wire  [10:0]   wire_ws_dgrp_gray2bin_bin;
+       wire  [10:0]   wire_rdptr_g_q;
+       wire  [10:0]   wire_rdptr_g1p_q;
+       wire  [10:0]   wire_wrptr_g1p_q;
+       wire  [15:0]   wire_fifo_ram_q_b;
+       reg     [10:0]  delayed_wrptr_g;
+       reg     [10:0]  wrptr_g;
+       wire  [10:0]   wire_rs_brp_q;
+       wire  [10:0]   wire_rs_bwp_q;
+       wire  [10:0]   wire_rs_dgwp_q;
+       wire  [10:0]   wire_ws_brp_q;
+       wire  [10:0]   wire_ws_bwp_q;
+       wire  [10:0]   wire_ws_dgrp_q;
+       wire  [10:0]   wire_rdusedw_sub_result;
+       wire  [10:0]   wire_wrusedw_sub_result;
+       reg     wire_rdempty_eq_comp_aeb_int;
+       wire    wire_rdempty_eq_comp_aeb;
+       wire    [10:0]  wire_rdempty_eq_comp_dataa;
+       wire    [10:0]  wire_rdempty_eq_comp_datab;
+       reg     wire_wrfull_eq_comp_aeb_int;
+       wire    wire_wrfull_eq_comp_aeb;
+       wire    [10:0]  wire_wrfull_eq_comp_dataa;
+       wire    [10:0]  wire_wrfull_eq_comp_datab;
+       wire  int_rdempty;
+       wire  int_wrfull;
+       wire  valid_rdreq;
+       wire  valid_wrreq;
+
+       fifo_2k_a_gray2bin_8m4   rdptr_g_gray2bin
+       ( 
+       .bin(wire_rdptr_g_gray2bin_bin),
+       .gray(wire_rdptr_g_q));
+       fifo_2k_a_gray2bin_8m4   rs_dgwp_gray2bin
+       ( 
+       .bin(wire_rs_dgwp_gray2bin_bin),
+       .gray(wire_rs_dgwp_q));
+       fifo_2k_a_gray2bin_8m4   wrptr_g_gray2bin
+       ( 
+       .bin(wire_wrptr_g_gray2bin_bin),
+       .gray(wrptr_g));
+       fifo_2k_a_gray2bin_8m4   ws_dgrp_gray2bin
+       ( 
+       .bin(wire_ws_dgrp_gray2bin_bin),
+       .gray(wire_ws_dgrp_q));
+       fifo_2k_a_graycounter_726   rdptr_g
+       ( 
+       .aclr(aclr),
+       .clock(rdclk),
+       .cnt_en(valid_rdreq),
+       .q(wire_rdptr_g_q));
+       fifo_2k_a_graycounter_2r6   rdptr_g1p
+       ( 
+       .aclr(aclr),
+       .clock(rdclk),
+       .cnt_en(valid_rdreq),
+       .q(wire_rdptr_g1p_q));
+       fifo_2k_a_graycounter_2r6   wrptr_g1p
+       ( 
+       .aclr(aclr),
+       .clock(wrclk),
+       .cnt_en(valid_wrreq),
+       .q(wire_wrptr_g1p_q));
+       fifo_2k_altsyncram_6pl   fifo_ram
+       ( 
+       .address_a(wrptr_g),
+       .address_b(((wire_rdptr_g_q & {11{int_rdempty}}) | (wire_rdptr_g1p_q & {11{(~ int_rdempty)}}))),
+       .clock0(wrclk),
+       .clock1(rdclk),
+       .clocken1((valid_rdreq | int_rdempty)),
+       .data_a(data),
+       .q_b(wire_fifo_ram_q_b),
+       .wren_a(valid_wrreq));
+       // synopsys translate_off
+       initial
+               delayed_wrptr_g = 0;
+       // synopsys translate_on
+       always @ ( posedge wrclk or  posedge aclr)
+               if (aclr == 1'b1) delayed_wrptr_g <= 11'b0;
+               else  delayed_wrptr_g <= wrptr_g;
+       // synopsys translate_off
+       initial
+               wrptr_g = 0;
+       // synopsys translate_on
+       always @ ( posedge wrclk or  posedge aclr)
+               if (aclr == 1'b1) wrptr_g <= 11'b0;
+               else if  (valid_wrreq == 1'b1)   wrptr_g <= wire_wrptr_g1p_q;
+       fifo_2k_dffpipe_ab3   rs_brp
+       ( 
+       .clock(rdclk),
+       .clrn((~ aclr)),
+       .d(wire_rdptr_g_gray2bin_bin),
+       .q(wire_rs_brp_q));
+       fifo_2k_dffpipe_ab3   rs_bwp
+       ( 
+       .clock(rdclk),
+       .clrn((~ aclr)),
+       .d(wire_rs_dgwp_gray2bin_bin),
+       .q(wire_rs_bwp_q));
+       fifo_2k_alt_synch_pipe_dm2   rs_dgwp
+       ( 
+       .clock(rdclk),
+       .clrn((~ aclr)),
+       .d(delayed_wrptr_g),
+       .q(wire_rs_dgwp_q));
+       fifo_2k_dffpipe_ab3   ws_brp
+       ( 
+       .clock(wrclk),
+       .clrn((~ aclr)),
+       .d(wire_ws_dgrp_gray2bin_bin),
+       .q(wire_ws_brp_q));
+       fifo_2k_dffpipe_ab3   ws_bwp
+       ( 
+       .clock(wrclk),
+       .clrn((~ aclr)),
+       .d(wire_wrptr_g_gray2bin_bin),
+       .q(wire_ws_bwp_q));
+       fifo_2k_alt_synch_pipe_dm2   ws_dgrp
+       ( 
+       .clock(wrclk),
+       .clrn((~ aclr)),
+       .d(wire_rdptr_g_q),
+       .q(wire_ws_dgrp_q));
+       fifo_2k_add_sub_a18   rdusedw_sub
+       ( 
+       .dataa(wire_rs_bwp_q),
+       .datab(wire_rs_brp_q),
+       .result(wire_rdusedw_sub_result));
+       fifo_2k_add_sub_a18   wrusedw_sub
+       ( 
+       .dataa(wire_ws_bwp_q),
+       .datab(wire_ws_brp_q),
+       .result(wire_wrusedw_sub_result));
+       always @(wire_rdempty_eq_comp_dataa or wire_rdempty_eq_comp_datab)
+               if (wire_rdempty_eq_comp_dataa == wire_rdempty_eq_comp_datab) 
+                       begin
+                               wire_rdempty_eq_comp_aeb_int = 1'b1;
+                       end
+               else
+                       begin
+                               wire_rdempty_eq_comp_aeb_int = 1'b0;
+                       end
+       assign
+               wire_rdempty_eq_comp_aeb = wire_rdempty_eq_comp_aeb_int;
+       assign
+               wire_rdempty_eq_comp_dataa = wire_rs_dgwp_q,
+               wire_rdempty_eq_comp_datab = wire_rdptr_g_q;
+       always @(wire_wrfull_eq_comp_dataa or wire_wrfull_eq_comp_datab)
+               if (wire_wrfull_eq_comp_dataa == wire_wrfull_eq_comp_datab) 
+                       begin
+                               wire_wrfull_eq_comp_aeb_int = 1'b1;
+                       end
+               else
+                       begin
+                               wire_wrfull_eq_comp_aeb_int = 1'b0;
+                       end
+       assign
+               wire_wrfull_eq_comp_aeb = wire_wrfull_eq_comp_aeb_int;
+       assign
+               wire_wrfull_eq_comp_dataa = wire_ws_dgrp_q,
+               wire_wrfull_eq_comp_datab = wire_wrptr_g1p_q;
+       assign
+               int_rdempty = wire_rdempty_eq_comp_aeb,
+               int_wrfull = wire_wrfull_eq_comp_aeb,
+               q = wire_fifo_ram_q_b,
+               rdempty = int_rdempty,
+               rdusedw = wire_rdusedw_sub_result,
+               valid_rdreq = rdreq,
+               valid_wrreq = wrreq,
+               wrfull = int_wrfull,
+               wrusedw = wire_wrusedw_sub_result;
+endmodule //fifo_2k_dcfifo_0cq
+//VALID FILE
+
+
+// synopsys translate_off
+`timescale 1 ps / 1 ps
+// synopsys translate_on
+module fifo_2k (
+       data,
+       wrreq,
+       rdreq,
+       rdclk,
+       wrclk,
+       aclr,
+       q,
+       rdempty,
+       rdusedw,
+       wrfull,
+       wrusedw)/* synthesis synthesis_clearbox = 1 */;
+
+       input   [15:0]  data;
+       input     wrreq;
+       input     rdreq;
+       input     rdclk;
+       input     wrclk;
+       input     aclr;
+       output  [15:0]  q;
+       output    rdempty;
+       output  [10:0]  rdusedw;
+       output    wrfull;
+       output  [10:0]  wrusedw;
+
+       wire  sub_wire0;
+       wire [10:0] sub_wire1;
+       wire  sub_wire2;
+       wire [15:0] sub_wire3;
+       wire [10:0] sub_wire4;
+       wire  rdempty = sub_wire0;
+       wire [10:0] wrusedw = sub_wire1[10:0];
+       wire  wrfull = sub_wire2;
+       wire [15:0] q = sub_wire3[15:0];
+       wire [10:0] rdusedw = sub_wire4[10:0];
+
+       fifo_2k_dcfifo_0cq      fifo_2k_dcfifo_0cq_component (
+                               .wrclk (wrclk),
+                               .rdreq (rdreq),
+                               .aclr (aclr),
+                               .rdclk (rdclk),
+                               .wrreq (wrreq),
+                               .data (data),
+                               .rdempty (sub_wire0),
+                               .wrusedw (sub_wire1),
+                               .wrfull (sub_wire2),
+                               .q (sub_wire3),
+                               .rdusedw (sub_wire4));
+
+endmodule
+
+// ============================================================
+// CNX file retrieval info
+// ============================================================
+// Retrieval info: PRIVATE: Width NUMERIC "16"
+// Retrieval info: PRIVATE: Depth NUMERIC "2048"
+// Retrieval info: PRIVATE: Clock NUMERIC "4"
+// Retrieval info: PRIVATE: CLOCKS_ARE_SYNCHRONIZED NUMERIC "0"
+// Retrieval info: PRIVATE: Full NUMERIC "1"
+// Retrieval info: PRIVATE: Empty NUMERIC "1"
+// Retrieval info: PRIVATE: UsedW NUMERIC "1"
+// Retrieval info: PRIVATE: AlmostFull NUMERIC "0"
+// Retrieval info: PRIVATE: AlmostEmpty NUMERIC "0"
+// Retrieval info: PRIVATE: AlmostFullThr NUMERIC "-1"
+// Retrieval info: PRIVATE: AlmostEmptyThr NUMERIC "-1"
+// Retrieval info: PRIVATE: sc_aclr NUMERIC "0"
+// Retrieval info: PRIVATE: sc_sclr NUMERIC "0"
+// Retrieval info: PRIVATE: rsFull NUMERIC "0"
+// Retrieval info: PRIVATE: rsEmpty NUMERIC "1"
+// Retrieval info: PRIVATE: rsUsedW NUMERIC "1"
+// Retrieval info: PRIVATE: wsFull NUMERIC "1"
+// Retrieval info: PRIVATE: wsEmpty NUMERIC "0"
+// Retrieval info: PRIVATE: wsUsedW NUMERIC "1"
+// Retrieval info: PRIVATE: dc_aclr NUMERIC "1"
+// Retrieval info: PRIVATE: LegacyRREQ NUMERIC "0"
+// Retrieval info: PRIVATE: RAM_BLOCK_TYPE NUMERIC "0"
+// Retrieval info: PRIVATE: MAX_DEPTH_BY_9 NUMERIC "0"
+// Retrieval info: PRIVATE: LE_BasedFIFO NUMERIC "0"
+// Retrieval info: PRIVATE: Optimize NUMERIC "2"
+// Retrieval info: PRIVATE: OVERFLOW_CHECKING NUMERIC "1"
+// Retrieval info: PRIVATE: UNDERFLOW_CHECKING NUMERIC "1"
+// Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING "Cyclone"
+// Retrieval info: CONSTANT: LPM_WIDTH NUMERIC "16"
+// Retrieval info: CONSTANT: LPM_NUMWORDS NUMERIC "2048"
+// Retrieval info: CONSTANT: LPM_WIDTHU NUMERIC "11"
+// Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone"
+// Retrieval info: CONSTANT: CLOCKS_ARE_SYNCHRONIZED STRING "FALSE"
+// Retrieval info: CONSTANT: LPM_TYPE STRING "dcfifo"
+// Retrieval info: CONSTANT: LPM_SHOWAHEAD STRING "ON"
+// Retrieval info: CONSTANT: OVERFLOW_CHECKING STRING "OFF"
+// Retrieval info: CONSTANT: UNDERFLOW_CHECKING STRING "OFF"
+// Retrieval info: CONSTANT: USE_EAB STRING "ON"
+// Retrieval info: CONSTANT: ADD_RAM_OUTPUT_REGISTER STRING "OFF"
+// Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone"
+// Retrieval info: USED_PORT: data 0 0 16 0 INPUT NODEFVAL data[15..0]
+// Retrieval info: USED_PORT: q 0 0 16 0 OUTPUT NODEFVAL q[15..0]
+// Retrieval info: USED_PORT: wrreq 0 0 0 0 INPUT NODEFVAL wrreq
+// Retrieval info: USED_PORT: rdreq 0 0 0 0 INPUT NODEFVAL rdreq
+// Retrieval info: USED_PORT: rdclk 0 0 0 0 INPUT NODEFVAL rdclk
+// Retrieval info: USED_PORT: wrclk 0 0 0 0 INPUT NODEFVAL wrclk
+// Retrieval info: USED_PORT: rdempty 0 0 0 0 OUTPUT NODEFVAL rdempty
+// Retrieval info: USED_PORT: rdusedw 0 0 11 0 OUTPUT NODEFVAL rdusedw[10..0]
+// Retrieval info: USED_PORT: wrfull 0 0 0 0 OUTPUT NODEFVAL wrfull
+// Retrieval info: USED_PORT: wrusedw 0 0 11 0 OUTPUT NODEFVAL wrusedw[10..0]
+// Retrieval info: USED_PORT: aclr 0 0 0 0 INPUT GND aclr
+// Retrieval info: CONNECT: @data 0 0 16 0 data 0 0 16 0
+// Retrieval info: CONNECT: q 0 0 16 0 @q 0 0 16 0
+// Retrieval info: CONNECT: @wrreq 0 0 0 0 wrreq 0 0 0 0
+// Retrieval info: CONNECT: @rdreq 0 0 0 0 rdreq 0 0 0 0
+// Retrieval info: CONNECT: @rdclk 0 0 0 0 rdclk 0 0 0 0
+// Retrieval info: CONNECT: @wrclk 0 0 0 0 wrclk 0 0 0 0
+// Retrieval info: CONNECT: rdempty 0 0 0 0 @rdempty 0 0 0 0
+// Retrieval info: CONNECT: rdusedw 0 0 11 0 @rdusedw 0 0 11 0
+// Retrieval info: CONNECT: wrfull 0 0 0 0 @wrfull 0 0 0 0
+// Retrieval info: CONNECT: wrusedw 0 0 11 0 @wrusedw 0 0 11 0
+// Retrieval info: CONNECT: @aclr 0 0 0 0 aclr 0 0 0 0
+// Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all
+// Retrieval info: GEN_FILE: TYPE_NORMAL fifo_2k.v TRUE
+// Retrieval info: GEN_FILE: TYPE_NORMAL fifo_2k.inc FALSE
+// Retrieval info: GEN_FILE: TYPE_NORMAL fifo_2k.cmp FALSE
+// Retrieval info: GEN_FILE: TYPE_NORMAL fifo_2k.bsf FALSE
+// Retrieval info: GEN_FILE: TYPE_NORMAL fifo_2k_inst.v FALSE
+// Retrieval info: GEN_FILE: TYPE_NORMAL fifo_2k_bb.v TRUE
+// Retrieval info: GEN_FILE: TYPE_NORMAL fifo_2k_waveforms.html TRUE
+// Retrieval info: GEN_FILE: TYPE_NORMAL fifo_2k_wave*.jpg FALSE
diff --git a/usrp/fpga/megacells/fifo_2k_bb.v b/usrp/fpga/megacells/fifo_2k_bb.v
new file mode 100644 (file)
index 0000000..3fcc2a4
--- /dev/null
@@ -0,0 +1,131 @@
+// megafunction wizard: %FIFO%VBB%
+// GENERATION: STANDARD
+// VERSION: WM1.0
+// MODULE: dcfifo 
+
+// ============================================================
+// File Name: fifo_2k.v
+// Megafunction Name(s):
+//                     dcfifo
+// ============================================================
+// ************************************************************
+// THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE!
+//
+// 5.0 Build 168 06/22/2005 SP 1 SJ Web Edition
+// ************************************************************
+
+//Copyright (C) 1991-2005 Altera Corporation
+//Your use of Altera Corporation's design tools, logic functions 
+//and other software and tools, and its AMPP partner logic       
+//functions, and any output files any of the foregoing           
+//(including device programming or simulation files), and any    
+//associated documentation or information are expressly subject  
+//to the terms and conditions of the Altera Program License      
+//Subscription Agreement, Altera MegaCore Function License       
+//Agreement, or other applicable license agreement, including,   
+//without limitation, that your use is for the sole purpose of   
+//programming logic devices manufactured by Altera and sold by   
+//Altera or its authorized distributors.  Please refer to the    
+//applicable agreement for further details.
+
+module fifo_2k (
+       data,
+       wrreq,
+       rdreq,
+       rdclk,
+       wrclk,
+       aclr,
+       q,
+       rdempty,
+       rdusedw,
+       wrfull,
+       wrusedw)/* synthesis synthesis_clearbox = 1 */;
+
+       input   [15:0]  data;
+       input     wrreq;
+       input     rdreq;
+       input     rdclk;
+       input     wrclk;
+       input     aclr;
+       output  [15:0]  q;
+       output    rdempty;
+       output  [10:0]  rdusedw;
+       output    wrfull;
+       output  [10:0]  wrusedw;
+
+endmodule
+
+// ============================================================
+// CNX file retrieval info
+// ============================================================
+// Retrieval info: PRIVATE: Width NUMERIC "16"
+// Retrieval info: PRIVATE: Depth NUMERIC "2048"
+// Retrieval info: PRIVATE: Clock NUMERIC "4"
+// Retrieval info: PRIVATE: CLOCKS_ARE_SYNCHRONIZED NUMERIC "0"
+// Retrieval info: PRIVATE: Full NUMERIC "1"
+// Retrieval info: PRIVATE: Empty NUMERIC "1"
+// Retrieval info: PRIVATE: UsedW NUMERIC "1"
+// Retrieval info: PRIVATE: AlmostFull NUMERIC "0"
+// Retrieval info: PRIVATE: AlmostEmpty NUMERIC "0"
+// Retrieval info: PRIVATE: AlmostFullThr NUMERIC "-1"
+// Retrieval info: PRIVATE: AlmostEmptyThr NUMERIC "-1"
+// Retrieval info: PRIVATE: sc_aclr NUMERIC "0"
+// Retrieval info: PRIVATE: sc_sclr NUMERIC "0"
+// Retrieval info: PRIVATE: rsFull NUMERIC "0"
+// Retrieval info: PRIVATE: rsEmpty NUMERIC "1"
+// Retrieval info: PRIVATE: rsUsedW NUMERIC "1"
+// Retrieval info: PRIVATE: wsFull NUMERIC "1"
+// Retrieval info: PRIVATE: wsEmpty NUMERIC "0"
+// Retrieval info: PRIVATE: wsUsedW NUMERIC "1"
+// Retrieval info: PRIVATE: dc_aclr NUMERIC "1"
+// Retrieval info: PRIVATE: LegacyRREQ NUMERIC "0"
+// Retrieval info: PRIVATE: RAM_BLOCK_TYPE NUMERIC "0"
+// Retrieval info: PRIVATE: MAX_DEPTH_BY_9 NUMERIC "0"
+// Retrieval info: PRIVATE: LE_BasedFIFO NUMERIC "0"
+// Retrieval info: PRIVATE: Optimize NUMERIC "2"
+// Retrieval info: PRIVATE: OVERFLOW_CHECKING NUMERIC "1"
+// Retrieval info: PRIVATE: UNDERFLOW_CHECKING NUMERIC "1"
+// Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING "Cyclone"
+// Retrieval info: CONSTANT: LPM_WIDTH NUMERIC "16"
+// Retrieval info: CONSTANT: LPM_NUMWORDS NUMERIC "2048"
+// Retrieval info: CONSTANT: LPM_WIDTHU NUMERIC "11"
+// Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone"
+// Retrieval info: CONSTANT: CLOCKS_ARE_SYNCHRONIZED STRING "FALSE"
+// Retrieval info: CONSTANT: LPM_TYPE STRING "dcfifo"
+// Retrieval info: CONSTANT: LPM_SHOWAHEAD STRING "ON"
+// Retrieval info: CONSTANT: OVERFLOW_CHECKING STRING "OFF"
+// Retrieval info: CONSTANT: UNDERFLOW_CHECKING STRING "OFF"
+// Retrieval info: CONSTANT: USE_EAB STRING "ON"
+// Retrieval info: CONSTANT: ADD_RAM_OUTPUT_REGISTER STRING "OFF"
+// Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone"
+// Retrieval info: USED_PORT: data 0 0 16 0 INPUT NODEFVAL data[15..0]
+// Retrieval info: USED_PORT: q 0 0 16 0 OUTPUT NODEFVAL q[15..0]
+// Retrieval info: USED_PORT: wrreq 0 0 0 0 INPUT NODEFVAL wrreq
+// Retrieval info: USED_PORT: rdreq 0 0 0 0 INPUT NODEFVAL rdreq
+// Retrieval info: USED_PORT: rdclk 0 0 0 0 INPUT NODEFVAL rdclk
+// Retrieval info: USED_PORT: wrclk 0 0 0 0 INPUT NODEFVAL wrclk
+// Retrieval info: USED_PORT: rdempty 0 0 0 0 OUTPUT NODEFVAL rdempty
+// Retrieval info: USED_PORT: rdusedw 0 0 11 0 OUTPUT NODEFVAL rdusedw[10..0]
+// Retrieval info: USED_PORT: wrfull 0 0 0 0 OUTPUT NODEFVAL wrfull
+// Retrieval info: USED_PORT: wrusedw 0 0 11 0 OUTPUT NODEFVAL wrusedw[10..0]
+// Retrieval info: USED_PORT: aclr 0 0 0 0 INPUT GND aclr
+// Retrieval info: CONNECT: @data 0 0 16 0 data 0 0 16 0
+// Retrieval info: CONNECT: q 0 0 16 0 @q 0 0 16 0
+// Retrieval info: CONNECT: @wrreq 0 0 0 0 wrreq 0 0 0 0
+// Retrieval info: CONNECT: @rdreq 0 0 0 0 rdreq 0 0 0 0
+// Retrieval info: CONNECT: @rdclk 0 0 0 0 rdclk 0 0 0 0
+// Retrieval info: CONNECT: @wrclk 0 0 0 0 wrclk 0 0 0 0
+// Retrieval info: CONNECT: rdempty 0 0 0 0 @rdempty 0 0 0 0
+// Retrieval info: CONNECT: rdusedw 0 0 11 0 @rdusedw 0 0 11 0
+// Retrieval info: CONNECT: wrfull 0 0 0 0 @wrfull 0 0 0 0
+// Retrieval info: CONNECT: wrusedw 0 0 11 0 @wrusedw 0 0 11 0
+// Retrieval info: CONNECT: @aclr 0 0 0 0 aclr 0 0 0 0
+// Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all
+// Retrieval info: GEN_FILE: TYPE_NORMAL fifo_2k.v TRUE
+// Retrieval info: GEN_FILE: TYPE_NORMAL fifo_2k.inc FALSE
+// Retrieval info: GEN_FILE: TYPE_NORMAL fifo_2k.cmp FALSE
+// Retrieval info: GEN_FILE: TYPE_NORMAL fifo_2k.bsf FALSE
+// Retrieval info: GEN_FILE: TYPE_NORMAL fifo_2k_inst.v FALSE
+// Retrieval info: GEN_FILE: TYPE_NORMAL fifo_2k_bb.v TRUE
+// Retrieval info: GEN_FILE: TYPE_NORMAL fifo_2k_waveforms.html TRUE
+// Retrieval info: GEN_FILE: TYPE_NORMAL fifo_2k_wave*.jpg FALSE
diff --git a/usrp/fpga/megacells/fifo_4k.v b/usrp/fpga/megacells/fifo_4k.v
new file mode 100644 (file)
index 0000000..a5ab466
--- /dev/null
@@ -0,0 +1,3495 @@
+// megafunction wizard: %FIFO%CBX%
+// GENERATION: STANDARD
+// VERSION: WM1.0
+// MODULE: dcfifo 
+
+// ============================================================
+// File Name: fifo_4k.v
+// Megafunction Name(s):
+//                     dcfifo
+// ============================================================
+// ************************************************************
+// THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE!
+//
+// 5.0 Build 168 06/22/2005 SP 1 SJ Web Edition
+// ************************************************************
+
+
+//Copyright (C) 1991-2005 Altera Corporation
+//Your use of Altera Corporation's design tools, logic functions 
+//and other software and tools, and its AMPP partner logic       
+//functions, and any output files any of the foregoing           
+//(including device programming or simulation files), and any    
+//associated documentation or information are expressly subject  
+//to the terms and conditions of the Altera Program License      
+//Subscription Agreement, Altera MegaCore Function License       
+//Agreement, or other applicable license agreement, including,   
+//without limitation, that your use is for the sole purpose of   
+//programming logic devices manufactured by Altera and sold by   
+//Altera or its authorized distributors.  Please refer to the    
+//applicable agreement for further details.
+
+
+//dcfifo ADD_RAM_OUTPUT_REGISTER="OFF" CLOCKS_ARE_SYNCHRONIZED="FALSE" DEVICE_FAMILY="Cyclone" LPM_NUMWORDS=4096 LPM_SHOWAHEAD="ON" LPM_WIDTH=16 LPM_WIDTHU=12 OVERFLOW_CHECKING="OFF" UNDERFLOW_CHECKING="OFF" USE_EAB="ON" aclr data q rdclk rdempty rdreq rdusedw wrclk wrfull wrreq wrusedw
+//VERSION_BEGIN 5.0 cbx_a_gray2bin 2004:03:06:00:52:20:SJ cbx_a_graycounter 2004:10:01:12:13:16:SJ cbx_altdpram 2004:11:30:11:29:56:SJ cbx_altsyncram 2005:03:24:13:58:56:SJ cbx_cycloneii 2004:12:20:14:28:52:SJ cbx_dcfifo 2005:03:07:17:11:14:SJ cbx_fifo_common 2004:12:13:14:26:24:SJ cbx_flex10ke 2002:10:18:16:54:38:SJ cbx_lpm_add_sub 2005:04:12:13:30:42:SJ cbx_lpm_compare 2004:11:30:11:30:40:SJ cbx_lpm_counter 2005:02:02:04:37:10:SJ cbx_lpm_decode 2004:12:13:14:19:12:SJ cbx_lpm_mux 2004:12:13:14:16:38:SJ cbx_mgl 2005:05:19:13:51:58:SJ cbx_scfifo 2005:03:10:10:52:20:SJ cbx_stratix 2005:06:02:09:53:04:SJ cbx_stratixii 2004:12:22:13:27:12:SJ cbx_util_mgl 2005:04:04:13:50:06:SJ  VERSION_END
+
+
+//a_gray2bin device_family="Cyclone" WIDTH=12 bin gray
+//VERSION_BEGIN 5.0 cbx_a_gray2bin 2004:03:06:00:52:20:SJ cbx_mgl 2005:05:19:13:51:58:SJ  VERSION_END
+
+//synthesis_resources = 
+//synopsys translate_off
+`timescale 1 ps / 1 ps
+//synopsys translate_on
+module  fifo_4k_a_gray2bin_9m4
+       ( 
+       bin,
+       gray) /* synthesis synthesis_clearbox=1 */;
+       output   [11:0]  bin;
+       input   [11:0]  gray;
+
+       wire  xor0;
+       wire  xor1;
+       wire  xor10;
+       wire  xor2;
+       wire  xor3;
+       wire  xor4;
+       wire  xor5;
+       wire  xor6;
+       wire  xor7;
+       wire  xor8;
+       wire  xor9;
+
+       assign
+               bin = {gray[11], xor10, xor9, xor8, xor7, xor6, xor5, xor4, xor3, xor2, xor1, xor0},
+               xor0 = (gray[0] ^ xor1),
+               xor1 = (gray[1] ^ xor2),
+               xor10 = (gray[11] ^ gray[10]),
+               xor2 = (gray[2] ^ xor3),
+               xor3 = (gray[3] ^ xor4),
+               xor4 = (gray[4] ^ xor5),
+               xor5 = (gray[5] ^ xor6),
+               xor6 = (gray[6] ^ xor7),
+               xor7 = (gray[7] ^ xor8),
+               xor8 = (gray[8] ^ xor9),
+               xor9 = (gray[9] ^ xor10);
+endmodule //fifo_4k_a_gray2bin_9m4
+
+
+//a_graycounter DEVICE_FAMILY="Cyclone" WIDTH=12 aclr clock cnt_en q
+//VERSION_BEGIN 5.0 cbx_a_gray2bin 2004:03:06:00:52:20:SJ cbx_a_graycounter 2004:10:01:12:13:16:SJ cbx_cycloneii 2004:12:20:14:28:52:SJ cbx_flex10ke 2002:10:18:16:54:38:SJ cbx_mgl 2005:05:19:13:51:58:SJ cbx_stratix 2005:06:02:09:53:04:SJ cbx_stratixii 2004:12:22:13:27:12:SJ  VERSION_END
+
+//synthesis_resources = lut 13 
+//synopsys translate_off
+`timescale 1 ps / 1 ps
+//synopsys translate_on
+module  fifo_4k_a_graycounter_826
+       ( 
+       aclr,
+       clock,
+       cnt_en,
+       q) /* synthesis synthesis_clearbox=1 */;
+       input   aclr;
+       input   clock;
+       input   cnt_en;
+       output   [11:0]  q;
+
+       wire  [0:0]   wire_countera_0cout;
+       wire  [0:0]   wire_countera_1cout;
+       wire  [0:0]   wire_countera_2cout;
+       wire  [0:0]   wire_countera_3cout;
+       wire  [0:0]   wire_countera_4cout;
+       wire  [0:0]   wire_countera_5cout;
+       wire  [0:0]   wire_countera_6cout;
+       wire  [0:0]   wire_countera_7cout;
+       wire  [0:0]   wire_countera_8cout;
+       wire  [0:0]   wire_countera_9cout;
+       wire  [0:0]   wire_countera_10cout;
+       wire  [11:0]   wire_countera_regout;
+       wire  wire_parity_cout;
+       wire  wire_parity_regout;
+       wire  [11:0]  power_modified_counter_values;
+       wire sclr;
+       wire updown;
+
+       cyclone_lcell   countera_0
+       ( 
+       .aclr(aclr),
+       .cin(wire_parity_cout),
+       .clk(clock),
+       .combout(),
+       .cout(wire_countera_0cout[0:0]),
+       .dataa(cnt_en),
+       .datab(wire_countera_regout[0:0]),
+       .ena(1'b1),
+       .regout(wire_countera_regout[0:0]),
+       .sclr(sclr)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_off
+       `endif
+       ,
+       .aload(1'b0),
+       .datac(1'b1),
+       .datad(1'b1),
+       .inverta(1'b0),
+       .regcascin(1'b0),
+       .sload(1'b0)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_on
+       `endif
+       // synopsys translate_off
+       ,
+       .cin0(),
+       .cin1(),
+       .cout0(),
+       .cout1(),
+       .devclrn(),
+       .devpor()
+       // synopsys translate_on
+       );
+       defparam
+               countera_0.cin_used = "true",
+               countera_0.lut_mask = "c6a0",
+               countera_0.operation_mode = "arithmetic",
+               countera_0.sum_lutc_input = "cin",
+               countera_0.synch_mode = "on",
+               countera_0.lpm_type = "cyclone_lcell";
+       cyclone_lcell   countera_1
+       ( 
+       .aclr(aclr),
+       .cin(wire_countera_0cout[0:0]),
+       .clk(clock),
+       .combout(),
+       .cout(wire_countera_1cout[0:0]),
+       .dataa(power_modified_counter_values[0]),
+       .datab(power_modified_counter_values[1]),
+       .ena(1'b1),
+       .regout(wire_countera_regout[1:1]),
+       .sclr(sclr)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_off
+       `endif
+       ,
+       .aload(1'b0),
+       .datac(1'b1),
+       .datad(1'b1),
+       .inverta(1'b0),
+       .regcascin(1'b0),
+       .sload(1'b0)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_on
+       `endif
+       // synopsys translate_off
+       ,
+       .cin0(),
+       .cin1(),
+       .cout0(),
+       .cout1(),
+       .devclrn(),
+       .devpor()
+       // synopsys translate_on
+       );
+       defparam
+               countera_1.cin_used = "true",
+               countera_1.lut_mask = "6c50",
+               countera_1.operation_mode = "arithmetic",
+               countera_1.sum_lutc_input = "cin",
+               countera_1.synch_mode = "on",
+               countera_1.lpm_type = "cyclone_lcell";
+       cyclone_lcell   countera_2
+       ( 
+       .aclr(aclr),
+       .cin(wire_countera_1cout[0:0]),
+       .clk(clock),
+       .combout(),
+       .cout(wire_countera_2cout[0:0]),
+       .dataa(power_modified_counter_values[1]),
+       .datab(power_modified_counter_values[2]),
+       .ena(1'b1),
+       .regout(wire_countera_regout[2:2]),
+       .sclr(sclr)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_off
+       `endif
+       ,
+       .aload(1'b0),
+       .datac(1'b1),
+       .datad(1'b1),
+       .inverta(1'b0),
+       .regcascin(1'b0),
+       .sload(1'b0)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_on
+       `endif
+       // synopsys translate_off
+       ,
+       .cin0(),
+       .cin1(),
+       .cout0(),
+       .cout1(),
+       .devclrn(),
+       .devpor()
+       // synopsys translate_on
+       );
+       defparam
+               countera_2.cin_used = "true",
+               countera_2.lut_mask = "6c50",
+               countera_2.operation_mode = "arithmetic",
+               countera_2.sum_lutc_input = "cin",
+               countera_2.synch_mode = "on",
+               countera_2.lpm_type = "cyclone_lcell";
+       cyclone_lcell   countera_3
+       ( 
+       .aclr(aclr),
+       .cin(wire_countera_2cout[0:0]),
+       .clk(clock),
+       .combout(),
+       .cout(wire_countera_3cout[0:0]),
+       .dataa(power_modified_counter_values[2]),
+       .datab(power_modified_counter_values[3]),
+       .ena(1'b1),
+       .regout(wire_countera_regout[3:3]),
+       .sclr(sclr)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_off
+       `endif
+       ,
+       .aload(1'b0),
+       .datac(1'b1),
+       .datad(1'b1),
+       .inverta(1'b0),
+       .regcascin(1'b0),
+       .sload(1'b0)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_on
+       `endif
+       // synopsys translate_off
+       ,
+       .cin0(),
+       .cin1(),
+       .cout0(),
+       .cout1(),
+       .devclrn(),
+       .devpor()
+       // synopsys translate_on
+       );
+       defparam
+               countera_3.cin_used = "true",
+               countera_3.lut_mask = "6c50",
+               countera_3.operation_mode = "arithmetic",
+               countera_3.sum_lutc_input = "cin",
+               countera_3.synch_mode = "on",
+               countera_3.lpm_type = "cyclone_lcell";
+       cyclone_lcell   countera_4
+       ( 
+       .aclr(aclr),
+       .cin(wire_countera_3cout[0:0]),
+       .clk(clock),
+       .combout(),
+       .cout(wire_countera_4cout[0:0]),
+       .dataa(power_modified_counter_values[3]),
+       .datab(power_modified_counter_values[4]),
+       .ena(1'b1),
+       .regout(wire_countera_regout[4:4]),
+       .sclr(sclr)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_off
+       `endif
+       ,
+       .aload(1'b0),
+       .datac(1'b1),
+       .datad(1'b1),
+       .inverta(1'b0),
+       .regcascin(1'b0),
+       .sload(1'b0)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_on
+       `endif
+       // synopsys translate_off
+       ,
+       .cin0(),
+       .cin1(),
+       .cout0(),
+       .cout1(),
+       .devclrn(),
+       .devpor()
+       // synopsys translate_on
+       );
+       defparam
+               countera_4.cin_used = "true",
+               countera_4.lut_mask = "6c50",
+               countera_4.operation_mode = "arithmetic",
+               countera_4.sum_lutc_input = "cin",
+               countera_4.synch_mode = "on",
+               countera_4.lpm_type = "cyclone_lcell";
+       cyclone_lcell   countera_5
+       ( 
+       .aclr(aclr),
+       .cin(wire_countera_4cout[0:0]),
+       .clk(clock),
+       .combout(),
+       .cout(wire_countera_5cout[0:0]),
+       .dataa(power_modified_counter_values[4]),
+       .datab(power_modified_counter_values[5]),
+       .ena(1'b1),
+       .regout(wire_countera_regout[5:5]),
+       .sclr(sclr)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_off
+       `endif
+       ,
+       .aload(1'b0),
+       .datac(1'b1),
+       .datad(1'b1),
+       .inverta(1'b0),
+       .regcascin(1'b0),
+       .sload(1'b0)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_on
+       `endif
+       // synopsys translate_off
+       ,
+       .cin0(),
+       .cin1(),
+       .cout0(),
+       .cout1(),
+       .devclrn(),
+       .devpor()
+       // synopsys translate_on
+       );
+       defparam
+               countera_5.cin_used = "true",
+               countera_5.lut_mask = "6c50",
+               countera_5.operation_mode = "arithmetic",
+               countera_5.sum_lutc_input = "cin",
+               countera_5.synch_mode = "on",
+               countera_5.lpm_type = "cyclone_lcell";
+       cyclone_lcell   countera_6
+       ( 
+       .aclr(aclr),
+       .cin(wire_countera_5cout[0:0]),
+       .clk(clock),
+       .combout(),
+       .cout(wire_countera_6cout[0:0]),
+       .dataa(power_modified_counter_values[5]),
+       .datab(power_modified_counter_values[6]),
+       .ena(1'b1),
+       .regout(wire_countera_regout[6:6]),
+       .sclr(sclr)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_off
+       `endif
+       ,
+       .aload(1'b0),
+       .datac(1'b1),
+       .datad(1'b1),
+       .inverta(1'b0),
+       .regcascin(1'b0),
+       .sload(1'b0)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_on
+       `endif
+       // synopsys translate_off
+       ,
+       .cin0(),
+       .cin1(),
+       .cout0(),
+       .cout1(),
+       .devclrn(),
+       .devpor()
+       // synopsys translate_on
+       );
+       defparam
+               countera_6.cin_used = "true",
+               countera_6.lut_mask = "6c50",
+               countera_6.operation_mode = "arithmetic",
+               countera_6.sum_lutc_input = "cin",
+               countera_6.synch_mode = "on",
+               countera_6.lpm_type = "cyclone_lcell";
+       cyclone_lcell   countera_7
+       ( 
+       .aclr(aclr),
+       .cin(wire_countera_6cout[0:0]),
+       .clk(clock),
+       .combout(),
+       .cout(wire_countera_7cout[0:0]),
+       .dataa(power_modified_counter_values[6]),
+       .datab(power_modified_counter_values[7]),
+       .ena(1'b1),
+       .regout(wire_countera_regout[7:7]),
+       .sclr(sclr)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_off
+       `endif
+       ,
+       .aload(1'b0),
+       .datac(1'b1),
+       .datad(1'b1),
+       .inverta(1'b0),
+       .regcascin(1'b0),
+       .sload(1'b0)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_on
+       `endif
+       // synopsys translate_off
+       ,
+       .cin0(),
+       .cin1(),
+       .cout0(),
+       .cout1(),
+       .devclrn(),
+       .devpor()
+       // synopsys translate_on
+       );
+       defparam
+               countera_7.cin_used = "true",
+               countera_7.lut_mask = "6c50",
+               countera_7.operation_mode = "arithmetic",
+               countera_7.sum_lutc_input = "cin",
+               countera_7.synch_mode = "on",
+               countera_7.lpm_type = "cyclone_lcell";
+       cyclone_lcell   countera_8
+       ( 
+       .aclr(aclr),
+       .cin(wire_countera_7cout[0:0]),
+       .clk(clock),
+       .combout(),
+       .cout(wire_countera_8cout[0:0]),
+       .dataa(power_modified_counter_values[7]),
+       .datab(power_modified_counter_values[8]),
+       .ena(1'b1),
+       .regout(wire_countera_regout[8:8]),
+       .sclr(sclr)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_off
+       `endif
+       ,
+       .aload(1'b0),
+       .datac(1'b1),
+       .datad(1'b1),
+       .inverta(1'b0),
+       .regcascin(1'b0),
+       .sload(1'b0)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_on
+       `endif
+       // synopsys translate_off
+       ,
+       .cin0(),
+       .cin1(),
+       .cout0(),
+       .cout1(),
+       .devclrn(),
+       .devpor()
+       // synopsys translate_on
+       );
+       defparam
+               countera_8.cin_used = "true",
+               countera_8.lut_mask = "6c50",
+               countera_8.operation_mode = "arithmetic",
+               countera_8.sum_lutc_input = "cin",
+               countera_8.synch_mode = "on",
+               countera_8.lpm_type = "cyclone_lcell";
+       cyclone_lcell   countera_9
+       ( 
+       .aclr(aclr),
+       .cin(wire_countera_8cout[0:0]),
+       .clk(clock),
+       .combout(),
+       .cout(wire_countera_9cout[0:0]),
+       .dataa(power_modified_counter_values[8]),
+       .datab(power_modified_counter_values[9]),
+       .ena(1'b1),
+       .regout(wire_countera_regout[9:9]),
+       .sclr(sclr)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_off
+       `endif
+       ,
+       .aload(1'b0),
+       .datac(1'b1),
+       .datad(1'b1),
+       .inverta(1'b0),
+       .regcascin(1'b0),
+       .sload(1'b0)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_on
+       `endif
+       // synopsys translate_off
+       ,
+       .cin0(),
+       .cin1(),
+       .cout0(),
+       .cout1(),
+       .devclrn(),
+       .devpor()
+       // synopsys translate_on
+       );
+       defparam
+               countera_9.cin_used = "true",
+               countera_9.lut_mask = "6c50",
+               countera_9.operation_mode = "arithmetic",
+               countera_9.sum_lutc_input = "cin",
+               countera_9.synch_mode = "on",
+               countera_9.lpm_type = "cyclone_lcell";
+       cyclone_lcell   countera_10
+       ( 
+       .aclr(aclr),
+       .cin(wire_countera_9cout[0:0]),
+       .clk(clock),
+       .combout(),
+       .cout(wire_countera_10cout[0:0]),
+       .dataa(power_modified_counter_values[9]),
+       .datab(power_modified_counter_values[10]),
+       .ena(1'b1),
+       .regout(wire_countera_regout[10:10]),
+       .sclr(sclr)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_off
+       `endif
+       ,
+       .aload(1'b0),
+       .datac(1'b1),
+       .datad(1'b1),
+       .inverta(1'b0),
+       .regcascin(1'b0),
+       .sload(1'b0)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_on
+       `endif
+       // synopsys translate_off
+       ,
+       .cin0(),
+       .cin1(),
+       .cout0(),
+       .cout1(),
+       .devclrn(),
+       .devpor()
+       // synopsys translate_on
+       );
+       defparam
+               countera_10.cin_used = "true",
+               countera_10.lut_mask = "6c50",
+               countera_10.operation_mode = "arithmetic",
+               countera_10.sum_lutc_input = "cin",
+               countera_10.synch_mode = "on",
+               countera_10.lpm_type = "cyclone_lcell";
+       cyclone_lcell   countera_11
+       ( 
+       .aclr(aclr),
+       .cin(wire_countera_10cout[0:0]),
+       .clk(clock),
+       .combout(),
+       .cout(),
+       .dataa(power_modified_counter_values[11]),
+       .ena(1'b1),
+       .regout(wire_countera_regout[11:11]),
+       .sclr(sclr)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_off
+       `endif
+       ,
+       .aload(1'b0),
+       .datab(1'b1),
+       .datac(1'b1),
+       .datad(1'b1),
+       .inverta(1'b0),
+       .regcascin(1'b0),
+       .sload(1'b0)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_on
+       `endif
+       // synopsys translate_off
+       ,
+       .cin0(),
+       .cin1(),
+       .cout0(),
+       .cout1(),
+       .devclrn(),
+       .devpor()
+       // synopsys translate_on
+       );
+       defparam
+               countera_11.cin_used = "true",
+               countera_11.lut_mask = "5a5a",
+               countera_11.operation_mode = "normal",
+               countera_11.sum_lutc_input = "cin",
+               countera_11.synch_mode = "on",
+               countera_11.lpm_type = "cyclone_lcell";
+       cyclone_lcell   parity
+       ( 
+       .aclr(aclr),
+       .cin(updown),
+       .clk(clock),
+       .combout(),
+       .cout(wire_parity_cout),
+       .dataa(cnt_en),
+       .datab(wire_parity_regout),
+       .ena(1'b1),
+       .regout(wire_parity_regout),
+       .sclr(sclr)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_off
+       `endif
+       ,
+       .aload(1'b0),
+       .datac(1'b1),
+       .datad(1'b1),
+       .inverta(1'b0),
+       .regcascin(1'b0),
+       .sload(1'b0)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_on
+       `endif
+       // synopsys translate_off
+       ,
+       .cin0(),
+       .cin1(),
+       .cout0(),
+       .cout1(),
+       .devclrn(),
+       .devpor()
+       // synopsys translate_on
+       );
+       defparam
+               parity.cin_used = "true",
+               parity.lut_mask = "6682",
+               parity.operation_mode = "arithmetic",
+               parity.synch_mode = "on",
+               parity.lpm_type = "cyclone_lcell";
+       assign
+               power_modified_counter_values = {wire_countera_regout[11:0]},
+               q = power_modified_counter_values,
+               sclr = 1'b0,
+               updown = 1'b1;
+endmodule //fifo_4k_a_graycounter_826
+
+
+//a_graycounter DEVICE_FAMILY="Cyclone" PVALUE=1 WIDTH=12 aclr clock cnt_en q
+//VERSION_BEGIN 5.0 cbx_a_gray2bin 2004:03:06:00:52:20:SJ cbx_a_graycounter 2004:10:01:12:13:16:SJ cbx_cycloneii 2004:12:20:14:28:52:SJ cbx_flex10ke 2002:10:18:16:54:38:SJ cbx_mgl 2005:05:19:13:51:58:SJ cbx_stratix 2005:06:02:09:53:04:SJ cbx_stratixii 2004:12:22:13:27:12:SJ  VERSION_END
+
+//synthesis_resources = lut 13 
+//synopsys translate_off
+`timescale 1 ps / 1 ps
+//synopsys translate_on
+module  fifo_4k_a_graycounter_3r6
+       ( 
+       aclr,
+       clock,
+       cnt_en,
+       q) /* synthesis synthesis_clearbox=1 */;
+       input   aclr;
+       input   clock;
+       input   cnt_en;
+       output   [11:0]  q;
+
+       wire  [0:0]   wire_countera_0cout;
+       wire  [0:0]   wire_countera_1cout;
+       wire  [0:0]   wire_countera_2cout;
+       wire  [0:0]   wire_countera_3cout;
+       wire  [0:0]   wire_countera_4cout;
+       wire  [0:0]   wire_countera_5cout;
+       wire  [0:0]   wire_countera_6cout;
+       wire  [0:0]   wire_countera_7cout;
+       wire  [0:0]   wire_countera_8cout;
+       wire  [0:0]   wire_countera_9cout;
+       wire  [0:0]   wire_countera_10cout;
+       wire  [11:0]   wire_countera_regout;
+       wire  wire_parity_cout;
+       wire  wire_parity_regout;
+       wire  [11:0]  power_modified_counter_values;
+       wire sclr;
+       wire updown;
+
+       cyclone_lcell   countera_0
+       ( 
+       .aclr(aclr),
+       .cin(wire_parity_cout),
+       .clk(clock),
+       .combout(),
+       .cout(wire_countera_0cout[0:0]),
+       .dataa(cnt_en),
+       .datab(wire_countera_regout[0:0]),
+       .ena(1'b1),
+       .regout(wire_countera_regout[0:0]),
+       .sclr(sclr)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_off
+       `endif
+       ,
+       .aload(1'b0),
+       .datac(1'b1),
+       .datad(1'b1),
+       .inverta(1'b0),
+       .regcascin(1'b0),
+       .sload(1'b0)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_on
+       `endif
+       // synopsys translate_off
+       ,
+       .cin0(),
+       .cin1(),
+       .cout0(),
+       .cout1(),
+       .devclrn(),
+       .devpor()
+       // synopsys translate_on
+       );
+       defparam
+               countera_0.cin_used = "true",
+               countera_0.lut_mask = "c6a0",
+               countera_0.operation_mode = "arithmetic",
+               countera_0.sum_lutc_input = "cin",
+               countera_0.synch_mode = "on",
+               countera_0.lpm_type = "cyclone_lcell";
+       cyclone_lcell   countera_1
+       ( 
+       .aclr(aclr),
+       .cin(wire_countera_0cout[0:0]),
+       .clk(clock),
+       .combout(),
+       .cout(wire_countera_1cout[0:0]),
+       .dataa(power_modified_counter_values[0]),
+       .datab(power_modified_counter_values[1]),
+       .ena(1'b1),
+       .regout(wire_countera_regout[1:1]),
+       .sclr(sclr)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_off
+       `endif
+       ,
+       .aload(1'b0),
+       .datac(1'b1),
+       .datad(1'b1),
+       .inverta(1'b0),
+       .regcascin(1'b0),
+       .sload(1'b0)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_on
+       `endif
+       // synopsys translate_off
+       ,
+       .cin0(),
+       .cin1(),
+       .cout0(),
+       .cout1(),
+       .devclrn(),
+       .devpor()
+       // synopsys translate_on
+       );
+       defparam
+               countera_1.cin_used = "true",
+               countera_1.lut_mask = "6c50",
+               countera_1.operation_mode = "arithmetic",
+               countera_1.sum_lutc_input = "cin",
+               countera_1.synch_mode = "on",
+               countera_1.lpm_type = "cyclone_lcell";
+       cyclone_lcell   countera_2
+       ( 
+       .aclr(aclr),
+       .cin(wire_countera_1cout[0:0]),
+       .clk(clock),
+       .combout(),
+       .cout(wire_countera_2cout[0:0]),
+       .dataa(power_modified_counter_values[1]),
+       .datab(power_modified_counter_values[2]),
+       .ena(1'b1),
+       .regout(wire_countera_regout[2:2]),
+       .sclr(sclr)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_off
+       `endif
+       ,
+       .aload(1'b0),
+       .datac(1'b1),
+       .datad(1'b1),
+       .inverta(1'b0),
+       .regcascin(1'b0),
+       .sload(1'b0)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_on
+       `endif
+       // synopsys translate_off
+       ,
+       .cin0(),
+       .cin1(),
+       .cout0(),
+       .cout1(),
+       .devclrn(),
+       .devpor()
+       // synopsys translate_on
+       );
+       defparam
+               countera_2.cin_used = "true",
+               countera_2.lut_mask = "6c50",
+               countera_2.operation_mode = "arithmetic",
+               countera_2.sum_lutc_input = "cin",
+               countera_2.synch_mode = "on",
+               countera_2.lpm_type = "cyclone_lcell";
+       cyclone_lcell   countera_3
+       ( 
+       .aclr(aclr),
+       .cin(wire_countera_2cout[0:0]),
+       .clk(clock),
+       .combout(),
+       .cout(wire_countera_3cout[0:0]),
+       .dataa(power_modified_counter_values[2]),
+       .datab(power_modified_counter_values[3]),
+       .ena(1'b1),
+       .regout(wire_countera_regout[3:3]),
+       .sclr(sclr)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_off
+       `endif
+       ,
+       .aload(1'b0),
+       .datac(1'b1),
+       .datad(1'b1),
+       .inverta(1'b0),
+       .regcascin(1'b0),
+       .sload(1'b0)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_on
+       `endif
+       // synopsys translate_off
+       ,
+       .cin0(),
+       .cin1(),
+       .cout0(),
+       .cout1(),
+       .devclrn(),
+       .devpor()
+       // synopsys translate_on
+       );
+       defparam
+               countera_3.cin_used = "true",
+               countera_3.lut_mask = "6c50",
+               countera_3.operation_mode = "arithmetic",
+               countera_3.sum_lutc_input = "cin",
+               countera_3.synch_mode = "on",
+               countera_3.lpm_type = "cyclone_lcell";
+       cyclone_lcell   countera_4
+       ( 
+       .aclr(aclr),
+       .cin(wire_countera_3cout[0:0]),
+       .clk(clock),
+       .combout(),
+       .cout(wire_countera_4cout[0:0]),
+       .dataa(power_modified_counter_values[3]),
+       .datab(power_modified_counter_values[4]),
+       .ena(1'b1),
+       .regout(wire_countera_regout[4:4]),
+       .sclr(sclr)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_off
+       `endif
+       ,
+       .aload(1'b0),
+       .datac(1'b1),
+       .datad(1'b1),
+       .inverta(1'b0),
+       .regcascin(1'b0),
+       .sload(1'b0)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_on
+       `endif
+       // synopsys translate_off
+       ,
+       .cin0(),
+       .cin1(),
+       .cout0(),
+       .cout1(),
+       .devclrn(),
+       .devpor()
+       // synopsys translate_on
+       );
+       defparam
+               countera_4.cin_used = "true",
+               countera_4.lut_mask = "6c50",
+               countera_4.operation_mode = "arithmetic",
+               countera_4.sum_lutc_input = "cin",
+               countera_4.synch_mode = "on",
+               countera_4.lpm_type = "cyclone_lcell";
+       cyclone_lcell   countera_5
+       ( 
+       .aclr(aclr),
+       .cin(wire_countera_4cout[0:0]),
+       .clk(clock),
+       .combout(),
+       .cout(wire_countera_5cout[0:0]),
+       .dataa(power_modified_counter_values[4]),
+       .datab(power_modified_counter_values[5]),
+       .ena(1'b1),
+       .regout(wire_countera_regout[5:5]),
+       .sclr(sclr)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_off
+       `endif
+       ,
+       .aload(1'b0),
+       .datac(1'b1),
+       .datad(1'b1),
+       .inverta(1'b0),
+       .regcascin(1'b0),
+       .sload(1'b0)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_on
+       `endif
+       // synopsys translate_off
+       ,
+       .cin0(),
+       .cin1(),
+       .cout0(),
+       .cout1(),
+       .devclrn(),
+       .devpor()
+       // synopsys translate_on
+       );
+       defparam
+               countera_5.cin_used = "true",
+               countera_5.lut_mask = "6c50",
+               countera_5.operation_mode = "arithmetic",
+               countera_5.sum_lutc_input = "cin",
+               countera_5.synch_mode = "on",
+               countera_5.lpm_type = "cyclone_lcell";
+       cyclone_lcell   countera_6
+       ( 
+       .aclr(aclr),
+       .cin(wire_countera_5cout[0:0]),
+       .clk(clock),
+       .combout(),
+       .cout(wire_countera_6cout[0:0]),
+       .dataa(power_modified_counter_values[5]),
+       .datab(power_modified_counter_values[6]),
+       .ena(1'b1),
+       .regout(wire_countera_regout[6:6]),
+       .sclr(sclr)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_off
+       `endif
+       ,
+       .aload(1'b0),
+       .datac(1'b1),
+       .datad(1'b1),
+       .inverta(1'b0),
+       .regcascin(1'b0),
+       .sload(1'b0)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_on
+       `endif
+       // synopsys translate_off
+       ,
+       .cin0(),
+       .cin1(),
+       .cout0(),
+       .cout1(),
+       .devclrn(),
+       .devpor()
+       // synopsys translate_on
+       );
+       defparam
+               countera_6.cin_used = "true",
+               countera_6.lut_mask = "6c50",
+               countera_6.operation_mode = "arithmetic",
+               countera_6.sum_lutc_input = "cin",
+               countera_6.synch_mode = "on",
+               countera_6.lpm_type = "cyclone_lcell";
+       cyclone_lcell   countera_7
+       ( 
+       .aclr(aclr),
+       .cin(wire_countera_6cout[0:0]),
+       .clk(clock),
+       .combout(),
+       .cout(wire_countera_7cout[0:0]),
+       .dataa(power_modified_counter_values[6]),
+       .datab(power_modified_counter_values[7]),
+       .ena(1'b1),
+       .regout(wire_countera_regout[7:7]),
+       .sclr(sclr)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_off
+       `endif
+       ,
+       .aload(1'b0),
+       .datac(1'b1),
+       .datad(1'b1),
+       .inverta(1'b0),
+       .regcascin(1'b0),
+       .sload(1'b0)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_on
+       `endif
+       // synopsys translate_off
+       ,
+       .cin0(),
+       .cin1(),
+       .cout0(),
+       .cout1(),
+       .devclrn(),
+       .devpor()
+       // synopsys translate_on
+       );
+       defparam
+               countera_7.cin_used = "true",
+               countera_7.lut_mask = "6c50",
+               countera_7.operation_mode = "arithmetic",
+               countera_7.sum_lutc_input = "cin",
+               countera_7.synch_mode = "on",
+               countera_7.lpm_type = "cyclone_lcell";
+       cyclone_lcell   countera_8
+       ( 
+       .aclr(aclr),
+       .cin(wire_countera_7cout[0:0]),
+       .clk(clock),
+       .combout(),
+       .cout(wire_countera_8cout[0:0]),
+       .dataa(power_modified_counter_values[7]),
+       .datab(power_modified_counter_values[8]),
+       .ena(1'b1),
+       .regout(wire_countera_regout[8:8]),
+       .sclr(sclr)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_off
+       `endif
+       ,
+       .aload(1'b0),
+       .datac(1'b1),
+       .datad(1'b1),
+       .inverta(1'b0),
+       .regcascin(1'b0),
+       .sload(1'b0)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_on
+       `endif
+       // synopsys translate_off
+       ,
+       .cin0(),
+       .cin1(),
+       .cout0(),
+       .cout1(),
+       .devclrn(),
+       .devpor()
+       // synopsys translate_on
+       );
+       defparam
+               countera_8.cin_used = "true",
+               countera_8.lut_mask = "6c50",
+               countera_8.operation_mode = "arithmetic",
+               countera_8.sum_lutc_input = "cin",
+               countera_8.synch_mode = "on",
+               countera_8.lpm_type = "cyclone_lcell";
+       cyclone_lcell   countera_9
+       ( 
+       .aclr(aclr),
+       .cin(wire_countera_8cout[0:0]),
+       .clk(clock),
+       .combout(),
+       .cout(wire_countera_9cout[0:0]),
+       .dataa(power_modified_counter_values[8]),
+       .datab(power_modified_counter_values[9]),
+       .ena(1'b1),
+       .regout(wire_countera_regout[9:9]),
+       .sclr(sclr)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_off
+       `endif
+       ,
+       .aload(1'b0),
+       .datac(1'b1),
+       .datad(1'b1),
+       .inverta(1'b0),
+       .regcascin(1'b0),
+       .sload(1'b0)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_on
+       `endif
+       // synopsys translate_off
+       ,
+       .cin0(),
+       .cin1(),
+       .cout0(),
+       .cout1(),
+       .devclrn(),
+       .devpor()
+       // synopsys translate_on
+       );
+       defparam
+               countera_9.cin_used = "true",
+               countera_9.lut_mask = "6c50",
+               countera_9.operation_mode = "arithmetic",
+               countera_9.sum_lutc_input = "cin",
+               countera_9.synch_mode = "on",
+               countera_9.lpm_type = "cyclone_lcell";
+       cyclone_lcell   countera_10
+       ( 
+       .aclr(aclr),
+       .cin(wire_countera_9cout[0:0]),
+       .clk(clock),
+       .combout(),
+       .cout(wire_countera_10cout[0:0]),
+       .dataa(power_modified_counter_values[9]),
+       .datab(power_modified_counter_values[10]),
+       .ena(1'b1),
+       .regout(wire_countera_regout[10:10]),
+       .sclr(sclr)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_off
+       `endif
+       ,
+       .aload(1'b0),
+       .datac(1'b1),
+       .datad(1'b1),
+       .inverta(1'b0),
+       .regcascin(1'b0),
+       .sload(1'b0)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_on
+       `endif
+       // synopsys translate_off
+       ,
+       .cin0(),
+       .cin1(),
+       .cout0(),
+       .cout1(),
+       .devclrn(),
+       .devpor()
+       // synopsys translate_on
+       );
+       defparam
+               countera_10.cin_used = "true",
+               countera_10.lut_mask = "6c50",
+               countera_10.operation_mode = "arithmetic",
+               countera_10.sum_lutc_input = "cin",
+               countera_10.synch_mode = "on",
+               countera_10.lpm_type = "cyclone_lcell";
+       cyclone_lcell   countera_11
+       ( 
+       .aclr(aclr),
+       .cin(wire_countera_10cout[0:0]),
+       .clk(clock),
+       .combout(),
+       .cout(),
+       .dataa(power_modified_counter_values[11]),
+       .ena(1'b1),
+       .regout(wire_countera_regout[11:11]),
+       .sclr(sclr)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_off
+       `endif
+       ,
+       .aload(1'b0),
+       .datab(1'b1),
+       .datac(1'b1),
+       .datad(1'b1),
+       .inverta(1'b0),
+       .regcascin(1'b0),
+       .sload(1'b0)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_on
+       `endif
+       // synopsys translate_off
+       ,
+       .cin0(),
+       .cin1(),
+       .cout0(),
+       .cout1(),
+       .devclrn(),
+       .devpor()
+       // synopsys translate_on
+       );
+       defparam
+               countera_11.cin_used = "true",
+               countera_11.lut_mask = "5a5a",
+               countera_11.operation_mode = "normal",
+               countera_11.sum_lutc_input = "cin",
+               countera_11.synch_mode = "on",
+               countera_11.lpm_type = "cyclone_lcell";
+       cyclone_lcell   parity
+       ( 
+       .aclr(aclr),
+       .cin(updown),
+       .clk(clock),
+       .combout(),
+       .cout(wire_parity_cout),
+       .dataa(cnt_en),
+       .datab((~ wire_parity_regout)),
+       .ena(1'b1),
+       .regout(wire_parity_regout),
+       .sclr(sclr)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_off
+       `endif
+       ,
+       .aload(1'b0),
+       .datac(1'b1),
+       .datad(1'b1),
+       .inverta(1'b0),
+       .regcascin(1'b0),
+       .sload(1'b0)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_on
+       `endif
+       // synopsys translate_off
+       ,
+       .cin0(),
+       .cin1(),
+       .cout0(),
+       .cout1(),
+       .devclrn(),
+       .devpor()
+       // synopsys translate_on
+       );
+       defparam
+               parity.cin_used = "true",
+               parity.lut_mask = "9982",
+               parity.operation_mode = "arithmetic",
+               parity.synch_mode = "on",
+               parity.lpm_type = "cyclone_lcell";
+       assign
+               power_modified_counter_values = {wire_countera_regout[11:1], (~ wire_countera_regout[0])},
+               q = power_modified_counter_values,
+               sclr = 1'b0,
+               updown = 1'b1;
+endmodule //fifo_4k_a_graycounter_3r6
+
+
+//altsyncram ADDRESS_REG_B="CLOCK1" DEVICE_FAMILY="Cyclone" OPERATION_MODE="DUAL_PORT" OUTDATA_REG_B="UNREGISTERED" WIDTH_A=16 WIDTH_B=16 WIDTH_BYTEENA_A=1 WIDTHAD_A=12 WIDTHAD_B=12 address_a address_b clock0 clock1 clocken1 data_a q_b wren_a
+//VERSION_BEGIN 5.0 cbx_altsyncram 2005:03:24:13:58:56:SJ cbx_cycloneii 2004:12:20:14:28:52:SJ cbx_lpm_add_sub 2005:04:12:13:30:42:SJ cbx_lpm_compare 2004:11:30:11:30:40:SJ cbx_lpm_decode 2004:12:13:14:19:12:SJ cbx_lpm_mux 2004:12:13:14:16:38:SJ cbx_mgl 2005:05:19:13:51:58:SJ cbx_stratix 2005:06:02:09:53:04:SJ cbx_stratixii 2004:12:22:13:27:12:SJ cbx_util_mgl 2005:04:04:13:50:06:SJ  VERSION_END
+
+//synthesis_resources = M4K 16 
+//synopsys translate_off
+`timescale 1 ps / 1 ps
+//synopsys translate_on
+module  fifo_4k_altsyncram_8pl
+       ( 
+       address_a,
+       address_b,
+       clock0,
+       clock1,
+       clocken1,
+       data_a,
+       q_b,
+       wren_a) /* synthesis synthesis_clearbox=1 */;
+       input   [11:0]  address_a;
+       input   [11:0]  address_b;
+       input   clock0;
+       input   clock1;
+       input   clocken1;
+       input   [15:0]  data_a;
+       output   [15:0]  q_b;
+       input   wren_a;
+
+       wire  [0:0]   wire_ram_block3a_0portbdataout;
+       wire  [0:0]   wire_ram_block3a_1portbdataout;
+       wire  [0:0]   wire_ram_block3a_2portbdataout;
+       wire  [0:0]   wire_ram_block3a_3portbdataout;
+       wire  [0:0]   wire_ram_block3a_4portbdataout;
+       wire  [0:0]   wire_ram_block3a_5portbdataout;
+       wire  [0:0]   wire_ram_block3a_6portbdataout;
+       wire  [0:0]   wire_ram_block3a_7portbdataout;
+       wire  [0:0]   wire_ram_block3a_8portbdataout;
+       wire  [0:0]   wire_ram_block3a_9portbdataout;
+       wire  [0:0]   wire_ram_block3a_10portbdataout;
+       wire  [0:0]   wire_ram_block3a_11portbdataout;
+       wire  [0:0]   wire_ram_block3a_12portbdataout;
+       wire  [0:0]   wire_ram_block3a_13portbdataout;
+       wire  [0:0]   wire_ram_block3a_14portbdataout;
+       wire  [0:0]   wire_ram_block3a_15portbdataout;
+       wire  [11:0]  address_a_wire;
+       wire  [11:0]  address_b_wire;
+
+       cyclone_ram_block   ram_block3a_0
+       ( 
+       .clk0(clock0),
+       .clk1(clock1),
+       .ena0(wren_a),
+       .ena1(clocken1),
+       .portaaddr({address_a_wire[11:0]}),
+       .portadatain({data_a[0]}),
+       .portadataout(),
+       .portawe(1'b1),
+       .portbaddr({address_b_wire[11:0]}),
+       .portbdataout(wire_ram_block3a_0portbdataout[0:0]),
+       .portbrewe(1'b1)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_off
+       `endif
+       ,
+       .clr0(1'b0),
+       .clr1(1'b0),
+       .portabyteenamasks(1'b1),
+       .portbbyteenamasks(1'b1),
+       .portbdatain(1'b0)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_on
+       `endif
+       // synopsys translate_off
+       ,
+       .devclrn(),
+       .devpor()
+       // synopsys translate_on
+       );
+       defparam
+               ram_block3a_0.connectivity_checking = "OFF",
+               ram_block3a_0.logical_ram_name = "ALTSYNCRAM",
+               ram_block3a_0.mixed_port_feed_through_mode = "dont_care",
+               ram_block3a_0.operation_mode = "dual_port",
+               ram_block3a_0.port_a_address_width = 12,
+               ram_block3a_0.port_a_data_width = 1,
+               ram_block3a_0.port_a_first_address = 0,
+               ram_block3a_0.port_a_first_bit_number = 0,
+               ram_block3a_0.port_a_last_address = 4095,
+               ram_block3a_0.port_a_logical_ram_depth = 4096,
+               ram_block3a_0.port_a_logical_ram_width = 16,
+               ram_block3a_0.port_b_address_clear = "none",
+               ram_block3a_0.port_b_address_clock = "clock1",
+               ram_block3a_0.port_b_address_width = 12,
+               ram_block3a_0.port_b_data_out_clear = "none",
+               ram_block3a_0.port_b_data_out_clock = "none",
+               ram_block3a_0.port_b_data_width = 1,
+               ram_block3a_0.port_b_first_address = 0,
+               ram_block3a_0.port_b_first_bit_number = 0,
+               ram_block3a_0.port_b_last_address = 4095,
+               ram_block3a_0.port_b_logical_ram_depth = 4096,
+               ram_block3a_0.port_b_logical_ram_width = 16,
+               ram_block3a_0.port_b_read_enable_write_enable_clock = "clock1",
+               ram_block3a_0.ram_block_type = "auto",
+               ram_block3a_0.lpm_type = "cyclone_ram_block";
+       cyclone_ram_block   ram_block3a_1
+       ( 
+       .clk0(clock0),
+       .clk1(clock1),
+       .ena0(wren_a),
+       .ena1(clocken1),
+       .portaaddr({address_a_wire[11:0]}),
+       .portadatain({data_a[1]}),
+       .portadataout(),
+       .portawe(1'b1),
+       .portbaddr({address_b_wire[11:0]}),
+       .portbdataout(wire_ram_block3a_1portbdataout[0:0]),
+       .portbrewe(1'b1)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_off
+       `endif
+       ,
+       .clr0(1'b0),
+       .clr1(1'b0),
+       .portabyteenamasks(1'b1),
+       .portbbyteenamasks(1'b1),
+       .portbdatain(1'b0)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_on
+       `endif
+       // synopsys translate_off
+       ,
+       .devclrn(),
+       .devpor()
+       // synopsys translate_on
+       );
+       defparam
+               ram_block3a_1.connectivity_checking = "OFF",
+               ram_block3a_1.logical_ram_name = "ALTSYNCRAM",
+               ram_block3a_1.mixed_port_feed_through_mode = "dont_care",
+               ram_block3a_1.operation_mode = "dual_port",
+               ram_block3a_1.port_a_address_width = 12,
+               ram_block3a_1.port_a_data_width = 1,
+               ram_block3a_1.port_a_first_address = 0,
+               ram_block3a_1.port_a_first_bit_number = 1,
+               ram_block3a_1.port_a_last_address = 4095,
+               ram_block3a_1.port_a_logical_ram_depth = 4096,
+               ram_block3a_1.port_a_logical_ram_width = 16,
+               ram_block3a_1.port_b_address_clear = "none",
+               ram_block3a_1.port_b_address_clock = "clock1",
+               ram_block3a_1.port_b_address_width = 12,
+               ram_block3a_1.port_b_data_out_clear = "none",
+               ram_block3a_1.port_b_data_out_clock = "none",
+               ram_block3a_1.port_b_data_width = 1,
+               ram_block3a_1.port_b_first_address = 0,
+               ram_block3a_1.port_b_first_bit_number = 1,
+               ram_block3a_1.port_b_last_address = 4095,
+               ram_block3a_1.port_b_logical_ram_depth = 4096,
+               ram_block3a_1.port_b_logical_ram_width = 16,
+               ram_block3a_1.port_b_read_enable_write_enable_clock = "clock1",
+               ram_block3a_1.ram_block_type = "auto",
+               ram_block3a_1.lpm_type = "cyclone_ram_block";
+       cyclone_ram_block   ram_block3a_2
+       ( 
+       .clk0(clock0),
+       .clk1(clock1),
+       .ena0(wren_a),
+       .ena1(clocken1),
+       .portaaddr({address_a_wire[11:0]}),
+       .portadatain({data_a[2]}),
+       .portadataout(),
+       .portawe(1'b1),
+       .portbaddr({address_b_wire[11:0]}),
+       .portbdataout(wire_ram_block3a_2portbdataout[0:0]),
+       .portbrewe(1'b1)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_off
+       `endif
+       ,
+       .clr0(1'b0),
+       .clr1(1'b0),
+       .portabyteenamasks(1'b1),
+       .portbbyteenamasks(1'b1),
+       .portbdatain(1'b0)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_on
+       `endif
+       // synopsys translate_off
+       ,
+       .devclrn(),
+       .devpor()
+       // synopsys translate_on
+       );
+       defparam
+               ram_block3a_2.connectivity_checking = "OFF",
+               ram_block3a_2.logical_ram_name = "ALTSYNCRAM",
+               ram_block3a_2.mixed_port_feed_through_mode = "dont_care",
+               ram_block3a_2.operation_mode = "dual_port",
+               ram_block3a_2.port_a_address_width = 12,
+               ram_block3a_2.port_a_data_width = 1,
+               ram_block3a_2.port_a_first_address = 0,
+               ram_block3a_2.port_a_first_bit_number = 2,
+               ram_block3a_2.port_a_last_address = 4095,
+               ram_block3a_2.port_a_logical_ram_depth = 4096,
+               ram_block3a_2.port_a_logical_ram_width = 16,
+               ram_block3a_2.port_b_address_clear = "none",
+               ram_block3a_2.port_b_address_clock = "clock1",
+               ram_block3a_2.port_b_address_width = 12,
+               ram_block3a_2.port_b_data_out_clear = "none",
+               ram_block3a_2.port_b_data_out_clock = "none",
+               ram_block3a_2.port_b_data_width = 1,
+               ram_block3a_2.port_b_first_address = 0,
+               ram_block3a_2.port_b_first_bit_number = 2,
+               ram_block3a_2.port_b_last_address = 4095,
+               ram_block3a_2.port_b_logical_ram_depth = 4096,
+               ram_block3a_2.port_b_logical_ram_width = 16,
+               ram_block3a_2.port_b_read_enable_write_enable_clock = "clock1",
+               ram_block3a_2.ram_block_type = "auto",
+               ram_block3a_2.lpm_type = "cyclone_ram_block";
+       cyclone_ram_block   ram_block3a_3
+       ( 
+       .clk0(clock0),
+       .clk1(clock1),
+       .ena0(wren_a),
+       .ena1(clocken1),
+       .portaaddr({address_a_wire[11:0]}),
+       .portadatain({data_a[3]}),
+       .portadataout(),
+       .portawe(1'b1),
+       .portbaddr({address_b_wire[11:0]}),
+       .portbdataout(wire_ram_block3a_3portbdataout[0:0]),
+       .portbrewe(1'b1)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_off
+       `endif
+       ,
+       .clr0(1'b0),
+       .clr1(1'b0),
+       .portabyteenamasks(1'b1),
+       .portbbyteenamasks(1'b1),
+       .portbdatain(1'b0)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_on
+       `endif
+       // synopsys translate_off
+       ,
+       .devclrn(),
+       .devpor()
+       // synopsys translate_on
+       );
+       defparam
+               ram_block3a_3.connectivity_checking = "OFF",
+               ram_block3a_3.logical_ram_name = "ALTSYNCRAM",
+               ram_block3a_3.mixed_port_feed_through_mode = "dont_care",
+               ram_block3a_3.operation_mode = "dual_port",
+               ram_block3a_3.port_a_address_width = 12,
+               ram_block3a_3.port_a_data_width = 1,
+               ram_block3a_3.port_a_first_address = 0,
+               ram_block3a_3.port_a_first_bit_number = 3,
+               ram_block3a_3.port_a_last_address = 4095,
+               ram_block3a_3.port_a_logical_ram_depth = 4096,
+               ram_block3a_3.port_a_logical_ram_width = 16,
+               ram_block3a_3.port_b_address_clear = "none",
+               ram_block3a_3.port_b_address_clock = "clock1",
+               ram_block3a_3.port_b_address_width = 12,
+               ram_block3a_3.port_b_data_out_clear = "none",
+               ram_block3a_3.port_b_data_out_clock = "none",
+               ram_block3a_3.port_b_data_width = 1,
+               ram_block3a_3.port_b_first_address = 0,
+               ram_block3a_3.port_b_first_bit_number = 3,
+               ram_block3a_3.port_b_last_address = 4095,
+               ram_block3a_3.port_b_logical_ram_depth = 4096,
+               ram_block3a_3.port_b_logical_ram_width = 16,
+               ram_block3a_3.port_b_read_enable_write_enable_clock = "clock1",
+               ram_block3a_3.ram_block_type = "auto",
+               ram_block3a_3.lpm_type = "cyclone_ram_block";
+       cyclone_ram_block   ram_block3a_4
+       ( 
+       .clk0(clock0),
+       .clk1(clock1),
+       .ena0(wren_a),
+       .ena1(clocken1),
+       .portaaddr({address_a_wire[11:0]}),
+       .portadatain({data_a[4]}),
+       .portadataout(),
+       .portawe(1'b1),
+       .portbaddr({address_b_wire[11:0]}),
+       .portbdataout(wire_ram_block3a_4portbdataout[0:0]),
+       .portbrewe(1'b1)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_off
+       `endif
+       ,
+       .clr0(1'b0),
+       .clr1(1'b0),
+       .portabyteenamasks(1'b1),
+       .portbbyteenamasks(1'b1),
+       .portbdatain(1'b0)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_on
+       `endif
+       // synopsys translate_off
+       ,
+       .devclrn(),
+       .devpor()
+       // synopsys translate_on
+       );
+       defparam
+               ram_block3a_4.connectivity_checking = "OFF",
+               ram_block3a_4.logical_ram_name = "ALTSYNCRAM",
+               ram_block3a_4.mixed_port_feed_through_mode = "dont_care",
+               ram_block3a_4.operation_mode = "dual_port",
+               ram_block3a_4.port_a_address_width = 12,
+               ram_block3a_4.port_a_data_width = 1,
+               ram_block3a_4.port_a_first_address = 0,
+               ram_block3a_4.port_a_first_bit_number = 4,
+               ram_block3a_4.port_a_last_address = 4095,
+               ram_block3a_4.port_a_logical_ram_depth = 4096,
+               ram_block3a_4.port_a_logical_ram_width = 16,
+               ram_block3a_4.port_b_address_clear = "none",
+               ram_block3a_4.port_b_address_clock = "clock1",
+               ram_block3a_4.port_b_address_width = 12,
+               ram_block3a_4.port_b_data_out_clear = "none",
+               ram_block3a_4.port_b_data_out_clock = "none",
+               ram_block3a_4.port_b_data_width = 1,
+               ram_block3a_4.port_b_first_address = 0,
+               ram_block3a_4.port_b_first_bit_number = 4,
+               ram_block3a_4.port_b_last_address = 4095,
+               ram_block3a_4.port_b_logical_ram_depth = 4096,
+               ram_block3a_4.port_b_logical_ram_width = 16,
+               ram_block3a_4.port_b_read_enable_write_enable_clock = "clock1",
+               ram_block3a_4.ram_block_type = "auto",
+               ram_block3a_4.lpm_type = "cyclone_ram_block";
+       cyclone_ram_block   ram_block3a_5
+       ( 
+       .clk0(clock0),
+       .clk1(clock1),
+       .ena0(wren_a),
+       .ena1(clocken1),
+       .portaaddr({address_a_wire[11:0]}),
+       .portadatain({data_a[5]}),
+       .portadataout(),
+       .portawe(1'b1),
+       .portbaddr({address_b_wire[11:0]}),
+       .portbdataout(wire_ram_block3a_5portbdataout[0:0]),
+       .portbrewe(1'b1)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_off
+       `endif
+       ,
+       .clr0(1'b0),
+       .clr1(1'b0),
+       .portabyteenamasks(1'b1),
+       .portbbyteenamasks(1'b1),
+       .portbdatain(1'b0)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_on
+       `endif
+       // synopsys translate_off
+       ,
+       .devclrn(),
+       .devpor()
+       // synopsys translate_on
+       );
+       defparam
+               ram_block3a_5.connectivity_checking = "OFF",
+               ram_block3a_5.logical_ram_name = "ALTSYNCRAM",
+               ram_block3a_5.mixed_port_feed_through_mode = "dont_care",
+               ram_block3a_5.operation_mode = "dual_port",
+               ram_block3a_5.port_a_address_width = 12,
+               ram_block3a_5.port_a_data_width = 1,
+               ram_block3a_5.port_a_first_address = 0,
+               ram_block3a_5.port_a_first_bit_number = 5,
+               ram_block3a_5.port_a_last_address = 4095,
+               ram_block3a_5.port_a_logical_ram_depth = 4096,
+               ram_block3a_5.port_a_logical_ram_width = 16,
+               ram_block3a_5.port_b_address_clear = "none",
+               ram_block3a_5.port_b_address_clock = "clock1",
+               ram_block3a_5.port_b_address_width = 12,
+               ram_block3a_5.port_b_data_out_clear = "none",
+               ram_block3a_5.port_b_data_out_clock = "none",
+               ram_block3a_5.port_b_data_width = 1,
+               ram_block3a_5.port_b_first_address = 0,
+               ram_block3a_5.port_b_first_bit_number = 5,
+               ram_block3a_5.port_b_last_address = 4095,
+               ram_block3a_5.port_b_logical_ram_depth = 4096,
+               ram_block3a_5.port_b_logical_ram_width = 16,
+               ram_block3a_5.port_b_read_enable_write_enable_clock = "clock1",
+               ram_block3a_5.ram_block_type = "auto",
+               ram_block3a_5.lpm_type = "cyclone_ram_block";
+       cyclone_ram_block   ram_block3a_6
+       ( 
+       .clk0(clock0),
+       .clk1(clock1),
+       .ena0(wren_a),
+       .ena1(clocken1),
+       .portaaddr({address_a_wire[11:0]}),
+       .portadatain({data_a[6]}),
+       .portadataout(),
+       .portawe(1'b1),
+       .portbaddr({address_b_wire[11:0]}),
+       .portbdataout(wire_ram_block3a_6portbdataout[0:0]),
+       .portbrewe(1'b1)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_off
+       `endif
+       ,
+       .clr0(1'b0),
+       .clr1(1'b0),
+       .portabyteenamasks(1'b1),
+       .portbbyteenamasks(1'b1),
+       .portbdatain(1'b0)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_on
+       `endif
+       // synopsys translate_off
+       ,
+       .devclrn(),
+       .devpor()
+       // synopsys translate_on
+       );
+       defparam
+               ram_block3a_6.connectivity_checking = "OFF",
+               ram_block3a_6.logical_ram_name = "ALTSYNCRAM",
+               ram_block3a_6.mixed_port_feed_through_mode = "dont_care",
+               ram_block3a_6.operation_mode = "dual_port",
+               ram_block3a_6.port_a_address_width = 12,
+               ram_block3a_6.port_a_data_width = 1,
+               ram_block3a_6.port_a_first_address = 0,
+               ram_block3a_6.port_a_first_bit_number = 6,
+               ram_block3a_6.port_a_last_address = 4095,
+               ram_block3a_6.port_a_logical_ram_depth = 4096,
+               ram_block3a_6.port_a_logical_ram_width = 16,
+               ram_block3a_6.port_b_address_clear = "none",
+               ram_block3a_6.port_b_address_clock = "clock1",
+               ram_block3a_6.port_b_address_width = 12,
+               ram_block3a_6.port_b_data_out_clear = "none",
+               ram_block3a_6.port_b_data_out_clock = "none",
+               ram_block3a_6.port_b_data_width = 1,
+               ram_block3a_6.port_b_first_address = 0,
+               ram_block3a_6.port_b_first_bit_number = 6,
+               ram_block3a_6.port_b_last_address = 4095,
+               ram_block3a_6.port_b_logical_ram_depth = 4096,
+               ram_block3a_6.port_b_logical_ram_width = 16,
+               ram_block3a_6.port_b_read_enable_write_enable_clock = "clock1",
+               ram_block3a_6.ram_block_type = "auto",
+               ram_block3a_6.lpm_type = "cyclone_ram_block";
+       cyclone_ram_block   ram_block3a_7
+       ( 
+       .clk0(clock0),
+       .clk1(clock1),
+       .ena0(wren_a),
+       .ena1(clocken1),
+       .portaaddr({address_a_wire[11:0]}),
+       .portadatain({data_a[7]}),
+       .portadataout(),
+       .portawe(1'b1),
+       .portbaddr({address_b_wire[11:0]}),
+       .portbdataout(wire_ram_block3a_7portbdataout[0:0]),
+       .portbrewe(1'b1)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_off
+       `endif
+       ,
+       .clr0(1'b0),
+       .clr1(1'b0),
+       .portabyteenamasks(1'b1),
+       .portbbyteenamasks(1'b1),
+       .portbdatain(1'b0)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_on
+       `endif
+       // synopsys translate_off
+       ,
+       .devclrn(),
+       .devpor()
+       // synopsys translate_on
+       );
+       defparam
+               ram_block3a_7.connectivity_checking = "OFF",
+               ram_block3a_7.logical_ram_name = "ALTSYNCRAM",
+               ram_block3a_7.mixed_port_feed_through_mode = "dont_care",
+               ram_block3a_7.operation_mode = "dual_port",
+               ram_block3a_7.port_a_address_width = 12,
+               ram_block3a_7.port_a_data_width = 1,
+               ram_block3a_7.port_a_first_address = 0,
+               ram_block3a_7.port_a_first_bit_number = 7,
+               ram_block3a_7.port_a_last_address = 4095,
+               ram_block3a_7.port_a_logical_ram_depth = 4096,
+               ram_block3a_7.port_a_logical_ram_width = 16,
+               ram_block3a_7.port_b_address_clear = "none",
+               ram_block3a_7.port_b_address_clock = "clock1",
+               ram_block3a_7.port_b_address_width = 12,
+               ram_block3a_7.port_b_data_out_clear = "none",
+               ram_block3a_7.port_b_data_out_clock = "none",
+               ram_block3a_7.port_b_data_width = 1,
+               ram_block3a_7.port_b_first_address = 0,
+               ram_block3a_7.port_b_first_bit_number = 7,
+               ram_block3a_7.port_b_last_address = 4095,
+               ram_block3a_7.port_b_logical_ram_depth = 4096,
+               ram_block3a_7.port_b_logical_ram_width = 16,
+               ram_block3a_7.port_b_read_enable_write_enable_clock = "clock1",
+               ram_block3a_7.ram_block_type = "auto",
+               ram_block3a_7.lpm_type = "cyclone_ram_block";
+       cyclone_ram_block   ram_block3a_8
+       ( 
+       .clk0(clock0),
+       .clk1(clock1),
+       .ena0(wren_a),
+       .ena1(clocken1),
+       .portaaddr({address_a_wire[11:0]}),
+       .portadatain({data_a[8]}),
+       .portadataout(),
+       .portawe(1'b1),
+       .portbaddr({address_b_wire[11:0]}),
+       .portbdataout(wire_ram_block3a_8portbdataout[0:0]),
+       .portbrewe(1'b1)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_off
+       `endif
+       ,
+       .clr0(1'b0),
+       .clr1(1'b0),
+       .portabyteenamasks(1'b1),
+       .portbbyteenamasks(1'b1),
+       .portbdatain(1'b0)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_on
+       `endif
+       // synopsys translate_off
+       ,
+       .devclrn(),
+       .devpor()
+       // synopsys translate_on
+       );
+       defparam
+               ram_block3a_8.connectivity_checking = "OFF",
+               ram_block3a_8.logical_ram_name = "ALTSYNCRAM",
+               ram_block3a_8.mixed_port_feed_through_mode = "dont_care",
+               ram_block3a_8.operation_mode = "dual_port",
+               ram_block3a_8.port_a_address_width = 12,
+               ram_block3a_8.port_a_data_width = 1,
+               ram_block3a_8.port_a_first_address = 0,
+               ram_block3a_8.port_a_first_bit_number = 8,
+               ram_block3a_8.port_a_last_address = 4095,
+               ram_block3a_8.port_a_logical_ram_depth = 4096,
+               ram_block3a_8.port_a_logical_ram_width = 16,
+               ram_block3a_8.port_b_address_clear = "none",
+               ram_block3a_8.port_b_address_clock = "clock1",
+               ram_block3a_8.port_b_address_width = 12,
+               ram_block3a_8.port_b_data_out_clear = "none",
+               ram_block3a_8.port_b_data_out_clock = "none",
+               ram_block3a_8.port_b_data_width = 1,
+               ram_block3a_8.port_b_first_address = 0,
+               ram_block3a_8.port_b_first_bit_number = 8,
+               ram_block3a_8.port_b_last_address = 4095,
+               ram_block3a_8.port_b_logical_ram_depth = 4096,
+               ram_block3a_8.port_b_logical_ram_width = 16,
+               ram_block3a_8.port_b_read_enable_write_enable_clock = "clock1",
+               ram_block3a_8.ram_block_type = "auto",
+               ram_block3a_8.lpm_type = "cyclone_ram_block";
+       cyclone_ram_block   ram_block3a_9
+       ( 
+       .clk0(clock0),
+       .clk1(clock1),
+       .ena0(wren_a),
+       .ena1(clocken1),
+       .portaaddr({address_a_wire[11:0]}),
+       .portadatain({data_a[9]}),
+       .portadataout(),
+       .portawe(1'b1),
+       .portbaddr({address_b_wire[11:0]}),
+       .portbdataout(wire_ram_block3a_9portbdataout[0:0]),
+       .portbrewe(1'b1)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_off
+       `endif
+       ,
+       .clr0(1'b0),
+       .clr1(1'b0),
+       .portabyteenamasks(1'b1),
+       .portbbyteenamasks(1'b1),
+       .portbdatain(1'b0)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_on
+       `endif
+       // synopsys translate_off
+       ,
+       .devclrn(),
+       .devpor()
+       // synopsys translate_on
+       );
+       defparam
+               ram_block3a_9.connectivity_checking = "OFF",
+               ram_block3a_9.logical_ram_name = "ALTSYNCRAM",
+               ram_block3a_9.mixed_port_feed_through_mode = "dont_care",
+               ram_block3a_9.operation_mode = "dual_port",
+               ram_block3a_9.port_a_address_width = 12,
+               ram_block3a_9.port_a_data_width = 1,
+               ram_block3a_9.port_a_first_address = 0,
+               ram_block3a_9.port_a_first_bit_number = 9,
+               ram_block3a_9.port_a_last_address = 4095,
+               ram_block3a_9.port_a_logical_ram_depth = 4096,
+               ram_block3a_9.port_a_logical_ram_width = 16,
+               ram_block3a_9.port_b_address_clear = "none",
+               ram_block3a_9.port_b_address_clock = "clock1",
+               ram_block3a_9.port_b_address_width = 12,
+               ram_block3a_9.port_b_data_out_clear = "none",
+               ram_block3a_9.port_b_data_out_clock = "none",
+               ram_block3a_9.port_b_data_width = 1,
+               ram_block3a_9.port_b_first_address = 0,
+               ram_block3a_9.port_b_first_bit_number = 9,
+               ram_block3a_9.port_b_last_address = 4095,
+               ram_block3a_9.port_b_logical_ram_depth = 4096,
+               ram_block3a_9.port_b_logical_ram_width = 16,
+               ram_block3a_9.port_b_read_enable_write_enable_clock = "clock1",
+               ram_block3a_9.ram_block_type = "auto",
+               ram_block3a_9.lpm_type = "cyclone_ram_block";
+       cyclone_ram_block   ram_block3a_10
+       ( 
+       .clk0(clock0),
+       .clk1(clock1),
+       .ena0(wren_a),
+       .ena1(clocken1),
+       .portaaddr({address_a_wire[11:0]}),
+       .portadatain({data_a[10]}),
+       .portadataout(),
+       .portawe(1'b1),
+       .portbaddr({address_b_wire[11:0]}),
+       .portbdataout(wire_ram_block3a_10portbdataout[0:0]),
+       .portbrewe(1'b1)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_off
+       `endif
+       ,
+       .clr0(1'b0),
+       .clr1(1'b0),
+       .portabyteenamasks(1'b1),
+       .portbbyteenamasks(1'b1),
+       .portbdatain(1'b0)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_on
+       `endif
+       // synopsys translate_off
+       ,
+       .devclrn(),
+       .devpor()
+       // synopsys translate_on
+       );
+       defparam
+               ram_block3a_10.connectivity_checking = "OFF",
+               ram_block3a_10.logical_ram_name = "ALTSYNCRAM",
+               ram_block3a_10.mixed_port_feed_through_mode = "dont_care",
+               ram_block3a_10.operation_mode = "dual_port",
+               ram_block3a_10.port_a_address_width = 12,
+               ram_block3a_10.port_a_data_width = 1,
+               ram_block3a_10.port_a_first_address = 0,
+               ram_block3a_10.port_a_first_bit_number = 10,
+               ram_block3a_10.port_a_last_address = 4095,
+               ram_block3a_10.port_a_logical_ram_depth = 4096,
+               ram_block3a_10.port_a_logical_ram_width = 16,
+               ram_block3a_10.port_b_address_clear = "none",
+               ram_block3a_10.port_b_address_clock = "clock1",
+               ram_block3a_10.port_b_address_width = 12,
+               ram_block3a_10.port_b_data_out_clear = "none",
+               ram_block3a_10.port_b_data_out_clock = "none",
+               ram_block3a_10.port_b_data_width = 1,
+               ram_block3a_10.port_b_first_address = 0,
+               ram_block3a_10.port_b_first_bit_number = 10,
+               ram_block3a_10.port_b_last_address = 4095,
+               ram_block3a_10.port_b_logical_ram_depth = 4096,
+               ram_block3a_10.port_b_logical_ram_width = 16,
+               ram_block3a_10.port_b_read_enable_write_enable_clock = "clock1",
+               ram_block3a_10.ram_block_type = "auto",
+               ram_block3a_10.lpm_type = "cyclone_ram_block";
+       cyclone_ram_block   ram_block3a_11
+       ( 
+       .clk0(clock0),
+       .clk1(clock1),
+       .ena0(wren_a),
+       .ena1(clocken1),
+       .portaaddr({address_a_wire[11:0]}),
+       .portadatain({data_a[11]}),
+       .portadataout(),
+       .portawe(1'b1),
+       .portbaddr({address_b_wire[11:0]}),
+       .portbdataout(wire_ram_block3a_11portbdataout[0:0]),
+       .portbrewe(1'b1)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_off
+       `endif
+       ,
+       .clr0(1'b0),
+       .clr1(1'b0),
+       .portabyteenamasks(1'b1),
+       .portbbyteenamasks(1'b1),
+       .portbdatain(1'b0)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_on
+       `endif
+       // synopsys translate_off
+       ,
+       .devclrn(),
+       .devpor()
+       // synopsys translate_on
+       );
+       defparam
+               ram_block3a_11.connectivity_checking = "OFF",
+               ram_block3a_11.logical_ram_name = "ALTSYNCRAM",
+               ram_block3a_11.mixed_port_feed_through_mode = "dont_care",
+               ram_block3a_11.operation_mode = "dual_port",
+               ram_block3a_11.port_a_address_width = 12,
+               ram_block3a_11.port_a_data_width = 1,
+               ram_block3a_11.port_a_first_address = 0,
+               ram_block3a_11.port_a_first_bit_number = 11,
+               ram_block3a_11.port_a_last_address = 4095,
+               ram_block3a_11.port_a_logical_ram_depth = 4096,
+               ram_block3a_11.port_a_logical_ram_width = 16,
+               ram_block3a_11.port_b_address_clear = "none",
+               ram_block3a_11.port_b_address_clock = "clock1",
+               ram_block3a_11.port_b_address_width = 12,
+               ram_block3a_11.port_b_data_out_clear = "none",
+               ram_block3a_11.port_b_data_out_clock = "none",
+               ram_block3a_11.port_b_data_width = 1,
+               ram_block3a_11.port_b_first_address = 0,
+               ram_block3a_11.port_b_first_bit_number = 11,
+               ram_block3a_11.port_b_last_address = 4095,
+               ram_block3a_11.port_b_logical_ram_depth = 4096,
+               ram_block3a_11.port_b_logical_ram_width = 16,
+               ram_block3a_11.port_b_read_enable_write_enable_clock = "clock1",
+               ram_block3a_11.ram_block_type = "auto",
+               ram_block3a_11.lpm_type = "cyclone_ram_block";
+       cyclone_ram_block   ram_block3a_12
+       ( 
+       .clk0(clock0),
+       .clk1(clock1),
+       .ena0(wren_a),
+       .ena1(clocken1),
+       .portaaddr({address_a_wire[11:0]}),
+       .portadatain({data_a[12]}),
+       .portadataout(),
+       .portawe(1'b1),
+       .portbaddr({address_b_wire[11:0]}),
+       .portbdataout(wire_ram_block3a_12portbdataout[0:0]),
+       .portbrewe(1'b1)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_off
+       `endif
+       ,
+       .clr0(1'b0),
+       .clr1(1'b0),
+       .portabyteenamasks(1'b1),
+       .portbbyteenamasks(1'b1),
+       .portbdatain(1'b0)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_on
+       `endif
+       // synopsys translate_off
+       ,
+       .devclrn(),
+       .devpor()
+       // synopsys translate_on
+       );
+       defparam
+               ram_block3a_12.connectivity_checking = "OFF",
+               ram_block3a_12.logical_ram_name = "ALTSYNCRAM",
+               ram_block3a_12.mixed_port_feed_through_mode = "dont_care",
+               ram_block3a_12.operation_mode = "dual_port",
+               ram_block3a_12.port_a_address_width = 12,
+               ram_block3a_12.port_a_data_width = 1,
+               ram_block3a_12.port_a_first_address = 0,
+               ram_block3a_12.port_a_first_bit_number = 12,
+               ram_block3a_12.port_a_last_address = 4095,
+               ram_block3a_12.port_a_logical_ram_depth = 4096,
+               ram_block3a_12.port_a_logical_ram_width = 16,
+               ram_block3a_12.port_b_address_clear = "none",
+               ram_block3a_12.port_b_address_clock = "clock1",
+               ram_block3a_12.port_b_address_width = 12,
+               ram_block3a_12.port_b_data_out_clear = "none",
+               ram_block3a_12.port_b_data_out_clock = "none",
+               ram_block3a_12.port_b_data_width = 1,
+               ram_block3a_12.port_b_first_address = 0,
+               ram_block3a_12.port_b_first_bit_number = 12,
+               ram_block3a_12.port_b_last_address = 4095,
+               ram_block3a_12.port_b_logical_ram_depth = 4096,
+               ram_block3a_12.port_b_logical_ram_width = 16,
+               ram_block3a_12.port_b_read_enable_write_enable_clock = "clock1",
+               ram_block3a_12.ram_block_type = "auto",
+               ram_block3a_12.lpm_type = "cyclone_ram_block";
+       cyclone_ram_block   ram_block3a_13
+       ( 
+       .clk0(clock0),
+       .clk1(clock1),
+       .ena0(wren_a),
+       .ena1(clocken1),
+       .portaaddr({address_a_wire[11:0]}),
+       .portadatain({data_a[13]}),
+       .portadataout(),
+       .portawe(1'b1),
+       .portbaddr({address_b_wire[11:0]}),
+       .portbdataout(wire_ram_block3a_13portbdataout[0:0]),
+       .portbrewe(1'b1)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_off
+       `endif
+       ,
+       .clr0(1'b0),
+       .clr1(1'b0),
+       .portabyteenamasks(1'b1),
+       .portbbyteenamasks(1'b1),
+       .portbdatain(1'b0)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_on
+       `endif
+       // synopsys translate_off
+       ,
+       .devclrn(),
+       .devpor()
+       // synopsys translate_on
+       );
+       defparam
+               ram_block3a_13.connectivity_checking = "OFF",
+               ram_block3a_13.logical_ram_name = "ALTSYNCRAM",
+               ram_block3a_13.mixed_port_feed_through_mode = "dont_care",
+               ram_block3a_13.operation_mode = "dual_port",
+               ram_block3a_13.port_a_address_width = 12,
+               ram_block3a_13.port_a_data_width = 1,
+               ram_block3a_13.port_a_first_address = 0,
+               ram_block3a_13.port_a_first_bit_number = 13,
+               ram_block3a_13.port_a_last_address = 4095,
+               ram_block3a_13.port_a_logical_ram_depth = 4096,
+               ram_block3a_13.port_a_logical_ram_width = 16,
+               ram_block3a_13.port_b_address_clear = "none",
+               ram_block3a_13.port_b_address_clock = "clock1",
+               ram_block3a_13.port_b_address_width = 12,
+               ram_block3a_13.port_b_data_out_clear = "none",
+               ram_block3a_13.port_b_data_out_clock = "none",
+               ram_block3a_13.port_b_data_width = 1,
+               ram_block3a_13.port_b_first_address = 0,
+               ram_block3a_13.port_b_first_bit_number = 13,
+               ram_block3a_13.port_b_last_address = 4095,
+               ram_block3a_13.port_b_logical_ram_depth = 4096,
+               ram_block3a_13.port_b_logical_ram_width = 16,
+               ram_block3a_13.port_b_read_enable_write_enable_clock = "clock1",
+               ram_block3a_13.ram_block_type = "auto",
+               ram_block3a_13.lpm_type = "cyclone_ram_block";
+       cyclone_ram_block   ram_block3a_14
+       ( 
+       .clk0(clock0),
+       .clk1(clock1),
+       .ena0(wren_a),
+       .ena1(clocken1),
+       .portaaddr({address_a_wire[11:0]}),
+       .portadatain({data_a[14]}),
+       .portadataout(),
+       .portawe(1'b1),
+       .portbaddr({address_b_wire[11:0]}),
+       .portbdataout(wire_ram_block3a_14portbdataout[0:0]),
+       .portbrewe(1'b1)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_off
+       `endif
+       ,
+       .clr0(1'b0),
+       .clr1(1'b0),
+       .portabyteenamasks(1'b1),
+       .portbbyteenamasks(1'b1),
+       .portbdatain(1'b0)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_on
+       `endif
+       // synopsys translate_off
+       ,
+       .devclrn(),
+       .devpor()
+       // synopsys translate_on
+       );
+       defparam
+               ram_block3a_14.connectivity_checking = "OFF",
+               ram_block3a_14.logical_ram_name = "ALTSYNCRAM",
+               ram_block3a_14.mixed_port_feed_through_mode = "dont_care",
+               ram_block3a_14.operation_mode = "dual_port",
+               ram_block3a_14.port_a_address_width = 12,
+               ram_block3a_14.port_a_data_width = 1,
+               ram_block3a_14.port_a_first_address = 0,
+               ram_block3a_14.port_a_first_bit_number = 14,
+               ram_block3a_14.port_a_last_address = 4095,
+               ram_block3a_14.port_a_logical_ram_depth = 4096,
+               ram_block3a_14.port_a_logical_ram_width = 16,
+               ram_block3a_14.port_b_address_clear = "none",
+               ram_block3a_14.port_b_address_clock = "clock1",
+               ram_block3a_14.port_b_address_width = 12,
+               ram_block3a_14.port_b_data_out_clear = "none",
+               ram_block3a_14.port_b_data_out_clock = "none",
+               ram_block3a_14.port_b_data_width = 1,
+               ram_block3a_14.port_b_first_address = 0,
+               ram_block3a_14.port_b_first_bit_number = 14,
+               ram_block3a_14.port_b_last_address = 4095,
+               ram_block3a_14.port_b_logical_ram_depth = 4096,
+               ram_block3a_14.port_b_logical_ram_width = 16,
+               ram_block3a_14.port_b_read_enable_write_enable_clock = "clock1",
+               ram_block3a_14.ram_block_type = "auto",
+               ram_block3a_14.lpm_type = "cyclone_ram_block";
+       cyclone_ram_block   ram_block3a_15
+       ( 
+       .clk0(clock0),
+       .clk1(clock1),
+       .ena0(wren_a),
+       .ena1(clocken1),
+       .portaaddr({address_a_wire[11:0]}),
+       .portadatain({data_a[15]}),
+       .portadataout(),
+       .portawe(1'b1),
+       .portbaddr({address_b_wire[11:0]}),
+       .portbdataout(wire_ram_block3a_15portbdataout[0:0]),
+       .portbrewe(1'b1)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_off
+       `endif
+       ,
+       .clr0(1'b0),
+       .clr1(1'b0),
+       .portabyteenamasks(1'b1),
+       .portbbyteenamasks(1'b1),
+       .portbdatain(1'b0)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_on
+       `endif
+       // synopsys translate_off
+       ,
+       .devclrn(),
+       .devpor()
+       // synopsys translate_on
+       );
+       defparam
+               ram_block3a_15.connectivity_checking = "OFF",
+               ram_block3a_15.logical_ram_name = "ALTSYNCRAM",
+               ram_block3a_15.mixed_port_feed_through_mode = "dont_care",
+               ram_block3a_15.operation_mode = "dual_port",
+               ram_block3a_15.port_a_address_width = 12,
+               ram_block3a_15.port_a_data_width = 1,
+               ram_block3a_15.port_a_first_address = 0,
+               ram_block3a_15.port_a_first_bit_number = 15,
+               ram_block3a_15.port_a_last_address = 4095,
+               ram_block3a_15.port_a_logical_ram_depth = 4096,
+               ram_block3a_15.port_a_logical_ram_width = 16,
+               ram_block3a_15.port_b_address_clear = "none",
+               ram_block3a_15.port_b_address_clock = "clock1",
+               ram_block3a_15.port_b_address_width = 12,
+               ram_block3a_15.port_b_data_out_clear = "none",
+               ram_block3a_15.port_b_data_out_clock = "none",
+               ram_block3a_15.port_b_data_width = 1,
+               ram_block3a_15.port_b_first_address = 0,
+               ram_block3a_15.port_b_first_bit_number = 15,
+               ram_block3a_15.port_b_last_address = 4095,
+               ram_block3a_15.port_b_logical_ram_depth = 4096,
+               ram_block3a_15.port_b_logical_ram_width = 16,
+               ram_block3a_15.port_b_read_enable_write_enable_clock = "clock1",
+               ram_block3a_15.ram_block_type = "auto",
+               ram_block3a_15.lpm_type = "cyclone_ram_block";
+       assign
+               address_a_wire = address_a,
+               address_b_wire = address_b,
+               q_b = {wire_ram_block3a_15portbdataout[0], wire_ram_block3a_14portbdataout[0], wire_ram_block3a_13portbdataout[0], wire_ram_block3a_12portbdataout[0], wire_ram_block3a_11portbdataout[0], wire_ram_block3a_10portbdataout[0], wire_ram_block3a_9portbdataout[0], wire_ram_block3a_8portbdataout[0], wire_ram_block3a_7portbdataout[0], wire_ram_block3a_6portbdataout[0], wire_ram_block3a_5portbdataout[0], wire_ram_block3a_4portbdataout[0], wire_ram_block3a_3portbdataout[0], wire_ram_block3a_2portbdataout[0], wire_ram_block3a_1portbdataout[0], wire_ram_block3a_0portbdataout[0]};
+endmodule //fifo_4k_altsyncram_8pl
+
+
+//dffpipe DELAY=1 WIDTH=12 clock clrn d q
+//VERSION_BEGIN 5.0 cbx_mgl 2005:05:19:13:51:58:SJ cbx_stratixii 2004:12:22:13:27:12:SJ cbx_util_mgl 2005:04:04:13:50:06:SJ  VERSION_END
+
+//synthesis_resources = lut 12 
+//synopsys translate_off
+`timescale 1 ps / 1 ps
+//synopsys translate_on
+module  fifo_4k_dffpipe_bb3
+       ( 
+       clock,
+       clrn,
+       d,
+       q) /* synthesis synthesis_clearbox=1 */
+               /* synthesis ALTERA_ATTRIBUTE="AUTO_SHIFT_REGISTER_RECOGNITION=OFF" */;
+       input   clock;
+       input   clrn;
+       input   [11:0]  d;
+       output   [11:0]  q;
+
+       wire    [11:0]  wire_dffe4a_D;
+       reg     [11:0]  dffe4a;
+       wire ena;
+       wire prn;
+       wire sclr;
+
+       // synopsys translate_off
+       initial
+               dffe4a[0:0] = 0;
+       // synopsys translate_on
+       always @ ( posedge clock or  negedge prn or  negedge clrn)
+               if (prn == 1'b0) dffe4a[0:0] <= 1'b1;
+               else if (clrn == 1'b0) dffe4a[0:0] <= 1'b0;
+               else if  (ena == 1'b1)   dffe4a[0:0] <= wire_dffe4a_D[0:0];
+       // synopsys translate_off
+       initial
+               dffe4a[1:1] = 0;
+       // synopsys translate_on
+       always @ ( posedge clock or  negedge prn or  negedge clrn)
+               if (prn == 1'b0) dffe4a[1:1] <= 1'b1;
+               else if (clrn == 1'b0) dffe4a[1:1] <= 1'b0;
+               else if  (ena == 1'b1)   dffe4a[1:1] <= wire_dffe4a_D[1:1];
+       // synopsys translate_off
+       initial
+               dffe4a[2:2] = 0;
+       // synopsys translate_on
+       always @ ( posedge clock or  negedge prn or  negedge clrn)
+               if (prn == 1'b0) dffe4a[2:2] <= 1'b1;
+               else if (clrn == 1'b0) dffe4a[2:2] <= 1'b0;
+               else if  (ena == 1'b1)   dffe4a[2:2] <= wire_dffe4a_D[2:2];
+       // synopsys translate_off
+       initial
+               dffe4a[3:3] = 0;
+       // synopsys translate_on
+       always @ ( posedge clock or  negedge prn or  negedge clrn)
+               if (prn == 1'b0) dffe4a[3:3] <= 1'b1;
+               else if (clrn == 1'b0) dffe4a[3:3] <= 1'b0;
+               else if  (ena == 1'b1)   dffe4a[3:3] <= wire_dffe4a_D[3:3];
+       // synopsys translate_off
+       initial
+               dffe4a[4:4] = 0;
+       // synopsys translate_on
+       always @ ( posedge clock or  negedge prn or  negedge clrn)
+               if (prn == 1'b0) dffe4a[4:4] <= 1'b1;
+               else if (clrn == 1'b0) dffe4a[4:4] <= 1'b0;
+               else if  (ena == 1'b1)   dffe4a[4:4] <= wire_dffe4a_D[4:4];
+       // synopsys translate_off
+       initial
+               dffe4a[5:5] = 0;
+       // synopsys translate_on
+       always @ ( posedge clock or  negedge prn or  negedge clrn)
+               if (prn == 1'b0) dffe4a[5:5] <= 1'b1;
+               else if (clrn == 1'b0) dffe4a[5:5] <= 1'b0;
+               else if  (ena == 1'b1)   dffe4a[5:5] <= wire_dffe4a_D[5:5];
+       // synopsys translate_off
+       initial
+               dffe4a[6:6] = 0;
+       // synopsys translate_on
+       always @ ( posedge clock or  negedge prn or  negedge clrn)
+               if (prn == 1'b0) dffe4a[6:6] <= 1'b1;
+               else if (clrn == 1'b0) dffe4a[6:6] <= 1'b0;
+               else if  (ena == 1'b1)   dffe4a[6:6] <= wire_dffe4a_D[6:6];
+       // synopsys translate_off
+       initial
+               dffe4a[7:7] = 0;
+       // synopsys translate_on
+       always @ ( posedge clock or  negedge prn or  negedge clrn)
+               if (prn == 1'b0) dffe4a[7:7] <= 1'b1;
+               else if (clrn == 1'b0) dffe4a[7:7] <= 1'b0;
+               else if  (ena == 1'b1)   dffe4a[7:7] <= wire_dffe4a_D[7:7];
+       // synopsys translate_off
+       initial
+               dffe4a[8:8] = 0;
+       // synopsys translate_on
+       always @ ( posedge clock or  negedge prn or  negedge clrn)
+               if (prn == 1'b0) dffe4a[8:8] <= 1'b1;
+               else if (clrn == 1'b0) dffe4a[8:8] <= 1'b0;
+               else if  (ena == 1'b1)   dffe4a[8:8] <= wire_dffe4a_D[8:8];
+       // synopsys translate_off
+       initial
+               dffe4a[9:9] = 0;
+       // synopsys translate_on
+       always @ ( posedge clock or  negedge prn or  negedge clrn)
+               if (prn == 1'b0) dffe4a[9:9] <= 1'b1;
+               else if (clrn == 1'b0) dffe4a[9:9] <= 1'b0;
+               else if  (ena == 1'b1)   dffe4a[9:9] <= wire_dffe4a_D[9:9];
+       // synopsys translate_off
+       initial
+               dffe4a[10:10] = 0;
+       // synopsys translate_on
+       always @ ( posedge clock or  negedge prn or  negedge clrn)
+               if (prn == 1'b0) dffe4a[10:10] <= 1'b1;
+               else if (clrn == 1'b0) dffe4a[10:10] <= 1'b0;
+               else if  (ena == 1'b1)   dffe4a[10:10] <= wire_dffe4a_D[10:10];
+       // synopsys translate_off
+       initial
+               dffe4a[11:11] = 0;
+       // synopsys translate_on
+       always @ ( posedge clock or  negedge prn or  negedge clrn)
+               if (prn == 1'b0) dffe4a[11:11] <= 1'b1;
+               else if (clrn == 1'b0) dffe4a[11:11] <= 1'b0;
+               else if  (ena == 1'b1)   dffe4a[11:11] <= wire_dffe4a_D[11:11];
+       assign
+               wire_dffe4a_D = (d & {12{(~ sclr)}});
+       assign
+               ena = 1'b1,
+               prn = 1'b1,
+               q = dffe4a,
+               sclr = 1'b0;
+endmodule //fifo_4k_dffpipe_bb3
+
+
+//dffpipe WIDTH=12 clock clrn d q
+//VERSION_BEGIN 5.0 cbx_a_gray2bin 2004:03:06:00:52:20:SJ cbx_a_graycounter 2004:10:01:12:13:16:SJ cbx_altdpram 2004:11:30:11:29:56:SJ cbx_altsyncram 2005:03:24:13:58:56:SJ cbx_cycloneii 2004:12:20:14:28:52:SJ cbx_dcfifo 2005:03:07:17:11:14:SJ cbx_fifo_common 2004:12:13:14:26:24:SJ cbx_flex10ke 2002:10:18:16:54:38:SJ cbx_lpm_add_sub 2005:04:12:13:30:42:SJ cbx_lpm_compare 2004:11:30:11:30:40:SJ cbx_lpm_counter 2005:02:02:04:37:10:SJ cbx_lpm_decode 2004:12:13:14:19:12:SJ cbx_lpm_mux 2004:12:13:14:16:38:SJ cbx_mgl 2005:05:19:13:51:58:SJ cbx_scfifo 2005:03:10:10:52:20:SJ cbx_stratix 2005:06:02:09:53:04:SJ cbx_stratixii 2004:12:22:13:27:12:SJ cbx_util_mgl 2005:04:04:13:50:06:SJ  VERSION_END
+
+
+//dffpipe WIDTH=12 clock clrn d q
+//VERSION_BEGIN 5.0 cbx_mgl 2005:05:19:13:51:58:SJ cbx_stratixii 2004:12:22:13:27:12:SJ cbx_util_mgl 2005:04:04:13:50:06:SJ  VERSION_END
+
+//synthesis_resources = lut 12 
+//synopsys translate_off
+`timescale 1 ps / 1 ps
+//synopsys translate_on
+module  fifo_4k_dffpipe_em2
+       ( 
+       clock,
+       clrn,
+       d,
+       q) /* synthesis synthesis_clearbox=1 */
+               /* synthesis ALTERA_ATTRIBUTE="AUTO_SHIFT_REGISTER_RECOGNITION=OFF" */;
+       input   clock;
+       input   clrn;
+       input   [11:0]  d;
+       output   [11:0]  q;
+
+       wire    [11:0]  wire_dffe6a_D;
+       reg     [11:0]  dffe6a;
+       wire ena;
+       wire prn;
+       wire sclr;
+
+       // synopsys translate_off
+       initial
+               dffe6a[0:0] = 0;
+       // synopsys translate_on
+       always @ ( posedge clock or  negedge prn or  negedge clrn)
+               if (prn == 1'b0) dffe6a[0:0] <= 1'b1;
+               else if (clrn == 1'b0) dffe6a[0:0] <= 1'b0;
+               else if  (ena == 1'b1)   dffe6a[0:0] <= wire_dffe6a_D[0:0];
+       // synopsys translate_off
+       initial
+               dffe6a[1:1] = 0;
+       // synopsys translate_on
+       always @ ( posedge clock or  negedge prn or  negedge clrn)
+               if (prn == 1'b0) dffe6a[1:1] <= 1'b1;
+               else if (clrn == 1'b0) dffe6a[1:1] <= 1'b0;
+               else if  (ena == 1'b1)   dffe6a[1:1] <= wire_dffe6a_D[1:1];
+       // synopsys translate_off
+       initial
+               dffe6a[2:2] = 0;
+       // synopsys translate_on
+       always @ ( posedge clock or  negedge prn or  negedge clrn)
+               if (prn == 1'b0) dffe6a[2:2] <= 1'b1;
+               else if (clrn == 1'b0) dffe6a[2:2] <= 1'b0;
+               else if  (ena == 1'b1)   dffe6a[2:2] <= wire_dffe6a_D[2:2];
+       // synopsys translate_off
+       initial
+               dffe6a[3:3] = 0;
+       // synopsys translate_on
+       always @ ( posedge clock or  negedge prn or  negedge clrn)
+               if (prn == 1'b0) dffe6a[3:3] <= 1'b1;
+               else if (clrn == 1'b0) dffe6a[3:3] <= 1'b0;
+               else if  (ena == 1'b1)   dffe6a[3:3] <= wire_dffe6a_D[3:3];
+       // synopsys translate_off
+       initial
+               dffe6a[4:4] = 0;
+       // synopsys translate_on
+       always @ ( posedge clock or  negedge prn or  negedge clrn)
+               if (prn == 1'b0) dffe6a[4:4] <= 1'b1;
+               else if (clrn == 1'b0) dffe6a[4:4] <= 1'b0;
+               else if  (ena == 1'b1)   dffe6a[4:4] <= wire_dffe6a_D[4:4];
+       // synopsys translate_off
+       initial
+               dffe6a[5:5] = 0;
+       // synopsys translate_on
+       always @ ( posedge clock or  negedge prn or  negedge clrn)
+               if (prn == 1'b0) dffe6a[5:5] <= 1'b1;
+               else if (clrn == 1'b0) dffe6a[5:5] <= 1'b0;
+               else if  (ena == 1'b1)   dffe6a[5:5] <= wire_dffe6a_D[5:5];
+       // synopsys translate_off
+       initial
+               dffe6a[6:6] = 0;
+       // synopsys translate_on
+       always @ ( posedge clock or  negedge prn or  negedge clrn)
+               if (prn == 1'b0) dffe6a[6:6] <= 1'b1;
+               else if (clrn == 1'b0) dffe6a[6:6] <= 1'b0;
+               else if  (ena == 1'b1)   dffe6a[6:6] <= wire_dffe6a_D[6:6];
+       // synopsys translate_off
+       initial
+               dffe6a[7:7] = 0;
+       // synopsys translate_on
+       always @ ( posedge clock or  negedge prn or  negedge clrn)
+               if (prn == 1'b0) dffe6a[7:7] <= 1'b1;
+               else if (clrn == 1'b0) dffe6a[7:7] <= 1'b0;
+               else if  (ena == 1'b1)   dffe6a[7:7] <= wire_dffe6a_D[7:7];
+       // synopsys translate_off
+       initial
+               dffe6a[8:8] = 0;
+       // synopsys translate_on
+       always @ ( posedge clock or  negedge prn or  negedge clrn)
+               if (prn == 1'b0) dffe6a[8:8] <= 1'b1;
+               else if (clrn == 1'b0) dffe6a[8:8] <= 1'b0;
+               else if  (ena == 1'b1)   dffe6a[8:8] <= wire_dffe6a_D[8:8];
+       // synopsys translate_off
+       initial
+               dffe6a[9:9] = 0;
+       // synopsys translate_on
+       always @ ( posedge clock or  negedge prn or  negedge clrn)
+               if (prn == 1'b0) dffe6a[9:9] <= 1'b1;
+               else if (clrn == 1'b0) dffe6a[9:9] <= 1'b0;
+               else if  (ena == 1'b1)   dffe6a[9:9] <= wire_dffe6a_D[9:9];
+       // synopsys translate_off
+       initial
+               dffe6a[10:10] = 0;
+       // synopsys translate_on
+       always @ ( posedge clock or  negedge prn or  negedge clrn)
+               if (prn == 1'b0) dffe6a[10:10] <= 1'b1;
+               else if (clrn == 1'b0) dffe6a[10:10] <= 1'b0;
+               else if  (ena == 1'b1)   dffe6a[10:10] <= wire_dffe6a_D[10:10];
+       // synopsys translate_off
+       initial
+               dffe6a[11:11] = 0;
+       // synopsys translate_on
+       always @ ( posedge clock or  negedge prn or  negedge clrn)
+               if (prn == 1'b0) dffe6a[11:11] <= 1'b1;
+               else if (clrn == 1'b0) dffe6a[11:11] <= 1'b0;
+               else if  (ena == 1'b1)   dffe6a[11:11] <= wire_dffe6a_D[11:11];
+       assign
+               wire_dffe6a_D = (d & {12{(~ sclr)}});
+       assign
+               ena = 1'b1,
+               prn = 1'b1,
+               q = dffe6a,
+               sclr = 1'b0;
+endmodule //fifo_4k_dffpipe_em2
+
+//synthesis_resources = lut 12 
+//synopsys translate_off
+`timescale 1 ps / 1 ps
+//synopsys translate_on
+module  fifo_4k_alt_synch_pipe_em2
+       ( 
+       clock,
+       clrn,
+       d,
+       q) /* synthesis synthesis_clearbox=1 */
+               /* synthesis ALTERA_ATTRIBUTE="X_ON_VIOLATION_OPTION=OFF" */;
+       input   clock;
+       input   clrn;
+       input   [11:0]  d;
+       output   [11:0]  q;
+
+       wire  [11:0]   wire_dffpipe5_q;
+
+       fifo_4k_dffpipe_em2   dffpipe5
+       ( 
+       .clock(clock),
+       .clrn(clrn),
+       .d(d),
+       .q(wire_dffpipe5_q));
+       assign
+               q = wire_dffpipe5_q;
+endmodule //fifo_4k_alt_synch_pipe_em2
+
+
+//lpm_add_sub DEVICE_FAMILY="Cyclone" LPM_DIRECTION="SUB" LPM_WIDTH=12 dataa datab result
+//VERSION_BEGIN 5.0 cbx_cycloneii 2004:12:20:14:28:52:SJ cbx_lpm_add_sub 2005:04:12:13:30:42:SJ cbx_mgl 2005:05:19:13:51:58:SJ cbx_stratix 2005:06:02:09:53:04:SJ cbx_stratixii 2004:12:22:13:27:12:SJ  VERSION_END
+
+//synthesis_resources = lut 12 
+//synopsys translate_off
+`timescale 1 ps / 1 ps
+//synopsys translate_on
+module  fifo_4k_add_sub_b18
+       ( 
+       dataa,
+       datab,
+       result) /* synthesis synthesis_clearbox=1 */;
+       input   [11:0]  dataa;
+       input   [11:0]  datab;
+       output   [11:0]  result;
+
+       wire  [11:0]   wire_add_sub_cella_combout;
+       wire  [0:0]   wire_add_sub_cella_0cout;
+       wire  [0:0]   wire_add_sub_cella_1cout;
+       wire  [0:0]   wire_add_sub_cella_2cout;
+       wire  [0:0]   wire_add_sub_cella_3cout;
+       wire  [0:0]   wire_add_sub_cella_4cout;
+       wire  [0:0]   wire_add_sub_cella_5cout;
+       wire  [0:0]   wire_add_sub_cella_6cout;
+       wire  [0:0]   wire_add_sub_cella_7cout;
+       wire  [0:0]   wire_add_sub_cella_8cout;
+       wire  [0:0]   wire_add_sub_cella_9cout;
+       wire  [0:0]   wire_add_sub_cella_10cout;
+       wire  [11:0]   wire_add_sub_cella_dataa;
+       wire  [11:0]   wire_add_sub_cella_datab;
+
+       cyclone_lcell   add_sub_cella_0
+       ( 
+       .cin(1'b1),
+       .combout(wire_add_sub_cella_combout[0:0]),
+       .cout(wire_add_sub_cella_0cout[0:0]),
+       .dataa(wire_add_sub_cella_dataa[0:0]),
+       .datab(wire_add_sub_cella_datab[0:0]),
+       .regout()
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_off
+       `endif
+       ,
+       .aclr(1'b0),
+       .aload(1'b0),
+       .clk(1'b1),
+       .datac(1'b1),
+       .datad(1'b1),
+       .ena(1'b1),
+       .inverta(1'b0),
+       .regcascin(1'b0),
+       .sclr(1'b0),
+       .sload(1'b0)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_on
+       `endif
+       // synopsys translate_off
+       ,
+       .cin0(),
+       .cin1(),
+       .cout0(),
+       .cout1(),
+       .devclrn(),
+       .devpor()
+       // synopsys translate_on
+       );
+       defparam
+               add_sub_cella_0.cin_used = "true",
+               add_sub_cella_0.lut_mask = "69b2",
+               add_sub_cella_0.operation_mode = "arithmetic",
+               add_sub_cella_0.sum_lutc_input = "cin",
+               add_sub_cella_0.lpm_type = "cyclone_lcell";
+       cyclone_lcell   add_sub_cella_1
+       ( 
+       .cin(wire_add_sub_cella_0cout[0:0]),
+       .combout(wire_add_sub_cella_combout[1:1]),
+       .cout(wire_add_sub_cella_1cout[0:0]),
+       .dataa(wire_add_sub_cella_dataa[1:1]),
+       .datab(wire_add_sub_cella_datab[1:1]),
+       .regout()
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_off
+       `endif
+       ,
+       .aclr(1'b0),
+       .aload(1'b0),
+       .clk(1'b1),
+       .datac(1'b1),
+       .datad(1'b1),
+       .ena(1'b1),
+       .inverta(1'b0),
+       .regcascin(1'b0),
+       .sclr(1'b0),
+       .sload(1'b0)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_on
+       `endif
+       // synopsys translate_off
+       ,
+       .cin0(),
+       .cin1(),
+       .cout0(),
+       .cout1(),
+       .devclrn(),
+       .devpor()
+       // synopsys translate_on
+       );
+       defparam
+               add_sub_cella_1.cin_used = "true",
+               add_sub_cella_1.lut_mask = "69b2",
+               add_sub_cella_1.operation_mode = "arithmetic",
+               add_sub_cella_1.sum_lutc_input = "cin",
+               add_sub_cella_1.lpm_type = "cyclone_lcell";
+       cyclone_lcell   add_sub_cella_2
+       ( 
+       .cin(wire_add_sub_cella_1cout[0:0]),
+       .combout(wire_add_sub_cella_combout[2:2]),
+       .cout(wire_add_sub_cella_2cout[0:0]),
+       .dataa(wire_add_sub_cella_dataa[2:2]),
+       .datab(wire_add_sub_cella_datab[2:2]),
+       .regout()
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_off
+       `endif
+       ,
+       .aclr(1'b0),
+       .aload(1'b0),
+       .clk(1'b1),
+       .datac(1'b1),
+       .datad(1'b1),
+       .ena(1'b1),
+       .inverta(1'b0),
+       .regcascin(1'b0),
+       .sclr(1'b0),
+       .sload(1'b0)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_on
+       `endif
+       // synopsys translate_off
+       ,
+       .cin0(),
+       .cin1(),
+       .cout0(),
+       .cout1(),
+       .devclrn(),
+       .devpor()
+       // synopsys translate_on
+       );
+       defparam
+               add_sub_cella_2.cin_used = "true",
+               add_sub_cella_2.lut_mask = "69b2",
+               add_sub_cella_2.operation_mode = "arithmetic",
+               add_sub_cella_2.sum_lutc_input = "cin",
+               add_sub_cella_2.lpm_type = "cyclone_lcell";
+       cyclone_lcell   add_sub_cella_3
+       ( 
+       .cin(wire_add_sub_cella_2cout[0:0]),
+       .combout(wire_add_sub_cella_combout[3:3]),
+       .cout(wire_add_sub_cella_3cout[0:0]),
+       .dataa(wire_add_sub_cella_dataa[3:3]),
+       .datab(wire_add_sub_cella_datab[3:3]),
+       .regout()
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_off
+       `endif
+       ,
+       .aclr(1'b0),
+       .aload(1'b0),
+       .clk(1'b1),
+       .datac(1'b1),
+       .datad(1'b1),
+       .ena(1'b1),
+       .inverta(1'b0),
+       .regcascin(1'b0),
+       .sclr(1'b0),
+       .sload(1'b0)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_on
+       `endif
+       // synopsys translate_off
+       ,
+       .cin0(),
+       .cin1(),
+       .cout0(),
+       .cout1(),
+       .devclrn(),
+       .devpor()
+       // synopsys translate_on
+       );
+       defparam
+               add_sub_cella_3.cin_used = "true",
+               add_sub_cella_3.lut_mask = "69b2",
+               add_sub_cella_3.operation_mode = "arithmetic",
+               add_sub_cella_3.sum_lutc_input = "cin",
+               add_sub_cella_3.lpm_type = "cyclone_lcell";
+       cyclone_lcell   add_sub_cella_4
+       ( 
+       .cin(wire_add_sub_cella_3cout[0:0]),
+       .combout(wire_add_sub_cella_combout[4:4]),
+       .cout(wire_add_sub_cella_4cout[0:0]),
+       .dataa(wire_add_sub_cella_dataa[4:4]),
+       .datab(wire_add_sub_cella_datab[4:4]),
+       .regout()
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_off
+       `endif
+       ,
+       .aclr(1'b0),
+       .aload(1'b0),
+       .clk(1'b1),
+       .datac(1'b1),
+       .datad(1'b1),
+       .ena(1'b1),
+       .inverta(1'b0),
+       .regcascin(1'b0),
+       .sclr(1'b0),
+       .sload(1'b0)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_on
+       `endif
+       // synopsys translate_off
+       ,
+       .cin0(),
+       .cin1(),
+       .cout0(),
+       .cout1(),
+       .devclrn(),
+       .devpor()
+       // synopsys translate_on
+       );
+       defparam
+               add_sub_cella_4.cin_used = "true",
+               add_sub_cella_4.lut_mask = "69b2",
+               add_sub_cella_4.operation_mode = "arithmetic",
+               add_sub_cella_4.sum_lutc_input = "cin",
+               add_sub_cella_4.lpm_type = "cyclone_lcell";
+       cyclone_lcell   add_sub_cella_5
+       ( 
+       .cin(wire_add_sub_cella_4cout[0:0]),
+       .combout(wire_add_sub_cella_combout[5:5]),
+       .cout(wire_add_sub_cella_5cout[0:0]),
+       .dataa(wire_add_sub_cella_dataa[5:5]),
+       .datab(wire_add_sub_cella_datab[5:5]),
+       .regout()
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_off
+       `endif
+       ,
+       .aclr(1'b0),
+       .aload(1'b0),
+       .clk(1'b1),
+       .datac(1'b1),
+       .datad(1'b1),
+       .ena(1'b1),
+       .inverta(1'b0),
+       .regcascin(1'b0),
+       .sclr(1'b0),
+       .sload(1'b0)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_on
+       `endif
+       // synopsys translate_off
+       ,
+       .cin0(),
+       .cin1(),
+       .cout0(),
+       .cout1(),
+       .devclrn(),
+       .devpor()
+       // synopsys translate_on
+       );
+       defparam
+               add_sub_cella_5.cin_used = "true",
+               add_sub_cella_5.lut_mask = "69b2",
+               add_sub_cella_5.operation_mode = "arithmetic",
+               add_sub_cella_5.sum_lutc_input = "cin",
+               add_sub_cella_5.lpm_type = "cyclone_lcell";
+       cyclone_lcell   add_sub_cella_6
+       ( 
+       .cin(wire_add_sub_cella_5cout[0:0]),
+       .combout(wire_add_sub_cella_combout[6:6]),
+       .cout(wire_add_sub_cella_6cout[0:0]),
+       .dataa(wire_add_sub_cella_dataa[6:6]),
+       .datab(wire_add_sub_cella_datab[6:6]),
+       .regout()
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_off
+       `endif
+       ,
+       .aclr(1'b0),
+       .aload(1'b0),
+       .clk(1'b1),
+       .datac(1'b1),
+       .datad(1'b1),
+       .ena(1'b1),
+       .inverta(1'b0),
+       .regcascin(1'b0),
+       .sclr(1'b0),
+       .sload(1'b0)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_on
+       `endif
+       // synopsys translate_off
+       ,
+       .cin0(),
+       .cin1(),
+       .cout0(),
+       .cout1(),
+       .devclrn(),
+       .devpor()
+       // synopsys translate_on
+       );
+       defparam
+               add_sub_cella_6.cin_used = "true",
+               add_sub_cella_6.lut_mask = "69b2",
+               add_sub_cella_6.operation_mode = "arithmetic",
+               add_sub_cella_6.sum_lutc_input = "cin",
+               add_sub_cella_6.lpm_type = "cyclone_lcell";
+       cyclone_lcell   add_sub_cella_7
+       ( 
+       .cin(wire_add_sub_cella_6cout[0:0]),
+       .combout(wire_add_sub_cella_combout[7:7]),
+       .cout(wire_add_sub_cella_7cout[0:0]),
+       .dataa(wire_add_sub_cella_dataa[7:7]),
+       .datab(wire_add_sub_cella_datab[7:7]),
+       .regout()
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_off
+       `endif
+       ,
+       .aclr(1'b0),
+       .aload(1'b0),
+       .clk(1'b1),
+       .datac(1'b1),
+       .datad(1'b1),
+       .ena(1'b1),
+       .inverta(1'b0),
+       .regcascin(1'b0),
+       .sclr(1'b0),
+       .sload(1'b0)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_on
+       `endif
+       // synopsys translate_off
+       ,
+       .cin0(),
+       .cin1(),
+       .cout0(),
+       .cout1(),
+       .devclrn(),
+       .devpor()
+       // synopsys translate_on
+       );
+       defparam
+               add_sub_cella_7.cin_used = "true",
+               add_sub_cella_7.lut_mask = "69b2",
+               add_sub_cella_7.operation_mode = "arithmetic",
+               add_sub_cella_7.sum_lutc_input = "cin",
+               add_sub_cella_7.lpm_type = "cyclone_lcell";
+       cyclone_lcell   add_sub_cella_8
+       ( 
+       .cin(wire_add_sub_cella_7cout[0:0]),
+       .combout(wire_add_sub_cella_combout[8:8]),
+       .cout(wire_add_sub_cella_8cout[0:0]),
+       .dataa(wire_add_sub_cella_dataa[8:8]),
+       .datab(wire_add_sub_cella_datab[8:8]),
+       .regout()
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_off
+       `endif
+       ,
+       .aclr(1'b0),
+       .aload(1'b0),
+       .clk(1'b1),
+       .datac(1'b1),
+       .datad(1'b1),
+       .ena(1'b1),
+       .inverta(1'b0),
+       .regcascin(1'b0),
+       .sclr(1'b0),
+       .sload(1'b0)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_on
+       `endif
+       // synopsys translate_off
+       ,
+       .cin0(),
+       .cin1(),
+       .cout0(),
+       .cout1(),
+       .devclrn(),
+       .devpor()
+       // synopsys translate_on
+       );
+       defparam
+               add_sub_cella_8.cin_used = "true",
+               add_sub_cella_8.lut_mask = "69b2",
+               add_sub_cella_8.operation_mode = "arithmetic",
+               add_sub_cella_8.sum_lutc_input = "cin",
+               add_sub_cella_8.lpm_type = "cyclone_lcell";
+       cyclone_lcell   add_sub_cella_9
+       ( 
+       .cin(wire_add_sub_cella_8cout[0:0]),
+       .combout(wire_add_sub_cella_combout[9:9]),
+       .cout(wire_add_sub_cella_9cout[0:0]),
+       .dataa(wire_add_sub_cella_dataa[9:9]),
+       .datab(wire_add_sub_cella_datab[9:9]),
+       .regout()
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_off
+       `endif
+       ,
+       .aclr(1'b0),
+       .aload(1'b0),
+       .clk(1'b1),
+       .datac(1'b1),
+       .datad(1'b1),
+       .ena(1'b1),
+       .inverta(1'b0),
+       .regcascin(1'b0),
+       .sclr(1'b0),
+       .sload(1'b0)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_on
+       `endif
+       // synopsys translate_off
+       ,
+       .cin0(),
+       .cin1(),
+       .cout0(),
+       .cout1(),
+       .devclrn(),
+       .devpor()
+       // synopsys translate_on
+       );
+       defparam
+               add_sub_cella_9.cin_used = "true",
+               add_sub_cella_9.lut_mask = "69b2",
+               add_sub_cella_9.operation_mode = "arithmetic",
+               add_sub_cella_9.sum_lutc_input = "cin",
+               add_sub_cella_9.lpm_type = "cyclone_lcell";
+       cyclone_lcell   add_sub_cella_10
+       ( 
+       .cin(wire_add_sub_cella_9cout[0:0]),
+       .combout(wire_add_sub_cella_combout[10:10]),
+       .cout(wire_add_sub_cella_10cout[0:0]),
+       .dataa(wire_add_sub_cella_dataa[10:10]),
+       .datab(wire_add_sub_cella_datab[10:10]),
+       .regout()
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_off
+       `endif
+       ,
+       .aclr(1'b0),
+       .aload(1'b0),
+       .clk(1'b1),
+       .datac(1'b1),
+       .datad(1'b1),
+       .ena(1'b1),
+       .inverta(1'b0),
+       .regcascin(1'b0),
+       .sclr(1'b0),
+       .sload(1'b0)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_on
+       `endif
+       // synopsys translate_off
+       ,
+       .cin0(),
+       .cin1(),
+       .cout0(),
+       .cout1(),
+       .devclrn(),
+       .devpor()
+       // synopsys translate_on
+       );
+       defparam
+               add_sub_cella_10.cin_used = "true",
+               add_sub_cella_10.lut_mask = "69b2",
+               add_sub_cella_10.operation_mode = "arithmetic",
+               add_sub_cella_10.sum_lutc_input = "cin",
+               add_sub_cella_10.lpm_type = "cyclone_lcell";
+       cyclone_lcell   add_sub_cella_11
+       ( 
+       .cin(wire_add_sub_cella_10cout[0:0]),
+       .combout(wire_add_sub_cella_combout[11:11]),
+       .cout(),
+       .dataa(wire_add_sub_cella_dataa[11:11]),
+       .datab(wire_add_sub_cella_datab[11:11]),
+       .regout()
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_off
+       `endif
+       ,
+       .aclr(1'b0),
+       .aload(1'b0),
+       .clk(1'b1),
+       .datac(1'b1),
+       .datad(1'b1),
+       .ena(1'b1),
+       .inverta(1'b0),
+       .regcascin(1'b0),
+       .sclr(1'b0),
+       .sload(1'b0)
+       `ifdef FORMAL_VERIFICATION
+       `else
+       // synopsys translate_on
+       `endif
+       // synopsys translate_off
+       ,
+       .cin0(),
+       .cin1(),
+       .cout0(),
+       .cout1(),
+       .devclrn(),
+       .devpor()
+       // synopsys translate_on
+       );
+       defparam
+               add_sub_cella_11.cin_used = "true",
+               add_sub_cella_11.lut_mask = "6969",
+               add_sub_cella_11.operation_mode = "normal",
+               add_sub_cella_11.sum_lutc_input = "cin",
+               add_sub_cella_11.lpm_type = "cyclone_lcell";
+       assign
+               wire_add_sub_cella_dataa = dataa,
+               wire_add_sub_cella_datab = datab;
+       assign
+               result = wire_add_sub_cella_combout;
+endmodule //fifo_4k_add_sub_b18
+
+
+//lpm_compare DEVICE_FAMILY="Cyclone" LPM_WIDTH=12 aeb dataa datab
+//VERSION_BEGIN 5.0 cbx_cycloneii 2004:12:20:14:28:52:SJ cbx_lpm_add_sub 2005:04:12:13:30:42:SJ cbx_lpm_compare 2004:11:30:11:30:40:SJ cbx_mgl 2005:05:19:13:51:58:SJ cbx_stratix 2005:06:02:09:53:04:SJ cbx_stratixii 2004:12:22:13:27:12:SJ  VERSION_END
+
+
+//lpm_compare DEVICE_FAMILY="Cyclone" LPM_WIDTH=12 aeb dataa datab
+//VERSION_BEGIN 5.0 cbx_cycloneii 2004:12:20:14:28:52:SJ cbx_lpm_add_sub 2005:04:12:13:30:42:SJ cbx_lpm_compare 2004:11:30:11:30:40:SJ cbx_mgl 2005:05:19:13:51:58:SJ cbx_stratix 2005:06:02:09:53:04:SJ cbx_stratixii 2004:12:22:13:27:12:SJ  VERSION_END
+
+//synthesis_resources = lut 104 M4K 16 
+//synopsys translate_off
+`timescale 1 ps / 1 ps
+//synopsys translate_on
+module  fifo_4k_dcfifo_6cq
+       ( 
+       aclr,
+       data,
+       q,
+       rdclk,
+       rdempty,
+       rdreq,
+       rdusedw,
+       wrclk,
+       wrfull,
+       wrreq,
+       wrusedw) /* synthesis synthesis_clearbox=1 */
+               /* synthesis ALTERA_ATTRIBUTE="AUTO_SHIFT_REGISTER_RECOGNITION=OFF;{ -from \"rdptr_g|power_modified_counter_values\" -to \"ws_dgrp|dffpipe5|dffe6a\" }CUT=ON;{ -from \"delayed_wrptr_g\" -to \"rs_dgwp|dffpipe5|dffe6a\" }CUT=ON" */;
+       input   aclr;
+       input   [15:0]  data;
+       output   [15:0]  q;
+       input   rdclk;
+       output   rdempty;
+       input   rdreq;
+       output   [11:0]  rdusedw;
+       input   wrclk;
+       output   wrfull;
+       input   wrreq;
+       output   [11:0]  wrusedw;
+
+       wire  [11:0]   wire_rdptr_g_gray2bin_bin;
+       wire  [11:0]   wire_rs_dgwp_gray2bin_bin;
+       wire  [11:0]   wire_wrptr_g_gray2bin_bin;
+       wire  [11:0]   wire_ws_dgrp_gray2bin_bin;
+       wire  [11:0]   wire_rdptr_g_q;
+       wire  [11:0]   wire_rdptr_g1p_q;
+       wire  [11:0]   wire_wrptr_g1p_q;
+       wire  [15:0]   wire_fifo_ram_q_b;
+       reg     [11:0]  delayed_wrptr_g;
+       reg     [11:0]  wrptr_g;
+       wire  [11:0]   wire_rs_brp_q;
+       wire  [11:0]   wire_rs_bwp_q;
+       wire  [11:0]   wire_rs_dgwp_q;
+       wire  [11:0]   wire_ws_brp_q;
+       wire  [11:0]   wire_ws_bwp_q;
+       wire  [11:0]   wire_ws_dgrp_q;
+       wire  [11:0]   wire_rdusedw_sub_result;
+       wire  [11:0]   wire_wrusedw_sub_result;
+       reg     wire_rdempty_eq_comp_aeb_int;
+       wire    wire_rdempty_eq_comp_aeb;
+       wire    [11:0]  wire_rdempty_eq_comp_dataa;
+       wire    [11:0]  wire_rdempty_eq_comp_datab;
+       reg     wire_wrfull_eq_comp_aeb_int;
+       wire    wire_wrfull_eq_comp_aeb;
+       wire    [11:0]  wire_wrfull_eq_comp_dataa;
+       wire    [11:0]  wire_wrfull_eq_comp_datab;
+       wire  int_rdempty;
+       wire  int_wrfull;
+       wire  valid_rdreq;
+       wire  valid_wrreq;
+
+       fifo_4k_a_gray2bin_9m4   rdptr_g_gray2bin
+       ( 
+       .bin(wire_rdptr_g_gray2bin_bin),
+       .gray(wire_rdptr_g_q));
+       fifo_4k_a_gray2bin_9m4   rs_dgwp_gray2bin
+       ( 
+       .bin(wire_rs_dgwp_gray2bin_bin),
+       .gray(wire_rs_dgwp_q));
+       fifo_4k_a_gray2bin_9m4   wrptr_g_gray2bin
+       ( 
+       .bin(wire_wrptr_g_gray2bin_bin),
+       .gray(wrptr_g));
+       fifo_4k_a_gray2bin_9m4   ws_dgrp_gray2bin
+       ( 
+       .bin(wire_ws_dgrp_gray2bin_bin),
+       .gray(wire_ws_dgrp_q));
+       fifo_4k_a_graycounter_826   rdptr_g
+       ( 
+       .aclr(aclr),
+       .clock(rdclk),
+       .cnt_en(valid_rdreq),
+       .q(wire_rdptr_g_q));
+       fifo_4k_a_graycounter_3r6   rdptr_g1p
+       ( 
+       .aclr(aclr),
+       .clock(rdclk),
+       .cnt_en(valid_rdreq),
+       .q(wire_rdptr_g1p_q));
+       fifo_4k_a_graycounter_3r6   wrptr_g1p
+       ( 
+       .aclr(aclr),
+       .clock(wrclk),
+       .cnt_en(valid_wrreq),
+       .q(wire_wrptr_g1p_q));
+       fifo_4k_altsyncram_8pl   fifo_ram
+       ( 
+       .address_a(wrptr_g),
+       .address_b(((wire_rdptr_g_q & {12{int_rdempty}}) | (wire_rdptr_g1p_q & {12{(~ int_rdempty)}}))),
+       .clock0(wrclk),
+       .clock1(rdclk),
+       .clocken1((valid_rdreq | int_rdempty)),
+       .data_a(data),
+       .q_b(wire_fifo_ram_q_b),
+       .wren_a(valid_wrreq));
+       // synopsys translate_off
+       initial
+               delayed_wrptr_g = 0;
+       // synopsys translate_on
+       always @ ( posedge wrclk or  posedge aclr)
+               if (aclr == 1'b1) delayed_wrptr_g <= 12'b0;
+               else  delayed_wrptr_g <= wrptr_g;
+       // synopsys translate_off
+       initial
+               wrptr_g = 0;
+       // synopsys translate_on
+       always @ ( posedge wrclk or  posedge aclr)
+               if (aclr == 1'b1) wrptr_g <= 12'b0;
+               else if  (valid_wrreq == 1'b1)   wrptr_g <= wire_wrptr_g1p_q;
+       fifo_4k_dffpipe_bb3   rs_brp
+       ( 
+       .clock(rdclk),
+       .clrn((~ aclr)),
+       .d(wire_rdptr_g_gray2bin_bin),
+       .q(wire_rs_brp_q));
+       fifo_4k_dffpipe_bb3   rs_bwp
+       ( 
+       .clock(rdclk),
+       .clrn((~ aclr)),
+       .d(wire_rs_dgwp_gray2bin_bin),
+       .q(wire_rs_bwp_q));
+       fifo_4k_alt_synch_pipe_em2   rs_dgwp
+       ( 
+       .clock(rdclk),
+       .clrn((~ aclr)),
+       .d(delayed_wrptr_g),
+       .q(wire_rs_dgwp_q));
+       fifo_4k_dffpipe_bb3   ws_brp
+       ( 
+       .clock(wrclk),
+       .clrn((~ aclr)),
+       .d(wire_ws_dgrp_gray2bin_bin),
+       .q(wire_ws_brp_q));
+       fifo_4k_dffpipe_bb3   ws_bwp
+       ( 
+       .clock(wrclk),
+       .clrn((~ aclr)),
+       .d(wire_wrptr_g_gray2bin_bin),
+       .q(wire_ws_bwp_q));
+       fifo_4k_alt_synch_pipe_em2   ws_dgrp
+       ( 
+       .clock(wrclk),
+       .clrn((~ aclr)),
+       .d(wire_rdptr_g_q),
+       .q(wire_ws_dgrp_q));
+       fifo_4k_add_sub_b18   rdusedw_sub
+       ( 
+       .dataa(wire_rs_bwp_q),
+       .datab(wire_rs_brp_q),
+       .result(wire_rdusedw_sub_result));
+       fifo_4k_add_sub_b18   wrusedw_sub
+       ( 
+       .dataa(wire_ws_bwp_q),
+       .datab(wire_ws_brp_q),
+       .result(wire_wrusedw_sub_result));
+       always @(wire_rdempty_eq_comp_dataa or wire_rdempty_eq_comp_datab)
+               if (wire_rdempty_eq_comp_dataa == wire_rdempty_eq_comp_datab) 
+                       begin
+                               wire_rdempty_eq_comp_aeb_int = 1'b1;
+                       end
+               else
+                       begin
+                               wire_rdempty_eq_comp_aeb_int = 1'b0;
+                       end
+       assign
+               wire_rdempty_eq_comp_aeb = wire_rdempty_eq_comp_aeb_int;
+       assign
+               wire_rdempty_eq_comp_dataa = wire_rs_dgwp_q,
+               wire_rdempty_eq_comp_datab = wire_rdptr_g_q;
+       always @(wire_wrfull_eq_comp_dataa or wire_wrfull_eq_comp_datab)
+               if (wire_wrfull_eq_comp_dataa == wire_wrfull_eq_comp_datab) 
+                       begin
+                               wire_wrfull_eq_comp_aeb_int = 1'b1;
+                       end
+               else
+                       begin
+                               wire_wrfull_eq_comp_aeb_int = 1'b0;
+                       end
+       assign
+               wire_wrfull_eq_comp_aeb = wire_wrfull_eq_comp_aeb_int;
+       assign
+               wire_wrfull_eq_comp_dataa = wire_ws_dgrp_q,
+               wire_wrfull_eq_comp_datab = wire_wrptr_g1p_q;
+       assign
+               int_rdempty = wire_rdempty_eq_comp_aeb,
+               int_wrfull = wire_wrfull_eq_comp_aeb,
+               q = wire_fifo_ram_q_b,
+               rdempty = int_rdempty,
+               rdusedw = wire_rdusedw_sub_result,
+               valid_rdreq = rdreq,
+               valid_wrreq = wrreq,
+               wrfull = int_wrfull,
+               wrusedw = wire_wrusedw_sub_result;
+endmodule //fifo_4k_dcfifo_6cq
+//VALID FILE
+
+
+// synopsys translate_off
+`timescale 1 ps / 1 ps
+// synopsys translate_on
+module fifo_4k (
+       data,
+       wrreq,
+       rdreq,
+       rdclk,
+       wrclk,
+       aclr,
+       q,
+       rdempty,
+       rdusedw,
+       wrfull,
+       wrusedw)/* synthesis synthesis_clearbox = 1 */;
+
+       input   [15:0]  data;
+       input     wrreq;
+       input     rdreq;
+       input     rdclk;
+       input     wrclk;
+       input     aclr;
+       output  [15:0]  q;
+       output    rdempty;
+       output  [11:0]  rdusedw;
+       output    wrfull;
+       output  [11:0]  wrusedw;
+
+       wire  sub_wire0;
+       wire [11:0] sub_wire1;
+       wire  sub_wire2;
+       wire [15:0] sub_wire3;
+       wire [11:0] sub_wire4;
+       wire  rdempty = sub_wire0;
+       wire [11:0] wrusedw = sub_wire1[11:0];
+       wire  wrfull = sub_wire2;
+       wire [15:0] q = sub_wire3[15:0];
+       wire [11:0] rdusedw = sub_wire4[11:0];
+
+       fifo_4k_dcfifo_6cq      fifo_4k_dcfifo_6cq_component (
+                               .wrclk (wrclk),
+                               .rdreq (rdreq),
+                               .aclr (aclr),
+                               .rdclk (rdclk),
+                               .wrreq (wrreq),
+                               .data (data),
+                               .rdempty (sub_wire0),
+                               .wrusedw (sub_wire1),
+                               .wrfull (sub_wire2),
+                               .q (sub_wire3),
+                               .rdusedw (sub_wire4));
+
+endmodule
+
+// ============================================================
+// CNX file retrieval info
+// ============================================================
+// Retrieval info: PRIVATE: Width NUMERIC "16"
+// Retrieval info: PRIVATE: Depth NUMERIC "4096"
+// Retrieval info: PRIVATE: Clock NUMERIC "4"
+// Retrieval info: PRIVATE: CLOCKS_ARE_SYNCHRONIZED NUMERIC "0"
+// Retrieval info: PRIVATE: Full NUMERIC "1"
+// Retrieval info: PRIVATE: Empty NUMERIC "1"
+// Retrieval info: PRIVATE: UsedW NUMERIC "1"
+// Retrieval info: PRIVATE: AlmostFull NUMERIC "0"
+// Retrieval info: PRIVATE: AlmostEmpty NUMERIC "0"
+// Retrieval info: PRIVATE: AlmostFullThr NUMERIC "-1"
+// Retrieval info: PRIVATE: AlmostEmptyThr NUMERIC "-1"
+// Retrieval info: PRIVATE: sc_aclr NUMERIC "0"
+// Retrieval info: PRIVATE: sc_sclr NUMERIC "0"
+// Retrieval info: PRIVATE: rsFull NUMERIC "0"
+// Retrieval info: PRIVATE: rsEmpty NUMERIC "1"
+// Retrieval info: PRIVATE: rsUsedW NUMERIC "1"
+// Retrieval info: PRIVATE: wsFull NUMERIC "1"
+// Retrieval info: PRIVATE: wsEmpty NUMERIC "0"
+// Retrieval info: PRIVATE: wsUsedW NUMERIC "1"
+// Retrieval info: PRIVATE: dc_aclr NUMERIC "1"
+// Retrieval info: PRIVATE: LegacyRREQ NUMERIC "0"
+// Retrieval info: PRIVATE: RAM_BLOCK_TYPE NUMERIC "0"
+// Retrieval info: PRIVATE: MAX_DEPTH_BY_9 NUMERIC "0"
+// Retrieval info: PRIVATE: LE_BasedFIFO NUMERIC "0"
+// Retrieval info: PRIVATE: Optimize NUMERIC "2"
+// Retrieval info: PRIVATE: OVERFLOW_CHECKING NUMERIC "1"
+// Retrieval info: PRIVATE: UNDERFLOW_CHECKING NUMERIC "1"
+// Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING "Cyclone"
+// Retrieval info: CONSTANT: LPM_WIDTH NUMERIC "16"
+// Retrieval info: CONSTANT: LPM_NUMWORDS NUMERIC "4096"
+// Retrieval info: CONSTANT: LPM_WIDTHU NUMERIC "12"
+// Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone"
+// Retrieval info: CONSTANT: CLOCKS_ARE_SYNCHRONIZED STRING "FALSE"
+// Retrieval info: CONSTANT: LPM_TYPE STRING "dcfifo"
+// Retrieval info: CONSTANT: LPM_SHOWAHEAD STRING "ON"
+// Retrieval info: CONSTANT: OVERFLOW_CHECKING STRING "OFF"
+// Retrieval info: CONSTANT: UNDERFLOW_CHECKING STRING "OFF"
+// Retrieval info: CONSTANT: USE_EAB STRING "ON"
+// Retrieval info: CONSTANT: ADD_RAM_OUTPUT_REGISTER STRING "OFF"
+// Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone"
+// Retrieval info: USED_PORT: data 0 0 16 0 INPUT NODEFVAL data[15..0]
+// Retrieval info: USED_PORT: q 0 0 16 0 OUTPUT NODEFVAL q[15..0]
+// Retrieval info: USED_PORT: wrreq 0 0 0 0 INPUT NODEFVAL wrreq
+// Retrieval info: USED_PORT: rdreq 0 0 0 0 INPUT NODEFVAL rdreq
+// Retrieval info: USED_PORT: rdclk 0 0 0 0 INPUT NODEFVAL rdclk
+// Retrieval info: USED_PORT: wrclk 0 0 0 0 INPUT NODEFVAL wrclk
+// Retrieval info: USED_PORT: rdempty 0 0 0 0 OUTPUT NODEFVAL rdempty
+// Retrieval info: USED_PORT: rdusedw 0 0 12 0 OUTPUT NODEFVAL rdusedw[11..0]
+// Retrieval info: USED_PORT: wrfull 0 0 0 0 OUTPUT NODEFVAL wrfull
+// Retrieval info: USED_PORT: wrusedw 0 0 12 0 OUTPUT NODEFVAL wrusedw[11..0]
+// Retrieval info: USED_PORT: aclr 0 0 0 0 INPUT GND aclr
+// Retrieval info: CONNECT: @data 0 0 16 0 data 0 0 16 0
+// Retrieval info: CONNECT: q 0 0 16 0 @q 0 0 16 0
+// Retrieval info: CONNECT: @wrreq 0 0 0 0 wrreq 0 0 0 0
+// Retrieval info: CONNECT: @rdreq 0 0 0 0 rdreq 0 0 0 0
+// Retrieval info: CONNECT: @rdclk 0 0 0 0 rdclk 0 0 0 0
+// Retrieval info: CONNECT: @wrclk 0 0 0 0 wrclk 0 0 0 0
+// Retrieval info: CONNECT: rdempty 0 0 0 0 @rdempty 0 0 0 0
+// Retrieval info: CONNECT: rdusedw 0 0 12 0 @rdusedw 0 0 12 0
+// Retrieval info: CONNECT: wrfull 0 0 0 0 @wrfull 0 0 0 0
+// Retrieval info: CONNECT: wrusedw 0 0 12 0 @wrusedw 0 0 12 0
+// Retrieval info: CONNECT: @aclr 0 0 0 0 aclr 0 0 0 0
+// Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all
+// Retrieval info: GEN_FILE: TYPE_NORMAL fifo_4k.v TRUE
+// Retrieval info: GEN_FILE: TYPE_NORMAL fifo_4k.inc FALSE
+// Retrieval info: GEN_FILE: TYPE_NORMAL fifo_4k.cmp FALSE
+// Retrieval info: GEN_FILE: TYPE_NORMAL fifo_4k.bsf FALSE
+// Retrieval info: GEN_FILE: TYPE_NORMAL fifo_4k_inst.v FALSE
+// Retrieval info: GEN_FILE: TYPE_NORMAL fifo_4k_bb.v TRUE
+// Retrieval info: GEN_FILE: TYPE_NORMAL fifo_4k_waveforms.html TRUE
+// Retrieval info: GEN_FILE: TYPE_NORMAL fifo_4k_wave*.jpg FALSE
diff --git a/usrp/fpga/megacells/fifo_4k_bb.v b/usrp/fpga/megacells/fifo_4k_bb.v
new file mode 100644 (file)
index 0000000..fc4ca97
--- /dev/null
@@ -0,0 +1,131 @@
+// megafunction wizard: %FIFO%VBB%
+// GENERATION: STANDARD
+// VERSION: WM1.0
+// MODULE: dcfifo 
+
+// ============================================================
+// File Name: fifo_4k.v
+// Megafunction Name(s):
+//                     dcfifo
+// ============================================================
+// ************************************************************
+// THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE!
+//
+// 5.0 Build 168 06/22/2005 SP 1 SJ Web Edition
+// ************************************************************
+
+//Copyright (C) 1991-2005 Altera Corporation
+//Your use of Altera Corporation's design tools, logic functions 
+//and other software and tools, and its AMPP partner logic       
+//functions, and any output files any of the foregoing           
+//(including device programming or simulation files), and any    
+//associated documentation or information are expressly subject  
+//to the terms and conditions of the Altera Program License      
+//Subscription Agreement, Altera MegaCore Function License       
+//Agreement, or other applicable license agreement, including,   
+//without limitation, that your use is for the sole purpose of   
+//programming logic devices manufactured by Altera and sold by   
+//Altera or its authorized distributors.  Please refer to the    
+//applicable agreement for further details.
+
+module fifo_4k (
+       data,
+       wrreq,
+       rdreq,
+       rdclk,
+       wrclk,
+       aclr,
+       q,
+       rdempty,
+       rdusedw,
+       wrfull,
+       wrusedw)/* synthesis synthesis_clearbox = 1 */;
+
+       input   [15:0]  data;
+       input     wrreq;
+       input     rdreq;
+       input     rdclk;
+       input     wrclk;
+       input     aclr;
+       output  [15:0]  q;
+       output    rdempty;
+       output  [11:0]  rdusedw;
+       output    wrfull;
+       output  [11:0]  wrusedw;
+
+endmodule
+
+// ============================================================
+// CNX file retrieval info
+// ============================================================
+// Retrieval info: PRIVATE: Width NUMERIC "16"
+// Retrieval info: PRIVATE: Depth NUMERIC "4096"
+// Retrieval info: PRIVATE: Clock NUMERIC "4"
+// Retrieval info: PRIVATE: CLOCKS_ARE_SYNCHRONIZED NUMERIC "0"
+// Retrieval info: PRIVATE: Full NUMERIC "1"
+// Retrieval info: PRIVATE: Empty NUMERIC "1"
+// Retrieval info: PRIVATE: UsedW NUMERIC "1"
+// Retrieval info: PRIVATE: AlmostFull NUMERIC "0"
+// Retrieval info: PRIVATE: AlmostEmpty NUMERIC "0"
+// Retrieval info: PRIVATE: AlmostFullThr NUMERIC "-1"
+// Retrieval info: PRIVATE: AlmostEmptyThr NUMERIC "-1"
+// Retrieval info: PRIVATE: sc_aclr NUMERIC "0"
+// Retrieval info: PRIVATE: sc_sclr NUMERIC "0"
+// Retrieval info: PRIVATE: rsFull NUMERIC "0"
+// Retrieval info: PRIVATE: rsEmpty NUMERIC "1"
+// Retrieval info: PRIVATE: rsUsedW NUMERIC "1"
+// Retrieval info: PRIVATE: wsFull NUMERIC "1"
+// Retrieval info: PRIVATE: wsEmpty NUMERIC "0"
+// Retrieval info: PRIVATE: wsUsedW NUMERIC "1"
+// Retrieval info: PRIVATE: dc_aclr NUMERIC "1"
+// Retrieval info: PRIVATE: LegacyRREQ NUMERIC "0"
+// Retrieval info: PRIVATE: RAM_BLOCK_TYPE NUMERIC "0"
+// Retrieval info: PRIVATE: MAX_DEPTH_BY_9 NUMERIC "0"
+// Retrieval info: PRIVATE: LE_BasedFIFO NUMERIC "0"
+// Retrieval info: PRIVATE: Optimize NUMERIC "2"
+// Retrieval info: PRIVATE: OVERFLOW_CHECKING NUMERIC "1"
+// Retrieval info: PRIVATE: UNDERFLOW_CHECKING NUMERIC "1"
+// Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING "Cyclone"
+// Retrieval info: CONSTANT: LPM_WIDTH NUMERIC "16"
+// Retrieval info: CONSTANT: LPM_NUMWORDS NUMERIC "4096"
+// Retrieval info: CONSTANT: LPM_WIDTHU NUMERIC "12"
+// Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone"
+// Retrieval info: CONSTANT: CLOCKS_ARE_SYNCHRONIZED STRING "FALSE"
+// Retrieval info: CONSTANT: LPM_TYPE STRING "dcfifo"
+// Retrieval info: CONSTANT: LPM_SHOWAHEAD STRING "ON"
+// Retrieval info: CONSTANT: OVERFLOW_CHECKING STRING "OFF"
+// Retrieval info: CONSTANT: UNDERFLOW_CHECKING STRING "OFF"
+// Retrieval info: CONSTANT: USE_EAB STRING "ON"
+// Retrieval info: CONSTANT: ADD_RAM_OUTPUT_REGISTER STRING "OFF"
+// Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone"
+// Retrieval info: USED_PORT: data 0 0 16 0 INPUT NODEFVAL data[15..0]
+// Retrieval info: USED_PORT: q 0 0 16 0 OUTPUT NODEFVAL q[15..0]
+// Retrieval info: USED_PORT: wrreq 0 0 0 0 INPUT NODEFVAL wrreq
+// Retrieval info: USED_PORT: rdreq 0 0 0 0 INPUT NODEFVAL rdreq
+// Retrieval info: USED_PORT: rdclk 0 0 0 0 INPUT NODEFVAL rdclk
+// Retrieval info: USED_PORT: wrclk 0 0 0 0 INPUT NODEFVAL wrclk
+// Retrieval info: USED_PORT: rdempty 0 0 0 0 OUTPUT NODEFVAL rdempty
+// Retrieval info: USED_PORT: rdusedw 0 0 12 0 OUTPUT NODEFVAL rdusedw[11..0]
+// Retrieval info: USED_PORT: wrfull 0 0 0 0 OUTPUT NODEFVAL wrfull
+// Retrieval info: USED_PORT: wrusedw 0 0 12 0 OUTPUT NODEFVAL wrusedw[11..0]
+// Retrieval info: USED_PORT: aclr 0 0 0 0 INPUT GND aclr
+// Retrieval info: CONNECT: @data 0 0 16 0 data 0 0 16 0
+// Retrieval info: CONNECT: q 0 0 16 0 @q 0 0 16 0
+// Retrieval info: CONNECT: @wrreq 0 0 0 0 wrreq 0 0 0 0
+// Retrieval info: CONNECT: @rdreq 0 0 0 0 rdreq 0 0 0 0
+// Retrieval info: CONNECT: @rdclk 0 0 0 0 rdclk 0 0 0 0
+// Retrieval info: CONNECT: @wrclk 0 0 0 0 wrclk 0 0 0 0
+// Retrieval info: CONNECT: rdempty 0 0 0 0 @rdempty 0 0 0 0
+// Retrieval info: CONNECT: rdusedw 0 0 12 0 @rdusedw 0 0 12 0
+// Retrieval info: CONNECT: wrfull 0 0 0 0 @wrfull 0 0 0 0
+// Retrieval info: CONNECT: wrusedw 0 0 12 0 @wrusedw 0 0 12 0
+// Retrieval info: CONNECT: @aclr 0 0 0 0 aclr 0 0 0 0
+// Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all
+// Retrieval info: GEN_FILE: TYPE_NORMAL fifo_4k.v TRUE
+// Retrieval info: GEN_FILE: TYPE_NORMAL fifo_4k.inc FALSE
+// Retrieval info: GEN_FILE: TYPE_NORMAL fifo_4k.cmp FALSE
+// Retrieval info: GEN_FILE: TYPE_NORMAL fifo_4k.bsf FALSE
+// Retrieval info: GEN_FILE: TYPE_NORMAL fifo_4k_inst.v FALSE
+// Retrieval info: GEN_FILE: TYPE_NORMAL fifo_4k_bb.v TRUE
+// Retrieval info: GEN_FILE: TYPE_NORMAL fifo_4k_waveforms.html TRUE
+// Retrieval info: GEN_FILE: TYPE_NORMAL fifo_4k_wave*.jpg FALSE
diff --git a/usrp/fpga/megacells/mylpm_addsub.bsf b/usrp/fpga/megacells/mylpm_addsub.bsf
new file mode 100755 (executable)
index 0000000..e5c1ded
--- /dev/null
@@ -0,0 +1,80 @@
+/*
+WARNING: Do NOT edit the input and output ports in this file in a text
+editor if you plan to continue editing the block that represents it in
+the Block Editor! File corruption is VERY likely to occur.
+*/
+/*
+Copyright (C) 1991-2003 Altera Corporation
+Any  megafunction  design,  and related netlist (encrypted  or  decrypted),
+support information,  device programming or simulation file,  and any other
+associated  documentation or information  provided by  Altera  or a partner
+under  Altera's   Megafunction   Partnership   Program  may  be  used  only
+to program  PLD  devices (but not masked  PLD  devices) from  Altera.   Any
+other  use  of such  megafunction  design,  netlist,  support  information,
+device programming or simulation file,  or any other  related documentation
+or information  is prohibited  for  any  other purpose,  including, but not
+limited to  modification,  reverse engineering,  de-compiling, or use  with
+any other  silicon devices,  unless such use is  explicitly  licensed under
+a separate agreement with  Altera  or a megafunction partner.  Title to the
+intellectual property,  including patents,  copyrights,  trademarks,  trade
+secrets,  or maskworks,  embodied in any such megafunction design, netlist,
+support  information,  device programming or simulation file,  or any other
+related documentation or information provided by  Altera  or a megafunction
+partner, remains with Altera, the megafunction partner, or their respective
+licensors. No other licenses, including any licenses needed under any third
+party's intellectual property, are provided herein.
+*/
+(header "symbol" (version "1.1"))
+(symbol
+       (rect 0 0 160 112)
+       (text "mylpm_addsub" (rect 26 2 145 21)(font "Arial" (font_size 10)))
+       (text "inst" (rect 8 93 30 108)(font "Arial" ))
+       (port
+               (pt 0 56)
+               (input)
+               (text "dataa[15..0]" (rect 0 0 75 16)(font "Arial" (font_size 8)))
+               (text "dataa[15..0]" (rect 4 40 73 56)(font "Arial" (font_size 8)))
+               (line (pt 0 56)(pt 64 56)(line_width 3))
+       )
+       (port
+               (pt 0 88)
+               (input)
+               (text "datab[15..0]" (rect 0 0 75 16)(font "Arial" (font_size 8)))
+               (text "datab[15..0]" (rect 4 72 73 88)(font "Arial" (font_size 8)))
+               (line (pt 0 88)(pt 64 88)(line_width 3))
+       )
+       (port
+               (pt 0 72)
+               (input)
+               (text "clock" (rect 0 0 34 16)(font "Arial" (font_size 8)))
+               (text "clock" (rect 4 56 35 72)(font "Arial" (font_size 8)))
+               (line (pt 0 72)(pt 64 72)(line_width 1))
+       )
+       (port
+               (pt 0 32)
+               (input)
+               (text "add_sub" (rect 0 0 53 16)(font "Arial" (font_size 8)))
+               (text "add_sub" (rect 4 16 53 32)(font "Arial" (font_size 8)))
+               (line (pt 0 32)(pt 80 32)(line_width 1))
+       )
+       (port
+               (pt 160 72)
+               (output)
+               (text "result[15..0]" (rect 0 0 75 16)(font "Arial" (font_size 8)))
+               (text "result[15..0]" (rect 88 56 157 72)(font "Arial" (font_size 8)))
+               (line (pt 160 72)(pt 96 72)(line_width 3))
+       )
+       (drawing
+               (text "A" (rect 66 48 75 64)(font "Arial" (font_size 8)))
+               (text "B" (rect 66 80 75 96)(font "Arial" (font_size 8)))
+               (text "A+B/A-B" (rect 82 37 134 53)(font "Arial" (font_size 8)))
+               (line (pt 64 48)(pt 96 56)(line_width 1))
+               (line (pt 96 56)(pt 96 88)(line_width 1))
+               (line (pt 96 88)(pt 64 96)(line_width 1))
+               (line (pt 64 96)(pt 64 48)(line_width 1))
+               (line (pt 80 32)(pt 80 52)(line_width 1))
+               (line (pt 106 40)(pt 125 40)(line_width 1))
+               (line (pt 64 66)(pt 70 72)(line_width 1))
+               (line (pt 70 72)(pt 64 78)(line_width 1))
+       )
+)
diff --git a/usrp/fpga/megacells/mylpm_addsub.cmp b/usrp/fpga/megacells/mylpm_addsub.cmp
new file mode 100755 (executable)
index 0000000..311c54a
--- /dev/null
@@ -0,0 +1,31 @@
+--Copyright (C) 1991-2003 Altera Corporation
+--Any  megafunction  design,  and related netlist (encrypted  or  decrypted),
+--support information,  device programming or simulation file,  and any other
+--associated  documentation or information  provided by  Altera  or a partner
+--under  Altera's   Megafunction   Partnership   Program  may  be  used  only
+--to program  PLD  devices (but not masked  PLD  devices) from  Altera.   Any
+--other  use  of such  megafunction  design,  netlist,  support  information,
+--device programming or simulation file,  or any other  related documentation
+--or information  is prohibited  for  any  other purpose,  including, but not
+--limited to  modification,  reverse engineering,  de-compiling, or use  with
+--any other  silicon devices,  unless such use is  explicitly  licensed under
+--a separate agreement with  Altera  or a megafunction partner.  Title to the
+--intellectual property,  including patents,  copyrights,  trademarks,  trade
+--secrets,  or maskworks,  embodied in any such megafunction design, netlist,
+--support  information,  device programming or simulation file,  or any other
+--related documentation or information provided by  Altera  or a megafunction
+--partner, remains with Altera, the megafunction partner, or their respective
+--licensors. No other licenses, including any licenses needed under any third
+--party's intellectual property, are provided herein.
+
+
+component mylpm_addsub
+       PORT
+       (
+               add_sub         : IN STD_LOGIC ;
+               dataa           : IN STD_LOGIC_VECTOR (15 DOWNTO 0);
+               datab           : IN STD_LOGIC_VECTOR (15 DOWNTO 0);
+               clock           : IN STD_LOGIC ;
+               result          : OUT STD_LOGIC_VECTOR (15 DOWNTO 0)
+       );
+end component;
diff --git a/usrp/fpga/megacells/mylpm_addsub.inc b/usrp/fpga/megacells/mylpm_addsub.inc
new file mode 100755 (executable)
index 0000000..d8b283f
--- /dev/null
@@ -0,0 +1,32 @@
+--Copyright (C) 1991-2003 Altera Corporation
+--Any  megafunction  design,  and related netlist (encrypted  or  decrypted),
+--support information,  device programming or simulation file,  and any other
+--associated  documentation or information  provided by  Altera  or a partner
+--under  Altera's   Megafunction   Partnership   Program  may  be  used  only
+--to program  PLD  devices (but not masked  PLD  devices) from  Altera.   Any
+--other  use  of such  megafunction  design,  netlist,  support  information,
+--device programming or simulation file,  or any other  related documentation
+--or information  is prohibited  for  any  other purpose,  including, but not
+--limited to  modification,  reverse engineering,  de-compiling, or use  with
+--any other  silicon devices,  unless such use is  explicitly  licensed under
+--a separate agreement with  Altera  or a megafunction partner.  Title to the
+--intellectual property,  including patents,  copyrights,  trademarks,  trade
+--secrets,  or maskworks,  embodied in any such megafunction design, netlist,
+--support  information,  device programming or simulation file,  or any other
+--related documentation or information provided by  Altera  or a megafunction
+--partner, remains with Altera, the megafunction partner, or their respective
+--licensors. No other licenses, including any licenses needed under any third
+--party's intellectual property, are provided herein.
+
+
+FUNCTION mylpm_addsub 
+(
+       add_sub,
+       dataa[15..0],
+       datab[15..0],
+       clock
+)
+
+RETURNS (
+       result[15..0]
+);
diff --git a/usrp/fpga/megacells/mylpm_addsub.v b/usrp/fpga/megacells/mylpm_addsub.v
new file mode 100755 (executable)
index 0000000..0566f7e
--- /dev/null
@@ -0,0 +1,102 @@
+// megafunction wizard: %LPM_ADD_SUB%
+// GENERATION: STANDARD
+// VERSION: WM1.0
+// MODULE: lpm_add_sub 
+
+// ============================================================
+// File Name: mylpm_addsub.v
+// Megafunction Name(s):
+//                     lpm_add_sub
+// ============================================================
+// ************************************************************
+// THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE!
+// ************************************************************
+
+
+//Copyright (C) 1991-2003 Altera Corporation
+//Any  megafunction  design,  and related netlist (encrypted  or  decrypted),
+//support information,  device programming or simulation file,  and any other
+//associated  documentation or information  provided by  Altera  or a partner
+//under  Altera's   Megafunction   Partnership   Program  may  be  used  only
+//to program  PLD  devices (but not masked  PLD  devices) from  Altera.   Any
+//other  use  of such  megafunction  design,  netlist,  support  information,
+//device programming or simulation file,  or any other  related documentation
+//or information  is prohibited  for  any  other purpose,  including, but not
+//limited to  modification,  reverse engineering,  de-compiling, or use  with
+//any other  silicon devices,  unless such use is  explicitly  licensed under
+//a separate agreement with  Altera  or a megafunction partner.  Title to the
+//intellectual property,  including patents,  copyrights,  trademarks,  trade
+//secrets,  or maskworks,  embodied in any such megafunction design, netlist,
+//support  information,  device programming or simulation file,  or any other
+//related documentation or information provided by  Altera  or a megafunction
+//partner, remains with Altera, the megafunction partner, or their respective
+//licensors. No other licenses, including any licenses needed under any third
+//party's intellectual property, are provided herein.
+
+
+module mylpm_addsub (
+       add_sub,
+       dataa,
+       datab,
+       clock,
+       result);
+
+       input     add_sub;
+       input   [15:0]  dataa;
+       input   [15:0]  datab;
+       input     clock;
+       output  [15:0]  result;
+
+       wire [15:0] sub_wire0;
+       wire [15:0] result = sub_wire0[15:0];
+
+       lpm_add_sub     lpm_add_sub_component (
+                               .dataa (dataa),
+                               .add_sub (add_sub),
+                               .datab (datab),
+                               .clock (clock),
+                               .result (sub_wire0));
+       defparam
+               lpm_add_sub_component.lpm_width = 16,
+               lpm_add_sub_component.lpm_direction = "UNUSED",
+               lpm_add_sub_component.lpm_type = "LPM_ADD_SUB",
+               lpm_add_sub_component.lpm_hint = "ONE_INPUT_IS_CONSTANT=NO",
+               lpm_add_sub_component.lpm_pipeline = 1;
+
+
+endmodule
+
+// ============================================================
+// CNX file retrieval info
+// ============================================================
+// Retrieval info: PRIVATE: nBit NUMERIC "16"
+// Retrieval info: PRIVATE: Function NUMERIC "2"
+// Retrieval info: PRIVATE: WhichConstant NUMERIC "0"
+// Retrieval info: PRIVATE: ConstantA NUMERIC "0"
+// Retrieval info: PRIVATE: ConstantB NUMERIC "0"
+// Retrieval info: PRIVATE: ValidCtA NUMERIC "0"
+// Retrieval info: PRIVATE: ValidCtB NUMERIC "0"
+// Retrieval info: PRIVATE: CarryIn NUMERIC "0"
+// Retrieval info: PRIVATE: CarryOut NUMERIC "0"
+// Retrieval info: PRIVATE: Overflow NUMERIC "0"
+// Retrieval info: PRIVATE: Latency NUMERIC "1"
+// Retrieval info: PRIVATE: aclr NUMERIC "0"
+// Retrieval info: PRIVATE: clken NUMERIC "0"
+// Retrieval info: PRIVATE: LPM_PIPELINE NUMERIC "1"
+// Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING "Cyclone"
+// Retrieval info: CONSTANT: LPM_WIDTH NUMERIC "16"
+// Retrieval info: CONSTANT: LPM_DIRECTION STRING "UNUSED"
+// Retrieval info: CONSTANT: LPM_TYPE STRING "LPM_ADD_SUB"
+// Retrieval info: CONSTANT: LPM_HINT STRING "ONE_INPUT_IS_CONSTANT=NO"
+// Retrieval info: CONSTANT: LPM_PIPELINE NUMERIC "1"
+// Retrieval info: USED_PORT: add_sub 0 0 0 0 INPUT NODEFVAL add_sub
+// Retrieval info: USED_PORT: result 0 0 16 0 OUTPUT NODEFVAL result[15..0]
+// Retrieval info: USED_PORT: dataa 0 0 16 0 INPUT NODEFVAL dataa[15..0]
+// Retrieval info: USED_PORT: datab 0 0 16 0 INPUT NODEFVAL datab[15..0]
+// Retrieval info: USED_PORT: clock 0 0 0 0 INPUT NODEFVAL clock
+// Retrieval info: CONNECT: @add_sub 0 0 0 0 add_sub 0 0 0 0
+// Retrieval info: CONNECT: result 0 0 16 0 @result 0 0 16 0
+// Retrieval info: CONNECT: @dataa 0 0 16 0 dataa 0 0 16 0
+// Retrieval info: CONNECT: @datab 0 0 16 0 datab 0 0 16 0
+// Retrieval info: CONNECT: @clock 0 0 0 0 clock 0 0 0 0
+// Retrieval info: LIBRARY: lpm lpm.lpm_components.all
diff --git a/usrp/fpga/megacells/mylpm_addsub_bb.v b/usrp/fpga/megacells/mylpm_addsub_bb.v
new file mode 100755 (executable)
index 0000000..598d3da
--- /dev/null
@@ -0,0 +1,35 @@
+//Copyright (C) 1991-2003 Altera Corporation
+//Any  megafunction  design,  and related netlist (encrypted  or  decrypted),
+//support information,  device programming or simulation file,  and any other
+//associated  documentation or information  provided by  Altera  or a partner
+//under  Altera's   Megafunction   Partnership   Program  may  be  used  only
+//to program  PLD  devices (but not masked  PLD  devices) from  Altera.   Any
+//other  use  of such  megafunction  design,  netlist,  support  information,
+//device programming or simulation file,  or any other  related documentation
+//or information  is prohibited  for  any  other purpose,  including, but not
+//limited to  modification,  reverse engineering,  de-compiling, or use  with
+//any other  silicon devices,  unless such use is  explicitly  licensed under
+//a separate agreement with  Altera  or a megafunction partner.  Title to the
+//intellectual property,  including patents,  copyrights,  trademarks,  trade
+//secrets,  or maskworks,  embodied in any such megafunction design, netlist,
+//support  information,  device programming or simulation file,  or any other
+//related documentation or information provided by  Altera  or a megafunction
+//partner, remains with Altera, the megafunction partner, or their respective
+//licensors. No other licenses, including any licenses needed under any third
+//party's intellectual property, are provided herein.
+
+module mylpm_addsub (
+       add_sub,
+       dataa,
+       datab,
+       clock,
+       result);
+
+       input     add_sub;
+       input   [15:0]  dataa;
+       input   [15:0]  datab;
+       input     clock;
+       output  [15:0]  result;
+
+endmodule
+
diff --git a/usrp/fpga/megacells/mylpm_addsub_inst.v b/usrp/fpga/megacells/mylpm_addsub_inst.v
new file mode 100755 (executable)
index 0000000..dd732bd
--- /dev/null
@@ -0,0 +1,7 @@
+mylpm_addsub   mylpm_addsub_inst (
+       .add_sub ( add_sub_sig ),
+       .dataa ( dataa_sig ),
+       .datab ( datab_sig ),
+       .clock ( clock_sig ),
+       .result ( result_sig )
+       );
diff --git a/usrp/fpga/megacells/pll.v b/usrp/fpga/megacells/pll.v
new file mode 100644 (file)
index 0000000..dacd11f
--- /dev/null
@@ -0,0 +1,207 @@
+// megafunction wizard: %ALTPLL%
+// GENERATION: STANDARD
+// VERSION: WM1.0
+// MODULE: altpll 
+
+// ============================================================
+// File Name: pll.v
+// Megafunction Name(s):
+//                     altpll
+// ============================================================
+// ************************************************************
+// THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE!
+//
+// 4.0 Build 214 3/25/2004 SP 1 SJ Web Edition
+// ************************************************************
+
+
+//Copyright (C) 1991-2004 Altera Corporation
+//Any  megafunction  design,  and related netlist (encrypted  or  decrypted),
+//support information,  device programming or simulation file,  and any other
+//associated  documentation or information  provided by  Altera  or a partner
+//under  Altera's   Megafunction   Partnership   Program  may  be  used  only
+//to program  PLD  devices (but not masked  PLD  devices) from  Altera.   Any
+//other  use  of such  megafunction  design,  netlist,  support  information,
+//device programming or simulation file,  or any other  related documentation
+//or information  is prohibited  for  any  other purpose,  including, but not
+//limited to  modification,  reverse engineering,  de-compiling, or use  with
+//any other  silicon devices,  unless such use is  explicitly  licensed under
+//a separate agreement with  Altera  or a megafunction partner.  Title to the
+//intellectual property,  including patents,  copyrights,  trademarks,  trade
+//secrets,  or maskworks,  embodied in any such megafunction design, netlist,
+//support  information,  device programming or simulation file,  or any other
+//related documentation or information provided by  Altera  or a megafunction
+//partner, remains with Altera, the megafunction partner, or their respective
+//licensors. No other licenses, including any licenses needed under any third
+//party's intellectual property, are provided herein.
+
+
+// synopsys translate_off
+`timescale 1 ps / 1 ps
+// synopsys translate_on
+module pll (
+       inclk0,
+       c0);
+
+       input     inclk0;
+       output    c0;
+
+       wire [5:0] sub_wire0;
+       wire [0:0] sub_wire4 = 1'h0;
+       wire [0:0] sub_wire1 = sub_wire0[0:0];
+       wire  c0 = sub_wire1;
+       wire  sub_wire2 = inclk0;
+       wire [1:0] sub_wire3 = {sub_wire4, sub_wire2};
+
+       altpll  altpll_component (
+                               .inclk (sub_wire3),
+                               .clk (sub_wire0)
+                               // synopsys translate_off
+,
+                               .fbin (),
+                               .pllena (),
+                               .clkswitch (),
+                               .areset (),
+                               .pfdena (),
+                               .clkena (),
+                               .extclkena (),
+                               .scanclk (),
+                               .scanaclr (),
+                               .scandata (),
+                               .scanread (),
+                               .scanwrite (),
+                               .extclk (),
+                               .clkbad (),
+                               .activeclock (),
+                               .locked (),
+                               .clkloss (),
+                               .scandataout (),
+                               .scandone (),
+                               .sclkout1 (),
+                               .sclkout0 (),
+                               .enable0 (),
+                               .enable1 ()
+                               // synopsys translate_on
+
+);
+       defparam
+               altpll_component.clk0_duty_cycle = 50,
+               altpll_component.lpm_type = "altpll",
+               altpll_component.clk0_multiply_by = 1,
+               altpll_component.inclk0_input_frequency = 20833,
+               altpll_component.clk0_divide_by = 1,
+               altpll_component.pll_type = "AUTO",
+               altpll_component.clk0_time_delay = "0",
+               altpll_component.intended_device_family = "Cyclone",
+               altpll_component.operation_mode = "NORMAL",
+               altpll_component.compensate_clock = "CLK0",
+               altpll_component.clk0_phase_shift = "-3000";
+
+
+endmodule
+
+// ============================================================
+// CNX file retrieval info
+// ============================================================
+// Retrieval info: PRIVATE: MIRROR_CLK0 STRING "0"
+// Retrieval info: PRIVATE: PHASE_SHIFT_UNIT0 STRING "ns"
+// Retrieval info: PRIVATE: OUTPUT_FREQ_UNIT0 STRING "MHz"
+// Retrieval info: PRIVATE: INCLK1_FREQ_UNIT_COMBO STRING "MHz"
+// Retrieval info: PRIVATE: SPREAD_USE STRING "0"
+// Retrieval info: PRIVATE: SPREAD_FEATURE_ENABLED STRING "0"
+// Retrieval info: PRIVATE: GLOCKED_COUNTER_EDIT_CHANGED STRING "1"
+// Retrieval info: PRIVATE: GLOCK_COUNTER_EDIT NUMERIC "1048575"
+// Retrieval info: PRIVATE: SRC_SYNCH_COMP_RADIO STRING "0"
+// Retrieval info: PRIVATE: DUTY_CYCLE0 STRING "50.00000000"
+// Retrieval info: PRIVATE: PHASE_SHIFT0 STRING "-3.00000000"
+// Retrieval info: PRIVATE: MULT_FACTOR0 NUMERIC "1"
+// Retrieval info: PRIVATE: OUTPUT_FREQ_MODE0 STRING "0"
+// Retrieval info: PRIVATE: SPREAD_PERCENT STRING "0.500"
+// Retrieval info: PRIVATE: LOCKED_OUTPUT_CHECK STRING "0"
+// Retrieval info: PRIVATE: PLL_ARESET_CHECK STRING "0"
+// Retrieval info: PRIVATE: TIME_SHIFT0 STRING "0.00000000"
+// Retrieval info: PRIVATE: STICKY_CLK0 STRING "1"
+// Retrieval info: PRIVATE: BANDWIDTH STRING "1.000"
+// Retrieval info: PRIVATE: BANDWIDTH_USE_CUSTOM STRING "0"
+// Retrieval info: PRIVATE: DEVICE_SPEED_GRADE STRING "8"
+// Retrieval info: PRIVATE: SPREAD_FREQ STRING "50.000"
+// Retrieval info: PRIVATE: BANDWIDTH_FEATURE_ENABLED STRING "0"
+// Retrieval info: PRIVATE: LONG_SCAN_RADIO STRING "1"
+// Retrieval info: PRIVATE: PLL_ENHPLL_CHECK NUMERIC "0"
+// Retrieval info: PRIVATE: LVDS_MODE_DATA_RATE_DIRTY NUMERIC "0"
+// Retrieval info: PRIVATE: USE_CLK0 STRING "1"
+// Retrieval info: PRIVATE: INCLK1_FREQ_EDIT_CHANGED STRING "1"
+// Retrieval info: PRIVATE: SCAN_FEATURE_ENABLED STRING "0"
+// Retrieval info: PRIVATE: ZERO_DELAY_RADIO STRING "0"
+// Retrieval info: PRIVATE: PLL_PFDENA_CHECK STRING "0"
+// Retrieval info: PRIVATE: CREATE_CLKBAD_CHECK STRING "0"
+// Retrieval info: PRIVATE: INCLK1_FREQ_EDIT STRING "100.000"
+// Retrieval info: PRIVATE: CUR_DEDICATED_CLK STRING "c0"
+// Retrieval info: PRIVATE: PLL_FASTPLL_CHECK NUMERIC "0"
+// Retrieval info: PRIVATE: ACTIVECLK_CHECK STRING "0"
+// Retrieval info: PRIVATE: BANDWIDTH_FREQ_UNIT STRING "MHz"
+// Retrieval info: PRIVATE: INCLK0_FREQ_UNIT_COMBO STRING "MHz"
+// Retrieval info: PRIVATE: MEGAFN_PORT_INFO_0 STRING "inclk;fbin;pllena;clkswitch;areset"
+// Retrieval info: PRIVATE: GLOCKED_MODE_CHECK STRING "0"
+// Retrieval info: PRIVATE: NORMAL_MODE_RADIO STRING "1"
+// Retrieval info: PRIVATE: CUR_FBIN_CLK STRING "e0"
+// Retrieval info: PRIVATE: MEGAFN_PORT_INFO_1 STRING "pfdena;clkena;extclkena;scanclk;scanaclr"
+// Retrieval info: PRIVATE: DIV_FACTOR0 NUMERIC "1"
+// Retrieval info: PRIVATE: INCLK1_FREQ_UNIT_CHANGED STRING "1"
+// Retrieval info: PRIVATE: HAS_MANUAL_SWITCHOVER STRING "1"
+// Retrieval info: PRIVATE: EXT_FEEDBACK_RADIO STRING "0"
+// Retrieval info: PRIVATE: PLL_AUTOPLL_CHECK NUMERIC "1"
+// Retrieval info: PRIVATE: MEGAFN_PORT_INFO_2 STRING "scandata;scanread;scanwrite;clk;extclk"
+// Retrieval info: PRIVATE: CLKLOSS_CHECK STRING "0"
+// Retrieval info: PRIVATE: BANDWIDTH_USE_AUTO STRING "1"
+// Retrieval info: PRIVATE: SHORT_SCAN_RADIO STRING "0"
+// Retrieval info: PRIVATE: LVDS_MODE_DATA_RATE STRING "528.000"
+// Retrieval info: PRIVATE: MEGAFN_PORT_INFO_3 STRING "clkbad;activeclock;locked;clkloss;scandataout"
+// Retrieval info: PRIVATE: CLKSWITCH_CHECK STRING "0"
+// Retrieval info: PRIVATE: SPREAD_FREQ_UNIT STRING "KHz"
+// Retrieval info: PRIVATE: PLL_ENA_CHECK STRING "0"
+// Retrieval info: PRIVATE: INCLK0_FREQ_EDIT STRING "48.000"
+// Retrieval info: PRIVATE: MEGAFN_PORT_INFO_4 STRING "scandone;sclkout1;sclkout0;enable0;enable1"
+// Retrieval info: PRIVATE: CNX_NO_COMPENSATE_RADIO STRING "0"
+// Retrieval info: PRIVATE: INT_FEEDBACK__MODE_RADIO STRING "1"
+// Retrieval info: PRIVATE: OUTPUT_FREQ0 STRING "100.000"
+// Retrieval info: PRIVATE: PRIMARY_CLK_COMBO STRING "inclk0"
+// Retrieval info: PRIVATE: CREATE_INCLK1_CHECK STRING "0"
+// Retrieval info: PRIVATE: SACN_INPUTS_CHECK STRING "0"
+// Retrieval info: PRIVATE: DEV_FAMILY STRING "Cyclone"
+// Retrieval info: PRIVATE: LOCK_LOSS_SWITCHOVER_CHECK STRING "0"
+// Retrieval info: PRIVATE: SWITCHOVER_COUNT_EDIT NUMERIC "1"
+// Retrieval info: PRIVATE: SWITCHOVER_FEATURE_ENABLED STRING "0"
+// Retrieval info: PRIVATE: BANDWIDTH_PRESET STRING "Low"
+// Retrieval info: PRIVATE: GLOCKED_FEATURE_ENABLED STRING "0"
+// Retrieval info: PRIVATE: USE_CLKENA0 STRING "0"
+// Retrieval info: PRIVATE: LVDS_PHASE_SHIFT_UNIT0 STRING "deg"
+// Retrieval info: PRIVATE: CLKBAD_SWITCHOVER_CHECK STRING "0"
+// Retrieval info: PRIVATE: BANDWIDTH_USE_PRESET STRING "0"
+// Retrieval info: PRIVATE: PLL_LVDS_PLL_CHECK NUMERIC "0"
+// Retrieval info: PRIVATE: DEVICE_FAMILY NUMERIC "11"
+// Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all
+// Retrieval info: CONSTANT: CLK0_DUTY_CYCLE NUMERIC "50"
+// Retrieval info: CONSTANT: LPM_TYPE STRING "altpll"
+// Retrieval info: CONSTANT: CLK0_MULTIPLY_BY NUMERIC "1"
+// Retrieval info: CONSTANT: INCLK0_INPUT_FREQUENCY NUMERIC "20833"
+// Retrieval info: CONSTANT: CLK0_DIVIDE_BY NUMERIC "1"
+// Retrieval info: CONSTANT: PLL_TYPE STRING "AUTO"
+// Retrieval info: CONSTANT: CLK0_TIME_DELAY STRING "0"
+// Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone"
+// Retrieval info: CONSTANT: OPERATION_MODE STRING "NORMAL"
+// Retrieval info: CONSTANT: COMPENSATE_CLOCK STRING "CLK0"
+// Retrieval info: CONSTANT: CLK0_PHASE_SHIFT STRING "-3000"
+// Retrieval info: USED_PORT: c0 0 0 0 0 OUTPUT VCC "c0"
+// Retrieval info: USED_PORT: @clk 0 0 6 0 OUTPUT VCC "@clk[5..0]"
+// Retrieval info: USED_PORT: inclk0 0 0 0 0 INPUT GND "inclk0"
+// Retrieval info: USED_PORT: @extclk 0 0 4 0 OUTPUT VCC "@extclk[3..0]"
+// Retrieval info: CONNECT: @inclk 0 0 1 0 inclk0 0 0 0 0
+// Retrieval info: CONNECT: c0 0 0 0 0 @clk 0 0 1 0
+// Retrieval info: CONNECT: @inclk 0 0 1 1 GND 0 0 0 0
+// Retrieval info: GEN_FILE: TYPE_NORMAL pll.v TRUE FALSE
+// Retrieval info: GEN_FILE: TYPE_NORMAL pll.inc FALSE FALSE
+// Retrieval info: GEN_FILE: TYPE_NORMAL pll.cmp FALSE FALSE
+// Retrieval info: GEN_FILE: TYPE_NORMAL pll.bsf FALSE FALSE
+// Retrieval info: GEN_FILE: TYPE_NORMAL pll_inst.v TRUE FALSE
+// Retrieval info: GEN_FILE: TYPE_NORMAL pll_bb.v TRUE FALSE
diff --git a/usrp/fpga/megacells/pll_bb.v b/usrp/fpga/megacells/pll_bb.v
new file mode 100644 (file)
index 0000000..debadaa
--- /dev/null
@@ -0,0 +1,29 @@
+//Copyright (C) 1991-2004 Altera Corporation
+//Any  megafunction  design,  and related netlist (encrypted  or  decrypted),
+//support information,  device programming or simulation file,  and any other
+//associated  documentation or information  provided by  Altera  or a partner
+//under  Altera's   Megafunction   Partnership   Program  may  be  used  only
+//to program  PLD  devices (but not masked  PLD  devices) from  Altera.   Any
+//other  use  of such  megafunction  design,  netlist,  support  information,
+//device programming or simulation file,  or any other  related documentation
+//or information  is prohibited  for  any  other purpose,  including, but not
+//limited to  modification,  reverse engineering,  de-compiling, or use  with
+//any other  silicon devices,  unless such use is  explicitly  licensed under
+//a separate agreement with  Altera  or a megafunction partner.  Title to the
+//intellectual property,  including patents,  copyrights,  trademarks,  trade
+//secrets,  or maskworks,  embodied in any such megafunction design, netlist,
+//support  information,  device programming or simulation file,  or any other
+//related documentation or information provided by  Altera  or a megafunction
+//partner, remains with Altera, the megafunction partner, or their respective
+//licensors. No other licenses, including any licenses needed under any third
+//party's intellectual property, are provided herein.
+
+module pll (
+       inclk0,
+       c0);
+
+       input     inclk0;
+       output    c0;
+
+endmodule
+
diff --git a/usrp/fpga/megacells/pll_inst.v b/usrp/fpga/megacells/pll_inst.v
new file mode 100644 (file)
index 0000000..97db58b
--- /dev/null
@@ -0,0 +1,4 @@
+pll    pll_inst (
+       .inclk0 ( inclk0_sig ),
+       .c0 ( c0_sig )
+       );
diff --git a/usrp/fpga/megacells/sub32.bsf b/usrp/fpga/megacells/sub32.bsf
new file mode 100755 (executable)
index 0000000..753fdc7
--- /dev/null
@@ -0,0 +1,87 @@
+/*
+WARNING: Do NOT edit the input and output ports in this file in a text
+editor if you plan to continue editing the block that represents it in
+the Block Editor! File corruption is VERY likely to occur.
+*/
+/*
+Copyright (C) 1991-2003 Altera Corporation
+Any  megafunction  design,  and related netlist (encrypted  or  decrypted),
+support information,  device programming or simulation file,  and any other
+associated  documentation or information  provided by  Altera  or a partner
+under  Altera's   Megafunction   Partnership   Program  may  be  used  only
+to program  PLD  devices (but not masked  PLD  devices) from  Altera.   Any
+other  use  of such  megafunction  design,  netlist,  support  information,
+device programming or simulation file,  or any other  related documentation
+or information  is prohibited  for  any  other purpose,  including, but not
+limited to  modification,  reverse engineering,  de-compiling, or use  with
+any other  silicon devices,  unless such use is  explicitly  licensed under
+a separate agreement with  Altera  or a megafunction partner.  Title to the
+intellectual property,  including patents,  copyrights,  trademarks,  trade
+secrets,  or maskworks,  embodied in any such megafunction design, netlist,
+support  information,  device programming or simulation file,  or any other
+related documentation or information provided by  Altera  or a megafunction
+partner, remains with Altera, the megafunction partner, or their respective
+licensors. No other licenses, including any licenses needed under any third
+party's intellectual property, are provided herein.
+*/
+(header "symbol" (version "1.1"))
+(symbol
+       (rect 0 0 160 128)
+       (text "sub32" (rect 58 2 109 21)(font "Arial" (font_size 10)))
+       (text "inst" (rect 8 109 31 124)(font "Arial" ))
+       (port
+               (pt 0 40)
+               (input)
+               (text "dataa[31..0]" (rect 0 0 81 16)(font "Arial" (font_size 8)))
+               (text "dataa[31..0]" (rect 4 24 73 40)(font "Arial" (font_size 8)))
+               (line (pt 0 40)(pt 64 40)(line_width 3))
+       )
+       (port
+               (pt 0 72)
+               (input)
+               (text "datab[31..0]" (rect 0 0 81 16)(font "Arial" (font_size 8)))
+               (text "datab[31..0]" (rect 4 56 73 72)(font "Arial" (font_size 8)))
+               (line (pt 0 72)(pt 64 72)(line_width 3))
+       )
+       (port
+               (pt 0 56)
+               (input)
+               (text "clock" (rect 0 0 36 16)(font "Arial" (font_size 8)))
+               (text "clock" (rect 4 40 35 56)(font "Arial" (font_size 8)))
+               (line (pt 0 56)(pt 64 56)(line_width 1))
+       )
+       (port
+               (pt 0 96)
+               (input)
+               (text "clken" (rect 0 0 36 16)(font "Arial" (font_size 8)))
+               (text "clken" (rect 4 80 35 96)(font "Arial" (font_size 8)))
+               (line (pt 0 96)(pt 74 96)(line_width 1))
+       )
+       (port
+               (pt 0 112)
+               (input)
+               (text "aclr" (rect 0 0 24 16)(font "Arial" (font_size 8)))
+               (text "aclr" (rect 4 96 25 112)(font "Arial" (font_size 8)))
+               (line (pt 0 112)(pt 85 112)(line_width 1))
+       )
+       (port
+               (pt 160 56)
+               (output)
+               (text "result[31..0]" (rect 0 0 81 16)(font "Arial" (font_size 8)))
+               (text "result[31..0]" (rect 88 40 157 56)(font "Arial" (font_size 8)))
+               (line (pt 160 56)(pt 96 56)(line_width 3))
+       )
+       (drawing
+               (text "A" (rect 66 32 75 48)(font "Arial" (font_size 8)))
+               (text "B" (rect 66 64 75 80)(font "Arial" (font_size 8)))
+               (text "A-B" (rect 72 48 94 64)(font "Arial" (font_size 8)))
+               (line (pt 64 32)(pt 96 40)(line_width 1))
+               (line (pt 96 40)(pt 96 72)(line_width 1))
+               (line (pt 96 72)(pt 64 80)(line_width 1))
+               (line (pt 64 80)(pt 64 32)(line_width 1))
+               (line (pt 74 96)(pt 74 77)(line_width 1))
+               (line (pt 85 112)(pt 85 74)(line_width 1))
+               (line (pt 64 50)(pt 70 56)(line_width 1))
+               (line (pt 70 56)(pt 64 62)(line_width 1))
+       )
+)
diff --git a/usrp/fpga/megacells/sub32.cmp b/usrp/fpga/megacells/sub32.cmp
new file mode 100755 (executable)
index 0000000..0d5b62e
--- /dev/null
@@ -0,0 +1,32 @@
+--Copyright (C) 1991-2003 Altera Corporation
+--Any  megafunction  design,  and related netlist (encrypted  or  decrypted),
+--support information,  device programming or simulation file,  and any other
+--associated  documentation or information  provided by  Altera  or a partner
+--under  Altera's   Megafunction   Partnership   Program  may  be  used  only
+--to program  PLD  devices (but not masked  PLD  devices) from  Altera.   Any
+--other  use  of such  megafunction  design,  netlist,  support  information,
+--device programming or simulation file,  or any other  related documentation
+--or information  is prohibited  for  any  other purpose,  including, but not
+--limited to  modification,  reverse engineering,  de-compiling, or use  with
+--any other  silicon devices,  unless such use is  explicitly  licensed under
+--a separate agreement with  Altera  or a megafunction partner.  Title to the
+--intellectual property,  including patents,  copyrights,  trademarks,  trade
+--secrets,  or maskworks,  embodied in any such megafunction design, netlist,
+--support  information,  device programming or simulation file,  or any other
+--related documentation or information provided by  Altera  or a megafunction
+--partner, remains with Altera, the megafunction partner, or their respective
+--licensors. No other licenses, including any licenses needed under any third
+--party's intellectual property, are provided herein.
+
+
+component sub32
+       PORT
+       (
+               dataa           : IN STD_LOGIC_VECTOR (31 DOWNTO 0);
+               datab           : IN STD_LOGIC_VECTOR (31 DOWNTO 0);
+               clock           : IN STD_LOGIC ;
+               aclr            : IN STD_LOGIC ;
+               clken           : IN STD_LOGIC ;
+               result          : OUT STD_LOGIC_VECTOR (31 DOWNTO 0)
+       );
+end component;
diff --git a/usrp/fpga/megacells/sub32.inc b/usrp/fpga/megacells/sub32.inc
new file mode 100755 (executable)
index 0000000..3c64e21
--- /dev/null
@@ -0,0 +1,33 @@
+--Copyright (C) 1991-2003 Altera Corporation
+--Any  megafunction  design,  and related netlist (encrypted  or  decrypted),
+--support information,  device programming or simulation file,  and any other
+--associated  documentation or information  provided by  Altera  or a partner
+--under  Altera's   Megafunction   Partnership   Program  may  be  used  only
+--to program  PLD  devices (but not masked  PLD  devices) from  Altera.   Any
+--other  use  of such  megafunction  design,  netlist,  support  information,
+--device programming or simulation file,  or any other  related documentation
+--or information  is prohibited  for  any  other purpose,  including, but not
+--limited to  modification,  reverse engineering,  de-compiling, or use  with
+--any other  silicon devices,  unless such use is  explicitly  licensed under
+--a separate agreement with  Altera  or a megafunction partner.  Title to the
+--intellectual property,  including patents,  copyrights,  trademarks,  trade
+--secrets,  or maskworks,  embodied in any such megafunction design, netlist,
+--support  information,  device programming or simulation file,  or any other
+--related documentation or information provided by  Altera  or a megafunction
+--partner, remains with Altera, the megafunction partner, or their respective
+--licensors. No other licenses, including any licenses needed under any third
+--party's intellectual property, are provided herein.
+
+
+FUNCTION sub32 
+(
+       dataa[31..0],
+       datab[31..0],
+       clock,
+       aclr,
+       clken
+)
+
+RETURNS (
+       result[31..0]
+);
diff --git a/usrp/fpga/megacells/sub32.v b/usrp/fpga/megacells/sub32.v
new file mode 100755 (executable)
index 0000000..dd825d9
--- /dev/null
@@ -0,0 +1,675 @@
+// megafunction wizard: %LPM_ADD_SUB%CBX%
+// GENERATION: STANDARD
+// VERSION: WM1.0
+// MODULE: lpm_add_sub 
+
+// ============================================================
+// File Name: sub32.v
+// Megafunction Name(s):
+//                     lpm_add_sub
+// ============================================================
+// ************************************************************
+// THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE!
+// ************************************************************
+
+
+//Copyright (C) 1991-2003 Altera Corporation
+//Any  megafunction  design,  and related netlist (encrypted  or  decrypted),
+//support information,  device programming or simulation file,  and any other
+//associated  documentation or information  provided by  Altera  or a partner
+//under  Altera's   Megafunction   Partnership   Program  may  be  used  only
+//to program  PLD  devices (but not masked  PLD  devices) from  Altera.   Any
+//other  use  of such  megafunction  design,  netlist,  support  information,
+//device programming or simulation file,  or any other  related documentation
+//or information  is prohibited  for  any  other purpose,  including, but not
+//limited to  modification,  reverse engineering,  de-compiling, or use  with
+//any other  silicon devices,  unless such use is  explicitly  licensed under
+//a separate agreement with  Altera  or a megafunction partner.  Title to the
+//intellectual property,  including patents,  copyrights,  trademarks,  trade
+//secrets,  or maskworks,  embodied in any such megafunction design, netlist,
+//support  information,  device programming or simulation file,  or any other
+//related documentation or information provided by  Altera  or a megafunction
+//partner, remains with Altera, the megafunction partner, or their respective
+//licensors. No other licenses, including any licenses needed under any third
+//party's intellectual property, are provided herein.
+
+
+//lpm_add_sub DEVICE_FAMILY=Cyclone LPM_DIRECTION=SUB LPM_PIPELINE=1 LPM_WIDTH=32 aclr clken clock dataa datab result
+//VERSION_BEGIN 3.0 cbx_lpm_add_sub 2003:04:10:18:28:42:SJ cbx_mgl 2003:06:11:11:00:44:SJ cbx_stratix 2003:05:16:10:26:50:SJ  VERSION_END
+
+//synthesis_resources = lut 32 
+module  sub32_add_sub_cqa
+       ( 
+       aclr,
+       clken,
+       clock,
+       dataa,
+       datab,
+       result) /* synthesis synthesis_clearbox=1 */;
+       input   aclr;
+       input   clken;
+       input   clock;
+       input   [31:0]  dataa;
+       input   [31:0]  datab;
+       output   [31:0]  result;
+
+       wire  [0:0]   wire_add_sub_cella_0cout;
+       wire  [0:0]   wire_add_sub_cella_1cout;
+       wire  [0:0]   wire_add_sub_cella_2cout;
+       wire  [0:0]   wire_add_sub_cella_3cout;
+       wire  [0:0]   wire_add_sub_cella_4cout;
+       wire  [0:0]   wire_add_sub_cella_5cout;
+       wire  [0:0]   wire_add_sub_cella_6cout;
+       wire  [0:0]   wire_add_sub_cella_7cout;
+       wire  [0:0]   wire_add_sub_cella_8cout;
+       wire  [0:0]   wire_add_sub_cella_9cout;
+       wire  [0:0]   wire_add_sub_cella_10cout;
+       wire  [0:0]   wire_add_sub_cella_11cout;
+       wire  [0:0]   wire_add_sub_cella_12cout;
+       wire  [0:0]   wire_add_sub_cella_13cout;
+       wire  [0:0]   wire_add_sub_cella_14cout;
+       wire  [0:0]   wire_add_sub_cella_15cout;
+       wire  [0:0]   wire_add_sub_cella_16cout;
+       wire  [0:0]   wire_add_sub_cella_17cout;
+       wire  [0:0]   wire_add_sub_cella_18cout;
+       wire  [0:0]   wire_add_sub_cella_19cout;
+       wire  [0:0]   wire_add_sub_cella_20cout;
+       wire  [0:0]   wire_add_sub_cella_21cout;
+       wire  [0:0]   wire_add_sub_cella_22cout;
+       wire  [0:0]   wire_add_sub_cella_23cout;
+       wire  [0:0]   wire_add_sub_cella_24cout;
+       wire  [0:0]   wire_add_sub_cella_25cout;
+       wire  [0:0]   wire_add_sub_cella_26cout;
+       wire  [0:0]   wire_add_sub_cella_27cout;
+       wire  [0:0]   wire_add_sub_cella_28cout;
+       wire  [0:0]   wire_add_sub_cella_29cout;
+       wire  [0:0]   wire_add_sub_cella_30cout;
+       wire  [31:0]   wire_add_sub_cella_dataa;
+       wire  [31:0]   wire_add_sub_cella_datab;
+       wire  [31:0]   wire_add_sub_cella_regout;
+
+       stratix_lcell   add_sub_cella_0
+       ( 
+       .aclr(aclr),
+       .cin(1'b1),
+       .clk(clock),
+       .cout(wire_add_sub_cella_0cout[0:0]),
+       .dataa(wire_add_sub_cella_dataa[0:0]),
+       .datab(wire_add_sub_cella_datab[0:0]),
+       .ena(clken),
+       .regout(wire_add_sub_cella_regout[0:0]));
+       defparam
+               add_sub_cella_0.cin_used = "true",
+               add_sub_cella_0.lut_mask = "69b2",
+               add_sub_cella_0.operation_mode = "arithmetic",
+               add_sub_cella_0.sum_lutc_input = "cin",
+               add_sub_cella_0.lpm_type = "stratix_lcell";
+       stratix_lcell   add_sub_cella_1
+       ( 
+       .aclr(aclr),
+       .cin(wire_add_sub_cella_0cout[0:0]),
+       .clk(clock),
+       .cout(wire_add_sub_cella_1cout[0:0]),
+       .dataa(wire_add_sub_cella_dataa[1:1]),
+       .datab(wire_add_sub_cella_datab[1:1]),
+       .ena(clken),
+       .regout(wire_add_sub_cella_regout[1:1]));
+       defparam
+               add_sub_cella_1.cin_used = "true",
+               add_sub_cella_1.lut_mask = "69b2",
+               add_sub_cella_1.operation_mode = "arithmetic",
+               add_sub_cella_1.sum_lutc_input = "cin",
+               add_sub_cella_1.lpm_type = "stratix_lcell";
+       stratix_lcell   add_sub_cella_2
+       ( 
+       .aclr(aclr),
+       .cin(wire_add_sub_cella_1cout[0:0]),
+       .clk(clock),
+       .cout(wire_add_sub_cella_2cout[0:0]),
+       .dataa(wire_add_sub_cella_dataa[2:2]),
+       .datab(wire_add_sub_cella_datab[2:2]),
+       .ena(clken),
+       .regout(wire_add_sub_cella_regout[2:2]));
+       defparam
+               add_sub_cella_2.cin_used = "true",
+               add_sub_cella_2.lut_mask = "69b2",
+               add_sub_cella_2.operation_mode = "arithmetic",
+               add_sub_cella_2.sum_lutc_input = "cin",
+               add_sub_cella_2.lpm_type = "stratix_lcell";
+       stratix_lcell   add_sub_cella_3
+       ( 
+       .aclr(aclr),
+       .cin(wire_add_sub_cella_2cout[0:0]),
+       .clk(clock),
+       .cout(wire_add_sub_cella_3cout[0:0]),
+       .dataa(wire_add_sub_cella_dataa[3:3]),
+       .datab(wire_add_sub_cella_datab[3:3]),
+       .ena(clken),
+       .regout(wire_add_sub_cella_regout[3:3]));
+       defparam
+               add_sub_cella_3.cin_used = "true",
+               add_sub_cella_3.lut_mask = "69b2",
+               add_sub_cella_3.operation_mode = "arithmetic",
+               add_sub_cella_3.sum_lutc_input = "cin",
+               add_sub_cella_3.lpm_type = "stratix_lcell";
+       stratix_lcell   add_sub_cella_4
+       ( 
+       .aclr(aclr),
+       .cin(wire_add_sub_cella_3cout[0:0]),
+       .clk(clock),
+       .cout(wire_add_sub_cella_4cout[0:0]),
+       .dataa(wire_add_sub_cella_dataa[4:4]),
+       .datab(wire_add_sub_cella_datab[4:4]),
+       .ena(clken),
+       .regout(wire_add_sub_cella_regout[4:4]));
+       defparam
+               add_sub_cella_4.cin_used = "true",
+               add_sub_cella_4.lut_mask = "69b2",
+               add_sub_cella_4.operation_mode = "arithmetic",
+               add_sub_cella_4.sum_lutc_input = "cin",
+               add_sub_cella_4.lpm_type = "stratix_lcell";
+       stratix_lcell   add_sub_cella_5
+       ( 
+       .aclr(aclr),
+       .cin(wire_add_sub_cella_4cout[0:0]),
+       .clk(clock),
+       .cout(wire_add_sub_cella_5cout[0:0]),
+       .dataa(wire_add_sub_cella_dataa[5:5]),
+       .datab(wire_add_sub_cella_datab[5:5]),
+       .ena(clken),
+       .regout(wire_add_sub_cella_regout[5:5]));
+       defparam
+               add_sub_cella_5.cin_used = "true",
+               add_sub_cella_5.lut_mask = "69b2",
+               add_sub_cella_5.operation_mode = "arithmetic",
+               add_sub_cella_5.sum_lutc_input = "cin",
+               add_sub_cella_5.lpm_type = "stratix_lcell";
+       stratix_lcell   add_sub_cella_6
+       ( 
+       .aclr(aclr),
+       .cin(wire_add_sub_cella_5cout[0:0]),
+       .clk(clock),
+       .cout(wire_add_sub_cella_6cout[0:0]),
+       .dataa(wire_add_sub_cella_dataa[6:6]),
+       .datab(wire_add_sub_cella_datab[6:6]),
+       .ena(clken),
+       .regout(wire_add_sub_cella_regout[6:6]));
+       defparam
+               add_sub_cella_6.cin_used = "true",
+               add_sub_cella_6.lut_mask = "69b2",
+               add_sub_cella_6.operation_mode = "arithmetic",
+               add_sub_cella_6.sum_lutc_input = "cin",
+               add_sub_cella_6.lpm_type = "stratix_lcell";
+       stratix_lcell   add_sub_cella_7
+       ( 
+       .aclr(aclr),
+       .cin(wire_add_sub_cella_6cout[0:0]),
+       .clk(clock),
+       .cout(wire_add_sub_cella_7cout[0:0]),
+       .dataa(wire_add_sub_cella_dataa[7:7]),
+       .datab(wire_add_sub_cella_datab[7:7]),
+       .ena(clken),
+       .regout(wire_add_sub_cella_regout[7:7]));
+       defparam
+               add_sub_cella_7.cin_used = "true",
+               add_sub_cella_7.lut_mask = "69b2",
+               add_sub_cella_7.operation_mode = "arithmetic",
+               add_sub_cella_7.sum_lutc_input = "cin",
+               add_sub_cella_7.lpm_type = "stratix_lcell";
+       stratix_lcell   add_sub_cella_8
+       ( 
+       .aclr(aclr),
+       .cin(wire_add_sub_cella_7cout[0:0]),
+       .clk(clock),
+       .cout(wire_add_sub_cella_8cout[0:0]),
+       .dataa(wire_add_sub_cella_dataa[8:8]),
+       .datab(wire_add_sub_cella_datab[8:8]),
+       .ena(clken),
+       .regout(wire_add_sub_cella_regout[8:8]));
+       defparam
+               add_sub_cella_8.cin_used = "true",
+               add_sub_cella_8.lut_mask = "69b2",
+               add_sub_cella_8.operation_mode = "arithmetic",
+               add_sub_cella_8.sum_lutc_input = "cin",
+               add_sub_cella_8.lpm_type = "stratix_lcell";
+       stratix_lcell   add_sub_cella_9
+       ( 
+       .aclr(aclr),
+       .cin(wire_add_sub_cella_8cout[0:0]),
+       .clk(clock),
+       .cout(wire_add_sub_cella_9cout[0:0]),
+       .dataa(wire_add_sub_cella_dataa[9:9]),
+       .datab(wire_add_sub_cella_datab[9:9]),
+       .ena(clken),
+       .regout(wire_add_sub_cella_regout[9:9]));
+       defparam
+               add_sub_cella_9.cin_used = "true",
+               add_sub_cella_9.lut_mask = "69b2",
+               add_sub_cella_9.operation_mode = "arithmetic",
+               add_sub_cella_9.sum_lutc_input = "cin",
+               add_sub_cella_9.lpm_type = "stratix_lcell";
+       stratix_lcell   add_sub_cella_10
+       ( 
+       .aclr(aclr),
+       .cin(wire_add_sub_cella_9cout[0:0]),
+       .clk(clock),
+       .cout(wire_add_sub_cella_10cout[0:0]),
+       .dataa(wire_add_sub_cella_dataa[10:10]),
+       .datab(wire_add_sub_cella_datab[10:10]),
+       .ena(clken),
+       .regout(wire_add_sub_cella_regout[10:10]));
+       defparam
+               add_sub_cella_10.cin_used = "true",
+               add_sub_cella_10.lut_mask = "69b2",
+               add_sub_cella_10.operation_mode = "arithmetic",
+               add_sub_cella_10.sum_lutc_input = "cin",
+               add_sub_cella_10.lpm_type = "stratix_lcell";
+       stratix_lcell   add_sub_cella_11
+       ( 
+       .aclr(aclr),
+       .cin(wire_add_sub_cella_10cout[0:0]),
+       .clk(clock),
+       .cout(wire_add_sub_cella_11cout[0:0]),
+       .dataa(wire_add_sub_cella_dataa[11:11]),
+       .datab(wire_add_sub_cella_datab[11:11]),
+       .ena(clken),
+       .regout(wire_add_sub_cella_regout[11:11]));
+       defparam
+               add_sub_cella_11.cin_used = "true",
+               add_sub_cella_11.lut_mask = "69b2",
+               add_sub_cella_11.operation_mode = "arithmetic",
+               add_sub_cella_11.sum_lutc_input = "cin",
+               add_sub_cella_11.lpm_type = "stratix_lcell";
+       stratix_lcell   add_sub_cella_12
+       ( 
+       .aclr(aclr),
+       .cin(wire_add_sub_cella_11cout[0:0]),
+       .clk(clock),
+       .cout(wire_add_sub_cella_12cout[0:0]),
+       .dataa(wire_add_sub_cella_dataa[12:12]),
+       .datab(wire_add_sub_cella_datab[12:12]),
+       .ena(clken),
+       .regout(wire_add_sub_cella_regout[12:12]));
+       defparam
+               add_sub_cella_12.cin_used = "true",
+               add_sub_cella_12.lut_mask = "69b2",
+               add_sub_cella_12.operation_mode = "arithmetic",
+               add_sub_cella_12.sum_lutc_input = "cin",
+               add_sub_cella_12.lpm_type = "stratix_lcell";
+       stratix_lcell   add_sub_cella_13
+       ( 
+       .aclr(aclr),
+       .cin(wire_add_sub_cella_12cout[0:0]),
+       .clk(clock),
+       .cout(wire_add_sub_cella_13cout[0:0]),
+       .dataa(wire_add_sub_cella_dataa[13:13]),
+       .datab(wire_add_sub_cella_datab[13:13]),
+       .ena(clken),
+       .regout(wire_add_sub_cella_regout[13:13]));
+       defparam
+               add_sub_cella_13.cin_used = "true",
+               add_sub_cella_13.lut_mask = "69b2",
+               add_sub_cella_13.operation_mode = "arithmetic",
+               add_sub_cella_13.sum_lutc_input = "cin",
+               add_sub_cella_13.lpm_type = "stratix_lcell";
+       stratix_lcell   add_sub_cella_14
+       ( 
+       .aclr(aclr),
+       .cin(wire_add_sub_cella_13cout[0:0]),
+       .clk(clock),
+       .cout(wire_add_sub_cella_14cout[0:0]),
+       .dataa(wire_add_sub_cella_dataa[14:14]),
+       .datab(wire_add_sub_cella_datab[14:14]),
+       .ena(clken),
+       .regout(wire_add_sub_cella_regout[14:14]));
+       defparam
+               add_sub_cella_14.cin_used = "true",
+               add_sub_cella_14.lut_mask = "69b2",
+               add_sub_cella_14.operation_mode = "arithmetic",
+               add_sub_cella_14.sum_lutc_input = "cin",
+               add_sub_cella_14.lpm_type = "stratix_lcell";
+       stratix_lcell   add_sub_cella_15
+       ( 
+       .aclr(aclr),
+       .cin(wire_add_sub_cella_14cout[0:0]),
+       .clk(clock),
+       .cout(wire_add_sub_cella_15cout[0:0]),
+       .dataa(wire_add_sub_cella_dataa[15:15]),
+       .datab(wire_add_sub_cella_datab[15:15]),
+       .ena(clken),
+       .regout(wire_add_sub_cella_regout[15:15]));
+       defparam
+               add_sub_cella_15.cin_used = "true",
+               add_sub_cella_15.lut_mask = "69b2",
+               add_sub_cella_15.operation_mode = "arithmetic",
+               add_sub_cella_15.sum_lutc_input = "cin",
+               add_sub_cella_15.lpm_type = "stratix_lcell";
+       stratix_lcell   add_sub_cella_16
+       ( 
+       .aclr(aclr),
+       .cin(wire_add_sub_cella_15cout[0:0]),
+       .clk(clock),
+       .cout(wire_add_sub_cella_16cout[0:0]),
+       .dataa(wire_add_sub_cella_dataa[16:16]),
+       .datab(wire_add_sub_cella_datab[16:16]),
+       .ena(clken),
+       .regout(wire_add_sub_cella_regout[16:16]));
+       defparam
+               add_sub_cella_16.cin_used = "true",
+               add_sub_cella_16.lut_mask = "69b2",
+               add_sub_cella_16.operation_mode = "arithmetic",
+               add_sub_cella_16.sum_lutc_input = "cin",
+               add_sub_cella_16.lpm_type = "stratix_lcell";
+       stratix_lcell   add_sub_cella_17
+       ( 
+       .aclr(aclr),
+       .cin(wire_add_sub_cella_16cout[0:0]),
+       .clk(clock),
+       .cout(wire_add_sub_cella_17cout[0:0]),
+       .dataa(wire_add_sub_cella_dataa[17:17]),
+       .datab(wire_add_sub_cella_datab[17:17]),
+       .ena(clken),
+       .regout(wire_add_sub_cella_regout[17:17]));
+       defparam
+               add_sub_cella_17.cin_used = "true",
+               add_sub_cella_17.lut_mask = "69b2",
+               add_sub_cella_17.operation_mode = "arithmetic",
+               add_sub_cella_17.sum_lutc_input = "cin",
+               add_sub_cella_17.lpm_type = "stratix_lcell";
+       stratix_lcell   add_sub_cella_18
+       ( 
+       .aclr(aclr),
+       .cin(wire_add_sub_cella_17cout[0:0]),
+       .clk(clock),
+       .cout(wire_add_sub_cella_18cout[0:0]),
+       .dataa(wire_add_sub_cella_dataa[18:18]),
+       .datab(wire_add_sub_cella_datab[18:18]),
+       .ena(clken),
+       .regout(wire_add_sub_cella_regout[18:18]));
+       defparam
+               add_sub_cella_18.cin_used = "true",
+               add_sub_cella_18.lut_mask = "69b2",
+               add_sub_cella_18.operation_mode = "arithmetic",
+               add_sub_cella_18.sum_lutc_input = "cin",
+               add_sub_cella_18.lpm_type = "stratix_lcell";
+       stratix_lcell   add_sub_cella_19
+       ( 
+       .aclr(aclr),
+       .cin(wire_add_sub_cella_18cout[0:0]),
+       .clk(clock),
+       .cout(wire_add_sub_cella_19cout[0:0]),
+       .dataa(wire_add_sub_cella_dataa[19:19]),
+       .datab(wire_add_sub_cella_datab[19:19]),
+       .ena(clken),
+       .regout(wire_add_sub_cella_regout[19:19]));
+       defparam
+               add_sub_cella_19.cin_used = "true",
+               add_sub_cella_19.lut_mask = "69b2",
+               add_sub_cella_19.operation_mode = "arithmetic",
+               add_sub_cella_19.sum_lutc_input = "cin",
+               add_sub_cella_19.lpm_type = "stratix_lcell";
+       stratix_lcell   add_sub_cella_20
+       ( 
+       .aclr(aclr),
+       .cin(wire_add_sub_cella_19cout[0:0]),
+       .clk(clock),
+       .cout(wire_add_sub_cella_20cout[0:0]),
+       .dataa(wire_add_sub_cella_dataa[20:20]),
+       .datab(wire_add_sub_cella_datab[20:20]),
+       .ena(clken),
+       .regout(wire_add_sub_cella_regout[20:20]));
+       defparam
+               add_sub_cella_20.cin_used = "true",
+               add_sub_cella_20.lut_mask = "69b2",
+               add_sub_cella_20.operation_mode = "arithmetic",
+               add_sub_cella_20.sum_lutc_input = "cin",
+               add_sub_cella_20.lpm_type = "stratix_lcell";
+       stratix_lcell   add_sub_cella_21
+       ( 
+       .aclr(aclr),
+       .cin(wire_add_sub_cella_20cout[0:0]),
+       .clk(clock),
+       .cout(wire_add_sub_cella_21cout[0:0]),
+       .dataa(wire_add_sub_cella_dataa[21:21]),
+       .datab(wire_add_sub_cella_datab[21:21]),
+       .ena(clken),
+       .regout(wire_add_sub_cella_regout[21:21]));
+       defparam
+               add_sub_cella_21.cin_used = "true",
+               add_sub_cella_21.lut_mask = "69b2",
+               add_sub_cella_21.operation_mode = "arithmetic",
+               add_sub_cella_21.sum_lutc_input = "cin",
+               add_sub_cella_21.lpm_type = "stratix_lcell";
+       stratix_lcell   add_sub_cella_22
+       ( 
+       .aclr(aclr),
+       .cin(wire_add_sub_cella_21cout[0:0]),
+       .clk(clock),
+       .cout(wire_add_sub_cella_22cout[0:0]),
+       .dataa(wire_add_sub_cella_dataa[22:22]),
+       .datab(wire_add_sub_cella_datab[22:22]),
+       .ena(clken),
+       .regout(wire_add_sub_cella_regout[22:22]));
+       defparam
+               add_sub_cella_22.cin_used = "true",
+               add_sub_cella_22.lut_mask = "69b2",
+               add_sub_cella_22.operation_mode = "arithmetic",
+               add_sub_cella_22.sum_lutc_input = "cin",
+               add_sub_cella_22.lpm_type = "stratix_lcell";
+       stratix_lcell   add_sub_cella_23
+       ( 
+       .aclr(aclr),
+       .cin(wire_add_sub_cella_22cout[0:0]),
+       .clk(clock),
+       .cout(wire_add_sub_cella_23cout[0:0]),
+       .dataa(wire_add_sub_cella_dataa[23:23]),
+       .datab(wire_add_sub_cella_datab[23:23]),
+       .ena(clken),
+       .regout(wire_add_sub_cella_regout[23:23]));
+       defparam
+               add_sub_cella_23.cin_used = "true",
+               add_sub_cella_23.lut_mask = "69b2",
+               add_sub_cella_23.operation_mode = "arithmetic",
+               add_sub_cella_23.sum_lutc_input = "cin",
+               add_sub_cella_23.lpm_type = "stratix_lcell";
+       stratix_lcell   add_sub_cella_24
+       ( 
+       .aclr(aclr),
+       .cin(wire_add_sub_cella_23cout[0:0]),
+       .clk(clock),
+       .cout(wire_add_sub_cella_24cout[0:0]),
+       .dataa(wire_add_sub_cella_dataa[24:24]),
+       .datab(wire_add_sub_cella_datab[24:24]),
+       .ena(clken),
+       .regout(wire_add_sub_cella_regout[24:24]));
+       defparam
+               add_sub_cella_24.cin_used = "true",
+               add_sub_cella_24.lut_mask = "69b2",
+               add_sub_cella_24.operation_mode = "arithmetic",
+               add_sub_cella_24.sum_lutc_input = "cin",
+               add_sub_cella_24.lpm_type = "stratix_lcell";
+       stratix_lcell   add_sub_cella_25
+       ( 
+       .aclr(aclr),
+       .cin(wire_add_sub_cella_24cout[0:0]),
+       .clk(clock),
+       .cout(wire_add_sub_cella_25cout[0:0]),
+       .dataa(wire_add_sub_cella_dataa[25:25]),
+       .datab(wire_add_sub_cella_datab[25:25]),
+       .ena(clken),
+       .regout(wire_add_sub_cella_regout[25:25]));
+       defparam
+               add_sub_cella_25.cin_used = "true",
+               add_sub_cella_25.lut_mask = "69b2",
+               add_sub_cella_25.operation_mode = "arithmetic",
+               add_sub_cella_25.sum_lutc_input = "cin",
+               add_sub_cella_25.lpm_type = "stratix_lcell";
+       stratix_lcell   add_sub_cella_26
+       ( 
+       .aclr(aclr),
+       .cin(wire_add_sub_cella_25cout[0:0]),
+       .clk(clock),
+       .cout(wire_add_sub_cella_26cout[0:0]),
+       .dataa(wire_add_sub_cella_dataa[26:26]),
+       .datab(wire_add_sub_cella_datab[26:26]),
+       .ena(clken),
+       .regout(wire_add_sub_cella_regout[26:26]));
+       defparam
+               add_sub_cella_26.cin_used = "true",
+               add_sub_cella_26.lut_mask = "69b2",
+               add_sub_cella_26.operation_mode = "arithmetic",
+               add_sub_cella_26.sum_lutc_input = "cin",
+               add_sub_cella_26.lpm_type = "stratix_lcell";
+       stratix_lcell   add_sub_cella_27
+       ( 
+       .aclr(aclr),
+       .cin(wire_add_sub_cella_26cout[0:0]),
+       .clk(clock),
+       .cout(wire_add_sub_cella_27cout[0:0]),
+       .dataa(wire_add_sub_cella_dataa[27:27]),
+       .datab(wire_add_sub_cella_datab[27:27]),
+       .ena(clken),
+       .regout(wire_add_sub_cella_regout[27:27]));
+       defparam
+               add_sub_cella_27.cin_used = "true",
+               add_sub_cella_27.lut_mask = "69b2",
+               add_sub_cella_27.operation_mode = "arithmetic",
+               add_sub_cella_27.sum_lutc_input = "cin",
+               add_sub_cella_27.lpm_type = "stratix_lcell";
+       stratix_lcell   add_sub_cella_28
+       ( 
+       .aclr(aclr),
+       .cin(wire_add_sub_cella_27cout[0:0]),
+       .clk(clock),
+       .cout(wire_add_sub_cella_28cout[0:0]),
+       .dataa(wire_add_sub_cella_dataa[28:28]),
+       .datab(wire_add_sub_cella_datab[28:28]),
+       .ena(clken),
+       .regout(wire_add_sub_cella_regout[28:28]));
+       defparam
+               add_sub_cella_28.cin_used = "true",
+               add_sub_cella_28.lut_mask = "69b2",
+               add_sub_cella_28.operation_mode = "arithmetic",
+               add_sub_cella_28.sum_lutc_input = "cin",
+               add_sub_cella_28.lpm_type = "stratix_lcell";
+       stratix_lcell   add_sub_cella_29
+       ( 
+       .aclr(aclr),
+       .cin(wire_add_sub_cella_28cout[0:0]),
+       .clk(clock),
+       .cout(wire_add_sub_cella_29cout[0:0]),
+       .dataa(wire_add_sub_cella_dataa[29:29]),
+       .datab(wire_add_sub_cella_datab[29:29]),
+       .ena(clken),
+       .regout(wire_add_sub_cella_regout[29:29]));
+       defparam
+               add_sub_cella_29.cin_used = "true",
+               add_sub_cella_29.lut_mask = "69b2",
+               add_sub_cella_29.operation_mode = "arithmetic",
+               add_sub_cella_29.sum_lutc_input = "cin",
+               add_sub_cella_29.lpm_type = "stratix_lcell";
+       stratix_lcell   add_sub_cella_30
+       ( 
+       .aclr(aclr),
+       .cin(wire_add_sub_cella_29cout[0:0]),
+       .clk(clock),
+       .cout(wire_add_sub_cella_30cout[0:0]),
+       .dataa(wire_add_sub_cella_dataa[30:30]),
+       .datab(wire_add_sub_cella_datab[30:30]),
+       .ena(clken),
+       .regout(wire_add_sub_cella_regout[30:30]));
+       defparam
+               add_sub_cella_30.cin_used = "true",
+               add_sub_cella_30.lut_mask = "69b2",
+               add_sub_cella_30.operation_mode = "arithmetic",
+               add_sub_cella_30.sum_lutc_input = "cin",
+               add_sub_cella_30.lpm_type = "stratix_lcell";
+       stratix_lcell   add_sub_cella_31
+       ( 
+       .aclr(aclr),
+       .cin(wire_add_sub_cella_30cout[0:0]),
+       .clk(clock),
+       .dataa(wire_add_sub_cella_dataa[31:31]),
+       .datab(wire_add_sub_cella_datab[31:31]),
+       .ena(clken),
+       .regout(wire_add_sub_cella_regout[31:31]));
+       defparam
+               add_sub_cella_31.cin_used = "true",
+               add_sub_cella_31.lut_mask = "6969",
+               add_sub_cella_31.operation_mode = "normal",
+               add_sub_cella_31.sum_lutc_input = "cin",
+               add_sub_cella_31.lpm_type = "stratix_lcell";
+       assign
+               wire_add_sub_cella_dataa = dataa,
+               wire_add_sub_cella_datab = datab;
+       assign
+               result = wire_add_sub_cella_regout;
+endmodule //sub32_add_sub_cqa
+//VALID FILE
+
+
+module sub32 (
+       dataa,
+       datab,
+       clock,
+       aclr,
+       clken,
+       result)/* synthesis synthesis_clearbox = 1 */;
+
+       input   [31:0]  dataa;
+       input   [31:0]  datab;
+       input     clock;
+       input     aclr;
+       input     clken;
+       output  [31:0]  result;
+
+       wire [31:0] sub_wire0;
+       wire [31:0] result = sub_wire0[31:0];
+
+       sub32_add_sub_cqa       sub32_add_sub_cqa_component (
+                               .dataa (dataa),
+                               .datab (datab),
+                               .clken (clken),
+                               .aclr (aclr),
+                               .clock (clock),
+                               .result (sub_wire0));
+
+endmodule
+
+// ============================================================
+// CNX file retrieval info
+// ============================================================
+// Retrieval info: PRIVATE: nBit NUMERIC "32"
+// Retrieval info: PRIVATE: Function NUMERIC "1"
+// Retrieval info: PRIVATE: WhichConstant NUMERIC "0"
+// Retrieval info: PRIVATE: ConstantA NUMERIC "0"
+// Retrieval info: PRIVATE: ConstantB NUMERIC "0"
+// Retrieval info: PRIVATE: ValidCtA NUMERIC "0"
+// Retrieval info: PRIVATE: ValidCtB NUMERIC "0"
+// Retrieval info: PRIVATE: CarryIn NUMERIC "0"
+// Retrieval info: PRIVATE: CarryOut NUMERIC "0"
+// Retrieval info: PRIVATE: Overflow NUMERIC "0"
+// Retrieval info: PRIVATE: Latency NUMERIC "1"
+// Retrieval info: PRIVATE: aclr NUMERIC "1"
+// Retrieval info: PRIVATE: clken NUMERIC "1"
+// Retrieval info: PRIVATE: LPM_PIPELINE NUMERIC "1"
+// Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING "Cyclone"
+// Retrieval info: CONSTANT: LPM_WIDTH NUMERIC "32"
+// Retrieval info: CONSTANT: LPM_DIRECTION STRING "SUB"
+// Retrieval info: CONSTANT: LPM_TYPE STRING "LPM_ADD_SUB"
+// Retrieval info: CONSTANT: LPM_HINT STRING "ONE_INPUT_IS_CONSTANT=NO"
+// Retrieval info: CONSTANT: LPM_PIPELINE NUMERIC "1"
+// Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone"
+// Retrieval info: USED_PORT: result 0 0 32 0 OUTPUT NODEFVAL result[31..0]
+// Retrieval info: USED_PORT: dataa 0 0 32 0 INPUT NODEFVAL dataa[31..0]
+// Retrieval info: USED_PORT: datab 0 0 32 0 INPUT NODEFVAL datab[31..0]
+// Retrieval info: USED_PORT: clock 0 0 0 0 INPUT NODEFVAL clock
+// Retrieval info: USED_PORT: aclr 0 0 0 0 INPUT NODEFVAL aclr
+// Retrieval info: USED_PORT: clken 0 0 0 0 INPUT NODEFVAL clken
+// Retrieval info: CONNECT: result 0 0 32 0 @result 0 0 32 0
+// Retrieval info: CONNECT: @dataa 0 0 32 0 dataa 0 0 32 0
+// Retrieval info: CONNECT: @datab 0 0 32 0 datab 0 0 32 0
+// Retrieval info: CONNECT: @clock 0 0 0 0 clock 0 0 0 0
+// Retrieval info: CONNECT: @aclr 0 0 0 0 aclr 0 0 0 0
+// Retrieval info: CONNECT: @clken 0 0 0 0 clken 0 0 0 0
+// Retrieval info: LIBRARY: lpm lpm.lpm_components.all
diff --git a/usrp/fpga/megacells/sub32_bb.v b/usrp/fpga/megacells/sub32_bb.v
new file mode 100755 (executable)
index 0000000..488ab51
--- /dev/null
@@ -0,0 +1,37 @@
+//Copyright (C) 1991-2003 Altera Corporation
+//Any  megafunction  design,  and related netlist (encrypted  or  decrypted),
+//support information,  device programming or simulation file,  and any other
+//associated  documentation or information  provided by  Altera  or a partner
+//under  Altera's   Megafunction   Partnership   Program  may  be  used  only
+//to program  PLD  devices (but not masked  PLD  devices) from  Altera.   Any
+//other  use  of such  megafunction  design,  netlist,  support  information,
+//device programming or simulation file,  or any other  related documentation
+//or information  is prohibited  for  any  other purpose,  including, but not
+//limited to  modification,  reverse engineering,  de-compiling, or use  with
+//any other  silicon devices,  unless such use is  explicitly  licensed under
+//a separate agreement with  Altera  or a megafunction partner.  Title to the
+//intellectual property,  including patents,  copyrights,  trademarks,  trade
+//secrets,  or maskworks,  embodied in any such megafunction design, netlist,
+//support  information,  device programming or simulation file,  or any other
+//related documentation or information provided by  Altera  or a megafunction
+//partner, remains with Altera, the megafunction partner, or their respective
+//licensors. No other licenses, including any licenses needed under any third
+//party's intellectual property, are provided herein.
+
+module sub32 (
+       dataa,
+       datab,
+       clock,
+       aclr,
+       clken,
+       result)/* synthesis synthesis_clearbox = 1 */;
+
+       input   [31:0]  dataa;
+       input   [31:0]  datab;
+       input     clock;
+       input     aclr;
+       input     clken;
+       output  [31:0]  result;
+
+endmodule
+
diff --git a/usrp/fpga/megacells/sub32_inst.v b/usrp/fpga/megacells/sub32_inst.v
new file mode 100755 (executable)
index 0000000..1916fc5
--- /dev/null
@@ -0,0 +1,8 @@
+sub32  sub32_inst (
+       .dataa ( dataa_sig ),
+       .datab ( datab_sig ),
+       .clock ( clock_sig ),
+       .aclr ( aclr_sig ),
+       .clken ( clken_sig ),
+       .result ( result_sig )
+       );
diff --git a/usrp/fpga/models/bustri.v b/usrp/fpga/models/bustri.v
new file mode 100644 (file)
index 0000000..6e5a0f7
--- /dev/null
@@ -0,0 +1,17 @@
+
+// Model for tristate bus on altera
+// FIXME do we really need to use a megacell for this?
+
+module bustri (data,
+              enabledt,
+              tridata);
+   
+   input [15:0]  data;
+   input        enabledt;
+   inout [15:0]  tridata;
+   
+   assign       tridata = enabledt ? data :16'bz;
+   
+endmodule // bustri
+
+
diff --git a/usrp/fpga/models/fifo.v b/usrp/fpga/models/fifo.v
new file mode 100644 (file)
index 0000000..a04e7da
--- /dev/null
@@ -0,0 +1,81 @@
+// Model of FIFO in Altera
+
+module fifo( data, wrreq, rdreq, rdclk, wrclk, aclr, q,
+                   rdfull, rdempty, rdusedw, wrfull, wrempty, wrusedw);
+   
+   parameter width = 16;
+   parameter depth = 1024;
+   parameter addr_bits = 10;
+   
+   //`define rd_req 0;  // Set this to 0 for rd_ack, 1 for rd_req
+   
+   input [width-1:0] data;
+   input            wrreq;
+   input            rdreq;
+   input            rdclk;
+   input            wrclk;
+   input            aclr;
+   output [width-1:0] q;
+   output            rdfull;
+   output            rdempty;
+   output reg [addr_bits-1:0]  rdusedw;
+   output wrfull;
+   output wrempty;
+   output reg [addr_bits-1:0]  wrusedw;
+   
+   reg [width-1:0] mem [0:depth-1];
+   reg [addr_bits-1:0]               rdptr;
+   reg [addr_bits-1:0]               wrptr;
+   
+`ifdef rd_req
+   reg [width-1:0]    q;
+`else
+   wire [width-1:0]   q;
+`endif
+   
+   integer           i;
+   
+   always @( aclr)
+     begin
+       wrptr <= #1 0;
+       rdptr <= #1 0;
+       for(i=0;i<depth;i=i+1)
+         mem[i] <= #1 0;
+     end
+   
+   always @(posedge wrclk)
+     if(wrreq)
+       begin
+         wrptr <= #1 wrptr+1;
+         mem[wrptr] <= #1 data;
+       end
+   
+   always @(posedge rdclk)
+     if(rdreq)
+       begin
+         rdptr <= #1 rdptr+1;
+`ifdef rd_req
+         q <= #1 mem[rdptr];
+`endif
+       end
+   
+`ifdef rd_req
+`else
+   assign q = mem[rdptr];
+`endif
+   
+   // Fix these
+   always @(posedge wrclk)
+     wrusedw <= #1 wrptr - rdptr;
+   
+   always @(posedge rdclk)
+     rdusedw <= #1 wrptr - rdptr;
+   
+   assign wrempty = (wrusedw == 0);
+   assign wrfull = (wrusedw == depth-1);
+   
+   assign rdempty = (rdusedw == 0);
+   assign rdfull = (rdusedw == depth-1);
+   
+endmodule // fifo_1c_1k
+
diff --git a/usrp/fpga/models/fifo_1c_1k.v b/usrp/fpga/models/fifo_1c_1k.v
new file mode 100644 (file)
index 0000000..d11040b
--- /dev/null
@@ -0,0 +1,81 @@
+// Model of FIFO in Altera
+
+module fifo_1c_1k ( data, wrreq, rdreq, rdclk, wrclk, aclr, q,
+                   rdfull, rdempty, rdusedw, wrfull, wrempty, wrusedw);
+
+   parameter width = 32;
+   parameter depth = 1024;
+   //`define rd_req 0;  // Set this to 0 for rd_ack, 1 for rd_req
+      
+   input [31:0] data;
+   input       wrreq;
+   input       rdreq;
+   input       rdclk;
+   input       wrclk;
+   input       aclr;
+   output [31:0] q;
+   output       rdfull;
+   output       rdempty;
+   output [9:0]  rdusedw;
+   output       wrfull;
+   output       wrempty;
+   output [9:0]  wrusedw;
+   
+   reg [width-1:0] mem [0:depth-1];
+   reg [7:0]      rdptr;
+   reg [7:0]      wrptr;
+   
+`ifdef rd_req
+   reg [width-1:0] q;
+`else
+   wire [width-1:0] q;
+`endif
+   
+   reg [9:0]       rdusedw;
+   reg [9:0]       wrusedw;
+   
+   integer         i;
+
+   always @( aclr)
+     begin
+       wrptr <= #1 0;
+       rdptr <= #1 0;
+       for(i=0;i<depth;i=i+1)
+         mem[i] <= #1 0;
+     end
+   
+   always @(posedge wrclk)
+     if(wrreq)
+       begin
+         wrptr <= #1 wrptr+1;
+         mem[wrptr] <= #1 data;
+       end
+   
+   always @(posedge rdclk)
+     if(rdreq)
+       begin
+         rdptr <= #1 rdptr+1;
+`ifdef rd_req
+         q <= #1 mem[rdptr];
+`endif
+       end
+   
+`ifdef rd_req
+`else
+   assign q = mem[rdptr];
+`endif
+   
+   // Fix these
+   always @(posedge wrclk)
+     wrusedw <= #1 wrptr - rdptr;
+   
+   always @(posedge rdclk)
+     rdusedw <= #1 wrptr - rdptr;
+
+   assign wrempty = (wrusedw == 0);
+   assign wrfull = (wrusedw == depth-1);
+
+   assign rdempty = (rdusedw == 0);
+   assign rdfull = (rdusedw == depth-1);
+   
+endmodule // fifo_1c_1k
diff --git a/usrp/fpga/models/fifo_1c_2k.v b/usrp/fpga/models/fifo_1c_2k.v
new file mode 100644 (file)
index 0000000..5c3acfe
--- /dev/null
@@ -0,0 +1,81 @@
+// Model of FIFO in Altera
+
+module fifo_1c_2k ( data, wrreq, rdreq, rdclk, wrclk, aclr, q,
+                   rdfull, rdempty, rdusedw, wrfull, wrempty, wrusedw);
+
+   parameter width = 32;
+   parameter depth = 2048;
+   //`define rd_req 0;  // Set this to 0 for rd_ack, 1 for rd_req
+      
+   input [31:0] data;
+   input       wrreq;
+   input       rdreq;
+   input       rdclk;
+   input       wrclk;
+   input       aclr;
+   output [31:0] q;
+   output       rdfull;
+   output       rdempty;
+   output [10:0]  rdusedw;
+   output       wrfull;
+   output       wrempty;
+   output [10:0]  wrusedw;
+   
+   reg [width-1:0] mem [0:depth-1];
+   reg [7:0]      rdptr;
+   reg [7:0]      wrptr;
+   
+`ifdef rd_req
+   reg [width-1:0] q;
+`else
+   wire [width-1:0] q;
+`endif
+   
+   reg [10:0]      rdusedw;
+   reg [10:0]      wrusedw;
+   
+   integer         i;
+
+   always @( aclr)
+     begin
+       wrptr <= #1 0;
+       rdptr <= #1 0;
+       for(i=0;i<depth;i=i+1)
+         mem[i] <= #1 0;
+     end
+   
+   always @(posedge wrclk)
+     if(wrreq)
+       begin
+         wrptr <= #1 wrptr+1;
+         mem[wrptr] <= #1 data;
+       end
+   
+   always @(posedge rdclk)
+     if(rdreq)
+       begin
+         rdptr <= #1 rdptr+1;
+`ifdef rd_req
+         q <= #1 mem[rdptr];
+`endif
+       end
+   
+`ifdef rd_req
+`else
+   assign q = mem[rdptr];
+`endif
+   
+   // Fix these
+   always @(posedge wrclk)
+     wrusedw <= #1 wrptr - rdptr;
+   
+   always @(posedge rdclk)
+     rdusedw <= #1 wrptr - rdptr;
+
+   assign wrempty = (wrusedw == 0);
+   assign wrfull = (wrusedw == depth-1);
+   
+   assign rdempty = (rdusedw == 0);
+   assign rdfull = (rdusedw == depth-1);
+   
+endmodule // fifo_1c_2k
diff --git a/usrp/fpga/models/fifo_1c_4k.v b/usrp/fpga/models/fifo_1c_4k.v
new file mode 100644 (file)
index 0000000..3e5ddd0
--- /dev/null
@@ -0,0 +1,76 @@
+// Model of FIFO in Altera
+
+module fifo_1c_4k ( data, wrreq, rdreq, rdclk, wrclk, aclr, q,
+                   rdfull, rdempty, rdusedw, wrfull, wrempty, wrusedw);
+
+   parameter width = 32;
+   parameter depth = 4096;
+   //`define rd_req 0;  // Set this to 0 for rd_ack, 1 for rd_req
+      
+   input [31:0] data;
+   input       wrreq;
+   input       rdreq;
+   input       rdclk;
+   input       wrclk;
+   input       aclr;
+   output [31:0] q;
+   output       rdfull;
+   output       rdempty;
+   output [7:0]  rdusedw;
+   output       wrfull;
+   output       wrempty;
+   output [7:0]  wrusedw;
+   
+   reg [width-1:0] mem [0:depth-1];
+   reg [7:0]      rdptr;
+   reg [7:0]      wrptr;
+   
+`ifdef rd_req
+   reg [width-1:0] q;
+`else
+   wire [width-1:0] q;
+`endif
+   
+   reg [7:0]       rdusedw;
+   reg [7:0]       wrusedw;
+   
+   integer         i;
+
+   always @( aclr)
+     begin
+       wrptr <= #1 0;
+       rdptr <= #1 0;
+       for(i=0;i<depth;i=i+1)
+         mem[i] <= #1 0;
+     end
+   
+   always @(posedge wrclk)
+     if(wrreq)
+       begin
+         wrptr <= #1 wrptr+1;
+         mem[wrptr] <= #1 data;
+       end
+   
+   always @(posedge rdclk)
+     if(rdreq)
+       begin
+         rdptr <= #1 rdptr+1;
+`ifdef rd_req
+         q <= #1 mem[rdptr];
+`endif
+       end
+   
+`ifdef rd_req
+`else
+   assign q = mem[rdptr];
+`endif
+   
+   // Fix these
+   always @(posedge wrclk)
+     wrusedw <= #1 wrptr - rdptr;
+   
+   always @(posedge rdclk)
+     rdusedw <= #1 wrptr - rdptr;
+   
+   
+endmodule // fifo_1c_4k
diff --git a/usrp/fpga/models/fifo_1k.v b/usrp/fpga/models/fifo_1k.v
new file mode 100644 (file)
index 0000000..acfa4d1
--- /dev/null
@@ -0,0 +1,24 @@
+
+
+module fifo_1k
+  (  input [15:0] data,
+     input     wrreq,
+     input     rdreq,
+     input     rdclk,
+     input     wrclk,
+     input     aclr,
+     output [15:0] q,
+     output     rdfull,
+     output     rdempty,
+     output [9:0] rdusedw,
+     output     wrfull,
+     output     wrempty,
+     output [9:0]  wrusedw
+     );
+
+fifo #(.width(16),.depth(1024),.addr_bits(10)) fifo_1k 
+  ( data, wrreq, rdreq, rdclk, wrclk, aclr, q,
+    rdfull, rdempty, rdusedw, wrfull, wrempty, wrusedw);
+   
+endmodule // fifo_1k
+   
diff --git a/usrp/fpga/models/fifo_2k.v b/usrp/fpga/models/fifo_2k.v
new file mode 100644 (file)
index 0000000..50cd781
--- /dev/null
@@ -0,0 +1,24 @@
+
+
+module fifo_2k
+  (  input [15:0] data,
+     input     wrreq,
+     input     rdreq,
+     input     rdclk,
+     input     wrclk,
+     input     aclr,
+     output [15:0] q,
+     output     rdfull,
+     output     rdempty,
+     output [10:0] rdusedw,
+     output     wrfull,
+     output     wrempty,
+     output [10:0]  wrusedw
+     );
+
+fifo #(.width(16),.depth(2048),.addr_bits(11)) fifo_2k 
+  ( data, wrreq, rdreq, rdclk, wrclk, aclr, q,
+    rdfull, rdempty, rdusedw, wrfull, wrempty, wrusedw);
+   
+endmodule // fifo_1k
+   
diff --git a/usrp/fpga/models/fifo_4k.v b/usrp/fpga/models/fifo_4k.v
new file mode 100644 (file)
index 0000000..1fa4ba0
--- /dev/null
@@ -0,0 +1,24 @@
+
+
+module fifo_4k
+  (  input [15:0] data,
+     input     wrreq,
+     input     rdreq,
+     input     rdclk,
+     input     wrclk,
+     input     aclr,
+     output [15:0] q,
+     output     rdfull,
+     output     rdempty,
+     output [11:0] rdusedw,
+     output     wrfull,
+     output     wrempty,
+     output [11:0]  wrusedw
+     );
+
+fifo #(.width(16),.depth(4096),.addr_bits(12)) fifo_4k 
+  ( data, wrreq, rdreq, rdclk, wrclk, aclr, q,
+    rdfull, rdempty, rdusedw, wrfull, wrempty, wrusedw);
+   
+endmodule // fifo_1k
+   
diff --git a/usrp/fpga/models/pll.v b/usrp/fpga/models/pll.v
new file mode 100644 (file)
index 0000000..d879648
--- /dev/null
@@ -0,0 +1,33 @@
+// -*- verilog -*-
+//
+//  USRP - Universal Software Radio Peripheral
+//
+//  Copyright (C) 2003 Matt Ettus
+//
+//  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
+//
+
+// Very simple model for the PLL in the RX buffer
+
+module pll (inclk0,c0);
+   
+   input         inclk0;
+   output        c0;
+
+   assign        c0 = #9 inclk0;
+      
+endmodule // pll
+
+
diff --git a/usrp/fpga/models/ssram.v b/usrp/fpga/models/ssram.v
new file mode 100644 (file)
index 0000000..fd73399
--- /dev/null
@@ -0,0 +1,38 @@
+
+// Model of Pipelined [ZBT] Synchronous SRAM
+
+module ssram(clock,addr,data,wen,ce);
+   parameter addrbits = 19;
+   parameter depth = 524288;
+
+   input clock;
+   input [addrbits-1:0] addr;
+   inout [35:0] data;
+   input wen;
+   input ce;
+
+   reg [35:0] ram [0:depth-1];
+   
+   reg read_d1,read_d2;
+   reg write_d1,write_d2;
+   reg [addrbits-1:0] addr_d1,addr_d2;
+   
+   always @(posedge clock)
+     begin
+       read_d1 <= #1 ce & ~wen;
+       write_d1 <= #1 ce & wen;
+       addr_d1 <= #1 addr;
+       read_d2 <= #1 read_d1;
+       write_d2 <= #1 write_d1;
+       addr_d2 <= #1 addr_d1;
+       if(write_d2)
+         ram[addr_d2] = data;
+     end // always @ (posedge clock)
+
+   data = (ce & read_d2) ? ram[addr_d2] : 36'bz;
+
+   always @(posedge clock)
+     if(~ce & (write_d2 | write_d1 | wen))
+       $display("$time ERROR:  RAM CE not asserted during write cycle");
+   
+endmodule // ssram
diff --git a/usrp/fpga/rbf/Makefile.am b/usrp/fpga/rbf/Makefile.am
new file mode 100644 (file)
index 0000000..dbc2875
--- /dev/null
@@ -0,0 +1,49 @@
+#
+# 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 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.
+# 
+
+include $(top_srcdir)/Makefile.common
+
+datadir = $(prefix)/share/usrp
+
+rbfs =                                 \
+       rev2/std_2rxhb_2tx.rbf  \
+       rev2/std_4rx_0tx.rbf    \
+       rev4/std_2rxhb_2tx.rbf  \
+       rev4/std_4rx_0tx.rbf    \
+       rev2/multi_2rxhb_2tx.rbf        \
+       rev4/multi_2rxhb_2tx.rbf                
+
+
+EXTRA_DIST =                   \
+       $(rbfs)
+
+
+install-data-local:
+       @for file in $(rbfs); do \
+               echo "$(INSTALL_DATA) $(srcdir)/$$file $(DESTDIR)$(datadir)/$$file"; \
+               $(INSTALL_DATA) $(srcdir)/$$file $(DESTDIR)$(datadir)/$$file; \
+       done
+
+uninstall-local:
+       @for file in $(rbfs); do \
+               echo "$(RM) $(DESTDIR)$(datadir)/$$file"; \
+               $(RM) $(DESTDIR)$(datadir)/$$file; \
+       done
diff --git a/usrp/fpga/rbf/rev2/multi_2rxhb_2tx.rbf b/usrp/fpga/rbf/rev2/multi_2rxhb_2tx.rbf
new file mode 100755 (executable)
index 0000000..2683d86
Binary files /dev/null and b/usrp/fpga/rbf/rev2/multi_2rxhb_2tx.rbf differ
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/rev2/std_2rxhb_2tx.rbf b/usrp/fpga/rbf/rev2/std_2rxhb_2tx.rbf
new file mode 100755 (executable)
index 0000000..80f336c
Binary files /dev/null and b/usrp/fpga/rbf/rev2/std_2rxhb_2tx.rbf differ
diff --git a/usrp/fpga/rbf/rev2/std_4rx_0tx.rbf b/usrp/fpga/rbf/rev2/std_4rx_0tx.rbf
new file mode 100755 (executable)
index 0000000..7dc16e2
Binary files /dev/null and b/usrp/fpga/rbf/rev2/std_4rx_0tx.rbf differ
diff --git a/usrp/fpga/rbf/rev4/multi_2rxhb_2tx.rbf b/usrp/fpga/rbf/rev4/multi_2rxhb_2tx.rbf
new file mode 100755 (executable)
index 0000000..2683d86
Binary files /dev/null and b/usrp/fpga/rbf/rev4/multi_2rxhb_2tx.rbf differ
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/fpga/rbf/rev4/std_2rxhb_2tx.rbf b/usrp/fpga/rbf/rev4/std_2rxhb_2tx.rbf
new file mode 100755 (executable)
index 0000000..80f336c
Binary files /dev/null and b/usrp/fpga/rbf/rev4/std_2rxhb_2tx.rbf differ
diff --git a/usrp/fpga/rbf/rev4/std_4rx_0tx.rbf b/usrp/fpga/rbf/rev4/std_4rx_0tx.rbf
new file mode 100755 (executable)
index 0000000..7dc16e2
Binary files /dev/null and b/usrp/fpga/rbf/rev4/std_4rx_0tx.rbf differ
diff --git a/usrp/fpga/sdr_lib/adc_interface.v b/usrp/fpga/sdr_lib/adc_interface.v
new file mode 100644 (file)
index 0000000..f18ffc1
--- /dev/null
@@ -0,0 +1,71 @@
+
+
+`include "../../firmware/include/fpga_regs_common.v"
+`include "../../firmware/include/fpga_regs_standard.v"
+
+module adc_interface
+  (input clock, input reset, input enable,
+   input wire [6:0] serial_addr, input wire [31:0] serial_data, input serial_strobe,
+   input wire [11:0] rx_a_a, input wire [11:0] rx_b_a, input wire [11:0] rx_a_b, input wire [11:0] rx_b_b,
+   output wire [31:0] rssi_0, output wire [31:0] rssi_1, output wire [31:0] rssi_2, output wire [31:0] rssi_3,
+   output reg [15:0] ddc0_in_i, output reg [15:0] ddc0_in_q, 
+   output reg [15:0] ddc1_in_i, output reg [15:0] ddc1_in_q, 
+   output reg [15:0] ddc2_in_i, output reg [15:0] ddc2_in_q, 
+   output reg [15:0] ddc3_in_i, output reg [15:0] ddc3_in_q,
+   output wire [3:0] rx_numchan);
+      
+    // Buffer at input to chip
+   reg [11:0] adc0,adc1,adc2,adc3;
+   always @(posedge clock)
+     begin
+       adc0 <= #1 rx_a_a;
+       adc1 <= #1 rx_b_a;
+       adc2 <= #1 rx_a_b;
+       adc3 <= #1 rx_b_b;
+     end
+   
+   // then scale and subtract dc offset
+   wire [3:0] dco_en;
+   wire [15:0]         adc0_corr,adc1_corr,adc2_corr,adc3_corr;
+   
+   setting_reg #(`FR_DC_OFFSET_CL_EN) sr_dco_en(.clock(clock),.reset(reset),.strobe(serial_strobe),.addr(serial_addr),.in(serial_data),
+                                .out(dco_en));
+
+   rx_dcoffset #(`FR_ADC_OFFSET_0) rx_dcoffset0(.clock(clock),.enable(dco_en[0]),.reset(reset),.adc_in({adc0[11],adc0,3'b0}),.adc_out(adc0_corr),
+                                               .serial_addr(serial_addr),.serial_data(serial_data),.serial_strobe(serial_strobe));
+   rx_dcoffset #(`FR_ADC_OFFSET_1) rx_dcoffset1(.clock(clock),.enable(dco_en[1]),.reset(reset),.adc_in({adc1[11],adc1,3'b0}),.adc_out(adc1_corr),
+                                               .serial_addr(serial_addr),.serial_data(serial_data),.serial_strobe(serial_strobe));
+   rx_dcoffset #(`FR_ADC_OFFSET_2) rx_dcoffset2(.clock(clock),.enable(dco_en[2]),.reset(reset),.adc_in({adc2[11],adc2,3'b0}),.adc_out(adc2_corr),
+                                               .serial_addr(serial_addr),.serial_data(serial_data),.serial_strobe(serial_strobe));
+   rx_dcoffset #(`FR_ADC_OFFSET_3) rx_dcoffset3(.clock(clock),.enable(dco_en[3]),.reset(reset),.adc_in({adc3[11],adc3,3'b0}),.adc_out(adc3_corr),
+                                               .serial_addr(serial_addr),.serial_data(serial_data),.serial_strobe(serial_strobe));
+
+   // Level sensing for AGC
+   rssi rssi_block_0 (.clock(clock),.reset(reset),.enable(enable),.adc(adc0),.rssi(rssi_0[15:0]),.over_count(rssi_0[31:16]));
+   rssi rssi_block_1 (.clock(clock),.reset(reset),.enable(enable),.adc(adc1),.rssi(rssi_1[15:0]),.over_count(rssi_1[31:16]));
+   rssi rssi_block_2 (.clock(clock),.reset(reset),.enable(enable),.adc(adc2),.rssi(rssi_2[15:0]),.over_count(rssi_2[31:16]));
+   rssi rssi_block_3 (.clock(clock),.reset(reset),.enable(enable),.adc(adc3),.rssi(rssi_3[15:0]),.over_count(rssi_3[31:16]));
+   
+   // And mux to the appropriate outputs
+   wire [3:0]  ddc3mux,ddc2mux,ddc1mux,ddc0mux;
+   wire        rx_realsignals;
+   
+   setting_reg #(`FR_RX_MUX) sr_rxmux(.clock(clock),.reset(reset),.strobe(serial_strobe),.addr(serial_addr),
+                                     .in(serial_data),.out({ddc3mux,ddc2mux,ddc1mux,ddc0mux,rx_realsignals,rx_numchan[3:1]}));
+   assign      rx_numchan[0] = 1'b0;
+   
+   always @(posedge clock)
+     begin
+       ddc0_in_i <= #1 ddc0mux[1] ? (ddc0mux[0] ? adc3_corr : adc2_corr) : (ddc0mux[0] ? adc1_corr : adc0_corr);
+       ddc0_in_q <= #1 rx_realsignals ? 16'd0 : ddc0mux[3] ? (ddc0mux[2] ? adc3_corr : adc2_corr) : (ddc0mux[2] ? adc1_corr : adc0_corr);
+       ddc1_in_i <= #1 ddc1mux[1] ? (ddc1mux[0] ? adc3_corr : adc2_corr) : (ddc1mux[0] ? adc1_corr : adc0_corr);
+       ddc1_in_q <= #1 rx_realsignals ? 16'd0 : ddc1mux[3] ? (ddc1mux[2] ? adc3_corr : adc2_corr) : (ddc1mux[2] ? adc1_corr : adc0_corr);
+       ddc2_in_i <= #1 ddc2mux[1] ? (ddc2mux[0] ? adc3_corr : adc2_corr) : (ddc2mux[0] ? adc1_corr : adc0_corr);
+       ddc2_in_q <= #1 rx_realsignals ? 16'd0 : ddc2mux[3] ? (ddc2mux[2] ? adc3_corr : adc2_corr) : (ddc2mux[2] ? adc1_corr : adc0_corr);
+       ddc3_in_i <= #1 ddc3mux[1] ? (ddc3mux[0] ? adc3_corr : adc2_corr) : (ddc3mux[0] ? adc1_corr : adc0_corr);
+       ddc3_in_q <= #1 rx_realsignals ? 16'd0 : ddc3mux[3] ? (ddc3mux[2] ? adc3_corr : adc2_corr) : (ddc3mux[2] ? adc1_corr : adc0_corr);
+     end
+
+endmodule // adc_interface
+
+   
diff --git a/usrp/fpga/sdr_lib/bidir_reg.v b/usrp/fpga/sdr_lib/bidir_reg.v
new file mode 100644 (file)
index 0000000..b124412
--- /dev/null
@@ -0,0 +1,29 @@
+// Bidirectional registers
+
+module bidir_reg
+  ( inout wire [15:0] tristate,
+    input wire [15:0] oe,
+    input wire [15:0] reg_val );
+
+   // This would be much cleaner if all the tools
+   // supported "for generate"........
+
+   assign       tristate[0] = oe[0] ? reg_val[0] : 1'bz;
+   assign       tristate[1] = oe[1] ? reg_val[1] : 1'bz;
+   assign       tristate[2] = oe[2] ? reg_val[2] : 1'bz;
+   assign       tristate[3] = oe[3] ? reg_val[3] : 1'bz;
+   assign       tristate[4] = oe[4] ? reg_val[4] : 1'bz;
+   assign       tristate[5] = oe[5] ? reg_val[5] : 1'bz;
+   assign       tristate[6] = oe[6] ? reg_val[6] : 1'bz;
+   assign       tristate[7] = oe[7] ? reg_val[7] : 1'bz;
+   assign       tristate[8] = oe[8] ? reg_val[8] : 1'bz;
+   assign       tristate[9] = oe[9] ? reg_val[9] : 1'bz;
+   assign       tristate[10] = oe[10] ? reg_val[10] : 1'bz;
+   assign       tristate[11] = oe[11] ? reg_val[11] : 1'bz;
+   assign       tristate[12] = oe[12] ? reg_val[12] : 1'bz;
+   assign       tristate[13] = oe[13] ? reg_val[13] : 1'bz;
+   assign       tristate[14] = oe[14] ? reg_val[14] : 1'bz;
+   assign       tristate[15] = oe[15] ? reg_val[15] : 1'bz;
+   
+endmodule // bidir_reg
+
diff --git a/usrp/fpga/sdr_lib/bus_interface.v b/usrp/fpga/sdr_lib/bus_interface.v
new file mode 100755 (executable)
index 0000000..3f5f748
--- /dev/null
@@ -0,0 +1,213 @@
+// -*- verilog -*-
+//
+//  USRP - Universal Software Radio Peripheral
+//
+//  Copyright (C) 2003 Matt Ettus
+//
+//  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
+//
+
+// Interface to Cypress FX2 bus
+// A packet is 512 Bytes.  Each fifo line is 4 bytes
+// Fifo has 1024 or 2048 lines
+
+module bus_interface
+  (     input usbclk,
+       input reset,
+       inout [15:0] usbdata,   // TRISTATE
+       input wire [5:0] usbctl,
+       output wire [5:0] usbrdy,
+       output [31:0] txdata,
+       input [31:0] rxdata,
+       input txclk,
+       input txstrobe,
+       input rxclk,
+       input rxstrobe,
+       output [11:0] debugbus,
+       input clear_status
+       );
+
+   parameter   IN_CHANNELS = 1;
+   parameter   OUT_CHANNELS = 1;
+   parameter   bitmask = (IN_CHANNELS*2)-1;
+
+   wire have_space, have_pkt_rdy;
+   wire WR, RD, OE;
+   reg tx_underrun, rx_overrun;
+   
+   assign WR = usbctl[0];
+   assign RD = usbctl[1];
+   assign OE = usbctl[2];
+   
+   assign usbrdy[0] = have_space;
+   assign usbrdy[1] = have_pkt_rdy;
+   assign usbrdy[2] = tx_underrun;
+   assign usbrdy[3] = rx_overrun;
+   
+   reg [IN_CHANNELS*2*16-1:0] fifo_in;
+   wire [OUT_CHANNELS*2*16-1:0] fifo_out;
+   
+   wire [15:0] usbdata_in = usbdata;
+   
+   reg select_out;
+   reg select_in;
+   
+   reg commit;
+   reg rd_next;
+   reg [15:0] usbdata_out;
+   wire [10:0] txfifolevel,rxfifolevel;
+   reg [8:0] write_count;
+   wire tx_empty;
+   wire tx_full;
+   wire rx_empty;
+   wire rx_full;
+   wire [31:0] txd;
+   wire rdreq;
+       
+   // Tri-state bus macro
+   bustri bustri(.data(usbdata_out),
+                .enabledt(OE),
+                .tridata(usbdata)  );
+
+   //////////////////////////////////////////////
+   // TX Side (USB --> DAC)
+   always @(posedge usbclk, posedge reset)
+     begin
+       if(reset)
+         begin
+            fifo_in <= #1 0;
+            write_count <= #1 0;
+         end
+       else 
+         if(WR & ~write_count[8])
+           begin
+              case(write_count[0])
+                1'b0 : fifo_in[31:16] <= #1 usbdata_in;  // I
+                1'b1 : fifo_in[15:0] <= #1 usbdata_in;   // Q
+              endcase
+              write_count <= #1 write_count + 9'd1;
+           end
+         else
+           write_count <= #1 WR ? write_count : 9'b0;
+     end
+   
+   always @(posedge usbclk)
+     if(reset)
+       commit <= #1 1'b0;
+     else
+       if(write_count[0] && ~write_count[8] && WR)
+        commit <= #1 1'b1;
+       else 
+        commit <= #1 1'b0;
+   
+   assign rdreq = txstrobe & !tx_empty;
+   assign txdata = tx_empty ? 32'b0 : txd;
+   
+   always @(posedge txclk)
+     if(reset)
+       tx_underrun <= 1'b0;
+     else if(txstrobe & tx_empty)
+       tx_underrun <= 1'b1;
+     else if(clear_status)
+       tx_underrun <= 1'b0;
+
+   fifo_1c_2k  txfifo (.data ( fifo_in ),
+                       .wrreq ( commit ),
+                       .wrclk ( usbclk ),
+
+                       .q ( txd ),                     
+                       .rdreq ( rdreq),
+                       .rdclk ( txclk ),
+                       
+                       .aclr ( reset ),
+
+                       .rdempty ( tx_empty ),
+                       .rdusedw (  ),
+                       .wrfull ( tx_full ),
+                       .wrusedw ( txfifolevel )
+                       );
+   
+   assign have_space = (txfifolevel <= (2048-128));
+   
+   //////////////////////////////
+   // Receive FIFO (ADC --> USB)
+
+   always @(posedge rxclk)
+     if(reset)
+       rx_overrun <= 1'b0;
+     else if(rxstrobe & rx_full)
+       rx_overrun <= 1'b1;
+     else if(clear_status)
+       rx_overrun <= 1'b0;
+
+   always @(select_out, fifo_out)
+     case(select_out)
+       0 : usbdata_out = fifo_out[31:16];  // I
+       1 : usbdata_out = fifo_out[15:0];   // Q
+     endcase
+  
+/*
+       always @(posedge usbclk, posedge reset)
+       if(reset)
+               usbdata_out <= #1 16'b0;
+       else
+               if(select_out)
+                       usbdata_out = fifo_out[31:16];
+               else
+                       usbdata_out = fifo_out[15:0];
+       */
+        
+   always @(negedge usbclk, posedge reset)
+     if(reset)
+       select_out <= #1 1'b0;
+     else if(~RD)
+       select_out <= #1 1'b0;
+     else 
+       select_out <= #1 ~select_out;
+   fifo_1c_2k  rxfifo (.data ( rxdata ), // counter ),
+                       .wrreq (rxstrobe & ~rx_full ),
+                       .wrclk ( rxclk ),
+                       
+                       .q ( fifo_out ),
+                       .rdreq ( select_out ),// & RD ), // FIXME
+                       .rdclk ( usbclk ),
+                       
+                       .aclr ( reset ),
+                       
+                       .rdempty ( rx_empty ),
+                       .rdusedw ( rxfifolevel ),
+                       .wrfull ( rx_full ),
+                       .wrusedw (  )
+                       );
+   
+   assign have_pkt_rdy = (rxfifolevel >= 128);
+
+   // Debugging Aids
+   assign debugbus[0] = tx_underrun;
+   assign debugbus[1] = rx_overrun;
+   assign debugbus[2] = tx_empty;
+   assign debugbus[3] = tx_full;
+   assign debugbus[4] = rx_empty;
+   assign debugbus[5] = rx_full;
+   assign debugbus[6] = txstrobe;
+   assign debugbus[7] = rxstrobe;
+   assign debugbus[8] = select_out;
+   assign debugbus[9] = rxstrobe & ~rx_full;
+   assign debugbus[10] = have_space;
+   assign debugbus[11] = have_pkt_rdy;
+   
+endmodule // bus_interface
+
diff --git a/usrp/fpga/sdr_lib/cic_decim.v b/usrp/fpga/sdr_lib/cic_decim.v
new file mode 100755 (executable)
index 0000000..45b863f
--- /dev/null
@@ -0,0 +1,106 @@
+// -*- verilog -*-
+//
+//  USRP - Universal Software Radio Peripheral
+//
+//  Copyright (C) 2003 Matt Ettus
+//
+//  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
+//
+
+
+module cic_decim
+  ( clock,reset,enable,rate,strobe_in,strobe_out,signal_in,signal_out);
+   parameter bw = 16;
+   parameter N = 4;
+   parameter log2_of_max_rate = 8;
+   parameter maxbitgain = N * log2_of_max_rate;
+   
+   input clock;
+   input reset;
+   input enable;
+   input [7:0] rate;
+   input strobe_in,strobe_out; 
+   input [bw-1:0] signal_in;
+   output [bw-1:0] signal_out;
+   reg [bw-1:0] signal_out;
+
+   wire [bw+maxbitgain-1:0] signal_in_ext;
+   reg [bw+maxbitgain-1:0]  integrator [0:N-1];
+   reg [bw+maxbitgain-1:0] differentiator [0:N-1];
+   reg [bw+maxbitgain-1:0] pipeline [0:N-1];
+   reg [bw+maxbitgain-1:0] sampler;
+   
+   integer i;
+   
+   sign_extend #(bw,bw+maxbitgain) 
+      ext_input (.in(signal_in),.out(signal_in_ext));
+   
+   always @(posedge clock)
+     if(reset)
+       for(i=0;i<N;i=i+1)
+        integrator[i] <= #1 0;
+     else if (enable && strobe_in)
+       begin
+         integrator[0] <= #1 integrator[0] + signal_in_ext;
+         for(i=1;i<N;i=i+1)
+           integrator[i] <= #1 integrator[i] + integrator[i-1];
+       end     
+   
+   always @(posedge clock)
+     if(reset)
+       begin
+         sampler <= #1 0;
+         for(i=0;i<N;i=i+1)
+           begin
+              pipeline[i] <= #1 0;
+              differentiator[i] <= #1 0;
+           end
+       end
+     else if (enable && strobe_out)
+       begin
+         sampler <= #1 integrator[N-1];
+         differentiator[0] <= #1 sampler;
+         pipeline[0] <= #1 sampler - differentiator[0];
+         for(i=1;i<N;i=i+1)
+           begin
+              differentiator[i] <= #1 pipeline[i-1];
+              pipeline[i] <= #1 pipeline[i-1] - differentiator[i];
+           end
+       end // if (enable && strobe_out)
+      
+   wire [bw+maxbitgain-1:0] signal_out_unnorm = pipeline[N-1];
+
+   // Output Scaling to same width as input
+   function [2:0] log_ceil;
+      input [7:0] val;
+      log_ceil = val[6] ? 3'd7 : val[5] ? 3'd6 : val[4] ? 3'd5 :
+                val[3] ? 3'd4 : val[2] ? 3'd3 : val[1] ? 3'd2 : 3'd1; 
+   endfunction // log_ceil
+   
+   wire [2:0] shift = log_ceil(rate);
+   
+   always @*
+     case(shift)
+       3'd2 : signal_out = signal_out_unnorm[2*N+bw-1:2*N]; //  Decim by 4
+       3'd3 : signal_out = signal_out_unnorm[3*N+bw-1:3*N];
+       3'd4 : signal_out = signal_out_unnorm[4*N+bw-1:4*N];
+       3'd5 : signal_out = signal_out_unnorm[5*N+bw-1:5*N];
+       3'd6 : signal_out = signal_out_unnorm[6*N+bw-1:6*N];
+       3'd7 : signal_out = signal_out_unnorm[7*N+bw-1:7*N];
+       default : signal_out = signal_out_unnorm[7*N+bw-1:7*N];
+     endcase // case(shift)
+   
+endmodule // cic_decim
+
diff --git a/usrp/fpga/sdr_lib/cic_int_shifter.v b/usrp/fpga/sdr_lib/cic_int_shifter.v
new file mode 100644 (file)
index 0000000..112d871
--- /dev/null
@@ -0,0 +1,98 @@
+// -*- verilog -*-
+//
+//  USRP - Universal Software Radio Peripheral
+//
+//  Copyright (C) 2003 Matt Ettus
+//
+//  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
+//
+
+
+module cic_int_shifter(rate,signal_in,signal_out);
+   parameter bw = 16;
+   parameter N = 4;
+   parameter log2_of_max_rate = 7;
+   parameter maxbitgain = (N-1)*log2_of_max_rate;
+   
+   input [7:0] rate;
+   input       wire [bw+maxbitgain-1:0] signal_in;
+   output      reg [bw-1:0] signal_out;
+
+   function [2:0] log_ceil;
+      input [7:0] val;
+      log_ceil = val[6] ? 3'd7 : val[5] ? 3'd6 : val[4] ? 3'd5 : 
+                val[3] ? 3'd4 : val[2] ? 3'd3 : val[1] ? 3'd2 : 3'd1; 
+   endfunction // log_ceil
+   
+   function [4:0] bitgain;
+      input [7:0] rate;
+      case(rate)
+       8'd4 : bitgain = 2*(N-1);
+       8'd8 : bitgain = 3*(N-1);
+       8'd16 : bitgain = 4*(N-1);
+       8'd32 : bitgain = 5*(N-1);
+       8'd64 : bitgain = 6*(N-1);
+       8'd128 : bitgain = 7*(N-1);
+       
+       8'd5 : bitgain = 7;
+       8'd6 : bitgain = 8;
+       8'd7 : bitgain = 9;
+       8'd9,8'd10 : bitgain = 10;
+       8'd12 : bitgain = 11;
+       8'd13,8'd14,8'd15 : bitgain = 12;
+       8'd17,8'd18,8'd19,8'd20 : bitgain = 13;
+       8'd21,8'd22,8'd23,8'd24,8'd25 : bitgain = 14;
+       8'd26,8'd27,8'd28,8'd29,8'd30,8'd31 : bitgain = 15;
+       8'd33,8'd34,8'd35,8'd36,8'd37,8'd38,8'd39,8'd40 : bitgain = 16;
+       8'd41,8'd42,8'd43,8'd44,8'd45,8'd46,8'd47,8'd48,8'd49,8'd50 : bitgain = 17;
+       8'd51,8'd52,8'd53,8'd54,8'd55,8'd56,8'd57,8'd58,8'd59,8'd60,8'd61,8'd62,8'd63 : bitgain = 18;
+       8'd65,8'd66,8'd67,8'd68,8'd69,8'd70,8'd71,8'd72,8'd73,8'd74,8'd75,8'd76,8'd77,8'd78,8'd79,8'd80 : bitgain = 19;
+       8'd81,8'd82,8'd83,8'd84,8'd85,8'd86,8'd87,8'd88,8'd89,8'd90,8'd91,8'd92,8'd93,8'd94,8'd95,8'd96,8'd97,8'd98,8'd99,8'd100,8'd101 : bitgain = 20;
+       
+       default : bitgain = 21;
+      endcase // case(rate)
+   endfunction // bitgain
+   
+   wire [4:0]    shift = bitgain(rate+1);
+   
+   // We should be able to do this, but can't ....
+   // assign     signal_out = signal_in[shift+bw-1:shift];
+   
+   always @*
+     case(shift)
+       5'd6  : signal_out = signal_in[6+bw-1:6];
+       5'd9  : signal_out = signal_in[9+bw-1:9];
+       5'd12 : signal_out = signal_in[12+bw-1:12];
+       5'd15 : signal_out = signal_in[15+bw-1:15];
+       5'd18 : signal_out = signal_in[18+bw-1:18];
+       5'd21 : signal_out = signal_in[21+bw-1:21];
+       
+       5'd7  : signal_out = signal_in[7+bw-1:7];
+       5'd8  : signal_out = signal_in[8+bw-1:8];
+       5'd10 : signal_out = signal_in[10+bw-1:10];
+       5'd11 : signal_out = signal_in[11+bw-1:11];
+       5'd13 : signal_out = signal_in[13+bw-1:13];
+       5'd14 : signal_out = signal_in[14+bw-1:14];
+       5'd16 : signal_out = signal_in[16+bw-1:16];
+       5'd17 : signal_out = signal_in[17+bw-1:17];
+       5'd19 : signal_out = signal_in[19+bw-1:19];
+       5'd20 : signal_out = signal_in[20+bw-1:20];
+       
+       
+       default : signal_out = signal_in[21+bw-1:21];
+     endcase // case(shift)
+
+endmodule // cic_int_shifter
+
diff --git a/usrp/fpga/sdr_lib/cic_interp.v b/usrp/fpga/sdr_lib/cic_interp.v
new file mode 100755 (executable)
index 0000000..43ab17d
--- /dev/null
@@ -0,0 +1,88 @@
+// -*- verilog -*-
+//
+//  USRP - Universal Software Radio Peripheral
+//
+//  Copyright (C) 2003 Matt Ettus
+//
+//  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
+//
+
+
+module cic_interp(clock,reset,enable,rate,strobe_in,strobe_out,signal_in,signal_out);
+   parameter bw = 16;
+   parameter N = 4;
+   parameter log2_of_max_rate = 7;
+   parameter maxbitgain = (N-1)*log2_of_max_rate;
+   
+   input clock;
+   input reset;
+   input enable;
+   input [7:0] rate;
+   input strobe_in,strobe_out; 
+   input [bw-1:0] signal_in;
+   wire [bw-1:0]       signal_in;
+   output [bw-1:0] signal_out;
+   wire [bw-1:0]   signal_out;
+
+   wire [bw+maxbitgain-1:0] signal_in_ext;
+   reg [bw+maxbitgain-1:0] integrator [0:N-1];
+   reg [bw+maxbitgain-1:0] differentiator [0:N-1];
+   reg [bw+maxbitgain-1:0] pipeline [0:N-1];
+
+   integer i;
+
+   sign_extend #(bw,bw+maxbitgain) 
+      ext_input (.in(signal_in),.out(signal_in_ext));
+   
+   //FIXME Note that this section has pipe and diff reversed
+   // It still works, but is confusing
+   always @(posedge clock)
+     if(reset)
+       for(i=0;i<N;i=i+1)
+        integrator[i] <= #1 0;
+     else if (enable & strobe_out)
+       begin
+         if(strobe_in)
+           integrator[0] <= #1 integrator[0] + pipeline[N-1];
+         for(i=1;i<N;i=i+1)
+           integrator[i] <= #1 integrator[i] + integrator[i-1];
+       end
+   
+   always @(posedge clock)
+     if(reset)
+       begin
+         for(i=0;i<N;i=i+1)
+           begin
+              differentiator[i] <= #1 0;
+              pipeline[i] <= #1 0;
+           end
+       end
+     else if (enable && strobe_in)
+       begin
+         differentiator[0] <= #1 signal_in_ext;
+         pipeline[0] <= #1 signal_in_ext - differentiator[0];
+         for(i=1;i<N;i=i+1)
+           begin
+              differentiator[i] <= #1 pipeline[i-1];
+              pipeline[i] <= #1 pipeline[i-1] - differentiator[i];
+           end
+       end
+   
+   wire [bw+maxbitgain-1:0] signal_out_unnorm = integrator[N-1];
+
+   cic_int_shifter cic_int_shifter(rate,signal_out_unnorm,signal_out);
+   
+endmodule // cic_interp
+
diff --git a/usrp/fpga/sdr_lib/clk_divider.v b/usrp/fpga/sdr_lib/clk_divider.v
new file mode 100755 (executable)
index 0000000..a687297
--- /dev/null
@@ -0,0 +1,43 @@
+// -*- verilog -*-
+//
+//  USRP - Universal Software Radio Peripheral
+//
+//  Copyright (C) 2003 Matt Ettus
+//
+//  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
+//
+
+
+module clk_divider(input reset, input wire in_clk,output reg out_clk, input [7:0] ratio);
+   reg [7:0] counter;
+   
+   // FIXME maybe should use PLL or switch to double edge version      
+       
+   always @(posedge in_clk or posedge reset)
+     if(reset)
+       counter <= #1 8'd0;
+     else if(counter == 0)
+       counter <= #1 ratio[7:1] + (ratio[0] & out_clk) - 8'b1;
+     else
+       counter <= #1 counter-8'd1;
+   
+   always @(posedge in_clk or posedge reset)
+     if(reset)
+       out_clk <= #1 1'b0;
+     else if(counter == 0)
+       out_clk <= #1 ~out_clk;
+   
+endmodule // clk_divider
+
diff --git a/usrp/fpga/sdr_lib/cordic.v b/usrp/fpga/sdr_lib/cordic.v
new file mode 100755 (executable)
index 0000000..8c8c0ab
--- /dev/null
@@ -0,0 +1,109 @@
+// -*- verilog -*-
+//
+//  USRP - Universal Software Radio Peripheral
+//
+//  Copyright (C) 2003 Matt Ettus
+//
+//  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
+//
+
+module cordic(clock, reset, enable, xi, yi, zi, xo, yo, zo );
+   parameter bitwidth = 16;
+   parameter zwidth = 16;
+   
+   input clock;
+   input reset;
+   input enable;
+   input [bitwidth-1:0] xi, yi;
+   output [bitwidth-1:0] xo, yo;
+   input [zwidth-1:0] zi;
+   output [zwidth-1:0] zo;
+   
+   reg [bitwidth+1:0]   x0,y0;
+   reg [zwidth-2:0]     z0;
+   wire [bitwidth+1:0]          x1,x2,x3,x4,x5,x6,x7,x8,x9,x10,x11,x12;
+   wire [bitwidth+1:0]          y1,y2,y3,y4,y5,y6,y7,y8,y9,y10,y11,y12;
+   wire [zwidth-2:0] z1,z2,z3,z4,z5,z6,z7,z8,z9,z10,z11,z12;
+   
+   wire [bitwidth+1:0] xi_ext = {{2{xi[bitwidth-1]}},xi};
+   wire [bitwidth+1:0] yi_ext = {{2{yi[bitwidth-1]}},yi};
+
+   // Compute consts.  Would be easier if vlog had atan...
+   // see gen_cordic_consts.py
+   
+`define c00 16'd8192
+`define c01 16'd4836
+`define c02 16'd2555
+`define c03 16'd1297
+`define c04 16'd651
+`define c05 16'd326
+`define c06 16'd163
+`define c07 16'd81
+`define c08 16'd41
+`define c09 16'd20
+`define c10 16'd10
+`define c11 16'd5
+`define c12 16'd3
+`define c13 16'd1
+`define c14 16'd1
+`define c15 16'd0
+`define c16 16'd0
+
+   always @(posedge clock)
+     if(reset)
+       begin
+         x0   <= #1 0; y0   <= #1 0;  z0   <= #1 0;
+       end
+     else// if(enable)
+       begin
+         z0 <= #1 zi[zwidth-2:0];
+         case (zi[zwidth-1:zwidth-2])
+           2'b00, 2'b11 : 
+             begin
+                x0 <= #1 xi_ext;
+                y0 <= #1 yi_ext;
+             end
+           2'b01, 2'b10 :
+             begin
+                x0 <= #1 -xi_ext;
+                y0 <= #1 -yi_ext;
+             end
+         endcase // case(zi[zwidth-1:zwidth-2])
+       end // else: !if(reset)
+   
+   // FIXME need to handle variable number of stages
+   // FIXME should be able to narrow zwidth but quartus makes it bigger...
+   // This would be easier if arrays worked better in vlog...
+   cordic_stage #(bitwidth+2,zwidth-1,0) cordic_stage0 (clock,reset,enable,x0,y0,z0,`c00,x1,y1,z1);
+   cordic_stage #(bitwidth+2,zwidth-1,1) cordic_stage1 (clock,reset,enable,x1,y1,z1,`c01,x2,y2,z2);
+   cordic_stage #(bitwidth+2,zwidth-1,2) cordic_stage2 (clock,reset,enable,x2,y2,z2,`c02,x3,y3,z3);
+   cordic_stage #(bitwidth+2,zwidth-1,3) cordic_stage3 (clock,reset,enable,x3,y3,z3,`c03,x4,y4,z4);
+   cordic_stage #(bitwidth+2,zwidth-1,4) cordic_stage4 (clock,reset,enable,x4,y4,z4,`c04,x5,y5,z5);
+   cordic_stage #(bitwidth+2,zwidth-1,5) cordic_stage5 (clock,reset,enable,x5,y5,z5,`c05,x6,y6,z6);
+   cordic_stage #(bitwidth+2,zwidth-1,6) cordic_stage6 (clock,reset,enable,x6,y6,z6,`c06,x7,y7,z7);
+   cordic_stage #(bitwidth+2,zwidth-1,7) cordic_stage7 (clock,reset,enable,x7,y7,z7,`c07,x8,y8,z8);
+   cordic_stage #(bitwidth+2,zwidth-1,8) cordic_stage8 (clock,reset,enable,x8,y8,z8,`c08,x9,y9,z9);
+   cordic_stage #(bitwidth+2,zwidth-1,9) cordic_stage9 (clock,reset,enable,x9,y9,z9,`c09,x10,y10,z10);
+   cordic_stage #(bitwidth+2,zwidth-1,10) cordic_stage10 (clock,reset,enable,x10,y10,z10,`c10,x11,y11,z11);
+   cordic_stage #(bitwidth+2,zwidth-1,11) cordic_stage11 (clock,reset,enable,x11,y11,z11,`c11,x12,y12,z12);
+
+   assign xo = x12[bitwidth:1];  
+   assign yo = y12[bitwidth:1];
+   //assign xo = x12[bitwidth+1:2];  // CORDIC gain is ~1.6, plus gain from rotating vectors
+   //assign yo = y12[bitwidth+1:2];
+   assign zo = z12;              
+
+endmodule // cordic
+
diff --git a/usrp/fpga/sdr_lib/cordic_stage.v b/usrp/fpga/sdr_lib/cordic_stage.v
new file mode 100755 (executable)
index 0000000..c9c0ef9
--- /dev/null
@@ -0,0 +1,60 @@
+// -*- verilog -*-
+//
+//  USRP - Universal Software Radio Peripheral
+//
+//  Copyright (C) 2003 Matt Ettus
+//
+//  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
+//
+
+module cordic_stage( clock, reset, enable, xi,yi,zi,constant,xo,yo,zo);
+   parameter bitwidth = 16;
+   parameter zwidth = 16;
+   parameter shift = 1;
+   
+   input     clock;
+   input     reset;
+   input     enable;
+   input [bitwidth-1:0] xi,yi;
+   input [zwidth-1:0] zi;
+   input [zwidth-1:0] constant;
+   output [bitwidth-1:0] xo,yo;
+   output [zwidth-1:0] zo;
+   
+   wire z_is_pos = ~zi[zwidth-1];
+
+   reg [bitwidth-1:0]   xo,yo;
+   reg [zwidth-1:0] zo;
+   
+   always @(posedge clock)
+     if(reset)
+       begin
+         xo <= #1 0;
+         yo <= #1 0;
+         zo <= #1 0;
+       end
+     else //if(enable)
+       begin
+         xo <= #1 z_is_pos ?   
+               xi - {{shift+1{yi[bitwidth-1]}},yi[bitwidth-2:shift]} :
+               xi + {{shift+1{yi[bitwidth-1]}},yi[bitwidth-2:shift]};
+         yo <= #1 z_is_pos ?   
+               yi + {{shift+1{xi[bitwidth-1]}},xi[bitwidth-2:shift]} :
+               yi - {{shift+1{xi[bitwidth-1]}},xi[bitwidth-2:shift]};
+         zo <= #1 z_is_pos ?   
+               zi - constant :
+               zi + constant;
+       end
+endmodule
diff --git a/usrp/fpga/sdr_lib/ddc.v b/usrp/fpga/sdr_lib/ddc.v
new file mode 100755 (executable)
index 0000000..48bca9a
--- /dev/null
@@ -0,0 +1,97 @@
+// -*- verilog -*-
+//
+//  USRP - Universal Software Radio Peripheral
+//
+//  Copyright (C) 2003 Matt Ettus
+//
+//  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
+//
+
+
+
+// DDC block
+
+module ddc(input clock,
+                       input reset,
+                       input enable,
+                       input [3:0] rate1,
+                       input [3:0] rate2,
+                       output strobe,
+                       input [31:0] freq,
+                       input [15:0] i_in,
+                       input [15:0] q_in,
+                       output [15:0] i_out,
+                       output [15:0] q_out
+                       );
+   parameter bw = 16;
+   parameter zw = 16;
+
+       wire [15:0] i_cordic_out, q_cordic_out;
+       wire [31:0] phase;
+
+       wire strobe1, strobe2;
+       reg [3:0] strobe_ctr1,strobe_ctr2;
+
+       always @(posedge clock)
+               if(reset | ~enable)
+                       strobe_ctr2 <= #1 4'd0;
+               else if(strobe2)
+                       strobe_ctr2 <= #1 4'd0;
+               else    
+                       strobe_ctr2 <= #1 strobe_ctr2 + 4'd1;
+                               
+       always @(posedge clock)
+               if(reset | ~enable)
+                       strobe_ctr1 <= #1 4'd0;
+               else if(strobe1)
+                       strobe_ctr1 <= #1 4'd0;
+               else if(strobe2)
+                       strobe_ctr1 <= #1 strobe_ctr1 + 4'd1;
+                               
+
+       assign strobe2 = enable & ( strobe_ctr2 == rate2 );
+       assign strobe1 = strobe2 & ( strobe_ctr1 == rate1 );
+
+       assign strobe = strobe1;
+
+       function [2:0] log_ceil;
+       input [3:0] val;
+       
+               log_ceil = val[3] ? 3'd4 : val[2] ? 3'd3 : val[1] ? 3'd2 : 3'd1; 
+       endfunction     
+       
+       wire [2:0] shift1 = log_ceil(rate1);
+       wire [2:0] shift2 = log_ceil(rate2);
+       
+       cordic #(.bitwidth(bw),.zwidth(zw),.stages(16))
+               cordic(.clock(clock), .reset(reset), .enable(enable),
+                       .xi(i_in), .yi(q_in), .zi(phase[31:32-zw]), 
+                       .xo(i_cordic_out), .yo(q_cordic_out), .zo()  );
+               
+       cic_decim_2stage #(.bw(bw),.N(4)) 
+               decim_i(.clock(clock),.reset(reset),.enable(enable),
+                       .strobe1(1'b1),.strobe2(strobe2),.strobe3(strobe1),.shift1(shift2),.shift2(shift1),
+                       .signal_in(i_cordic_out),.signal_out(i_out));
+                       
+       cic_decim_2stage #(.bw(bw),.N(4)) 
+               decim_q(.clock(clock),.reset(reset),.enable(enable),
+                       .strobe1(1'b1),.strobe2(strobe2),.strobe3(strobe1),.shift1(shift2),.shift2(shift1),
+                       .signal_in(q_cordic_out),.signal_out(q_out));
+       
+       phase_acc #(.resolution(32))
+               nco (.clk(clock),.reset(reset),.enable(enable),
+                       .freq(freq),.phase(phase));
+               
+endmodule
diff --git a/usrp/fpga/sdr_lib/dpram.v b/usrp/fpga/sdr_lib/dpram.v
new file mode 100644 (file)
index 0000000..5c38dec
--- /dev/null
@@ -0,0 +1,47 @@
+// -*- verilog -*-
+//
+//  USRP - Universal Software Radio Peripheral
+//
+//  Copyright (C) 2003 Matt Ettus
+//
+//  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
+//
+
+
+
+module dpram(wclk,wdata,waddr,wen,rclk,rdata,raddr);
+   parameter depth = 4;
+   parameter width = 16;
+   parameter size = 16;
+   
+   input wclk;
+   input [width-1:0] wdata;
+   input [depth-1:0] waddr;
+   input            wen;
+
+   input rclk;
+   output reg [width-1:0] rdata;
+   input [depth-1:0]  raddr;
+   
+   reg [width-1:0]    ram [0:size-1];
+   
+   always @(posedge wclk)
+     if(wen)
+       ram[waddr] <= #1 wdata;
+   
+   always @(posedge rclk)
+     rdata <= #1 ram[raddr];
+   
+endmodule // dpram
diff --git a/usrp/fpga/sdr_lib/duc.v b/usrp/fpga/sdr_lib/duc.v
new file mode 100755 (executable)
index 0000000..780fc9f
--- /dev/null
@@ -0,0 +1,95 @@
+// -*- verilog -*-
+//
+//  USRP - Universal Software Radio Peripheral
+//
+//  Copyright (C) 2003 Matt Ettus
+//
+//  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
+//
+
+// DUC block
+
+module duc(input clock,
+                       input reset,
+                       input enable,
+                       input [3:0] rate1,
+                       input [3:0] rate2,
+                       output strobe,
+                       input [31:0] freq,
+                       input [15:0] i_in,
+                       input [15:0] q_in,
+                       output [15:0] i_out,
+                       output [15:0] q_out
+                       );
+   parameter bw = 16;
+   parameter zw = 16;
+   
+       wire [15:0] i_interp_out, q_interp_out;
+       wire [31:0] phase;
+
+       wire strobe1, strobe2;
+       reg [3:0] strobe_ctr1,strobe_ctr2;
+
+       always @(posedge clock)
+               if(reset | ~enable)
+                       strobe_ctr2 <= #1 4'd0;
+               else if(strobe2)
+                       strobe_ctr2 <= #1 4'd0;
+               else    
+                       strobe_ctr2 <= #1 strobe_ctr2 + 4'd1;
+                               
+       always @(posedge clock)
+               if(reset | ~enable)
+                       strobe_ctr1 <= #1 4'd0;
+               else if(strobe1)
+                       strobe_ctr1 <= #1 4'd0;
+               else if(strobe2)
+                       strobe_ctr1 <= #1 strobe_ctr1 + 4'd1;
+                               
+
+       assign strobe2 = enable & ( strobe_ctr2 == rate2 );
+       assign strobe1 = strobe2 & ( strobe_ctr1 == rate1 );
+
+       assign strobe = strobe1;
+
+       function [2:0] log_ceil;
+       input [3:0] val;
+       
+               log_ceil = val[3] ? 3'd4 : val[2] ? 3'd3 : val[1] ? 3'd2 : 3'd1; 
+       endfunction     
+       
+       wire [2:0] shift1 = log_ceil(rate1);
+       wire [2:0] shift2 = log_ceil(rate2);
+       
+       cordic #(.bitwidth(bw),.zwidth(zw),.stages(16))
+               cordic(.clock(clock), .reset(reset), .enable(enable),
+                       .xi(i_interp_out), .yi(q_interp_out), .zi(phase[31:32-zw]), 
+                       .xo(i_out), .yo(q_out), .zo()  );
+               
+       cic_interp_2stage #(.bw(bw),.N(4)) 
+               interp_i(.clock(clock),.reset(reset),.enable(enable),
+                       .strobe1(strobe1),.strobe2(strobe2),.strobe3(1'b1),.shift1(shift1),.shift2(shift2),
+                       .signal_in(i_in),.signal_out(i_interp_out));
+
+       cic_interp_2stage #(.bw(bw),.N(4)) 
+               interp_q(.clock(clock),.reset(reset),.enable(enable),
+                       .strobe1(strobe1),.strobe2(strobe2),.strobe3(1'b1),.shift1(shift1),.shift2(shift2),
+                       .signal_in(q_in),.signal_out(q_interp_out));
+       
+       phase_acc #(.resolution(32))
+               nco (.clk(clock),.reset(reset),.enable(enable),
+                       .freq(freq),.phase(phase));
+               
+endmodule
diff --git a/usrp/fpga/sdr_lib/ext_fifo.v b/usrp/fpga/sdr_lib/ext_fifo.v
new file mode 100644 (file)
index 0000000..dfe1f2f
--- /dev/null
@@ -0,0 +1,126 @@
+// -*- verilog -*-
+//
+//  USRP - Universal Software Radio Peripheral
+//
+//  Copyright (C) 2003 Matt Ettus
+//
+//  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
+//
+
+// Vendor Independent FIFO module
+// Width and Depth should be parameterizable
+// Asynchronous clocks for each side
+// Read side is read-acknowledge, not read-request
+// FIFO does not enforce "don't write when full, don't read when empty"
+// That is up to the connecting modules
+// The FIFO only holds 2^N-1 entries, not 2^N
+
+module fifo (reset,data,write,wrclk,wr_used,q,read_ack,rdclk,rd_used);
+   parameter width=32;
+   parameter depth=10;
+
+   input reset;  // Asynchronous
+   input [width-1:0] data;
+   input write;
+   input wrclk;
+   output [depth-1:0] wr_used;
+   output [width-1:0] q;
+   input read_ack;
+   input rdclk;
+   output [depth-1:0] rd_used;
+
+   reg [depth-1:0] read_addr, write_addr, 
+                  read_addr_gray, read_addr_gray_sync,
+                  write_addr_gray, write_addr_gray_sync;
+
+   // Pseudo-dual-port RAM
+   dpram #(.depth(10),.width(width),.size(1024))
+         fifo_ram (.wclk(wrclk),.wdata(data),.waddr(write_addr),.wen(write),
+                  .rclk(rdclk), .rdata(q),.raddr(read_addr) );
+
+   wire [depth-1:0] wag,rag;
+
+   // Keep track of own side's pointer
+   always @(posedge wrclk or posedge reset)
+     if(reset) write_addr <= #1 0;
+     else if(write) write_addr <= #1 write_addr + 1;
+
+   always @(posedge rdclk or posedge reset)
+     if(reset) read_addr <= #1 0;
+     else if(read_ack) read_addr <= #1 read_addr + 1;
+
+   // Convert own side pointer to gray
+   bin2gray #(depth) write_b2g (write_addr,wag);
+   bin2gray #(depth) read_b2g (read_addr,rag);
+
+   // Latch it
+   always @(posedge wrclk or posedge reset)
+     if(reset) write_addr_gray <= #1 0;
+     else write_addr_gray <= #1 wag;
+
+   always @(posedge rdclk or posedge reset)
+     if(reset) read_addr_gray <= #1 0;
+     else read_addr_gray <= #1 rag;
+
+   // Send it to other side and latch
+   always @(posedge wrclk or posedge reset)
+     if(reset) read_addr_gray_sync <= #1 0;
+     else read_addr_gray_sync <= #1 read_addr_gray;
+
+   always @(posedge rdclk or posedge reset)
+     if(reset) write_addr_gray_sync <= #1 0;
+     else write_addr_gray_sync <= #1 write_addr_gray;
+
+   wire [depth-1:0] write_addr_sync, read_addr_sync;
+   
+   // Convert back to binary
+   gray2bin #(depth) write_g2b (write_addr_gray_sync, write_addr_sync);
+   gray2bin #(depth) read_g2b (read_addr_gray_sync, read_addr_sync);
+   assign rd_used = write_addr_sync - read_addr;
+   assign wr_used = write_addr - read_addr_sync;
+                 
+endmodule // fifo
+
+module bin2gray(bin_val,gray_val);
+   parameter width = 8;
+   input [width-1:0] bin_val;
+   output reg [width-1:0] gray_val;
+   
+   integer i;
+
+   always @*
+     begin
+       gray_val[width-1] = bin_val[width-1];
+       for(i=0;i<width-1;i=i+1)
+         gray_val[i] = bin_val[i] ^ bin_val[i+1];
+     end
+endmodule // bin2gray
+
+module gray2bin(gray_val,bin_val);
+   parameter width = 8;
+   input [width-1:0] gray_val;
+   output reg [width-1:0] bin_val;
+
+   integer i;
+   
+   always @*
+     begin
+       bin_val[width-1] = gray_val[width-1];
+       for(i=width-2;i>=0;i=i-1)
+         bin_val[i] = bin_val[i+1] ^ gray_val[i];
+     end
+endmodule // gray2bin
diff --git a/usrp/fpga/sdr_lib/gen_cordic_consts.py b/usrp/fpga/sdr_lib/gen_cordic_consts.py
new file mode 100755 (executable)
index 0000000..ab66cfe
--- /dev/null
@@ -0,0 +1,10 @@
+#!/usr/bin/env python
+
+import math
+
+zwidth = 16
+
+for i in range(17):
+    c = math.atan (1.0/(2**i)) / (2 * math.pi) * (1 << zwidth)
+    print "`define c%02d %d'd%d" % (i, zwidth, round (c))
+    
diff --git a/usrp/fpga/sdr_lib/gen_sync.v b/usrp/fpga/sdr_lib/gen_sync.v
new file mode 100644 (file)
index 0000000..d72b39d
--- /dev/null
@@ -0,0 +1,43 @@
+// -*- verilog -*-
+//
+//  USRP - Universal Software Radio Peripheral
+//
+//  Copyright (C) 2003 Matt Ettus
+//
+//  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
+//
+
+module gen_sync
+  ( input clock,
+    input reset,
+    input enable,
+    input [7:0] rate,
+    output wire sync );
+   
+//   parameter width = 8;
+   
+   reg [7:0] counter;
+   assign sync = |(((rate+1)>>1)& counter);
+      
+   always @(posedge clock)
+     if(reset || ~enable)
+       counter <= #1 0;
+     else if(counter == rate)
+       counter <= #1 0;
+     else 
+       counter <= #1 counter + 8'd1;
+   
+endmodule // gen_sync
+
diff --git a/usrp/fpga/sdr_lib/hb/acc.v b/usrp/fpga/sdr_lib/hb/acc.v
new file mode 100644 (file)
index 0000000..195d5ea
--- /dev/null
@@ -0,0 +1,22 @@
+
+
+module acc (input clock, input reset, input clear, input enable_in, output reg enable_out,
+           input signed [30:0] addend, output reg signed [33:0] sum );
+
+   always @(posedge clock)
+     if(reset)
+       sum <= #1 34'd0;
+     //else if(clear & enable_in)
+     //  sum <= #1 addend;
+     //else if(clear)
+     //  sum <= #1 34'd0;
+     else if(clear)
+       sum <= #1 addend;
+     else if(enable_in)
+       sum <= #1 sum + addend;
+
+   always @(posedge clock)
+     enable_out <= #1 enable_in;
+   
+endmodule // acc
+
diff --git a/usrp/fpga/sdr_lib/hb/coeff_ram.v b/usrp/fpga/sdr_lib/hb/coeff_ram.v
new file mode 100644 (file)
index 0000000..6546082
--- /dev/null
@@ -0,0 +1,26 @@
+
+
+module coeff_ram (input clock, input [3:0] rd_addr, output reg [15:0] rd_data);
+
+   always @(posedge clock)
+     case (rd_addr)
+       4'd0 : rd_data <= #1 -16'd16;
+       4'd1 : rd_data <= #1 16'd74;
+       4'd2 : rd_data <= #1 -16'd254;
+       4'd3 : rd_data <= #1 16'd669;
+       4'd4 : rd_data <= #1 -16'd1468;
+       4'd5 : rd_data <= #1 16'd2950;
+       4'd6 : rd_data <= #1 -16'd6158;
+       4'd7 : rd_data <= #1 16'd20585;
+       4'd8 : rd_data <= #1 16'd20585;
+       4'd9 : rd_data <= #1 -16'd6158;
+       4'd10 : rd_data <= #1 16'd2950;
+       4'd11 : rd_data <= #1 -16'd1468;
+       4'd12 : rd_data <= #1 16'd669;
+       4'd13 : rd_data <= #1 -16'd254;
+       4'd14 : rd_data <= #1 16'd74;
+       4'd15 : rd_data <= #1 -16'd16;
+       default : rd_data <= #1 16'd0;
+     endcase // case(rd_addr)
+   
+endmodule // ram
diff --git a/usrp/fpga/sdr_lib/hb/coeff_rom.v b/usrp/fpga/sdr_lib/hb/coeff_rom.v
new file mode 100644 (file)
index 0000000..c287eaa
--- /dev/null
@@ -0,0 +1,19 @@
+
+
+module coeff_rom (input clock, input [2:0] addr, output reg [15:0] data);
+
+   always @(posedge clock)
+     case (addr)
+       3'd0 : data <= #1 -16'd16;
+       3'd1 : data <= #1 16'd74;
+       3'd2 : data <= #1 -16'd254;
+       3'd3 : data <= #1 16'd669;
+       3'd4 : data <= #1 -16'd1468;
+       3'd5 : data <= #1 16'd2950;
+       3'd6 : data <= #1 -16'd6158;
+       3'd7 : data <= #1 16'd20585;
+     endcase // case(addr)
+      
+endmodule // coeff_rom
+
+
diff --git a/usrp/fpga/sdr_lib/hb/halfband_decim.v b/usrp/fpga/sdr_lib/hb/halfband_decim.v
new file mode 100644 (file)
index 0000000..2a05ce5
--- /dev/null
@@ -0,0 +1,163 @@
+/* -*- verilog -*-
+ * 
+ *  USRP - Universal Software Radio Peripheral
+ * 
+ *  Copyright (C) 2005 Matt Ettus
+ * 
+ *  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
+ */
+
+/*
+ * This implements a 31-tap halfband filter that decimates by two.
+ * The coefficients are symmetric, and with the exception of the middle tap,
+ * every other coefficient is zero.  The middle section of taps looks like this:
+ *
+ *  ..., -1468, 0, 2950, 0, -6158, 0, 20585, 32768, 20585, 0, -6158, 0, 2950, 0, -1468, ...
+ *                                             |
+ *                           middle tap -------+
+ *
+ * See coeff_rom.v for the full set.  The taps are scaled relative to 32768,
+ * thus the middle tap equals 1.0.  Not counting the middle tap, there are 8
+ * non-zero taps on each side, and they are symmetric.  A naive implementation
+ * requires a mulitply for each non-zero tap.  Because of symmetry, we can
+ * replace 2 multiplies with 1 add and 1 multiply.  Thus, to compute each output
+ * sample, we need to perform 8 multiplications.  Since the middle tap is 1.0,
+ * we just add the corresponding delay line value.
+ *
+ * About timing: We implement this with a single multiplier, so it takes
+ * 8 cycles to compute a single output.  However, since we're decimating by two 
+ * we can accept a new input value every 4 cycles.  strobe_in is asserted when
+ * there's a new input sample available.  Depending on the overall decimation
+ * rate, strobe_in may be asserted less frequently than once every 4 clocks.
+ * On the output side, we assert strobe_out when output contains a new sample.
+ *
+ * Implementation: Every time strobe_in is asserted we store the new data into
+ * the delay line.  We split the delay line into two components, one for the
+ * even samples, and one for the odd samples.  ram16_odd is the delay line for
+ * the odd samples.  This ram is written on each odd assertion of strobe_in, and
+ * is read on each clock when we're computing the dot product.  ram16_even is
+ * similar, although because it holds the even samples we must be able to read
+ * two samples from different addresses at the same time, while writing the incoming
+ * even samples. Thus it's "triple-ported".
+ */
+
+module halfband_decim
+  (input clock, input reset, input enable, input strobe_in, output wire strobe_out,
+   input wire [15:0] data_in, output reg [15:0] data_out,output wire [15:0] debugctrl);
+
+   reg [3:0] rd_addr1;
+   reg [3:0] rd_addr2;
+   reg [3:0] phase;
+   reg [3:0] base_addr;
+
+   wire      signed [15:0] mac_out,middle_data, sum, coeff;
+   wire      signed [30:0] product;
+   wire      signed [33:0] sum_even;
+   wire      clear;
+   reg              store_odd;
+   
+   always @(posedge clock)
+     if(reset)
+       store_odd <= #1 1'b0;
+     else
+       if(strobe_in)
+        store_odd <= #1 ~store_odd;
+
+   wire      start = strobe_in & store_odd;
+   always @(posedge clock)
+     if(reset)
+       base_addr <= #1 4'd0;
+     else if(start)
+       base_addr <= #1 base_addr + 4'd1;
+
+   always @(posedge clock)
+     if(reset)
+       phase <= #1 4'd8;
+     else if (start)
+       phase <= #1 4'd0;
+     else if(phase != 4'd8)
+       phase <= #1 phase + 4'd1;
+
+   reg              start_d1,start_d2,start_d3,start_d4,start_d5,start_d6,start_d7,start_d8,start_d9,start_dA,start_dB,start_dC,start_dD;
+   always @(posedge clock)
+     begin
+       start_d1 <= #1 start;
+       start_d2 <= #1 start_d1;
+       start_d3 <= #1 start_d2;
+       start_d4 <= #1 start_d3;
+       start_d5 <= #1 start_d4;
+       start_d6 <= #1 start_d5;
+       start_d7 <= #1 start_d6;
+       start_d8 <= #1 start_d7;
+       start_d9 <= #1 start_d8;
+       start_dA <= #1 start_d9;
+       start_dB <= #1 start_dA;
+       start_dC <= #1 start_dB;
+       start_dD <= #1 start_dC;
+     end // always @ (posedge clock)
+   
+   reg           mult_en, mult_en_pre;
+   always @(posedge clock)
+     begin
+       mult_en_pre <= #1 phase!=8;
+       mult_en <= #1 mult_en_pre;
+     end
+   
+   assign clear = start_d4; // was dC
+   wire   latch_result = start_d4; // was dC
+   assign strobe_out = start_d5; // was dD
+   wire   acc_en;
+   
+   always @*
+     case(phase[2:0])
+       3'd0 : begin rd_addr1 = base_addr + 4'd0; rd_addr2 = base_addr + 4'd15; end
+       3'd1 : begin rd_addr1 = base_addr + 4'd1; rd_addr2 = base_addr + 4'd14; end
+       3'd2 : begin rd_addr1 = base_addr + 4'd2; rd_addr2 = base_addr + 4'd13; end
+       3'd3 : begin rd_addr1 = base_addr + 4'd3; rd_addr2 = base_addr + 4'd12; end
+       3'd4 : begin rd_addr1 = base_addr + 4'd4; rd_addr2 = base_addr + 4'd11; end
+       3'd5 : begin rd_addr1 = base_addr + 4'd5; rd_addr2 = base_addr + 4'd10; end
+       3'd6 : begin rd_addr1 = base_addr + 4'd6; rd_addr2 = base_addr + 4'd9; end
+       3'd7 : begin rd_addr1 = base_addr + 4'd7; rd_addr2 = base_addr + 4'd8; end
+       default: begin rd_addr1 = base_addr + 4'd0; rd_addr2 = base_addr + 4'd15; end
+     endcase // case(phase)
+   
+   coeff_rom coeff_rom (.clock(clock),.addr(phase[2:0]-3'd1),.data(coeff));
+   
+   ram16_2sum ram16_even (.clock(clock),.write(strobe_in & ~store_odd),
+                         .wr_addr(base_addr),.wr_data(data_in),
+                         .rd_addr1(rd_addr1),.rd_addr2(rd_addr2),
+                         .sum(sum));
+
+   ram16 ram16_odd (.clock(clock),.write(strobe_in & store_odd),  // Holds middle items
+                   .wr_addr(base_addr),.wr_data(data_in),
+                   //.rd_addr(base_addr+4'd7),.rd_data(middle_data));
+                   .rd_addr(base_addr+4'd6),.rd_data(middle_data));
+
+   mult mult(.clock(clock),.x(coeff),.y(sum),.product(product),.enable_in(mult_en),.enable_out(acc_en));
+
+   acc acc(.clock(clock),.reset(reset),.enable_in(acc_en),.enable_out(),
+          .clear(clear),.addend(product),.sum(sum_even));
+
+   wire signed [33:0] dout = sum_even + {{4{middle_data[15]}},middle_data,14'b0}; // We already divided product by 2!!!!
+
+   always @(posedge clock)
+     if(reset)
+       data_out <= #1 16'd0;
+     else if(latch_result)
+       data_out <= #1 dout[30:15] + (dout[33]& |dout[14:0]);
+
+   assign  debugctrl = { clock,reset,acc_en,mult_en,clear,latch_result,store_odd,strobe_in,strobe_out,phase};
+   
+endmodule // halfband_decim
diff --git a/usrp/fpga/sdr_lib/hb/halfband_interp.v b/usrp/fpga/sdr_lib/hb/halfband_interp.v
new file mode 100644 (file)
index 0000000..cdb11c1
--- /dev/null
@@ -0,0 +1,121 @@
+
+
+module halfband_interp 
+  (input clock, input reset, input enable,
+   input strobe_in, input strobe_out,
+   input [15:0] signal_in_i, input [15:0] signal_in_q, 
+   output reg [15:0] signal_out_i, output reg [15:0] signal_out_q,
+   output wire [12:0] debug);
+   
+   wire [15:0]         coeff_ram_out;
+   wire [15:0]         data_ram_out_i;
+   wire [15:0]         data_ram_out_q;
+
+   wire [3:0]  data_rd_addr;
+   reg [3:0]   data_wr_addr;
+   reg [2:0]   coeff_rd_addr;
+
+   wire                filt_done;
+   
+   wire [15:0]         mac_out_i;
+   wire [15:0]         mac_out_q;
+   reg [15:0]  delayed_middle_i, delayed_middle_q;
+   wire [7:0]  shift = 8'd9;
+
+   reg                 stb_out_happened;
+
+   wire [15:0]         data_ram_out_i_b;
+   
+   always @(posedge clock)
+     if(strobe_in)
+       stb_out_happened <= #1 1'b0;
+     else if(strobe_out)
+       stb_out_happened <= #1 1'b1;
+   
+assign debug = {filt_done,data_rd_addr,data_wr_addr,coeff_rd_addr};
+
+   wire [15:0]         signal_out_i = stb_out_happened ? mac_out_i : delayed_middle_i;
+   wire [15:0]         signal_out_q = stb_out_happened ? mac_out_q : delayed_middle_q;
+
+/*   always @(posedge clock)
+     if(reset)
+       begin
+         signal_out_i <= #1 16'd0;
+         signal_out_q <= #1 16'd0;
+       end
+     else if(strobe_in)
+       begin
+         signal_out_i <= #1 delayed_middle_i; // Multiply by 1 for middle coeff
+         signal_out_q <= #1 delayed_middle_q;
+       end
+     //else if(filt_done&stb_out_happened)
+     else if(stb_out_happened)
+       begin
+         signal_out_i <= #1 mac_out_i;
+         signal_out_q <= #1 mac_out_q;
+       end
+*/
+   
+   always @(posedge clock)
+     if(reset)
+       coeff_rd_addr <= #1 3'd0;
+     else if(coeff_rd_addr != 3'd0)
+       coeff_rd_addr <= #1 coeff_rd_addr + 3'd1;
+     else if(strobe_in)
+       coeff_rd_addr <= #1 3'd1;
+
+   reg filt_done_d1;
+   always@(posedge clock)
+     filt_done_d1 <= #1 filt_done;
+   
+   always @(posedge clock)
+     if(reset)
+       data_wr_addr <= #1 4'd0;
+   //else if(strobe_in)
+     else if(filt_done & ~filt_done_d1)
+       data_wr_addr <= #1 data_wr_addr + 4'd1;
+
+   always @(posedge clock)
+     if(coeff_rd_addr == 3'd7)
+       begin
+         delayed_middle_i <= #1 data_ram_out_i_b;
+       //  delayed_middle_q <= #1 data_ram_out_q_b;
+       end
+   
+//   always @(posedge clock)
+//     if(reset)
+//       data_rd_addr <= #1 4'd0;
+//     else if(strobe_in)
+//       data_rd_addr <= #1 data_wr_addr + 4'd1;
+//     else if(!filt_done)
+//       data_rd_addr <= #1 data_rd_addr + 4'd1;
+//     else
+//       data_rd_addr <= #1 data_wr_addr;
+  
+   wire [3:0] data_rd_addr1 = data_wr_addr + {1'b0,coeff_rd_addr};
+   wire [3:0] data_rd_addr2 = data_wr_addr + 15 - {1'b0,coeff_rd_addr};
+//   always @(posedge clock)
+//     if(reset)
+//       filt_done <= #1 1'b1;
+//     else if(strobe_in)
+ //      filt_done <= #1 1'b0;
+//     else if(coeff_rd_addr == 4'd0)
+//       filt_done <= #1 1'b1;
+
+   assign filt_done = (coeff_rd_addr == 3'd0);
+   
+   coeff_ram coeff_ram ( .clock(clock),.rd_addr({1'b0,coeff_rd_addr}),.rd_data(coeff_ram_out) );
+   
+   ram16_2sum data_ram_i ( .clock(clock),.write(strobe_in),.wr_addr(data_wr_addr),.wr_data(signal_in_i),
+                     .rd_addr1(data_rd_addr1),.rd_addr2(data_rd_addr2),.rd_data(data_ram_out_i_b),.sum(data_ram_out_i));
+   
+   ram16_2sum data_ram_q ( .clock(clock),.write(strobe_in),.wr_addr(data_wr_addr),.wr_data(signal_in_q),
+                     .rd_addr1(data_rd_addr1),.rd_addr2(data_rd_addr2),.rd_data(data_ram_out_q));
+   
+   mac mac_i (.clock(clock),.reset(reset),.enable(~filt_done),.clear(strobe_in),
+             .x(data_ram_out_i),.y(coeff_ram_out),.shift(shift),.z(mac_out_i) );
+   
+   mac mac_q (.clock(clock),.reset(reset),.enable(~filt_done),.clear(strobe_in),
+             .x(data_ram_out_q),.y(coeff_ram_out),.shift(shift),.z(mac_out_q) );
+
+endmodule // halfband_interp
diff --git a/usrp/fpga/sdr_lib/hb/hbd_tb/HBD b/usrp/fpga/sdr_lib/hb/hbd_tb/HBD
new file mode 100644 (file)
index 0000000..574fbba
--- /dev/null
@@ -0,0 +1,80 @@
+*-6.432683 5736 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
+@28
+test_hbd.clock
+test_hbd.reset
+@420
+test_hbd.halfband_decim.middle_data[15:0]
+@22
+test_hbd.halfband_decim.sum_even[33:0]
+test_hbd.halfband_decim.base_addr[3:0]
+@420
+test_hbd.i_in[15:0]
+@24
+test_hbd.halfband_decim.phase[3:0]
+test_hbd.halfband_decim.ram16_even.rd_addr1[3:0]
+test_hbd.halfband_decim.ram16_even.rd_addr2[3:0]
+test_hbd.halfband_decim.ram16_even.wr_addr[3:0]
+test_hbd.halfband_decim.ram16_even.wr_data[15:0]
+@28
+test_hbd.halfband_decim.ram16_even.write
+@420
+test_hbd.halfband_decim.sum[15:0]
+test_hbd.halfband_decim.product[30:0]
+test_hbd.halfband_decim.dout[33:0]
+test_hbd.halfband_decim.sum_even[33:0]
+@22
+test_hbd.halfband_decim.acc.addend[30:0]
+@28
+test_hbd.halfband_decim.acc.reset
+@420
+test_hbd.halfband_decim.acc.sum[33:0]
+test_hbd.halfband_decim.mult.x[15:0]
+test_hbd.halfband_decim.mult.y[15:0]
+@28
+test_hbd.halfband_decim.acc.clear
+test_hbd.strobe_in
+test_hbd.strobe_out
+test_hbd.halfband_decim.acc_en
+@420
+test_hbd.i_out[15:0]
+@28
+test_hbd.halfband_decim.mult_en
+test_hbd.halfband_decim.latch_result
+@420
+test_hbd.halfband_decim.sum[15:0]
+test_hbd.halfband_decim.sum_even[33:0]
+test_hbd.halfband_decim.dout[33:0]
+test_hbd.halfband_decim.data_out[15:0]
+@22
+test_hbd.halfband_decim.data_out[15:0]
+@28
+test_hbd.halfband_decim.dout[33:0]
+@29
+test_hbd.halfband_decim.acc_en
+@22
+test_hbd.halfband_decim.base_addr[3:0]
+@28
+test_hbd.halfband_decim.clear
+test_hbd.halfband_decim.latch_result
+test_hbd.halfband_decim.mult_en
+test_hbd.halfband_decim.mult_en_pre
+@22
+test_hbd.halfband_decim.phase[3:0]
+@28
+test_hbd.halfband_decim.start
+test_hbd.halfband_decim.start_d1
+test_hbd.halfband_decim.start_d2
+test_hbd.halfband_decim.start_d3
+test_hbd.halfband_decim.start_d4
+test_hbd.halfband_decim.start_d5
+test_hbd.halfband_decim.start_d6
+test_hbd.halfband_decim.start_d7
+test_hbd.halfband_decim.start_d8
+test_hbd.halfband_decim.start_d9
+test_hbd.halfband_decim.start_dA
+test_hbd.halfband_decim.start_dB
+test_hbd.halfband_decim.start_dC
+test_hbd.halfband_decim.start_dD
+test_hbd.halfband_decim.store_odd
+test_hbd.halfband_decim.strobe_in
+test_hbd.halfband_decim.strobe_out
diff --git a/usrp/fpga/sdr_lib/hb/hbd_tb/really_golden b/usrp/fpga/sdr_lib/hb/hbd_tb/really_golden
new file mode 100644 (file)
index 0000000..2d24a9e
--- /dev/null
@@ -0,0 +1,142 @@
+VCD info: dumpfile test_hbd.vcd opened for output.
+    x
+    x
+    x
+    x
+    x
+    x
+    x
+    x
+    x
+    x
+    x
+    x
+    x
+    x
+    x
+    x
+    0
+    0
+    0
+    0
+    0
+    0
+    0
+    0
+    0
+    0
+    0
+ 8192
+    0
+    0
+    0
+    0
+    0
+    0
+    0
+    0
+    0
+    0
+    0
+    0
+    0
+-     4
+   18
+-    63
+  167
+-   367
+  737
+-  1539
+ 5146
+ 5146
+-  1539
+  737
+-   367
+  167
+-    63
+   18
+-     4
+    0
+    0
+    0
+    0
+    0
+-     4
+   14
+-    49
+  118
+-   249
+  488
+ 7141
+12287
+17433
+15894
+16631
+16264
+16432
+16368
+16387
+16383
+16383
+16383
+16383
+16383
+16387
+16368
+16432
+16264
+16631
+15894
+ 9241
+ 4095
+-  1051
+  488
+-   249
+  118
+-    49
+   14
+-     4
+    0
+    0
+    0
+    0
+    0
+-     4
+   14
+-    49
+  118
+-   249
+  488
+-  1051
+12287
+17433
+15894
+16631
+16264
+16432
+16368
+16387
+16383
+16383
+16383
+16383
+16383
+16387
+16368
+16432
+16264
+16631
+15894
+17433
+ 4095
+-  1051
+  488
+-   249
+  118
+-    49
+   14
+-     4
+    0
+    0
+    0
+    0
diff --git a/usrp/fpga/sdr_lib/hb/hbd_tb/regression b/usrp/fpga/sdr_lib/hb/hbd_tb/regression
new file mode 100644 (file)
index 0000000..fc279c2
--- /dev/null
@@ -0,0 +1,95 @@
+echo "Baseline 1000"
+iverilog -y .. -o test_hbd -DRATE=1000 test_hbd.v  ; ./test_hbd >golden
+diff golden really_golden
+
+echo
+echo "Test 100"
+iverilog -y .. -o test_hbd -DRATE=100 test_hbd.v  ; ./test_hbd >output ; diff output golden
+
+echo
+echo "Test 50"
+iverilog -y .. -o test_hbd -DRATE=50 test_hbd.v  ; ./test_hbd >output ; diff output golden
+
+echo
+echo "Test 40"
+iverilog -y .. -o test_hbd -DRATE=40 test_hbd.v  ; ./test_hbd >output ; diff output golden
+
+echo
+echo "Test 30"
+iverilog -y .. -o test_hbd -DRATE=30 test_hbd.v  ; ./test_hbd >output ; diff output golden
+
+echo
+echo "Test 25"
+iverilog -y .. -o test_hbd -DRATE=25 test_hbd.v  ; ./test_hbd >output ; diff output golden
+
+echo
+echo "Test 20"
+iverilog -y .. -o test_hbd -DRATE=20 test_hbd.v  ; ./test_hbd >output ; diff output golden
+
+echo
+echo "Test 19"
+iverilog -y .. -o test_hbd -DRATE=19 test_hbd.v  ; ./test_hbd >output ; diff output golden
+
+echo
+echo "Test 18"
+iverilog -y .. -o test_hbd -DRATE=18 test_hbd.v  ; ./test_hbd >output ; diff output golden
+
+echo
+echo "Test 17"
+iverilog -y .. -o test_hbd -DRATE=17 test_hbd.v  ; ./test_hbd >output ; diff output golden
+
+echo
+echo "Test 16"
+iverilog -y .. -o test_hbd -DRATE=16 test_hbd.v  ; ./test_hbd >output ; diff output golden
+
+echo
+echo "Test 15"
+iverilog -y .. -o test_hbd -DRATE=15 test_hbd.v  ; ./test_hbd >output ; diff output golden
+
+echo
+echo "Test 14"
+iverilog -y .. -o test_hbd -DRATE=14 test_hbd.v  ; ./test_hbd >output ; diff output golden
+
+echo
+echo "Test 13"
+iverilog -y .. -o test_hbd -DRATE=13 test_hbd.v  ; ./test_hbd >output ; diff output golden
+
+echo
+echo "Test 12"
+iverilog -y .. -o test_hbd -DRATE=12 test_hbd.v  ; ./test_hbd >output ; diff output golden
+
+echo
+echo "Test 11"
+iverilog -y .. -o test_hbd -DRATE=11 test_hbd.v  ; ./test_hbd >output ; diff output golden
+
+echo
+echo "Test 10"
+iverilog -y .. -o test_hbd -DRATE=10 test_hbd.v  ; ./test_hbd >output ; diff output golden
+
+echo
+echo "Test 9"
+iverilog -y .. -o test_hbd -DRATE=9 test_hbd.v  ; ./test_hbd >output ; diff output golden
+
+echo
+echo "Test 8"
+iverilog -y .. -o test_hbd -DRATE=8 test_hbd.v  ; ./test_hbd >output ; diff output golden
+
+echo
+echo "Test 7"
+iverilog -y .. -o test_hbd -DRATE=7 test_hbd.v  ; ./test_hbd >output ; diff output golden
+
+echo
+echo "Test 6"
+iverilog -y .. -o test_hbd -DRATE=6 test_hbd.v  ; ./test_hbd >output ; diff output golden
+
+echo
+echo "Test 5"
+iverilog -y .. -o test_hbd -DRATE=5 test_hbd.v  ; ./test_hbd >output ; diff output golden
+
+echo
+echo "Test 4"
+iverilog -y .. -o test_hbd -DRATE=4 test_hbd.v  ; ./test_hbd >output ; diff output golden
+
+echo
+echo "Test 3"
+iverilog -y .. -o test_hbd -DRATE=3 test_hbd.v  ; ./test_hbd >output ; diff output golden
diff --git a/usrp/fpga/sdr_lib/hb/hbd_tb/run_hbd b/usrp/fpga/sdr_lib/hb/hbd_tb/run_hbd
new file mode 100755 (executable)
index 0000000..b8aec75
--- /dev/null
@@ -0,0 +1,4 @@
+#!/bin/sh
+
+iverilog -y .. -o test_hbd test_hbd.v
+./test_hbd
diff --git a/usrp/fpga/sdr_lib/hb/hbd_tb/test_hbd.v b/usrp/fpga/sdr_lib/hb/hbd_tb/test_hbd.v
new file mode 100644 (file)
index 0000000..01ab5e7
--- /dev/null
@@ -0,0 +1,75 @@
+
+
+module test_hbd();
+
+   reg clock;
+   initial clock = 1'b0;
+   always #5 clock <= ~clock;
+
+   reg reset;
+   initial reset = 1'b1;
+   initial #1000 reset = 1'b0;
+   
+   initial $dumpfile("test_hbd.vcd");
+   initial $dumpvars(0,test_hbd);
+
+   reg [15:0] i_in, q_in;
+   wire [15:0] i_out, q_out;
+
+   reg                strobe_in;
+   wire        strobe_out;
+   reg                coeff_write;
+   reg [15:0]  coeff_data;
+   reg [4:0]   coeff_addr;
+   
+   halfband_decim halfband_decim 
+     ( .clock(clock),.reset(reset),.enable(),.strobe_in(strobe_in),.strobe_out(strobe_out),
+       .data_in(i_in),.data_out(i_out) );
+   
+   always @(posedge strobe_out)
+     if(i_out[15])
+       $display("-%d",65536-i_out);
+     else
+       $display("%d",i_out);
+
+   initial
+     begin
+       strobe_in = 1'b0;
+       @(negedge reset);
+       @(posedge clock);
+       while(1)
+         begin
+            strobe_in <= #1 1'b1;
+            @(posedge clock);
+            strobe_in <= #1 1'b0;
+            repeat (`RATE)
+              @(posedge clock);
+         end
+     end
+
+   initial #10000000 $finish;    // Just in case...
+
+   initial
+     begin
+       i_in <= #1 16'd0;
+       repeat (40) @(posedge strobe_in);
+       i_in <= #1 16'd16384;
+       @(posedge strobe_in);
+       i_in <= #1 16'd0;
+       repeat (40) @(posedge strobe_in);
+       i_in <= #1 16'd16384;
+       @(posedge strobe_in);
+       i_in <= #1 16'd0;
+       repeat (40) @(posedge strobe_in);
+       i_in <= #1 16'd16384;
+       repeat (40) @(posedge strobe_in);
+       i_in <= #1 16'd0;
+       repeat (41) @(posedge strobe_in);
+       i_in <= #1 16'd16384;
+       repeat (40) @(posedge strobe_in);
+       i_in <= #1 16'd0;
+       repeat (40) @(posedge strobe_in);
+       repeat (7) @(posedge clock);
+       $finish;
+     end // initial begin
+endmodule // test_hb
diff --git a/usrp/fpga/sdr_lib/hb/mac.v b/usrp/fpga/sdr_lib/hb/mac.v
new file mode 100644 (file)
index 0000000..5a270bc
--- /dev/null
@@ -0,0 +1,58 @@
+
+
+module mac (input clock, input reset, input enable, input clear,
+           input signed [15:0] x, input signed [15:0] y,
+           input [7:0] shift, output [15:0] z );
+
+   reg signed [30:0] product;
+   reg signed [39:0] z_int;
+   reg signed [15:0] z_shift;
+
+   reg enable_d1;
+   always @(posedge clock)
+     enable_d1 <= #1 enable;
+   
+   always @(posedge clock)
+     if(reset | clear)
+       z_int <= #1 40'd0;
+     else if(enable_d1)
+       z_int <= #1 z_int + {{9{product[30]}},product};
+
+   always @(posedge clock)
+     product <= #1 x*y;
+
+   always @*   // FIXME full case? parallel case?
+     case(shift)
+       //8'd0 : z_shift <= z_int[39:24];
+       //8'd1 : z_shift <= z_int[38:23];
+       //8'd2 : z_shift <= z_int[37:22];
+       //8'd3 : z_shift <= z_int[36:21];
+       //8'd4 : z_shift <= z_int[35:20];
+       //8'd5 : z_shift <= z_int[34:19];
+       8'd6 : z_shift <= z_int[33:18];
+       8'd7 : z_shift <= z_int[32:17];
+       8'd8 : z_shift <= z_int[31:16];
+       8'd9 : z_shift <= z_int[30:15];
+       8'd10 : z_shift <= z_int[29:14];
+       8'd11 : z_shift <= z_int[28:13];
+       //8'd12 : z_shift <= z_int[27:12];
+       //8'd13 : z_shift <= z_int[26:11];
+       //8'd14 : z_shift <= z_int[25:10];
+       //8'd15 : z_shift <= z_int[24:9];
+       //8'd16 : z_shift <= z_int[23:8];
+       //8'd17 : z_shift <= z_int[22:7];
+       //8'd18 : z_shift <= z_int[21:6];
+       //8'd19 : z_shift <= z_int[20:5];
+       //8'd20 : z_shift <= z_int[19:4];
+       //8'd21 : z_shift <= z_int[18:3];
+       //8'd22 : z_shift <= z_int[17:2];
+       //8'd23 : z_shift <= z_int[16:1];
+       //8'd24 : z_shift <= z_int[15:0];
+       default : z_shift <= z_int[15:0];
+     endcase // case(shift)
+   
+   // FIXME do we need to saturate?
+   //assign z = z_shift;
+   assign z = z_int[15:0];
+   
+endmodule // mac
diff --git a/usrp/fpga/sdr_lib/hb/mult.v b/usrp/fpga/sdr_lib/hb/mult.v
new file mode 100644 (file)
index 0000000..a8d4cb1
--- /dev/null
@@ -0,0 +1,16 @@
+
+
+module mult (input clock, input signed [15:0] x, input signed [15:0] y, output reg signed [30:0] product,
+            input enable_in, output reg enable_out );
+
+   always @(posedge clock)
+     if(enable_in)
+       product <= #1 x*y;
+     else
+       product <= #1 31'd0;
+   
+   always @(posedge clock)
+     enable_out <= #1 enable_in;
+   
+endmodule // mult
+
diff --git a/usrp/fpga/sdr_lib/hb/ram16_2port.v b/usrp/fpga/sdr_lib/hb/ram16_2port.v
new file mode 100644 (file)
index 0000000..e1761a9
--- /dev/null
@@ -0,0 +1,22 @@
+
+
+module ram16_2port (input clock, input write, 
+                   input [3:0] wr_addr, input [15:0] wr_data,
+                   input [3:0] rd_addr1, output reg [15:0] rd_data1,
+                   input [3:0] rd_addr2, output reg [15:0] rd_data2);
+   
+   reg [15:0]                  ram_array [0:31];
+   
+   always @(posedge clock)
+     rd_data1 <= #1 ram_array[rd_addr1];
+   
+   always @(posedge clock)
+     rd_data2 <= #1 ram_array[rd_addr2];
+   
+   always @(posedge clock)
+     if(write)
+       ram_array[wr_addr] <= #1 wr_data;
+   
+endmodule // ram16_2port
+
+
diff --git a/usrp/fpga/sdr_lib/hb/ram16_2sum.v b/usrp/fpga/sdr_lib/hb/ram16_2sum.v
new file mode 100644 (file)
index 0000000..559b06f
--- /dev/null
@@ -0,0 +1,27 @@
+
+
+module ram16_2sum (input clock, input write, 
+                  input [3:0] wr_addr, input [15:0] wr_data,
+                  input [3:0] rd_addr1, input [3:0] rd_addr2,
+                   output reg [15:0] sum);
+   
+   reg signed [15:0]     ram_array [0:15];
+   reg signed [15:0]     a,b;
+   wire signed [16:0]    sum_int;
+   
+   always @(posedge clock)
+     if(write)
+       ram_array[wr_addr] <= #1 wr_data;
+      
+   always @(posedge clock)
+     begin
+       a <= #1 ram_array[rd_addr1];
+       b <= #1 ram_array[rd_addr2];
+     end
+   
+   assign sum_int = {a[15],a} + {b[15],b};
+   
+   always @(posedge clock)
+     sum <= #1 sum_int[16:1] + (sum_int[16]&sum_int[0]);
+     
+endmodule // ram16_2sum
diff --git a/usrp/fpga/sdr_lib/hb/ram32_2sum.v b/usrp/fpga/sdr_lib/hb/ram32_2sum.v
new file mode 100644 (file)
index 0000000..d1f55b7
--- /dev/null
@@ -0,0 +1,22 @@
+
+
+module ram32_2sum (input clock, input write, 
+                  input [4:0] wr_addr, input [15:0] wr_data,
+                  input [4:0] rd_addr1, input [4:0] rd_addr2,
+                  output reg [15:0] sum);
+   
+   reg [15:0]                  ram_array [0:31];
+   wire [16:0]                         sum_int;
+   
+   always @(posedge clock)
+     if(write)
+       ram_array[wr_addr] <= #1 wr_data;
+
+   assign sum_int = ram_array[rd_addr1] + ram_array[rd_addr2];
+
+   always @(posedge clock)
+     sum <= #1 sum_int[16:1] + (sum_int[16]&sum_int[0]);
+
+   
+endmodule // ram32_2sum
+
diff --git a/usrp/fpga/sdr_lib/io_pins.v b/usrp/fpga/sdr_lib/io_pins.v
new file mode 100644 (file)
index 0000000..da20b3b
--- /dev/null
@@ -0,0 +1,52 @@
+// -*- verilog -*-
+//
+//  USRP - Universal Software Radio Peripheral
+//
+//  Copyright (C) 2005,2006 Matt Ettus
+//
+//  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
+//
+
+`include "../../firmware/include/fpga_regs_common.v"
+`include "../../firmware/include/fpga_regs_standard.v"
+
+module io_pins
+  ( inout wire [15:0] io_0, inout wire [15:0] io_1, inout wire [15:0] io_2, inout wire [15:0] io_3,
+    input wire [15:0] reg_0, input wire [15:0] reg_1, input wire [15:0] reg_2, input wire [15:0] reg_3,
+    input clock, input rx_reset, input tx_reset,
+    input [6:0] serial_addr, input [31:0] serial_data, input serial_strobe);
+   
+   reg [15:0] io_0_oe,io_1_oe,io_2_oe,io_3_oe;
+   
+   bidir_reg bidir_reg_0 (.tristate(io_0),.oe(io_0_oe),.reg_val(reg_0));
+   bidir_reg bidir_reg_1 (.tristate(io_1),.oe(io_1_oe),.reg_val(reg_1));
+   bidir_reg bidir_reg_2 (.tristate(io_2),.oe(io_2_oe),.reg_val(reg_2));
+   bidir_reg bidir_reg_3 (.tristate(io_3),.oe(io_3_oe),.reg_val(reg_3));
+   
+   // Upper 16 bits are mask for lower 16
+   always @(posedge clock)
+     if(serial_strobe)
+       case(serial_addr)
+        `FR_OE_0 : io_0_oe
+          <= #1 (io_0_oe & ~serial_data[31:16]) | (serial_data[15:0] & serial_data[31:16] );
+        `FR_OE_1 : io_1_oe
+          <= #1 (io_1_oe & ~serial_data[31:16]) | (serial_data[15:0] & serial_data[31:16] );
+        `FR_OE_2 : io_2_oe
+          <= #1 (io_2_oe & ~serial_data[31:16]) | (serial_data[15:0] & serial_data[31:16] );
+        `FR_OE_3 : io_3_oe
+          <= #1 (io_3_oe & ~serial_data[31:16]) | (serial_data[15:0] & serial_data[31:16] );
+       endcase // case(serial_addr)
+
+endmodule // io_pins
diff --git a/usrp/fpga/sdr_lib/master_control.v b/usrp/fpga/sdr_lib/master_control.v
new file mode 100644 (file)
index 0000000..d42817c
--- /dev/null
@@ -0,0 +1,155 @@
+// -*- verilog -*-
+//
+//  USRP - Universal Software Radio Peripheral
+//
+//  Copyright (C) 2003,2005 Matt Ettus
+//
+//  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
+//
+
+// Clock, enable, and reset controls for whole system
+
+module master_control
+  ( input master_clk, input usbclk,
+    input wire [6:0] serial_addr, input wire [31:0] serial_data, input wire serial_strobe,
+    output tx_bus_reset, output rx_bus_reset,
+    output wire tx_dsp_reset, output wire rx_dsp_reset,
+    output wire enable_tx, output wire enable_rx,
+    output wire [7:0] interp_rate, output wire [7:0] decim_rate,
+    output tx_sample_strobe, output strobe_interp,
+    output rx_sample_strobe, output strobe_decim,
+    input tx_empty,
+    input wire [15:0] debug_0,input wire [15:0] debug_1,input wire [15:0] debug_2,input wire [15:0] debug_3,
+    output wire [15:0] reg_0, output wire [15:0] reg_1, output wire [15:0] reg_2, output wire [15:0] reg_3
+    );
+   
+   // FIXME need a separate reset for all control settings 
+   // Master Controls assignments
+   wire [7:0] master_controls;
+   setting_reg #(`FR_MASTER_CTRL) sr_mstr_ctrl(.clock(master_clk),.reset(1'b0),.strobe(serial_strobe),.addr(serial_addr),.in(serial_data),.out(master_controls));
+   assign     enable_tx = master_controls[0];
+   assign     enable_rx = master_controls[1];
+   assign     tx_dsp_reset = master_controls[2];
+   assign     rx_dsp_reset = master_controls[3];
+   // Unused - 4-7
+
+   // Strobe Generators
+   setting_reg #(`FR_INTERP_RATE) sr_interp(.clock(master_clk),.reset(tx_dsp_reset),.strobe(serial_strobe),.addr(serial_addr),.in(serial_data),.out(interp_rate));
+   setting_reg #(`FR_DECIM_RATE) sr_decim(.clock(master_clk),.reset(rx_dsp_reset),.strobe(serial_strobe),.addr(serial_addr),.in(serial_data),.out(decim_rate));
+   
+   strobe_gen da_strobe_gen
+     ( .clock(master_clk),.reset(tx_dsp_reset),.enable(enable_tx),
+       .rate(8'd1),.strobe_in(1'b1),.strobe(tx_sample_strobe) );
+
+   strobe_gen tx_strobe_gen
+     ( .clock(master_clk),.reset(tx_dsp_reset),.enable(enable_tx),
+       .rate(interp_rate),.strobe_in(tx_sample_strobe),.strobe(strobe_interp) );
+
+   assign  rx_sample_strobe = 1'b1;
+   
+   strobe_gen decim_strobe_gen
+     ( .clock(master_clk),.reset(rx_dsp_reset),.enable(enable_rx),
+       .rate(decim_rate),.strobe_in(rx_sample_strobe),.strobe(strobe_decim) );
+   
+   // Reset syncs for bus (usbclk) side
+   // The RX bus side reset isn't used, the TX bus side one may not be needed
+   reg           tx_reset_bus_sync1, rx_reset_bus_sync1, tx_reset_bus_sync2, rx_reset_bus_sync2;
+          
+   always @(posedge usbclk)
+     begin
+       tx_reset_bus_sync1 <= #1 tx_dsp_reset;
+       rx_reset_bus_sync1 <= #1 rx_dsp_reset;
+       tx_reset_bus_sync2 <= #1 tx_reset_bus_sync1;
+       rx_reset_bus_sync2 <= #1 rx_reset_bus_sync1;
+     end
+
+   assign tx_bus_reset = tx_reset_bus_sync2;
+   assign rx_bus_reset = rx_reset_bus_sync2;
+
+   wire [7:0]   txa_refclk, rxa_refclk, txb_refclk, rxb_refclk;
+   wire        txaclk,txbclk,rxaclk,rxbclk;
+   wire [3:0]  debug_en, txcvr_ctrl;
+
+   wire [31:0] txcvr_rxlines, txcvr_txlines;
+      
+   setting_reg #(`FR_TX_A_REFCLK) sr_txaref(.clock(master_clk),.reset(tx_dsp_reset),.strobe(serial_strobe),.addr(serial_addr),.in(serial_data),.out(txa_refclk));
+   setting_reg #(`FR_RX_A_REFCLK) sr_rxaref(.clock(master_clk),.reset(rx_dsp_reset),.strobe(serial_strobe),.addr(serial_addr),.in(serial_data),.out(rxa_refclk));
+   setting_reg #(`FR_TX_B_REFCLK) sr_txbref(.clock(master_clk),.reset(tx_dsp_reset),.strobe(serial_strobe),.addr(serial_addr),.in(serial_data),.out(txb_refclk));
+   setting_reg #(`FR_RX_B_REFCLK) sr_rxbref(.clock(master_clk),.reset(rx_dsp_reset),.strobe(serial_strobe),.addr(serial_addr),.in(serial_data),.out(rxb_refclk));
+
+   setting_reg #(`FR_DEBUG_EN) sr_debugen(.clock(master_clk),.reset(rx_dsp_reset|tx_dsp_reset),.strobe(serial_strobe),.addr(serial_addr),.in(serial_data),.out(debug_en));
+         
+   clk_divider clk_div_0 (.reset(tx_dsp_reset),.in_clk(master_clk),.out_clk(txaclk),.ratio(txa_refclk[6:0]));
+   clk_divider clk_div_1 (.reset(rx_dsp_reset),.in_clk(master_clk),.out_clk(rxaclk),.ratio(rxa_refclk[6:0]));
+   clk_divider clk_div_2 (.reset(tx_dsp_reset),.in_clk(master_clk),.out_clk(txbclk),.ratio(txb_refclk[6:0]));
+   clk_divider clk_div_3 (.reset(rx_dsp_reset),.in_clk(master_clk),.out_clk(rxbclk),.ratio(rxb_refclk[6:0]));
+   
+   reg [15:0]  io_0_reg,io_1_reg,io_2_reg,io_3_reg;
+   // Upper 16 bits are mask for lower 16
+   always @(posedge master_clk)
+     if(serial_strobe)
+       case(serial_addr)
+        `FR_IO_0 : io_0_reg
+          <= #1 (io_0_reg & ~serial_data[31:16]) | (serial_data[15:0] & serial_data[31:16] );
+        `FR_IO_1 : io_1_reg
+          <= #1 (io_1_reg & ~serial_data[31:16]) | (serial_data[15:0] & serial_data[31:16] );
+        `FR_IO_2 : io_2_reg
+          <= #1 (io_2_reg & ~serial_data[31:16]) | (serial_data[15:0] & serial_data[31:16] );
+        `FR_IO_3 : io_3_reg
+          <= #1 (io_3_reg & ~serial_data[31:16]) | (serial_data[15:0] & serial_data[31:16] );
+       endcase // case(serial_addr)
+
+   wire        transmit_now = !tx_empty & enable_tx;
+   wire        atr_ctl;
+   wire [15:0] atr_mask_0, atr_txval_0, atr_rxval_0, atr_mask_1, atr_txval_1, atr_rxval_1, atr_mask_2, atr_txval_2, atr_rxval_2, atr_mask_3, atr_txval_3, atr_rxval_3;
+      
+   setting_reg #(`FR_ATR_MASK_0) sr_atr_mask_0(.clock(master_clk),.reset(1'b0),.strobe(serial_strobe),.addr(serial_addr),.in(serial_data),.out(atr_mask_0));
+   setting_reg #(`FR_ATR_TXVAL_0) sr_atr_txval_0(.clock(master_clk),.reset(1'b0),.strobe(serial_strobe),.addr(serial_addr),.in(serial_data),.out(atr_txval_0));
+   setting_reg #(`FR_ATR_RXVAL_0) sr_atr_rxval_0(.clock(master_clk),.reset(1'b0),.strobe(serial_strobe),.addr(serial_addr),.in(serial_data),.out(atr_rxval_0));
+
+   setting_reg #(`FR_ATR_MASK_1) sr_atr_mask_1(.clock(master_clk),.reset(1'b0),.strobe(serial_strobe),.addr(serial_addr),.in(serial_data),.out(atr_mask_1));
+   setting_reg #(`FR_ATR_TXVAL_1) sr_atr_txval_1(.clock(master_clk),.reset(1'b0),.strobe(serial_strobe),.addr(serial_addr),.in(serial_data),.out(atr_txval_1));
+   setting_reg #(`FR_ATR_RXVAL_1) sr_atr_rxval_1(.clock(master_clk),.reset(1'b0),.strobe(serial_strobe),.addr(serial_addr),.in(serial_data),.out(atr_rxval_1));
+
+   setting_reg #(`FR_ATR_MASK_2) sr_atr_mask_2(.clock(master_clk),.reset(1'b0),.strobe(serial_strobe),.addr(serial_addr),.in(serial_data),.out(atr_mask_2));
+   setting_reg #(`FR_ATR_TXVAL_2) sr_atr_txval_2(.clock(master_clk),.reset(1'b0),.strobe(serial_strobe),.addr(serial_addr),.in(serial_data),.out(atr_txval_2));
+   setting_reg #(`FR_ATR_RXVAL_2) sr_atr_rxval_2(.clock(master_clk),.reset(1'b0),.strobe(serial_strobe),.addr(serial_addr),.in(serial_data),.out(atr_rxval_2));
+
+   setting_reg #(`FR_ATR_MASK_3) sr_atr_mask_3(.clock(master_clk),.reset(1'b0),.strobe(serial_strobe),.addr(serial_addr),.in(serial_data),.out(atr_mask_3));
+   setting_reg #(`FR_ATR_TXVAL_3) sr_atr_txval_3(.clock(master_clk),.reset(1'b0),.strobe(serial_strobe),.addr(serial_addr),.in(serial_data),.out(atr_txval_3));
+   setting_reg #(`FR_ATR_RXVAL_3) sr_atr_rxval_3(.clock(master_clk),.reset(1'b0),.strobe(serial_strobe),.addr(serial_addr),.in(serial_data),.out(atr_rxval_3));
+
+   //setting_reg #(`FR_ATR_CTL) sr_atr_ctl(.clock(master_clk),.reset(1'b0),.strobe(serial_strobe),.addr(serial_addr),.in(serial_data),.out(atr_ctl));
+   assign      atr_ctl = 1'b1;
+
+   wire [15:0] atr_selected_0 = transmit_now ? atr_txval_0 : atr_rxval_0;
+   wire [15:0] io_0 = ({{16{atr_ctl}}} &  atr_mask_0 & atr_selected_0) | (~({{16{atr_ctl}}} & atr_mask_0) & io_0_reg);
+   
+   wire [15:0] atr_selected_1 = transmit_now ? atr_txval_1 : atr_rxval_1;
+   wire [15:0] io_1 = ({{16{atr_ctl}}} &  atr_mask_1 & atr_selected_1) | (~({{16{atr_ctl}}} & atr_mask_1) & io_1_reg);
+   
+   wire [15:0] atr_selected_2 = transmit_now ? atr_txval_2 : atr_rxval_2;
+   wire [15:0] io_2 = ({{16{atr_ctl}}} &  atr_mask_2 & atr_selected_2) | (~({{16{atr_ctl}}} & atr_mask_2) & io_2_reg);
+   
+   wire [15:0] atr_selected_3 = transmit_now ? atr_txval_3 : atr_rxval_3;
+   wire [15:0] io_3 = ({{16{atr_ctl}}} &  atr_mask_3 & atr_selected_3) | (~({{16{atr_ctl}}} & atr_mask_3) & io_3_reg);
+   
+   assign reg_0 = debug_en[0] ? debug_0 : txa_refclk[7] ? {io_0[15:1],txaclk} : io_0;
+   assign reg_1 = debug_en[1] ? debug_1 : rxa_refclk[7] ? {io_1[15:1],rxaclk} : io_1;
+   assign reg_2 = debug_en[2] ? debug_2 : txb_refclk[7] ? {io_2[15:1],txbclk} : io_2;
+   assign reg_3 = debug_en[3] ? debug_3 : rxb_refclk[7] ? {io_3[15:1],rxbclk} : io_3;
+
+   
+endmodule // master_control
diff --git a/usrp/fpga/sdr_lib/master_control_multi.v b/usrp/fpga/sdr_lib/master_control_multi.v
new file mode 100644 (file)
index 0000000..af1e0b1
--- /dev/null
@@ -0,0 +1,73 @@
+// -*- verilog -*-
+//
+//  USRP - Universal Software Radio Peripheral
+//
+//  Copyright (C) 2006 Martin Dudok van Heel
+//
+//  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
+//
+`include "usrp_multi.vh"
+`include "../../../firmware/include/fpga_regs_common.v"
+`include "../../../firmware/include/fpga_regs_standard.v"
+// Clock, enable, and reset controls for whole system
+// Modified version to enable multi_usrp synchronisation
+
+module master_control_multi
+  ( input master_clk, input usbclk,
+    input wire [6:0] serial_addr, input wire [31:0] serial_data, input wire serial_strobe,
+    input wire rx_slave_sync,
+    output tx_bus_reset, output rx_bus_reset,
+    output wire tx_dsp_reset, output wire rx_dsp_reset,
+    output wire enable_tx, output wire enable_rx,
+    output wire sync_rx,
+    output wire [7:0] interp_rate, output wire [7:0] decim_rate,
+    output tx_sample_strobe, output strobe_interp,
+    output rx_sample_strobe, output strobe_decim,
+    input tx_empty,
+    input wire [15:0] debug_0,input wire [15:0] debug_1,input wire [15:0] debug_2,input wire [15:0] debug_3,
+    output wire [15:0] reg_0, output wire [15:0] reg_1, output wire [15:0] reg_2, output wire [15:0] reg_3
+    );
+   
+   wire [15:0] reg_1_std;
+
+   master_control master_control_standard
+     ( .master_clk(master_clk),.usbclk(usbclk),
+       .serial_addr(serial_addr),.serial_data(serial_data),.serial_strobe(serial_strobe),
+       .tx_bus_reset(tx_bus_reset),.rx_bus_reset(rx_bus_reset),
+       .tx_dsp_reset(tx_dsp_reset),.rx_dsp_reset(rx_dsp_reset),
+       .enable_tx(enable_tx),.enable_rx(enable_rx),
+       .interp_rate(interp_rate),.decim_rate(decim_rate),
+       .tx_sample_strobe(tx_sample_strobe),.strobe_interp(strobe_interp),
+       .rx_sample_strobe(rx_sample_strobe),.strobe_decim(strobe_decim),
+       .tx_empty(tx_empty),
+       .debug_0(debug_0),.debug_1(debug_1),
+       .debug_2(debug_2),.debug_3(debug_3),
+       .reg_0(reg_0),.reg_1(reg_1_std),.reg_2(reg_2),.reg_3(reg_3) );
+
+   // FIXME need a separate reset for all control settings 
+   // Master/slave Controls assignments
+   wire [7:0] rx_master_slave_controls;
+   setting_reg_masked #(`FR_RX_MASTER_SLAVE) sr_rx_mstr_slv_ctrl(.clock(master_clk),.reset(1'b0),.strobe(serial_strobe),.addr(serial_addr),.in(serial_data),.out(rx_master_slave_controls));
+   assign     sync_rx = rx_master_slave_controls[`bitnoFR_RX_SYNC] | (rx_master_slave_controls[`bitnoFR_RX_SYNC_SLAVE] & rx_slave_sync);
+  //sync if we are told by master_control or if we get a hardware slave sync
+  //TODO There can be a one sample difference between master and slave sync. 
+  //     Maybe use a register for sync_rx which uses the (neg or pos) edge of master_clock and/or rx_slave_sync to trigger
+  //     Or even use a seperate sync_rx_out and sync_rx_internal (which lags behind)
+  //TODO make output pin not hardwired
+assign reg_1 ={(rx_master_slave_controls[`bitnoFR_RX_SYNC_MASTER])? sync_rx:reg_1_std[15],reg_1_std[14:0]};
+
+   
+endmodule // master_control
diff --git a/usrp/fpga/sdr_lib/phase_acc.v b/usrp/fpga/sdr_lib/phase_acc.v
new file mode 100755 (executable)
index 0000000..d00716f
--- /dev/null
@@ -0,0 +1,52 @@
+// -*- verilog -*-
+//
+//  USRP - Universal Software Radio Peripheral
+//
+//  Copyright (C) 2003 Matt Ettus
+//
+//  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
+//
+
+
+
+// Basic Phase accumulator for DDS
+
+
+module phase_acc (clk,reset,enable,strobe,serial_addr,serial_data,serial_strobe,phase);   
+   parameter FREQADDR = 0;
+   parameter PHASEADDR = 0;
+   parameter resolution = 32;
+   
+   input     clk, reset, enable, strobe;
+   input [6:0] serial_addr;
+   input [31:0] serial_data;
+   input       serial_strobe;
+   
+   output reg [resolution-1:0] phase;
+   wire [resolution-1:0] freq;
+
+   setting_reg #(FREQADDR) sr_rxfreq0(.clock(clk),.reset(1'b0),.strobe(serial_strobe),.addr(serial_addr),.in(serial_data),.out(freq));
+
+   always @(posedge clk)
+     if(reset)
+       phase <= #1 32'b0;
+     else if(serial_strobe & (serial_addr == PHASEADDR))
+       phase <= #1 serial_data;
+     else if(enable & strobe)
+       phase <= #1 phase + freq;
+
+endmodule // phase_acc
+
+   
diff --git a/usrp/fpga/sdr_lib/ram.v b/usrp/fpga/sdr_lib/ram.v
new file mode 100644 (file)
index 0000000..fb64cde
--- /dev/null
@@ -0,0 +1,16 @@
+
+
+module ram (input clock, input write, 
+           input [4:0] wr_addr, input [15:0] wr_data,
+           input [4:0] rd_addr, output reg [15:0] rd_data);
+
+   reg [15:0]          ram_array [0:31];
+
+   always @(posedge clock)
+     rd_data <= #1 ram_array[rd_addr];
+
+   always @(posedge clock)
+     if(write)
+       ram_array[wr_addr] <= #1 wr_data;
+
+endmodule // ram
diff --git a/usrp/fpga/sdr_lib/ram16.v b/usrp/fpga/sdr_lib/ram16.v
new file mode 100644 (file)
index 0000000..0c93da2
--- /dev/null
@@ -0,0 +1,17 @@
+
+
+module ram16 (input clock, input write, 
+             input [3:0] wr_addr, input [15:0] wr_data,
+             input [3:0] rd_addr, output reg [15:0] rd_data);
+
+   reg [15:0]          ram_array [0:15];
+
+   always @(posedge clock)
+     rd_data <= #1 ram_array[rd_addr];
+
+   always @(posedge clock)
+     if(write)
+       ram_array[wr_addr] <= #1 wr_data;
+
+endmodule // ram16
+
diff --git a/usrp/fpga/sdr_lib/ram32.v b/usrp/fpga/sdr_lib/ram32.v
new file mode 100644 (file)
index 0000000..064e273
--- /dev/null
@@ -0,0 +1,17 @@
+
+
+module ram32 (input clock, input write, 
+             input [4:0] wr_addr, input [15:0] wr_data,
+             input [4:0] rd_addr, output reg [15:0] rd_data);
+
+   reg [15:0]          ram_array [0:31];
+
+   always @(posedge clock)
+     rd_data <= #1 ram_array[rd_addr];
+
+   always @(posedge clock)
+     if(write)
+       ram_array[wr_addr] <= #1 wr_data;
+
+endmodule // ram32
+
diff --git a/usrp/fpga/sdr_lib/ram64.v b/usrp/fpga/sdr_lib/ram64.v
new file mode 100644 (file)
index 0000000..0845458
--- /dev/null
@@ -0,0 +1,16 @@
+
+
+module ram64 (input clock, input write, 
+             input [5:0] wr_addr, input [15:0] wr_data,
+             input [5:0] rd_addr, output reg [15:0] rd_data);
+
+   reg [15:0]          ram_array [0:63];
+
+   always @(posedge clock)
+     rd_data <= #1 ram_array[rd_addr];
+
+   always @(posedge clock)
+     if(write)
+       ram_array[wr_addr] <= #1 wr_data;
+
+endmodule // ram64
diff --git a/usrp/fpga/sdr_lib/rssi.v b/usrp/fpga/sdr_lib/rssi.v
new file mode 100644 (file)
index 0000000..e45e214
--- /dev/null
@@ -0,0 +1,30 @@
+
+
+module rssi (input clock, input reset, input enable,
+            input [11:0] adc, output [15:0] rssi, output [15:0] over_count);
+
+   wire                  over_hi = (adc == 12'h7FF);
+   wire                  over_lo = (adc == 12'h800);
+   wire                  over = over_hi | over_lo;
+
+   reg [25:0]            over_count_int;
+   always @(posedge clock)
+     if(reset | ~enable)
+       over_count_int <= #1 26'd0;
+     else
+       over_count_int <= #1 over_count_int + (over ? 26'd65535 : 26'd0) - over_count_int[25:10];
+   
+   assign      over_count = over_count_int[25:10];
+   
+   wire [11:0] abs_adc = adc[11] ? ~adc : adc;
+
+   reg [25:0]  rssi_int;
+   always @(posedge clock)
+     if(reset | ~enable)
+       rssi_int <= #1 26'd0;
+     else
+       rssi_int <= #1 rssi_int + abs_adc - rssi_int[25:10];
+
+   assign      rssi = rssi_int[25:10];
+   
+endmodule // rssi
diff --git a/usrp/fpga/sdr_lib/rx_buffer.v b/usrp/fpga/sdr_lib/rx_buffer.v
new file mode 100644 (file)
index 0000000..70c800e
--- /dev/null
@@ -0,0 +1,182 @@
+// -*- verilog -*-
+//
+//  USRP - Universal Software Radio Peripheral
+//
+//  Copyright (C) 2003 Matt Ettus
+//
+//  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
+//
+
+// Interface to Cypress FX2 bus
+// A packet is 512 Bytes.  Each fifo line is 2 bytes
+// Fifo has 1024 or 2048 lines
+
+`include "../../firmware/include/fpga_regs_common.v"
+`include "../../firmware/include/fpga_regs_standard.v"
+
+module rx_buffer
+  ( input usbclk,
+    input bus_reset,  // Not used in RX
+    input reset,  // DSP side reset (used here), do not reset registers
+    input reset_regs, //Only reset registers
+    output [15:0] usbdata,
+    input RD,
+    output wire have_pkt_rdy,
+    output reg rx_overrun,
+    input wire [3:0] channels,
+    input wire [15:0] ch_0,
+    input wire [15:0] ch_1,
+    input wire [15:0] ch_2,
+    input wire [15:0] ch_3,
+    input wire [15:0] ch_4,
+    input wire [15:0] ch_5,
+    input wire [15:0] ch_6,
+    input wire [15:0] ch_7,
+    input rxclk,
+    input rxstrobe,
+    input clear_status,
+    input [6:0] serial_addr, input [31:0] serial_data, input serial_strobe,
+    output [15:0] debugbus
+    );
+
+   wire [15:0] fifodata, fifodata_8;
+   reg [15:0]  fifodata_16;
+   
+   wire [11:0] rxfifolevel;
+   wire rx_empty, rx_full;
+
+   wire bypass_hb, want_q;
+   wire [4:0] bitwidth;
+   wire [3:0] bitshift;
+   
+   setting_reg #(`FR_RX_FORMAT) sr_rxformat(.clock(rxclk),.reset(reset_regs),
+                                           .strobe(serial_strobe),.addr(serial_addr),.in(serial_data),
+                                           .out({bypass_hb,want_q,bitwidth,bitshift}));
+
+   // Receive FIFO (ADC --> USB)
+
+   // 257 Bug Fix
+   reg [8:0] read_count;
+   always @(negedge usbclk)
+     if(bus_reset)
+       read_count <= #1 9'd0;
+     else if(RD & ~read_count[8])
+       read_count <= #1 read_count + 9'd1;
+     else
+       read_count <= #1 RD ? read_count : 9'b0;
+   
+   // Detect overrun
+   always @(posedge rxclk)
+     if(reset)
+       rx_overrun <= 1'b0;
+     else if(rxstrobe & (store_next != 0))
+       rx_overrun <= 1'b1;
+     else if(clear_status)
+       rx_overrun <= 1'b0;
+
+   reg [3:0] store_next;
+   always @(posedge rxclk)
+     if(reset)
+       store_next <= #1 4'd0;
+     else if(rxstrobe & (store_next == 0))
+       store_next <= #1 4'd1;
+     else if(~rx_full & (store_next == channels))
+       store_next <= #1 4'd0;
+     else if(~rx_full & (bitwidth == 5'd8) & (store_next == (channels>>1)))
+       store_next <= #1 4'd0;
+     else if(~rx_full & (store_next != 0))
+       store_next <= #1 store_next + 4'd1;
+
+   assign    fifodata = (bitwidth == 5'd8) ? fifodata_8 : fifodata_16;
+
+   assign    fifodata_8 = {round_8(top),round_8(bottom)};
+   reg [15:0] top,bottom;
+
+   function [7:0] round_8;
+      input [15:0] in_val;
+
+      round_8 = in_val[15:8] + (in_val[15] & |in_val[7:0]);
+   endfunction // round_8
+      
+   always @*
+     case(store_next)
+       4'd1 : begin
+         bottom = ch_0;
+         top = ch_1;
+       end
+       4'd2 : begin
+         bottom = ch_2;
+         top = ch_3;
+       end
+       4'd3 : begin
+         bottom = ch_4;
+         top = ch_5;
+       end
+       4'd4 : begin
+         bottom = ch_6;
+         top = ch_7;
+       end
+       default : begin
+         top = 16'hFFFF;
+         bottom = 16'hFFFF;
+       end
+     endcase // case(store_next)
+   
+   always @*
+     case(store_next)
+       4'd1 : fifodata_16 = ch_0;
+       4'd2 : fifodata_16 = ch_1;
+       4'd3 : fifodata_16 = ch_2;
+       4'd4 : fifodata_16 = ch_3;
+       4'd5 : fifodata_16 = ch_4;
+       4'd6 : fifodata_16 = ch_5;
+       4'd7 : fifodata_16 = ch_6;
+       4'd8 : fifodata_16 = ch_7;
+       default : fifodata_16 = 16'hFFFF;
+     endcase // case(store_next)
+   
+   fifo_4k rxfifo 
+     ( .data ( fifodata ),
+       .wrreq (~rx_full & (store_next != 0)),
+       .wrclk ( rxclk ),
+
+       .q ( usbdata ),
+       .rdreq ( RD & ~read_count[8] ), 
+       .rdclk ( ~usbclk ),
+       
+       .aclr ( reset ),  // This one is asynchronous, so we can use either reset
+       
+       .rdempty ( rx_empty ),
+       .rdusedw ( rxfifolevel ),
+       .wrfull ( rx_full ),
+       .wrusedw (  )
+       );
+   
+   assign have_pkt_rdy = (rxfifolevel >= 256);
+
+   // Debugging Aids
+   assign debugbus[0] = RD;
+   assign debugbus[1] = rx_overrun;
+   assign debugbus[2] = read_count[8];
+   assign debugbus[3] = rx_full;
+   assign debugbus[4] = rxstrobe;
+   assign debugbus[5] = usbclk;
+   assign debugbus[6] = have_pkt_rdy;
+   assign debugbus[10:7] = store_next;
+   //assign debugbus[15:11] = rxfifolevel[4:0];
+   assign debugbus[15:11] = bitwidth;
+   
+endmodule // rx_buffer
+
diff --git a/usrp/fpga/sdr_lib/rx_chain.v b/usrp/fpga/sdr_lib/rx_chain.v
new file mode 100644 (file)
index 0000000..4031e6b
--- /dev/null
@@ -0,0 +1,105 @@
+// -*- verilog -*-
+//
+//  USRP - Universal Software Radio Peripheral
+//
+//  Copyright (C) 2003 Matt Ettus
+//
+//  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
+//
+
+// Following defines conditionally include RX path circuitry
+
+`include "usrp_std.vh"
+module rx_chain
+  (input clock,
+   input reset,
+   input enable,
+   input wire [7:0] decim_rate,
+   input sample_strobe,
+   input decimator_strobe,
+   output wire hb_strobe,
+   input [6:0] serial_addr, input [31:0] serial_data, input serial_strobe,
+   input wire [15:0] i_in,
+   input wire [15:0] q_in,
+   output wire [15:0] i_out,
+   output wire [15:0] q_out,
+   output wire [15:0] debugdata,output wire [15:0] debugctrl
+   );
+
+   parameter FREQADDR = 0;
+   parameter PHASEADDR = 0;
+   
+   wire [31:0] phase;
+   wire [15:0] bb_i, bb_q;
+   wire [15:0] hb_in_i, hb_in_q;
+   
+   assign      debugdata = hb_in_i;
+
+`ifdef RX_NCO_ON
+    phase_acc #(FREQADDR,PHASEADDR,32) rx_phase_acc
+     (.clk(clock),.reset(reset),.enable(enable),
+      .serial_addr(serial_addr),.serial_data(serial_data),.serial_strobe(serial_strobe),
+      .strobe(sample_strobe),.phase(phase) );
+
+   cordic rx_cordic
+     ( .clock(clock),.reset(reset),.enable(enable), 
+       .xi(i_in),.yi(q_in),.zi(phase[31:16]),
+       .xo(bb_i),.yo(bb_q),.zo() );
+`else
+   assign bb_i = i_in;
+   assign bb_q = q_in;
+   assign sample_strobe = 1;
+`endif // !`ifdef RX_NCO_ON
+   
+`ifdef RX_CIC_ON
+   cic_decim cic_decim_i_0
+     ( .clock(clock),.reset(reset),.enable(enable),
+       .rate(decim_rate),.strobe_in(sample_strobe),.strobe_out(decimator_strobe),
+       .signal_in(bb_i),.signal_out(hb_in_i) );
+`else
+   assign hb_in_i = bb_i;
+   assign decimator_strobe = sample_strobe;
+`endif
+   
+`ifdef RX_HB_ON
+   halfband_decim hbd_i_0
+     ( .clock(clock),.reset(reset),.enable(enable),
+       .strobe_in(decimator_strobe),.strobe_out(hb_strobe),
+       .data_in(hb_in_i),.data_out(i_out),.debugctrl(debugctrl) );
+`else
+   assign i_out = hb_in_i;
+   assign hb_strobe = decimator_strobe;
+`endif
+   
+`ifdef RX_CIC_ON
+   cic_decim cic_decim_q_0
+     ( .clock(clock),.reset(reset),.enable(enable),
+       .rate(decim_rate),.strobe_in(sample_strobe),.strobe_out(decimator_strobe),
+       .signal_in(bb_q),.signal_out(hb_in_q) );
+`else
+   assign hb_in_q = bb_q;
+`endif
+
+`ifdef RX_HB_ON
+   halfband_decim hbd_q_0
+     ( .clock(clock),.reset(reset),.enable(enable),
+       .strobe_in(decimator_strobe),.strobe_out(),
+       .data_in(hb_in_q),.data_out(q_out) );   
+`else
+   assign q_out = hb_in_q;
+`endif
+
+
+endmodule // rx_chain
diff --git a/usrp/fpga/sdr_lib/rx_chain_dual.v b/usrp/fpga/sdr_lib/rx_chain_dual.v
new file mode 100644 (file)
index 0000000..6988594
--- /dev/null
@@ -0,0 +1,103 @@
+// -*- verilog -*-
+//
+//  USRP - Universal Software Radio Peripheral
+//
+//  Copyright (C) 2003 Matt Ettus
+//
+//  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
+//
+
+module rx_chain_dual
+  (input clock,
+   input clock_2x,
+   input reset,
+   input enable,
+   input wire [7:0] decim_rate,
+   input sample_strobe,
+   input decimator_strobe,
+   input wire [31:0] freq0,
+   input wire [15:0] i_in0,
+   input wire [15:0] q_in0,
+   output wire [15:0] i_out0,
+   output wire [15:0] q_out0,
+   input wire [31:0] freq1,
+   input wire [15:0] i_in1,
+   input wire [15:0] q_in1,
+   output wire [15:0] i_out1,
+   output wire [15:0] q_out1
+   );
+
+   wire [15:0] phase;
+   wire [15:0] bb_i, bb_q;
+   wire [15:0] i_in, q_in;
+   
+   wire [31:0] phase0;
+   wire [31:0] phase1;
+   reg [15:0] bb_i0, bb_q0;
+   reg [15:0] bb_i1, bb_q1;
+
+   // We want to time-share the CORDIC by double-clocking it
+   
+   phase_acc rx_phase_acc_0
+     (.clk(clock),.reset(reset),.enable(enable),
+      .strobe(sample_strobe),.freq(freq0),.phase(phase0) );
+
+   phase_acc rx_phase_acc_1
+     (.clk(clock),.reset(reset),.enable(enable),
+      .strobe(sample_strobe),.freq(freq1),.phase(phase1) );
+   
+   assign phase = clock ? phase0[31:16] : phase1[31:16];
+   assign i_in = clock ? i_in0 : i_in1;
+   assign q_in = clock ? q_in0 : q_in1;
+
+// This appears reversed because of the number of CORDIC stages
+   always @(posedge clock_2x)
+     if(clock)
+       begin
+         bb_i1 <= #1 bb_i;
+         bb_q1 <= #1 bb_q;
+       end
+     else
+       begin
+         bb_i0 <= #1 bb_i;
+         bb_q0 <= #1 bb_q;
+       end
+       
+   cordic rx_cordic
+     ( .clock(clock_2x),.reset(reset),.enable(enable), 
+       .xi(i_in),.yi(q_in),.zi(phase),
+       .xo(bb_i),.yo(bb_q),.zo() );
+   
+   cic_decim cic_decim_i_0
+     ( .clock(clock),.reset(reset),.enable(enable),
+       .rate(decim_rate),.strobe_in(sample_strobe),.strobe_out(decimator_strobe),
+       .signal_in(bb_i0),.signal_out(i_out0) );
+
+   cic_decim cic_decim_q_0
+     ( .clock(clock),.reset(reset),.enable(enable),
+       .rate(decim_rate),.strobe_in(sample_strobe),.strobe_out(decimator_strobe),
+       .signal_in(bb_q0),.signal_out(q_out0) );
+
+   cic_decim cic_decim_i_1
+     ( .clock(clock),.reset(reset),.enable(enable),
+       .rate(decim_rate),.strobe_in(sample_strobe),.strobe_out(decimator_strobe),
+       .signal_in(bb_i1),.signal_out(i_out1) );
+
+   cic_decim cic_decim_q_1
+     ( .clock(clock),.reset(reset),.enable(enable),
+       .rate(decim_rate),.strobe_in(sample_strobe),.strobe_out(decimator_strobe),
+       .signal_in(bb_q1),.signal_out(q_out1) );
+
+endmodule // rx_chain
diff --git a/usrp/fpga/sdr_lib/rx_dcoffset.v b/usrp/fpga/sdr_lib/rx_dcoffset.v
new file mode 100644 (file)
index 0000000..3be475e
--- /dev/null
@@ -0,0 +1,22 @@
+
+
+module rx_dcoffset (input clock, input enable, input reset, 
+                   input signed [15:0] adc_in, output signed [15:0] adc_out,
+                   input wire [6:0] serial_addr, input wire [31:0] serial_data, input serial_strobe);
+   parameter             MYADDR = 0;
+   
+   reg signed [31:0]            integrator;
+   wire signed [15:0]           scaled_integrator = integrator[31:16] + (integrator[31] & |integrator[15:0]);
+   assign                       adc_out = adc_in - scaled_integrator;
+
+   // FIXME do we need signed?
+   //FIXME  What do we do when clipping?
+   always @(posedge clock)
+     if(reset)
+       integrator <= #1 32'd0;
+     else if(serial_strobe & (MYADDR == serial_addr))
+       integrator <= #1 {serial_data[15:0],16'd0};
+     else if(enable)
+       integrator <= #1 integrator + adc_out;
+
+endmodule // rx_dcoffset
diff --git a/usrp/fpga/sdr_lib/serial_io.v b/usrp/fpga/sdr_lib/serial_io.v
new file mode 100644 (file)
index 0000000..1fe43c9
--- /dev/null
@@ -0,0 +1,118 @@
+// -*- verilog -*-
+//
+//  USRP - Universal Software Radio Peripheral
+//
+//  Copyright (C) 2003,2004 Matt Ettus
+//
+//  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
+//
+
+
+
+// Serial Control Bus from Cypress chip
+
+module serial_io
+  ( input master_clk,
+    input serial_clock,
+    input serial_data_in,
+    input enable,
+    input reset,
+    inout wire serial_data_out,
+    output reg [6:0] serial_addr,
+    output reg [31:0] serial_data,
+    output wire serial_strobe,
+    input wire [31:0] readback_0,
+    input wire [31:0] readback_1,
+    input wire [31:0] readback_2,
+    input wire [31:0] readback_3,
+    input wire [31:0] readback_4,
+    input wire [31:0] readback_5,
+    input wire [31:0] readback_6,
+    input wire [31:0] readback_7
+    );
+       
+   reg               is_read;
+   reg [7:0]  ser_ctr;
+   reg               write_done;
+
+   assign serial_data_out = is_read ? serial_data[31] : 1'bz;
+
+   always @(posedge serial_clock, posedge reset, negedge enable)
+     if(reset)
+       ser_ctr <= #1 8'd0;
+     else if(~enable)
+       ser_ctr <= #1 8'd0;
+     else if(ser_ctr == 39)
+       ser_ctr <= #1 8'd0;
+     else
+       ser_ctr <= #1 ser_ctr + 8'd1;
+
+   always @(posedge serial_clock, posedge reset, negedge enable)
+     if(reset)
+       is_read <= #1 1'b0;
+     else if(~enable)
+       is_read <= #1 1'b0;
+     else if((ser_ctr == 7)&&(serial_addr[6]==1))
+       is_read <= #1 1'b1;
+   
+   always @(posedge serial_clock, posedge reset)
+     if(reset)
+       begin
+         serial_addr <= #1 7'b0;
+         serial_data <= #1 32'b0;
+         write_done <= #1 1'b0;
+       end
+     else if(~enable)
+       begin
+         //serial_addr <= #1 7'b0;
+         //serial_data <= #1 32'b0;
+         write_done <= #1 1'b0;
+       end
+     else 
+       begin
+         if(~is_read && (ser_ctr == 39))
+           write_done <= #1 1'b1;
+         else
+           write_done <= #1 1'b0;
+         if(is_read & (ser_ctr==8))
+           case (serial_addr)
+             7'd1: serial_data <= #1 readback_0;
+             7'd2: serial_data <= #1 readback_1;
+             7'd3: serial_data <= #1 readback_2;
+             7'd4: serial_data <= #1 readback_3;
+             7'd5: serial_data <= #1 readback_4;
+             7'd6: serial_data <= #1 readback_5;
+             7'd7: serial_data <= #1 readback_6;
+             7'd8: serial_data <= #1 readback_7;
+             default: serial_data <= #1 32'd0;
+           endcase // case(serial_addr)
+         else if(ser_ctr >= 8)
+           serial_data <= #1 {serial_data[30:0],serial_data_in};
+         else if(ser_ctr < 8)
+           serial_addr <= #1 {serial_addr[5:0],serial_data_in};
+       end // else: !if(~enable)
+
+   reg enable_d1, enable_d2;
+   always @(posedge master_clk)
+     begin
+       enable_d1 <= #1 enable;
+       enable_d2 <= #1 enable_d1;
+     end
+
+   assign serial_strobe = enable_d2 & ~enable_d1;
+   
+endmodule // serial_io
+
+
diff --git a/usrp/fpga/sdr_lib/setting_reg.v b/usrp/fpga/sdr_lib/setting_reg.v
new file mode 100644 (file)
index 0000000..3d31a9e
--- /dev/null
@@ -0,0 +1,23 @@
+
+
+module setting_reg
+  ( input clock, input reset, input strobe, input wire [6:0] addr,
+    input wire [31:0] in, output reg [31:0] out, output reg changed);
+   parameter my_addr = 0;
+   
+   always @(posedge clock)
+     if(reset)
+       begin
+         out <= #1 32'd0;
+         changed <= #1 1'b0;
+       end
+     else
+       if(strobe & (my_addr==addr))
+        begin
+           out <= #1 in;
+           changed <= #1 1'b1;
+        end
+       else
+        changed <= #1 1'b0;
+   
+endmodule // setting_reg
diff --git a/usrp/fpga/sdr_lib/setting_reg_masked.v b/usrp/fpga/sdr_lib/setting_reg_masked.v
new file mode 100644 (file)
index 0000000..72f7e21
--- /dev/null
@@ -0,0 +1,26 @@
+
+
+module setting_reg_masked
+  ( input clock, input reset, input strobe, input wire [6:0] addr,
+    input wire [31:0] in, output reg [31:0] out, output reg changed);
+/* upper 16 bits are mask, lower 16 bits are value 
+ * Note that you get a 16 bit register, not a 32 bit one */
+
+   parameter my_addr = 0;
+   
+   always @(posedge clock)
+     if(reset)
+       begin
+         out <= #1 32'd0;
+         changed <= #1 1'b0;
+       end
+     else
+       if(strobe & (my_addr==addr))
+        begin
+           out <= #1 (out & ~in[31:16]) | (in[15:0] & in[31:16] );
+           changed <= #1 1'b1;
+        end
+       else
+        changed <= #1 1'b0;
+   
+endmodule // setting_reg_masked
diff --git a/usrp/fpga/sdr_lib/sign_extend.v b/usrp/fpga/sdr_lib/sign_extend.v
new file mode 100644 (file)
index 0000000..2417909
--- /dev/null
@@ -0,0 +1,35 @@
+// -*- verilog -*-
+//
+//  USRP - Universal Software Radio Peripheral
+//
+//  Copyright (C) 2003 Matt Ettus
+//
+//  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
+//
+
+
+// Sign extension "macro"
+// bits_out should be greater than bits_in
+
+module sign_extend (in,out);
+       parameter bits_in=0;  // FIXME Quartus insists on a default
+       parameter bits_out=0;
+       
+       input [bits_in-1:0] in;
+       output [bits_out-1:0] out;
+       
+       assign out = {{(bits_out-bits_in){in[bits_in-1]}},in};
+       
+endmodule
diff --git a/usrp/fpga/sdr_lib/strobe_gen.v b/usrp/fpga/sdr_lib/strobe_gen.v
new file mode 100644 (file)
index 0000000..0511b6a
--- /dev/null
@@ -0,0 +1,44 @@
+// -*- verilog -*-
+//
+//  USRP - Universal Software Radio Peripheral
+//
+//  Copyright (C) 2003 Matt Ettus
+//
+//  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
+//
+
+module strobe_gen 
+  ( input clock,
+    input reset,
+    input enable,
+    input [7:0] rate,
+    input strobe_in,
+    output wire strobe );
+   
+//   parameter width = 8;
+   
+   reg [7:0] counter;
+   assign strobe = ~|counter && enable && strobe_in;
+   
+   always @(posedge clock)
+     if(reset | ~enable)
+       counter <= #1 8'd0;
+     else if(strobe_in)
+       if(counter == 0)
+        counter <= #1 rate;
+       else 
+        counter <= #1 counter - 8'd1;
+   
+endmodule // strobe_gen
diff --git a/usrp/fpga/sdr_lib/tx_buffer.v b/usrp/fpga/sdr_lib/tx_buffer.v
new file mode 100644 (file)
index 0000000..cae6607
--- /dev/null
@@ -0,0 +1,138 @@
+// -*- verilog -*-
+//
+//  USRP - Universal Software Radio Peripheral
+//
+//  Copyright (C) 2003 Matt Ettus
+//
+//  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
+//
+
+// Interface to Cypress FX2 bus
+// A packet is 512 Bytes.  Each fifo line is 2 bytes
+// Fifo has 1024 or 2048 lines
+
+module tx_buffer
+  ( input usbclk,
+    input bus_reset,  // Used here for the 257-Hack to fix the FX2 bug
+    input reset,  // standard DSP-side reset
+    input [15:0] usbdata,
+    input wire WR,
+    output wire have_space,
+    output reg tx_underrun,
+    input wire [3:0] channels,
+    output reg [15:0] tx_i_0,
+    output reg [15:0] tx_q_0,
+    output reg [15:0] tx_i_1,
+    output reg [15:0] tx_q_1,
+    output reg [15:0] tx_i_2,
+    output reg [15:0] tx_q_2,
+    output reg [15:0] tx_i_3,
+    output reg [15:0] tx_q_3,
+    input txclk,
+    input txstrobe,
+    input clear_status,
+    output wire tx_empty,
+    output [11:0] debugbus
+    );
+   
+   wire [11:0] txfifolevel;
+   reg [8:0] write_count;
+   wire tx_full;
+   wire [15:0] fifodata;
+   wire rdreq;
+
+   reg [3:0] load_next;
+
+   // DAC Side of FIFO
+   assign    rdreq = ((load_next != channels) & !tx_empty);
+   
+   always @(posedge txclk)
+     if(reset)
+       begin
+         {tx_i_0,tx_q_0,tx_i_1,tx_q_1,tx_i_2,tx_q_2,tx_i_3,tx_q_3}
+           <= #1 128'h0;
+         load_next <= #1 4'd0;
+       end
+     else
+       if((load_next != channels) & !tx_empty)
+        begin
+           load_next <= #1 load_next + 4'd1;
+           case(load_next)
+             4'd0 : tx_i_0 <= #1 fifodata;
+             4'd1 : tx_q_0 <= #1 fifodata;
+             4'd2 : tx_i_1 <= #1 fifodata;
+             4'd3 : tx_q_1 <= #1 fifodata;
+             4'd4 : tx_i_2 <= #1 fifodata;
+             4'd5 : tx_q_2 <= #1 fifodata;
+             4'd6 : tx_i_3 <= #1 fifodata;
+             4'd7 : tx_q_3 <= #1 fifodata;
+           endcase // case(load_next)
+        end // if ((load_next != channels) & !tx_empty)
+       else if(txstrobe & (load_next == channels))
+        begin
+           load_next <= #1 4'd0;
+        end
+
+   // USB Side of FIFO
+   assign have_space = (txfifolevel <= (4095-256));
+
+   always @(posedge usbclk)
+     if(bus_reset)        // Use bus reset because this is on usbclk
+       write_count <= #1 0;
+     else if(WR & ~write_count[8])
+       write_count <= #1 write_count + 9'd1;
+     else
+       write_count <= #1 WR ? write_count : 9'b0;
+
+   // Detect Underruns
+   always @(posedge txclk)
+     if(reset)
+       tx_underrun <= 1'b0;
+     else if(txstrobe & (load_next != channels))
+       tx_underrun <= 1'b1;
+     else if(clear_status)
+       tx_underrun <= 1'b0;
+
+   // FIFO
+   fifo_4k txfifo 
+     ( .data ( usbdata ),
+       .wrreq ( WR & ~write_count[8] ),
+       .wrclk ( usbclk ),
+       
+       .q ( fifodata ),                        
+       .rdreq ( rdreq ),
+       .rdclk ( txclk ),
+       
+       .aclr ( reset ),  // asynch, so we can use either
+       
+       .rdempty ( tx_empty ),
+       .rdusedw (  ),
+       .wrfull ( tx_full ),
+       .wrusedw ( txfifolevel )
+       );
+   
+   // Debugging Aids
+   assign debugbus[0] = WR;
+   assign debugbus[1] = have_space;
+   assign debugbus[2] = tx_empty;
+   assign debugbus[3] = tx_full;
+   assign debugbus[4] = tx_underrun;
+   assign debugbus[5] = write_count[8];
+   assign debugbus[6] = txstrobe;
+   assign debugbus[7] = rdreq;
+   assign debugbus[11:8] = load_next;
+   
+endmodule // tx_buffer
+
diff --git a/usrp/fpga/sdr_lib/tx_chain.v b/usrp/fpga/sdr_lib/tx_chain.v
new file mode 100644 (file)
index 0000000..8f0a17a
--- /dev/null
@@ -0,0 +1,65 @@
+// -*- verilog -*-
+//
+//  USRP - Universal Software Radio Peripheral
+//
+//  Copyright (C) 2003 Matt Ettus
+//
+//  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
+//
+
+module tx_chain
+  (input clock,
+   input reset,
+   input enable,
+   input wire [7:0] interp_rate,
+   input sample_strobe,
+   input interpolator_strobe,
+   input wire [31:0] freq,
+   input wire [15:0] i_in,
+   input wire [15:0] q_in,
+   output wire [15:0] i_out,
+   output wire [15:0] q_out
+   );
+
+   wire [15:0] bb_i, bb_q;
+
+   cic_interp cic_interp_i
+     ( .clock(clock),.reset(reset),.enable(enable),
+       .rate(interp_rate),.strobe_in(interpolator_strobe),.strobe_out(sample_strobe),
+       .signal_in(i_in),.signal_out(bb_i) );
+
+   cic_interp cic_interp_q
+     ( .clock(clock),.reset(reset),.enable(enable),
+       .rate(interp_rate),.strobe_in(interpolator_strobe),.strobe_out(sample_strobe),
+       .signal_in(q_in),.signal_out(bb_q) );
+   
+`define NOCORDIC_TX
+`ifdef NOCORDIC_TX
+   assign      i_out = bb_i;
+   assign      q_out = bb_q;
+`else
+   wire [31:0] phase;
+
+   phase_acc phase_acc_tx
+     (.clk(clock),.reset(reset),.enable(enable),
+      .strobe(sample_strobe),.freq(freq),.phase(phase) );
+   
+   cordic tx_cordic_0
+     ( .clock(clock),.reset(reset),.enable(sample_strobe), 
+       .xi(bb_i),.yi(bb_q),.zi(phase[31:16]),
+       .xo(i_out),.yo(q_out),.zo() );
+`endif
+
+endmodule // tx_chain
diff --git a/usrp/fpga/sdr_lib/tx_chain_hb.v b/usrp/fpga/sdr_lib/tx_chain_hb.v
new file mode 100644 (file)
index 0000000..6cbe29c
--- /dev/null
@@ -0,0 +1,76 @@
+// -*- verilog -*-
+//
+//  USRP - Universal Software Radio Peripheral
+//
+//  Copyright (C) 2003 Matt Ettus
+//
+//  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
+//
+
+module tx_chain_hb
+  (input clock,
+   input reset,
+   input enable,
+   input wire [7:0] interp_rate,
+   input sample_strobe,
+   input interpolator_strobe,
+   input hb_strobe,
+   input wire [31:0] freq,
+   input wire [15:0] i_in,
+   input wire [15:0] q_in,
+   output wire [15:0] i_out,
+   output wire [15:0] q_out,
+output wire [15:0] debug, output [15:0] hb_i_out
+   );
+assign debug[15:13] = {sample_strobe,hb_strobe,interpolator_strobe};
+
+   wire [15:0] bb_i, bb_q;
+   wire [15:0] hb_i_out, hb_q_out;
+   
+   halfband_interp hb
+     (.clock(clock),.reset(reset),.enable(enable),
+      .strobe_in(interpolator_strobe),.strobe_out(hb_strobe),
+      .signal_in_i(i_in),.signal_in_q(q_in),
+      .signal_out_i(hb_i_out),.signal_out_q(hb_q_out),
+       .debug(debug[12:0]));
+      
+   cic_interp cic_interp_i
+     ( .clock(clock),.reset(reset),.enable(enable),
+       .rate(interp_rate),.strobe_in(hb_strobe),.strobe_out(sample_strobe),
+       .signal_in(hb_i_out),.signal_out(bb_i) );
+
+   cic_interp cic_interp_q
+     ( .clock(clock),.reset(reset),.enable(enable),
+       .rate(interp_rate),.strobe_in(hb_strobe),.strobe_out(sample_strobe),
+       .signal_in(hb_q_out),.signal_out(bb_q) );
+   
+`define NOCORDIC_TX
+`ifdef NOCORDIC_TX
+   assign      i_out = bb_i;
+   assign      q_out = bb_q;
+`else
+   wire [31:0] phase;
+
+   phase_acc phase_acc_tx
+     (.clk(clock),.reset(reset),.enable(enable),
+      .strobe(sample_strobe),.freq(freq),.phase(phase) );
+   
+   cordic tx_cordic_0
+     ( .clock(clock),.reset(reset),.enable(sample_strobe), 
+       .xi(bb_i),.yi(bb_q),.zi(phase[31:16]),
+       .xo(i_out),.yo(q_out),.zo() );
+`endif
+
+endmodule // tx_chain
diff --git a/usrp/fpga/tb/cbus_tb.v b/usrp/fpga/tb/cbus_tb.v
new file mode 100644 (file)
index 0000000..53cc127
--- /dev/null
@@ -0,0 +1,71 @@
+module cbus_tb;
+
+`define ch1in_freq 0
+`define ch2in_freq 1
+`define ch3in_freq 2
+`define ch4in_freq 3
+`define ch1out_freq 4
+`define ch2out_freq 5
+`define ch3out_freq 6
+`define ch4out_freq 7
+`define rates 8
+`define misc 9
+  
+   task send_config_word;
+      input [7:0] addr;
+      input [31:0] data;
+      integer i;
+      
+      begin
+        #10 serenable = 1;
+        for(i=7;i>=0;i=i-1)
+          begin
+             #10 serdata = addr[i];
+             #10 serclk = 0;
+             #10 serclk = 1;
+             #10 serclk = 0;
+          end
+        for(i=31;i>=0;i=i-1)
+          begin
+             #10 serdata = data[i];
+             #10 serclk = 0;
+             #10 serclk = 1;
+             #10 serclk = 0;
+          end
+        #10 serenable = 0;
+        // #10 serclk = 1;
+        // #10 serclk = 0;
+      end
+   endtask // send_config_word
+   
+   initial $dumpfile("cbus_tb.vcd");
+   initial $dumpvars(0,cbus_tb);
+
+   initial reset = 1;
+   initial #500 reset = 0;
+      
+   reg serclk, serdata, serenable, reset;
+   wire SDO;
+   
+  control_bus control_bus
+    ( .serial_clock(serclk),
+      .serial_data_in(serdata),
+      .enable(serenable),
+      .reset(reset),
+      .serial_data_out(SDO) );
+
+
+   initial 
+     begin
+       #1000 send_config_word(8'd1,32'hDEAD_BEEF);
+       #1000 send_config_word(8'd3,32'hDDEE_FF01);
+       #1000 send_config_word(8'd19,32'hFFFF_FFFF);
+       #1000 send_config_word(8'd23,32'h1234_FEDC);
+       #1000 send_config_word(8'h80,32'h0);
+       #1000 send_config_word(8'h81,32'h0);
+       #1000 send_config_word(8'h82,32'h0);
+       #1000 reset = 1;
+       #1 $finish;
+     end
+   
+endmodule // cbus_tb
diff --git a/usrp/fpga/tb/cordic_tb.v b/usrp/fpga/tb/cordic_tb.v
new file mode 100644 (file)
index 0000000..ed85b37
--- /dev/null
@@ -0,0 +1,61 @@
+// -*- verilog -*-
+//
+//  USRP - Universal Software Radio Peripheral
+//
+//  Copyright (C) 2003 Matt Ettus
+//
+//  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
+//
+
+
+
+module cordic_tb();
+
+   cordic cordic(clk, reset, enable, xi, yi, zi, xo, yo, zo );
+
+   reg reset;
+   reg clk;
+   reg enable;
+   reg [15:0] xi, yi, zi;
+   
+   initial reset = 1'b1;
+   initial #1000 reset = 1'b0;
+
+   initial clk = 1'b0;
+   always #50 clk <= ~clk;
+   
+   initial enable = 1'b1;
+
+   initial zi = 16'b0;
+
+   always @(posedge clk)
+     zi <= #1 zi + 16'd0;
+   
+   wire [15:0] xo,yo,zo;
+
+   initial $dumpfile("cordic.vcd");
+  initial $dumpvars(0,cordic_tb);
+   initial
+     begin
+`include "sine.txt"
+     end
+
+       wire [15:0] xiu = {~xi[15],xi[14:0]};
+       wire [15:0] yiu = {~yi[15],yi[14:0]};
+       wire [15:0] xou = {~xo[15],xo[14:0]};
+       wire [15:0] you = {~yo[15],yo[14:0]};
+   initial $monitor("%d\t%d\t%d\t%d\t%d",$time,xiu,yiu,xou,you);
+
+endmodule // cordic_tb
diff --git a/usrp/fpga/tb/decim_tb.v b/usrp/fpga/tb/decim_tb.v
new file mode 100644 (file)
index 0000000..ecf20cf
--- /dev/null
@@ -0,0 +1,108 @@
+// -*- verilog -*-
+//
+//  USRP - Universal Software Radio Peripheral
+//
+//  Copyright (C) 2003 Matt Ettus
+//
+//  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
+//
+
+
+// testbench for fullchip
+
+module decim_tb();
+
+`include "usrp_tasks.v"
+   
+       reg clk_120mhz;
+       reg usbclk;
+       reg reset;
+
+       reg [11:0] adc1_data, adc2_data;
+       wire [13:0] dac1_data, dac2_data;
+
+       wire [5:0] usbctl;
+       wire [5:0] usbrdy;
+
+       wire [15:0] usbdata;
+
+       reg WE, RD, OE;
+
+        assign usbctl[0] = WE;
+        assign usbctl[1] = RD;
+        assign usbctl[2] = OE;
+       assign usbctl[5:3] = 0;
+
+       reg tb_oe;
+       assign usbdata = tb_oe ? usbdatareg : 16'hxxxx;
+       reg serload, serenable, serclk, serdata;
+       reg enable_tx, enable_rx;
+       reg [15:0] usbdatareg;
+
+///////////////////////////////////////////////
+//  Simulation Control
+initial
+begin
+       $dumpfile("decim_tb.vcd");
+       $dumpvars(0, fc_tb);
+end
+
+initial #100000 $finish;
+
+///////////////////////////////////////////////
+//  Monitors
+
+reg [7:0] counter_decim;
+wire [7:0] decim_rate;
+assign decim_rate = 32;
+initial $monitor(dac1_data);
+
+       always @(posedge clk_120mhz)
+        begin
+                if(reset | ~enable_tx)
+                        counter_decim <= #1 0;
+                else if(counter_decim == 0)
+                        counter_decim <= #1 decim_rate - 8'b1;
+                else
+                        counter_decim <= #1 counter_decim - 8'b1;
+        end
+
+///////////////////////////////////////////////
+// Clock and reset
+
+initial clk_120mhz = 0;
+initial usbclk = 0;
+always #48 clk_120mhz = ~clk_120mhz;
+always #120 usbclk = ~usbclk;
+
+initial reset = 1'b1;
+initial #500 reset = 1'b0;
+
+
+initial enable_tx = 1'b1;
+
+       wire [31:0] decim_out, q_decim_out;
+       wire [31:0] decim_out;
+       wire [31:0] phase;
+                       
+       cic_decim #(.bitwidth(32),.stages(4)) 
+               decim_i(.clock(clk_120mhz),.reset(reset),.enable(enable_tx),
+                       .strobe(counter_decim == 8'b0),.signal_in(32'h1),.signal_out(decim_out));
+
+       cic_decim #(.bitwidth(32),.stages(4)) 
+               decim(.clock(clk_120mhz),.reset(reset),.enable(enable_tx),
+                       .strobe(counter_decim == 8'b0),.signal_in(32'h1),.signal_out(decim_out));
+                       
+endmodule
diff --git a/usrp/fpga/tb/fullchip_tb.v b/usrp/fpga/tb/fullchip_tb.v
new file mode 100755 (executable)
index 0000000..c446ff0
--- /dev/null
@@ -0,0 +1,174 @@
+// -*- verilog -*-
+//
+//  USRP - Universal Software Radio Peripheral
+//
+//  Copyright (C) 2003 Matt Ettus
+//
+//  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
+//
+
+
+// testbench for fullchip
+
+`timescale 1ns/1ns
+
+module fullchip_tb();
+
+`include "usrp_tasks.v"
+
+fullchip fullchip
+  (
+   .clk_120mhz(clk_120mhz),
+   .reset(reset),
+   .enable_rx(enable_rx),
+   .enable_tx(enable_tx),
+   .SLD(serload),
+   .SEN(serenable),
+   .clear_status(),
+   .SDI(serdata),
+   .SCLK(serclk),
+         
+   .adc1_data(adc1_data),
+   .adc2_data(adc2_data),
+   .adc3_data(adc1_data),
+   .adc4_data(adc2_data),
+   
+   .dac1_data(dac1_data),
+   .dac2_data(dac2_data),
+   .dac3_data(),.dac4_data(),
+   
+   .adclk0(adclk),.adclk1(),
+   
+   .adc_oeb(),.adc_otr(4'b0),
+   
+   .clk_out(clk_out),
+   
+   .misc_pins(),
+   
+   // USB interface
+   .usbclk(usbclk),.usbctl(usbctl),
+   .usbrdy(usbrdy),.usbdata(usbdata)
+   );  
+       
+       reg clk_120mhz;
+       reg usbclk;
+       reg reset;
+
+       reg [11:0] adc1_data, adc2_data;
+       wire [13:0] dac1_data, dac2_data;
+
+       wire [5:0] usbctl;
+       wire [5:0] usbrdy;
+
+       wire [15:0] usbdata;
+
+       reg WE, RD, OE;
+
+        assign usbctl[0] = WE;
+        assign usbctl[1] = RD;
+        assign usbctl[2] = OE;
+       assign usbctl[5:3] = 0;
+
+        wire have_packet_rdy = usbrdy[1];
+   
+       reg tb_oe;
+   initial tb_oe=1'b1;
+   
+       assign usbdata = tb_oe ? usbdatareg : 16'hxxxx;
+       reg serload, serenable, serclk, serdata;
+       reg enable_tx, enable_rx;
+       reg [15:0] usbdatareg;
+
+///////////////////////////////////////////////
+//  Simulation Control
+initial
+begin
+       $dumpfile("fullchip_tb.vcd");
+       $dumpvars(0, fullchip_tb);
+end
+
+//initial #1000000 $finish;
+
+///////////////////////////////////////////////
+//  Monitors
+
+//initial $monitor(dac1_data);
+
+///////////////////////////////////////////////
+// Clock and reset
+
+initial clk_120mhz = 0;
+initial usbclk = 0;
+always #24 clk_120mhz = ~clk_120mhz;
+always #60 usbclk = ~usbclk;
+
+initial reset = 1'b1;
+initial #500 reset = 1'b0;
+
+/////////////////////////////////////////////////
+// Run AD input
+
+always @(posedge adclk)         adc1_data <= #1 12'd1234;
+always @(posedge adclk)         adc2_data <= #1 12'd1234;
+
+/////////////////////////////////////////////////
+// USB interface
+
+  initial 
+    begin
+       initialize_usb;
+       #30000 @(posedge usbclk);
+       burst_usb_write(257);
+       
+       #30000 burst_usb_read(256);
+       #10000 $finish;
+   
+//     repeat(30)
+//     begin
+//             write_from_usb;
+//             read_from_usb;
+//     end
+end
+
+/////////////////////////////////////////////////
+// TX and RX enable
+
+initial enable_tx = 1'b0;
+initial #40000 enable_tx = 1'b1;
+initial enable_rx = 1'b0;
+initial #40000 enable_rx = 1'b1;
+
+//////////////////////////////////////////////////
+// Set up control bus
+
+initial 
+begin
+       #1000 send_config_word(`ch1in_freq,32'h0); // 1 MHz on 60 MHz clock
+       send_config_word(`ch2in_freq,32'h0);
+       send_config_word(`ch3in_freq,32'h0);
+       send_config_word(`ch4in_freq,32'h0);
+       send_config_word(`ch1out_freq,32'h01234567);
+       send_config_word(`ch2out_freq,32'h0);
+       send_config_word(`ch3out_freq,32'h0);
+       send_config_word(`ch4out_freq,32'h0);
+       send_config_word(`misc,32'h0);
+       send_config_word(`rates,{8'd2,8'd12,8'h0f,8'h07});
+       // adc, ext, interp, decim
+end
+
+/////////////////////////////////////////////////////////
+
+endmodule
+
diff --git a/usrp/fpga/tb/interp_tb.v b/usrp/fpga/tb/interp_tb.v
new file mode 100755 (executable)
index 0000000..8a8e89f
--- /dev/null
@@ -0,0 +1,108 @@
+// -*- verilog -*-
+//
+//  USRP - Universal Software Radio Peripheral
+//
+//  Copyright (C) 2003 Matt Ettus
+//
+//  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
+//
+
+
+// testbench for fullchip
+
+module interp_tb();
+
+`include "usrp_tasks.v"
+   
+       reg clk_120mhz;
+       reg usbclk;
+       reg reset;
+
+       reg [11:0] adc1_data, adc2_data;
+       wire [13:0] dac1_data, dac2_data;
+
+       wire [5:0] usbctl;
+       wire [5:0] usbrdy;
+
+       wire [15:0] usbdata;
+
+       reg WE, RD, OE;
+
+        assign usbctl[0] = WE;
+        assign usbctl[1] = RD;
+        assign usbctl[2] = OE;
+       assign usbctl[5:3] = 0;
+
+       reg tb_oe;
+       assign usbdata = tb_oe ? usbdatareg : 16'hxxxx;
+       reg serload, serenable, serclk, serdata;
+       reg enable_tx, enable_rx;
+       reg [15:0] usbdatareg;
+
+///////////////////////////////////////////////
+//  Simulation Control
+initial
+begin
+       $dumpfile("interp_tb.vcd");
+       $dumpvars(0, fc_tb);
+end
+
+initial #100000 $finish;
+
+///////////////////////////////////////////////
+//  Monitors
+
+reg [7:0] counter_interp;
+wire [7:0] interp_rate;
+assign interp_rate = 32;
+initial $monitor(dac1_data);
+
+       always @(posedge clk_120mhz)
+        begin
+                if(reset | ~enable_tx)
+                        counter_interp <= #1 0;
+                else if(counter_interp == 0)
+                        counter_interp <= #1 interp_rate - 8'b1;
+                else
+                        counter_interp <= #1 counter_interp - 8'b1;
+        end
+
+///////////////////////////////////////////////
+// Clock and reset
+
+initial clk_120mhz = 0;
+initial usbclk = 0;
+always #48 clk_120mhz = ~clk_120mhz;
+always #120 usbclk = ~usbclk;
+
+initial reset = 1'b1;
+initial #500 reset = 1'b0;
+
+
+initial enable_tx = 1'b1;
+
+       wire [31:0] interp_out, q_interp_out;
+       wire [31:0] decim_out;
+       wire [31:0] phase;
+                       
+       cic_interp #(.bitwidth(32),.stages(4)) 
+               interp_i(.clock(clk_120mhz),.reset(reset),.enable(enable_tx),
+                       .strobe(counter_interp == 8'b0),.signal_in(32'h1),.signal_out(interp_out));
+
+       cic_decim #(.bitwidth(32),.stages(4)) 
+               decim(.clock(clk_120mhz),.reset(reset),.enable(enable_tx),
+                       .strobe(counter_interp == 8'b0),.signal_in(32'h1),.signal_out(decim_out));
+                       
+endmodule
diff --git a/usrp/fpga/tb/justinterp_tb.v b/usrp/fpga/tb/justinterp_tb.v
new file mode 100644 (file)
index 0000000..ffbd0f1
--- /dev/null
@@ -0,0 +1,73 @@
+// -*- verilog -*-
+//
+//  USRP - Universal Software Radio Peripheral
+//
+//  Copyright (C) 2003 Matt Ettus
+//
+//  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
+//
+
+
+module cic_decim_tb;
+
+cic_decim #(.bitwidth(16),.stages(4))
+   decim(clock,reset,enable,strobe_in,strobe_out,signal_in,signal_out);
+       
+   reg clock;
+   reg reset;
+   reg enable;
+   wire strobe;
+   reg [15:0] signal_in;
+   wire [15:0] signal_out;
+
+   assign      strobe_in = 1'b1;
+   reg                strobe_out;
+
+   always @(posedge clock)
+     while(1)
+       begin
+         @(posedge clock);
+         @(posedge clock);
+         @(posedge clock);
+         @(posedge clock);
+         strobe_out <= 1'b1;
+         @(posedge clock);
+         @(posedge clock);
+         @(posedge clock);
+         @(posedge clock);
+         strobe_out <= 1'b0;
+       end
+   
+   initial clock = 0;
+   always #50 clock = ~clock;
+   
+   initial reset = 1;
+   initial #1000 reset = 0;
+
+   initial enable = 0;
+   initial #2000 enable = 1;
+   
+   initial signal_in = 16'h1;
+   initial #500000 signal_in = 16'h7fff;
+   initial #1000000 signal_in = 16'h8000;
+   initial #1500000 signal_in = 16'hffff;
+
+   
+   initial $dumpfile("decim.vcd");
+   initial $dumpvars(0,cic_decim_tb);
+
+   initial #10000000 $finish;
+   
+endmodule // cic_decim_tb
diff --git a/usrp/fpga/tb/makesine.pl b/usrp/fpga/tb/makesine.pl
new file mode 100755 (executable)
index 0000000..9aebd69
--- /dev/null
@@ -0,0 +1,14 @@
+#!/usr/bin/perl
+
+$angle = 0;
+$angle_inc = 2*3.14159/87.2;
+$amp = 1;
+$amp_rate = 1.0035;
+for($i=0;$i<3500;$i++)
+  {
+    printf("@(posedge clk);xi<= #1 16'h%x;yi<= #1 16'h%x;\n",65535&int($amp*cos($angle)),65535&int($amp*sin($angle)));
+    $angle += $angle_inc;
+    $amp *= $amp_rate;
+  }
+
+printf("\$finish;\n");
diff --git a/usrp/fpga/tb/run_cordic b/usrp/fpga/tb/run_cordic
new file mode 100755 (executable)
index 0000000..68144fc
--- /dev/null
@@ -0,0 +1,4 @@
+#!/bin/sh
+
+iverilog -y ../sdr_lib -o cordic_tb cordic_tb.v
+
diff --git a/usrp/fpga/tb/run_fullchip b/usrp/fpga/tb/run_fullchip
new file mode 100755 (executable)
index 0000000..eb81d7f
--- /dev/null
@@ -0,0 +1,4 @@
+#!/bin/sh
+
+iverilog -y ../toplevel/fullchip -y ../sdr_lib -y ../models -y . -o fullchip_tb fullchip_tb.v
+
diff --git a/usrp/fpga/tb/usrp_tasks.v b/usrp/fpga/tb/usrp_tasks.v
new file mode 100755 (executable)
index 0000000..00f82b9
--- /dev/null
@@ -0,0 +1,145 @@
+// -*- verilog -*-
+//
+//  USRP - Universal Software Radio Peripheral
+//
+//  Copyright (C) 2003 Matt Ettus
+//
+//  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
+//
+
+// Tasks
+
+/////////////////////////////////////////////////
+// USB interface
+
+task initialize_usb;
+begin
+       OE = 0;WE = 0;RD = 0;
+       usbdatareg <= 16'h0;
+end
+endtask
+
+task write_from_usb;
+begin
+       tb_oe <= 1'b1;
+       @(posedge usbclk);
+       usbdatareg <= #1 $random % 65536;
+       WE <= #1 1'b1;
+       @(posedge usbclk)
+       WE <= #1 1'b0;
+       tb_oe <= #1 1'b0;
+end
+endtask
+
+task burst_usb_write;
+      input [31:0] repeat_count;
+      
+      begin
+        tb_oe <= 1'b1;
+        repeat(repeat_count)
+          begin
+             @(posedge usbclk)
+               usbdatareg <= #1 usbdatareg + 1;              //$random % 65536;
+             WE <= #1 1'b1;
+          end
+        @(posedge usbclk)
+          WE <= #1 1'b0;
+        tb_oe <= 1'b0;
+      end
+endtask // burst_usb_write
+
+
+task read_from_usb;
+begin
+       @(posedge usbclk);
+       RD <= #1 1'b1;
+       @(posedge usbclk);
+       RD <= #1 1'b0;
+       OE <= #1 1'b1;
+       @(posedge usbclk);
+       OE <= #1 1'b0;
+end
+endtask
+
+task burst_usb_read;
+      input [31:0] repeat_count;
+      begin
+        while (~have_packet_rdy) begin
+           @(posedge usbclk);
+        end
+        
+        @(posedge usbclk)
+          RD <= #1 1'b1;
+        repeat(repeat_count)
+          begin
+             @(posedge usbclk)
+               OE <= #1 1'b1;
+          end
+        RD <= #1 1'b0;
+        @(posedge usbclk);
+        OE <= #1 1'b0;
+      end
+endtask // burst_usb_read
+
+/////////////////////////////////////////////////
+// TX and RX enable
+
+//////////////////////////////////////////////////
+// Set up control bus
+
+`define ch1in_freq 0
+`define ch2in_freq 1
+`define ch3in_freq 2
+`define ch4in_freq 3
+`define ch1out_freq 4
+`define ch2out_freq 5
+`define ch3out_freq 6
+`define ch4out_freq 7
+`define rates 8
+`define misc 9
+  
+  task send_config_word;
+      input [7:0] addr;
+      input [31:0] data;
+      integer i;
+      
+      begin
+        #10 serenable = 1;
+        for(i=7;i>=0;i=i-1)
+          begin
+             #10 serdata = addr[i];
+             #10 serclk = 0;
+             #10 serclk = 1;
+             #10 serclk = 0;
+          end
+        for(i=31;i>=0;i=i-1)
+          begin
+             #10 serdata = data[i];
+             #10 serclk = 0;
+             #10 serclk = 1;
+             #10 serclk = 0;
+          end
+        #10 serenable = 0;
+        //     #10 serload = 0;
+        //     #10 serload = 1;
+        #10 serclk = 1;
+        #10 serclk = 0;
+        //#10 serload = 0;
+      end
+  endtask // send_config_word
+
+
+/////////////////////////////////////////////////////////
+
diff --git a/usrp/fpga/toplevel/mrfm/biquad_2stage.v b/usrp/fpga/toplevel/mrfm/biquad_2stage.v
new file mode 100644 (file)
index 0000000..9b76901
--- /dev/null
@@ -0,0 +1,131 @@
+`include "mrfm.vh"
+
+module biquad_2stage (input clock, input reset, input strobe_in,
+                     input serial_strobe, input [6:0] serial_addr, input [31:0] serial_data,
+                     input wire [15:0] sample_in, output reg [15:0] sample_out, output wire [63:0] debugbus);
+
+   wire [3:0]         coeff_addr, coeff_wr_addr;
+   wire [3:0]         data_addr, data_wr_addr;
+   reg [3:0]          cur_offset, data_addr_int, data_wr_addr_int;
+   
+   wire [15:0]                coeff, coeff_wr_data, data, data_wr_data;
+   wire               coeff_wr;
+   reg                        data_wr;
+   
+   wire [30:0]                product;
+   wire [33:0]                accum;
+   wire [15:0]                scaled_accum;             
+   
+   wire [7:0]         shift;
+   reg [3:0]          phase;
+   wire               enable_mult, enable_acc, latch_out, select_input;
+   reg                        done, clear_acc;
+   
+   setting_reg #(`FR_MRFM_IIR_COEFF) sr_coeff(.clock(clock),.reset(reset),
+                                             .strobe(serial_strobe),.addr(serial_addr),.in(serial_data),
+                                             .out({coeff_wr_addr,coeff_wr_data}),.changed(coeff_wr));
+   
+   setting_reg #(`FR_MRFM_IIR_SHIFT) sr_shift(.clock(clock),.reset(reset),
+                                             .strobe(serial_strobe),.addr(serial_addr),.in(serial_data),
+                                             .out(shift),.changed());
+   
+   ram16 coeff_ram(.clock(clock),.write(coeff_wr),.wr_addr(coeff_wr_addr),.wr_data(coeff_wr_data),
+                  .rd_addr(coeff_addr),.rd_data(coeff));
+   
+   ram16 data_ram(.clock(clock),.write(data_wr),.wr_addr(data_wr_addr),.wr_data(data_wr_data),
+                 .rd_addr(data_addr),.rd_data(data));
+   
+   mult mult (.clock(clock),.x(data),.y(coeff),.product(product),.enable_in(enable_mult),.enable_out() );
+   
+   acc acc (.clock(clock),.reset(reset),.clear(clear_acc),.enable_in(enable_acc),.enable_out(),
+           .addend(product),.sum(accum) );
+   
+   shifter shifter (.in(accum),.out(scaled_accum),.shift(shift));
+   
+   assign             data_wr_data = select_input ? sample_in : scaled_accum;
+   assign             enable_mult = 1'b1;
+   
+   always @(posedge clock)
+     if(reset)
+       cur_offset <= #1 4'd0;
+     else if(latch_out)
+       cur_offset <= #1 cur_offset + 4'd1;
+   
+   assign             data_addr = data_addr_int + cur_offset;           
+   assign             data_wr_addr = data_wr_addr_int + cur_offset;             
+   
+   always @(posedge clock)
+     if(reset)
+       done <= #1 1'b0;
+     else if(latch_out)
+       done <= #1 1'b1;
+     else if(strobe_in)
+       done <= #1 1'b0;
+   
+   always @(posedge clock)
+     if(reset)
+       phase <= #1 4'd0;
+     else if(strobe_in)
+       phase <= #1 4'd0;
+     else if(!done)
+       phase <= #1 phase + 4'd1;
+   
+   assign             coeff_addr = phase;
+   
+   always @(phase)
+     case(phase)
+       4'd01 : data_addr_int = 4'd00; 4'd02 : data_addr_int = 4'd01; 4'd03 : data_addr_int = 4'd02;
+       4'd04 : data_addr_int = 4'd03; 4'd05 : data_addr_int = 4'd04;
+       
+       4'd07 : data_addr_int = 4'd03; 4'd08 : data_addr_int = 4'd04; 4'd09 : data_addr_int = 4'd05;
+       4'd10 : data_addr_int = 4'd06; 4'd11 : data_addr_int = 4'd07;
+       default : data_addr_int = 4'd00;
+     endcase // case(phase)
+   
+   always @(phase)
+     case(phase)
+       4'd0 : data_wr_addr_int = 4'd2;
+       4'd8 : data_wr_addr_int = 4'd5;
+       4'd14 : data_wr_addr_int = 4'd8;
+       default : data_wr_addr_int = 4'd0;
+     endcase // case(phase)
+
+   always @(phase)
+     case(phase)
+       4'd0, 4'd8, 4'd14 : data_wr = 1'b1;
+       default : data_wr = 1'b0;
+     endcase // case(phase)
+
+   assign             select_input = (phase == 4'd0);
+   
+   always @(phase)
+     case(phase)
+       4'd0, 4'd1, 4'd2, 4'd3, 4'd9, 4'd15 : clear_acc = 1'd1;
+       default : clear_acc = 1'b0;
+     endcase // case(phase)
+   
+   assign             enable_acc = ~clear_acc;
+   assign             latch_out = (phase == 4'd14);
+   
+   always @(posedge clock)
+     if(reset)
+       sample_out <= #1 16'd0;
+     else if(latch_out)
+       sample_out <= #1 scaled_accum;
+
+   ////////////////////////////////////////////////////////
+   //  Debug
+
+   wire [3:0]         debugmux;
+   
+   setting_reg #(`FR_MRFM_DEBUG) sr_debugmux(.clock(clock),.reset(reset),
+                                            .strobe(serial_strobe),.addr(serial_addr),.in(serial_data),
+                                            .out(debugmux),.changed());
+
+   assign             debugbus[15:0] = debugmux[0] ? {coeff_addr,data_addr,data_wr_addr,cur_offset} : {phase,data_addr_int,data_wr_addr_int,cur_offset};
+   assign             debugbus[31:16] = debugmux[1] ? scaled_accum : {clock, strobe_in, data_wr, enable_mult, enable_acc, clear_acc, latch_out,select_input,done, data_addr_int};
+   assign             debugbus[47:32] = debugmux[2] ? sample_out : coeff;
+   assign             debugbus[63:48] = debugmux[3] ? sample_in : data;
+      
+endmodule // biquad_2stage
+
diff --git a/usrp/fpga/toplevel/mrfm/biquad_6stage.v b/usrp/fpga/toplevel/mrfm/biquad_6stage.v
new file mode 100644 (file)
index 0000000..2b0c511
--- /dev/null
@@ -0,0 +1,137 @@
+`include "mrfm.vh"
+
+module mrfm_iir (input clock, input reset, input strobe_in,
+                input serial_strobe, input [6:0] serial_addr, input [31:0] serial_data,
+                input wire [15:0] sample_in, output reg [15:0] sample_out);
+
+   wire [5:0]         coeff_addr, coeff_wr_addr;
+   wire [4:0]         data_addr, data_wr_addr;
+   reg [4:0]          cur_offset, data_addr_int, data_wr_addr_int;
+   
+   wire [15:0]                coeff, coeff_wr_data, data, data_wr_data;
+   wire               coeff_wr;
+   reg                        data_wr;
+   
+   wire [30:0]                product;
+   wire [33:0]                accum;
+   wire [15:0]                scaled_accum;             
+   
+   wire [7:0]         shift;
+   reg [5:0]          phase;
+   wire               enable_mult, enable_acc, latch_out, select_input;
+   reg                        done, clear_acc;
+   
+   setting_reg #(`FR_MRFM_IIR_COEFF) sr_coeff(.clock(clock),.reset(reset),
+                                             .strobe(serial_strobe),.addr(serial_addr),.in(serial_data),
+                                             .out({coeff_wr_addr,coeff_wr_data}),.changed(coeff_wr));
+   
+   setting_reg #(`FR_MRFM_IIR_SHIFT) sr_shift(.clock(clock),.reset(reset),
+                                             .strobe(serial_strobe),.addr(serial_addr),.in(serial_data),
+                                             .out(shift),.changed());
+   
+   ram64 coeff_ram(.clock(clock),.write(coeff_wr),.wr_addr(coeff_wr_addr),.wr_data(coeff_wr_data),
+                  .rd_addr(coeff_addr),.rd_data(coeff));
+   
+   ram32 data_ram(.clock(clock),.write(data_wr),.wr_addr(data_wr_addr),.wr_data(data_wr_data),
+                 .rd_addr(data_addr),.rd_data(data));
+   
+   mult mult (.clock(clock),.x(data),.y(coeff),.product(product),.enable_in(enable_mult),.enable_out() );
+   
+   acc acc (.clock(clock),.reset(reset),.clear(clear_acc),.enable_in(enable_acc),.enable_out(),
+           .addend(product),.sum(accum) );
+   
+   shifter shifter (.in(accum),.out(scaled_accum),.shift(shift));
+   
+   assign             data_wr_data = select_input ? sample_in : scaled_accum;
+   assign             enable_mult = 1'b1;
+   
+   always @(posedge clock)
+     if(reset)
+       cur_offset <= #1 5'd0;
+     else if(latch_out)
+       cur_offset <= #1 cur_offset + 5'd1;
+   
+   assign             data_addr = data_addr_int + cur_offset;           
+   assign             data_wr_addr = data_wr_addr_int + cur_offset;             
+   
+   always @(posedge clock)
+     if(reset)
+       done <= #1 1'b0;
+     else if(latch_out)
+       done <= #1 1'b1;
+     else if(strobe_in)
+       done <= #1 1'b0;
+   
+   always @(posedge clock)
+     if(reset)
+       phase <= #1 6'd0;
+     else if(strobe_in)
+       phase <= #1 6'd0;
+     else if(!done)
+       phase <= #1 phase + 6'd1;
+   
+   always @(phase)
+     case(phase)
+       6'd0 : data_addr_int = 5'd0;
+       default : data_addr_int = 5'd0;
+     endcase // case(phase)
+   
+   assign             coeff_addr = phase;
+   
+   always @(phase)
+     case(phase)
+       6'd01 : data_addr_int = 5'd00; 6'd02 : data_addr_int = 5'd01; 6'd03 : data_addr_int = 5'd02;
+       6'd04 : data_addr_int = 5'd03; 6'd05 : data_addr_int = 5'd04;
+       
+       6'd07 : data_addr_int = 5'd03; 6'd08 : data_addr_int = 5'd04; 6'd09 : data_addr_int = 5'd05;
+       6'd10 : data_addr_int = 5'd06; 6'd11 : data_addr_int = 5'd07;
+       
+       6'd13 : data_addr_int = 5'd06; 6'd14 : data_addr_int = 5'd07; 6'd15 : data_addr_int = 5'd08;
+       6'd16 : data_addr_int = 5'd09; 6'd17 : data_addr_int = 5'd10;
+       
+       6'd19 : data_addr_int = 5'd09; 6'd20 : data_addr_int = 5'd10; 6'd21 : data_addr_int = 5'd11;
+       6'd22 : data_addr_int = 5'd12; 6'd23 : data_addr_int = 5'd13;
+       
+       6'd25 : data_addr_int = 5'd12; 6'd26 : data_addr_int = 5'd13; 6'd27 : data_addr_int = 5'd14;
+       6'd28 : data_addr_int = 5'd15; 6'd29 : data_addr_int = 5'd16;
+       
+       6'd31 : data_addr_int = 5'd15; 6'd32 : data_addr_int = 5'd16; 6'd33 : data_addr_int = 5'd17;
+       6'd34 : data_addr_int = 5'd18; 6'd35 : data_addr_int = 5'd19;
+       
+       default : data_addr_int = 5'd00;
+     endcase // case(phase)
+   
+   always @(phase)
+     case(phase)
+       6'd0 : data_wr_addr_int = 5'd2;
+       6'd8 : data_wr_addr_int = 5'd5;
+       6'd14 : data_wr_addr_int = 5'd8;
+       6'd20 : data_wr_addr_int = 5'd11;
+       6'd26 : data_wr_addr_int = 5'd14;
+       6'd32 : data_wr_addr_int = 5'd17;
+       6'd38 : data_wr_addr_int = 5'd20;
+       default : data_wr_addr_int = 5'd0;
+     endcase // case(phase)
+
+   always @(phase)
+     case(phase)
+       6'd0, 6'd8, 6'd14, 6'd20, 6'd26, 6'd32, 6'd38: data_wr = 1'b1;
+       default : data_wr = 1'b0;
+     endcase // case(phase)
+      
+   always @(phase)
+     case(phase)
+       6'd0, 6'd1, 6'd2, 6'd3, 6'd9, 6'd15, 6'd21, 6'd27, 6'd33 : clear_acc = 1'd1;
+       default : clear_acc = 1'b0;
+     endcase // case(phase)
+   
+   assign             enable_acc = ~clear_acc;
+   assign             latch_out = (phase == 6'd38);
+   
+   always @(posedge clock)
+     if(reset)
+       sample_out <= #1 16'd0;
+     else if(latch_out)
+       sample_out <= #1 scaled_accum;
+   
+endmodule // mrfm_iir
diff --git a/usrp/fpga/toplevel/mrfm/mrfm.csf b/usrp/fpga/toplevel/mrfm/mrfm.csf
new file mode 100644 (file)
index 0000000..2c30b99
--- /dev/null
@@ -0,0 +1,444 @@
+COMPILER_SETTINGS
+{
+       IO_PLACEMENT_OPTIMIZATION = OFF;
+       ENABLE_DRC_SETTINGS = OFF;
+       PHYSICAL_SYNTHESIS_REGISTER_RETIMING = OFF;
+       PHYSICAL_SYNTHESIS_REGISTER_DUPLICATION = OFF;
+       PHYSICAL_SYNTHESIS_COMBO_LOGIC = OFF;
+       DRC_FANOUT_EXCEEDING = 30;
+       DRC_REPORT_FANOUT_EXCEEDING = OFF;
+       DRC_TOP_FANOUT = 50;
+       DRC_REPORT_TOP_FANOUT = OFF;
+       RUN_DRC_DURING_COMPILATION = OFF;
+       ADV_NETLIST_OPT_RETIME_CORE_AND_IO = ON;
+       ADV_NETLIST_OPT_SYNTH_USE_FITTER_INFO = OFF;
+       ADV_NETLIST_OPT_SYNTH_GATE_RETIME = OFF;
+       ADV_NETLIST_OPT_SYNTH_WYSIWYG_REMAP = OFF;
+       SMART_COMPILE_IGNORES_TDC_FOR_STRATIX_PLL_CHANGES = OFF;
+       MERGE_HEX_FILE = OFF;
+       TRUE_WYSIWYG_FLOW = OFF;
+       SEED = 1;
+       FINAL_PLACEMENT_OPTIMIZATION = AUTOMATICALLY;
+       FAMILY = Cyclone;
+       DPRAM_DUAL_PORT_MODE_OTHER_SIGNALS_EPXA1 = "DPRAM0 TO 1 DPRAM1 TO 2";
+       DPRAM_32BIT_SINGLE_PORT_MODE_OTHER_SIGNALS_EPXA1 = "MEGALAB COLUMN 1";
+       DPRAM_8BIT_16BIT_SINGLE_PORT_MODE_OTHER_SIGNALS_EPXA1 = "MEGALAB COLUMN 1";
+       DPRAM_DUAL_PORT_MODE_OUTPUT_EPXA1 = "DPRAM0 TO 1 DPRAM1 TO 2";
+       DPRAM_32BIT_SINGLE_PORT_MODE_OUTPUT_EPXA1 = "LOWER TO 1ESB UPPER TO 1";
+       DPRAM_8BIT_16BIT_SINGLE_PORT_MODE_OUTPUT_EPXA1 = "MEGALAB COLUMN 1";
+       DPRAM_DUAL_PORT_MODE_INPUT_EPXA1 = "DPRAM0 TO 1 DPRAM1 TO 2";
+       DPRAM_32BIT_SINGLE_PORT_MODE_INPUT_EPXA1 = "MEGALAB COLUMN 1";
+       DPRAM_8BIT_16BIT_SINGLE_PORT_MODE_INPUT_EPXA1 = "MEGALAB COLUMN 1";
+       DPRAM_DUAL_PORT_MODE_OTHER_SIGNALS_EPXA4_10 = "DPRAM0 TO 3 DPRAM1 TO 4";
+       DPRAM_SINGLE_PORT_MODE_OTHER_SIGNALS_EPXA4_10 = "DPRAM0 TO 3 DPRAM1 TO 4";
+       DPRAM_WIDE_MODE_OTHER_SIGNALS_EPXA4_10 = "MEGALAB COLUMN 3";
+       DPRAM_DEEP_MODE_OTHER_SIGNALS_EPXA4_10 = "MEGALAB COLUMN 3";
+       DPRAM_DUAL_PORT_MODE_OUTPUT_EPXA4_10 = "DPRAM0 TO 3 DPRAM1 TO 4ESB";
+       DPRAM_SINGLE_PORT_MODE_OUTPUT_EPXA4_10 = "DPRAM0 TO 3 DPRAM1 TO 4ESB";
+       DPRAM_WIDE_MODE_OUTPUT_EPXA4_10 = "LOWER TO 3 UPPER TO 4ESB";
+       DPRAM_DEEP_MODE_OUTPUT_EPXA4_10 = "MEGALAB COLUMN 3";
+       DPRAM_DUAL_PORT_MODE_INPUT_EPXA4_10 = "DPRAM0 TO 3 DPRAM1 TO 4";
+       DPRAM_SINGLE_PORT_MODE_INPUT_EPXA4_10 = "DPRAM0 TO 3 DPRAM1 TO 4";
+       DPRAM_WIDE_MODE_INPUT_EPXA4_10 = "LOWER TO 3 UPPER TO 4";
+       DPRAM_DEEP_MODE_INPUT_EPXA4_10 = "MEGALAB COLUMN 3";
+       DPRAM_OTHER_SIGNALS_EPXA4_10 = "DEFAULT OTHER ROUTING OPTIONS";
+       DPRAM_OUTPUT_EPXA4_10 = "DEFAULT OUTPUT ROUTING OPTIONS";
+       DPRAM_INPUT_EPXA4_10 = "DEFAULT INPUT ROUTING OPTIONS";
+       STRIPE_TO_PLD_INTERRUPTS_EPXA4_10 = "MEGALAB COLUMN 2";
+       PLD_TO_STRIPE_INTERRUPTS_EPXA4_10 = "MEGALAB COLUMN 2";
+       PROCESSOR_DEBUG_EXTENSIONS_EPXA4_10 = "MEGALAB COLUMN 2";
+       STRIPE_TO_PLD_BRIDGE_EPXA4_10 = "MEGALAB COLUMN 1";
+       FAST_FIT_COMPILATION = OFF;
+       SIGNALPROBE_DURING_NORMAL_COMPILATION = OFF;
+       OPTIMIZE_IOC_REGISTER_PLACEMENT_FOR_TIMING = ON;
+       OPTIMIZE_TIMING = "NORMAL COMPILATION";
+       OPTIMIZE_HOLD_TIMING = OFF;
+       COMPILATION_LEVEL = FULL;
+       SAVE_DISK_SPACE = OFF;
+       SPEED_DISK_USAGE_TRADEOFF = NORMAL;
+       LOGICLOCK_INCREMENTAL_COMPILE_ASSIGNMENT = OFF;
+       SIGNALPROBE_ALLOW_OVERUSE = OFF;
+       FOCUS_ENTITY_NAME = |mrfm;
+       ROUTING_BACK_ANNOTATION_MODE = OFF;
+       INC_PLC_MODE = OFF;
+       FIT_ONLY_ONE_ATTEMPT = OFF;
+}
+DEFAULT_DEVICE_OPTIONS
+{
+       GENERATE_CONFIG_HEXOUT_FILE = OFF;
+       GENERATE_CONFIG_JBC_FILE_COMPRESSED = ON;
+       GENERATE_CONFIG_JBC_FILE = OFF;
+       GENERATE_CONFIG_JAM_FILE = OFF;
+       GENERATE_CONFIG_ISC_FILE = OFF;
+       GENERATE_CONFIG_SVF_FILE = OFF;
+       GENERATE_JBC_FILE_COMPRESSED = ON;
+       GENERATE_JBC_FILE = OFF;
+       GENERATE_JAM_FILE = OFF;
+       GENERATE_ISC_FILE = OFF;
+       GENERATE_SVF_FILE = OFF;
+       RESERVE_PIN = "AS INPUT TRI-STATED";
+       RESERVE_ALL_UNUSED_PINS = "AS OUTPUT DRIVING GROUND";
+       HEXOUT_FILE_COUNT_DIRECTION = UP;
+       HEXOUT_FILE_START_ADDRESS = 0;
+       GENERATE_HEX_FILE = OFF;
+       GENERATE_RBF_FILE = OFF;
+       GENERATE_TTF_FILE = OFF;
+       RESERVE_ASDO_AFTER_CONFIGURATION = "USE AS REGULAR IO";
+       RESERVE_DATA0_AFTER_CONFIGURATION = "AS INPUT TRI-STATED";
+       RESERVE_DATA7_THROUGH_DATA1_AFTER_CONFIGURATION = "USE AS REGULAR IO";
+       RESERVE_RDYNBUSY_AFTER_CONFIGURATION = "USE AS REGULAR IO";
+       RESERVE_NWS_NRS_NCS_CS_AFTER_CONFIGURATION = "USE AS REGULAR IO";
+       DISABLE_NCS_AND_OE_PULLUPS_ON_CONFIG_DEVICE = OFF;
+       AUTO_INCREMENT_CONFIG_DEVICE_JTAG_USER_CODE = ON;
+       EPROM_USE_CHECKSUM_AS_USERCODE = OFF;
+       FLEX10K_CONFIG_DEVICE_JTAG_USER_CODE = FFFFFFFF;
+       MERCURY_CONFIG_DEVICE_JTAG_USER_CODE = FFFFFFFF;
+       STRATIX_CONFIG_DEVICE_JTAG_USER_CODE = FFFFFFFF;
+       APEX20K_CONFIG_DEVICE_JTAG_USER_CODE = FFFFFFFF;
+       STRATIX_CONFIGURATION_DEVICE = AUTO;
+       CYCLONE_CONFIGURATION_DEVICE = AUTO;
+       FLEX10K_CONFIGURATION_DEVICE = AUTO;
+       FLEX6K_CONFIGURATION_DEVICE = AUTO;
+       MERCURY_CONFIGURATION_DEVICE = AUTO;
+       EXCALIBUR_CONFIGURATION_DEVICE = AUTO;
+       APEX20K_CONFIGURATION_DEVICE = AUTO;
+       USE_CONFIGURATION_DEVICE = ON;
+       ENABLE_INIT_DONE_OUTPUT = OFF;
+       FLEX10K_ENABLE_LOCK_OUTPUT = OFF;
+       ENABLE_DEVICE_WIDE_OE = OFF;
+       ENABLE_DEVICE_WIDE_RESET = OFF;
+       RELEASE_CLEARS_BEFORE_TRI_STATES = OFF;
+       AUTO_RESTART_CONFIGURATION = OFF;
+       ENABLE_VREFB_PIN = OFF;
+       ENABLE_VREFA_PIN = OFF;
+       SECURITY_BIT = OFF;
+       USER_START_UP_CLOCK = OFF;
+       APEXII_CONFIGURATION_SCHEME = "PASSIVE SERIAL";
+       FLEX10K_CONFIGURATION_SCHEME = "PASSIVE SERIAL";
+       FLEX6K_CONFIGURATION_SCHEME = "PASSIVE SERIAL";
+       MERCURY_CONFIGURATION_SCHEME = "PASSIVE SERIAL";
+       EXCALIBUR_CONFIGURATION_SCHEME = "PASSIVE SERIAL";
+       CYCLONE_CONFIGURATION_SCHEME = "ACTIVE SERIAL";
+       STRATIX_CONFIGURATION_SCHEME = "PASSIVE SERIAL";
+       APEX20K_CONFIGURATION_SCHEME = "PASSIVE SERIAL";
+       STRATIX_UPDATE_MODE = STANDARD;
+       USE_CHECKSUM_AS_USERCODE = OFF;
+       MAX7000_USE_CHECKSUM_AS_USERCODE = OFF;
+       MAX7000_JTAG_USER_CODE = FFFFFFFF;
+       FLEX10K_JTAG_USER_CODE = 7F;
+       MERCURY_JTAG_USER_CODE = FFFFFFFF;
+       APEX20K_JTAG_USER_CODE = FFFFFFFF;
+       STRATIX_JTAG_USER_CODE = FFFFFFFF;
+       MAX7000S_JTAG_USER_CODE = FFFF;
+       RESERVE_NCEO_AFTER_CONFIGURATION = "USE AS REGULAR IO";
+       FLEX10K_ENABLE_LOW_VOLTAGE_MODE_ON_CONFIG_DEVICE = ON;
+       FLEX6K_ENABLE_LOW_VOLTAGE_MODE_ON_CONFIG_DEVICE = OFF;
+       ENABLE_LOW_VOLTAGE_MODE_ON_CONFIG_DEVICE = ON;
+       MAX7000_ENABLE_JTAG_BST_SUPPORT = ON;
+       ENABLE_JTAG_BST_SUPPORT = OFF;
+       CONFIGURATION_CLOCK_DIVISOR = 1;
+       CONFIGURATION_CLOCK_FREQUENCY = "10 MHZ";
+       CLOCK_SOURCE = INTERNAL;
+       COMPRESSION_MODE = OFF;
+       ON_CHIP_BITSTREAM_DECOMPRESSION = OFF;
+}
+AUTO_SLD_HUB_ENTITY
+{
+       AUTO_INSERT_SLD_HUB_ENTITY = ENABLE;
+       HUB_INSTANCE_NAME = SLD_HUB_INST;
+       HUB_ENTITY_NAME = SLD_HUB;
+}
+SIGNALTAP_LOGIC_ANALYZER_SETTINGS
+{
+       ENABLE_SIGNALTAP = Off;
+       AUTO_ENABLE_SMART_COMPILE = On;
+}
+CHIP(mrfm)
+{
+       DEVICE = EP1C12Q240C8;
+       DEVICE_FILTER_PACKAGE = "ANY QFP";
+       DEVICE_FILTER_PIN_COUNT = 240;
+       DEVICE_FILTER_SPEED_GRADE = ANY;
+       AUTO_RESTART_CONFIGURATION = OFF;
+       RELEASE_CLEARS_BEFORE_TRI_STATES = OFF;
+       USER_START_UP_CLOCK = OFF;
+       ENABLE_DEVICE_WIDE_RESET = OFF;
+       ENABLE_DEVICE_WIDE_OE = OFF;
+       ENABLE_INIT_DONE_OUTPUT = OFF;
+       FLEX10K_ENABLE_LOCK_OUTPUT = OFF;
+       ENABLE_JTAG_BST_SUPPORT = OFF;
+       MAX7000_ENABLE_JTAG_BST_SUPPORT = ON;
+       APEX20K_JTAG_USER_CODE = FFFFFFFF;
+       MERCURY_JTAG_USER_CODE = FFFFFFFF;
+       FLEX10K_JTAG_USER_CODE = 7F;
+       MAX7000_JTAG_USER_CODE = FFFFFFFF;
+       MAX7000S_JTAG_USER_CODE = FFFF;
+       STRATIX_JTAG_USER_CODE = FFFFFFFF;
+       APEX20K_CONFIGURATION_SCHEME = "PASSIVE SERIAL";
+       MERCURY_CONFIGURATION_SCHEME = "PASSIVE SERIAL";
+       FLEX6K_CONFIGURATION_SCHEME = "PASSIVE SERIAL";
+       FLEX10K_CONFIGURATION_SCHEME = "PASSIVE SERIAL";
+       EXCALIBUR_CONFIGURATION_SCHEME = "PASSIVE SERIAL";
+       APEXII_CONFIGURATION_SCHEME = "PASSIVE SERIAL";
+       STRATIX_CONFIGURATION_SCHEME = "PASSIVE SERIAL";
+       CYCLONE_CONFIGURATION_SCHEME = "PASSIVE SERIAL";
+       USE_CONFIGURATION_DEVICE = OFF;
+       APEX20K_CONFIGURATION_DEVICE = AUTO;
+       MERCURY_CONFIGURATION_DEVICE = AUTO;
+       FLEX6K_CONFIGURATION_DEVICE = AUTO;
+       FLEX10K_CONFIGURATION_DEVICE = AUTO;
+       EXCALIBUR_CONFIGURATION_DEVICE = AUTO;
+       STRATIX_CONFIGURATION_DEVICE = AUTO;
+       CYCLONE_CONFIGURATION_DEVICE = AUTO;
+       STRATIX_UPDATE_MODE = STANDARD;
+       APEX20K_CONFIG_DEVICE_JTAG_USER_CODE = FFFFFFFF;
+       MERCURY_CONFIG_DEVICE_JTAG_USER_CODE = FFFFFFFF;
+       FLEX10K_CONFIG_DEVICE_JTAG_USER_CODE = FFFFFFFF;
+       STRATIX_CONFIG_DEVICE_JTAG_USER_CODE = FFFFFFFF;
+       AUTO_INCREMENT_CONFIG_DEVICE_JTAG_USER_CODE = ON;
+       DISABLE_NCS_AND_OE_PULLUPS_ON_CONFIG_DEVICE = OFF;
+       COMPRESSION_MODE = OFF;
+       ENABLE_LOW_VOLTAGE_MODE_ON_CONFIG_DEVICE = ON;
+       FLEX6K_ENABLE_LOW_VOLTAGE_MODE_ON_CONFIG_DEVICE = OFF;
+       FLEX10K_ENABLE_LOW_VOLTAGE_MODE_ON_CONFIG_DEVICE = ON;
+       EPROM_USE_CHECKSUM_AS_USERCODE = OFF;
+       USE_CHECKSUM_AS_USERCODE = OFF;
+       MAX7000_USE_CHECKSUM_AS_USERCODE = OFF;
+       GENERATE_TTF_FILE = OFF;
+       GENERATE_RBF_FILE = ON;
+       GENERATE_HEX_FILE = OFF;
+       SECURITY_BIT = OFF;
+       ENABLE_VREFA_PIN = OFF;
+       ENABLE_VREFB_PIN = OFF;
+       GENERATE_SVF_FILE = OFF;
+       GENERATE_ISC_FILE = OFF;
+       GENERATE_JAM_FILE = OFF;
+       GENERATE_JBC_FILE = OFF;
+       GENERATE_JBC_FILE_COMPRESSED = ON;
+       GENERATE_CONFIG_SVF_FILE = OFF;
+       GENERATE_CONFIG_ISC_FILE = OFF;
+       GENERATE_CONFIG_JAM_FILE = OFF;
+       GENERATE_CONFIG_JBC_FILE = OFF;
+       GENERATE_CONFIG_JBC_FILE_COMPRESSED = ON;
+       GENERATE_CONFIG_HEXOUT_FILE = OFF;
+       ON_CHIP_BITSTREAM_DECOMPRESSION = OFF;
+       BASE_PIN_OUT_FILE_ON_SAMEFRAME_DEVICE = OFF;
+       HEXOUT_FILE_START_ADDRESS = 0;
+       HEXOUT_FILE_COUNT_DIRECTION = UP;
+       RESERVE_ALL_UNUSED_PINS = "AS INPUT TRI-STATED";
+       STRATIX_DEVICE_IO_STANDARD = LVTTL;
+       CLOCK_SOURCE = INTERNAL;
+       CONFIGURATION_CLOCK_FREQUENCY = "10 MHZ";
+       CONFIGURATION_CLOCK_DIVISOR = 1;
+       RESERVE_NWS_NRS_NCS_CS_AFTER_CONFIGURATION = "USE AS REGULAR IO";
+       RESERVE_RDYNBUSY_AFTER_CONFIGURATION = "USE AS REGULAR IO";
+       RESERVE_DATA7_THROUGH_DATA1_AFTER_CONFIGURATION = "USE AS REGULAR IO";
+       RESERVE_DATA0_AFTER_CONFIGURATION = "AS INPUT TRI-STATED";
+       RESERVE_NCEO_AFTER_CONFIGURATION = "USE AS REGULAR IO";
+       RESERVE_ASDO_AFTER_CONFIGURATION = "USE AS REGULAR IO";
+       SCLK : LOCATION = Pin_101;
+       SDI : LOCATION = Pin_100;
+       SEN : LOCATION = Pin_98;
+       SLD : LOCATION = Pin_95;
+       adc1_data[0] : LOCATION = Pin_5;
+       adc1_data[10] : LOCATION = Pin_235;
+       adc1_data[11] : LOCATION = Pin_234;
+       adc1_data[1] : LOCATION = Pin_4;
+       adc1_data[2] : LOCATION = Pin_3;
+       adc1_data[3] : LOCATION = Pin_2;
+       adc1_data[4] : LOCATION = Pin_1;
+       adc1_data[4] : IO_STANDARD = LVTTL;
+       adc1_data[5] : LOCATION = Pin_240;
+       adc1_data[6] : LOCATION = Pin_239;
+       adc1_data[7] : LOCATION = Pin_238;
+       adc1_data[8] : LOCATION = Pin_237;
+       adc1_data[9] : LOCATION = Pin_236;
+       adc2_data[0] : LOCATION = Pin_20;
+       adc2_data[10] : LOCATION = Pin_8;
+       adc2_data[11] : LOCATION = Pin_7;
+       adc2_data[1] : LOCATION = Pin_19;
+       adc2_data[2] : LOCATION = Pin_18;
+       adc2_data[3] : LOCATION = Pin_17;
+       adc2_data[4] : LOCATION = Pin_16;
+       adc2_data[5] : LOCATION = Pin_15;
+       adc2_data[6] : LOCATION = Pin_14;
+       adc2_data[7] : LOCATION = Pin_13;
+       adc2_data[8] : LOCATION = Pin_12;
+       adc2_data[9] : LOCATION = Pin_11;
+       adc3_data[0] : LOCATION = Pin_200;
+       adc3_data[10] : LOCATION = Pin_184;
+       adc3_data[11] : LOCATION = Pin_183;
+       adc3_data[1] : LOCATION = Pin_197;
+       adc3_data[2] : LOCATION = Pin_196;
+       adc3_data[3] : LOCATION = Pin_195;
+       adc3_data[4] : LOCATION = Pin_194;
+       adc3_data[5] : LOCATION = Pin_193;
+       adc3_data[6] : LOCATION = Pin_188;
+       adc3_data[7] : LOCATION = Pin_187;
+       adc3_data[8] : LOCATION = Pin_186;
+       adc3_data[9] : LOCATION = Pin_185;
+       adc4_data[0] : LOCATION = Pin_222;
+       adc4_data[10] : LOCATION = Pin_203;
+       adc4_data[11] : LOCATION = Pin_202;
+       adc4_data[1] : LOCATION = Pin_219;
+       adc4_data[2] : LOCATION = Pin_217;
+       adc4_data[3] : LOCATION = Pin_216;
+       adc4_data[4] : LOCATION = Pin_215;
+       adc4_data[5] : LOCATION = Pin_214;
+       adc4_data[6] : LOCATION = Pin_213;
+       adc4_data[7] : LOCATION = Pin_208;
+       adc4_data[8] : LOCATION = Pin_207;
+       adc4_data[9] : LOCATION = Pin_206;
+       adc_oeb[0] : LOCATION = Pin_228;
+       adc_oeb[1] : LOCATION = Pin_21;
+       adc_oeb[2] : LOCATION = Pin_181;
+       adc_oeb[3] : LOCATION = Pin_218;
+       adc_otr[0] : LOCATION = Pin_233;
+       adc_otr[1] : LOCATION = Pin_6;
+       adc_otr[2] : LOCATION = Pin_182;
+       adc_otr[3] : LOCATION = Pin_201;
+       adclk0 : LOCATION = Pin_224;
+       adclk1 : LOCATION = Pin_226;
+       clk0 : LOCATION = Pin_28;
+       clk0 : RESERVE_PIN = "AS INPUT TRI-STATED";
+       clk0 : IO_STANDARD = LVTTL;
+       clk1 : LOCATION = Pin_29;
+       clk1 : RESERVE_PIN = "AS INPUT TRI-STATED";
+       clk1 : IO_STANDARD = LVTTL;
+       clk3 : LOCATION = Pin_152;
+       clk3 : RESERVE_PIN = "AS INPUT TRI-STATED";
+       clk3 : IO_STANDARD = LVTTL;
+       clk_120mhz : LOCATION = Pin_153;
+       clk_120mhz : IO_STANDARD = LVTTL;
+       clk_out : LOCATION = Pin_63;
+       clk_out : IO_STANDARD = LVTTL;
+       dac1_data[0] : LOCATION = Pin_165;
+       dac1_data[10] : LOCATION = Pin_177;
+       dac1_data[11] : LOCATION = Pin_178;
+       dac1_data[12] : LOCATION = Pin_179;
+       dac1_data[13] : LOCATION = Pin_180;
+       dac1_data[1] : LOCATION = Pin_166;
+       dac1_data[2] : LOCATION = Pin_167;
+       dac1_data[3] : LOCATION = Pin_168;
+       dac1_data[4] : LOCATION = Pin_169;
+       dac1_data[5] : LOCATION = Pin_170;
+       dac1_data[6] : LOCATION = Pin_173;
+       dac1_data[7] : LOCATION = Pin_174;
+       dac1_data[8] : LOCATION = Pin_175;
+       dac1_data[9] : LOCATION = Pin_176;
+       dac2_data[0] : LOCATION = Pin_159;
+       dac2_data[10] : LOCATION = Pin_163;
+       dac2_data[11] : LOCATION = Pin_139;
+       dac2_data[12] : LOCATION = Pin_164;
+       dac2_data[13] : LOCATION = Pin_138;
+       dac2_data[1] : LOCATION = Pin_158;
+       dac2_data[2] : LOCATION = Pin_160;
+       dac2_data[3] : LOCATION = Pin_156;
+       dac2_data[4] : LOCATION = Pin_161;
+       dac2_data[5] : LOCATION = Pin_144;
+       dac2_data[6] : LOCATION = Pin_162;
+       dac2_data[7] : LOCATION = Pin_141;
+       dac2_data[8] : LOCATION = Pin_143;
+       dac2_data[9] : LOCATION = Pin_140;
+       dac3_data[0] : LOCATION = Pin_122;
+       dac3_data[10] : LOCATION = Pin_134;
+       dac3_data[11] : LOCATION = Pin_135;
+       dac3_data[12] : LOCATION = Pin_136;
+       dac3_data[13] : LOCATION = Pin_137;
+       dac3_data[1] : LOCATION = Pin_123;
+       dac3_data[2] : LOCATION = Pin_124;
+       dac3_data[3] : LOCATION = Pin_125;
+       dac3_data[4] : LOCATION = Pin_126;
+       dac3_data[5] : LOCATION = Pin_127;
+       dac3_data[6] : LOCATION = Pin_128;
+       dac3_data[7] : LOCATION = Pin_131;
+       dac3_data[8] : LOCATION = Pin_132;
+       dac3_data[9] : LOCATION = Pin_133;
+       dac4_data[0] : LOCATION = Pin_104;
+       dac4_data[10] : LOCATION = Pin_118;
+       dac4_data[11] : LOCATION = Pin_119;
+       dac4_data[12] : LOCATION = Pin_120;
+       dac4_data[13] : LOCATION = Pin_121;
+       dac4_data[1] : LOCATION = Pin_105;
+       dac4_data[2] : LOCATION = Pin_106;
+       dac4_data[3] : LOCATION = Pin_107;
+       dac4_data[4] : LOCATION = Pin_108;
+       dac4_data[5] : LOCATION = Pin_113;
+       dac4_data[6] : LOCATION = Pin_114;
+       dac4_data[7] : LOCATION = Pin_115;
+       dac4_data[8] : LOCATION = Pin_116;
+       dac4_data[9] : LOCATION = Pin_117;
+       enable_rx : LOCATION = Pin_88;
+       enable_tx : LOCATION = Pin_93;
+       gndbus[0] : LOCATION = Pin_223;
+       gndbus[0] : RESERVE_PIN = "AS INPUT TRI-STATED";
+       gndbus[0] : IO_STANDARD = LVTTL;
+       gndbus[1] : LOCATION = Pin_225;
+       gndbus[1] : RESERVE_PIN = "AS INPUT TRI-STATED";
+       gndbus[1] : IO_STANDARD = LVTTL;
+       gndbus[2] : LOCATION = Pin_227;
+       gndbus[2] : RESERVE_PIN = "AS INPUT TRI-STATED";
+       gndbus[2] : IO_STANDARD = LVTTL;
+       gndbus[3] : LOCATION = Pin_62;
+       gndbus[3] : RESERVE_PIN = "AS INPUT TRI-STATED";
+       gndbus[3] : IO_STANDARD = LVTTL;
+       gndbus[4] : LOCATION = Pin_64;
+       gndbus[4] : RESERVE_PIN = "AS INPUT TRI-STATED";
+       gndbus[4] : IO_STANDARD = LVTTL;
+       misc_pins[0] : LOCATION = Pin_87;
+       misc_pins[0] : IO_STANDARD = LVTTL;
+       misc_pins[10] : LOCATION = Pin_76;
+       misc_pins[10] : IO_STANDARD = LVTTL;
+       misc_pins[11] : LOCATION = Pin_74;
+       misc_pins[11] : IO_STANDARD = LVTTL;
+       misc_pins[1] : LOCATION = Pin_86;
+       misc_pins[1] : IO_STANDARD = LVTTL;
+       misc_pins[2] : LOCATION = Pin_85;
+       misc_pins[2] : IO_STANDARD = LVTTL;
+       misc_pins[3] : LOCATION = Pin_84;
+       misc_pins[3] : IO_STANDARD = LVTTL;
+       misc_pins[4] : LOCATION = Pin_83;
+       misc_pins[4] : IO_STANDARD = LVTTL;
+       misc_pins[5] : LOCATION = Pin_82;
+       misc_pins[5] : IO_STANDARD = LVTTL;
+       misc_pins[6] : LOCATION = Pin_79;
+       misc_pins[6] : IO_STANDARD = LVTTL;
+       misc_pins[7] : LOCATION = Pin_78;
+       misc_pins[7] : IO_STANDARD = LVTTL;
+       misc_pins[8] : LOCATION = Pin_77;
+       misc_pins[8] : IO_STANDARD = LVTTL;
+       misc_pins[9] : LOCATION = Pin_75;
+       misc_pins[9] : IO_STANDARD = LVTTL;
+       reset : LOCATION = Pin_94;
+       usbclk : LOCATION = Pin_55;
+       usbctl[0] : LOCATION = Pin_56;
+       usbctl[1] : LOCATION = Pin_54;
+       usbctl[2] : LOCATION = Pin_53;
+       usbctl[3] : LOCATION = Pin_58;
+       usbctl[4] : LOCATION = Pin_57;
+       usbctl[5] : LOCATION = Pin_44;
+       usbdata[0] : LOCATION = Pin_73;
+       usbdata[10] : LOCATION = Pin_41;
+       usbdata[11] : LOCATION = Pin_39;
+       usbdata[12] : LOCATION = Pin_38;
+       usbdata[12] : IO_STANDARD = LVTTL;
+       usbdata[13] : LOCATION = Pin_37;
+       usbdata[14] : LOCATION = Pin_24;
+       usbdata[15] : LOCATION = Pin_23;
+       usbdata[1] : LOCATION = Pin_68;
+       usbdata[2] : LOCATION = Pin_67;
+       usbdata[3] : LOCATION = Pin_66;
+       usbdata[4] : LOCATION = Pin_65;
+       usbdata[5] : LOCATION = Pin_61;
+       usbdata[6] : LOCATION = Pin_60;
+       usbdata[7] : LOCATION = Pin_59;
+       usbdata[8] : LOCATION = Pin_43;
+       usbdata[9] : LOCATION = Pin_42;
+       usbrdy[0] : LOCATION = Pin_45;
+       usbrdy[1] : LOCATION = Pin_46;
+       usbrdy[2] : LOCATION = Pin_47;
+       usbrdy[3] : LOCATION = Pin_48;
+       usbrdy[4] : LOCATION = Pin_49;
+       usbrdy[5] : LOCATION = Pin_50;
+       clear_status : LOCATION = Pin_99;
+}
diff --git a/usrp/fpga/toplevel/mrfm/mrfm.esf b/usrp/fpga/toplevel/mrfm/mrfm.esf
new file mode 100644 (file)
index 0000000..72b84e3
--- /dev/null
@@ -0,0 +1,14 @@
+SIMULATOR_SETTINGS
+{
+       ESTIMATE_POWER_CONSUMPTION = OFF;
+       GLITCH_INTERVAL = 1NS;
+       GLITCH_DETECTION = OFF;
+       SIMULATION_COVERAGE = ON;
+       CHECK_OUTPUTS = OFF;
+       SETUP_HOLD_DETECTION = OFF;
+       POWER_ESTIMATION_START_TIME = "0 NS";
+       ADD_DEFAULT_PINS_TO_SIMULATION_OUTPUT_WAVEFORMS = ON;
+       SIMULATION_MODE = TIMING;
+       START_TIME = 0NS;
+       USE_COMPILER_SETTINGS = mrfm;
+}
diff --git a/usrp/fpga/toplevel/mrfm/mrfm.psf b/usrp/fpga/toplevel/mrfm/mrfm.psf
new file mode 100644 (file)
index 0000000..678a7fa
--- /dev/null
@@ -0,0 +1,312 @@
+DEFAULT_DESIGN_ASSISTANT_SETTINGS
+{
+       HCPY_ALOAD_SIGNALS = OFF;
+       HCPY_VREF_PINS = OFF;
+       HCPY_CAT = OFF;
+       HCPY_ILLEGAL_HC_DEV_PKG = OFF;
+       ACLK_RULE_IMSZER_ADOMAIN = OFF;
+       ACLK_RULE_SZER_BTW_ACLK_DOMAIN = OFF;
+       ACLK_RULE_NO_SZER_ACLK_DOMAIN = OFF;
+       ACLK_CAT = OFF;
+       SIGNALRACE_RULE_ASYNCHPIN_SYNCH_CLKPIN = OFF;
+       SIGNALRACE_CAT = OFF;
+       NONSYNCHSTRUCT_RULE_LATCH_UNIDENTIFIED = OFF;
+       NONSYNCHSTRUCT_RULE_SRLATCH = OFF;
+       NONSYNCHSTRUCT_RULE_DLATCH = OFF;
+       NONSYNCHSTRUCT_RULE_MULTI_VIBRATOR = OFF;
+       NONSYNCHSTRUCT_RULE_ILLEGAL_PULSE_GEN = OFF;
+       NONSYNCHSTRUCT_RULE_RIPPLE_CLK = OFF;
+       NONSYNCHSTRUCT_RULE_DELAY_CHAIN = OFF;
+       NONSYNCHSTRUCT_RULE_REG_LOOP = OFF;
+       NONSYNCHSTRUCT_RULE_COMBLOOP = OFF;
+       NONSYNCHSTRUCT_CAT = OFF;
+       NONSYNCHSTRUCT_RULE_COMB_DRIVES_RAM_WE = OFF;
+       TIMING_RULE_COIN_CLKEDGE = OFF;
+       TIMING_RULE_SHIFT_REG = OFF;
+       TIMING_RULE_HIGH_FANOUTS = OFF;
+       TIMING_CAT = OFF;
+       RESET_RULE_ALL = OFF;
+       RESET_RULE_IMSYNCH_ASYNCH_DOMAIN = OFF;
+       RESET_RULE_UNSYNCH_ASYNCH_DOMAIN = OFF;
+       RESET_RULE_REG_ASNYCH = OFF;
+       RESET_RULE_COMB_ASYNCH_RESET = OFF;
+       RESET_RULE_IMSYNCH_EXRESET = OFF;
+       RESET_RULE_UNSYNCH_EXRESET = OFF;
+       RESET_RULE_INPINS_RESETNET = OFF;
+       RESET_CAT = OFF;
+       CLK_RULE_ALL = OFF;
+       CLK_RULE_MIX_EDGES = OFF;
+       CLK_RULE_CLKNET_CLKSPINES = OFF;
+       CLK_RULE_INPINS_CLKNET = OFF;
+       CLK_RULE_GATING_SCHEME = OFF;
+       CLK_RULE_INV_CLOCK = OFF;
+       CLK_RULE_COMB_CLOCK = OFF;
+       CLK_CAT = OFF;
+       HCPY_EXCEED_USER_IO_USAGE = OFF;
+       HCPY_EXCEED_RAM_USAGE = OFF;
+       NONSYNCHSTRUCT_RULE_ASYN_RAM = OFF;
+       SIGNALRACE_RULE_TRISTATE = OFF;
+       ASSG_RULE_MISSING_TIMING = OFF;
+       ASSG_RULE_MISSING_FMAX = OFF;
+       ASSG_CAT = OFF;
+}
+SYNTHESIS_FITTING_SETTINGS
+{
+       AUTO_SHIFT_REGISTER_RECOGNITION = ON;
+       AUTO_DSP_RECOGNITION = ON;
+       AUTO_RAM_RECOGNITION = ON;
+       REMOVE_DUPLICATE_LOGIC = ON;
+       AUTO_TURBO_BIT = ON;
+       AUTO_MERGE_PLLS = ON;
+       AUTO_OPEN_DRAIN_PINS = ON;
+       AUTO_PARALLEL_EXPANDERS = ON;
+       AUTO_FAST_OUTPUT_ENABLE_REGISTERS = OFF;
+       AUTO_FAST_OUTPUT_REGISTERS = OFF;
+       AUTO_FAST_INPUT_REGISTERS = OFF;
+       AUTO_CASCADE_CHAINS = ON;
+       AUTO_CARRY_CHAINS = ON;
+       AUTO_DELAY_CHAINS = ON;
+       MAX7000_PARALLEL_EXPANDER_CHAIN_LENGTH = 4;
+       PARALLEL_EXPANDER_CHAIN_LENGTH = 16;
+       CASCADE_CHAIN_LENGTH = 2;
+       STRATIX_CARRY_CHAIN_LENGTH = 70;
+       MERCURY_CARRY_CHAIN_LENGTH = 48;
+       FLEX10K_CARRY_CHAIN_LENGTH = 32;
+       FLEX6K_CARRY_CHAIN_LENGTH = 32;
+       CARRY_CHAIN_LENGTH = 48;
+       CARRY_OUT_PINS_LCELL_INSERT = ON;
+       NORMAL_LCELL_INSERT = ON;
+       AUTO_LCELL_INSERTION = ON;
+       ALLOW_XOR_GATE_USAGE = ON;
+       AUTO_PACKED_REGISTERS_STRATIX = NORMAL;
+       AUTO_PACKED_REGISTERS = OFF;
+       AUTO_PACKED_REG_CYCLONE = NORMAL;
+       FLEX10K_OPTIMIZATION_TECHNIQUE = AREA;
+       FLEX6K_OPTIMIZATION_TECHNIQUE = AREA;
+       MERCURY_OPTIMIZATION_TECHNIQUE = AREA;
+       APEX20K_OPTIMIZATION_TECHNIQUE = SPEED;
+       MAX7000_OPTIMIZATION_TECHNIQUE = SPEED;
+       STRATIX_OPTIMIZATION_TECHNIQUE = SPEED;
+       CYCLONE_OPTIMIZATION_TECHNIQUE = AREA;
+       FLEX10K_TECHNOLOGY_MAPPER = LUT;
+       FLEX6K_TECHNOLOGY_MAPPER = LUT;
+       MERCURY_TECHNOLOGY_MAPPER = LUT;
+       APEX20K_TECHNOLOGY_MAPPER = LUT;
+       MAX7000_TECHNOLOGY_MAPPER = "PRODUCT TERM";
+       STRATIX_TECHNOLOGY_MAPPER = LUT;
+       AUTO_IMPLEMENT_IN_ROM = OFF;
+       AUTO_GLOBAL_MEMORY_CONTROLS = OFF;
+       AUTO_GLOBAL_REGISTER_CONTROLS = ON;
+       AUTO_GLOBAL_OE = ON;
+       AUTO_GLOBAL_CLOCK = ON;
+       USE_LPM_FOR_AHDL_OPERATORS = ON;
+       LIMIT_AHDL_INTEGERS_TO_32_BITS = OFF;
+       ENABLE_BUS_HOLD_CIRCUITRY = OFF;
+       WEAK_PULL_UP_RESISTOR = OFF;
+       TURBO_BIT = ON;
+       MAX7000_IGNORE_SOFT_BUFFERS = OFF;
+       IGNORE_SOFT_BUFFERS = ON;
+       MAX7000_IGNORE_LCELL_BUFFERS = AUTO;
+       IGNORE_LCELL_BUFFERS = OFF;
+       IGNORE_ROW_GLOBAL_BUFFERS = OFF;
+       IGNORE_GLOBAL_BUFFERS = OFF;
+       IGNORE_CASCADE_BUFFERS = OFF;
+       IGNORE_CARRY_BUFFERS = OFF;
+       REMOVE_DUPLICATE_REGISTERS = ON;
+       REMOVE_REDUNDANT_LOGIC_CELLS = OFF;
+       ALLOW_POWER_UP_DONT_CARE = ON;
+       PCI_IO = OFF;
+       NOT_GATE_PUSH_BACK = ON;
+       SLOW_SLEW_RATE = OFF;
+       DSP_BLOCK_BALANCING = AUTO;
+       STATE_MACHINE_PROCESSING = AUTO;
+}
+DEFAULT_HARDCOPY_SETTINGS
+{
+       HARDCOPY_EXTERNAL_CLOCK_JITTER = "0.0 NS";
+}
+DEFAULT_TIMING_REQUIREMENTS
+{
+       INCLUDE_EXTERNAL_PIN_DELAYS_IN_FMAX_CALCULATIONS = OFF;
+       RUN_ALL_TIMING_ANALYSES = ON;
+       IGNORE_CLOCK_SETTINGS = OFF;
+       DEFAULT_HOLD_MULTICYCLE = "SAME AS MULTICYCLE";
+       CUT_OFF_IO_PIN_FEEDBACK = ON;
+       CUT_OFF_CLEAR_AND_PRESET_PATHS = ON;
+       CUT_OFF_READ_DURING_WRITE_PATHS = ON;
+       CUT_OFF_PATHS_BETWEEN_CLOCK_DOMAINS = ON;
+       DO_MIN_ANALYSIS = ON;
+       DO_MIN_TIMING = OFF;
+       NUMBER_OF_PATHS_TO_REPORT = 200;
+       NUMBER_OF_DESTINATION_TO_REPORT = 10;
+       NUMBER_OF_SOURCES_PER_DESTINATION_TO_REPORT = 10;
+       MAX_SCC_SIZE = 50;
+}
+HDL_SETTINGS
+{
+       VERILOG_INPUT_VERSION = VERILOG_2001;
+       ENABLE_IP_DEBUG = OFF;
+       VHDL_INPUT_VERSION = VHDL93;
+       VHDL_SHOW_LMF_MAPPING_MESSAGES = OFF;
+}
+PROJECT_INFO(mrfm)
+{
+       ORIGINAL_QUARTUS_VERSION = 3.0;
+       PROJECT_CREATION_TIME_DATE = "00:14:04  JULY 13, 2003";
+       LAST_QUARTUS_VERSION = 3.0;
+       SHOW_REGISTRATION_MESSAGE = ON;
+       USER_LIBRARIES = "e:\usrp\fpga\megacells";
+}
+THIRD_PARTY_EDA_TOOLS(mrfm)
+{
+       EDA_DESIGN_ENTRY_SYNTHESIS_TOOL = "<NONE>";
+       EDA_SIMULATION_TOOL = "<NONE>";
+       EDA_TIMING_ANALYSIS_TOOL = "<NONE>";
+       EDA_BOARD_DESIGN_TOOL = "<NONE>";
+       EDA_FORMAL_VERIFICATION_TOOL = "<NONE>";
+       EDA_RESYNTHESIS_TOOL = "<NONE>";
+}
+EDA_TOOL_SETTINGS(eda_design_synthesis)
+{
+       EDA_INPUT_GND_NAME = GND;
+       EDA_INPUT_VCC_NAME = VCC;
+       EDA_SHOW_LMF_MAPPING_MESSAGES = OFF;
+       EDA_RUN_TOOL_AUTOMATICALLY = OFF;
+       EDA_INPUT_DATA_FORMAT = EDIF;
+       EDA_OUTPUT_DATA_FORMAT = NONE;
+       USE_GENERATED_PHYSICAL_CONSTRAINTS = ON;
+       RESYNTHESIS_PHYSICAL_SYNTHESIS = NORMAL;
+       RESYNTHESIS_OPTIMIZATION_EFFORT = NORMAL;
+       RESYNTHESIS_RETIMING = FULL;
+}
+EDA_TOOL_SETTINGS(eda_simulation)
+{
+       EDA_INCLUDE_VHDL_CONFIGURATION_DECLARATION = OFF;
+       EDA_TRUNCATE_LONG_HIERARCHY_PATHS = OFF;
+       EDA_MAINTAIN_DESIGN_HIERARCHY = OFF;
+       EDA_WRITE_DEVICE_CONTROL_PORTS = OFF;
+       EDA_GENERATE_FUNCTIONAL_NETLIST = OFF;
+       EDA_FLATTEN_BUSES = OFF;
+       EDA_MAP_ILLEGAL_CHARACTERS = OFF;
+       EDA_EXCALIBUR_ATOMS_AS_SINGLE_STRIPE = OFF;
+       EDA_RUN_TOOL_AUTOMATICALLY = OFF;
+       EDA_OUTPUT_DATA_FORMAT = NONE;
+       USE_GENERATED_PHYSICAL_CONSTRAINTS = ON;
+       RESYNTHESIS_PHYSICAL_SYNTHESIS = NORMAL;
+       RESYNTHESIS_OPTIMIZATION_EFFORT = NORMAL;
+       RESYNTHESIS_RETIMING = FULL;
+}
+EDA_TOOL_SETTINGS(eda_timing_analysis)
+{
+       EDA_INCLUDE_VHDL_CONFIGURATION_DECLARATION = OFF;
+       EDA_TRUNCATE_LONG_HIERARCHY_PATHS = OFF;
+       EDA_MAINTAIN_DESIGN_HIERARCHY = OFF;
+       EDA_WRITE_DEVICE_CONTROL_PORTS = OFF;
+       EDA_GENERATE_FUNCTIONAL_NETLIST = OFF;
+       EDA_FLATTEN_BUSES = OFF;
+       EDA_MAP_ILLEGAL_CHARACTERS = OFF;
+       EDA_EXCALIBUR_ATOMS_AS_SINGLE_STRIPE = OFF;
+       EDA_RUN_TOOL_AUTOMATICALLY = OFF;
+       EDA_OUTPUT_DATA_FORMAT = NONE;
+       EDA_LAUNCH_CMD_LINE_TOOL = OFF;
+       USE_GENERATED_PHYSICAL_CONSTRAINTS = ON;
+       RESYNTHESIS_PHYSICAL_SYNTHESIS = NORMAL;
+       RESYNTHESIS_OPTIMIZATION_EFFORT = NORMAL;
+       RESYNTHESIS_RETIMING = FULL;
+}
+EDA_TOOL_SETTINGS(eda_board_design)
+{
+       EDA_INCLUDE_VHDL_CONFIGURATION_DECLARATION = OFF;
+       EDA_TRUNCATE_LONG_HIERARCHY_PATHS = OFF;
+       EDA_MAINTAIN_DESIGN_HIERARCHY = OFF;
+       EDA_WRITE_DEVICE_CONTROL_PORTS = OFF;
+       EDA_GENERATE_FUNCTIONAL_NETLIST = OFF;
+       EDA_FLATTEN_BUSES = OFF;
+       EDA_MAP_ILLEGAL_CHARACTERS = OFF;
+       EDA_EXCALIBUR_ATOMS_AS_SINGLE_STRIPE = OFF;
+       EDA_RUN_TOOL_AUTOMATICALLY = OFF;
+       EDA_OUTPUT_DATA_FORMAT = NONE;
+       USE_GENERATED_PHYSICAL_CONSTRAINTS = ON;
+       RESYNTHESIS_PHYSICAL_SYNTHESIS = NORMAL;
+       RESYNTHESIS_OPTIMIZATION_EFFORT = NORMAL;
+       RESYNTHESIS_RETIMING = FULL;
+}
+EDA_TOOL_SETTINGS(eda_formal_verification)
+{
+       EDA_INCLUDE_VHDL_CONFIGURATION_DECLARATION = OFF;
+       EDA_TRUNCATE_LONG_HIERARCHY_PATHS = OFF;
+       EDA_MAINTAIN_DESIGN_HIERARCHY = OFF;
+       EDA_WRITE_DEVICE_CONTROL_PORTS = OFF;
+       EDA_GENERATE_FUNCTIONAL_NETLIST = OFF;
+       EDA_FLATTEN_BUSES = OFF;
+       EDA_MAP_ILLEGAL_CHARACTERS = OFF;
+       EDA_EXCALIBUR_ATOMS_AS_SINGLE_STRIPE = OFF;
+       EDA_RUN_TOOL_AUTOMATICALLY = OFF;
+       EDA_OUTPUT_DATA_FORMAT = NONE;
+       USE_GENERATED_PHYSICAL_CONSTRAINTS = ON;
+       RESYNTHESIS_PHYSICAL_SYNTHESIS = NORMAL;
+       RESYNTHESIS_OPTIMIZATION_EFFORT = NORMAL;
+       RESYNTHESIS_RETIMING = FULL;
+}
+EDA_TOOL_SETTINGS(eda_palace)
+{
+       EDA_INCLUDE_VHDL_CONFIGURATION_DECLARATION = OFF;
+       EDA_TRUNCATE_LONG_HIERARCHY_PATHS = OFF;
+       EDA_MAINTAIN_DESIGN_HIERARCHY = OFF;
+       EDA_WRITE_DEVICE_CONTROL_PORTS = OFF;
+       EDA_GENERATE_FUNCTIONAL_NETLIST = OFF;
+       EDA_FLATTEN_BUSES = OFF;
+       EDA_MAP_ILLEGAL_CHARACTERS = OFF;
+       EDA_EXCALIBUR_ATOMS_AS_SINGLE_STRIPE = OFF;
+       EDA_RUN_TOOL_AUTOMATICALLY = OFF;
+       EDA_OUTPUT_DATA_FORMAT = NONE;
+       RESYNTHESIS_RETIMING = FULL;
+       RESYNTHESIS_PHYSICAL_SYNTHESIS = NORMAL;
+       RESYNTHESIS_OPTIMIZATION_EFFORT = NORMAL;
+       USE_GENERATED_PHYSICAL_CONSTRAINTS = ON;
+}
+CLOCK(clk_120mhz)
+{
+       FMAX_REQUIREMENT = "120.0 MHz";
+       INCLUDE_EXTERNAL_PIN_DELAYS_IN_FMAX_CALCULATIONS = OFF;
+       DUTY_CYCLE = 50;
+       DIVIDE_BASE_CLOCK_PERIOD_BY = 1;
+       MULTIPLY_BASE_CLOCK_PERIOD_BY = 1;
+       INVERT_BASE_CLOCK = OFF;
+}
+CLOCK(usbclk)
+{
+       FMAX_REQUIREMENT = "48.0 MHz";
+       INCLUDE_EXTERNAL_PIN_DELAYS_IN_FMAX_CALCULATIONS = OFF;
+       DUTY_CYCLE = 50;
+       DIVIDE_BASE_CLOCK_PERIOD_BY = 1;
+       MULTIPLY_BASE_CLOCK_PERIOD_BY = 1;
+       INVERT_BASE_CLOCK = OFF;
+}
+CLOCK(SCLK)
+{
+       FMAX_REQUIREMENT = "1.0 MHz";
+       INCLUDE_EXTERNAL_PIN_DELAYS_IN_FMAX_CALCULATIONS = OFF;
+       DUTY_CYCLE = 50;
+       DIVIDE_BASE_CLOCK_PERIOD_BY = 1;
+       MULTIPLY_BASE_CLOCK_PERIOD_BY = 1;
+       INVERT_BASE_CLOCK = OFF;
+}
+CLOCK(adclk0)
+{
+       FMAX_REQUIREMENT = "60.0 MHz";
+       INCLUDE_EXTERNAL_PIN_DELAYS_IN_FMAX_CALCULATIONS = OFF;
+       DUTY_CYCLE = 50;
+       DIVIDE_BASE_CLOCK_PERIOD_BY = 1;
+       MULTIPLY_BASE_CLOCK_PERIOD_BY = 1;
+       INVERT_BASE_CLOCK = OFF;
+}
+CLOCK(adclk1)
+{
+       FMAX_REQUIREMENT = "60.0 MHz";
+       INCLUDE_EXTERNAL_PIN_DELAYS_IN_FMAX_CALCULATIONS = OFF;
+       DUTY_CYCLE = 50;
+       DIVIDE_BASE_CLOCK_PERIOD_BY = 1;
+       MULTIPLY_BASE_CLOCK_PERIOD_BY = 1;
+       INVERT_BASE_CLOCK = OFF;
+}
diff --git a/usrp/fpga/toplevel/mrfm/mrfm.py b/usrp/fpga/toplevel/mrfm/mrfm.py
new file mode 100644 (file)
index 0000000..0ce4601
--- /dev/null
@@ -0,0 +1,129 @@
+#!/usr/bin/env python
+#
+# This is mrfm_fft_sos.py
+# Modification of Matt's mrfm_fft.py that reads filter coefs from file
+#
+# 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 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.
+# 
+
+from gnuradio import gr, gru
+from gnuradio import usrp
+
+class source_c(usrp.source_c):
+    def __init__(self,fpga_filename):
+        usrp.source_c.__init__(self,which=0, decim_rate=64, nchan=2, mux=0x32103210, mode=0,
+                               fpga_filename=fpga_filename)
+
+        self._write_9862(0,2,0x80)  # Bypass ADC buffer, minimum gain
+        self._write_9862(0,3,0x80)  # Bypass ADC buffer, minimum gain
+
+        self._write_9862(0,8,0)   # TX PWR Down
+        self._write_9862(0,10,0)  # DAC offset
+        self._write_9862(0,11,0)  # DAC offset
+        self._write_9862(0,14,0x80)  # gain
+        self._write_9862(0,16,0xff)  # pga
+        self._write_9862(0,18,0x0c)  # TX IF
+        self._write_9862(0,19,0x01)  # TX Digital
+        self._write_9862(0,20,0x00)  # TX Mod
+
+        # max/min values are +/-2, so scale is set to make 2 = 32767 
+
+        self._write_fpga_reg(69,0x0e)   # debug mux
+        self._write_fpga_reg(5,-1)
+        self._write_fpga_reg(7,-1)
+        self._write_oe(0,0xffff, 0xffff)
+        self._write_oe(1,0xffff, 0xffff)
+        self._write_fpga_reg(14,0xf)
+
+        self.decim = None
+        
+    def set_coeffs(self,frac_bits,b20,b10,b00,a20,a10,b21,b11,b01,a21,a11):
+        def make_val(address,value):
+            return (address << 16) | (value & 0xffff)
+
+        # gain, scale already included in a's and b's from file
+
+        self._write_fpga_reg(67,make_val(1,b20))
+        self._write_fpga_reg(67,make_val(2,b10))
+        self._write_fpga_reg(67,make_val(3,b00))
+        self._write_fpga_reg(67,make_val(4,a20))
+        self._write_fpga_reg(67,make_val(5,a10))
+        
+        self._write_fpga_reg(67,make_val(7,b21))
+        self._write_fpga_reg(67,make_val(8,b11))
+        self._write_fpga_reg(67,make_val(9,b01))
+        self._write_fpga_reg(67,make_val(10,a21))
+        self._write_fpga_reg(67,make_val(11,a11))
+        
+        self._write_fpga_reg(68,frac_bits)   # Shift
+        
+        print "Biquad 0 : b2=%d b1=%d b0=%d a2=%d a1=%d" % (b20,b10,b00,a20,a10)
+        print "Biquad 1 : b2=%d b1=%d b0=%d a2=%d a1=%d" % (b21,b11,b01,a21,a11)
+
+    def set_decim_rate(self,rate=None):
+        i=2
+        turn=1
+        a=1
+        b=1
+        while (rate>1) and (i<257):
+            if (rate/i) * i == rate:
+                if turn == 1:
+                    if a*i<257:
+                        a = a * i
+                        turn = 0
+                    elif b*i<257:
+                        b = b * i
+                        turn = 0
+                    else:
+                        print "Failed to set DECIMATOR"
+                        return self.decim
+                elif b*i<257:
+                    b = b * i
+                    turn = 1
+                elif a*i<257:
+                    a = a * i
+                    turn = 1
+                else:
+                    print "Failed to set DECIMATOR"
+                    return self.decim
+                rate=rate/i
+                continue
+            i = i + 1
+        if rate > 1:
+            print "Failed to set DECIMATOR"
+            return self.decim
+        else:    
+            self.decim = a*b
+            print "a = %d  b = %d" % (a,b)
+            self._write_fpga_reg(64,(a-1)*256+(b-1))   # Set actual decimation
+
+    def decim_rate(self):
+        return self.decim
+    
+    def set_center_freq(self,freq):
+        self._write_fpga_reg(65,int(-freq/64e6*65536*65536))  # set center freq
+
+    def set_compensator(self,a11,a12,a21,a22,shift):
+        self._write_fpga_reg(70,a11)
+        self._write_fpga_reg(71,a12)
+        self._write_fpga_reg(72,a21)
+        self._write_fpga_reg(73,a22)
+        self._write_fpga_reg(74,shift)   # comp shift
+        
diff --git a/usrp/fpga/toplevel/mrfm/mrfm.qpf b/usrp/fpga/toplevel/mrfm/mrfm.qpf
new file mode 100644 (file)
index 0000000..9591408
--- /dev/null
@@ -0,0 +1,29 @@
+# Copyright (C) 1991-2004 Altera Corporation
+# Any  megafunction  design,  and related netlist (encrypted  or  decrypted),
+# support information,  device programming or simulation file,  and any other
+# associated  documentation or information  provided by  Altera  or a partner
+# under  Altera's   Megafunction   Partnership   Program  may  be  used  only
+# to program  PLD  devices (but not masked  PLD  devices) from  Altera.   Any
+# other  use  of such  megafunction  design,  netlist,  support  information,
+# device programming or simulation file,  or any other  related documentation
+# or information  is prohibited  for  any  other purpose,  including, but not
+# limited to  modification,  reverse engineering,  de-compiling, or use  with
+# any other  silicon devices,  unless such use is  explicitly  licensed under
+# a separate agreement with  Altera  or a megafunction partner.  Title to the
+# intellectual property,  including patents,  copyrights,  trademarks,  trade
+# secrets,  or maskworks,  embodied in any such megafunction design, netlist,
+# support  information,  device programming or simulation file,  or any other
+# related documentation or information provided by  Altera  or a megafunction
+# partner, remains with Altera, the megafunction partner, or their respective
+# licensors. No other licenses, including any licenses needed under any third
+# party's intellectual property, are provided herein.
+
+
+
+QUARTUS_VERSION = "4.0"
+DATE = "17:10:11  December 20, 2004"
+
+
+# Active Revisions
+
+PROJECT_REVISION = "mrfm"
diff --git a/usrp/fpga/toplevel/mrfm/mrfm.qsf b/usrp/fpga/toplevel/mrfm/mrfm.qsf
new file mode 100644 (file)
index 0000000..ba1ae02
--- /dev/null
@@ -0,0 +1,411 @@
+# Copyright (C) 1991-2005 Altera Corporation
+# Your use of Altera Corporation's design tools, logic functions 
+# and other software and tools, and its AMPP partner logic       
+# functions, and any output files any of the foregoing           
+# (including device programming or simulation files), and any    
+# associated documentation or information are expressly subject  
+# to the terms and conditions of the Altera Program License      
+# Subscription Agreement, Altera MegaCore Function License       
+# Agreement, or other applicable license agreement, including,   
+# without limitation, that your use is for the sole purpose of   
+# programming logic devices manufactured by Altera and sold by   
+# Altera or its authorized distributors.  Please refer to the    
+# applicable agreement for further details.
+
+
+# The default values for assignments are stored in the file
+#              mrfm_assignment_defaults.qdf
+# If this file doesn't exist, and for assignments not listed, see file
+#              assignment_defaults.qdf
+
+# Altera recommends that you do not modify this file. This
+# file is updated automatically by the Quartus II software
+# and any changes you make may be lost or overwritten.
+
+
+# Project-Wide Assignments
+# ========================
+set_global_assignment -name ORIGINAL_QUARTUS_VERSION 3.0
+set_global_assignment -name PROJECT_CREATION_TIME_DATE "00:14:04  JULY 13, 2003"
+set_global_assignment -name LAST_QUARTUS_VERSION "5.1 SP2"
+
+# Pin & Location Assignments
+# ==========================
+set_global_assignment -name RESERVE_PIN "AS INPUT TRI-STATED"
+set_location_assignment PIN_29 -to SCLK
+set_location_assignment PIN_117 -to SDI
+set_location_assignment PIN_28 -to usbclk
+set_location_assignment PIN_107 -to usbctl[0]
+set_location_assignment PIN_106 -to usbctl[1]
+set_location_assignment PIN_105 -to usbctl[2]
+set_location_assignment PIN_100 -to usbdata[0]
+set_location_assignment PIN_84 -to usbdata[10]
+set_location_assignment PIN_83 -to usbdata[11]
+set_location_assignment PIN_82 -to usbdata[12]
+set_location_assignment PIN_79 -to usbdata[13]
+set_location_assignment PIN_78 -to usbdata[14]
+set_location_assignment PIN_77 -to usbdata[15]
+set_location_assignment PIN_99 -to usbdata[1]
+set_location_assignment PIN_98 -to usbdata[2]
+set_location_assignment PIN_95 -to usbdata[3]
+set_location_assignment PIN_94 -to usbdata[4]
+set_location_assignment PIN_93 -to usbdata[5]
+set_location_assignment PIN_88 -to usbdata[6]
+set_location_assignment PIN_87 -to usbdata[7]
+set_location_assignment PIN_86 -to usbdata[8]
+set_location_assignment PIN_85 -to usbdata[9]
+set_location_assignment PIN_104 -to usbrdy[0]
+set_location_assignment PIN_101 -to usbrdy[1]
+set_location_assignment PIN_76 -to FX2_1
+set_location_assignment PIN_75 -to FX2_2
+set_location_assignment PIN_74 -to FX2_3
+set_location_assignment PIN_116 -to io_rx_a[0]
+set_location_assignment PIN_115 -to io_rx_a[1]
+set_location_assignment PIN_114 -to io_rx_a[2]
+set_location_assignment PIN_113 -to io_rx_a[3]
+set_location_assignment PIN_108 -to io_rx_a[4]
+set_location_assignment PIN_195 -to io_rx_a[5]
+set_location_assignment PIN_196 -to io_rx_a[6]
+set_location_assignment PIN_197 -to io_rx_a[7]
+set_location_assignment PIN_200 -to io_rx_a[8]
+set_location_assignment PIN_201 -to io_rx_a[9]
+set_location_assignment PIN_202 -to io_rx_a[10]
+set_location_assignment PIN_203 -to io_rx_a[11]
+set_location_assignment PIN_206 -to io_rx_a[12]
+set_location_assignment PIN_207 -to io_rx_a[13]
+set_location_assignment PIN_208 -to io_rx_a[14]
+set_location_assignment PIN_214 -to io_rx_b[0]
+set_location_assignment PIN_215 -to io_rx_b[1]
+set_location_assignment PIN_216 -to io_rx_b[2]
+set_location_assignment PIN_217 -to io_rx_b[3]
+set_location_assignment PIN_218 -to io_rx_b[4]
+set_location_assignment PIN_219 -to io_rx_b[5]
+set_location_assignment PIN_222 -to io_rx_b[6]
+set_location_assignment PIN_223 -to io_rx_b[7]
+set_location_assignment PIN_224 -to io_rx_b[8]
+set_location_assignment PIN_225 -to io_rx_b[9]
+set_location_assignment PIN_226 -to io_rx_b[10]
+set_location_assignment PIN_227 -to io_rx_b[11]
+set_location_assignment PIN_228 -to io_rx_b[12]
+set_location_assignment PIN_233 -to io_rx_b[13]
+set_location_assignment PIN_234 -to io_rx_b[14]
+set_location_assignment PIN_175 -to io_tx_a[0]
+set_location_assignment PIN_176 -to io_tx_a[1]
+set_location_assignment PIN_177 -to io_tx_a[2]
+set_location_assignment PIN_178 -to io_tx_a[3]
+set_location_assignment PIN_179 -to io_tx_a[4]
+set_location_assignment PIN_180 -to io_tx_a[5]
+set_location_assignment PIN_181 -to io_tx_a[6]
+set_location_assignment PIN_182 -to io_tx_a[7]
+set_location_assignment PIN_183 -to io_tx_a[8]
+set_location_assignment PIN_184 -to io_tx_a[9]
+set_location_assignment PIN_185 -to io_tx_a[10]
+set_location_assignment PIN_186 -to io_tx_a[11]
+set_location_assignment PIN_187 -to io_tx_a[12]
+set_location_assignment PIN_188 -to io_tx_a[13]
+set_location_assignment PIN_193 -to io_tx_a[14]
+set_location_assignment PIN_73 -to io_tx_b[0]
+set_location_assignment PIN_68 -to io_tx_b[1]
+set_location_assignment PIN_67 -to io_tx_b[2]
+set_location_assignment PIN_66 -to io_tx_b[3]
+set_location_assignment PIN_65 -to io_tx_b[4]
+set_location_assignment PIN_64 -to io_tx_b[5]
+set_location_assignment PIN_63 -to io_tx_b[6]
+set_location_assignment PIN_62 -to io_tx_b[7]
+set_location_assignment PIN_61 -to io_tx_b[8]
+set_location_assignment PIN_60 -to io_tx_b[9]
+set_location_assignment PIN_59 -to io_tx_b[10]
+set_location_assignment PIN_58 -to io_tx_b[11]
+set_location_assignment PIN_57 -to io_tx_b[12]
+set_location_assignment PIN_56 -to io_tx_b[13]
+set_location_assignment PIN_55 -to io_tx_b[14]
+set_location_assignment PIN_152 -to master_clk
+set_location_assignment PIN_144 -to rx_a_a[0]
+set_location_assignment PIN_143 -to rx_a_a[1]
+set_location_assignment PIN_141 -to rx_a_a[2]
+set_location_assignment PIN_140 -to rx_a_a[3]
+set_location_assignment PIN_139 -to rx_a_a[4]
+set_location_assignment PIN_138 -to rx_a_a[5]
+set_location_assignment PIN_137 -to rx_a_a[6]
+set_location_assignment PIN_136 -to rx_a_a[7]
+set_location_assignment PIN_135 -to rx_a_a[8]
+set_location_assignment PIN_134 -to rx_a_a[9]
+set_location_assignment PIN_133 -to rx_a_a[10]
+set_location_assignment PIN_132 -to rx_a_a[11]
+set_location_assignment PIN_23 -to rx_a_b[0]
+set_location_assignment PIN_21 -to rx_a_b[1]
+set_location_assignment PIN_20 -to rx_a_b[2]
+set_location_assignment PIN_19 -to rx_a_b[3]
+set_location_assignment PIN_18 -to rx_a_b[4]
+set_location_assignment PIN_17 -to rx_a_b[5]
+set_location_assignment PIN_16 -to rx_a_b[6]
+set_location_assignment PIN_15 -to rx_a_b[7]
+set_location_assignment PIN_14 -to rx_a_b[8]
+set_location_assignment PIN_13 -to rx_a_b[9]
+set_location_assignment PIN_12 -to rx_a_b[10]
+set_location_assignment PIN_11 -to rx_a_b[11]
+set_location_assignment PIN_131 -to rx_b_a[0]
+set_location_assignment PIN_128 -to rx_b_a[1]
+set_location_assignment PIN_127 -to rx_b_a[2]
+set_location_assignment PIN_126 -to rx_b_a[3]
+set_location_assignment PIN_125 -to rx_b_a[4]
+set_location_assignment PIN_124 -to rx_b_a[5]
+set_location_assignment PIN_123 -to rx_b_a[6]
+set_location_assignment PIN_122 -to rx_b_a[7]
+set_location_assignment PIN_121 -to rx_b_a[8]
+set_location_assignment PIN_120 -to rx_b_a[9]
+set_location_assignment PIN_119 -to rx_b_a[10]
+set_location_assignment PIN_118 -to rx_b_a[11]
+set_location_assignment PIN_8 -to rx_b_b[0]
+set_location_assignment PIN_7 -to rx_b_b[1]
+set_location_assignment PIN_6 -to rx_b_b[2]
+set_location_assignment PIN_5 -to rx_b_b[3]
+set_location_assignment PIN_4 -to rx_b_b[4]
+set_location_assignment PIN_3 -to rx_b_b[5]
+set_location_assignment PIN_2 -to rx_b_b[6]
+set_location_assignment PIN_240 -to rx_b_b[7]
+set_location_assignment PIN_239 -to rx_b_b[8]
+set_location_assignment PIN_238 -to rx_b_b[9]
+set_location_assignment PIN_237 -to rx_b_b[10]
+set_location_assignment PIN_236 -to rx_b_b[11]
+set_location_assignment PIN_156 -to SDO
+set_location_assignment PIN_153 -to SEN_FPGA
+set_location_assignment PIN_159 -to tx_a[0]
+set_location_assignment PIN_160 -to tx_a[1]
+set_location_assignment PIN_161 -to tx_a[2]
+set_location_assignment PIN_162 -to tx_a[3]
+set_location_assignment PIN_163 -to tx_a[4]
+set_location_assignment PIN_164 -to tx_a[5]
+set_location_assignment PIN_165 -to tx_a[6]
+set_location_assignment PIN_166 -to tx_a[7]
+set_location_assignment PIN_167 -to tx_a[8]
+set_location_assignment PIN_168 -to tx_a[9]
+set_location_assignment PIN_169 -to tx_a[10]
+set_location_assignment PIN_170 -to tx_a[11]
+set_location_assignment PIN_173 -to tx_a[12]
+set_location_assignment PIN_174 -to tx_a[13]
+set_location_assignment PIN_38 -to tx_b[0]
+set_location_assignment PIN_39 -to tx_b[1]
+set_location_assignment PIN_41 -to tx_b[2]
+set_location_assignment PIN_42 -to tx_b[3]
+set_location_assignment PIN_43 -to tx_b[4]
+set_location_assignment PIN_44 -to tx_b[5]
+set_location_assignment PIN_45 -to tx_b[6]
+set_location_assignment PIN_46 -to tx_b[7]
+set_location_assignment PIN_47 -to tx_b[8]
+set_location_assignment PIN_48 -to tx_b[9]
+set_location_assignment PIN_49 -to tx_b[10]
+set_location_assignment PIN_50 -to tx_b[11]
+set_location_assignment PIN_53 -to tx_b[12]
+set_location_assignment PIN_54 -to tx_b[13]
+set_location_assignment PIN_158 -to TXSYNC_A
+set_location_assignment PIN_37 -to TXSYNC_B
+set_location_assignment PIN_235 -to io_rx_b[15]
+set_location_assignment PIN_24 -to io_tx_b[15]
+set_location_assignment PIN_213 -to io_rx_a[15]
+set_location_assignment PIN_194 -to io_tx_a[15]
+set_location_assignment PIN_1 -to MYSTERY_SIGNAL
+
+# Timing Assignments
+# ==================
+set_global_assignment -name INCLUDE_EXTERNAL_PIN_DELAYS_IN_FMAX_CALCULATIONS OFF
+
+# Analysis & Synthesis Assignments
+# ================================
+set_global_assignment -name SAVE_DISK_SPACE OFF
+set_global_assignment -name DEVICE_FILTER_PACKAGE "ANY QFP"
+set_global_assignment -name DEVICE_FILTER_PIN_COUNT 240
+set_global_assignment -name EDA_DESIGN_ENTRY_SYNTHESIS_TOOL "<None>"
+set_global_assignment -name FAMILY Cyclone
+set_global_assignment -name CYCLONE_OPTIMIZATION_TECHNIQUE SPEED
+set_global_assignment -name STRATIX_OPTIMIZATION_TECHNIQUE SPEED
+set_global_assignment -name APEX20K_OPTIMIZATION_TECHNIQUE SPEED
+set_global_assignment -name TOP_LEVEL_ENTITY mrfm
+set_global_assignment -name VHDL_SHOW_LMF_MAPPING_MESSAGES OFF
+set_global_assignment -name USER_LIBRARIES "e:\\usrp\\fpga\\megacells"
+set_global_assignment -name AUTO_ENABLE_SMART_COMPILE ON
+
+# Fitter Assignments
+# ==================
+set_global_assignment -name DEVICE EP1C12Q240C8
+set_global_assignment -name CYCLONE_CONFIGURATION_SCHEME "PASSIVE SERIAL"
+set_global_assignment -name RESERVE_ALL_UNUSED_PINS "AS INPUT TRI-STATED"
+set_global_assignment -name OPTIMIZE_HOLD_TIMING OFF
+set_global_assignment -name OPTIMIZE_TIMING "NORMAL COMPILATION"
+set_global_assignment -name PHYSICAL_SYNTHESIS_COMBO_LOGIC ON
+set_global_assignment -name PHYSICAL_SYNTHESIS_REGISTER_DUPLICATION ON
+set_global_assignment -name PHYSICAL_SYNTHESIS_REGISTER_RETIMING ON
+set_global_assignment -name IO_PLACEMENT_OPTIMIZATION OFF
+set_global_assignment -name PHYSICAL_SYNTHESIS_EFFORT EXTRA
+set_global_assignment -name INC_PLC_MODE OFF
+set_global_assignment -name ROUTING_BACK_ANNOTATION_MODE OFF
+set_instance_assignment -name IO_STANDARD LVTTL -to usbdata[12]
+set_global_assignment -name STRATIX_DEVICE_IO_STANDARD LVTTL
+set_global_assignment -name ERROR_CHECK_FREQUENCY_DIVISOR 1
+
+# Timing Analysis Assignments
+# ===========================
+set_global_assignment -name MAX_SCC_SIZE 50
+
+# EDA Netlist Writer Assignments
+# ==============================
+set_global_assignment -name EDA_SIMULATION_TOOL "<None>"
+set_global_assignment -name EDA_TIMING_ANALYSIS_TOOL "<NONE>"
+set_global_assignment -name EDA_BOARD_DESIGN_TOOL "<NONE>"
+set_global_assignment -name EDA_FORMAL_VERIFICATION_TOOL "<NONE>"
+set_global_assignment -name EDA_RESYNTHESIS_TOOL "<NONE>"
+
+# Assembler Assignments
+# =====================
+set_global_assignment -name USE_CONFIGURATION_DEVICE OFF
+set_global_assignment -name GENERATE_RBF_FILE ON
+set_global_assignment -name RESERVE_ALL_UNUSED_PINS_NO_OUTPUT_GND "AS INPUT TRI-STATED"
+set_global_assignment -name AUTO_RESTART_CONFIGURATION OFF
+
+# Simulator Assignments
+# =====================
+set_global_assignment -name START_TIME "0 ns"
+set_global_assignment -name GLITCH_INTERVAL "1 ns"
+
+# Design Assistant Assignments
+# ============================
+set_global_assignment -name DRC_REPORT_TOP_FANOUT OFF
+set_global_assignment -name DRC_REPORT_FANOUT_EXCEEDING OFF
+set_global_assignment -name ASSG_CAT OFF
+set_global_assignment -name ASSG_RULE_MISSING_FMAX OFF
+set_global_assignment -name ASSG_RULE_MISSING_TIMING OFF
+set_global_assignment -name NONSYNCHSTRUCT_RULE_ASYN_RAM OFF
+set_global_assignment -name CLK_CAT OFF
+set_global_assignment -name CLK_RULE_COMB_CLOCK OFF
+set_global_assignment -name CLK_RULE_INV_CLOCK OFF
+set_global_assignment -name CLK_RULE_GATING_SCHEME OFF
+set_global_assignment -name CLK_RULE_INPINS_CLKNET OFF
+set_global_assignment -name CLK_RULE_CLKNET_CLKSPINES OFF
+set_global_assignment -name CLK_RULE_MIX_EDGES OFF
+set_global_assignment -name RESET_CAT OFF
+set_global_assignment -name RESET_RULE_INPINS_RESETNET OFF
+set_global_assignment -name RESET_RULE_UNSYNCH_EXRESET OFF
+set_global_assignment -name RESET_RULE_IMSYNCH_EXRESET OFF
+set_global_assignment -name RESET_RULE_COMB_ASYNCH_RESET OFF
+set_global_assignment -name RESET_RULE_UNSYNCH_ASYNCH_DOMAIN OFF
+set_global_assignment -name RESET_RULE_IMSYNCH_ASYNCH_DOMAIN OFF
+set_global_assignment -name TIMING_CAT OFF
+set_global_assignment -name TIMING_RULE_SHIFT_REG OFF
+set_global_assignment -name TIMING_RULE_COIN_CLKEDGE OFF
+set_global_assignment -name NONSYNCHSTRUCT_RULE_COMB_DRIVES_RAM_WE OFF
+set_global_assignment -name NONSYNCHSTRUCT_CAT OFF
+set_global_assignment -name NONSYNCHSTRUCT_RULE_COMBLOOP OFF
+set_global_assignment -name NONSYNCHSTRUCT_RULE_REG_LOOP OFF
+set_global_assignment -name NONSYNCHSTRUCT_RULE_DELAY_CHAIN OFF
+set_global_assignment -name NONSYNCHSTRUCT_RULE_RIPPLE_CLK OFF
+set_global_assignment -name NONSYNCHSTRUCT_RULE_ILLEGAL_PULSE_GEN OFF
+set_global_assignment -name NONSYNCHSTRUCT_RULE_MULTI_VIBRATOR OFF
+set_global_assignment -name NONSYNCHSTRUCT_RULE_SRLATCH OFF
+set_global_assignment -name NONSYNCHSTRUCT_RULE_LATCH_UNIDENTIFIED OFF
+set_global_assignment -name SIGNALRACE_CAT OFF
+set_global_assignment -name ACLK_CAT OFF
+set_global_assignment -name ACLK_RULE_NO_SZER_ACLK_DOMAIN OFF
+set_global_assignment -name ACLK_RULE_SZER_BTW_ACLK_DOMAIN OFF
+set_global_assignment -name ACLK_RULE_IMSZER_ADOMAIN OFF
+set_global_assignment -name HCPY_CAT OFF
+set_global_assignment -name HCPY_VREF_PINS OFF
+
+# SignalTap II Assignments
+# ========================
+set_global_assignment -name HUB_ENTITY_NAME SLD_HUB
+set_global_assignment -name HUB_INSTANCE_NAME SLD_HUB_INST
+set_global_assignment -name ENABLE_SIGNALTAP OFF
+
+# LogicLock Region Assignments
+# ============================
+set_global_assignment -name LOGICLOCK_INCREMENTAL_COMPILE_ASSIGNMENT OFF
+
+# -----------------
+# start CLOCK(SCLK)
+
+       # Timing Assignments
+       # ==================
+set_global_assignment -name DUTY_CYCLE 50 -section_id SCLK
+set_global_assignment -name FMAX_REQUIREMENT "1 MHz" -section_id SCLK
+set_global_assignment -name INCLUDE_EXTERNAL_PIN_DELAYS_IN_FMAX_CALCULATIONS OFF -section_id SCLK
+
+# end CLOCK(SCLK)
+# ---------------
+
+# -----------------------
+# start CLOCK(master_clk)
+
+       # Timing Assignments
+       # ==================
+set_global_assignment -name DUTY_CYCLE 50 -section_id master_clk
+set_global_assignment -name FMAX_REQUIREMENT "64 MHz" -section_id master_clk
+set_global_assignment -name INCLUDE_EXTERNAL_PIN_DELAYS_IN_FMAX_CALCULATIONS OFF -section_id master_clk
+
+# end CLOCK(master_clk)
+# ---------------------
+
+# -------------------
+# start CLOCK(usbclk)
+
+       # Timing Assignments
+       # ==================
+set_global_assignment -name DUTY_CYCLE 50 -section_id usbclk
+set_global_assignment -name FMAX_REQUIREMENT "48 MHz" -section_id usbclk
+set_global_assignment -name INCLUDE_EXTERNAL_PIN_DELAYS_IN_FMAX_CALCULATIONS OFF -section_id usbclk
+
+# end CLOCK(usbclk)
+# -----------------
+
+# ----------------------
+# start ENTITY(mrfm)
+
+       # Timing Assignments
+       # ==================
+set_instance_assignment -name CLOCK_SETTINGS SCLK -to SCLK
+set_instance_assignment -name CLOCK_SETTINGS usbclk -to usbclk
+set_instance_assignment -name CLOCK_SETTINGS master_clk -to master_clk
+
+# end ENTITY(mrfm)
+# --------------------
+
+
+set_global_assignment -name PHYSICAL_SYNTHESIS_ASYNCHRONOUS_SIGNAL_PIPELINING ON
+set_global_assignment -name SMART_RECOMPILE ON
+set_global_assignment -name VERILOG_FILE mrfm.vh
+set_global_assignment -name VERILOG_FILE biquad_2stage.v
+set_global_assignment -name VERILOG_FILE mrfm_compensator.v
+set_global_assignment -name VERILOG_FILE ../../sdr_lib/ram16.v
+set_global_assignment -name VERILOG_FILE mrfm_proc.v
+set_global_assignment -name VERILOG_FILE ../../megacells/fifo_4k.v
+set_global_assignment -name VERILOG_FILE ../../sdr_lib/hb/acc.v
+set_global_assignment -name VERILOG_FILE ../../sdr_lib/hb/mult.v
+set_global_assignment -name VERILOG_FILE ../../sdr_lib/hb/ram16_2sum.v
+set_global_assignment -name VERILOG_FILE ../../sdr_lib/hb/coeff_rom.v
+set_global_assignment -name VERILOG_FILE ../../sdr_lib/hb/halfband_decim.v
+set_global_assignment -name VERILOG_FILE ../../sdr_lib/hb/mac.v
+set_global_assignment -name VERILOG_FILE ../../sdr_lib/hb/coeff_ram.v
+set_global_assignment -name VERILOG_FILE ../../sdr_lib/tx_chain.v
+set_global_assignment -name VERILOG_FILE ../../sdr_lib/rx_dcoffset.v
+set_global_assignment -name VERILOG_FILE ../../sdr_lib/adc_interface.v
+set_global_assignment -name VERILOG_FILE ../../sdr_lib/io_pins.v
+set_global_assignment -name VERILOG_FILE ../../sdr_lib/setting_reg.v
+set_global_assignment -name VERILOG_FILE ../../sdr_lib/bidir_reg.v
+set_global_assignment -name VERILOG_FILE ../../sdr_lib/cic_int_shifter.v
+set_global_assignment -name VERILOG_FILE ../../megacells/clk_doubler.v
+set_global_assignment -name VERILOG_FILE ../../sdr_lib/gen_sync.v
+set_global_assignment -name VERILOG_FILE ../../sdr_lib/master_control.v
+set_global_assignment -name VERILOG_FILE ../../megacells/fifo_2k.v
+set_global_assignment -name VERILOG_FILE ../../megacells/bustri.v
+set_global_assignment -name VERILOG_FILE ../../sdr_lib/rx_buffer.v
+set_global_assignment -name VERILOG_FILE ../../sdr_lib/tx_buffer.v
+set_global_assignment -name VERILOG_FILE ../../sdr_lib/phase_acc.v
+set_global_assignment -name VERILOG_FILE ../../sdr_lib/cic_interp.v
+set_global_assignment -name VERILOG_FILE ../../sdr_lib/cic_decim.v
+set_global_assignment -name VERILOG_FILE ../../sdr_lib/cordic_stage.v
+set_global_assignment -name VERILOG_FILE ../../sdr_lib/cordic.v
+set_global_assignment -name VERILOG_FILE mrfm.v
+set_global_assignment -name VERILOG_FILE ../../sdr_lib/clk_divider.v
+set_global_assignment -name VERILOG_FILE ../../sdr_lib/serial_io.v
+set_global_assignment -name VERILOG_FILE ../../sdr_lib/strobe_gen.v
+set_global_assignment -name VERILOG_FILE ../../sdr_lib/sign_extend.v
+set_global_assignment -name FITTER_EFFORT "STANDARD FIT"
\ No newline at end of file
diff --git a/usrp/fpga/toplevel/mrfm/mrfm.v b/usrp/fpga/toplevel/mrfm/mrfm.v
new file mode 100644 (file)
index 0000000..cf9d111
--- /dev/null
@@ -0,0 +1,199 @@
+// -*- verilog -*-
+//
+//  USRP - Universal Software Radio Peripheral
+//
+//  Copyright (C) 2006 Matt Ettus
+//
+//  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
+//
+
+// Top level module for a full setup with DUCs and DDCs
+
+// Uncomment the following to include optional circuitry
+
+`include "mrfm.vh"
+`include "../../../firmware/include/fpga_regs_common.v"
+`include "../../../firmware/include/fpga_regs_standard.v"
+
+module mrfm
+(output MYSTERY_SIGNAL,
+ input master_clk,
+ input SCLK,
+ input SDI,
+ inout SDO,
+ input SEN_FPGA,
+
+ input FX2_1,
+ output FX2_2,
+ output FX2_3,
+ input wire [11:0] rx_a_a,
+ input wire [11:0] rx_b_a,
+ input wire [11:0] rx_a_b,
+ input wire [11:0] rx_b_b,
+ output wire [13:0] tx_a,
+ output wire [13:0] tx_b,
+ output wire TXSYNC_A,
+ output wire TXSYNC_B,
+ // USB interface
+ input usbclk,
+ input wire [2:0] usbctl,
+ output wire [1:0] usbrdy,
+ inout [15:0] usbdata,  // NB Careful, inout
+ // These are the general purpose i/o's that go to the daughterboard slots
+ inout wire [15:0] io_tx_a,
+ inout wire [15:0] io_tx_b,
+ inout wire [15:0] io_rx_a,
+ inout wire [15:0] io_rx_b
+ );    
+   wire [15:0] debugdata,debugctrl;
+   assign MYSTERY_SIGNAL = 1'b0;
+   
+   wire clk64;
+   
+   wire WR = usbctl[0];
+   wire RD = usbctl[1];
+   wire OE = usbctl[2];
+
+   wire have_space, have_pkt_rdy;
+   assign usbrdy[0] = have_space;
+   assign usbrdy[1] = have_pkt_rdy;
+
+   wire   tx_underrun, rx_overrun;    
+   wire   clear_status = FX2_1;
+   assign FX2_2 = rx_overrun;
+   assign FX2_3 = tx_underrun;
+      
+   wire [15:0] usbdata_out;
+   
+   wire [3:0]  dac0mux,dac1mux,dac2mux,dac3mux;
+   
+   wire        tx_realsignals;
+   wire [3:0]  rx_numchan;
+   
+   wire [15:0] tx_debugbus, rx_debugbus;
+   
+   wire        enable_tx, enable_rx;
+   wire        tx_dsp_reset, rx_dsp_reset, tx_bus_reset, rx_bus_reset;
+   wire [7:0]  settings;
+   
+   // Tri-state bus macro
+   bustri bustri( .data(usbdata_out),.enabledt(OE),.tridata(usbdata) );
+
+   assign      clk64 = master_clk;
+
+   wire [15:0] ch0tx,ch1tx,ch2tx,ch3tx; 
+   wire [15:0] ch0rx,ch1rx,ch2rx,ch3rx,ch4rx,ch5rx,ch6rx,ch7rx;
+   
+   wire        serial_strobe;
+   wire [6:0]  serial_addr;
+   wire [31:0] serial_data;
+   
+   /////////////////////////////////////////////////////////////////////////////////////////////////////
+   
+   setting_reg #(`FR_TX_MUX) 
+     sr_txmux(.clock(clk64),.reset(tx_dsp_reset),.strobe(serial_strobe),.addr(serial_addr),.in(serial_data),
+             .out({dac3mux,dac2mux,dac1mux,dac0mux,tx_realsignals,tx_numchan}));
+      
+   //////////////////////////////////////////////////////////////////////////////////////////////////////
+   // Signal Processing Chain
+
+   reg [15:0]  adc0;
+   wire [15:0] dac0;
+   wire [15:0] i,q,ip,qp;
+   wire        strobe_out;
+   wire        sync_out;
+   
+   always @(posedge clk64)
+     adc0 <= #1 {rx_a_a[11],rx_a_a[11:0],3'b0};
+
+   wire [15:0] adc0_corr;
+   rx_dcoffset #(0)rx_dcoffset0(.clock(clk64),.enable(1'b1),.reset(reset),.adc_in(adc0),.adc_out(adc0_corr),
+       .serial_addr(7'd0),.serial_data(32'd0),.serial_strobe(1'b0));
+
+   //wire [63:0] filt_debug = 64'd0;
+   
+   mrfm_proc mrfm_proc(.clock(clk64),.reset(rx_dsp_reset),.enable(enable_rx),
+                      .serial_addr(serial_addr),.serial_data(serial_data),.serial_strobe(serial_strobe),
+                      .signal_in(adc0_corr),.signal_out(dac0),.sync_out(sync_out),
+                      .i(i),.q(q),.ip(ip),.qp(qp),.strobe_out(strobe_out),
+                      .debugbus( /* filt_debug */ ));
+          
+   wire txsync = 1'b0;
+   assign TXSYNC_A = txsync;
+   assign TXSYNC_B = txsync;
+
+   assign tx_a = dac0[15:2];
+
+   //////////////////////////////////////////////////////////////////////////////////////////////////
+   //  Data Collection on RX Buffer
+
+   assign     rx_numchan[0] = 1'b0;
+   setting_reg #(`FR_RX_MUX) sr_rxmux(.clock(clk64),.reset(rx_dsp_reset),.strobe(serial_strobe),.addr(serial_addr),
+                                     .in(serial_data),.out(rx_numchan[3:1]));
+   
+   rx_buffer rx_buffer
+     ( .usbclk(usbclk),.bus_reset(rx_bus_reset),.reset(rx_dsp_reset),
+       .usbdata(usbdata_out),.RD(RD),.have_pkt_rdy(have_pkt_rdy),.rx_overrun(rx_overrun),
+       .channels(rx_numchan),
+       .ch_0(i),.ch_1(q),
+       .ch_2(ip),.ch_3(qp),
+       .ch_4(16'd0),.ch_5(16'd0),
+       .ch_6(16'd0),.ch_7(16'd0),
+       .rxclk(clk64),.rxstrobe(strobe_out),
+       .clear_status(clear_status),
+       .serial_addr(serial_addr),.serial_data(serial_data),.serial_strobe(serial_strobe),
+       .debugbus(rx_debugbus) );
+   
+   //////////////////////////////////////////////////////////////////////////////
+   // Control Functions
+       
+   wire [31:0] capabilities = 32'd2;
+
+   serial_io serial_io
+     ( .master_clk(clk64),.serial_clock(SCLK),.serial_data_in(SDI),
+       .enable(SEN_FPGA),.reset(1'b0),.serial_data_out(SDO),
+       .serial_addr(serial_addr),.serial_data(serial_data),.serial_strobe(serial_strobe),
+       .readback_0({io_rx_a,io_tx_a}),.readback_1({io_rx_b,io_tx_b}),.readback_2(capabilities),.readback_3(32'hf0f0931a) );
+
+   wire [15:0] reg_0,reg_1,reg_2,reg_3;
+   master_control master_control
+     ( .master_clk(clk64),.usbclk(usbclk),
+       .serial_addr(serial_addr),.serial_data(serial_data),.serial_strobe(serial_strobe),
+       .tx_bus_reset(tx_bus_reset),.rx_bus_reset(rx_bus_reset),
+       .tx_dsp_reset(tx_dsp_reset),.rx_dsp_reset(rx_dsp_reset),
+       .enable_tx(enable_tx),.enable_rx(enable_rx),
+       .interp_rate(interp_rate),.decim_rate(decim_rate),
+       .tx_sample_strobe(tx_sample_strobe),.strobe_interp(strobe_interp),
+       .rx_sample_strobe(rx_sample_strobe),.strobe_decim(strobe_decim),
+       .tx_empty(tx_empty),
+       .debug_0({15'd0,sync_out}), //filt_debug[63:48]),
+       .debug_1({15'd0,sync_out}), //filt_debug[47:32]),
+       .debug_2({15'd0,sync_out}), //filt_debug[31:16]),
+       .debug_3({15'd0,sync_out}), //filt_debug[15:0]),
+       .reg_0(reg_0),.reg_1(reg_1),.reg_2(reg_2),.reg_3(reg_3) );
+   
+   io_pins io_pins
+     (.io_0(io_tx_a),.io_1(io_rx_a),.io_2(io_tx_b),.io_3(io_rx_b),
+      .reg_0(reg_0),.reg_1(reg_1),.reg_2(reg_2),.reg_3(reg_3),
+      .clock(clk64),.rx_reset(rx_dsp_reset),.tx_reset(tx_dsp_reset),
+      .serial_addr(serial_addr),.serial_data(serial_data),.serial_strobe(serial_strobe));
+   
+endmodule // mrfm
+
diff --git a/usrp/fpga/toplevel/mrfm/mrfm.vh b/usrp/fpga/toplevel/mrfm/mrfm.vh
new file mode 100644 (file)
index 0000000..808342d
--- /dev/null
@@ -0,0 +1,21 @@
+
+
+//   MRFM Register defines
+
+`define FR_MRFM_DECIM             7'd64
+`define FR_MRFM_FREQ              7'd65
+`define FR_MRFM_PHASE             7'd66
+`define FR_MRFM_IIR_COEFF         7'd67
+`define FR_MRFM_IIR_SHIFT         7'd68
+`define FR_MRFM_DEBUG             7'd69
+`define FR_MRFM_COMP_A11          7'd70
+`define FR_MRFM_COMP_A12          7'd71
+`define FR_MRFM_COMP_A21          7'd72
+`define FR_MRFM_COMP_A22          7'd73
+`define FR_MRFM_COMP_SHIFT        7'd74
+`define FR_USER_11                7'd75
+`define FR_USER_12                7'd76
+`define FR_USER_13                7'd77
+`define FR_USER_14                7'd78
+`define FR_USER_15                7'd79
+
diff --git a/usrp/fpga/toplevel/mrfm/mrfm_compensator.v b/usrp/fpga/toplevel/mrfm/mrfm_compensator.v
new file mode 100644 (file)
index 0000000..f44b73b
--- /dev/null
@@ -0,0 +1,80 @@
+
+
+module mrfm_compensator (input clock, input reset, input strobe_in,
+                        input serial_strobe, input [6:0] serial_addr, input [31:0] serial_data,
+                        input [15:0] i_in, input [15:0] q_in, output reg [15:0] i_out, output reg [15:0] q_out);
+
+   wire [15:0]                               a11,a12,a21,a22;
+   reg [15:0]                        i_in_reg, q_in_reg;
+   wire [30:0]                               product;
+   reg [3:0]                         phase;
+   wire [15:0]                               data,coeff;
+   wire [7:0]                        shift;
+   wire [33:0]                               accum;
+   wire [15:0]                               scaled_accum;
+   wire enable_acc;
+
+   setting_reg #(`FR_MRFM_COMP_A11) sr_a11(.clock(clock),.reset(reset),
+                                          .strobe(serial_strobe),.addr(serial_addr),.in(serial_data),
+                                          .out(a11),.changed());
+   setting_reg #(`FR_MRFM_COMP_A12) sr_a12(.clock(clock),.reset(reset),
+                                          .strobe(serial_strobe),.addr(serial_addr),.in(serial_data),
+                                          .out(a12),.changed());
+   setting_reg #(`FR_MRFM_COMP_A21) sr_a21(.clock(clock),.reset(reset),
+                                          .strobe(serial_strobe),.addr(serial_addr),.in(serial_data),
+                                          .out(a21),.changed());
+   setting_reg #(`FR_MRFM_COMP_A22) sr_a22(.clock(clock),.reset(reset),
+                                          .strobe(serial_strobe),.addr(serial_addr),.in(serial_data),
+                                          .out(a22),.changed());
+   setting_reg #(`FR_MRFM_COMP_SHIFT) sr_cshift(.clock(clock),.reset(reset),
+                                               .strobe(serial_strobe),.addr(serial_addr),.in(serial_data),
+                                               .out(shift),.changed());
+   
+   mult mult (.clock(clock),.x(data),.y(coeff),.product(product),.enable_in(1'b1),.enable_out() );
+   acc acc (.clock(clock),.reset(reset),.clear(clear_acc),.enable_in(enable_acc),.enable_out(),
+           .addend(product),.sum(accum) );   
+   shifter shifter (.in(accum),.out(scaled_accum),.shift(shift));
+   
+   always @(posedge clock)
+     if(reset)
+       begin
+         i_in_reg <= #1 16'd0;
+         q_in_reg <= #1 16'd0;
+       end
+     else if(strobe_in)
+       begin
+         i_in_reg <= #1 i_in;
+         q_in_reg <= #1 q_in;
+       end       
+
+   always @(posedge clock)
+     if(reset)
+       phase <= #1 4'd0;
+     else if(strobe_in)
+       phase <= #1 4'd1;
+     else if(strobe_in != 4'd8)
+       phase <= #1 phase + 4'd1;
+
+   assign data = ((phase == 4'd1)||(phase === 4'd4)) ? i_in_reg : 
+         ((phase == 4'd2)||(phase == 4'd5)) ? q_in_reg : 16'd0;
+
+   assign coeff = (phase == 4'd1) ? a11 : (phase == 4'd2) ? a12 : 
+         (phase == 4'd4) ? a21 : (phase == 4'd5) ? a22 : 16'd0;
+
+   assign clear_acc = (phase == 4'd0) || (phase == 4'd1) || (phase == 4'd4) || (phase==4'd8);
+   assign enable_acc = ~clear_acc;
+   
+   always @(posedge clock)
+     if(reset)
+       i_out <= #1 16'd0;
+     else if(phase == 4'd4)
+       i_out <= #1 scaled_accum;
+
+   always @(posedge clock)
+     if(reset)
+       q_out <= #1 16'd0;
+     else if(phase == 4'd7)
+       q_out <= #1 scaled_accum;
+   
+       
+endmodule // mrfm_compensator
diff --git a/usrp/fpga/toplevel/mrfm/mrfm_fft.py b/usrp/fpga/toplevel/mrfm/mrfm_fft.py
new file mode 100755 (executable)
index 0000000..343ab01
--- /dev/null
@@ -0,0 +1,319 @@
+#!/usr/bin/env python
+#
+# This is mrfm_fft_sos.py
+# Modification of Matt's mrfm_fft.py that reads filter coefs from file
+#
+# 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 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.
+# 
+
+from gnuradio import gr, gru
+from gnuradio import usrp
+from gnuradio import eng_notation
+from gnuradio.eng_option import eng_option
+from gnuradio.wxgui import stdgui, fftsink, waterfallsink, scopesink, form, slider
+from optparse import OptionParser
+import wx
+import sys
+import mrfm
+
+
+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)
+
+def read_ints(filename):
+    try:
+        f = open(filename)
+        ints = [ int(i) for i in f.read().split() ]
+        f.close()
+        return ints
+    except:
+        return []
+
+class app_flow_graph(stdgui.gui_flow_graph):
+    def __init__(self, frame, panel, vbox, argv):
+        stdgui.gui_flow_graph.__init__(self)
+
+        self.frame = frame
+        self.panel = panel
+        
+        parser = OptionParser(option_class=eng_option)
+        parser.add_option("-R", "--rx-subdev-spec", type="subdev", default=None,
+                          help="select USRP Rx side A or B (default=first one with a daughterboard)")
+        parser.add_option("-d", "--decim", type="int", default=16,
+                          help="set fgpa decimation rate to DECIM [default=%default]")
+        parser.add_option("-f", "--freq", type="eng_float", default=None,
+                          help="set frequency to FREQ", metavar="FREQ")
+        parser.add_option("-g", "--gain", type="eng_float", default=None,
+                          help="set gain in dB (default is midpoint)")
+        parser.add_option("-W", "--waterfall", action="store_true", default=False,
+                          help="Enable waterfall display")
+        parser.add_option("-8", "--width-8", action="store_true", default=False,
+                          help="Enable 8-bit samples across USB")
+        parser.add_option("-S", "--oscilloscope", action="store_true", default=False,
+                          help="Enable oscilloscope display")
+        parser.add_option("-F", "--filename", default=None,
+                          help="Name of file with filter coefficients")
+        parser.add_option("-C", "--cfilename", default=None,
+                          help="Name of file with compensator coefficients")
+        parser.add_option("-B", "--bitstream", default="mrfm.rbf",
+                          help="Name of FPGA Bitstream file (.rbf)")
+        parser.add_option("-n", "--frame-decim", type="int", default=20,
+                          help="set oscope frame decimation factor to n [default=12]")
+        (options, args) = parser.parse_args()
+        if len(args) != 0:
+            parser.print_help()
+            sys.exit(1)
+
+        self.show_debug_info = True
+
+        # default filter coefs
+        b00 = b01 = 16384  
+        b10 = b20 = a10 = a20 = b11 = b21 = a11 = a21 = 0
+
+        ba = read_ints(options.filename)
+        if len(ba) >= 6:
+            b00 = ba[0]; b10 = ba[1]; b20 = ba[2]; a10 = ba[4]; a20 = ba[5]
+        if len(ba) >= 12:
+            b01 = ba[6]; b11 = ba[7]; b21 = ba[8]; a11 = ba[10]; a21=ba[11]
+        print b00, b10, b20, a10, a20, b01, b11, b21, a11, a21 
+
+        # default compensator coefficients
+        c11 = c22 = 1
+        c12 = c21 = cscale = 0
+
+        cs = read_ints(options.cfilename)
+        if len(cs) >= 5:
+            c11 = cs[0]; c12 = cs[1]; c21 = cs[2]; c22 = cs[3]; cscale = cs[4]
+        print c11, c12, c21, c22, cscale
+     
+        # build the graph
+        self.u = mrfm.source_c(options.bitstream)
+
+        self.u.set_decim_rate(options.decim)
+        self.u.set_center_freq(options.freq)
+
+        frac_bits = 14
+        self.u.set_coeffs(frac_bits,b20,b10,b00,a20,a10,b21,b11,b01,a21,a11)
+
+        self.u.set_compensator(c11,c12,c21,c22,cscale)
+
+        if options.rx_subdev_spec is None:
+            options.rx_subdev_spec = pick_subdevice(self.u)
+        self.u.set_mux(usrp.determine_rx_mux_value(self.u, options.rx_subdev_spec))
+
+        if options.width_8:
+            width = 8
+            shift = 8
+            format = self.u.make_format(width, shift)
+            print "format =", hex(format)
+            r = self.u.set_format(format)
+            print "set_format =", r
+            
+        # determine the daughterboard subdevice we're using
+        self.subdev = usrp.selected_subdev(self.u, options.rx_subdev_spec)
+
+        #input_rate = self.u.adc_freq() / self.u.decim_rate()
+        input_rate = self.u.adc_freq() / options.decim
+
+        # fft_rate = 15
+        fft_rate = 5
+                
+        self.deint = gr.deinterleave(gr.sizeof_gr_complex)
+        self.connect(self.u,self.deint)
+        
+        if options.waterfall:
+            self.scope1=waterfallsink.waterfall_sink_c (self, panel, fft_size=1024, sample_rate=input_rate,
+                                                        fft_rate=fft_rate)
+            self.scope2=waterfallsink.waterfall_sink_c (self, panel, fft_size=1024, sample_rate=input_rate,
+                                                        fft_rate=fft_rate)
+
+        elif options.oscilloscope:
+            self.scope1 = scopesink.scope_sink_c(self, panel, sample_rate=input_rate,frame_decim=options.frame_decim) # added option JPJ 4/21/2006
+            self.scope2 = scopesink.scope_sink_c(self, panel, sample_rate=input_rate,frame_decim=options.frame_decim) 
+
+        else:
+            self.scope1 = fftsink.fft_sink_c (self, panel, fft_size=1024, sample_rate=input_rate,
+                                             fft_rate=fft_rate)
+            self.scope2 = fftsink.fft_sink_c (self, panel, fft_size=1024, sample_rate=input_rate,
+                                             fft_rate=fft_rate)
+
+        # Show I, I' on top scope panel, Q, Q' on bottom
+        #self.fin = gr.complex_to_float()
+        #self.fout = gr.complex_to_float()
+
+        #self.connect((self.deint,0), self.fin)
+        #self.connect((self.deint,1), self.fout)
+
+        #self.ii = gr.float_to_complex()
+        #self.qq = gr.float_to_complex()
+        
+        #self.connect((self.fin,0), (self.ii,0))
+        #self.connect((self.fout,0), (self.ii,1))
+        #self.connect((self.fin,1), (self.qq,0))
+        #self.connect((self.fout,1), (self.qq,1))
+        
+        #self.connect(self.ii, self.scope1)
+        #self.connect(self.qq, self.scope2)
+
+        self.connect ((self.deint,0),self.scope1)
+        self.connect ((self.deint,1),self.scope2)
+
+        self._build_gui(vbox)
+
+        # set initial values
+
+        if options.gain is None:
+            # if no gain was specified, use the mid-point in dB
+            g = self.subdev.gain_range()
+            options.gain = float(g[0]+g[1])/2
+
+        if options.freq is None:
+            # if no freq was specified, use the mid-point
+            r = self.subdev.freq_range()
+            options.freq = float(r[0]+r[1])/2
+
+        self.set_gain(options.gain)
+
+        if not(self.set_freq(options.freq)):
+            self._set_status_msg("Failed to set initial frequency")
+
+        if self.show_debug_info:
+            self.myform['decim'].set_value(self.u.decim_rate())
+            self.myform['fs@usb'].set_value(self.u.adc_freq() / self.u.decim_rate())
+            self.myform['dbname'].set_value(self.subdev.name())
+                        
+
+    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.scope1.win, 10, wx.EXPAND)
+        vbox.Add(self.scope2.win, 10, wx.EXPAND)
+        
+        # add control area at the bottom
+        self.myform = myform = form.form()
+        hbox = wx.BoxSizer(wx.HORIZONTAL)
+        hbox.Add((5,0), 0, 0)
+        myform['freq'] = form.float_field(
+            parent=self.panel, sizer=hbox, label="Center freq", weight=1,
+            callback=myform.check_input_and_call(_form_set_freq, self._set_status_msg))
+
+        hbox.Add((5,0), 0, 0)
+        g = self.subdev.gain_range()
+        myform['gain'] = form.slider_field(parent=self.panel, sizer=hbox, label="Gain",
+                                           weight=3,
+                                           min=int(g[0]), max=int(g[1]),
+                                           callback=self.set_gain)
+
+        hbox.Add((5,0), 0, 0)
+        vbox.Add(hbox, 0, wx.EXPAND)
+
+        self._build_subpanel(vbox)
+
+    def _build_subpanel(self, vbox_arg):
+        # build a secondary information panel (sometimes hidden)
+
+        # FIXME figure out how to have this be a subpanel that is always
+        # created, but has its visibility controlled by foo.Show(True/False)
+        
+        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.static_float_field(
+            parent=panel, sizer=hbox, label="Decim")
+
+        hbox.Add((5,0), 1)
+        myform['fs@usb'] = form.static_float_field(
+            parent=panel, sizer=hbox, label="Fs@USB")
+
+        hbox.Add((5,0), 1)
+        myform['dbname'] = form.static_text_field(
+            parent=panel, sizer=hbox)
+
+        hbox.Add((5,0), 1)
+        myform['baseband'] = form.static_float_field(
+            parent=panel, sizer=hbox, label="Analog BB")
+
+        hbox.Add((5,0), 1)
+        myform['ddc'] = form.static_float_field(
+            parent=panel, sizer=hbox, label="DDC")
+
+        hbox.Add((5,0), 0)
+        vbox.Add(hbox, 0, wx.EXPAND)
+
+        
+        
+    def set_freq(self, target_freq):
+        """
+        Set the center frequency we're interested in.
+
+        @param target_freq: frequency in Hz
+        @rypte: bool
+
+        Tuning is a two step process.  First we ask the front-end to
+        tune as close to the desired frequency as it can.  Then we use
+        the result of that operation and our target_frequency to
+        determine the value for the digital down converter.
+        """
+        r = self.u.tune(0, self.subdev, target_freq)
+        
+        if r:
+            self.myform['freq'].set_value(target_freq)     # update displayed value
+            if self.show_debug_info:
+                self.myform['baseband'].set_value(r.baseband_freq)
+                self.myform['ddc'].set_value(r.dxc_freq)
+            return True
+
+        return False
+
+    def set_gain(self, gain):
+        self.myform['gain'].set_value(gain)     # update displayed value
+        self.subdev.set_gain(gain)
+
+
+def main ():
+    app = stdgui.stdapp(app_flow_graph, "USRP FFT", nstatus=1)
+    app.MainLoop()
+
+if __name__ == '__main__':
+    main ()
diff --git a/usrp/fpga/toplevel/mrfm/mrfm_proc.v b/usrp/fpga/toplevel/mrfm/mrfm_proc.v
new file mode 100644 (file)
index 0000000..80de9fc
--- /dev/null
@@ -0,0 +1,96 @@
+
+`include "mrfm.vh"
+`include "../../../firmware/include/fpga_regs_common.v"
+`include "../../../firmware/include/fpga_regs_standard.v"
+
+module mrfm_proc (input clock, input reset, input enable,
+                 input [6:0] serial_addr, input [31:0] serial_data, input serial_strobe,
+                 input [15:0] signal_in, output wire [15:0] signal_out, output wire sync_out,
+                 output wire [15:0] i, output wire [15:0] q, 
+                 output wire [15:0] ip, output wire [15:0] qp,
+                 output wire strobe_out, output wire [63:0] debugbus);
+
+   // Strobes
+   wire        sample_strobe, strobe_0, strobe_1, strobe_2;
+   assign      sample_strobe = 1'b1;
+   wire [7:0]  rate_0, rate_1, rate_2;
+
+   setting_reg #(`FR_MRFM_DECIM) sr_decim(.clock(clock),.reset(reset),.strobe(serial_strobe),.addr(serial_addr),.in(serial_data),.out({rate_2,rate_1,rate_0}));
+   
+   strobe_gen strobe_gen_0
+     ( .clock(clock),.reset(reset),.enable(enable),
+       .rate(rate_0),.strobe_in(sample_strobe),.strobe(strobe_0) );
+   strobe_gen strobe_gen_1
+     ( .clock(clock),.reset(reset),.enable(enable),
+       .rate(rate_1),.strobe_in(strobe_0),.strobe(strobe_1) );
+   
+   wire [31:0] phase;
+
+   assign      sync_out = phase[31];
+   wire [15:0] i_decim_0, i_decim_1, i_decim_2;
+   wire [15:0] q_decim_0, q_decim_1, q_decim_2;
+
+   wire [15:0] i_interp_0, i_interp_1, i_interp_2;
+   wire [15:0] q_interp_0, q_interp_1, q_interp_2;
+
+   wire [15:0] i_filt, q_filt, i_comp, q_comp;
+
+   assign      ip=i_comp;
+   assign      qp=q_comp;
+   
+   phase_acc #(`FR_MRFM_FREQ,`FR_MRFM_PHASE,32) rx_phase_acc
+     (.clk(clock),.reset(reset),.enable(enable),
+      .serial_addr(serial_addr),.serial_data(serial_data),.serial_strobe(serial_strobe),
+      .strobe(sample_strobe),.phase(phase) );
+   
+   cordic rx_cordic (.clock(clock),.reset(reset),.enable(enable),
+                    .xi(signal_in),.yi(16'd0),.zi(phase[31:16]),
+                    .xo(i_decim_0),.yo(q_decim_0),.zo() );
+   
+   cic_decim cic_decim_i_0 (.clock(clock),.reset(reset),.enable(enable),
+                           .rate(rate_0),.strobe_in(sample_strobe),.strobe_out(strobe_0),
+                           .signal_in(i_decim_0),.signal_out(i_decim_1));
+   cic_decim cic_decim_i_1 (.clock(clock),.reset(reset),.enable(enable),
+                           .rate(rate_1),.strobe_in(strobe_0),.strobe_out(strobe_1),
+                           .signal_in(i_decim_1),.signal_out(i));
+
+   cic_decim cic_decim_q_0 (.clock(clock),.reset(reset),.enable(enable),
+                           .rate(rate_0),.strobe_in(sample_strobe),.strobe_out(strobe_0),
+                           .signal_in(q_decim_0),.signal_out(q_decim_1));
+   cic_decim cic_decim_q_1 (.clock(clock),.reset(reset),.enable(enable),
+                           .rate(rate_1),.strobe_in(strobe_0),.strobe_out(strobe_1),
+                           .signal_in(q_decim_1),.signal_out(q));
+
+   assign      strobe_out = strobe_1;
+
+   biquad_2stage iir_i (.clock(clock),.reset(reset),.strobe_in(strobe_1),
+                       .serial_strobe(serial_strobe),.serial_addr(serial_addr),.serial_data(serial_data),
+                       .sample_in(i),.sample_out(i_filt),.debugbus(debugbus));
+
+   biquad_2stage iir_q (.clock(clock),.reset(reset),.strobe_in(strobe_1),
+                       .serial_strobe(serial_strobe),.serial_addr(serial_addr),.serial_data(serial_data),
+                       .sample_in(q),.sample_out(q_filt),.debugbus());
+
+   mrfm_compensator compensator (.clock(clock),.reset(reset),.strobe_in(strobe_1),
+                                .serial_strobe(serial_strobe),.serial_addr(serial_addr),.serial_data(serial_data),
+                                .i_in(i_filt),.q_in(q_filt),.i_out(i_comp),.q_out(q_comp));
+   
+   cic_interp cic_interp_i_0 (.clock(clock),.reset(reset),.enable(enable),
+                           .rate(rate_1),.strobe_in(strobe_1),.strobe_out(strobe_0),
+                           .signal_in(i_comp),.signal_out(i_interp_0));
+   cic_interp cic_interp_i_1 (.clock(clock),.reset(reset),.enable(enable),
+                           .rate(rate_0),.strobe_in(strobe_0),.strobe_out(sample_strobe),
+                           .signal_in(i_interp_0),.signal_out(i_interp_1));
+
+   cic_interp cic_interp_q_0 (.clock(clock),.reset(reset),.enable(enable),
+                           .rate(rate_1),.strobe_in(strobe_1),.strobe_out(strobe_0),
+                           .signal_in(q_comp),.signal_out(q_interp_0));
+   cic_interp cic_interp_q_1 (.clock(clock),.reset(reset),.enable(enable),
+                           .rate(rate_0),.strobe_in(strobe_0),.strobe_out(sample_strobe),
+                           .signal_in(q_interp_0),.signal_out(q_interp_1));
+
+   cordic tx_cordic (.clock(clock),.reset(reset),.enable(enable),
+                    .xi(i_interp_1),.yi(q_interp_1),.zi(-phase[31:16]),
+                    .xo(signal_out),.yo(),.zo() );
+
+endmodule // mrfm_proc
diff --git a/usrp/fpga/toplevel/mrfm/shifter.v b/usrp/fpga/toplevel/mrfm/shifter.v
new file mode 100644 (file)
index 0000000..08d49db
--- /dev/null
@@ -0,0 +1,106 @@
+// -*- verilog -*-
+//
+//  USRP - Universal Software Radio Peripheral
+//
+//  Copyright (C) 2005,2006 Matt Ettus
+//
+//  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
+//
+
+module shifter(input wire [33:0] in, output wire [15:0] out, input wire [7:0] shift);
+   // Wish we could do  assign out = in[15+shift:shift];
+
+   reg [15:0] quotient, remainder;
+   wire [15:0] out_unclipped;
+   reg [18:0]  msbs;
+   wire        in_range;
+   
+   always @*
+     case(shift)
+       0 : quotient = in[15:0];
+       1 : quotient = in[16:1];
+       2 : quotient = in[17:2];
+       3 : quotient = in[18:3];
+       4 : quotient = in[19:4];
+       5 : quotient = in[20:5];
+       6 : quotient = in[21:6];
+       7 : quotient = in[22:7];
+       8 : quotient = in[23:8];
+       9 : quotient = in[24:9];
+       10 : quotient = in[25:10];
+       11 : quotient = in[26:11];
+       12 : quotient = in[27:12];
+       13 : quotient = in[28:13];
+       14 : quotient = in[29:14];
+       15 : quotient = in[30:15];
+       16 : quotient = in[31:16];
+       17 : quotient = in[32:17];
+       18 : quotient = in[33:18];
+       default : quotient = in[15:0];
+     endcase // case(shift)
+
+   always @*
+     case(shift)
+       0 : remainder = 16'b0;
+       1 : remainder = {in[0],15'b0};
+       2 : remainder = {in[1:0],14'b0};
+       3 : remainder = {in[2:0],13'b0};
+       4 : remainder = {in[3:0],12'b0};
+       5 : remainder = {in[4:0],11'b0};
+       6 : remainder = {in[5:0],10'b0};
+       7 : remainder = {in[6:0],9'b0};
+       8 : remainder = {in[7:0],8'b0};
+       9 : remainder = {in[8:0],7'b0};
+       10 : remainder = {in[9:0],6'b0};
+       11 : remainder = {in[10:0],5'b0};
+       12 : remainder = {in[11:0],4'b0};
+       13 : remainder = {in[12:0],3'b0};
+       14 : remainder = {in[13:0],2'b0};
+       15 : remainder = {in[14:0],1'b0};
+       16 : remainder = in[15:0];
+       17 : remainder = in[16:1];
+       18 : remainder = in[17:2];
+       default : remainder = 16'b0;
+     endcase // case(shift)
+
+   always @*
+     case(shift)
+       0 : msbs = in[33:15];
+       1 : msbs = {in[33],in[33:16]};
+       2 : msbs = {{2{in[33]}},in[33:17]};
+       3 : msbs = {{3{in[33]}},in[33:18]};
+       4 : msbs = {{4{in[33]}},in[33:19]};
+       5 : msbs = {{5{in[33]}},in[33:20]};
+       6 : msbs = {{6{in[33]}},in[33:21]};
+       7 : msbs = {{7{in[33]}},in[33:22]};
+       8 : msbs = {{8{in[33]}},in[33:23]};
+       9 : msbs = {{9{in[33]}},in[33:24]};
+       10 : msbs = {{10{in[33]}},in[33:25]};
+       11 : msbs = {{11{in[33]}},in[33:26]};
+       12 : msbs = {{12{in[33]}},in[33:27]};
+       13 : msbs = {{13{in[33]}},in[33:28]};
+       14 : msbs = {{14{in[33]}},in[33:29]};
+       15 : msbs = {{15{in[33]}},in[33:30]};
+       16 : msbs = {{16{in[33]}},in[33:31]};
+       17 : msbs = {{17{in[33]}},in[33:32]};
+       18 : msbs = {{18{in[33]}},in[33]};
+       default : msbs = in[33:15];
+     endcase // case(shift)
+
+   assign     in_range = &msbs | ~(|msbs);
+   assign     out_unclipped = quotient + (in[33] & |remainder);
+   assign     out = in_range ? out_unclipped : {in[33],{15{~in[33]}}};
+   
+endmodule // shifter
diff --git a/usrp/fpga/toplevel/sizetest/sizetest.csf b/usrp/fpga/toplevel/sizetest/sizetest.csf
new file mode 100644 (file)
index 0000000..4b724e7
--- /dev/null
@@ -0,0 +1,160 @@
+COMPILER_SETTINGS
+{
+       IO_PLACEMENT_OPTIMIZATION = OFF;
+       ENABLE_DRC_SETTINGS = OFF;
+       PHYSICAL_SYNTHESIS_REGISTER_RETIMING = OFF;
+       PHYSICAL_SYNTHESIS_REGISTER_DUPLICATION = OFF;
+       PHYSICAL_SYNTHESIS_COMBO_LOGIC = OFF;
+       DRC_FANOUT_EXCEEDING = 30;
+       DRC_REPORT_FANOUT_EXCEEDING = OFF;
+       DRC_TOP_FANOUT = 50;
+       DRC_REPORT_TOP_FANOUT = OFF;
+       RUN_DRC_DURING_COMPILATION = OFF;
+       ADV_NETLIST_OPT_RETIME_CORE_AND_IO = ON;
+       ADV_NETLIST_OPT_SYNTH_USE_FITTER_INFO = OFF;
+       ADV_NETLIST_OPT_SYNTH_GATE_RETIME = OFF;
+       ADV_NETLIST_OPT_SYNTH_WYSIWYG_REMAP = OFF;
+       SMART_COMPILE_IGNORES_TDC_FOR_STRATIX_PLL_CHANGES = OFF;
+       MERGE_HEX_FILE = OFF;
+       TRUE_WYSIWYG_FLOW = OFF;
+       SEED = 1;
+       FINAL_PLACEMENT_OPTIMIZATION = AUTOMATICALLY;
+       FAMILY = Cyclone;
+       DPRAM_DUAL_PORT_MODE_OTHER_SIGNALS_EPXA1 = "DPRAM0 TO 1 DPRAM1 TO 2";
+       DPRAM_32BIT_SINGLE_PORT_MODE_OTHER_SIGNALS_EPXA1 = "MEGALAB COLUMN 1";
+       DPRAM_8BIT_16BIT_SINGLE_PORT_MODE_OTHER_SIGNALS_EPXA1 = "MEGALAB COLUMN 1";
+       DPRAM_DUAL_PORT_MODE_OUTPUT_EPXA1 = "DPRAM0 TO 1 DPRAM1 TO 2";
+       DPRAM_32BIT_SINGLE_PORT_MODE_OUTPUT_EPXA1 = "LOWER TO 1ESB UPPER TO 1";
+       DPRAM_8BIT_16BIT_SINGLE_PORT_MODE_OUTPUT_EPXA1 = "MEGALAB COLUMN 1";
+       DPRAM_DUAL_PORT_MODE_INPUT_EPXA1 = "DPRAM0 TO 1 DPRAM1 TO 2";
+       DPRAM_32BIT_SINGLE_PORT_MODE_INPUT_EPXA1 = "MEGALAB COLUMN 1";
+       DPRAM_8BIT_16BIT_SINGLE_PORT_MODE_INPUT_EPXA1 = "MEGALAB COLUMN 1";
+       DPRAM_DUAL_PORT_MODE_OTHER_SIGNALS_EPXA4_10 = "DPRAM0 TO 3 DPRAM1 TO 4";
+       DPRAM_SINGLE_PORT_MODE_OTHER_SIGNALS_EPXA4_10 = "DPRAM0 TO 3 DPRAM1 TO 4";
+       DPRAM_WIDE_MODE_OTHER_SIGNALS_EPXA4_10 = "MEGALAB COLUMN 3";
+       DPRAM_DEEP_MODE_OTHER_SIGNALS_EPXA4_10 = "MEGALAB COLUMN 3";
+       DPRAM_DUAL_PORT_MODE_OUTPUT_EPXA4_10 = "DPRAM0 TO 3 DPRAM1 TO 4ESB";
+       DPRAM_SINGLE_PORT_MODE_OUTPUT_EPXA4_10 = "DPRAM0 TO 3 DPRAM1 TO 4ESB";
+       DPRAM_WIDE_MODE_OUTPUT_EPXA4_10 = "LOWER TO 3 UPPER TO 4ESB";
+       DPRAM_DEEP_MODE_OUTPUT_EPXA4_10 = "MEGALAB COLUMN 3";
+       DPRAM_DUAL_PORT_MODE_INPUT_EPXA4_10 = "DPRAM0 TO 3 DPRAM1 TO 4";
+       DPRAM_SINGLE_PORT_MODE_INPUT_EPXA4_10 = "DPRAM0 TO 3 DPRAM1 TO 4";
+       DPRAM_WIDE_MODE_INPUT_EPXA4_10 = "LOWER TO 3 UPPER TO 4";
+       DPRAM_DEEP_MODE_INPUT_EPXA4_10 = "MEGALAB COLUMN 3";
+       DPRAM_OTHER_SIGNALS_EPXA4_10 = "DEFAULT OTHER ROUTING OPTIONS";
+       DPRAM_OUTPUT_EPXA4_10 = "DEFAULT OUTPUT ROUTING OPTIONS";
+       DPRAM_INPUT_EPXA4_10 = "DEFAULT INPUT ROUTING OPTIONS";
+       STRIPE_TO_PLD_INTERRUPTS_EPXA4_10 = "MEGALAB COLUMN 2";
+       PLD_TO_STRIPE_INTERRUPTS_EPXA4_10 = "MEGALAB COLUMN 2";
+       PROCESSOR_DEBUG_EXTENSIONS_EPXA4_10 = "MEGALAB COLUMN 2";
+       STRIPE_TO_PLD_BRIDGE_EPXA4_10 = "MEGALAB COLUMN 1";
+       FAST_FIT_COMPILATION = OFF;
+       SIGNALPROBE_DURING_NORMAL_COMPILATION = OFF;
+       OPTIMIZE_IOC_REGISTER_PLACEMENT_FOR_TIMING = OFF;
+       OPTIMIZE_TIMING = OFF;
+       OPTIMIZE_HOLD_TIMING = OFF;
+       COMPILATION_LEVEL = FULL;
+       SAVE_DISK_SPACE = ON;
+       SPEED_DISK_USAGE_TRADEOFF = NORMAL;
+       LOGICLOCK_INCREMENTAL_COMPILE_ASSIGNMENT = OFF;
+       SIGNALPROBE_ALLOW_OVERUSE = OFF;
+       FOCUS_ENTITY_NAME = |sizetest;
+       FIT_ONLY_ONE_ATTEMPT = OFF;
+}
+DEFAULT_DEVICE_OPTIONS
+{
+       GENERATE_CONFIG_HEXOUT_FILE = OFF;
+       GENERATE_CONFIG_JBC_FILE_COMPRESSED = ON;
+       GENERATE_CONFIG_JBC_FILE = OFF;
+       GENERATE_CONFIG_JAM_FILE = OFF;
+       GENERATE_CONFIG_ISC_FILE = OFF;
+       GENERATE_CONFIG_SVF_FILE = OFF;
+       GENERATE_JBC_FILE_COMPRESSED = ON;
+       GENERATE_JBC_FILE = OFF;
+       GENERATE_JAM_FILE = OFF;
+       GENERATE_ISC_FILE = OFF;
+       GENERATE_SVF_FILE = OFF;
+       RESERVE_PIN = "AS INPUT TRI-STATED";
+       RESERVE_ALL_UNUSED_PINS = "AS OUTPUT DRIVING GROUND";
+       HEXOUT_FILE_COUNT_DIRECTION = UP;
+       HEXOUT_FILE_START_ADDRESS = 0;
+       GENERATE_HEX_FILE = OFF;
+       GENERATE_RBF_FILE = OFF;
+       GENERATE_TTF_FILE = OFF;
+       RESERVE_ASDO_AFTER_CONFIGURATION = "USE AS REGULAR IO";
+       RESERVE_DATA0_AFTER_CONFIGURATION = "AS INPUT TRI-STATED";
+       RESERVE_DATA7_THROUGH_DATA1_AFTER_CONFIGURATION = "USE AS REGULAR IO";
+       RESERVE_RDYNBUSY_AFTER_CONFIGURATION = "USE AS REGULAR IO";
+       RESERVE_NWS_NRS_NCS_CS_AFTER_CONFIGURATION = "USE AS REGULAR IO";
+       DISABLE_NCS_AND_OE_PULLUPS_ON_CONFIG_DEVICE = OFF;
+       AUTO_INCREMENT_CONFIG_DEVICE_JTAG_USER_CODE = ON;
+       EPROM_USE_CHECKSUM_AS_USERCODE = OFF;
+       FLEX10K_CONFIG_DEVICE_JTAG_USER_CODE = FFFFFFFF;
+       MERCURY_CONFIG_DEVICE_JTAG_USER_CODE = FFFFFFFF;
+       STRATIX_CONFIG_DEVICE_JTAG_USER_CODE = FFFFFFFF;
+       APEX20K_CONFIG_DEVICE_JTAG_USER_CODE = FFFFFFFF;
+       STRATIX_CONFIGURATION_DEVICE = AUTO;
+       CYCLONE_CONFIGURATION_DEVICE = AUTO;
+       FLEX10K_CONFIGURATION_DEVICE = AUTO;
+       FLEX6K_CONFIGURATION_DEVICE = AUTO;
+       MERCURY_CONFIGURATION_DEVICE = AUTO;
+       EXCALIBUR_CONFIGURATION_DEVICE = AUTO;
+       APEX20K_CONFIGURATION_DEVICE = AUTO;
+       USE_CONFIGURATION_DEVICE = ON;
+       ENABLE_INIT_DONE_OUTPUT = OFF;
+       FLEX10K_ENABLE_LOCK_OUTPUT = OFF;
+       ENABLE_DEVICE_WIDE_OE = OFF;
+       ENABLE_DEVICE_WIDE_RESET = OFF;
+       RELEASE_CLEARS_BEFORE_TRI_STATES = OFF;
+       AUTO_RESTART_CONFIGURATION = OFF;
+       ENABLE_VREFB_PIN = OFF;
+       ENABLE_VREFA_PIN = OFF;
+       SECURITY_BIT = OFF;
+       USER_START_UP_CLOCK = OFF;
+       APEXII_CONFIGURATION_SCHEME = "PASSIVE SERIAL";
+       FLEX10K_CONFIGURATION_SCHEME = "PASSIVE SERIAL";
+       FLEX6K_CONFIGURATION_SCHEME = "PASSIVE SERIAL";
+       MERCURY_CONFIGURATION_SCHEME = "PASSIVE SERIAL";
+       EXCALIBUR_CONFIGURATION_SCHEME = "PASSIVE SERIAL";
+       CYCLONE_CONFIGURATION_SCHEME = "ACTIVE SERIAL";
+       STRATIX_CONFIGURATION_SCHEME = "PASSIVE SERIAL";
+       APEX20K_CONFIGURATION_SCHEME = "PASSIVE SERIAL";
+       STRATIX_UPDATE_MODE = STANDARD;
+       USE_CHECKSUM_AS_USERCODE = OFF;
+       MAX7000_USE_CHECKSUM_AS_USERCODE = OFF;
+       MAX7000_JTAG_USER_CODE = FFFFFFFF;
+       FLEX10K_JTAG_USER_CODE = 7F;
+       MERCURY_JTAG_USER_CODE = FFFFFFFF;
+       APEX20K_JTAG_USER_CODE = FFFFFFFF;
+       STRATIX_JTAG_USER_CODE = FFFFFFFF;
+       MAX7000S_JTAG_USER_CODE = FFFF;
+       RESERVE_NCEO_AFTER_CONFIGURATION = "USE AS REGULAR IO";
+       FLEX10K_ENABLE_LOW_VOLTAGE_MODE_ON_CONFIG_DEVICE = ON;
+       FLEX6K_ENABLE_LOW_VOLTAGE_MODE_ON_CONFIG_DEVICE = OFF;
+       ENABLE_LOW_VOLTAGE_MODE_ON_CONFIG_DEVICE = ON;
+       MAX7000_ENABLE_JTAG_BST_SUPPORT = ON;
+       ENABLE_JTAG_BST_SUPPORT = OFF;
+       CONFIGURATION_CLOCK_DIVISOR = 1;
+       CONFIGURATION_CLOCK_FREQUENCY = "10 MHZ";
+       CLOCK_SOURCE = INTERNAL;
+       COMPRESSION_MODE = OFF;
+       ON_CHIP_BITSTREAM_DECOMPRESSION = OFF;
+}
+AUTO_SLD_HUB_ENTITY
+{
+       AUTO_INSERT_SLD_HUB_ENTITY = ENABLE;
+       HUB_INSTANCE_NAME = SLD_HUB_INST;
+       HUB_ENTITY_NAME = SLD_HUB;
+}
+CHIP(sizetest)
+{
+       DEVICE = EP1C12Q240C8;
+       DEVICE_FILTER_PACKAGE = "ANY QFP";
+       DEVICE_FILTER_PIN_COUNT = 240;
+       DEVICE_FILTER_SPEED_GRADE = ANY;
+}
+SIGNALTAP_LOGIC_ANALYZER_SETTINGS
+{
+       ENABLE_SIGNALTAP = Off;
+       AUTO_ENABLE_SMART_COMPILE = On;
+}
diff --git a/usrp/fpga/toplevel/sizetest/sizetest.psf b/usrp/fpga/toplevel/sizetest/sizetest.psf
new file mode 100644 (file)
index 0000000..e4fc6aa
--- /dev/null
@@ -0,0 +1,228 @@
+DEFAULT_DESIGN_ASSISTANT_SETTINGS
+{
+       HCPY_ALOAD_SIGNALS = OFF;
+       HCPY_VREF_PINS = OFF;
+       HCPY_CAT = OFF;
+       HCPY_ILLEGAL_HC_DEV_PKG = OFF;
+       ACLK_RULE_IMSZER_ADOMAIN = OFF;
+       ACLK_RULE_SZER_BTW_ACLK_DOMAIN = OFF;
+       ACLK_RULE_NO_SZER_ACLK_DOMAIN = OFF;
+       ACLK_CAT = OFF;
+       SIGNALRACE_RULE_ASYNCHPIN_SYNCH_CLKPIN = OFF;
+       SIGNALRACE_CAT = OFF;
+       NONSYNCHSTRUCT_RULE_LATCH_UNIDENTIFIED = OFF;
+       NONSYNCHSTRUCT_RULE_SRLATCH = OFF;
+       NONSYNCHSTRUCT_RULE_DLATCH = OFF;
+       NONSYNCHSTRUCT_RULE_MULTI_VIBRATOR = OFF;
+       NONSYNCHSTRUCT_RULE_ILLEGAL_PULSE_GEN = OFF;
+       NONSYNCHSTRUCT_RULE_RIPPLE_CLK = OFF;
+       NONSYNCHSTRUCT_RULE_DELAY_CHAIN = OFF;
+       NONSYNCHSTRUCT_RULE_REG_LOOP = OFF;
+       NONSYNCHSTRUCT_RULE_COMBLOOP = OFF;
+       NONSYNCHSTRUCT_CAT = OFF;
+       NONSYNCHSTRUCT_RULE_COMB_DRIVES_RAM_WE = OFF;
+       TIMING_RULE_COIN_CLKEDGE = OFF;
+       TIMING_RULE_SHIFT_REG = OFF;
+       TIMING_RULE_HIGH_FANOUTS = OFF;
+       TIMING_CAT = OFF;
+       RESET_RULE_ALL = OFF;
+       RESET_RULE_IMSYNCH_ASYNCH_DOMAIN = OFF;
+       RESET_RULE_UNSYNCH_ASYNCH_DOMAIN = OFF;
+       RESET_RULE_REG_ASNYCH = OFF;
+       RESET_RULE_COMB_ASYNCH_RESET = OFF;
+       RESET_RULE_IMSYNCH_EXRESET = OFF;
+       RESET_RULE_UNSYNCH_EXRESET = OFF;
+       RESET_RULE_INPINS_RESETNET = OFF;
+       RESET_CAT = OFF;
+       CLK_RULE_ALL = OFF;
+       CLK_RULE_MIX_EDGES = OFF;
+       CLK_RULE_CLKNET_CLKSPINES = OFF;
+       CLK_RULE_INPINS_CLKNET = OFF;
+       CLK_RULE_GATING_SCHEME = OFF;
+       CLK_RULE_INV_CLOCK = OFF;
+       CLK_RULE_COMB_CLOCK = OFF;
+       CLK_CAT = OFF;
+       HCPY_EXCEED_USER_IO_USAGE = OFF;
+       HCPY_EXCEED_RAM_USAGE = OFF;
+       NONSYNCHSTRUCT_RULE_ASYN_RAM = OFF;
+       SIGNALRACE_RULE_TRISTATE = OFF;
+       ASSG_RULE_MISSING_TIMING = OFF;
+       ASSG_RULE_MISSING_FMAX = OFF;
+       ASSG_CAT = OFF;
+}
+SYNTHESIS_FITTING_SETTINGS
+{
+       AUTO_SHIFT_REGISTER_RECOGNITION = ON;
+       AUTO_RAM_RECOGNITION = ON;
+       REMOVE_DUPLICATE_LOGIC = ON;
+       AUTO_MERGE_PLLS = ON;
+       AUTO_OPEN_DRAIN_PINS = ON;
+       AUTO_CARRY_CHAINS = ON;
+       AUTO_DELAY_CHAINS = ON;
+       STRATIX_CARRY_CHAIN_LENGTH = 70;
+       AUTO_PACKED_REG_CYCLONE = "MINIMIZE AREA WITH CHAINS";
+       CYCLONE_OPTIMIZATION_TECHNIQUE = SPEED;
+       AUTO_GLOBAL_MEMORY_CONTROLS = OFF;
+       AUTO_GLOBAL_REGISTER_CONTROLS = ON;
+       AUTO_GLOBAL_CLOCK = ON;
+       LIMIT_AHDL_INTEGERS_TO_32_BITS = OFF;
+       ENABLE_BUS_HOLD_CIRCUITRY = OFF;
+       WEAK_PULL_UP_RESISTOR = OFF;
+       IGNORE_SOFT_BUFFERS = ON;
+       IGNORE_LCELL_BUFFERS = OFF;
+       IGNORE_ROW_GLOBAL_BUFFERS = OFF;
+       IGNORE_GLOBAL_BUFFERS = OFF;
+       IGNORE_CASCADE_BUFFERS = OFF;
+       IGNORE_CARRY_BUFFERS = OFF;
+       REMOVE_DUPLICATE_REGISTERS = ON;
+       REMOVE_REDUNDANT_LOGIC_CELLS = OFF;
+       ALLOW_POWER_UP_DONT_CARE = ON;
+       PCI_IO = OFF;
+       NOT_GATE_PUSH_BACK = ON;
+       SLOW_SLEW_RATE = OFF;
+       STATE_MACHINE_PROCESSING = AUTO;
+}
+DEFAULT_HARDCOPY_SETTINGS
+{
+       HARDCOPY_EXTERNAL_CLOCK_JITTER = "0.0 NS";
+}
+DEFAULT_TIMING_REQUIREMENTS
+{
+       INCLUDE_EXTERNAL_PIN_DELAYS_IN_FMAX_CALCULATIONS = OFF;
+       RUN_ALL_TIMING_ANALYSES = ON;
+       IGNORE_CLOCK_SETTINGS = OFF;
+       DEFAULT_HOLD_MULTICYCLE = "SAME AS MULTICYCLE";
+       CUT_OFF_IO_PIN_FEEDBACK = ON;
+       CUT_OFF_CLEAR_AND_PRESET_PATHS = ON;
+       CUT_OFF_READ_DURING_WRITE_PATHS = ON;
+       CUT_OFF_PATHS_BETWEEN_CLOCK_DOMAINS = ON;
+       DO_MIN_ANALYSIS = ON;
+       DO_MIN_TIMING = OFF;
+       NUMBER_OF_PATHS_TO_REPORT = 200;
+       NUMBER_OF_DESTINATION_TO_REPORT = 10;
+       NUMBER_OF_SOURCES_PER_DESTINATION_TO_REPORT = 10;
+       MAX_SCC_SIZE = 50;
+}
+HDL_SETTINGS
+{
+       VERILOG_INPUT_VERSION = VERILOG_2001;
+       ENABLE_IP_DEBUG = OFF;
+       VHDL_INPUT_VERSION = VHDL93;
+       VHDL_SHOW_LMF_MAPPING_MESSAGES = OFF;
+}
+PROJECT_INFO(sizetest)
+{
+       USER_LIBRARIES = "e:\fpga\megacells\";
+       ORIGINAL_QUARTUS_VERSION = 3.0;
+       PROJECT_CREATION_TIME_DATE = "22:00:25  SEPTEMBER 28, 2003";
+       LAST_QUARTUS_VERSION = 3.0;
+       SHOW_REGISTRATION_MESSAGE = ON;
+}
+THIRD_PARTY_EDA_TOOLS(sizetest)
+{
+       EDA_DESIGN_ENTRY_SYNTHESIS_TOOL = "<NONE>";
+       EDA_SIMULATION_TOOL = "<NONE>";
+       EDA_TIMING_ANALYSIS_TOOL = "<NONE>";
+       EDA_BOARD_DESIGN_TOOL = "<NONE>";
+       EDA_FORMAL_VERIFICATION_TOOL = "<NONE>";
+       EDA_RESYNTHESIS_TOOL = "<NONE>";
+}
+EDA_TOOL_SETTINGS(eda_design_synthesis)
+{
+       EDA_INPUT_GND_NAME = GND;
+       EDA_INPUT_VCC_NAME = VCC;
+       EDA_SHOW_LMF_MAPPING_MESSAGES = OFF;
+       EDA_RUN_TOOL_AUTOMATICALLY = OFF;
+       EDA_INPUT_DATA_FORMAT = EDIF;
+       EDA_OUTPUT_DATA_FORMAT = NONE;
+       USE_GENERATED_PHYSICAL_CONSTRAINTS = ON;
+       RESYNTHESIS_PHYSICAL_SYNTHESIS = NORMAL;
+       RESYNTHESIS_OPTIMIZATION_EFFORT = NORMAL;
+       RESYNTHESIS_RETIMING = FULL;
+}
+EDA_TOOL_SETTINGS(eda_simulation)
+{
+       EDA_INCLUDE_VHDL_CONFIGURATION_DECLARATION = OFF;
+       EDA_TRUNCATE_LONG_HIERARCHY_PATHS = OFF;
+       EDA_MAINTAIN_DESIGN_HIERARCHY = OFF;
+       EDA_WRITE_DEVICE_CONTROL_PORTS = OFF;
+       EDA_GENERATE_FUNCTIONAL_NETLIST = OFF;
+       EDA_FLATTEN_BUSES = OFF;
+       EDA_MAP_ILLEGAL_CHARACTERS = OFF;
+       EDA_EXCALIBUR_ATOMS_AS_SINGLE_STRIPE = OFF;
+       EDA_RUN_TOOL_AUTOMATICALLY = OFF;
+       EDA_OUTPUT_DATA_FORMAT = NONE;
+       USE_GENERATED_PHYSICAL_CONSTRAINTS = ON;
+       RESYNTHESIS_PHYSICAL_SYNTHESIS = NORMAL;
+       RESYNTHESIS_OPTIMIZATION_EFFORT = NORMAL;
+       RESYNTHESIS_RETIMING = FULL;
+}
+EDA_TOOL_SETTINGS(eda_timing_analysis)
+{
+       EDA_INCLUDE_VHDL_CONFIGURATION_DECLARATION = OFF;
+       EDA_TRUNCATE_LONG_HIERARCHY_PATHS = OFF;
+       EDA_MAINTAIN_DESIGN_HIERARCHY = OFF;
+       EDA_WRITE_DEVICE_CONTROL_PORTS = OFF;
+       EDA_GENERATE_FUNCTIONAL_NETLIST = OFF;
+       EDA_FLATTEN_BUSES = OFF;
+       EDA_MAP_ILLEGAL_CHARACTERS = OFF;
+       EDA_EXCALIBUR_ATOMS_AS_SINGLE_STRIPE = OFF;
+       EDA_RUN_TOOL_AUTOMATICALLY = OFF;
+       EDA_OUTPUT_DATA_FORMAT = NONE;
+       EDA_LAUNCH_CMD_LINE_TOOL = OFF;
+       USE_GENERATED_PHYSICAL_CONSTRAINTS = ON;
+       RESYNTHESIS_PHYSICAL_SYNTHESIS = NORMAL;
+       RESYNTHESIS_OPTIMIZATION_EFFORT = NORMAL;
+       RESYNTHESIS_RETIMING = FULL;
+}
+EDA_TOOL_SETTINGS(eda_board_design)
+{
+       EDA_INCLUDE_VHDL_CONFIGURATION_DECLARATION = OFF;
+       EDA_TRUNCATE_LONG_HIERARCHY_PATHS = OFF;
+       EDA_MAINTAIN_DESIGN_HIERARCHY = OFF;
+       EDA_WRITE_DEVICE_CONTROL_PORTS = OFF;
+       EDA_GENERATE_FUNCTIONAL_NETLIST = OFF;
+       EDA_FLATTEN_BUSES = OFF;
+       EDA_MAP_ILLEGAL_CHARACTERS = OFF;
+       EDA_EXCALIBUR_ATOMS_AS_SINGLE_STRIPE = OFF;
+       EDA_RUN_TOOL_AUTOMATICALLY = OFF;
+       EDA_OUTPUT_DATA_FORMAT = NONE;
+       USE_GENERATED_PHYSICAL_CONSTRAINTS = ON;
+       RESYNTHESIS_PHYSICAL_SYNTHESIS = NORMAL;
+       RESYNTHESIS_OPTIMIZATION_EFFORT = NORMAL;
+       RESYNTHESIS_RETIMING = FULL;
+}
+EDA_TOOL_SETTINGS(eda_formal_verification)
+{
+       EDA_INCLUDE_VHDL_CONFIGURATION_DECLARATION = OFF;
+       EDA_TRUNCATE_LONG_HIERARCHY_PATHS = OFF;
+       EDA_MAINTAIN_DESIGN_HIERARCHY = OFF;
+       EDA_WRITE_DEVICE_CONTROL_PORTS = OFF;
+       EDA_GENERATE_FUNCTIONAL_NETLIST = OFF;
+       EDA_FLATTEN_BUSES = OFF;
+       EDA_MAP_ILLEGAL_CHARACTERS = OFF;
+       EDA_EXCALIBUR_ATOMS_AS_SINGLE_STRIPE = OFF;
+       EDA_RUN_TOOL_AUTOMATICALLY = OFF;
+       EDA_OUTPUT_DATA_FORMAT = NONE;
+       USE_GENERATED_PHYSICAL_CONSTRAINTS = ON;
+       RESYNTHESIS_PHYSICAL_SYNTHESIS = NORMAL;
+       RESYNTHESIS_OPTIMIZATION_EFFORT = NORMAL;
+       RESYNTHESIS_RETIMING = FULL;
+}
+EDA_TOOL_SETTINGS(eda_palace)
+{
+       EDA_INCLUDE_VHDL_CONFIGURATION_DECLARATION = OFF;
+       EDA_TRUNCATE_LONG_HIERARCHY_PATHS = OFF;
+       EDA_MAINTAIN_DESIGN_HIERARCHY = OFF;
+       EDA_WRITE_DEVICE_CONTROL_PORTS = OFF;
+       EDA_GENERATE_FUNCTIONAL_NETLIST = OFF;
+       EDA_FLATTEN_BUSES = OFF;
+       EDA_MAP_ILLEGAL_CHARACTERS = OFF;
+       EDA_EXCALIBUR_ATOMS_AS_SINGLE_STRIPE = OFF;
+       EDA_RUN_TOOL_AUTOMATICALLY = OFF;
+       EDA_OUTPUT_DATA_FORMAT = NONE;
+       RESYNTHESIS_RETIMING = FULL;
+       RESYNTHESIS_PHYSICAL_SYNTHESIS = NORMAL;
+       RESYNTHESIS_OPTIMIZATION_EFFORT = NORMAL;
+       USE_GENERATED_PHYSICAL_CONSTRAINTS = ON;
+}
diff --git a/usrp/fpga/toplevel/sizetest/sizetest.quartus b/usrp/fpga/toplevel/sizetest/sizetest.quartus
new file mode 100644 (file)
index 0000000..d1eaf22
--- /dev/null
@@ -0,0 +1,19 @@
+COMPILER_SETTINGS_LIST
+{
+       COMPILER_SETTINGS = sizetest;
+}
+SIMULATOR_SETTINGS_LIST
+{
+       SIMULATOR_SETTINGS = sizetest;
+}
+SOFTWARE_SETTINGS_LIST
+{
+       SOFTWARE_SETTINGS = Debug;
+       SOFTWARE_SETTINGS = Release;
+}
+FILES
+{
+       VERILOG_FILE = ..\..\sdr_lib\cordic_stage.v;
+       VERILOG_FILE = ..\..\sdr_lib\cordic.v;
+       VERILOG_FILE = sizetest.v;
+}
diff --git a/usrp/fpga/toplevel/sizetest/sizetest.ssf b/usrp/fpga/toplevel/sizetest/sizetest.ssf
new file mode 100644 (file)
index 0000000..1aceab1
--- /dev/null
@@ -0,0 +1,14 @@
+SIMULATOR_SETTINGS
+{
+       ESTIMATE_POWER_CONSUMPTION = OFF;
+       GLITCH_INTERVAL = 1NS;
+       GLITCH_DETECTION = OFF;
+       SIMULATION_COVERAGE = ON;
+       CHECK_OUTPUTS = OFF;
+       SETUP_HOLD_DETECTION = OFF;
+       POWER_ESTIMATION_START_TIME = "0 NS";
+       ADD_DEFAULT_PINS_TO_SIMULATION_OUTPUT_WAVEFORMS = ON;
+       SIMULATION_MODE = TIMING;
+       START_TIME = 0NS;
+       USE_COMPILER_SETTINGS = sizetest;
+}
diff --git a/usrp/fpga/toplevel/sizetest/sizetest.v b/usrp/fpga/toplevel/sizetest/sizetest.v
new file mode 100644 (file)
index 0000000..cdbd086
--- /dev/null
@@ -0,0 +1,39 @@
+// -*- verilog -*-
+//
+//  USRP - Universal Software Radio Peripheral
+//
+//  Copyright (C) 2003 Matt Ettus
+//
+//  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
+//
+
+
+module sizetest(input clock, 
+                               input reset, 
+                               input enable, 
+                               input [15:0]xi, 
+                               input [15:0] yi, 
+                               input [15:0] zi, 
+                               output [15:0] xo, 
+                               output [15:0] yo,
+                               output [15:0] zo
+//                             input [15:0] constant 
+                               );
+
+wire [16:0] zo;
+
+cordic_stage cordic_stage(clock, reset, enable, xi, yi, zi, 16'd16383, xo, yo, zo );
+
+endmodule
diff --git a/usrp/fpga/toplevel/usrp_multi/usrp_multi.csf b/usrp/fpga/toplevel/usrp_multi/usrp_multi.csf
new file mode 100644 (file)
index 0000000..2f5df2b
--- /dev/null
@@ -0,0 +1,444 @@
+COMPILER_SETTINGS
+{
+       IO_PLACEMENT_OPTIMIZATION = OFF;
+       ENABLE_DRC_SETTINGS = OFF;
+       PHYSICAL_SYNTHESIS_REGISTER_RETIMING = OFF;
+       PHYSICAL_SYNTHESIS_REGISTER_DUPLICATION = OFF;
+       PHYSICAL_SYNTHESIS_COMBO_LOGIC = OFF;
+       DRC_FANOUT_EXCEEDING = 30;
+       DRC_REPORT_FANOUT_EXCEEDING = OFF;
+       DRC_TOP_FANOUT = 50;
+       DRC_REPORT_TOP_FANOUT = OFF;
+       RUN_DRC_DURING_COMPILATION = OFF;
+       ADV_NETLIST_OPT_RETIME_CORE_AND_IO = ON;
+       ADV_NETLIST_OPT_SYNTH_USE_FITTER_INFO = OFF;
+       ADV_NETLIST_OPT_SYNTH_GATE_RETIME = OFF;
+       ADV_NETLIST_OPT_SYNTH_WYSIWYG_REMAP = OFF;
+       SMART_COMPILE_IGNORES_TDC_FOR_STRATIX_PLL_CHANGES = OFF;
+       MERGE_HEX_FILE = OFF;
+       TRUE_WYSIWYG_FLOW = OFF;
+       SEED = 1;
+       FINAL_PLACEMENT_OPTIMIZATION = AUTOMATICALLY;
+       FAMILY = Cyclone;
+       DPRAM_DUAL_PORT_MODE_OTHER_SIGNALS_EPXA1 = "DPRAM0 TO 1 DPRAM1 TO 2";
+       DPRAM_32BIT_SINGLE_PORT_MODE_OTHER_SIGNALS_EPXA1 = "MEGALAB COLUMN 1";
+       DPRAM_8BIT_16BIT_SINGLE_PORT_MODE_OTHER_SIGNALS_EPXA1 = "MEGALAB COLUMN 1";
+       DPRAM_DUAL_PORT_MODE_OUTPUT_EPXA1 = "DPRAM0 TO 1 DPRAM1 TO 2";
+       DPRAM_32BIT_SINGLE_PORT_MODE_OUTPUT_EPXA1 = "LOWER TO 1ESB UPPER TO 1";
+       DPRAM_8BIT_16BIT_SINGLE_PORT_MODE_OUTPUT_EPXA1 = "MEGALAB COLUMN 1";
+       DPRAM_DUAL_PORT_MODE_INPUT_EPXA1 = "DPRAM0 TO 1 DPRAM1 TO 2";
+       DPRAM_32BIT_SINGLE_PORT_MODE_INPUT_EPXA1 = "MEGALAB COLUMN 1";
+       DPRAM_8BIT_16BIT_SINGLE_PORT_MODE_INPUT_EPXA1 = "MEGALAB COLUMN 1";
+       DPRAM_DUAL_PORT_MODE_OTHER_SIGNALS_EPXA4_10 = "DPRAM0 TO 3 DPRAM1 TO 4";
+       DPRAM_SINGLE_PORT_MODE_OTHER_SIGNALS_EPXA4_10 = "DPRAM0 TO 3 DPRAM1 TO 4";
+       DPRAM_WIDE_MODE_OTHER_SIGNALS_EPXA4_10 = "MEGALAB COLUMN 3";
+       DPRAM_DEEP_MODE_OTHER_SIGNALS_EPXA4_10 = "MEGALAB COLUMN 3";
+       DPRAM_DUAL_PORT_MODE_OUTPUT_EPXA4_10 = "DPRAM0 TO 3 DPRAM1 TO 4ESB";
+       DPRAM_SINGLE_PORT_MODE_OUTPUT_EPXA4_10 = "DPRAM0 TO 3 DPRAM1 TO 4ESB";
+       DPRAM_WIDE_MODE_OUTPUT_EPXA4_10 = "LOWER TO 3 UPPER TO 4ESB";
+       DPRAM_DEEP_MODE_OUTPUT_EPXA4_10 = "MEGALAB COLUMN 3";
+       DPRAM_DUAL_PORT_MODE_INPUT_EPXA4_10 = "DPRAM0 TO 3 DPRAM1 TO 4";
+       DPRAM_SINGLE_PORT_MODE_INPUT_EPXA4_10 = "DPRAM0 TO 3 DPRAM1 TO 4";
+       DPRAM_WIDE_MODE_INPUT_EPXA4_10 = "LOWER TO 3 UPPER TO 4";
+       DPRAM_DEEP_MODE_INPUT_EPXA4_10 = "MEGALAB COLUMN 3";
+       DPRAM_OTHER_SIGNALS_EPXA4_10 = "DEFAULT OTHER ROUTING OPTIONS";
+       DPRAM_OUTPUT_EPXA4_10 = "DEFAULT OUTPUT ROUTING OPTIONS";
+       DPRAM_INPUT_EPXA4_10 = "DEFAULT INPUT ROUTING OPTIONS";
+       STRIPE_TO_PLD_INTERRUPTS_EPXA4_10 = "MEGALAB COLUMN 2";
+       PLD_TO_STRIPE_INTERRUPTS_EPXA4_10 = "MEGALAB COLUMN 2";
+       PROCESSOR_DEBUG_EXTENSIONS_EPXA4_10 = "MEGALAB COLUMN 2";
+       STRIPE_TO_PLD_BRIDGE_EPXA4_10 = "MEGALAB COLUMN 1";
+       FAST_FIT_COMPILATION = OFF;
+       SIGNALPROBE_DURING_NORMAL_COMPILATION = OFF;
+       OPTIMIZE_IOC_REGISTER_PLACEMENT_FOR_TIMING = ON;
+       OPTIMIZE_TIMING = "NORMAL COMPILATION";
+       OPTIMIZE_HOLD_TIMING = OFF;
+       COMPILATION_LEVEL = FULL;
+       SAVE_DISK_SPACE = OFF;
+       SPEED_DISK_USAGE_TRADEOFF = NORMAL;
+       LOGICLOCK_INCREMENTAL_COMPILE_ASSIGNMENT = OFF;
+       SIGNALPROBE_ALLOW_OVERUSE = OFF;
+       FOCUS_ENTITY_NAME = |usrp_multi;
+       ROUTING_BACK_ANNOTATION_MODE = OFF;
+       INC_PLC_MODE = OFF;
+       FIT_ONLY_ONE_ATTEMPT = OFF;
+}
+DEFAULT_DEVICE_OPTIONS
+{
+       GENERATE_CONFIG_HEXOUT_FILE = OFF;
+       GENERATE_CONFIG_JBC_FILE_COMPRESSED = ON;
+       GENERATE_CONFIG_JBC_FILE = OFF;
+       GENERATE_CONFIG_JAM_FILE = OFF;
+       GENERATE_CONFIG_ISC_FILE = OFF;
+       GENERATE_CONFIG_SVF_FILE = OFF;
+       GENERATE_JBC_FILE_COMPRESSED = ON;
+       GENERATE_JBC_FILE = OFF;
+       GENERATE_JAM_FILE = OFF;
+       GENERATE_ISC_FILE = OFF;
+       GENERATE_SVF_FILE = OFF;
+       RESERVE_PIN = "AS INPUT TRI-STATED";
+       RESERVE_ALL_UNUSED_PINS = "AS OUTPUT DRIVING GROUND";
+       HEXOUT_FILE_COUNT_DIRECTION = UP;
+       HEXOUT_FILE_START_ADDRESS = 0;
+       GENERATE_HEX_FILE = OFF;
+       GENERATE_RBF_FILE = OFF;
+       GENERATE_TTF_FILE = OFF;
+       RESERVE_ASDO_AFTER_CONFIGURATION = "USE AS REGULAR IO";
+       RESERVE_DATA0_AFTER_CONFIGURATION = "AS INPUT TRI-STATED";
+       RESERVE_DATA7_THROUGH_DATA1_AFTER_CONFIGURATION = "USE AS REGULAR IO";
+       RESERVE_RDYNBUSY_AFTER_CONFIGURATION = "USE AS REGULAR IO";
+       RESERVE_NWS_NRS_NCS_CS_AFTER_CONFIGURATION = "USE AS REGULAR IO";
+       DISABLE_NCS_AND_OE_PULLUPS_ON_CONFIG_DEVICE = OFF;
+       AUTO_INCREMENT_CONFIG_DEVICE_JTAG_USER_CODE = ON;
+       EPROM_USE_CHECKSUM_AS_USERCODE = OFF;
+       FLEX10K_CONFIG_DEVICE_JTAG_USER_CODE = FFFFFFFF;
+       MERCURY_CONFIG_DEVICE_JTAG_USER_CODE = FFFFFFFF;
+       STRATIX_CONFIG_DEVICE_JTAG_USER_CODE = FFFFFFFF;
+       APEX20K_CONFIG_DEVICE_JTAG_USER_CODE = FFFFFFFF;
+       STRATIX_CONFIGURATION_DEVICE = AUTO;
+       CYCLONE_CONFIGURATION_DEVICE = AUTO;
+       FLEX10K_CONFIGURATION_DEVICE = AUTO;
+       FLEX6K_CONFIGURATION_DEVICE = AUTO;
+       MERCURY_CONFIGURATION_DEVICE = AUTO;
+       EXCALIBUR_CONFIGURATION_DEVICE = AUTO;
+       APEX20K_CONFIGURATION_DEVICE = AUTO;
+       USE_CONFIGURATION_DEVICE = ON;
+       ENABLE_INIT_DONE_OUTPUT = OFF;
+       FLEX10K_ENABLE_LOCK_OUTPUT = OFF;
+       ENABLE_DEVICE_WIDE_OE = OFF;
+       ENABLE_DEVICE_WIDE_RESET = OFF;
+       RELEASE_CLEARS_BEFORE_TRI_STATES = OFF;
+       AUTO_RESTART_CONFIGURATION = OFF;
+       ENABLE_VREFB_PIN = OFF;
+       ENABLE_VREFA_PIN = OFF;
+       SECURITY_BIT = OFF;
+       USER_START_UP_CLOCK = OFF;
+       APEXII_CONFIGURATION_SCHEME = "PASSIVE SERIAL";
+       FLEX10K_CONFIGURATION_SCHEME = "PASSIVE SERIAL";
+       FLEX6K_CONFIGURATION_SCHEME = "PASSIVE SERIAL";
+       MERCURY_CONFIGURATION_SCHEME = "PASSIVE SERIAL";
+       EXCALIBUR_CONFIGURATION_SCHEME = "PASSIVE SERIAL";
+       CYCLONE_CONFIGURATION_SCHEME = "ACTIVE SERIAL";
+       STRATIX_CONFIGURATION_SCHEME = "PASSIVE SERIAL";
+       APEX20K_CONFIGURATION_SCHEME = "PASSIVE SERIAL";
+       STRATIX_UPDATE_MODE = STANDARD;
+       USE_CHECKSUM_AS_USERCODE = OFF;
+       MAX7000_USE_CHECKSUM_AS_USERCODE = OFF;
+       MAX7000_JTAG_USER_CODE = FFFFFFFF;
+       FLEX10K_JTAG_USER_CODE = 7F;
+       MERCURY_JTAG_USER_CODE = FFFFFFFF;
+       APEX20K_JTAG_USER_CODE = FFFFFFFF;
+       STRATIX_JTAG_USER_CODE = FFFFFFFF;
+       MAX7000S_JTAG_USER_CODE = FFFF;
+       RESERVE_NCEO_AFTER_CONFIGURATION = "USE AS REGULAR IO";
+       FLEX10K_ENABLE_LOW_VOLTAGE_MODE_ON_CONFIG_DEVICE = ON;
+       FLEX6K_ENABLE_LOW_VOLTAGE_MODE_ON_CONFIG_DEVICE = OFF;
+       ENABLE_LOW_VOLTAGE_MODE_ON_CONFIG_DEVICE = ON;
+       MAX7000_ENABLE_JTAG_BST_SUPPORT = ON;
+       ENABLE_JTAG_BST_SUPPORT = OFF;
+       CONFIGURATION_CLOCK_DIVISOR = 1;
+       CONFIGURATION_CLOCK_FREQUENCY = "10 MHZ";
+       CLOCK_SOURCE = INTERNAL;
+       COMPRESSION_MODE = OFF;
+       ON_CHIP_BITSTREAM_DECOMPRESSION = OFF;
+}
+AUTO_SLD_HUB_ENTITY
+{
+       AUTO_INSERT_SLD_HUB_ENTITY = ENABLE;
+       HUB_INSTANCE_NAME = SLD_HUB_INST;
+       HUB_ENTITY_NAME = SLD_HUB;
+}
+SIGNALTAP_LOGIC_ANALYZER_SETTINGS
+{
+       ENABLE_SIGNALTAP = Off;
+       AUTO_ENABLE_SMART_COMPILE = On;
+}
+CHIP(usrp_multi)
+{
+       DEVICE = EP1C12Q240C8;
+       DEVICE_FILTER_PACKAGE = "ANY QFP";
+       DEVICE_FILTER_PIN_COUNT = 240;
+       DEVICE_FILTER_SPEED_GRADE = ANY;
+       AUTO_RESTART_CONFIGURATION = OFF;
+       RELEASE_CLEARS_BEFORE_TRI_STATES = OFF;
+       USER_START_UP_CLOCK = OFF;
+       ENABLE_DEVICE_WIDE_RESET = OFF;
+       ENABLE_DEVICE_WIDE_OE = OFF;
+       ENABLE_INIT_DONE_OUTPUT = OFF;
+       FLEX10K_ENABLE_LOCK_OUTPUT = OFF;
+       ENABLE_JTAG_BST_SUPPORT = OFF;
+       MAX7000_ENABLE_JTAG_BST_SUPPORT = ON;
+       APEX20K_JTAG_USER_CODE = FFFFFFFF;
+       MERCURY_JTAG_USER_CODE = FFFFFFFF;
+       FLEX10K_JTAG_USER_CODE = 7F;
+       MAX7000_JTAG_USER_CODE = FFFFFFFF;
+       MAX7000S_JTAG_USER_CODE = FFFF;
+       STRATIX_JTAG_USER_CODE = FFFFFFFF;
+       APEX20K_CONFIGURATION_SCHEME = "PASSIVE SERIAL";
+       MERCURY_CONFIGURATION_SCHEME = "PASSIVE SERIAL";
+       FLEX6K_CONFIGURATION_SCHEME = "PASSIVE SERIAL";
+       FLEX10K_CONFIGURATION_SCHEME = "PASSIVE SERIAL";
+       EXCALIBUR_CONFIGURATION_SCHEME = "PASSIVE SERIAL";
+       APEXII_CONFIGURATION_SCHEME = "PASSIVE SERIAL";
+       STRATIX_CONFIGURATION_SCHEME = "PASSIVE SERIAL";
+       CYCLONE_CONFIGURATION_SCHEME = "PASSIVE SERIAL";
+       USE_CONFIGURATION_DEVICE = OFF;
+       APEX20K_CONFIGURATION_DEVICE = AUTO;
+       MERCURY_CONFIGURATION_DEVICE = AUTO;
+       FLEX6K_CONFIGURATION_DEVICE = AUTO;
+       FLEX10K_CONFIGURATION_DEVICE = AUTO;
+       EXCALIBUR_CONFIGURATION_DEVICE = AUTO;
+       STRATIX_CONFIGURATION_DEVICE = AUTO;
+       CYCLONE_CONFIGURATION_DEVICE = AUTO;
+       STRATIX_UPDATE_MODE = STANDARD;
+       APEX20K_CONFIG_DEVICE_JTAG_USER_CODE = FFFFFFFF;
+       MERCURY_CONFIG_DEVICE_JTAG_USER_CODE = FFFFFFFF;
+       FLEX10K_CONFIG_DEVICE_JTAG_USER_CODE = FFFFFFFF;
+       STRATIX_CONFIG_DEVICE_JTAG_USER_CODE = FFFFFFFF;
+       AUTO_INCREMENT_CONFIG_DEVICE_JTAG_USER_CODE = ON;
+       DISABLE_NCS_AND_OE_PULLUPS_ON_CONFIG_DEVICE = OFF;
+       COMPRESSION_MODE = OFF;
+       ENABLE_LOW_VOLTAGE_MODE_ON_CONFIG_DEVICE = ON;
+       FLEX6K_ENABLE_LOW_VOLTAGE_MODE_ON_CONFIG_DEVICE = OFF;
+       FLEX10K_ENABLE_LOW_VOLTAGE_MODE_ON_CONFIG_DEVICE = ON;
+       EPROM_USE_CHECKSUM_AS_USERCODE = OFF;
+       USE_CHECKSUM_AS_USERCODE = OFF;
+       MAX7000_USE_CHECKSUM_AS_USERCODE = OFF;
+       GENERATE_TTF_FILE = OFF;
+       GENERATE_RBF_FILE = ON;
+       GENERATE_HEX_FILE = OFF;
+       SECURITY_BIT = OFF;
+       ENABLE_VREFA_PIN = OFF;
+       ENABLE_VREFB_PIN = OFF;
+       GENERATE_SVF_FILE = OFF;
+       GENERATE_ISC_FILE = OFF;
+       GENERATE_JAM_FILE = OFF;
+       GENERATE_JBC_FILE = OFF;
+       GENERATE_JBC_FILE_COMPRESSED = ON;
+       GENERATE_CONFIG_SVF_FILE = OFF;
+       GENERATE_CONFIG_ISC_FILE = OFF;
+       GENERATE_CONFIG_JAM_FILE = OFF;
+       GENERATE_CONFIG_JBC_FILE = OFF;
+       GENERATE_CONFIG_JBC_FILE_COMPRESSED = ON;
+       GENERATE_CONFIG_HEXOUT_FILE = OFF;
+       ON_CHIP_BITSTREAM_DECOMPRESSION = OFF;
+       BASE_PIN_OUT_FILE_ON_SAMEFRAME_DEVICE = OFF;
+       HEXOUT_FILE_START_ADDRESS = 0;
+       HEXOUT_FILE_COUNT_DIRECTION = UP;
+       RESERVE_ALL_UNUSED_PINS = "AS INPUT TRI-STATED";
+       STRATIX_DEVICE_IO_STANDARD = LVTTL;
+       CLOCK_SOURCE = INTERNAL;
+       CONFIGURATION_CLOCK_FREQUENCY = "10 MHZ";
+       CONFIGURATION_CLOCK_DIVISOR = 1;
+       RESERVE_NWS_NRS_NCS_CS_AFTER_CONFIGURATION = "USE AS REGULAR IO";
+       RESERVE_RDYNBUSY_AFTER_CONFIGURATION = "USE AS REGULAR IO";
+       RESERVE_DATA7_THROUGH_DATA1_AFTER_CONFIGURATION = "USE AS REGULAR IO";
+       RESERVE_DATA0_AFTER_CONFIGURATION = "AS INPUT TRI-STATED";
+       RESERVE_NCEO_AFTER_CONFIGURATION = "USE AS REGULAR IO";
+       RESERVE_ASDO_AFTER_CONFIGURATION = "USE AS REGULAR IO";
+       SCLK : LOCATION = Pin_101;
+       SDI : LOCATION = Pin_100;
+       SEN : LOCATION = Pin_98;
+       SLD : LOCATION = Pin_95;
+       adc1_data[0] : LOCATION = Pin_5;
+       adc1_data[10] : LOCATION = Pin_235;
+       adc1_data[11] : LOCATION = Pin_234;
+       adc1_data[1] : LOCATION = Pin_4;
+       adc1_data[2] : LOCATION = Pin_3;
+       adc1_data[3] : LOCATION = Pin_2;
+       adc1_data[4] : LOCATION = Pin_1;
+       adc1_data[4] : IO_STANDARD = LVTTL;
+       adc1_data[5] : LOCATION = Pin_240;
+       adc1_data[6] : LOCATION = Pin_239;
+       adc1_data[7] : LOCATION = Pin_238;
+       adc1_data[8] : LOCATION = Pin_237;
+       adc1_data[9] : LOCATION = Pin_236;
+       adc2_data[0] : LOCATION = Pin_20;
+       adc2_data[10] : LOCATION = Pin_8;
+       adc2_data[11] : LOCATION = Pin_7;
+       adc2_data[1] : LOCATION = Pin_19;
+       adc2_data[2] : LOCATION = Pin_18;
+       adc2_data[3] : LOCATION = Pin_17;
+       adc2_data[4] : LOCATION = Pin_16;
+       adc2_data[5] : LOCATION = Pin_15;
+       adc2_data[6] : LOCATION = Pin_14;
+       adc2_data[7] : LOCATION = Pin_13;
+       adc2_data[8] : LOCATION = Pin_12;
+       adc2_data[9] : LOCATION = Pin_11;
+       adc3_data[0] : LOCATION = Pin_200;
+       adc3_data[10] : LOCATION = Pin_184;
+       adc3_data[11] : LOCATION = Pin_183;
+       adc3_data[1] : LOCATION = Pin_197;
+       adc3_data[2] : LOCATION = Pin_196;
+       adc3_data[3] : LOCATION = Pin_195;
+       adc3_data[4] : LOCATION = Pin_194;
+       adc3_data[5] : LOCATION = Pin_193;
+       adc3_data[6] : LOCATION = Pin_188;
+       adc3_data[7] : LOCATION = Pin_187;
+       adc3_data[8] : LOCATION = Pin_186;
+       adc3_data[9] : LOCATION = Pin_185;
+       adc4_data[0] : LOCATION = Pin_222;
+       adc4_data[10] : LOCATION = Pin_203;
+       adc4_data[11] : LOCATION = Pin_202;
+       adc4_data[1] : LOCATION = Pin_219;
+       adc4_data[2] : LOCATION = Pin_217;
+       adc4_data[3] : LOCATION = Pin_216;
+       adc4_data[4] : LOCATION = Pin_215;
+       adc4_data[5] : LOCATION = Pin_214;
+       adc4_data[6] : LOCATION = Pin_213;
+       adc4_data[7] : LOCATION = Pin_208;
+       adc4_data[8] : LOCATION = Pin_207;
+       adc4_data[9] : LOCATION = Pin_206;
+       adc_oeb[0] : LOCATION = Pin_228;
+       adc_oeb[1] : LOCATION = Pin_21;
+       adc_oeb[2] : LOCATION = Pin_181;
+       adc_oeb[3] : LOCATION = Pin_218;
+       adc_otr[0] : LOCATION = Pin_233;
+       adc_otr[1] : LOCATION = Pin_6;
+       adc_otr[2] : LOCATION = Pin_182;
+       adc_otr[3] : LOCATION = Pin_201;
+       adclk0 : LOCATION = Pin_224;
+       adclk1 : LOCATION = Pin_226;
+       clk0 : LOCATION = Pin_28;
+       clk0 : RESERVE_PIN = "AS INPUT TRI-STATED";
+       clk0 : IO_STANDARD = LVTTL;
+       clk1 : LOCATION = Pin_29;
+       clk1 : RESERVE_PIN = "AS INPUT TRI-STATED";
+       clk1 : IO_STANDARD = LVTTL;
+       clk3 : LOCATION = Pin_152;
+       clk3 : RESERVE_PIN = "AS INPUT TRI-STATED";
+       clk3 : IO_STANDARD = LVTTL;
+       clk_120mhz : LOCATION = Pin_153;
+       clk_120mhz : IO_STANDARD = LVTTL;
+       clk_out : LOCATION = Pin_63;
+       clk_out : IO_STANDARD = LVTTL;
+       dac1_data[0] : LOCATION = Pin_165;
+       dac1_data[10] : LOCATION = Pin_177;
+       dac1_data[11] : LOCATION = Pin_178;
+       dac1_data[12] : LOCATION = Pin_179;
+       dac1_data[13] : LOCATION = Pin_180;
+       dac1_data[1] : LOCATION = Pin_166;
+       dac1_data[2] : LOCATION = Pin_167;
+       dac1_data[3] : LOCATION = Pin_168;
+       dac1_data[4] : LOCATION = Pin_169;
+       dac1_data[5] : LOCATION = Pin_170;
+       dac1_data[6] : LOCATION = Pin_173;
+       dac1_data[7] : LOCATION = Pin_174;
+       dac1_data[8] : LOCATION = Pin_175;
+       dac1_data[9] : LOCATION = Pin_176;
+       dac2_data[0] : LOCATION = Pin_159;
+       dac2_data[10] : LOCATION = Pin_163;
+       dac2_data[11] : LOCATION = Pin_139;
+       dac2_data[12] : LOCATION = Pin_164;
+       dac2_data[13] : LOCATION = Pin_138;
+       dac2_data[1] : LOCATION = Pin_158;
+       dac2_data[2] : LOCATION = Pin_160;
+       dac2_data[3] : LOCATION = Pin_156;
+       dac2_data[4] : LOCATION = Pin_161;
+       dac2_data[5] : LOCATION = Pin_144;
+       dac2_data[6] : LOCATION = Pin_162;
+       dac2_data[7] : LOCATION = Pin_141;
+       dac2_data[8] : LOCATION = Pin_143;
+       dac2_data[9] : LOCATION = Pin_140;
+       dac3_data[0] : LOCATION = Pin_122;
+       dac3_data[10] : LOCATION = Pin_134;
+       dac3_data[11] : LOCATION = Pin_135;
+       dac3_data[12] : LOCATION = Pin_136;
+       dac3_data[13] : LOCATION = Pin_137;
+       dac3_data[1] : LOCATION = Pin_123;
+       dac3_data[2] : LOCATION = Pin_124;
+       dac3_data[3] : LOCATION = Pin_125;
+       dac3_data[4] : LOCATION = Pin_126;
+       dac3_data[5] : LOCATION = Pin_127;
+       dac3_data[6] : LOCATION = Pin_128;
+       dac3_data[7] : LOCATION = Pin_131;
+       dac3_data[8] : LOCATION = Pin_132;
+       dac3_data[9] : LOCATION = Pin_133;
+       dac4_data[0] : LOCATION = Pin_104;
+       dac4_data[10] : LOCATION = Pin_118;
+       dac4_data[11] : LOCATION = Pin_119;
+       dac4_data[12] : LOCATION = Pin_120;
+       dac4_data[13] : LOCATION = Pin_121;
+       dac4_data[1] : LOCATION = Pin_105;
+       dac4_data[2] : LOCATION = Pin_106;
+       dac4_data[3] : LOCATION = Pin_107;
+       dac4_data[4] : LOCATION = Pin_108;
+       dac4_data[5] : LOCATION = Pin_113;
+       dac4_data[6] : LOCATION = Pin_114;
+       dac4_data[7] : LOCATION = Pin_115;
+       dac4_data[8] : LOCATION = Pin_116;
+       dac4_data[9] : LOCATION = Pin_117;
+       enable_rx : LOCATION = Pin_88;
+       enable_tx : LOCATION = Pin_93;
+       gndbus[0] : LOCATION = Pin_223;
+       gndbus[0] : RESERVE_PIN = "AS INPUT TRI-STATED";
+       gndbus[0] : IO_STANDARD = LVTTL;
+       gndbus[1] : LOCATION = Pin_225;
+       gndbus[1] : RESERVE_PIN = "AS INPUT TRI-STATED";
+       gndbus[1] : IO_STANDARD = LVTTL;
+       gndbus[2] : LOCATION = Pin_227;
+       gndbus[2] : RESERVE_PIN = "AS INPUT TRI-STATED";
+       gndbus[2] : IO_STANDARD = LVTTL;
+       gndbus[3] : LOCATION = Pin_62;
+       gndbus[3] : RESERVE_PIN = "AS INPUT TRI-STATED";
+       gndbus[3] : IO_STANDARD = LVTTL;
+       gndbus[4] : LOCATION = Pin_64;
+       gndbus[4] : RESERVE_PIN = "AS INPUT TRI-STATED";
+       gndbus[4] : IO_STANDARD = LVTTL;
+       misc_pins[0] : LOCATION = Pin_87;
+       misc_pins[0] : IO_STANDARD = LVTTL;
+       misc_pins[10] : LOCATION = Pin_76;
+       misc_pins[10] : IO_STANDARD = LVTTL;
+       misc_pins[11] : LOCATION = Pin_74;
+       misc_pins[11] : IO_STANDARD = LVTTL;
+       misc_pins[1] : LOCATION = Pin_86;
+       misc_pins[1] : IO_STANDARD = LVTTL;
+       misc_pins[2] : LOCATION = Pin_85;
+       misc_pins[2] : IO_STANDARD = LVTTL;
+       misc_pins[3] : LOCATION = Pin_84;
+       misc_pins[3] : IO_STANDARD = LVTTL;
+       misc_pins[4] : LOCATION = Pin_83;
+       misc_pins[4] : IO_STANDARD = LVTTL;
+       misc_pins[5] : LOCATION = Pin_82;
+       misc_pins[5] : IO_STANDARD = LVTTL;
+       misc_pins[6] : LOCATION = Pin_79;
+       misc_pins[6] : IO_STANDARD = LVTTL;
+       misc_pins[7] : LOCATION = Pin_78;
+       misc_pins[7] : IO_STANDARD = LVTTL;
+       misc_pins[8] : LOCATION = Pin_77;
+       misc_pins[8] : IO_STANDARD = LVTTL;
+       misc_pins[9] : LOCATION = Pin_75;
+       misc_pins[9] : IO_STANDARD = LVTTL;
+       reset : LOCATION = Pin_94;
+       usbclk : LOCATION = Pin_55;
+       usbctl[0] : LOCATION = Pin_56;
+       usbctl[1] : LOCATION = Pin_54;
+       usbctl[2] : LOCATION = Pin_53;
+       usbctl[3] : LOCATION = Pin_58;
+       usbctl[4] : LOCATION = Pin_57;
+       usbctl[5] : LOCATION = Pin_44;
+       usbdata[0] : LOCATION = Pin_73;
+       usbdata[10] : LOCATION = Pin_41;
+       usbdata[11] : LOCATION = Pin_39;
+       usbdata[12] : LOCATION = Pin_38;
+       usbdata[12] : IO_STANDARD = LVTTL;
+       usbdata[13] : LOCATION = Pin_37;
+       usbdata[14] : LOCATION = Pin_24;
+       usbdata[15] : LOCATION = Pin_23;
+       usbdata[1] : LOCATION = Pin_68;
+       usbdata[2] : LOCATION = Pin_67;
+       usbdata[3] : LOCATION = Pin_66;
+       usbdata[4] : LOCATION = Pin_65;
+       usbdata[5] : LOCATION = Pin_61;
+       usbdata[6] : LOCATION = Pin_60;
+       usbdata[7] : LOCATION = Pin_59;
+       usbdata[8] : LOCATION = Pin_43;
+       usbdata[9] : LOCATION = Pin_42;
+       usbrdy[0] : LOCATION = Pin_45;
+       usbrdy[1] : LOCATION = Pin_46;
+       usbrdy[2] : LOCATION = Pin_47;
+       usbrdy[3] : LOCATION = Pin_48;
+       usbrdy[4] : LOCATION = Pin_49;
+       usbrdy[5] : LOCATION = Pin_50;
+       clear_status : LOCATION = Pin_99;
+}
diff --git a/usrp/fpga/toplevel/usrp_multi/usrp_multi.esf b/usrp/fpga/toplevel/usrp_multi/usrp_multi.esf
new file mode 100644 (file)
index 0000000..df45f67
--- /dev/null
@@ -0,0 +1,14 @@
+SIMULATOR_SETTINGS
+{
+       ESTIMATE_POWER_CONSUMPTION = OFF;
+       GLITCH_INTERVAL = 1NS;
+       GLITCH_DETECTION = OFF;
+       SIMULATION_COVERAGE = ON;
+       CHECK_OUTPUTS = OFF;
+       SETUP_HOLD_DETECTION = OFF;
+       POWER_ESTIMATION_START_TIME = "0 NS";
+       ADD_DEFAULT_PINS_TO_SIMULATION_OUTPUT_WAVEFORMS = ON;
+       SIMULATION_MODE = TIMING;
+       START_TIME = 0NS;
+       USE_COMPILER_SETTINGS = usrp_multi;
+}
diff --git a/usrp/fpga/toplevel/usrp_multi/usrp_multi.psf b/usrp/fpga/toplevel/usrp_multi/usrp_multi.psf
new file mode 100644 (file)
index 0000000..68c2d12
--- /dev/null
@@ -0,0 +1,312 @@
+DEFAULT_DESIGN_ASSISTANT_SETTINGS
+{
+       HCPY_ALOAD_SIGNALS = OFF;
+       HCPY_VREF_PINS = OFF;
+       HCPY_CAT = OFF;
+       HCPY_ILLEGAL_HC_DEV_PKG = OFF;
+       ACLK_RULE_IMSZER_ADOMAIN = OFF;
+       ACLK_RULE_SZER_BTW_ACLK_DOMAIN = OFF;
+       ACLK_RULE_NO_SZER_ACLK_DOMAIN = OFF;
+       ACLK_CAT = OFF;
+       SIGNALRACE_RULE_ASYNCHPIN_SYNCH_CLKPIN = OFF;
+       SIGNALRACE_CAT = OFF;
+       NONSYNCHSTRUCT_RULE_LATCH_UNIDENTIFIED = OFF;
+       NONSYNCHSTRUCT_RULE_SRLATCH = OFF;
+       NONSYNCHSTRUCT_RULE_DLATCH = OFF;
+       NONSYNCHSTRUCT_RULE_MULTI_VIBRATOR = OFF;
+       NONSYNCHSTRUCT_RULE_ILLEGAL_PULSE_GEN = OFF;
+       NONSYNCHSTRUCT_RULE_RIPPLE_CLK = OFF;
+       NONSYNCHSTRUCT_RULE_DELAY_CHAIN = OFF;
+       NONSYNCHSTRUCT_RULE_REG_LOOP = OFF;
+       NONSYNCHSTRUCT_RULE_COMBLOOP = OFF;
+       NONSYNCHSTRUCT_CAT = OFF;
+       NONSYNCHSTRUCT_RULE_COMB_DRIVES_RAM_WE = OFF;
+       TIMING_RULE_COIN_CLKEDGE = OFF;
+       TIMING_RULE_SHIFT_REG = OFF;
+       TIMING_RULE_HIGH_FANOUTS = OFF;
+       TIMING_CAT = OFF;
+       RESET_RULE_ALL = OFF;
+       RESET_RULE_IMSYNCH_ASYNCH_DOMAIN = OFF;
+       RESET_RULE_UNSYNCH_ASYNCH_DOMAIN = OFF;
+       RESET_RULE_REG_ASNYCH = OFF;
+       RESET_RULE_COMB_ASYNCH_RESET = OFF;
+       RESET_RULE_IMSYNCH_EXRESET = OFF;
+       RESET_RULE_UNSYNCH_EXRESET = OFF;
+       RESET_RULE_INPINS_RESETNET = OFF;
+       RESET_CAT = OFF;
+       CLK_RULE_ALL = OFF;
+       CLK_RULE_MIX_EDGES = OFF;
+       CLK_RULE_CLKNET_CLKSPINES = OFF;
+       CLK_RULE_INPINS_CLKNET = OFF;
+       CLK_RULE_GATING_SCHEME = OFF;
+       CLK_RULE_INV_CLOCK = OFF;
+       CLK_RULE_COMB_CLOCK = OFF;
+       CLK_CAT = OFF;
+       HCPY_EXCEED_USER_IO_USAGE = OFF;
+       HCPY_EXCEED_RAM_USAGE = OFF;
+       NONSYNCHSTRUCT_RULE_ASYN_RAM = OFF;
+       SIGNALRACE_RULE_TRISTATE = OFF;
+       ASSG_RULE_MISSING_TIMING = OFF;
+       ASSG_RULE_MISSING_FMAX = OFF;
+       ASSG_CAT = OFF;
+}
+SYNTHESIS_FITTING_SETTINGS
+{
+       AUTO_SHIFT_REGISTER_RECOGNITION = ON;
+       AUTO_DSP_RECOGNITION = ON;
+       AUTO_RAM_RECOGNITION = ON;
+       REMOVE_DUPLICATE_LOGIC = ON;
+       AUTO_TURBO_BIT = ON;
+       AUTO_MERGE_PLLS = ON;
+       AUTO_OPEN_DRAIN_PINS = ON;
+       AUTO_PARALLEL_EXPANDERS = ON;
+       AUTO_FAST_OUTPUT_ENABLE_REGISTERS = OFF;
+       AUTO_FAST_OUTPUT_REGISTERS = OFF;
+       AUTO_FAST_INPUT_REGISTERS = OFF;
+       AUTO_CASCADE_CHAINS = ON;
+       AUTO_CARRY_CHAINS = ON;
+       AUTO_DELAY_CHAINS = ON;
+       MAX7000_PARALLEL_EXPANDER_CHAIN_LENGTH = 4;
+       PARALLEL_EXPANDER_CHAIN_LENGTH = 16;
+       CASCADE_CHAIN_LENGTH = 2;
+       STRATIX_CARRY_CHAIN_LENGTH = 70;
+       MERCURY_CARRY_CHAIN_LENGTH = 48;
+       FLEX10K_CARRY_CHAIN_LENGTH = 32;
+       FLEX6K_CARRY_CHAIN_LENGTH = 32;
+       CARRY_CHAIN_LENGTH = 48;
+       CARRY_OUT_PINS_LCELL_INSERT = ON;
+       NORMAL_LCELL_INSERT = ON;
+       AUTO_LCELL_INSERTION = ON;
+       ALLOW_XOR_GATE_USAGE = ON;
+       AUTO_PACKED_REGISTERS_STRATIX = NORMAL;
+       AUTO_PACKED_REGISTERS = OFF;
+       AUTO_PACKED_REG_CYCLONE = NORMAL;
+       FLEX10K_OPTIMIZATION_TECHNIQUE = AREA;
+       FLEX6K_OPTIMIZATION_TECHNIQUE = AREA;
+       MERCURY_OPTIMIZATION_TECHNIQUE = AREA;
+       APEX20K_OPTIMIZATION_TECHNIQUE = SPEED;
+       MAX7000_OPTIMIZATION_TECHNIQUE = SPEED;
+       STRATIX_OPTIMIZATION_TECHNIQUE = SPEED;
+       CYCLONE_OPTIMIZATION_TECHNIQUE = AREA;
+       FLEX10K_TECHNOLOGY_MAPPER = LUT;
+       FLEX6K_TECHNOLOGY_MAPPER = LUT;
+       MERCURY_TECHNOLOGY_MAPPER = LUT;
+       APEX20K_TECHNOLOGY_MAPPER = LUT;
+       MAX7000_TECHNOLOGY_MAPPER = "PRODUCT TERM";
+       STRATIX_TECHNOLOGY_MAPPER = LUT;
+       AUTO_IMPLEMENT_IN_ROM = OFF;
+       AUTO_GLOBAL_MEMORY_CONTROLS = OFF;
+       AUTO_GLOBAL_REGISTER_CONTROLS = ON;
+       AUTO_GLOBAL_OE = ON;
+       AUTO_GLOBAL_CLOCK = ON;
+       USE_LPM_FOR_AHDL_OPERATORS = ON;
+       LIMIT_AHDL_INTEGERS_TO_32_BITS = OFF;
+       ENABLE_BUS_HOLD_CIRCUITRY = OFF;
+       WEAK_PULL_UP_RESISTOR = OFF;
+       TURBO_BIT = ON;
+       MAX7000_IGNORE_SOFT_BUFFERS = OFF;
+       IGNORE_SOFT_BUFFERS = ON;
+       MAX7000_IGNORE_LCELL_BUFFERS = AUTO;
+       IGNORE_LCELL_BUFFERS = OFF;
+       IGNORE_ROW_GLOBAL_BUFFERS = OFF;
+       IGNORE_GLOBAL_BUFFERS = OFF;
+       IGNORE_CASCADE_BUFFERS = OFF;
+       IGNORE_CARRY_BUFFERS = OFF;
+       REMOVE_DUPLICATE_REGISTERS = ON;
+       REMOVE_REDUNDANT_LOGIC_CELLS = OFF;
+       ALLOW_POWER_UP_DONT_CARE = ON;
+       PCI_IO = OFF;
+       NOT_GATE_PUSH_BACK = ON;
+       SLOW_SLEW_RATE = OFF;
+       DSP_BLOCK_BALANCING = AUTO;
+       STATE_MACHINE_PROCESSING = AUTO;
+}
+DEFAULT_HARDCOPY_SETTINGS
+{
+       HARDCOPY_EXTERNAL_CLOCK_JITTER = "0.0 NS";
+}
+DEFAULT_TIMING_REQUIREMENTS
+{
+       INCLUDE_EXTERNAL_PIN_DELAYS_IN_FMAX_CALCULATIONS = OFF;
+       RUN_ALL_TIMING_ANALYSES = ON;
+       IGNORE_CLOCK_SETTINGS = OFF;
+       DEFAULT_HOLD_MULTICYCLE = "SAME AS MULTICYCLE";
+       CUT_OFF_IO_PIN_FEEDBACK = ON;
+       CUT_OFF_CLEAR_AND_PRESET_PATHS = ON;
+       CUT_OFF_READ_DURING_WRITE_PATHS = ON;
+       CUT_OFF_PATHS_BETWEEN_CLOCK_DOMAINS = ON;
+       DO_MIN_ANALYSIS = ON;
+       DO_MIN_TIMING = OFF;
+       NUMBER_OF_PATHS_TO_REPORT = 200;
+       NUMBER_OF_DESTINATION_TO_REPORT = 10;
+       NUMBER_OF_SOURCES_PER_DESTINATION_TO_REPORT = 10;
+       MAX_SCC_SIZE = 50;
+}
+HDL_SETTINGS
+{
+       VERILOG_INPUT_VERSION = VERILOG_2001;
+       ENABLE_IP_DEBUG = OFF;
+       VHDL_INPUT_VERSION = VHDL93;
+       VHDL_SHOW_LMF_MAPPING_MESSAGES = OFF;
+}
+PROJECT_INFO(usrp_multi)
+{
+       ORIGINAL_QUARTUS_VERSION = 3.0;
+       PROJECT_CREATION_TIME_DATE = "00:14:04  JULY 13, 2003";
+       LAST_QUARTUS_VERSION = 3.0;
+       SHOW_REGISTRATION_MESSAGE = ON;
+       USER_LIBRARIES = "e:\usrp\fpga\megacells";
+}
+THIRD_PARTY_EDA_TOOLS(usrp_multi)
+{
+       EDA_DESIGN_ENTRY_SYNTHESIS_TOOL = "<NONE>";
+       EDA_SIMULATION_TOOL = "<NONE>";
+       EDA_TIMING_ANALYSIS_TOOL = "<NONE>";
+       EDA_BOARD_DESIGN_TOOL = "<NONE>";
+       EDA_FORMAL_VERIFICATION_TOOL = "<NONE>";
+       EDA_RESYNTHESIS_TOOL = "<NONE>";
+}
+EDA_TOOL_SETTINGS(eda_design_synthesis)
+{
+       EDA_INPUT_GND_NAME = GND;
+       EDA_INPUT_VCC_NAME = VCC;
+       EDA_SHOW_LMF_MAPPING_MESSAGES = OFF;
+       EDA_RUN_TOOL_AUTOMATICALLY = OFF;
+       EDA_INPUT_DATA_FORMAT = EDIF;
+       EDA_OUTPUT_DATA_FORMAT = NONE;
+       USE_GENERATED_PHYSICAL_CONSTRAINTS = ON;
+       RESYNTHESIS_PHYSICAL_SYNTHESIS = NORMAL;
+       RESYNTHESIS_OPTIMIZATION_EFFORT = NORMAL;
+       RESYNTHESIS_RETIMING = FULL;
+}
+EDA_TOOL_SETTINGS(eda_simulation)
+{
+       EDA_INCLUDE_VHDL_CONFIGURATION_DECLARATION = OFF;
+       EDA_TRUNCATE_LONG_HIERARCHY_PATHS = OFF;
+       EDA_MAINTAIN_DESIGN_HIERARCHY = OFF;
+       EDA_WRITE_DEVICE_CONTROL_PORTS = OFF;
+       EDA_GENERATE_FUNCTIONAL_NETLIST = OFF;
+       EDA_FLATTEN_BUSES = OFF;
+       EDA_MAP_ILLEGAL_CHARACTERS = OFF;
+       EDA_EXCALIBUR_ATOMS_AS_SINGLE_STRIPE = OFF;
+       EDA_RUN_TOOL_AUTOMATICALLY = OFF;
+       EDA_OUTPUT_DATA_FORMAT = NONE;
+       USE_GENERATED_PHYSICAL_CONSTRAINTS = ON;
+       RESYNTHESIS_PHYSICAL_SYNTHESIS = NORMAL;
+       RESYNTHESIS_OPTIMIZATION_EFFORT = NORMAL;
+       RESYNTHESIS_RETIMING = FULL;
+}
+EDA_TOOL_SETTINGS(eda_timing_analysis)
+{
+       EDA_INCLUDE_VHDL_CONFIGURATION_DECLARATION = OFF;
+       EDA_TRUNCATE_LONG_HIERARCHY_PATHS = OFF;
+       EDA_MAINTAIN_DESIGN_HIERARCHY = OFF;
+       EDA_WRITE_DEVICE_CONTROL_PORTS = OFF;
+       EDA_GENERATE_FUNCTIONAL_NETLIST = OFF;
+       EDA_FLATTEN_BUSES = OFF;
+       EDA_MAP_ILLEGAL_CHARACTERS = OFF;
+       EDA_EXCALIBUR_ATOMS_AS_SINGLE_STRIPE = OFF;
+       EDA_RUN_TOOL_AUTOMATICALLY = OFF;
+       EDA_OUTPUT_DATA_FORMAT = NONE;
+       EDA_LAUNCH_CMD_LINE_TOOL = OFF;
+       USE_GENERATED_PHYSICAL_CONSTRAINTS = ON;
+       RESYNTHESIS_PHYSICAL_SYNTHESIS = NORMAL;
+       RESYNTHESIS_OPTIMIZATION_EFFORT = NORMAL;
+       RESYNTHESIS_RETIMING = FULL;
+}
+EDA_TOOL_SETTINGS(eda_board_design)
+{
+       EDA_INCLUDE_VHDL_CONFIGURATION_DECLARATION = OFF;
+       EDA_TRUNCATE_LONG_HIERARCHY_PATHS = OFF;
+       EDA_MAINTAIN_DESIGN_HIERARCHY = OFF;
+       EDA_WRITE_DEVICE_CONTROL_PORTS = OFF;
+       EDA_GENERATE_FUNCTIONAL_NETLIST = OFF;
+       EDA_FLATTEN_BUSES = OFF;
+       EDA_MAP_ILLEGAL_CHARACTERS = OFF;
+       EDA_EXCALIBUR_ATOMS_AS_SINGLE_STRIPE = OFF;
+       EDA_RUN_TOOL_AUTOMATICALLY = OFF;
+       EDA_OUTPUT_DATA_FORMAT = NONE;
+       USE_GENERATED_PHYSICAL_CONSTRAINTS = ON;
+       RESYNTHESIS_PHYSICAL_SYNTHESIS = NORMAL;
+       RESYNTHESIS_OPTIMIZATION_EFFORT = NORMAL;
+       RESYNTHESIS_RETIMING = FULL;
+}
+EDA_TOOL_SETTINGS(eda_formal_verification)
+{
+       EDA_INCLUDE_VHDL_CONFIGURATION_DECLARATION = OFF;
+       EDA_TRUNCATE_LONG_HIERARCHY_PATHS = OFF;
+       EDA_MAINTAIN_DESIGN_HIERARCHY = OFF;
+       EDA_WRITE_DEVICE_CONTROL_PORTS = OFF;
+       EDA_GENERATE_FUNCTIONAL_NETLIST = OFF;
+       EDA_FLATTEN_BUSES = OFF;
+       EDA_MAP_ILLEGAL_CHARACTERS = OFF;
+       EDA_EXCALIBUR_ATOMS_AS_SINGLE_STRIPE = OFF;
+       EDA_RUN_TOOL_AUTOMATICALLY = OFF;
+       EDA_OUTPUT_DATA_FORMAT = NONE;
+       USE_GENERATED_PHYSICAL_CONSTRAINTS = ON;
+       RESYNTHESIS_PHYSICAL_SYNTHESIS = NORMAL;
+       RESYNTHESIS_OPTIMIZATION_EFFORT = NORMAL;
+       RESYNTHESIS_RETIMING = FULL;
+}
+EDA_TOOL_SETTINGS(eda_palace)
+{
+       EDA_INCLUDE_VHDL_CONFIGURATION_DECLARATION = OFF;
+       EDA_TRUNCATE_LONG_HIERARCHY_PATHS = OFF;
+       EDA_MAINTAIN_DESIGN_HIERARCHY = OFF;
+       EDA_WRITE_DEVICE_CONTROL_PORTS = OFF;
+       EDA_GENERATE_FUNCTIONAL_NETLIST = OFF;
+       EDA_FLATTEN_BUSES = OFF;
+       EDA_MAP_ILLEGAL_CHARACTERS = OFF;
+       EDA_EXCALIBUR_ATOMS_AS_SINGLE_STRIPE = OFF;
+       EDA_RUN_TOOL_AUTOMATICALLY = OFF;
+       EDA_OUTPUT_DATA_FORMAT = NONE;
+       RESYNTHESIS_RETIMING = FULL;
+       RESYNTHESIS_PHYSICAL_SYNTHESIS = NORMAL;
+       RESYNTHESIS_OPTIMIZATION_EFFORT = NORMAL;
+       USE_GENERATED_PHYSICAL_CONSTRAINTS = ON;
+}
+CLOCK(clk_120mhz)
+{
+       FMAX_REQUIREMENT = "120.0 MHz";
+       INCLUDE_EXTERNAL_PIN_DELAYS_IN_FMAX_CALCULATIONS = OFF;
+       DUTY_CYCLE = 50;
+       DIVIDE_BASE_CLOCK_PERIOD_BY = 1;
+       MULTIPLY_BASE_CLOCK_PERIOD_BY = 1;
+       INVERT_BASE_CLOCK = OFF;
+}
+CLOCK(usbclk)
+{
+       FMAX_REQUIREMENT = "48.0 MHz";
+       INCLUDE_EXTERNAL_PIN_DELAYS_IN_FMAX_CALCULATIONS = OFF;
+       DUTY_CYCLE = 50;
+       DIVIDE_BASE_CLOCK_PERIOD_BY = 1;
+       MULTIPLY_BASE_CLOCK_PERIOD_BY = 1;
+       INVERT_BASE_CLOCK = OFF;
+}
+CLOCK(SCLK)
+{
+       FMAX_REQUIREMENT = "1.0 MHz";
+       INCLUDE_EXTERNAL_PIN_DELAYS_IN_FMAX_CALCULATIONS = OFF;
+       DUTY_CYCLE = 50;
+       DIVIDE_BASE_CLOCK_PERIOD_BY = 1;
+       MULTIPLY_BASE_CLOCK_PERIOD_BY = 1;
+       INVERT_BASE_CLOCK = OFF;
+}
+CLOCK(adclk0)
+{
+       FMAX_REQUIREMENT = "60.0 MHz";
+       INCLUDE_EXTERNAL_PIN_DELAYS_IN_FMAX_CALCULATIONS = OFF;
+       DUTY_CYCLE = 50;
+       DIVIDE_BASE_CLOCK_PERIOD_BY = 1;
+       MULTIPLY_BASE_CLOCK_PERIOD_BY = 1;
+       INVERT_BASE_CLOCK = OFF;
+}
+CLOCK(adclk1)
+{
+       FMAX_REQUIREMENT = "60.0 MHz";
+       INCLUDE_EXTERNAL_PIN_DELAYS_IN_FMAX_CALCULATIONS = OFF;
+       DUTY_CYCLE = 50;
+       DIVIDE_BASE_CLOCK_PERIOD_BY = 1;
+       MULTIPLY_BASE_CLOCK_PERIOD_BY = 1;
+       INVERT_BASE_CLOCK = OFF;
+}
diff --git a/usrp/fpga/toplevel/usrp_multi/usrp_multi.qpf b/usrp/fpga/toplevel/usrp_multi/usrp_multi.qpf
new file mode 100644 (file)
index 0000000..1524de1
--- /dev/null
@@ -0,0 +1,29 @@
+# Copyright (C) 1991-2004 Altera Corporation
+# Any  megafunction  design,  and related netlist (encrypted  or  decrypted),
+# support information,  device programming or simulation file,  and any other
+# associated  documentation or information  provided by  Altera  or a partner
+# under  Altera's   Megafunction   Partnership   Program  may  be  used  only
+# to program  PLD  devices (but not masked  PLD  devices) from  Altera.   Any
+# other  use  of such  megafunction  design,  netlist,  support  information,
+# device programming or simulation file,  or any other  related documentation
+# or information  is prohibited  for  any  other purpose,  including, but not
+# limited to  modification,  reverse engineering,  de-compiling, or use  with
+# any other  silicon devices,  unless such use is  explicitly  licensed under
+# a separate agreement with  Altera  or a megafunction partner.  Title to the
+# intellectual property,  including patents,  copyrights,  trademarks,  trade
+# secrets,  or maskworks,  embodied in any such megafunction design, netlist,
+# support  information,  device programming or simulation file,  or any other
+# related documentation or information provided by  Altera  or a megafunction
+# partner, remains with Altera, the megafunction partner, or their respective
+# licensors. No other licenses, including any licenses needed under any third
+# party's intellectual property, are provided herein.
+
+
+
+QUARTUS_VERSION = "4.0"
+DATE = "17:10:11  December 20, 2004"
+
+
+# Active Revisions
+
+PROJECT_REVISION = "usrp_multi"
diff --git a/usrp/fpga/toplevel/usrp_multi/usrp_multi.qsf b/usrp/fpga/toplevel/usrp_multi/usrp_multi.qsf
new file mode 100644 (file)
index 0000000..e45c683
--- /dev/null
@@ -0,0 +1,408 @@
+# Copyright (C) 1991-2005 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 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
+# The default values for assignments are stored in the file\r
+#              usrp_multi_assignment_defaults.qdf\r
+# If this file doesn't exist, and for assignments not listed, see file\r
+#              assignment_defaults.qdf\r
+\r
+# Altera recommends that you do not modify this file. This\r
+# file is updated automatically by the Quartus II software\r
+# and any changes you make may be lost or overwritten.\r
+\r
+\r
+# Project-Wide Assignments\r
+# ========================\r
+set_global_assignment -name ORIGINAL_QUARTUS_VERSION 3.0\r
+set_global_assignment -name PROJECT_CREATION_TIME_DATE "00:14:04  JULY 13, 2003"\r
+set_global_assignment -name LAST_QUARTUS_VERSION "5.1 SP1"\r
+\r
+# Pin & Location Assignments\r
+# ==========================\r
+set_global_assignment -name RESERVE_PIN "AS INPUT TRI-STATED"\r
+set_location_assignment PIN_29 -to SCLK\r
+set_location_assignment PIN_117 -to SDI\r
+set_location_assignment PIN_28 -to usbclk\r
+set_location_assignment PIN_107 -to usbctl[0]\r
+set_location_assignment PIN_106 -to usbctl[1]\r
+set_location_assignment PIN_105 -to usbctl[2]\r
+set_location_assignment PIN_100 -to usbdata[0]\r
+set_location_assignment PIN_84 -to usbdata[10]\r
+set_location_assignment PIN_83 -to usbdata[11]\r
+set_location_assignment PIN_82 -to usbdata[12]\r
+set_location_assignment PIN_79 -to usbdata[13]\r
+set_location_assignment PIN_78 -to usbdata[14]\r
+set_location_assignment PIN_77 -to usbdata[15]\r
+set_location_assignment PIN_99 -to usbdata[1]\r
+set_location_assignment PIN_98 -to usbdata[2]\r
+set_location_assignment PIN_95 -to usbdata[3]\r
+set_location_assignment PIN_94 -to usbdata[4]\r
+set_location_assignment PIN_93 -to usbdata[5]\r
+set_location_assignment PIN_88 -to usbdata[6]\r
+set_location_assignment PIN_87 -to usbdata[7]\r
+set_location_assignment PIN_86 -to usbdata[8]\r
+set_location_assignment PIN_85 -to usbdata[9]\r
+set_location_assignment PIN_104 -to usbrdy[0]\r
+set_location_assignment PIN_101 -to usbrdy[1]\r
+set_location_assignment PIN_76 -to FX2_1\r
+set_location_assignment PIN_75 -to FX2_2\r
+set_location_assignment PIN_74 -to FX2_3\r
+set_location_assignment PIN_116 -to io_rx_a[0]\r
+set_location_assignment PIN_115 -to io_rx_a[1]\r
+set_location_assignment PIN_114 -to io_rx_a[2]\r
+set_location_assignment PIN_113 -to io_rx_a[3]\r
+set_location_assignment PIN_108 -to io_rx_a[4]\r
+set_location_assignment PIN_195 -to io_rx_a[5]\r
+set_location_assignment PIN_196 -to io_rx_a[6]\r
+set_location_assignment PIN_197 -to io_rx_a[7]\r
+set_location_assignment PIN_200 -to io_rx_a[8]\r
+set_location_assignment PIN_201 -to io_rx_a[9]\r
+set_location_assignment PIN_202 -to io_rx_a[10]\r
+set_location_assignment PIN_203 -to io_rx_a[11]\r
+set_location_assignment PIN_206 -to io_rx_a[12]\r
+set_location_assignment PIN_207 -to io_rx_a[13]\r
+set_location_assignment PIN_208 -to io_rx_a[14]\r
+set_location_assignment PIN_214 -to io_rx_b[0]\r
+set_location_assignment PIN_215 -to io_rx_b[1]\r
+set_location_assignment PIN_216 -to io_rx_b[2]\r
+set_location_assignment PIN_217 -to io_rx_b[3]\r
+set_location_assignment PIN_218 -to io_rx_b[4]\r
+set_location_assignment PIN_219 -to io_rx_b[5]\r
+set_location_assignment PIN_222 -to io_rx_b[6]\r
+set_location_assignment PIN_223 -to io_rx_b[7]\r
+set_location_assignment PIN_224 -to io_rx_b[8]\r
+set_location_assignment PIN_225 -to io_rx_b[9]\r
+set_location_assignment PIN_226 -to io_rx_b[10]\r
+set_location_assignment PIN_227 -to io_rx_b[11]\r
+set_location_assignment PIN_228 -to io_rx_b[12]\r
+set_location_assignment PIN_233 -to io_rx_b[13]\r
+set_location_assignment PIN_234 -to io_rx_b[14]\r
+set_location_assignment PIN_175 -to io_tx_a[0]\r
+set_location_assignment PIN_176 -to io_tx_a[1]\r
+set_location_assignment PIN_177 -to io_tx_a[2]\r
+set_location_assignment PIN_178 -to io_tx_a[3]\r
+set_location_assignment PIN_179 -to io_tx_a[4]\r
+set_location_assignment PIN_180 -to io_tx_a[5]\r
+set_location_assignment PIN_181 -to io_tx_a[6]\r
+set_location_assignment PIN_182 -to io_tx_a[7]\r
+set_location_assignment PIN_183 -to io_tx_a[8]\r
+set_location_assignment PIN_184 -to io_tx_a[9]\r
+set_location_assignment PIN_185 -to io_tx_a[10]\r
+set_location_assignment PIN_186 -to io_tx_a[11]\r
+set_location_assignment PIN_187 -to io_tx_a[12]\r
+set_location_assignment PIN_188 -to io_tx_a[13]\r
+set_location_assignment PIN_193 -to io_tx_a[14]\r
+set_location_assignment PIN_73 -to io_tx_b[0]\r
+set_location_assignment PIN_68 -to io_tx_b[1]\r
+set_location_assignment PIN_67 -to io_tx_b[2]\r
+set_location_assignment PIN_66 -to io_tx_b[3]\r
+set_location_assignment PIN_65 -to io_tx_b[4]\r
+set_location_assignment PIN_64 -to io_tx_b[5]\r
+set_location_assignment PIN_63 -to io_tx_b[6]\r
+set_location_assignment PIN_62 -to io_tx_b[7]\r
+set_location_assignment PIN_61 -to io_tx_b[8]\r
+set_location_assignment PIN_60 -to io_tx_b[9]\r
+set_location_assignment PIN_59 -to io_tx_b[10]\r
+set_location_assignment PIN_58 -to io_tx_b[11]\r
+set_location_assignment PIN_57 -to io_tx_b[12]\r
+set_location_assignment PIN_56 -to io_tx_b[13]\r
+set_location_assignment PIN_55 -to io_tx_b[14]\r
+set_location_assignment PIN_152 -to master_clk\r
+set_location_assignment PIN_144 -to rx_a_a[0]\r
+set_location_assignment PIN_143 -to rx_a_a[1]\r
+set_location_assignment PIN_141 -to rx_a_a[2]\r
+set_location_assignment PIN_140 -to rx_a_a[3]\r
+set_location_assignment PIN_139 -to rx_a_a[4]\r
+set_location_assignment PIN_138 -to rx_a_a[5]\r
+set_location_assignment PIN_137 -to rx_a_a[6]\r
+set_location_assignment PIN_136 -to rx_a_a[7]\r
+set_location_assignment PIN_135 -to rx_a_a[8]\r
+set_location_assignment PIN_134 -to rx_a_a[9]\r
+set_location_assignment PIN_133 -to rx_a_a[10]\r
+set_location_assignment PIN_132 -to rx_a_a[11]\r
+set_location_assignment PIN_23 -to rx_a_b[0]\r
+set_location_assignment PIN_21 -to rx_a_b[1]\r
+set_location_assignment PIN_20 -to rx_a_b[2]\r
+set_location_assignment PIN_19 -to rx_a_b[3]\r
+set_location_assignment PIN_18 -to rx_a_b[4]\r
+set_location_assignment PIN_17 -to rx_a_b[5]\r
+set_location_assignment PIN_16 -to rx_a_b[6]\r
+set_location_assignment PIN_15 -to rx_a_b[7]\r
+set_location_assignment PIN_14 -to rx_a_b[8]\r
+set_location_assignment PIN_13 -to rx_a_b[9]\r
+set_location_assignment PIN_12 -to rx_a_b[10]\r
+set_location_assignment PIN_11 -to rx_a_b[11]\r
+set_location_assignment PIN_131 -to rx_b_a[0]\r
+set_location_assignment PIN_128 -to rx_b_a[1]\r
+set_location_assignment PIN_127 -to rx_b_a[2]\r
+set_location_assignment PIN_126 -to rx_b_a[3]\r
+set_location_assignment PIN_125 -to rx_b_a[4]\r
+set_location_assignment PIN_124 -to rx_b_a[5]\r
+set_location_assignment PIN_123 -to rx_b_a[6]\r
+set_location_assignment PIN_122 -to rx_b_a[7]\r
+set_location_assignment PIN_121 -to rx_b_a[8]\r
+set_location_assignment PIN_120 -to rx_b_a[9]\r
+set_location_assignment PIN_119 -to rx_b_a[10]\r
+set_location_assignment PIN_118 -to rx_b_a[11]\r
+set_location_assignment PIN_8 -to rx_b_b[0]\r
+set_location_assignment PIN_7 -to rx_b_b[1]\r
+set_location_assignment PIN_6 -to rx_b_b[2]\r
+set_location_assignment PIN_5 -to rx_b_b[3]\r
+set_location_assignment PIN_4 -to rx_b_b[4]\r
+set_location_assignment PIN_3 -to rx_b_b[5]\r
+set_location_assignment PIN_2 -to rx_b_b[6]\r
+set_location_assignment PIN_240 -to rx_b_b[7]\r
+set_location_assignment PIN_239 -to rx_b_b[8]\r
+set_location_assignment PIN_238 -to rx_b_b[9]\r
+set_location_assignment PIN_237 -to rx_b_b[10]\r
+set_location_assignment PIN_236 -to rx_b_b[11]\r
+set_location_assignment PIN_156 -to SDO\r
+set_location_assignment PIN_153 -to SEN_FPGA\r
+set_location_assignment PIN_159 -to tx_a[0]\r
+set_location_assignment PIN_160 -to tx_a[1]\r
+set_location_assignment PIN_161 -to tx_a[2]\r
+set_location_assignment PIN_162 -to tx_a[3]\r
+set_location_assignment PIN_163 -to tx_a[4]\r
+set_location_assignment PIN_164 -to tx_a[5]\r
+set_location_assignment PIN_165 -to tx_a[6]\r
+set_location_assignment PIN_166 -to tx_a[7]\r
+set_location_assignment PIN_167 -to tx_a[8]\r
+set_location_assignment PIN_168 -to tx_a[9]\r
+set_location_assignment PIN_169 -to tx_a[10]\r
+set_location_assignment PIN_170 -to tx_a[11]\r
+set_location_assignment PIN_173 -to tx_a[12]\r
+set_location_assignment PIN_174 -to tx_a[13]\r
+set_location_assignment PIN_38 -to tx_b[0]\r
+set_location_assignment PIN_39 -to tx_b[1]\r
+set_location_assignment PIN_41 -to tx_b[2]\r
+set_location_assignment PIN_42 -to tx_b[3]\r
+set_location_assignment PIN_43 -to tx_b[4]\r
+set_location_assignment PIN_44 -to tx_b[5]\r
+set_location_assignment PIN_45 -to tx_b[6]\r
+set_location_assignment PIN_46 -to tx_b[7]\r
+set_location_assignment PIN_47 -to tx_b[8]\r
+set_location_assignment PIN_48 -to tx_b[9]\r
+set_location_assignment PIN_49 -to tx_b[10]\r
+set_location_assignment PIN_50 -to tx_b[11]\r
+set_location_assignment PIN_53 -to tx_b[12]\r
+set_location_assignment PIN_54 -to tx_b[13]\r
+set_location_assignment PIN_158 -to TXSYNC_A\r
+set_location_assignment PIN_37 -to TXSYNC_B\r
+set_location_assignment PIN_235 -to io_rx_b[15]\r
+set_location_assignment PIN_24 -to io_tx_b[15]\r
+set_location_assignment PIN_213 -to io_rx_a[15]\r
+set_location_assignment PIN_194 -to io_tx_a[15]\r
+set_location_assignment PIN_1 -to MYSTERY_SIGNAL\r
+\r
+# Timing Assignments\r
+# ==================\r
+set_global_assignment -name INCLUDE_EXTERNAL_PIN_DELAYS_IN_FMAX_CALCULATIONS OFF\r
+\r
+# Analysis & Synthesis Assignments\r
+# ================================\r
+set_global_assignment -name SAVE_DISK_SPACE OFF\r
+set_global_assignment -name DEVICE_FILTER_PACKAGE "ANY QFP"\r
+set_global_assignment -name DEVICE_FILTER_PIN_COUNT 240\r
+set_global_assignment -name EDA_DESIGN_ENTRY_SYNTHESIS_TOOL "<None>"\r
+set_global_assignment -name FAMILY Cyclone\r
+set_global_assignment -name CYCLONE_OPTIMIZATION_TECHNIQUE BALANCED\r
+set_global_assignment -name STRATIX_OPTIMIZATION_TECHNIQUE SPEED\r
+set_global_assignment -name APEX20K_OPTIMIZATION_TECHNIQUE SPEED\r
+set_global_assignment -name TOP_LEVEL_ENTITY usrp_multi\r
+set_global_assignment -name VHDL_SHOW_LMF_MAPPING_MESSAGES OFF\r
+set_global_assignment -name USER_LIBRARIES "H:\\usrp-for2.7\\fpga\\megacells"\r
+set_global_assignment -name AUTO_ENABLE_SMART_COMPILE On\r
+\r
+# Fitter Assignments\r
+# ==================\r
+set_global_assignment -name DEVICE EP1C12Q240C8\r
+set_global_assignment -name CYCLONE_CONFIGURATION_SCHEME "PASSIVE SERIAL"\r
+set_global_assignment -name RESERVE_ALL_UNUSED_PINS "AS INPUT TRI-STATED"\r
+set_global_assignment -name OPTIMIZE_HOLD_TIMING OFF\r
+set_global_assignment -name OPTIMIZE_TIMING "NORMAL COMPILATION"\r
+set_global_assignment -name PHYSICAL_SYNTHESIS_COMBO_LOGIC OFF\r
+set_global_assignment -name PHYSICAL_SYNTHESIS_REGISTER_DUPLICATION OFF\r
+set_global_assignment -name PHYSICAL_SYNTHESIS_REGISTER_RETIMING OFF\r
+set_global_assignment -name IO_PLACEMENT_OPTIMIZATION OFF\r
+set_global_assignment -name PHYSICAL_SYNTHESIS_EFFORT NORMAL\r
+set_global_assignment -name INC_PLC_MODE OFF\r
+set_global_assignment -name ROUTING_BACK_ANNOTATION_MODE OFF\r
+set_instance_assignment -name IO_STANDARD LVTTL -to usbdata[12]\r
+set_global_assignment -name STRATIX_DEVICE_IO_STANDARD LVTTL\r
+set_global_assignment -name ERROR_CHECK_FREQUENCY_DIVISOR 1\r
+\r
+# Timing Analysis Assignments\r
+# ===========================\r
+set_global_assignment -name MAX_SCC_SIZE 50\r
+\r
+# EDA Netlist Writer Assignments\r
+# ==============================\r
+set_global_assignment -name EDA_SIMULATION_TOOL "<None>"\r
+set_global_assignment -name EDA_TIMING_ANALYSIS_TOOL "<NONE>"\r
+set_global_assignment -name EDA_BOARD_DESIGN_TOOL "<NONE>"\r
+set_global_assignment -name EDA_FORMAL_VERIFICATION_TOOL "<NONE>"\r
+set_global_assignment -name EDA_RESYNTHESIS_TOOL "<NONE>"\r
+\r
+# Assembler Assignments\r
+# =====================\r
+set_global_assignment -name USE_CONFIGURATION_DEVICE OFF\r
+set_global_assignment -name GENERATE_RBF_FILE ON\r
+set_global_assignment -name RESERVE_ALL_UNUSED_PINS_NO_OUTPUT_GND "AS INPUT TRI-STATED"\r
+set_global_assignment -name AUTO_RESTART_CONFIGURATION OFF\r
+\r
+# Simulator Assignments\r
+# =====================\r
+set_global_assignment -name START_TIME "0 ns"\r
+set_global_assignment -name GLITCH_INTERVAL "1 ns"\r
+\r
+# Design Assistant Assignments\r
+# ============================\r
+set_global_assignment -name DRC_REPORT_TOP_FANOUT OFF\r
+set_global_assignment -name DRC_REPORT_FANOUT_EXCEEDING OFF\r
+set_global_assignment -name ASSG_CAT OFF\r
+set_global_assignment -name ASSG_RULE_MISSING_FMAX OFF\r
+set_global_assignment -name ASSG_RULE_MISSING_TIMING OFF\r
+set_global_assignment -name NONSYNCHSTRUCT_RULE_ASYN_RAM OFF\r
+set_global_assignment -name CLK_CAT OFF\r
+set_global_assignment -name CLK_RULE_COMB_CLOCK OFF\r
+set_global_assignment -name CLK_RULE_INV_CLOCK OFF\r
+set_global_assignment -name CLK_RULE_GATING_SCHEME OFF\r
+set_global_assignment -name CLK_RULE_INPINS_CLKNET OFF\r
+set_global_assignment -name CLK_RULE_CLKNET_CLKSPINES OFF\r
+set_global_assignment -name CLK_RULE_MIX_EDGES OFF\r
+set_global_assignment -name RESET_CAT OFF\r
+set_global_assignment -name RESET_RULE_INPINS_RESETNET OFF\r
+set_global_assignment -name RESET_RULE_UNSYNCH_EXRESET OFF\r
+set_global_assignment -name RESET_RULE_IMSYNCH_EXRESET OFF\r
+set_global_assignment -name RESET_RULE_COMB_ASYNCH_RESET OFF\r
+set_global_assignment -name RESET_RULE_UNSYNCH_ASYNCH_DOMAIN OFF\r
+set_global_assignment -name RESET_RULE_IMSYNCH_ASYNCH_DOMAIN OFF\r
+set_global_assignment -name TIMING_CAT OFF\r
+set_global_assignment -name TIMING_RULE_SHIFT_REG OFF\r
+set_global_assignment -name TIMING_RULE_COIN_CLKEDGE OFF\r
+set_global_assignment -name NONSYNCHSTRUCT_RULE_COMB_DRIVES_RAM_WE OFF\r
+set_global_assignment -name NONSYNCHSTRUCT_CAT OFF\r
+set_global_assignment -name NONSYNCHSTRUCT_RULE_COMBLOOP OFF\r
+set_global_assignment -name NONSYNCHSTRUCT_RULE_REG_LOOP OFF\r
+set_global_assignment -name NONSYNCHSTRUCT_RULE_DELAY_CHAIN OFF\r
+set_global_assignment -name NONSYNCHSTRUCT_RULE_RIPPLE_CLK OFF\r
+set_global_assignment -name NONSYNCHSTRUCT_RULE_ILLEGAL_PULSE_GEN OFF\r
+set_global_assignment -name NONSYNCHSTRUCT_RULE_MULTI_VIBRATOR OFF\r
+set_global_assignment -name NONSYNCHSTRUCT_RULE_SRLATCH OFF\r
+set_global_assignment -name NONSYNCHSTRUCT_RULE_LATCH_UNIDENTIFIED OFF\r
+set_global_assignment -name SIGNALRACE_CAT OFF\r
+set_global_assignment -name ACLK_CAT OFF\r
+set_global_assignment -name ACLK_RULE_NO_SZER_ACLK_DOMAIN OFF\r
+set_global_assignment -name ACLK_RULE_SZER_BTW_ACLK_DOMAIN OFF\r
+set_global_assignment -name ACLK_RULE_IMSZER_ADOMAIN OFF\r
+set_global_assignment -name HCPY_CAT OFF\r
+set_global_assignment -name HCPY_VREF_PINS OFF\r
+\r
+# SignalTap II Assignments\r
+# ========================\r
+set_global_assignment -name HUB_ENTITY_NAME SLD_HUB\r
+set_global_assignment -name HUB_INSTANCE_NAME SLD_HUB_INST\r
+set_global_assignment -name ENABLE_SIGNALTAP Off\r
+\r
+# LogicLock Region Assignments\r
+# ============================\r
+set_global_assignment -name LOGICLOCK_INCREMENTAL_COMPILE_ASSIGNMENT OFF\r
+\r
+# -----------------\r
+# start CLOCK(SCLK)\r
+\r
+       # Timing Assignments\r
+       # ==================\r
+set_global_assignment -name DUTY_CYCLE 50 -section_id SCLK\r
+       set_global_assignment -name FMAX_REQUIREMENT "1.0 MHz" -section_id SCLK\r
+       set_global_assignment -name INCLUDE_EXTERNAL_PIN_DELAYS_IN_FMAX_CALCULATIONS OFF -section_id SCLK\r
+\r
+# end CLOCK(SCLK)\r
+# ---------------\r
+\r
+# -----------------------\r
+# start CLOCK(master_clk)\r
+\r
+       # Timing Assignments\r
+       # ==================\r
+set_global_assignment -name DUTY_CYCLE 50 -section_id master_clk\r
+       set_global_assignment -name FMAX_REQUIREMENT "64.0 MHz" -section_id master_clk\r
+       set_global_assignment -name INCLUDE_EXTERNAL_PIN_DELAYS_IN_FMAX_CALCULATIONS OFF -section_id master_clk\r
+\r
+# end CLOCK(master_clk)\r
+# ---------------------\r
+\r
+# -------------------\r
+# start CLOCK(usbclk)\r
+\r
+       # Timing Assignments\r
+       # ==================\r
+set_global_assignment -name DUTY_CYCLE 50 -section_id usbclk\r
+       set_global_assignment -name FMAX_REQUIREMENT "48.0 MHz" -section_id usbclk\r
+       set_global_assignment -name INCLUDE_EXTERNAL_PIN_DELAYS_IN_FMAX_CALCULATIONS OFF -section_id usbclk\r
+\r
+# end CLOCK(usbclk)\r
+# -----------------\r
+\r
+# ----------------------\r
+# start ENTITY(usrp_multi)\r
+\r
+       # Timing Assignments\r
+       # ==================\r
+       set_instance_assignment -name CLOCK_SETTINGS SCLK -to SCLK\r
+       set_instance_assignment -name CLOCK_SETTINGS usbclk -to usbclk\r
+       set_instance_assignment -name CLOCK_SETTINGS master_clk -to master_clk\r
+\r
+# end ENTITY(usrp_multi)\r
+# --------------------\r
+\r
+\r
+set_global_assignment -name VERILOG_FILE ../../sdr_lib/setting_reg_masked.v\r
+set_global_assignment -name VERILOG_FILE ../../sdr_lib/master_control_multi.v\r
+set_global_assignment -name VERILOG_FILE ../../sdr_lib/ram16.v\r
+set_global_assignment -name VERILOG_FILE usrp_multi.vh\r
+set_global_assignment -name VERILOG_FILE ../../megacells/fifo_4k.v\r
+set_global_assignment -name VERILOG_FILE ../../sdr_lib/hb/acc.v\r
+set_global_assignment -name VERILOG_FILE ../../sdr_lib/hb/mult.v\r
+set_global_assignment -name VERILOG_FILE ../../sdr_lib/hb/ram16_2sum.v\r
+set_global_assignment -name VERILOG_FILE ../../sdr_lib/hb/coeff_rom.v\r
+set_global_assignment -name VERILOG_FILE ../../sdr_lib/hb/halfband_decim.v\r
+set_global_assignment -name VERILOG_FILE ../../sdr_lib/hb/mac.v\r
+set_global_assignment -name VERILOG_FILE ../../sdr_lib/hb/coeff_ram.v\r
+set_global_assignment -name VERILOG_FILE ../../sdr_lib/tx_chain.v\r
+set_global_assignment -name VERILOG_FILE ../../sdr_lib/rx_dcoffset.v\r
+set_global_assignment -name VERILOG_FILE ../../sdr_lib/adc_interface.v\r
+set_global_assignment -name VERILOG_FILE ../../sdr_lib/io_pins.v\r
+set_global_assignment -name VERILOG_FILE ../../sdr_lib/setting_reg.v\r
+set_global_assignment -name VERILOG_FILE ../../sdr_lib/bidir_reg.v\r
+set_global_assignment -name VERILOG_FILE ../../sdr_lib/cic_int_shifter.v\r
+set_global_assignment -name VERILOG_FILE ../../megacells/clk_doubler.v\r
+set_global_assignment -name VERILOG_FILE ../../sdr_lib/rx_chain.v\r
+set_global_assignment -name VERILOG_FILE ../../sdr_lib/gen_sync.v\r
+set_global_assignment -name VERILOG_FILE ../../sdr_lib/master_control.v\r
+set_global_assignment -name VERILOG_FILE ../../megacells/fifo_2k.v\r
+set_global_assignment -name VERILOG_FILE ../../megacells/bustri.v\r
+set_global_assignment -name VERILOG_FILE ../../sdr_lib/rx_buffer.v\r
+set_global_assignment -name VERILOG_FILE ../../sdr_lib/tx_buffer.v\r
+set_global_assignment -name VERILOG_FILE ../../sdr_lib/phase_acc.v\r
+set_global_assignment -name VERILOG_FILE ../../sdr_lib/cic_interp.v\r
+set_global_assignment -name VERILOG_FILE ../../sdr_lib/cic_decim.v\r
+set_global_assignment -name VERILOG_FILE ../../sdr_lib/cordic_stage.v\r
+set_global_assignment -name VERILOG_FILE ../../sdr_lib/cordic.v\r
+set_global_assignment -name VERILOG_FILE usrp_multi.v\r
+set_global_assignment -name VERILOG_FILE ../../sdr_lib/clk_divider.v\r
+set_global_assignment -name VERILOG_FILE ../../sdr_lib/serial_io.v\r
+set_global_assignment -name VERILOG_FILE ../../sdr_lib/strobe_gen.v\r
+set_global_assignment -name VERILOG_FILE ../../sdr_lib/sign_extend.v
\ No newline at end of file
diff --git a/usrp/fpga/toplevel/usrp_multi/usrp_multi.v b/usrp/fpga/toplevel/usrp_multi/usrp_multi.v
new file mode 100644 (file)
index 0000000..b27d3d3
--- /dev/null
@@ -0,0 +1,379 @@
+// -*- verilog -*-
+//
+//  USRP - Universal Software Radio Peripheral
+//
+//  Copyright (C) 2003,2004,2005,2006 Matt Ettus
+//  Copyright (C) 2006 Martin Dudok van Heel
+//
+//  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
+//
+
+// Top level module for a full setup with DUCs and DDCs
+
+// Define DEBUG_OWNS_IO_PINS if we're using the daughterboard i/o pins
+// for debugging info.  NB, This can kill the m'board and/or d'board if you
+// have anything except basic d'boards installed.
+
+// Uncomment the following to include optional circuitry
+
+`include "usrp_multi.vh"
+`include "../../../firmware/include/fpga_regs_common.v"
+`include "../../../firmware/include/fpga_regs_standard.v"
+
+module usrp_multi
+(output MYSTERY_SIGNAL,
+ input master_clk,
+ input SCLK,
+ input SDI,
+ inout SDO,
+ input SEN_FPGA,
+
+ input FX2_1,
+ output FX2_2,
+ output FX2_3,
+ input wire [11:0] rx_a_a,
+ input wire [11:0] rx_b_a,
+ input wire [11:0] rx_a_b,
+ input wire [11:0] rx_b_b,
+
+ output wire [13:0] tx_a,
+ output wire [13:0] tx_b,
+
+ output wire TXSYNC_A,
+ output wire TXSYNC_B,
+  // USB interface
+ input usbclk,
+ input wire [2:0] usbctl,
+ output wire [1:0] usbrdy,
+ inout [15:0] usbdata,  // NB Careful, inout
+
+ // These are the general purpose i/o's that go to the daughterboard slots
+ inout wire [15:0] io_tx_a,
+ inout wire [15:0] io_tx_b,
+ inout wire [15:0] io_rx_a,
+ inout wire [15:0] io_rx_b
+ );    
+   wire [15:0] debugdata,debugctrl;
+   assign MYSTERY_SIGNAL = 1'b0;
+   
+   wire clk64,clk128;
+   
+   wire WR = usbctl[0];
+   wire RD = usbctl[1];
+   wire OE = usbctl[2];
+
+   wire have_space, have_pkt_rdy;
+   assign usbrdy[0] = have_space;
+   assign usbrdy[1] = have_pkt_rdy;
+
+   wire   tx_underrun, rx_overrun;    
+   wire   clear_status = FX2_1;
+   assign FX2_2 = rx_overrun;
+   assign FX2_3 = tx_underrun;
+      
+   wire [15:0] usbdata_out;
+   
+   wire [3:0]  dac0mux,dac1mux,dac2mux,dac3mux;
+   
+   wire        tx_realsignals;
+   wire [3:0]  rx_numchan;
+   wire [2:0]  tx_numchan;
+   
+   wire [7:0]  interp_rate, decim_rate;
+   wire [15:0] tx_debugbus, rx_debugbus;
+   
+   wire        enable_tx, enable_rx;
+   wire        reset_data;
+`ifdef MULTI_ON
+   wire        sync_rx;
+   assign reset_data = sync_rx;
+`else
+   assign reset_data = 1'b0;
+`endif //  `ifdef MULTI_ON
+
+   wire        tx_dsp_reset, rx_dsp_reset, tx_bus_reset, rx_bus_reset;
+   wire [7:0]  settings;
+   
+   // Tri-state bus macro
+   bustri bustri( .data(usbdata_out),.enabledt(OE),.tridata(usbdata) );
+
+   assign      clk64 = master_clk;
+
+   wire [15:0] ch0tx,ch1tx,ch2tx,ch3tx; //,ch4tx,ch5tx,ch6tx,ch7tx;
+   wire [15:0] ch0rx,ch1rx,ch2rx,ch3rx,ch4rx,ch5rx,ch6rx,ch7rx;
+   
+   // TX
+   wire [15:0] i_out_0,i_out_1,q_out_0,q_out_1;
+   wire [15:0] bb_tx_i0,bb_tx_q0,bb_tx_i1,bb_tx_q1;  // bb_tx_i2,bb_tx_q2,bb_tx_i3,bb_tx_q3;
+   
+   wire        strobe_interp, tx_sample_strobe;
+   wire        tx_empty;
+   
+   wire        serial_strobe;
+   wire [6:0]  serial_addr;
+   wire [31:0] serial_data;
+
+   reg [15:0] debug_counter;
+`ifdef COUNTER_32BIT_ON
+   reg [31:0] sample_counter_32bit;
+`endif //  `ifdef COUNTER_32BIT_ON
+   reg [15:0] loopback_i_0,loopback_q_0;
+   
+   ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+   // Transmit Side
+`ifdef TX_ON
+   assign     bb_tx_i0 = ch0tx;
+   assign      bb_tx_q0 = ch1tx;
+   assign      bb_tx_i1 = ch2tx;
+   assign      bb_tx_q1 = ch3tx;
+   
+   tx_buffer tx_buffer
+     ( .usbclk(usbclk),.bus_reset(tx_bus_reset),.reset(tx_dsp_reset),
+       .usbdata(usbdata),.WR(WR),.have_space(have_space),.tx_underrun(tx_underrun),
+       .channels({tx_numchan,1'b0}),
+       .tx_i_0(ch0tx),.tx_q_0(ch1tx),
+       .tx_i_1(ch2tx),.tx_q_1(ch3tx),
+       .tx_i_2(),.tx_q_2(),
+       .tx_i_3(),.tx_q_3(),
+       .txclk(clk64),.txstrobe(strobe_interp),
+       .clear_status(clear_status),
+       .tx_empty(tx_empty),
+       .debugbus(tx_debugbus) );
+
+   tx_chain tx_chain_0
+     ( .clock(clk64),.reset(tx_dsp_reset),.enable(enable_tx),
+       .interp_rate(interp_rate),.sample_strobe(tx_sample_strobe),
+       .interpolator_strobe(strobe_interp),.freq(),
+       .i_in(bb_tx_i0),.q_in(bb_tx_q0),.i_out(i_out_0),.q_out(q_out_0) );
+
+   tx_chain tx_chain_1
+     ( .clock(clk64),.reset(tx_dsp_reset),.enable(enable_tx),
+       .interp_rate(interp_rate),.sample_strobe(tx_sample_strobe),
+       .interpolator_strobe(strobe_interp),.freq(),
+       .i_in(bb_tx_i1),.q_in(bb_tx_q1),.i_out(i_out_1),.q_out(q_out_1) );
+
+   setting_reg #(`FR_TX_MUX) 
+     sr_txmux(.clock(clk64),.reset(tx_dsp_reset),.strobe(serial_strobe),.addr(serial_addr),.in(serial_data),
+             .out({dac3mux,dac2mux,dac1mux,dac0mux,tx_realsignals,tx_numchan}));
+   
+   wire [15:0] tx_a_a = dac0mux[3] ? (dac0mux[1] ? (dac0mux[0] ? q_out_1 : i_out_1) : (dac0mux[0] ? q_out_0 : i_out_0)) : 16'b0;
+   wire [15:0] tx_b_a = dac1mux[3] ? (dac1mux[1] ? (dac1mux[0] ? q_out_1 : i_out_1) : (dac1mux[0] ? q_out_0 : i_out_0)) : 16'b0;
+   wire [15:0] tx_a_b = dac2mux[3] ? (dac2mux[1] ? (dac2mux[0] ? q_out_1 : i_out_1) : (dac2mux[0] ? q_out_0 : i_out_0)) : 16'b0;
+   wire [15:0] tx_b_b = dac3mux[3] ? (dac3mux[1] ? (dac3mux[0] ? q_out_1 : i_out_1) : (dac3mux[0] ? q_out_0 : i_out_0)) : 16'b0;
+
+   wire txsync = tx_sample_strobe;
+   assign TXSYNC_A = txsync;
+   assign TXSYNC_B = txsync;
+
+   assign tx_a = txsync ? tx_b_a[15:2] : tx_a_a[15:2];
+   assign tx_b = txsync ? tx_b_b[15:2] : tx_a_b[15:2];
+`endif //  `ifdef TX_ON
+   
+   /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+   // Receive Side
+`ifdef RX_ON
+   wire        rx_sample_strobe,strobe_decim,hb_strobe;
+   wire [15:0] bb_rx_i0,bb_rx_q0,bb_rx_i1,bb_rx_q1,
+              bb_rx_i2,bb_rx_q2,bb_rx_i3,bb_rx_q3;
+
+   wire loopback = settings[0];
+   wire counter = settings[1];
+`ifdef COUNTER_32BIT_ON
+   wire counter_32bit = settings[2];
+
+   always @(posedge clk64)
+     if(rx_dsp_reset)
+       sample_counter_32bit <= #1 32'd0;
+     else if(~enable_rx | reset_data)
+       sample_counter_32bit <=#1 32'd0;
+     else if(hb_strobe)
+       sample_counter_32bit <=#1 sample_counter_32bit + 32'd1;
+`endif //  `ifdef COUNTER_32BIT_ON
+
+   always @(posedge clk64)
+     if(rx_dsp_reset)
+       debug_counter <= #1 16'd0;
+     else if(~enable_rx)
+       debug_counter <= #1 16'd0;
+     else if(hb_strobe)
+       debug_counter <=#1 debug_counter + 16'd2;
+   
+   always @(posedge clk64)
+     if(strobe_interp)
+       begin
+         loopback_i_0 <= #1 ch0tx;
+         loopback_q_0 <= #1 ch1tx;
+       end
+   
+`ifdef COUNTER_32BIT_ON
+   assign ch0rx = counter_32bit?sample_counter_32bit[31:16]:counter ? debug_counter : loopback ? loopback_i_0 : bb_rx_i0;
+   assign ch1rx = counter_32bit?sample_counter_32bit[15:0]:counter ? debug_counter + 16'd1 : loopback ? loopback_q_0 : bb_rx_q0;
+   assign ch2rx = bb_rx_i1;
+   assign ch3rx = bb_rx_q1;
+   assign ch4rx = counter_32bit?bb_rx_i0:bb_rx_i2;
+   assign ch5rx = counter_32bit?bb_rx_q0:bb_rx_q2;// If using counter replicate channels here to be able to get rx_i0 when using counter
+                           //This means if you use 4 channels that channel 3 will be replaced by channel 0
+                           // and channel 0 will output the 32 bit counter.
+   assign ch6rx = bb_rx_i3;
+   assign ch7rx = bb_rx_q3;
+`else
+   assign ch0rx = counter ? debug_counter : loopback ? loopback_i_0 : bb_rx_i0;
+   assign ch1rx = counter ? debug_counter + 16'd1 : loopback ? loopback_q_0 : bb_rx_q0;
+   assign ch2rx = bb_rx_i1;
+   assign ch3rx = bb_rx_q1;
+   assign ch4rx = bb_rx_i2;
+   assign ch5rx = bb_rx_q2;
+   assign ch6rx = bb_rx_i3;
+   assign ch7rx = bb_rx_q3;
+`endif //  `ifdef COUNTER_32BIT_ON
+
+
+   wire [15:0] ddc0_in_i,ddc0_in_q,ddc1_in_i,ddc1_in_q,ddc2_in_i,ddc2_in_q,ddc3_in_i,ddc3_in_q;
+   adc_interface adc_interface(.clock(clk64),.reset(rx_dsp_reset),.enable(1'b1),
+                              .serial_addr(serial_addr),.serial_data(serial_data),.serial_strobe(serial_strobe),
+                              .rx_a_a(rx_a_a),.rx_b_a(rx_b_a),.rx_a_b(rx_a_b),.rx_b_b(rx_b_b),
+                              .ddc0_in_i(ddc0_in_i),.ddc0_in_q(ddc0_in_q),
+                              .ddc1_in_i(ddc1_in_i),.ddc1_in_q(ddc1_in_q),
+                              .ddc2_in_i(ddc2_in_i),.ddc2_in_q(ddc2_in_q),
+                              .ddc3_in_i(ddc3_in_i),.ddc3_in_q(ddc3_in_q),.rx_numchan(rx_numchan) );
+   
+   rx_buffer rx_buffer
+     ( .usbclk(usbclk),.bus_reset(rx_bus_reset),.reset(rx_dsp_reset | reset_data),
+       .reset_regs(rx_dsp_reset),
+       .usbdata(usbdata_out),.RD(RD),.have_pkt_rdy(have_pkt_rdy),.rx_overrun(rx_overrun),
+       .channels(rx_numchan),
+       .ch_0(ch0rx),.ch_1(ch1rx),
+       .ch_2(ch2rx),.ch_3(ch3rx),
+       .ch_4(ch4rx),.ch_5(ch5rx),
+       .ch_6(ch6rx),.ch_7(ch7rx),
+       .rxclk(clk64),.rxstrobe(hb_strobe),
+       .clear_status(clear_status),
+       .serial_addr(serial_addr),.serial_data(serial_data),.serial_strobe(serial_strobe),
+       .debugbus(rx_debugbus) );
+   
+ `ifdef RX_EN_0
+   rx_chain #(`FR_RX_FREQ_0,`FR_RX_PHASE_0) rx_chain_0
+     ( .clock(clk64),.reset(reset_data),.enable(enable_rx),
+       .decim_rate(decim_rate),.sample_strobe(rx_sample_strobe),.decimator_strobe(strobe_decim),.hb_strobe(hb_strobe),
+       .serial_addr(serial_addr),.serial_data(serial_data),.serial_strobe(serial_strobe),
+       .i_in(ddc0_in_i),.q_in(ddc0_in_q),.i_out(bb_rx_i0),.q_out(bb_rx_q0),.debugdata(debugdata),.debugctrl(debugctrl));
+ `else
+   assign      bb_rx_i0=16'd0;
+   assign      bb_rx_q0=16'd0;
+ `endif
+   
+ `ifdef RX_EN_1
+   rx_chain #(`FR_RX_FREQ_1,`FR_RX_PHASE_1) rx_chain_1
+     ( .clock(clk64),.reset(reset_data),.enable(enable_rx),
+       .decim_rate(decim_rate),.sample_strobe(rx_sample_strobe),.decimator_strobe(strobe_decim),.hb_strobe(),
+       .serial_addr(serial_addr),.serial_data(serial_data),.serial_strobe(serial_strobe),
+       .i_in(ddc1_in_i),.q_in(ddc1_in_q),.i_out(bb_rx_i1),.q_out(bb_rx_q1));
+ `else
+   assign      bb_rx_i1=16'd0;
+   assign      bb_rx_q1=16'd0;
+ `endif
+   
+ `ifdef RX_EN_2
+   rx_chain #(`FR_RX_FREQ_2,`FR_RX_PHASE_2) rx_chain_2
+     ( .clock(clk64),.reset(reset_data),.enable(enable_rx),
+       .decim_rate(decim_rate),.sample_strobe(rx_sample_strobe),.decimator_strobe(strobe_decim),.hb_strobe(),
+       .serial_addr(serial_addr),.serial_data(serial_data),.serial_strobe(serial_strobe),
+       .i_in(ddc2_in_i),.q_in(ddc2_in_q),.i_out(bb_rx_i2),.q_out(bb_rx_q2));
+ `else
+   assign      bb_rx_i2=16'd0;
+   assign      bb_rx_q2=16'd0;
+ `endif
+
+ `ifdef RX_EN_3
+   rx_chain #(`FR_RX_FREQ_3,`FR_RX_PHASE_3) rx_chain_3
+     ( .clock(clk64),.reset(reset_data),.enable(enable_rx),
+       .decim_rate(decim_rate),.sample_strobe(rx_sample_strobe),.decimator_strobe(strobe_decim),.hb_strobe(),
+       .serial_addr(serial_addr),.serial_data(serial_data),.serial_strobe(serial_strobe),
+       .i_in(ddc3_in_i),.q_in(ddc3_in_q),.i_out(bb_rx_i3),.q_out(bb_rx_q3));
+   assign      bb_rx_i3=16'd0;
+   assign      bb_rx_q3=16'd0;
+ `endif
+
+`endif //  `ifdef RX_ON
+   
+   ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+   // Control Functions
+
+   wire [31:0] capabilities;
+   assign      capabilities[7] =   `TX_CAP_HB;
+   assign      capabilities[6:4] = `TX_CAP_NCHAN;
+   assign      capabilities[3] =   `RX_CAP_HB;
+   assign      capabilities[2:0] = `RX_CAP_NCHAN;
+
+
+   serial_io serial_io
+     ( .master_clk(clk64),.serial_clock(SCLK),.serial_data_in(SDI),
+       .enable(SEN_FPGA),.reset(1'b0),.serial_data_out(SDO),
+       .serial_addr(serial_addr),.serial_data(serial_data),.serial_strobe(serial_strobe),
+       .readback_0({io_rx_a,io_tx_a}),.readback_1({io_rx_b,io_tx_b}),.readback_2(capabilities),.readback_3(32'hf0f0931a) );
+
+   wire [15:0] reg_0,reg_1,reg_2,reg_3;
+
+`ifdef MULTI_ON
+
+   master_control_multi master_control
+     ( .master_clk(clk64),.usbclk(usbclk),
+       .serial_addr(serial_addr),.serial_data(serial_data),.serial_strobe(serial_strobe),
+       .rx_slave_sync(io_rx_a[`bitnoFR_RX_SYNC_INPUT_IOPIN]),
+       .tx_bus_reset(tx_bus_reset),.rx_bus_reset(rx_bus_reset),
+       .tx_dsp_reset(tx_dsp_reset),.rx_dsp_reset(rx_dsp_reset),
+       .enable_tx(enable_tx),.enable_rx(enable_rx),
+       .sync_rx(sync_rx),
+       .interp_rate(interp_rate),.decim_rate(decim_rate),
+       .tx_sample_strobe(tx_sample_strobe),.strobe_interp(strobe_interp),
+       .rx_sample_strobe(rx_sample_strobe),.strobe_decim(strobe_decim),
+       .tx_empty(tx_empty),
+       //.debug_0(rx_a_a),.debug_1(ddc0_in_i),
+       .debug_0(rx_debugbus),.debug_1(ddc0_in_i),
+       .debug_2({rx_sample_strobe,strobe_decim,serial_strobe,serial_addr}),.debug_3({rx_dsp_reset,tx_dsp_reset,rx_bus_reset,tx_bus_reset,enable_rx,tx_underrun,rx_overrun,decim_rate}),
+       .reg_0(reg_0),.reg_1(reg_1),.reg_2(reg_2),.reg_3(reg_3) );
+
+`else //`ifdef MULTI_ON
+
+   master_control master_control
+     ( .master_clk(clk64),.usbclk(usbclk),
+       .serial_addr(serial_addr),.serial_data(serial_data),.serial_strobe(serial_strobe),
+       .tx_bus_reset(tx_bus_reset),.rx_bus_reset(rx_bus_reset),
+       .tx_dsp_reset(tx_dsp_reset),.rx_dsp_reset(rx_dsp_reset),
+       .enable_tx(enable_tx),.enable_rx(enable_rx),
+       .interp_rate(interp_rate),.decim_rate(decim_rate),
+       .tx_sample_strobe(tx_sample_strobe),.strobe_interp(strobe_interp),
+       .rx_sample_strobe(rx_sample_strobe),.strobe_decim(strobe_decim),
+       .tx_empty(tx_empty),
+       //.debug_0(rx_a_a),.debug_1(ddc0_in_i),
+       .debug_0(rx_debugbus),.debug_1(ddc0_in_i),
+       .debug_2({rx_sample_strobe,strobe_decim,serial_strobe,serial_addr}),.debug_3({rx_dsp_reset,tx_dsp_reset,rx_bus_reset,tx_bus_reset,enable_rx,tx_underrun,rx_overrun,decim_rate}),
+       .reg_0(reg_0),.reg_1(reg_1),.reg_2(reg_2),.reg_3(reg_3) );
+
+`endif //`ifdef MULTI_ON   
+
+   io_pins io_pins
+     (.io_0(io_tx_a),.io_1(io_rx_a),.io_2(io_tx_b),.io_3(io_rx_b),
+      .reg_0(reg_0),.reg_1(reg_1),.reg_2(reg_2),.reg_3(reg_3),
+      .clock(clk64),.rx_reset(rx_dsp_reset),.tx_reset(tx_dsp_reset),
+      .serial_addr(serial_addr),.serial_data(serial_data),.serial_strobe(serial_strobe));
+   
+   ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+   // Misc Settings
+   setting_reg #(`FR_MODE) sr_misc(.clock(clk64),.reset(rx_dsp_reset),.strobe(serial_strobe),.addr(serial_addr),.in(serial_data),.out(settings));
+
+endmodule // usrp_multi
diff --git a/usrp/fpga/toplevel/usrp_multi/usrp_multi.vh b/usrp/fpga/toplevel/usrp_multi/usrp_multi.vh
new file mode 100644 (file)
index 0000000..2904a93
--- /dev/null
@@ -0,0 +1,141 @@
+// -*- verilog -*-
+//
+//  USRP - Universal Software Radio Peripheral
+//
+//  Copyright (C) 2006 Matt Ettus
+//  Copyright (C) 2006 Martin Dudok van Heel
+//
+//  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
+//
+
+// ====================================================================
+//            User control over what parts get included
+//
+//                  >>>> EDIT ONLY THIS SECTION <<<<
+//                  Uncomment only ONE configuration
+// ====================================================================
+
+// ==== Multi usrp configurations ====
+// Uncomment this for multi with 2 rx channels (w/ halfband) & 2 transmit channels
+`include "usrp_multi_config_2rxhb_2tx.vh"
+
+// Uncomment this for multi with 4 rx channels (w/o halfband) & 0 transmit channels
+//`include "usrp_multi_config_4rx_0tx.vh"
+
+// Uncomment this for multi with 2 rx channels (w/ halfband) & 0 transmit channels
+//`include "usrp_multi_config_2rxhb_0tx.vh"
+
+// Uncomment this for multi with 2 rx channels (w/o halfband) & 0 transmit channels
+//`include "usrp_multi_config_2rx_0tx.vh"
+
+// ==== Standard configurations (no multi support) ====
+// Uncomment this for standard with 2 rx channels (w/ halfband) & 2 transmit channels
+//  `include "../usrp_std/usrp_std_config_2rxhb_2tx.vh"
+
+// Uncomment this for standard with 4 rx channels (w/o halfband) & 0 transmit channels
+//`include "../usrp_std/usrp_std_config_4rx_0tx.vh"
+
+// Add other "known to fit" configurations here...
+
+// ====================================================================
+// 
+//                  >>>> DO NOT EDIT BELOW HERE <<<<
+//
+// [The stuff from here down is derived from the stuff included above]
+//
+// N.B., *all* the remainder of the code should be conditionalized
+// only in terms of:
+//
+//  TX_ON, TX_EN_0, TX_EN_1, TX_EN_2, TX_EN_3, TX_CAP_NCHAN, TX_CAP_HB,
+//  RX_ON, RX_EN_0, RX_EN_1, RX_EN_2, RX_EN_3, RX_CAP_NCHAN, RX_CAP_HB,
+//  RX_NCO_ON, RX_CIC_ON
+// ====================================================================
+`ifdef MULTI_ON
+  `define COUNTER_32BIT_ON
+`endif
+
+`ifdef TX_ON
+
+ `ifdef TX_SINGLE
+  `define TX_EN_0
+  `define TX_CAP_NCHAN 3'd1
+ `endif
+
+ `ifdef TX_DUAL
+  `define TX_EN_0
+  `define TX_EN_1
+  `define TX_CAP_NCHAN 3'd2
+ `endif
+
+ `ifdef TX_QUAD
+  `define TX_EN_0
+  `define TX_EN_1
+  `define TX_EN_2
+  `define TX_EN_3
+  `define TX_CAP_NCHAN 3'd4
+ `endif
+
+ `ifdef TX_HB_ON
+  `define TX_CAP_HB   1
+ `else
+  `define TX_CAP_HB   0
+ `endif
+
+`else  // !ifdef TX_ON
+
+ `define TX_CAP_NCHAN 3'd0
+ `define TX_CAP_HB 0
+
+`endif // !ifdef TX_ON
+
+// --------------------------------------------------------------------
+
+`ifdef RX_ON
+
+ `ifdef RX_SINGLE
+  `define RX_EN_0
+  `define RX_CAP_NCHAN 3'd1
+ `endif
+
+ `ifdef RX_DUAL
+  `define RX_EN_0
+  `define RX_EN_1
+  `ifdef MULTI_ON
+    `define RX_CAP_NCHAN 3'd4
+  `else
+    `define RX_CAP_NCHAN 3'd2
+  `endif
+ `endif
+
+ `ifdef RX_QUAD
+  `define RX_EN_0
+  `define RX_EN_1
+  `define RX_EN_2
+  `define RX_EN_3
+  `define RX_CAP_NCHAN 3'd4
+ `endif
+
+ `ifdef RX_HB_ON
+  `define RX_CAP_HB   1
+ `else
+  `define RX_CAP_HB   0
+ `endif
+
+`else  // !ifdef RX_ON
+
+ `define RX_CAP_NCHAN 3'd0
+ `define RX_CAP_HB 0
+
+`endif // !ifdef RX_ON
diff --git a/usrp/fpga/toplevel/usrp_multi/usrp_multi_config_2rx_0tx.vh b/usrp/fpga/toplevel/usrp_multi/usrp_multi_config_2rx_0tx.vh
new file mode 100644 (file)
index 0000000..26a41e4
--- /dev/null
@@ -0,0 +1,62 @@
+// -*- verilog -*-
+//
+//  USRP - Universal Software Radio Peripheral
+//
+//  Copyright (C) 2006 Matt Ettus
+//  Copyright (C) 2006 Martin Dudok van Heel
+//
+//  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
+//
+`define MULTI_ON
+// ------------------------------------------------------------
+// If TX_ON is not defined, there is *no* transmit circuitry built
+// `define TX_ON
+
+// ------------------------------------------------------------
+// Define 1 and only one of TX_SINGLE, TX_DUAL and TX_QUAD
+// to respectively enable 1, 2 or 4 transmit channels.
+// [Please note that only TX_DUAL is currently valid]
+//`define TX_SINGLE
+//`define TX_DUAL
+//`define TX_QUAD
+
+// ------------------------------------------------------------
+// Define TX_HB_ON to enable the transmit halfband filter
+// [Not implemented]
+//`define TX_HB_ON
+
+// ------------------------------------------------------------
+// IF RX_ON is not defined, there is *no* transmit circuitry built
+  `define RX_ON
+
+// ------------------------------------------------------------
+// Define 1 and only one of RX_SINGLE, RX_DUAL and RX_QUAD
+// to respectively define 1, 2 or 4 receive channels.
+
+//`define RX_SINGLE
+`define RX_DUAL
+//`define RX_QUAD
+
+// ------------------------------------------------------------
+// Define RX_HB_ON to enable the receive halfband filter
+//`define RX_HB_ON
+
+// ------------------------------------------------------------
+// Define RX_NCO_ON to enable the receive Numerical Controlled Osc
+  `define RX_NCO_ON
+
+// ------------------------------------------------------------
+// Define RX_CIC_ON to enable the receive Cascaded Integrator Comb filter
+  `define RX_CIC_ON
diff --git a/usrp/fpga/toplevel/usrp_multi/usrp_multi_config_2rxhb_0tx.vh b/usrp/fpga/toplevel/usrp_multi/usrp_multi_config_2rxhb_0tx.vh
new file mode 100644 (file)
index 0000000..0673d96
--- /dev/null
@@ -0,0 +1,62 @@
+// -*- verilog -*-
+//
+//  USRP - Universal Software Radio Peripheral
+//
+//  Copyright (C) 2006 Matt Ettus
+//  Copyright (C) 2006 Martin Dudok van Heel
+//
+//  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
+//
+`define MULTI_ON
+// ------------------------------------------------------------
+// If TX_ON is not defined, there is *no* transmit circuitry built
+// `define TX_ON
+
+// ------------------------------------------------------------
+// Define 1 and only one of TX_SINGLE, TX_DUAL and TX_QUAD
+// to respectively enable 1, 2 or 4 transmit channels.
+// [Please note that only TX_DUAL is currently valid]
+//`define TX_SINGLE
+//`define TX_DUAL
+//`define TX_QUAD
+
+// ------------------------------------------------------------
+// Define TX_HB_ON to enable the transmit halfband filter
+// [Not implemented]
+//`define TX_HB_ON
+
+// ------------------------------------------------------------
+// IF RX_ON is not defined, there is *no* transmit circuitry built
+  `define RX_ON
+
+// ------------------------------------------------------------
+// Define 1 and only one of RX_SINGLE, RX_DUAL and RX_QUAD
+// to respectively define 1, 2 or 4 receive channels.
+
+//`define RX_SINGLE
+  `define RX_DUAL
+//`define RX_QUAD
+
+// ------------------------------------------------------------
+// Define RX_HB_ON to enable the receive halfband filter
+  `define RX_HB_ON
+
+// ------------------------------------------------------------
+// Define RX_NCO_ON to enable the receive Numerical Controlled Osc
+  `define RX_NCO_ON
+
+// ------------------------------------------------------------
+// Define RX_CIC_ON to enable the receive Cascaded Integrator Comb filter
+  `define RX_CIC_ON
diff --git a/usrp/fpga/toplevel/usrp_multi/usrp_multi_config_2rxhb_2tx.vh b/usrp/fpga/toplevel/usrp_multi/usrp_multi_config_2rxhb_2tx.vh
new file mode 100644 (file)
index 0000000..80c7fbd
--- /dev/null
@@ -0,0 +1,62 @@
+// -*- verilog -*-
+//
+//  USRP - Universal Software Radio Peripheral
+//
+//  Copyright (C) 2006 Matt Ettus
+//  Copyright (C) 2006 Martin Dudok van Heel
+//
+//  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
+//
+`define MULTI_ON
+// ------------------------------------------------------------
+// If TX_ON is not defined, there is *no* transmit circuitry built
+  `define TX_ON
+
+// ------------------------------------------------------------
+// Define 1 and only one of TX_SINGLE, TX_DUAL and TX_QUAD
+// to respectively enable 1, 2 or 4 transmit channels.
+// [Please note that only TX_DUAL is currently valid]
+//`define TX_SINGLE
+  `define TX_DUAL
+//`define TX_QUAD
+
+// ------------------------------------------------------------
+// Define TX_HB_ON to enable the transmit halfband filter
+// [Not implemented]
+//`define TX_HB_ON
+
+// ------------------------------------------------------------
+// IF RX_ON is not defined, there is *no* transmit circuitry built
+  `define RX_ON
+
+// ------------------------------------------------------------
+// Define 1 and only one of RX_SINGLE, RX_DUAL and RX_QUAD
+// to respectively define 1, 2 or 4 receive channels.
+
+//`define RX_SINGLE
+  `define RX_DUAL
+//`define RX_QUAD
+
+// ------------------------------------------------------------
+// Define RX_HB_ON to enable the receive halfband filter
+  `define RX_HB_ON
+
+// ------------------------------------------------------------
+// Define RX_NCO_ON to enable the receive Numerical Controlled Osc
+  `define RX_NCO_ON
+
+// ------------------------------------------------------------
+// Define RX_CIC_ON to enable the receive Cascaded Integrator Comb filter
+  `define RX_CIC_ON
diff --git a/usrp/fpga/toplevel/usrp_multi/usrp_multi_config_4rx_0tx.vh b/usrp/fpga/toplevel/usrp_multi/usrp_multi_config_4rx_0tx.vh
new file mode 100644 (file)
index 0000000..36176be
--- /dev/null
@@ -0,0 +1,62 @@
+// -*- verilog -*-
+//
+//  USRP - Universal Software Radio Peripheral
+//
+//  Copyright (C) 2006 Matt Ettus
+//  Copyright (C) 2006 Martin Dudok van Heel
+//
+//  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
+//
+`define MULTI_ON
+// ------------------------------------------------------------
+// If TX_ON is not defined, there is *no* transmit circuitry built
+// `define TX_ON
+
+// ------------------------------------------------------------
+// Define 1 and only one of TX_SINGLE, TX_DUAL and TX_QUAD
+// to respectively enable 1, 2 or 4 transmit channels.
+// [Please note that only TX_DUAL is currently valid]
+//`define TX_SINGLE
+//`define TX_DUAL
+//`define TX_QUAD
+
+// ------------------------------------------------------------
+// Define TX_HB_ON to enable the transmit halfband filter
+// [Not implemented]
+//`define TX_HB_ON
+
+// ------------------------------------------------------------
+// IF RX_ON is not defined, there is *no* transmit circuitry built
+  `define RX_ON
+
+// ------------------------------------------------------------
+// Define 1 and only one of RX_SINGLE, RX_DUAL and RX_QUAD
+// to respectively define 1, 2 or 4 receive channels.
+
+//`define RX_SINGLE
+//`define RX_DUAL
+  `define RX_QUAD
+
+// ------------------------------------------------------------
+// Define RX_HB_ON to enable the receive halfband filter
+//`define RX_HB_ON
+
+// ------------------------------------------------------------
+// Define RX_NCO_ON to enable the receive Numerical Controlled Osc
+  `define RX_NCO_ON
+
+// ------------------------------------------------------------
+// Define RX_CIC_ON to enable the receive Cascaded Integrator Comb filter
+  `define RX_CIC_ON
diff --git a/usrp/fpga/toplevel/usrp_multi/usrp_std.vh b/usrp/fpga/toplevel/usrp_multi/usrp_std.vh
new file mode 100644 (file)
index 0000000..189cf14
--- /dev/null
@@ -0,0 +1,29 @@
+// -*- verilog -*-
+//
+//  USRP - Universal Software Radio Peripheral
+//
+//  Copyright (C) 2006 Martin Dudok van Heel
+//
+//  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
+//
+
+// ====================================================================
+//            Do not remove or edit this file.
+//            This is a redirect to usrp_multi.vh
+//            This is needed because some common source files have a 
+//            hardcoded `include "usrp_std.vh"
+// ====================================================================
+
+`include "usrp_multi.vh"
diff --git a/usrp/fpga/toplevel/usrp_std/usrp_std.csf b/usrp/fpga/toplevel/usrp_std/usrp_std.csf
new file mode 100644 (file)
index 0000000..627197c
--- /dev/null
@@ -0,0 +1,444 @@
+COMPILER_SETTINGS
+{
+       IO_PLACEMENT_OPTIMIZATION = OFF;
+       ENABLE_DRC_SETTINGS = OFF;
+       PHYSICAL_SYNTHESIS_REGISTER_RETIMING = OFF;
+       PHYSICAL_SYNTHESIS_REGISTER_DUPLICATION = OFF;
+       PHYSICAL_SYNTHESIS_COMBO_LOGIC = OFF;
+       DRC_FANOUT_EXCEEDING = 30;
+       DRC_REPORT_FANOUT_EXCEEDING = OFF;
+       DRC_TOP_FANOUT = 50;
+       DRC_REPORT_TOP_FANOUT = OFF;
+       RUN_DRC_DURING_COMPILATION = OFF;
+       ADV_NETLIST_OPT_RETIME_CORE_AND_IO = ON;
+       ADV_NETLIST_OPT_SYNTH_USE_FITTER_INFO = OFF;
+       ADV_NETLIST_OPT_SYNTH_GATE_RETIME = OFF;
+       ADV_NETLIST_OPT_SYNTH_WYSIWYG_REMAP = OFF;
+       SMART_COMPILE_IGNORES_TDC_FOR_STRATIX_PLL_CHANGES = OFF;
+       MERGE_HEX_FILE = OFF;
+       TRUE_WYSIWYG_FLOW = OFF;
+       SEED = 1;
+       FINAL_PLACEMENT_OPTIMIZATION = AUTOMATICALLY;
+       FAMILY = Cyclone;
+       DPRAM_DUAL_PORT_MODE_OTHER_SIGNALS_EPXA1 = "DPRAM0 TO 1 DPRAM1 TO 2";
+       DPRAM_32BIT_SINGLE_PORT_MODE_OTHER_SIGNALS_EPXA1 = "MEGALAB COLUMN 1";
+       DPRAM_8BIT_16BIT_SINGLE_PORT_MODE_OTHER_SIGNALS_EPXA1 = "MEGALAB COLUMN 1";
+       DPRAM_DUAL_PORT_MODE_OUTPUT_EPXA1 = "DPRAM0 TO 1 DPRAM1 TO 2";
+       DPRAM_32BIT_SINGLE_PORT_MODE_OUTPUT_EPXA1 = "LOWER TO 1ESB UPPER TO 1";
+       DPRAM_8BIT_16BIT_SINGLE_PORT_MODE_OUTPUT_EPXA1 = "MEGALAB COLUMN 1";
+       DPRAM_DUAL_PORT_MODE_INPUT_EPXA1 = "DPRAM0 TO 1 DPRAM1 TO 2";
+       DPRAM_32BIT_SINGLE_PORT_MODE_INPUT_EPXA1 = "MEGALAB COLUMN 1";
+       DPRAM_8BIT_16BIT_SINGLE_PORT_MODE_INPUT_EPXA1 = "MEGALAB COLUMN 1";
+       DPRAM_DUAL_PORT_MODE_OTHER_SIGNALS_EPXA4_10 = "DPRAM0 TO 3 DPRAM1 TO 4";
+       DPRAM_SINGLE_PORT_MODE_OTHER_SIGNALS_EPXA4_10 = "DPRAM0 TO 3 DPRAM1 TO 4";
+       DPRAM_WIDE_MODE_OTHER_SIGNALS_EPXA4_10 = "MEGALAB COLUMN 3";
+       DPRAM_DEEP_MODE_OTHER_SIGNALS_EPXA4_10 = "MEGALAB COLUMN 3";
+       DPRAM_DUAL_PORT_MODE_OUTPUT_EPXA4_10 = "DPRAM0 TO 3 DPRAM1 TO 4ESB";
+       DPRAM_SINGLE_PORT_MODE_OUTPUT_EPXA4_10 = "DPRAM0 TO 3 DPRAM1 TO 4ESB";
+       DPRAM_WIDE_MODE_OUTPUT_EPXA4_10 = "LOWER TO 3 UPPER TO 4ESB";
+       DPRAM_DEEP_MODE_OUTPUT_EPXA4_10 = "MEGALAB COLUMN 3";
+       DPRAM_DUAL_PORT_MODE_INPUT_EPXA4_10 = "DPRAM0 TO 3 DPRAM1 TO 4";
+       DPRAM_SINGLE_PORT_MODE_INPUT_EPXA4_10 = "DPRAM0 TO 3 DPRAM1 TO 4";
+       DPRAM_WIDE_MODE_INPUT_EPXA4_10 = "LOWER TO 3 UPPER TO 4";
+       DPRAM_DEEP_MODE_INPUT_EPXA4_10 = "MEGALAB COLUMN 3";
+       DPRAM_OTHER_SIGNALS_EPXA4_10 = "DEFAULT OTHER ROUTING OPTIONS";
+       DPRAM_OUTPUT_EPXA4_10 = "DEFAULT OUTPUT ROUTING OPTIONS";
+       DPRAM_INPUT_EPXA4_10 = "DEFAULT INPUT ROUTING OPTIONS";
+       STRIPE_TO_PLD_INTERRUPTS_EPXA4_10 = "MEGALAB COLUMN 2";
+       PLD_TO_STRIPE_INTERRUPTS_EPXA4_10 = "MEGALAB COLUMN 2";
+       PROCESSOR_DEBUG_EXTENSIONS_EPXA4_10 = "MEGALAB COLUMN 2";
+       STRIPE_TO_PLD_BRIDGE_EPXA4_10 = "MEGALAB COLUMN 1";
+       FAST_FIT_COMPILATION = OFF;
+       SIGNALPROBE_DURING_NORMAL_COMPILATION = OFF;
+       OPTIMIZE_IOC_REGISTER_PLACEMENT_FOR_TIMING = ON;
+       OPTIMIZE_TIMING = "NORMAL COMPILATION";
+       OPTIMIZE_HOLD_TIMING = OFF;
+       COMPILATION_LEVEL = FULL;
+       SAVE_DISK_SPACE = OFF;
+       SPEED_DISK_USAGE_TRADEOFF = NORMAL;
+       LOGICLOCK_INCREMENTAL_COMPILE_ASSIGNMENT = OFF;
+       SIGNALPROBE_ALLOW_OVERUSE = OFF;
+       FOCUS_ENTITY_NAME = |usrp_std;
+       ROUTING_BACK_ANNOTATION_MODE = OFF;
+       INC_PLC_MODE = OFF;
+       FIT_ONLY_ONE_ATTEMPT = OFF;
+}
+DEFAULT_DEVICE_OPTIONS
+{
+       GENERATE_CONFIG_HEXOUT_FILE = OFF;
+       GENERATE_CONFIG_JBC_FILE_COMPRESSED = ON;
+       GENERATE_CONFIG_JBC_FILE = OFF;
+       GENERATE_CONFIG_JAM_FILE = OFF;
+       GENERATE_CONFIG_ISC_FILE = OFF;
+       GENERATE_CONFIG_SVF_FILE = OFF;
+       GENERATE_JBC_FILE_COMPRESSED = ON;
+       GENERATE_JBC_FILE = OFF;
+       GENERATE_JAM_FILE = OFF;
+       GENERATE_ISC_FILE = OFF;
+       GENERATE_SVF_FILE = OFF;
+       RESERVE_PIN = "AS INPUT TRI-STATED";
+       RESERVE_ALL_UNUSED_PINS = "AS OUTPUT DRIVING GROUND";
+       HEXOUT_FILE_COUNT_DIRECTION = UP;
+       HEXOUT_FILE_START_ADDRESS = 0;
+       GENERATE_HEX_FILE = OFF;
+       GENERATE_RBF_FILE = OFF;
+       GENERATE_TTF_FILE = OFF;
+       RESERVE_ASDO_AFTER_CONFIGURATION = "USE AS REGULAR IO";
+       RESERVE_DATA0_AFTER_CONFIGURATION = "AS INPUT TRI-STATED";
+       RESERVE_DATA7_THROUGH_DATA1_AFTER_CONFIGURATION = "USE AS REGULAR IO";
+       RESERVE_RDYNBUSY_AFTER_CONFIGURATION = "USE AS REGULAR IO";
+       RESERVE_NWS_NRS_NCS_CS_AFTER_CONFIGURATION = "USE AS REGULAR IO";
+       DISABLE_NCS_AND_OE_PULLUPS_ON_CONFIG_DEVICE = OFF;
+       AUTO_INCREMENT_CONFIG_DEVICE_JTAG_USER_CODE = ON;
+       EPROM_USE_CHECKSUM_AS_USERCODE = OFF;
+       FLEX10K_CONFIG_DEVICE_JTAG_USER_CODE = FFFFFFFF;
+       MERCURY_CONFIG_DEVICE_JTAG_USER_CODE = FFFFFFFF;
+       STRATIX_CONFIG_DEVICE_JTAG_USER_CODE = FFFFFFFF;
+       APEX20K_CONFIG_DEVICE_JTAG_USER_CODE = FFFFFFFF;
+       STRATIX_CONFIGURATION_DEVICE = AUTO;
+       CYCLONE_CONFIGURATION_DEVICE = AUTO;
+       FLEX10K_CONFIGURATION_DEVICE = AUTO;
+       FLEX6K_CONFIGURATION_DEVICE = AUTO;
+       MERCURY_CONFIGURATION_DEVICE = AUTO;
+       EXCALIBUR_CONFIGURATION_DEVICE = AUTO;
+       APEX20K_CONFIGURATION_DEVICE = AUTO;
+       USE_CONFIGURATION_DEVICE = ON;
+       ENABLE_INIT_DONE_OUTPUT = OFF;
+       FLEX10K_ENABLE_LOCK_OUTPUT = OFF;
+       ENABLE_DEVICE_WIDE_OE = OFF;
+       ENABLE_DEVICE_WIDE_RESET = OFF;
+       RELEASE_CLEARS_BEFORE_TRI_STATES = OFF;
+       AUTO_RESTART_CONFIGURATION = OFF;
+       ENABLE_VREFB_PIN = OFF;
+       ENABLE_VREFA_PIN = OFF;
+       SECURITY_BIT = OFF;
+       USER_START_UP_CLOCK = OFF;
+       APEXII_CONFIGURATION_SCHEME = "PASSIVE SERIAL";
+       FLEX10K_CONFIGURATION_SCHEME = "PASSIVE SERIAL";
+       FLEX6K_CONFIGURATION_SCHEME = "PASSIVE SERIAL";
+       MERCURY_CONFIGURATION_SCHEME = "PASSIVE SERIAL";
+       EXCALIBUR_CONFIGURATION_SCHEME = "PASSIVE SERIAL";
+       CYCLONE_CONFIGURATION_SCHEME = "ACTIVE SERIAL";
+       STRATIX_CONFIGURATION_SCHEME = "PASSIVE SERIAL";
+       APEX20K_CONFIGURATION_SCHEME = "PASSIVE SERIAL";
+       STRATIX_UPDATE_MODE = STANDARD;
+       USE_CHECKSUM_AS_USERCODE = OFF;
+       MAX7000_USE_CHECKSUM_AS_USERCODE = OFF;
+       MAX7000_JTAG_USER_CODE = FFFFFFFF;
+       FLEX10K_JTAG_USER_CODE = 7F;
+       MERCURY_JTAG_USER_CODE = FFFFFFFF;
+       APEX20K_JTAG_USER_CODE = FFFFFFFF;
+       STRATIX_JTAG_USER_CODE = FFFFFFFF;
+       MAX7000S_JTAG_USER_CODE = FFFF;
+       RESERVE_NCEO_AFTER_CONFIGURATION = "USE AS REGULAR IO";
+       FLEX10K_ENABLE_LOW_VOLTAGE_MODE_ON_CONFIG_DEVICE = ON;
+       FLEX6K_ENABLE_LOW_VOLTAGE_MODE_ON_CONFIG_DEVICE = OFF;
+       ENABLE_LOW_VOLTAGE_MODE_ON_CONFIG_DEVICE = ON;
+       MAX7000_ENABLE_JTAG_BST_SUPPORT = ON;
+       ENABLE_JTAG_BST_SUPPORT = OFF;
+       CONFIGURATION_CLOCK_DIVISOR = 1;
+       CONFIGURATION_CLOCK_FREQUENCY = "10 MHZ";
+       CLOCK_SOURCE = INTERNAL;
+       COMPRESSION_MODE = OFF;
+       ON_CHIP_BITSTREAM_DECOMPRESSION = OFF;
+}
+AUTO_SLD_HUB_ENTITY
+{
+       AUTO_INSERT_SLD_HUB_ENTITY = ENABLE;
+       HUB_INSTANCE_NAME = SLD_HUB_INST;
+       HUB_ENTITY_NAME = SLD_HUB;
+}
+SIGNALTAP_LOGIC_ANALYZER_SETTINGS
+{
+       ENABLE_SIGNALTAP = Off;
+       AUTO_ENABLE_SMART_COMPILE = On;
+}
+CHIP(usrp_std)
+{
+       DEVICE = EP1C12Q240C8;
+       DEVICE_FILTER_PACKAGE = "ANY QFP";
+       DEVICE_FILTER_PIN_COUNT = 240;
+       DEVICE_FILTER_SPEED_GRADE = ANY;
+       AUTO_RESTART_CONFIGURATION = OFF;
+       RELEASE_CLEARS_BEFORE_TRI_STATES = OFF;
+       USER_START_UP_CLOCK = OFF;
+       ENABLE_DEVICE_WIDE_RESET = OFF;
+       ENABLE_DEVICE_WIDE_OE = OFF;
+       ENABLE_INIT_DONE_OUTPUT = OFF;
+       FLEX10K_ENABLE_LOCK_OUTPUT = OFF;
+       ENABLE_JTAG_BST_SUPPORT = OFF;
+       MAX7000_ENABLE_JTAG_BST_SUPPORT = ON;
+       APEX20K_JTAG_USER_CODE = FFFFFFFF;
+       MERCURY_JTAG_USER_CODE = FFFFFFFF;
+       FLEX10K_JTAG_USER_CODE = 7F;
+       MAX7000_JTAG_USER_CODE = FFFFFFFF;
+       MAX7000S_JTAG_USER_CODE = FFFF;
+       STRATIX_JTAG_USER_CODE = FFFFFFFF;
+       APEX20K_CONFIGURATION_SCHEME = "PASSIVE SERIAL";
+       MERCURY_CONFIGURATION_SCHEME = "PASSIVE SERIAL";
+       FLEX6K_CONFIGURATION_SCHEME = "PASSIVE SERIAL";
+       FLEX10K_CONFIGURATION_SCHEME = "PASSIVE SERIAL";
+       EXCALIBUR_CONFIGURATION_SCHEME = "PASSIVE SERIAL";
+       APEXII_CONFIGURATION_SCHEME = "PASSIVE SERIAL";
+       STRATIX_CONFIGURATION_SCHEME = "PASSIVE SERIAL";
+       CYCLONE_CONFIGURATION_SCHEME = "PASSIVE SERIAL";
+       USE_CONFIGURATION_DEVICE = OFF;
+       APEX20K_CONFIGURATION_DEVICE = AUTO;
+       MERCURY_CONFIGURATION_DEVICE = AUTO;
+       FLEX6K_CONFIGURATION_DEVICE = AUTO;
+       FLEX10K_CONFIGURATION_DEVICE = AUTO;
+       EXCALIBUR_CONFIGURATION_DEVICE = AUTO;
+       STRATIX_CONFIGURATION_DEVICE = AUTO;
+       CYCLONE_CONFIGURATION_DEVICE = AUTO;
+       STRATIX_UPDATE_MODE = STANDARD;
+       APEX20K_CONFIG_DEVICE_JTAG_USER_CODE = FFFFFFFF;
+       MERCURY_CONFIG_DEVICE_JTAG_USER_CODE = FFFFFFFF;
+       FLEX10K_CONFIG_DEVICE_JTAG_USER_CODE = FFFFFFFF;
+       STRATIX_CONFIG_DEVICE_JTAG_USER_CODE = FFFFFFFF;
+       AUTO_INCREMENT_CONFIG_DEVICE_JTAG_USER_CODE = ON;
+       DISABLE_NCS_AND_OE_PULLUPS_ON_CONFIG_DEVICE = OFF;
+       COMPRESSION_MODE = OFF;
+       ENABLE_LOW_VOLTAGE_MODE_ON_CONFIG_DEVICE = ON;
+       FLEX6K_ENABLE_LOW_VOLTAGE_MODE_ON_CONFIG_DEVICE = OFF;
+       FLEX10K_ENABLE_LOW_VOLTAGE_MODE_ON_CONFIG_DEVICE = ON;
+       EPROM_USE_CHECKSUM_AS_USERCODE = OFF;
+       USE_CHECKSUM_AS_USERCODE = OFF;
+       MAX7000_USE_CHECKSUM_AS_USERCODE = OFF;
+       GENERATE_TTF_FILE = OFF;
+       GENERATE_RBF_FILE = ON;
+       GENERATE_HEX_FILE = OFF;
+       SECURITY_BIT = OFF;
+       ENABLE_VREFA_PIN = OFF;
+       ENABLE_VREFB_PIN = OFF;
+       GENERATE_SVF_FILE = OFF;
+       GENERATE_ISC_FILE = OFF;
+       GENERATE_JAM_FILE = OFF;
+       GENERATE_JBC_FILE = OFF;
+       GENERATE_JBC_FILE_COMPRESSED = ON;
+       GENERATE_CONFIG_SVF_FILE = OFF;
+       GENERATE_CONFIG_ISC_FILE = OFF;
+       GENERATE_CONFIG_JAM_FILE = OFF;
+       GENERATE_CONFIG_JBC_FILE = OFF;
+       GENERATE_CONFIG_JBC_FILE_COMPRESSED = ON;
+       GENERATE_CONFIG_HEXOUT_FILE = OFF;
+       ON_CHIP_BITSTREAM_DECOMPRESSION = OFF;
+       BASE_PIN_OUT_FILE_ON_SAMEFRAME_DEVICE = OFF;
+       HEXOUT_FILE_START_ADDRESS = 0;
+       HEXOUT_FILE_COUNT_DIRECTION = UP;
+       RESERVE_ALL_UNUSED_PINS = "AS INPUT TRI-STATED";
+       STRATIX_DEVICE_IO_STANDARD = LVTTL;
+       CLOCK_SOURCE = INTERNAL;
+       CONFIGURATION_CLOCK_FREQUENCY = "10 MHZ";
+       CONFIGURATION_CLOCK_DIVISOR = 1;
+       RESERVE_NWS_NRS_NCS_CS_AFTER_CONFIGURATION = "USE AS REGULAR IO";
+       RESERVE_RDYNBUSY_AFTER_CONFIGURATION = "USE AS REGULAR IO";
+       RESERVE_DATA7_THROUGH_DATA1_AFTER_CONFIGURATION = "USE AS REGULAR IO";
+       RESERVE_DATA0_AFTER_CONFIGURATION = "AS INPUT TRI-STATED";
+       RESERVE_NCEO_AFTER_CONFIGURATION = "USE AS REGULAR IO";
+       RESERVE_ASDO_AFTER_CONFIGURATION = "USE AS REGULAR IO";
+       SCLK : LOCATION = Pin_101;
+       SDI : LOCATION = Pin_100;
+       SEN : LOCATION = Pin_98;
+       SLD : LOCATION = Pin_95;
+       adc1_data[0] : LOCATION = Pin_5;
+       adc1_data[10] : LOCATION = Pin_235;
+       adc1_data[11] : LOCATION = Pin_234;
+       adc1_data[1] : LOCATION = Pin_4;
+       adc1_data[2] : LOCATION = Pin_3;
+       adc1_data[3] : LOCATION = Pin_2;
+       adc1_data[4] : LOCATION = Pin_1;
+       adc1_data[4] : IO_STANDARD = LVTTL;
+       adc1_data[5] : LOCATION = Pin_240;
+       adc1_data[6] : LOCATION = Pin_239;
+       adc1_data[7] : LOCATION = Pin_238;
+       adc1_data[8] : LOCATION = Pin_237;
+       adc1_data[9] : LOCATION = Pin_236;
+       adc2_data[0] : LOCATION = Pin_20;
+       adc2_data[10] : LOCATION = Pin_8;
+       adc2_data[11] : LOCATION = Pin_7;
+       adc2_data[1] : LOCATION = Pin_19;
+       adc2_data[2] : LOCATION = Pin_18;
+       adc2_data[3] : LOCATION = Pin_17;
+       adc2_data[4] : LOCATION = Pin_16;
+       adc2_data[5] : LOCATION = Pin_15;
+       adc2_data[6] : LOCATION = Pin_14;
+       adc2_data[7] : LOCATION = Pin_13;
+       adc2_data[8] : LOCATION = Pin_12;
+       adc2_data[9] : LOCATION = Pin_11;
+       adc3_data[0] : LOCATION = Pin_200;
+       adc3_data[10] : LOCATION = Pin_184;
+       adc3_data[11] : LOCATION = Pin_183;
+       adc3_data[1] : LOCATION = Pin_197;
+       adc3_data[2] : LOCATION = Pin_196;
+       adc3_data[3] : LOCATION = Pin_195;
+       adc3_data[4] : LOCATION = Pin_194;
+       adc3_data[5] : LOCATION = Pin_193;
+       adc3_data[6] : LOCATION = Pin_188;
+       adc3_data[7] : LOCATION = Pin_187;
+       adc3_data[8] : LOCATION = Pin_186;
+       adc3_data[9] : LOCATION = Pin_185;
+       adc4_data[0] : LOCATION = Pin_222;
+       adc4_data[10] : LOCATION = Pin_203;
+       adc4_data[11] : LOCATION = Pin_202;
+       adc4_data[1] : LOCATION = Pin_219;
+       adc4_data[2] : LOCATION = Pin_217;
+       adc4_data[3] : LOCATION = Pin_216;
+       adc4_data[4] : LOCATION = Pin_215;
+       adc4_data[5] : LOCATION = Pin_214;
+       adc4_data[6] : LOCATION = Pin_213;
+       adc4_data[7] : LOCATION = Pin_208;
+       adc4_data[8] : LOCATION = Pin_207;
+       adc4_data[9] : LOCATION = Pin_206;
+       adc_oeb[0] : LOCATION = Pin_228;
+       adc_oeb[1] : LOCATION = Pin_21;
+       adc_oeb[2] : LOCATION = Pin_181;
+       adc_oeb[3] : LOCATION = Pin_218;
+       adc_otr[0] : LOCATION = Pin_233;
+       adc_otr[1] : LOCATION = Pin_6;
+       adc_otr[2] : LOCATION = Pin_182;
+       adc_otr[3] : LOCATION = Pin_201;
+       adclk0 : LOCATION = Pin_224;
+       adclk1 : LOCATION = Pin_226;
+       clk0 : LOCATION = Pin_28;
+       clk0 : RESERVE_PIN = "AS INPUT TRI-STATED";
+       clk0 : IO_STANDARD = LVTTL;
+       clk1 : LOCATION = Pin_29;
+       clk1 : RESERVE_PIN = "AS INPUT TRI-STATED";
+       clk1 : IO_STANDARD = LVTTL;
+       clk3 : LOCATION = Pin_152;
+       clk3 : RESERVE_PIN = "AS INPUT TRI-STATED";
+       clk3 : IO_STANDARD = LVTTL;
+       clk_120mhz : LOCATION = Pin_153;
+       clk_120mhz : IO_STANDARD = LVTTL;
+       clk_out : LOCATION = Pin_63;
+       clk_out : IO_STANDARD = LVTTL;
+       dac1_data[0] : LOCATION = Pin_165;
+       dac1_data[10] : LOCATION = Pin_177;
+       dac1_data[11] : LOCATION = Pin_178;
+       dac1_data[12] : LOCATION = Pin_179;
+       dac1_data[13] : LOCATION = Pin_180;
+       dac1_data[1] : LOCATION = Pin_166;
+       dac1_data[2] : LOCATION = Pin_167;
+       dac1_data[3] : LOCATION = Pin_168;
+       dac1_data[4] : LOCATION = Pin_169;
+       dac1_data[5] : LOCATION = Pin_170;
+       dac1_data[6] : LOCATION = Pin_173;
+       dac1_data[7] : LOCATION = Pin_174;
+       dac1_data[8] : LOCATION = Pin_175;
+       dac1_data[9] : LOCATION = Pin_176;
+       dac2_data[0] : LOCATION = Pin_159;
+       dac2_data[10] : LOCATION = Pin_163;
+       dac2_data[11] : LOCATION = Pin_139;
+       dac2_data[12] : LOCATION = Pin_164;
+       dac2_data[13] : LOCATION = Pin_138;
+       dac2_data[1] : LOCATION = Pin_158;
+       dac2_data[2] : LOCATION = Pin_160;
+       dac2_data[3] : LOCATION = Pin_156;
+       dac2_data[4] : LOCATION = Pin_161;
+       dac2_data[5] : LOCATION = Pin_144;
+       dac2_data[6] : LOCATION = Pin_162;
+       dac2_data[7] : LOCATION = Pin_141;
+       dac2_data[8] : LOCATION = Pin_143;
+       dac2_data[9] : LOCATION = Pin_140;
+       dac3_data[0] : LOCATION = Pin_122;
+       dac3_data[10] : LOCATION = Pin_134;
+       dac3_data[11] : LOCATION = Pin_135;
+       dac3_data[12] : LOCATION = Pin_136;
+       dac3_data[13] : LOCATION = Pin_137;
+       dac3_data[1] : LOCATION = Pin_123;
+       dac3_data[2] : LOCATION = Pin_124;
+       dac3_data[3] : LOCATION = Pin_125;
+       dac3_data[4] : LOCATION = Pin_126;
+       dac3_data[5] : LOCATION = Pin_127;
+       dac3_data[6] : LOCATION = Pin_128;
+       dac3_data[7] : LOCATION = Pin_131;
+       dac3_data[8] : LOCATION = Pin_132;
+       dac3_data[9] : LOCATION = Pin_133;
+       dac4_data[0] : LOCATION = Pin_104;
+       dac4_data[10] : LOCATION = Pin_118;
+       dac4_data[11] : LOCATION = Pin_119;
+       dac4_data[12] : LOCATION = Pin_120;
+       dac4_data[13] : LOCATION = Pin_121;
+       dac4_data[1] : LOCATION = Pin_105;
+       dac4_data[2] : LOCATION = Pin_106;
+       dac4_data[3] : LOCATION = Pin_107;
+       dac4_data[4] : LOCATION = Pin_108;
+       dac4_data[5] : LOCATION = Pin_113;
+       dac4_data[6] : LOCATION = Pin_114;
+       dac4_data[7] : LOCATION = Pin_115;
+       dac4_data[8] : LOCATION = Pin_116;
+       dac4_data[9] : LOCATION = Pin_117;
+       enable_rx : LOCATION = Pin_88;
+       enable_tx : LOCATION = Pin_93;
+       gndbus[0] : LOCATION = Pin_223;
+       gndbus[0] : RESERVE_PIN = "AS INPUT TRI-STATED";
+       gndbus[0] : IO_STANDARD = LVTTL;
+       gndbus[1] : LOCATION = Pin_225;
+       gndbus[1] : RESERVE_PIN = "AS INPUT TRI-STATED";
+       gndbus[1] : IO_STANDARD = LVTTL;
+       gndbus[2] : LOCATION = Pin_227;
+       gndbus[2] : RESERVE_PIN = "AS INPUT TRI-STATED";
+       gndbus[2] : IO_STANDARD = LVTTL;
+       gndbus[3] : LOCATION = Pin_62;
+       gndbus[3] : RESERVE_PIN = "AS INPUT TRI-STATED";
+       gndbus[3] : IO_STANDARD = LVTTL;
+       gndbus[4] : LOCATION = Pin_64;
+       gndbus[4] : RESERVE_PIN = "AS INPUT TRI-STATED";
+       gndbus[4] : IO_STANDARD = LVTTL;
+       misc_pins[0] : LOCATION = Pin_87;
+       misc_pins[0] : IO_STANDARD = LVTTL;
+       misc_pins[10] : LOCATION = Pin_76;
+       misc_pins[10] : IO_STANDARD = LVTTL;
+       misc_pins[11] : LOCATION = Pin_74;
+       misc_pins[11] : IO_STANDARD = LVTTL;
+       misc_pins[1] : LOCATION = Pin_86;
+       misc_pins[1] : IO_STANDARD = LVTTL;
+       misc_pins[2] : LOCATION = Pin_85;
+       misc_pins[2] : IO_STANDARD = LVTTL;
+       misc_pins[3] : LOCATION = Pin_84;
+       misc_pins[3] : IO_STANDARD = LVTTL;
+       misc_pins[4] : LOCATION = Pin_83;
+       misc_pins[4] : IO_STANDARD = LVTTL;
+       misc_pins[5] : LOCATION = Pin_82;
+       misc_pins[5] : IO_STANDARD = LVTTL;
+       misc_pins[6] : LOCATION = Pin_79;
+       misc_pins[6] : IO_STANDARD = LVTTL;
+       misc_pins[7] : LOCATION = Pin_78;
+       misc_pins[7] : IO_STANDARD = LVTTL;
+       misc_pins[8] : LOCATION = Pin_77;
+       misc_pins[8] : IO_STANDARD = LVTTL;
+       misc_pins[9] : LOCATION = Pin_75;
+       misc_pins[9] : IO_STANDARD = LVTTL;
+       reset : LOCATION = Pin_94;
+       usbclk : LOCATION = Pin_55;
+       usbctl[0] : LOCATION = Pin_56;
+       usbctl[1] : LOCATION = Pin_54;
+       usbctl[2] : LOCATION = Pin_53;
+       usbctl[3] : LOCATION = Pin_58;
+       usbctl[4] : LOCATION = Pin_57;
+       usbctl[5] : LOCATION = Pin_44;
+       usbdata[0] : LOCATION = Pin_73;
+       usbdata[10] : LOCATION = Pin_41;
+       usbdata[11] : LOCATION = Pin_39;
+       usbdata[12] : LOCATION = Pin_38;
+       usbdata[12] : IO_STANDARD = LVTTL;
+       usbdata[13] : LOCATION = Pin_37;
+       usbdata[14] : LOCATION = Pin_24;
+       usbdata[15] : LOCATION = Pin_23;
+       usbdata[1] : LOCATION = Pin_68;
+       usbdata[2] : LOCATION = Pin_67;
+       usbdata[3] : LOCATION = Pin_66;
+       usbdata[4] : LOCATION = Pin_65;
+       usbdata[5] : LOCATION = Pin_61;
+       usbdata[6] : LOCATION = Pin_60;
+       usbdata[7] : LOCATION = Pin_59;
+       usbdata[8] : LOCATION = Pin_43;
+       usbdata[9] : LOCATION = Pin_42;
+       usbrdy[0] : LOCATION = Pin_45;
+       usbrdy[1] : LOCATION = Pin_46;
+       usbrdy[2] : LOCATION = Pin_47;
+       usbrdy[3] : LOCATION = Pin_48;
+       usbrdy[4] : LOCATION = Pin_49;
+       usbrdy[5] : LOCATION = Pin_50;
+       clear_status : LOCATION = Pin_99;
+}
diff --git a/usrp/fpga/toplevel/usrp_std/usrp_std.esf b/usrp/fpga/toplevel/usrp_std/usrp_std.esf
new file mode 100644 (file)
index 0000000..b88c159
--- /dev/null
@@ -0,0 +1,14 @@
+SIMULATOR_SETTINGS
+{
+       ESTIMATE_POWER_CONSUMPTION = OFF;
+       GLITCH_INTERVAL = 1NS;
+       GLITCH_DETECTION = OFF;
+       SIMULATION_COVERAGE = ON;
+       CHECK_OUTPUTS = OFF;
+       SETUP_HOLD_DETECTION = OFF;
+       POWER_ESTIMATION_START_TIME = "0 NS";
+       ADD_DEFAULT_PINS_TO_SIMULATION_OUTPUT_WAVEFORMS = ON;
+       SIMULATION_MODE = TIMING;
+       START_TIME = 0NS;
+       USE_COMPILER_SETTINGS = usrp_std;
+}
diff --git a/usrp/fpga/toplevel/usrp_std/usrp_std.psf b/usrp/fpga/toplevel/usrp_std/usrp_std.psf
new file mode 100644 (file)
index 0000000..506c81b
--- /dev/null
@@ -0,0 +1,312 @@
+DEFAULT_DESIGN_ASSISTANT_SETTINGS
+{
+       HCPY_ALOAD_SIGNALS = OFF;
+       HCPY_VREF_PINS = OFF;
+       HCPY_CAT = OFF;
+       HCPY_ILLEGAL_HC_DEV_PKG = OFF;
+       ACLK_RULE_IMSZER_ADOMAIN = OFF;
+       ACLK_RULE_SZER_BTW_ACLK_DOMAIN = OFF;
+       ACLK_RULE_NO_SZER_ACLK_DOMAIN = OFF;
+       ACLK_CAT = OFF;
+       SIGNALRACE_RULE_ASYNCHPIN_SYNCH_CLKPIN = OFF;
+       SIGNALRACE_CAT = OFF;
+       NONSYNCHSTRUCT_RULE_LATCH_UNIDENTIFIED = OFF;
+       NONSYNCHSTRUCT_RULE_SRLATCH = OFF;
+       NONSYNCHSTRUCT_RULE_DLATCH = OFF;
+       NONSYNCHSTRUCT_RULE_MULTI_VIBRATOR = OFF;
+       NONSYNCHSTRUCT_RULE_ILLEGAL_PULSE_GEN = OFF;
+       NONSYNCHSTRUCT_RULE_RIPPLE_CLK = OFF;
+       NONSYNCHSTRUCT_RULE_DELAY_CHAIN = OFF;
+       NONSYNCHSTRUCT_RULE_REG_LOOP = OFF;
+       NONSYNCHSTRUCT_RULE_COMBLOOP = OFF;
+       NONSYNCHSTRUCT_CAT = OFF;
+       NONSYNCHSTRUCT_RULE_COMB_DRIVES_RAM_WE = OFF;
+       TIMING_RULE_COIN_CLKEDGE = OFF;
+       TIMING_RULE_SHIFT_REG = OFF;
+       TIMING_RULE_HIGH_FANOUTS = OFF;
+       TIMING_CAT = OFF;
+       RESET_RULE_ALL = OFF;
+       RESET_RULE_IMSYNCH_ASYNCH_DOMAIN = OFF;
+       RESET_RULE_UNSYNCH_ASYNCH_DOMAIN = OFF;
+       RESET_RULE_REG_ASNYCH = OFF;
+       RESET_RULE_COMB_ASYNCH_RESET = OFF;
+       RESET_RULE_IMSYNCH_EXRESET = OFF;
+       RESET_RULE_UNSYNCH_EXRESET = OFF;
+       RESET_RULE_INPINS_RESETNET = OFF;
+       RESET_CAT = OFF;
+       CLK_RULE_ALL = OFF;
+       CLK_RULE_MIX_EDGES = OFF;
+       CLK_RULE_CLKNET_CLKSPINES = OFF;
+       CLK_RULE_INPINS_CLKNET = OFF;
+       CLK_RULE_GATING_SCHEME = OFF;
+       CLK_RULE_INV_CLOCK = OFF;
+       CLK_RULE_COMB_CLOCK = OFF;
+       CLK_CAT = OFF;
+       HCPY_EXCEED_USER_IO_USAGE = OFF;
+       HCPY_EXCEED_RAM_USAGE = OFF;
+       NONSYNCHSTRUCT_RULE_ASYN_RAM = OFF;
+       SIGNALRACE_RULE_TRISTATE = OFF;
+       ASSG_RULE_MISSING_TIMING = OFF;
+       ASSG_RULE_MISSING_FMAX = OFF;
+       ASSG_CAT = OFF;
+}
+SYNTHESIS_FITTING_SETTINGS
+{
+       AUTO_SHIFT_REGISTER_RECOGNITION = ON;
+       AUTO_DSP_RECOGNITION = ON;
+       AUTO_RAM_RECOGNITION = ON;
+       REMOVE_DUPLICATE_LOGIC = ON;
+       AUTO_TURBO_BIT = ON;
+       AUTO_MERGE_PLLS = ON;
+       AUTO_OPEN_DRAIN_PINS = ON;
+       AUTO_PARALLEL_EXPANDERS = ON;
+       AUTO_FAST_OUTPUT_ENABLE_REGISTERS = OFF;
+       AUTO_FAST_OUTPUT_REGISTERS = OFF;
+       AUTO_FAST_INPUT_REGISTERS = OFF;
+       AUTO_CASCADE_CHAINS = ON;
+       AUTO_CARRY_CHAINS = ON;
+       AUTO_DELAY_CHAINS = ON;
+       MAX7000_PARALLEL_EXPANDER_CHAIN_LENGTH = 4;
+       PARALLEL_EXPANDER_CHAIN_LENGTH = 16;
+       CASCADE_CHAIN_LENGTH = 2;
+       STRATIX_CARRY_CHAIN_LENGTH = 70;
+       MERCURY_CARRY_CHAIN_LENGTH = 48;
+       FLEX10K_CARRY_CHAIN_LENGTH = 32;
+       FLEX6K_CARRY_CHAIN_LENGTH = 32;
+       CARRY_CHAIN_LENGTH = 48;
+       CARRY_OUT_PINS_LCELL_INSERT = ON;
+       NORMAL_LCELL_INSERT = ON;
+       AUTO_LCELL_INSERTION = ON;
+       ALLOW_XOR_GATE_USAGE = ON;
+       AUTO_PACKED_REGISTERS_STRATIX = NORMAL;
+       AUTO_PACKED_REGISTERS = OFF;
+       AUTO_PACKED_REG_CYCLONE = NORMAL;
+       FLEX10K_OPTIMIZATION_TECHNIQUE = AREA;
+       FLEX6K_OPTIMIZATION_TECHNIQUE = AREA;
+       MERCURY_OPTIMIZATION_TECHNIQUE = AREA;
+       APEX20K_OPTIMIZATION_TECHNIQUE = SPEED;
+       MAX7000_OPTIMIZATION_TECHNIQUE = SPEED;
+       STRATIX_OPTIMIZATION_TECHNIQUE = SPEED;
+       CYCLONE_OPTIMIZATION_TECHNIQUE = AREA;
+       FLEX10K_TECHNOLOGY_MAPPER = LUT;
+       FLEX6K_TECHNOLOGY_MAPPER = LUT;
+       MERCURY_TECHNOLOGY_MAPPER = LUT;
+       APEX20K_TECHNOLOGY_MAPPER = LUT;
+       MAX7000_TECHNOLOGY_MAPPER = "PRODUCT TERM";
+       STRATIX_TECHNOLOGY_MAPPER = LUT;
+       AUTO_IMPLEMENT_IN_ROM = OFF;
+       AUTO_GLOBAL_MEMORY_CONTROLS = OFF;
+       AUTO_GLOBAL_REGISTER_CONTROLS = ON;
+       AUTO_GLOBAL_OE = ON;
+       AUTO_GLOBAL_CLOCK = ON;
+       USE_LPM_FOR_AHDL_OPERATORS = ON;
+       LIMIT_AHDL_INTEGERS_TO_32_BITS = OFF;
+       ENABLE_BUS_HOLD_CIRCUITRY = OFF;
+       WEAK_PULL_UP_RESISTOR = OFF;
+       TURBO_BIT = ON;
+       MAX7000_IGNORE_SOFT_BUFFERS = OFF;
+       IGNORE_SOFT_BUFFERS = ON;
+       MAX7000_IGNORE_LCELL_BUFFERS = AUTO;
+       IGNORE_LCELL_BUFFERS = OFF;
+       IGNORE_ROW_GLOBAL_BUFFERS = OFF;
+       IGNORE_GLOBAL_BUFFERS = OFF;
+       IGNORE_CASCADE_BUFFERS = OFF;
+       IGNORE_CARRY_BUFFERS = OFF;
+       REMOVE_DUPLICATE_REGISTERS = ON;
+       REMOVE_REDUNDANT_LOGIC_CELLS = OFF;
+       ALLOW_POWER_UP_DONT_CARE = ON;
+       PCI_IO = OFF;
+       NOT_GATE_PUSH_BACK = ON;
+       SLOW_SLEW_RATE = OFF;
+       DSP_BLOCK_BALANCING = AUTO;
+       STATE_MACHINE_PROCESSING = AUTO;
+}
+DEFAULT_HARDCOPY_SETTINGS
+{
+       HARDCOPY_EXTERNAL_CLOCK_JITTER = "0.0 NS";
+}
+DEFAULT_TIMING_REQUIREMENTS
+{
+       INCLUDE_EXTERNAL_PIN_DELAYS_IN_FMAX_CALCULATIONS = OFF;
+       RUN_ALL_TIMING_ANALYSES = ON;
+       IGNORE_CLOCK_SETTINGS = OFF;
+       DEFAULT_HOLD_MULTICYCLE = "SAME AS MULTICYCLE";
+       CUT_OFF_IO_PIN_FEEDBACK = ON;
+       CUT_OFF_CLEAR_AND_PRESET_PATHS = ON;
+       CUT_OFF_READ_DURING_WRITE_PATHS = ON;
+       CUT_OFF_PATHS_BETWEEN_CLOCK_DOMAINS = ON;
+       DO_MIN_ANALYSIS = ON;
+       DO_MIN_TIMING = OFF;
+       NUMBER_OF_PATHS_TO_REPORT = 200;
+       NUMBER_OF_DESTINATION_TO_REPORT = 10;
+       NUMBER_OF_SOURCES_PER_DESTINATION_TO_REPORT = 10;
+       MAX_SCC_SIZE = 50;
+}
+HDL_SETTINGS
+{
+       VERILOG_INPUT_VERSION = VERILOG_2001;
+       ENABLE_IP_DEBUG = OFF;
+       VHDL_INPUT_VERSION = VHDL93;
+       VHDL_SHOW_LMF_MAPPING_MESSAGES = OFF;
+}
+PROJECT_INFO(usrp_std)
+{
+       ORIGINAL_QUARTUS_VERSION = 3.0;
+       PROJECT_CREATION_TIME_DATE = "00:14:04  JULY 13, 2003";
+       LAST_QUARTUS_VERSION = 3.0;
+       SHOW_REGISTRATION_MESSAGE = ON;
+       USER_LIBRARIES = "e:\usrp\fpga\megacells";
+}
+THIRD_PARTY_EDA_TOOLS(usrp_std)
+{
+       EDA_DESIGN_ENTRY_SYNTHESIS_TOOL = "<NONE>";
+       EDA_SIMULATION_TOOL = "<NONE>";
+       EDA_TIMING_ANALYSIS_TOOL = "<NONE>";
+       EDA_BOARD_DESIGN_TOOL = "<NONE>";
+       EDA_FORMAL_VERIFICATION_TOOL = "<NONE>";
+       EDA_RESYNTHESIS_TOOL = "<NONE>";
+}
+EDA_TOOL_SETTINGS(eda_design_synthesis)
+{
+       EDA_INPUT_GND_NAME = GND;
+       EDA_INPUT_VCC_NAME = VCC;
+       EDA_SHOW_LMF_MAPPING_MESSAGES = OFF;
+       EDA_RUN_TOOL_AUTOMATICALLY = OFF;
+       EDA_INPUT_DATA_FORMAT = EDIF;
+       EDA_OUTPUT_DATA_FORMAT = NONE;
+       USE_GENERATED_PHYSICAL_CONSTRAINTS = ON;
+       RESYNTHESIS_PHYSICAL_SYNTHESIS = NORMAL;
+       RESYNTHESIS_OPTIMIZATION_EFFORT = NORMAL;
+       RESYNTHESIS_RETIMING = FULL;
+}
+EDA_TOOL_SETTINGS(eda_simulation)
+{
+       EDA_INCLUDE_VHDL_CONFIGURATION_DECLARATION = OFF;
+       EDA_TRUNCATE_LONG_HIERARCHY_PATHS = OFF;
+       EDA_MAINTAIN_DESIGN_HIERARCHY = OFF;
+       EDA_WRITE_DEVICE_CONTROL_PORTS = OFF;
+       EDA_GENERATE_FUNCTIONAL_NETLIST = OFF;
+       EDA_FLATTEN_BUSES = OFF;
+       EDA_MAP_ILLEGAL_CHARACTERS = OFF;
+       EDA_EXCALIBUR_ATOMS_AS_SINGLE_STRIPE = OFF;
+       EDA_RUN_TOOL_AUTOMATICALLY = OFF;
+       EDA_OUTPUT_DATA_FORMAT = NONE;
+       USE_GENERATED_PHYSICAL_CONSTRAINTS = ON;
+       RESYNTHESIS_PHYSICAL_SYNTHESIS = NORMAL;
+       RESYNTHESIS_OPTIMIZATION_EFFORT = NORMAL;
+       RESYNTHESIS_RETIMING = FULL;
+}
+EDA_TOOL_SETTINGS(eda_timing_analysis)
+{
+       EDA_INCLUDE_VHDL_CONFIGURATION_DECLARATION = OFF;
+       EDA_TRUNCATE_LONG_HIERARCHY_PATHS = OFF;
+       EDA_MAINTAIN_DESIGN_HIERARCHY = OFF;
+       EDA_WRITE_DEVICE_CONTROL_PORTS = OFF;
+       EDA_GENERATE_FUNCTIONAL_NETLIST = OFF;
+       EDA_FLATTEN_BUSES = OFF;
+       EDA_MAP_ILLEGAL_CHARACTERS = OFF;
+       EDA_EXCALIBUR_ATOMS_AS_SINGLE_STRIPE = OFF;
+       EDA_RUN_TOOL_AUTOMATICALLY = OFF;
+       EDA_OUTPUT_DATA_FORMAT = NONE;
+       EDA_LAUNCH_CMD_LINE_TOOL = OFF;
+       USE_GENERATED_PHYSICAL_CONSTRAINTS = ON;
+       RESYNTHESIS_PHYSICAL_SYNTHESIS = NORMAL;
+       RESYNTHESIS_OPTIMIZATION_EFFORT = NORMAL;
+       RESYNTHESIS_RETIMING = FULL;
+}
+EDA_TOOL_SETTINGS(eda_board_design)
+{
+       EDA_INCLUDE_VHDL_CONFIGURATION_DECLARATION = OFF;
+       EDA_TRUNCATE_LONG_HIERARCHY_PATHS = OFF;
+       EDA_MAINTAIN_DESIGN_HIERARCHY = OFF;
+       EDA_WRITE_DEVICE_CONTROL_PORTS = OFF;
+       EDA_GENERATE_FUNCTIONAL_NETLIST = OFF;
+       EDA_FLATTEN_BUSES = OFF;
+       EDA_MAP_ILLEGAL_CHARACTERS = OFF;
+       EDA_EXCALIBUR_ATOMS_AS_SINGLE_STRIPE = OFF;
+       EDA_RUN_TOOL_AUTOMATICALLY = OFF;
+       EDA_OUTPUT_DATA_FORMAT = NONE;
+       USE_GENERATED_PHYSICAL_CONSTRAINTS = ON;
+       RESYNTHESIS_PHYSICAL_SYNTHESIS = NORMAL;
+       RESYNTHESIS_OPTIMIZATION_EFFORT = NORMAL;
+       RESYNTHESIS_RETIMING = FULL;
+}
+EDA_TOOL_SETTINGS(eda_formal_verification)
+{
+       EDA_INCLUDE_VHDL_CONFIGURATION_DECLARATION = OFF;
+       EDA_TRUNCATE_LONG_HIERARCHY_PATHS = OFF;
+       EDA_MAINTAIN_DESIGN_HIERARCHY = OFF;
+       EDA_WRITE_DEVICE_CONTROL_PORTS = OFF;
+       EDA_GENERATE_FUNCTIONAL_NETLIST = OFF;
+       EDA_FLATTEN_BUSES = OFF;
+       EDA_MAP_ILLEGAL_CHARACTERS = OFF;
+       EDA_EXCALIBUR_ATOMS_AS_SINGLE_STRIPE = OFF;
+       EDA_RUN_TOOL_AUTOMATICALLY = OFF;
+       EDA_OUTPUT_DATA_FORMAT = NONE;
+       USE_GENERATED_PHYSICAL_CONSTRAINTS = ON;
+       RESYNTHESIS_PHYSICAL_SYNTHESIS = NORMAL;
+       RESYNTHESIS_OPTIMIZATION_EFFORT = NORMAL;
+       RESYNTHESIS_RETIMING = FULL;
+}
+EDA_TOOL_SETTINGS(eda_palace)
+{
+       EDA_INCLUDE_VHDL_CONFIGURATION_DECLARATION = OFF;
+       EDA_TRUNCATE_LONG_HIERARCHY_PATHS = OFF;
+       EDA_MAINTAIN_DESIGN_HIERARCHY = OFF;
+       EDA_WRITE_DEVICE_CONTROL_PORTS = OFF;
+       EDA_GENERATE_FUNCTIONAL_NETLIST = OFF;
+       EDA_FLATTEN_BUSES = OFF;
+       EDA_MAP_ILLEGAL_CHARACTERS = OFF;
+       EDA_EXCALIBUR_ATOMS_AS_SINGLE_STRIPE = OFF;
+       EDA_RUN_TOOL_AUTOMATICALLY = OFF;
+       EDA_OUTPUT_DATA_FORMAT = NONE;
+       RESYNTHESIS_RETIMING = FULL;
+       RESYNTHESIS_PHYSICAL_SYNTHESIS = NORMAL;
+       RESYNTHESIS_OPTIMIZATION_EFFORT = NORMAL;
+       USE_GENERATED_PHYSICAL_CONSTRAINTS = ON;
+}
+CLOCK(clk_120mhz)
+{
+       FMAX_REQUIREMENT = "120.0 MHz";
+       INCLUDE_EXTERNAL_PIN_DELAYS_IN_FMAX_CALCULATIONS = OFF;
+       DUTY_CYCLE = 50;
+       DIVIDE_BASE_CLOCK_PERIOD_BY = 1;
+       MULTIPLY_BASE_CLOCK_PERIOD_BY = 1;
+       INVERT_BASE_CLOCK = OFF;
+}
+CLOCK(usbclk)
+{
+       FMAX_REQUIREMENT = "48.0 MHz";
+       INCLUDE_EXTERNAL_PIN_DELAYS_IN_FMAX_CALCULATIONS = OFF;
+       DUTY_CYCLE = 50;
+       DIVIDE_BASE_CLOCK_PERIOD_BY = 1;
+       MULTIPLY_BASE_CLOCK_PERIOD_BY = 1;
+       INVERT_BASE_CLOCK = OFF;
+}
+CLOCK(SCLK)
+{
+       FMAX_REQUIREMENT = "1.0 MHz";
+       INCLUDE_EXTERNAL_PIN_DELAYS_IN_FMAX_CALCULATIONS = OFF;
+       DUTY_CYCLE = 50;
+       DIVIDE_BASE_CLOCK_PERIOD_BY = 1;
+       MULTIPLY_BASE_CLOCK_PERIOD_BY = 1;
+       INVERT_BASE_CLOCK = OFF;
+}
+CLOCK(adclk0)
+{
+       FMAX_REQUIREMENT = "60.0 MHz";
+       INCLUDE_EXTERNAL_PIN_DELAYS_IN_FMAX_CALCULATIONS = OFF;
+       DUTY_CYCLE = 50;
+       DIVIDE_BASE_CLOCK_PERIOD_BY = 1;
+       MULTIPLY_BASE_CLOCK_PERIOD_BY = 1;
+       INVERT_BASE_CLOCK = OFF;
+}
+CLOCK(adclk1)
+{
+       FMAX_REQUIREMENT = "60.0 MHz";
+       INCLUDE_EXTERNAL_PIN_DELAYS_IN_FMAX_CALCULATIONS = OFF;
+       DUTY_CYCLE = 50;
+       DIVIDE_BASE_CLOCK_PERIOD_BY = 1;
+       MULTIPLY_BASE_CLOCK_PERIOD_BY = 1;
+       INVERT_BASE_CLOCK = OFF;
+}
diff --git a/usrp/fpga/toplevel/usrp_std/usrp_std.qpf b/usrp/fpga/toplevel/usrp_std/usrp_std.qpf
new file mode 100644 (file)
index 0000000..e8b2750
--- /dev/null
@@ -0,0 +1,29 @@
+# Copyright (C) 1991-2004 Altera Corporation
+# Any  megafunction  design,  and related netlist (encrypted  or  decrypted),
+# support information,  device programming or simulation file,  and any other
+# associated  documentation or information  provided by  Altera  or a partner
+# under  Altera's   Megafunction   Partnership   Program  may  be  used  only
+# to program  PLD  devices (but not masked  PLD  devices) from  Altera.   Any
+# other  use  of such  megafunction  design,  netlist,  support  information,
+# device programming or simulation file,  or any other  related documentation
+# or information  is prohibited  for  any  other purpose,  including, but not
+# limited to  modification,  reverse engineering,  de-compiling, or use  with
+# any other  silicon devices,  unless such use is  explicitly  licensed under
+# a separate agreement with  Altera  or a megafunction partner.  Title to the
+# intellectual property,  including patents,  copyrights,  trademarks,  trade
+# secrets,  or maskworks,  embodied in any such megafunction design, netlist,
+# support  information,  device programming or simulation file,  or any other
+# related documentation or information provided by  Altera  or a megafunction
+# partner, remains with Altera, the megafunction partner, or their respective
+# licensors. No other licenses, including any licenses needed under any third
+# party's intellectual property, are provided herein.
+
+
+
+QUARTUS_VERSION = "4.0"
+DATE = "17:10:11  December 20, 2004"
+
+
+# Active Revisions
+
+PROJECT_REVISION = "usrp_std"
diff --git a/usrp/fpga/toplevel/usrp_std/usrp_std.qsf b/usrp/fpga/toplevel/usrp_std/usrp_std.qsf
new file mode 100644 (file)
index 0000000..51d7e1e
--- /dev/null
@@ -0,0 +1,406 @@
+# Copyright (C) 1991-2005 Altera Corporation
+# Your use of Altera Corporation's design tools, logic functions 
+# and other software and tools, and its AMPP partner logic       
+# functions, and any output files any of the foregoing           
+# (including device programming or simulation files), and any    
+# associated documentation or information are expressly subject  
+# to the terms and conditions of the Altera Program License      
+# Subscription Agreement, Altera MegaCore Function License       
+# Agreement, or other applicable license agreement, including,   
+# without limitation, that your use is for the sole purpose of   
+# programming logic devices manufactured by Altera and sold by   
+# Altera or its authorized distributors.  Please refer to the    
+# applicable agreement for further details.
+
+
+# The default values for assignments are stored in the file
+#              usrp_std_assignment_defaults.qdf
+# If this file doesn't exist, and for assignments not listed, see file
+#              assignment_defaults.qdf
+
+# Altera recommends that you do not modify this file. This
+# file is updated automatically by the Quartus II software
+# and any changes you make may be lost or overwritten.
+
+
+# Project-Wide Assignments
+# ========================
+set_global_assignment -name ORIGINAL_QUARTUS_VERSION 3.0
+set_global_assignment -name PROJECT_CREATION_TIME_DATE "00:14:04  JULY 13, 2003"
+set_global_assignment -name LAST_QUARTUS_VERSION "5.1 SP2"
+
+# Pin & Location Assignments
+# ==========================
+set_global_assignment -name RESERVE_PIN "AS INPUT TRI-STATED"
+set_location_assignment PIN_29 -to SCLK
+set_location_assignment PIN_117 -to SDI
+set_location_assignment PIN_28 -to usbclk
+set_location_assignment PIN_107 -to usbctl[0]
+set_location_assignment PIN_106 -to usbctl[1]
+set_location_assignment PIN_105 -to usbctl[2]
+set_location_assignment PIN_100 -to usbdata[0]
+set_location_assignment PIN_84 -to usbdata[10]
+set_location_assignment PIN_83 -to usbdata[11]
+set_location_assignment PIN_82 -to usbdata[12]
+set_location_assignment PIN_79 -to usbdata[13]
+set_location_assignment PIN_78 -to usbdata[14]
+set_location_assignment PIN_77 -to usbdata[15]
+set_location_assignment PIN_99 -to usbdata[1]
+set_location_assignment PIN_98 -to usbdata[2]
+set_location_assignment PIN_95 -to usbdata[3]
+set_location_assignment PIN_94 -to usbdata[4]
+set_location_assignment PIN_93 -to usbdata[5]
+set_location_assignment PIN_88 -to usbdata[6]
+set_location_assignment PIN_87 -to usbdata[7]
+set_location_assignment PIN_86 -to usbdata[8]
+set_location_assignment PIN_85 -to usbdata[9]
+set_location_assignment PIN_104 -to usbrdy[0]
+set_location_assignment PIN_101 -to usbrdy[1]
+set_location_assignment PIN_76 -to FX2_1
+set_location_assignment PIN_75 -to FX2_2
+set_location_assignment PIN_74 -to FX2_3
+set_location_assignment PIN_116 -to io_rx_a[0]
+set_location_assignment PIN_115 -to io_rx_a[1]
+set_location_assignment PIN_114 -to io_rx_a[2]
+set_location_assignment PIN_113 -to io_rx_a[3]
+set_location_assignment PIN_108 -to io_rx_a[4]
+set_location_assignment PIN_195 -to io_rx_a[5]
+set_location_assignment PIN_196 -to io_rx_a[6]
+set_location_assignment PIN_197 -to io_rx_a[7]
+set_location_assignment PIN_200 -to io_rx_a[8]
+set_location_assignment PIN_201 -to io_rx_a[9]
+set_location_assignment PIN_202 -to io_rx_a[10]
+set_location_assignment PIN_203 -to io_rx_a[11]
+set_location_assignment PIN_206 -to io_rx_a[12]
+set_location_assignment PIN_207 -to io_rx_a[13]
+set_location_assignment PIN_208 -to io_rx_a[14]
+set_location_assignment PIN_214 -to io_rx_b[0]
+set_location_assignment PIN_215 -to io_rx_b[1]
+set_location_assignment PIN_216 -to io_rx_b[2]
+set_location_assignment PIN_217 -to io_rx_b[3]
+set_location_assignment PIN_218 -to io_rx_b[4]
+set_location_assignment PIN_219 -to io_rx_b[5]
+set_location_assignment PIN_222 -to io_rx_b[6]
+set_location_assignment PIN_223 -to io_rx_b[7]
+set_location_assignment PIN_224 -to io_rx_b[8]
+set_location_assignment PIN_225 -to io_rx_b[9]
+set_location_assignment PIN_226 -to io_rx_b[10]
+set_location_assignment PIN_227 -to io_rx_b[11]
+set_location_assignment PIN_228 -to io_rx_b[12]
+set_location_assignment PIN_233 -to io_rx_b[13]
+set_location_assignment PIN_234 -to io_rx_b[14]
+set_location_assignment PIN_175 -to io_tx_a[0]
+set_location_assignment PIN_176 -to io_tx_a[1]
+set_location_assignment PIN_177 -to io_tx_a[2]
+set_location_assignment PIN_178 -to io_tx_a[3]
+set_location_assignment PIN_179 -to io_tx_a[4]
+set_location_assignment PIN_180 -to io_tx_a[5]
+set_location_assignment PIN_181 -to io_tx_a[6]
+set_location_assignment PIN_182 -to io_tx_a[7]
+set_location_assignment PIN_183 -to io_tx_a[8]
+set_location_assignment PIN_184 -to io_tx_a[9]
+set_location_assignment PIN_185 -to io_tx_a[10]
+set_location_assignment PIN_186 -to io_tx_a[11]
+set_location_assignment PIN_187 -to io_tx_a[12]
+set_location_assignment PIN_188 -to io_tx_a[13]
+set_location_assignment PIN_193 -to io_tx_a[14]
+set_location_assignment PIN_73 -to io_tx_b[0]
+set_location_assignment PIN_68 -to io_tx_b[1]
+set_location_assignment PIN_67 -to io_tx_b[2]
+set_location_assignment PIN_66 -to io_tx_b[3]
+set_location_assignment PIN_65 -to io_tx_b[4]
+set_location_assignment PIN_64 -to io_tx_b[5]
+set_location_assignment PIN_63 -to io_tx_b[6]
+set_location_assignment PIN_62 -to io_tx_b[7]
+set_location_assignment PIN_61 -to io_tx_b[8]
+set_location_assignment PIN_60 -to io_tx_b[9]
+set_location_assignment PIN_59 -to io_tx_b[10]
+set_location_assignment PIN_58 -to io_tx_b[11]
+set_location_assignment PIN_57 -to io_tx_b[12]
+set_location_assignment PIN_56 -to io_tx_b[13]
+set_location_assignment PIN_55 -to io_tx_b[14]
+set_location_assignment PIN_152 -to master_clk
+set_location_assignment PIN_144 -to rx_a_a[0]
+set_location_assignment PIN_143 -to rx_a_a[1]
+set_location_assignment PIN_141 -to rx_a_a[2]
+set_location_assignment PIN_140 -to rx_a_a[3]
+set_location_assignment PIN_139 -to rx_a_a[4]
+set_location_assignment PIN_138 -to rx_a_a[5]
+set_location_assignment PIN_137 -to rx_a_a[6]
+set_location_assignment PIN_136 -to rx_a_a[7]
+set_location_assignment PIN_135 -to rx_a_a[8]
+set_location_assignment PIN_134 -to rx_a_a[9]
+set_location_assignment PIN_133 -to rx_a_a[10]
+set_location_assignment PIN_132 -to rx_a_a[11]
+set_location_assignment PIN_23 -to rx_a_b[0]
+set_location_assignment PIN_21 -to rx_a_b[1]
+set_location_assignment PIN_20 -to rx_a_b[2]
+set_location_assignment PIN_19 -to rx_a_b[3]
+set_location_assignment PIN_18 -to rx_a_b[4]
+set_location_assignment PIN_17 -to rx_a_b[5]
+set_location_assignment PIN_16 -to rx_a_b[6]
+set_location_assignment PIN_15 -to rx_a_b[7]
+set_location_assignment PIN_14 -to rx_a_b[8]
+set_location_assignment PIN_13 -to rx_a_b[9]
+set_location_assignment PIN_12 -to rx_a_b[10]
+set_location_assignment PIN_11 -to rx_a_b[11]
+set_location_assignment PIN_131 -to rx_b_a[0]
+set_location_assignment PIN_128 -to rx_b_a[1]
+set_location_assignment PIN_127 -to rx_b_a[2]
+set_location_assignment PIN_126 -to rx_b_a[3]
+set_location_assignment PIN_125 -to rx_b_a[4]
+set_location_assignment PIN_124 -to rx_b_a[5]
+set_location_assignment PIN_123 -to rx_b_a[6]
+set_location_assignment PIN_122 -to rx_b_a[7]
+set_location_assignment PIN_121 -to rx_b_a[8]
+set_location_assignment PIN_120 -to rx_b_a[9]
+set_location_assignment PIN_119 -to rx_b_a[10]
+set_location_assignment PIN_118 -to rx_b_a[11]
+set_location_assignment PIN_8 -to rx_b_b[0]
+set_location_assignment PIN_7 -to rx_b_b[1]
+set_location_assignment PIN_6 -to rx_b_b[2]
+set_location_assignment PIN_5 -to rx_b_b[3]
+set_location_assignment PIN_4 -to rx_b_b[4]
+set_location_assignment PIN_3 -to rx_b_b[5]
+set_location_assignment PIN_2 -to rx_b_b[6]
+set_location_assignment PIN_240 -to rx_b_b[7]
+set_location_assignment PIN_239 -to rx_b_b[8]
+set_location_assignment PIN_238 -to rx_b_b[9]
+set_location_assignment PIN_237 -to rx_b_b[10]
+set_location_assignment PIN_236 -to rx_b_b[11]
+set_location_assignment PIN_156 -to SDO
+set_location_assignment PIN_153 -to SEN_FPGA
+set_location_assignment PIN_159 -to tx_a[0]
+set_location_assignment PIN_160 -to tx_a[1]
+set_location_assignment PIN_161 -to tx_a[2]
+set_location_assignment PIN_162 -to tx_a[3]
+set_location_assignment PIN_163 -to tx_a[4]
+set_location_assignment PIN_164 -to tx_a[5]
+set_location_assignment PIN_165 -to tx_a[6]
+set_location_assignment PIN_166 -to tx_a[7]
+set_location_assignment PIN_167 -to tx_a[8]
+set_location_assignment PIN_168 -to tx_a[9]
+set_location_assignment PIN_169 -to tx_a[10]
+set_location_assignment PIN_170 -to tx_a[11]
+set_location_assignment PIN_173 -to tx_a[12]
+set_location_assignment PIN_174 -to tx_a[13]
+set_location_assignment PIN_38 -to tx_b[0]
+set_location_assignment PIN_39 -to tx_b[1]
+set_location_assignment PIN_41 -to tx_b[2]
+set_location_assignment PIN_42 -to tx_b[3]
+set_location_assignment PIN_43 -to tx_b[4]
+set_location_assignment PIN_44 -to tx_b[5]
+set_location_assignment PIN_45 -to tx_b[6]
+set_location_assignment PIN_46 -to tx_b[7]
+set_location_assignment PIN_47 -to tx_b[8]
+set_location_assignment PIN_48 -to tx_b[9]
+set_location_assignment PIN_49 -to tx_b[10]
+set_location_assignment PIN_50 -to tx_b[11]
+set_location_assignment PIN_53 -to tx_b[12]
+set_location_assignment PIN_54 -to tx_b[13]
+set_location_assignment PIN_158 -to TXSYNC_A
+set_location_assignment PIN_37 -to TXSYNC_B
+set_location_assignment PIN_235 -to io_rx_b[15]
+set_location_assignment PIN_24 -to io_tx_b[15]
+set_location_assignment PIN_213 -to io_rx_a[15]
+set_location_assignment PIN_194 -to io_tx_a[15]
+set_location_assignment PIN_1 -to MYSTERY_SIGNAL
+
+# Timing Assignments
+# ==================
+set_global_assignment -name INCLUDE_EXTERNAL_PIN_DELAYS_IN_FMAX_CALCULATIONS OFF
+
+# Analysis & Synthesis Assignments
+# ================================
+set_global_assignment -name SAVE_DISK_SPACE OFF
+set_global_assignment -name DEVICE_FILTER_PACKAGE "ANY QFP"
+set_global_assignment -name DEVICE_FILTER_PIN_COUNT 240
+set_global_assignment -name EDA_DESIGN_ENTRY_SYNTHESIS_TOOL "<None>"
+set_global_assignment -name FAMILY Cyclone
+set_global_assignment -name CYCLONE_OPTIMIZATION_TECHNIQUE BALANCED
+set_global_assignment -name STRATIX_OPTIMIZATION_TECHNIQUE SPEED
+set_global_assignment -name APEX20K_OPTIMIZATION_TECHNIQUE SPEED
+set_global_assignment -name TOP_LEVEL_ENTITY usrp_std
+set_global_assignment -name VHDL_SHOW_LMF_MAPPING_MESSAGES OFF
+set_global_assignment -name USER_LIBRARIES "e:\\usrp\\fpga\\megacells"
+set_global_assignment -name AUTO_ENABLE_SMART_COMPILE On
+
+# Fitter Assignments
+# ==================
+set_global_assignment -name DEVICE EP1C12Q240C8
+set_global_assignment -name CYCLONE_CONFIGURATION_SCHEME "PASSIVE SERIAL"
+set_global_assignment -name RESERVE_ALL_UNUSED_PINS "AS INPUT TRI-STATED"
+set_global_assignment -name OPTIMIZE_HOLD_TIMING OFF
+set_global_assignment -name OPTIMIZE_TIMING "NORMAL COMPILATION"
+set_global_assignment -name PHYSICAL_SYNTHESIS_COMBO_LOGIC OFF
+set_global_assignment -name PHYSICAL_SYNTHESIS_REGISTER_DUPLICATION OFF
+set_global_assignment -name PHYSICAL_SYNTHESIS_REGISTER_RETIMING OFF
+set_global_assignment -name IO_PLACEMENT_OPTIMIZATION OFF
+set_global_assignment -name PHYSICAL_SYNTHESIS_EFFORT NORMAL
+set_global_assignment -name INC_PLC_MODE OFF
+set_global_assignment -name ROUTING_BACK_ANNOTATION_MODE OFF
+set_instance_assignment -name IO_STANDARD LVTTL -to usbdata[12]
+set_global_assignment -name STRATIX_DEVICE_IO_STANDARD LVTTL
+set_global_assignment -name ERROR_CHECK_FREQUENCY_DIVISOR 1
+
+# Timing Analysis Assignments
+# ===========================
+set_global_assignment -name MAX_SCC_SIZE 50
+
+# EDA Netlist Writer Assignments
+# ==============================
+set_global_assignment -name EDA_SIMULATION_TOOL "<None>"
+set_global_assignment -name EDA_TIMING_ANALYSIS_TOOL "<NONE>"
+set_global_assignment -name EDA_BOARD_DESIGN_TOOL "<NONE>"
+set_global_assignment -name EDA_FORMAL_VERIFICATION_TOOL "<NONE>"
+set_global_assignment -name EDA_RESYNTHESIS_TOOL "<NONE>"
+
+# Assembler Assignments
+# =====================
+set_global_assignment -name USE_CONFIGURATION_DEVICE OFF
+set_global_assignment -name GENERATE_RBF_FILE ON
+set_global_assignment -name RESERVE_ALL_UNUSED_PINS_NO_OUTPUT_GND "AS INPUT TRI-STATED"
+set_global_assignment -name AUTO_RESTART_CONFIGURATION OFF
+
+# Simulator Assignments
+# =====================
+set_global_assignment -name START_TIME "0 ns"
+set_global_assignment -name GLITCH_INTERVAL "1 ns"
+
+# Design Assistant Assignments
+# ============================
+set_global_assignment -name DRC_REPORT_TOP_FANOUT OFF
+set_global_assignment -name DRC_REPORT_FANOUT_EXCEEDING OFF
+set_global_assignment -name ASSG_CAT OFF
+set_global_assignment -name ASSG_RULE_MISSING_FMAX OFF
+set_global_assignment -name ASSG_RULE_MISSING_TIMING OFF
+set_global_assignment -name NONSYNCHSTRUCT_RULE_ASYN_RAM OFF
+set_global_assignment -name CLK_CAT OFF
+set_global_assignment -name CLK_RULE_COMB_CLOCK OFF
+set_global_assignment -name CLK_RULE_INV_CLOCK OFF
+set_global_assignment -name CLK_RULE_GATING_SCHEME OFF
+set_global_assignment -name CLK_RULE_INPINS_CLKNET OFF
+set_global_assignment -name CLK_RULE_CLKNET_CLKSPINES OFF
+set_global_assignment -name CLK_RULE_MIX_EDGES OFF
+set_global_assignment -name RESET_CAT OFF
+set_global_assignment -name RESET_RULE_INPINS_RESETNET OFF
+set_global_assignment -name RESET_RULE_UNSYNCH_EXRESET OFF
+set_global_assignment -name RESET_RULE_IMSYNCH_EXRESET OFF
+set_global_assignment -name RESET_RULE_COMB_ASYNCH_RESET OFF
+set_global_assignment -name RESET_RULE_UNSYNCH_ASYNCH_DOMAIN OFF
+set_global_assignment -name RESET_RULE_IMSYNCH_ASYNCH_DOMAIN OFF
+set_global_assignment -name TIMING_CAT OFF
+set_global_assignment -name TIMING_RULE_SHIFT_REG OFF
+set_global_assignment -name TIMING_RULE_COIN_CLKEDGE OFF
+set_global_assignment -name NONSYNCHSTRUCT_RULE_COMB_DRIVES_RAM_WE OFF
+set_global_assignment -name NONSYNCHSTRUCT_CAT OFF
+set_global_assignment -name NONSYNCHSTRUCT_RULE_COMBLOOP OFF
+set_global_assignment -name NONSYNCHSTRUCT_RULE_REG_LOOP OFF
+set_global_assignment -name NONSYNCHSTRUCT_RULE_DELAY_CHAIN OFF
+set_global_assignment -name NONSYNCHSTRUCT_RULE_RIPPLE_CLK OFF
+set_global_assignment -name NONSYNCHSTRUCT_RULE_ILLEGAL_PULSE_GEN OFF
+set_global_assignment -name NONSYNCHSTRUCT_RULE_MULTI_VIBRATOR OFF
+set_global_assignment -name NONSYNCHSTRUCT_RULE_SRLATCH OFF
+set_global_assignment -name NONSYNCHSTRUCT_RULE_LATCH_UNIDENTIFIED OFF
+set_global_assignment -name SIGNALRACE_CAT OFF
+set_global_assignment -name ACLK_CAT OFF
+set_global_assignment -name ACLK_RULE_NO_SZER_ACLK_DOMAIN OFF
+set_global_assignment -name ACLK_RULE_SZER_BTW_ACLK_DOMAIN OFF
+set_global_assignment -name ACLK_RULE_IMSZER_ADOMAIN OFF
+set_global_assignment -name HCPY_CAT OFF
+set_global_assignment -name HCPY_VREF_PINS OFF
+
+# SignalTap II Assignments
+# ========================
+set_global_assignment -name HUB_ENTITY_NAME SLD_HUB
+set_global_assignment -name HUB_INSTANCE_NAME SLD_HUB_INST
+set_global_assignment -name ENABLE_SIGNALTAP Off
+
+# LogicLock Region Assignments
+# ============================
+set_global_assignment -name LOGICLOCK_INCREMENTAL_COMPILE_ASSIGNMENT OFF
+
+# -----------------
+# start CLOCK(SCLK)
+
+       # Timing Assignments
+       # ==================
+set_global_assignment -name DUTY_CYCLE 50 -section_id SCLK
+       set_global_assignment -name FMAX_REQUIREMENT "1.0 MHz" -section_id SCLK
+       set_global_assignment -name INCLUDE_EXTERNAL_PIN_DELAYS_IN_FMAX_CALCULATIONS OFF -section_id SCLK
+
+# end CLOCK(SCLK)
+# ---------------
+
+# -----------------------
+# start CLOCK(master_clk)
+
+       # Timing Assignments
+       # ==================
+set_global_assignment -name DUTY_CYCLE 50 -section_id master_clk
+       set_global_assignment -name FMAX_REQUIREMENT "64.0 MHz" -section_id master_clk
+       set_global_assignment -name INCLUDE_EXTERNAL_PIN_DELAYS_IN_FMAX_CALCULATIONS OFF -section_id master_clk
+
+# end CLOCK(master_clk)
+# ---------------------
+
+# -------------------
+# start CLOCK(usbclk)
+
+       # Timing Assignments
+       # ==================
+set_global_assignment -name DUTY_CYCLE 50 -section_id usbclk
+       set_global_assignment -name FMAX_REQUIREMENT "48.0 MHz" -section_id usbclk
+       set_global_assignment -name INCLUDE_EXTERNAL_PIN_DELAYS_IN_FMAX_CALCULATIONS OFF -section_id usbclk
+
+# end CLOCK(usbclk)
+# -----------------
+
+# ----------------------
+# start ENTITY(usrp_std)
+
+       # Timing Assignments
+       # ==================
+       set_instance_assignment -name CLOCK_SETTINGS SCLK -to SCLK
+       set_instance_assignment -name CLOCK_SETTINGS usbclk -to usbclk
+       set_instance_assignment -name CLOCK_SETTINGS master_clk -to master_clk
+
+# end ENTITY(usrp_std)
+# --------------------
+
+set_global_assignment -name VERILOG_FILE ../../sdr_lib/rssi.v
+set_global_assignment -name VERILOG_FILE ../../sdr_lib/ram16.v
+set_global_assignment -name VERILOG_FILE usrp_std.vh
+set_global_assignment -name VERILOG_FILE ../../megacells/fifo_4k.v
+set_global_assignment -name VERILOG_FILE ../../sdr_lib/hb/acc.v
+set_global_assignment -name VERILOG_FILE ../../sdr_lib/hb/mult.v
+set_global_assignment -name VERILOG_FILE ../../sdr_lib/hb/ram16_2sum.v
+set_global_assignment -name VERILOG_FILE ../../sdr_lib/hb/coeff_rom.v
+set_global_assignment -name VERILOG_FILE ../../sdr_lib/hb/halfband_decim.v
+set_global_assignment -name VERILOG_FILE ../../sdr_lib/hb/mac.v
+set_global_assignment -name VERILOG_FILE ../../sdr_lib/hb/coeff_ram.v
+set_global_assignment -name VERILOG_FILE ../../sdr_lib/tx_chain.v
+set_global_assignment -name VERILOG_FILE ../../sdr_lib/rx_dcoffset.v
+set_global_assignment -name VERILOG_FILE ../../sdr_lib/adc_interface.v
+set_global_assignment -name VERILOG_FILE ../../sdr_lib/io_pins.v
+set_global_assignment -name VERILOG_FILE ../../sdr_lib/setting_reg.v
+set_global_assignment -name VERILOG_FILE ../../sdr_lib/bidir_reg.v
+set_global_assignment -name VERILOG_FILE ../../sdr_lib/cic_int_shifter.v
+set_global_assignment -name VERILOG_FILE ../../megacells/clk_doubler.v
+set_global_assignment -name VERILOG_FILE ../../sdr_lib/rx_chain.v
+set_global_assignment -name VERILOG_FILE ../../sdr_lib/gen_sync.v
+set_global_assignment -name VERILOG_FILE ../../sdr_lib/master_control.v
+set_global_assignment -name VERILOG_FILE ../../megacells/fifo_2k.v
+set_global_assignment -name VERILOG_FILE ../../megacells/bustri.v
+set_global_assignment -name VERILOG_FILE ../../sdr_lib/rx_buffer.v
+set_global_assignment -name VERILOG_FILE ../../sdr_lib/tx_buffer.v
+set_global_assignment -name VERILOG_FILE ../../sdr_lib/phase_acc.v
+set_global_assignment -name VERILOG_FILE ../../sdr_lib/cic_interp.v
+set_global_assignment -name VERILOG_FILE ../../sdr_lib/cic_decim.v
+set_global_assignment -name VERILOG_FILE ../../sdr_lib/cordic_stage.v
+set_global_assignment -name VERILOG_FILE ../../sdr_lib/cordic.v
+set_global_assignment -name VERILOG_FILE usrp_std.v
+set_global_assignment -name VERILOG_FILE ../../sdr_lib/clk_divider.v
+set_global_assignment -name VERILOG_FILE ../../sdr_lib/serial_io.v
+set_global_assignment -name VERILOG_FILE ../../sdr_lib/strobe_gen.v
+set_global_assignment -name VERILOG_FILE ../../sdr_lib/sign_extend.v
\ No newline at end of file
diff --git a/usrp/fpga/toplevel/usrp_std/usrp_std.v b/usrp/fpga/toplevel/usrp_std/usrp_std.v
new file mode 100644 (file)
index 0000000..9ba8c7c
--- /dev/null
@@ -0,0 +1,324 @@
+// -*- verilog -*-
+//
+//  USRP - Universal Software Radio Peripheral
+//
+//  Copyright (C) 2003,2004 Matt Ettus
+//
+//  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
+//
+
+// Top level module for a full setup with DUCs and DDCs
+
+// Define DEBUG_OWNS_IO_PINS if we're using the daughterboard i/o pins
+// for debugging info.  NB, This can kill the m'board and/or d'board if you
+// have anything except basic d'boards installed.
+
+// Uncomment the following to include optional circuitry
+
+`include "usrp_std.vh"
+`include "../../../firmware/include/fpga_regs_common.v"
+`include "../../../firmware/include/fpga_regs_standard.v"
+
+module usrp_std
+(output MYSTERY_SIGNAL,
+ input master_clk,
+ input SCLK,
+ input SDI,
+ inout SDO,
+ input SEN_FPGA,
+
+ input FX2_1,
+ output FX2_2,
+ output FX2_3,
+ input wire [11:0] rx_a_a,
+ input wire [11:0] rx_b_a,
+ input wire [11:0] rx_a_b,
+ input wire [11:0] rx_b_b,
+
+ output wire [13:0] tx_a,
+ output wire [13:0] tx_b,
+
+ output wire TXSYNC_A,
+ output wire TXSYNC_B,
+  // USB interface
+ input usbclk,
+ input wire [2:0] usbctl,
+ output wire [1:0] usbrdy,
+ inout [15:0] usbdata,  // NB Careful, inout
+
+ // These are the general purpose i/o's that go to the daughterboard slots
+ inout wire [15:0] io_tx_a,
+ inout wire [15:0] io_tx_b,
+ inout wire [15:0] io_rx_a,
+ inout wire [15:0] io_rx_b
+ );    
+   wire [15:0] debugdata,debugctrl;
+   assign MYSTERY_SIGNAL = 1'b0;
+   
+   wire clk64,clk128;
+   
+   wire WR = usbctl[0];
+   wire RD = usbctl[1];
+   wire OE = usbctl[2];
+
+   wire have_space, have_pkt_rdy;
+   assign usbrdy[0] = have_space;
+   assign usbrdy[1] = have_pkt_rdy;
+
+   wire   tx_underrun, rx_overrun;    
+   wire   clear_status = FX2_1;
+   assign FX2_2 = rx_overrun;
+   assign FX2_3 = tx_underrun;
+      
+   wire [15:0] usbdata_out;
+   
+   wire [3:0]  dac0mux,dac1mux,dac2mux,dac3mux;
+   
+   wire        tx_realsignals;
+   wire [3:0]  rx_numchan;
+   wire [2:0]  tx_numchan;
+   
+   wire [7:0]  interp_rate, decim_rate;
+   wire [15:0] tx_debugbus, rx_debugbus;
+   
+   wire        enable_tx, enable_rx;
+   wire        tx_dsp_reset, rx_dsp_reset, tx_bus_reset, rx_bus_reset;
+   wire [7:0]  settings;
+   
+   // Tri-state bus macro
+   bustri bustri( .data(usbdata_out),.enabledt(OE),.tridata(usbdata) );
+
+   assign      clk64 = master_clk;
+
+   wire [15:0] ch0tx,ch1tx,ch2tx,ch3tx; //,ch4tx,ch5tx,ch6tx,ch7tx;
+   wire [15:0] ch0rx,ch1rx,ch2rx,ch3rx,ch4rx,ch5rx,ch6rx,ch7rx;
+   
+   // TX
+   wire [15:0] i_out_0,i_out_1,q_out_0,q_out_1;
+   wire [15:0] bb_tx_i0,bb_tx_q0,bb_tx_i1,bb_tx_q1;  // bb_tx_i2,bb_tx_q2,bb_tx_i3,bb_tx_q3;
+   
+   wire        strobe_interp, tx_sample_strobe;
+   wire        tx_empty;
+   
+   wire        serial_strobe;
+   wire [6:0]  serial_addr;
+   wire [31:0] serial_data;
+
+   reg [15:0] debug_counter;
+   reg [15:0] loopback_i_0,loopback_q_0;
+   
+   ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+   // Transmit Side
+`ifdef TX_ON
+   assign     bb_tx_i0 = ch0tx;
+   assign      bb_tx_q0 = ch1tx;
+   assign      bb_tx_i1 = ch2tx;
+   assign      bb_tx_q1 = ch3tx;
+   
+   tx_buffer tx_buffer
+     ( .usbclk(usbclk),.bus_reset(tx_bus_reset),.reset(tx_dsp_reset),
+       .usbdata(usbdata),.WR(WR),.have_space(have_space),.tx_underrun(tx_underrun),
+       .channels({tx_numchan,1'b0}),
+       .tx_i_0(ch0tx),.tx_q_0(ch1tx),
+       .tx_i_1(ch2tx),.tx_q_1(ch3tx),
+       .tx_i_2(),.tx_q_2(),
+       .tx_i_3(),.tx_q_3(),
+       .txclk(clk64),.txstrobe(strobe_interp),
+       .clear_status(clear_status),
+       .tx_empty(tx_empty),
+       .debugbus(tx_debugbus) );
+
+   tx_chain tx_chain_0
+     ( .clock(clk64),.reset(tx_dsp_reset),.enable(enable_tx),
+       .interp_rate(interp_rate),.sample_strobe(tx_sample_strobe),
+       .interpolator_strobe(strobe_interp),.freq(),
+       .i_in(bb_tx_i0),.q_in(bb_tx_q0),.i_out(i_out_0),.q_out(q_out_0) );
+
+   tx_chain tx_chain_1
+     ( .clock(clk64),.reset(tx_dsp_reset),.enable(enable_tx),
+       .interp_rate(interp_rate),.sample_strobe(tx_sample_strobe),
+       .interpolator_strobe(strobe_interp),.freq(),
+       .i_in(bb_tx_i1),.q_in(bb_tx_q1),.i_out(i_out_1),.q_out(q_out_1) );
+
+   setting_reg #(`FR_TX_MUX) 
+     sr_txmux(.clock(clk64),.reset(tx_dsp_reset),.strobe(serial_strobe),.addr(serial_addr),.in(serial_data),
+             .out({dac3mux,dac2mux,dac1mux,dac0mux,tx_realsignals,tx_numchan}));
+   
+   wire [15:0] tx_a_a = dac0mux[3] ? (dac0mux[1] ? (dac0mux[0] ? q_out_1 : i_out_1) : (dac0mux[0] ? q_out_0 : i_out_0)) : 16'b0;
+   wire [15:0] tx_b_a = dac1mux[3] ? (dac1mux[1] ? (dac1mux[0] ? q_out_1 : i_out_1) : (dac1mux[0] ? q_out_0 : i_out_0)) : 16'b0;
+   wire [15:0] tx_a_b = dac2mux[3] ? (dac2mux[1] ? (dac2mux[0] ? q_out_1 : i_out_1) : (dac2mux[0] ? q_out_0 : i_out_0)) : 16'b0;
+   wire [15:0] tx_b_b = dac3mux[3] ? (dac3mux[1] ? (dac3mux[0] ? q_out_1 : i_out_1) : (dac3mux[0] ? q_out_0 : i_out_0)) : 16'b0;
+
+   wire txsync = tx_sample_strobe;
+   assign TXSYNC_A = txsync;
+   assign TXSYNC_B = txsync;
+
+   assign tx_a = txsync ? tx_b_a[15:2] : tx_a_a[15:2];
+   assign tx_b = txsync ? tx_b_b[15:2] : tx_a_b[15:2];
+`endif //  `ifdef TX_ON
+   
+   /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+   // Receive Side
+`ifdef RX_ON
+   wire        rx_sample_strobe,strobe_decim,hb_strobe;
+   wire [15:0] bb_rx_i0,bb_rx_q0,bb_rx_i1,bb_rx_q1,
+              bb_rx_i2,bb_rx_q2,bb_rx_i3,bb_rx_q3;
+
+   wire loopback = settings[0];
+   wire counter = settings[1];
+
+   always @(posedge clk64)
+     if(rx_dsp_reset)
+       debug_counter <= #1 16'd0;
+     else if(~enable_rx)
+       debug_counter <= #1 16'd0;
+     else if(hb_strobe)
+       debug_counter <=#1 debug_counter + 16'd2;
+   
+   always @(posedge clk64)
+     if(strobe_interp)
+       begin
+         loopback_i_0 <= #1 ch0tx;
+         loopback_q_0 <= #1 ch1tx;
+       end
+   
+   assign ch0rx = counter ? debug_counter : loopback ? loopback_i_0 : bb_rx_i0;
+   assign ch1rx = counter ? debug_counter + 16'd1 : loopback ? loopback_q_0 : bb_rx_q0;
+   assign ch2rx = bb_rx_i1;
+   assign ch3rx = bb_rx_q1;
+   assign ch4rx = bb_rx_i2;
+   assign ch5rx = bb_rx_q2;
+   assign ch6rx = bb_rx_i3;
+   assign ch7rx = bb_rx_q3;
+
+   wire [15:0] ddc0_in_i,ddc0_in_q,ddc1_in_i,ddc1_in_q,ddc2_in_i,ddc2_in_q,ddc3_in_i,ddc3_in_q;
+   wire [31:0] rssi_0,rssi_1,rssi_2,rssi_3;
+   
+   adc_interface adc_interface(.clock(clk64),.reset(rx_dsp_reset),.enable(1'b1),
+                              .serial_addr(serial_addr),.serial_data(serial_data),.serial_strobe(serial_strobe),
+                              .rx_a_a(rx_a_a),.rx_b_a(rx_b_a),.rx_a_b(rx_a_b),.rx_b_b(rx_b_b),
+                              .rssi_0(rssi_0),.rssi_1(rssi_1),.rssi_2(rssi_2),.rssi_3(rssi_3),
+                              .ddc0_in_i(ddc0_in_i),.ddc0_in_q(ddc0_in_q),
+                              .ddc1_in_i(ddc1_in_i),.ddc1_in_q(ddc1_in_q),
+                              .ddc2_in_i(ddc2_in_i),.ddc2_in_q(ddc2_in_q),
+                              .ddc3_in_i(ddc3_in_i),.ddc3_in_q(ddc3_in_q),.rx_numchan(rx_numchan) );
+   
+   rx_buffer rx_buffer
+     ( .usbclk(usbclk),.bus_reset(rx_bus_reset),.reset(rx_dsp_reset),
+       .reset_regs(rx_dsp_reset),
+       .usbdata(usbdata_out),.RD(RD),.have_pkt_rdy(have_pkt_rdy),.rx_overrun(rx_overrun),
+       .channels(rx_numchan),
+       .ch_0(ch0rx),.ch_1(ch1rx),
+       .ch_2(ch2rx),.ch_3(ch3rx),
+       .ch_4(ch4rx),.ch_5(ch5rx),
+       .ch_6(ch6rx),.ch_7(ch7rx),
+       .rxclk(clk64),.rxstrobe(hb_strobe),
+       .clear_status(clear_status),
+       .serial_addr(serial_addr),.serial_data(serial_data),.serial_strobe(serial_strobe),
+       .debugbus(rx_debugbus) );
+   
+ `ifdef RX_EN_0
+   rx_chain #(`FR_RX_FREQ_0,`FR_RX_PHASE_0) rx_chain_0
+     ( .clock(clk64),.reset(1'b0),.enable(enable_rx),
+       .decim_rate(decim_rate),.sample_strobe(rx_sample_strobe),.decimator_strobe(strobe_decim),.hb_strobe(hb_strobe),
+       .serial_addr(serial_addr),.serial_data(serial_data),.serial_strobe(serial_strobe),
+       .i_in(ddc0_in_i),.q_in(ddc0_in_q),.i_out(bb_rx_i0),.q_out(bb_rx_q0),.debugdata(debugdata),.debugctrl(debugctrl));
+ `else
+   assign      bb_rx_i0=16'd0;
+   assign      bb_rx_q0=16'd0;
+ `endif
+   
+ `ifdef RX_EN_1
+   rx_chain #(`FR_RX_FREQ_1,`FR_RX_PHASE_1) rx_chain_1
+     ( .clock(clk64),.reset(1'b0),.enable(enable_rx),
+       .decim_rate(decim_rate),.sample_strobe(rx_sample_strobe),.decimator_strobe(strobe_decim),.hb_strobe(),
+       .serial_addr(serial_addr),.serial_data(serial_data),.serial_strobe(serial_strobe),
+       .i_in(ddc1_in_i),.q_in(ddc1_in_q),.i_out(bb_rx_i1),.q_out(bb_rx_q1));
+ `else
+   assign      bb_rx_i1=16'd0;
+   assign      bb_rx_q1=16'd0;
+ `endif
+   
+ `ifdef RX_EN_2
+   rx_chain #(`FR_RX_FREQ_2,`FR_RX_PHASE_2) rx_chain_2
+     ( .clock(clk64),.reset(1'b0),.enable(enable_rx),
+       .decim_rate(decim_rate),.sample_strobe(rx_sample_strobe),.decimator_strobe(strobe_decim),.hb_strobe(),
+       .serial_addr(serial_addr),.serial_data(serial_data),.serial_strobe(serial_strobe),
+       .i_in(ddc2_in_i),.q_in(ddc2_in_q),.i_out(bb_rx_i2),.q_out(bb_rx_q2));
+ `else
+   assign      bb_rx_i2=16'd0;
+   assign      bb_rx_q2=16'd0;
+ `endif
+
+ `ifdef RX_EN_3
+   rx_chain #(`FR_RX_FREQ_3,`FR_RX_PHASE_3) rx_chain_3
+     ( .clock(clk64),.reset(1'b0),.enable(enable_rx),
+       .decim_rate(decim_rate),.sample_strobe(rx_sample_strobe),.decimator_strobe(strobe_decim),.hb_strobe(),
+       .serial_addr(serial_addr),.serial_data(serial_data),.serial_strobe(serial_strobe),
+       .i_in(ddc3_in_i),.q_in(ddc3_in_q),.i_out(bb_rx_i3),.q_out(bb_rx_q3));
+ `else
+   assign      bb_rx_i3=16'd0;
+   assign      bb_rx_q3=16'd0;
+ `endif
+
+`endif //  `ifdef RX_ON
+   
+   ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+   // Control Functions
+
+   wire [31:0] capabilities;
+   assign      capabilities[7] =   `TX_CAP_HB;
+   assign      capabilities[6:4] = `TX_CAP_NCHAN;
+   assign      capabilities[3] =   `RX_CAP_HB;
+   assign      capabilities[2:0] = `RX_CAP_NCHAN;
+
+
+   serial_io serial_io
+     ( .master_clk(clk64),.serial_clock(SCLK),.serial_data_in(SDI),
+       .enable(SEN_FPGA),.reset(1'b0),.serial_data_out(SDO),
+       .serial_addr(serial_addr),.serial_data(serial_data),.serial_strobe(serial_strobe),
+       .readback_0({io_rx_a,io_tx_a}),.readback_1({io_rx_b,io_tx_b}),.readback_2(capabilities),.readback_3(32'hf0f0931a),
+       .readback_4(rssi_0),.readback_5(rssi_1),.readback_6(rssi_2),.readback_7(rssi_3)
+       );
+
+   wire [15:0] reg_0,reg_1,reg_2,reg_3;
+   master_control master_control
+     ( .master_clk(clk64),.usbclk(usbclk),
+       .serial_addr(serial_addr),.serial_data(serial_data),.serial_strobe(serial_strobe),
+       .tx_bus_reset(tx_bus_reset),.rx_bus_reset(rx_bus_reset),
+       .tx_dsp_reset(tx_dsp_reset),.rx_dsp_reset(rx_dsp_reset),
+       .enable_tx(enable_tx),.enable_rx(enable_rx),
+       .interp_rate(interp_rate),.decim_rate(decim_rate),
+       .tx_sample_strobe(tx_sample_strobe),.strobe_interp(strobe_interp),
+       .rx_sample_strobe(rx_sample_strobe),.strobe_decim(strobe_decim),
+       .tx_empty(tx_empty),
+       //.debug_0(rx_a_a),.debug_1(ddc0_in_i),
+       .debug_0(rx_debugbus),.debug_1(ddc0_in_i),
+       .debug_2({rx_sample_strobe,strobe_decim,serial_strobe,serial_addr}),.debug_3({rx_dsp_reset,tx_dsp_reset,rx_bus_reset,tx_bus_reset,enable_rx,tx_underrun,rx_overrun,decim_rate}),
+       .reg_0(reg_0),.reg_1(reg_1),.reg_2(reg_2),.reg_3(reg_3) );
+   
+   io_pins io_pins
+     (.io_0(io_tx_a),.io_1(io_rx_a),.io_2(io_tx_b),.io_3(io_rx_b),
+      .reg_0(reg_0),.reg_1(reg_1),.reg_2(reg_2),.reg_3(reg_3),
+      .clock(clk64),.rx_reset(rx_dsp_reset),.tx_reset(tx_dsp_reset),
+      .serial_addr(serial_addr),.serial_data(serial_data),.serial_strobe(serial_strobe));
+   
+   ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+   // Misc Settings
+   setting_reg #(`FR_MODE) sr_misc(.clock(clk64),.reset(rx_dsp_reset),.strobe(serial_strobe),.addr(serial_addr),.in(serial_data),.out(settings));
+
+endmodule // usrp_std
diff --git a/usrp/fpga/toplevel/usrp_std/usrp_std.vh b/usrp/fpga/toplevel/usrp_std/usrp_std.vh
new file mode 100644 (file)
index 0000000..65aed9b
--- /dev/null
@@ -0,0 +1,119 @@
+// -*- verilog -*-
+//
+//  USRP - Universal Software Radio Peripheral
+//
+//  Copyright (C) 2006 Matt Ettus
+//
+//  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
+//
+
+// ====================================================================
+//            User control over what parts get included
+//
+//                  >>>> EDIT ONLY THIS SECTION <<<<
+//
+// ====================================================================
+
+// Uncomment this for 2 rx channels (w/ halfband) & 2 transmit channels
+  `include "usrp_std_config_2rxhb_2tx.vh"
+
+// Uncomment this for 4 rx channels (w/o halfband) & 0 transmit channels
+//`include "usrp_std_config_4rx_0tx.vh"
+
+// Add other "known to fit" configurations here...
+
+// ====================================================================
+// 
+//                  >>>> DO NOT EDIT BELOW HERE <<<<
+//
+// [The stuff from here down is derived from the stuff included above]
+//
+// N.B., *all* the remainder of the code should be conditionalized
+// only in terms of:
+//
+//  TX_ON, TX_EN_0, TX_EN_1, TX_EN_2, TX_EN_3, TX_CAP_NCHAN, TX_CAP_HB,
+//  RX_ON, RX_EN_0, RX_EN_1, RX_EN_2, RX_EN_3, RX_CAP_NCHAN, RX_CAP_HB,
+//  RX_NCO_ON, RX_CIC_ON
+// ====================================================================
+
+`ifdef TX_ON
+
+ `ifdef TX_SINGLE
+  `define TX_EN_0
+  `define TX_CAP_NCHAN 3'd1
+ `endif
+
+ `ifdef TX_DUAL
+  `define TX_EN_0
+  `define TX_EN_1
+  `define TX_CAP_NCHAN 3'd2
+ `endif
+
+ `ifdef TX_QUAD
+  `define TX_EN_0
+  `define TX_EN_1
+  `define TX_EN_2
+  `define TX_EN_3
+  `define TX_CAP_NCHAN 3'd4
+ `endif
+
+ `ifdef TX_HB_ON
+  `define TX_CAP_HB   1
+ `else
+  `define TX_CAP_HB   0
+ `endif
+
+`else  // !ifdef TX_ON
+
+ `define TX_CAP_NCHAN 3'd0
+ `define TX_CAP_HB 0
+
+`endif // !ifdef TX_ON
+
+// --------------------------------------------------------------------
+
+`ifdef RX_ON
+
+ `ifdef RX_SINGLE
+  `define RX_EN_0
+  `define RX_CAP_NCHAN 3'd1
+ `endif
+
+ `ifdef RX_DUAL
+  `define RX_EN_0
+  `define RX_EN_1
+  `define RX_CAP_NCHAN 3'd2
+ `endif
+
+ `ifdef RX_QUAD
+  `define RX_EN_0
+  `define RX_EN_1
+  `define RX_EN_2
+  `define RX_EN_3
+  `define RX_CAP_NCHAN 3'd4
+ `endif
+
+ `ifdef RX_HB_ON
+  `define RX_CAP_HB   1
+ `else
+  `define RX_CAP_HB   0
+ `endif
+
+`else  // !ifdef RX_ON
+
+ `define RX_CAP_NCHAN 3'd0
+ `define RX_CAP_HB 0
+
+`endif // !ifdef RX_ON
diff --git a/usrp/fpga/toplevel/usrp_std/usrp_std_config_2rxhb_2tx.vh b/usrp/fpga/toplevel/usrp_std/usrp_std_config_2rxhb_2tx.vh
new file mode 100644 (file)
index 0000000..74f1bfd
--- /dev/null
@@ -0,0 +1,61 @@
+// -*- verilog -*-
+//
+//  USRP - Universal Software Radio Peripheral
+//
+//  Copyright (C) 2006 Matt Ettus
+//
+//  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
+//
+
+// ------------------------------------------------------------
+// If TX_ON is not defined, there is *no* transmit circuitry built
+  `define TX_ON
+
+// ------------------------------------------------------------
+// Define 1 and only one of TX_SINGLE, TX_DUAL and TX_QUAD
+// to respectively enable 1, 2 or 4 transmit channels.
+// [Please note that only TX_DUAL is currently valid]
+//`define TX_SINGLE
+  `define TX_DUAL
+//`define TX_QUAD
+
+// ------------------------------------------------------------
+// Define TX_HB_ON to enable the transmit halfband filter
+// [Not implemented]
+//`define TX_HB_ON
+
+// ------------------------------------------------------------
+// IF RX_ON is not defined, there is *no* transmit circuitry built
+  `define RX_ON
+
+// ------------------------------------------------------------
+// Define 1 and only one of RX_SINGLE, RX_DUAL and RX_QUAD
+// to respectively define 1, 2 or 4 receive channels.
+
+//`define RX_SINGLE
+  `define RX_DUAL
+//`define RX_QUAD
+
+// ------------------------------------------------------------
+// Define RX_HB_ON to enable the receive halfband filter
+  `define RX_HB_ON
+
+// ------------------------------------------------------------
+// Define RX_NCO_ON to enable the receive Numerical Controlled Osc
+  `define RX_NCO_ON
+
+// ------------------------------------------------------------
+// Define RX_CIC_ON to enable the receive Cascaded Integrator Comb filter
+  `define RX_CIC_ON
diff --git a/usrp/fpga/toplevel/usrp_std/usrp_std_config_4rx_0tx.vh b/usrp/fpga/toplevel/usrp_std/usrp_std_config_4rx_0tx.vh
new file mode 100644 (file)
index 0000000..0bd1887
--- /dev/null
@@ -0,0 +1,61 @@
+// -*- verilog -*-
+//
+//  USRP - Universal Software Radio Peripheral
+//
+//  Copyright (C) 2006 Matt Ettus
+//
+//  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
+//
+
+// ------------------------------------------------------------
+// If TX_ON is not defined, there is *no* transmit circuitry built
+// `define TX_ON
+
+// ------------------------------------------------------------
+// Define 1 and only one of TX_SINGLE, TX_DUAL and TX_QUAD
+// to respectively enable 1, 2 or 4 transmit channels.
+// [Please note that only TX_DUAL is currently valid]
+//`define TX_SINGLE
+//`define TX_DUAL
+//`define TX_QUAD
+
+// ------------------------------------------------------------
+// Define TX_HB_ON to enable the transmit halfband filter
+// [Not implemented]
+//`define TX_HB_ON
+
+// ------------------------------------------------------------
+// IF RX_ON is not defined, there is *no* transmit circuitry built
+  `define RX_ON
+
+// ------------------------------------------------------------
+// Define 1 and only one of RX_SINGLE, RX_DUAL and RX_QUAD
+// to respectively define 1, 2 or 4 receive channels.
+
+//`define RX_SINGLE
+//`define RX_DUAL
+  `define RX_QUAD
+
+// ------------------------------------------------------------
+// Define RX_HB_ON to enable the receive halfband filter
+//`define RX_HB_ON
+
+// ------------------------------------------------------------
+// Define RX_NCO_ON to enable the receive Numerical Controlled Osc
+  `define RX_NCO_ON
+
+// ------------------------------------------------------------
+// Define RX_CIC_ON to enable the receive Cascaded Integrator Comb filter
+  `define RX_CIC_ON
diff --git a/usrp/host/Makefile.am b/usrp/host/Makefile.am
new file mode 100644 (file)
index 0000000..05ba517
--- /dev/null
@@ -0,0 +1,23 @@
+#
+# 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 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.
+# 
+
+SUBDIRS = misc lib swig apps
+
diff --git a/usrp/host/apps/Makefile.am b/usrp/host/apps/Makefile.am
new file mode 100644 (file)
index 0000000..b08e325
--- /dev/null
@@ -0,0 +1,53 @@
+#
+# 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 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.
+# 
+
+INCLUDES = -I../lib -I$(top_srcdir)/usrp/firmware/include
+
+bin_PROGRAMS =                         \
+       usrper                          \
+       usrp_cal_dc_offset              
+
+noinst_PROGRAMS =                      \
+       check_order_quickly             \
+       test_usrp_standard_rx           \
+       test_usrp_standard_tx           
+
+noinst_HEADERS =                       \
+       time_stuff.h
+
+noinst_PYTHON =                                \
+       burn-db-eeprom                  \
+       burn-serial-number              
+
+
+check_order_quickly_SOURCES    = check_order_quickly.cc
+
+test_usrp_standard_rx_SOURCES  = test_usrp_standard_rx.cc time_stuff.c
+test_usrp_standard_rx_LDADD    = $(top_builddir)/usrp/host/lib/libusrp.la
+
+test_usrp_standard_tx_SOURCES  = test_usrp_standard_tx.cc time_stuff.c
+test_usrp_standard_tx_LDADD    = $(top_builddir)/usrp/host/lib/libusrp.la
+
+usrper_SOURCES                 = usrper.cc
+usrper_LDADD                   = $(top_builddir)/usrp/host/lib/libusrp.la
+
+usrp_cal_dc_offset_SOURCES     = usrp_cal_dc_offset.cc
+usrp_cal_dc_offset_LDADD       = $(top_builddir)/usrp/host/lib/libusrp.la
diff --git a/usrp/host/apps/burn-db-eeprom b/usrp/host/apps/burn-db-eeprom
new file mode 100755 (executable)
index 0000000..e7c92eb
--- /dev/null
@@ -0,0 +1,164 @@
+#!/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 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.
+# 
+
+from usrp_prims import *
+from optparse import OptionParser
+import sys
+from usrp_dbid import *
+
+i2c_addr_map = { 'TX_A' : 0x54,    'RX_A' : 0x55,    'TX_B' : 0x56,    'RX_B' : 0x57 }
+
+daughterboards = {
+    # name            : ((tx-dbid, tx-oe),          (rx-dbid, rx-oe))
+    'basictx'         : ((BASIC_TX, 0x0000),        None),
+    'basicrx'         : (None,                      (BASIC_RX, 0x0000)),
+    'dbsrx'           : (None,                      (DBS_RX, 0x0000)),
+    'dbsrx2'          : (None,                      (DBS_RX_REV_2_1, 0x0000)),
+    'tvrx'            : (None,                      (TV_RX, 0x0000)),
+    'tvrx2'           : (None,                      (TV_RX_REV_2, 0x0000)),
+    'tvrx3'           : (None,                      (TV_RX_REV_3, 0x0000)),
+    'rfx400'          : ((FLEX_400_TX, 0x0000),     (FLEX_400_RX, 0x0000)),
+    'rfx900'          : ((FLEX_900_TX, 0x0000),     (FLEX_900_RX, 0x0000)),
+    'rfx1200'         : ((FLEX_1200_TX, 0x0000),    (FLEX_1200_RX, 0x0000)),
+    'rfx1800'         : ((FLEX_1800_TX, 0x0000),    (FLEX_1800_RX, 0x0000)),
+    'rfx2400'         : ((FLEX_2400_TX, 0x0000),    (FLEX_2400_RX, 0x0000)),
+    'rfx400_tx'       : ((FLEX_400_TX, 0x0000),     None),
+    'rfx900_tx'       : ((FLEX_900_TX, 0x0000),     None),
+    'rfx1200_tx'      : ((FLEX_1200_TX, 0x0000),    None),
+    'rfx1800_tx'      : ((FLEX_1800_TX, 0x0000),    None),
+    'rfx2400_tx'      : ((FLEX_2400_TX, 0x0000),    None),
+    'rfx400_rx'       : (None,                      (FLEX_400_RX, 0x0000)),
+    'rfx900_rx'       : (None,                      (FLEX_900_RX, 0x0000)),
+    'rfx1200_rx'      : (None,                      (FLEX_1200_RX, 0x0000)),
+    'rfx1800_rx'      : (None,                      (FLEX_1800_RX, 0x0000)),
+    'rfx2400_rx'      : (None,                      (FLEX_2400_RX, 0x0000)),
+    'rfx400_mimo_a'   : ((FLEX_400_TX_MIMO_A, 0x0000),     (FLEX_400_RX_MIMO_A, 0x0000)),
+    'rfx900_mimo_a'   : ((FLEX_900_TX_MIMO_A, 0x0000),     (FLEX_900_RX_MIMO_A, 0x0000)),
+    'rfx1200_mimo_a'  : ((FLEX_1200_TX_MIMO_A, 0x0000),    (FLEX_1200_RX_MIMO_A, 0x0000)),
+    'rfx1800_mimo_a'  : ((FLEX_1800_TX_MIMO_A, 0x0000),    (FLEX_1800_RX_MIMO_A, 0x0000)),
+    'rfx2400_mimo_a'  : ((FLEX_2400_TX_MIMO_A, 0x0000),    (FLEX_2400_RX_MIMO_A, 0x0000)),
+    'rfx400_mimo_b'   : ((FLEX_400_TX_MIMO_B, 0x0000),     (FLEX_400_RX_MIMO_B, 0x0000)),
+    'rfx900_mimo_b'   : ((FLEX_900_TX_MIMO_B, 0x0000),     (FLEX_900_RX_MIMO_B, 0x0000)),
+    'rfx1200_mimo_b'  : ((FLEX_1200_TX_MIMO_B, 0x0000),    (FLEX_1200_RX_MIMO_B, 0x0000)),
+    'rfx1800_mimo_b'  : ((FLEX_1800_TX_MIMO_B, 0x0000),    (FLEX_1800_RX_MIMO_B, 0x0000)),
+    'rfx2400_mimo_b'  : ((FLEX_2400_TX_MIMO_B, 0x0000),    (FLEX_2400_RX_MIMO_B, 0x0000)),
+    'lftx'            : ((LF_TX, 0x0000),           None),
+    'lfrx'            : (None,                      (LF_RX, 0x0000)),
+    'experimental_tx' : ((EXPERIMENTAL_TX, 0x0000), None),
+    'experimental_rx' : (None,                      (EXPERIMENTAL_RX, 0x0000)),
+    }
+
+def open_cmd_interface(which_board = 0):
+    if not usrp_load_standard_bits (which_board, 0):
+        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"
+    return u
+
+def write_dboard_eeprom(u, i2c_addr, dbid, oe):
+    eeprom = 0x20 * [0]
+    eeprom[0] = 0xDB                    # magic value
+    eeprom[1] = dbid & 0xff
+    eeprom[2] = (dbid >> 8) & 0xff
+    eeprom[3] = oe & 0xff
+    eeprom[4] = (oe >> 8) & 0xff
+    eeprom[0x1f] = 0xff & (-reduce(lambda x, y: x+y, eeprom)) # checksum
+    s = ''.join (map (chr, eeprom))
+    ok = usrp_eeprom_write (u, i2c_addr, 0, s)
+    return ok
+
+
+def init_eeprom(u, slot_name, force, dbid, oe):
+    i2c_addr = i2c_addr_map[slot_name]
+    e = usrp_eeprom_read (u, i2c_addr, 0, 0x20)
+    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
+
+    print "%s: OK" % (slot_name,)
+    return True
+
+
+def init_daughterboard(u, side, type, force):
+    ok = True
+    dbinfo = daughterboards[type]
+    if dbinfo[0] is not None:           # burn tx slot
+        ok &= init_eeprom(u, 'TX_' + side, force, dbinfo[0][0], dbinfo[0][1])
+    if dbinfo[1] is not None:           # burn rx slot
+        ok &= init_eeprom(u, 'RX_' + side, force, dbinfo[1][0], dbinfo[1][1])
+    return ok
+
+
+def main():
+    dbs = daughterboards.keys()
+    dbs.sort()
+    usage = """\
+usage: %prog [options]
+You must specify a type with -t or --type,
+and at least one side using -A and/or -B."""
+
+    parser = OptionParser(usage=usage)
+    parser.add_option ("-t", "--type", type="choice", help="choose type from %r" % (dbs,),
+                       choices=dbs, default=None)
+    parser.add_option ("-A", "--burn-a", action="store_true", default=False,
+                       help="burn eeprom(s) on side A")
+    parser.add_option ("-B", "--burn-b", action="store_true", default=False,
+                       help="burn eeprom(s) on side B")
+    parser.add_option ("-f", "--force", action="store_true", default=False,
+                       help="force init of already initialized eeproms")
+    (options, args) = parser.parse_args ()
+
+    which=[]
+    if options.burn_a:
+        which.append('A')
+    if options.burn_b:
+        which.append('B')
+
+    if len(args) != 0 or len(which) == 0 or options.type is None:
+        parser.print_help()
+        sys.exit (1)
+
+    u = open_cmd_interface (0)
+    ok = True
+    for w in which:
+        ok &= init_daughterboard (u, w, options.type, options.force)
+
+    if ok:
+        sys.exit (0)
+    else:
+        sys.exit (1)
+
+if __name__ == "__main__":
+    main ()
+    
diff --git a/usrp/host/apps/burn-serial-number b/usrp/host/apps/burn-serial-number
new file mode 100755 (executable)
index 0000000..1bf944e
--- /dev/null
@@ -0,0 +1,80 @@
+#!/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 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.
+# 
+
+from usrp_prims import *
+from optparse import OptionParser
+import sys
+import time
+
+
+def open_cmd_interface(which_board = 0):
+    if not usrp_load_standard_bits (which_board, 0):
+        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"
+    return u
+
+
+def write_serial_number_eeprom(u, serial_number):
+    if not str(serial_number):
+        raise TypeError
+
+    i2c_addr = 0x50                 # usrp boot rom
+    serial_number_offset = 248      # offset to serial number
+    serial_number_len = 8           # length of serial number
+
+    lsn = len(serial_number)
+    if lsn > serial_number_len:
+        serial_number = serial_number[0:serial_number_len]
+    if lsn < serial_number_len:
+        serial_number = serial_number + (serial_number_len - lsn) * ' '
+    
+    ok = usrp_eeprom_write (u, i2c_addr, serial_number_offset, serial_number)
+    return ok
+
+
+def main():
+
+    default_serial_number = hex(int(time.time()))[2:]
+    parser = OptionParser()
+    parser.add_option ("-s", "--serial-number", default=default_serial_number,
+                       help="set serial number [default=%default]")
+    (options, args) = parser.parse_args ()
+
+    if len(args) != 0:
+        parser.print_help()
+        sys.exit(1)
+
+    u = open_cmd_interface (0)
+    ok = write_serial_number_eeprom(u, options.serial_number)
+
+    if ok:
+        sys.exit(0)
+    else:
+        sys.exit(1)
+
+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/check_order_quickly.cc b/usrp/host/apps/check_order_quickly.cc
new file mode 100644 (file)
index 0000000..d6ebd2f
--- /dev/null
@@ -0,0 +1,62 @@
+/* -*- 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 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.
+ */
+
+#include <stdio.h>
+
+static bool
+check (int v, int counter, int offset)
+{
+  if ((v & 0x0fff) != counter){
+    fprintf (stdout, "%08x: expected 0x%04x, got 0x%04x\n", offset, counter, v & 0x0fff);
+    return false;
+  }
+
+  if (((v >> 12) & 0xf) != (v & 0xf)){
+    fprintf (stdout, "%08x: bad high bits 0x%04x\n", offset, v);
+    return false;
+  }
+
+  return true;
+}
+
+int
+main (int argc, char **argv)
+{
+  static const int BUFSIZE = 64 * 1024;
+  unsigned short buf[BUFSIZE];
+
+  int  n;
+  int  i;
+  int  counter = 0;
+  int  offset = 0;
+  bool  ok = true;
+
+  while ((n = fread (buf, sizeof (short), BUFSIZE, stdin)) != 0){
+    for (i = 0; i < n; i++){
+      ok &= check (buf[i], counter, offset);
+      counter = (counter + 1) & 0x0fff;
+      offset++;
+    }
+  }
+
+  return ok ? 0 : 1;
+}
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/print-db b/usrp/host/apps/print-db
new file mode 100755 (executable)
index 0000000..b741969
--- /dev/null
@@ -0,0 +1,19 @@
+#!/usr/bin/env python
+
+from gnuradio import gr
+from gnuradio import usrp
+from optparse import OptionParser
+import usrp_dbid
+
+u_source = usrp.source_c()
+u_sink = usrp.sink_c()
+subdev_Ar = usrp.selected_subdev(u_source, (0,0))
+subdev_Br = usrp.selected_subdev(u_source, (1,0))
+subdev_At = usrp.selected_subdev(u_sink, (0,0))
+subdev_Bt = usrp.selected_subdev(u_sink, (1,0))
+
+print "RX d'board %s" % (subdev_Ar.side_and_name(),)
+print "RX d'board %s" % (subdev_Br.side_and_name(),)
+print "TX d'board %s" % (subdev_At.side_and_name(),)
+print "TX d'board %s" % (subdev_Bt.side_and_name(),)
+
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
+
diff --git a/usrp/host/apps/test_usrp_standard_rx.cc b/usrp/host/apps/test_usrp_standard_rx.cc
new file mode 100644 (file)
index 0000000..d19b6a6
--- /dev/null
@@ -0,0 +1,276 @@
+/* -*- 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 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.
+ */
+
+#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 <math.h>
+#include "time_stuff.h"
+#include "usrp_standard.h"
+#include "usrp_bytesex.h"
+#include "fpga_regs_common.h"
+#include "fpga_regs_standard.h"
+
+#ifdef HAVE_SCHED_H
+#include <sched.h>
+#endif
+
+char *prog_name;
+
+static bool test_input  (usrp_standard_rx *urx, int max_bytes, FILE *fp);
+
+static void
+set_progname (char *path)
+{
+  char *p = strrchr (path, '/');
+  if (p != 0)
+    prog_name = p+1;
+  else
+    prog_name = path;
+}
+
+static void
+usage ()
+{
+  fprintf (stderr, "usage: %s [-f] [-v] [-l] [-c] [-D <decim>] [-F freq] [-o output_file]\n", prog_name);
+  fprintf (stderr, "  [-f] loop forever\n");
+  fprintf (stderr, "  [-M] how many Megabytes to transfer (default 128)\n");
+  fprintf (stderr, "  [-v] verbose\n");
+  fprintf (stderr, "  [-l] digital loopback in FPGA\n");
+  fprintf (stderr, "  [-c] counting in FPGA\n");
+  fprintf (stderr, "  [-8] 8-bit samples across USB\n");
+  fprintf (stderr, "  [-B <fusb_block_size>] set fast usb block_size\n");
+  fprintf (stderr, "  [-N <fusb_nblocks>] set fast usb nblocks\n");
+  fprintf (stderr, "  [-R] set real time scheduling: SCHED_FIFO; pri = midpoint\n");
+
+  exit (1);
+}
+
+static void
+die (const char *msg)
+{
+  fprintf (stderr, "die: %s: %s\n", prog_name, msg);
+  exit (1);
+}
+
+int
+main (int argc, char **argv)
+{
+  bool         verbose_p = false;
+  bool loopback_p = false;
+  bool  counting_p = false;
+  bool width_8_p = false;
+  int   max_bytes = 128 * (1L << 20);
+  int  ch;
+  char *output_filename = 0;
+  int  which_board = 0;
+  int  decim = 8;                      // 32 MB/sec
+  double       center_freq = 0;
+  int  fusb_block_size = 0;
+  int  fusb_nblocks = 0;
+  bool realtime_p = false;
+
+
+  set_progname (argv[0]);
+
+  while ((ch = getopt (argc, argv, "fvlco:D:F:M:8B:N:R")) != EOF){
+    switch (ch){
+    case 'f':
+      max_bytes = 0;
+      break;
+
+    case 'v':
+      verbose_p = true;
+      break;
+
+    case 'l':
+      loopback_p = true;
+      break;
+
+    case 'c':
+      counting_p = true;
+      break;
+      
+    case '8':
+      width_8_p = true;
+      break;
+      
+    case 'o':
+      output_filename = optarg;
+      break;
+      
+    case 'D':
+      decim = strtol (optarg, 0, 0);
+      break;
+
+    case 'F':
+      center_freq = strtod (optarg, 0);
+      break;
+
+    case 'M':
+      max_bytes = strtol (optarg, 0, 0) * (1L << 20);
+      if (max_bytes < 0) max_bytes = 0;
+      break;
+
+    case 'B':
+      fusb_block_size = strtol (optarg, 0, 0);
+      break;
+
+    case 'N':
+      fusb_nblocks = strtol (optarg, 0, 0);
+      break;
+
+    case 'R':
+      realtime_p = true;
+      break;
+
+    default:
+      usage ();
+    }
+  }
+
+#ifdef HAVE_SCHED_SETSCHEDULER
+  if (realtime_p){
+    int policy = SCHED_FIFO;
+    int pri = (sched_get_priority_max (policy) - sched_get_priority_min (policy)) / 2;
+    int pid = 0;  // this process
+
+    struct sched_param param;
+    memset(&param, 0, sizeof(param));
+    param.sched_priority = pri;
+    int result = sched_setscheduler(pid, policy, &param);
+    if (result != 0){
+      perror ("sched_setscheduler: failed to set real time priority");
+    }
+    else
+      printf("SCHED_FIFO enabled with priority = %d\n", pri);
+  }
+#endif
+
+  FILE *fp = 0;
+
+  if (output_filename){
+    fp = fopen (output_filename, "wb");
+    if (fp == 0)
+      perror (output_filename);
+  }
+      
+  int mode = 0;
+  if (loopback_p)
+    mode |= usrp_standard_rx::FPGA_MODE_LOOPBACK;
+  if (counting_p)
+    mode |= usrp_standard_rx::FPGA_MODE_COUNTING;
+
+
+  usrp_standard_rx *urx = 
+    usrp_standard_rx::make (which_board, decim, 1, -1, mode,
+                           fusb_block_size, fusb_nblocks);
+
+  if (urx == 0)
+    die ("usrp_standard_rx::make");
+
+  if (!urx->set_rx_freq (0, center_freq))
+    die ("urx->set_rx_freq");
+    
+  if (width_8_p){
+    int width = 8;
+    int shift = 8;
+    bool want_q = true;
+    if (!urx->set_format(usrp_standard_rx::make_format(width, shift, want_q)))
+      die("urx->set_format");
+  }
+
+  urx->start();                // start data xfers
+
+  test_input (urx, max_bytes, fp);
+
+  if (fp)
+    fclose (fp);
+
+  delete urx;
+
+  return 0;
+}
+
+
+static bool
+test_input  (usrp_standard_rx *urx, int max_bytes, FILE *fp)
+{
+  int             fd = -1;
+  static const int BUFSIZE = urx->block_size();
+  static const int N = BUFSIZE/sizeof (short);
+  short           buf[N];
+  int             nbytes = 0;
+
+  double          start_wall_time = get_elapsed_time ();
+  double          start_cpu_time  = get_cpu_usage ();
+
+  if (fp)
+    fd = fileno (fp);
+  
+  bool overrun;
+  int noverruns = 0;
+
+  for (nbytes = 0; max_bytes == 0 || nbytes < max_bytes; nbytes += BUFSIZE){
+
+    unsigned int       ret = urx->read (buf, sizeof (buf), &overrun);
+    if (ret != sizeof (buf)){
+      fprintf (stderr, "test_input: error, ret = %d\n", ret);
+    }
+
+    if (overrun){
+      printf ("rx_overrun\n");
+      noverruns++;
+    }
+    
+    if (fd != -1){
+
+      for (unsigned int i = 0; i < sizeof (buf) / sizeof (short); i++)
+       buf[i] = usrp_to_host_short (buf[i]);
+
+      if (write (fd, buf, sizeof (buf)) == -1){
+       perror ("write");
+       fd = -1;
+      }
+    }
+  }
+
+  double stop_wall_time = get_elapsed_time ();
+  double stop_cpu_time  = get_cpu_usage ();
+
+  double delta_wall = stop_wall_time - start_wall_time;
+  double delta_cpu  = stop_cpu_time  - start_cpu_time;
+
+  printf ("xfered %.3g bytes in %.3g seconds.  %.4g bytes/sec.  cpu time = %.4g\n",
+         (double) max_bytes, delta_wall, max_bytes / delta_wall, delta_cpu);
+  printf ("noverruns = %d\n", noverruns);
+
+  return true;
+}
diff --git a/usrp/host/apps/test_usrp_standard_tx.cc b/usrp/host/apps/test_usrp_standard_tx.cc
new file mode 100644 (file)
index 0000000..8aebaeb
--- /dev/null
@@ -0,0 +1,319 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003,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.
+ */
+
+#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 <math.h>
+#include "time_stuff.h"
+#include "usrp_standard.h"
+#include "usrp_bytesex.h"
+
+#ifdef HAVE_SCHED_H
+#include <sched.h>
+#endif
+
+char *prog_name;
+
+static bool test_output (usrp_standard_tx *utx, int max_bytes, double ampl,
+                        bool dc_p, bool counting_p);
+
+static void
+set_progname (char *path)
+{
+  char *p = strrchr (path, '/');
+  if (p != 0)
+    prog_name = p+1;
+  else
+    prog_name = path;
+}
+
+static void
+usage ()
+{
+  fprintf (stderr, 
+          "usage: %s [-f] [-v] [-d] [-c] [-a <ampl>][-I <interp>] [-F freq] [-D]\n", prog_name);
+  fprintf (stderr, "  [-f] loop forever\n");
+  fprintf (stderr, "  [-M] how many Megabytes to transfer (default 128)\n");
+  fprintf (stderr, "  [-v] verbose\n");
+  fprintf (stderr, "  [-d] dump registers\n");
+  // fprintf (stderr, "  [-l] digital loopback in FPGA\n");
+  fprintf (stderr, "  [-c] Tx counting sequence\n");
+  fprintf (stderr, "  [-D] DC output\n");
+
+  fprintf (stderr, "  [-B <fusb_block_size>] set fast usb block_size\n");
+  fprintf (stderr, "  [-N <fusb_nblocks>] set fast usb nblocks\n");
+  fprintf (stderr, "  [-R] set real time scheduling: SCHED_FIFO; pri = midpoint\n");
+
+  exit (1);
+}
+
+static void
+die (const char *msg)
+{
+  fprintf (stderr, "die: %s: %s\n", prog_name, msg);
+  exit (1);
+}
+
+static void
+dump_codec_regs (usrp_basic *u, int which_codec, FILE *fp)
+{
+  for (int i = 0; i < 64; i++){
+    unsigned char v;
+    u->_read_9862 (which_codec, i, &v);
+    fprintf (fp, "%2d:  0x%02x\n", i, v); 
+  }
+  fflush (fp);
+}
+
+static void
+do_dump_codec_regs (usrp_basic *u)
+{
+  char name[100];
+  strcpy (name, "regsXXXXXX");
+  int fd = mkstemp (name);
+  if (fd == -1){
+    perror (name);
+  }
+  else {
+    FILE *fp = fdopen (fd, "w");
+    dump_codec_regs (u, 0, fp);
+    fclose (fp);
+  }
+}
+
+int
+main (int argc, char **argv)
+{
+  bool         verbose_p = false;
+  bool  dump_regs_p = false;
+  bool dc_p = false;
+  // bool  loopback_p = false;
+  bool  counting_p = false;
+  int   max_bytes = 128 * (1L << 20);
+  int  ch;
+  int  which_board = 0;
+  int  interp = 16;                    // 32.0 MB/sec 
+  double       center_freq = 0;
+  double       ampl = 10000;
+  int  fusb_block_size = 0;
+  int  fusb_nblocks = 0;
+  bool realtime_p = false;
+
+
+  set_progname (argv[0]);
+
+  while ((ch = getopt (argc, argv, "vfdcI:F:a:DM:B:N:R")) != EOF){
+    switch (ch){
+    case 'f':
+      max_bytes = 0;
+      break;
+
+    case 'v':
+      verbose_p = true;
+      break;
+
+    case 'd':
+      dump_regs_p = true;
+      break;
+      
+    case 'D':
+      dc_p = true;
+      break;
+      
+#if 0
+    case 'l':
+      loopback_p = true;
+      break;
+#endif
+      
+    case 'c':
+      counting_p = true;
+      break;
+      
+    case 'I':
+      interp = strtol (optarg, 0, 0);
+      break;
+                     
+    case 'F':
+      center_freq = strtod (optarg, 0);
+      break;
+      
+    case 'a':
+      ampl = strtod (optarg, 0);
+      break;
+
+    case 'M':
+      max_bytes = strtol (optarg, 0, 0) * (1L << 20);
+      if (max_bytes < 0) max_bytes = 0;
+      break;
+
+    case 'B':
+      fusb_block_size = strtol (optarg, 0, 0);
+      break;
+
+    case 'N':
+      fusb_nblocks = strtol (optarg, 0, 0);
+      break;
+
+    case 'R':
+      realtime_p = true;
+      break;
+
+    default:
+      usage ();
+    }
+  }
+
+#ifdef HAVE_SCHED_SETSCHEDULER
+  if (realtime_p){
+    int policy = SCHED_FIFO;
+    int pri = (sched_get_priority_max (policy) - sched_get_priority_min (policy)) / 2;
+    int pid = 0;  // this process
+
+    struct sched_param param;
+    memset(&param, 0, sizeof(param));
+    param.sched_priority = pri;
+    int result = sched_setscheduler(pid, policy, &param);
+    if (result != 0){
+      perror ("sched_setscheduler: failed to set real time priority");
+    }
+    else
+      printf("SCHED_FIFO enabled with priority = %d\n", pri);
+  }
+#endif
+
+  usrp_standard_tx *utx;
+
+  utx = usrp_standard_tx::make (which_board,
+                               interp,
+                               1,      // nchan
+                               -1,     // mux
+                               fusb_block_size,
+                               fusb_nblocks);
+
+  if (utx == 0)
+    die ("usrp_standard_tx::make");
+    
+  if (!utx->set_tx_freq (0, center_freq))
+    die ("utx->set_tx_freq");
+    
+  if (dump_regs_p)
+    do_dump_codec_regs (utx);
+  
+  
+  fflush (stdout);
+  fflush (stderr);
+
+  utx->start();                // start data xfers
+
+  test_output (utx, max_bytes, ampl, dc_p, counting_p);
+
+  delete utx;
+
+  return 0;
+}
+
+
+static bool
+test_output (usrp_standard_tx *utx, int max_bytes, double ampl,
+            bool dc_p, bool counting_p)
+{
+  static const int BUFSIZE = utx->block_size();
+  static const int N = BUFSIZE/sizeof (short);
+
+  short           buf[N];
+  int             nbytes = 0;
+  int             counter = 0;
+
+  static const int    PERIOD = 65;             // any value is valid
+  static const int    PATLEN = 2 * PERIOD;     
+  short                      pattern[PATLEN];
+
+  for (int i = 0; i < PERIOD; i++){
+    if (dc_p){
+      pattern[2*i+0] = host_to_usrp_short ((short) ampl);
+      pattern[2*i+1] = host_to_usrp_short ((short) 0);
+    }
+    else {
+      pattern[2*i+0] = host_to_usrp_short ((short) (ampl * cos (2*M_PI * i / PERIOD)));
+      pattern[2*i+1] = host_to_usrp_short ((short) (ampl * sin (2*M_PI * i / PERIOD)));
+    }
+  }
+
+  double          start_wall_time = get_elapsed_time ();
+  double          start_cpu_time  = get_cpu_usage ();
+
+  bool         underrun;
+  int  nunderruns = 0;
+  int  pi = 0;
+
+  for (nbytes = 0; max_bytes == 0 || nbytes < max_bytes; nbytes += BUFSIZE){
+
+    if (counting_p){
+      for (int i = 0; i < N; i++)
+       buf[i] = host_to_usrp_short (counter++ & 0xffff);
+    }
+    else {
+      for (int i = 0; i < N; i++){
+       buf[i] = pattern[pi];
+       pi++;
+       if (pi >= PATLEN)
+         pi = 0;
+      }
+    }
+
+    int        ret = utx->write (buf, sizeof (buf), &underrun);
+    if ((unsigned) ret != sizeof (buf)){
+      fprintf (stderr, "test_output: error, ret = %d\n", ret);
+    }
+
+    if (underrun){
+      nunderruns++;
+      printf ("tx_underrun\n");
+      //printf ("tx_underrun %9d %6d\n", nbytes, nbytes/BUFSIZE);
+    }
+  }
+
+  utx->wait_for_completion ();
+
+  double stop_wall_time = get_elapsed_time ();
+  double stop_cpu_time  = get_cpu_usage ();
+
+  double delta_wall = stop_wall_time - start_wall_time;
+  double delta_cpu  = stop_cpu_time  - start_cpu_time;
+
+  printf ("xfered %.3g bytes in %.3g seconds.  %.4g bytes/sec.  cpu time = %.3g\n",
+         (double) max_bytes, delta_wall, max_bytes / delta_wall, delta_cpu);
+
+  printf ("%d underruns\n", nunderruns);
+
+  return true;
+}
diff --git a/usrp/host/apps/time_stuff.c b/usrp/host/apps/time_stuff.c
new file mode 100644 (file)
index 0000000..aa62e9a
--- /dev/null
@@ -0,0 +1,68 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "time_stuff.h"
+
+#include <sys/time.h>
+#ifdef HAVE_SYS_RESOURCE_H
+#include <sys/resource.h>
+#endif
+#include <unistd.h>
+
+static double
+timeval_to_secs (struct timeval *tv)
+{
+  return (double) tv->tv_sec + (double) tv->tv_usec * 1e-6;
+}
+
+double
+get_cpu_usage (void)
+{
+#ifdef HAVE_GETRUSAGE
+  struct rusage        ru;
+
+  if (getrusage (RUSAGE_SELF, &ru) != 0)
+    return 0;
+
+  return timeval_to_secs (&ru.ru_utime) + timeval_to_secs (&ru.ru_stime);
+#else
+  return 0;    /* FIXME */
+#endif
+}
+
+/*
+ * return elapsed time (wall time) in seconds
+ */
+double
+get_elapsed_time (void)
+{
+  struct timeval       tv;
+  if (gettimeofday (&tv, 0) != 0)
+    return 0;
+
+  return timeval_to_secs (&tv);
+}
+
diff --git a/usrp/host/apps/time_stuff.h b/usrp/host/apps/time_stuff.h
new file mode 100644 (file)
index 0000000..c995ef6
--- /dev/null
@@ -0,0 +1,48 @@
+/* -*- 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 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.
+ */
+
+#ifndef _TIME_STUFF_H_
+#define _TIME_STUFF_H_
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * return USER + SYS cpu time in seconds
+ */
+double get_cpu_usage (void);
+
+/*
+ * return elapsed time in seconds
+ */
+double get_elapsed_time (void);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* _TIME_STUFF_H_ */
diff --git a/usrp/host/apps/usrp_cal_dc_offset.cc b/usrp/host/apps/usrp_cal_dc_offset.cc
new file mode 100644 (file)
index 0000000..2308bdd
--- /dev/null
@@ -0,0 +1,242 @@
+/* -*- 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 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.
+ */
+
+#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 <math.h>
+#include <boost/scoped_ptr.hpp>
+#include "usrp_local_sighandler.h"
+#include "usrp_standard.h"
+#include "usrp_bytesex.h"
+
+char *prog_name;
+
+
+
+
+static void 
+run_cal(usrp_standard_rx *u, int which_side, int decim, bool verbose_p)
+{
+  static const int BUFSIZE = u->block_size();
+  static const int N = BUFSIZE/sizeof (short);
+  short           buf[N];
+  bool         cal_done = false;
+  bool overrun;
+  int  noverruns = 0;
+
+  static const double K = 1e-4;
+  long integrator[2];
+  int  offset[2];
+
+  integrator[0] = 0;
+  integrator[1] = 0;
+  offset[0] = 0;
+  offset[1] = 0;
+
+  u->start();          // start data xfers
+
+  while(!cal_done){
+    int        ret = u->read (buf, sizeof (buf), &overrun);
+    if (ret != (int) sizeof (buf)){
+      fprintf (stderr, "usrp_cal_dc_offset: error, ret = %d\n", ret);
+      continue;
+    }
+    if (overrun){
+      fprintf (stderr, "O");
+      noverruns++;
+    }
+    else {
+      // fputc('.', stderr);
+    }
+
+    static const int MAX = (1L << 30);         // 1G
+
+    for (int i = 0; i < N/2; i++){
+      for (int n = 0; n < 2; n++){
+       integrator[n] = integrator[n] + buf[2*i + n];
+       if (integrator[n] > MAX)
+         integrator[n] = MAX;
+       else if (integrator[n] < -MAX)
+         integrator[n] = -MAX;
+      }
+    }
+
+#if 1
+    for (int n = 0; n < 2; n++){
+      offset[n] = (int) rint(integrator[n] * K);
+      if (offset[n] > 32767)
+       offset[n] = 32767;
+      else if (offset[n] < -32767)
+       offset[n] = -32767;
+      u->set_adc_offset(which_side * 2 + n, offset[n]);
+    }
+#else
+    offset[0] = (int) rint(integrator[0] * K);
+    if (offset[0] > 32767)
+      offset[0] = 32767;
+    else if (offset[0] < -32767)
+      offset[0] = -32767;
+    u->set_adc_offset(which_side * 2 + 0, offset[0]);
+    u->set_adc_offset(which_side * 2 + 1, offset[0]);
+#endif
+    
+
+    printf ("%9ld : %6d\t\t%9ld : %6d\n",
+           integrator[0], offset[0], integrator[1], offset[1]);
+  }
+
+  u->stop();
+}
+
+
+static void
+set_progname (char *path)
+{
+  char *p = strrchr (path, '/');
+  if (p != 0)
+    prog_name = p+1;
+  else
+    prog_name = path;
+}
+
+static void
+usage ()
+{
+  fprintf(stderr, "usage: %s [-v] [-w which_side] [-D decim] [-c ddc_freq] [-g gain]\n", prog_name);
+  fprintf(stderr, "  [-S fusb_block_size] [-N fusb_nblocks]\n");
+  exit (1);
+}
+
+static void
+die (const char *msg)
+{
+  fprintf (stderr, "die: %s: %s\n", prog_name, msg);
+  exit (1);
+}
+
+int
+main (int argc, char **argv)
+{
+  int      ch;
+  int      decim = 128;                // 500 kS/sec
+  bool     verbose_p = false;
+  int      which_board = 0;
+  int      which_side = 0;
+  double    ddc_freq = 0;
+  int      fusb_block_size = 1024;
+  int      fusb_nblocks = 4;
+  double    pga_gain = 0.0;
+
+  set_progname(argv[0]);
+
+  while ((ch = getopt (argc, argv, "vw:D:c:S:N:g:")) != EOF){
+    switch (ch){
+
+    case 'w':
+      which_side = strtol (optarg, 0, 0);
+      if (which_side < 0 || which_side > 1)
+       usage();
+      break;
+
+    case 'D':
+      decim = strtol (optarg, 0, 0);
+      if (decim < 1)
+       usage();
+      break;
+
+    case 'c':
+      ddc_freq = strtod (optarg, 0);
+      break;
+
+    case 'v':
+      verbose_p = true;
+      break;
+
+    case 'S':
+      fusb_block_size = strtol(optarg, 0, 0);
+      break;
+
+    case 'N':
+      fusb_nblocks = strtol(optarg, 0, 0);
+      break;
+
+    case 'g':
+      pga_gain = strtod (optarg, 0);
+      break;
+
+    default:
+      usage ();
+    }
+  }
+
+  int nchannels = 1;
+  int mode = usrp_standard_rx::FPGA_MODE_NORMAL;
+  int mux;
+
+  if (which_side == 0)
+    mux = 0x00000010;
+  else
+    mux = 0x00000032;
+
+#ifdef SIGINT
+  usrp_local_sighandler sigint (SIGINT, usrp_local_sighandler::throw_signal);
+#endif
+#ifdef SIGQUIT
+  usrp_local_sighandler sigquit (SIGQUIT, usrp_local_sighandler::throw_signal);
+#endif
+
+  usrp_standard_rx *urx =
+    usrp_standard_rx::make(which_board, decim,
+                          nchannels, mux, mode,
+                          fusb_block_size, fusb_nblocks);
+  if (urx == 0)
+    die("usrp_standard_rx::make");
+
+  try {
+
+    if (!urx->set_rx_freq(0, ddc_freq))
+      die("urx->set_rx_freq");
+
+    urx->set_pga(2 * which_side + 0, pga_gain);
+    urx->set_pga(2 * which_side + 1, pga_gain);
+    
+    run_cal(urx, which_side, decim, verbose_p);
+  }
+  catch (usrp_signal &sig){
+    fprintf (stderr, "usrp_cal_dc_offset: caught %s\n", sig.name().c_str());
+  }
+  catch(...){
+    fprintf (stderr, "usrp_cal_dc_offset: caught something\n");
+  }
+
+  delete urx;
+}
+
diff --git a/usrp/host/apps/usrper.cc b/usrp/host/apps/usrper.cc
new file mode 100644 (file)
index 0000000..51c5ee6
--- /dev/null
@@ -0,0 +1,352 @@
+/* -*- c++ -*- */
+/*
+ * USRP - Universal Software Radio Peripheral
+ *
+ * Copyright (C) 2003,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 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
+ */
+
+#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_spi_defs.h"
+
+char *prog_name;
+
+
+static void
+set_progname (char *path)
+{
+  char *p = strrchr (path, '/');
+  if (p != 0)
+    prog_name = p+1;
+  else
+    prog_name = path;
+}
+
+static void
+usage ()
+{
+  fprintf (stderr, "usage: \n");
+  fprintf (stderr, "  %s [-v] [-w <which_board>] [-x] ...\n", prog_name);
+  fprintf (stderr, "  %s load_standard_bits\n", prog_name);
+  fprintf (stderr, "  %s load_firmware <file.ihx>\n", prog_name);
+  fprintf (stderr, "  %s load_fpga <file.rbf>\n", prog_name);
+  fprintf (stderr, "  %s write_fpga_reg <reg8> <value32>\n", prog_name);
+  fprintf (stderr, "  %s set_fpga_reset {on|off}\n", prog_name);
+  fprintf (stderr, "  %s set_fpga_tx_enable {on|off}\n", prog_name);
+  fprintf (stderr, "  %s set_fpga_rx_enable {on|off}\n", prog_name);
+  fprintf (stderr, "  ----- diagnostic routines -----\n");
+  fprintf (stderr, "  %s led0 {on|off}\n", prog_name);
+  fprintf (stderr, "  %s led1 {on|off}\n", prog_name);
+  fprintf (stderr, "  %s set_hash0 <hex-string>\n", prog_name);
+  fprintf (stderr, "  %s get_hash0\n", prog_name);
+  fprintf (stderr, "  %s i2c_read i2c_addr len\n", prog_name);
+  fprintf (stderr, "  %s i2c_write i2c_addr <hex-string>\n", prog_name);
+  fprintf (stderr, "  %s 9862a_write regno value\n", prog_name);
+  fprintf (stderr, "  %s 9862b_write regno value\n", prog_name);
+  fprintf (stderr, "  %s 9862a_read regno\n", prog_name);
+  fprintf (stderr, "  %s 9862b_read regno\n", prog_name);
+  exit (1);
+}
+
+static void
+die (const char *msg)
+{
+  fprintf (stderr, "%s (die): %s\n", prog_name, msg);
+  exit (1);
+}
+
+static int 
+hexval (char ch)
+{
+  if ('0' <= ch && ch <= '9')
+    return ch - '0';
+
+  if ('a' <= ch && ch <= 'f')
+    return ch - 'a' + 10;
+
+  if ('A' <= ch && ch <= 'F')
+    return ch - 'A' + 10;
+
+  return -1;
+}
+
+static unsigned char *
+hex_string_to_binary (const char *string, int *lenptr)
+{
+  int  sl = strlen (string);
+  if (sl & 0x01){
+    fprintf (stderr, "%s: odd number of chars in <hex-string>\n", prog_name);
+    return 0;
+  }
+
+  int len = sl / 2;
+  *lenptr = len;
+  unsigned char *buf = new unsigned char [len];
+
+  for (int i = 0; i < len; i++){
+    int hi = hexval (string[2 * i]);
+    int lo = hexval (string[2 * i + 1]);
+    if (hi < 0 || lo < 0){
+      fprintf (stderr, "%s: invalid char in <hex-string>\n", prog_name);
+      delete [] buf;
+      return 0;
+    }
+    buf[i] = (hi << 4) | lo;
+  }
+  return buf;
+}
+
+static void
+print_hex (FILE *fp, unsigned char *buf, int len)
+{
+  for (int i = 0; i < len; i++){
+    fprintf (fp, "%02x", buf[i]);
+  }
+  fprintf (fp, "\n");
+}
+
+static void
+chk_result (bool ok)
+{
+  if (!ok){
+    fprintf (stderr, "%s: failed\n", prog_name);
+    exit (1);
+  }
+}
+
+static bool
+get_on_off (const char *s)
+{
+  if (strcmp (s, "on") == 0)
+    return true;
+
+  if (strcmp (s, "off") == 0)
+    return false;
+
+  usage ();                    // no return
+  return false;
+}
+
+
+int
+main (int argc, char **argv)
+{
+  int          ch;
+  bool         verbose = false;
+  int          which_board = 0;
+  bool         fx2_ok_p = false;
+  
+  set_progname (argv[0]);
+  
+  while ((ch = getopt (argc, argv, "vw:x")) != EOF){
+    switch (ch){
+
+    case 'v':
+      verbose = true;
+      break;
+      
+    case 'w':
+      which_board = strtol (optarg, 0, 0);
+      break;
+      
+    case 'x':
+      fx2_ok_p = true;
+      break;
+      
+    default:
+      usage ();
+    }
+  }
+
+  int nopts = argc - optind;
+
+  if (nopts < 1)
+    usage ();
+
+  const char *cmd = argv[optind++];
+  nopts--;
+
+  usrp_one_time_init ();
+
+  
+  struct usb_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);
+  }
+
+  if (usrp_unconfigured_usrp_p (udev)){
+    fprintf (stderr, "%s: found unconfigured usrp; needs firmware.\n", prog_name);
+  }
+
+  if (usrp_fx2_p (udev)){
+    fprintf (stderr, "%s: found unconfigured FX2; needs firmware.\n", prog_name);
+  }
+
+  struct usb_dev_handle *udh = usrp_open_cmd_interface (udev);
+  if (udh == 0){
+    fprintf (stderr, "%s: failed to open_cmd_interface\n", prog_name);
+    exit (1);
+  }
+
+#define CHKARGS(n) if (nopts != n) usage (); else
+
+  if (strcmp (cmd, "led0") == 0){
+    CHKARGS (1);
+    bool on = get_on_off (argv[optind]);
+    chk_result (usrp_set_led (udh, 0, on));
+  }
+  else if (strcmp (cmd, "led1") == 0){
+    CHKARGS (1);
+    bool on = get_on_off (argv[optind]);
+    chk_result (usrp_set_led (udh, 1, on));
+  }
+  else if (strcmp (cmd, "led2") == 0){
+    CHKARGS (1);
+    bool on = get_on_off (argv[optind]);
+    chk_result (usrp_set_led (udh, 2, on));
+  }
+  else if (strcmp (cmd, "set_hash0") == 0){
+    CHKARGS (1);
+    char *p = argv[optind];
+    unsigned char buf[16];
+
+    memset (buf, ' ', 16);
+    for (int i = 0; i < 16 && *p; i++)
+      buf[i] = *p++;
+    
+    chk_result (usrp_set_hash (udh, 0, buf));
+  }
+  else if (strcmp (cmd, "get_hash0") == 0){
+    CHKARGS (0);
+    unsigned char buf[17];
+    memset (buf, 0, 17);
+    bool r = usrp_get_hash (udh, 0, buf);
+    if (r)
+      printf ("hash: %s\n", buf);
+    chk_result (r);
+  }
+  else if (strcmp (cmd, "load_fpga") == 0){
+    CHKARGS (1);
+    char *filename = argv[optind];
+    chk_result (usrp_load_fpga (udh, filename, true));
+  }
+  else if (strcmp (cmd, "load_firmware") == 0){
+    CHKARGS (1);
+    char *filename = argv[optind];
+    chk_result (usrp_load_firmware (udh, filename, true));
+  }
+  else if (strcmp (cmd, "write_fpga_reg") == 0){
+    CHKARGS (2);
+    chk_result (usrp_write_fpga_reg (udh, strtoul (argv[optind], 0, 0),
+                                    strtoul(argv[optind+1], 0, 0)));
+  }
+  else if (strcmp (cmd, "set_fpga_reset") == 0){
+    CHKARGS (1);
+    chk_result (usrp_set_fpga_reset (udh, get_on_off (argv[optind])));
+  }
+  else if (strcmp (cmd, "set_fpga_tx_enable") == 0){
+    CHKARGS (1);
+    chk_result (usrp_set_fpga_tx_enable (udh, get_on_off (argv[optind])));
+  }
+  else if (strcmp (cmd, "set_fpga_rx_enable") == 0){
+    CHKARGS (1);
+    chk_result (usrp_set_fpga_rx_enable (udh, get_on_off (argv[optind])));
+  }
+  else if (strcmp (cmd, "load_standard_bits") == 0){
+    CHKARGS (0);
+    usrp_close_interface (udh);
+    udh = 0;
+    chk_result (usrp_load_standard_bits (which_board, true));
+  }
+  else if (strcmp (cmd, "i2c_read") == 0){
+    CHKARGS (2);
+    int        i2c_addr = strtol (argv[optind], 0, 0);
+    int len = strtol (argv[optind + 1], 0, 0);
+    if (len < 0)
+      chk_result (0);
+
+    unsigned char *buf = new unsigned char [len];
+    bool result = usrp_i2c_read (udh, i2c_addr, buf, len);
+    if (!result){
+      chk_result (0);
+    }
+    print_hex (stdout, buf, len);
+  }
+  else if (strcmp (cmd, "i2c_write") == 0){
+    CHKARGS (2);
+    int        i2c_addr = strtol (argv[optind], 0, 0);
+    int        len;
+    char *hex_string  = argv[optind + 1];
+    unsigned char *buf = hex_string_to_binary (hex_string, &len);
+    if (buf == 0)
+      chk_result (0);
+
+    bool result = usrp_i2c_write (udh, i2c_addr, buf, len);
+    chk_result (result);
+  }
+  else if (strcmp (cmd, "9862a_write") == 0){
+    CHKARGS (2);
+    int regno = strtol (argv[optind], 0, 0);
+    int value = strtol (argv[optind+1], 0, 0);
+    chk_result (usrp_9862_write (udh, 0, regno, value));
+  }
+  else if (strcmp (cmd, "9862b_write") == 0){
+    CHKARGS (2);
+    int regno = strtol (argv[optind], 0, 0);
+    int value = strtol (argv[optind+1], 0, 0);
+    chk_result (usrp_9862_write (udh, 1, regno, value));
+  }
+  else if (strcmp (cmd, "9862a_read") == 0){
+    CHKARGS (1);
+    int regno = strtol (argv[optind], 0, 0);
+    unsigned char value;
+    bool result = usrp_9862_read (udh, 0, regno, &value);
+    if (!result){
+      chk_result (0);
+    }
+    fprintf (stdout, "reg[%d] = 0x%02x\n", regno, value);
+  }
+  else if (strcmp (cmd, "9862b_read") == 0){
+    CHKARGS (1);
+    int regno = strtol (argv[optind], 0, 0);
+    unsigned char value;
+    bool result = usrp_9862_read (udh, 1, regno, &value);
+    if (!result){
+      chk_result (0);
+    }
+    fprintf (stdout, "reg[%d] = 0x%02x\n", regno, value);
+  }
+  else {
+    usage ();
+  }
+
+  if (udh){
+    usrp_close_interface (udh);
+    udh = 0;
+  }
+
+  return 0;
+}
diff --git a/usrp/host/lib/Makefile.am b/usrp/host/lib/Makefile.am
new file mode 100644 (file)
index 0000000..e2086bc
--- /dev/null
@@ -0,0 +1,137 @@
+#
+#  USRP - Universal Software Radio Peripheral
+# 
+#  Copyright (C) 2003,2004,2006 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
+# 
+INCLUDES = -I$(top_srcdir)/usrp/firmware/include
+
+lib_LTLIBRARIES = libusrp.la
+
+
+EXTRA_DIST =                           \
+       std_paths.h.in                  \
+       usrp_dbid.dat                   
+
+
+BUILT_SOURCES =                        \
+       usrp_dbid.h                     \
+       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
+
+darwin_CODE =                          \
+       fusb_darwin.cc                  \
+       fusb_sysconfig_darwin.cc        \
+       README_OSX                      \
+       circular_buffer.h               \
+       circular_linked_list.h          \
+       darwin_libusb.h                 \
+       mld_threads.h                   
+
+win32_CODE =                           \
+       fusb_win32.cc                   \
+       fusb_sysconfig_win32.cc         
+
+linux_CODE =                           \
+       fusb_linux.cc                   \
+       fusb_sysconfig_linux.cc         
+
+
+#
+# include each <foo>_CODE entry here...
+#
+EXTRA_libusrp_la_SOURCES =             \
+       $(generic_CODE)                 \
+       $(darwin_CODE)                  \
+       $(win32_CODE)                   \
+       $(linux_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.cc                   \
+       usrp_standard.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
+
+
+libusrp_la_LDFLAGS = $(NO_UNDEFINED) -version-info 0:0:0
+libusrp_la_LIBADD = $(USB_LIBS) ../misc/libmisc.la
+
+include_HEADERS =                      \
+       usrp_basic.h                    \
+       usrp_bytesex.h                  \
+       usrp_config.h                   \
+       usrp_dbid.h                     \
+       usrp_prims.h                    \
+       usrp_slots.h                    \
+       usrp_standard.h                 
+
+noinst_HEADERS =                       \
+       ad9862.h                        \
+       fusb.h                          \
+       fusb_darwin.h                   \
+       fusb_win32.h                    \
+       fusb_generic.h                  \
+       fusb_linux.h                    \
+       md5.h                           \
+       rate_to_regval.h                \
+       usrp_local_sighandler.h         
+
+python_PYTHON =                                \
+       usrp_dbid.py                    
+
+noinst_PYTHON =                                \
+       gen_usrp_dbid.py
+
+usrp_dbid.py usrp_dbid.h usrp_dbid.cc: gen_usrp_dbid.py usrp_dbid.dat
+       PYTHONPATH=$(top_srcdir)/usrp/src srcdir=$(srcdir) $(srcdir)/gen_usrp_dbid.py $(srcdir)/usrp_dbid.dat
+
+MOSTLYCLEANFILES = \
+       $(BUILT_SOURCES) *~ *.pyc
diff --git a/usrp/host/lib/README_OSX b/usrp/host/lib/README_OSX
new file mode 100644 (file)
index 0000000..20230f1
--- /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 funciton 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..70cb202
--- /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 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.
+ */
+
+#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..0f8ea2e
--- /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 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.
+
+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..4d507c2
--- /dev/null
@@ -0,0 +1,325 @@
+/* -*- 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 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.
+ */
+
+#ifndef _CIRCULAR_BUFFER_H_
+#define _CIRCULAR_BUFFER_H_
+
+#include "mld_threads.h"
+#include <stdexcept>
+
+#define DO_DEBUG 0
+
+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;
+
+// stuff to control access to class internals
+  mld_mutex_ptr d_internal;
+  mld_condition_ptr d_readBlock, 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 (UInt32 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 ();
+#if DO_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"));
+#endif
+  };
+
+  ~circular_buffer () {
+    delete_mutex_cond ();
+    delete [] d_buffer;
+  };
+
+  inline UInt32 n_avail_write_items () {
+    d_internal->lock ();
+    UInt32 retVal = d_n_avail_write_I;
+    d_internal->unlock ();
+    return (retVal);
+  };
+
+  inline UInt32 n_avail_read_items () {
+    d_internal->lock ();
+    UInt32 retVal = d_n_avail_read_I;
+    d_internal->unlock ();
+    return (retVal);
+  };
+
+  inline UInt32 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 ();
+    d_internal = new mld_mutex ();
+    d_readBlock = new mld_condition ();
+    d_writeBlock = new mld_condition ();
+  };
+
+/*
+ * 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, UInt32 bufLen_I) {
+#if DO_DEBUG
+    fprintf (stderr, "enqueue: buf = %X, bufLen = %ld.\n",
+            (unsigned int)buf, bufLen_I);
+#endif
+    if (bufLen_I > d_bufLen_I) {
+      fprintf (stderr, "cannot add buffer longer (%ld"
+              ") than instantiated length (%ld"
+              ").\n", bufLen_I, d_bufLen_I);
+      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");
+    d_internal->lock ();
+    if (d_doAbort) {
+      d_internal->unlock ();
+      return (2);
+    }
+    if (bufLen_I > d_n_avail_write_I) {
+      if (d_doWriteBlock) {
+       while (bufLen_I > d_n_avail_write_I) {
+#if DO_DEBUG
+         fprintf (stderr, "enqueue: #len > #a, waiting.\n");
+#endif
+         d_internal->unlock ();
+         d_writeBlock->wait ();
+         d_internal->lock ();
+         if (d_doAbort) {
+           d_internal->unlock ();
+#if DO_DEBUG
+           fprintf (stderr, "enqueue: #len > #a, aborting.\n");
+#endif
+           return (2);
+         }
+#if DO_DEBUG
+         fprintf (stderr, "enqueue: #len > #a, done waiting.\n");
+#endif
+       }
+      } else {
+       d_n_avail_read_I = d_bufLen_I - bufLen_I;
+       d_n_avail_write_I = bufLen_I;
+#if DO_DEBUG
+       fprintf (stderr, "circular_buffer::enqueue: overflow\n");
+#endif
+       return (-1);
+      }
+    }
+    UInt32 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->signal ();
+    d_internal->unlock ();
+    return (1);
+  };
+
+/*
+ * 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, UInt32* bufLen_I) {
+#if DO_DEBUG
+    fprintf (stderr, "dequeue: buf = %X, *bufLen = %ld.\n",
+            (unsigned int)buf, *bufLen_I);
+#endif
+    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;
+    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);
+      throw std::runtime_error ("circular_buffer::dequeue()");
+    }
+
+    d_internal->lock ();
+    if (d_doAbort) {
+      d_internal->unlock ();
+      return (2);
+    }
+    if (d_doFullRead) {
+      while (d_n_avail_read_I < l_bufLen_I) {
+#if DO_DEBUG
+       fprintf (stderr, "dequeue: #a < #len, waiting.\n");
+#endif
+       d_internal->unlock ();
+       d_readBlock->wait ();
+       d_internal->lock ();
+       if (d_doAbort) {
+         d_internal->unlock ();
+#if DO_DEBUG
+         fprintf (stderr, "dequeue: #a < #len, aborting.\n");
+#endif
+         return (2);
+       }
+#if DO_DEBUG
+       fprintf (stderr, "dequeue: #a < #len, done waiting.\n");
+#endif
+     }
+    } else {
+      while (d_n_avail_read_I == 0) {
+#if DO_DEBUG
+       fprintf (stderr, "dequeue: #a == 0, waiting.\n");
+#endif
+       d_internal->unlock ();
+       d_readBlock->wait ();
+       d_internal->lock ();
+       if (d_doAbort) {
+         d_internal->unlock ();
+#if DO_DEBUG
+         fprintf (stderr, "dequeue: #a == 0, aborting.\n");
+#endif
+         return (2);
+       }
+#if DO_DEBUG
+       fprintf (stderr, "dequeue: #a == 0, done waiting.\n");
+#endif
+      }
+    }
+    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;
+    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->signal ();
+    d_internal->unlock ();
+    return (1);
+  };
+
+  void abort () {
+    d_internal->lock ();
+    d_doAbort = true;
+    d_writeBlock->signal ();
+    d_readBlock->signal ();
+    d_internal->unlock ();
+  };
+};
+
+#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..bdfcb08
--- /dev/null
@@ -0,0 +1,267 @@
+/* -*- 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 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.
+ */
+
+#ifndef _CIRCULAR_LINKED_LIST_H_
+#define _CIRCULAR_LINKED_LIST_H_
+
+#include <mld_threads.h>
+#include <stdexcept>
+
+#define __INLINE__ inline
+
+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;
+  UInt32 d_n_nodes, d_n_used;
+  mld_mutex_ptr d_internal;
+  mld_condition_ptr d_ioBlock;
+
+public:
+  circular_linked_list (UInt32 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) {
+       UInt32 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_internal = new mld_mutex ();
+    d_ioBlock = new mld_condition ();
+  };
+
+  ~circular_linked_list () {
+    iterate_start ();
+    s_node_ptr l_node = iterate_next ();
+    while (l_node) {
+      delete l_node;
+      l_node = iterate_next ();
+    }
+    delete d_internal;
+    d_internal = NULL;
+    delete d_ioBlock;
+    d_ioBlock = NULL;
+    d_available = d_inUse = d_iterate = d_current = NULL;
+    d_n_used = d_n_nodes = 0;
+  };
+
+  s_node_ptr find_next_available_node () {
+    d_internal->lock ();
+// find an available node
+    s_node_ptr l_node = d_available; 
+    while (! l_node) {
+      d_internal->unlock ();
+      d_ioBlock->wait ();
+      d_internal->lock ();
+      l_node = d_available;
+    }
+//  fprintf (stderr, "::f_n_a_n: #u = %ld, node = %p\n", num_used(), l_node);
+// 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 ();
+    d_internal->unlock ();
+    return (l_node);
+  };
+
+  void make_node_available (s_node_ptr l_node) {
+    if (!l_node) return;
+    d_internal->lock ();
+//  fprintf (stderr, "::m_n_a: #u = %ld, node = %p\n", num_used(), l_node);
+// 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--;
+// signal the condition when new data arrives
+    d_ioBlock->signal ();
+// unlock the mutex for thread safety
+    d_internal->unlock ();
+  };
+
+  __INLINE__ void iterate_start () { d_iterate = d_current; };
+
+  s_node_ptr iterate_next () {
+#if 0
+// lock the mutex for thread safety
+    d_internal->lock ();
+#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;
+    }
+#if 0
+// unlock the mutex for thread safety
+    d_internal->unlock ();
+#endif
+    return (l_this);
+  };
+
+  __INLINE__ T object () { return (d_current->d_object); };
+  __INLINE__ void object (T l_object) { d_current->d_object = l_object; };
+  __INLINE__ UInt32 num_nodes () { return (d_n_nodes); };
+  __INLINE__ UInt32 num_used () { return (d_n_used); };
+  __INLINE__ void num_used (UInt32 l_n_used) { d_n_used = l_n_used; };
+  __INLINE__ UInt32 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->signal ();
+  };
+  __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..164ab9c
--- /dev/null
@@ -0,0 +1,190 @@
+/* -*- 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 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.
+ */
+
+/*
+ * 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 char *
+darwin_error_str (int result)
+{
+  switch (result) {
+  case kIOReturnSuccess:
+    return "no error";
+  case kIOReturnNotOpen:
+    return "device not opened for exclusive access";
+  case kIOReturnNoDevice:
+    return "no connection to an IOService";
+  case kIOUSBNoAsyncPortErr:
+    return "no asyc port has been opened for interface";
+  case kIOReturnExclusiveAccess:
+    return "another process has device opened for exclusive access";
+  case kIOUSBPipeStalled:
+    return "pipe is stalled";
+  case kIOReturnError:
+    return "could not establish a connection to Darin kernel";
+  case kIOReturnBadArgument:
+    return "invalid argument";
+  default:
+    return "unknown error";
+  }
+}
+
+/* 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) \
+            fprintf(stderr, "USB error: %s\n", usb_error_str); \
+         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) \
+            fprintf(stderr, "USB error: %s\n", usb_error_str); \
+         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) \
+            fprintf(stderr, "USB error: %s\n", usb_error_str); \
+       } 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)
+    fprintf(stderr, "Converting ep address to pipeRef.\n");
+
+  /* retrieve the total number of endpoints on this interface */
+  ret = (*(device->interface))->GetNumEndpoints(device->interface, &numep);
+  if ( ret ) {
+    if ( usb_debug > 3 )
+      fprintf ( stderr, "ep_to_pipeRef: interface is %p\n", device->interface );
+    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) {
+      fprintf (stderr, "ep_to_pipeRef: an error occurred getting pipe information on pipe %d\n",
+              i );
+      USB_ERROR_STR_ORIG (-darwin_to_errno(ret), "ep_to_pipeRef(GetPipeProperties): %s", darwin_error_str(ret));
+    }
+
+    if (usb_debug > 3)
+      fprintf (stderr, "ep_to_pipeRef: Pipe %i: DIR: %i number: %i\n", i, direction, number);
+
+    /* 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)
+       fprintf(stderr, "ep_to_pipeRef: pipeRef for ep address 0x%02x found: 0x%02x\n", ep, i);
+
+      return i;
+    }
+  }
+
+  if (usb_debug > 3)
+    fprintf(stderr, "ep_to_pipeRef: No pipeRef found with endpoint address 0x%02x.\n", ep);
+  
+  /* none of the found pipes match the requested endpoint */
+  return -1;
+}
+
+}
+#endif /* __DARWIN_LIBUSB_H__ */
diff --git a/usrp/host/lib/dump_data.py b/usrp/host/lib/dump_data.py
new file mode 100755 (executable)
index 0000000..fea0b9d
--- /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 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.
+
+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/dxc-io-assignments.gnumeric b/usrp/host/lib/dxc-io-assignments.gnumeric
new file mode 100644 (file)
index 0000000..85e1a88
Binary files /dev/null and b/usrp/host/lib/dxc-io-assignments.gnumeric differ
diff --git a/usrp/host/lib/fusb.cc b/usrp/host/lib/fusb.cc
new file mode 100644 (file)
index 0000000..ef32cd8
--- /dev/null
@@ -0,0 +1,60 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <fusb.h>
+
+
+// ------------------------------------------------------------------------
+//                          device handle
+// ------------------------------------------------------------------------
+
+fusb_devhandle::fusb_devhandle (usb_dev_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..5a90227
--- /dev/null
@@ -0,0 +1,128 @@
+/* -*- 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 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.
+ */
+
+// Fast USB interface
+
+#ifndef _FUSB_H_
+#define _FUSB_H_
+
+
+struct  usb_dev_handle;
+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:
+  usb_dev_handle               *d_udh;
+
+public:
+  // CREATORS
+  fusb_devhandle (usb_dev_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
+  usb_dev_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 (usb_dev_handle *udh);
+
+  /*!
+   * \brief returns max block size hard limit
+   */
+  static int max_block_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..081e981
--- /dev/null
@@ -0,0 +1,499 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+// tell mld_threads to NOT use omni_threads,
+// but rather Darwin's pthreads
+#undef _USE_OMNI_THREADS_
+
+#include <usb.h>
+#include "fusb.h"
+#include "fusb_darwin.h"
+#include "darwin_libusb.h"
+
+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 mld_mutex ();
+  d_runThreadRunning = new mld_mutex ();
+  d_runBlock = new mld_condition ();
+  d_readBlock = new mld_condition ();
+}
+
+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;
+  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)
+    fprintf (stderr, "fusb_ephandle_darwin::start: "
+            "dev = %p, device = %p\n", dev, device);
+
+  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)
+    fprintf (stderr, "fusb_ephandle_darwin::start "
+            "d_endpoint = %d, d_input_p = %s\n",
+            d_endpoint, d_input_p ? "TRUE" : "FALSE");
+
+  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)
+    fprintf (stderr, "fusb_ephandle_darwin::start: %s: ep = 0x%02x, "
+            "pipeRef = %d, d_i = %p, d_iR = %p, if_dir = %d, if_# = %d, "
+            "if_int = %d, if_maxPS = %d\n", d_input_p ? "read" : "write",
+            d_endpoint, d_pipeRef, d_interface, d_interfaceRef, direction,
+            number, interval, maxPacketSize);
+
+// set global start boolean
+  d_started = true;
+
+// create the run thread, which allows OSX to process I/O separately
+  d_runThread = new mld_thread (run_thread, this);
+
+// wait until the threads are -really- going
+  d_runBlock->wait ();
+
+  if (usb_debug)
+    fprintf (stderr, "fusb_ephandle_darwin::start: %s started.\n",
+            d_input_p ? "read" : "write");
+
+  return (true);
+}
+
+void
+fusb_ephandle_darwin::run_thread (void* arg)
+{
+  fusb_ephandle_darwin* This = static_cast<fusb_ephandle_darwin*>(arg);
+  mld_mutex_ptr l_runThreadRunning = This->d_runThreadRunning;
+  l_runThreadRunning->lock ();
+
+  mld_mutex_ptr l_readRunning = This->d_readRunning;
+  mld_condition_ptr l_readBlock = This->d_readBlock;
+
+  bool l_input_p = This->d_input_p;
+
+  if (usb_debug)
+    fprintf (stderr, "fusb_ephandle_darwin::run_thread: "
+            "starting for %s.\n",
+            l_input_p ? "read" : "write");
+
+  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 ();
+
+  mld_thread_ptr l_rwThread = NULL;
+
+  if (l_input_p) {
+    l_rwThread = new mld_thread (read_thread, arg);
+// wait until the the rwThread is -really- going
+    l_readBlock->wait ();
+  }
+
+// now signal the run condition to release and finish ::start()
+  This->d_runBlock->signal ();
+
+// run the loop
+  CFRunLoopRun ();
+
+  if (l_input_p) {
+// wait for read_thread () to finish
+    l_readRunning->lock ();
+    l_readRunning->unlock ();
+  }
+
+// remove run loop stuff
+  CFRunLoopRemoveSource (CFRunLoopGetCurrent (),
+                        l_cfSource, kCFRunLoopDefaultMode);
+
+  if (usb_debug)
+    fprintf (stderr, "fusb_ephandle_darwin::run_thread: finished for %s.\n",
+            l_input_p ? "read" : "write");
+
+  l_runThreadRunning->unlock ();
+}
+
+void
+fusb_ephandle_darwin::read_thread (void* arg)
+{
+  if (usb_debug)
+    fprintf (stderr, "fusb_ephandle_darwin::read_thread: starting.\n");
+
+  fusb_ephandle_darwin* This = static_cast<fusb_ephandle_darwin*>(arg);
+
+  mld_mutex_ptr l_readRunning = This->d_readRunning;
+  l_readRunning->lock ();
+
+// signal the read condition from run_thread() to continue
+  mld_condition_ptr l_readBlock = This->d_readBlock;
+  l_readBlock->signal ();
+
+  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)
+    fprintf (stderr, "fusb_ephandle_darwin::read_thread: finished.\n");
+
+  l_readRunning->unlock ();
+}
+
+void
+fusb_ephandle_darwin::read_issue (s_both_ptr l_both)
+{
+  if ((! l_both) || (! d_started))
+    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
+  UInt32 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));
+}
+
+void
+fusb_ephandle_darwin::read_completed (void* refCon,
+                                     io_return_t result,
+                                     void* io_size)
+{
+  UInt32 l_size = (UInt32) 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 ();
+  UInt32 l_i_size = l_buf->n_used ();
+
+  if (This->d_started && (l_i_size != l_size))
+    fprintf (stderr, "fusb_ephandle_darwin::read_completed: "
+            "Expected %ld bytes; read %ld.\n",
+            l_i_size, l_size);
+
+// add this read to the transfer buffer
+  if (l_buffer->enqueue (l_buf->buffer (), l_size) == -1) {
+    fputs ("iU", 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)
+{
+  UInt32 l_nbytes = (UInt32) nbytes;
+  d_buffer->dequeue ((char*) buffer, &l_nbytes);
+  return ((int) l_nbytes);
+}
+
+int
+fusb_ephandle_darwin::write (const void* buffer, int nbytes)
+{
+  UInt32 l_nbytes = (UInt32) nbytes;
+
+  if (! d_started) return (0);
+
+  while (l_nbytes != 0) {
+// find out how much data to copy; limited to "d_bufLenBytes" per node
+    UInt32 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, l_nbytes,
+        (IOAsyncCallback1) write_completed, (void*) l_both);
+    else
+      result = d_interface->WritePipeAsyncTO
+       (d_interfaceRef, d_pipeRef, v_buffer, l_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));
+    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 ());
+  UInt32 l_size = (UInt32) 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 ();
+  UInt32 l_i_size = l_buf->n_used ();
+
+  if (This->d_started && (l_i_size != l_size))
+    fprintf (stderr, "fusb_ephandle_darwin::write_completed: "
+            "Expected %ld bytes written; wrote %ld.\n",
+            l_i_size, l_size);
+
+// 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)
+    fprintf (stderr, "fusb_ephandle_darwin::abort: starting.\n");
+
+  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)
+    fprintf (stderr, "fusb_ephandle_darwin::abort: finished.\n");
+}
+
+bool
+fusb_ephandle_darwin::stop ()
+{
+  if (! d_started)
+    return (true);
+
+  if (usb_debug)
+    fprintf (stderr, "fusb_ephandle_darwin::stop: stopping %s.\n",
+            d_input_p ? "read" : "write");
+
+  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
+  d_runThreadRunning->lock ();
+  d_runThreadRunning->unlock ();
+
+  if (usb_debug)
+    fprintf (stderr, "fusb_ephandle_darwin::stop: %s stopped.\n",
+            d_input_p ? "read" : "write");
+
+  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..601f39a
--- /dev/null
@@ -0,0 +1,215 @@
+/* -*- 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 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.
+ */
+
+#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;
+  UInt32 d_n_used, d_n_alloc;
+
+public:
+  inline s_buffer (UInt32 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 UInt32 n_used () { return (d_n_used); };
+  inline void n_used (UInt32 bufLen) {
+    d_n_used = (bufLen > d_n_alloc) ? d_n_alloc : bufLen; };
+  inline UInt32 n_alloc () { return (d_n_alloc); };
+  void buffer (char* l_buffer, UInt32 bufLen) {
+    if (bufLen > d_n_alloc) {
+      fprintf (stderr, "s_buffer::set: Copying only allocated bytes.\n");
+      bufLen = d_n_alloc;
+    }
+    if (!l_buffer) {
+      fprintf (stderr, "s_buffer::set: NULL buffer.\n");
+      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;
+  mld_thread_ptr d_runThread;
+  mld_mutex_ptr 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;
+  UInt32 d_bufLenBytes;
+  mld_mutex_ptr d_readRunning;
+  mld_condition_ptr d_runBlock, 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..0013632
--- /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 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.
+ */
+
+#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..93ae77f
--- /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 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.
+ */
+
+#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_linux.cc b/usrp/host/lib/fusb_linux.cc
new file mode 100644 (file)
index 0000000..2fe244f
--- /dev/null
@@ -0,0 +1,684 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <fusb_linux.h>
+#include <usb.h>               // libusb header
+#include <stdexcept>
+#include <linux/compiler.h>
+#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>
+
+#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.
+ */
+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 ())
+    _reap (true);
+}
+\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;
+  
+  d_devhandle->_cancel_pending_rqsts (this);
+  d_devhandle->_reap (false);
+
+
+  usbdevfs_urb *urb;
+  while ((urb = completed_list_get ()) != 0)
+    free_list_add (urb);
+
+  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;
+  }
+
+  if (d_free_list.size () != (unsigned) d_nblocks)
+    fprintf (stderr, "d_free_list.size () = %d, d_nblocks = %d\n",
+            d_free_list.size (), d_nblocks);
+    
+  assert (d_free_list.size () == (unsigned) d_nblocks);
+
+  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();
+    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 ();
+    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.
+
+    d_devhandle->_reap (true);
+  }
+}
+
+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)
+      d_devhandle->_reap (true);
+
+    // check result of completed read
+
+    if (urb->status != 0){
+      // We've got a problem.
+      // Report the problem and resubmit.
+      fprintf (stderr, "fusb: (rd status %d) %s\n", urb->status, strerror (-urb->status));
+      urb->actual_length = 0;
+      if (!submit_urb (urb))
+       return false;
+
+      continue;
+    }
+
+    // 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..9b70918
--- /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 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.
+ */
+
+// 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_sysconfig_darwin.cc b/usrp/host/lib/fusb_sysconfig_darwin.cc
new file mode 100644 (file)
index 0000000..3a4fcf9
--- /dev/null
@@ -0,0 +1,37 @@
+/* -*- 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 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.
+ */
+
+#include <fusb.h>
+#include <fusb_darwin.h>
+
+static const int MAX_BLOCK_SIZE = 32 * 1024;           // hard limit
+
+fusb_devhandle *
+fusb_sysconfig::make_devhandle (usb_dev_handle *udh)
+{
+  return new fusb_devhandle_darwin (udh);
+}
+
+int fusb_sysconfig::max_block_size ()
+{
+  return MAX_BLOCK_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..6fa2e48
--- /dev/null
@@ -0,0 +1,37 @@
+/* -*- 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 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.
+ */
+
+#include <fusb.h>
+#include <fusb_generic.h>
+
+static const int MAX_BLOCK_SIZE = 16 * 1024;           // hard limit
+
+fusb_devhandle *
+fusb_sysconfig::make_devhandle (usb_dev_handle *udh)
+{
+  return new fusb_devhandle_generic (udh);
+}
+       
+int fusb_sysconfig::max_block_size ()
+{
+  return MAX_BLOCK_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..f7fc5d6
--- /dev/null
@@ -0,0 +1,37 @@
+/* -*- 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 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.
+ */
+
+#include <fusb.h>
+#include <fusb_linux.h>
+
+static const int MAX_BLOCK_SIZE = 16 * 1024;           // hard limit
+
+fusb_devhandle *
+fusb_sysconfig::make_devhandle (usb_dev_handle *udh)
+{
+  return new fusb_devhandle_linux (udh);
+}
+
+int fusb_sysconfig::max_block_size ()
+{
+  return MAX_BLOCK_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..b2b6cb1
--- /dev/null
@@ -0,0 +1,37 @@
+/* -*- 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 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.
+ */
+
+#include <fusb.h>
+#include <fusb_win32.h>
+
+static const int MAX_BLOCK_SIZE = 64 * 1024;           // Windows kernel hard limit
+       
+fusb_devhandle *
+fusb_sysconfig::make_devhandle (usb_dev_handle *udh)
+{
+  return new fusb_devhandle_win32 (udh);
+}
+
+int fusb_sysconfig::max_block_size ()
+{
+  return MAX_BLOCK_SIZE;
+}
diff --git a/usrp/host/lib/fusb_win32.cc b/usrp/host/lib/fusb_win32.cc
new file mode 100644 (file)
index 0000000..494a6be
--- /dev/null
@@ -0,0 +1,265 @@
+/* -*- 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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <fusb_win32.h>
+#include <usb.h>
+#include <assert.h>
+#include <stdexcept>
+
+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);
+
+       if (bytes_to_write == 0)
+               return nbytes;
+
+       assert(d_output_short == 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;
+      }
+  }
+
+  memcpy(buf, (void *) &(((char*)buffer)[a]), bytes_to_write);
+
+  d_output_short = d_block_size - bytes_to_write;
+  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);
+
+       if (bytes_to_read == 0)
+               return nbytes;
+
+       assert(d_input_leftover == 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());
+
+  memcpy((void *) &(((char*)buffer)[a]), buf, bytes_to_read);
+
+  d_input_leftover = d_block_size - bytes_to_read;
+  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..77435d0
--- /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 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.
+ */
+
+#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..34a994f
--- /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('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 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.
+ */
+
+#include <usrp_prims.h>
+#include <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/md5.c b/usrp/host/lib/md5.c
new file mode 100644 (file)
index 0000000..9fbed5b
--- /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 2, 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.  */
+
+/* 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..2b33607
--- /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 2, 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.  */
+
+#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/mld_threads.h b/usrp/host/lib/mld_threads.h
new file mode 100644 (file)
index 0000000..ae6253e
--- /dev/null
@@ -0,0 +1,257 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio.
+ *
+ * Primary Author: Michael Dickens, NCIP Lab, University of Notre Dame
+ * 
+ * GNU Radio is free software; you can 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.
+ */
+
+#ifndef _INCLUDED_MLD_THREADS_H_
+#define _INCLUDED_MLD_THREADS_H_
+
+/* classes which allow for either pthreads or omni_threads */
+
+#ifdef _USE_OMNI_THREADS_
+#include <gnuradio/omnithread.h>
+#else
+#include <pthread.h>
+#endif
+
+#include <stdexcept>
+
+#define __INLINE__ inline
+
+class mld_condition_t;
+
+class mld_mutex_t {
+#ifdef _USE_OMNI_THREADS_
+  typedef omni_mutex l_mutex, *l_mutex_ptr;
+#else
+  typedef pthread_mutex_t l_mutex, *l_mutex_ptr;
+#endif
+
+  friend class mld_condition_t;
+
+private:
+  l_mutex_ptr d_mutex;
+
+protected:
+  inline l_mutex_ptr mutex () { return (d_mutex); };
+
+public:
+  __INLINE__ mld_mutex_t () {
+#ifdef _USE_OMNI_THREADS_
+    d_mutex = new omni_mutex ();
+#else
+    d_mutex = (l_mutex_ptr) new l_mutex;
+    int l_ret = pthread_mutex_init (d_mutex, NULL);
+    if (l_ret != 0) {
+      fprintf (stderr, "Error %d creating mutex.\n", l_ret);
+      throw std::runtime_error ("mld_mutex_t::mld_mutex_t()\n");
+    }
+#endif
+  };
+
+  __INLINE__ ~mld_mutex_t () {
+    unlock ();
+#ifndef _USE_OMNI_THREADS_
+    int l_ret = pthread_mutex_destroy (d_mutex);
+    if (l_ret != 0) {
+      fprintf (stderr, "mld_mutex_t::~mld_mutex_t(): "
+              "Error %d destroying mutex.\n", l_ret);
+    }
+#endif
+    delete d_mutex;
+    d_mutex = NULL;
+  };
+
+  __INLINE__ void lock () {
+#ifdef _USE_OMNI_THREADS_
+    d_mutex->lock ();
+#else
+    int l_ret = pthread_mutex_lock (d_mutex);
+    if (l_ret != 0) {
+      fprintf (stderr, "mld_mutex_t::lock(): "
+              "Error %d locking mutex.\n", l_ret);
+    }
+#endif
+  };
+
+  __INLINE__ void unlock () {
+#ifdef _USE_OMNI_THREADS_
+    d_mutex->unlock ();
+#else
+    int l_ret = pthread_mutex_unlock (d_mutex);
+    if (l_ret != 0) {
+      fprintf (stderr, "mld_mutex_t::unlock(): "
+              "Error %d locking mutex.\n", l_ret);
+    }
+#endif
+  };
+
+  __INLINE__ bool trylock () {
+#ifdef _USE_OMNI_THREADS_
+    int l_ret = d_mutex->trylock ();
+#else
+    int l_ret = pthread_mutex_unlock (d_mutex);
+#endif
+    return (l_ret == 0 ? true : false);
+  };
+
+  inline void acquire () { lock(); };
+  inline void release () { unlock(); };
+  inline void wait () { lock(); };
+  inline void post () { unlock(); };
+};
+
+typedef mld_mutex_t mld_mutex, *mld_mutex_ptr;
+
+class mld_condition_t {
+#ifdef _USE_OMNI_THREADS_
+  typedef omni_condition l_condition, *l_condition_ptr;
+#else
+  typedef pthread_cond_t l_condition, *l_condition_ptr;
+#endif
+
+private:
+  l_condition_ptr d_condition;
+  mld_mutex_ptr d_mutex;
+  bool d_waiting;
+
+public:
+  __INLINE__ mld_condition_t () {
+    d_waiting = false;
+    d_mutex = new mld_mutex ();
+#ifdef _USE_OMNI_THREADS_
+    d_condition = new omni_condition (d_mutex->mutex ());
+#else
+    d_condition = (l_condition_ptr) new l_condition;
+    int l_ret = pthread_cond_init (d_condition, NULL);
+    if (l_ret != 0) {
+      fprintf (stderr, "Error %d creating condition.\n", l_ret);
+      throw std::runtime_error ("mld_condition_t::mld_condition_t()\n");
+    }
+#endif
+  };
+
+  __INLINE__ ~mld_condition_t () {
+    signal ();
+#ifndef _USE_OMNI_THREADS_
+    int l_ret = pthread_cond_destroy (d_condition);
+    if (l_ret != 0) {
+      fprintf (stderr, "mld_condition_t::mld_condition_t(): "
+              "Error %d destroying condition.\n", l_ret);
+    }
+#endif
+    delete d_condition;
+    d_condition = NULL;
+    delete d_mutex;
+    d_mutex = NULL;
+  };
+
+  __INLINE__ void signal () {
+    if (d_waiting == true) {
+#ifdef _USE_OMNI_THREADS_
+      d_condition->signal ();
+#else
+      int l_ret = pthread_cond_signal (d_condition);
+      if (l_ret != 0) {
+       fprintf (stderr, "mld_condition_t::signal(): "
+                "Error %d.\n", l_ret);
+      }
+#endif
+      d_waiting = false;
+    }
+  };
+
+  __INLINE__ void wait () {
+    if (d_waiting == false) {
+      d_waiting = true;
+#ifdef _USE_OMNI_THREADS_
+      d_condition->wait ();
+#else
+      int l_ret = pthread_cond_wait (d_condition, d_mutex->mutex ());
+      if (l_ret != 0) {
+       fprintf (stderr, "mld_condition_t::wait(): "
+                "Error %d.\n", l_ret);
+      }
+#endif
+    }
+  };
+};
+
+typedef mld_condition_t mld_condition, *mld_condition_ptr;
+
+class mld_thread_t {
+#ifdef _USE_OMNI_THREADS_
+  typedef omni_thread l_thread, *l_thread_ptr;
+#else
+  typedef pthread_t l_thread, *l_thread_ptr;
+#endif
+
+private:
+#ifndef _USE_OMNI_THREADS_
+  l_thread d_thread;
+  void (*d_start_routine)(void*);
+  void *d_arg;
+#else
+  l_thread_ptr d_thread;
+#endif
+
+#ifndef _USE_OMNI_THREADS_
+  static void* local_start_routine (void *arg) {
+    mld_thread_t* This = (mld_thread_t*) arg;
+    (*(This->d_start_routine))(This->d_arg);
+    return (NULL);
+  };
+#endif
+
+public:
+  __INLINE__ mld_thread_t (void (*start_routine)(void *), void *arg) {
+#ifdef _USE_OMNI_THREADS_
+    d_thread = new omni_thread (start_routine, arg);
+    d_thread->start ();
+#else
+    d_start_routine = start_routine;
+    d_arg = arg;
+    int l_ret = pthread_create (&d_thread, NULL, local_start_routine, this);
+    if (l_ret != 0) {
+      fprintf (stderr, "Error %d creating thread.\n", l_ret);
+      throw std::runtime_error ("mld_thread_t::mld_thread_t()\n");
+    }
+#endif
+  };
+
+  __INLINE__ ~mld_thread_t () {
+#ifdef _USE_OMNI_THREADS_
+//  delete d_thread;
+    d_thread = NULL;
+#else
+    int l_ret = pthread_detach (d_thread);
+    if (l_ret != 0) {
+      fprintf (stderr, "Error %d detaching thread.\n", l_ret);
+      throw std::runtime_error ("mld_thread_t::~mld_thread_t()\n");
+    }
+#endif
+  };
+};
+
+typedef mld_thread_t mld_thread, *mld_thread_ptr;
+
+#endif /* _INCLUDED_MLD_THREADS_H_ */
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..fe973e3
--- /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 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.
+ */
+
+static 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..2029480
--- /dev/null
@@ -0,0 +1,1239 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003,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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "usrp_basic.h"
+#include "usrp_prims.h"
+#include "usrp_interfaces.h"
+#include "fpga_regs_common.h"
+#include "fusb.h"
+#include <usb.h>
+#include <stdexcept>
+#include <assert.h>
+#include <math.h>
+#include <ad9862.h>
+
+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 = 2 * (1L << 20);    // 2 MB (was 8 MB)
+//static const int FUSB_BUFFER_SIZE = 256 * (1L << 10);        // 256 kB
+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 struct usb_dev_handle *
+open_rx_interface (struct usb_device *dev)
+{
+  struct usb_dev_handle *udh = usrp_open_rx_interface (dev);
+  if (udh == 0){
+    fprintf (stderr, "usrp_basic_rx: can't open rx interface\n");
+    usb_strerror ();
+  }
+  return udh;
+}
+
+static struct usb_dev_handle *
+open_tx_interface (struct usb_device *dev)
+{
+  struct usb_dev_handle *udh = usrp_open_tx_interface (dev);
+  if (udh == 0){
+    fprintf (stderr, "usrp_basic_tx: can't open tx interface\n");
+    usb_strerror ();
+  }
+  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, 
+                       struct usb_dev_handle *
+                       open_interface (struct usb_device *dev),
+                       const std::string fpga_filename,
+                       const std::string firmware_filename)
+  : d_udh (0),
+    d_usb_data_rate (16000000),        // SWAG, see below
+    d_bytes_per_poll ((int) (POLLING_INTERVAL * d_usb_data_rate)),
+    d_verbose (false)
+{
+  /*
+   * 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 ();
+
+  if (!usrp_load_standard_bits (which_board, false, fpga_filename, firmware_filename))
+    throw std::runtime_error ("usrp_basic/usrp_load_standard_bits");
+
+  struct usb_device *dev = usrp_find_device (which_board);
+  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 ()
+{
+  if (d_udh)
+    usb_close (d_udh);
+}
+
+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, int offset)
+{
+  if (which < 0 || which > 3)
+    return false;
+
+  return _write_fpga_reg (FR_ADC_OFFSET_0 + which, offset);
+}
+
+bool
+usrp_basic::set_dac_offset (int which, int offset, int offset_pin)
+{
+  if (which < 0 || which > 3)
+    return false;
+
+  int which_codec = which >> 1;
+  int tx_a = (which & 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, bool bypass)
+{
+  if (which < 0 || which > 3)
+    return false;
+
+  int codec = which >> 1;
+  int reg = (which & 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 & 1) == 0) ? RX_PWR_DN_BUF_A : RX_PWR_DN_BUF_B;
+  }
+  else {
+    cur_rx &= ~RX_X_BYPASS_INPUT_BUFFER;
+    cur_pwr_dn &= ~(((which & 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::_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, bool on)
+{
+  return usrp_set_led (d_udh, which, on);
+}
+
+////////////////////////////////////////////////////////////////
+//
+//                        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);
+
+  // 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_ephandle = d_devhandle->make_ephandle (USRP_RX_ENDPOINT, true,
+                                          fusb_block_size, fusb_nblocks);
+
+  _write_fpga_reg(FR_ATR_MASK_1, 0);   // zero Rx side Auto Transmit/Receive regs
+  _write_fpga_reg(FR_ATR_TXVAL_1, 0);
+  _write_fpga_reg(FR_ATR_RXVAL_1, 0);
+  _write_fpga_reg(FR_ATR_MASK_3, 0);
+  _write_fpga_reg(FR_ATR_TXVAL_3, 0);
+  _write_fpga_reg(FR_ATR_RXVAL_3, 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");
+    usb_strerror ();
+  }
+
+  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");
+  }
+}
+
+
+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");
+    usb_strerror ();
+    return false;
+  }
+
+  if (!set_rx_enable (true)){
+    fprintf (stderr, "usrp_basic_rx: set_rx_enable failed\n");
+    usb_strerror ();
+    return false;
+  }
+  
+  return true;
+}
+
+bool
+usrp_basic_rx::stop ()
+{
+  bool ok = usrp_basic::stop();
+
+  if (!d_ephandle->stop()){
+    fprintf (stderr, "usrp_basic_rx: failed to stop end point streaming");
+    usb_strerror ();
+    ok = false;
+  }
+  if (!set_rx_enable(false)){
+    fprintf (stderr, "usrp_basic_rx: set_rx_enable(false) failed\n");
+    usb_strerror ();
+    ok = false;
+  }
+  return false;
+}
+
+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");
+      usb_strerror ();
+    }
+  }
+    
+  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);
+}
+
+bool
+usrp_basic_rx::set_pga (int which, double gain)
+{
+  if (which < 0 || which > 3)
+    return false;
+
+  gain = std::max (pga_min (), gain);
+  gain = std::min (pga_max (), gain);
+
+  int codec = which >> 1;
+  int reg = (which & 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;
+
+  int int_gain = (int) rint ((gain - pga_min ()) / pga_db_per_step());
+
+  cur_rx = (cur_rx & RX_X_BYPASS_INPUT_BUFFER) | (int_gain & 0x7f);
+  return _write_9862 (codec, reg, cur_rx);
+}
+
+double
+usrp_basic_rx::pga (int which) const
+{
+  if (which < 0 || which > 3)
+    return READ_FAILED;
+
+  int codec = which >> 1;
+  int reg = (which & 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();
+}
+
+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];
+}
+
+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::_write_oe (int which_dboard, int value, int mask)
+{
+  if (! (0 <= which_dboard && which_dboard <= 1))
+    return false;
+
+  return _write_fpga_reg (slot_id_to_oe_reg (dboard_to_slot (which_dboard)),
+                         (mask << 16) | (value & 0xffff));
+}
+
+bool
+usrp_basic_rx::write_io (int which_dboard, int value, int mask)
+{
+  if (! (0 <= which_dboard && which_dboard <= 1))
+    return false;
+
+  return _write_fpga_reg (slot_id_to_io_reg (dboard_to_slot (which_dboard)),
+                         (mask << 16) | (value & 0xffff));
+}
+
+bool
+usrp_basic_rx::read_io (int which_dboard, int *value)
+{
+  if (! (0 <= which_dboard && which_dboard <= 1))
+    return false;
+
+  int t;
+  int reg = which_dboard + 1;  // FIXME, *very* magic number (fix in serial_io.v)
+  bool ok = _read_fpga_reg (reg, &t);
+  if (!ok)
+    return false;
+
+  *value = (t >> 16) & 0xffff; // FIXME, more magic
+  return true;
+}
+
+int
+usrp_basic_rx::read_io (int which_dboard)
+{
+  int  value;
+  if (!read_io (which_dboard, &value))
+    return READ_FAILED;
+  return value;
+}
+
+bool
+usrp_basic_rx::write_aux_dac (int which_dboard, int which_dac, int value)
+{
+  return usrp_basic::write_aux_dac (dboard_to_slot (which_dboard),
+                                   which_dac, value);
+}
+
+bool
+usrp_basic_rx::read_aux_adc (int which_dboard, int which_adc, int *value)
+{
+  return usrp_basic::read_aux_adc (dboard_to_slot (which_dboard),
+                                  which_adc, value);
+}
+
+int
+usrp_basic_rx::read_aux_adc (int which_dboard, int which_adc)
+{
+  return usrp_basic::read_aux_adc (dboard_to_slot (which_dboard), which_adc);
+}
+
+int
+usrp_basic_rx::block_size () const { return d_ephandle->block_size(); }
+
+bool
+usrp_basic_rx::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));
+}
+
+////////////////////////////////////////////////////////////////
+//
+//                        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);
+
+  // 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_ephandle = d_devhandle->make_ephandle (USRP_TX_ENDPOINT, false,
+                                          fusb_block_size, fusb_nblocks);
+
+  _write_fpga_reg(FR_ATR_MASK_0, 0); // zero Tx side Auto Transmit/Receive regs
+  _write_fpga_reg(FR_ATR_TXVAL_0, 0);
+  _write_fpga_reg(FR_ATR_RXVAL_0, 0);
+  _write_fpga_reg(FR_ATR_MASK_2, 0);
+  _write_fpga_reg(FR_ATR_TXVAL_2, 0);
+  _write_fpga_reg(FR_ATR_RXVAL_2, 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");
+  }
+}
+
+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");
+    usb_strerror ();
+    return false;
+  }
+  
+  if (!d_ephandle->start ()){
+    fprintf (stderr, "usrp_basic_tx: failed to start end point streaming");
+    usb_strerror ();
+    return false;
+  }
+
+  return true;
+}
+
+bool
+usrp_basic_tx::stop ()
+{
+  bool ok = usrp_basic::stop ();
+
+  if (!set_tx_enable (false)){
+    fprintf (stderr, "usrp_basic_tx: set_tx_enable(false) failed\n");
+    usb_strerror ();
+    ok = false;
+  }
+  if (!d_ephandle->stop ()){
+    fprintf (stderr, "usrp_basic_tx: failed to stop end point streaming");
+    usb_strerror ();
+    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");
+      usb_strerror ();
+    }
+  }
+
+  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);
+}
+
+bool
+usrp_basic_tx::set_pga (int which, double gain)
+{
+  if (which < 0 || which > 3)
+    return false;
+
+  gain = std::max (pga_min (), gain);
+  gain = std::min (pga_max (), gain);
+
+  int codec = which >> 1;      // 0 and 1 are same, as are 2 and 3
+
+  int int_gain = (int) rint ((gain - pga_min ()) / pga_db_per_step());
+
+  return _write_9862 (codec, REG_TX_PGA, int_gain);
+}
+
+double
+usrp_basic_tx::pga (int which) const
+{
+  if (which < 0 || which > 3)
+    return READ_FAILED;
+
+  int codec = which >> 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();
+}
+
+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::_write_oe (int which_dboard, int value, int mask)
+{
+  if (! (0 <= which_dboard && which_dboard <= 1))
+    return false;
+
+  return _write_fpga_reg (slot_id_to_oe_reg (dboard_to_slot (which_dboard)),
+                         (mask << 16) | (value & 0xffff));
+}
+
+bool
+usrp_basic_tx::write_io (int which_dboard, int value, int mask)
+{
+  if (! (0 <= which_dboard && which_dboard <= 1))
+    return false;
+
+  return _write_fpga_reg (slot_id_to_io_reg (dboard_to_slot (which_dboard)),
+                         (mask << 16) | (value & 0xffff));
+}
+
+bool
+usrp_basic_tx::read_io (int which_dboard, int *value)
+{
+  if (! (0 <= which_dboard && which_dboard <= 1))
+    return false;
+
+  int t;
+  int reg = which_dboard + 1;  // FIXME, *very* magic number (fix in serial_io.v)
+  bool ok = _read_fpga_reg (reg, &t);
+  if (!ok)
+    return false;
+
+  *value = t & 0xffff;         // FIXME, more magic
+  return true;
+}
+
+int
+usrp_basic_tx::read_io (int which_dboard)
+{
+  int  value;
+  if (!read_io (which_dboard, &value))
+    return READ_FAILED;
+  return value;
+}
+
+bool
+usrp_basic_tx::write_aux_dac (int which_dboard, int which_dac, int value)
+{
+  return usrp_basic::write_aux_dac (dboard_to_slot (which_dboard),
+                                   which_dac, value);
+}
+
+bool
+usrp_basic_tx::read_aux_adc (int which_dboard, int which_adc, int *value)
+{
+  return usrp_basic::read_aux_adc (dboard_to_slot (which_dboard),
+                                  which_adc, value);
+}
+
+int
+usrp_basic_tx::read_aux_adc (int which_dboard, int which_adc)
+{
+  return usrp_basic::read_aux_adc (dboard_to_slot (which_dboard), which_adc);
+}
+
+int
+usrp_basic_tx::block_size () const { return d_ephandle->block_size(); }
+
diff --git a/usrp/host/lib/usrp_basic.h b/usrp/host/lib/usrp_basic.h
new file mode 100644 (file)
index 0000000..df775c5
--- /dev/null
@@ -0,0 +1,776 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003,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.
+ */
+
+/*
+ * ----------------------------------------------------------------------
+ * 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.
+ * ----------------------------------------------------------------------
+ */
+
+#ifndef INCLUDED_USRP_BASIC_H
+#define INCLUDED_USRP_BASIC_H
+
+#include <usrp_slots.h>
+#include <string>
+
+struct usb_dev_handle;
+class  fusb_devhandle;
+class  fusb_ephandle;
+
+/*!
+ * \brief base class for usrp operations
+ */
+class usrp_basic
+{
+private:
+  // NOT IMPLEMENTED
+  usrp_basic (const usrp_basic &rhs);                  // no copy constructor
+  usrp_basic &operator= (const usrp_basic &rhs);       // no assignment operator
+
+  
+protected:
+  struct usb_dev_handle        *d_udh;
+  int                   d_usb_data_rate;       // bytes/sec
+  int                   d_bytes_per_poll;      // how often to poll for overruns
+  bool                  d_verbose;
+
+  static const int      MAX_REGS = 128;
+  unsigned int          d_fpga_shadows[MAX_REGS];
+
+  usrp_basic (int which_board,
+             struct usb_dev_handle *open_interface (struct usb_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 ();
+
+  /*!
+   * \brief return frequency of master oscillator on USRP
+   */
+  long  fpga_master_clock_freq () const { return 64000000; }
+
+  /*!
+   * \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      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, int offset);
+
+  /*!
+   * \brief Set DAC offset correction
+   * \param which      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, int offset, int offset_pin);
+
+  /*!
+   * \brief Control ADC input buffer
+   * \param which      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, bool bypass);
+
+
+  /*!
+   * \brief return the usrp's serial number.
+   *
+   * \returns non-zero length string iff successful.
+   */
+  std::string serial_number();
+
+  // ----------------------------------------------------------------
+  // Low level implementation routines.
+  // You probably shouldn't be using these...
+  //
+
+  bool _set_led (int which, 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
+ */
+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:
+  int                   d_dbid[2];             // Rx daughterboard ID's
+
+  /*!
+   * \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. 
+   */
+  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);
+  int  dboard_to_slot (int dboard) { return (dboard << 1) | 1; }
+
+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. 
+   */
+  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 = ""
+                             );
+
+  // MANIPULATORS
+
+  /*!
+   * \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);
+
+  // ACCESSORS
+
+  //! sampling rate of A/D converter
+  virtual long converter_rate() const { return fpga_master_clock_freq(); } // 64M
+  long adc_rate() const { return converter_rate(); }
+  long adc_freq() const { return converter_rate(); }   //!< deprecated method name
+
+  /*!
+   * \brief Return daughterboard ID for given Rx daughterboard slot [0,1].
+   *
+   * \param which_dboard       [0,1] which Rx daughterboard
+   *
+   * \return daughterboard id >= 0 if successful
+   * \return -1 if no daugherboard
+   * \return -2 if invalid EEPROM on daughterboard
+   */
+  int daughterboard_id (int which_dboard) const { return d_dbid[which_dboard & 0x1]; }
+
+  // ----------------------------------------------------------------
+  // routines for controlling the Programmable Gain Amplifier
+  /*!
+   * \brief Set Programmable Gain Amplifier (PGA)
+   *
+   * \param which      which A/D [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 set_pga (int which, double gain_in_db);
+
+  /*!
+   * \brief Return programmable gain amplifier gain setting in dB.
+   *
+   * \param which      which A/D [0,3]
+   */
+  double pga (int which) const;
+
+  /*!
+   * \brief Return minimum legal PGA gain in dB.
+   */
+  double pga_min () const { return 0.0; }
+
+  /*!
+   * \brief Return maximum legal PGA gain in dB.
+   */
+  double pga_max () const { return 20.0; }
+
+  /*!
+   * \brief Return hardware step size of PGA (linear in dB).
+   */
+  double pga_db_per_step () const { return 20.0 / 20; }
+
+  /*!
+   * \brief Write direction register (output enables) for pins that go to daughterboard.
+   *
+   * \param which_dboard       [0,1] which d'board
+   * \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 _write_oe (int which_dboard, int value, int mask);
+
+  /*!
+   * \brief Write daughterboard i/o pin value
+   *
+   * \param which_dboard       [0,1] which d'board
+   * \param value              value to write into register
+   * \param mask               which bits of value to write into reg
+   */
+  bool write_io (int which_dboard, int value, int mask);
+
+  /*!
+   * \brief Read daughterboard i/o pin value
+   *
+   * \param which_dboard       [0,1] which d'board
+   * \param value              output
+   */
+  bool read_io (int which_dboard, int *value);
+
+  /*!
+   * \brief Read daughterboard i/o pin value
+   *
+   * \param which_dboard       [0,1] which d'board
+   * \returns register value if successful, else READ_FAILED
+   */
+  int read_io (int which_dboard);
+
+  /*!
+   * \brief Write auxiliary digital to analog converter.
+   *
+   * \param which_dboard       [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 write_aux_dac (int which_board, int which_dac, int value);
+
+  /*!
+   * \brief Read auxiliary analog to digital converter.
+   *
+   * \param which_dboard       [0,1] which d'board
+   * \param which_adc          [0,1]
+   * \param value              return 12-bit value [0,4095]
+   * \returns true iff successful
+   */
+  bool read_aux_adc (int which_dboard, int which_adc, int *value);
+
+  /*!
+   * \brief Read auxiliary analog to digital converter.
+   *
+   * \param which_dboard       [0,1] which d'board
+   * \param which_adc          [0,1]
+   * \returns value in the range [0,4095] if successful, else READ_FAILED.
+   */
+  int read_aux_adc (int which_dboard, int which_adc);
+
+  /*!
+   * \brief returns current fusb block size
+   */
+  int block_size() const;
+
+  /*!
+   * \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);
+
+  // called in base class to derived class order
+  bool start ();
+  bool stop ();
+};
+
+\f/*!
+ * \brief class for accessing the transmit side of the 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:
+  int                   d_dbid[2];             // Tx daughterboard ID's
+
+  /*!
+   * \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.
+   */
+  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);
+  int  dboard_to_slot (int dboard) { return (dboard << 1) | 0; }
+
+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. 
+   */
+  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 = ""
+                             );
+
+  // MANIPULATORS
+
+  /*!
+   * \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 ();
+
+  // ACCESSORS
+
+  //! 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(); }
+  long dac_freq() const { return converter_rate(); }   //!< deprecated method name
+
+  /*!
+   * \brief Return daughterboard ID for given Tx daughterboard slot [0,1].
+   *
+   * \return daughterboard id >= 0 if successful
+   * \return -1 if no daugherboard
+   * \return -2 if invalid EEPROM on daughterboard
+   */
+  int daughterboard_id (int which_dboard) const { return d_dbid[which_dboard & 0x1]; }
+
+  // ----------------------------------------------------------------
+  // routines for controlling the Programmable Gain Amplifier
+  /*!
+   * \brief Set Programmable Gain Amplifier (PGA)
+   *
+   * \param which      which D/A [0,3]
+   * \param gain_in_db gain value (linear in dB)
+   *
+   * gain is rounded to closest setting supported by hardware.
+   * Note that DAC 0 and DAC 1 share a gain setting as do DAC 2 and DAC 3.
+   * Setting DAC 0 affects DAC 1 and vice versa.  Same with DAC 2 and DAC 3.
+   *
+   * \returns true iff sucessful.
+   *
+   * \sa pga_min(), pga_max(), pga_db_per_step()
+   */
+  bool set_pga (int which, double gain_in_db);
+
+  /*!
+   * \brief Return programmable gain amplifier gain in dB.
+   *
+   * \param which      which D/A [0,3]
+   */
+  double pga (int which) const;
+
+  /*!
+   * \brief Return minimum legal PGA gain in dB.
+   */
+  double pga_min () const { return -20.0; }
+
+  /*!
+   * \brief Return maximum legal PGA gain in dB.
+   */
+  double pga_max () const { return 0.0; }
+
+  /*!
+   * \brief Return hardware step size of PGA (linear in dB).
+   */
+  double pga_db_per_step () const { return 20.0/255; }
+
+  /*!
+   * \brief Write direction register (output enables) for pins that go to daughterboard.
+   *
+   * \param which_dboard       [0,1] which d'board
+   * \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 _write_oe (int which_dboard, int value, int mask);
+
+  /*!
+   * \brief Write daughterboard i/o pin value
+   *
+   * \param which_dboard       [0,1] which d'board
+   * \param value              value to write into register
+   * \param mask               which bits of value to write into reg
+   */
+  bool write_io (int which_dboard, int value, int mask);
+
+  /*!
+   * \brief Read daughterboard i/o pin value
+   *
+   * \param which_dboard       [0,1] which d'board
+   * \param value              return value
+   */
+  bool read_io (int which_dboard, int *value);
+
+  /*!
+   * \brief Read daughterboard i/o pin value
+   *
+   * \param which_dboard       [0,1] which d'board
+   * \returns register value if successful, else READ_FAILED
+   */
+  int read_io (int which_dboard);
+
+  /*!
+   * \brief Write auxiliary digital to analog converter.
+   *
+   * \param which_dboard       [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 write_aux_dac (int which_board, int which_dac, int value);
+
+  /*!
+   * \brief Read auxiliary analog to digital converter.
+   *
+   * \param which_dboard       [0,1] which d'board
+   * \param which_adc          [0,1]
+   * \param value              return 12-bit value [0,4095]
+   * \returns true iff successful
+   */
+  bool read_aux_adc (int which_dboard, int which_adc, int *value);
+
+  /*!
+   * \brief Read auxiliary analog to digital converter.
+   *
+   * \param which_dboard       [0,1] which d'board
+   * \param which_adc          [0,1]
+   * \returns value in the range [0,4095] if successful, else READ_FAILED.
+   */
+  int read_aux_adc (int which_dboard, int which_adc);
+
+  /*!
+   * \brief returns current fusb block size
+   */
+  int block_size() const;
+
+  // called in base class to derived class order
+  bool start ();
+  bool stop ();
+};
+
+#endif
diff --git a/usrp/host/lib/usrp_bytesex.h b/usrp/host/lib/usrp_bytesex.h
new file mode 100644 (file)
index 0000000..de34c05
--- /dev/null
@@ -0,0 +1,74 @@
+/* -*- 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 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.
+ */
+#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
+static inline unsigned short int
+bswap_16 (unsigned short int x)
+{
+  return ((((x) >> 8) & 0xff) | (((x) & 0xff) << 8));
+}
+#endif
+
+
+#ifdef WORDS_BIGENDIAN
+
+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 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/lib/usrp_config.cc b/usrp/host/lib/usrp_config.cc
new file mode 100644 (file)
index 0000000..04303cd
--- /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 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.
+ */
+
+#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..3675a10
--- /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 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.
+ */
+
+#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..fe3ed1e
--- /dev/null
@@ -0,0 +1,75 @@
+#
+# 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 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 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 Rev 2_1"       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
+
+"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..567d7d0
--- /dev/null
@@ -0,0 +1,190 @@
+/* -*- 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 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 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_local_sighandler.h>
+#include <stdexcept>
+#include <stdio.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_local_sighandler.h b/usrp/host/lib/usrp_local_sighandler.h
new file mode 100644 (file)
index 0000000..0bb29c2
--- /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 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.
+ */
+
+#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/lib/usrp_prims.cc b/usrp/host/lib/usrp_prims.cc
new file mode 100644 (file)
index 0000000..5d1c26d
--- /dev/null
@@ -0,0 +1,1355 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003,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 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "usrp_prims.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 <usb.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>
+
+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 char *default_firmware_filename = "std.ihx";
+static char *default_fpga_filename     = "std_2rxhb_2tx.rbf";
+
+#include "std_paths.h"
+
+static char *
+find_file (const char *filename, int hw_rev)
+{
+  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 (struct usb_dev_handle *udh);
+
+void
+usrp_one_time_init ()
+{
+  static bool first = true;
+
+  if (first){
+    first = false;
+    usb_init ();                       // usb library init
+    usb_find_busses ();
+    usb_find_devices ();
+  }
+}
+
+void
+usrp_rescan ()
+{
+  usb_find_busses ();
+  usb_find_devices ();
+}
+
+
+// ----------------------------------------------------------------
+// Danger, big, fragile KLUDGE.  The problem is that we want to be
+// able to get from a usb_dev_handle back to a usb_device, and the
+// right way to do this is buried in a non-installed include file.
+
+static struct usb_device *
+dev_handle_to_dev (usb_dev_handle *udh)
+{
+  struct usb_dev_handle_kludge {
+    int                         fd;
+    struct usb_bus     *bus;
+    struct usb_device  *device;
+  };
+
+  return ((struct usb_dev_handle_kludge *) udh)->device;
+}
+
+// ----------------------------------------------------------------
+
+/*
+ * q must be a real USRP, not an FX2.  Return its hardware rev number.
+ */
+int
+usrp_hw_rev (struct usb_device *q)
+{
+  return q->descriptor.bcdDevice & 0x00FF;
+}
+
+/*
+ * q must be a real USRP, not an FX2.  Return true if it's configured.
+ */
+static bool
+_usrp_configured_p (struct usb_device *q)
+{
+  return (q->descriptor.bcdDevice & 0xFF00) != 0;
+}
+
+bool
+usrp_usrp_p (struct usb_device *q)
+{
+  return (q->descriptor.idVendor == USB_VID_FSF
+         && q->descriptor.idProduct == USB_PID_FSF_USRP);
+}
+
+bool
+usrp_fx2_p (struct usb_device *q)
+{
+  return (q->descriptor.idVendor == USB_VID_CYPRESS
+         && q->descriptor.idProduct == USB_PID_CYPRESS_FX2);
+}
+
+bool
+usrp_usrp0_p (struct usb_device *q)
+{
+  return usrp_usrp_p (q) && usrp_hw_rev (q) == 0;
+}
+
+bool
+usrp_usrp1_p (struct usb_device *q)
+{
+  return usrp_usrp_p (q) && usrp_hw_rev (q) == 1;
+}
+
+bool
+usrp_usrp2_p (struct usb_device *q)
+{
+  return usrp_usrp_p (q) && usrp_hw_rev (q) == 2;
+}
+
+
+bool
+usrp_unconfigured_usrp_p (struct usb_device *q)
+{
+  return usrp_usrp_p (q) && !_usrp_configured_p (q);
+}
+
+bool
+usrp_configured_usrp_p (struct usb_device *q)
+{
+  return usrp_usrp_p (q) && _usrp_configured_p (q);
+}
+
+// ----------------------------------------------------------------
+
+struct usb_device *
+usrp_find_device (int nth, bool fx2_ok_p)
+{
+  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
+}
+
+static 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 != dev_handle_to_dev (udh)){
+    fprintf (stderr, "%s:%d: internal error!\n", __FILE__, __LINE__);
+    abort ();
+  }
+
+#if defined(WIN32)
+  // 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...
+
+  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;
+}
+
+struct usb_dev_handle *
+usrp_open_cmd_interface (struct usb_device *dev)
+{
+  return usrp_open_interface (dev, USRP_CMD_INTERFACE, USRP_CMD_ALTINTERFACE);
+}
+
+struct usb_dev_handle *
+usrp_open_rx_interface (struct usb_device *dev)
+{
+  return usrp_open_interface (dev, USRP_RX_INTERFACE, USRP_RX_ALTINTERFACE);
+}
+
+struct usb_dev_handle *
+usrp_open_tx_interface (struct usb_device *dev)
+{
+  return usrp_open_interface (dev, USRP_TX_INTERFACE, USRP_TX_ALTINTERFACE);
+}
+
+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 internal ram using Cypress vendor extension
+
+static bool
+write_internal_ram (struct usb_dev_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_msg (udh, 0x40, 0xA0,
+                        addr, 0, (char *)(buf + (addr - start_addr)), n, 1000);
+
+    if (a < 0){
+      fprintf(stderr,"write_internal_ram failed: %s\n", usb_strerror());
+      return false;
+    }
+  }
+  return true;
+}
+
+// ----------------------------------------------------------------
+// whack the CPUCS register using the upload RAM vendor extension
+
+static bool
+reset_cpu (struct usb_dev_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 (struct usb_dev_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;
+}
+
+// ----------------------------------------------------------------
+// write vendor extension command to USRP
+
+static 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 ());
+  }
+
+  return r;
+}
+
+// ----------------------------------------------------------------
+// load fpga
+
+static bool
+_usrp_load_fpga (struct usb_dev_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 (struct usb_dev_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 (struct usb_dev_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_msg (udh, 0x40, 0xa0, hash_slot_addr[which], 0,
+                          (char *) hash, USRP_HASH_SIZE, 1000);
+  return r == USRP_HASH_SIZE;
+}
+
+bool
+usrp_get_hash (struct usb_dev_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_msg (udh, 0xc0, 0xa0, hash_slot_addr[which], 0,
+                          (char *) hash, USRP_HASH_SIZE, 1000);
+  return r == USRP_HASH_SIZE;
+}
+
+static bool
+usrp_set_switch (struct usb_dev_handle *udh, int cmd_byte, bool on)
+{
+  return write_cmd (udh, cmd_byte, on, 0, 0, 0) == 0;
+}
+
+
+static bool
+usrp1_fpga_write (struct usb_dev_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 (struct usb_dev_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 (struct usb_dev_handle *udh, int reg, int value)
+{
+  switch (usrp_hw_rev (dev_handle_to_dev (udh))){
+  case 0:                      // not supported ;)
+    abort();   
+
+  default:
+    return usrp1_fpga_write (udh, reg, value);
+  }
+}
+
+bool
+usrp_read_fpga_reg (struct usb_dev_handle *udh, int reg, int *value)
+{
+  switch (usrp_hw_rev (dev_handle_to_dev (udh))){
+  case 0:              // not supported ;)
+    abort();
+    
+  default:
+    return usrp1_fpga_read (udh, reg, value);
+  }
+}
+
+bool 
+usrp_set_fpga_reset (struct usb_dev_handle *udh, bool on)
+{
+  return usrp_set_switch (udh, VRQ_FPGA_SET_RESET, on);
+}
+
+bool 
+usrp_set_fpga_tx_enable (struct usb_dev_handle *udh, bool on)
+{
+  return usrp_set_switch (udh, VRQ_FPGA_SET_TX_ENABLE, on);
+}
+
+bool 
+usrp_set_fpga_rx_enable (struct usb_dev_handle *udh, bool on)
+{
+  return usrp_set_switch (udh, VRQ_FPGA_SET_RX_ENABLE, on);
+}
+
+bool 
+usrp_set_fpga_tx_reset (struct usb_dev_handle *udh, bool on)
+{
+  return usrp_set_switch (udh, VRQ_FPGA_SET_TX_RESET, on);
+}
+
+bool 
+usrp_set_fpga_rx_reset (struct usb_dev_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 (struct usb_dev_handle *udh,
+                                  const char *filename,
+                                  bool force,
+                                  int slot,
+                                  bool loader (struct usb_dev_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 (struct usb_dev_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 (struct usb_dev_handle *udh,
+               const char *filename,
+               bool force)
+{
+  return usrp_conditionally_load_something (udh, filename, force,
+                                           FPGA_HASH_SLOT,
+                                           _usrp_load_fpga);
+}
+
+static usb_dev_handle *
+open_nth_cmd_interface (int nth)
+{
+  struct usb_device *udev = usrp_find_device (nth);
+  if (udev == 0){
+    fprintf (stderr, "usrp: failed to find usrp[%d]\n", nth);
+    return 0;
+  }
+
+  struct usb_dev_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");
+    usb_strerror ();
+    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){
+  struct usb_dev_handle *udh = open_nth_cmd_interface (nth);
+  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 1 second
+    t.tv_sec = 2;
+    t.tv_nsec = 0;
+    our_nanosleep (&t);
+
+    usb_find_busses ();                // rescan busses and devices
+    usb_find_devices ();
+
+    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)
+{
+  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
+  {
+    struct usb_device *udev = usrp_find_device (nth);
+    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);
+  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;
+  }
+
+  struct usb_dev_handle *udh = open_nth_cmd_interface (nth);
+  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 (struct usb_dev_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 (struct usb_dev_handle *udh, bool *overrun_p)
+{
+  return _usrp_get_status (udh, GS_RX_OVERRUN, overrun_p);
+}
+
+bool
+usrp_check_tx_underrun (struct usb_dev_handle *udh, bool *underrun_p)
+{
+  return _usrp_get_status (udh, GS_TX_UNDERRUN, underrun_p);
+}
+
+
+bool
+usrp_i2c_write (struct usb_dev_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 (struct usb_dev_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 (struct usb_dev_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 (struct usb_dev_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 (struct usb_dev_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 (struct usb_dev_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 (struct usb_dev_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 (struct usb_dev_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 (struct usb_dev_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 (dev_handle_to_dev (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 (struct usb_dev_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 (struct usb_dev_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 (struct usb_dev_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 (struct usb_dev_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 (struct usb_dev_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 (struct usb_dev_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 (struct usb_dev_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(struct usb_dev_handle *udh)
+{
+  u_int8_t iserial = usb_device(udh)->descriptor.iSerialNumber;
+  if (iserial == 0)
+    return "";
+
+  char buf[1024];
+  if (usb_get_string_simple(udh, iserial, buf, sizeof(buf)) < 0)
+    return "";
+
+  return buf;
+}
diff --git a/usrp/host/lib/usrp_prims.h b/usrp/host/lib/usrp_prims.h
new file mode 100644 (file)
index 0000000..a4bbb62
--- /dev/null
@@ -0,0 +1,294 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003,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 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.
+ */
+
+/*
+ * Low level primitives for directly messing with USRP hardware.
+ *
+ * If you're trying to use the USRP, you'll probably want to take a look
+ * at the usrp_rx and usrp_tx classes.  They hide a bunch of low level details
+ * and provide high performance streaming i/o.
+ *
+ * This interface is built on top of libusb, which allegedly works under
+ * Linux, *BSD and Mac OS/X.  http://libusb.sourceforge.net
+ */
+
+#ifndef _USRP_PRIMS_H_
+#define _USRP_PRIMS_H_
+
+#include <usrp_slots.h>
+#include <string>
+
+static const int USRP_HASH_SIZE = 16;
+
+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 ();
+
+/*
+ * 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)
+ */
+struct usb_device *usrp_find_device (int nth, bool fx2_ok_p = false);
+
+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_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
+
+/*!
+ * \brief given a usb_device return an instance of the appropriate usb_dev_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.
+ */
+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);
+
+/*!
+ * \brief close interface.
+ */
+bool usrp_close_interface (struct usb_dev_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 (struct usb_dev_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);
+
+/*!
+ * \brief load fpga configuration bitstream
+ */
+usrp_load_status_t
+usrp_load_fpga (struct usb_dev_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 = "");
+
+/*!
+ * \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 (struct usb_dev_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 (struct usb_dev_handle *udh, int which,
+                   unsigned char hash[USRP_HASH_SIZE]);
+
+bool usrp_write_fpga_reg (struct usb_dev_handle *udh, int reg, int value);
+bool usrp_read_fpga_reg (struct usb_dev_handle *udh, int reg, int *value);
+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_check_rx_overrun (struct usb_dev_handle *udh, bool *overrun_p);
+bool usrp_check_tx_underrun (struct usb_dev_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,
+                    const void *buf, int len);
+
+bool usrp_i2c_read (struct usb_dev_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,
+                    int optional_header, int enables, int format,
+                    const void *buf, int len);
+
+bool usrp_spi_read (struct usb_dev_handle *udh,
+                    int optional_header, int enables, int format,
+                    void *buf, int len);
+
+
+bool usrp_9862_write (struct usb_dev_handle *udh,
+                     int which_codec,                  // [0,  1]
+                     int regno,                        // [0, 63]
+                     int value);                       // [0, 255]     
+
+bool usrp_9862_read (struct usb_dev_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 (struct usb_dev_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 (struct usb_dev_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 (struct usb_dev_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 (struct usb_dev_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 (struct usb_dev_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 (struct usb_dev_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 (struct usb_dev_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 (struct usb_dev_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(struct usb_dev_handle *udh);
+
+#endif /* _USRP_PRIMS_H_ */
diff --git a/usrp/host/lib/usrp_slots.h b/usrp/host/lib/usrp_slots.h
new file mode 100644 (file)
index 0000000..1568ce7
--- /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 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.
+ */
+
+#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/lib/usrp_standard.cc b/usrp/host/lib/usrp_standard.cc
new file mode 100644 (file)
index 0000000..d59920f
--- /dev/null
@@ -0,0 +1,831 @@
+/* -*- 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 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.
+ */
+
+#include <usrp_standard.h>
+
+#include "usrp_prims.h"
+#include "fpga_regs_common.h"
+#include "fpga_regs_standard.h"
+#include <stdexcept>
+#include <assert.h>
+#include <math.h>
+#include <ad9862.h>
+
+
+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]))
+
+
+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 *
+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
+                       )
+{
+  usrp_standard_rx *u = 0;
+  
+  try {
+    u = new usrp_standard_rx (which_board, decim_rate,
+                             nchan, mux, mode,
+                             fusb_block_size, fusb_nblocks,
+                             fpga_filename, firmware_filename);
+    return u;
+  }
+  catch (...){
+    delete u;
+    return 0;
+  }
+
+  return u;
+}
+
+bool
+usrp_standard_rx::set_decim_rate(unsigned int rate)
+{
+  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;
+  }
+
+  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;
+}
+
+
+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_freq(),
+                                   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;
+}
+
+//////////////////////////////////////////////////////////////////
+
+
+// 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 *
+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
+                       )
+{
+  usrp_standard_tx *u = 0;
+  
+  try {
+    u = new usrp_standard_tx (which_board, interp_rate, nchan, mux,
+                             fusb_block_size, fusb_nblocks,
+                             fpga_filename, firmware_filename);
+    return u;
+  }
+  catch (...){
+    delete u;
+    return 0;
+  }
+
+  return u;
+}
+
+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;
+}
+
+#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_freq () / 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;
+
+  assert (dac_freq () == 128000000);
+
+  if (freq < -44e6)            // too low
+    return false;
+  else if (freq < -24e6){      // [-44, -24)
+    cm = CM_NEG_FDAC_OVER_4;
+    coarse = -dac_freq () / 4;
+  }
+  else if (freq < -8e6){       // [-24, -8)
+    cm = CM_NEG_FDAC_OVER_8;
+    coarse = -dac_freq () / 8;
+  }
+  else if (freq < 8e6){                // [-8, 8)
+    cm = CM_OFF;
+    coarse = 0;
+  }
+  else if (freq < 24e6){       // [8, 24)
+    cm = CM_POS_FDAC_OVER_8;
+    coarse = dac_freq () / 8;
+  }
+  else if (freq <= 44e6){      // [24, 44]
+    cm = CM_POS_FDAC_OVER_4;
+    coarse = dac_freq () / 4;
+  }
+  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_freq () / 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];
+}
diff --git a/usrp/host/lib/usrp_standard.h b/usrp/host/lib/usrp_standard.h
new file mode 100644 (file)
index 0000000..9f468a6
--- /dev/null
@@ -0,0 +1,366 @@
+/* -*- 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 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.
+ */
+
+#ifndef INCLUDED_USRP_STANDARD_H
+#define INCLUDED_USRP_STANDARD_H
+
+#include <usrp_basic.h>
+
+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 standard usrp RX class.  
+ *
+ * Assumes digital down converter in FPGA
+ */
+class usrp_standard_rx : public usrp_basic_rx, 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 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. 
+   */
+  static usrp_standard_rx *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);
+
+  /*!
+   * \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);
+
+  // 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 standard usrp TX class.
+ *
+ * Uses digital upconverter (coarse & fine modulators) in AD9862...
+ */
+class usrp_standard_tx : public usrp_basic_tx, 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 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. 
+   */
+  static usrp_standard_tx *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);
+
+  /*!
+   * \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;
+
+  // called in base class to derived class order
+  bool start ();
+  bool stop ();
+};
+
+#endif /* INCLUDED_USRP_STANDARD_H */
diff --git a/usrp/host/misc/Makefile.am b/usrp/host/misc/Makefile.am
new file mode 100644 (file)
index 0000000..08826a0
--- /dev/null
@@ -0,0 +1,31 @@
+#
+# Copyright 2003,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.
+# 
+
+EXTRA_DIST = \
+       getopt.c getopt.h \
+       gettimeofday.c \
+       tempname.c mkstemp.c \
+       usleep.c
+
+noinst_LTLIBRARIES = libmisc.la
+
+libmisc_la_SOURCES = bug_work_around_8.cc
+libmisc_la_LIBADD = @LTLIBOBJS@
diff --git a/usrp/host/misc/bug_work_around_8.cc b/usrp/host/misc/bug_work_around_8.cc
new file mode 100644 (file)
index 0000000..4194324
--- /dev/null
@@ -0,0 +1,2 @@
+// if libmisc has no sources, it doesn't get built correctly
+int gr_bug_work_around_8;
diff --git a/usrp/host/misc/getopt.c b/usrp/host/misc/getopt.c
new file mode 100644 (file)
index 0000000..93fb6ea
--- /dev/null
@@ -0,0 +1,733 @@
+/* Getopt for GNU.
+   NOTE: getopt is now part of the C library, so if you don't know what
+   "Keep this file name-space clean" means, talk to roland@gnu.ai.mit.edu
+   before changing it!
+
+   Copyright (C) 1987, 88, 89, 90, 91, 92, 1993
+       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, 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, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+\f
+/* NOTE!!!  AIX requires this to be the first thing in the file.
+   Do not put ANYTHING before it!  */
+#if !defined (__GNUC__) && defined (_AIX)
+ #pragma alloca
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifdef __GNUC__
+#define alloca __builtin_alloca
+#else /* not __GNUC__ */
+#if defined (HAVE_ALLOCA_H) || (defined(sparc) && (defined(sun) || (!defined(USG) && !defined(SVR4) && !defined(__svr4__))))
+#include <alloca.h>
+#else
+#ifndef _AIX
+char *alloca ();
+#endif
+#endif /* alloca.h */
+#endif /* not __GNUC__ */
+
+#if !__STDC__ && !defined(const) && IN_GCC
+#define const
+#endif
+
+/* This tells Alpha OSF/1 not to define a getopt prototype in <stdio.h>.  */
+#ifndef _NO_PROTO
+#define _NO_PROTO
+#endif
+
+#include <stdio.h>
+
+/* Comment out all this code if we are using the GNU C Library, and are not
+   actually compiling the library itself.  This code is part of the GNU C
+   Library, but also included in many other GNU distributions.  Compiling
+   and linking in this code is a waste when using the GNU C library
+   (especially if it is a shared library).  Rather than having every GNU
+   program understand `configure --with-gnu-libc' and omit the object files,
+   it is simpler to just do this in the source for each such file.  */
+
+#if defined (_LIBC) || !defined (__GNU_LIBRARY__)
+
+
+/* This needs to come after some library #include
+   to get __GNU_LIBRARY__ defined.  */
+#ifdef __GNU_LIBRARY__
+#undef alloca
+/* Don't include stdlib.h for non-GNU C libraries because some of them
+   contain conflicting prototypes for getopt.  */
+#include <stdlib.h>
+#else  /* Not GNU C library.  */
+#define        __alloca        alloca
+#endif /* GNU C library.  */
+
+/* If GETOPT_COMPAT is defined, `+' as well as `--' can introduce a
+   long-named option.  Because this is not POSIX.2 compliant, it is
+   being phased out.  */
+/* #define GETOPT_COMPAT */
+
+/* This version of `getopt' appears to the caller like standard Unix `getopt'
+   but it behaves differently for the user, since it allows the user
+   to intersperse the options with the other arguments.
+
+   As `getopt' works, it permutes the elements of ARGV so that,
+   when it is done, all the options precede everything else.  Thus
+   all application programs are extended to handle flexible argument order.
+
+   Setting the environment variable POSIXLY_CORRECT disables permutation.
+   Then the behavior is completely standard.
+
+   GNU application programs can use a third alternative mode in which
+   they can distinguish the relative order of options and other arguments.  */
+
+#include "getopt.h"
+
+/* For communication from `getopt' to the caller.
+   When `getopt' finds an option that takes an argument,
+   the argument value is returned here.
+   Also, when `ordering' is RETURN_IN_ORDER,
+   each non-option ARGV-element is returned here.  */
+
+char *optarg = 0;
+
+/* Index in ARGV of the next element to be scanned.
+   This is used for communication to and from the caller
+   and for communication between successive calls to `getopt'.
+
+   On entry to `getopt', zero means this is the first call; initialize.
+
+   When `getopt' returns EOF, this is the index of the first of the
+   non-option elements that the caller should itself scan.
+
+   Otherwise, `optind' communicates from one call to the next
+   how much of ARGV has been scanned so far.  */
+
+/* XXX 1003.2 says this must be 1 before any call.  */
+int optind = 0;
+
+/* The next char to be scanned in the option-element
+   in which the last option character we returned was found.
+   This allows us to pick up the scan where we left off.
+
+   If this is zero, or a null string, it means resume the scan
+   by advancing to the next ARGV-element.  */
+
+static char *nextchar;
+
+/* Callers store zero here to inhibit the error message
+   for unrecognized options.  */
+
+int opterr = 1;
+
+/* Set to an option character which was unrecognized.
+   This must be initialized on some systems to avoid linking in the
+   system's own getopt implementation.  */
+
+int optopt = '?';
+
+/* Describe how to deal with options that follow non-option ARGV-elements.
+
+   If the caller did not specify anything,
+   the default is REQUIRE_ORDER if the environment variable
+   POSIXLY_CORRECT is defined, PERMUTE otherwise.
+
+   REQUIRE_ORDER means don't recognize them as options;
+   stop option processing when the first non-option is seen.
+   This is what Unix does.
+   This mode of operation is selected by either setting the environment
+   variable POSIXLY_CORRECT, or using `+' as the first character
+   of the list of option characters.
+
+   PERMUTE is the default.  We permute the contents of ARGV as we scan,
+   so that eventually all the non-options are at the end.  This allows options
+   to be given in any order, even with programs that were not written to
+   expect this.
+
+   RETURN_IN_ORDER is an option available to programs that were written
+   to expect options and other ARGV-elements in any order and that care about
+   the ordering of the two.  We describe each non-option ARGV-element
+   as if it were the argument of an option with character code 1.
+   Using `-' as the first character of the list of option characters
+   selects this mode of operation.
+
+   The special argument `--' forces an end of option-scanning regardless
+   of the value of `ordering'.  In the case of RETURN_IN_ORDER, only
+   `--' can cause `getopt' to return EOF with `optind' != ARGC.  */
+
+static enum
+{
+  REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER
+} ordering;
+\f
+#ifdef __GNU_LIBRARY__
+/* We want to avoid inclusion of string.h with non-GNU libraries
+   because there are many ways it can cause trouble.
+   On some systems, it contains special magic macros that don't work
+   in GCC.  */
+#include <string.h>
+#define        my_index        strchr
+#define        my_bcopy(src, dst, n)   memcpy ((dst), (src), (n))
+#else
+
+/* Avoid depending on library functions or files
+   whose names are inconsistent.  */
+
+char *getenv ();
+
+static char *
+my_index (str, chr)
+     const char *str;
+     int chr;
+{
+  while (*str)
+    {
+      if (*str == chr)
+       return (char *) str;
+      str++;
+    }
+  return 0;
+}
+
+static void
+my_bcopy (from, to, size)
+     const char *from;
+     char *to;
+     int size;
+{
+  int i;
+  for (i = 0; i < size; i++)
+    to[i] = from[i];
+}
+#endif                         /* GNU C library.  */
+\f
+/* Handle permutation of arguments.  */
+
+/* Describe the part of ARGV that contains non-options that have
+   been skipped.  `first_nonopt' is the index in ARGV of the first of them;
+   `last_nonopt' is the index after the last of them.  */
+
+static int first_nonopt;
+static int last_nonopt;
+
+/* Exchange two adjacent subsequences of ARGV.
+   One subsequence is elements [first_nonopt,last_nonopt)
+   which contains all the non-options that have been skipped so far.
+   The other is elements [last_nonopt,optind), which contains all
+   the options processed since those non-options were skipped.
+
+   `first_nonopt' and `last_nonopt' are relocated so that they describe
+   the new indices of the non-options in ARGV after they are moved.  */
+
+static void
+exchange (argv)
+     char **argv;
+{
+  int nonopts_size = (last_nonopt - first_nonopt) * sizeof (char *);
+  char **temp = (char **) __alloca (nonopts_size);
+
+  /* Interchange the two blocks of data in ARGV.  */
+
+  my_bcopy ((char *) &argv[first_nonopt], (char *) temp, nonopts_size);
+  my_bcopy ((char *) &argv[last_nonopt], (char *) &argv[first_nonopt],
+           (optind - last_nonopt) * sizeof (char *));
+  my_bcopy ((char *) temp,
+           (char *) &argv[first_nonopt + optind - last_nonopt],
+           nonopts_size);
+
+  /* Update records for the slots the non-options now occupy.  */
+
+  first_nonopt += (optind - last_nonopt);
+  last_nonopt = optind;
+}
+\f
+/* Scan elements of ARGV (whose length is ARGC) for option characters
+   given in OPTSTRING.
+
+   If an element of ARGV starts with '-', and is not exactly "-" or "--",
+   then it is an option element.  The characters of this element
+   (aside from the initial '-') are option characters.  If `getopt'
+   is called repeatedly, it returns successively each of the option characters
+   from each of the option elements.
+
+   If `getopt' finds another option character, it returns that character,
+   updating `optind' and `nextchar' so that the next call to `getopt' can
+   resume the scan with the following option character or ARGV-element.
+
+   If there are no more option characters, `getopt' returns `EOF'.
+   Then `optind' is the index in ARGV of the first ARGV-element
+   that is not an option.  (The ARGV-elements have been permuted
+   so that those that are not options now come last.)
+
+   OPTSTRING is a string containing the legitimate option characters.
+   If an option character is seen that is not listed in OPTSTRING,
+   return '?' after printing an error message.  If you set `opterr' to
+   zero, the error message is suppressed but we still return '?'.
+
+   If a char in OPTSTRING is followed by a colon, that means it wants an arg,
+   so the following text in the same ARGV-element, or the text of the following
+   ARGV-element, is returned in `optarg'.  Two colons mean an option that
+   wants an optional arg; if there is text in the current ARGV-element,
+   it is returned in `optarg', otherwise `optarg' is set to zero.
+
+   If OPTSTRING starts with `-' or `+', it requests different methods of
+   handling the non-option ARGV-elements.
+   See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above.
+
+   Long-named options begin with `--' instead of `-'.
+   Their names may be abbreviated as long as the abbreviation is unique
+   or is an exact match for some defined option.  If they have an
+   argument, it follows the option name in the same ARGV-element, separated
+   from the option name by a `=', or else the in next ARGV-element.
+   When `getopt' finds a long-named option, it returns 0 if that option's
+   `flag' field is nonzero, the value of the option's `val' field
+   if the `flag' field is zero.
+
+   The elements of ARGV aren't really const, because we permute them.
+   But we pretend they're const in the prototype to be compatible
+   with other systems.
+
+   LONGOPTS is a vector of `struct option' terminated by an
+   element containing a name which is zero.
+
+   LONGIND returns the index in LONGOPT of the long-named option found.
+   It is only valid when a long-named option has been found by the most
+   recent call.
+
+   If LONG_ONLY is nonzero, '-' as well as '--' can introduce
+   long-named options.  */
+
+int
+_getopt_internal (argc, argv, optstring, longopts, longind, long_only)
+     int argc;
+     char *const *argv;
+     const char *optstring;
+     const struct option *longopts;
+     int *longind;
+     int long_only;
+{
+  int option_index;
+
+  optarg = 0;
+
+  /* Initialize the internal data when the first call is made.
+     Start processing options with ARGV-element 1 (since ARGV-element 0
+     is the program name); the sequence of previously skipped
+     non-option ARGV-elements is empty.  */
+
+  if (optind == 0)
+    {
+      first_nonopt = last_nonopt = optind = 1;
+
+      nextchar = NULL;
+
+      /* Determine how to handle the ordering of options and nonoptions.  */
+
+      if (optstring[0] == '-')
+       {
+         ordering = RETURN_IN_ORDER;
+         ++optstring;
+       }
+      else if (optstring[0] == '+')
+       {
+         ordering = REQUIRE_ORDER;
+         ++optstring;
+       }
+      else if (getenv ("POSIXLY_CORRECT") != NULL)
+       ordering = REQUIRE_ORDER;
+      else
+       ordering = PERMUTE;
+    }
+
+  if (nextchar == NULL || *nextchar == '\0')
+    {
+      if (ordering == PERMUTE)
+       {
+         /* If we have just processed some options following some non-options,
+            exchange them so that the options come first.  */
+
+         if (first_nonopt != last_nonopt && last_nonopt != optind)
+           exchange ((char **) argv);
+         else if (last_nonopt != optind)
+           first_nonopt = optind;
+
+         /* Now skip any additional non-options
+            and extend the range of non-options previously skipped.  */
+
+         while (optind < argc
+                && (argv[optind][0] != '-' || argv[optind][1] == '\0')
+#ifdef GETOPT_COMPAT
+                && (longopts == NULL
+                    || argv[optind][0] != '+' || argv[optind][1] == '\0')
+#endif                         /* GETOPT_COMPAT */
+                )
+           optind++;
+         last_nonopt = optind;
+       }
+
+      /* Special ARGV-element `--' means premature end of options.
+        Skip it like a null option,
+        then exchange with previous non-options as if it were an option,
+        then skip everything else like a non-option.  */
+
+      if (optind != argc && !strcmp (argv[optind], "--"))
+       {
+         optind++;
+
+         if (first_nonopt != last_nonopt && last_nonopt != optind)
+           exchange ((char **) argv);
+         else if (first_nonopt == last_nonopt)
+           first_nonopt = optind;
+         last_nonopt = argc;
+
+         optind = argc;
+       }
+
+      /* If we have done all the ARGV-elements, stop the scan
+        and back over any non-options that we skipped and permuted.  */
+
+      if (optind == argc)
+       {
+         /* Set the next-arg-index to point at the non-options
+            that we previously skipped, so the caller will digest them.  */
+         if (first_nonopt != last_nonopt)
+           optind = first_nonopt;
+         return EOF;
+       }
+
+      /* If we have come to a non-option and did not permute it,
+        either stop the scan or describe it to the caller and pass it by.  */
+
+      if ((argv[optind][0] != '-' || argv[optind][1] == '\0')
+#ifdef GETOPT_COMPAT
+         && (longopts == NULL
+             || argv[optind][0] != '+' || argv[optind][1] == '\0')
+#endif                         /* GETOPT_COMPAT */
+         )
+       {
+         if (ordering == REQUIRE_ORDER)
+           return EOF;
+         optarg = argv[optind++];
+         return 1;
+       }
+
+      /* We have found another option-ARGV-element.
+        Start decoding its characters.  */
+
+      nextchar = (argv[optind] + 1
+                 + (longopts != NULL && argv[optind][1] == '-'));
+    }
+
+  if (longopts != NULL
+      && ((argv[optind][0] == '-'
+          && (argv[optind][1] == '-' || long_only))
+#ifdef GETOPT_COMPAT
+         || argv[optind][0] == '+'
+#endif                         /* GETOPT_COMPAT */
+         ))
+    {
+      const struct option *p;
+      char *s = nextchar;
+      int exact = 0;
+      int ambig = 0;
+      const struct option *pfound = NULL;
+      int indfound;
+
+      while (*s && *s != '=')
+       s++;
+
+      /* Test all options for either exact match or abbreviated matches.  */
+      for (p = longopts, option_index = 0; p->name;
+          p++, option_index++)
+       if (!strncmp (p->name, nextchar, s - nextchar))
+         {
+           if (s - nextchar == strlen (p->name))
+             {
+               /* Exact match found.  */
+               pfound = p;
+               indfound = option_index;
+               exact = 1;
+               break;
+             }
+           else if (pfound == NULL)
+             {
+               /* First nonexact match found.  */
+               pfound = p;
+               indfound = option_index;
+             }
+           else
+             /* Second nonexact match found.  */
+             ambig = 1;
+         }
+
+      if (ambig && !exact)
+       {
+         if (opterr)
+           fprintf (stderr, "%s: option `%s' is ambiguous\n",
+                    argv[0], argv[optind]);
+         nextchar += strlen (nextchar);
+         optind++;
+         return '?';
+       }
+
+      if (pfound != NULL)
+       {
+         option_index = indfound;
+         optind++;
+         if (*s)
+           {
+             /* Don't test has_arg with >, because some C compilers don't
+                allow it to be used on enums.  */
+             if (pfound->has_arg)
+               optarg = s + 1;
+             else
+               {
+                 if (opterr)
+                   {
+                     if (argv[optind - 1][1] == '-')
+                       /* --option */
+                       fprintf (stderr,
+                                "%s: option `--%s' doesn't allow an argument\n",
+                                argv[0], pfound->name);
+                     else
+                       /* +option or -option */
+                       fprintf (stderr,
+                            "%s: option `%c%s' doesn't allow an argument\n",
+                            argv[0], argv[optind - 1][0], pfound->name);
+                   }
+                 nextchar += strlen (nextchar);
+                 return '?';
+               }
+           }
+         else if (pfound->has_arg == 1)
+           {
+             if (optind < argc)
+               optarg = argv[optind++];
+             else
+               {
+                 if (opterr)
+                   fprintf (stderr, "%s: option `%s' requires an argument\n",
+                            argv[0], argv[optind - 1]);
+                 nextchar += strlen (nextchar);
+                 return optstring[0] == ':' ? ':' : '?';
+               }
+           }
+         nextchar += strlen (nextchar);
+         if (longind != NULL)
+           *longind = option_index;
+         if (pfound->flag)
+           {
+             *(pfound->flag) = pfound->val;
+             return 0;
+           }
+         return pfound->val;
+       }
+      /* Can't find it as a long option.  If this is not getopt_long_only,
+        or the option starts with '--' or is not a valid short
+        option, then it's an error.
+        Otherwise interpret it as a short option.  */
+      if (!long_only || argv[optind][1] == '-'
+#ifdef GETOPT_COMPAT
+         || argv[optind][0] == '+'
+#endif                         /* GETOPT_COMPAT */
+         || my_index (optstring, *nextchar) == NULL)
+       {
+         if (opterr)
+           {
+             if (argv[optind][1] == '-')
+               /* --option */
+               fprintf (stderr, "%s: unrecognized option `--%s'\n",
+                        argv[0], nextchar);
+             else
+               /* +option or -option */
+               fprintf (stderr, "%s: unrecognized option `%c%s'\n",
+                        argv[0], argv[optind][0], nextchar);
+           }
+         nextchar = (char *) "";
+         optind++;
+         return '?';
+       }
+    }
+
+  /* Look at and handle the next option-character.  */
+
+  {
+    char c = *nextchar++;
+    char *temp = my_index (optstring, c);
+
+    /* Increment `optind' when we start to process its last character.  */
+    if (*nextchar == '\0')
+      ++optind;
+
+    if (temp == NULL || c == ':')
+      {
+       if (opterr)
+         {
+#if 0
+           if (c < 040 || c >= 0177)
+             fprintf (stderr, "%s: unrecognized option, character code 0%o\n",
+                      argv[0], c);
+           else
+             fprintf (stderr, "%s: unrecognized option `-%c'\n", argv[0], c);
+#else
+           /* 1003.2 specifies the format of this message.  */
+           fprintf (stderr, "%s: illegal option -- %c\n", argv[0], c);
+#endif
+         }
+       optopt = c;
+       return '?';
+      }
+    if (temp[1] == ':')
+      {
+       if (temp[2] == ':')
+         {
+           /* This is an option that accepts an argument optionally.  */
+           if (*nextchar != '\0')
+             {
+               optarg = nextchar;
+               optind++;
+             }
+           else
+             optarg = 0;
+           nextchar = NULL;
+         }
+       else
+         {
+           /* This is an option that requires an argument.  */
+           if (*nextchar != '\0')
+             {
+               optarg = nextchar;
+               /* If we end this ARGV-element by taking the rest as an arg,
+                  we must advance to the next element now.  */
+               optind++;
+             }
+           else if (optind == argc)
+             {
+               if (opterr)
+                 {
+#if 0
+                   fprintf (stderr, "%s: option `-%c' requires an argument\n",
+                            argv[0], c);
+#else
+                   /* 1003.2 specifies the format of this message.  */
+                   fprintf (stderr, "%s: option requires an argument -- %c\n",
+                            argv[0], c);
+#endif
+                 }
+               optopt = c;
+               if (optstring[0] == ':')
+                 c = ':';
+               else
+                 c = '?';
+             }
+           else
+             /* We already incremented `optind' once;
+                increment it again when taking next ARGV-elt as argument.  */
+             optarg = argv[optind++];
+           nextchar = NULL;
+         }
+      }
+    return c;
+  }
+}
+
+#ifdef GETOPT
+int
+getopt (argc, argv, optstring)
+     int argc;
+     char *const *argv;
+     const char *optstring;
+{
+  return _getopt_internal (argc, argv, optstring,
+                          (const struct option *) 0,
+                          (int *) 0,
+                          0);
+}
+#endif
+
+#endif /* _LIBC or not __GNU_LIBRARY__.  */
+\f
+#ifdef TEST
+
+/* Compile with -DTEST to make an executable for use in testing
+   the above definition of `getopt'.  */
+
+int
+main (argc, argv)
+     int argc;
+     char **argv;
+{
+  int c;
+  int digit_optind = 0;
+
+  while (1)
+    {
+      int this_option_optind = optind ? optind : 1;
+
+      c = getopt (argc, argv, "abc:d:0123456789");
+      if (c == EOF)
+       break;
+
+      switch (c)
+       {
+       case '0':
+       case '1':
+       case '2':
+       case '3':
+       case '4':
+       case '5':
+       case '6':
+       case '7':
+       case '8':
+       case '9':
+         if (digit_optind != 0 && digit_optind != this_option_optind)
+           printf ("digits occur in two different argv-elements.\n");
+         digit_optind = this_option_optind;
+         printf ("option %c\n", c);
+         break;
+
+       case 'a':
+         printf ("option a\n");
+         break;
+
+       case 'b':
+         printf ("option b\n");
+         break;
+
+       case 'c':
+         printf ("option c with value `%s'\n", optarg);
+         break;
+
+       case '?':
+         break;
+
+       default:
+         printf ("?? getopt returned character code 0%o ??\n", c);
+       }
+    }
+
+  if (optind < argc)
+    {
+      printf ("non-option ARGV-elements: ");
+      while (optind < argc)
+       printf ("%s ", argv[optind++]);
+      printf ("\n");
+    }
+
+  exit (0);
+}
+
+#endif /* TEST */
diff --git a/usrp/host/misc/getopt.h b/usrp/host/misc/getopt.h
new file mode 100644 (file)
index 0000000..45541f5
--- /dev/null
@@ -0,0 +1,129 @@
+/* Declarations for getopt.
+   Copyright (C) 1989, 1990, 1991, 1992, 1993 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, 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, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+#ifndef _GETOPT_H
+#define _GETOPT_H 1
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* For communication from `getopt' to the caller.
+   When `getopt' finds an option that takes an argument,
+   the argument value is returned here.
+   Also, when `ordering' is RETURN_IN_ORDER,
+   each non-option ARGV-element is returned here.  */
+
+extern char *optarg;
+
+/* Index in ARGV of the next element to be scanned.
+   This is used for communication to and from the caller
+   and for communication between successive calls to `getopt'.
+
+   On entry to `getopt', zero means this is the first call; initialize.
+
+   When `getopt' returns EOF, this is the index of the first of the
+   non-option elements that the caller should itself scan.
+
+   Otherwise, `optind' communicates from one call to the next
+   how much of ARGV has been scanned so far.  */
+
+extern int optind;
+
+/* Callers store zero here to inhibit the error message `getopt' prints
+   for unrecognized options.  */
+
+extern int opterr;
+
+/* Set to an option character which was unrecognized.  */
+
+extern int optopt;
+
+/* Describe the long-named options requested by the application.
+   The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector
+   of `struct option' terminated by an element containing a name which is
+   zero.
+
+   The field `has_arg' is:
+   no_argument         (or 0) if the option does not take an argument,
+   required_argument   (or 1) if the option requires an argument,
+   optional_argument   (or 2) if the option takes an optional argument.
+
+   If the field `flag' is not NULL, it points to a variable that is set
+   to the value given in the field `val' when the option is found, but
+   left unchanged if the option is not found.
+
+   To have a long-named option do something other than set an `int' to
+   a compiled-in constant, such as set a value from `optarg', set the
+   option's `flag' field to zero and its `val' field to a nonzero
+   value (the equivalent single-letter option character, if there is
+   one).  For long options that have a zero `flag' field, `getopt'
+   returns the contents of the `val' field.  */
+
+struct option
+{
+#if    __STDC__
+  const char *name;
+#else
+  char *name;
+#endif
+  /* has_arg can't be an enum because some compilers complain about
+     type mismatches in all the code that assumes it is an int.  */
+  int has_arg;
+  int *flag;
+  int val;
+};
+
+/* Names for the values of the `has_arg' field of `struct option'.  */
+
+#define        no_argument             0
+#define required_argument      1
+#define optional_argument      2
+
+#if __STDC__
+#if defined(__GNU_LIBRARY__)
+/* Many other libraries have conflicting prototypes for getopt, with
+   differences in the consts, in stdlib.h.  To avoid compilation
+   errors, only prototype getopt for the GNU C library.  */
+extern int getopt (int argc, char *const *argv, const char *shortopts);
+#else /* not __GNU_LIBRARY__ */
+extern int getopt ();
+#endif /* not __GNU_LIBRARY__ */
+extern int getopt_long (int argc, char *const *argv, const char *shortopts,
+                       const struct option *longopts, int *longind);
+extern int getopt_long_only (int argc, char *const *argv,
+                            const char *shortopts,
+                            const struct option *longopts, int *longind);
+
+/* Internal only.  Users should not call this directly.  */
+extern int _getopt_internal (int argc, char *const *argv,
+                            const char *shortopts,
+                            const struct option *longopts, int *longind,
+                            int long_only);
+#else /* not __STDC__ */
+extern int getopt ();
+extern int getopt_long ();
+extern int getopt_long_only ();
+
+extern int _getopt_internal ();
+#endif /* not __STDC__ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _GETOPT_H */
diff --git a/usrp/host/misc/gettimeofday.c b/usrp/host/misc/gettimeofday.c
new file mode 100644 (file)
index 0000000..4ed15e2
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * 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 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.
+ */
+
+#include <config.h>
+
+#ifdef HAVE_WINDOWS_H
+#include <windows.h>
+#endif
+#ifdef HAVE_WINBASE_H
+# include <winbase.h>
+#endif
+
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#endif
+
+/* 
+ * broken implementation for WIN32. 
+ * FIXME: usec precision
+ */
+int gettimeofday(struct timeval *tv, struct timezone *tz)
+{
+       if (tv) {
+               time_t tm;
+               
+               time(&tm);
+               tv->tv_sec = tm;
+               tv->tv_usec = 0;
+       }
+       return 0;
+}
+
diff --git a/usrp/host/misc/mkstemp.c b/usrp/host/misc/mkstemp.c
new file mode 100644 (file)
index 0000000..f6312b6
--- /dev/null
@@ -0,0 +1,42 @@
+/* Copyright (C) 1998, 1999, 2001 Free Software Foundation, Inc.
+   This file is derived from the one in the GNU C Library.
+
+   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, 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.  */
+
+#include <config.h>
+
+/* Disable the definition of mkstemp to rpl_mkstemp (from config.h) in this
+   file.  Otherwise, we'd get conflicting prototypes for rpl_mkstemp on
+   most systems.  */
+#undef mkstemp
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#ifndef __GT_FILE
+# define __GT_FILE 0
+#endif
+
+int __gen_tempname ();
+
+/* Generate a unique temporary file name from TEMPLATE.
+   The last six characters of TEMPLATE must be "XXXXXX";
+   they are replaced with a string that makes the filename unique.
+   Then open the file and return a fd. */
+int
+rpl_mkstemp (char *template)
+{
+  return __gen_tempname (template, __GT_FILE);
+}
diff --git a/usrp/host/misc/tempname.c b/usrp/host/misc/tempname.c
new file mode 100644 (file)
index 0000000..2e78dfc
--- /dev/null
@@ -0,0 +1,352 @@
+/* tempname.c - generate the name of a temporary file.
+
+   Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+   2000, 2001, 2002, 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 2, 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.  */
+
+#if HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <sys/types.h>
+#include <assert.h>
+
+#include <errno.h>
+#ifndef __set_errno
+# define __set_errno(Val) errno = (Val)
+#endif
+
+#include <stdio.h>
+#ifndef P_tmpdir
+# define P_tmpdir "/tmp"
+#endif
+#ifndef TMP_MAX
+# define TMP_MAX 238328
+#endif
+#ifndef __GT_FILE
+# define __GT_FILE     0
+# define __GT_BIGFILE  1
+# define __GT_DIR      2
+# define __GT_NOCREATE 3
+#endif
+
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+
+#if HAVE_FCNTL_H || _LIBC
+# include <fcntl.h>
+#endif
+
+#if HAVE_SYS_TIME_H || _LIBC
+# include <sys/time.h>
+#endif
+
+#if HAVE_STDINT_H || _LIBC
+# include <stdint.h>
+#endif
+#if HAVE_INTTYPES_H
+# include <inttypes.h>
+#endif
+
+#if HAVE_UNISTD_H || _LIBC
+# include <unistd.h>
+#endif
+
+#include <sys/stat.h>
+#if STAT_MACROS_BROKEN
+# undef S_ISDIR
+#endif
+#if !defined S_ISDIR && defined S_IFDIR
+# define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR)
+#endif
+#if !S_IRUSR && S_IREAD
+# define S_IRUSR S_IREAD
+#endif
+#if !S_IRUSR
+# define S_IRUSR 00400
+#endif
+#if !S_IWUSR && S_IWRITE
+# define S_IWUSR S_IWRITE
+#endif
+#if !S_IWUSR
+# define S_IWUSR 00200
+#endif
+#if !S_IXUSR && S_IEXEC
+# define S_IXUSR S_IEXEC
+#endif
+#if !S_IXUSR
+# define S_IXUSR 00100
+#endif
+
+#if _LIBC
+# define struct_stat64 struct stat64
+#else
+# define struct_stat64 struct stat
+# define __getpid getpid
+# define __gettimeofday gettimeofday
+#ifdef MKDIR_TAKES_ONE_ARG
+# define __mkdir(pathname,mode) mkdir((pathname))
+#else
+# define __mkdir mkdir
+#endif
+# define __open open
+# define __open64 open
+#ifdef HAVE_LSTAT
+# define __lxstat64(version, path, buf) lstat (path, buf)
+#else
+# define __lxstat64(version, path, buf) stat (path, buf)
+#endif
+# define __xstat64(version, path, buf) stat (path, buf)
+#endif
+
+#if ! (HAVE___SECURE_GETENV || _LIBC)
+# define __secure_getenv getenv
+#endif
+
+#ifdef _LIBC
+# include <hp-timing.h>
+# if HP_TIMING_AVAIL
+#  define RANDOM_BITS(Var) \
+  if (__builtin_expect (value == UINT64_C (0), 0))                           \
+    {                                                                        \
+      /* If this is the first time this function is used initialize          \
+        the variable we accumulate the value in to some somewhat             \
+        random value.  If we'd not do this programs at startup time          \
+        might have a reduced set of possible names, at least on slow         \
+        machines.  */                                                        \
+      struct timeval tv;                                                     \
+      __gettimeofday (&tv, NULL);                                            \
+      value = ((uint64_t) tv.tv_usec << 16) ^ tv.tv_sec;                     \
+    }                                                                        \
+  HP_TIMING_NOW (Var)
+# endif
+#endif
+
+/* Use the widest available unsigned type if uint64_t is not
+   available.  The algorithm below extracts a number less than 62**6
+   (approximately 2**35.725) from uint64_t, so ancient hosts where
+   uintmax_t is only 32 bits lose about 3.725 bits of randomness,
+   which is better than not having mkstemp at all.  */
+#if !defined UINT64_MAX && !defined uint64_t
+# define uint64_t uintmax_t
+#endif
+
+/* Return nonzero if DIR is an existent directory.  */
+static int
+direxists (const char *dir)
+{
+  struct_stat64 buf;
+  return __xstat64 (_STAT_VER, dir, &buf) == 0 && S_ISDIR (buf.st_mode);
+}
+
+/* Path search algorithm, for tmpnam, tmpfile, etc.  If DIR is
+   non-null and exists, uses it; otherwise uses the first of $TMPDIR,
+   P_tmpdir, /tmp that exists.  Copies into TMPL a template suitable
+   for use with mk[s]temp.  Will fail (-1) if DIR is non-null and
+   doesn't exist, none of the searched dirs exists, or there's not
+   enough space in TMPL. */
+int
+__path_search (char *tmpl, size_t tmpl_len, const char *dir, const char *pfx,
+              int try_tmpdir)
+{
+  const char *d;
+  size_t dlen, plen;
+
+  if (!pfx || !pfx[0])
+    {
+      pfx = "file";
+      plen = 4;
+    }
+  else
+    {
+      plen = strlen (pfx);
+      if (plen > 5)
+       plen = 5;
+    }
+
+  if (try_tmpdir)
+    {
+      d = __secure_getenv ("TMPDIR");
+      if (d != NULL && direxists (d))
+       dir = d;
+      else if (dir != NULL && direxists (dir))
+       /* nothing */ ;
+      else
+       dir = NULL;
+    }
+  if (dir == NULL)
+    {
+      if (direxists (P_tmpdir))
+       dir = P_tmpdir;
+      else if (strcmp (P_tmpdir, "/tmp") != 0 && direxists ("/tmp"))
+       dir = "/tmp";
+      else
+       {
+         __set_errno (ENOENT);
+         return -1;
+       }
+    }
+
+  dlen = strlen (dir);
+  while (dlen > 1 && dir[dlen - 1] == '/')
+    dlen--;                    /* remove trailing slashes */
+
+  /* check we have room for "${dir}/${pfx}XXXXXX\0" */
+  if (tmpl_len < dlen + 1 + plen + 6 + 1)
+    {
+      __set_errno (EINVAL);
+      return -1;
+    }
+
+  sprintf (tmpl, "%.*s/%.*sXXXXXX", (int) dlen, dir, (int) plen, pfx);
+  return 0;
+}
+
+/* These are the characters used in temporary filenames.  */
+static const char letters[] =
+"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
+
+/* Generate a temporary file name based on TMPL.  TMPL must match the
+   rules for mk[s]temp (i.e. end in "XXXXXX").  The name constructed
+   does not exist at the time of the call to __gen_tempname.  TMPL is
+   overwritten with the result.
+
+   KIND may be one of:
+   __GT_NOCREATE:      simply verify that the name does not exist
+                       at the time of the call.
+   __GT_FILE:          create the file using open(O_CREAT|O_EXCL)
+                       and return a read-write fd.  The file is mode 0600.
+   __GT_BIGFILE:       same as __GT_FILE but use open64().
+   __GT_DIR:           create a directory, which will be mode 0700.
+
+   We use a clever algorithm to get hard-to-predict names. */
+int
+__gen_tempname (char *tmpl, int kind)
+{
+  int len;
+  char *XXXXXX;
+  static uint64_t value;
+  uint64_t random_time_bits;
+  unsigned int count;
+  int fd = -1;
+  int save_errno = errno;
+  struct_stat64 st;
+
+  /* A lower bound on the number of temporary files to attempt to
+     generate.  The maximum total number of temporary file names that
+     can exist for a given template is 62**6.  It should never be
+     necessary to try all these combinations.  Instead if a reasonable
+     number of names is tried (we define reasonable as 62**3) fail to
+     give the system administrator the chance to remove the problems.  */
+  unsigned int attempts_min = 62 * 62 * 62;
+
+  /* The number of times to attempt to generate a temporary file.  To
+     conform to POSIX, this must be no smaller than TMP_MAX.  */
+  unsigned int attempts = attempts_min < TMP_MAX ? TMP_MAX : attempts_min;
+
+  len = strlen (tmpl);
+  if (len < 6 || strcmp (&tmpl[len - 6], "XXXXXX"))
+    {
+      __set_errno (EINVAL);
+      return -1;
+    }
+
+  /* This is where the Xs start.  */
+  XXXXXX = &tmpl[len - 6];
+
+  /* Get some more or less random data.  */
+#ifdef RANDOM_BITS
+  RANDOM_BITS (random_time_bits);
+#else
+# if HAVE_GETTIMEOFDAY || _LIBC
+  {
+    struct timeval tv;
+    __gettimeofday (&tv, NULL);
+    random_time_bits = ((uint64_t) tv.tv_usec << 16) ^ tv.tv_sec;
+  }
+# else
+  random_time_bits = time (NULL);
+# endif
+#endif
+  value += random_time_bits ^ __getpid ();
+
+  for (count = 0; count < attempts; value += 7777, ++count)
+    {
+      uint64_t v = value;
+
+      /* Fill in the random bits.  */
+      XXXXXX[0] = letters[v % 62];
+      v /= 62;
+      XXXXXX[1] = letters[v % 62];
+      v /= 62;
+      XXXXXX[2] = letters[v % 62];
+      v /= 62;
+      XXXXXX[3] = letters[v % 62];
+      v /= 62;
+      XXXXXX[4] = letters[v % 62];
+      v /= 62;
+      XXXXXX[5] = letters[v % 62];
+
+      switch (kind)
+       {
+       case __GT_FILE:
+         fd = __open (tmpl, O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR);
+         break;
+
+       case __GT_BIGFILE:
+         fd = __open64 (tmpl, O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR);
+         break;
+
+       case __GT_DIR:
+         fd = __mkdir (tmpl, S_IRUSR | S_IWUSR | S_IXUSR);
+         break;
+
+       case __GT_NOCREATE:
+         /* This case is backward from the other three.  __gen_tempname
+            succeeds if __xstat fails because the name does not exist.
+            Note the continue to bypass the common logic at the bottom
+            of the loop.  */
+         if (__lxstat64 (_STAT_VER, tmpl, &st) < 0)
+           {
+             if (errno == ENOENT)
+               {
+                 __set_errno (save_errno);
+                 return 0;
+               }
+             else
+               /* Give up now. */
+               return -1;
+           }
+         continue;
+
+       default:
+         assert (! "invalid KIND in __gen_tempname");
+       }
+
+      if (fd >= 0)
+       {
+         __set_errno (save_errno);
+         return fd;
+       }
+      else if (errno != EEXIST)
+       return -1;
+    }
+
+  /* We got out of the loop because we ran out of combinations to try.  */
+  __set_errno (EEXIST);
+  return -1;
+}
diff --git a/usrp/host/misc/usleep.c b/usrp/host/misc/usleep.c
new file mode 100644 (file)
index 0000000..4a0f75e
--- /dev/null
@@ -0,0 +1,67 @@
+/* Copyright (C) 1992 Free Software Foundation, Inc.
+This file is part of the GNU C Library.
+
+The GNU C Library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public License as
+published by the Free Software Foundation; either version 2 of the
+License, or (at your option) any later version.
+
+The GNU C Library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <config.h>
+
+#ifndef HAVE_USLEEP
+
+#include <sys/types.h>
+#include <sys/time.h>
+
+#ifdef HAVE_SYS_SELECT_H
+# include <sys/select.h>
+#endif
+
+#ifdef HAVE_WINDOWS_H
+#include <windows.h>
+#endif
+#ifdef HAVE_WINBASE_H
+# include <winbase.h>
+#endif
+
+#ifdef apollo
+# include <apollo/base.h>
+# include <apollo/time.h>
+  static time_$clock_t DomainTime100mS =
+    {
+       0, 100000/4
+    };
+  static status_$t DomainStatus;
+#endif
+
+/* Sleep USECONDS microseconds, or until a previously set timer goes off.  */
+int
+usleep (unsigned long useconds)
+{
+#ifdef apollo
+  /* The usleep function does not work under the SYS5.3 environment.
+     Use the Domain/OS time_$wait call instead. */
+  time_$wait (time_$relative, DomainTime100mS, &DomainStatus);
+#elif defined(HAVE_SSLEEP)     /* Win32 */
+  Sleep( useconds/1000 );
+#else
+  struct timeval delay;
+
+  delay.tv_sec = 0;
+  delay.tv_usec = useconds;
+  select (0, 0, 0, 0, &delay);
+#endif
+  return 0;
+}
+
+#endif /* !HAVE_USLEEP */
diff --git a/usrp/host/swig/Makefile.am b/usrp/host/swig/Makefile.am
new file mode 100644 (file)
index 0000000..469a5d7
--- /dev/null
@@ -0,0 +1,84 @@
+#
+# Copyright 2001,2003,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.
+# 
+
+include $(top_srcdir)/Makefile.common
+
+# This usually ends up at:
+#   ${prefix}/lib/python${python_version}/site-packages/usrp_prims
+
+ourpythondir = $(pythondir)
+ourlibdir    = $(pyexecdir)
+
+
+LOCAL_IFILES =                         \
+       prims.i
+
+
+ALL_IFILES =                           \
+       $(LOCAL_IFILES)                 
+
+
+EXTRA_DIST =                           \
+       $(LOCAL_IFILES)
+
+
+BUILT_SOURCES =                                \
+       prims.cc                        \
+       usrp_prims.py
+
+
+ourpython_PYTHON =                     \
+       __init__.py                     \
+       usrp_fpga_regs.py               \
+       usrp_prims.py                   
+
+
+INCLUDES = -I$(top_srcdir)/usrp/firmware/include $(PYTHON_CPPFLAGS) -I$(srcdir)
+
+
+SWIGPYTHONARGS = $(SWIGPYTHONFLAGS) $(INCLUDES)
+
+
+ourlib_LTLIBRARIES =                   \
+       _usrp_prims.la
+
+_usrp_prims_la_SOURCES =               \
+       prims.cc                
+
+
+noinst_HEADERS =
+
+_usrp_prims_la_LIBADD  = $(top_builddir)/usrp/host/lib/libusrp.la -lstdc++ $(PYTHON_LDFLAGS)
+_usrp_prims_la_LDFLAGS = $(NO_UNDEFINED) -module -avoid-version
+
+
+prims.cc usrp_prims.py : prims.i ../../firmware/include/fpga_regs_common.h ../../firmware/include/fpga_regs_standard.h
+       $(SWIG) $(SWIGPYTHONARGS) -module usrp_prims -o prims.cc $<
+
+
+MOSTLYCLEANFILES = \
+       prims.cc usrp_prims.py *~ *.pyc
+
+# Don't distribute output of swig
+dist-hook:
+       @for file in $(BUILT_SOURCES); do echo $(RM) $(distdir)/$$file; done
+       @for file in $(BUILT_SOURCES); do $(RM) $(distdir)/$$file; done
+
diff --git a/usrp/host/swig/__init__.py b/usrp/host/swig/__init__.py
new file mode 100644 (file)
index 0000000..a4917cf
--- /dev/null
@@ -0,0 +1 @@
+# make this a package
diff --git a/usrp/host/swig/prims.i b/usrp/host/swig/prims.i
new file mode 100644 (file)
index 0000000..bbf960c
--- /dev/null
@@ -0,0 +1,266 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003,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.
+ */
+
+/*
+ * Low level primitives for directly messing with USRP hardware.
+ *
+ * If you're trying to use the USRP, you'll probably want to take a
+ * look at the usrp_standard_rx and usrp_standard_tx classes.  They
+ * hide a bunch of low level details and provide high performance
+ * streaming i/o.
+ *
+ * This interface is built on top of libusb, which allegedly works under
+ * Linux, *BSD and Mac OS/X.  http://libusb.sourceforge.net
+ */
+
+%include <stl.i>       // pick up string stuff
+
+
+%{
+#include <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_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)
+ */
+struct usb_device *usrp_find_device (int nth, bool fx2_ok_p = false);
+
+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_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
+
+/*!
+ * \brief given a usb_device return an instance of the appropriate usb_dev_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.
+ */
+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);
+
+/*!
+ * \brief close interface.
+ */
+bool usrp_close_interface (struct usb_dev_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 (struct usb_dev_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);
+
+/*!
+ * \brief load fpga configuration bitstream
+ */
+usrp_load_status_t
+usrp_load_fpga (struct usb_dev_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);
+
+
+%include <fpga_regs_common.h>
+%include <fpga_regs_standard.h>
+
+
+bool usrp_write_fpga_reg (struct usb_dev_handle *udh, int reg, int value);
+
+%inline %{
+
+int 
+usrp_read_fpga_reg (struct usb_dev_handle *udh, int reg)
+{
+  int value;
+  bool ok = usrp_read_fpga_reg (udh, reg, &value);
+  if (ok)
+    return value;
+  else
+    return -999;
+}
+
+%}
+
+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_check_rx_overrun (struct usb_dev_handle *udh, bool *overrun_p);
+bool usrp_check_tx_underrun (struct usb_dev_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,
+                    void *buf, int len);
+
+bool usrp_i2c_read (struct usb_dev_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,
+                    int optional_header, int enables, int format,
+                    unsigned char *buf, int len);
+
+bool usrp_spi_read (struct usb_dev_handle *udh,
+                    int optional_header, int enables, int format,
+                    unsigned char *buf, int len);
+
+
+bool usrp_9862_write (struct usb_dev_handle *udh,
+                     int which_codec,                  // [0,  1]
+                     int regno,                        // [0, 63]
+                     int value);                       // [0, 255]     
+
+%inline %{
+
+int 
+usrp_9862_read (struct usb_dev_handle *udh, int which_codec, int reg)
+{
+  unsigned char value;
+  bool ok = usrp_9862_read (udh, which_codec, reg, &value);
+  if (ok)
+    return value;
+  else
+    return -999;
+}
+
+%}
+
+%inline %{
+
+bool 
+usrp_eeprom_write (struct usb_dev_handle *udh, int i2c_addr,
+                  int eeprom_offset, const std::string buf)
+{
+  return usrp_eeprom_write (udh, i2c_addr, eeprom_offset,
+                           buf.data (), buf.size ());
+}
+  
+std::string
+usrp_eeprom_read (struct usb_dev_handle *udh, int i2c_addr,
+                 int eeprom_offset, int len)
+{
+  if (len <= 0)
+    return "";
+  
+  char buf[len];
+
+  if (!usrp_eeprom_read (udh, i2c_addr, eeprom_offset, buf, len))
+    return "";
+
+  return std::string (buf, len);
+}
+
+%}
+
+bool usrp_write_aux_dac (struct usb_dev_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 value;
+  bool ok = usrp_read_aux_adc (udh, slot, which_adc, &value);
+  if (ok)
+    return value;
+  else
+    return -999;
+}
+
+%}
+
+/*!
+ * \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(struct usb_dev_handle *udh);
+
+/*!
+ * \brief usrp daughterboard id to name mapping
+ */
+const std::string usrp_dbid_to_string (int dbid);
+
+%inline %{
+#include "../../firmware/include/fpga_regs_common.h"
+#include "../../firmware/include/fpga_regs_standard.h"
+%}
diff --git a/usrp/host/swig/usrp_fpga_regs.py b/usrp/host/swig/usrp_fpga_regs.py
new file mode 100644 (file)
index 0000000..9fdf62c
--- /dev/null
@@ -0,0 +1,30 @@
+#
+# 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 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.
+# 
+
+import usrp_prims
+
+# Copy everything that starts with FR_ or bmFR_ from the usrp_prims
+# name space into our name space.  This is effectively a python binding for
+# the contents of firmware/include/fpga_regs_common.h and fpga_regs_standard.h
+
+for name in dir(usrp_prims):
+    if name.startswith("FR_") or name.startswith("bmFR_"):
+        globals()[name] = usrp_prims.__dict__[name]
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
+
diff --git a/usrp/usrp.inf b/usrp/usrp.inf
new file mode 100644 (file)
index 0000000..b612d1e
--- /dev/null
@@ -0,0 +1,91 @@
+[Version]
+Signature = "$Chicago$"
+provider  = %manufacturer%
+DriverVer = 03/09/2005,0.1.10.1
+CatalogFile = usrp.cat
+
+Class = LibUsbDevices
+ClassGUID = {EB781AAF-9C70-4523-A5DF-642A87ECA567}
+
+[ClassInstall]
+AddReg=ClassInstall.AddReg
+
+[ClassInstall32]
+AddReg=ClassInstall.AddReg
+
+[ClassInstall.AddReg]
+HKR,,,,"LibUSB-Win32 Devices"
+HKR,,Icon,,"-20"
+
+[Manufacturer]
+%manufacturer%=Devices
+
+;--------------------------------------------------------------------------
+; Files
+;--------------------------------------------------------------------------
+
+[SourceDisksNames]
+1 = "Libusb-Win32 Driver Installation Disk",,
+
+[SourceDisksFiles]
+libusb0.sys = 1,,
+libusb0.dll = 1,,
+
+[DestinationDirs]
+LIBUSB.Files.Sys = 10,System32\Drivers
+LIBUSB.Files.Dll = 10,System32
+
+[LIBUSB.Files.Sys]
+libusb0.sys
+
+[LIBUSB.Files.Dll]
+libusb0.dll
+
+;--------------------------------------------------------------------------
+; Device driver
+;--------------------------------------------------------------------------
+
+[LIBUSB_DEV]
+CopyFiles = LIBUSB.Files.Sys, LIBUSB.Files.Dll
+AddReg    = LIBUSB_DEV.AddReg
+
+[LIBUSB_DEV.NT]
+CopyFiles = LIBUSB.Files.Sys, LIBUSB.Files.Dll
+
+[LIBUSB_DEV.HW]
+DelReg = LIBUSB_DEV.DelReg.HW
+
+[LIBUSB_DEV.NT.HW]
+DelReg = LIBUSB_DEV.DelReg.HW
+
+[LIBUSB_DEV.NT.Services]
+AddService = libusb0, 0x00000002, LIBUSB.AddService
+
+[LIBUSB_DEV.AddReg]
+HKR,,DevLoader,,*ntkern
+HKR,,NTMPDriver,,libusb0.sys
+
+[LIBUSB_DEV.DelReg.HW]
+HKR,,"LowerFilters"
+
+;--------------------------------------------------------------------------
+; Services
+;--------------------------------------------------------------------------
+
+[LIBUSB.AddService]
+DisplayName    = "LibUsb-Win32 - Kernel Driver 03/09/2005, 0.1.10.1"
+ServiceType    = 1
+StartType      = 3
+ErrorControl   = 0
+ServiceBinary  = %12%\libusb0.sys
+
+;--------------------------------------------------------------------------
+; Devices
+;--------------------------------------------------------------------------
+
+[Devices]
+"USRP filter"=LIBUSB_DEV, USB\VID_fffe&PID_0002
+
+[Strings]
+manufacturer = "GNU Radio folks"
+
diff --git a/usrp/usrp.iss.in b/usrp/usrp.iss.in
new file mode 100644 (file)
index 0000000..b9a4f75
--- /dev/null
@@ -0,0 +1,69 @@
+;
+; 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 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.
+;
+
+; Requirements: Inno Setup (http://www.jrsoftware.org/isdl.php)
+;
+; To compile this script do the following:
+; - copy libusb's driver (libusb0.sys, libusb0.dll) to this folder
+; - copy the USRP filter .inf file to this folder
+; - copy the USRP .exe and .dll files to this folder
+; - open this scipt with Inno Setup
+; - compile and run
+
+[Setup]
+AppName=USRP
+AppVerName=USRP @VERSION@
+AppPublisher=GNU Radio folks
+AppPublisherURL=http://www.gnu.org/software/gnuradio/
+AppVersion=@VERSION@
+DefaultDirName={pf}\Usrp
+DefaultGroupName=Usrp
+Compression=lzma
+SolidCompression=yes
+; Win98 or higher
+MinVersion=4,5
+PrivilegesRequired=admin
+LicenseFile="COPYING_GPL.txt"
+
+[Files]
+; copy the file to the App folder
+Source: "*.sys"; DestDir: "{app}\driver"
+;Source: "*.cat"; DestDir: "{app}\driver"
+Source: "*.dll"; DestDir: "{app}\driver"
+Source: "usrp.inf"; DestDir: "{app}\driver"
+
+; also copy the DLL to the system folders so that rundll32.exe will find it
+Source: "*.dll"; DestDir: "{win}\system32"; FLags: replacesameversion restartreplace
+
+Source: "COPYING_GPL.txt"; DestDir: "{app}"
+Source: "README.txt"; DestDir: "{app}"; Flags: isreadme
+
+Source: "*.exe"; DestDir: "{app}"
+Source: "*.ihx"; DestDir: "{app}\rev2"
+Source: "*.rbf"; DestDir: "{app}\rev2"
+
+[Icons]
+Name: "{group}\Uninstall TestDrivers"; Filename: "{uninstallexe}"
+
+[Run]
+; invoke libusb's DLL to install the .inf file
+Filename: "rundll32"; Parameters: "libusb0.dll,usb_install_driver_np_rundll {app}\driver\usrp.inf"; StatusMsg: "Installing driver (this may take a few seconds) ..."
+
diff --git a/usrp/usrp.pc.in b/usrp/usrp.pc.in
new file mode 100644 (file)
index 0000000..49d27e7
--- /dev/null
@@ -0,0 +1,11 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: usrp
+Description: Universal Software Radio Peripheral
+Requires:
+Version: @VERSION@
+Libs: -L${libdir} -lusrp -lusb
+Cflags: -I${includedir} @DEFINES@