summaryrefslogtreecommitdiff
path: root/gnuradio-core/src
diff options
context:
space:
mode:
Diffstat (limited to 'gnuradio-core/src')
-rw-r--r--gnuradio-core/src/examples/CMakeLists.txt25
-rw-r--r--gnuradio-core/src/examples/mp-sched/CMakeLists.txt36
-rw-r--r--gnuradio-core/src/examples/mp-sched/README2
-rwxr-xr-xgnuradio-core/src/examples/mp-sched/affinity_set.py70
-rw-r--r--gnuradio-core/src/examples/mp-sched/perf-data/core-duo.dat65
-rw-r--r--gnuradio-core/src/examples/mp-sched/perf-data/core2-duo.dat65
-rw-r--r--gnuradio-core/src/examples/mp-sched/perf-data/dual-quad-core-2.33-clovertown.dat257
-rw-r--r--gnuradio-core/src/examples/mp-sched/perf-data/dual-quad-core-3.00-penryn.dat257
-rw-r--r--gnuradio-core/src/examples/mp-sched/perf-data/js21-altivec.dat65
-rw-r--r--gnuradio-core/src/examples/mp-sched/perf-data/js21.dat65
-rw-r--r--gnuradio-core/src/examples/mp-sched/perf-data/ps3-altivec.dat65
-rw-r--r--gnuradio-core/src/examples/mp-sched/perf-data/ps3.dat65
-rw-r--r--gnuradio-core/src/examples/mp-sched/perf-data/qs21-altivec.dat65
-rw-r--r--gnuradio-core/src/examples/mp-sched/perf-data/qs21.dat65
-rwxr-xr-xgnuradio-core/src/examples/mp-sched/plot_flops.py98
-rwxr-xr-xgnuradio-core/src/examples/mp-sched/run_synthetic.py101
-rwxr-xr-xgnuradio-core/src/examples/mp-sched/synthetic.py118
-rwxr-xr-xgnuradio-core/src/examples/mp-sched/wfm_rcv_pll_to_wav.py127
-rw-r--r--gnuradio-core/src/examples/msg_passing/CMakeLists.txt27
-rw-r--r--gnuradio-core/src/examples/msg_passing/hier/test_msg_hier.grc287
-rw-r--r--gnuradio-core/src/examples/msg_passing/hier/test_msg_hier_topblock.grc185
-rw-r--r--gnuradio-core/src/examples/msg_passing/strobe.grc266
-rw-r--r--gnuradio-core/src/examples/network/CMakeLists.txt30
-rwxr-xr-xgnuradio-core/src/examples/network/audio_sink.py72
-rwxr-xr-xgnuradio-core/src/examples/network/audio_source.py69
-rwxr-xr-xgnuradio-core/src/examples/network/dial_tone_sink.py65
-rwxr-xr-xgnuradio-core/src/examples/network/dial_tone_source.py70
-rwxr-xr-xgnuradio-core/src/examples/network/vector_sink.py64
-rwxr-xr-xgnuradio-core/src/examples/network/vector_source.py60
-rw-r--r--gnuradio-core/src/examples/pfb/CMakeLists.txt41
-rwxr-xr-xgnuradio-core/src/examples/pfb/channelize.py191
-rwxr-xr-xgnuradio-core/src/examples/pfb/chirp_channelize.py203
-rwxr-xr-xgnuradio-core/src/examples/pfb/decimate.py178
-rwxr-xr-xgnuradio-core/src/examples/pfb/fmtest.py225
-rwxr-xr-xgnuradio-core/src/examples/pfb/interpolate.py233
-rwxr-xr-xgnuradio-core/src/examples/pfb/reconstruction.py131
-rwxr-xr-xgnuradio-core/src/examples/pfb/resampler.py127
-rw-r--r--gnuradio-core/src/examples/pfb/resampler_demo.grc598
-rwxr-xr-xgnuradio-core/src/examples/pfb/synth_filter.py83
-rwxr-xr-xgnuradio-core/src/examples/pfb/synth_to_chan.py117
-rw-r--r--gnuradio-core/src/examples/tags/CMakeLists.txt28
-rwxr-xr-xgnuradio-core/src/examples/tags/test_file_tags.py55
-rwxr-xr-xgnuradio-core/src/examples/tags/uhd_burst_detector.py116
-rw-r--r--gnuradio-core/src/examples/volk_benchmark/CMakeLists.txt35
-rw-r--r--gnuradio-core/src/examples/volk_benchmark/README252
-rwxr-xr-xgnuradio-core/src/examples/volk_benchmark/volk_math.py151
-rwxr-xr-xgnuradio-core/src/examples/volk_benchmark/volk_plot.py169
-rw-r--r--gnuradio-core/src/examples/volk_benchmark/volk_test_funcs.py171
-rwxr-xr-xgnuradio-core/src/examples/volk_benchmark/volk_types.py182
-rw-r--r--gnuradio-core/src/gen_interpolator_taps/Makefile.am.obsolete39
-rw-r--r--gnuradio-core/src/gen_interpolator_taps/README47
-rw-r--r--gnuradio-core/src/gen_interpolator_taps/gen_interpolator_taps.c186
-rw-r--r--gnuradio-core/src/gen_interpolator_taps/objective_fct.c124
-rw-r--r--gnuradio-core/src/gen_interpolator_taps/praxis.f1705
-rw-r--r--gnuradio-core/src/gen_interpolator_taps/praxis.txt176
-rw-r--r--gnuradio-core/src/gen_interpolator_taps/simpson.c76
-rw-r--r--gnuradio-core/src/gen_interpolator_taps/simpson.h3
-rw-r--r--gnuradio-core/src/lib/CMakeLists.txt106
-rw-r--r--gnuradio-core/src/lib/ConfigChecks.cmake212
-rw-r--r--gnuradio-core/src/lib/bug_work_around_6.cc3
-rw-r--r--gnuradio-core/src/lib/filter/3dnow_float_dotprod_really_simple.S99
-rw-r--r--gnuradio-core/src/lib/filter/3dnow_float_dotprod_simple.S106
-rw-r--r--gnuradio-core/src/lib/filter/CMakeLists.txt357
-rw-r--r--gnuradio-core/src/lib/filter/Makefile.gen124
-rw-r--r--gnuradio-core/src/lib/filter/README28
-rw-r--r--gnuradio-core/src/lib/filter/assembly.h67
-rw-r--r--gnuradio-core/src/lib/filter/ccomplex_dotprod_3dnow.S220
-rw-r--r--gnuradio-core/src/lib/filter/ccomplex_dotprod_3dnow64.S217
-rw-r--r--gnuradio-core/src/lib/filter/ccomplex_dotprod_3dnowext.S195
-rw-r--r--gnuradio-core/src/lib/filter/ccomplex_dotprod_3dnowext64.S192
-rw-r--r--gnuradio-core/src/lib/filter/ccomplex_dotprod_generic.cc58
-rw-r--r--gnuradio-core/src/lib/filter/ccomplex_dotprod_generic.h34
-rw-r--r--gnuradio-core/src/lib/filter/ccomplex_dotprod_sse.S198
-rw-r--r--gnuradio-core/src/lib/filter/ccomplex_dotprod_sse64.S195
-rw-r--r--gnuradio-core/src/lib/filter/ccomplex_dotprod_x86.h46
-rw-r--r--gnuradio-core/src/lib/filter/complex_dotprod_3dnow.S192
-rw-r--r--gnuradio-core/src/lib/filter/complex_dotprod_3dnow64.S187
-rw-r--r--gnuradio-core/src/lib/filter/complex_dotprod_3dnowext.S171
-rw-r--r--gnuradio-core/src/lib/filter/complex_dotprod_3dnowext64.S168
-rw-r--r--gnuradio-core/src/lib/filter/complex_dotprod_generic.cc54
-rw-r--r--gnuradio-core/src/lib/filter/complex_dotprod_generic.h34
-rw-r--r--gnuradio-core/src/lib/filter/complex_dotprod_sse.S206
-rw-r--r--gnuradio-core/src/lib/filter/complex_dotprod_sse64.S202
-rw-r--r--gnuradio-core/src/lib/filter/complex_dotprod_x86.h46
-rw-r--r--gnuradio-core/src/lib/filter/dotprod_ccf_armv7_a.c90
-rw-r--r--gnuradio-core/src/lib/filter/dotprod_ccf_armv7_a.h47
-rw-r--r--gnuradio-core/src/lib/filter/dotprod_fff_altivec.c162
-rw-r--r--gnuradio-core/src/lib/filter/dotprod_fff_altivec.h50
-rw-r--r--gnuradio-core/src/lib/filter/dotprod_fff_armv7_a.c87
-rw-r--r--gnuradio-core/src/lib/filter/dotprod_fff_armv7_a.h50
-rw-r--r--gnuradio-core/src/lib/filter/fcomplex_dotprod_3dnow.S176
-rw-r--r--gnuradio-core/src/lib/filter/fcomplex_dotprod_3dnow64.S170
-rw-r--r--gnuradio-core/src/lib/filter/fcomplex_dotprod_sse.S188
-rw-r--r--gnuradio-core/src/lib/filter/fcomplex_dotprod_sse64.S183
-rw-r--r--gnuradio-core/src/lib/filter/fcomplex_dotprod_x86.h42
-rw-r--r--gnuradio-core/src/lib/filter/filter.i70
-rw-r--r--gnuradio-core/src/lib/filter/float_dotprod_3dnow.S152
-rw-r--r--gnuradio-core/src/lib/filter/float_dotprod_3dnow64.S149
-rw-r--r--gnuradio-core/src/lib/filter/float_dotprod_generic.c49
-rw-r--r--gnuradio-core/src/lib/filter/float_dotprod_generic.h41
-rw-r--r--gnuradio-core/src/lib/filter/float_dotprod_sse.S171
-rw-r--r--gnuradio-core/src/lib/filter/float_dotprod_sse64.S165
-rw-r--r--gnuradio-core/src/lib/filter/float_dotprod_x86.h44
-rw-r--r--gnuradio-core/src/lib/filter/gcc_x86_cpuid.h178
-rwxr-xr-xgnuradio-core/src/lib/filter/generate_all.py48
-rwxr-xr-xgnuradio-core/src/lib/filter/generate_gr_fir_XXX.py75
-rwxr-xr-xgnuradio-core/src/lib/filter/generate_gr_fir_filter_XXX.py49
-rwxr-xr-xgnuradio-core/src/lib/filter/generate_gr_fir_sysconfig.py133
-rwxr-xr-xgnuradio-core/src/lib/filter/generate_gr_fir_sysconfig_generic.py186
-rwxr-xr-xgnuradio-core/src/lib/filter/generate_gr_fir_util.py190
-rwxr-xr-xgnuradio-core/src/lib/filter/generate_gr_freq_xlating_fir_filter_XXX.py53
-rw-r--r--gnuradio-core/src/lib/filter/generate_gr_interp_fir_filter_XXX.py48
-rw-r--r--gnuradio-core/src/lib/filter/generate_gr_rational_resampler_base_XXX.py48
-rwxr-xr-xgnuradio-core/src/lib/filter/generate_gri_fir_filter_with_buffer_XXX.py64
-rw-r--r--gnuradio-core/src/lib/filter/generate_utils.py31
-rw-r--r--gnuradio-core/src/lib/filter/gr_adaptive_fir_ccc.cc88
-rw-r--r--gnuradio-core/src/lib/filter/gr_adaptive_fir_ccc.h62
-rw-r--r--gnuradio-core/src/lib/filter/gr_adaptive_fir_ccc.i31
-rw-r--r--gnuradio-core/src/lib/filter/gr_adaptive_fir_ccf.cc81
-rw-r--r--gnuradio-core/src/lib/filter/gr_adaptive_fir_ccf.h59
-rw-r--r--gnuradio-core/src/lib/filter/gr_adaptive_fir_ccf.i30
-rw-r--r--gnuradio-core/src/lib/filter/gr_altivec.c38
-rw-r--r--gnuradio-core/src/lib/filter/gr_altivec.h76
-rw-r--r--gnuradio-core/src/lib/filter/gr_cpu.h42
-rw-r--r--gnuradio-core/src/lib/filter/gr_cpu_armv7_a.cc65
-rw-r--r--gnuradio-core/src/lib/filter/gr_cpu_powerpc.cc65
-rw-r--r--gnuradio-core/src/lib/filter/gr_cpu_x86.cc119
-rw-r--r--gnuradio-core/src/lib/filter/gr_dc_blocker_cc.cc138
-rw-r--r--gnuradio-core/src/lib/filter/gr_dc_blocker_cc.h111
-rw-r--r--gnuradio-core/src/lib/filter/gr_dc_blocker_cc.i34
-rw-r--r--gnuradio-core/src/lib/filter/gr_dc_blocker_ff.cc138
-rw-r--r--gnuradio-core/src/lib/filter/gr_dc_blocker_ff.h112
-rw-r--r--gnuradio-core/src/lib/filter/gr_dc_blocker_ff.i34
-rw-r--r--gnuradio-core/src/lib/filter/gr_fft_filter_ccc.cc132
-rw-r--r--gnuradio-core/src/lib/filter/gr_fft_filter_ccc.h90
-rw-r--r--gnuradio-core/src/lib/filter/gr_fft_filter_ccc.i46
-rw-r--r--gnuradio-core/src/lib/filter/gr_fft_filter_fff.cc123
-rw-r--r--gnuradio-core/src/lib/filter/gr_fft_filter_fff.h88
-rw-r--r--gnuradio-core/src/lib/filter/gr_fft_filter_fff.i45
-rw-r--r--gnuradio-core/src/lib/filter/gr_filter_delay_fc.cc80
-rw-r--r--gnuradio-core/src/lib/filter/gr_filter_delay_fc.h73
-rw-r--r--gnuradio-core/src/lib/filter/gr_filter_delay_fc.i34
-rw-r--r--gnuradio-core/src/lib/filter/gr_fir_XXX.cc.t30
-rw-r--r--gnuradio-core/src/lib/filter/gr_fir_XXX.h.t124
-rw-r--r--gnuradio-core/src/lib/filter/gr_fir_XXX_generic.cc.t103
-rw-r--r--gnuradio-core/src/lib/filter/gr_fir_XXX_generic.h.t78
-rw-r--r--gnuradio-core/src/lib/filter/gr_fir_ccc_simd.cc142
-rw-r--r--gnuradio-core/src/lib/filter/gr_fir_ccc_simd.h65
-rw-r--r--gnuradio-core/src/lib/filter/gr_fir_ccc_x86.cc77
-rw-r--r--gnuradio-core/src/lib/filter/gr_fir_ccc_x86.h56
-rw-r--r--gnuradio-core/src/lib/filter/gr_fir_ccf_armv7_a.cc91
-rw-r--r--gnuradio-core/src/lib/filter/gr_fir_ccf_armv7_a.h45
-rw-r--r--gnuradio-core/src/lib/filter/gr_fir_ccf_simd.cc141
-rw-r--r--gnuradio-core/src/lib/filter/gr_fir_ccf_simd.h66
-rw-r--r--gnuradio-core/src/lib/filter/gr_fir_ccf_x86.cc60
-rw-r--r--gnuradio-core/src/lib/filter/gr_fir_ccf_x86.h51
-rw-r--r--gnuradio-core/src/lib/filter/gr_fir_fcc_simd.cc139
-rw-r--r--gnuradio-core/src/lib/filter/gr_fir_fcc_simd.h66
-rw-r--r--gnuradio-core/src/lib/filter/gr_fir_fcc_x86.cc60
-rw-r--r--gnuradio-core/src/lib/filter/gr_fir_fcc_x86.h51
-rw-r--r--gnuradio-core/src/lib/filter/gr_fir_fff_altivec.cc84
-rw-r--r--gnuradio-core/src/lib/filter/gr_fir_fff_altivec.h46
-rw-r--r--gnuradio-core/src/lib/filter/gr_fir_fff_armv7_a.cc86
-rw-r--r--gnuradio-core/src/lib/filter/gr_fir_fff_armv7_a.h46
-rw-r--r--gnuradio-core/src/lib/filter/gr_fir_fff_simd.cc134
-rw-r--r--gnuradio-core/src/lib/filter/gr_fir_fff_simd.h64
-rw-r--r--gnuradio-core/src/lib/filter/gr_fir_fff_x86.cc60
-rw-r--r--gnuradio-core/src/lib/filter/gr_fir_fff_x86.h49
-rw-r--r--gnuradio-core/src/lib/filter/gr_fir_filter_XXX.cc.t94
-rw-r--r--gnuradio-core/src/lib/filter/gr_fir_filter_XXX.h.t69
-rw-r--r--gnuradio-core/src/lib/filter/gr_fir_filter_XXX.i.t42
-rw-r--r--gnuradio-core/src/lib/filter/gr_fir_fsf_simd.cc133
-rw-r--r--gnuradio-core/src/lib/filter/gr_fir_fsf_simd.h64
-rw-r--r--gnuradio-core/src/lib/filter/gr_fir_fsf_x86.cc60
-rw-r--r--gnuradio-core/src/lib/filter/gr_fir_fsf_x86.h51
-rw-r--r--gnuradio-core/src/lib/filter/gr_fir_scc_simd.cc140
-rw-r--r--gnuradio-core/src/lib/filter/gr_fir_scc_simd.h65
-rw-r--r--gnuradio-core/src/lib/filter/gr_fir_scc_x86.cc77
-rw-r--r--gnuradio-core/src/lib/filter/gr_fir_scc_x86.h59
-rw-r--r--gnuradio-core/src/lib/filter/gr_fir_sysconfig_armv7_a.cc337
-rw-r--r--gnuradio-core/src/lib/filter/gr_fir_sysconfig_armv7_a.h47
-rw-r--r--gnuradio-core/src/lib/filter/gr_fir_sysconfig_powerpc.cc340
-rw-r--r--gnuradio-core/src/lib/filter/gr_fir_sysconfig_powerpc.h47
-rw-r--r--gnuradio-core/src/lib/filter/gr_fir_sysconfig_x86.cc553
-rw-r--r--gnuradio-core/src/lib/filter/gr_fir_sysconfig_x86.h47
-rw-r--r--gnuradio-core/src/lib/filter/gr_fractional_interpolator_cc.cc93
-rw-r--r--gnuradio-core/src/lib/filter/gr_fractional_interpolator_cc.h68
-rw-r--r--gnuradio-core/src/lib/filter/gr_fractional_interpolator_cc.i37
-rw-r--r--gnuradio-core/src/lib/filter/gr_fractional_interpolator_ff.cc93
-rw-r--r--gnuradio-core/src/lib/filter/gr_fractional_interpolator_ff.h68
-rw-r--r--gnuradio-core/src/lib/filter/gr_fractional_interpolator_ff.i37
-rw-r--r--gnuradio-core/src/lib/filter/gr_freq_xlating_fir_filter_XXX.cc.t123
-rw-r--r--gnuradio-core/src/lib/filter/gr_freq_xlating_fir_filter_XXX.h.t101
-rw-r--r--gnuradio-core/src/lib/filter/gr_freq_xlating_fir_filter_XXX.i.t47
-rw-r--r--gnuradio-core/src/lib/filter/gr_goertzel_fc.cc76
-rw-r--r--gnuradio-core/src/lib/filter/gr_goertzel_fc.h61
-rw-r--r--gnuradio-core/src/lib/filter/gr_goertzel_fc.i35
-rw-r--r--gnuradio-core/src/lib/filter/gr_hilbert_fc.cc67
-rw-r--r--gnuradio-core/src/lib/filter/gr_hilbert_fc.h69
-rw-r--r--gnuradio-core/src/lib/filter/gr_hilbert_fc.i34
-rw-r--r--gnuradio-core/src/lib/filter/gr_iir_filter_ffd.cc82
-rw-r--r--gnuradio-core/src/lib/filter/gr_iir_filter_ffd.h99
-rw-r--r--gnuradio-core/src/lib/filter/gr_iir_filter_ffd.i40
-rw-r--r--gnuradio-core/src/lib/filter/gr_interp_fir_filter_XXX.cc.t146
-rw-r--r--gnuradio-core/src/lib/filter/gr_interp_fir_filter_XXX.h.t70
-rw-r--r--gnuradio-core/src/lib/filter/gr_interp_fir_filter_XXX.i.t41
-rw-r--r--gnuradio-core/src/lib/filter/gr_pfb_arb_resampler_ccf.cc210
-rw-r--r--gnuradio-core/src/lib/filter/gr_pfb_arb_resampler_ccf.h178
-rw-r--r--gnuradio-core/src/lib/filter/gr_pfb_arb_resampler_ccf.i42
-rw-r--r--gnuradio-core/src/lib/filter/gr_pfb_arb_resampler_fff.cc210
-rw-r--r--gnuradio-core/src/lib/filter/gr_pfb_arb_resampler_fff.h178
-rw-r--r--gnuradio-core/src/lib/filter/gr_pfb_arb_resampler_fff.i42
-rw-r--r--gnuradio-core/src/lib/filter/gr_pfb_channelizer_ccf.cc240
-rw-r--r--gnuradio-core/src/lib/filter/gr_pfb_channelizer_ccf.h226
-rw-r--r--gnuradio-core/src/lib/filter/gr_pfb_channelizer_ccf.i45
-rw-r--r--gnuradio-core/src/lib/filter/gr_pfb_clock_sync_ccf.cc441
-rw-r--r--gnuradio-core/src/lib/filter/gr_pfb_clock_sync_ccf.h375
-rw-r--r--gnuradio-core/src/lib/filter/gr_pfb_clock_sync_ccf.i67
-rw-r--r--gnuradio-core/src/lib/filter/gr_pfb_clock_sync_fff.cc288
-rw-r--r--gnuradio-core/src/lib/filter/gr_pfb_clock_sync_fff.h266
-rw-r--r--gnuradio-core/src/lib/filter/gr_pfb_clock_sync_fff.i54
-rw-r--r--gnuradio-core/src/lib/filter/gr_pfb_decimator_ccf.cc176
-rw-r--r--gnuradio-core/src/lib/filter/gr_pfb_decimator_ccf.h150
-rw-r--r--gnuradio-core/src/lib/filter/gr_pfb_decimator_ccf.i41
-rw-r--r--gnuradio-core/src/lib/filter/gr_pfb_interpolator_ccf.cc143
-rw-r--r--gnuradio-core/src/lib/filter/gr_pfb_interpolator_ccf.h131
-rw-r--r--gnuradio-core/src/lib/filter/gr_pfb_interpolator_ccf.i39
-rw-r--r--gnuradio-core/src/lib/filter/gr_pfb_synthesizer_ccf.cc287
-rw-r--r--gnuradio-core/src/lib/filter/gr_pfb_synthesizer_ccf.h147
-rw-r--r--gnuradio-core/src/lib/filter/gr_pfb_synthesizer_ccf.i44
-rw-r--r--gnuradio-core/src/lib/filter/gr_rational_resampler_base_XXX.cc.t172
-rw-r--r--gnuradio-core/src/lib/filter/gr_rational_resampler_base_XXX.h.t88
-rw-r--r--gnuradio-core/src/lib/filter/gr_rational_resampler_base_XXX.i.t42
-rw-r--r--gnuradio-core/src/lib/filter/gr_rotator.h54
-rw-r--r--gnuradio-core/src/lib/filter/gr_sincos.c83
-rw-r--r--gnuradio-core/src/lib/filter/gr_sincos.h41
-rw-r--r--gnuradio-core/src/lib/filter/gr_single_pole_iir.h191
-rw-r--r--gnuradio-core/src/lib/filter/gr_single_pole_iir_filter_cc.cc81
-rw-r--r--gnuradio-core/src/lib/filter/gr_single_pole_iir_filter_cc.h88
-rw-r--r--gnuradio-core/src/lib/filter/gr_single_pole_iir_filter_cc.i34
-rw-r--r--gnuradio-core/src/lib/filter/gr_single_pole_iir_filter_ff.cc81
-rw-r--r--gnuradio-core/src/lib/filter/gr_single_pole_iir_filter_ff.h87
-rw-r--r--gnuradio-core/src/lib/filter/gr_single_pole_iir_filter_ff.i34
-rw-r--r--gnuradio-core/src/lib/filter/gr_vec_types.h54
-rw-r--r--gnuradio-core/src/lib/filter/gri_fft_filter_ccc_generic.cc184
-rw-r--r--gnuradio-core/src/lib/filter/gri_fft_filter_ccc_generic.h96
-rw-r--r--gnuradio-core/src/lib/filter/gri_fft_filter_ccc_sse.cc186
-rw-r--r--gnuradio-core/src/lib/filter/gri_fft_filter_ccc_sse.h83
-rw-r--r--gnuradio-core/src/lib/filter/gri_fft_filter_fff_generic.cc175
-rw-r--r--gnuradio-core/src/lib/filter/gri_fft_filter_fff_generic.h94
-rw-r--r--gnuradio-core/src/lib/filter/gri_fft_filter_fff_sse.cc184
-rw-r--r--gnuradio-core/src/lib/filter/gri_fft_filter_fff_sse.h82
-rw-r--r--gnuradio-core/src/lib/filter/gri_fir_filter_with_buffer_XXX.cc.t121
-rw-r--r--gnuradio-core/src/lib/filter/gri_fir_filter_with_buffer_XXX.h.t132
-rw-r--r--gnuradio-core/src/lib/filter/gri_goertzel.cc75
-rw-r--r--gnuradio-core/src/lib/filter/gri_goertzel.h57
-rw-r--r--gnuradio-core/src/lib/filter/gri_iir.h177
-rw-r--r--gnuradio-core/src/lib/filter/gri_mmse_fir_interpolator.cc71
-rw-r--r--gnuradio-core/src/lib/filter/gri_mmse_fir_interpolator.h71
-rw-r--r--gnuradio-core/src/lib/filter/gri_mmse_fir_interpolator_cc.cc71
-rw-r--r--gnuradio-core/src/lib/filter/gri_mmse_fir_interpolator_cc.h74
-rw-r--r--gnuradio-core/src/lib/filter/interpolator_taps.h141
-rw-r--r--gnuradio-core/src/lib/filter/qa_ccomplex_dotprod_x86.cc341
-rw-r--r--gnuradio-core/src/lib/filter/qa_ccomplex_dotprod_x86.h74
-rw-r--r--gnuradio-core/src/lib/filter/qa_complex_dotprod_x86.cc347
-rw-r--r--gnuradio-core/src/lib/filter/qa_complex_dotprod_x86.h74
-rw-r--r--gnuradio-core/src/lib/filter/qa_dotprod.h30
-rw-r--r--gnuradio-core/src/lib/filter/qa_dotprod_armv7_a.cc32
-rw-r--r--gnuradio-core/src/lib/filter/qa_dotprod_generic.cc32
-rw-r--r--gnuradio-core/src/lib/filter/qa_dotprod_powerpc.cc32
-rw-r--r--gnuradio-core/src/lib/filter/qa_dotprod_x86.cc37
-rw-r--r--gnuradio-core/src/lib/filter/qa_filter.cc68
-rw-r--r--gnuradio-core/src/lib/filter/qa_filter.h38
-rw-r--r--gnuradio-core/src/lib/filter/qa_float_dotprod_x86.cc270
-rw-r--r--gnuradio-core/src/lib/filter/qa_float_dotprod_x86.h69
-rw-r--r--gnuradio-core/src/lib/filter/qa_gr_fir_ccc.cc184
-rw-r--r--gnuradio-core/src/lib/filter/qa_gr_fir_ccc.h40
-rw-r--r--gnuradio-core/src/lib/filter/qa_gr_fir_ccf.cc184
-rw-r--r--gnuradio-core/src/lib/filter/qa_gr_fir_ccf.h43
-rw-r--r--gnuradio-core/src/lib/filter/qa_gr_fir_fcc.cc181
-rw-r--r--gnuradio-core/src/lib/filter/qa_gr_fir_fcc.h40
-rw-r--r--gnuradio-core/src/lib/filter/qa_gr_fir_fff.cc226
-rw-r--r--gnuradio-core/src/lib/filter/qa_gr_fir_fff.h43
-rw-r--r--gnuradio-core/src/lib/filter/qa_gr_fir_scc.cc179
-rw-r--r--gnuradio-core/src/lib/filter/qa_gr_fir_scc.h40
-rw-r--r--gnuradio-core/src/lib/filter/qa_gr_rotator.cc75
-rw-r--r--gnuradio-core/src/lib/filter/qa_gr_rotator.h39
-rw-r--r--gnuradio-core/src/lib/filter/qa_gri_fir_filter_with_buffer_ccc.cc161
-rw-r--r--gnuradio-core/src/lib/filter/qa_gri_fir_filter_with_buffer_ccc.h46
-rw-r--r--gnuradio-core/src/lib/filter/qa_gri_fir_filter_with_buffer_ccf.cc167
-rw-r--r--gnuradio-core/src/lib/filter/qa_gri_fir_filter_with_buffer_ccf.h46
-rw-r--r--gnuradio-core/src/lib/filter/qa_gri_fir_filter_with_buffer_fcc.cc168
-rw-r--r--gnuradio-core/src/lib/filter/qa_gri_fir_filter_with_buffer_fcc.h46
-rw-r--r--gnuradio-core/src/lib/filter/qa_gri_fir_filter_with_buffer_fff.cc156
-rw-r--r--gnuradio-core/src/lib/filter/qa_gri_fir_filter_with_buffer_fff.h46
-rw-r--r--gnuradio-core/src/lib/filter/qa_gri_fir_filter_with_buffer_fsf.cc147
-rw-r--r--gnuradio-core/src/lib/filter/qa_gri_fir_filter_with_buffer_fsf.h46
-rw-r--r--gnuradio-core/src/lib/filter/qa_gri_fir_filter_with_buffer_scc.cc167
-rw-r--r--gnuradio-core/src/lib/filter/qa_gri_fir_filter_with_buffer_scc.h46
-rw-r--r--gnuradio-core/src/lib/filter/qa_gri_mmse_fir_interpolator.cc66
-rw-r--r--gnuradio-core/src/lib/filter/qa_gri_mmse_fir_interpolator.h40
-rw-r--r--gnuradio-core/src/lib/filter/qa_gri_mmse_fir_interpolator_cc.cc124
-rw-r--r--gnuradio-core/src/lib/filter/qa_gri_mmse_fir_interpolator_cc.h42
-rw-r--r--gnuradio-core/src/lib/filter/short_dotprod_generic.c49
-rw-r--r--gnuradio-core/src/lib/filter/short_dotprod_generic.h41
-rw-r--r--gnuradio-core/src/lib/filter/short_dotprod_mmx.S117
-rw-r--r--gnuradio-core/src/lib/filter/short_dotprod_mmx64.S105
-rw-r--r--gnuradio-core/src/lib/filter/short_dotprod_x86.h44
-rw-r--r--gnuradio-core/src/lib/filter/sse_debug.c62
-rw-r--r--gnuradio-core/src/lib/filter/sse_debug.h48
-rw-r--r--gnuradio-core/src/lib/filter/sysconfig_armv7_a.cc39
-rw-r--r--gnuradio-core/src/lib/filter/sysconfig_generic.cc35
-rw-r--r--gnuradio-core/src/lib/filter/sysconfig_powerpc.cc38
-rw-r--r--gnuradio-core/src/lib/filter/sysconfig_x86.cc38
-rw-r--r--gnuradio-core/src/lib/general/CMakeLists.txt312
-rw-r--r--gnuradio-core/src/lib/general/README98
-rw-r--r--gnuradio-core/src/lib/general/atsc_rrc1x.dat57
-rw-r--r--gnuradio-core/src/lib/general/atsc_rrc20.dat101
-rw-r--r--gnuradio-core/src/lib/general/atsc_rrc2x.dat102
-rw-r--r--gnuradio-core/src/lib/general/complex_vec_test.cc82
-rw-r--r--gnuradio-core/src/lib/general/complex_vec_test.h28
-rw-r--r--gnuradio-core/src/lib/general/complex_vec_test.i25
-rwxr-xr-xgnuradio-core/src/lib/general/gen_sine_table.py77
-rw-r--r--gnuradio-core/src/lib/general/general.i273
-rw-r--r--gnuradio-core/src/lib/general/general_generated.i166
-rw-r--r--gnuradio-core/src/lib/general/gr_add_ff.cc66
-rw-r--r--gnuradio-core/src/lib/general/gr_add_ff.h56
-rw-r--r--gnuradio-core/src/lib/general/gr_add_ff.i32
-rw-r--r--gnuradio-core/src/lib/general/gr_additive_scrambler_bb.cc65
-rw-r--r--gnuradio-core/src/lib/general/gr_additive_scrambler_bb.h68
-rw-r--r--gnuradio-core/src/lib/general/gr_additive_scrambler_bb.i31
-rw-r--r--gnuradio-core/src/lib/general/gr_agc2_cc.cc56
-rw-r--r--gnuradio-core/src/lib/general/gr_agc2_cc.h56
-rw-r--r--gnuradio-core/src/lib/general/gr_agc2_cc.i35
-rw-r--r--gnuradio-core/src/lib/general/gr_agc2_ff.cc57
-rw-r--r--gnuradio-core/src/lib/general/gr_agc2_ff.h54
-rw-r--r--gnuradio-core/src/lib/general/gr_agc2_ff.i35
-rw-r--r--gnuradio-core/src/lib/general/gr_agc_cc.cc56
-rw-r--r--gnuradio-core/src/lib/general/gr_agc_cc.h55
-rw-r--r--gnuradio-core/src/lib/general/gr_agc_cc.i35
-rw-r--r--gnuradio-core/src/lib/general/gr_agc_ff.cc54
-rw-r--r--gnuradio-core/src/lib/general/gr_agc_ff.h55
-rw-r--r--gnuradio-core/src/lib/general/gr_agc_ff.i34
-rw-r--r--gnuradio-core/src/lib/general/gr_align_on_samplenumbers_ss.cc464
-rw-r--r--gnuradio-core/src/lib/general/gr_align_on_samplenumbers_ss.h92
-rw-r--r--gnuradio-core/src/lib/general/gr_align_on_samplenumbers_ss.i34
-rw-r--r--gnuradio-core/src/lib/general/gr_annotator_1to1.cc107
-rw-r--r--gnuradio-core/src/lib/general/gr_annotator_1to1.h75
-rw-r--r--gnuradio-core/src/lib/general/gr_annotator_1to1.i25
-rw-r--r--gnuradio-core/src/lib/general/gr_annotator_alltoall.cc110
-rw-r--r--gnuradio-core/src/lib/general/gr_annotator_alltoall.h76
-rw-r--r--gnuradio-core/src/lib/general/gr_annotator_alltoall.i25
-rw-r--r--gnuradio-core/src/lib/general/gr_annotator_raw.cc106
-rw-r--r--gnuradio-core/src/lib/general/gr_annotator_raw.h69
-rw-r--r--gnuradio-core/src/lib/general/gr_annotator_raw.i26
-rw-r--r--gnuradio-core/src/lib/general/gr_bin_statistics_f.cc174
-rw-r--r--gnuradio-core/src/lib/general/gr_bin_statistics_f.h100
-rw-r--r--gnuradio-core/src/lib/general/gr_bin_statistics_f.i47
-rw-r--r--gnuradio-core/src/lib/general/gr_block_gateway.cc184
-rw-r--r--gnuradio-core/src/lib/general/gr_block_gateway.h264
-rw-r--r--gnuradio-core/src/lib/general/gr_block_gateway.i46
-rw-r--r--gnuradio-core/src/lib/general/gr_burst_tagger.cc109
-rw-r--r--gnuradio-core/src/lib/general/gr_burst_tagger.h64
-rw-r--r--gnuradio-core/src/lib/general/gr_burst_tagger.i35
-rw-r--r--gnuradio-core/src/lib/general/gr_bytes_to_syms.cc74
-rw-r--r--gnuradio-core/src/lib/general/gr_bytes_to_syms.h61
-rw-r--r--gnuradio-core/src/lib/general/gr_bytes_to_syms.i30
-rw-r--r--gnuradio-core/src/lib/general/gr_char_to_float.cc72
-rw-r--r--gnuradio-core/src/lib/general/gr_char_to_float.h70
-rw-r--r--gnuradio-core/src/lib/general/gr_char_to_float.i33
-rw-r--r--gnuradio-core/src/lib/general/gr_char_to_short.cc64
-rw-r--r--gnuradio-core/src/lib/general/gr_char_to_short.h58
-rw-r--r--gnuradio-core/src/lib/general/gr_char_to_short.i30
-rw-r--r--gnuradio-core/src/lib/general/gr_check_counting_s.cc190
-rw-r--r--gnuradio-core/src/lib/general/gr_check_counting_s.h89
-rw-r--r--gnuradio-core/src/lib/general/gr_check_counting_s.i31
-rw-r--r--gnuradio-core/src/lib/general/gr_check_lfsr_32k_s.cc169
-rw-r--r--gnuradio-core/src/lib/general/gr_check_lfsr_32k_s.h103
-rw-r--r--gnuradio-core/src/lib/general/gr_check_lfsr_32k_s.i36
-rw-r--r--gnuradio-core/src/lib/general/gr_circular_file.cc203
-rw-r--r--gnuradio-core/src/lib/general/gr_circular_file.h60
-rw-r--r--gnuradio-core/src/lib/general/gr_complex_to_interleaved_short.cc62
-rw-r--r--gnuradio-core/src/lib/general/gr_complex_to_interleaved_short.h52
-rw-r--r--gnuradio-core/src/lib/general/gr_complex_to_interleaved_short.i30
-rw-r--r--gnuradio-core/src/lib/general/gr_complex_to_xxx.cc280
-rw-r--r--gnuradio-core/src/lib/general/gr_complex_to_xxx.h160
-rw-r--r--gnuradio-core/src/lib/general/gr_complex_to_xxx.i64
-rw-r--r--gnuradio-core/src/lib/general/gr_conjugate_cc.cc65
-rw-r--r--gnuradio-core/src/lib/general/gr_conjugate_cc.h52
-rw-r--r--gnuradio-core/src/lib/general/gr_conjugate_cc.i33
-rw-r--r--gnuradio-core/src/lib/general/gr_constants.cc.in57
-rw-r--r--gnuradio-core/src/lib/general/gr_constants.h53
-rw-r--r--gnuradio-core/src/lib/general/gr_constants.i13
-rw-r--r--gnuradio-core/src/lib/general/gr_copy.cc71
-rw-r--r--gnuradio-core/src/lib/general/gr_copy.h63
-rw-r--r--gnuradio-core/src/lib/general/gr_copy.i36
-rw-r--r--gnuradio-core/src/lib/general/gr_core_api.h33
-rw-r--r--gnuradio-core/src/lib/general/gr_correlate_access_code_tag_bb.cc129
-rw-r--r--gnuradio-core/src/lib/general/gr_correlate_access_code_tag_bb.h87
-rw-r--r--gnuradio-core/src/lib/general/gr_correlate_access_code_tag_bb.i60
-rw-r--r--gnuradio-core/src/lib/general/gr_count_bits.cc93
-rw-r--r--gnuradio-core/src/lib/general/gr_count_bits.h33
-rw-r--r--gnuradio-core/src/lib/general/gr_cpfsk_bc.cc78
-rw-r--r--gnuradio-core/src/lib/general/gr_cpfsk_bc.h64
-rw-r--r--gnuradio-core/src/lib/general/gr_cpfsk_bc.i34
-rw-r--r--gnuradio-core/src/lib/general/gr_cpm.cc218
-rw-r--r--gnuradio-core/src/lib/general/gr_cpm.h81
-rw-r--r--gnuradio-core/src/lib/general/gr_cpm.i40
-rw-r--r--gnuradio-core/src/lib/general/gr_ctcss_squelch_ff.cc112
-rw-r--r--gnuradio-core/src/lib/general/gr_ctcss_squelch_ff.h68
-rw-r--r--gnuradio-core/src/lib/general/gr_ctcss_squelch_ff.i39
-rw-r--r--gnuradio-core/src/lib/general/gr_decode_ccsds_27_fb.cc86
-rw-r--r--gnuradio-core/src/lib/general/gr_decode_ccsds_27_fb.h78
-rw-r--r--gnuradio-core/src/lib/general/gr_decode_ccsds_27_fb.i31
-rw-r--r--gnuradio-core/src/lib/general/gr_deinterleave.cc78
-rw-r--r--gnuradio-core/src/lib/general/gr_deinterleave.h57
-rw-r--r--gnuradio-core/src/lib/general/gr_deinterleave.i30
-rw-r--r--gnuradio-core/src/lib/general/gr_delay.cc129
-rw-r--r--gnuradio-core/src/lib/general/gr_delay.h61
-rw-r--r--gnuradio-core/src/lib/general/gr_delay.i35
-rw-r--r--gnuradio-core/src/lib/general/gr_descrambler_bb.cc56
-rw-r--r--gnuradio-core/src/lib/general/gr_descrambler_bb.h60
-rw-r--r--gnuradio-core/src/lib/general/gr_descrambler_bb.i31
-rw-r--r--gnuradio-core/src/lib/general/gr_diff_decoder_bb.cc61
-rw-r--r--gnuradio-core/src/lib/general/gr_diff_decoder_bb.h53
-rw-r--r--gnuradio-core/src/lib/general/gr_diff_decoder_bb.i31
-rw-r--r--gnuradio-core/src/lib/general/gr_diff_encoder_bb.cc62
-rw-r--r--gnuradio-core/src/lib/general/gr_diff_encoder_bb.h54
-rw-r--r--gnuradio-core/src/lib/general/gr_diff_encoder_bb.i31
-rw-r--r--gnuradio-core/src/lib/general/gr_diff_phasor_cc.cc61
-rw-r--r--gnuradio-core/src/lib/general/gr_diff_phasor_cc.h53
-rw-r--r--gnuradio-core/src/lib/general/gr_diff_phasor_cc.i34
-rw-r--r--gnuradio-core/src/lib/general/gr_dpll_bb.cc84
-rw-r--r--gnuradio-core/src/lib/general/gr_dpll_bb.h58
-rw-r--r--gnuradio-core/src/lib/general/gr_dpll_bb.i31
-rw-r--r--gnuradio-core/src/lib/general/gr_encode_ccsds_27_bb.cc62
-rw-r--r--gnuradio-core/src/lib/general/gr_encode_ccsds_27_bb.h64
-rw-r--r--gnuradio-core/src/lib/general/gr_encode_ccsds_27_bb.i31
-rw-r--r--gnuradio-core/src/lib/general/gr_endian_swap.cc101
-rw-r--r--gnuradio-core/src/lib/general/gr_endian_swap.h57
-rw-r--r--gnuradio-core/src/lib/general/gr_endian_swap.i31
-rw-r--r--gnuradio-core/src/lib/general/gr_expj.h38
-rw-r--r--gnuradio-core/src/lib/general/gr_fake_channel_coder_pp.cc113
-rw-r--r--gnuradio-core/src/lib/general/gr_fake_channel_coder_pp.h91
-rw-r--r--gnuradio-core/src/lib/general/gr_fake_channel_coder_pp.i53
-rw-r--r--gnuradio-core/src/lib/general/gr_fast_atan2f.cc199
-rw-r--r--gnuradio-core/src/lib/general/gr_feedforward_agc_cc.cc91
-rw-r--r--gnuradio-core/src/lib/general/gr_feedforward_agc_cc.h57
-rw-r--r--gnuradio-core/src/lib/general/gr_feedforward_agc_cc.i34
-rw-r--r--gnuradio-core/src/lib/general/gr_feval.cc132
-rw-r--r--gnuradio-core/src/lib/general/gr_feval.h177
-rw-r--r--gnuradio-core/src/lib/general/gr_feval.i233
-rw-r--r--gnuradio-core/src/lib/general/gr_fft_vcc.cc80
-rw-r--r--gnuradio-core/src/lib/general/gr_fft_vcc.h68
-rw-r--r--gnuradio-core/src/lib/general/gr_fft_vcc.i41
-rw-r--r--gnuradio-core/src/lib/general/gr_fft_vcc_fftw.cc130
-rw-r--r--gnuradio-core/src/lib/general/gr_fft_vcc_fftw.h67
-rw-r--r--gnuradio-core/src/lib/general/gr_fft_vfc.cc135
-rw-r--r--gnuradio-core/src/lib/general/gr_fft_vfc.h72
-rw-r--r--gnuradio-core/src/lib/general/gr_fft_vfc.i42
-rw-r--r--gnuradio-core/src/lib/general/gr_firdes.cc840
-rw-r--r--gnuradio-core/src/lib/general/gr_firdes.h373
-rw-r--r--gnuradio-core/src/lib/general/gr_firdes.i360
-rw-r--r--gnuradio-core/src/lib/general/gr_float_to_char.cc79
-rw-r--r--gnuradio-core/src/lib/general/gr_float_to_char.h70
-rw-r--r--gnuradio-core/src/lib/general/gr_float_to_char.i33
-rw-r--r--gnuradio-core/src/lib/general/gr_float_to_complex.cc72
-rw-r--r--gnuradio-core/src/lib/general/gr_float_to_complex.h55
-rw-r--r--gnuradio-core/src/lib/general/gr_float_to_complex.i30
-rw-r--r--gnuradio-core/src/lib/general/gr_float_to_int.cc89
-rw-r--r--gnuradio-core/src/lib/general/gr_float_to_int.h70
-rw-r--r--gnuradio-core/src/lib/general/gr_float_to_int.i33
-rw-r--r--gnuradio-core/src/lib/general/gr_float_to_short.cc79
-rw-r--r--gnuradio-core/src/lib/general/gr_float_to_short.h69
-rw-r--r--gnuradio-core/src/lib/general/gr_float_to_short.i33
-rw-r--r--gnuradio-core/src/lib/general/gr_float_to_uchar.cc58
-rw-r--r--gnuradio-core/src/lib/general/gr_float_to_uchar.h52
-rw-r--r--gnuradio-core/src/lib/general/gr_float_to_uchar.i30
-rw-r--r--gnuradio-core/src/lib/general/gr_fmdet_cf.cc105
-rw-r--r--gnuradio-core/src/lib/general/gr_fmdet_cf.h63
-rw-r--r--gnuradio-core/src/lib/general/gr_fmdet_cf.i31
-rw-r--r--gnuradio-core/src/lib/general/gr_framer_sink_1.cc190
-rw-r--r--gnuradio-core/src/lib/general/gr_framer_sink_1.h107
-rw-r--r--gnuradio-core/src/lib/general/gr_framer_sink_1.i35
-rw-r--r--gnuradio-core/src/lib/general/gr_frequency_modulator_fc.cc71
-rw-r--r--gnuradio-core/src/lib/general/gr_frequency_modulator_fc.h59
-rw-r--r--gnuradio-core/src/lib/general/gr_frequency_modulator_fc.i34
-rw-r--r--gnuradio-core/src/lib/general/gr_fxpt.cc35
-rw-r--r--gnuradio-core/src/lib/general/gr_fxpt.h104
-rw-r--r--gnuradio-core/src/lib/general/gr_fxpt_nco.h153
-rw-r--r--gnuradio-core/src/lib/general/gr_fxpt_vco.h73
-rw-r--r--gnuradio-core/src/lib/general/gr_glfsr_source_b.cc84
-rw-r--r--gnuradio-core/src/lib/general/gr_glfsr_source_b.h66
-rw-r--r--gnuradio-core/src/lib/general/gr_glfsr_source_b.i37
-rw-r--r--gnuradio-core/src/lib/general/gr_glfsr_source_f.cc84
-rw-r--r--gnuradio-core/src/lib/general/gr_glfsr_source_f.h66
-rw-r--r--gnuradio-core/src/lib/general/gr_glfsr_source_f.i37
-rw-r--r--gnuradio-core/src/lib/general/gr_head.cc61
-rw-r--r--gnuradio-core/src/lib/general/gr_head.h61
-rw-r--r--gnuradio-core/src/lib/general/gr_head.i33
-rw-r--r--gnuradio-core/src/lib/general/gr_int_to_float.cc67
-rw-r--r--gnuradio-core/src/lib/general/gr_int_to_float.h70
-rw-r--r--gnuradio-core/src/lib/general/gr_int_to_float.i32
-rw-r--r--gnuradio-core/src/lib/general/gr_interleave.cc77
-rw-r--r--gnuradio-core/src/lib/general/gr_interleave.h57
-rw-r--r--gnuradio-core/src/lib/general/gr_interleave.i30
-rw-r--r--gnuradio-core/src/lib/general/gr_interleaved_short_to_complex.cc59
-rw-r--r--gnuradio-core/src/lib/general/gr_interleaved_short_to_complex.h52
-rw-r--r--gnuradio-core/src/lib/general/gr_interleaved_short_to_complex.i30
-rw-r--r--gnuradio-core/src/lib/general/gr_iqcomp_cc.cc62
-rw-r--r--gnuradio-core/src/lib/general/gr_iqcomp_cc.h55
-rw-r--r--gnuradio-core/src/lib/general/gr_iqcomp_cc.i36
-rw-r--r--gnuradio-core/src/lib/general/gr_keep_m_in_n.cc98
-rw-r--r--gnuradio-core/src/lib/general/gr_keep_m_in_n.h67
-rw-r--r--gnuradio-core/src/lib/general/gr_keep_m_in_n.i35
-rw-r--r--gnuradio-core/src/lib/general/gr_keep_one_in_n.cc105
-rw-r--r--gnuradio-core/src/lib/general/gr_keep_one_in_n.h62
-rw-r--r--gnuradio-core/src/lib/general/gr_keep_one_in_n.i35
-rw-r--r--gnuradio-core/src/lib/general/gr_kludge_copy.cc64
-rw-r--r--gnuradio-core/src/lib/general/gr_kludge_copy.h56
-rw-r--r--gnuradio-core/src/lib/general/gr_kludge_copy.i31
-rw-r--r--gnuradio-core/src/lib/general/gr_lfsr_32k_source_s.cc70
-rw-r--r--gnuradio-core/src/lib/general/gr_lfsr_32k_source_s.h61
-rw-r--r--gnuradio-core/src/lib/general/gr_lfsr_32k_source_s.i31
-rw-r--r--gnuradio-core/src/lib/general/gr_log2_const.h47
-rw-r--r--gnuradio-core/src/lib/general/gr_map_bb.cc61
-rw-r--r--gnuradio-core/src/lib/general/gr_map_bb.h52
-rw-r--r--gnuradio-core/src/lib/general/gr_map_bb.i32
-rw-r--r--gnuradio-core/src/lib/general/gr_math.h209
-rw-r--r--gnuradio-core/src/lib/general/gr_message_strobe.cc75
-rw-r--r--gnuradio-core/src/lib/general/gr_message_strobe.h62
-rw-r--r--gnuradio-core/src/lib/general/gr_message_strobe.i30
-rw-r--r--gnuradio-core/src/lib/general/gr_misc.cc65
-rw-r--r--gnuradio-core/src/lib/general/gr_misc.h39
-rw-r--r--gnuradio-core/src/lib/general/gr_multiply_cc.cc69
-rw-r--r--gnuradio-core/src/lib/general/gr_multiply_cc.h56
-rw-r--r--gnuradio-core/src/lib/general/gr_multiply_cc.i32
-rw-r--r--gnuradio-core/src/lib/general/gr_multiply_conjugate_cc.cc69
-rw-r--r--gnuradio-core/src/lib/general/gr_multiply_conjugate_cc.h57
-rw-r--r--gnuradio-core/src/lib/general/gr_multiply_conjugate_cc.i32
-rw-r--r--gnuradio-core/src/lib/general/gr_multiply_const_cc.cc80
-rw-r--r--gnuradio-core/src/lib/general/gr_multiply_const_cc.h60
-rw-r--r--gnuradio-core/src/lib/general/gr_multiply_const_cc.i33
-rw-r--r--gnuradio-core/src/lib/general/gr_multiply_const_ff.cc80
-rw-r--r--gnuradio-core/src/lib/general/gr_multiply_const_ff.h60
-rw-r--r--gnuradio-core/src/lib/general/gr_multiply_const_ff.i33
-rw-r--r--gnuradio-core/src/lib/general/gr_multiply_ff.cc69
-rw-r--r--gnuradio-core/src/lib/general/gr_multiply_ff.h56
-rw-r--r--gnuradio-core/src/lib/general/gr_multiply_ff.i32
-rw-r--r--gnuradio-core/src/lib/general/gr_nco.h198
-rw-r--r--gnuradio-core/src/lib/general/gr_nlog10_ff.cc64
-rw-r--r--gnuradio-core/src/lib/general/gr_nlog10_ff.h56
-rw-r--r--gnuradio-core/src/lib/general/gr_nlog10_ff.i33
-rw-r--r--gnuradio-core/src/lib/general/gr_nop.cc66
-rw-r--r--gnuradio-core/src/lib/general/gr_nop.h61
-rw-r--r--gnuradio-core/src/lib/general/gr_nop.i31
-rw-r--r--gnuradio-core/src/lib/general/gr_null_sink.cc49
-rw-r--r--gnuradio-core/src/lib/general/gr_null_sink.h53
-rw-r--r--gnuradio-core/src/lib/general/gr_null_sink.i31
-rw-r--r--gnuradio-core/src/lib/general/gr_null_source.cc52
-rw-r--r--gnuradio-core/src/lib/general/gr_null_source.h52
-rw-r--r--gnuradio-core/src/lib/general/gr_null_source.i31
-rw-r--r--gnuradio-core/src/lib/general/gr_ofdm_bpsk_demapper.cc97
-rw-r--r--gnuradio-core/src/lib/general/gr_ofdm_bpsk_demapper.h69
-rw-r--r--gnuradio-core/src/lib/general/gr_ofdm_bpsk_demapper.i40
-rw-r--r--gnuradio-core/src/lib/general/gr_ofdm_frame_sink2.cc374
-rw-r--r--gnuradio-core/src/lib/general/gr_ofdm_frame_sink2.h121
-rw-r--r--gnuradio-core/src/lib/general/gr_ofdm_frame_sink2.i39
-rw-r--r--gnuradio-core/src/lib/general/gr_pa_2x2_phase_combiner.cc74
-rw-r--r--gnuradio-core/src/lib/general/gr_pa_2x2_phase_combiner.h63
-rw-r--r--gnuradio-core/src/lib/general/gr_pa_2x2_phase_combiner.i34
-rw-r--r--gnuradio-core/src/lib/general/gr_pack_k_bits_bb.cc69
-rw-r--r--gnuradio-core/src/lib/general/gr_pack_k_bits_bb.h56
-rw-r--r--gnuradio-core/src/lib/general/gr_pack_k_bits_bb.i34
-rw-r--r--gnuradio-core/src/lib/general/gr_packet_sink.cc207
-rw-r--r--gnuradio-core/src/lib/general/gr_packet_sink.h112
-rw-r--r--gnuradio-core/src/lib/general/gr_packet_sink.i41
-rw-r--r--gnuradio-core/src/lib/general/gr_peak_detector2_fb.cc107
-rw-r--r--gnuradio-core/src/lib/general/gr_peak_detector2_fb.h109
-rw-r--r--gnuradio-core/src/lib/general/gr_peak_detector2_fb.i45
-rw-r--r--gnuradio-core/src/lib/general/gr_phase_modulator_fc.cc62
-rw-r--r--gnuradio-core/src/lib/general/gr_phase_modulator_fc.h56
-rw-r--r--gnuradio-core/src/lib/general/gr_phase_modulator_fc.i31
-rw-r--r--gnuradio-core/src/lib/general/gr_pll_carriertracking_cc.cc120
-rw-r--r--gnuradio-core/src/lib/general/gr_pll_carriertracking_cc.h74
-rw-r--r--gnuradio-core/src/lib/general/gr_pll_carriertracking_cc.i39
-rw-r--r--gnuradio-core/src/lib/general/gr_pll_freqdet_cf.cc90
-rw-r--r--gnuradio-core/src/lib/general/gr_pll_freqdet_cf.h67
-rw-r--r--gnuradio-core/src/lib/general/gr_pll_freqdet_cf.i33
-rw-r--r--gnuradio-core/src/lib/general/gr_pll_refout_cc.cc93
-rw-r--r--gnuradio-core/src/lib/general/gr_pll_refout_cc.h65
-rw-r--r--gnuradio-core/src/lib/general/gr_pll_refout_cc.i32
-rw-r--r--gnuradio-core/src/lib/general/gr_pn_correlator_cc.cc77
-rw-r--r--gnuradio-core/src/lib/general/gr_pn_correlator_cc.h62
-rw-r--r--gnuradio-core/src/lib/general/gr_pn_correlator_cc.i32
-rw-r--r--gnuradio-core/src/lib/general/gr_prefs.cc229
-rw-r--r--gnuradio-core/src/lib/general/gr_prefs.h94
-rw-r--r--gnuradio-core/src/lib/general/gr_prefs.i69
-rw-r--r--gnuradio-core/src/lib/general/gr_probe_avg_mag_sqrd_c.cc84
-rw-r--r--gnuradio-core/src/lib/general/gr_probe_avg_mag_sqrd_c.h75
-rw-r--r--gnuradio-core/src/lib/general/gr_probe_avg_mag_sqrd_c.i36
-rw-r--r--gnuradio-core/src/lib/general/gr_probe_avg_mag_sqrd_cf.cc86
-rw-r--r--gnuradio-core/src/lib/general/gr_probe_avg_mag_sqrd_cf.h77
-rw-r--r--gnuradio-core/src/lib/general/gr_probe_avg_mag_sqrd_cf.i36
-rw-r--r--gnuradio-core/src/lib/general/gr_probe_avg_mag_sqrd_f.cc84
-rw-r--r--gnuradio-core/src/lib/general/gr_probe_avg_mag_sqrd_f.h75
-rw-r--r--gnuradio-core/src/lib/general/gr_probe_avg_mag_sqrd_f.i36
-rw-r--r--gnuradio-core/src/lib/general/gr_probe_density_b.cc68
-rw-r--r--gnuradio-core/src/lib/general/gr_probe_density_b.h73
-rw-r--r--gnuradio-core/src/lib/general/gr_probe_density_b.i36
-rw-r--r--gnuradio-core/src/lib/general/gr_pwr_squelch_cc.cc55
-rw-r--r--gnuradio-core/src/lib/general/gr_pwr_squelch_cc.h63
-rw-r--r--gnuradio-core/src/lib/general/gr_pwr_squelch_cc.i42
-rw-r--r--gnuradio-core/src/lib/general/gr_pwr_squelch_ff.cc55
-rw-r--r--gnuradio-core/src/lib/general/gr_pwr_squelch_ff.h63
-rw-r--r--gnuradio-core/src/lib/general/gr_pwr_squelch_ff.i42
-rw-r--r--gnuradio-core/src/lib/general/gr_quadrature_demod_cf.cc62
-rw-r--r--gnuradio-core/src/lib/general/gr_quadrature_demod_cf.h56
-rw-r--r--gnuradio-core/src/lib/general/gr_quadrature_demod_cf.i34
-rw-r--r--gnuradio-core/src/lib/general/gr_rail_ff.cc62
-rw-r--r--gnuradio-core/src/lib/general/gr_rail_ff.h57
-rw-r--r--gnuradio-core/src/lib/general/gr_rail_ff.i30
-rw-r--r--gnuradio-core/src/lib/general/gr_random.cc183
-rw-r--r--gnuradio-core/src/lib/general/gr_random.h65
-rw-r--r--gnuradio-core/src/lib/general/gr_random_pdu.cc84
-rw-r--r--gnuradio-core/src/lib/general/gr_random_pdu.h64
-rw-r--r--gnuradio-core/src/lib/general/gr_random_pdu.i30
-rw-r--r--gnuradio-core/src/lib/general/gr_regenerate_bb.cc90
-rw-r--r--gnuradio-core/src/lib/general/gr_regenerate_bb.h76
-rw-r--r--gnuradio-core/src/lib/general/gr_regenerate_bb.i38
-rw-r--r--gnuradio-core/src/lib/general/gr_remez.cc1033
-rw-r--r--gnuradio-core/src/lib/general/gr_remez.h65
-rw-r--r--gnuradio-core/src/lib/general/gr_remez.i32
-rw-r--r--gnuradio-core/src/lib/general/gr_repeat.cc69
-rw-r--r--gnuradio-core/src/lib/general/gr_repeat.h57
-rw-r--r--gnuradio-core/src/lib/general/gr_repeat.i11
-rw-r--r--gnuradio-core/src/lib/general/gr_reverse.cc60
-rw-r--r--gnuradio-core/src/lib/general/gr_reverse.h34
-rw-r--r--gnuradio-core/src/lib/general/gr_rms_cf.cc71
-rw-r--r--gnuradio-core/src/lib/general/gr_rms_cf.h61
-rw-r--r--gnuradio-core/src/lib/general/gr_rms_cf.i33
-rw-r--r--gnuradio-core/src/lib/general/gr_rms_ff.cc71
-rw-r--r--gnuradio-core/src/lib/general/gr_rms_ff.h61
-rw-r--r--gnuradio-core/src/lib/general/gr_rms_ff.i33
-rw-r--r--gnuradio-core/src/lib/general/gr_scrambler_bb.cc56
-rw-r--r--gnuradio-core/src/lib/general/gr_scrambler_bb.h60
-rw-r--r--gnuradio-core/src/lib/general/gr_scrambler_bb.i31
-rw-r--r--gnuradio-core/src/lib/general/gr_short_to_char.cc67
-rw-r--r--gnuradio-core/src/lib/general/gr_short_to_char.h58
-rw-r--r--gnuradio-core/src/lib/general/gr_short_to_char.i31
-rw-r--r--gnuradio-core/src/lib/general/gr_short_to_float.cc78
-rw-r--r--gnuradio-core/src/lib/general/gr_short_to_float.h70
-rw-r--r--gnuradio-core/src/lib/general/gr_short_to_float.i33
-rw-r--r--gnuradio-core/src/lib/general/gr_simple_correlator.cc237
-rw-r--r--gnuradio-core/src/lib/general/gr_simple_correlator.h111
-rw-r--r--gnuradio-core/src/lib/general/gr_simple_correlator.i31
-rw-r--r--gnuradio-core/src/lib/general/gr_simple_framer.cc101
-rw-r--r--gnuradio-core/src/lib/general/gr_simple_framer.h59
-rw-r--r--gnuradio-core/src/lib/general/gr_simple_framer.i31
-rw-r--r--gnuradio-core/src/lib/general/gr_simple_framer_sync.h51
-rw-r--r--gnuradio-core/src/lib/general/gr_simple_squelch_cc.cc99
-rw-r--r--gnuradio-core/src/lib/general/gr_simple_squelch_cc.h67
-rw-r--r--gnuradio-core/src/lib/general/gr_simple_squelch_cc.i37
-rw-r--r--gnuradio-core/src/lib/general/gr_skiphead.cc83
-rw-r--r--gnuradio-core/src/lib/general/gr_skiphead.h60
-rw-r--r--gnuradio-core/src/lib/general/gr_skiphead.i30
-rw-r--r--gnuradio-core/src/lib/general/gr_squelch_base_cc.cc93
-rw-r--r--gnuradio-core/src/lib/general/gr_squelch_base_cc.h59
-rw-r--r--gnuradio-core/src/lib/general/gr_squelch_base_cc.i40
-rw-r--r--gnuradio-core/src/lib/general/gr_squelch_base_ff.cc93
-rw-r--r--gnuradio-core/src/lib/general/gr_squelch_base_ff.h59
-rw-r--r--gnuradio-core/src/lib/general/gr_squelch_base_ff.i40
-rw-r--r--gnuradio-core/src/lib/general/gr_stream_mux.cc124
-rw-r--r--gnuradio-core/src/lib/general/gr_stream_mux.h93
-rw-r--r--gnuradio-core/src/lib/general/gr_stream_mux.i42
-rw-r--r--gnuradio-core/src/lib/general/gr_stream_to_streams.cc66
-rw-r--r--gnuradio-core/src/lib/general/gr_stream_to_streams.h56
-rw-r--r--gnuradio-core/src/lib/general/gr_stream_to_streams.i34
-rw-r--r--gnuradio-core/src/lib/general/gr_stream_to_vector.cc58
-rw-r--r--gnuradio-core/src/lib/general/gr_stream_to_vector.h55
-rw-r--r--gnuradio-core/src/lib/general/gr_stream_to_vector.i34
-rw-r--r--gnuradio-core/src/lib/general/gr_streams_to_stream.cc68
-rw-r--r--gnuradio-core/src/lib/general/gr_streams_to_stream.h56
-rw-r--r--gnuradio-core/src/lib/general/gr_streams_to_stream.i34
-rw-r--r--gnuradio-core/src/lib/general/gr_streams_to_vector.cc64
-rw-r--r--gnuradio-core/src/lib/general/gr_streams_to_vector.h54
-rw-r--r--gnuradio-core/src/lib/general/gr_streams_to_vector.i34
-rw-r--r--gnuradio-core/src/lib/general/gr_stretch_ff.cc74
-rw-r--r--gnuradio-core/src/lib/general/gr_stretch_ff.h60
-rw-r--r--gnuradio-core/src/lib/general/gr_stretch_ff.i31
-rw-r--r--gnuradio-core/src/lib/general/gr_tag_debug.cc104
-rw-r--r--gnuradio-core/src/lib/general/gr_tag_debug.h85
-rw-r--r--gnuradio-core/src/lib/general/gr_tag_debug.i35
-rw-r--r--gnuradio-core/src/lib/general/gr_test.cc177
-rw-r--r--gnuradio-core/src/lib/general/gr_test.h195
-rw-r--r--gnuradio-core/src/lib/general/gr_test.i64
-rw-r--r--gnuradio-core/src/lib/general/gr_test_types.h46
-rw-r--r--gnuradio-core/src/lib/general/gr_threshold_ff.cc67
-rw-r--r--gnuradio-core/src/lib/general/gr_threshold_ff.h59
-rw-r--r--gnuradio-core/src/lib/general/gr_threshold_ff.i39
-rw-r--r--gnuradio-core/src/lib/general/gr_throttle.cc89
-rw-r--r--gnuradio-core/src/lib/general/gr_throttle.h50
-rw-r--r--gnuradio-core/src/lib/general/gr_throttle.i29
-rw-r--r--gnuradio-core/src/lib/general/gr_transcendental.cc153
-rw-r--r--gnuradio-core/src/lib/general/gr_transcendental.h49
-rw-r--r--gnuradio-core/src/lib/general/gr_transcendental.i33
-rw-r--r--gnuradio-core/src/lib/general/gr_uchar_to_float.cc55
-rw-r--r--gnuradio-core/src/lib/general/gr_uchar_to_float.h52
-rw-r--r--gnuradio-core/src/lib/general/gr_uchar_to_float.i30
-rw-r--r--gnuradio-core/src/lib/general/gr_unpack_k_bits_bb.cc70
-rw-r--r--gnuradio-core/src/lib/general/gr_unpack_k_bits_bb.h56
-rw-r--r--gnuradio-core/src/lib/general/gr_unpack_k_bits_bb.i34
-rw-r--r--gnuradio-core/src/lib/general/gr_vco.h94
-rw-r--r--gnuradio-core/src/lib/general/gr_vco_f.cc58
-rw-r--r--gnuradio-core/src/lib/general/gr_vco_f.h75
-rw-r--r--gnuradio-core/src/lib/general/gr_vco_f.i38
-rw-r--r--gnuradio-core/src/lib/general/gr_vector_map.cc117
-rw-r--r--gnuradio-core/src/lib/general/gr_vector_map.h83
-rw-r--r--gnuradio-core/src/lib/general/gr_vector_map.i28
-rw-r--r--gnuradio-core/src/lib/general/gr_vector_to_stream.cc58
-rw-r--r--gnuradio-core/src/lib/general/gr_vector_to_stream.h54
-rw-r--r--gnuradio-core/src/lib/general/gr_vector_to_stream.i34
-rw-r--r--gnuradio-core/src/lib/general/gr_vector_to_streams.cc64
-rw-r--r--gnuradio-core/src/lib/general/gr_vector_to_streams.h54
-rw-r--r--gnuradio-core/src/lib/general/gr_vector_to_streams.i34
-rw-r--r--gnuradio-core/src/lib/general/gri_add_const_ss.h36
-rw-r--r--gnuradio-core/src/lib/general/gri_add_const_ss_generic.cc49
-rw-r--r--gnuradio-core/src/lib/general/gri_agc2_cc.h91
-rw-r--r--gnuradio-core/src/lib/general/gri_agc2_cc.i47
-rw-r--r--gnuradio-core/src/lib/general/gri_agc2_ff.h90
-rw-r--r--gnuradio-core/src/lib/general/gri_agc2_ff.i47
-rw-r--r--gnuradio-core/src/lib/general/gri_agc_cc.h75
-rw-r--r--gnuradio-core/src/lib/general/gri_agc_cc.i41
-rw-r--r--gnuradio-core/src/lib/general/gri_agc_ff.h72
-rw-r--r--gnuradio-core/src/lib/general/gri_agc_ff.i36
-rw-r--r--gnuradio-core/src/lib/general/gri_char_to_float.cc40
-rw-r--r--gnuradio-core/src/lib/general/gri_char_to_float.h34
-rw-r--r--gnuradio-core/src/lib/general/gri_control_loop.cc210
-rw-r--r--gnuradio-core/src/lib/general/gri_control_loop.h230
-rw-r--r--gnuradio-core/src/lib/general/gri_control_loop.i57
-rw-r--r--gnuradio-core/src/lib/general/gri_debugger_hook.cc29
-rw-r--r--gnuradio-core/src/lib/general/gri_debugger_hook.h30
-rw-r--r--gnuradio-core/src/lib/general/gri_fft.cc330
-rw-r--r--gnuradio-core/src/lib/general/gri_fft.h185
-rw-r--r--gnuradio-core/src/lib/general/gri_float_to_char.cc46
-rw-r--r--gnuradio-core/src/lib/general/gri_float_to_char.h33
-rw-r--r--gnuradio-core/src/lib/general/gri_float_to_int.cc47
-rw-r--r--gnuradio-core/src/lib/general/gri_float_to_int.h33
-rw-r--r--gnuradio-core/src/lib/general/gri_float_to_short.cc46
-rw-r--r--gnuradio-core/src/lib/general/gri_float_to_short.h33
-rw-r--r--gnuradio-core/src/lib/general/gri_float_to_uchar.cc46
-rw-r--r--gnuradio-core/src/lib/general/gri_float_to_uchar.h33
-rw-r--r--gnuradio-core/src/lib/general/gri_glfsr.cc67
-rw-r--r--gnuradio-core/src/lib/general/gri_glfsr.h57
-rw-r--r--gnuradio-core/src/lib/general/gri_int_to_float.cc37
-rw-r--r--gnuradio-core/src/lib/general/gri_int_to_float.h34
-rw-r--r--gnuradio-core/src/lib/general/gri_interleaved_short_to_complex.cc39
-rw-r--r--gnuradio-core/src/lib/general/gri_interleaved_short_to_complex.h38
-rw-r--r--gnuradio-core/src/lib/general/gri_lfsr.h152
-rw-r--r--gnuradio-core/src/lib/general/gri_lfsr_15_1_0.h60
-rw-r--r--gnuradio-core/src/lib/general/gri_lfsr_32k.h80
-rw-r--r--gnuradio-core/src/lib/general/gri_short_to_float.cc40
-rw-r--r--gnuradio-core/src/lib/general/gri_short_to_float.h34
-rw-r--r--gnuradio-core/src/lib/general/gri_uchar_to_float.cc40
-rw-r--r--gnuradio-core/src/lib/general/gri_uchar_to_float.h34
-rw-r--r--gnuradio-core/src/lib/general/malloc16.c46
-rw-r--r--gnuradio-core/src/lib/general/malloc16.h37
-rw-r--r--gnuradio-core/src/lib/general/qa_general.cc53
-rw-r--r--gnuradio-core/src/lib/general/qa_general.h38
-rw-r--r--gnuradio-core/src/lib/general/qa_gr_circular_file.cc72
-rw-r--r--gnuradio-core/src/lib/general/qa_gr_circular_file.h40
-rw-r--r--gnuradio-core/src/lib/general/qa_gr_cpm.cc140
-rw-r--r--gnuradio-core/src/lib/general/qa_gr_cpm.h49
-rw-r--r--gnuradio-core/src/lib/general/qa_gr_firdes.cc618
-rw-r--r--gnuradio-core/src/lib/general/qa_gr_firdes.h52
-rw-r--r--gnuradio-core/src/lib/general/qa_gr_fxpt.cc103
-rw-r--r--gnuradio-core/src/lib/general/qa_gr_fxpt.h48
-rw-r--r--gnuradio-core/src/lib/general/qa_gr_fxpt_nco.cc119
-rw-r--r--gnuradio-core/src/lib/general/qa_gr_fxpt_nco.h48
-rw-r--r--gnuradio-core/src/lib/general/qa_gr_fxpt_vco.cc110
-rw-r--r--gnuradio-core/src/lib/general/qa_gr_fxpt_vco.h48
-rw-r--r--gnuradio-core/src/lib/general/qa_gr_math.cc105
-rw-r--r--gnuradio-core/src/lib/general/qa_gr_math.h42
-rw-r--r--gnuradio-core/src/lib/general/qa_gri_lfsr.cc142
-rw-r--r--gnuradio-core/src/lib/general/qa_gri_lfsr.h42
-rw-r--r--gnuradio-core/src/lib/general/random.h38
-rw-r--r--gnuradio-core/src/lib/general/sine_table.h1025
-rw-r--r--gnuradio-core/src/lib/gengen/CMakeLists.txt175
-rwxr-xr-xgnuradio-core/src/lib/gengen/generate_all.py33
-rwxr-xr-xgnuradio-core/src/lib/gengen/generate_common.py106
-rw-r--r--gnuradio-core/src/lib/gengen/gengen.i33
-rw-r--r--gnuradio-core/src/lib/gengen/gr_add_XX.cc.t63
-rw-r--r--gnuradio-core/src/lib/gengen/gr_add_XX.h.t57
-rw-r--r--gnuradio-core/src/lib/gengen/gr_add_XX.i.t33
-rw-r--r--gnuradio-core/src/lib/gengen/gr_add_const_XX.cc.t72
-rw-r--r--gnuradio-core/src/lib/gengen/gr_add_const_XX.h.t56
-rw-r--r--gnuradio-core/src/lib/gengen/gr_add_const_XX.i.t37
-rwxr-xr-xgnuradio-core/src/lib/gengen/gr_add_const_vXX.cc.t61
-rw-r--r--gnuradio-core/src/lib/gengen/gr_add_const_vXX.h.t56
-rwxr-xr-xgnuradio-core/src/lib/gengen/gr_add_const_vXX.i.t37
-rw-r--r--gnuradio-core/src/lib/gengen/gr_and_XX.cc.t62
-rw-r--r--gnuradio-core/src/lib/gengen/gr_and_XX.h.t55
-rw-r--r--gnuradio-core/src/lib/gengen/gr_and_XX.i.t33
-rw-r--r--gnuradio-core/src/lib/gengen/gr_and_const_XX.cc.t72
-rw-r--r--gnuradio-core/src/lib/gengen/gr_and_const_XX.h.t58
-rw-r--r--gnuradio-core/src/lib/gengen/gr_and_const_XX.i.t37
-rw-r--r--gnuradio-core/src/lib/gengen/gr_argmax_XX.cc.t79
-rw-r--r--gnuradio-core/src/lib/gengen/gr_argmax_XX.h.t52
-rw-r--r--gnuradio-core/src/lib/gengen/gr_argmax_XX.i.t34
-rw-r--r--gnuradio-core/src/lib/gengen/gr_chunks_to_symbols_XX.cc.t74
-rw-r--r--gnuradio-core/src/lib/gengen/gr_chunks_to_symbols_XX.h.t73
-rw-r--r--gnuradio-core/src/lib/gengen/gr_chunks_to_symbols_XX.i.t37
-rw-r--r--gnuradio-core/src/lib/gengen/gr_divide_XX.cc.t72
-rw-r--r--gnuradio-core/src/lib/gengen/gr_divide_XX.h.t57
-rw-r--r--gnuradio-core/src/lib/gengen/gr_divide_XX.i.t33
-rw-r--r--gnuradio-core/src/lib/gengen/gr_endianness.h27
-rw-r--r--gnuradio-core/src/lib/gengen/gr_endianness.i23
-rw-r--r--gnuradio-core/src/lib/gengen/gr_fastnoise_source_X.cc.t116
-rw-r--r--gnuradio-core/src/lib/gengen/gr_fastnoise_source_X.h.t87
-rw-r--r--gnuradio-core/src/lib/gengen/gr_fastnoise_source_X.i.t40
-rw-r--r--gnuradio-core/src/lib/gengen/gr_integrate_XX.cc.t67
-rw-r--r--gnuradio-core/src/lib/gengen/gr_integrate_XX.h.t61
-rw-r--r--gnuradio-core/src/lib/gengen/gr_integrate_XX.i.t33
-rw-r--r--gnuradio-core/src/lib/gengen/gr_max_XX.cc.t71
-rw-r--r--gnuradio-core/src/lib/gengen/gr_max_XX.h.t52
-rw-r--r--gnuradio-core/src/lib/gengen/gr_max_XX.i.t34
-rw-r--r--gnuradio-core/src/lib/gengen/gr_moving_average_XX.cc.t93
-rw-r--r--gnuradio-core/src/lib/gengen/gr_moving_average_XX.h.t72
-rw-r--r--gnuradio-core/src/lib/gengen/gr_moving_average_XX.i.t38
-rw-r--r--gnuradio-core/src/lib/gengen/gr_multiply_XX.cc.t63
-rw-r--r--gnuradio-core/src/lib/gengen/gr_multiply_XX.h.t57
-rw-r--r--gnuradio-core/src/lib/gengen/gr_multiply_XX.i.t33
-rw-r--r--gnuradio-core/src/lib/gengen/gr_multiply_const_XX.cc.t72
-rw-r--r--gnuradio-core/src/lib/gengen/gr_multiply_const_XX.h.t56
-rw-r--r--gnuradio-core/src/lib/gengen/gr_multiply_const_XX.i.t37
-rwxr-xr-xgnuradio-core/src/lib/gengen/gr_multiply_const_vXX.cc.t61
-rw-r--r--gnuradio-core/src/lib/gengen/gr_multiply_const_vXX.h.t56
-rwxr-xr-xgnuradio-core/src/lib/gengen/gr_multiply_const_vXX.i.t37
-rw-r--r--gnuradio-core/src/lib/gengen/gr_mute_XX.cc.t79
-rw-r--r--gnuradio-core/src/lib/gengen/gr_mute_XX.h.t56
-rw-r--r--gnuradio-core/src/lib/gengen/gr_mute_XX.i.t37
-rw-r--r--gnuradio-core/src/lib/gengen/gr_noise_source_X.cc.t99
-rw-r--r--gnuradio-core/src/lib/gengen/gr_noise_source_X.h.t83
-rw-r--r--gnuradio-core/src/lib/gengen/gr_noise_source_X.i.t40
-rw-r--r--gnuradio-core/src/lib/gengen/gr_noise_type.h30
-rw-r--r--gnuradio-core/src/lib/gengen/gr_not_XX.cc.t58
-rw-r--r--gnuradio-core/src/lib/gengen/gr_not_XX.h.t55
-rw-r--r--gnuradio-core/src/lib/gengen/gr_not_XX.i.t33
-rw-r--r--gnuradio-core/src/lib/gengen/gr_or_XX.cc.t62
-rw-r--r--gnuradio-core/src/lib/gengen/gr_or_XX.h.t55
-rw-r--r--gnuradio-core/src/lib/gengen/gr_or_XX.i.t33
-rw-r--r--gnuradio-core/src/lib/gengen/gr_packed_to_unpacked_XX.cc.t137
-rw-r--r--gnuradio-core/src/lib/gengen/gr_packed_to_unpacked_XX.h.t85
-rw-r--r--gnuradio-core/src/lib/gengen/gr_packed_to_unpacked_XX.i.t33
-rw-r--r--gnuradio-core/src/lib/gengen/gr_peak_detector_XX.cc.t111
-rw-r--r--gnuradio-core/src/lib/gengen/gr_peak_detector_XX.h.t126
-rw-r--r--gnuradio-core/src/lib/gengen/gr_peak_detector_XX.i.t49
-rw-r--r--gnuradio-core/src/lib/gengen/gr_probe_signal_X.cc.t59
-rw-r--r--gnuradio-core/src/lib/gengen/gr_probe_signal_X.h.t58
-rw-r--r--gnuradio-core/src/lib/gengen/gr_probe_signal_X.i.t32
-rw-r--r--gnuradio-core/src/lib/gengen/gr_probe_signal_vX.cc.t59
-rw-r--r--gnuradio-core/src/lib/gengen/gr_probe_signal_vX.h.t62
-rw-r--r--gnuradio-core/src/lib/gengen/gr_probe_signal_vX.i.t32
-rw-r--r--gnuradio-core/src/lib/gengen/gr_sample_and_hold_XX.cc.t62
-rw-r--r--gnuradio-core/src/lib/gengen/gr_sample_and_hold_XX.h.t58
-rw-r--r--gnuradio-core/src/lib/gengen/gr_sample_and_hold_XX.i.t33
-rw-r--r--gnuradio-core/src/lib/gengen/gr_sig_source_X.cc.t241
-rw-r--r--gnuradio-core/src/lib/gengen/gr_sig_source_X.h.t82
-rw-r--r--gnuradio-core/src/lib/gengen/gr_sig_source_X.i.t52
-rw-r--r--gnuradio-core/src/lib/gengen/gr_sig_source_waveform.h29
-rw-r--r--gnuradio-core/src/lib/gengen/gr_sub_XX.cc.t71
-rw-r--r--gnuradio-core/src/lib/gengen/gr_sub_XX.h.t57
-rw-r--r--gnuradio-core/src/lib/gengen/gr_sub_XX.i.t33
-rw-r--r--gnuradio-core/src/lib/gengen/gr_unpacked_to_packed_XX.cc.t129
-rw-r--r--gnuradio-core/src/lib/gengen/gr_unpacked_to_packed_XX.h.t82
-rw-r--r--gnuradio-core/src/lib/gengen/gr_unpacked_to_packed_XX.i.t33
-rw-r--r--gnuradio-core/src/lib/gengen/gr_vector_insert_X.cc.t100
-rw-r--r--gnuradio-core/src/lib/gengen/gr_vector_insert_X.h.t61
-rw-r--r--gnuradio-core/src/lib/gengen/gr_vector_insert_X.i.t37
-rw-r--r--gnuradio-core/src/lib/gengen/gr_vector_sink_X.cc.t64
-rw-r--r--gnuradio-core/src/lib/gengen/gr_vector_sink_X.h.t59
-rw-r--r--gnuradio-core/src/lib/gengen/gr_vector_sink_X.i.t39
-rw-r--r--gnuradio-core/src/lib/gengen/gr_vector_source_X.cc.t89
-rw-r--r--gnuradio-core/src/lib/gengen/gr_vector_source_X.h.t61
-rw-r--r--gnuradio-core/src/lib/gengen/gr_vector_source_X.i.t37
-rw-r--r--gnuradio-core/src/lib/gengen/gr_xor_XX.cc.t62
-rw-r--r--gnuradio-core/src/lib/gengen/gr_xor_XX.h.t55
-rw-r--r--gnuradio-core/src/lib/gengen/gr_xor_XX.i.t33
-rw-r--r--gnuradio-core/src/lib/gnuradio-config-info.cc72
-rw-r--r--gnuradio-core/src/lib/hier/CMakeLists.txt42
-rw-r--r--gnuradio-core/src/lib/hier/gr_channel_model.cc126
-rw-r--r--gnuradio-core/src/lib/hier/gr_channel_model.h79
-rw-r--r--gnuradio-core/src/lib/hier/gr_channel_model.i50
-rw-r--r--gnuradio-core/src/lib/hier/hier.i32
-rw-r--r--gnuradio-core/src/lib/io/CMakeLists.txt118
-rw-r--r--gnuradio-core/src/lib/io/gr_file_descriptor_sink.cc87
-rw-r--r--gnuradio-core/src/lib/io/gr_file_descriptor_sink.h59
-rw-r--r--gnuradio-core/src/lib/io/gr_file_descriptor_sink.i35
-rw-r--r--gnuradio-core/src/lib/io/gr_file_descriptor_source.cc151
-rw-r--r--gnuradio-core/src/lib/io/gr_file_descriptor_source.h68
-rw-r--r--gnuradio-core/src/lib/io/gr_file_descriptor_source.i35
-rw-r--r--gnuradio-core/src/lib/io/gr_file_sink.cc84
-rw-r--r--gnuradio-core/src/lib/io/gr_file_sink.h58
-rw-r--r--gnuradio-core/src/lib/io/gr_file_sink.i45
-rw-r--r--gnuradio-core/src/lib/io/gr_file_sink_base.cc125
-rw-r--r--gnuradio-core/src/lib/io/gr_file_sink_base.h75
-rw-r--r--gnuradio-core/src/lib/io/gr_file_sink_base.i51
-rw-r--r--gnuradio-core/src/lib/io/gr_file_source.cc192
-rw-r--r--gnuradio-core/src/lib/io/gr_file_source.h107
-rw-r--r--gnuradio-core/src/lib/io/gr_file_source.i45
-rw-r--r--gnuradio-core/src/lib/io/gr_histo_sink.i39
-rw-r--r--gnuradio-core/src/lib/io/gr_histo_sink_f.cc165
-rw-r--r--gnuradio-core/src/lib/io/gr_histo_sink_f.h71
-rw-r--r--gnuradio-core/src/lib/io/gr_message_burst_source.cc144
-rw-r--r--gnuradio-core/src/lib/io/gr_message_burst_source.h71
-rw-r--r--gnuradio-core/src/lib/io/gr_message_burst_source.i38
-rw-r--r--gnuradio-core/src/lib/io/gr_message_debug.cc120
-rw-r--r--gnuradio-core/src/lib/io/gr_message_debug.h114
-rw-r--r--gnuradio-core/src/lib/io/gr_message_debug.i30
-rw-r--r--gnuradio-core/src/lib/io/gr_message_sink.cc79
-rw-r--r--gnuradio-core/src/lib/io/gr_message_sink.h63
-rw-r--r--gnuradio-core/src/lib/io/gr_message_sink.i36
-rw-r--r--gnuradio-core/src/lib/io/gr_message_source.cc120
-rw-r--r--gnuradio-core/src/lib/io/gr_message_source.h69
-rw-r--r--gnuradio-core/src/lib/io/gr_message_source.i38
-rw-r--r--gnuradio-core/src/lib/io/gr_oscope_guts.cc437
-rw-r--r--gnuradio-core/src/lib/io/gr_oscope_guts.h123
-rw-r--r--gnuradio-core/src/lib/io/gr_oscope_sink.i77
-rw-r--r--gnuradio-core/src/lib/io/gr_oscope_sink_f.cc78
-rw-r--r--gnuradio-core/src/lib/io/gr_oscope_sink_f.h63
-rw-r--r--gnuradio-core/src/lib/io/gr_oscope_sink_x.cc156
-rw-r--r--gnuradio-core/src/lib/io/gr_oscope_sink_x.h77
-rw-r--r--gnuradio-core/src/lib/io/gr_pdu.cc79
-rw-r--r--gnuradio-core/src/lib/io/gr_pdu.h39
-rw-r--r--gnuradio-core/src/lib/io/gr_pdu.i30
-rw-r--r--gnuradio-core/src/lib/io/gr_pdu_to_tagged_stream.cc132
-rw-r--r--gnuradio-core/src/lib/io/gr_pdu_to_tagged_stream.h63
-rw-r--r--gnuradio-core/src/lib/io/gr_pdu_to_tagged_stream.i31
-rw-r--r--gnuradio-core/src/lib/io/gr_socket_pdu.cc157
-rw-r--r--gnuradio-core/src/lib/io/gr_socket_pdu.h203
-rw-r--r--gnuradio-core/src/lib/io/gr_socket_pdu.i33
-rw-r--r--gnuradio-core/src/lib/io/gr_stream_pdu_base.cc123
-rw-r--r--gnuradio-core/src/lib/io/gr_stream_pdu_base.h59
-rw-r--r--gnuradio-core/src/lib/io/gr_tagged_file_sink.cc216
-rw-r--r--gnuradio-core/src/lib/io/gr_tagged_file_sink.h72
-rw-r--r--gnuradio-core/src/lib/io/gr_tagged_file_sink.i35
-rw-r--r--gnuradio-core/src/lib/io/gr_tagged_stream_to_pdu.cc137
-rw-r--r--gnuradio-core/src/lib/io/gr_tagged_stream_to_pdu.h76
-rw-r--r--gnuradio-core/src/lib/io/gr_tagged_stream_to_pdu.i31
-rw-r--r--gnuradio-core/src/lib/io/gr_trigger_mode.h38
-rw-r--r--gnuradio-core/src/lib/io/gr_tuntap_pdu.cc145
-rw-r--r--gnuradio-core/src/lib/io/gr_tuntap_pdu.h74
-rw-r--r--gnuradio-core/src/lib/io/gr_tuntap_pdu.i30
-rw-r--r--gnuradio-core/src/lib/io/gr_udp_sink.cc304
-rw-r--r--gnuradio-core/src/lib/io/gr_udp_sink.h112
-rw-r--r--gnuradio-core/src/lib/io/gr_udp_sink.i46
-rw-r--r--gnuradio-core/src/lib/io/gr_udp_source.cc374
-rw-r--r--gnuradio-core/src/lib/io/gr_udp_source.h110
-rw-r--r--gnuradio-core/src/lib/io/gr_udp_source.i41
-rw-r--r--gnuradio-core/src/lib/io/gr_wavfile_sink.cc280
-rw-r--r--gnuradio-core/src/lib/io/gr_wavfile_sink.h138
-rw-r--r--gnuradio-core/src/lib/io/gr_wavfile_sink.i47
-rw-r--r--gnuradio-core/src/lib/io/gr_wavfile_source.cc171
-rw-r--r--gnuradio-core/src/lib/io/gr_wavfile_source.h95
-rw-r--r--gnuradio-core/src/lib/io/gr_wavfile_source.i42
-rw-r--r--gnuradio-core/src/lib/io/gri_wavfile.cc251
-rw-r--r--gnuradio-core/src/lib/io/gri_wavfile.h96
-rw-r--r--gnuradio-core/src/lib/io/i2c.cc28
-rw-r--r--gnuradio-core/src/lib/io/i2c.h49
-rw-r--r--gnuradio-core/src/lib/io/i2c_bbio.cc29
-rw-r--r--gnuradio-core/src/lib/io/i2c_bbio.h51
-rw-r--r--gnuradio-core/src/lib/io/i2c_bbio_pp.cc87
-rw-r--r--gnuradio-core/src/lib/io/i2c_bbio_pp.h57
-rw-r--r--gnuradio-core/src/lib/io/i2c_bitbang.cc144
-rw-r--r--gnuradio-core/src/lib/io/i2c_bitbang.h65
-rw-r--r--gnuradio-core/src/lib/io/io.i83
-rw-r--r--gnuradio-core/src/lib/io/microtune_4702.cc183
-rw-r--r--gnuradio-core/src/lib/io/microtune_4702.h71
-rw-r--r--gnuradio-core/src/lib/io/microtune_4702_eval_board.cc88
-rw-r--r--gnuradio-core/src/lib/io/microtune_4702_eval_board.h49
-rw-r--r--gnuradio-core/src/lib/io/microtune_4702_eval_board.i36
-rw-r--r--gnuradio-core/src/lib/io/microtune_4937.cc146
-rw-r--r--gnuradio-core/src/lib/io/microtune_4937.h68
-rw-r--r--gnuradio-core/src/lib/io/microtune_4937_eval_board.cc97
-rw-r--r--gnuradio-core/src/lib/io/microtune_4937_eval_board.h50
-rw-r--r--gnuradio-core/src/lib/io/microtune_4937_eval_board.i36
-rw-r--r--gnuradio-core/src/lib/io/microtune_eval_board.i95
-rw-r--r--gnuradio-core/src/lib/io/microtune_eval_board_defs.h71
-rw-r--r--gnuradio-core/src/lib/io/microtune_xxxx.cc41
-rw-r--r--gnuradio-core/src/lib/io/microtune_xxxx.h66
-rw-r--r--gnuradio-core/src/lib/io/microtune_xxxx_eval_board.cc144
-rw-r--r--gnuradio-core/src/lib/io/microtune_xxxx_eval_board.h98
-rw-r--r--gnuradio-core/src/lib/io/microtune_xxxx_eval_board.i58
-rw-r--r--gnuradio-core/src/lib/io/ppio.cc39
-rw-r--r--gnuradio-core/src/lib/io/ppio.h63
-rw-r--r--gnuradio-core/src/lib/io/ppio.i48
-rw-r--r--gnuradio-core/src/lib/io/ppio_ppdev.cc321
-rw-r--r--gnuradio-core/src/lib/io/ppio_ppdev.h62
-rw-r--r--gnuradio-core/src/lib/io/sdr_1000.cc65
-rw-r--r--gnuradio-core/src/lib/io/sdr_1000.h53
-rw-r--r--gnuradio-core/src/lib/io/sdr_1000.i36
-rw-r--r--gnuradio-core/src/lib/missing/CMakeLists.txt32
-rw-r--r--gnuradio-core/src/lib/missing/bug_work_around_8.cc3
-rw-r--r--gnuradio-core/src/lib/missing/getopt.c733
-rw-r--r--gnuradio-core/src/lib/missing/getopt.h129
-rw-r--r--gnuradio-core/src/lib/missing/gettimeofday.c50
-rw-r--r--gnuradio-core/src/lib/missing/posix_memalign.cc114
-rw-r--r--gnuradio-core/src/lib/missing/posix_memalign.h42
-rw-r--r--gnuradio-core/src/lib/missing/usleep.c67
-rw-r--r--gnuradio-core/src/lib/reed-solomon/CMakeLists.txt62
-rw-r--r--gnuradio-core/src/lib/reed-solomon/Makefile.in.karn99
-rw-r--r--gnuradio-core/src/lib/reed-solomon/README5
-rw-r--r--gnuradio-core/src/lib/reed-solomon/README.karn22
-rw-r--r--gnuradio-core/src/lib/reed-solomon/ccsds.h1
-rw-r--r--gnuradio-core/src/lib/reed-solomon/char.h57
-rw-r--r--gnuradio-core/src/lib/reed-solomon/decode_rs.c270
-rw-r--r--gnuradio-core/src/lib/reed-solomon/decode_rs_ccsds.c27
-rw-r--r--gnuradio-core/src/lib/reed-solomon/encode_rs.c47
-rw-r--r--gnuradio-core/src/lib/reed-solomon/encode_rs_ccsds.c24
-rw-r--r--gnuradio-core/src/lib/reed-solomon/exercise.c134
-rw-r--r--gnuradio-core/src/lib/reed-solomon/fixed.h40
-rw-r--r--gnuradio-core/src/lib/reed-solomon/gen_ccsds.c34
-rw-r--r--gnuradio-core/src/lib/reed-solomon/gen_ccsds_tal.c50
-rw-r--r--gnuradio-core/src/lib/reed-solomon/init_rs.c129
-rw-r--r--gnuradio-core/src/lib/reed-solomon/int.h55
-rw-r--r--gnuradio-core/src/lib/reed-solomon/rs.3170
-rw-r--r--gnuradio-core/src/lib/reed-solomon/rs.h31
-rw-r--r--gnuradio-core/src/lib/reed-solomon/rstest.c117
-rw-r--r--gnuradio-core/src/lib/runtime/CMakeLists.txt187
-rw-r--r--gnuradio-core/src/lib/runtime/gr_basic_block.cc227
-rw-r--r--gnuradio-core/src/lib/runtime/gr_basic_block.h299
-rw-r--r--gnuradio-core/src/lib/runtime/gr_basic_block.i62
-rw-r--r--gnuradio-core/src/lib/runtime/gr_block.cc459
-rw-r--r--gnuradio-core/src/lib/runtime/gr_block.h437
-rw-r--r--gnuradio-core/src/lib/runtime/gr_block.i93
-rw-r--r--gnuradio-core/src/lib/runtime/gr_block_detail.cc414
-rw-r--r--gnuradio-core/src/lib/runtime/gr_block_detail.h235
-rw-r--r--gnuradio-core/src/lib/runtime/gr_block_detail.i66
-rw-r--r--gnuradio-core/src/lib/runtime/gr_block_executor.cc487
-rw-r--r--gnuradio-core/src/lib/runtime/gr_block_executor.h78
-rw-r--r--gnuradio-core/src/lib/runtime/gr_block_registry.cc76
-rw-r--r--gnuradio-core/src/lib/runtime/gr_block_registry.h43
-rw-r--r--gnuradio-core/src/lib/runtime/gr_buffer.cc347
-rw-r--r--gnuradio-core/src/lib/runtime/gr_buffer.h309
-rw-r--r--gnuradio-core/src/lib/runtime/gr_buffer.i63
-rw-r--r--gnuradio-core/src/lib/runtime/gr_complex.h46
-rw-r--r--gnuradio-core/src/lib/runtime/gr_dispatcher.cc193
-rw-r--r--gnuradio-core/src/lib/runtime/gr_dispatcher.h69
-rw-r--r--gnuradio-core/src/lib/runtime/gr_dispatcher.i55
-rw-r--r--gnuradio-core/src/lib/runtime/gr_error_handler.cc244
-rw-r--r--gnuradio-core/src/lib/runtime/gr_error_handler.h117
-rw-r--r--gnuradio-core/src/lib/runtime/gr_error_handler.i69
-rw-r--r--gnuradio-core/src/lib/runtime/gr_flat_flowgraph.cc403
-rw-r--r--gnuradio-core/src/lib/runtime/gr_flat_flowgraph.h80
-rw-r--r--gnuradio-core/src/lib/runtime/gr_flowgraph.cc515
-rw-r--r--gnuradio-core/src/lib/runtime/gr_flowgraph.h251
-rw-r--r--gnuradio-core/src/lib/runtime/gr_hier_block2.cc77
-rw-r--r--gnuradio-core/src/lib/runtime/gr_hier_block2.h71
-rw-r--r--gnuradio-core/src/lib/runtime/gr_hier_block2.i88
-rw-r--r--gnuradio-core/src/lib/runtime/gr_hier_block2_detail.cc615
-rw-r--r--gnuradio-core/src/lib/runtime/gr_hier_block2_detail.h74
-rw-r--r--gnuradio-core/src/lib/runtime/gr_io_signature.cc112
-rw-r--r--gnuradio-core/src/lib/runtime/gr_io_signature.h117
-rw-r--r--gnuradio-core/src/lib/runtime/gr_io_signature.i73
-rw-r--r--gnuradio-core/src/lib/runtime/gr_local_sighandler.cc187
-rw-r--r--gnuradio-core/src/lib/runtime/gr_local_sighandler.h65
-rw-r--r--gnuradio-core/src/lib/runtime/gr_message.cc78
-rw-r--r--gnuradio-core/src/lib/runtime/gr_message.h91
-rw-r--r--gnuradio-core/src/lib/runtime/gr_message.i65
-rw-r--r--gnuradio-core/src/lib/runtime/gr_msg_accepter.cc59
-rw-r--r--gnuradio-core/src/lib/runtime/gr_msg_accepter.h43
-rw-r--r--gnuradio-core/src/lib/runtime/gr_msg_handler.cc30
-rw-r--r--gnuradio-core/src/lib/runtime/gr_msg_handler.h43
-rw-r--r--gnuradio-core/src/lib/runtime/gr_msg_handler.i32
-rw-r--r--gnuradio-core/src/lib/runtime/gr_msg_queue.cc125
-rw-r--r--gnuradio-core/src/lib/runtime/gr_msg_queue.h92
-rw-r--r--gnuradio-core/src/lib/runtime/gr_msg_queue.i107
-rw-r--r--gnuradio-core/src/lib/runtime/gr_pagesize.cc56
-rw-r--r--gnuradio-core/src/lib/runtime/gr_pagesize.h34
-rw-r--r--gnuradio-core/src/lib/runtime/gr_preferences.cc108
-rw-r--r--gnuradio-core/src/lib/runtime/gr_preferences.h34
-rw-r--r--gnuradio-core/src/lib/runtime/gr_realtime.cc32
-rw-r--r--gnuradio-core/src/lib/runtime/gr_realtime.h37
-rw-r--r--gnuradio-core/src/lib/runtime/gr_realtime.i44
-rw-r--r--gnuradio-core/src/lib/runtime/gr_runtime_types.h56
-rw-r--r--gnuradio-core/src/lib/runtime/gr_scheduler.cc33
-rw-r--r--gnuradio-core/src/lib/runtime/gr_scheduler.h65
-rw-r--r--gnuradio-core/src/lib/runtime/gr_scheduler_sts.cc87
-rw-r--r--gnuradio-core/src/lib/runtime/gr_scheduler_sts.h63
-rw-r--r--gnuradio-core/src/lib/runtime/gr_scheduler_tpb.cc103
-rw-r--r--gnuradio-core/src/lib/runtime/gr_scheduler_tpb.h61
-rw-r--r--gnuradio-core/src/lib/runtime/gr_select_handler.cc36
-rw-r--r--gnuradio-core/src/lib/runtime/gr_select_handler.h85
-rw-r--r--gnuradio-core/src/lib/runtime/gr_single_threaded_scheduler.cc364
-rw-r--r--gnuradio-core/src/lib/runtime/gr_single_threaded_scheduler.h62
-rw-r--r--gnuradio-core/src/lib/runtime/gr_single_threaded_scheduler.i54
-rw-r--r--gnuradio-core/src/lib/runtime/gr_sptr_magic.cc72
-rw-r--r--gnuradio-core/src/lib/runtime/gr_sptr_magic.h52
-rw-r--r--gnuradio-core/src/lib/runtime/gr_sync_block.cc55
-rw-r--r--gnuradio-core/src/lib/runtime/gr_sync_block.h74
-rw-r--r--gnuradio-core/src/lib/runtime/gr_sync_block.i29
-rw-r--r--gnuradio-core/src/lib/runtime/gr_sync_decimator.cc48
-rw-r--r--gnuradio-core/src/lib/runtime/gr_sync_decimator.h43
-rw-r--r--gnuradio-core/src/lib/runtime/gr_sync_decimator.i31
-rw-r--r--gnuradio-core/src/lib/runtime/gr_sync_interpolator.cc48
-rw-r--r--gnuradio-core/src/lib/runtime/gr_sync_interpolator.h43
-rw-r--r--gnuradio-core/src/lib/runtime/gr_sync_interpolator.i31
-rw-r--r--gnuradio-core/src/lib/runtime/gr_sys_paths.cc55
-rw-r--r--gnuradio-core/src/lib/runtime/gr_sys_paths.h33
-rw-r--r--gnuradio-core/src/lib/runtime/gr_tags.h55
-rw-r--r--gnuradio-core/src/lib/runtime/gr_tags.i32
-rw-r--r--gnuradio-core/src/lib/runtime/gr_timer.h84
-rw-r--r--gnuradio-core/src/lib/runtime/gr_top_block.cc95
-rw-r--r--gnuradio-core/src/lib/runtime/gr_top_block.h67
-rw-r--r--gnuradio-core/src/lib/runtime/gr_top_block.i73
-rw-r--r--gnuradio-core/src/lib/runtime/gr_top_block_impl.cc195
-rw-r--r--gnuradio-core/src/lib/runtime/gr_top_block_impl.h85
-rw-r--r--gnuradio-core/src/lib/runtime/gr_tpb_detail.cc70
-rw-r--r--gnuradio-core/src/lib/runtime/gr_tpb_detail.h89
-rw-r--r--gnuradio-core/src/lib/runtime/gr_tpb_thread_body.cc151
-rw-r--r--gnuradio-core/src/lib/runtime/gr_tpb_thread_body.h46
-rw-r--r--gnuradio-core/src/lib/runtime/gr_types.h56
-rw-r--r--gnuradio-core/src/lib/runtime/gr_unittests.h43
-rw-r--r--gnuradio-core/src/lib/runtime/gr_vmcircbuf.cc295
-rw-r--r--gnuradio-core/src/lib/runtime/gr_vmcircbuf.h122
-rw-r--r--gnuradio-core/src/lib/runtime/gr_vmcircbuf_createfilemapping.cc204
-rw-r--r--gnuradio-core/src/lib/runtime/gr_vmcircbuf_createfilemapping.h76
-rw-r--r--gnuradio-core/src/lib/runtime/gr_vmcircbuf_mmap_shm_open.cc205
-rw-r--r--gnuradio-core/src/lib/runtime/gr_vmcircbuf_mmap_shm_open.h67
-rw-r--r--gnuradio-core/src/lib/runtime/gr_vmcircbuf_mmap_tmpfile.cc197
-rw-r--r--gnuradio-core/src/lib/runtime/gr_vmcircbuf_mmap_tmpfile.h67
-rw-r--r--gnuradio-core/src/lib/runtime/gr_vmcircbuf_sysv_shm.cc194
-rw-r--r--gnuradio-core/src/lib/runtime/gr_vmcircbuf_sysv_shm.h67
-rw-r--r--gnuradio-core/src/lib/runtime/pmx_helper.hpp268
-rw-r--r--gnuradio-core/src/lib/runtime/qa_block_tags.cc450
-rw-r--r--gnuradio-core/src/lib/runtime/qa_block_tags.h52
-rw-r--r--gnuradio-core/src/lib/runtime/qa_gr_block.cc88
-rw-r--r--gnuradio-core/src/lib/runtime/qa_gr_block.h48
-rw-r--r--gnuradio-core/src/lib/runtime/qa_gr_buffer.cc307
-rw-r--r--gnuradio-core/src/lib/runtime/qa_gr_buffer.h53
-rw-r--r--gnuradio-core/src/lib/runtime/qa_gr_flowgraph.cc245
-rw-r--r--gnuradio-core/src/lib/runtime/qa_gr_flowgraph.h75
-rw-r--r--gnuradio-core/src/lib/runtime/qa_gr_hier_block2.cc57
-rw-r--r--gnuradio-core/src/lib/runtime/qa_gr_hier_block2.h42
-rw-r--r--gnuradio-core/src/lib/runtime/qa_gr_hier_block2_derived.cc87
-rw-r--r--gnuradio-core/src/lib/runtime/qa_gr_hier_block2_derived.h41
-rw-r--r--gnuradio-core/src/lib/runtime/qa_gr_io_signature.cc64
-rw-r--r--gnuradio-core/src/lib/runtime/qa_gr_io_signature.h46
-rw-r--r--gnuradio-core/src/lib/runtime/qa_gr_top_block.cc285
-rw-r--r--gnuradio-core/src/lib/runtime/qa_gr_top_block.h66
-rw-r--r--gnuradio-core/src/lib/runtime/qa_gr_vmcircbuf.cc40
-rw-r--r--gnuradio-core/src/lib/runtime/qa_gr_vmcircbuf.h39
-rw-r--r--gnuradio-core/src/lib/runtime/qa_runtime.cc61
-rw-r--r--gnuradio-core/src/lib/runtime/qa_runtime.h38
-rw-r--r--gnuradio-core/src/lib/runtime/qa_set_msg_handler.cc81
-rw-r--r--gnuradio-core/src/lib/runtime/qa_set_msg_handler.h43
-rw-r--r--gnuradio-core/src/lib/runtime/runtime.i123
-rw-r--r--gnuradio-core/src/lib/runtime/test_shared_block_ptr.cc53
-rw-r--r--gnuradio-core/src/lib/swig/CMakeLists.txt88
-rwxr-xr-xgnuradio-core/src/lib/swig/gen-swig-bug-fix111
-rw-r--r--gnuradio-core/src/lib/swig/gnuradio.i91
-rw-r--r--gnuradio-core/src/lib/swig/gnuradio_core.py28
-rw-r--r--gnuradio-core/src/lib/swig/gnuradio_core_filter.i32
-rw-r--r--gnuradio-core/src/lib/swig/gnuradio_core_general.i54
-rw-r--r--gnuradio-core/src/lib/swig/gnuradio_core_gengen.i32
-rw-r--r--gnuradio-core/src/lib/swig/gnuradio_core_hier.i32
-rw-r--r--gnuradio-core/src/lib/swig/gnuradio_core_io.i32
-rw-r--r--gnuradio-core/src/lib/swig/gnuradio_core_runtime.i34
-rw-r--r--gnuradio-core/src/lib/swig/gnuradio_swig_bug_workaround.h45
-rw-r--r--gnuradio-core/src/lib/swig/gr_shared_ptr.i43
-rw-r--r--gnuradio-core/src/lib/swig/gr_swig_block_magic.i50
-rw-r--r--gnuradio-core/src/lib/viterbi/CMakeLists.txt63
-rw-r--r--gnuradio-core/src/lib/viterbi/decode.cc88
-rw-r--r--gnuradio-core/src/lib/viterbi/encode.cc54
-rw-r--r--gnuradio-core/src/lib/viterbi/metrics.c126
-rw-r--r--gnuradio-core/src/lib/viterbi/tab.c57
-rw-r--r--gnuradio-core/src/lib/viterbi/viterbi.c355
-rw-r--r--gnuradio-core/src/lib/viterbi/viterbi.h53
-rwxr-xr-xgnuradio-core/src/python/bin/microtune.py42
-rw-r--r--gnuradio-core/src/python/build_utils.py226
-rw-r--r--gnuradio-core/src/python/build_utils_codes.py52
-rw-r--r--gnuradio-core/src/python/gnuradio/CMakeLists.txt38
-rw-r--r--gnuradio-core/src/python/gnuradio/__init__.py1
-rw-r--r--gnuradio-core/src/python/gnuradio/blks2/CMakeLists.txt26
-rw-r--r--gnuradio-core/src/python/gnuradio/blks2/__init__.py37
-rw-r--r--gnuradio-core/src/python/gnuradio/blks2impl/CMakeLists.txt45
-rw-r--r--gnuradio-core/src/python/gnuradio/blks2impl/__init__.py1
-rw-r--r--gnuradio-core/src/python/gnuradio/blks2impl/am_demod.py75
-rw-r--r--gnuradio-core/src/python/gnuradio/blks2impl/channel_model.py26
-rw-r--r--gnuradio-core/src/python/gnuradio/blks2impl/digital_voice.py.real102
-rw-r--r--gnuradio-core/src/python/gnuradio/blks2impl/filterbank.py169
-rw-r--r--gnuradio-core/src/python/gnuradio/blks2impl/fm_demod.py111
-rw-r--r--gnuradio-core/src/python/gnuradio/blks2impl/fm_emph.py151
-rw-r--r--gnuradio-core/src/python/gnuradio/blks2impl/logpwrfft.py155
-rw-r--r--gnuradio-core/src/python/gnuradio/blks2impl/nbfm_rx.py88
-rw-r--r--gnuradio-core/src/python/gnuradio/blks2impl/nbfm_tx.py92
-rw-r--r--gnuradio-core/src/python/gnuradio/blks2impl/pfb_arb_resampler.py128
-rw-r--r--gnuradio-core/src/python/gnuradio/blks2impl/pfb_channelizer.py73
-rw-r--r--gnuradio-core/src/python/gnuradio/blks2impl/pfb_decimator.py69
-rw-r--r--gnuradio-core/src/python/gnuradio/blks2impl/pfb_interpolator.py70
-rw-r--r--gnuradio-core/src/python/gnuradio/blks2impl/rational_resampler.py131
-rw-r--r--gnuradio-core/src/python/gnuradio/blks2impl/standard_squelch.py76
-rw-r--r--gnuradio-core/src/python/gnuradio/blks2impl/stream_to_vector_decimator.py93
-rw-r--r--gnuradio-core/src/python/gnuradio/blks2impl/wfm_rcv.py69
-rwxr-xr-xgnuradio-core/src/python/gnuradio/blks2impl/wfm_rcv_fmdet.py216
-rw-r--r--gnuradio-core/src/python/gnuradio/blks2impl/wfm_rcv_pll.py190
-rw-r--r--gnuradio-core/src/python/gnuradio/blks2impl/wfm_tx.py79
-rw-r--r--gnuradio-core/src/python/gnuradio/eng_notation.py71
-rw-r--r--gnuradio-core/src/python/gnuradio/eng_option.py62
-rw-r--r--gnuradio-core/src/python/gnuradio/gr/CMakeLists.txt49
-rw-r--r--gnuradio-core/src/python/gnuradio/gr/__init__.py116
-rwxr-xr-xgnuradio-core/src/python/gnuradio/gr/benchmark_filters.py75
-rw-r--r--gnuradio-core/src/python/gnuradio/gr/exceptions.py27
-rw-r--r--gnuradio-core/src/python/gnuradio/gr/gateway.py246
-rw-r--r--gnuradio-core/src/python/gnuradio/gr/gr_threading.py35
-rw-r--r--gnuradio-core/src/python/gnuradio/gr/gr_threading_23.py724
-rw-r--r--gnuradio-core/src/python/gnuradio/gr/gr_threading_24.py793
-rw-r--r--gnuradio-core/src/python/gnuradio/gr/hier_block2.py129
-rw-r--r--gnuradio-core/src/python/gnuradio/gr/prefs.py127
-rw-r--r--gnuradio-core/src/python/gnuradio/gr/pubsub.py153
-rwxr-xr-xgnuradio-core/src/python/gnuradio/gr/qa_add_and_friends.py163
-rwxr-xr-xgnuradio-core/src/python/gnuradio/gr/qa_add_v_and_friends.py353
-rw-r--r--gnuradio-core/src/python/gnuradio/gr/qa_affinity.py49
-rwxr-xr-xgnuradio-core/src/python/gnuradio/gr/qa_agc.py433
-rw-r--r--gnuradio-core/src/python/gnuradio/gr/qa_argmax.py77
-rwxr-xr-xgnuradio-core/src/python/gnuradio/gr/qa_bin_statistics.py230
-rw-r--r--gnuradio-core/src/python/gnuradio/gr/qa_block_gateway.py235
-rwxr-xr-xgnuradio-core/src/python/gnuradio/gr/qa_boolean_operators.py162
-rwxr-xr-xgnuradio-core/src/python/gnuradio/gr/qa_complex_to_xxx.py142
-rw-r--r--gnuradio-core/src/python/gnuradio/gr/qa_conjugate.py53
-rwxr-xr-xgnuradio-core/src/python/gnuradio/gr/qa_copy.py58
-rwxr-xr-xgnuradio-core/src/python/gnuradio/gr/qa_dc_blocker.py108
-rwxr-xr-xgnuradio-core/src/python/gnuradio/gr/qa_delay.py65
-rwxr-xr-xgnuradio-core/src/python/gnuradio/gr/qa_diff_encoder.py86
-rwxr-xr-xgnuradio-core/src/python/gnuradio/gr/qa_diff_phasor_cc.py50
-rwxr-xr-xgnuradio-core/src/python/gnuradio/gr/qa_ecc_ccsds_27.py50
-rw-r--r--gnuradio-core/src/python/gnuradio/gr/qa_endian_swap.py66
-rwxr-xr-xgnuradio-core/src/python/gnuradio/gr/qa_feval.py110
-rwxr-xr-xgnuradio-core/src/python/gnuradio/gr/qa_fft.py212
-rwxr-xr-xgnuradio-core/src/python/gnuradio/gr/qa_fft_filter.py383
-rwxr-xr-xgnuradio-core/src/python/gnuradio/gr/qa_filter_delay_fc.py317
-rwxr-xr-xgnuradio-core/src/python/gnuradio/gr/qa_float_to_char.py82
-rwxr-xr-xgnuradio-core/src/python/gnuradio/gr/qa_float_to_int.py85
-rwxr-xr-xgnuradio-core/src/python/gnuradio/gr/qa_float_to_short.py86
-rwxr-xr-xgnuradio-core/src/python/gnuradio/gr/qa_float_to_uchar.py64
-rwxr-xr-xgnuradio-core/src/python/gnuradio/gr/qa_fractional_interpolator.py38
-rwxr-xr-xgnuradio-core/src/python/gnuradio/gr/qa_frequency_modulator.py56
-rwxr-xr-xgnuradio-core/src/python/gnuradio/gr/qa_fsk_stuff.py75
-rwxr-xr-xgnuradio-core/src/python/gnuradio/gr/qa_glfsr_source.py94
-rwxr-xr-xgnuradio-core/src/python/gnuradio/gr/qa_goertzel.py64
-rwxr-xr-xgnuradio-core/src/python/gnuradio/gr/qa_head.py47
-rwxr-xr-xgnuradio-core/src/python/gnuradio/gr/qa_hier_block2.py369
-rwxr-xr-xgnuradio-core/src/python/gnuradio/gr/qa_hilbert.py116
-rwxr-xr-xgnuradio-core/src/python/gnuradio/gr/qa_iir.py159
-rwxr-xr-xgnuradio-core/src/python/gnuradio/gr/qa_int_to_float.py69
-rwxr-xr-xgnuradio-core/src/python/gnuradio/gr/qa_integrate.py75
-rwxr-xr-xgnuradio-core/src/python/gnuradio/gr/qa_interleave.py81
-rwxr-xr-xgnuradio-core/src/python/gnuradio/gr/qa_interp_fir_filter.py54
-rwxr-xr-xgnuradio-core/src/python/gnuradio/gr/qa_keep_m_in_n.py58
-rwxr-xr-xgnuradio-core/src/python/gnuradio/gr/qa_kludge_copy.py91
-rwxr-xr-xgnuradio-core/src/python/gnuradio/gr/qa_kludged_imports.py43
-rwxr-xr-xgnuradio-core/src/python/gnuradio/gr/qa_max.py70
-rwxr-xr-xgnuradio-core/src/python/gnuradio/gr/qa_message.py131
-rw-r--r--gnuradio-core/src/python/gnuradio/gr/qa_multiply_conjugate.py57
-rwxr-xr-xgnuradio-core/src/python/gnuradio/gr/qa_mute.py89
-rwxr-xr-xgnuradio-core/src/python/gnuradio/gr/qa_nlog10.py47
-rwxr-xr-xgnuradio-core/src/python/gnuradio/gr/qa_noise.py51
-rwxr-xr-xgnuradio-core/src/python/gnuradio/gr/qa_pack_k_bits.py67
-rwxr-xr-xgnuradio-core/src/python/gnuradio/gr/qa_packed_to_unpacked.py405
-rwxr-xr-xgnuradio-core/src/python/gnuradio/gr/qa_pdu.py109
-rwxr-xr-xgnuradio-core/src/python/gnuradio/gr/qa_pipe_fittings.py143
-rwxr-xr-xgnuradio-core/src/python/gnuradio/gr/qa_pll_carriertracking.py156
-rwxr-xr-xgnuradio-core/src/python/gnuradio/gr/qa_pll_freqdet.py160
-rwxr-xr-xgnuradio-core/src/python/gnuradio/gr/qa_pll_refout.py156
-rwxr-xr-xgnuradio-core/src/python/gnuradio/gr/qa_pn_correlator_cc.py50
-rw-r--r--gnuradio-core/src/python/gnuradio/gr/qa_probe_signal.py67
-rw-r--r--gnuradio-core/src/python/gnuradio/gr/qa_python_message_passing.py123
-rwxr-xr-xgnuradio-core/src/python/gnuradio/gr/qa_rational_resampler.py298
-rwxr-xr-xgnuradio-core/src/python/gnuradio/gr/qa_regenerate.py90
-rwxr-xr-xgnuradio-core/src/python/gnuradio/gr/qa_repeat.py48
-rwxr-xr-xgnuradio-core/src/python/gnuradio/gr/qa_scrambler.py64
-rwxr-xr-xgnuradio-core/src/python/gnuradio/gr/qa_short_to_char.py69
-rwxr-xr-xgnuradio-core/src/python/gnuradio/gr/qa_short_to_float.py70
-rwxr-xr-xgnuradio-core/src/python/gnuradio/gr/qa_sig_source.py157
-rwxr-xr-xgnuradio-core/src/python/gnuradio/gr/qa_single_pole_iir.py72
-rwxr-xr-xgnuradio-core/src/python/gnuradio/gr/qa_single_pole_iir_cc.py72
-rwxr-xr-xgnuradio-core/src/python/gnuradio/gr/qa_skiphead.py102
-rwxr-xr-xgnuradio-core/src/python/gnuradio/gr/qa_stream_mux.py168
-rwxr-xr-xgnuradio-core/src/python/gnuradio/gr/qa_tag_debug.py43
-rwxr-xr-xgnuradio-core/src/python/gnuradio/gr/qa_tag_utils.py55
-rwxr-xr-xgnuradio-core/src/python/gnuradio/gr/qa_udp_sink_source.py99
-rwxr-xr-xgnuradio-core/src/python/gnuradio/gr/qa_unpack_k_bits.py57
-rwxr-xr-xgnuradio-core/src/python/gnuradio/gr/qa_vector_insert.py58
-rw-r--r--gnuradio-core/src/python/gnuradio/gr/qa_vector_map.py105
-rwxr-xr-xgnuradio-core/src/python/gnuradio/gr/qa_vector_sink_source.py65
-rwxr-xr-xgnuradio-core/src/python/gnuradio/gr/qa_wavefile.py69
-rw-r--r--gnuradio-core/src/python/gnuradio/gr/tag_utils.py54
-rw-r--r--gnuradio-core/src/python/gnuradio/gr/test_16bit_1chunk.wavbin0 -> 52 bytes
-rw-r--r--gnuradio-core/src/python/gnuradio/gr/top_block.py165
-rwxr-xr-xgnuradio-core/src/python/gnuradio/gr_unittest.py167
-rw-r--r--gnuradio-core/src/python/gnuradio/gr_xmlrunner.py387
-rw-r--r--gnuradio-core/src/python/gnuradio/gru/CMakeLists.txt26
-rw-r--r--gnuradio-core/src/python/gnuradio/gru/__init__.py37
-rw-r--r--gnuradio-core/src/python/gnuradio/gruimpl/CMakeLists.txt38
-rw-r--r--gnuradio-core/src/python/gnuradio/gruimpl/__init__.py1
-rw-r--r--gnuradio-core/src/python/gnuradio/gruimpl/daemon.py102
-rw-r--r--gnuradio-core/src/python/gnuradio/gruimpl/freqz.py344
-rwxr-xr-xgnuradio-core/src/python/gnuradio/gruimpl/gnuplot_freqz.py82
-rw-r--r--gnuradio-core/src/python/gnuradio/gruimpl/hexint.py44
-rw-r--r--gnuradio-core/src/python/gnuradio/gruimpl/listmisc.py29
-rwxr-xr-xgnuradio-core/src/python/gnuradio/gruimpl/lmx2306.py186
-rw-r--r--gnuradio-core/src/python/gnuradio/gruimpl/mathmisc.py33
-rw-r--r--gnuradio-core/src/python/gnuradio/gruimpl/msgq_runner.py82
-rw-r--r--gnuradio-core/src/python/gnuradio/gruimpl/os_read_exactly.py36
-rw-r--r--gnuradio-core/src/python/gnuradio/gruimpl/sdr_1000.py84
-rw-r--r--gnuradio-core/src/python/gnuradio/gruimpl/seq_with_cursor.py77
-rw-r--r--gnuradio-core/src/python/gnuradio/gruimpl/socket_stuff.py56
-rw-r--r--gnuradio-core/src/python/gnuradio/optfir.py341
-rw-r--r--gnuradio-core/src/python/gnuradio/window.py180
-rw-r--r--gnuradio-core/src/tests/CMakeLists.txt72
-rwxr-xr-xgnuradio-core/src/tests/benchmark_dotprod46
-rw-r--r--gnuradio-core/src/tests/benchmark_dotprod_ccc.cc151
-rw-r--r--gnuradio-core/src/tests/benchmark_dotprod_ccf.cc153
-rw-r--r--gnuradio-core/src/tests/benchmark_dotprod_fcc.cc152
-rw-r--r--gnuradio-core/src/tests/benchmark_dotprod_fff.cc148
-rw-r--r--gnuradio-core/src/tests/benchmark_dotprod_fsf.cc151
-rw-r--r--gnuradio-core/src/tests/benchmark_dotprod_scc.cc151
-rw-r--r--gnuradio-core/src/tests/benchmark_nco.cc220
-rw-r--r--gnuradio-core/src/tests/benchmark_vco.cc167
-rw-r--r--gnuradio-core/src/tests/nco_results48
-rw-r--r--gnuradio-core/src/tests/test_all.cc50
-rw-r--r--gnuradio-core/src/tests/test_atsc.cc42
-rwxr-xr-xgnuradio-core/src/tests/test_buffers.py136
-rw-r--r--gnuradio-core/src/tests/test_filter.cc42
-rw-r--r--gnuradio-core/src/tests/test_general.cc42
-rw-r--r--gnuradio-core/src/tests/test_runtime.cc42
-rw-r--r--gnuradio-core/src/tests/test_vmcircbuf.cc44
-rw-r--r--gnuradio-core/src/utils/cic_comp_taps.m45
-rw-r--r--gnuradio-core/src/utils/cool.m50
-rw-r--r--gnuradio-core/src/utils/db_width.m35
-rw-r--r--gnuradio-core/src/utils/filter_tools.m42
-rw-r--r--gnuradio-core/src/utils/is_complex.m24
-rw-r--r--gnuradio-core/src/utils/lp_to_bp.m27
-rw-r--r--gnuradio-core/src/utils/partition-cascaded-decimating-filters.scm67
-rw-r--r--gnuradio-core/src/utils/permute.scm27
-rw-r--r--gnuradio-core/src/utils/plot_cic_decimator_response.m44
-rw-r--r--gnuradio-core/src/utils/plot_freq_response.m36
-rw-r--r--gnuradio-core/src/utils/plot_freq_response_db.m39
-rw-r--r--gnuradio-core/src/utils/plot_freq_response_phase.m38
-rw-r--r--gnuradio-core/src/utils/plotfft.m40
-rw-r--r--gnuradio-core/src/utils/plotfftavgk.m61
-rw-r--r--gnuradio-core/src/utils/plotfftavgk_db.m73
-rw-r--r--gnuradio-core/src/utils/plotfftk.m41
-rw-r--r--gnuradio-core/src/utils/plotfftk_db.m43
-rw-r--r--gnuradio-core/src/utils/put_markers.m32
-rw-r--r--gnuradio-core/src/utils/rainbow.m53
-rw-r--r--gnuradio-core/src/utils/read_char_binary.m45
-rw-r--r--gnuradio-core/src/utils/read_complex_binary.m48
-rw-r--r--gnuradio-core/src/utils/read_cshort_binary.m46
-rw-r--r--gnuradio-core/src/utils/read_float_binary.m45
-rw-r--r--gnuradio-core/src/utils/read_int_binary.m46
-rw-r--r--gnuradio-core/src/utils/read_short_binary.m45
-rw-r--r--gnuradio-core/src/utils/read_xambi.m46
-rw-r--r--gnuradio-core/src/utils/runsum.m9
-rw-r--r--gnuradio-core/src/utils/single_pole_iir.m25
-rw-r--r--gnuradio-core/src/utils/split_vect.m15
-rw-r--r--gnuradio-core/src/utils/write_float_binary.m40
-rw-r--r--gnuradio-core/src/utils/write_short_binary.m40
1368 files changed, 128244 insertions, 0 deletions
diff --git a/gnuradio-core/src/examples/CMakeLists.txt b/gnuradio-core/src/examples/CMakeLists.txt
new file mode 100644
index 000000000..01d9eb83e
--- /dev/null
+++ b/gnuradio-core/src/examples/CMakeLists.txt
@@ -0,0 +1,25 @@
+# Copyright 2011 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+
+add_subdirectory(mp-sched)
+add_subdirectory(msg_passing)
+add_subdirectory(network)
+add_subdirectory(pfb)
+add_subdirectory(tags)
+add_subdirectory(volk_benchmark) \ No newline at end of file
diff --git a/gnuradio-core/src/examples/mp-sched/CMakeLists.txt b/gnuradio-core/src/examples/mp-sched/CMakeLists.txt
new file mode 100644
index 000000000..d2d910ecf
--- /dev/null
+++ b/gnuradio-core/src/examples/mp-sched/CMakeLists.txt
@@ -0,0 +1,36 @@
+# Copyright 2011 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+
+include(GrPython)
+
+GR_PYTHON_INSTALL(PROGRAMS
+ affinity_set.py
+ plot_flops.py
+ run_synthetic.py
+ synthetic.py
+ wfm_rcv_pll_to_wav.py
+ DESTINATION ${GR_PKG_DATA_DIR}/examples/mp-sched
+ COMPONENT "core_python"
+)
+
+install(
+ FILES README
+ DESTINATION ${GR_PKG_DATA_DIR}/examples/mp-sched
+ COMPONENT "core_python"
+)
diff --git a/gnuradio-core/src/examples/mp-sched/README b/gnuradio-core/src/examples/mp-sched/README
new file mode 100644
index 000000000..ae575437a
--- /dev/null
+++ b/gnuradio-core/src/examples/mp-sched/README
@@ -0,0 +1,2 @@
+These are pieces of code used to test and benchmark the
+multi-processor scheduler.
diff --git a/gnuradio-core/src/examples/mp-sched/affinity_set.py b/gnuradio-core/src/examples/mp-sched/affinity_set.py
new file mode 100755
index 000000000..65e929051
--- /dev/null
+++ b/gnuradio-core/src/examples/mp-sched/affinity_set.py
@@ -0,0 +1,70 @@
+#!/usr/bin/env python
+##################################################
+# Gnuradio Python Flow Graph
+# Title: Affinity Set Test
+##################################################
+
+from gnuradio import eng_notation
+from gnuradio import gr
+from gnuradio.eng_option import eng_option
+from gnuradio.gr import firdes
+from optparse import OptionParser
+import sys
+
+class affinity_set(gr.top_block):
+
+ def __init__(self):
+ gr.top_block.__init__(self, "Affinity Set Test")
+
+ ##################################################
+ # Variables
+ ##################################################
+ self.samp_rate = samp_rate = 32000
+
+ ##################################################
+ # Blocks
+ ##################################################
+ vec_len = 1
+ self.gr_throttle_0 = gr.throttle(gr.sizeof_gr_complex*vec_len, samp_rate)
+ self.gr_null_source_0 = gr.null_source(gr.sizeof_gr_complex*vec_len)
+ self.gr_null_sink_0 = gr.null_sink(gr.sizeof_gr_complex*vec_len)
+ self.gr_filt_0 = gr.fir_filter_ccc(1, 40000*[0.2+0.3j,])
+ self.gr_filt_1 = gr.fir_filter_ccc(1, 40000*[0.2+0.3j,])
+
+ self.gr_filt_0.set_processor_affinity([0,])
+ self.gr_filt_1.set_processor_affinity([0,1])
+
+ ##################################################
+ # Connections
+ ##################################################
+ self.connect((self.gr_null_source_0, 0), (self.gr_throttle_0, 0))
+ self.connect((self.gr_throttle_0, 0), (self.gr_filt_0, 0))
+ self.connect((self.gr_filt_0, 0), (self.gr_filt_1, 0))
+ self.connect((self.gr_filt_1, 0), (self.gr_null_sink_0, 0))
+
+ def get_samp_rate(self):
+ return self.samp_rate
+
+ def set_samp_rate(self, samp_rate):
+ self.samp_rate = samp_rate
+
+if __name__ == '__main__':
+ parser = OptionParser(option_class=eng_option, usage="%prog: [options]")
+ (options, args) = parser.parse_args()
+ tb = affinity_set()
+ tb.start()
+
+ while(1):
+ ret = raw_input('Enter a new Core # or Press Enter to quit: ')
+ if(len(ret) == 0):
+ tb.stop()
+ sys.exit(0)
+ elif(ret.lower() == "none"):
+ tb.gr_filt_0.unset_processor_affinity()
+ else:
+ try:
+ n = int(ret)
+ except ValueError:
+ print "Invalid number"
+ else:
+ tb.gr_filt_0.set_processor_affinity([n,])
diff --git a/gnuradio-core/src/examples/mp-sched/perf-data/core-duo.dat b/gnuradio-core/src/examples/mp-sched/perf-data/core-duo.dat
new file mode 100644
index 000000000..064d1e128
--- /dev/null
+++ b/gnuradio-core/src/examples/mp-sched/perf-data/core-duo.dat
@@ -0,0 +1,65 @@
+#D Core Duo 1.83 GHz (T2400)
+ 1 1 5.273e+07 10.010 10.160 0.060 1.021 2.700000e+10 2.697e+09
+ 1 2 5.273e+07 10.410 20.180 0.150 1.953 5.400000e+10 5.187e+09
+ 1 3 3.516e+07 10.360 20.030 0.150 1.948 5.400000e+10 5.212e+09
+ 1 4 2.637e+07 10.100 20.030 0.100 1.993 5.400000e+10 5.347e+09
+ 1 5 2.109e+07 10.140 19.980 0.110 1.981 5.400000e+10 5.325e+09
+ 1 6 1.758e+07 10.110 20.030 0.110 1.992 5.400000e+10 5.341e+09
+ 1 7 1.507e+07 10.120 20.030 0.110 1.990 5.400000e+10 5.336e+09
+ 1 8 1.318e+07 10.060 19.980 0.090 1.995 5.400000e+10 5.368e+09
+ 2 1 5.273e+07 10.210 20.130 0.260 1.997 5.400000e+10 5.289e+09
+ 2 2 2.637e+07 10.110 20.030 0.140 1.995 5.400000e+10 5.341e+09
+ 2 3 1.758e+07 10.120 20.010 0.150 1.992 5.400000e+10 5.336e+09
+ 2 4 1.318e+07 10.080 19.990 0.110 1.994 5.400000e+10 5.357e+09
+ 2 5 1.055e+07 10.050 19.990 0.090 1.998 5.400000e+10 5.373e+09
+ 2 6 8.789e+06 10.050 19.980 0.080 1.996 5.400000e+10 5.373e+09
+ 2 7 7.533e+06 10.050 19.970 0.090 1.996 5.400000e+10 5.373e+09
+ 2 8 6.592e+06 10.040 19.970 0.090 1.998 5.399999e+10 5.378e+09
+ 3 1 3.516e+07 10.630 20.130 0.230 1.915 5.400000e+10 5.080e+09
+ 3 2 1.758e+07 10.120 20.020 0.170 1.995 5.400000e+10 5.336e+09
+ 3 3 1.172e+07 10.140 20.050 0.130 1.990 5.400000e+10 5.325e+09
+ 3 4 8.789e+06 10.070 20.010 0.100 1.997 5.400000e+10 5.362e+09
+ 3 5 7.031e+06 10.060 19.980 0.100 1.996 5.400000e+10 5.368e+09
+ 3 6 5.859e+06 10.060 20.000 0.100 1.998 5.400000e+10 5.368e+09
+ 3 7 5.022e+06 10.050 20.010 0.070 1.998 5.400000e+10 5.373e+09
+ 3 8 4.395e+06 10.050 19.990 0.070 1.996 5.400000e+10 5.373e+09
+ 4 1 2.637e+07 10.180 20.080 0.240 1.996 5.400000e+10 5.305e+09
+ 4 2 1.318e+07 10.140 20.000 0.180 1.990 5.400000e+10 5.325e+09
+ 4 3 8.789e+06 10.110 20.020 0.120 1.992 5.400000e+10 5.341e+09
+ 4 4 6.592e+06 10.080 20.020 0.090 1.995 5.399999e+10 5.357e+09
+ 4 5 5.273e+06 10.050 19.990 0.090 1.998 5.399999e+10 5.373e+09
+ 4 6 4.395e+06 10.080 20.010 0.080 1.993 5.400000e+10 5.357e+09
+ 4 7 3.767e+06 10.070 20.000 0.080 1.994 5.400000e+10 5.362e+09
+ 4 8 3.296e+06 10.050 20.000 0.080 1.998 5.399999e+10 5.373e+09
+ 5 1 2.109e+07 11.240 20.080 0.260 1.810 5.400000e+10 4.804e+09
+ 5 2 1.055e+07 10.130 19.990 0.150 1.988 5.400000e+10 5.331e+09
+ 5 3 7.031e+06 10.100 20.020 0.120 1.994 5.400000e+10 5.347e+09
+ 5 4 5.273e+06 10.070 20.000 0.090 1.995 5.399999e+10 5.362e+09
+ 5 5 4.219e+06 10.100 20.040 0.090 1.993 5.400000e+10 5.347e+09
+ 5 6 3.516e+06 10.080 20.000 0.090 1.993 5.400000e+10 5.357e+09
+ 5 7 3.013e+06 10.070 20.000 0.100 1.996 5.399998e+10 5.362e+09
+ 5 8 2.637e+06 10.070 20.000 0.090 1.995 5.399998e+10 5.362e+09
+ 6 1 1.758e+07 10.220 20.100 0.290 1.995 5.400000e+10 5.284e+09
+ 6 2 8.789e+06 10.080 20.010 0.130 1.998 5.400000e+10 5.357e+09
+ 6 3 5.859e+06 10.090 20.030 0.120 1.997 5.400000e+10 5.352e+09
+ 6 4 4.395e+06 10.100 20.030 0.080 1.991 5.400000e+10 5.347e+09
+ 6 5 3.516e+06 10.060 20.020 0.080 1.998 5.400000e+10 5.368e+09
+ 6 6 2.930e+06 10.070 20.030 0.090 1.998 5.399999e+10 5.362e+09
+ 6 7 2.511e+06 10.070 20.030 0.080 1.997 5.399998e+10 5.362e+09
+ 6 8 2.197e+06 10.070 20.010 0.090 1.996 5.399998e+10 5.362e+09
+ 7 1 1.507e+07 10.420 20.030 0.260 1.947 5.400000e+10 5.182e+09
+ 7 2 7.533e+06 10.100 20.010 0.140 1.995 5.400000e+10 5.347e+09
+ 7 3 5.022e+06 10.080 20.020 0.120 1.998 5.400000e+10 5.357e+09
+ 7 4 3.767e+06 10.080 20.010 0.100 1.995 5.400000e+10 5.357e+09
+ 7 5 3.013e+06 10.070 20.030 0.080 1.997 5.399998e+10 5.362e+09
+ 7 6 2.511e+06 10.080 20.010 0.090 1.994 5.399998e+10 5.357e+09
+ 7 7 2.152e+06 10.080 20.060 0.070 1.997 5.399999e+10 5.357e+09
+ 7 8 1.883e+06 10.070 20.040 0.070 1.997 5.399998e+10 5.362e+09
+ 8 1 1.318e+07 10.220 20.080 0.270 1.991 5.400000e+10 5.284e+09
+ 8 2 6.592e+06 10.100 20.010 0.140 1.995 5.399999e+10 5.347e+09
+ 8 3 4.395e+06 10.110 20.020 0.120 1.992 5.400000e+10 5.341e+09
+ 8 4 3.296e+06 10.090 20.040 0.090 1.995 5.399999e+10 5.352e+09
+ 8 5 2.637e+06 10.090 20.040 0.090 1.995 5.399998e+10 5.352e+09
+ 8 6 2.197e+06 10.070 20.040 0.100 2.000 5.399998e+10 5.362e+09
+ 8 7 1.883e+06 10.090 20.050 0.080 1.995 5.399998e+10 5.352e+09
+ 8 8 1.648e+06 10.090 20.040 0.090 1.995 5.399999e+10 5.352e+09
diff --git a/gnuradio-core/src/examples/mp-sched/perf-data/core2-duo.dat b/gnuradio-core/src/examples/mp-sched/perf-data/core2-duo.dat
new file mode 100644
index 000000000..d67dee8e5
--- /dev/null
+++ b/gnuradio-core/src/examples/mp-sched/perf-data/core2-duo.dat
@@ -0,0 +1,65 @@
+#D Core2 Duo 2.66 GHz (6700)
+ 1 1 1.406e+08 9.890 10.100 0.230 1.044 7.200000e+10 7.280e+09
+ 1 2 1.406e+08 10.400 19.900 0.290 1.941 1.440000e+11 1.385e+10
+ 1 3 9.375e+07 11.410 19.950 0.200 1.766 1.440000e+11 1.262e+10
+ 1 4 7.031e+07 10.230 19.800 0.230 1.958 1.440000e+11 1.408e+10
+ 1 5 5.625e+07 10.640 19.800 0.180 1.878 1.440000e+11 1.353e+10
+ 1 6 4.688e+07 10.000 19.780 0.130 1.991 1.440000e+11 1.440e+10
+ 1 7 4.018e+07 10.500 19.690 0.180 1.892 1.440000e+11 1.371e+10
+ 1 8 3.516e+07 10.020 19.750 0.170 1.988 1.440000e+11 1.437e+10
+ 2 1 1.406e+08 10.330 20.000 0.460 1.981 1.440000e+11 1.394e+10
+ 2 2 7.031e+07 10.160 19.870 0.270 1.982 1.440000e+11 1.417e+10
+ 2 3 4.688e+07 10.210 19.780 0.230 1.960 1.440000e+11 1.410e+10
+ 2 4 3.516e+07 10.050 19.730 0.210 1.984 1.440000e+11 1.433e+10
+ 2 5 2.812e+07 10.060 19.760 0.170 1.981 1.440000e+11 1.431e+10
+ 2 6 2.344e+07 10.030 19.780 0.180 1.990 1.440000e+11 1.436e+10
+ 2 7 2.009e+07 10.040 19.820 0.180 1.992 1.440000e+11 1.434e+10
+ 2 8 1.758e+07 10.050 19.820 0.180 1.990 1.440000e+11 1.433e+10
+ 3 1 9.375e+07 13.140 19.950 0.450 1.553 1.440000e+11 1.096e+10
+ 3 2 4.688e+07 10.570 19.840 0.290 1.904 1.440000e+11 1.362e+10
+ 3 3 3.125e+07 10.420 19.730 0.280 1.920 1.440000e+11 1.382e+10
+ 3 4 2.344e+07 10.120 19.710 0.240 1.971 1.440000e+11 1.423e+10
+ 3 5 1.875e+07 10.140 19.750 0.190 1.966 1.440000e+11 1.420e+10
+ 3 6 1.562e+07 10.030 19.730 0.190 1.986 1.440000e+11 1.436e+10
+ 3 7 1.339e+07 10.020 19.720 0.200 1.988 1.440000e+11 1.437e+10
+ 3 8 1.172e+07 9.990 19.720 0.170 1.991 1.440000e+11 1.441e+10
+ 4 1 7.031e+07 10.310 19.980 0.460 1.983 1.440000e+11 1.397e+10
+ 4 2 3.516e+07 10.300 19.830 0.320 1.956 1.440000e+11 1.398e+10
+ 4 3 2.344e+07 10.180 19.780 0.230 1.966 1.440000e+11 1.415e+10
+ 4 4 1.758e+07 10.070 19.750 0.220 1.983 1.440000e+11 1.430e+10
+ 4 5 1.406e+07 10.090 19.750 0.190 1.976 1.440000e+11 1.427e+10
+ 4 6 1.172e+07 10.020 19.720 0.190 1.987 1.440000e+11 1.437e+10
+ 4 7 1.004e+07 10.040 19.780 0.190 1.989 1.440000e+11 1.434e+10
+ 4 8 8.789e+06 10.000 19.750 0.160 1.991 1.440000e+11 1.440e+10
+ 5 1 5.625e+07 11.580 19.930 0.500 1.764 1.440000e+11 1.244e+10
+ 5 2 2.812e+07 10.300 19.830 0.320 1.956 1.440000e+11 1.398e+10
+ 5 3 1.875e+07 10.240 19.760 0.240 1.953 1.440000e+11 1.406e+10
+ 5 4 1.406e+07 10.140 19.880 0.230 1.983 1.440000e+11 1.420e+10
+ 5 5 1.125e+07 10.040 19.730 0.200 1.985 1.440000e+11 1.434e+10
+ 5 6 9.375e+06 10.030 19.770 0.200 1.991 1.440000e+11 1.436e+10
+ 5 7 8.036e+06 10.030 19.780 0.170 1.989 1.440000e+11 1.436e+10
+ 5 8 7.031e+06 10.000 19.750 0.180 1.993 1.440000e+11 1.440e+10
+ 6 1 4.688e+07 10.340 19.910 0.560 1.980 1.440000e+11 1.393e+10
+ 6 2 2.344e+07 10.290 19.770 0.330 1.953 1.440000e+11 1.399e+10
+ 6 3 1.562e+07 10.150 19.770 0.270 1.974 1.440000e+11 1.419e+10
+ 6 4 1.172e+07 10.170 19.880 0.240 1.978 1.440000e+11 1.416e+10
+ 6 5 9.375e+06 10.080 19.780 0.240 1.986 1.440000e+11 1.429e+10
+ 6 6 7.812e+06 10.020 19.740 0.220 1.992 1.440000e+11 1.437e+10
+ 6 7 6.696e+06 10.050 19.760 0.200 1.986 1.440000e+11 1.433e+10
+ 6 8 5.859e+06 10.070 19.750 0.210 1.982 1.440000e+11 1.430e+10
+ 7 1 4.018e+07 11.220 19.880 0.530 1.819 1.440000e+11 1.283e+10
+ 7 2 2.009e+07 10.280 19.790 0.340 1.958 1.440000e+11 1.401e+10
+ 7 3 1.339e+07 10.190 19.760 0.250 1.964 1.440000e+11 1.413e+10
+ 7 4 1.004e+07 10.060 19.750 0.240 1.987 1.440000e+11 1.431e+10
+ 7 5 8.036e+06 10.070 19.750 0.240 1.985 1.440000e+11 1.430e+10
+ 7 6 6.696e+06 10.040 19.810 0.220 1.995 1.440000e+11 1.434e+10
+ 7 7 5.740e+06 10.050 19.780 0.210 1.989 1.440000e+11 1.433e+10
+ 7 8 5.022e+06 10.010 19.790 0.190 1.996 1.440000e+11 1.439e+10
+ 8 1 3.516e+07 10.320 19.900 0.470 1.974 1.440000e+11 1.395e+10
+ 8 2 1.758e+07 10.340 19.900 0.320 1.956 1.440000e+11 1.393e+10
+ 8 3 1.172e+07 10.130 19.770 0.290 1.980 1.440000e+11 1.422e+10
+ 8 4 8.789e+06 10.120 19.780 0.230 1.977 1.440000e+11 1.423e+10
+ 8 5 7.031e+06 10.040 19.790 0.200 1.991 1.440000e+11 1.434e+10
+ 8 6 5.859e+06 10.050 19.770 0.220 1.989 1.440000e+11 1.433e+10
+ 8 7 5.022e+06 10.030 19.800 0.200 1.994 1.440000e+11 1.436e+10
+ 8 8 4.395e+06 10.050 19.800 0.210 1.991 1.440000e+11 1.433e+10
diff --git a/gnuradio-core/src/examples/mp-sched/perf-data/dual-quad-core-2.33-clovertown.dat b/gnuradio-core/src/examples/mp-sched/perf-data/dual-quad-core-2.33-clovertown.dat
new file mode 100644
index 000000000..fa182c69a
--- /dev/null
+++ b/gnuradio-core/src/examples/mp-sched/perf-data/dual-quad-core-2.33-clovertown.dat
@@ -0,0 +1,257 @@
+#D Dual quad-core Xeon 2.33GHz (Clovertown E5345)
+ 1 1 1.367e+08 10.980 12.080 0.360 1.133 7.000000e+10 6.375e+09
+ 1 2 1.367e+08 12.250 24.310 0.400 2.017 1.400000e+11 1.143e+10
+ 1 3 1.367e+08 12.830 36.080 0.580 2.857 2.100000e+11 1.637e+10
+ 1 4 1.367e+08 12.600 46.820 0.770 3.777 2.800000e+11 2.222e+10
+ 1 5 1.367e+08 12.620 58.850 0.720 4.720 3.500000e+11 2.773e+10
+ 1 6 1.367e+08 12.310 69.430 0.860 5.710 4.200000e+11 3.412e+10
+ 1 7 1.367e+08 12.720 80.580 0.950 6.410 4.900000e+11 3.852e+10
+ 1 8 1.367e+08 12.440 91.530 1.010 7.439 5.600000e+11 4.502e+10
+ 1 9 1.367e+08 22.310 102.660 1.080 4.650 6.300000e+11 2.824e+10
+ 1 10 1.367e+08 22.610 113.670 1.160 5.079 7.000000e+11 3.096e+10
+ 1 11 1.367e+08 22.690 124.730 1.030 5.543 7.700000e+11 3.394e+10
+ 1 12 1.367e+08 23.260 136.520 1.030 5.914 8.400000e+11 3.611e+10
+ 1 13 1.367e+08 23.330 147.270 1.130 6.361 9.100000e+11 3.901e+10
+ 1 14 1.367e+08 24.110 158.070 1.010 6.598 9.800000e+11 4.065e+10
+ 1 15 1.367e+08 25.380 168.370 1.080 6.677 1.050000e+12 4.137e+10
+ 1 16 1.367e+08 26.660 179.130 1.250 6.766 1.120000e+12 4.201e+10
+ 2 1 1.367e+08 11.190 23.330 0.420 2.122 1.400000e+11 1.251e+10
+ 2 2 1.367e+08 12.650 46.350 0.940 3.738 2.800000e+11 2.213e+10
+ 2 3 1.367e+08 12.510 69.010 0.980 5.595 4.200000e+11 3.357e+10
+ 2 4 1.367e+08 13.250 89.330 0.890 6.809 5.600000e+11 4.226e+10
+ 2 5 1.367e+08 22.540 113.580 1.150 5.090 7.000000e+11 3.106e+10
+ 2 6 1.367e+08 22.940 135.790 1.260 5.974 8.400000e+11 3.662e+10
+ 2 7 1.367e+08 24.250 158.360 1.520 6.593 9.800000e+11 4.041e+10
+ 2 8 1.367e+08 26.610 179.840 1.490 6.814 1.120000e+12 4.209e+10
+ 2 9 1.215e+08 26.860 179.400 1.540 6.736 1.120000e+12 4.170e+10
+ 2 10 1.094e+08 26.350 178.740 1.430 6.838 1.120000e+12 4.250e+10
+ 2 11 9.943e+07 25.790 177.910 1.350 6.951 1.120000e+12 4.343e+10
+ 2 12 9.115e+07 25.200 176.980 1.460 7.081 1.120000e+12 4.444e+10
+ 2 13 8.413e+07 24.840 177.320 1.260 7.189 1.120000e+12 4.509e+10
+ 2 14 7.812e+07 24.450 176.920 1.130 7.282 1.120000e+12 4.581e+10
+ 2 15 7.292e+07 24.280 177.400 1.140 7.353 1.120000e+12 4.613e+10
+ 2 16 6.836e+07 23.830 176.290 1.100 7.444 1.120000e+12 4.700e+10
+ 3 1 1.367e+08 11.360 34.790 0.930 3.144 2.100000e+11 1.849e+10
+ 3 2 1.367e+08 12.560 68.800 1.400 5.589 4.200000e+11 3.344e+10
+ 3 3 1.367e+08 22.310 103.250 1.310 4.687 6.300000e+11 2.824e+10
+ 3 4 1.367e+08 22.940 136.120 1.500 5.999 8.400000e+11 3.662e+10
+ 3 5 1.367e+08 25.240 168.550 1.790 6.749 1.050000e+12 4.160e+10
+ 3 6 1.215e+08 26.800 178.710 1.610 6.728 1.120000e+12 4.179e+10
+ 3 7 1.042e+08 26.090 178.710 1.490 6.907 1.120000e+12 4.293e+10
+ 3 8 9.115e+07 25.420 178.140 1.360 7.061 1.120000e+12 4.406e+10
+ 3 9 8.102e+07 24.680 177.260 1.410 7.239 1.120000e+12 4.538e+10
+ 3 10 7.292e+07 24.270 176.830 1.390 7.343 1.120000e+12 4.615e+10
+ 3 11 6.629e+07 23.890 177.060 1.240 7.463 1.120000e+12 4.688e+10
+ 3 12 6.076e+07 23.620 176.290 1.300 7.519 1.120000e+12 4.742e+10
+ 3 13 5.609e+07 23.340 176.780 1.230 7.627 1.120000e+12 4.799e+10
+ 3 14 5.208e+07 23.140 176.330 1.300 7.676 1.120000e+12 4.840e+10
+ 3 15 4.861e+07 23.100 176.940 1.080 7.706 1.120000e+12 4.848e+10
+ 3 16 4.557e+07 22.850 176.120 1.060 7.754 1.120000e+12 4.902e+10
+ 4 1 1.367e+08 11.440 45.520 1.080 4.073 2.800000e+11 2.448e+10
+ 4 2 1.367e+08 12.410 90.020 1.440 7.370 5.600000e+11 4.512e+10
+ 4 3 1.367e+08 23.060 135.570 1.600 5.948 8.400000e+11 3.643e+10
+ 4 4 1.367e+08 26.720 179.780 1.880 6.799 1.120000e+12 4.192e+10
+ 4 5 1.094e+08 26.280 178.110 1.890 6.849 1.120000e+12 4.262e+10
+ 4 6 9.115e+07 25.250 177.280 1.700 7.088 1.120000e+12 4.436e+10
+ 4 7 7.812e+07 24.880 177.830 1.570 7.211 1.120000e+12 4.502e+10
+ 4 8 6.836e+07 24.150 177.240 1.350 7.395 1.120000e+12 4.638e+10
+ 4 9 6.076e+07 23.730 176.590 1.370 7.499 1.120000e+12 4.720e+10
+ 4 10 5.469e+07 23.380 176.570 1.310 7.608 1.120000e+12 4.790e+10
+ 4 11 4.972e+07 23.230 176.400 1.290 7.649 1.120000e+12 4.821e+10
+ 4 12 4.557e+07 22.950 176.100 1.250 7.728 1.120000e+12 4.880e+10
+ 4 13 4.207e+07 22.980 176.430 1.260 7.732 1.120000e+12 4.874e+10
+ 4 14 3.906e+07 22.820 176.300 1.350 7.785 1.120000e+12 4.908e+10
+ 4 15 3.646e+07 22.750 176.450 1.220 7.810 1.120000e+12 4.923e+10
+ 4 16 3.418e+07 22.620 176.350 1.080 7.844 1.120000e+12 4.951e+10
+ 5 1 1.367e+08 12.000 56.890 1.600 4.874 3.500000e+11 2.917e+10
+ 5 2 1.367e+08 22.390 112.870 1.920 5.127 7.000000e+11 3.126e+10
+ 5 3 1.367e+08 25.170 167.880 2.110 6.754 1.050000e+12 4.172e+10
+ 5 4 1.094e+08 26.380 178.010 1.900 6.820 1.120000e+12 4.246e+10
+ 5 5 8.750e+07 25.190 177.570 1.660 7.115 1.120000e+12 4.446e+10
+ 5 6 7.292e+07 24.400 176.750 1.650 7.311 1.120000e+12 4.590e+10
+ 5 7 6.250e+07 24.020 177.580 1.570 7.458 1.120000e+12 4.663e+10
+ 5 8 5.469e+07 23.470 176.650 1.350 7.584 1.120000e+12 4.772e+10
+ 5 9 4.861e+07 23.200 176.350 1.280 7.656 1.120000e+12 4.828e+10
+ 5 10 4.375e+07 23.140 176.230 1.410 7.677 1.120000e+12 4.840e+10
+ 5 11 3.977e+07 22.930 176.120 1.320 7.738 1.120000e+12 4.884e+10
+ 5 12 3.646e+07 22.740 176.060 1.330 7.801 1.120000e+12 4.925e+10
+ 5 13 3.365e+07 22.690 176.450 1.210 7.830 1.120000e+12 4.936e+10
+ 5 14 3.125e+07 22.690 176.430 1.230 7.830 1.120000e+12 4.936e+10
+ 5 15 2.917e+07 22.690 176.410 1.260 7.830 1.120000e+12 4.936e+10
+ 5 16 2.734e+07 22.560 176.150 1.110 7.857 1.120000e+12 4.965e+10
+ 6 1 1.367e+08 12.600 68.590 2.230 5.621 4.200000e+11 3.333e+10
+ 6 2 1.367e+08 22.830 135.260 2.100 6.017 8.400000e+11 3.679e+10
+ 6 3 1.215e+08 26.860 178.470 2.140 6.724 1.120000e+12 4.170e+10
+ 6 4 9.115e+07 25.450 177.110 2.060 7.040 1.120000e+12 4.401e+10
+ 6 5 7.292e+07 24.510 176.850 1.910 7.293 1.120000e+12 4.570e+10
+ 6 6 6.076e+07 23.890 176.450 1.760 7.460 1.120000e+12 4.688e+10
+ 6 7 5.208e+07 23.460 175.980 1.540 7.567 1.120000e+12 4.774e+10
+ 6 8 4.557e+07 23.150 176.480 1.370 7.683 1.120000e+12 4.838e+10
+ 6 9 4.051e+07 22.920 176.030 1.400 7.741 1.120000e+12 4.887e+10
+ 6 10 3.646e+07 22.880 176.300 1.350 7.764 1.120000e+12 4.895e+10
+ 6 11 3.314e+07 22.830 175.970 1.360 7.767 1.120000e+12 4.906e+10
+ 6 12 3.038e+07 22.710 176.040 1.190 7.804 1.120000e+12 4.932e+10
+ 6 13 2.804e+07 22.690 176.050 1.340 7.818 1.120000e+12 4.936e+10
+ 6 14 2.604e+07 22.650 176.410 1.140 7.839 1.120000e+12 4.945e+10
+ 6 15 2.431e+07 22.570 175.940 1.250 7.851 1.120000e+12 4.962e+10
+ 6 16 2.279e+07 22.500 175.980 1.170 7.873 1.120000e+12 4.978e+10
+ 7 1 1.367e+08 12.960 79.970 2.850 6.390 4.900000e+11 3.781e+10
+ 7 2 1.367e+08 24.040 156.540 2.500 6.616 9.800000e+11 4.077e+10
+ 7 3 1.042e+08 26.130 178.060 2.210 6.899 1.120000e+12 4.286e+10
+ 7 4 7.812e+07 24.860 176.880 1.810 7.188 1.120000e+12 4.505e+10
+ 7 5 6.250e+07 24.000 176.590 1.790 7.433 1.120000e+12 4.667e+10
+ 7 6 5.208e+07 23.540 176.480 1.670 7.568 1.120000e+12 4.758e+10
+ 7 7 4.464e+07 23.180 176.030 1.510 7.659 1.120000e+12 4.832e+10
+ 7 8 3.906e+07 22.980 176.500 1.340 7.739 1.120000e+12 4.874e+10
+ 7 9 3.472e+07 22.870 175.970 1.280 7.750 1.120000e+12 4.897e+10
+ 7 10 3.125e+07 22.730 176.220 1.300 7.810 1.120000e+12 4.927e+10
+ 7 11 2.841e+07 22.700 176.030 1.300 7.812 1.120000e+12 4.934e+10
+ 7 12 2.604e+07 22.650 176.300 1.210 7.837 1.120000e+12 4.945e+10
+ 7 13 2.404e+07 22.580 176.140 1.170 7.853 1.120000e+12 4.960e+10
+ 7 14 2.232e+07 22.540 176.550 1.130 7.883 1.120000e+12 4.969e+10
+ 7 15 2.083e+07 22.570 175.870 1.260 7.848 1.120000e+12 4.962e+10
+ 7 16 1.953e+07 22.520 175.980 1.310 7.873 1.120000e+12 4.973e+10
+ 8 1 1.367e+08 13.250 91.770 3.010 7.153 5.600000e+11 4.226e+10
+ 8 2 1.367e+08 26.280 178.100 2.980 6.890 1.120000e+12 4.262e+10
+ 8 3 9.115e+07 25.510 177.140 2.270 7.033 1.120000e+12 4.390e+10
+ 8 4 6.836e+07 24.330 176.850 1.870 7.346 1.120000e+12 4.603e+10
+ 8 5 5.469e+07 23.680 176.850 1.690 7.540 1.120000e+12 4.730e+10
+ 8 6 4.557e+07 23.430 176.210 1.700 7.593 1.120000e+12 4.780e+10
+ 8 7 3.906e+07 23.100 176.680 1.440 7.711 1.120000e+12 4.848e+10
+ 8 8 3.418e+07 22.890 176.270 1.430 7.763 1.120000e+12 4.893e+10
+ 8 9 3.038e+07 22.760 175.980 1.320 7.790 1.120000e+12 4.921e+10
+ 8 10 2.734e+07 22.760 176.340 1.290 7.804 1.120000e+12 4.921e+10
+ 8 11 2.486e+07 22.660 176.220 1.170 7.828 1.120000e+12 4.943e+10
+ 8 12 2.279e+07 22.660 176.050 1.280 7.826 1.120000e+12 4.943e+10
+ 8 13 2.103e+07 22.590 176.170 1.350 7.858 1.120000e+12 4.958e+10
+ 8 14 1.953e+07 22.550 176.120 1.320 7.869 1.120000e+12 4.967e+10
+ 8 15 1.823e+07 22.590 176.130 1.270 7.853 1.120000e+12 4.958e+10
+ 8 16 1.709e+07 22.500 176.090 1.230 7.881 1.120000e+12 4.978e+10
+ 9 1 1.367e+08 21.110 101.410 2.640 4.929 6.300000e+11 2.984e+10
+ 9 2 1.215e+08 27.400 178.180 2.720 6.602 1.120000e+12 4.088e+10
+ 9 3 8.102e+07 25.140 177.370 2.230 7.144 1.120000e+12 4.455e+10
+ 9 4 6.076e+07 24.110 176.810 1.910 7.413 1.120000e+12 4.645e+10
+ 9 5 4.861e+07 23.460 176.240 1.600 7.581 1.120000e+12 4.774e+10
+ 9 6 4.051e+07 23.200 176.310 1.620 7.669 1.120000e+12 4.828e+10
+ 9 7 3.472e+07 22.970 176.560 1.540 7.754 1.120000e+12 4.876e+10
+ 9 8 3.038e+07 22.920 176.300 1.440 7.755 1.120000e+12 4.887e+10
+ 9 9 2.701e+07 22.830 176.090 1.370 7.773 1.120000e+12 4.906e+10
+ 9 10 2.431e+07 22.730 175.960 1.430 7.804 1.120000e+12 4.927e+10
+ 9 11 2.210e+07 22.750 176.160 1.260 7.799 1.120000e+12 4.923e+10
+ 9 12 2.025e+07 22.660 176.100 1.380 7.832 1.120000e+12 4.943e+10
+ 9 13 1.870e+07 22.700 176.040 1.400 7.817 1.120000e+12 4.934e+10
+ 9 14 1.736e+07 22.620 175.940 1.410 7.840 1.120000e+12 4.951e+10
+ 9 15 1.620e+07 22.490 175.910 1.340 7.881 1.120000e+12 4.980e+10
+ 9 16 1.519e+07 22.540 175.990 1.330 7.867 1.120000e+12 4.969e+10
+ 10 1 1.367e+08 21.730 113.690 2.870 5.364 7.000000e+11 3.221e+10
+ 10 2 1.094e+08 26.660 177.920 3.180 6.793 1.120000e+12 4.201e+10
+ 10 3 7.292e+07 24.740 176.810 2.090 7.231 1.120000e+12 4.527e+10
+ 10 4 5.469e+07 23.880 176.280 2.020 7.466 1.120000e+12 4.690e+10
+ 10 5 4.375e+07 23.330 176.510 1.610 7.635 1.120000e+12 4.801e+10
+ 10 6 3.646e+07 23.170 176.160 1.680 7.675 1.120000e+12 4.834e+10
+ 10 7 3.125e+07 22.950 176.490 1.470 7.754 1.120000e+12 4.880e+10
+ 10 8 2.734e+07 22.830 176.260 1.360 7.780 1.120000e+12 4.906e+10
+ 10 9 2.431e+07 22.770 175.930 1.410 7.788 1.120000e+12 4.919e+10
+ 10 10 2.188e+07 22.680 175.870 1.440 7.818 1.120000e+12 4.938e+10
+ 10 11 1.989e+07 22.700 176.140 1.310 7.817 1.120000e+12 4.934e+10
+ 10 12 1.823e+07 22.630 176.040 1.430 7.842 1.120000e+12 4.949e+10
+ 10 13 1.683e+07 22.640 176.000 1.320 7.832 1.120000e+12 4.947e+10
+ 10 14 1.562e+07 22.610 176.160 1.230 7.846 1.120000e+12 4.954e+10
+ 10 15 1.458e+07 22.570 176.010 1.290 7.856 1.120000e+12 4.962e+10
+ 10 16 1.367e+07 22.640 176.060 1.270 7.833 1.120000e+12 4.947e+10
+ 11 1 1.367e+08 22.060 124.440 3.050 5.779 7.700000e+11 3.490e+10
+ 11 2 9.943e+07 26.060 178.400 3.000 6.961 1.120000e+12 4.298e+10
+ 11 3 6.629e+07 24.380 176.690 2.200 7.338 1.120000e+12 4.594e+10
+ 11 4 4.972e+07 23.650 176.730 1.830 7.550 1.120000e+12 4.736e+10
+ 11 5 3.977e+07 23.310 176.030 1.780 7.628 1.120000e+12 4.805e+10
+ 11 6 3.314e+07 23.050 176.210 1.680 7.718 1.120000e+12 4.859e+10
+ 11 7 2.841e+07 22.940 176.300 1.540 7.752 1.120000e+12 4.882e+10
+ 11 8 2.486e+07 22.830 175.990 1.530 7.776 1.120000e+12 4.906e+10
+ 11 9 2.210e+07 22.760 176.060 1.440 7.799 1.120000e+12 4.921e+10
+ 11 10 1.989e+07 22.630 176.010 1.430 7.841 1.120000e+12 4.949e+10
+ 11 11 1.808e+07 22.720 176.040 1.390 7.809 1.120000e+12 4.930e+10
+ 11 12 1.657e+07 22.640 175.890 1.400 7.831 1.120000e+12 4.947e+10
+ 11 13 1.530e+07 22.570 176.090 1.260 7.858 1.120000e+12 4.962e+10
+ 11 14 1.420e+07 22.610 176.150 1.450 7.855 1.120000e+12 4.954e+10
+ 11 15 1.326e+07 22.550 175.980 1.310 7.862 1.120000e+12 4.967e+10
+ 11 16 1.243e+07 22.610 175.920 1.400 7.843 1.120000e+12 4.954e+10
+ 12 1 1.367e+08 22.220 136.260 3.390 6.285 8.400000e+11 3.780e+10
+ 12 2 9.115e+07 25.610 178.090 2.800 7.063 1.120000e+12 4.373e+10
+ 12 3 6.076e+07 24.180 176.320 2.230 7.384 1.120000e+12 4.632e+10
+ 12 4 4.557e+07 23.570 176.570 2.010 7.577 1.120000e+12 4.752e+10
+ 12 5 3.646e+07 23.210 176.420 1.710 7.675 1.120000e+12 4.826e+10
+ 12 6 3.038e+07 23.040 175.910 1.640 7.706 1.120000e+12 4.861e+10
+ 12 7 2.604e+07 22.980 176.390 1.510 7.742 1.120000e+12 4.874e+10
+ 12 8 2.279e+07 22.840 176.110 1.640 7.782 1.120000e+12 4.904e+10
+ 12 9 2.025e+07 22.760 175.950 1.500 7.797 1.120000e+12 4.921e+10
+ 12 10 1.823e+07 22.660 175.810 1.600 7.829 1.120000e+12 4.943e+10
+ 12 11 1.657e+07 22.710 175.940 1.410 7.809 1.120000e+12 4.932e+10
+ 12 12 1.519e+07 22.650 175.870 1.400 7.826 1.120000e+12 4.945e+10
+ 12 13 1.402e+07 22.640 176.040 1.260 7.831 1.120000e+12 4.947e+10
+ 12 14 1.302e+07 22.650 176.130 1.450 7.840 1.120000e+12 4.945e+10
+ 12 15 1.215e+07 22.580 175.990 1.370 7.855 1.120000e+12 4.960e+10
+ 12 16 1.139e+07 22.640 175.870 1.440 7.832 1.120000e+12 4.947e+10
+ 13 1 1.367e+08 22.640 147.020 3.570 6.652 9.100000e+11 4.019e+10
+ 13 2 8.413e+07 25.600 177.820 2.870 7.058 1.120000e+12 4.375e+10
+ 13 3 5.609e+07 24.020 176.980 2.270 7.463 1.120000e+12 4.663e+10
+ 13 4 4.207e+07 23.440 176.430 2.030 7.613 1.120000e+12 4.778e+10
+ 13 5 3.365e+07 23.080 176.110 1.790 7.708 1.120000e+12 4.853e+10
+ 13 6 2.804e+07 22.870 176.210 1.600 7.775 1.120000e+12 4.897e+10
+ 13 7 2.404e+07 22.940 176.340 1.580 7.756 1.120000e+12 4.882e+10
+ 13 8 2.103e+07 22.880 176.050 1.520 7.761 1.120000e+12 4.895e+10
+ 13 9 1.870e+07 22.740 176.020 1.400 7.802 1.120000e+12 4.925e+10
+ 13 10 1.683e+07 22.710 175.880 1.440 7.808 1.120000e+12 4.932e+10
+ 13 11 1.530e+07 22.590 176.040 1.350 7.853 1.120000e+12 4.958e+10
+ 13 12 1.402e+07 22.600 175.930 1.380 7.846 1.120000e+12 4.956e+10
+ 13 13 1.294e+07 22.710 176.010 1.340 7.809 1.120000e+12 4.932e+10
+ 13 14 1.202e+07 22.690 176.270 1.350 7.828 1.120000e+12 4.936e+10
+ 13 15 1.122e+07 22.590 175.960 1.290 7.846 1.120000e+12 4.958e+10
+ 13 16 1.052e+07 22.610 175.960 1.370 7.843 1.120000e+12 4.954e+10
+ 14 1 1.367e+08 23.120 157.180 3.810 6.963 9.800000e+11 4.239e+10
+ 14 2 7.812e+07 25.310 177.210 3.020 7.121 1.120000e+12 4.425e+10
+ 14 3 5.208e+07 24.130 177.110 2.340 7.437 1.120000e+12 4.642e+10
+ 14 4 3.906e+07 23.390 176.660 1.800 7.630 1.120000e+12 4.788e+10
+ 14 5 3.125e+07 23.060 176.420 1.750 7.726 1.120000e+12 4.857e+10
+ 14 6 2.604e+07 22.890 176.180 1.530 7.764 1.120000e+12 4.893e+10
+ 14 7 2.232e+07 22.940 176.060 1.550 7.742 1.120000e+12 4.882e+10
+ 14 8 1.953e+07 22.810 176.110 1.500 7.786 1.120000e+12 4.910e+10
+ 14 9 1.736e+07 22.750 176.370 1.370 7.813 1.120000e+12 4.923e+10
+ 14 10 1.562e+07 22.720 176.020 1.450 7.811 1.120000e+12 4.930e+10
+ 14 11 1.420e+07 22.680 176.090 1.310 7.822 1.120000e+12 4.938e+10
+ 14 12 1.302e+07 22.710 175.950 1.510 7.814 1.120000e+12 4.932e+10
+ 14 13 1.202e+07 22.700 176.100 1.500 7.824 1.120000e+12 4.934e+10
+ 14 14 1.116e+07 22.660 176.150 1.460 7.838 1.120000e+12 4.943e+10
+ 14 15 1.042e+07 22.680 176.120 1.370 7.826 1.120000e+12 4.938e+10
+ 14 16 9.766e+06 22.710 176.110 1.430 7.818 1.120000e+12 4.932e+10
+ 15 1 1.367e+08 23.710 168.080 4.140 7.264 1.050000e+12 4.429e+10
+ 15 2 7.292e+07 25.170 176.640 2.930 7.134 1.120000e+12 4.450e+10
+ 15 3 4.861e+07 23.820 176.980 2.110 7.518 1.120000e+12 4.702e+10
+ 15 4 3.646e+07 23.250 176.190 1.970 7.663 1.120000e+12 4.817e+10
+ 15 5 2.917e+07 23.050 176.450 1.690 7.728 1.120000e+12 4.859e+10
+ 15 6 2.431e+07 22.900 175.980 1.680 7.758 1.120000e+12 4.891e+10
+ 15 7 2.083e+07 22.830 176.090 1.640 7.785 1.120000e+12 4.906e+10
+ 15 8 1.823e+07 22.850 176.160 1.530 7.776 1.120000e+12 4.902e+10
+ 15 9 1.620e+07 22.780 176.390 1.360 7.803 1.120000e+12 4.917e+10
+ 15 10 1.458e+07 22.660 176.000 1.440 7.831 1.120000e+12 4.943e+10
+ 15 11 1.326e+07 22.660 176.110 1.430 7.835 1.120000e+12 4.943e+10
+ 15 12 1.215e+07 22.660 176.150 1.380 7.835 1.120000e+12 4.943e+10
+ 15 13 1.122e+07 22.760 175.970 1.580 7.801 1.120000e+12 4.921e+10
+ 15 14 1.042e+07 22.670 176.290 1.270 7.832 1.120000e+12 4.940e+10
+ 15 15 9.722e+06 22.710 176.060 1.550 7.821 1.120000e+12 4.932e+10
+ 15 16 9.115e+06 22.800 176.020 1.490 7.786 1.120000e+12 4.912e+10
+ 16 1 1.367e+08 25.470 179.270 4.730 7.224 1.120000e+12 4.397e+10
+ 16 2 6.836e+07 24.870 176.820 2.960 7.229 1.120000e+12 4.503e+10
+ 16 3 4.557e+07 23.810 176.930 2.250 7.525 1.120000e+12 4.704e+10
+ 16 4 3.418e+07 23.240 176.650 1.950 7.685 1.120000e+12 4.819e+10
+ 16 5 2.734e+07 23.090 175.940 1.940 7.704 1.120000e+12 4.851e+10
+ 16 6 2.279e+07 22.900 176.120 1.680 7.764 1.120000e+12 4.891e+10
+ 16 7 1.953e+07 22.890 176.290 1.440 7.765 1.120000e+12 4.893e+10
+ 16 8 1.709e+07 22.820 176.040 1.610 7.785 1.120000e+12 4.908e+10
+ 16 9 1.519e+07 22.890 175.990 1.470 7.753 1.120000e+12 4.893e+10
+ 16 10 1.367e+07 22.700 175.890 1.470 7.813 1.120000e+12 4.934e+10
+ 16 11 1.243e+07 22.770 175.960 1.520 7.794 1.120000e+12 4.919e+10
+ 16 12 1.139e+07 22.730 176.000 1.430 7.806 1.120000e+12 4.927e+10
+ 16 13 1.052e+07 22.670 175.990 1.540 7.831 1.120000e+12 4.940e+10
+ 16 14 9.766e+06 22.720 176.130 1.440 7.816 1.120000e+12 4.930e+10
+ 16 15 9.115e+06 22.740 176.320 1.360 7.814 1.120000e+12 4.925e+10
+ 16 16 8.545e+06 22.680 176.170 1.320 7.826 1.120000e+12 4.938e+10
diff --git a/gnuradio-core/src/examples/mp-sched/perf-data/dual-quad-core-3.00-penryn.dat b/gnuradio-core/src/examples/mp-sched/perf-data/dual-quad-core-3.00-penryn.dat
new file mode 100644
index 000000000..57d49ed33
--- /dev/null
+++ b/gnuradio-core/src/examples/mp-sched/perf-data/dual-quad-core-3.00-penryn.dat
@@ -0,0 +1,257 @@
+#D Dual quad-core Xeon 3.0 GHz (Penryn E5472, 1600 MHz FSB, 5400 chipset)
+ 1 1 5.000e+07 2.720 3.020 0.110 1.151 2.560000e+10 9.412e+09
+ 1 2 5.000e+07 2.870 5.630 0.170 2.021 5.120000e+10 1.784e+10
+ 1 3 5.000e+07 2.880 8.380 0.160 2.965 7.680000e+10 2.667e+10
+ 1 4 5.000e+07 2.990 11.080 0.200 3.773 1.024000e+11 3.425e+10
+ 1 5 5.000e+07 2.950 13.950 0.190 4.793 1.280000e+11 4.339e+10
+ 1 6 5.000e+07 3.020 16.620 0.240 5.583 1.536000e+11 5.086e+10
+ 1 7 5.000e+07 2.930 19.250 0.200 6.638 1.792000e+11 6.116e+10
+ 1 8 5.000e+07 3.170 22.240 0.290 7.107 2.048000e+11 6.461e+10
+ 1 9 5.000e+07 5.450 24.410 0.310 4.536 2.304000e+11 4.228e+10
+ 1 10 5.000e+07 5.610 27.400 0.370 4.950 2.560000e+11 4.563e+10
+ 1 11 5.000e+07 5.680 29.960 0.370 5.340 2.816000e+11 4.958e+10
+ 1 12 5.000e+07 5.440 32.490 0.350 6.037 3.072000e+11 5.647e+10
+ 1 13 5.000e+07 5.630 35.270 0.400 6.336 3.328000e+11 5.911e+10
+ 1 14 5.000e+07 6.270 38.500 0.480 6.217 3.584000e+11 5.716e+10
+ 1 15 5.000e+07 6.080 40.880 0.490 6.804 3.840000e+11 6.316e+10
+ 1 16 5.000e+07 7.740 43.390 0.600 5.683 4.096000e+11 5.292e+10
+ 2 1 5.000e+07 2.820 5.700 0.210 2.096 5.120000e+10 1.816e+10
+ 2 2 5.000e+07 2.820 11.130 0.230 4.028 1.024000e+11 3.631e+10
+ 2 3 5.000e+07 2.960 16.570 0.320 5.706 1.536000e+11 5.189e+10
+ 2 4 5.000e+07 3.110 21.920 0.390 7.174 2.048000e+11 6.585e+10
+ 2 5 5.000e+07 5.650 27.550 0.520 4.968 2.560000e+11 4.531e+10
+ 2 6 5.000e+07 5.880 32.890 0.440 5.668 3.072000e+11 5.224e+10
+ 2 7 5.000e+07 6.750 38.210 0.560 5.744 3.584000e+11 5.310e+10
+ 2 8 5.000e+07 6.360 43.480 0.580 6.928 4.096000e+11 6.440e+10
+ 2 9 5.000e+07 8.270 48.750 0.730 5.983 4.608000e+11 5.572e+10
+ 2 10 5.000e+07 8.210 54.400 0.610 6.700 5.120000e+11 6.236e+10
+ 2 11 5.000e+07 8.750 59.760 0.640 6.903 5.632000e+11 6.437e+10
+ 2 12 5.000e+07 9.300 65.050 0.700 7.070 6.144000e+11 6.606e+10
+ 2 13 5.000e+07 9.990 70.750 0.750 7.157 6.656000e+11 6.663e+10
+ 2 14 5.000e+07 10.610 75.950 0.810 7.235 7.168000e+11 6.756e+10
+ 2 15 5.000e+07 11.900 80.400 0.870 6.829 7.680000e+11 6.454e+10
+ 2 16 5.000e+07 11.820 86.790 0.900 7.419 8.192000e+11 6.931e+10
+ 3 1 5.000e+07 2.970 8.300 0.380 2.923 7.680000e+10 2.586e+10
+ 3 2 5.000e+07 2.980 16.660 0.390 5.721 1.536000e+11 5.154e+10
+ 3 3 5.000e+07 5.480 24.690 0.420 4.582 2.304000e+11 4.204e+10
+ 3 4 5.000e+07 5.620 32.820 0.560 5.940 3.072000e+11 5.466e+10
+ 3 5 5.000e+07 6.940 40.800 0.620 5.968 3.840000e+11 5.533e+10
+ 3 6 5.000e+07 7.860 49.010 0.710 6.326 4.608000e+11 5.863e+10
+ 3 7 5.000e+07 8.470 57.130 0.750 6.834 5.376000e+11 6.347e+10
+ 3 8 5.000e+07 9.420 65.310 0.820 7.020 6.144000e+11 6.522e+10
+ 3 9 5.000e+07 10.350 73.640 0.940 7.206 6.912000e+11 6.678e+10
+ 3 10 5.000e+07 11.460 82.230 1.030 7.265 7.680000e+11 6.702e+10
+ 3 11 5.000e+07 12.200 89.590 1.050 7.430 8.448000e+11 6.925e+10
+ 3 12 5.000e+07 13.040 97.520 1.140 7.566 9.216000e+11 7.067e+10
+ 3 13 5.000e+07 14.000 105.560 1.150 7.622 9.984000e+11 7.131e+10
+ 3 14 5.000e+07 14.930 113.630 1.210 7.692 1.075200e+12 7.202e+10
+ 3 15 5.000e+07 15.920 121.610 1.350 7.724 1.152000e+12 7.236e+10
+ 3 16 5.000e+07 16.870 129.770 1.390 7.775 1.228800e+12 7.284e+10
+ 4 1 5.000e+07 2.900 11.100 0.340 3.945 1.024000e+11 3.531e+10
+ 4 2 5.000e+07 4.380 21.980 0.480 5.128 2.048000e+11 4.676e+10
+ 4 3 5.000e+07 5.720 32.800 0.610 5.841 3.072000e+11 5.371e+10
+ 4 4 5.000e+07 6.820 43.880 0.700 6.537 4.096000e+11 6.006e+10
+ 4 5 5.000e+07 8.150 54.420 0.760 6.771 5.120000e+11 6.282e+10
+ 4 6 5.000e+07 9.510 65.180 0.980 6.957 6.144000e+11 6.461e+10
+ 4 7 5.000e+07 10.650 76.080 1.020 7.239 7.168000e+11 6.731e+10
+ 4 8 5.000e+07 11.880 86.720 1.110 7.393 8.192000e+11 6.896e+10
+ 4 9 5.000e+07 13.150 97.920 1.250 7.541 9.216000e+11 7.008e+10
+ 4 10 5.000e+07 14.640 109.260 1.410 7.559 1.024000e+12 6.995e+10
+ 4 11 5.000e+07 15.710 119.170 1.440 7.677 1.126400e+12 7.170e+10
+ 4 12 5.000e+07 16.950 129.960 1.420 7.751 1.228800e+12 7.250e+10
+ 4 13 5.000e+07 18.260 140.520 1.620 7.784 1.331200e+12 7.290e+10
+ 4 14 5.000e+07 19.610 151.290 1.780 7.806 1.433600e+12 7.311e+10
+ 4 15 5.000e+07 21.060 162.760 1.890 7.818 1.536000e+12 7.293e+10
+ 4 16 5.000e+07 22.280 172.870 1.980 7.848 1.638400e+12 7.354e+10
+ 5 1 5.000e+07 3.040 13.810 0.390 4.671 1.280000e+11 4.211e+10
+ 5 2 5.000e+07 5.590 27.510 0.610 5.030 2.560000e+11 4.580e+10
+ 5 3 5.000e+07 6.550 40.970 0.780 6.374 3.840000e+11 5.863e+10
+ 5 4 5.000e+07 8.520 54.470 0.940 6.504 5.120000e+11 6.009e+10
+ 5 5 5.000e+07 9.920 67.950 1.060 6.957 6.400000e+11 6.452e+10
+ 5 6 5.000e+07 11.350 81.490 1.180 7.284 7.680000e+11 6.767e+10
+ 5 7 5.000e+07 12.910 94.960 1.300 7.456 8.960000e+11 6.940e+10
+ 5 8 5.000e+07 14.520 108.510 1.400 7.570 1.024000e+12 7.052e+10
+ 5 9 5.000e+07 16.070 122.120 1.620 7.700 1.152000e+12 7.169e+10
+ 5 10 5.000e+07 17.950 136.140 1.730 7.681 1.280000e+12 7.131e+10
+ 5 11 5.000e+07 19.470 148.330 1.830 7.712 1.408000e+12 7.232e+10
+ 5 12 5.000e+07 20.980 162.100 2.030 7.823 1.536000e+12 7.321e+10
+ 5 13 5.000e+07 22.670 175.470 2.160 7.835 1.664000e+12 7.340e+10
+ 5 14 5.000e+07 24.440 189.630 2.170 7.848 1.792000e+12 7.332e+10
+ 5 15 5.000e+07 26.100 203.010 2.450 7.872 1.920000e+12 7.356e+10
+ 5 16 5.000e+07 27.720 216.000 2.550 7.884 2.048000e+12 7.388e+10
+ 6 1 5.000e+07 2.950 16.560 0.540 5.797 1.536000e+11 5.207e+10
+ 6 2 5.000e+07 5.540 32.900 0.720 6.069 3.072000e+11 5.545e+10
+ 6 3 5.000e+07 8.490 48.860 1.000 5.873 4.608000e+11 5.428e+10
+ 6 4 5.000e+07 10.000 64.670 1.100 6.577 6.144000e+11 6.144e+10
+ 6 5 5.000e+07 11.440 81.430 1.310 7.233 7.680000e+11 6.713e+10
+ 6 6 5.000e+07 13.250 97.690 1.360 7.475 9.216000e+11 6.955e+10
+ 6 7 5.000e+07 15.270 113.730 1.610 7.553 1.075200e+12 7.041e+10
+ 6 8 5.000e+07 17.180 129.780 1.820 7.660 1.228800e+12 7.153e+10
+ 6 9 5.000e+07 19.200 146.020 1.870 7.703 1.382400e+12 7.200e+10
+ 6 10 5.000e+07 21.220 162.290 2.100 7.747 1.536000e+12 7.238e+10
+ 6 11 5.000e+07 23.070 178.420 2.160 7.827 1.689600e+12 7.324e+10
+ 6 12 5.000e+07 25.120 194.590 2.450 7.844 1.843200e+12 7.338e+10
+ 6 13 5.000e+07 27.110 210.640 2.660 7.868 1.996800e+12 7.366e+10
+ 6 14 5.000e+07 29.110 226.820 2.750 7.886 2.150400e+12 7.387e+10
+ 6 15 5.000e+07 31.130 242.800 2.940 7.894 2.304000e+12 7.401e+10
+ 6 16 5.000e+07 33.100 258.790 3.210 7.915 2.457600e+12 7.425e+10
+ 7 1 5.000e+07 2.940 19.140 0.590 6.711 1.792000e+11 6.095e+10
+ 7 2 5.000e+07 5.920 37.910 1.030 6.578 3.584000e+11 6.054e+10
+ 7 3 5.000e+07 8.570 57.010 1.150 6.786 5.376000e+11 6.273e+10
+ 7 4 5.000e+07 10.840 76.060 1.320 7.138 7.168000e+11 6.613e+10
+ 7 5 5.000e+07 13.070 94.920 1.540 7.380 8.960000e+11 6.855e+10
+ 7 6 5.000e+07 15.270 113.790 1.730 7.565 1.075200e+12 7.041e+10
+ 7 7 5.000e+07 17.700 132.560 1.960 7.600 1.254400e+12 7.087e+10
+ 7 8 5.000e+07 19.930 151.500 2.130 7.708 1.433600e+12 7.193e+10
+ 7 9 5.000e+07 22.250 170.570 2.340 7.771 1.612800e+12 7.249e+10
+ 7 10 5.000e+07 24.600 189.280 2.450 7.794 1.792000e+12 7.285e+10
+ 7 11 5.000e+07 26.950 208.030 2.700 7.819 1.971200e+12 7.314e+10
+ 7 12 5.000e+07 29.280 227.070 2.850 7.852 2.150400e+12 7.344e+10
+ 7 13 5.000e+07 31.570 245.750 3.040 7.881 2.329600e+12 7.379e+10
+ 7 14 5.000e+07 33.930 264.960 3.160 7.902 2.508800e+12 7.394e+10
+ 7 15 5.000e+07 36.310 283.960 3.440 7.915 2.688000e+12 7.403e+10
+ 7 16 5.000e+07 38.560 302.120 3.630 7.929 2.867200e+12 7.436e+10
+ 8 1 5.000e+07 3.200 21.880 0.860 7.106 2.048000e+11 6.400e+10
+ 8 2 5.000e+07 5.890 43.450 0.930 7.535 4.096000e+11 6.954e+10
+ 8 3 5.000e+07 9.520 65.180 1.250 6.978 6.144000e+11 6.454e+10
+ 8 4 5.000e+07 12.200 86.780 1.480 7.234 8.192000e+11 6.715e+10
+ 8 5 5.000e+07 14.760 108.420 1.670 7.459 1.024000e+12 6.938e+10
+ 8 6 5.000e+07 17.300 129.850 1.960 7.619 1.228800e+12 7.103e+10
+ 8 7 5.000e+07 20.020 151.430 2.190 7.673 1.433600e+12 7.161e+10
+ 8 8 5.000e+07 22.750 173.550 2.420 7.735 1.638400e+12 7.202e+10
+ 8 9 5.000e+07 25.410 194.560 2.760 7.765 1.843200e+12 7.254e+10
+ 8 10 5.000e+07 28.410 217.250 2.920 7.750 2.048000e+12 7.209e+10
+ 8 11 5.000e+07 30.720 237.990 3.210 7.852 2.252800e+12 7.333e+10
+ 8 12 5.000e+07 33.310 259.340 3.280 7.884 2.457600e+12 7.378e+10
+ 8 13 5.000e+07 36.000 280.760 3.670 7.901 2.662400e+12 7.396e+10
+ 8 14 5.000e+07 38.800 302.570 3.740 7.895 2.867200e+12 7.390e+10
+ 8 15 5.000e+07 41.530 324.520 4.060 7.912 3.072000e+12 7.397e+10
+ 8 16 5.000e+07 44.060 345.420 4.250 7.936 3.276800e+12 7.437e+10
+ 9 1 5.000e+07 5.460 24.660 1.000 4.700 2.304000e+11 4.220e+10
+ 9 2 5.000e+07 8.460 49.010 1.200 5.935 4.608000e+11 5.447e+10
+ 9 3 5.000e+07 10.810 71.410 1.400 6.735 6.912000e+11 6.394e+10
+ 9 4 5.000e+07 13.470 97.570 1.710 7.370 9.216000e+11 6.842e+10
+ 9 5 5.000e+07 16.490 121.780 2.130 7.514 1.152000e+12 6.986e+10
+ 9 6 5.000e+07 19.540 146.070 2.280 7.592 1.382400e+12 7.075e+10
+ 9 7 5.000e+07 22.660 170.830 2.570 7.652 1.612800e+12 7.117e+10
+ 9 8 5.000e+07 25.520 194.720 2.760 7.738 1.843200e+12 7.223e+10
+ 9 9 5.000e+07 28.400 219.020 3.060 7.820 2.073600e+12 7.301e+10
+ 9 10 5.000e+07 31.490 243.030 3.320 7.823 2.304000e+12 7.317e+10
+ 9 11 5.000e+07 34.530 267.230 3.420 7.838 2.534400e+12 7.340e+10
+ 9 12 5.000e+07 37.520 291.720 3.860 7.878 2.764800e+12 7.369e+10
+ 9 13 5.000e+07 40.550 315.780 4.170 7.890 2.995200e+12 7.386e+10
+ 9 14 5.000e+07 43.470 339.930 4.290 7.919 3.225600e+12 7.420e+10
+ 9 15 5.000e+07 46.820 364.970 4.640 7.894 3.456000e+12 7.381e+10
+ 9 16 5.000e+07 49.660 388.630 4.890 7.924 3.686400e+12 7.423e+10
+ 10 1 5.000e+07 5.500 27.290 0.980 5.140 2.560000e+11 4.655e+10
+ 10 2 5.000e+07 8.480 54.830 1.420 6.633 5.120000e+11 6.038e+10
+ 10 3 5.000e+07 11.540 81.580 1.630 7.211 7.680000e+11 6.655e+10
+ 10 4 5.000e+07 14.950 108.480 1.860 7.381 1.024000e+12 6.849e+10
+ 10 5 5.000e+07 18.330 135.300 2.280 7.506 1.280000e+12 6.983e+10
+ 10 6 5.000e+07 21.680 162.380 2.540 7.607 1.536000e+12 7.085e+10
+ 10 7 5.000e+07 24.950 189.360 2.730 7.699 1.792000e+12 7.182e+10
+ 10 8 5.000e+07 28.280 216.090 3.110 7.751 2.048000e+12 7.242e+10
+ 10 9 5.000e+07 31.730 243.290 3.450 7.776 2.304000e+12 7.261e+10
+ 10 10 5.000e+07 35.040 270.380 3.680 7.821 2.560000e+12 7.306e+10
+ 10 11 5.000e+07 38.340 297.080 4.050 7.854 2.816000e+12 7.345e+10
+ 10 12 5.000e+07 41.770 323.840 4.330 7.857 3.072000e+12 7.355e+10
+ 10 13 5.000e+07 45.120 351.380 4.710 7.892 3.328000e+12 7.376e+10
+ 10 14 5.000e+07 48.360 377.870 4.880 7.915 3.584000e+12 7.411e+10
+ 10 15 5.000e+07 51.760 404.740 5.110 7.918 3.840000e+12 7.419e+10
+ 10 16 5.000e+07 55.130 431.760 5.430 7.930 4.096000e+12 7.430e+10
+ 11 1 5.000e+07 5.570 30.080 1.080 5.594 2.816000e+11 5.056e+10
+ 11 2 5.000e+07 9.000 60.230 1.470 6.856 5.632000e+11 6.258e+10
+ 11 3 5.000e+07 12.630 89.890 1.770 7.257 8.448000e+11 6.689e+10
+ 11 4 5.000e+07 16.290 119.110 2.140 7.443 1.126400e+12 6.915e+10
+ 11 5 5.000e+07 19.940 148.730 2.440 7.581 1.408000e+12 7.061e+10
+ 11 6 5.000e+07 23.800 178.620 2.790 7.622 1.689600e+12 7.099e+10
+ 11 7 5.000e+07 27.480 208.510 3.160 7.703 1.971200e+12 7.173e+10
+ 11 8 5.000e+07 31.140 237.820 3.490 7.749 2.252800e+12 7.234e+10
+ 11 9 5.000e+07 34.770 267.390 3.800 7.800 2.534400e+12 7.289e+10
+ 11 10 5.000e+07 38.510 297.250 4.240 7.829 2.816000e+12 7.312e+10
+ 11 11 5.000e+07 42.080 326.570 4.610 7.870 3.097600e+12 7.361e+10
+ 11 12 5.000e+07 45.860 356.540 4.590 7.875 3.379200e+12 7.369e+10
+ 11 13 5.000e+07 49.570 386.250 5.150 7.896 3.660800e+12 7.385e+10
+ 11 14 5.000e+07 53.220 415.630 5.360 7.910 3.942400e+12 7.408e+10
+ 11 15 5.000e+07 57.000 445.200 5.870 7.914 4.224000e+12 7.411e+10
+ 11 16 5.000e+07 60.800 474.810 6.250 7.912 4.505600e+12 7.411e+10
+ 12 1 5.000e+07 5.600 32.770 1.240 6.073 3.072000e+11 5.486e+10
+ 12 2 5.000e+07 10.220 65.660 1.600 6.581 6.144000e+11 6.012e+10
+ 12 3 5.000e+07 13.680 97.900 2.000 7.303 9.216000e+11 6.737e+10
+ 12 4 5.000e+07 17.790 129.710 2.330 7.422 1.228800e+12 6.907e+10
+ 12 5 5.000e+07 21.770 162.420 2.700 7.585 1.536000e+12 7.056e+10
+ 12 6 5.000e+07 25.770 194.770 3.090 7.678 1.843200e+12 7.153e+10
+ 12 7 5.000e+07 29.940 227.290 3.390 7.705 2.150400e+12 7.182e+10
+ 12 8 5.000e+07 34.030 259.370 3.860 7.735 2.457600e+12 7.222e+10
+ 12 9 5.000e+07 38.070 291.890 4.310 7.780 2.764800e+12 7.262e+10
+ 12 10 5.000e+07 42.080 324.370 4.660 7.819 3.072000e+12 7.300e+10
+ 12 11 5.000e+07 45.950 356.370 5.000 7.864 3.379200e+12 7.354e+10
+ 12 12 5.000e+07 49.960 388.790 5.250 7.887 3.686400e+12 7.379e+10
+ 12 13 5.000e+07 54.010 422.050 5.420 7.915 3.993600e+12 7.394e+10
+ 12 14 5.000e+07 58.010 453.330 6.120 7.920 4.300800e+12 7.414e+10
+ 12 15 5.000e+07 62.080 485.830 6.310 7.928 4.608000e+12 7.423e+10
+ 12 16 5.000e+07 66.200 518.060 6.780 7.928 4.915200e+12 7.425e+10
+ 13 1 5.000e+07 5.630 35.420 1.300 6.522 3.328000e+11 5.911e+10
+ 13 2 5.000e+07 10.730 71.050 1.830 6.792 6.656000e+11 6.203e+10
+ 13 3 5.000e+07 14.690 105.710 2.160 7.343 9.984000e+11 6.796e+10
+ 13 4 5.000e+07 19.120 140.630 2.510 7.486 1.331200e+12 6.962e+10
+ 13 5 5.000e+07 23.600 175.730 3.000 7.573 1.664000e+12 7.051e+10
+ 13 6 5.000e+07 27.910 211.000 3.350 7.680 1.996800e+12 7.154e+10
+ 13 7 5.000e+07 32.370 246.320 3.860 7.729 2.329600e+12 7.197e+10
+ 13 8 5.000e+07 36.790 281.150 4.260 7.758 2.662400e+12 7.237e+10
+ 13 9 5.000e+07 41.080 316.080 4.520 7.804 2.995200e+12 7.291e+10
+ 13 10 5.000e+07 45.600 352.020 5.090 7.831 3.328000e+12 7.298e+10
+ 13 11 5.000e+07 49.760 386.130 5.470 7.870 3.660800e+12 7.357e+10
+ 13 12 5.000e+07 54.080 421.160 5.780 7.895 3.993600e+12 7.385e+10
+ 13 13 5.000e+07 58.520 455.980 6.170 7.897 4.326400e+12 7.393e+10
+ 13 14 5.000e+07 63.000 491.340 6.710 7.906 4.659200e+12 7.396e+10
+ 13 15 5.000e+07 67.250 525.920 6.920 7.923 4.992000e+12 7.423e+10
+ 13 16 5.000e+07 72.090 560.640 7.160 7.876 5.324800e+12 7.386e+10
+ 14 1 5.000e+07 5.670 38.290 1.330 6.988 3.584000e+11 6.321e+10
+ 14 2 5.000e+07 10.850 75.880 1.940 7.172 7.168000e+11 6.606e+10
+ 14 3 5.000e+07 15.840 114.160 2.400 7.359 1.075200e+12 6.788e+10
+ 14 4 5.000e+07 20.610 151.540 2.710 7.484 1.433600e+12 6.956e+10
+ 14 5 5.000e+07 25.330 189.160 3.320 7.599 1.792000e+12 7.075e+10
+ 14 6 5.000e+07 30.160 227.510 3.670 7.665 2.150400e+12 7.130e+10
+ 14 7 5.000e+07 34.730 265.020 3.960 7.745 2.508800e+12 7.224e+10
+ 14 8 5.000e+07 39.530 302.550 4.640 7.771 2.867200e+12 7.253e+10
+ 14 9 5.000e+07 44.220 340.330 5.180 7.813 3.225600e+12 7.294e+10
+ 14 10 5.000e+07 48.800 378.180 5.430 7.861 3.584000e+12 7.344e+10
+ 14 11 5.000e+07 53.550 415.790 5.800 7.873 3.942400e+12 7.362e+10
+ 14 12 5.000e+07 58.250 453.340 6.430 7.893 4.300800e+12 7.383e+10
+ 14 13 5.000e+07 63.150 492.200 6.960 7.904 4.659200e+12 7.378e+10
+ 14 14 5.000e+07 67.850 528.470 6.970 7.892 5.017600e+12 7.395e+10
+ 14 15 5.000e+07 72.510 566.950 7.720 7.925 5.376000e+12 7.414e+10
+ 14 16 5.000e+07 77.230 604.250 8.170 7.930 5.734400e+12 7.425e+10
+ 15 1 5.000e+07 5.800 41.070 1.460 7.333 3.840000e+11 6.621e+10
+ 15 2 5.000e+07 11.900 80.380 2.190 6.939 7.680000e+11 6.454e+10
+ 15 3 5.000e+07 16.990 121.790 2.610 7.322 1.152000e+12 6.780e+10
+ 15 4 5.000e+07 22.040 162.330 3.030 7.503 1.536000e+12 6.969e+10
+ 15 5 5.000e+07 27.120 202.750 3.460 7.604 1.920000e+12 7.080e+10
+ 15 6 5.000e+07 32.290 243.420 3.870 7.658 2.304000e+12 7.135e+10
+ 15 7 5.000e+07 37.450 284.300 4.410 7.709 2.688000e+12 7.178e+10
+ 15 8 5.000e+07 42.560 323.740 4.890 7.722 3.072000e+12 7.218e+10
+ 15 9 5.000e+07 47.440 364.880 5.330 7.804 3.456000e+12 7.285e+10
+ 15 10 5.000e+07 52.440 405.400 5.750 7.840 3.840000e+12 7.323e+10
+ 15 11 5.000e+07 57.270 445.500 6.070 7.885 4.224000e+12 7.376e+10
+ 15 12 5.000e+07 62.450 485.920 6.770 7.889 4.608000e+12 7.379e+10
+ 15 13 5.000e+07 67.680 527.540 7.440 7.905 4.992000e+12 7.376e+10
+ 15 14 5.000e+07 72.740 566.990 7.790 7.902 5.376000e+12 7.391e+10
+ 15 15 5.000e+07 77.760 607.620 8.060 7.918 5.760000e+12 7.407e+10
+ 15 16 5.000e+07 82.750 647.630 8.640 7.931 6.144000e+12 7.425e+10
+ 16 1 5.000e+07 6.310 43.540 1.790 7.184 4.096000e+11 6.491e+10
+ 16 2 5.000e+07 12.340 87.310 2.190 7.253 8.192000e+11 6.639e+10
+ 16 3 5.000e+07 17.930 130.440 2.830 7.433 1.228800e+12 6.853e+10
+ 16 4 5.000e+07 23.530 173.540 3.140 7.509 1.638400e+12 6.963e+10
+ 16 5 5.000e+07 28.910 216.290 3.710 7.610 2.048000e+12 7.084e+10
+ 16 6 5.000e+07 34.310 259.400 4.260 7.685 2.457600e+12 7.163e+10
+ 16 7 5.000e+07 39.790 302.740 4.620 7.725 2.867200e+12 7.206e+10
+ 16 8 5.000e+07 44.970 346.250 5.340 7.818 3.276800e+12 7.287e+10
+ 16 9 5.000e+07 50.470 388.870 5.910 7.822 3.686400e+12 7.304e+10
+ 16 10 5.000e+07 55.890 432.480 6.140 7.848 4.096000e+12 7.329e+10
+ 16 11 5.000e+07 61.250 475.380 6.770 7.872 4.505600e+12 7.356e+10
+ 16 12 5.000e+07 66.670 518.940 7.160 7.891 4.915200e+12 7.372e+10
+ 16 13 5.000e+07 72.160 562.230 7.890 7.901 5.324800e+12 7.379e+10
+ 16 14 5.000e+07 77.600 604.950 8.230 7.902 5.734400e+12 7.390e+10
+ 16 15 5.000e+07 82.970 648.420 8.690 7.920 6.144000e+12 7.405e+10
+ 16 16 5.000e+07 88.370 690.730 9.460 7.923 6.553600e+12 7.416e+10
diff --git a/gnuradio-core/src/examples/mp-sched/perf-data/js21-altivec.dat b/gnuradio-core/src/examples/mp-sched/perf-data/js21-altivec.dat
new file mode 100644
index 000000000..d0b8148f0
--- /dev/null
+++ b/gnuradio-core/src/examples/mp-sched/perf-data/js21-altivec.dat
@@ -0,0 +1,65 @@
+#D JS21 4-core PPC970M 2.5 GHz (using Altivec)
+ 1 1 9.766e+07 9.820 10.210 0.360 1.076 5.000000e+10 5.092e+09
+ 1 2 9.766e+07 10.620 19.890 0.640 1.933 1.000000e+11 9.416e+09
+ 1 3 9.766e+07 10.310 29.590 0.610 2.929 1.500000e+11 1.455e+10
+ 1 4 9.766e+07 10.440 39.290 0.680 3.829 2.000000e+11 1.916e+10
+ 1 5 7.812e+07 15.730 39.150 0.590 2.526 2.000000e+11 1.271e+10
+ 1 6 6.510e+07 13.100 39.080 0.590 3.028 2.000000e+11 1.527e+10
+ 1 7 5.580e+07 11.550 39.030 0.500 3.423 2.000000e+11 1.732e+10
+ 1 8 4.883e+07 10.410 39.010 0.510 3.796 2.000000e+11 1.921e+10
+ 2 1 9.766e+07 10.080 20.070 0.700 2.061 1.000000e+11 9.921e+09
+ 2 2 9.766e+07 11.360 39.650 0.960 3.575 2.000000e+11 1.761e+10
+ 2 3 6.510e+07 13.120 39.270 0.740 3.050 2.000000e+11 1.524e+10
+ 2 4 4.883e+07 10.410 39.110 0.650 3.819 2.000000e+11 1.921e+10
+ 2 5 3.906e+07 11.030 39.080 0.610 3.598 2.000000e+11 1.813e+10
+ 2 6 3.255e+07 10.640 39.020 0.560 3.720 2.000000e+11 1.880e+10
+ 2 7 2.790e+07 10.510 38.980 0.550 3.761 2.000000e+11 1.903e+10
+ 2 8 2.441e+07 10.440 38.970 0.570 3.787 2.000000e+11 1.916e+10
+ 3 1 9.766e+07 12.130 29.970 0.920 2.547 1.500000e+11 1.237e+10
+ 3 2 6.510e+07 13.100 39.300 0.920 3.070 2.000000e+11 1.527e+10
+ 3 3 4.340e+07 11.400 39.200 0.760 3.505 2.000000e+11 1.754e+10
+ 3 4 3.255e+07 10.730 39.100 0.690 3.708 2.000000e+11 1.864e+10
+ 3 5 2.604e+07 10.470 39.010 0.620 3.785 2.000000e+11 1.910e+10
+ 3 6 2.170e+07 10.380 39.010 0.620 3.818 2.000000e+11 1.927e+10
+ 3 7 1.860e+07 10.280 39.120 0.580 3.862 2.000000e+11 1.946e+10
+ 3 8 1.628e+07 10.230 39.000 0.600 3.871 2.000000e+11 1.955e+10
+ 4 1 9.766e+07 10.700 39.990 1.540 3.881 2.000000e+11 1.869e+10
+ 4 2 4.883e+07 10.530 39.260 0.940 3.818 2.000000e+11 1.899e+10
+ 4 3 3.255e+07 10.840 39.140 0.760 3.681 2.000000e+11 1.845e+10
+ 4 4 2.441e+07 10.530 39.040 0.680 3.772 2.000000e+11 1.899e+10
+ 4 5 1.953e+07 10.380 39.030 0.650 3.823 2.000000e+11 1.927e+10
+ 4 6 1.628e+07 10.310 39.020 0.650 3.848 2.000000e+11 1.940e+10
+ 4 7 1.395e+07 10.160 38.980 0.620 3.898 2.000000e+11 1.969e+10
+ 4 8 1.221e+07 10.150 38.990 0.580 3.899 2.000000e+11 1.970e+10
+ 5 1 7.812e+07 14.750 39.780 1.470 2.797 2.000000e+11 1.356e+10
+ 5 2 3.906e+07 11.350 39.240 0.950 3.541 2.000000e+11 1.762e+10
+ 5 3 2.604e+07 10.720 39.120 0.800 3.724 2.000000e+11 1.866e+10
+ 5 4 1.953e+07 10.440 39.060 0.730 3.811 2.000000e+11 1.916e+10
+ 5 5 1.562e+07 10.410 39.060 0.690 3.818 2.000000e+11 1.921e+10
+ 5 6 1.302e+07 10.260 38.970 0.650 3.862 2.000000e+11 1.949e+10
+ 5 7 1.116e+07 10.270 39.020 0.650 3.863 2.000000e+11 1.947e+10
+ 5 8 9.766e+06 10.130 39.010 0.660 3.916 2.000000e+11 1.974e+10
+ 6 1 6.510e+07 12.850 39.730 1.450 3.205 2.000000e+11 1.556e+10
+ 6 2 3.255e+07 10.700 39.300 0.990 3.765 2.000000e+11 1.869e+10
+ 6 3 2.170e+07 10.770 39.110 0.810 3.707 2.000000e+11 1.857e+10
+ 6 4 1.628e+07 10.570 39.090 0.750 3.769 2.000000e+11 1.892e+10
+ 6 5 1.302e+07 10.310 39.040 0.690 3.854 2.000000e+11 1.940e+10
+ 6 6 1.085e+07 10.260 39.030 0.700 3.872 2.000000e+11 1.949e+10
+ 6 7 9.301e+06 10.170 39.020 0.680 3.904 2.000000e+11 1.967e+10
+ 6 8 8.138e+06 10.150 39.020 0.670 3.910 2.000000e+11 1.970e+10
+ 7 1 5.580e+07 11.440 39.730 1.500 3.604 2.000000e+11 1.748e+10
+ 7 2 2.790e+07 10.950 39.260 0.990 3.676 2.000000e+11 1.826e+10
+ 7 3 1.860e+07 10.620 39.140 0.860 3.766 2.000000e+11 1.883e+10
+ 7 4 1.395e+07 10.420 39.070 0.750 3.821 2.000000e+11 1.919e+10
+ 7 5 1.116e+07 10.290 39.040 0.710 3.863 2.000000e+11 1.944e+10
+ 7 6 9.301e+06 10.200 39.040 0.720 3.898 2.000000e+11 1.961e+10
+ 7 7 7.972e+06 10.210 39.020 0.670 3.887 2.000000e+11 1.959e+10
+ 7 8 6.975e+06 10.160 39.020 0.650 3.905 2.000000e+11 1.969e+10
+ 8 1 4.883e+07 10.870 39.950 1.520 3.815 2.000000e+11 1.840e+10
+ 8 2 2.441e+07 10.690 39.270 1.000 3.767 2.000000e+11 1.871e+10
+ 8 3 1.628e+07 10.540 39.130 0.860 3.794 2.000000e+11 1.898e+10
+ 8 4 1.221e+07 10.410 39.110 0.790 3.833 2.000000e+11 1.921e+10
+ 8 5 9.766e+06 10.230 39.040 0.710 3.886 2.000000e+11 1.955e+10
+ 8 6 8.138e+06 10.260 39.050 0.700 3.874 2.000000e+11 1.949e+10
+ 8 7 6.975e+06 10.220 39.100 0.690 3.893 2.000000e+11 1.957e+10
+ 8 8 6.104e+06 10.170 39.020 0.650 3.901 2.000000e+11 1.967e+10
diff --git a/gnuradio-core/src/examples/mp-sched/perf-data/js21.dat b/gnuradio-core/src/examples/mp-sched/perf-data/js21.dat
new file mode 100644
index 000000000..a23bcebe7
--- /dev/null
+++ b/gnuradio-core/src/examples/mp-sched/perf-data/js21.dat
@@ -0,0 +1,65 @@
+#D JS21 4-core PPC970MP 2.5 GHz
+ 1 1 5.273e+07 10.050 10.180 0.290 1.042 2.700000e+10 2.687e+09
+ 1 2 5.273e+07 10.240 20.210 0.260 1.999 5.400000e+10 5.273e+09
+ 1 3 5.273e+07 10.300 30.090 0.340 2.954 8.100000e+10 7.864e+09
+ 1 4 5.273e+07 10.490 40.120 0.490 3.871 1.080000e+11 1.030e+10
+ 1 5 4.219e+07 16.010 39.900 0.380 2.516 1.080000e+11 6.746e+09
+ 1 6 3.516e+07 13.360 39.920 0.370 3.016 1.080000e+11 8.084e+09
+ 1 7 3.013e+07 11.510 39.900 0.330 3.495 1.080000e+11 9.383e+09
+ 1 8 2.637e+07 10.420 39.880 0.320 3.858 1.080000e+11 1.036e+10
+ 2 1 5.273e+07 10.370 20.340 0.470 2.007 5.400000e+10 5.207e+09
+ 2 2 5.273e+07 10.320 40.080 0.550 3.937 1.080000e+11 1.047e+10
+ 2 3 3.516e+07 13.340 39.990 0.470 3.033 1.080000e+11 8.096e+09
+ 2 4 2.637e+07 10.480 39.970 0.400 3.852 1.080000e+11 1.031e+10
+ 2 5 2.109e+07 10.910 39.920 0.390 3.695 1.080000e+11 9.899e+09
+ 2 6 1.758e+07 10.610 39.860 0.360 3.791 1.080000e+11 1.018e+10
+ 2 7 1.507e+07 10.520 39.890 0.360 3.826 1.080000e+11 1.027e+10
+ 2 8 1.318e+07 10.470 39.980 0.350 3.852 1.080000e+11 1.032e+10
+ 3 1 5.273e+07 10.230 30.320 0.600 3.022 8.100000e+10 7.918e+09
+ 3 2 3.516e+07 13.250 40.050 0.560 3.065 1.080000e+11 8.151e+09
+ 3 3 2.344e+07 11.160 40.010 0.470 3.627 1.080000e+11 9.677e+09
+ 3 4 1.758e+07 10.710 39.950 0.420 3.769 1.080000e+11 1.008e+10
+ 3 5 1.406e+07 10.520 39.920 0.400 3.833 1.080000e+11 1.027e+10
+ 3 6 1.172e+07 10.420 39.880 0.380 3.864 1.080000e+11 1.036e+10
+ 3 7 1.004e+07 10.340 39.880 0.370 3.893 1.080000e+11 1.044e+10
+ 3 8 8.789e+06 10.380 39.960 0.380 3.886 1.080000e+11 1.040e+10
+ 4 1 5.273e+07 10.570 40.390 0.890 3.905 1.080000e+11 1.022e+10
+ 4 2 2.637e+07 10.690 40.020 0.560 3.796 1.080000e+11 1.010e+10
+ 4 3 1.758e+07 10.790 39.980 0.480 3.750 1.080000e+11 1.001e+10
+ 4 4 1.318e+07 10.570 39.950 0.430 3.820 1.080000e+11 1.022e+10
+ 4 5 1.055e+07 10.440 39.950 0.420 3.867 1.080000e+11 1.034e+10
+ 4 6 8.789e+06 10.340 39.900 0.420 3.899 1.080000e+11 1.044e+10
+ 4 7 7.533e+06 10.290 39.870 0.410 3.914 1.080000e+11 1.050e+10
+ 4 8 6.592e+06 10.270 39.950 0.390 3.928 1.080000e+11 1.052e+10
+ 5 1 4.219e+07 15.110 40.290 0.830 2.721 1.080000e+11 7.148e+09
+ 5 2 2.109e+07 11.240 40.000 0.580 3.610 1.080000e+11 9.609e+09
+ 5 3 1.406e+07 10.710 39.970 0.490 3.778 1.080000e+11 1.008e+10
+ 5 4 1.055e+07 10.490 39.980 0.460 3.855 1.080000e+11 1.030e+10
+ 5 5 8.438e+06 10.430 39.940 0.440 3.872 1.080000e+11 1.035e+10
+ 5 6 7.031e+06 10.280 39.890 0.420 3.921 1.080000e+11 1.051e+10
+ 5 7 6.027e+06 10.290 39.870 0.400 3.914 1.080000e+11 1.050e+10
+ 5 8 5.273e+06 10.290 39.940 0.400 3.920 1.080000e+11 1.050e+10
+ 6 1 3.516e+07 12.880 40.250 0.850 3.191 1.080000e+11 8.385e+09
+ 6 2 1.758e+07 10.730 39.980 0.580 3.780 1.080000e+11 1.007e+10
+ 6 3 1.172e+07 10.740 39.980 0.490 3.768 1.080000e+11 1.006e+10
+ 6 4 8.789e+06 10.510 39.940 0.460 3.844 1.080000e+11 1.028e+10
+ 6 5 7.031e+06 10.430 39.920 0.450 3.871 1.080000e+11 1.035e+10
+ 6 6 5.859e+06 10.300 39.910 0.430 3.917 1.080000e+11 1.049e+10
+ 6 7 5.022e+06 10.290 39.870 0.420 3.915 1.080000e+11 1.050e+10
+ 6 8 4.395e+06 10.300 39.950 0.420 3.919 1.080000e+11 1.049e+10
+ 7 1 3.013e+07 11.240 40.270 0.860 3.659 1.080000e+11 9.609e+09
+ 7 2 1.507e+07 11.040 40.000 0.590 3.677 1.080000e+11 9.783e+09
+ 7 3 1.004e+07 10.660 39.970 0.520 3.798 1.080000e+11 1.013e+10
+ 7 4 7.533e+06 10.430 39.930 0.470 3.873 1.080000e+11 1.035e+10
+ 7 5 6.027e+06 10.390 39.920 0.470 3.887 1.080000e+11 1.039e+10
+ 7 6 5.022e+06 10.320 39.910 0.430 3.909 1.080000e+11 1.047e+10
+ 7 7 4.305e+06 10.330 39.890 0.420 3.902 1.080000e+11 1.045e+10
+ 7 8 3.767e+06 10.300 39.930 0.420 3.917 1.080000e+11 1.049e+10
+ 8 1 2.637e+07 10.530 40.290 0.910 3.913 1.080000e+11 1.026e+10
+ 8 2 1.318e+07 10.850 40.040 0.610 3.747 1.080000e+11 9.954e+09
+ 8 3 8.789e+06 10.500 39.960 0.540 3.857 1.080000e+11 1.029e+10
+ 8 4 6.592e+06 10.490 39.960 0.500 3.857 1.080000e+11 1.030e+10
+ 8 5 5.273e+06 10.330 39.930 0.480 3.912 1.080000e+11 1.045e+10
+ 8 6 4.395e+06 10.340 39.900 0.450 3.902 1.080000e+11 1.044e+10
+ 8 7 3.767e+06 10.260 39.900 0.430 3.931 1.080000e+11 1.053e+10
+ 8 8 3.296e+06 10.250 39.960 0.430 3.940 1.080000e+11 1.054e+10
diff --git a/gnuradio-core/src/examples/mp-sched/perf-data/ps3-altivec.dat b/gnuradio-core/src/examples/mp-sched/perf-data/ps3-altivec.dat
new file mode 100644
index 000000000..dd01b31bd
--- /dev/null
+++ b/gnuradio-core/src/examples/mp-sched/perf-data/ps3-altivec.dat
@@ -0,0 +1,65 @@
+#D Playstation 3 (using Altivec)
+ 1 1 3.906e+07 10.500 10.580 0.440 1.050 2.000000e+10 1.905e+09
+ 1 2 1.953e+07 7.010 13.200 0.400 1.940 2.000000e+10 2.853e+09
+ 1 3 1.302e+07 7.540 13.140 0.380 1.793 2.000000e+10 2.653e+09
+ 1 4 9.766e+06 7.200 13.620 0.370 1.943 2.000000e+10 2.778e+09
+ 1 5 7.812e+06 7.170 13.670 0.340 1.954 2.000000e+10 2.789e+09
+ 1 6 6.510e+06 7.010 13.590 0.320 1.984 2.000000e+10 2.853e+09
+ 1 7 5.580e+06 6.990 13.530 0.330 1.983 2.000000e+10 2.861e+09
+ 1 8 4.883e+06 6.980 13.490 0.320 1.979 2.000000e+10 2.865e+09
+ 2 1 1.953e+07 8.110 14.730 0.530 1.882 2.000000e+10 2.466e+09
+ 2 2 9.766e+06 7.090 13.570 0.420 1.973 2.000000e+10 2.821e+09
+ 2 3 6.510e+06 7.040 13.590 0.410 1.989 2.000000e+10 2.841e+09
+ 2 4 4.883e+06 6.990 13.490 0.370 1.983 2.000000e+10 2.861e+09
+ 2 5 3.906e+06 6.970 13.480 0.360 1.986 2.000000e+10 2.869e+09
+ 2 6 3.255e+06 6.990 13.530 0.370 1.989 2.000000e+10 2.861e+09
+ 2 7 2.790e+06 6.890 13.390 0.350 1.994 2.000000e+10 2.903e+09
+ 2 8 2.441e+06 6.880 13.380 0.350 1.996 2.000000e+10 2.907e+09
+ 3 1 1.302e+07 8.220 13.720 0.510 1.731 2.000000e+10 2.433e+09
+ 3 2 6.510e+06 7.050 13.480 0.450 1.976 2.000000e+10 2.837e+09
+ 3 3 4.340e+06 6.990 13.460 0.400 1.983 2.000000e+10 2.861e+09
+ 3 4 3.255e+06 6.990 13.550 0.380 1.993 2.000000e+10 2.861e+09
+ 3 5 2.604e+06 6.920 13.430 0.360 1.993 1.999999e+10 2.890e+09
+ 3 6 2.170e+06 6.940 13.460 0.360 1.991 1.999999e+10 2.882e+09
+ 3 7 1.860e+06 6.920 13.440 0.360 1.994 2.000000e+10 2.890e+09
+ 3 8 1.628e+06 6.890 13.380 0.350 1.993 2.000000e+10 2.903e+09
+ 4 1 9.766e+06 7.620 14.550 0.590 1.987 2.000000e+10 2.625e+09
+ 4 2 4.883e+06 7.010 13.460 0.440 1.983 2.000000e+10 2.853e+09
+ 4 3 3.255e+06 7.040 13.580 0.410 1.987 2.000000e+10 2.841e+09
+ 4 4 2.441e+06 6.960 13.470 0.390 1.991 2.000000e+10 2.874e+09
+ 4 5 1.953e+06 6.920 13.410 0.370 1.991 2.000000e+10 2.890e+09
+ 4 6 1.628e+06 6.950 13.490 0.370 1.994 2.000000e+10 2.878e+09
+ 4 7 1.395e+06 6.890 13.350 0.370 1.991 2.000000e+10 2.903e+09
+ 4 8 1.221e+06 6.940 13.490 0.360 1.996 2.000000e+10 2.882e+09
+ 5 1 7.812e+06 7.680 14.000 0.560 1.896 2.000000e+10 2.604e+09
+ 5 2 3.906e+06 7.070 13.460 0.460 1.969 2.000000e+10 2.829e+09
+ 5 3 2.604e+06 6.990 13.430 0.420 1.981 1.999999e+10 2.861e+09
+ 5 4 1.953e+06 7.010 13.550 0.390 1.989 2.000000e+10 2.853e+09
+ 5 5 1.562e+06 6.920 13.430 0.380 1.996 2.000000e+10 2.890e+09
+ 5 6 1.302e+06 6.920 13.410 0.380 1.993 1.999999e+10 2.890e+09
+ 5 7 1.116e+06 6.920 13.420 0.370 1.993 1.999999e+10 2.890e+09
+ 5 8 9.766e+05 6.910 13.360 0.370 1.987 1.999999e+10 2.894e+09
+ 6 1 6.510e+06 7.350 13.970 0.630 1.986 2.000000e+10 2.721e+09
+ 6 2 3.255e+06 7.040 13.470 0.470 1.980 2.000000e+10 2.841e+09
+ 6 3 2.170e+06 7.050 13.600 0.420 1.989 1.999999e+10 2.837e+09
+ 6 4 1.628e+06 6.970 13.480 0.400 1.991 2.000000e+10 2.869e+09
+ 6 5 1.302e+06 6.990 13.540 0.390 1.993 1.999999e+10 2.861e+09
+ 6 6 1.085e+06 6.970 13.470 0.380 1.987 1.999999e+10 2.869e+09
+ 6 7 9.301e+05 6.890 13.350 0.380 1.993 1.999999e+10 2.903e+09
+ 6 8 8.138e+05 6.920 13.420 0.370 1.993 2.000000e+10 2.890e+09
+ 7 1 5.580e+06 7.530 14.030 0.580 1.940 2.000000e+10 2.656e+09
+ 7 2 2.790e+06 7.000 13.370 0.460 1.976 2.000000e+10 2.857e+09
+ 7 3 1.860e+06 7.000 13.520 0.420 1.991 2.000000e+10 2.857e+09
+ 7 4 1.395e+06 7.060 13.590 0.410 1.983 2.000000e+10 2.833e+09
+ 7 5 1.116e+06 6.950 13.460 0.390 1.993 1.999999e+10 2.878e+09
+ 7 6 9.301e+05 6.950 13.420 0.380 1.986 1.999999e+10 2.878e+09
+ 7 7 7.972e+05 6.880 13.300 0.380 1.988 1.999998e+10 2.907e+09
+ 7 8 6.975e+05 6.920 13.390 0.380 1.990 1.999998e+10 2.890e+09
+ 8 1 4.883e+06 7.440 14.150 0.620 1.985 2.000000e+10 2.688e+09
+ 8 2 2.441e+06 6.990 13.400 0.480 1.986 2.000000e+10 2.861e+09
+ 8 3 1.628e+06 6.990 13.460 0.430 1.987 2.000000e+10 2.861e+09
+ 8 4 1.221e+06 7.020 13.550 0.410 1.989 2.000000e+10 2.849e+09
+ 8 5 9.766e+05 6.920 13.370 0.390 1.988 1.999999e+10 2.890e+09
+ 8 6 8.138e+05 6.950 13.400 0.390 1.984 2.000000e+10 2.878e+09
+ 8 7 6.975e+05 6.930 13.360 0.390 1.984 1.999998e+10 2.886e+09
+ 8 8 6.104e+05 6.920 13.390 0.380 1.990 1.999998e+10 2.890e+09
diff --git a/gnuradio-core/src/examples/mp-sched/perf-data/ps3.dat b/gnuradio-core/src/examples/mp-sched/perf-data/ps3.dat
new file mode 100644
index 000000000..c9bac37cc
--- /dev/null
+++ b/gnuradio-core/src/examples/mp-sched/perf-data/ps3.dat
@@ -0,0 +1,65 @@
+#D Playstation 3
+ 1 1 2.344e+07 9.970 9.960 0.280 1.027 1.200000e+10 1.204e+09
+ 1 2 1.172e+07 12.590 24.430 0.400 1.972 1.200000e+10 9.531e+08
+ 1 3 7.812e+06 12.200 22.790 0.360 1.898 1.200000e+10 9.836e+08
+ 1 4 5.859e+06 12.450 24.440 0.360 1.992 1.200000e+10 9.639e+08
+ 1 5 4.688e+06 12.390 24.100 0.360 1.974 1.200000e+10 9.685e+08
+ 1 6 3.906e+06 12.360 24.200 0.370 1.988 1.200000e+10 9.709e+08
+ 1 7 3.348e+06 12.460 24.390 0.360 1.986 1.200000e+10 9.631e+08
+ 1 8 2.930e+06 12.440 24.400 0.360 1.990 1.200000e+10 9.646e+08
+ 2 1 1.172e+07 12.580 24.660 0.490 1.999 1.200000e+10 9.539e+08
+ 2 2 5.859e+06 12.480 24.290 0.420 1.980 1.200000e+10 9.615e+08
+ 2 3 3.906e+06 12.500 24.500 0.400 1.992 1.200000e+10 9.600e+08
+ 2 4 2.930e+06 12.440 24.400 0.390 1.993 1.200000e+10 9.646e+08
+ 2 5 2.344e+06 12.500 24.510 0.380 1.991 1.200000e+10 9.600e+08
+ 2 6 1.953e+06 12.450 24.480 0.380 1.997 1.200000e+10 9.639e+08
+ 2 7 1.674e+06 12.450 24.430 0.380 1.993 1.200000e+10 9.639e+08
+ 2 8 1.465e+06 12.430 24.450 0.380 1.998 1.199999e+10 9.654e+08
+ 3 1 7.812e+06 12.280 23.600 0.460 1.959 1.200000e+10 9.772e+08
+ 3 2 3.906e+06 12.690 24.760 0.430 1.985 1.200000e+10 9.456e+08
+ 3 3 2.604e+06 12.610 24.700 0.410 1.991 1.200000e+10 9.516e+08
+ 3 4 1.953e+06 12.440 24.410 0.400 1.994 1.200000e+10 9.646e+08
+ 3 5 1.562e+06 12.400 24.370 0.380 1.996 1.200000e+10 9.677e+08
+ 3 6 1.302e+06 12.440 24.450 0.380 1.996 1.200000e+10 9.646e+08
+ 3 7 1.116e+06 12.470 24.470 0.380 1.993 1.200000e+10 9.623e+08
+ 3 8 9.766e+05 12.440 24.440 0.380 1.995 1.199999e+10 9.646e+08
+ 4 1 5.859e+06 12.670 24.710 0.500 1.990 1.200000e+10 9.471e+08
+ 4 2 2.930e+06 12.600 24.600 0.440 1.987 1.200000e+10 9.524e+08
+ 4 3 1.953e+06 12.490 24.480 0.410 1.993 1.200000e+10 9.608e+08
+ 4 4 1.465e+06 12.400 24.340 0.400 1.995 1.199999e+10 9.677e+08
+ 4 5 1.172e+06 12.440 24.410 0.390 1.994 1.200000e+10 9.646e+08
+ 4 6 9.766e+05 12.440 24.440 0.390 1.996 1.199999e+10 9.646e+08
+ 4 7 8.371e+05 12.450 24.420 0.390 1.993 1.199999e+10 9.639e+08
+ 4 8 7.324e+05 12.370 24.310 0.380 1.996 1.199999e+10 9.701e+08
+ 5 1 4.688e+06 12.890 24.790 0.500 1.962 1.200000e+10 9.310e+08
+ 5 2 2.344e+06 12.620 24.680 0.450 1.991 1.200000e+10 9.509e+08
+ 5 3 1.562e+06 12.430 24.360 0.410 1.993 1.200000e+10 9.654e+08
+ 5 4 1.172e+06 12.420 24.390 0.410 1.997 1.200000e+10 9.662e+08
+ 5 5 9.375e+05 12.430 24.380 0.400 1.994 1.200000e+10 9.654e+08
+ 5 6 7.812e+05 12.400 24.340 0.400 1.995 1.200000e+10 9.677e+08
+ 5 7 6.696e+05 12.360 24.290 0.390 1.997 1.199998e+10 9.709e+08
+ 5 8 5.859e+05 12.420 24.370 0.390 1.994 1.199999e+10 9.662e+08
+ 6 1 3.906e+06 12.990 25.320 0.560 1.992 1.200000e+10 9.238e+08
+ 6 2 1.953e+06 12.610 24.550 0.440 1.982 1.200000e+10 9.516e+08
+ 6 3 1.302e+06 12.520 24.310 0.420 1.975 1.200000e+10 9.585e+08
+ 6 4 9.766e+05 12.460 24.310 0.420 1.985 1.199999e+10 9.631e+08
+ 6 5 7.812e+05 12.440 24.240 0.410 1.982 1.200000e+10 9.646e+08
+ 6 6 6.510e+05 12.430 24.170 0.410 1.977 1.199999e+10 9.654e+08
+ 6 7 5.580e+05 12.450 24.230 0.410 1.979 1.199998e+10 9.639e+08
+ 6 8 4.883e+05 12.490 24.190 0.420 1.970 1.199999e+10 9.608e+08
+ 7 1 3.348e+06 13.150 24.280 0.500 1.884 1.200000e+10 9.125e+08
+ 7 2 1.674e+06 12.480 24.170 0.430 1.971 1.200000e+10 9.615e+08
+ 7 3 1.116e+06 12.480 24.430 0.440 1.993 1.200000e+10 9.615e+08
+ 7 4 8.371e+05 12.380 24.270 0.420 1.994 1.199999e+10 9.693e+08
+ 7 5 6.696e+05 12.390 24.290 0.430 1.995 1.199998e+10 9.685e+08
+ 7 6 5.580e+05 12.430 24.300 0.430 1.990 1.199998e+10 9.654e+08
+ 7 7 4.783e+05 12.460 24.360 0.430 1.990 1.199999e+10 9.631e+08
+ 7 8 4.185e+05 12.460 24.340 0.430 1.988 1.199998e+10 9.631e+08
+ 8 1 2.930e+06 12.960 24.600 0.530 1.939 1.200000e+10 9.259e+08
+ 8 2 1.465e+06 12.580 24.240 0.440 1.962 1.199999e+10 9.539e+08
+ 8 3 9.766e+05 12.520 24.060 0.430 1.956 1.199999e+10 9.585e+08
+ 8 4 7.324e+05 12.420 24.200 0.410 1.981 1.199999e+10 9.662e+08
+ 8 5 5.859e+05 12.430 24.310 0.430 1.990 1.199999e+10 9.654e+08
+ 8 6 4.883e+05 12.430 24.130 0.420 1.975 1.199999e+10 9.654e+08
+ 8 7 4.185e+05 12.800 24.220 0.490 1.930 1.199998e+10 9.375e+08
+ 8 8 3.662e+05 12.460 24.340 0.430 1.988 1.199997e+10 9.631e+08
diff --git a/gnuradio-core/src/examples/mp-sched/perf-data/qs21-altivec.dat b/gnuradio-core/src/examples/mp-sched/perf-data/qs21-altivec.dat
new file mode 100644
index 000000000..8364be363
--- /dev/null
+++ b/gnuradio-core/src/examples/mp-sched/perf-data/qs21-altivec.dat
@@ -0,0 +1,65 @@
+#D QS21 dual cell 3.2 GHz (using Altivec)
+ 1 1 3.516e+07 9.810 10.240 0.430 1.088 1.800000e+10 1.835e+09
+ 1 2 3.516e+07 11.650 22.840 0.750 2.025 3.600000e+10 3.090e+09
+ 1 3 2.344e+07 9.400 24.860 0.680 2.717 3.600000e+10 3.830e+09
+ 1 4 1.758e+07 7.800 26.820 0.740 3.533 3.600000e+10 4.615e+09
+ 1 5 1.406e+07 8.810 25.970 0.760 3.034 3.600000e+10 4.086e+09
+ 1 6 1.172e+07 8.110 25.710 0.740 3.261 3.600000e+10 4.439e+09
+ 1 7 1.004e+07 7.750 26.020 0.710 3.449 3.600000e+10 4.645e+09
+ 1 8 8.789e+06 7.290 26.600 0.690 3.743 3.600000e+10 4.938e+09
+ 2 1 3.516e+07 10.130 20.690 0.770 2.118 3.600000e+10 3.554e+09
+ 2 2 1.758e+07 7.240 26.820 0.920 3.831 3.600000e+10 4.972e+09
+ 2 3 1.172e+07 8.090 26.670 0.840 3.400 3.600000e+10 4.450e+09
+ 2 4 8.789e+06 7.480 27.010 0.790 3.717 3.600000e+10 4.813e+09
+ 2 5 7.031e+06 7.180 26.530 0.740 3.798 3.600000e+10 5.014e+09
+ 2 6 5.859e+06 7.060 26.590 0.730 3.870 3.600000e+10 5.099e+09
+ 2 7 5.022e+06 7.040 26.610 0.740 3.885 3.600000e+10 5.114e+09
+ 2 8 4.395e+06 7.090 27.020 0.730 3.914 3.600000e+10 5.078e+09
+ 3 1 2.344e+07 9.670 25.850 1.020 2.779 3.600000e+10 3.723e+09
+ 3 2 1.172e+07 7.700 25.940 0.930 3.490 3.600000e+10 4.675e+09
+ 3 3 7.812e+06 7.290 26.760 0.830 3.785 3.600000e+10 4.938e+09
+ 3 4 5.859e+06 7.210 26.900 0.800 3.842 3.600000e+10 4.993e+09
+ 3 5 4.688e+06 7.060 26.690 0.770 3.890 3.600000e+10 5.099e+09
+ 3 6 3.906e+06 7.060 26.830 0.810 3.915 3.600000e+10 5.099e+09
+ 3 7 3.348e+06 6.960 26.680 0.780 3.945 3.600000e+10 5.172e+09
+ 3 8 2.930e+06 6.960 26.600 0.770 3.932 3.599999e+10 5.172e+09
+ 4 1 1.758e+07 7.640 28.700 1.250 3.920 3.600000e+10 4.712e+09
+ 4 2 8.789e+06 7.230 26.640 0.940 3.815 3.600000e+10 4.979e+09
+ 4 3 5.859e+06 7.200 26.800 0.860 3.842 3.600000e+10 5.000e+09
+ 4 4 4.395e+06 7.110 26.900 0.840 3.902 3.600000e+10 5.063e+09
+ 4 5 3.516e+06 7.020 26.680 0.800 3.915 3.600000e+10 5.128e+09
+ 4 6 2.930e+06 6.950 26.700 0.800 3.957 3.599999e+10 5.180e+09
+ 4 7 2.511e+06 6.930 26.590 0.800 3.952 3.599999e+10 5.195e+09
+ 4 8 2.197e+06 6.960 26.570 0.790 3.931 3.599999e+10 5.172e+09
+ 5 1 1.406e+07 8.730 26.540 1.190 3.176 3.600000e+10 4.124e+09
+ 5 2 7.031e+06 7.270 26.450 0.960 3.770 3.600000e+10 4.952e+09
+ 5 3 4.688e+06 7.100 26.630 0.880 3.875 3.600000e+10 5.070e+09
+ 5 4 3.516e+06 7.050 26.700 0.850 3.908 3.600000e+10 5.106e+09
+ 5 5 2.812e+06 6.970 26.610 0.830 3.937 3.600000e+10 5.165e+09
+ 5 6 2.344e+06 6.980 26.710 0.840 3.947 3.600000e+10 5.158e+09
+ 5 7 2.009e+06 6.900 26.470 0.800 3.952 3.599999e+10 5.217e+09
+ 5 8 1.758e+06 6.940 26.580 0.820 3.948 3.599999e+10 5.187e+09
+ 6 1 1.172e+07 8.200 26.510 1.190 3.378 3.600000e+10 4.390e+09
+ 6 2 5.859e+06 7.210 26.590 0.970 3.822 3.600000e+10 4.993e+09
+ 6 3 3.906e+06 7.070 26.580 0.910 3.888 3.600000e+10 5.092e+09
+ 6 4 2.930e+06 7.090 26.750 0.860 3.894 3.599999e+10 5.078e+09
+ 6 5 2.344e+06 7.040 26.830 0.830 3.929 3.600000e+10 5.114e+09
+ 6 6 1.953e+06 6.960 26.600 0.830 3.941 3.600000e+10 5.172e+09
+ 6 7 1.674e+06 6.940 26.500 0.810 3.935 3.600000e+10 5.187e+09
+ 6 8 1.465e+06 6.940 26.540 0.830 3.944 3.599998e+10 5.187e+09
+ 7 1 1.004e+07 7.730 26.940 1.190 3.639 3.600000e+10 4.657e+09
+ 7 2 5.022e+06 7.240 26.600 0.980 3.809 3.600000e+10 4.972e+09
+ 7 3 3.348e+06 7.120 26.680 0.930 3.878 3.600000e+10 5.056e+09
+ 7 4 2.511e+06 7.070 26.840 0.890 3.922 3.599999e+10 5.092e+09
+ 7 5 2.009e+06 6.980 26.570 0.850 3.928 3.599999e+10 5.158e+09
+ 7 6 1.674e+06 6.950 26.530 0.840 3.938 3.600000e+10 5.180e+09
+ 7 7 1.435e+06 6.940 26.570 0.860 3.952 3.599998e+10 5.187e+09
+ 7 8 1.256e+06 6.980 26.590 0.840 3.930 3.599999e+10 5.158e+09
+ 8 1 8.789e+06 7.570 27.360 1.260 3.781 3.600000e+10 4.756e+09
+ 8 2 4.395e+06 7.130 26.460 0.980 3.849 3.600000e+10 5.049e+09
+ 8 3 2.930e+06 7.060 26.680 0.920 3.909 3.599999e+10 5.099e+09
+ 8 4 2.197e+06 7.040 26.670 0.880 3.913 3.599999e+10 5.114e+09
+ 8 5 1.758e+06 6.970 26.600 0.860 3.940 3.599999e+10 5.165e+09
+ 8 6 1.465e+06 6.940 26.490 0.840 3.938 3.599998e+10 5.187e+09
+ 8 7 1.256e+06 6.980 26.630 0.850 3.937 3.599999e+10 5.158e+09
+ 8 8 1.099e+06 7.010 26.820 0.860 3.949 3.599997e+10 5.136e+09
diff --git a/gnuradio-core/src/examples/mp-sched/perf-data/qs21.dat b/gnuradio-core/src/examples/mp-sched/perf-data/qs21.dat
new file mode 100644
index 000000000..cc628740a
--- /dev/null
+++ b/gnuradio-core/src/examples/mp-sched/perf-data/qs21.dat
@@ -0,0 +1,65 @@
+#D QS21 dual cell 3.2 GHz
+ 1 1 1.953e+07 8.480 8.730 0.270 1.061 1.000000e+10 1.179e+09
+ 1 2 1.953e+07 8.750 17.210 0.460 2.019 2.000000e+10 2.286e+09
+ 1 3 1.302e+07 12.390 29.530 0.540 2.427 2.000000e+10 1.614e+09
+ 1 4 9.766e+06 10.120 31.500 0.590 3.171 2.000000e+10 1.976e+09
+ 1 5 7.812e+06 10.200 31.350 0.610 3.133 2.000000e+10 1.961e+09
+ 1 6 6.510e+06 9.520 31.690 0.590 3.391 2.000000e+10 2.101e+09
+ 1 7 5.580e+06 9.430 32.610 0.600 3.522 2.000000e+10 2.121e+09
+ 1 8 4.883e+06 9.400 34.160 0.620 3.700 2.000000e+10 2.128e+09
+ 2 1 1.953e+07 8.800 17.750 0.500 2.074 2.000000e+10 2.273e+09
+ 2 2 9.766e+06 8.990 28.900 0.640 3.286 2.000000e+10 2.225e+09
+ 2 3 6.510e+06 9.390 32.450 0.660 3.526 2.000000e+10 2.130e+09
+ 2 4 4.883e+06 9.220 34.450 0.660 3.808 2.000000e+10 2.169e+09
+ 2 5 3.906e+06 9.180 34.730 0.650 3.854 2.000000e+10 2.179e+09
+ 2 6 3.255e+06 9.150 34.960 0.650 3.892 2.000000e+10 2.186e+09
+ 2 7 2.790e+06 9.140 35.290 0.650 3.932 2.000000e+10 2.188e+09
+ 2 8 2.441e+06 9.080 35.240 0.650 3.953 2.000000e+10 2.203e+09
+ 3 1 1.302e+07 11.720 28.890 0.740 2.528 2.000000e+10 1.706e+09
+ 3 2 6.510e+06 9.390 32.700 0.730 3.560 2.000000e+10 2.130e+09
+ 3 3 4.340e+06 9.150 33.930 0.690 3.784 2.000000e+10 2.186e+09
+ 3 4 3.255e+06 9.040 34.650 0.680 3.908 2.000000e+10 2.212e+09
+ 3 5 2.604e+06 9.090 34.990 0.680 3.924 1.999999e+10 2.200e+09
+ 3 6 2.170e+06 9.050 34.870 0.670 3.927 1.999999e+10 2.210e+09
+ 3 7 1.860e+06 9.010 34.850 0.660 3.941 2.000000e+10 2.220e+09
+ 3 8 1.628e+06 8.980 34.860 0.670 3.957 2.000000e+10 2.227e+09
+ 4 1 9.766e+06 9.000 34.680 0.940 3.958 2.000000e+10 2.222e+09
+ 4 2 4.883e+06 9.020 34.180 0.740 3.871 2.000000e+10 2.217e+09
+ 4 3 3.255e+06 9.150 34.640 0.710 3.863 2.000000e+10 2.186e+09
+ 4 4 2.441e+06 9.010 34.780 0.690 3.937 2.000000e+10 2.220e+09
+ 4 5 1.953e+06 8.980 34.680 0.690 3.939 2.000000e+10 2.227e+09
+ 4 6 1.628e+06 9.050 35.120 0.690 3.957 2.000000e+10 2.210e+09
+ 4 7 1.395e+06 9.010 34.900 0.670 3.948 2.000000e+10 2.220e+09
+ 4 8 1.221e+06 8.960 34.900 0.680 3.971 2.000000e+10 2.232e+09
+ 5 1 7.812e+06 10.150 31.760 0.840 3.212 2.000000e+10 1.970e+09
+ 5 2 3.906e+06 9.090 34.040 0.750 3.827 2.000000e+10 2.200e+09
+ 5 3 2.604e+06 9.030 34.650 0.720 3.917 1.999999e+10 2.215e+09
+ 5 4 1.953e+06 8.990 34.610 0.700 3.928 2.000000e+10 2.225e+09
+ 5 5 1.562e+06 9.000 34.920 0.700 3.958 2.000000e+10 2.222e+09
+ 5 6 1.302e+06 9.120 35.370 0.690 3.954 1.999999e+10 2.193e+09
+ 5 7 1.116e+06 8.910 34.680 0.690 3.970 1.999999e+10 2.245e+09
+ 5 8 9.766e+05 8.930 34.790 0.680 3.972 1.999999e+10 2.240e+09
+ 6 1 6.510e+06 9.390 31.810 0.840 3.477 2.000000e+10 2.130e+09
+ 6 2 3.255e+06 9.000 34.320 0.760 3.898 2.000000e+10 2.222e+09
+ 6 3 2.170e+06 8.960 34.310 0.740 3.912 1.999999e+10 2.232e+09
+ 6 4 1.628e+06 8.970 34.640 0.730 3.943 2.000000e+10 2.230e+09
+ 6 5 1.302e+06 9.110 35.360 0.710 3.959 1.999999e+10 2.195e+09
+ 6 6 1.085e+06 8.970 34.750 0.710 3.953 1.999999e+10 2.230e+09
+ 6 7 9.301e+05 8.950 34.710 0.700 3.956 1.999999e+10 2.235e+09
+ 6 8 8.138e+05 8.920 34.570 0.710 3.955 2.000000e+10 2.242e+09
+ 7 1 5.580e+06 9.290 32.840 0.870 3.629 2.000000e+10 2.153e+09
+ 7 2 2.790e+06 9.040 34.400 0.770 3.890 2.000000e+10 2.212e+09
+ 7 3 1.860e+06 8.940 34.380 0.740 3.928 2.000000e+10 2.237e+09
+ 7 4 1.395e+06 8.990 34.820 0.730 3.954 2.000000e+10 2.225e+09
+ 7 5 1.116e+06 8.990 34.820 0.720 3.953 1.999999e+10 2.225e+09
+ 7 6 9.301e+05 8.940 34.720 0.720 3.964 1.999999e+10 2.237e+09
+ 7 7 7.972e+05 8.930 34.700 0.710 3.965 1.999998e+10 2.240e+09
+ 7 8 6.975e+05 8.910 34.510 0.700 3.952 1.999998e+10 2.245e+09
+ 8 1 4.883e+06 9.070 33.770 0.910 3.824 2.000000e+10 2.205e+09
+ 8 2 2.441e+06 9.000 34.340 0.780 3.902 2.000000e+10 2.222e+09
+ 8 3 1.628e+06 8.990 34.510 0.740 3.921 2.000000e+10 2.225e+09
+ 8 4 1.221e+06 8.980 34.650 0.740 3.941 2.000000e+10 2.227e+09
+ 8 5 9.766e+05 8.960 34.700 0.720 3.953 1.999999e+10 2.232e+09
+ 8 6 8.138e+05 8.920 34.680 0.710 3.967 2.000000e+10 2.242e+09
+ 8 7 6.975e+05 8.900 34.580 0.720 3.966 1.999998e+10 2.247e+09
+ 8 8 6.104e+05 8.930 34.590 0.710 3.953 1.999998e+10 2.240e+09
diff --git a/gnuradio-core/src/examples/mp-sched/plot_flops.py b/gnuradio-core/src/examples/mp-sched/plot_flops.py
new file mode 100755
index 000000000..d9d810ae2
--- /dev/null
+++ b/gnuradio-core/src/examples/mp-sched/plot_flops.py
@@ -0,0 +1,98 @@
+#!/usr/bin/env python
+#
+# Copyright 2008 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+
+"""
+Reads output from run_synthetic.py and runs gnuplot showing
+GFLOPS as f(npipes, nstages)
+"""
+
+import re
+import sys
+import os
+import tempfile
+from optparse import OptionParser
+
+
+def parse_file(input_filename, output):
+ last = None
+ desc = ''
+ for line in open(input_filename, 'r'):
+ s = line.strip()
+ if s.startswith('>>>'): # ignore ">>> using SSE cruft"
+ continue
+
+ if s.startswith('#D'): # machine description
+ desc = s[2:].strip()
+ continue
+
+ fields = s.split()
+ npipes, nstages, flops = fields[0], fields[1], fields[8]
+
+ if last is not None and npipes != last:
+ output.write('\n')
+ last = npipes
+
+ output.write(' '.join((npipes, nstages, flops)))
+ output.write('\n')
+
+ output.flush()
+ return desc
+
+
+def handle_file(input_filename):
+ cmd_file = tempfile.NamedTemporaryFile(mode='w+', prefix='pf', suffix='.cmd')
+ cmd_file_name = cmd_file.name
+ data_file = tempfile.NamedTemporaryFile(mode='w+', prefix='pf', suffix='.dat')
+ data_file_name = data_file.name
+ desc = parse_file(input_filename, data_file)
+ if len(desc) > 0:
+ cmd_file.write("set title '%s'\n" % (desc,))
+ cmd_file.write("set xlabel 'N pipes'\n")
+ cmd_file.write("set ylabel 'N stages'\n")
+ cmd_file.write("set zlabel 'GFLOPS'\n")
+ cmd_file.write("set key off\n")
+ cmd_file.write("set view 60, 312\n")
+ cmd_file.write("set pm3d\n")
+ cmd_file.write("splot '%s' using 1:2:($3*1e-9) with pm3d at b, '%s' using 1:2:($3*1e-9) with pm3d\n" % (
+ data_file_name, data_file_name))
+
+ cmd_file.flush()
+ data_file.flush()
+
+ os.system("gnuplot " + cmd_file_name + " -")
+
+ #sys.stdout.write(open(cmd_file_name,'r').read())
+ #sys.stdout.write(open(data_file_name,'r').read())
+
+
+def main():
+ usage = "usage: %prog [options] file.dat"
+ parser = OptionParser(usage=usage)
+ (options, args) = parser.parse_args()
+ if len(args) != 1:
+ parser.print_help()
+ raise SystemExit, 1
+
+ handle_file(args[0])
+
+
+if __name__ == '__main__':
+ main()
diff --git a/gnuradio-core/src/examples/mp-sched/run_synthetic.py b/gnuradio-core/src/examples/mp-sched/run_synthetic.py
new file mode 100755
index 000000000..4896bca46
--- /dev/null
+++ b/gnuradio-core/src/examples/mp-sched/run_synthetic.py
@@ -0,0 +1,101 @@
+#!/usr/bin/env python
+#
+# Copyright 2008 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+
+"""
+Run synthetic.py for npipes in [1,16], nstages in [1,16]
+"""
+
+import re
+import sys
+import os
+import tempfile
+from optparse import OptionParser
+
+
+def write_shell_script(f, data_filename, description, ncores, gflops, max_pipes_and_stages):
+ """
+ f is the file to write the script to
+ data_filename is the where the data ends up
+ description describes the machine
+ ncores is the number of cores (used to size the workload)
+ gflops is the estimated GFLOPS per core (used to size the workload)
+ """
+
+ f.write("#!/bin/sh\n")
+ f.write("(\n")
+ if description:
+ f.write("echo '#D %s'\n" % (description,))
+
+ for npipes in range(1, max_pipes_and_stages + 1):
+ for nstages in range(1, max_pipes_and_stages + 1):
+ # We'd like each run of synthetic to take ~10 seconds
+ desired_time_per_run = 10
+ est_gflops_avail = min(nstages * npipes, ncores) * gflops
+ nsamples = (est_gflops_avail * desired_time_per_run)/(512.0 * nstages * npipes)
+ nsamples = int(nsamples * 1e9)
+
+ cmd = "./synthetic.py -m -s %d -p %d -N %d\n" % (nstages, npipes, nsamples)
+ f.write(cmd)
+ f.write('if test $? -ge 128; then exit 128; fi\n')
+
+ f.write(") 2>&1 | grep --line-buffered -v '^>>>' | tee %s\n" % (data_filename,))
+ f.flush()
+
+
+
+def main():
+ description = """%prog gathers multiprocessor scaling data using the ./synthetic.py benchmark.
+All combinations of npipes and nstages between 1 and --max-pipes-and-stages are tried.
+The -n and -f options provides hints used to size the workload. We'd like each run
+of synthetic to take about 10 seconds. For the full 16x16 case this results in a
+total runtime of about 43 minutes, assuming that your values for -n and -f are reasonable.
+For x86 machines, assume 3 FLOPS per processor Hz. E.g., 3 GHz machine -> 9 GFLOPS.
+plot_flops.py will make pretty graphs from the output data generated by %prog.
+"""
+ usage = "usage: %prog [options] output.dat"
+ parser = OptionParser(usage=usage, description=description)
+ parser.add_option("-d", "--description", metavar="DESC",
+ help="machine description, e.g., \"Dual quad-core Xeon 3 GHz\"", default=None)
+ parser.add_option("-n", "--ncores", type="int", default=1,
+ help="number of processor cores [default=%default]")
+ parser.add_option("-g", "--gflops", metavar="GFLOPS", type="float", default=3.0,
+ help="estimated GFLOPS per core [default=%default]")
+ parser.add_option("-m", "--max-pipes-and-stages", metavar="MAX", type="int", default=16,
+ help="maximum number of pipes and stages to use [default=%default]")
+ (options, args) = parser.parse_args()
+ if len(args) != 1:
+ parser.print_help()
+ raise SystemExit, 1
+
+ output_filename = args[0]
+
+ shell = os.popen("/bin/sh", "w")
+
+ write_shell_script(shell,
+ output_filename,
+ options.description,
+ options.ncores,
+ options.gflops,
+ options.max_pipes_and_stages)
+
+if __name__ == '__main__':
+ main()
+
diff --git a/gnuradio-core/src/examples/mp-sched/synthetic.py b/gnuradio-core/src/examples/mp-sched/synthetic.py
new file mode 100755
index 000000000..5ce1b5eb8
--- /dev/null
+++ b/gnuradio-core/src/examples/mp-sched/synthetic.py
@@ -0,0 +1,118 @@
+#!/usr/bin/env python
+#
+# Copyright 2008 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+
+from gnuradio import gr, gru, eng_notation, blks2
+from gnuradio.eng_option import eng_option
+from optparse import OptionParser
+import os
+
+
+class pipeline(gr.hier_block2):
+ def __init__(self, nstages, ntaps=256):
+ """
+ Create a pipeline of nstages of gr.fir_filter_fff's connected in serial
+ terminating in a gr.null_sink.
+ """
+ gr.hier_block2.__init__(self, "pipeline",
+ gr.io_signature(1, 1, gr.sizeof_float),
+ gr.io_signature(0, 0, 0))
+ taps = ntaps*[1.0/ntaps]
+ upstream = self
+ for i in range(nstages):
+ op = gr.fir_filter_fff(1, taps)
+ self.connect(upstream, op)
+ upstream = op
+
+ self.connect(upstream, gr.null_sink(gr.sizeof_float))
+
+
+class top(gr.top_block):
+ def __init__(self):
+ gr.top_block.__init__(self)
+
+ default_nsamples = 10e6
+ parser=OptionParser(option_class=eng_option)
+ parser.add_option("-p", "--npipelines", type="intx", default=1,
+ metavar="NPIPES", help="the number of pipelines to create (default=%default)")
+ parser.add_option("-s", "--nstages", type="intx", default=1,
+ metavar="NSTAGES", help="the number of stages in each pipeline (default=%default)")
+ parser.add_option("-N", "--nsamples", type="eng_float", default=default_nsamples,
+ help=("the number of samples to run through the graph (default=%s)" %
+ (eng_notation.num_to_str(default_nsamples))))
+ parser.add_option("-m", "--machine-readable", action="store_true", default=False,
+ help="enable machine readable output")
+
+ (options, args) = parser.parse_args()
+ if len(args) != 0:
+ parser.print_help()
+ raise SystemExit, 1
+
+ self.npipes = options.npipelines
+ self.nstages = options.nstages
+ self.nsamples = options.nsamples
+ self.machine_readable = options.machine_readable
+
+ ntaps = 256
+
+ # Something vaguely like floating point ops
+ self.flop = 2 * ntaps * options.npipelines * options.nstages * options.nsamples
+
+ src = gr.null_source(gr.sizeof_float)
+ head = gr.head(gr.sizeof_float, int(options.nsamples))
+ self.connect(src, head)
+
+ for n in range(options.npipelines):
+ self.connect(head, pipeline(options.nstages, ntaps))
+
+
+def time_it(tb):
+ start = os.times()
+ tb.run()
+ stop = os.times()
+ delta = map((lambda a, b: a-b), stop, start)
+ user, sys, childrens_user, childrens_sys, real = delta
+ total_user = user + childrens_user
+ total_sys = sys + childrens_sys
+ if tb.machine_readable:
+ print "%3d %3d %.3e %7.3f %7.3f %7.3f %7.3f %.6e %.3e" % (
+ tb.npipes, tb.nstages, tb.nsamples, real, total_user, total_sys, (total_user+total_sys)/real, tb.flop, tb.flop/real)
+ else:
+ print "npipes %7d" % (tb.npipes,)
+ print "nstages %7d" % (tb.nstages,)
+ print "nsamples %s" % (eng_notation.num_to_str(tb.nsamples),)
+ print "real %7.3f" % (real,)
+ print "user %7.3f" % (total_user,)
+ print "sys %7.3f" % (total_sys,)
+ print "(user+sys)/real %7.3f" % ((total_user + total_sys)/real,)
+ print "pseudo_flop %s" % (eng_notation.num_to_str(tb.flop),)
+ print "pseudo_flop/real %s" % (eng_notation.num_to_str(tb.flop/real),)
+
+
+if __name__ == "__main__":
+ try:
+ tb = top()
+ time_it(tb)
+ except KeyboardInterrupt:
+ raise SystemExit, 128
+
+
+
+
diff --git a/gnuradio-core/src/examples/mp-sched/wfm_rcv_pll_to_wav.py b/gnuradio-core/src/examples/mp-sched/wfm_rcv_pll_to_wav.py
new file mode 100755
index 000000000..81613922b
--- /dev/null
+++ b/gnuradio-core/src/examples/mp-sched/wfm_rcv_pll_to_wav.py
@@ -0,0 +1,127 @@
+#!/usr/bin/env python
+#
+# Copyright 2005,2006,2007 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr, gru, eng_notation, optfir
+from gnuradio import audio
+from gnuradio import blks2
+from gnuradio.eng_option import eng_option
+from optparse import OptionParser
+import sys
+import math
+
+class wfm_rx_block (gr.top_block):
+ def __init__(self):
+ gr.top_block.__init__(self)
+
+ usage = "usage: %prog [options] input-samples-320kS.dat output.wav"
+ parser=OptionParser(option_class=eng_option, usage=usage)
+ parser.add_option("-V", "--volume", type="eng_float", default=None,
+ help="set volume (default is midpoint)")
+
+ (options, args) = parser.parse_args()
+ if len(args) != 2:
+ parser.print_help()
+ sys.exit(1)
+
+ input_filename = args[0]
+ output_filename = args[1]
+
+ self.vol = 0
+
+ # build graph
+
+ self.src = gr.file_source(gr.sizeof_gr_complex, input_filename, False)
+
+ adc_rate = 64e6 # 64 MS/s
+ usrp_decim = 200
+ 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
+
+
+ chan_filt_coeffs = optfir.low_pass (1, # gain
+ usrp_rate, # sampling rate
+ 80e3, # passband cutoff
+ 115e3, # stopband cutoff
+ 0.1, # passband ripple
+ 60) # stopband attenuation
+ #print len(chan_filt_coeffs)
+ chan_filt = gr.fir_filter_ccf (chanfilt_decim, chan_filt_coeffs)
+
+
+ #self.guts = blks2.wfm_rcv (demod_rate, audio_decimation)
+ self.guts = blks2.wfm_rcv_pll (demod_rate, audio_decimation)
+
+ # FIXME rework {add,multiply}_const_* to handle multiple streams
+ self.volume_control_l = gr.multiply_const_ff(self.vol)
+ self.volume_control_r = gr.multiply_const_ff(self.vol)
+
+ # wave file as final sink
+ if 1:
+ sink = gr.wavfile_sink(output_filename, 2, int(audio_rate), 16)
+ else:
+ sink = audio.sink (int (audio_rate),
+ options.audio_output,
+ False) # ok_to_block
+
+ # now wire it all together
+ self.connect (self.src, chan_filt, self.guts)
+ self.connect ((self.guts, 0), self.volume_control_l, (sink, 0))
+ self.connect ((self.guts, 1), self.volume_control_r, (sink, 1))
+ try:
+ self.guts.stereo_carrier_pll_recovery.squelch_enable(True)
+ except:
+ pass
+ #print "FYI: This implementation of the stereo_carrier_pll_recovery has no squelch implementation yet"
+
+ if options.volume is None:
+ g = self.volume_range()
+ options.volume = float(g[0]+g[1])/2
+
+ # set initial values
+
+ self.set_vol(options.volume)
+ try:
+ self.guts.stereo_carrier_pll_recovery.set_lock_threshold(options.squelch)
+ except:
+ pass
+ #print "FYI: This implementation of the stereo_carrier_pll_recovery has no squelch implementation yet"
+
+
+ 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))
+
+ def volume_range(self):
+ return (-20.0, 0.0, 0.5)
+
+
+if __name__ == '__main__':
+ tb = wfm_rx_block()
+ try:
+ tb.run()
+ except KeyboardInterrupt:
+ pass
diff --git a/gnuradio-core/src/examples/msg_passing/CMakeLists.txt b/gnuradio-core/src/examples/msg_passing/CMakeLists.txt
new file mode 100644
index 000000000..c4b207a1e
--- /dev/null
+++ b/gnuradio-core/src/examples/msg_passing/CMakeLists.txt
@@ -0,0 +1,27 @@
+# Copyright 2012 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+
+include(GrPython)
+
+install(
+ FILES
+ strobe.grc
+ DESTINATION ${GR_PKG_DATA_DIR}/examples/msg_passing
+ COMPONENT "core_python"
+)
diff --git a/gnuradio-core/src/examples/msg_passing/hier/test_msg_hier.grc b/gnuradio-core/src/examples/msg_passing/hier/test_msg_hier.grc
new file mode 100644
index 000000000..0faed49bc
--- /dev/null
+++ b/gnuradio-core/src/examples/msg_passing/hier/test_msg_hier.grc
@@ -0,0 +1,287 @@
+<?xml version='1.0' encoding='ASCII'?>
+<flow_graph>
+ <timestamp>Mon Dec 10 19:56:24 2012</timestamp>
+ <block>
+ <key>options</key>
+ <param>
+ <key>id</key>
+ <value>test_msg_hier</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>title</key>
+ <value></value>
+ </param>
+ <param>
+ <key>author</key>
+ <value></value>
+ </param>
+ <param>
+ <key>description</key>
+ <value></value>
+ </param>
+ <param>
+ <key>window_size</key>
+ <value>1280, 1024</value>
+ </param>
+ <param>
+ <key>generate_options</key>
+ <value>hb</value>
+ </param>
+ <param>
+ <key>category</key>
+ <value>Custom</value>
+ </param>
+ <param>
+ <key>run_options</key>
+ <value>prompt</value>
+ </param>
+ <param>
+ <key>run</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>max_nouts</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>realtime_scheduling</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(10, 10)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>pad_source</key>
+ <param>
+ <key>id</key>
+ <value>pad_source_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>label</key>
+ <value>TEST_PORT</value>
+ </param>
+ <param>
+ <key>type</key>
+ <value>message</value>
+ </param>
+ <param>
+ <key>vlen</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>optional</key>
+ <value>False</value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(234, 145)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>pad_source</key>
+ <param>
+ <key>id</key>
+ <value>pad_source_0_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>label</key>
+ <value>TEST_PORT2</value>
+ </param>
+ <param>
+ <key>type</key>
+ <value>message</value>
+ </param>
+ <param>
+ <key>vlen</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>optional</key>
+ <value>False</value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(167, 54)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>gr_message_strobe</key>
+ <param>
+ <key>id</key>
+ <value>gr_message_strobe_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>msg</key>
+ <value>pmt.pmt_cons(pmt.PMT_NIL, pmt.pmt_make_u8vector(16,0x77))</value>
+ </param>
+ <param>
+ <key>period</key>
+ <value>200</value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(362, 81)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>pad_sink</key>
+ <param>
+ <key>id</key>
+ <value>pad_sink_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>label</key>
+ <value>TEST_PORT</value>
+ </param>
+ <param>
+ <key>type</key>
+ <value>message</value>
+ </param>
+ <param>
+ <key>vlen</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>optional</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(618, 87)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>gr_message_strobe</key>
+ <param>
+ <key>id</key>
+ <value>gr_message_strobe_0_1</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>msg</key>
+ <value>pmt.pmt_intern("OUTPUT2")</value>
+ </param>
+ <param>
+ <key>period</key>
+ <value>100</value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(400, 156)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>pad_sink</key>
+ <param>
+ <key>id</key>
+ <value>pad_sink_0_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>label</key>
+ <value>TEST_PORT3</value>
+ </param>
+ <param>
+ <key>type</key>
+ <value>message</value>
+ </param>
+ <param>
+ <key>vlen</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>optional</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(695, 172)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <connection>
+ <source_block_id>pad_source_0_0</source_block_id>
+ <sink_block_id>gr_message_strobe_0</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
+ </connection>
+ <connection>
+ <source_block_id>pad_source_0</source_block_id>
+ <sink_block_id>gr_message_strobe_0</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
+ </connection>
+ <connection>
+ <source_block_id>gr_message_strobe_0</source_block_id>
+ <sink_block_id>pad_sink_0</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
+ </connection>
+ <connection>
+ <source_block_id>gr_message_strobe_0_1</source_block_id>
+ <sink_block_id>pad_sink_0</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
+ </connection>
+ <connection>
+ <source_block_id>gr_message_strobe_0_1</source_block_id>
+ <sink_block_id>pad_sink_0_0</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
+ </connection>
+</flow_graph>
diff --git a/gnuradio-core/src/examples/msg_passing/hier/test_msg_hier_topblock.grc b/gnuradio-core/src/examples/msg_passing/hier/test_msg_hier_topblock.grc
new file mode 100644
index 000000000..f440b06b3
--- /dev/null
+++ b/gnuradio-core/src/examples/msg_passing/hier/test_msg_hier_topblock.grc
@@ -0,0 +1,185 @@
+<?xml version='1.0' encoding='ASCII'?>
+<flow_graph>
+ <timestamp>Mon Dec 10 19:56:42 2012</timestamp>
+ <block>
+ <key>options</key>
+ <param>
+ <key>id</key>
+ <value>test_msg_hier_topblock</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>title</key>
+ <value></value>
+ </param>
+ <param>
+ <key>author</key>
+ <value></value>
+ </param>
+ <param>
+ <key>description</key>
+ <value></value>
+ </param>
+ <param>
+ <key>window_size</key>
+ <value>1280, 1024</value>
+ </param>
+ <param>
+ <key>generate_options</key>
+ <value>no_gui</value>
+ </param>
+ <param>
+ <key>category</key>
+ <value>Custom</value>
+ </param>
+ <param>
+ <key>run_options</key>
+ <value>prompt</value>
+ </param>
+ <param>
+ <key>run</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>max_nouts</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>realtime_scheduling</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(10, 10)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>gr_message_strobe</key>
+ <param>
+ <key>id</key>
+ <value>gr_message_strobe_0_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>msg</key>
+ <value>pmt.pmt_intern("UPDATED2")</value>
+ </param>
+ <param>
+ <key>period</key>
+ <value>3000</value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(51, 88)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>gr_message_strobe</key>
+ <param>
+ <key>id</key>
+ <value>gr_message_strobe_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>msg</key>
+ <value>pmt.pmt_intern("UPDATED")</value>
+ </param>
+ <param>
+ <key>period</key>
+ <value>2000</value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(211, 168)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>gr_message_debug</key>
+ <param>
+ <key>id</key>
+ <value>gr_message_debug_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(758, 71)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>TEST_MSG_HIER</key>
+ <param>
+ <key>id</key>
+ <value>TEST_MSG_HIER_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(402, 52)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <connection>
+ <source_block_id>TEST_MSG_HIER_0</source_block_id>
+ <sink_block_id>gr_message_debug_0</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
+ </connection>
+ <connection>
+ <source_block_id>gr_message_strobe_0</source_block_id>
+ <sink_block_id>TEST_MSG_HIER_0</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
+ </connection>
+ <connection>
+ <source_block_id>gr_message_strobe_0_0</source_block_id>
+ <sink_block_id>TEST_MSG_HIER_0</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>1</sink_key>
+ </connection>
+ <connection>
+ <source_block_id>TEST_MSG_HIER_0</source_block_id>
+ <sink_block_id>gr_message_debug_0</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>1</sink_key>
+ </connection>
+ <connection>
+ <source_block_id>TEST_MSG_HIER_0</source_block_id>
+ <sink_block_id>gr_message_debug_0</sink_block_id>
+ <source_key>1</source_key>
+ <sink_key>0</sink_key>
+ </connection>
+</flow_graph>
diff --git a/gnuradio-core/src/examples/msg_passing/strobe.grc b/gnuradio-core/src/examples/msg_passing/strobe.grc
new file mode 100644
index 000000000..7e7e8c345
--- /dev/null
+++ b/gnuradio-core/src/examples/msg_passing/strobe.grc
@@ -0,0 +1,266 @@
+<?xml version='1.0' encoding='ASCII'?>
+<flow_graph>
+ <timestamp>Thu Dec 6 11:33:08 2012</timestamp>
+ <block>
+ <key>variable</key>
+ <param>
+ <key>id</key>
+ <value>samp_rate</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>value</key>
+ <value>32000</value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(10, 170)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>gr_pdu_to_tagged_stream</key>
+ <param>
+ <key>id</key>
+ <value>gr_pdu_to_tagged_stream_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>type</key>
+ <value>byte</value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(443, 89)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>gr_message_debug</key>
+ <param>
+ <key>id</key>
+ <value>gr_message_debug_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(1049, 176)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>gr_tagged_stream_to_pdu</key>
+ <param>
+ <key>id</key>
+ <value>gr_tagged_stream_to_pdu_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>type</key>
+ <value>byte</value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(870, 89)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>gr_kludge_copy</key>
+ <param>
+ <key>id</key>
+ <value>gr_kludge_copy_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>type</key>
+ <value>byte</value>
+ </param>
+ <param>
+ <key>num_ports</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>vlen</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(686, 89)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>gr_message_strobe</key>
+ <param>
+ <key>id</key>
+ <value>gr_message_strobe_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>msg</key>
+ <value>pmt.pmt_intern("TEST")</value>
+ </param>
+ <param>
+ <key>period</key>
+ <value>1000</value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(423, 177)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>gr_message_strobe</key>
+ <param>
+ <key>id</key>
+ <value>gr_message_strobe_0_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>msg</key>
+ <value>pmt.pmt_cons( pmt.PMT_NIL, pmt.pmt_make_u8vector(512,0) )</value>
+ </param>
+ <param>
+ <key>period</key>
+ <value>750</value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(99, 85)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>options</key>
+ <param>
+ <key>id</key>
+ <value>strobe</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>title</key>
+ <value></value>
+ </param>
+ <param>
+ <key>author</key>
+ <value></value>
+ </param>
+ <param>
+ <key>description</key>
+ <value></value>
+ </param>
+ <param>
+ <key>window_size</key>
+ <value>1280, 1024</value>
+ </param>
+ <param>
+ <key>generate_options</key>
+ <value>no_gui</value>
+ </param>
+ <param>
+ <key>category</key>
+ <value>Custom</value>
+ </param>
+ <param>
+ <key>run_options</key>
+ <value>prompt</value>
+ </param>
+ <param>
+ <key>run</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>max_nouts</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>realtime_scheduling</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(10, 10)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <connection>
+ <source_block_id>gr_message_strobe_0_0</source_block_id>
+ <sink_block_id>gr_pdu_to_tagged_stream_0</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
+ </connection>
+ <connection>
+ <source_block_id>gr_message_strobe_0</source_block_id>
+ <sink_block_id>gr_message_debug_0</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
+ </connection>
+ <connection>
+ <source_block_id>gr_tagged_stream_to_pdu_0</source_block_id>
+ <sink_block_id>gr_message_debug_0</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
+ </connection>
+ <connection>
+ <source_block_id>gr_kludge_copy_0</source_block_id>
+ <sink_block_id>gr_tagged_stream_to_pdu_0</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
+ </connection>
+ <connection>
+ <source_block_id>gr_pdu_to_tagged_stream_0</source_block_id>
+ <sink_block_id>gr_kludge_copy_0</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
+ </connection>
+</flow_graph>
diff --git a/gnuradio-core/src/examples/network/CMakeLists.txt b/gnuradio-core/src/examples/network/CMakeLists.txt
new file mode 100644
index 000000000..902933e29
--- /dev/null
+++ b/gnuradio-core/src/examples/network/CMakeLists.txt
@@ -0,0 +1,30 @@
+# Copyright 2011 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+
+GR_PYTHON_INSTALL(PROGRAMS
+ audio_sink.py
+ audio_source.py
+ dial_tone_sink.py
+ dial_tone_source.py
+ vector_sink.py
+ vector_source.py
+ DESTINATION ${GR_PKG_DATA_DIR}/examples/network
+ COMPONENT "core_python"
+)
+
diff --git a/gnuradio-core/src/examples/network/audio_sink.py b/gnuradio-core/src/examples/network/audio_sink.py
new file mode 100755
index 000000000..72a678816
--- /dev/null
+++ b/gnuradio-core/src/examples/network/audio_sink.py
@@ -0,0 +1,72 @@
+#!/usr/bin/env python
+#
+# Copyright 2006,2007,2010 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr
+from gnuradio.eng_option import eng_option
+from optparse import OptionParser
+import sys
+
+try:
+ from gnuradio import audio
+except ImportError:
+ sys.stderr.write("Failed to import gnuradio.audio. Make sure gr-audio component is installed.\n")
+ sys.exit(1)
+
+class audio_sink(gr.top_block):
+ def __init__(self, host, port, pkt_size, sample_rate, eof, wait):
+ gr.top_block.__init__(self, "audio_sink")
+ src = gr.udp_source(gr.sizeof_float, host, port, pkt_size,
+ eof=eof, wait=wait)
+ dst = audio.sink(sample_rate)
+ self.connect(src, dst)
+
+if __name__ == '__main__':
+ parser = OptionParser(option_class=eng_option)
+ parser.add_option("", "--host", type="string", default="0.0.0.0",
+ help="local host name (domain name or IP address)")
+ parser.add_option("", "--port", type="int", default=65500,
+ help="port value to listen to for connection")
+ parser.add_option("", "--packet-size", type="int", default=1472,
+ help="packet size.")
+ parser.add_option("-r", "--sample-rate", type="int", default=32000,
+ help="audio signal sample rate [default=%default]")
+ parser.add_option("", "--no-eof", action="store_true", default=False,
+ help="don't send EOF on disconnect")
+ parser.add_option("", "--no-wait", action="store_true", default=False,
+ help="don't wait for source")
+ (options, args) = parser.parse_args()
+ if len(args) != 0:
+ parser.print_help()
+ raise SystemExit, 1
+
+ # Create an instance of a hierarchical block
+ top_block = audio_sink(options.host, options.port,
+ options.packet_size, options.sample_rate,
+ not options.no_eof, not options.no_wait)
+
+ try:
+ # Run forever
+ top_block.run()
+ except KeyboardInterrupt:
+ # Ctrl-C exits
+ pass
+
diff --git a/gnuradio-core/src/examples/network/audio_source.py b/gnuradio-core/src/examples/network/audio_source.py
new file mode 100755
index 000000000..0baf7d2e9
--- /dev/null
+++ b/gnuradio-core/src/examples/network/audio_source.py
@@ -0,0 +1,69 @@
+#!/usr/bin/env python
+#
+# Copyright 2006,2007,2010 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr
+from gnuradio.eng_option import eng_option
+from optparse import OptionParser
+import sys
+
+try:
+ from gnuradio import audio
+except ImportError:
+ sys.stderr.write("Failed to import gnuradio.audio. Make sure gr-audio component is installed.\n")
+ sys.exit(1)
+
+class audio_source(gr.top_block):
+ def __init__(self, host, port, pkt_size, sample_rate, eof):
+ gr.top_block.__init__(self, "audio_source")
+ self.audio = audio.source(sample_rate)
+ self.sink = gr.udp_sink(gr.sizeof_float, host, port, pkt_size, eof=eof)
+ self.connect(self.audio, self.sink)
+
+if __name__ == '__main__':
+ parser = OptionParser(option_class=eng_option)
+ parser.add_option("", "--host", type="string", default="localhost",
+ help="Remote host name (domain name or IP address")
+ parser.add_option("", "--port", type="int", default=65500,
+ help="port number to connect to")
+ parser.add_option("", "--packet-size", type="int", default=1472,
+ help="packet size.")
+ parser.add_option("-r", "--sample-rate", type="int", default=32000 ,
+ help="audio signal sample rate [default=%default]")
+ parser.add_option("", "--no-eof", action="store_true", default=False,
+ help="don't send EOF on disconnect")
+ (options, args) = parser.parse_args()
+ if len(args) != 0:
+ parser.print_help()
+ raise SystemExit, 1
+
+ # Create an instance of a hierarchical block
+ top_block = audio_source(options.host, options.port,
+ options.packet_size, options.sample_rate,
+ not options.no_eof)
+
+ try:
+ # Run forever
+ top_block.run()
+ except KeyboardInterrupt:
+ # Ctrl-C exits
+ pass
+
diff --git a/gnuradio-core/src/examples/network/dial_tone_sink.py b/gnuradio-core/src/examples/network/dial_tone_sink.py
new file mode 100755
index 000000000..83ad376c0
--- /dev/null
+++ b/gnuradio-core/src/examples/network/dial_tone_sink.py
@@ -0,0 +1,65 @@
+#!/usr/bin/env python
+#
+# Copyright 2006,2007,2010 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr, audio
+from gnuradio.eng_option import eng_option
+from optparse import OptionParser
+
+class dial_tone_sink(gr.top_block):
+ def __init__(self, host, port, pkt_size, sample_rate, eof, wait):
+ gr.top_block.__init__(self, "dial_tone_sink")
+ udp = gr.udp_source(gr.sizeof_float, host, port, pkt_size,
+ eof=eof, wait=wait)
+ sink = audio.sink(sample_rate)
+ self.connect(udp, sink)
+
+if __name__ == '__main__':
+ parser = OptionParser(option_class=eng_option)
+ parser.add_option("", "--host", type="string", default="0.0.0.0",
+ help="local host name (domain name or IP address)")
+ parser.add_option("", "--port", type="int", default=65500,
+ help="port value to listen to for connection")
+ parser.add_option("", "--packet-size", type="int", default=1472,
+ help="packet size.")
+ parser.add_option("-r", "--sample-rate", type="int", default=8000,
+ help="audio signal sample rate [default=%default]")
+ parser.add_option("", "--no-eof", action="store_true", default=False,
+ help="don't send EOF on disconnect")
+ parser.add_option("", "--no-wait", action="store_true", default=False,
+ help="don't wait for source")
+ (options, args) = parser.parse_args()
+ if len(args) != 0:
+ parser.print_help()
+ raise SystemExit, 1
+
+ # Create an instance of a hierarchical block
+ top_block = dial_tone_sink(options.host, options.port,
+ options.packet_size, options.sample_rate,
+ not options.no_eof, not options.no_wait)
+
+ try:
+ # Run forever
+ top_block.run()
+ except KeyboardInterrupt:
+ # Ctrl-C exits
+ pass
+
diff --git a/gnuradio-core/src/examples/network/dial_tone_source.py b/gnuradio-core/src/examples/network/dial_tone_source.py
new file mode 100755
index 000000000..232a06de8
--- /dev/null
+++ b/gnuradio-core/src/examples/network/dial_tone_source.py
@@ -0,0 +1,70 @@
+#!/usr/bin/env python
+#
+# Copyright 2006,2007,2010 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr
+from gnuradio.eng_option import eng_option
+from optparse import OptionParser
+
+class dial_tone_source(gr.top_block):
+ def __init__(self, host, port, pkt_size, sample_rate, eof):
+ gr.top_block.__init__(self, "dial_tone_source")
+
+ amplitude = 0.3
+ src0 = gr.sig_source_f (sample_rate, gr.GR_SIN_WAVE, 350, amplitude)
+ src1 = gr.sig_source_f (sample_rate, gr.GR_SIN_WAVE, 440, amplitude)
+ add = gr.add_ff()
+
+ # Throttle needed here to account for the other side's audio card sampling rate
+ thr = gr.throttle(gr.sizeof_float, sample_rate)
+ sink = gr.udp_sink(gr.sizeof_float, host, port, pkt_size, eof=eof)
+ self.connect(src0, (add, 0))
+ self.connect(src1, (add, 1))
+ self.connect(add, thr, sink)
+
+if __name__ == '__main__':
+ parser = OptionParser(option_class=eng_option)
+ parser.add_option("", "--host", type="string", default="localhost",
+ help="Remote host name (domain name or IP address")
+ parser.add_option("", "--port", type="int", default=65500,
+ help="port number to connect to")
+ parser.add_option("", "--packet-size", type="int", default=1472,
+ help="packet size.")
+ parser.add_option("-r", "--sample-rate", type="int", default=8000,
+ help="audio signal sample rate [default=%default]")
+ parser.add_option("", "--no-eof", action="store_true", default=False,
+ help="don't send EOF on disconnect")
+ (options, args) = parser.parse_args()
+ if len(args) != 0:
+ parser.print_help()
+ raise SystemExit, 1
+
+ # Create an instance of a hierarchical block
+ top_block = dial_tone_source(options.host, options.port,
+ options.packet_size, options.sample_rate,
+ not options.no_eof)
+
+ try:
+ # Run forever
+ top_block.run()
+ except KeyboardInterrupt:
+ # Ctrl-C exits
+ pass
diff --git a/gnuradio-core/src/examples/network/vector_sink.py b/gnuradio-core/src/examples/network/vector_sink.py
new file mode 100755
index 000000000..e84a27d9f
--- /dev/null
+++ b/gnuradio-core/src/examples/network/vector_sink.py
@@ -0,0 +1,64 @@
+#!/usr/bin/env python
+#
+# Copyright 2006,2010 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr
+from gnuradio.eng_option import eng_option
+from optparse import OptionParser
+
+class vector_sink(gr.top_block):
+ def __init__(self, host, port, pkt_size, eof, wait):
+ gr.top_block.__init__(self, "vector_sink")
+
+ udp = gr.udp_source(gr.sizeof_float, host, port, pkt_size,
+ eof=eof, wait=wait)
+ sink = gr.file_sink(gr.sizeof_float, "received.dat")
+ self.connect(udp, sink)
+
+if __name__ == "__main__":
+ parser = OptionParser(option_class=eng_option)
+ parser.add_option("", "--host", type="string", default="0.0.0.0",
+ help="local host name (domain name or IP address)")
+ parser.add_option("", "--port", type="int", default=65500,
+ help="port value to listen to for connection")
+ parser.add_option("", "--packet-size", type="int", default=1471,
+ help="packet size.")
+ parser.add_option("", "--no-eof", action="store_true", default=False,
+ help="don't send EOF on disconnect")
+ parser.add_option("", "--no-wait", action="store_true", default=False,
+ help="don't wait for source")
+ (options, args) = parser.parse_args()
+ if len(args) != 0:
+ parser.print_help()
+ raise SystemExit, 1
+
+ # Create an instance of a hierarchical block
+ top_block = vector_sink(options.host, options.port,
+ options.packet_size,
+ not options.no_eof, not options.no_wait)
+
+ try:
+ # Run forever
+ top_block.run()
+ except KeyboardInterrupt:
+ # Ctrl-C exits
+ pass
+
diff --git a/gnuradio-core/src/examples/network/vector_source.py b/gnuradio-core/src/examples/network/vector_source.py
new file mode 100755
index 000000000..d322dda3b
--- /dev/null
+++ b/gnuradio-core/src/examples/network/vector_source.py
@@ -0,0 +1,60 @@
+#!/usr/bin/env python
+#
+# Copyright 2006,2010 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr
+from gnuradio.eng_option import eng_option
+from optparse import OptionParser
+
+class vector_source(gr.top_block):
+ def __init__(self, host, port, pkt_size, eof):
+ gr.top_block.__init__(self, "vector_source")
+ data = [i*0.01 for i in range(1000)]
+ vec = gr.vector_source_f(data, True)
+ udp = gr.udp_sink(gr.sizeof_float, host, port, pkt_size, eof=eof)
+ self.connect(vec, udp)
+
+if __name__ == '__main__':
+ parser = OptionParser(option_class=eng_option)
+ parser.add_option("", "--host", type="string", default="localhost",
+ help="Remote host name (domain name or IP address")
+ parser.add_option("", "--port", type="int", default=65500,
+ help="port number to connect to")
+ parser.add_option("", "--packet-size", type="int", default=1471,
+ help="packet size.")
+ parser.add_option("", "--no-eof", action="store_true", default=False,
+ help="don't send EOF on disconnect")
+ (options, args) = parser.parse_args()
+ if len(args) != 0:
+ parser.print_help()
+ raise SystemExit, 1
+
+# Create an instance of a hierarchical block
+ top_block = vector_source(options.host, options.port, options.packet_size,
+ not options.no_eof)
+
+ try:
+ # Run forever
+ top_block.run()
+ except KeyboardInterrupt:
+ # Ctrl-C exits
+ pass
+
diff --git a/gnuradio-core/src/examples/pfb/CMakeLists.txt b/gnuradio-core/src/examples/pfb/CMakeLists.txt
new file mode 100644
index 000000000..090b2401d
--- /dev/null
+++ b/gnuradio-core/src/examples/pfb/CMakeLists.txt
@@ -0,0 +1,41 @@
+# Copyright 2011 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+
+include(GrPython)
+
+GR_PYTHON_INSTALL(PROGRAMS
+ channelize.py
+ chirp_channelize.py
+ decimate.py
+ fmtest.py
+ interpolate.py
+ resampler.py
+ synth_filter.py
+ synth_to_chan.py
+ reconstruction.py
+ DESTINATION ${GR_PKG_DATA_DIR}/examples/pfb
+ COMPONENT "core_python"
+)
+
+install(
+ FILES
+ resampler_demo.grc
+ DESTINATION ${GR_PKG_DATA_DIR}/examples/pfb
+ COMPONENT "core_python"
+)
diff --git a/gnuradio-core/src/examples/pfb/channelize.py b/gnuradio-core/src/examples/pfb/channelize.py
new file mode 100755
index 000000000..442f263f4
--- /dev/null
+++ b/gnuradio-core/src/examples/pfb/channelize.py
@@ -0,0 +1,191 @@
+#!/usr/bin/env python
+#
+# Copyright 2009 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr, blks2
+import sys, time
+
+try:
+ import scipy
+ from scipy import fftpack
+except ImportError:
+ print "Error: Program requires scipy (see: www.scipy.org)."
+ sys.exit(1)
+
+try:
+ import pylab
+ from pylab import mlab
+except ImportError:
+ print "Error: Program requires matplotlib (see: matplotlib.sourceforge.net)."
+ sys.exit(1)
+
+class pfb_top_block(gr.top_block):
+ def __init__(self):
+ gr.top_block.__init__(self)
+
+ self._N = 2000000 # number of samples to use
+ self._fs = 9000 # initial sampling rate
+ self._M = 9 # Number of channels to channelize
+
+ # Create a set of taps for the PFB channelizer
+ self._taps = gr.firdes.low_pass_2(1, self._fs, 475.50, 50,
+ attenuation_dB=100, window=gr.firdes.WIN_BLACKMAN_hARRIS)
+
+ # Calculate the number of taps per channel for our own information
+ tpc = scipy.ceil(float(len(self._taps)) / float(self._M))
+ print "Number of taps: ", len(self._taps)
+ print "Number of channels: ", self._M
+ print "Taps per channel: ", tpc
+
+ # Create a set of signals at different frequencies
+ # freqs lists the frequencies of the signals that get stored
+ # in the list "signals", which then get summed together
+ self.signals = list()
+ self.add = gr.add_cc()
+ freqs = [-4070, -3050, -2030, -1010, 10, 1020, 2040, 3060, 4080]
+ for i in xrange(len(freqs)):
+ self.signals.append(gr.sig_source_c(self._fs, gr.GR_SIN_WAVE, freqs[i], 1))
+ self.connect(self.signals[i], (self.add,i))
+
+ self.head = gr.head(gr.sizeof_gr_complex, self._N)
+
+ # Construct the channelizer filter
+ self.pfb = blks2.pfb_channelizer_ccf(self._M, self._taps, 1)
+
+ # Construct a vector sink for the input signal to the channelizer
+ self.snk_i = gr.vector_sink_c()
+
+ # Connect the blocks
+ self.connect(self.add, self.head, self.pfb)
+ self.connect(self.add, self.snk_i)
+
+ # Use this to play with the channel mapping
+ #self.pfb.set_channel_map([5,6,7,8,0,1,2,3,4])
+
+ # Create a vector sink for each of M output channels of the filter and connect it
+ self.snks = list()
+ for i in xrange(self._M):
+ self.snks.append(gr.vector_sink_c())
+ self.connect((self.pfb, i), self.snks[i])
+
+
+def main():
+ tstart = time.time()
+
+ tb = pfb_top_block()
+ tb.run()
+
+ tend = time.time()
+ print "Run time: %f" % (tend - tstart)
+
+ if 1:
+ fig_in = pylab.figure(1, figsize=(16,9), facecolor="w")
+ fig1 = pylab.figure(2, figsize=(16,9), facecolor="w")
+ fig2 = pylab.figure(3, figsize=(16,9), facecolor="w")
+
+ Ns = 1000
+ Ne = 10000
+
+ fftlen = 8192
+ winfunc = scipy.blackman
+ fs = tb._fs
+
+ # Plot the input signal on its own figure
+ d = tb.snk_i.data()[Ns:Ne]
+ spin_f = fig_in.add_subplot(2, 1, 1)
+
+ X,freq = mlab.psd(d, NFFT=fftlen, noverlap=fftlen/4, Fs=fs,
+ window = lambda d: d*winfunc(fftlen),
+ scale_by_freq=True)
+ X_in = 10.0*scipy.log10(abs(X))
+ f_in = scipy.arange(-fs/2.0, fs/2.0, fs/float(X_in.size))
+ pin_f = spin_f.plot(f_in, X_in, "b")
+ spin_f.set_xlim([min(f_in), max(f_in)+1])
+ spin_f.set_ylim([-200.0, 50.0])
+
+ spin_f.set_title("Input Signal", weight="bold")
+ spin_f.set_xlabel("Frequency (Hz)")
+ spin_f.set_ylabel("Power (dBW)")
+
+
+ Ts = 1.0/fs
+ Tmax = len(d)*Ts
+
+ t_in = scipy.arange(0, Tmax, Ts)
+ x_in = scipy.array(d)
+ spin_t = fig_in.add_subplot(2, 1, 2)
+ pin_t = spin_t.plot(t_in, x_in.real, "b")
+ pin_t = spin_t.plot(t_in, x_in.imag, "r")
+
+ spin_t.set_xlabel("Time (s)")
+ spin_t.set_ylabel("Amplitude")
+
+ Ncols = int(scipy.floor(scipy.sqrt(tb._M)))
+ Nrows = int(scipy.floor(tb._M / Ncols))
+ if(tb._M % Ncols != 0):
+ Nrows += 1
+
+ # Plot each of the channels outputs. Frequencies on Figure 2 and
+ # time signals on Figure 3
+ fs_o = tb._fs / tb._M
+ Ts_o = 1.0/fs_o
+ Tmax_o = len(d)*Ts_o
+ for i in xrange(len(tb.snks)):
+ # remove issues with the transients at the beginning
+ # also remove some corruption at the end of the stream
+ # this is a bug, probably due to the corner cases
+ d = tb.snks[i].data()[Ns:Ne]
+
+ sp1_f = fig1.add_subplot(Nrows, Ncols, 1+i)
+ X,freq = mlab.psd(d, NFFT=fftlen, noverlap=fftlen/4, Fs=fs_o,
+ window = lambda d: d*winfunc(fftlen),
+ scale_by_freq=True)
+ X_o = 10.0*scipy.log10(abs(X))
+ f_o = scipy.arange(-fs_o/2.0, fs_o/2.0, fs_o/float(X_o.size))
+ p2_f = sp1_f.plot(f_o, X_o, "b")
+ sp1_f.set_xlim([min(f_o), max(f_o)+1])
+ sp1_f.set_ylim([-200.0, 50.0])
+
+ sp1_f.set_title(("Channel %d" % i), weight="bold")
+ sp1_f.set_xlabel("Frequency (Hz)")
+ sp1_f.set_ylabel("Power (dBW)")
+
+ x_o = scipy.array(d)
+ t_o = scipy.arange(0, Tmax_o, Ts_o)
+ sp2_o = fig2.add_subplot(Nrows, Ncols, 1+i)
+ p2_o = sp2_o.plot(t_o, x_o.real, "b")
+ p2_o = sp2_o.plot(t_o, x_o.imag, "r")
+ sp2_o.set_xlim([min(t_o), max(t_o)+1])
+ sp2_o.set_ylim([-2, 2])
+
+ sp2_o.set_title(("Channel %d" % i), weight="bold")
+ sp2_o.set_xlabel("Time (s)")
+ sp2_o.set_ylabel("Amplitude")
+
+ pylab.show()
+
+
+if __name__ == "__main__":
+ try:
+ main()
+ except KeyboardInterrupt:
+ pass
+
diff --git a/gnuradio-core/src/examples/pfb/chirp_channelize.py b/gnuradio-core/src/examples/pfb/chirp_channelize.py
new file mode 100755
index 000000000..1c485ea9d
--- /dev/null
+++ b/gnuradio-core/src/examples/pfb/chirp_channelize.py
@@ -0,0 +1,203 @@
+#!/usr/bin/env python
+#
+# Copyright 2009 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr, blks2
+import sys, time
+
+try:
+ import scipy
+ from scipy import fftpack
+except ImportError:
+ print "Error: Program requires scipy (see: www.scipy.org)."
+ sys.exit(1)
+
+try:
+ import pylab
+ from pylab import mlab
+except ImportError:
+ print "Error: Program requires matplotlib (see: matplotlib.sourceforge.net)."
+ sys.exit(1)
+
+class pfb_top_block(gr.top_block):
+ def __init__(self):
+ gr.top_block.__init__(self)
+
+ self._N = 200000 # number of samples to use
+ self._fs = 9000 # initial sampling rate
+ self._M = 9 # Number of channels to channelize
+
+ # Create a set of taps for the PFB channelizer
+ self._taps = gr.firdes.low_pass_2(1, self._fs, 500, 20,
+ attenuation_dB=10, window=gr.firdes.WIN_BLACKMAN_hARRIS)
+
+ # Calculate the number of taps per channel for our own information
+ tpc = scipy.ceil(float(len(self._taps)) / float(self._M))
+ print "Number of taps: ", len(self._taps)
+ print "Number of channels: ", self._M
+ print "Taps per channel: ", tpc
+
+ repeated = True
+ if(repeated):
+ self.vco_input = gr.sig_source_f(self._fs, gr.GR_SIN_WAVE, 0.25, 110)
+ else:
+ amp = 100
+ data = scipy.arange(0, amp, amp/float(self._N))
+ self.vco_input = gr.vector_source_f(data, False)
+
+ # Build a VCO controlled by either the sinusoid or single chirp tone
+ # Then convert this to a complex signal
+ self.vco = gr.vco_f(self._fs, 225, 1)
+ self.f2c = gr.float_to_complex()
+
+ self.head = gr.head(gr.sizeof_gr_complex, self._N)
+
+ # Construct the channelizer filter
+ self.pfb = blks2.pfb_channelizer_ccf(self._M, self._taps)
+
+ # Construct a vector sink for the input signal to the channelizer
+ self.snk_i = gr.vector_sink_c()
+
+ # Connect the blocks
+ self.connect(self.vco_input, self.vco, self.f2c)
+ self.connect(self.f2c, self.head, self.pfb)
+ self.connect(self.f2c, self.snk_i)
+
+ # Create a vector sink for each of M output channels of the filter and connect it
+ self.snks = list()
+ for i in xrange(self._M):
+ self.snks.append(gr.vector_sink_c())
+ self.connect((self.pfb, i), self.snks[i])
+
+
+def main():
+ tstart = time.time()
+
+ tb = pfb_top_block()
+ tb.run()
+
+ tend = time.time()
+ print "Run time: %f" % (tend - tstart)
+
+ if 1:
+ fig_in = pylab.figure(1, figsize=(16,9), facecolor="w")
+ fig1 = pylab.figure(2, figsize=(16,9), facecolor="w")
+ fig2 = pylab.figure(3, figsize=(16,9), facecolor="w")
+ fig3 = pylab.figure(4, figsize=(16,9), facecolor="w")
+
+ Ns = 650
+ Ne = 20000
+
+ fftlen = 8192
+ winfunc = scipy.blackman
+ fs = tb._fs
+
+ # Plot the input signal on its own figure
+ d = tb.snk_i.data()[Ns:Ne]
+ spin_f = fig_in.add_subplot(2, 1, 1)
+
+ X,freq = mlab.psd(d, NFFT=fftlen, noverlap=fftlen/4, Fs=fs,
+ window = lambda d: d*winfunc(fftlen),
+ scale_by_freq=True)
+ X_in = 10.0*scipy.log10(abs(fftpack.fftshift(X)))
+ f_in = scipy.arange(-fs/2.0, fs/2.0, fs/float(X_in.size))
+ pin_f = spin_f.plot(f_in, X_in, "b")
+ spin_f.set_xlim([min(f_in), max(f_in)+1])
+ spin_f.set_ylim([-200.0, 50.0])
+
+ spin_f.set_title("Input Signal", weight="bold")
+ spin_f.set_xlabel("Frequency (Hz)")
+ spin_f.set_ylabel("Power (dBW)")
+
+
+ Ts = 1.0/fs
+ Tmax = len(d)*Ts
+
+ t_in = scipy.arange(0, Tmax, Ts)
+ x_in = scipy.array(d)
+ spin_t = fig_in.add_subplot(2, 1, 2)
+ pin_t = spin_t.plot(t_in, x_in.real, "b")
+ pin_t = spin_t.plot(t_in, x_in.imag, "r")
+
+ spin_t.set_xlabel("Time (s)")
+ spin_t.set_ylabel("Amplitude")
+
+ Ncols = int(scipy.floor(scipy.sqrt(tb._M)))
+ Nrows = int(scipy.floor(tb._M / Ncols))
+ if(tb._M % Ncols != 0):
+ Nrows += 1
+
+ # Plot each of the channels outputs. Frequencies on Figure 2 and
+ # time signals on Figure 3
+ fs_o = tb._fs / tb._M
+ Ts_o = 1.0/fs_o
+ Tmax_o = len(d)*Ts_o
+ for i in xrange(len(tb.snks)):
+ # remove issues with the transients at the beginning
+ # also remove some corruption at the end of the stream
+ # this is a bug, probably due to the corner cases
+ d = tb.snks[i].data()[Ns:Ne]
+
+ sp1_f = fig1.add_subplot(Nrows, Ncols, 1+i)
+ X,freq = mlab.psd(d, NFFT=fftlen, noverlap=fftlen/4, Fs=fs_o,
+ window = lambda d: d*winfunc(fftlen),
+ scale_by_freq=True)
+ X_o = 10.0*scipy.log10(abs(X))
+ f_o = freq
+ p2_f = sp1_f.plot(f_o, X_o, "b")
+ sp1_f.set_xlim([min(f_o), max(f_o)+1])
+ sp1_f.set_ylim([-200.0, 50.0])
+
+ sp1_f.set_title(("Channel %d" % i), weight="bold")
+ sp1_f.set_xlabel("Frequency (Hz)")
+ sp1_f.set_ylabel("Power (dBW)")
+
+ x_o = scipy.array(d)
+ t_o = scipy.arange(0, Tmax_o, Ts_o)
+ sp2_o = fig2.add_subplot(Nrows, Ncols, 1+i)
+ p2_o = sp2_o.plot(t_o, x_o.real, "b")
+ p2_o = sp2_o.plot(t_o, x_o.imag, "r")
+ sp2_o.set_xlim([min(t_o), max(t_o)+1])
+ sp2_o.set_ylim([-2, 2])
+
+ sp2_o.set_title(("Channel %d" % i), weight="bold")
+ sp2_o.set_xlabel("Time (s)")
+ sp2_o.set_ylabel("Amplitude")
+
+
+ sp3 = fig3.add_subplot(1,1,1)
+ p3 = sp3.plot(t_o, x_o.real)
+ sp3.set_xlim([min(t_o), max(t_o)+1])
+ sp3.set_ylim([-2, 2])
+
+ sp3.set_title("All Channels")
+ sp3.set_xlabel("Time (s)")
+ sp3.set_ylabel("Amplitude")
+
+ pylab.show()
+
+
+if __name__ == "__main__":
+ try:
+ main()
+ except KeyboardInterrupt:
+ pass
+
diff --git a/gnuradio-core/src/examples/pfb/decimate.py b/gnuradio-core/src/examples/pfb/decimate.py
new file mode 100755
index 000000000..5322d746d
--- /dev/null
+++ b/gnuradio-core/src/examples/pfb/decimate.py
@@ -0,0 +1,178 @@
+#!/usr/bin/env python
+#
+# Copyright 2009 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr, blks2
+import sys, time
+
+try:
+ import scipy
+ from scipy import fftpack
+except ImportError:
+ print "Error: Program requires scipy (see: www.scipy.org)."
+ sys.exit(1)
+
+try:
+ import pylab
+ from pylab import mlab
+except ImportError:
+ print "Error: Program requires matplotlib (see: matplotlib.sourceforge.net)."
+ sys.exit(1)
+
+class pfb_top_block(gr.top_block):
+ def __init__(self):
+ gr.top_block.__init__(self)
+
+ self._N = 10000000 # number of samples to use
+ self._fs = 10000 # initial sampling rate
+ self._decim = 20 # Decimation rate
+
+ # Generate the prototype filter taps for the decimators with a 200 Hz bandwidth
+ self._taps = gr.firdes.low_pass_2(1, self._fs, 200, 150,
+ attenuation_dB=120, window=gr.firdes.WIN_BLACKMAN_hARRIS)
+
+ # Calculate the number of taps per channel for our own information
+ tpc = scipy.ceil(float(len(self._taps)) / float(self._decim))
+ print "Number of taps: ", len(self._taps)
+ print "Number of filters: ", self._decim
+ print "Taps per channel: ", tpc
+
+ # Build the input signal source
+ # We create a list of freqs, and a sine wave is generated and added to the source
+ # for each one of these frequencies.
+ self.signals = list()
+ self.add = gr.add_cc()
+ freqs = [10, 20, 2040]
+ for i in xrange(len(freqs)):
+ self.signals.append(gr.sig_source_c(self._fs, gr.GR_SIN_WAVE, freqs[i], 1))
+ self.connect(self.signals[i], (self.add,i))
+
+ self.head = gr.head(gr.sizeof_gr_complex, self._N)
+
+ # Construct a PFB decimator filter
+ self.pfb = blks2.pfb_decimator_ccf(self._decim, self._taps, 0)
+
+ # Construct a standard FIR decimating filter
+ self.dec = gr.fir_filter_ccf(self._decim, self._taps)
+
+ self.snk_i = gr.vector_sink_c()
+
+ # Connect the blocks
+ self.connect(self.add, self.head, self.pfb)
+ self.connect(self.add, self.snk_i)
+
+ # Create the sink for the decimated siganl
+ self.snk = gr.vector_sink_c()
+ self.connect(self.pfb, self.snk)
+
+
+def main():
+ tb = pfb_top_block()
+
+ tstart = time.time()
+ tb.run()
+ tend = time.time()
+ print "Run time: %f" % (tend - tstart)
+
+ if 1:
+ fig1 = pylab.figure(1, figsize=(16,9))
+ fig2 = pylab.figure(2, figsize=(16,9))
+
+ Ns = 10000
+ Ne = 10000
+
+ fftlen = 8192
+ winfunc = scipy.blackman
+ fs = tb._fs
+
+ # Plot the input to the decimator
+
+ d = tb.snk_i.data()[Ns:Ns+Ne]
+ sp1_f = fig1.add_subplot(2, 1, 1)
+
+ X,freq = mlab.psd(d, NFFT=fftlen, noverlap=fftlen/4, Fs=fs,
+ window = lambda d: d*winfunc(fftlen),
+ scale_by_freq=True)
+ X_in = 10.0*scipy.log10(abs(fftpack.fftshift(X)))
+ f_in = scipy.arange(-fs/2.0, fs/2.0, fs/float(X_in.size))
+ p1_f = sp1_f.plot(f_in, X_in, "b")
+ sp1_f.set_xlim([min(f_in), max(f_in)+1])
+ sp1_f.set_ylim([-200.0, 50.0])
+
+ sp1_f.set_title("Input Signal", weight="bold")
+ sp1_f.set_xlabel("Frequency (Hz)")
+ sp1_f.set_ylabel("Power (dBW)")
+
+ Ts = 1.0/fs
+ Tmax = len(d)*Ts
+
+ t_in = scipy.arange(0, Tmax, Ts)
+ x_in = scipy.array(d)
+ sp1_t = fig1.add_subplot(2, 1, 2)
+ p1_t = sp1_t.plot(t_in, x_in.real, "b")
+ p1_t = sp1_t.plot(t_in, x_in.imag, "r")
+ sp1_t.set_ylim([-tb._decim*1.1, tb._decim*1.1])
+
+ sp1_t.set_xlabel("Time (s)")
+ sp1_t.set_ylabel("Amplitude")
+
+
+ # Plot the output of the decimator
+ fs_o = tb._fs / tb._decim
+
+ sp2_f = fig2.add_subplot(2, 1, 1)
+ d = tb.snk.data()[Ns:Ns+Ne]
+ X,freq = mlab.psd(d, NFFT=fftlen, noverlap=fftlen/4, Fs=fs_o,
+ window = lambda d: d*winfunc(fftlen),
+ scale_by_freq=True)
+ X_o = 10.0*scipy.log10(abs(fftpack.fftshift(X)))
+ f_o = scipy.arange(-fs_o/2.0, fs_o/2.0, fs_o/float(X_o.size))
+ p2_f = sp2_f.plot(f_o, X_o, "b")
+ sp2_f.set_xlim([min(f_o), max(f_o)+1])
+ sp2_f.set_ylim([-200.0, 50.0])
+
+ sp2_f.set_title("PFB Decimated Signal", weight="bold")
+ sp2_f.set_xlabel("Frequency (Hz)")
+ sp2_f.set_ylabel("Power (dBW)")
+
+
+ Ts_o = 1.0/fs_o
+ Tmax_o = len(d)*Ts_o
+
+ x_o = scipy.array(d)
+ t_o = scipy.arange(0, Tmax_o, Ts_o)
+ sp2_t = fig2.add_subplot(2, 1, 2)
+ p2_t = sp2_t.plot(t_o, x_o.real, "b-o")
+ p2_t = sp2_t.plot(t_o, x_o.imag, "r-o")
+ sp2_t.set_ylim([-2.5, 2.5])
+
+ sp2_t.set_xlabel("Time (s)")
+ sp2_t.set_ylabel("Amplitude")
+
+ pylab.show()
+
+
+if __name__ == "__main__":
+ try:
+ main()
+ except KeyboardInterrupt:
+ pass
+
diff --git a/gnuradio-core/src/examples/pfb/fmtest.py b/gnuradio-core/src/examples/pfb/fmtest.py
new file mode 100755
index 000000000..b9dd9b382
--- /dev/null
+++ b/gnuradio-core/src/examples/pfb/fmtest.py
@@ -0,0 +1,225 @@
+#!/usr/bin/env python
+#
+# Copyright 2009 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr, blks2
+import sys, math, time
+
+try:
+ import scipy
+ from scipy import fftpack
+except ImportError:
+ print "Error: Program requires scipy (see: www.scipy.org)."
+ sys.exit(1)
+
+try:
+ import pylab
+except ImportError:
+ print "Error: Program requires matplotlib (see: matplotlib.sourceforge.net)."
+ sys.exit(1)
+
+
+class fmtx(gr.hier_block2):
+ def __init__(self, lo_freq, audio_rate, if_rate):
+
+ gr.hier_block2.__init__(self, "build_fm",
+ gr.io_signature(1, 1, gr.sizeof_float), # Input signature
+ gr.io_signature(1, 1, gr.sizeof_gr_complex)) # Output signature
+
+ fmtx = blks2.nbfm_tx (audio_rate, if_rate, max_dev=5e3, tau=75e-6)
+
+ # Local oscillator
+ lo = gr.sig_source_c (if_rate, # sample rate
+ gr.GR_SIN_WAVE, # waveform type
+ lo_freq, #frequency
+ 1.0, # amplitude
+ 0) # DC Offset
+ mixer = gr.multiply_cc ()
+
+ self.connect (self, fmtx, (mixer, 0))
+ self.connect (lo, (mixer, 1))
+ self.connect (mixer, self)
+
+class fmtest(gr.top_block):
+ def __init__(self):
+ gr.top_block.__init__(self)
+
+ self._nsamples = 1000000
+ self._audio_rate = 8000
+
+ # Set up N channels with their own baseband and IF frequencies
+ self._N = 5
+ chspacing = 16000
+ freq = [10, 20, 30, 40, 50]
+ f_lo = [0, 1*chspacing, -1*chspacing, 2*chspacing, -2*chspacing]
+
+ self._if_rate = 4*self._N*self._audio_rate
+
+ # Create a signal source and frequency modulate it
+ self.sum = gr.add_cc ()
+ for n in xrange(self._N):
+ sig = gr.sig_source_f(self._audio_rate, gr.GR_SIN_WAVE, freq[n], 0.5)
+ fm = fmtx(f_lo[n], self._audio_rate, self._if_rate)
+ self.connect(sig, fm)
+ self.connect(fm, (self.sum, n))
+
+ self.head = gr.head(gr.sizeof_gr_complex, self._nsamples)
+ self.snk_tx = gr.vector_sink_c()
+ self.channel = blks2.channel_model(0.1)
+
+ self.connect(self.sum, self.head, self.channel, self.snk_tx)
+
+
+ # Design the channlizer
+ self._M = 10
+ bw = chspacing/2.0
+ t_bw = chspacing/10.0
+ self._chan_rate = self._if_rate / self._M
+ self._taps = gr.firdes.low_pass_2(1, self._if_rate, bw, t_bw,
+ attenuation_dB=100,
+ window=gr.firdes.WIN_BLACKMAN_hARRIS)
+ tpc = math.ceil(float(len(self._taps)) / float(self._M))
+
+ print "Number of taps: ", len(self._taps)
+ print "Number of channels: ", self._M
+ print "Taps per channel: ", tpc
+
+ self.pfb = blks2.pfb_channelizer_ccf(self._M, self._taps)
+
+ self.connect(self.channel, self.pfb)
+
+ # Create a file sink for each of M output channels of the filter and connect it
+ self.fmdet = list()
+ self.squelch = list()
+ self.snks = list()
+ for i in xrange(self._M):
+ self.fmdet.append(blks2.nbfm_rx(self._audio_rate, self._chan_rate))
+ self.squelch.append(blks2.standard_squelch(self._audio_rate*10))
+ self.snks.append(gr.vector_sink_f())
+ self.connect((self.pfb, i), self.fmdet[i], self.squelch[i], self.snks[i])
+
+ def num_tx_channels(self):
+ return self._N
+
+ def num_rx_channels(self):
+ return self._M
+
+def main():
+
+ fm = fmtest()
+
+ tstart = time.time()
+ fm.run()
+ tend = time.time()
+
+ if 1:
+ fig1 = pylab.figure(1, figsize=(12,10), facecolor="w")
+ fig2 = pylab.figure(2, figsize=(12,10), facecolor="w")
+ fig3 = pylab.figure(3, figsize=(12,10), facecolor="w")
+
+ Ns = 10000
+ Ne = 100000
+
+ fftlen = 8192
+ winfunc = scipy.blackman
+
+ # Plot transmitted signal
+ fs = fm._if_rate
+
+ d = fm.snk_tx.data()[Ns:Ns+Ne]
+ sp1_f = fig1.add_subplot(2, 1, 1)
+
+ X,freq = sp1_f.psd(d, NFFT=fftlen, noverlap=fftlen/4, Fs=fs,
+ window = lambda d: d*winfunc(fftlen),
+ visible=False)
+ X_in = 10.0*scipy.log10(abs(fftpack.fftshift(X)))
+ f_in = scipy.arange(-fs/2.0, fs/2.0, fs/float(X_in.size))
+ p1_f = sp1_f.plot(f_in, X_in, "b")
+ sp1_f.set_xlim([min(f_in), max(f_in)+1])
+ sp1_f.set_ylim([-120.0, 20.0])
+
+ sp1_f.set_title("Input Signal", weight="bold")
+ sp1_f.set_xlabel("Frequency (Hz)")
+ sp1_f.set_ylabel("Power (dBW)")
+
+ Ts = 1.0/fs
+ Tmax = len(d)*Ts
+
+ t_in = scipy.arange(0, Tmax, Ts)
+ x_in = scipy.array(d)
+ sp1_t = fig1.add_subplot(2, 1, 2)
+ p1_t = sp1_t.plot(t_in, x_in.real, "b-o")
+ #p1_t = sp1_t.plot(t_in, x_in.imag, "r-o")
+ sp1_t.set_ylim([-5, 5])
+
+ # Set up the number of rows and columns for plotting the subfigures
+ Ncols = int(scipy.floor(scipy.sqrt(fm.num_rx_channels())))
+ Nrows = int(scipy.floor(fm.num_rx_channels() / Ncols))
+ if(fm.num_rx_channels() % Ncols != 0):
+ Nrows += 1
+
+ # Plot each of the channels outputs. Frequencies on Figure 2 and
+ # time signals on Figure 3
+ fs_o = fm._audio_rate
+ for i in xrange(len(fm.snks)):
+ # remove issues with the transients at the beginning
+ # also remove some corruption at the end of the stream
+ # this is a bug, probably due to the corner cases
+ d = fm.snks[i].data()[Ns:Ne]
+
+ sp2_f = fig2.add_subplot(Nrows, Ncols, 1+i)
+ X,freq = sp2_f.psd(d, NFFT=fftlen, noverlap=fftlen/4, Fs=fs_o,
+ window = lambda d: d*winfunc(fftlen),
+ visible=False)
+ #X_o = 10.0*scipy.log10(abs(fftpack.fftshift(X)))
+ X_o = 10.0*scipy.log10(abs(X))
+ #f_o = scipy.arange(-fs_o/2.0, fs_o/2.0, fs_o/float(X_o.size))
+ f_o = scipy.arange(0, fs_o/2.0, fs_o/2.0/float(X_o.size))
+ p2_f = sp2_f.plot(f_o, X_o, "b")
+ sp2_f.set_xlim([min(f_o), max(f_o)+0.1])
+ sp2_f.set_ylim([-120.0, 20.0])
+ sp2_f.grid(True)
+
+ sp2_f.set_title(("Channel %d" % i), weight="bold")
+ sp2_f.set_xlabel("Frequency (kHz)")
+ sp2_f.set_ylabel("Power (dBW)")
+
+
+ Ts = 1.0/fs_o
+ Tmax = len(d)*Ts
+ t_o = scipy.arange(0, Tmax, Ts)
+
+ x_t = scipy.array(d)
+ sp2_t = fig3.add_subplot(Nrows, Ncols, 1+i)
+ p2_t = sp2_t.plot(t_o, x_t.real, "b")
+ p2_t = sp2_t.plot(t_o, x_t.imag, "r")
+ sp2_t.set_xlim([min(t_o), max(t_o)+1])
+ sp2_t.set_ylim([-1, 1])
+
+ sp2_t.set_xlabel("Time (s)")
+ sp2_t.set_ylabel("Amplitude")
+
+
+ pylab.show()
+
+
+if __name__ == "__main__":
+ main()
diff --git a/gnuradio-core/src/examples/pfb/interpolate.py b/gnuradio-core/src/examples/pfb/interpolate.py
new file mode 100755
index 000000000..98068f220
--- /dev/null
+++ b/gnuradio-core/src/examples/pfb/interpolate.py
@@ -0,0 +1,233 @@
+#!/usr/bin/env python
+#
+# Copyright 2009 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr, blks2
+import sys, time
+
+try:
+ import scipy
+ from scipy import fftpack
+except ImportError:
+ print "Error: Program requires scipy (see: www.scipy.org)."
+ sys.exit(1)
+
+try:
+ import pylab
+ from pylab import mlab
+except ImportError:
+ print "Error: Program requires matplotlib (see: matplotlib.sourceforge.net)."
+ sys.exit(1)
+
+class pfb_top_block(gr.top_block):
+ def __init__(self):
+ gr.top_block.__init__(self)
+
+ self._N = 100000 # number of samples to use
+ self._fs = 2000 # initial sampling rate
+ self._interp = 5 # Interpolation rate for PFB interpolator
+ self._ainterp = 5.5 # Resampling rate for the PFB arbitrary resampler
+
+ # Frequencies of the signals we construct
+ freq1 = 100
+ freq2 = 200
+
+ # Create a set of taps for the PFB interpolator
+ # This is based on the post-interpolation sample rate
+ self._taps = gr.firdes.low_pass_2(self._interp, self._interp*self._fs, freq2+50, 50,
+ attenuation_dB=120, window=gr.firdes.WIN_BLACKMAN_hARRIS)
+
+ # Create a set of taps for the PFB arbitrary resampler
+ # The filter size is the number of filters in the filterbank; 32 will give very low side-lobes,
+ # and larger numbers will reduce these even farther
+ # The taps in this filter are based on a sampling rate of the filter size since it acts
+ # internally as an interpolator.
+ flt_size = 32
+ self._taps2 = gr.firdes.low_pass_2(flt_size, flt_size*self._fs, freq2+50, 150,
+ attenuation_dB=120, window=gr.firdes.WIN_BLACKMAN_hARRIS)
+
+ # Calculate the number of taps per channel for our own information
+ tpc = scipy.ceil(float(len(self._taps)) / float(self._interp))
+ print "Number of taps: ", len(self._taps)
+ print "Number of filters: ", self._interp
+ print "Taps per channel: ", tpc
+
+ # Create a couple of signals at different frequencies
+ self.signal1 = gr.sig_source_c(self._fs, gr.GR_SIN_WAVE, freq1, 0.5)
+ self.signal2 = gr.sig_source_c(self._fs, gr.GR_SIN_WAVE, freq2, 0.5)
+ self.signal = gr.add_cc()
+
+ self.head = gr.head(gr.sizeof_gr_complex, self._N)
+
+ # Construct the PFB interpolator filter
+ self.pfb = blks2.pfb_interpolator_ccf(self._interp, self._taps)
+
+ # Construct the PFB arbitrary resampler filter
+ self.pfb_ar = blks2.pfb_arb_resampler_ccf(self._ainterp, self._taps2, flt_size)
+ self.snk_i = gr.vector_sink_c()
+
+ #self.pfb_ar.pfb.print_taps()
+ #self.pfb.pfb.print_taps()
+
+ # Connect the blocks
+ self.connect(self.signal1, self.head, (self.signal,0))
+ self.connect(self.signal2, (self.signal,1))
+ self.connect(self.signal, self.pfb)
+ self.connect(self.signal, self.pfb_ar)
+ self.connect(self.signal, self.snk_i)
+
+ # Create the sink for the interpolated signals
+ self.snk1 = gr.vector_sink_c()
+ self.snk2 = gr.vector_sink_c()
+ self.connect(self.pfb, self.snk1)
+ self.connect(self.pfb_ar, self.snk2)
+
+
+def main():
+ tb = pfb_top_block()
+
+ tstart = time.time()
+ tb.run()
+ tend = time.time()
+ print "Run time: %f" % (tend - tstart)
+
+
+ if 1:
+ fig1 = pylab.figure(1, figsize=(12,10), facecolor="w")
+ fig2 = pylab.figure(2, figsize=(12,10), facecolor="w")
+ fig3 = pylab.figure(3, figsize=(12,10), facecolor="w")
+
+ Ns = 10000
+ Ne = 10000
+
+ fftlen = 8192
+ winfunc = scipy.blackman
+
+ # Plot input signal
+ fs = tb._fs
+
+ d = tb.snk_i.data()[Ns:Ns+Ne]
+ sp1_f = fig1.add_subplot(2, 1, 1)
+
+ X,freq = mlab.psd(d, NFFT=fftlen, noverlap=fftlen/4, Fs=fs,
+ window = lambda d: d*winfunc(fftlen),
+ scale_by_freq=True)
+ X_in = 10.0*scipy.log10(abs(fftpack.fftshift(X)))
+ f_in = scipy.arange(-fs/2.0, fs/2.0, fs/float(X_in.size))
+ p1_f = sp1_f.plot(f_in, X_in, "b")
+ sp1_f.set_xlim([min(f_in), max(f_in)+1])
+ sp1_f.set_ylim([-200.0, 50.0])
+
+
+ sp1_f.set_title("Input Signal", weight="bold")
+ sp1_f.set_xlabel("Frequency (Hz)")
+ sp1_f.set_ylabel("Power (dBW)")
+
+ Ts = 1.0/fs
+ Tmax = len(d)*Ts
+
+ t_in = scipy.arange(0, Tmax, Ts)
+ x_in = scipy.array(d)
+ sp1_t = fig1.add_subplot(2, 1, 2)
+ p1_t = sp1_t.plot(t_in, x_in.real, "b-o")
+ #p1_t = sp1_t.plot(t_in, x_in.imag, "r-o")
+ sp1_t.set_ylim([-2.5, 2.5])
+
+ sp1_t.set_title("Input Signal", weight="bold")
+ sp1_t.set_xlabel("Time (s)")
+ sp1_t.set_ylabel("Amplitude")
+
+
+ # Plot output of PFB interpolator
+ fs_int = tb._fs*tb._interp
+
+ sp2_f = fig2.add_subplot(2, 1, 1)
+ d = tb.snk1.data()[Ns:Ns+(tb._interp*Ne)]
+ X,freq = mlab.psd(d, NFFT=fftlen, noverlap=fftlen/4, Fs=fs,
+ window = lambda d: d*winfunc(fftlen),
+ scale_by_freq=True)
+ X_o = 10.0*scipy.log10(abs(fftpack.fftshift(X)))
+ f_o = scipy.arange(-fs_int/2.0, fs_int/2.0, fs_int/float(X_o.size))
+ p2_f = sp2_f.plot(f_o, X_o, "b")
+ sp2_f.set_xlim([min(f_o), max(f_o)+1])
+ sp2_f.set_ylim([-200.0, 50.0])
+
+ sp2_f.set_title("Output Signal from PFB Interpolator", weight="bold")
+ sp2_f.set_xlabel("Frequency (Hz)")
+ sp2_f.set_ylabel("Power (dBW)")
+
+ Ts_int = 1.0/fs_int
+ Tmax = len(d)*Ts_int
+
+ t_o = scipy.arange(0, Tmax, Ts_int)
+ x_o1 = scipy.array(d)
+ sp2_t = fig2.add_subplot(2, 1, 2)
+ p2_t = sp2_t.plot(t_o, x_o1.real, "b-o")
+ #p2_t = sp2_t.plot(t_o, x_o.imag, "r-o")
+ sp2_t.set_ylim([-2.5, 2.5])
+
+ sp2_t.set_title("Output Signal from PFB Interpolator", weight="bold")
+ sp2_t.set_xlabel("Time (s)")
+ sp2_t.set_ylabel("Amplitude")
+
+
+ # Plot output of PFB arbitrary resampler
+ fs_aint = tb._fs * tb._ainterp
+
+ sp3_f = fig3.add_subplot(2, 1, 1)
+ d = tb.snk2.data()[Ns:Ns+(tb._interp*Ne)]
+ X,freq = mlab.psd(d, NFFT=fftlen, noverlap=fftlen/4, Fs=fs,
+ window = lambda d: d*winfunc(fftlen),
+ scale_by_freq=True)
+ X_o = 10.0*scipy.log10(abs(fftpack.fftshift(X)))
+ f_o = scipy.arange(-fs_aint/2.0, fs_aint/2.0, fs_aint/float(X_o.size))
+ p3_f = sp3_f.plot(f_o, X_o, "b")
+ sp3_f.set_xlim([min(f_o), max(f_o)+1])
+ sp3_f.set_ylim([-200.0, 50.0])
+
+ sp3_f.set_title("Output Signal from PFB Arbitrary Resampler", weight="bold")
+ sp3_f.set_xlabel("Frequency (Hz)")
+ sp3_f.set_ylabel("Power (dBW)")
+
+ Ts_aint = 1.0/fs_aint
+ Tmax = len(d)*Ts_aint
+
+ t_o = scipy.arange(0, Tmax, Ts_aint)
+ x_o2 = scipy.array(d)
+ sp3_f = fig3.add_subplot(2, 1, 2)
+ p3_f = sp3_f.plot(t_o, x_o2.real, "b-o")
+ p3_f = sp3_f.plot(t_o, x_o1.real, "m-o")
+ #p3_f = sp3_f.plot(t_o, x_o2.imag, "r-o")
+ sp3_f.set_ylim([-2.5, 2.5])
+
+ sp3_f.set_title("Output Signal from PFB Arbitrary Resampler", weight="bold")
+ sp3_f.set_xlabel("Time (s)")
+ sp3_f.set_ylabel("Amplitude")
+
+ pylab.show()
+
+
+if __name__ == "__main__":
+ try:
+ main()
+ except KeyboardInterrupt:
+ pass
+
diff --git a/gnuradio-core/src/examples/pfb/reconstruction.py b/gnuradio-core/src/examples/pfb/reconstruction.py
new file mode 100755
index 000000000..59910e4d6
--- /dev/null
+++ b/gnuradio-core/src/examples/pfb/reconstruction.py
@@ -0,0 +1,131 @@
+#!/usr/bin/env python
+
+import scipy, math, pylab
+from scipy import fftpack
+from gnuradio import gr, digital, blks2
+
+fftlen = 8192
+
+def main():
+ N = 10000
+ fs = 2000.0
+ Ts = 1.0/fs
+ t = scipy.arange(0, N*Ts, Ts)
+
+ # When playing with the number of channels, be careful about the filter
+ # specs and the channel map of the synthesizer set below.
+ nchans = 10
+
+ # Build the filter(s)
+ bw = 1000
+ tb = 400
+ proto_taps = gr.firdes.low_pass_2(1, nchans*fs, bw, tb, 80,
+ gr.firdes.WIN_BLACKMAN_hARRIS)
+ print "Filter length: ", len(proto_taps)
+
+
+ # Create a modulated signal
+ npwr = 0.01
+ data = scipy.random.randint(0, 256, N)
+ rrc_taps = gr.firdes.root_raised_cosine(1, 2, 1, 0.35, 41)
+
+ src = gr.vector_source_b(data.astype(scipy.uint8).tolist(), False)
+ mod = digital.bpsk_mod(samples_per_symbol=2)
+ chan = gr.channel_model(npwr)
+ rrc = gr.fft_filter_ccc(1, rrc_taps)
+
+ # Split it up into pieces
+ channelizer = blks2.pfb_channelizer_ccf(nchans, proto_taps, 2)
+
+ # Put the pieces back together again
+ syn_taps = [nchans*t for t in proto_taps]
+ synthesizer = gr.pfb_synthesizer_ccf(nchans, syn_taps, True)
+ src_snk = gr.vector_sink_c()
+ snk = gr.vector_sink_c()
+
+ # Remap the location of the channels
+ # Can be done in synth or channelizer (watch out for rotattions in
+ # the channelizer)
+ synthesizer.set_channel_map([ 0, 1, 2, 3, 4,
+ 15, 16, 17, 18, 19])
+
+ tb = gr.top_block()
+ tb.connect(src, mod, chan, rrc, channelizer)
+ tb.connect(rrc, src_snk)
+
+ vsnk = []
+ for i in xrange(nchans):
+ tb.connect((channelizer,i), (synthesizer, i))
+
+ vsnk.append(gr.vector_sink_c())
+ tb.connect((channelizer,i), vsnk[i])
+
+ tb.connect(synthesizer, snk)
+ tb.run()
+
+ sin = scipy.array(src_snk.data()[1000:])
+ sout = scipy.array(snk.data()[1000:])
+
+
+ # Plot original signal
+ fs_in = nchans*fs
+ f1 = pylab.figure(1, figsize=(16,12), facecolor='w')
+ s11 = f1.add_subplot(2,2,1)
+ s11.psd(sin, NFFT=fftlen, Fs=fs_in)
+ s11.set_title("PSD of Original Signal")
+ s11.set_ylim([-200, -20])
+
+ s12 = f1.add_subplot(2,2,2)
+ s12.plot(sin.real[1000:1500], "o-b")
+ s12.plot(sin.imag[1000:1500], "o-r")
+ s12.set_title("Original Signal in Time")
+
+ start = 1
+ skip = 4
+ s13 = f1.add_subplot(2,2,3)
+ s13.plot(sin.real[start::skip], sin.imag[start::skip], "o")
+ s13.set_title("Constellation")
+ s13.set_xlim([-2, 2])
+ s13.set_ylim([-2, 2])
+
+ # Plot channels
+ nrows = int(scipy.sqrt(nchans))
+ ncols = int(scipy.ceil(float(nchans)/float(nrows)))
+
+ f2 = pylab.figure(2, figsize=(16,12), facecolor='w')
+ for n in xrange(nchans):
+ s = f2.add_subplot(nrows, ncols, n+1)
+ s.psd(vsnk[n].data(), NFFT=fftlen, Fs=fs_in)
+ s.set_title("Channel {0}".format(n))
+ s.set_ylim([-200, -20])
+
+ # Plot reconstructed signal
+ fs_out = 2*nchans*fs
+ f3 = pylab.figure(3, figsize=(16,12), facecolor='w')
+ s31 = f3.add_subplot(2,2,1)
+ s31.psd(sout, NFFT=fftlen, Fs=fs_out)
+ s31.set_title("PSD of Reconstructed Signal")
+ s31.set_ylim([-200, -20])
+
+ s32 = f3.add_subplot(2,2,2)
+ s32.plot(sout.real[1000:1500], "o-b")
+ s32.plot(sout.imag[1000:1500], "o-r")
+ s32.set_title("Reconstructed Signal in Time")
+
+ start = 2
+ skip = 4
+ s33 = f3.add_subplot(2,2,3)
+ s33.plot(sout.real[start::skip], sout.imag[start::skip], "o")
+ s33.set_title("Constellation")
+ s33.set_xlim([-2, 2])
+ s33.set_ylim([-2, 2])
+
+ pylab.show()
+
+
+if __name__ == "__main__":
+ try:
+ main()
+ except KeyboardInterrupt:
+ pass
+
diff --git a/gnuradio-core/src/examples/pfb/resampler.py b/gnuradio-core/src/examples/pfb/resampler.py
new file mode 100755
index 000000000..555938d28
--- /dev/null
+++ b/gnuradio-core/src/examples/pfb/resampler.py
@@ -0,0 +1,127 @@
+#!/usr/bin/env python
+#
+# Copyright 2009 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr, blks2
+import sys
+
+try:
+ import scipy
+except ImportError:
+ print "Error: Program requires scipy (see: www.scipy.org)."
+ sys.exit(1)
+
+try:
+ import pylab
+except ImportError:
+ print "Error: Program requires matplotlib (see: matplotlib.sourceforge.net)."
+ sys.exit(1)
+
+class mytb(gr.top_block):
+ def __init__(self, fs_in, fs_out, fc, N=10000):
+ gr.top_block.__init__(self)
+
+ rerate = float(fs_out) / float(fs_in)
+ print "Resampling from %f to %f by %f " %(fs_in, fs_out, rerate)
+
+ # Creating our own taps
+ taps = gr.firdes.low_pass_2(32, 32, 0.25, 0.1, 80)
+
+ self.src = gr.sig_source_c(fs_in, gr.GR_SIN_WAVE, fc, 1)
+ #self.src = gr.noise_source_c(gr.GR_GAUSSIAN, 1)
+ self.head = gr.head(gr.sizeof_gr_complex, N)
+
+ # A resampler with our taps
+ self.resamp_0 = blks2.pfb_arb_resampler_ccf(rerate, taps,
+ flt_size=32)
+
+ # A resampler that just needs a resampling rate.
+ # Filter is created for us and designed to cover
+ # entire bandwidth of the input signal.
+ # An optional atten=XX rate can be used here to
+ # specify the out-of-band rejection (default=80).
+ self.resamp_1 = blks2.pfb_arb_resampler_ccf(rerate)
+
+ self.snk_in = gr.vector_sink_c()
+ self.snk_0 = gr.vector_sink_c()
+ self.snk_1 = gr.vector_sink_c()
+
+ self.connect(self.src, self.head, self.snk_in)
+ self.connect(self.head, self.resamp_0, self.snk_0)
+ self.connect(self.head, self.resamp_1, self.snk_1)
+
+def main():
+ fs_in = 8000
+ fs_out = 20000
+ fc = 1000
+ N = 10000
+
+ tb = mytb(fs_in, fs_out, fc, N)
+ tb.run()
+
+
+ # Plot PSD of signals
+ nfftsize = 2048
+ fig1 = pylab.figure(1, figsize=(10,10), facecolor="w")
+ sp1 = fig1.add_subplot(2,1,1)
+ sp1.psd(tb.snk_in.data(), NFFT=nfftsize,
+ noverlap=nfftsize/4, Fs = fs_in)
+ sp1.set_title(("Input Signal at f_s=%.2f kHz" % (fs_in/1000.0)))
+ sp1.set_xlim([-fs_in/2, fs_in/2])
+
+ sp2 = fig1.add_subplot(2,1,2)
+ sp2.psd(tb.snk_0.data(), NFFT=nfftsize,
+ noverlap=nfftsize/4, Fs = fs_out,
+ label="With our filter")
+ sp2.psd(tb.snk_1.data(), NFFT=nfftsize,
+ noverlap=nfftsize/4, Fs = fs_out,
+ label="With auto-generated filter")
+ sp2.set_title(("Output Signals at f_s=%.2f kHz" % (fs_out/1000.0)))
+ sp2.set_xlim([-fs_out/2, fs_out/2])
+ sp2.legend()
+
+ # Plot signals in time
+ Ts_in = 1.0/fs_in
+ Ts_out = 1.0/fs_out
+ t_in = scipy.arange(0, len(tb.snk_in.data())*Ts_in, Ts_in)
+ t_out = scipy.arange(0, len(tb.snk_0.data())*Ts_out, Ts_out)
+
+ fig2 = pylab.figure(2, figsize=(10,10), facecolor="w")
+ sp21 = fig2.add_subplot(2,1,1)
+ sp21.plot(t_in, tb.snk_in.data())
+ sp21.set_title(("Input Signal at f_s=%.2f kHz" % (fs_in/1000.0)))
+ sp21.set_xlim([t_in[100], t_in[200]])
+
+ sp22 = fig2.add_subplot(2,1,2)
+ sp22.plot(t_out, tb.snk_0.data(),
+ label="With our filter")
+ sp22.plot(t_out, tb.snk_1.data(),
+ label="With auto-generated filter")
+ sp22.set_title(("Output Signals at f_s=%.2f kHz" % (fs_out/1000.0)))
+ r = float(fs_out)/float(fs_in)
+ sp22.set_xlim([t_out[r * 100], t_out[r * 200]])
+ sp22.legend()
+
+ pylab.show()
+
+if __name__ == "__main__":
+ main()
+
diff --git a/gnuradio-core/src/examples/pfb/resampler_demo.grc b/gnuradio-core/src/examples/pfb/resampler_demo.grc
new file mode 100644
index 000000000..468636a5c
--- /dev/null
+++ b/gnuradio-core/src/examples/pfb/resampler_demo.grc
@@ -0,0 +1,598 @@
+<?xml version='1.0' encoding='ASCII'?>
+<flow_graph>
+ <timestamp>Sun Aug 23 11:39:47 2009</timestamp>
+ <block>
+ <key>options</key>
+ <param>
+ <key>id</key>
+ <value>resampler_demo</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>title</key>
+ <value></value>
+ </param>
+ <param>
+ <key>author</key>
+ <value></value>
+ </param>
+ <param>
+ <key>description</key>
+ <value></value>
+ </param>
+ <param>
+ <key>window_size</key>
+ <value>1280, 1024</value>
+ </param>
+ <param>
+ <key>generate_options</key>
+ <value>wx_gui</value>
+ </param>
+ <param>
+ <key>category</key>
+ <value>Custom</value>
+ </param>
+ <param>
+ <key>run</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>realtime_scheduling</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(10, 10)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>import</key>
+ <param>
+ <key>id</key>
+ <value>import_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>import</key>
+ <value>import math</value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(11, 59)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>variable</key>
+ <param>
+ <key>id</key>
+ <value>rs_taps</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>value</key>
+ <value>firdes.low_pass(nphases, nphases, frac_bw, 0.5-frac_bw)</value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(273, 154)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>gr_add_const_vxx</key>
+ <param>
+ <key>id</key>
+ <value>adder</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>type</key>
+ <value>float</value>
+ </param>
+ <param>
+ <key>const</key>
+ <value>-1.0</value>
+ </param>
+ <param>
+ <key>vlen</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(227, 303)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>gr_throttle</key>
+ <param>
+ <key>id</key>
+ <value>throttle</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>type</key>
+ <value>float</value>
+ </param>
+ <param>
+ <key>samples_per_second</key>
+ <value>samp_rate</value>
+ </param>
+ <param>
+ <key>vlen</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(227, 493)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>wxgui_fftsink2</key>
+ <param>
+ <key>id</key>
+ <value>orig_fft</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>type</key>
+ <value>complex</value>
+ </param>
+ <param>
+ <key>title</key>
+ <value>Original Spectrum</value>
+ </param>
+ <param>
+ <key>samp_rate</key>
+ <value>samp_rate</value>
+ </param>
+ <param>
+ <key>baseband_freq</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>y_per_div</key>
+ <value>10</value>
+ </param>
+ <param>
+ <key>y_divs</key>
+ <value>10</value>
+ </param>
+ <param>
+ <key>ref_level</key>
+ <value>30</value>
+ </param>
+ <param>
+ <key>fft_size</key>
+ <value>1024</value>
+ </param>
+ <param>
+ <key>fft_rate</key>
+ <value>30</value>
+ </param>
+ <param>
+ <key>peak_hold</key>
+ <value>False</value>
+ </param>
+ <param>
+ <key>average</key>
+ <value>False</value>
+ </param>
+ <param>
+ <key>avg_alpha</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>grid_pos</key>
+ <value>1, 0, 1, 3</value>
+ </param>
+ <param>
+ <key>notebook</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(409, 289)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>180</value>
+ </param>
+ </block>
+ <block>
+ <key>wxgui_fftsink2</key>
+ <param>
+ <key>id</key>
+ <value>resamp_fft</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>type</key>
+ <value>complex</value>
+ </param>
+ <param>
+ <key>title</key>
+ <value>Resampled Spectrum</value>
+ </param>
+ <param>
+ <key>samp_rate</key>
+ <value>new_rate</value>
+ </param>
+ <param>
+ <key>baseband_freq</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>y_per_div</key>
+ <value>10</value>
+ </param>
+ <param>
+ <key>y_divs</key>
+ <value>10</value>
+ </param>
+ <param>
+ <key>ref_level</key>
+ <value>30</value>
+ </param>
+ <param>
+ <key>fft_size</key>
+ <value>1024</value>
+ </param>
+ <param>
+ <key>fft_rate</key>
+ <value>30</value>
+ </param>
+ <param>
+ <key>peak_hold</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>average</key>
+ <value>False</value>
+ </param>
+ <param>
+ <key>avg_alpha</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>grid_pos</key>
+ <value>2, 0, 1, 3</value>
+ </param>
+ <param>
+ <key>notebook</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(640, 256)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>180</value>
+ </param>
+ </block>
+ <block>
+ <key>gr_sig_source_x</key>
+ <param>
+ <key>id</key>
+ <value>tri_source</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>type</key>
+ <value>float</value>
+ </param>
+ <param>
+ <key>samp_rate</key>
+ <value>samp_rate</value>
+ </param>
+ <param>
+ <key>waveform</key>
+ <value>gr.GR_TRI_WAVE</value>
+ </param>
+ <param>
+ <key>freq</key>
+ <value>0.05</value>
+ </param>
+ <param>
+ <key>amp</key>
+ <value>2.0</value>
+ </param>
+ <param>
+ <key>offset</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(21, 271)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>gr_frequency_modulator_fc</key>
+ <param>
+ <key>id</key>
+ <value>fm_mod</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>sensitivity</key>
+ <value>math.pi</value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(411, 493)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>blks2_pfb_arb_resampler_ccf</key>
+ <param>
+ <key>id</key>
+ <value>resampler</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>rate</key>
+ <value>float(new_rate)/samp_rate</value>
+ </param>
+ <param>
+ <key>taps</key>
+ <value>rs_taps</value>
+ </param>
+ <param>
+ <key>size</key>
+ <value>nphases</value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(641, 477)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>variable</key>
+ <param>
+ <key>id</key>
+ <value>nphases</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>value</key>
+ <value>32</value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(185, 153)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>variable_static_text</key>
+ <param>
+ <key>id</key>
+ <value>samp_rate</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>label</key>
+ <value>Sample Rate</value>
+ </param>
+ <param>
+ <key>value</key>
+ <value>44100</value>
+ </param>
+ <param>
+ <key>converver</key>
+ <value>float_converter</value>
+ </param>
+ <param>
+ <key>formatter</key>
+ <value>None</value>
+ </param>
+ <param>
+ <key>grid_pos</key>
+ <value>0, 0, 1, 1</value>
+ </param>
+ <param>
+ <key>notebook</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(179, 14)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>variable_static_text</key>
+ <param>
+ <key>id</key>
+ <value>new_rate</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>label</key>
+ <value>Resampled Rate</value>
+ </param>
+ <param>
+ <key>value</key>
+ <value>48000</value>
+ </param>
+ <param>
+ <key>converver</key>
+ <value>float_converter</value>
+ </param>
+ <param>
+ <key>formatter</key>
+ <value>None</value>
+ </param>
+ <param>
+ <key>grid_pos</key>
+ <value>0, 1, 1, 1</value>
+ </param>
+ <param>
+ <key>notebook</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(328, 15)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>variable_static_text</key>
+ <param>
+ <key>id</key>
+ <value>frac_bw</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>label</key>
+ <value>Fractional Bandwidth</value>
+ </param>
+ <param>
+ <key>value</key>
+ <value>0.45</value>
+ </param>
+ <param>
+ <key>converver</key>
+ <value>float_converter</value>
+ </param>
+ <param>
+ <key>formatter</key>
+ <value>lambda x: "%0.2f"%x</value>
+ </param>
+ <param>
+ <key>grid_pos</key>
+ <value>0,2,1,1</value>
+ </param>
+ <param>
+ <key>notebook</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(473, 14)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <connection>
+ <source_block_id>tri_source</source_block_id>
+ <sink_block_id>adder</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
+ </connection>
+ <connection>
+ <source_block_id>adder</source_block_id>
+ <sink_block_id>throttle</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
+ </connection>
+ <connection>
+ <source_block_id>resampler</source_block_id>
+ <sink_block_id>resamp_fft</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
+ </connection>
+ <connection>
+ <source_block_id>fm_mod</source_block_id>
+ <sink_block_id>resampler</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
+ </connection>
+ <connection>
+ <source_block_id>fm_mod</source_block_id>
+ <sink_block_id>orig_fft</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
+ </connection>
+ <connection>
+ <source_block_id>throttle</source_block_id>
+ <sink_block_id>fm_mod</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
+ </connection>
+</flow_graph>
diff --git a/gnuradio-core/src/examples/pfb/synth_filter.py b/gnuradio-core/src/examples/pfb/synth_filter.py
new file mode 100755
index 000000000..c0f7376ec
--- /dev/null
+++ b/gnuradio-core/src/examples/pfb/synth_filter.py
@@ -0,0 +1,83 @@
+#!/usr/bin/env python
+#
+# Copyright 2010 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr, blks2
+import sys
+
+try:
+ import scipy
+except ImportError:
+ print "Error: Program requires scipy (see: www.scipy.org)."
+ sys.exit(1)
+
+try:
+ import pylab
+except ImportError:
+ print "Error: Program requires matplotlib (see: matplotlib.sourceforge.net)."
+ sys.exit(1)
+
+def main():
+ N = 1000000
+ fs = 8000
+
+ freqs = [100, 200, 300, 400, 500]
+ nchans = 7
+
+ sigs = list()
+ for fi in freqs:
+ s = gr.sig_source_c(fs, gr.GR_SIN_WAVE, fi, 1)
+ sigs.append(s)
+
+ taps = gr.firdes.low_pass_2(len(freqs), fs, fs/float(nchans)/2, 100, 100)
+ print "Num. Taps = %d (taps per filter = %d)" % (len(taps),
+ len(taps)/nchans)
+ filtbank = gr.pfb_synthesizer_ccf(nchans, taps)
+
+ head = gr.head(gr.sizeof_gr_complex, N)
+ snk = gr.vector_sink_c()
+
+ tb = gr.top_block()
+ tb.connect(filtbank, head, snk)
+
+ for i,si in enumerate(sigs):
+ tb.connect(si, (filtbank, i))
+
+ tb.run()
+
+ if 1:
+ f1 = pylab.figure(1)
+ s1 = f1.add_subplot(1,1,1)
+ s1.plot(snk.data()[1000:])
+
+ fftlen = 2048
+ f2 = pylab.figure(2)
+ s2 = f2.add_subplot(1,1,1)
+ winfunc = scipy.blackman
+ s2.psd(snk.data()[10000:], NFFT=fftlen,
+ Fs = nchans*fs,
+ noverlap=fftlen/4,
+ window = lambda d: d*winfunc(fftlen))
+
+ pylab.show()
+
+if __name__ == "__main__":
+ main()
diff --git a/gnuradio-core/src/examples/pfb/synth_to_chan.py b/gnuradio-core/src/examples/pfb/synth_to_chan.py
new file mode 100755
index 000000000..18b2e7b53
--- /dev/null
+++ b/gnuradio-core/src/examples/pfb/synth_to_chan.py
@@ -0,0 +1,117 @@
+#!/usr/bin/env python
+#
+# Copyright 2010 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr, blks2
+import sys
+
+try:
+ import scipy
+except ImportError:
+ print "Error: Program requires scipy (see: www.scipy.org)."
+ sys.exit(1)
+
+try:
+ import pylab
+except ImportError:
+ print "Error: Program requires matplotlib (see: matplotlib.sourceforge.net)."
+ sys.exit(1)
+
+def main():
+ N = 1000000
+ fs = 8000
+
+ freqs = [100, 200, 300, 400, 500]
+ nchans = 7
+
+ sigs = list()
+ fmtx = list()
+ for fi in freqs:
+ s = gr.sig_source_f(fs, gr.GR_SIN_WAVE, fi, 1)
+ fm = blks2.nbfm_tx (fs, 4*fs, max_dev=10000, tau=75e-6)
+ sigs.append(s)
+ fmtx.append(fm)
+
+ syntaps = gr.firdes.low_pass_2(len(freqs), fs, fs/float(nchans)/2, 100, 100)
+ print "Synthesis Num. Taps = %d (taps per filter = %d)" % (len(syntaps),
+ len(syntaps)/nchans)
+ chtaps = gr.firdes.low_pass_2(len(freqs), fs, fs/float(nchans)/2, 100, 100)
+ print "Channelizer Num. Taps = %d (taps per filter = %d)" % (len(chtaps),
+ len(chtaps)/nchans)
+ filtbank = gr.pfb_synthesizer_ccf(nchans, syntaps)
+ channelizer = blks2.pfb_channelizer_ccf(nchans, chtaps)
+
+ noise_level = 0.01
+ head = gr.head(gr.sizeof_gr_complex, N)
+ noise = gr.noise_source_c(gr.GR_GAUSSIAN, noise_level)
+ addnoise = gr.add_cc()
+ snk_synth = gr.vector_sink_c()
+
+ tb = gr.top_block()
+
+ tb.connect(noise, (addnoise,0))
+ tb.connect(filtbank, head, (addnoise, 1))
+ tb.connect(addnoise, channelizer)
+ tb.connect(addnoise, snk_synth)
+
+ snk = list()
+ for i,si in enumerate(sigs):
+ tb.connect(si, fmtx[i], (filtbank, i))
+
+ for i in xrange(nchans):
+ snk.append(gr.vector_sink_c())
+ tb.connect((channelizer, i), snk[i])
+
+ tb.run()
+
+ if 1:
+ channel = 1
+ data = snk[channel].data()[1000:]
+
+ f1 = pylab.figure(1)
+ s1 = f1.add_subplot(1,1,1)
+ s1.plot(data[10000:10200] )
+ s1.set_title(("Output Signal from Channel %d" % channel))
+
+ fftlen = 2048
+ winfunc = scipy.blackman
+ #winfunc = scipy.hamming
+
+ f2 = pylab.figure(2)
+ s2 = f2.add_subplot(1,1,1)
+ s2.psd(data, NFFT=fftlen,
+ Fs = nchans*fs,
+ noverlap=fftlen/4,
+ window = lambda d: d*winfunc(fftlen))
+ s2.set_title(("Output PSD from Channel %d" % channel))
+
+ f3 = pylab.figure(3)
+ s3 = f3.add_subplot(1,1,1)
+ s3.psd(snk_synth.data()[1000:], NFFT=fftlen,
+ Fs = nchans*fs,
+ noverlap=fftlen/4,
+ window = lambda d: d*winfunc(fftlen))
+ s3.set_title("Output of Synthesis Filter")
+
+ pylab.show()
+
+if __name__ == "__main__":
+ main()
diff --git a/gnuradio-core/src/examples/tags/CMakeLists.txt b/gnuradio-core/src/examples/tags/CMakeLists.txt
new file mode 100644
index 000000000..2d9dc2083
--- /dev/null
+++ b/gnuradio-core/src/examples/tags/CMakeLists.txt
@@ -0,0 +1,28 @@
+# Copyright 2011 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+
+include(GrPython)
+
+GR_PYTHON_INSTALL(PROGRAMS
+ test_file_tags.py
+ uhd_burst_detector.py
+ DESTINATION ${GR_PKG_DATA_DIR}/examples/tags
+ COMPONENT "core_python"
+)
+
diff --git a/gnuradio-core/src/examples/tags/test_file_tags.py b/gnuradio-core/src/examples/tags/test_file_tags.py
new file mode 100755
index 000000000..135626d2c
--- /dev/null
+++ b/gnuradio-core/src/examples/tags/test_file_tags.py
@@ -0,0 +1,55 @@
+#!/usr/bin/env python
+#
+# Copyright 2011 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr
+import sys
+
+try:
+ import scipy
+except ImportError:
+ print "Error: Program requires scipy (see: www.scipy.org)."
+ sys.exit(1)
+
+def main():
+ data = scipy.arange(0, 32000, 1).tolist()
+ trig = 100*[0,] + 100*[1,]
+
+ src = gr.vector_source_s(data, True)
+ trigger = gr.vector_source_s(trig, True)
+
+ thr = gr.throttle(gr.sizeof_short, 10e3)
+ ann = gr.annotator_alltoall(1000000, gr.sizeof_short)
+ tagger = gr.burst_tagger(gr.sizeof_short)
+
+ fsnk = gr.tagged_file_sink(gr.sizeof_short, 1)
+
+ tb = gr.top_block()
+ tb.connect(src, thr, (tagger, 0))
+ tb.connect(trigger, (tagger, 1))
+ tb.connect(tagger, fsnk)
+
+ tb.run()
+
+if __name__ == "__main__":
+ main()
+
+
diff --git a/gnuradio-core/src/examples/tags/uhd_burst_detector.py b/gnuradio-core/src/examples/tags/uhd_burst_detector.py
new file mode 100755
index 000000000..512fc715d
--- /dev/null
+++ b/gnuradio-core/src/examples/tags/uhd_burst_detector.py
@@ -0,0 +1,116 @@
+#!/usr/bin/env python
+#
+# Copyright 2011 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import eng_notation
+from gnuradio import gr
+from gnuradio import uhd
+from gnuradio import window
+from gnuradio.eng_option import eng_option
+from gnuradio.gr import firdes
+from optparse import OptionParser
+
+class uhd_burst_detector(gr.top_block):
+ def __init__(self, uhd_address, options):
+
+ gr.top_block.__init__(self)
+
+ self.uhd_addr = uhd_address
+ self.freq = options.freq
+ self.samp_rate = options.samp_rate
+ self.gain = options.gain
+ self.threshold = options.threshold
+ self.trigger = options.trigger
+
+ self.uhd_src = uhd.single_usrp_source(
+ device_addr=self.uhd_addr,
+ stream_args=uhd.stream_args('fc32'))
+
+ self.uhd_src.set_samp_rate(self.samp_rate)
+ self.uhd_src.set_center_freq(self.freq, 0)
+ self.uhd_src.set_gain(self.gain, 0)
+
+ taps = firdes.low_pass_2(1, 1, 0.4, 0.1, 60)
+ self.chanfilt = gr.fir_filter_ccc(10, taps)
+ self.tagger = gr.burst_tagger(gr.sizeof_gr_complex)
+
+ # Dummy signaler to collect a burst on known periods
+ data = 1000*[0,] + 1000*[1,]
+ self.signal = gr.vector_source_s(data, True)
+
+ # Energy detector to get signal burst
+ ## use squelch to detect energy
+ self.det = gr.simple_squelch_cc(self.threshold, 0.01)
+ ## convert to mag squared (float)
+ self.c2m = gr.complex_to_mag_squared()
+ ## average to debounce
+ self.avg = gr.single_pole_iir_filter_ff(0.01)
+ ## rescale signal for conversion to short
+ self.scale = gr.multiply_const_ff(2**16)
+ ## signal input uses shorts
+ self.f2s = gr.float_to_short()
+
+ # Use file sink burst tagger to capture bursts
+ self.fsnk = gr.tagged_file_sink(gr.sizeof_gr_complex, self.samp_rate)
+
+
+ ##################################################
+ # Connections
+ ##################################################
+ self.connect((self.uhd_src, 0), (self.tagger, 0))
+ self.connect((self.tagger, 0), (self.fsnk, 0))
+
+ if self.trigger:
+ # Connect a dummy signaler to the burst tagger
+ self.connect((self.signal, 0), (self.tagger, 1))
+
+ else:
+ # Connect an energy detector signaler to the burst tagger
+ self.connect(self.uhd_src, self.det)
+ self.connect(self.det, self.c2m, self.avg, self.scale, self.f2s)
+ self.connect(self.f2s, (self.tagger, 1))
+
+ def set_samp_rate(self, samp_rate):
+ self.samp_rate = samp_rate
+ self.uhd_src_0.set_samp_rate(self.samp_rate)
+
+if __name__ == '__main__':
+ parser = OptionParser(option_class=eng_option, usage="%prog: [options]")
+ parser.add_option("-a", "--address", type="string", default="addr=192.168.10.2",
+ help="select address of the device [default=%default]")
+ #parser.add_option("-A", "--antenna", default=None,
+ # help="select Rx Antenna (only on RFX-series boards)")
+ parser.add_option("-f", "--freq", type="eng_float", default=450e6,
+ help="set frequency to FREQ", metavar="FREQ")
+ parser.add_option("-g", "--gain", type="eng_float", default=0,
+ help="set gain in dB [default=%default]")
+ parser.add_option("-R", "--samp-rate", type="eng_float", default=200000,
+ help="set USRP sample rate [default=%default]")
+ parser.add_option("-t", "--threshold", type="float", default=-60,
+ help="Set the detection power threshold (dBm) [default=%default")
+ parser.add_option("-T", "--trigger", action="store_true", default=False,
+ help="Use internal trigger instead of detector [default=%default]")
+ (options, args) = parser.parse_args()
+
+ uhd_addr = options.address
+
+ tb = uhd_burst_detector(uhd_addr, options)
+ tb.run()
diff --git a/gnuradio-core/src/examples/volk_benchmark/CMakeLists.txt b/gnuradio-core/src/examples/volk_benchmark/CMakeLists.txt
new file mode 100644
index 000000000..255d9bf5c
--- /dev/null
+++ b/gnuradio-core/src/examples/volk_benchmark/CMakeLists.txt
@@ -0,0 +1,35 @@
+# Copyright 2012 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+
+include(GrPython)
+
+GR_PYTHON_INSTALL(PROGRAMS
+ volk_math.py
+ volk_plot.py
+ volk_test_funcs.py
+ volk_types.py
+ DESTINATION ${GR_PKG_DATA_DIR}/examples/volk_benchmark
+ COMPONENT "core_python"
+)
+
+install(
+ FILES README
+ DESTINATION ${GR_PKG_DATA_DIR}/examples/volk_benchmark
+ COMPONENT "core_python"
+)
diff --git a/gnuradio-core/src/examples/volk_benchmark/README b/gnuradio-core/src/examples/volk_benchmark/README
new file mode 100644
index 000000000..c58b40d11
--- /dev/null
+++ b/gnuradio-core/src/examples/volk_benchmark/README
@@ -0,0 +1,252 @@
+VOLK Benchmarking Scripts
+
+The Python programs in this directory are designed to help benchmark
+and compare Volk enhancements to GNU Radio. There are two kinds of
+scripts here: collecting data and displaying the data.
+
+Data collection is done by running a Volk testing script that will
+populate a SQLite database file (volk_results.db by default). The
+plotting utility provided here reads from the database files and plots
+bar graphs to compare the different installations.
+
+These benchmarks can be used to compare previous versions of GNU
+Radio to using Volk; they can be used to compare different Volk
+proto-kernels, as well, by editing the volk_config file; or they could
+be used to compare performance between different machines and/or
+processors.
+
+
+======================================================================
+Volk Profiling
+
+Before doing any kind of Volk benchmarking, it is important to run the
+volk_profile program. The profiler will build a config file for the
+best SIMD architecture for your processor. Run volk_profile that is
+installed into $PREFIX/bin. This program tests all known Volk kernels
+for each proto-kernel supported by the processor. When finished, it
+will write to $HOME/.volk/volk_config the best architecture for the
+VOLK function. This file is read when using a function to know the
+best version of the function to execute.
+
+The volk_config file contains a line for each kernel, where each line
+looks like:
+
+ volk_<KERNEL_NAME> <ARCHITECTURE>
+
+The architecture will be something like (sse, sse2, sse3, avx, neon,
+etc.), depending on your processor.
+
+
+======================================================================
+Benchmark Tests
+
+There are currently two benchmark scripts defined for collecting
+data. There is one that runs through the type conversions that have
+been converted to Volk (volk_types.py) and the other runs through the
+math operators converted to using Volk (volk_math.py).
+
+Script prototypes
+Both have the same structure for use:
+
+----------------------------------------------------------------------
+./volk_<test>.py [-h] -L LABEL [-D DATABASE] [-N NITEMS] [-I ITERATIONS]
+ [--tests [{0,1,2,3} [{0,1,2,3} ...]]] [--list]
+ [--all]
+
+optional arguments:
+ -h, --help show this help message and exit
+ -L LABEL, --label LABEL
+ Label of database table [default: None]
+ -D DATABASE, --database DATABASE
+ Database file to store data in [default:
+ volk_results.db]
+ -N NITEMS, --nitems NITEMS
+ Number of items per iterations [default: 1000000000.0]
+ -I ITERATIONS, --iterations ITERATIONS
+ Number of iterations [default: 20]
+ --tests [{0,1,2,3} [{0,1,2,3} ...]]
+ A list of tests to run; can be a single test or a
+ space-separated list.
+ --list List the available tests
+ --all Run all tests
+----------------------------------------------------------------------
+
+To run, you specify the tests to run and a label to store along with
+the results. To find out what the available tests are, use the
+'--list' option.
+
+To specify a subset of tests, use the '--tests' with space-separated
+list of tests numbers (e.g., --tests 0 2 4 9).
+
+Use the '--all' to run all tests.
+
+The label specified is used as an identifier for the benchmarking
+currently being done. This is required as it is important in
+organizing the data in the database (each label is its own
+table). Usually, the label will specify the type of run being done,
+such as "volk_aligned" or "v3_5_1". In these cases, the "volk_aligned"
+label says that this is for a benchmarking using the GNU Radio version
+that uses the aligned scheduler and Volk calls in the work
+functions. The "v3_5_1" label is if you were benchmarking an installed
+version 3.5.1 of GNU Radio, which is pre-Volk. These will then be
+plotted against each other to see the timing differences.
+
+The 'database' option will output the results to a new database
+file. This can be useful for separating the output of different runs
+or of different benchmarks, such as the types versus the math scripts,
+say, or to distinguish results from different computers.
+
+If rerun using the same database and label, the entries in the table
+will simply be replaced by the new results.
+
+It is often useful to use the 'sqlitebrowser' program to interrogate
+the database file farther, if you are interested in the structure or
+the raw data.
+
+Other parameters of this script set the number of items to process and
+number of iterations to use when computing the benchmarking
+data. These default to 1 billion samples per iteration over 20
+iterations. Expect a default run to take a long time. Using the '-N'
+and '-I' options can be used to change the runtime of the benchmarks
+but are set high to remove problems of variance between iterations.
+
+======================================================================
+Plotting Results
+
+The volk_plot.py script reads a given database file and plots the
+results. The default behavior is to read all of the labels stored in
+the database and plot them as data sets on a bar graph. This shows the
+average time taken to process the number of items given.
+
+The options for the plotting script are:
+
+usage: volk_plot.py [-h] [-D DATABASE] [-E] [-P {mean,min,max}] [-% table]
+
+Plot Volk performance results from a SQLite database. Run one of the volk
+tests first (e.g, volk_math.py)
+
+----------------------------------------------------------------------
+optional arguments:
+ -h, --help show this help message and exit
+ -D DATABASE, --database DATABASE
+ Database file to read data from [default:
+ volk_results.db]
+ -E, --errorbars Show error bars (1 standard dev.)
+ -P {mean,min,max}, --plot {mean,min,max}
+ Set the type of plot to produce [default: mean]
+ -% table, --percent table
+ Show percent difference to the given type [default:
+ None]
+----------------------------------------------------------------------
+
+This script allows you to specify the database used (-D), but will
+always read all rows from all tables from it and display them. You can
+also turn on plotting error bars (1 standard deviation the mean). Be
+careful, though, as some older versions of Matplotlib might have an
+issue with this option.
+
+The mean time is only one possible statistic that we might be
+interested in when looking at the data. It represents the average user
+experience when running a given block. On the other hand, the minimum
+runtime best represents the actual performance of a block given
+minimal OS interruptions while running. Right now, the data collected
+includes the mean, variance, min, and max over the number of
+iterations given. Using the '-P' option, you can specify the type of
+data to plot (mean, min, or max).
+
+Another useful way of looking at the data is to compare the percent
+improvement of a benchmark compared to another. This is done using the
+'-%' option with the provided table (or label) as the baseline. So if
+we were interested in comparing how much the 'volk_aligned' was over
+'v3_5_1', we would specify '-% v3_5_1' to see this. The plot would
+then only show the percent speedup observed using Volk for each of the
+blocks.
+
+
+======================================================================
+Benchmarking Walkthrough
+
+This will walk through an example of benchmarking the new Volk
+implementation versus the pre-Volk GNU Radio. It also shows how to
+look at the SIMD optimized versions versus the generic
+implementations.
+
+Since we introduced Volk in GNU Radio 3.5.2, we will use the following
+labels for our data:
+
+ 1.) volk_aligned: v3.5.2 with volk_profile results in .volk/volk_config
+ 2.) v3_5_2: v3.5.2 with the generic (non-SIMD) calls to Volk
+ 3.) v3_5_1: an installation of GNU Radio from version v3.5.1
+
+We assume that we have installed two versions of GNU Radio.
+
+ v3.5.2 installed into /opt/gr-3_5_2
+ v3.5.1 installed into /opt/gr-3_5_1
+
+To test cases 1 and 2 above, we have to run GNU Radio from the v3.5.2
+installation, so we set the following environmental variables. Note
+that this is written for Ubuntu 11.10. These commands and directories
+may have to be changed depending on your OS and versions.
+
+ export LD_LIBRARY_PATH=/opt/gr-3_5_2/lib
+ export LD_LIBRARY_PATH=/opt/gr-3_5_2/lib/python2.7/dist-packages
+
+Now we can run the benchmark tests, so we will focus on the math
+operators:
+
+ ./volk_math.py -D volk_results_math.db --all -L volk_aligned
+
+When this finishes, the 'volk_results_math.db' will contain our
+results for this run.
+
+We next want to run the generic, non-SIMD, calls. This can be done by
+changing the Volk kernel settings in $HOME/.volk/volk_config. First,
+make a backup of this file. Then edit it and change all architecture
+calls (sse, sse2, etc.) to 'generic.' Now, Volk will only call the
+generic versions of these functions. So we rerun the benchmark with:
+
+ ./volk_math.py -D volk_results_math.db --all -L v3_5_2
+
+Notice that the only thing changed here was the label to 'v3_5_2'.
+
+Next, we want to collect data for the non-Volk version of GNU
+Radio. This is important because some internals to GNU Radio were made
+when adding support for Volk, so it is nice to know what the
+differences do to our performance. First, we set the environmental
+variables to point to the v3.5.1 installation:
+
+ export LD_LIBRARY_PATH=/opt/gr-3_5_1/lib
+ export LD_LIBRARY_PATH=/opt/gr-3_5_1/lib/python2.7/dist-packages
+
+And when we run the test, we use the same command line, but the GNU
+Radio libraries and Python files used come from v3.5.1. We also change
+the label to indicate the different version to store.
+
+ ./volk_math.py -D volk_results_math.db --all -L v3_5_1
+
+We now have a database populated with three tables for the three
+different labels. We can plot them all together by simply running:
+
+ ./volk_plot.py -D volk_results_math.db
+
+This will show the average run times for each of the three
+configurations for all math functions tested. We might also be
+interested to see the difference in performance from the v3.5.1
+version, so we can run:
+
+ ./volk_plot.py -D volk_results_math.db -% v3_5_1
+
+That will plot both the 'volk_aligned' and 'v3_5_2' as a percentage
+improvement over v3_5_1. A positive value indicates that this version
+runs faster than the v3.5.1 version.
+
+
+----------------------------------------------------------------------
+
+Another interesting test case could be to compare results on different
+processors. So if you have different generation Intels, AMD, or
+whatever, you can simply pass the .db file around and run the Volk
+benchmark script to populate the database with different results. For
+this, you would specify a label like '-L i7_2620M' that indicates the
+processor type to uniquely ID the data.
+
diff --git a/gnuradio-core/src/examples/volk_benchmark/volk_math.py b/gnuradio-core/src/examples/volk_benchmark/volk_math.py
new file mode 100755
index 000000000..1d8bf04cc
--- /dev/null
+++ b/gnuradio-core/src/examples/volk_benchmark/volk_math.py
@@ -0,0 +1,151 @@
+#!/usr/bin/env python
+
+from gnuradio import gr
+import argparse
+from volk_test_funcs import *
+
+def multiply_const_cc(N):
+ k = 3.3
+ op = gr.multiply_const_cc(k)
+ tb = helper(N, op, gr.sizeof_gr_complex, gr.sizeof_gr_complex, 1, 1)
+ return tb
+
+######################################################################
+
+def multiply_const_ff(N):
+ k = 3.3
+ op = gr.multiply_const_ff(k)
+ tb = helper(N, op, gr.sizeof_float, gr.sizeof_float, 1, 1)
+ return tb
+
+######################################################################
+
+def multiply_cc(N):
+ op = gr.multiply_cc(1)
+ tb = helper(N, op, gr.sizeof_gr_complex, gr.sizeof_gr_complex, 2, 1)
+ return tb
+
+######################################################################
+
+def multiply_ff(N):
+ op = gr.multiply_ff()
+ tb = helper(N, op, gr.sizeof_float, gr.sizeof_float, 2, 1)
+ return tb
+
+######################################################################
+
+def add_ff(N):
+ op = gr.add_ff()
+ tb = helper(N, op, gr.sizeof_float, gr.sizeof_float, 2, 1)
+ return tb
+
+######################################################################
+
+def conjugate_cc(N):
+ op = gr.conjugate_cc()
+ tb = helper(N, op, gr.sizeof_gr_complex, gr.sizeof_gr_complex, 1, 1)
+ return tb
+
+######################################################################
+
+def multiply_conjugate_cc(N):
+ try:
+ op = gr.multiply_conjugate_cc()
+ tb = helper(N, op, gr.sizeof_gr_complex, gr.sizeof_gr_complex, 2, 1)
+ return tb
+
+ except AttributeError:
+ class s(gr.hier_block2):
+ def __init__(self):
+ gr.hier_block2.__init__(self, "s",
+ gr.io_signature(2, 2, gr.sizeof_gr_complex),
+ gr.io_signature(1, 1, gr.sizeof_gr_complex))
+ conj = gr.conjugate_cc()
+ mult = gr.multiply_cc()
+ self.connect((self,0), (mult,0))
+ self.connect((self,1), conj, (mult,1))
+ self.connect(mult, self)
+
+ op = s()
+ tb = helper(N, op, gr.sizeof_gr_complex, gr.sizeof_gr_complex, 2, 1)
+ return tb
+
+
+######################################################################
+
+def run_tests(func, N, iters):
+ print("Running Test: {0}".format(func.__name__))
+ try:
+ tb = func(N)
+ t = timeit(tb, iters)
+ res = format_results(func.__name__, t)
+ return res
+ except AttributeError:
+ print "\tCould not run test. Skipping."
+ return None
+
+def main():
+ avail_tests = [multiply_const_cc,
+ multiply_const_ff,
+ multiply_cc,
+ multiply_ff,
+ add_ff,
+ conjugate_cc,
+ multiply_conjugate_cc]
+
+ desc='Time an operation to compare with other implementations. \
+ This program runs a simple GNU Radio flowgraph to test a \
+ particular math function, mostly to compare the \
+ Volk-optimized implementation versus a regular \
+ implementation. The results are stored to an SQLite database \
+ that can then be read by volk_plot.py to plot the differences.'
+ parser = argparse.ArgumentParser(description=desc)
+ parser.add_argument('-L', '--label', type=str,
+ required=True, default=None,
+ help='Label of database table [default: %(default)s]')
+ parser.add_argument('-D', '--database', type=str,
+ default="volk_results.db",
+ help='Database file to store data in [default: %(default)s]')
+ parser.add_argument('-N', '--nitems', type=float,
+ default=1e9,
+ help='Number of items per iterations [default: %(default)s]')
+ parser.add_argument('-I', '--iterations', type=int,
+ default=20,
+ help='Number of iterations [default: %(default)s]')
+ parser.add_argument('--tests', type=int, nargs='*',
+ choices=xrange(len(avail_tests)),
+ help='A list of tests to run; can be a single test or a \
+ space-separated list.')
+ parser.add_argument('--list', action='store_true',
+ help='List the available tests')
+ parser.add_argument('--all', action='store_true',
+ help='Run all tests')
+ args = parser.parse_args()
+
+ if(args.list):
+ print "Available Tests to Run:"
+ print "\n".join(["\t{0}: {1}".format(i,f.__name__) for i,f in enumerate(avail_tests)])
+ sys.exit(0)
+
+ N = int(args.nitems)
+ iters = args.iterations
+ label = args.label
+
+ conn = create_connection(args.database)
+ new_table(conn, label)
+
+ if args.all:
+ tests = xrange(len(avail_tests))
+ else:
+ tests = args.tests
+
+ for test in tests:
+ res = run_tests(avail_tests[test], N, iters)
+ if res is not None:
+ replace_results(conn, label, N, iters, res)
+
+if __name__ == "__main__":
+ try:
+ main()
+ except KeyboardInterrupt:
+ pass
diff --git a/gnuradio-core/src/examples/volk_benchmark/volk_plot.py b/gnuradio-core/src/examples/volk_benchmark/volk_plot.py
new file mode 100755
index 000000000..48f992205
--- /dev/null
+++ b/gnuradio-core/src/examples/volk_benchmark/volk_plot.py
@@ -0,0 +1,169 @@
+#!/usr/bin/env python
+
+import sys, math
+import argparse
+from volk_test_funcs import *
+
+try:
+ import matplotlib
+ import matplotlib.pyplot as plt
+except ImportError:
+ sys.stderr.write("Could not import Matplotlib (http://matplotlib.sourceforge.net/)\n")
+ sys.exit(1)
+
+def main():
+ desc='Plot Volk performance results from a SQLite database. ' + \
+ 'Run one of the volk tests first (e.g, volk_math.py)'
+ parser = argparse.ArgumentParser(description=desc)
+ parser.add_argument('-D', '--database', type=str,
+ default='volk_results.db',
+ help='Database file to read data from [default: %(default)s]')
+ parser.add_argument('-E', '--errorbars',
+ action='store_true', default=False,
+ help='Show error bars (1 standard dev.)')
+ parser.add_argument('-P', '--plot', type=str,
+ choices=['mean', 'min', 'max'],
+ default='mean',
+ help='Set the type of plot to produce [default: %(default)s]')
+ parser.add_argument('-%', '--percent', type=str,
+ default=None, metavar="table",
+ help='Show percent difference to the given type [default: %(default)s]')
+ args = parser.parse_args()
+
+ # Set up global plotting properties
+ matplotlib.rcParams['figure.subplot.bottom'] = 0.2
+ matplotlib.rcParams['figure.subplot.top'] = 0.95
+ matplotlib.rcParams['figure.subplot.right'] = 0.98
+ matplotlib.rcParams['ytick.labelsize'] = 16
+ matplotlib.rcParams['xtick.labelsize'] = 16
+ matplotlib.rcParams['legend.fontsize'] = 18
+
+ # Get list of tables to compare
+ conn = create_connection(args.database)
+ tables = list_tables(conn)
+ M = len(tables)
+
+ # Colors to distinguish each table in the bar graph
+ # More than 5 tables will wrap around to the start.
+ colors = ['b', 'r', 'g', 'm', 'k']
+
+ # Set up figure for plotting
+ f0 = plt.figure(0, facecolor='w', figsize=(14,10))
+ s0 = f0.add_subplot(1,1,1)
+
+ # Create a register of names that exist in all tables
+ tmp_regs = []
+ for table in tables:
+ # Get results from the next table
+ res = get_results(conn, table[0])
+
+ tmp_regs.append(list())
+ for r in res:
+ try:
+ tmp_regs[-1].index(r['kernel'])
+ except ValueError:
+ tmp_regs[-1].append(r['kernel'])
+
+ # Get only those names that are common in all tables
+ name_reg = tmp_regs[0]
+ for t in tmp_regs[1:]:
+ name_reg = list(set(name_reg) & set(t))
+ name_reg.sort()
+
+ # Pull the data out for each table into a dictionary
+ # we can ref the table by it's name and the data associated
+ # with a given kernel in name_reg by it's name.
+ # This ensures there is no sorting issue with the data in the
+ # dictionary, so the kernels are plotted against each other.
+ table_data = dict()
+ for i,table in enumerate(tables):
+ # Get results from the next table
+ res = get_results(conn, table[0])
+
+ data = dict()
+ for r in res:
+ data[r['kernel']] = r
+
+ table_data[table[0]] = data
+
+ if args.percent is not None:
+ for i,t in enumerate(table_data):
+ if args.percent == t:
+ norm_data = []
+ for name in name_reg:
+ if(args.plot == 'max'):
+ norm_data.append(table_data[t][name]['max'])
+ elif(args.plot == 'min'):
+ norm_data.append(table_data[t][name]['min'])
+ elif(args.plot == 'mean'):
+ norm_data.append(table_data[t][name]['avg'])
+
+
+ # Plot the results
+ x0 = xrange(len(name_reg))
+ i = 0
+ for t in (table_data):
+ ydata = []
+ stds = []
+ for name in name_reg:
+ stds.append(math.sqrt(table_data[t][name]['var']))
+ if(args.plot == 'max'):
+ ydata.append(table_data[t][name]['max'])
+ elif(args.plot == 'min'):
+ ydata.append(table_data[t][name]['min'])
+ elif(args.plot == 'mean'):
+ ydata.append(table_data[t][name]['avg'])
+
+ if args.percent is not None:
+ ydata = [-100*(y-n)/y for y,n in zip(ydata,norm_data)]
+ if(args.percent != t):
+ # makes x values for this data set placement
+ # width of bars depends on number of comparisons
+ wdth = 0.80/(M-1)
+ x1 = [x + i*wdth for x in x0]
+ i += 1
+
+ s0.bar(x1, ydata, width=wdth,
+ color=colors[(i-1)%M], label=t,
+ edgecolor='k', linewidth=2)
+
+ else:
+ # makes x values for this data set placement
+ # width of bars depends on number of comparisons
+ wdth = 0.80/M
+ x1 = [x + i*wdth for x in x0]
+ i += 1
+
+ if(args.errorbars is False):
+ s0.bar(x1, ydata, width=wdth,
+ color=colors[(i-1)%M], label=t,
+ edgecolor='k', linewidth=2)
+ else:
+ s0.bar(x1, ydata, width=wdth,
+ yerr=stds,
+ color=colors[i%M], label=t,
+ edgecolor='k', linewidth=2,
+ error_kw={"ecolor": 'k', "capsize":5,
+ "linewidth":2})
+
+ nitems = res[0]['nitems']
+ if args.percent is None:
+ s0.set_ylabel("Processing time (sec) [{0:G} items]".format(nitems),
+ fontsize=22, fontweight='bold',
+ horizontalalignment='center')
+ else:
+ s0.set_ylabel("% Improvement over {0} [{1:G} items]".format(
+ args.percent, nitems),
+ fontsize=22, fontweight='bold')
+
+ s0.legend()
+ s0.set_xticks(x0)
+ s0.set_xticklabels(name_reg)
+ for label in s0.xaxis.get_ticklabels():
+ label.set_rotation(45)
+ label.set_fontsize(16)
+
+ plt.show()
+
+if __name__ == "__main__":
+ main()
diff --git a/gnuradio-core/src/examples/volk_benchmark/volk_test_funcs.py b/gnuradio-core/src/examples/volk_benchmark/volk_test_funcs.py
new file mode 100644
index 000000000..0ce25fcc6
--- /dev/null
+++ b/gnuradio-core/src/examples/volk_benchmark/volk_test_funcs.py
@@ -0,0 +1,171 @@
+#!/usr/bin/env python
+
+from gnuradio import gr
+import math, sys, os, time
+
+try:
+ import scipy
+except ImportError:
+ sys.stderr.write("Unable to import Scipy (www.scipy.org)\n")
+ sys.exit(1)
+
+try:
+ import sqlite3
+except ImportError:
+ sys.stderr.write("Unable to import sqlite3: requires Python 2.5\n")
+ sys.exit(1)
+
+def execute(conn, cmd):
+ '''
+ Executes the command cmd to the database opened in connection conn.
+ '''
+ c = conn.cursor()
+ c.execute(cmd)
+ conn.commit()
+ c.close()
+
+def create_connection(database):
+ '''
+ Returns a connection object to the SQLite database.
+ '''
+ return sqlite3.connect(database)
+
+def new_table(conn, tablename):
+ '''
+ Create a new table for results.
+ All results are in the form: [kernel | nitems | iters | avg. time | variance | max time | min time ]
+ Each table is meant as a different setting (e.g., volk_aligned, volk_unaligned, etc.)
+ '''
+ cols = "kernel text, nitems int, iters int, avg real, var real, max real, min real"
+ cmd = "create table if not exists {0} ({1})".format(
+ tablename, cols)
+ execute(conn, cmd)
+
+def replace_results(conn, tablename, nitems, iters, res):
+ '''
+ Inserts or replaces the results 'res' dictionary values into the table.
+ This deletes all old entries of the kernel in this table.
+ '''
+ cmd = "DELETE FROM {0} where kernel='{1}'".format(tablename, res["kernel"])
+ execute(conn, cmd)
+ insert_results(conn, tablename, nitems, iters, res)
+
+def insert_results(conn, tablename, nitems, iters, res):
+ '''
+ Inserts the results dictionary values into the table.
+ '''
+ cols = "kernel, nitems, iters, avg, var, max, min"
+ cmd = "INSERT INTO {0} ({1}) VALUES ('{2}', {3}, {4}, {5}, {6}, {7}, {8})".format(
+ tablename, cols, res["kernel"], nitems, iters,
+ res["avg"], res["var"], res["max"], res["min"])
+ execute(conn, cmd)
+
+def list_tables(conn):
+ '''
+ Returns a list of all tables in the database.
+ '''
+ cmd = "SELECT name FROM sqlite_master WHERE type='table' ORDER BY name"
+ c = conn.cursor()
+ c.execute(cmd)
+ t = c.fetchall()
+ c.close()
+
+ return t
+
+def get_results(conn, tablename):
+ '''
+ Gets all results in tablename.
+ '''
+ cmd = "SELECT * FROM {0}".format(tablename)
+ c = conn.cursor()
+ c.execute(cmd)
+ fetched = c.fetchall()
+ c.close()
+
+ res = list()
+ for f in fetched:
+ r = dict()
+ r['kernel'] = f[0]
+ r['nitems'] = f[1]
+ r['iters'] = f[2]
+ r['avg'] = f[3]
+ r['var'] = f[4]
+ r['min'] = f[5]
+ r['max'] = f[6]
+ res.append(r)
+
+ return res
+
+
+class helper(gr.top_block):
+ '''
+ Helper function to run the tests. The parameters are:
+ N: number of items to process (int)
+ op: The GR block/hier_block to test
+ isizeof: the sizeof the input type
+ osizeof: the sizeof the output type
+ nsrcs: number of inputs to the op
+ nsnks: number of outputs of the op
+
+ This function can only handle blocks where all inputs are the same
+ datatype and all outputs are the same data type
+ '''
+ def __init__(self, N, op,
+ isizeof=gr.sizeof_gr_complex,
+ osizeof=gr.sizeof_gr_complex,
+ nsrcs=1, nsnks=1):
+ gr.top_block.__init__(self, "helper")
+
+ self.op = op
+ self.srcs = []
+ self.snks = []
+ self.head = gr.head(isizeof, N)
+
+ for n in xrange(nsrcs):
+ self.srcs.append(gr.null_source(isizeof))
+
+ for n in xrange(nsnks):
+ self.snks.append(gr.null_sink(osizeof))
+
+ self.connect(self.srcs[0], self.head, (self.op,0))
+
+ for n in xrange(1, nsrcs):
+ self.connect(self.srcs[n], (self.op,n))
+
+ for n in xrange(nsnks):
+ self.connect((self.op,n), self.snks[n])
+
+def timeit(tb, iterations):
+ '''
+ Given a top block, this function times it for a number of
+ iterations and stores the time in a list that is returned.
+ '''
+ r = gr.enable_realtime_scheduling()
+ if r != gr.RT_OK:
+ print "Warning: failed to enable realtime scheduling"
+
+ times = []
+ for i in xrange(iterations):
+ start_time = time.time()
+ tb.run()
+ end_time = time.time()
+ tb.head.reset()
+
+ times.append(end_time - start_time)
+
+ return times
+
+def format_results(kernel, times):
+ '''
+ Convinience function to convert the results of the timeit function
+ into a dictionary.
+ '''
+ res = dict()
+ res["kernel"] = kernel
+ res["avg"] = scipy.mean(times)
+ res["var"] = scipy.var(times)
+ res["max"] = max(times)
+ res["min"] = min(times)
+ return res
+
+
diff --git a/gnuradio-core/src/examples/volk_benchmark/volk_types.py b/gnuradio-core/src/examples/volk_benchmark/volk_types.py
new file mode 100755
index 000000000..5dac23c53
--- /dev/null
+++ b/gnuradio-core/src/examples/volk_benchmark/volk_types.py
@@ -0,0 +1,182 @@
+#!/usr/bin/env python
+
+from gnuradio import gr
+import argparse
+from volk_test_funcs import *
+
+######################################################################
+
+def float_to_char(N):
+ op = gr.float_to_char()
+ tb = helper(N, op, gr.sizeof_float, gr.sizeof_char, 1, 1)
+ return tb
+
+######################################################################
+
+def float_to_int(N):
+ op = gr.float_to_int()
+ tb = helper(N, op, gr.sizeof_float, gr.sizeof_int, 1, 1)
+ return tb
+
+######################################################################
+
+def float_to_short(N):
+ op = gr.float_to_short()
+ tb = helper(N, op, gr.sizeof_float, gr.sizeof_short, 1, 1)
+ return tb
+
+######################################################################
+
+def short_to_float(N):
+ op = gr.short_to_float()
+ tb = helper(N, op, gr.sizeof_short, gr.sizeof_float, 1, 1)
+ return tb
+
+######################################################################
+
+def short_to_char(N):
+ op = gr.short_to_char()
+ tb = helper(N, op, gr.sizeof_short, gr.sizeof_char, 1, 1)
+ return tb
+
+######################################################################
+
+def char_to_short(N):
+ op = gr.char_to_short()
+ tb = helper(N, op, gr.sizeof_char, gr.sizeof_short, 1, 1)
+ return tb
+
+######################################################################
+
+def char_to_float(N):
+ op = gr.char_to_float()
+ tb = helper(N, op, gr.sizeof_char, gr.sizeof_float, 1, 1)
+ return tb
+
+######################################################################
+
+def int_to_float(N):
+ op = gr.int_to_float()
+ tb = helper(N, op, gr.sizeof_int, gr.sizeof_float, 1, 1)
+ return tb
+
+######################################################################
+
+def complex_to_float(N):
+ op = gr.complex_to_float()
+ tb = helper(N, op, gr.sizeof_gr_complex, gr.sizeof_float, 1, 2)
+ return tb
+
+######################################################################
+
+def complex_to_real(N):
+ op = gr.complex_to_real()
+ tb = helper(N, op, gr.sizeof_gr_complex, gr.sizeof_float, 1, 1)
+ return tb
+
+######################################################################
+
+def complex_to_imag(N):
+ op = gr.complex_to_imag()
+ tb = helper(N, op, gr.sizeof_gr_complex, gr.sizeof_float, 1, 1)
+ return tb
+
+######################################################################
+
+def complex_to_mag(N):
+ op = gr.complex_to_mag()
+ tb = helper(N, op, gr.sizeof_gr_complex, gr.sizeof_float, 1, 1)
+ return tb
+
+######################################################################
+
+def complex_to_mag_squared(N):
+ op = gr.complex_to_mag_squared()
+ tb = helper(N, op, gr.sizeof_gr_complex, gr.sizeof_float, 1, 1)
+ return tb
+
+######################################################################
+
+
+def run_tests(func, N, iters):
+ print("Running Test: {0}".format(func.__name__))
+ try:
+ tb = func(N)
+ t = timeit(tb, iters)
+ res = format_results(func.__name__, t)
+ return res
+ except AttributeError:
+ print "\tCould not run test. Skipping."
+ return None
+
+def main():
+ avail_tests = [float_to_char,
+ float_to_int,
+ float_to_short,
+ short_to_float,
+ short_to_char,
+ char_to_short,
+ char_to_float,
+ int_to_float,
+ complex_to_float,
+ complex_to_real,
+ complex_to_imag,
+ complex_to_mag,
+ complex_to_mag_squared]
+
+ desc='Time an operation to compare with other implementations. \
+ This program runs a simple GNU Radio flowgraph to test a \
+ particular math function, mostly to compare the \
+ Volk-optimized implementation versus a regular \
+ implementation. The results are stored to an SQLite database \
+ that can then be read by volk_plot.py to plot the differences.'
+ parser = argparse.ArgumentParser(description=desc)
+ parser.add_argument('-L', '--label', type=str,
+ required=True, default=None,
+ help='Label of database table [default: %(default)s]')
+ parser.add_argument('-D', '--database', type=str,
+ default="volk_results.db",
+ help='Database file to store data in [default: %(default)s]')
+ parser.add_argument('-N', '--nitems', type=float,
+ default=1e9,
+ help='Number of items per iterations [default: %(default)s]')
+ parser.add_argument('-I', '--iterations', type=int,
+ default=20,
+ help='Number of iterations [default: %(default)s]')
+ parser.add_argument('--tests', type=int, nargs='*',
+ choices=xrange(len(avail_tests)),
+ help='A list of tests to run; can be a single test or a \
+ space-separated list.')
+ parser.add_argument('--list', action='store_true',
+ help='List the available tests')
+ parser.add_argument('--all', action='store_true',
+ help='Run all tests')
+ args = parser.parse_args()
+
+ if(args.list):
+ print "Available Tests to Run:"
+ print "\n".join(["\t{0}: {1}".format(i,f.__name__) for i,f in enumerate(avail_tests)])
+ sys.exit(0)
+
+ N = int(args.nitems)
+ iters = args.iterations
+ label = args.label
+
+ conn = create_connection(args.database)
+ new_table(conn, label)
+
+ if args.all:
+ tests = xrange(len(avail_tests))
+ else:
+ tests = args.tests
+
+ for test in tests:
+ res = run_tests(avail_tests[test], N, iters)
+ if res is not None:
+ replace_results(conn, label, N, iters, res)
+
+if __name__ == "__main__":
+ try:
+ main()
+ except KeyboardInterrupt:
+ pass
diff --git a/gnuradio-core/src/gen_interpolator_taps/Makefile.am.obsolete b/gnuradio-core/src/gen_interpolator_taps/Makefile.am.obsolete
new file mode 100644
index 000000000..cd0edaf5c
--- /dev/null
+++ b/gnuradio-core/src/gen_interpolator_taps/Makefile.am.obsolete
@@ -0,0 +1,39 @@
+#
+# Copyright 2002 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+include $(top_srcdir)/Makefile.common
+
+EXTRA_DIST += \
+ praxis.txt \
+ simpson.h \
+ objective_fct.c \
+ gen_interpolator_taps.c \
+ simpson.c \
+ praxis.f
+
+# if ENABLE_FORTRAN
+# noinst_PROGRAMS = gen_interpolator_taps
+# noinst_HEADERS = simpson.h
+#
+# gen_interpolator_taps_SOURCES = gen_interpolator_taps.c objective_fct.c simpson.c praxis.f
+# gen_interpolator_taps_LDADD = $(FLIBS) -lm
+#
+# endif
diff --git a/gnuradio-core/src/gen_interpolator_taps/README b/gnuradio-core/src/gen_interpolator_taps/README
new file mode 100644
index 000000000..8fe3e2ba3
--- /dev/null
+++ b/gnuradio-core/src/gen_interpolator_taps/README
@@ -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 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+
+This 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
index 000000000..2f359102c
--- /dev/null
+++ b/gnuradio-core/src/gen_interpolator_taps/gen_interpolator_taps.c
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <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
index 000000000..129486d63
--- /dev/null
+++ b/gnuradio-core/src/gen_interpolator_taps/objective_fct.c
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+/*
+ * generate 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
index 000000000..9f3e03c97
--- /dev/null
+++ b/gnuradio-core/src/gen_interpolator_taps/praxis.f
@@ -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 3, 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., 51 Franklin Street,
+C Boston, MA 02110-1301, 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
index 000000000..9d0606566
--- /dev/null
+++ b/gnuradio-core/src/gen_interpolator_taps/praxis.txt
@@ -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
index 000000000..31aaae4ae
--- /dev/null
+++ b/gnuradio-core/src/gen_interpolator_taps/simpson.c
@@ -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
index 000000000..68774f9a2
--- /dev/null
+++ b/gnuradio-core/src/gen_interpolator_taps/simpson.h
@@ -0,0 +1,3 @@
+double qsimp (double (*func)(double),
+ double a, double b);
+
diff --git a/gnuradio-core/src/lib/CMakeLists.txt b/gnuradio-core/src/lib/CMakeLists.txt
new file mode 100644
index 000000000..c061a5723
--- /dev/null
+++ b/gnuradio-core/src/lib/CMakeLists.txt
@@ -0,0 +1,106 @@
+# Copyright 2010-2011 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+
+########################################################################
+# Setup compatibility checks and defines
+########################################################################
+include(${CMAKE_CURRENT_SOURCE_DIR}/ConfigChecks.cmake)
+
+########################################################################
+# Include subdirs rather to populate to the sources lists.
+########################################################################
+GR_INCLUDE_SUBDIRECTORY(missing)
+GR_INCLUDE_SUBDIRECTORY(runtime)
+GR_INCLUDE_SUBDIRECTORY(filter)
+GR_INCLUDE_SUBDIRECTORY(viterbi)
+GR_INCLUDE_SUBDIRECTORY(general)
+GR_INCLUDE_SUBDIRECTORY(gengen)
+GR_INCLUDE_SUBDIRECTORY(reed-solomon)
+GR_INCLUDE_SUBDIRECTORY(io)
+GR_INCLUDE_SUBDIRECTORY(hier)
+
+list(APPEND gnuradio_core_sources bug_work_around_6.cc)
+list(APPEND test_gnuradio_core_sources bug_work_around_6.cc)
+
+########################################################################
+# Setup the include and linker paths
+########################################################################
+include_directories(
+ ${GNURADIO_CORE_INCLUDE_DIRS}
+ ${VOLK_INCLUDE_DIRS}
+ ${GRUEL_INCLUDE_DIRS}
+ ${Boost_INCLUDE_DIRS}
+ ${FFTW3F_INCLUDE_DIRS}
+)
+
+link_directories(
+ ${Boost_LIBRARY_DIRS}
+ ${FFTW3F_LIBRARY_DIRS}
+)
+
+########################################################################
+# Setup library
+########################################################################
+list(APPEND gnuradio_core_libs
+ gruel
+ ${Boost_LIBRARIES}
+ ${FFTW3F_LIBRARIES}
+)
+
+if(FFTW3F_THREADS_LIBRARIES)
+ list(APPEND gnuradio_core_libs ${FFTW3F_THREADS_LIBRARIES} )
+ add_definitions("-DFFTW3F_THREADS")
+endif()
+
+#need to link with librt on ubuntu 11.10 for shm_*
+if(LINUX)
+ list(APPEND gnuradio_core_libs rt)
+endif()
+
+# Link against libvolk
+list(APPEND gnuradio_core_libs volk)
+
+add_library(gnuradio-core SHARED ${gnuradio_core_sources})
+target_link_libraries(gnuradio-core ${gnuradio_core_libs})
+GR_LIBRARY_FOO(gnuradio-core RUNTIME_COMPONENT "core_runtime" DEVEL_COMPONENT "core_devel")
+set_target_properties(gnuradio-core PROPERTIES LINK_INTERFACE_LIBRARIES "gruel")
+
+########################################################################
+# Setup executables
+########################################################################
+add_executable(gnuradio-config-info gnuradio-config-info.cc)
+target_link_libraries(gnuradio-config-info gnuradio-core ${Boost_LIBRARIES})
+install(
+ TARGETS gnuradio-config-info
+ DESTINATION ${GR_RUNTIME_DIR}
+ COMPONENT "core_runtime"
+)
+
+########################################################################
+# Setup tests
+########################################################################
+if(ENABLE_TESTING)
+
+include_directories(${CPPUNIT_INCLUDE_DIRS})
+link_directories(${CPPUNIT_LIBRARY_DIRS})
+
+add_library(test-gnuradio-core SHARED ${test_gnuradio_core_sources})
+target_link_libraries(test-gnuradio-core ${GR_TEST_TARGET_DEPS} ${CPPUNIT_LIBRARIES} ${Boost_LIBRARIES})
+
+endif(ENABLE_TESTING)
diff --git a/gnuradio-core/src/lib/ConfigChecks.cmake b/gnuradio-core/src/lib/ConfigChecks.cmake
new file mode 100644
index 000000000..26b778a7a
--- /dev/null
+++ b/gnuradio-core/src/lib/ConfigChecks.cmake
@@ -0,0 +1,212 @@
+# Copyright 2010-2011 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+
+########################################################################
+INCLUDE(GrMiscUtils)
+INCLUDE(CheckCXXSourceCompiles)
+
+IF(MSVC) #add this directory for our provided headers
+LIST(APPEND CMAKE_REQUIRED_INCLUDES ${CMAKE_SOURCE_DIR}/msvc)
+ENDIF(MSVC)
+
+GR_CHECK_HDR_N_DEF(netdb.h HAVE_NETDB_H)
+GR_CHECK_HDR_N_DEF(sys/time.h HAVE_SYS_TIME_H)
+GR_CHECK_HDR_N_DEF(sys/types.h HAVE_SYS_TYPES_H)
+GR_CHECK_HDR_N_DEF(sys/select.h HAVE_SYS_SELECT_H)
+GR_CHECK_HDR_N_DEF(sys/socket.h HAVE_SYS_SOCKET_H)
+GR_CHECK_HDR_N_DEF(io.h HAVE_IO_H)
+GR_CHECK_HDR_N_DEF(sys/mman.h HAVE_SYS_MMAN_H)
+GR_CHECK_HDR_N_DEF(sys/ipc.h HAVE_SYS_IPC_H)
+GR_CHECK_HDR_N_DEF(sys/shm.h HAVE_SYS_SHM_H)
+GR_CHECK_HDR_N_DEF(signal.h HAVE_SIGNAL_H)
+GR_CHECK_HDR_N_DEF(netinet/in.h HAVE_NETINET_IN_H)
+GR_CHECK_HDR_N_DEF(arpa/inet.h HAVE_ARPA_INET_H)
+GR_CHECK_HDR_N_DEF(byteswap.h HAVE_BYTESWAP_H)
+GR_CHECK_HDR_N_DEF(linux/ppdev.h HAVE_LINUX_PPDEV_H)
+GR_CHECK_HDR_N_DEF(dev/ppbus/ppi.h HAVE_DEV_PPBUS_PPI_H)
+GR_CHECK_HDR_N_DEF(unistd.h HAVE_UNISTD_H)
+GR_CHECK_HDR_N_DEF(malloc.h HAVE_MALLOC_H)
+
+
+########################################################################
+CHECK_CXX_SOURCE_COMPILES("
+ #include <stdio.h>
+ int main(){snprintf(0, 0, 0); return 0;}
+ " HAVE_SNPRINTF
+)
+GR_ADD_COND_DEF(HAVE_SNPRINTF)
+
+########################################################################
+CHECK_CXX_SOURCE_COMPILES("
+ #include <signal.h>
+ int main(){sigaction(0, 0, 0); return 0;}
+ " HAVE_SIGACTION
+)
+GR_ADD_COND_DEF(HAVE_SIGACTION)
+
+########################################################################
+CHECK_CXX_SOURCE_COMPILES("
+ #include <sys/select.h>
+ int main(){select(0, 0, 0, 0, 0); return 0;}
+ " HAVE_SELECT
+)
+GR_ADD_COND_DEF(HAVE_SELECT)
+
+
+########################################################################
+CHECK_CXX_SOURCE_COMPILES("
+ #include <unistd.h>
+ int main(){sysconf(0); return 0;}
+ " HAVE_SYSCONF
+)
+GR_ADD_COND_DEF(HAVE_SYSCONF)
+
+CHECK_CXX_SOURCE_COMPILES("
+ #include <unistd.h>
+ int main(){getpagesize(); return 0;}
+ " HAVE_GETPAGESIZE
+)
+GR_ADD_COND_DEF(HAVE_GETPAGESIZE)
+
+
+########################################################################
+CHECK_CXX_SOURCE_COMPILES("
+ #include <Winbase.h>
+ int main(){Sleep(0); return 0;}
+ " HAVE_SSLEEP
+)
+GR_ADD_COND_DEF(HAVE_SSLEEP)
+
+CHECK_CXX_SOURCE_COMPILES("
+ #include <time.h>
+ int main(){nanosleep(0, 0); return 0;}
+ " HAVE_NANOSLEEP
+)
+GR_ADD_COND_DEF(HAVE_NANOSLEEP)
+
+CHECK_CXX_SOURCE_COMPILES("
+ #include <sys/time.h>
+ int main(){gettimeofday(0, 0); return 0;}
+ " HAVE_GETTIMEOFDAY
+)
+GR_ADD_COND_DEF(HAVE_GETTIMEOFDAY)
+
+########################################################################
+CHECK_CXX_SOURCE_COMPILES("
+ #include <stdlib.h>
+ int main(){posix_memalign(0, 0, 0); return 0;}
+ " HAVE_POSIX_MEMALIGN
+)
+GR_ADD_COND_DEF(HAVE_POSIX_MEMALIGN)
+
+CHECK_CXX_SOURCE_COMPILES("
+ #include <malloc.h>
+ int main(){valloc(0); return 0;}
+ " HAVE_VALLOC
+)
+GR_ADD_COND_DEF(HAVE_VALLOC)
+
+ADD_DEFINITIONS(-DALIGNED_MALLOC=0)
+
+########################################################################
+SET(CMAKE_REQUIRED_LIBRARIES -lpthread)
+CHECK_CXX_SOURCE_COMPILES("
+ #include <signal.h>
+ int main(){pthread_sigmask(0, 0, 0); return 0;}
+ " HAVE_PTHREAD_SIGMASK
+)
+GR_ADD_COND_DEF(HAVE_PTHREAD_SIGMASK)
+SET(CMAKE_REQUIRED_LIBRARIES)
+
+########################################################################
+CHECK_CXX_SOURCE_COMPILES("
+ #include <windows.h>
+ int main(){
+ HANDLE handle;
+ int size;
+ LPCTSTR lpName;
+ handle = CreateFileMapping(
+ INVALID_HANDLE_VALUE, // use paging file
+ NULL, // default security
+ PAGE_READWRITE, // read/write access
+ 0, // max. object size
+ size, // buffer size
+ lpName); // name of mapping object
+ return 0;
+ } " HAVE_CREATEFILEMAPPING
+)
+GR_ADD_COND_DEF(HAVE_CREATEFILEMAPPING)
+
+########################################################################
+CHECK_INCLUDE_FILE_CXX(windows.h HAVE_WINDOWS_H)
+IF(HAVE_WINDOWS_H)
+ ADD_DEFINITIONS(-DHAVE_WINDOWS_H -DUSING_WINSOCK)
+ MESSAGE(STATUS "Adding windows libs to gnuradio core libs...")
+ LIST(APPEND gnuradio_core_libs WS2_32.lib WSock32.lib)
+ENDIF(HAVE_WINDOWS_H)
+
+########################################################################
+SET(CMAKE_REQUIRED_LIBRARIES -lrt)
+CHECK_CXX_SOURCE_COMPILES("
+ #include <sys/types.h>
+ #include <sys/mman.h>
+ int main(){shm_open(0, 0, 0); return 0;}
+ " HAVE_SHM_OPEN
+)
+GR_ADD_COND_DEF(HAVE_SHM_OPEN)
+SET(CMAKE_REQUIRED_LIBRARIES)
+
+########################################################################
+CHECK_CXX_SOURCE_COMPILES("
+ #define _GNU_SOURCE
+ #include <math.h>
+ int main(){double x, sin, cos; sincos(x, &sin, &cos); return 0;}
+ " HAVE_SINCOS
+)
+GR_ADD_COND_DEF(HAVE_SINCOS)
+
+CHECK_CXX_SOURCE_COMPILES("
+ #define _GNU_SOURCE
+ #include <math.h>
+ int main(){float x, sin, cos; sincosf(x, &sin, &cos); return 0;}
+ " HAVE_SINCOSF
+)
+GR_ADD_COND_DEF(HAVE_SINCOSF)
+
+CHECK_CXX_SOURCE_COMPILES("
+ #include <math.h>
+ int main(){sinf(0); return 0;}
+ " HAVE_SINF
+)
+GR_ADD_COND_DEF(HAVE_SINF)
+
+CHECK_CXX_SOURCE_COMPILES("
+ #include <math.h>
+ int main(){cosf(0); return 0;}
+ " HAVE_COSF
+)
+GR_ADD_COND_DEF(HAVE_COSF)
+
+########################################################################
+CHECK_CXX_SOURCE_COMPILES("
+ #include <sys/mman.h>
+ int main(){mmap(0, 0, 0, 0, 0, 0); return 0;}
+ " HAVE_MMAP
+)
+GR_ADD_COND_DEF(HAVE_MMAP)
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
index 000000000..f8012af0d
--- /dev/null
+++ b/gnuradio-core/src/lib/bug_work_around_6.cc
@@ -0,0 +1,3 @@
+// if libgrio has no sources, it doesn't get built correctly
+#include <gruel/attributes.h>
+static int gr_bug_work_around_6 __GR_ATTR_UNUSED;
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
index 000000000..546a4a6f3
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/3dnow_float_dotprod_really_simple.S
@@ -0,0 +1,99 @@
+#
+# Copyright 2002 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, 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"
+
+#if defined(__linux__) && defined(__ELF__)
+.section .note.GNU-stack,"",%progbits
+#endif
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
index 000000000..c721c3601
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/3dnow_float_dotprod_simple.S
@@ -0,0 +1,106 @@
+#
+# Copyright 2002 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, 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"
+
+#if defined(__linux__) && defined(__ELF__)
+.section .note.GNU-stack,"",%progbits
+#endif
diff --git a/gnuradio-core/src/lib/filter/CMakeLists.txt b/gnuradio-core/src/lib/filter/CMakeLists.txt
new file mode 100644
index 000000000..088d3376d
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/CMakeLists.txt
@@ -0,0 +1,357 @@
+# Copyright 2010-2011 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+
+########################################################################
+# This file included, use CMake directory variables
+########################################################################
+
+#set the C language property on the assembly files so the compiler will pick them up
+file(GLOB gr_core_filter_asms ${CMAKE_CURRENT_SOURCE_DIR}/*.S)
+foreach(gr_core_filter_asm ${gr_core_filter_asms})
+ set_property(SOURCE ${gr_core_filter_asm} PROPERTY LANGUAGE C)
+endforeach(gr_core_filter_asm)
+
+#detect 32 or 64 bit compiler
+if(CMAKE_SYSTEM_PROCESSOR MATCHES "^(i.86|x86|x86_64|amd64)$")
+ include(CheckTypeSize)
+ check_type_size("void*" SIZEOF_VOID_P BUILTIN_TYPES_ONLY)
+ if (${SIZEOF_VOID_P} EQUAL 8)
+ set(CMAKE_SYSTEM_PROCESSOR_x86 64)
+ else()
+ set(CMAKE_SYSTEM_PROCESSOR_x86 32)
+ endif()
+endif()
+
+########################################################################
+# Generate the makefile.gen, then extract its sources:
+# This is a round-about way to extract the sources,
+# but it requires minimum changed to the python utils.
+#
+# The recommended way to do this:
+# - Make a generation macro that registers the sources command.
+# - List the generation macro with each templated source file.
+# - Create a python script (very generic) to perform generation.
+# - This way the targets would depend only on their sources.
+########################################################################
+execute_process(
+ COMMAND ${PYTHON_EXECUTABLE} ${PYTHON_DASH_B} -c "
+import os, sys
+sys.path.append('${GR_CORE_PYTHONPATH}')
+sys.path.append('${CMAKE_CURRENT_SOURCE_DIR}')
+os.environ['srcdir'] = '${CMAKE_CURRENT_SOURCE_DIR}'
+os.environ['gendir'] = '${CMAKE_CURRENT_BINARY_DIR}'
+os.environ['do_makefile'] = '1'
+os.environ['do_sources'] = '0'
+from generate_all import generate_all
+generate_all()
+ " WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
+)
+
+macro(FILTER_GEN_EXTRACT outvar ext)
+ execute_process(COMMAND ${PYTHON_EXECUTABLE} -c "import os; print ';'.join(
+ map(lambda x: os.path.join('${CMAKE_CURRENT_BINARY_DIR}', x.replace('\\\\', '').strip()),
+ filter(lambda f: '${ext}' in f, open('${CMAKE_CURRENT_BINARY_DIR}/Makefile.gen').readlines()
+ )))" OUTPUT_STRIP_TRAILING_WHITESPACE OUTPUT_VARIABLE ${outvar})
+ file(TO_CMAKE_PATH "${${outvar}}" ${outvar})
+endmacro(FILTER_GEN_EXTRACT)
+
+FILTER_GEN_EXTRACT(generated_filter_sources ".cc")
+FILTER_GEN_EXTRACT(generated_filter_includes ".h")
+FILTER_GEN_EXTRACT(generated_filter_swigs ".i")
+
+#TODO simplify this list with a triple-threat for loop
+set(generated_filter_deps
+ ${CMAKE_CURRENT_SOURCE_DIR}/generate_all.py
+ ${CMAKE_CURRENT_SOURCE_DIR}/generate_gr_fir_XXX.py
+ ${CMAKE_CURRENT_SOURCE_DIR}/generate_gr_fir_filter_XXX.py
+ ${CMAKE_CURRENT_SOURCE_DIR}/generate_gr_interp_fir_filter_XXX.py
+ ${CMAKE_CURRENT_SOURCE_DIR}/generate_gr_rational_resampler_base_XXX.py
+ ${CMAKE_CURRENT_SOURCE_DIR}/generate_gr_fir_sysconfig.py
+ ${CMAKE_CURRENT_SOURCE_DIR}/generate_gr_fir_sysconfig_generic.py
+ ${CMAKE_CURRENT_SOURCE_DIR}/generate_gr_fir_util.py
+ ${CMAKE_CURRENT_SOURCE_DIR}/generate_gr_freq_xlating_fir_filter_XXX.py
+ ${CMAKE_CURRENT_SOURCE_DIR}/generate_gri_fir_filter_with_buffer_XXX.py
+ ${CMAKE_CURRENT_SOURCE_DIR}/generate_utils.py
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_fir_XXX.cc.t
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_fir_XXX.h.t
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_fir_XXX_generic.cc.t
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_fir_XXX_generic.h.t
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_fir_filter_XXX.cc.t
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_fir_filter_XXX.h.t
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_fir_filter_XXX.i.t
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_interp_fir_filter_XXX.cc.t
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_interp_fir_filter_XXX.h.t
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_interp_fir_filter_XXX.i.t
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_rational_resampler_base_XXX.cc.t
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_rational_resampler_base_XXX.h.t
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_rational_resampler_base_XXX.i.t
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_freq_xlating_fir_filter_XXX.cc.t
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_freq_xlating_fir_filter_XXX.h.t
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_freq_xlating_fir_filter_XXX.i.t
+ ${CMAKE_CURRENT_SOURCE_DIR}/gri_fir_filter_with_buffer_XXX.cc.t
+ ${CMAKE_CURRENT_SOURCE_DIR}/gri_fir_filter_with_buffer_XXX.h.t
+)
+
+add_custom_command(
+ OUTPUT
+ ${generated_filter_sources}
+ ${generated_filter_includes}
+ ${generated_filter_swigs}
+ DEPENDS ${generated_filter_deps}
+ COMMAND ${PYTHON_EXECUTABLE} ${PYTHON_DASH_B} -c
+ "import os, sys;sys.path.append('${GR_CORE_PYTHONPATH}');sys.path.append('${CMAKE_CURRENT_SOURCE_DIR}');os.environ['srcdir'] = '${CMAKE_CURRENT_SOURCE_DIR}';from generate_all import generate_all;generate_all()"
+ WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
+ COMMENT "generating filter files"
+ VERBATIM
+)
+
+add_custom_target(filter_generated DEPENDS
+ ${generated_filter_sources}
+ ${generated_filter_includes}
+ ${generated_filter_swigs}
+)
+
+########################################################################
+# Add target specific files
+# May VOLK put a rest to all the insanity below.
+########################################################################
+if(MSVC)
+ list(APPEND gnuradio_core_sources
+ ${CMAKE_CURRENT_SOURCE_DIR}/sysconfig_generic.cc
+ )
+ list(APPEND test_gnuradio_core_sources
+ ${CMAKE_CURRENT_SOURCE_DIR}/qa_dotprod_generic.cc
+ )
+else(MSVC)
+if(CMAKE_SYSTEM_PROCESSOR_x86)
+ list(APPEND gnuradio_core_sources
+ ${CMAKE_CURRENT_SOURCE_DIR}/sysconfig_x86.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_fir_sysconfig_x86.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_cpu_x86.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_fir_ccc_simd.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_fir_ccc_x86.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_fir_fff_simd.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_fir_fff_x86.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_fir_fsf_simd.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_fir_fsf_x86.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_fir_scc_simd.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_fir_scc_x86.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_fir_fcc_simd.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_fir_fcc_x86.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_fir_ccf_simd.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_fir_ccf_x86.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/sse_debug.c
+ )
+ list(APPEND test_gnuradio_core_sources
+ ${CMAKE_CURRENT_SOURCE_DIR}/qa_dotprod_x86.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/qa_float_dotprod_x86.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/qa_complex_dotprod_x86.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/qa_ccomplex_dotprod_x86.cc
+ )
+endif()
+
+if(CMAKE_SYSTEM_PROCESSOR_x86 AND "${CMAKE_SYSTEM_PROCESSOR_x86}" STREQUAL "64")
+ list(APPEND gnuradio_core_sources
+ ${CMAKE_CURRENT_SOURCE_DIR}/float_dotprod_sse64.S
+ ${CMAKE_CURRENT_SOURCE_DIR}/float_dotprod_3dnow64.S
+ ${CMAKE_CURRENT_SOURCE_DIR}/complex_dotprod_3dnowext64.S
+ ${CMAKE_CURRENT_SOURCE_DIR}/complex_dotprod_3dnow64.S
+ ${CMAKE_CURRENT_SOURCE_DIR}/complex_dotprod_sse64.S
+ ${CMAKE_CURRENT_SOURCE_DIR}/ccomplex_dotprod_3dnowext64.S
+ ${CMAKE_CURRENT_SOURCE_DIR}/ccomplex_dotprod_3dnow64.S
+ ${CMAKE_CURRENT_SOURCE_DIR}/ccomplex_dotprod_sse64.S
+ ${CMAKE_CURRENT_SOURCE_DIR}/fcomplex_dotprod_3dnow64.S
+ ${CMAKE_CURRENT_SOURCE_DIR}/fcomplex_dotprod_sse64.S
+ ${CMAKE_CURRENT_SOURCE_DIR}/short_dotprod_mmx64.S
+ )
+elseif(CMAKE_SYSTEM_PROCESSOR_x86 AND "${CMAKE_SYSTEM_PROCESSOR_x86}" STREQUAL "32")
+ list(APPEND gnuradio_core_sources
+ ${CMAKE_CURRENT_SOURCE_DIR}/float_dotprod_sse.S
+ ${CMAKE_CURRENT_SOURCE_DIR}/float_dotprod_3dnow.S
+ ${CMAKE_CURRENT_SOURCE_DIR}/complex_dotprod_3dnowext.S
+ ${CMAKE_CURRENT_SOURCE_DIR}/complex_dotprod_3dnow.S
+ ${CMAKE_CURRENT_SOURCE_DIR}/complex_dotprod_sse.S
+ ${CMAKE_CURRENT_SOURCE_DIR}/ccomplex_dotprod_3dnowext.S
+ ${CMAKE_CURRENT_SOURCE_DIR}/ccomplex_dotprod_3dnow.S
+ ${CMAKE_CURRENT_SOURCE_DIR}/ccomplex_dotprod_sse.S
+ ${CMAKE_CURRENT_SOURCE_DIR}/fcomplex_dotprod_3dnow.S
+ ${CMAKE_CURRENT_SOURCE_DIR}/fcomplex_dotprod_sse.S
+ ${CMAKE_CURRENT_SOURCE_DIR}/short_dotprod_mmx.S
+ )
+elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^(powerpc|ppc)")
+ if(CMAKE_COMPILER_IS_GNUCXX)
+ add_definitions(-maltivec)
+ endif()
+ list(APPEND gnuradio_core_sources
+ ${CMAKE_CURRENT_SOURCE_DIR}/sysconfig_powerpc.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_fir_sysconfig_powerpc.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_cpu_powerpc.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_fir_fff_altivec.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_altivec.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/dotprod_fff_altivec.c
+ )
+ list(APPEND test_gnuradio_core_sources
+ ${CMAKE_CURRENT_SOURCE_DIR}/qa_dotprod_powerpc.cc
+ )
+elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^arm")
+ if(have_mfpu_neon)
+ add_definitions(-DHAVE_MFPU_NEON)
+ endif()
+ list(APPEND gnuradio_core_sources
+ ${CMAKE_CURRENT_SOURCE_DIR}/sysconfig_armv7_a.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_fir_sysconfig_armv7_a.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_cpu_armv7_a.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_fir_fff_armv7_a.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/dotprod_fff_armv7_a.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/dotprod_ccf_armv7_a.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_fir_ccf_armv7_a.cc
+ )
+ list(APPEND test_gnuradio_core_sources
+ ${CMAKE_CURRENT_SOURCE_DIR}/qa_dotprod_armv7_a.cc
+ )
+else()
+ list(APPEND gnuradio_core_sources
+ ${CMAKE_CURRENT_SOURCE_DIR}/sysconfig_generic.cc
+ )
+ list(APPEND test_gnuradio_core_sources
+ ${CMAKE_CURRENT_SOURCE_DIR}/qa_dotprod_generic.cc
+ )
+endif()
+endif(MSVC)
+
+########################################################################
+# Append gnuradio-core library sources
+########################################################################
+list(APPEND gnuradio_core_sources
+ ${generated_filter_sources}
+ ${CMAKE_CURRENT_SOURCE_DIR}/gri_fft_filter_fff_generic.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/gri_fft_filter_ccc_generic.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_sincos.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/gri_goertzel.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/gri_mmse_fir_interpolator.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/gri_mmse_fir_interpolator_cc.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/complex_dotprod_generic.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/ccomplex_dotprod_generic.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/float_dotprod_generic.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/short_dotprod_generic.c
+)
+
+########################################################################
+# Append gnuradio-core test sources
+########################################################################
+list(APPEND test_gnuradio_core_sources
+ ${CMAKE_CURRENT_SOURCE_DIR}/qa_filter.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/qa_gr_fir_ccf.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/qa_gr_fir_fcc.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/qa_gr_fir_fff.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/qa_gr_fir_ccc.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/qa_gr_fir_scc.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/qa_gr_rotator.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/qa_gri_mmse_fir_interpolator.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/qa_gri_mmse_fir_interpolator_cc.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/qa_gri_fir_filter_with_buffer_ccf.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/qa_gri_fir_filter_with_buffer_ccc.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/qa_gri_fir_filter_with_buffer_fcc.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/qa_gri_fir_filter_with_buffer_fff.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/qa_gri_fir_filter_with_buffer_fsf.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/qa_gri_fir_filter_with_buffer_scc.cc
+)
+
+########################################################################
+# Install runtime headers
+########################################################################
+install(FILES
+ ${generated_filter_includes}
+ ${CMAKE_CURRENT_SOURCE_DIR}/complex_dotprod_generic.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/complex_dotprod_x86.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/fcomplex_dotprod_x86.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/ccomplex_dotprod_generic.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/ccomplex_dotprod_x86.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/float_dotprod_generic.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/float_dotprod_x86.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_altivec.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_cpu.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/gri_fft_filter_fff_generic.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/gri_fft_filter_ccc_generic.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_fir_sysconfig_x86.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_fir_sysconfig_powerpc.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_rotator.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_sincos.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_single_pole_iir.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_vec_types.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/gri_goertzel.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/gri_iir.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/gri_mmse_fir_interpolator.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/gri_mmse_fir_interpolator_cc.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/qa_filter.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/short_dotprod_generic.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/short_dotprod_x86.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/sse_debug.h
+ DESTINATION ${GR_INCLUDE_DIR}/gnuradio
+ COMPONENT "core_devel"
+)
+
+########################################################################
+# Install swig headers
+########################################################################
+if(ENABLE_PYTHON)
+install(FILES
+ ${generated_filter_swigs}
+ ${CMAKE_CURRENT_SOURCE_DIR}/filter.i
+ ${CMAKE_CURRENT_BINARY_DIR}/filter_generated.i
+ DESTINATION ${GR_INCLUDE_DIR}/gnuradio/swig
+ COMPONENT "core_swig"
+)
+endif(ENABLE_PYTHON)
+
+########################################################################
+# Handle triple-threat files that have cc, h, and i
+########################################################################
+set(gr_core_filter_triple_threats
+ gr_adaptive_fir_ccc
+ gr_adaptive_fir_ccf
+ gr_dc_blocker_cc
+ gr_dc_blocker_ff
+ gr_fft_filter_ccc
+ gr_fft_filter_fff
+ gr_filter_delay_fc
+ gr_fractional_interpolator_ff
+ gr_fractional_interpolator_cc
+ gr_goertzel_fc
+ gr_hilbert_fc
+ gr_iir_filter_ffd
+ gr_single_pole_iir_filter_ff
+ gr_single_pole_iir_filter_cc
+ gr_pfb_channelizer_ccf
+ gr_pfb_synthesizer_ccf
+ gr_pfb_decimator_ccf
+ gr_pfb_interpolator_ccf
+ gr_pfb_arb_resampler_ccf
+ gr_pfb_arb_resampler_fff
+ gr_pfb_clock_sync_ccf
+ gr_pfb_clock_sync_fff
+)
+
+foreach(file_tt ${gr_core_filter_triple_threats})
+ list(APPEND gnuradio_core_sources ${CMAKE_CURRENT_SOURCE_DIR}/${file_tt}.cc)
+ install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/${file_tt}.h DESTINATION ${GR_INCLUDE_DIR}/gnuradio COMPONENT "core_devel")
+ if(ENABLE_PYTHON)
+ install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/${file_tt}.i DESTINATION ${GR_INCLUDE_DIR}/gnuradio/swig COMPONENT "core_swig")
+ endif(ENABLE_PYTHON)
+endforeach(file_tt ${gr_core_filter_triple_threats})
diff --git a/gnuradio-core/src/lib/filter/Makefile.gen b/gnuradio-core/src/lib/filter/Makefile.gen
new file mode 100644
index 000000000..909899c05
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/Makefile.gen
@@ -0,0 +1,124 @@
+#
+# 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 \
+ gri_fir_filter_with_buffer_ccc.h \
+ gri_fir_filter_with_buffer_ccf.h \
+ gri_fir_filter_with_buffer_fcc.h \
+ gri_fir_filter_with_buffer_fff.h \
+ gri_fir_filter_with_buffer_fsf.h \
+ gri_fir_filter_with_buffer_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 \
+ gri_fir_filter_with_buffer_ccc.cc \
+ gri_fir_filter_with_buffer_ccf.cc \
+ gri_fir_filter_with_buffer_fcc.cc \
+ gri_fir_filter_with_buffer_fff.cc \
+ gri_fir_filter_with_buffer_fsf.cc \
+ gri_fir_filter_with_buffer_scc.cc
+
diff --git a/gnuradio-core/src/lib/filter/README b/gnuradio-core/src/lib/filter/README
new file mode 100644
index 000000000..90c1584fc
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/README
@@ -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 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+This directory 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
index 000000000..32477dfd7
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/assembly.h
@@ -0,0 +1,67 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef _ASSEMBLY_H_
+#define _ASSEMBLY_H_
+
+#if defined (__APPLE__) && defined (__APPLE_CC__)
+
+// XCode ignores the .scl and .type functions in XCode 2.2.1 and 2.3,
+// but creates an error in XCode 2.4. Just ignore them.
+
+#define GLOB_SYMB(f) _ ## f
+
+#define DEF_FUNC_HEAD(f) /* none */
+
+#define FUNC_TAIL(f) /* none*/
+
+#elif !defined (__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
index 000000000..f66356337
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/ccomplex_dotprod_3dnow.S
@@ -0,0 +1,220 @@
+#
+# Copyright 2002 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, 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"
+
+
+#if defined(__linux__) && defined(__ELF__)
+.section .note.GNU-stack,"",%progbits
+#endif
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
index 000000000..e81d21993
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/ccomplex_dotprod_3dnow64.S
@@ -0,0 +1,217 @@
+#
+# 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 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, 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"
+
+
+#if defined(__linux__) && defined(__ELF__)
+.section .note.GNU-stack,"",%progbits
+#endif
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
index 000000000..22c390bdd
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/ccomplex_dotprod_3dnowext.S
@@ -0,0 +1,195 @@
+#
+# Copyright 2002 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, 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"
+
+
+#if defined(__linux__) && defined(__ELF__)
+.section .note.GNU-stack,"",%progbits
+#endif
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
index 000000000..75608914b
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/ccomplex_dotprod_3dnowext64.S
@@ -0,0 +1,192 @@
+#
+# 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 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, 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"
+
+
+#if defined(__linux__) && defined(__ELF__)
+.section .note.GNU-stack,"",%progbits
+#endif
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
index 000000000..a6f392211
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/ccomplex_dotprod_generic.cc
@@ -0,0 +1,58 @@
+/* -*- c -*- */
+/*
+ * Copyright 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <gr_complex.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
index 000000000..c7d761c07
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/ccomplex_dotprod_generic.h
@@ -0,0 +1,34 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef _CCOMPLEX_DOTPROD_GENERIC_H_
+#define _CCOMPLEX_DOTPROD_GENERIC_H_
+
+#include <gr_core_api.h>
+
+GR_CORE_API 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
index 000000000..3d16c352e
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/ccomplex_dotprod_sse.S
@@ -0,0 +1,198 @@
+#
+# Copyright 2002 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, 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"
+
+#if defined(__linux__) && defined(__ELF__)
+.section .note.GNU-stack,"",%progbits
+#endif
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
index 000000000..95ac3dac3
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/ccomplex_dotprod_sse64.S
@@ -0,0 +1,195 @@
+#
+# 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 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, 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"
+
+#if defined(__linux__) && defined(__ELF__)
+.section .note.GNU-stack,"",%progbits
+#endif
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
index 000000000..ebb63c258
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/ccomplex_dotprod_x86.h
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef _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
index 000000000..be49bb863
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/complex_dotprod_3dnow.S
@@ -0,0 +1,192 @@
+#
+# Copyright 2002 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, 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"
+
+
+#if defined(__linux__) && defined(__ELF__)
+.section .note.GNU-stack,"",%progbits
+#endif
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
index 000000000..f1c813078
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/complex_dotprod_3dnow64.S
@@ -0,0 +1,187 @@
+#
+# 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 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, 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"
+
+
+#if defined(__linux__) && defined(__ELF__)
+.section .note.GNU-stack,"",%progbits
+#endif
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
index 000000000..52f04f10c
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/complex_dotprod_3dnowext.S
@@ -0,0 +1,171 @@
+#
+# Copyright 2002 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, 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"
+
+
+#if defined(__linux__) && defined(__ELF__)
+.section .note.GNU-stack,"",%progbits
+#endif
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
index 000000000..6d7ad5ad4
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/complex_dotprod_3dnowext64.S
@@ -0,0 +1,168 @@
+#
+# 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 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, 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"
+
+
+#if defined(__linux__) && defined(__ELF__)
+.section .note.GNU-stack,"",%progbits
+#endif
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
index 000000000..229cbe978
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/complex_dotprod_generic.cc
@@ -0,0 +1,54 @@
+/* -*- c -*- */
+/*
+ * Copyright 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <gr_complex.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
index 000000000..152f6e459
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/complex_dotprod_generic.h
@@ -0,0 +1,34 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef _COMPLEX_DOTPROD_GENERIC_H_
+#define _COMPLEX_DOTPROD_GENERIC_H_
+
+#include <gr_core_api.h>
+
+GR_CORE_API 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
index 000000000..fb998cc45
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/complex_dotprod_sse.S
@@ -0,0 +1,206 @@
+#
+# Copyright 2002 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, 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 .Lcleanup # 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.
+
+.Lcleanup: # 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"
+
+#if defined(__linux__) && defined(__ELF__)
+.section .note.GNU-stack,"",%progbits
+#endif
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
index 000000000..67d3519e4
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/complex_dotprod_sse64.S
@@ -0,0 +1,202 @@
+#
+# 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 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, 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 .Lcleanup # 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.
+
+.Lcleanup: # 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"
+
+#if defined(__linux__) && defined(__ELF__)
+.section .note.GNU-stack,"",%progbits
+#endif
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
index 000000000..aad9fb5e9
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/complex_dotprod_x86.h
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef _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/dotprod_ccf_armv7_a.c b/gnuradio-core/src/lib/filter/dotprod_ccf_armv7_a.c
new file mode 100644
index 000000000..c125b49b3
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/dotprod_ccf_armv7_a.c
@@ -0,0 +1,90 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008,2009,2011 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <dotprod_ccf_armv7_a.h>
+
+/*!
+ * \param x any value
+ * \param pow2 must be a power of 2
+ * \returns \p x rounded down to a multiple of \p pow2.
+ */
+static inline size_t
+gr_p2_round_down(size_t x, size_t pow2)
+{
+ return x & -pow2;
+}
+
+
+#ifndef HAVE_MFPU_NEON
+
+void
+dotprod_ccf_armv7_a(const float *a, const float *b, float *res, size_t n)
+{
+ size_t i;
+ res[0] = 0;
+ res[1] = 0;
+
+ for (i = 0; i < n; i++){
+ res[0] += a[2*i] * b[i];
+ res[1] += a[2*i+1] * b[i];
+ }
+}
+
+#else
+
+/*
+ * preconditions:
+ *
+ * n > 0 and a multiple of 4
+ * a 4-byte aligned
+ * b 16-byte aligned
+ */
+void
+dotprod_ccf_armv7_a(const float *a, const float *b, float *res, size_t n)
+{
+
+ asm volatile(
+ "vmov.f32 q14, #0.0 \n\t"
+ "vmov.f32 q15, #0.0 \n\t"
+ "1: \n\t"
+ "subs %2, %2, #4 \n\t"
+ "vld2.f32 {q0-q1}, [%0]! \n\t"
+ "vld1.f32 {q2}, [%1]! \n\t"
+ "vmla.f32 q14, q0, q2 \n\t"
+ "vmla.f32 q15, q1, q2 \n\t"
+ "bgt 1b \n\t"
+ "vpadd.f32 d0, d28, d29 \n\t"
+ "vpadd.f32 d1, d30, d31 \n\t"
+ "vpadd.f32 d0, d0, d1 \n\t"
+ "vst1.f32 {d0}, [%3] \n\t"
+
+ : "+&r"(a), "+&r"(b), "+&r"(n)
+ : "r"(res)
+ : "memory", "d0", "d1", "d2", "d3", "d4", "d5",
+ "d28", "d29", "d30", "d31" );
+}
+
+
+#endif
diff --git a/gnuradio-core/src/lib/filter/dotprod_ccf_armv7_a.h b/gnuradio-core/src/lib/filter/dotprod_ccf_armv7_a.h
new file mode 100644
index 000000000..e42d6d10b
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/dotprod_ccf_armv7_a.h
@@ -0,0 +1,47 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008,2009,2011 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+#ifndef INCLUDED_DOTPROD_CCF_ARMV7_A_H
+#define INCLUDED_DOTPROD_CCF_ARMV7_A_H
+
+#include <stddef.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*!
+ * <pre>
+ *
+ * preconditions:
+ *
+ * n > 0 and a multiple of 4
+ * a 4-byte aligned
+ * b 16-byte aligned
+ *
+ * </pre>
+ */
+void dotprod_ccf_armv7_a(const float *a, const float *b, float *res, size_t n);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* INCLUDED_DOTPROD_CCF_ARMV7_A_H */
diff --git a/gnuradio-core/src/lib/filter/dotprod_fff_altivec.c b/gnuradio-core/src/lib/filter/dotprod_fff_altivec.c
new file mode 100644
index 000000000..53d6df714
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/dotprod_fff_altivec.c
@@ -0,0 +1,162 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <dotprod_fff_altivec.h>
+#include <gr_altivec.h>
+
+/*!
+ * \param x any value
+ * \param pow2 must be a power of 2
+ * \returns \p x rounded down to a multiple of \p pow2.
+ */
+static inline size_t
+gr_p2_round_down(size_t x, size_t pow2)
+{
+ return x & -pow2;
+}
+
+
+#if 0
+
+float
+dotprod_fff_altivec(const float *a, const float *b, size_t n)
+{
+ float sum = 0;
+ for (size_t i = 0; i < n; i++){
+ sum += a[i] * b[i];
+ }
+ return sum;
+}
+
+#else
+
+/*
+ * preconditions:
+ *
+ * n > 0 and a multiple of 4
+ * a 4-byte aligned
+ * b 16-byte aligned
+ */
+float
+dotprod_fff_altivec(const float *_a, const float *_b, size_t n)
+{
+ const vec_float4 *a = (const vec_float4 *) _a;
+ const vec_float4 *b = (const vec_float4 *) _b;
+
+ static const size_t UNROLL_CNT = 4;
+
+ n = gr_p2_round_down(n, 4);
+ size_t loop_cnt = n / (UNROLL_CNT * FLOATS_PER_VEC);
+ size_t nleft = n % (UNROLL_CNT * FLOATS_PER_VEC);
+
+ // printf("n = %zd, loop_cnt = %zd, nleft = %zd\n", n, loop_cnt, nleft);
+
+ // Used with vperm to build a* from p*
+ vec_uchar16 lvsl_a = vec_lvsl(0, _a);
+
+ vec_float4 p0, p1, p2, p3;
+ vec_float4 a0, a1, a2, a3;
+ vec_float4 b0, b1, b2, b3;
+ vec_float4 acc0 = {0, 0, 0, 0};
+ vec_float4 acc1 = {0, 0, 0, 0};
+ vec_float4 acc2 = {0, 0, 0, 0};
+ vec_float4 acc3 = {0, 0, 0, 0};
+
+ // wind in
+
+ p0 = vec_ld(0*VS, a);
+ p1 = vec_ld(1*VS, a);
+ p2 = vec_ld(2*VS, a);
+ p3 = vec_ld(3*VS, a);
+ a += UNROLL_CNT;
+
+ a0 = vec_perm(p0, p1, lvsl_a);
+ b0 = vec_ld(0*VS, b);
+ p0 = vec_ld(0*VS, a);
+
+ size_t i;
+ for (i = 0; i < loop_cnt; i++){
+
+ a1 = vec_perm(p1, p2, lvsl_a);
+ b1 = vec_ld(1*VS, b);
+ p1 = vec_ld(1*VS, a);
+ acc0 = vec_madd(a0, b0, acc0);
+
+ a2 = vec_perm(p2, p3, lvsl_a);
+ b2 = vec_ld(2*VS, b);
+ p2 = vec_ld(2*VS, a);
+ acc1 = vec_madd(a1, b1, acc1);
+
+ a3 = vec_perm(p3, p0, lvsl_a);
+ b3 = vec_ld(3*VS, b);
+ p3 = vec_ld(3*VS, a);
+ acc2 = vec_madd(a2, b2, acc2);
+
+ a += UNROLL_CNT;
+ b += UNROLL_CNT;
+
+ a0 = vec_perm(p0, p1, lvsl_a);
+ b0 = vec_ld(0*VS, b);
+ p0 = vec_ld(0*VS, a);
+ acc3 = vec_madd(a3, b3, acc3);
+ }
+
+ /*
+ * The compiler ought to be able to figure out that 0, 4, 8 and 12
+ * are the only possible values for nleft.
+ */
+ switch (nleft){
+ case 0:
+ break;
+
+ case 4:
+ acc0 = vec_madd(a0, b0, acc0);
+ break;
+
+ case 8:
+ a1 = vec_perm(p1, p2, lvsl_a);
+ b1 = vec_ld(1*VS, b);
+ acc0 = vec_madd(a0, b0, acc0);
+ acc1 = vec_madd(a1, b1, acc1);
+ break;
+
+ case 12:
+ a1 = vec_perm(p1, p2, lvsl_a);
+ b1 = vec_ld(1*VS, b);
+ acc0 = vec_madd(a0, b0, acc0);
+ a2 = vec_perm(p2, p3, lvsl_a);
+ b2 = vec_ld(2*VS, b);
+ acc1 = vec_madd(a1, b1, acc1);
+ acc2 = vec_madd(a2, b2, acc2);
+ break;
+ }
+
+ acc0 = acc0 + acc1;
+ acc2 = acc2 + acc3;
+ acc0 = acc0 + acc2;
+
+ return horizontal_add_f(acc0);
+}
+
+#endif
diff --git a/gnuradio-core/src/lib/filter/dotprod_fff_altivec.h b/gnuradio-core/src/lib/filter/dotprod_fff_altivec.h
new file mode 100644
index 000000000..a52370d56
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/dotprod_fff_altivec.h
@@ -0,0 +1,50 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+#ifndef INCLUDED_DOTPROD_FFF_ALTIVEC_H
+#define INCLUDED_DOTPROD_FFF_ALTIVEC_H
+
+#include <gr_core_api.h>
+#include <stddef.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*!
+ * <pre>
+ *
+ * preconditions:
+ *
+ * n > 0 and a multiple of 4
+ * a 4-byte aligned
+ * b 16-byte aligned
+ *
+ * </pre>
+ */
+float
+dotprod_fff_altivec(const float *a, const float *b, size_t n);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* INCLUDED_DOTPROD_FFF_ALTIVEC_H */
diff --git a/gnuradio-core/src/lib/filter/dotprod_fff_armv7_a.c b/gnuradio-core/src/lib/filter/dotprod_fff_armv7_a.c
new file mode 100644
index 000000000..23bbef033
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/dotprod_fff_armv7_a.c
@@ -0,0 +1,87 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008,2009 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <dotprod_fff_armv7_a.h>
+
+/*!
+ * \param x any value
+ * \param pow2 must be a power of 2
+ * \returns \p x rounded down to a multiple of \p pow2.
+ */
+static inline size_t
+gr_p2_round_down(size_t x, size_t pow2)
+{
+ return x & -pow2;
+}
+
+
+#ifndef HAVE_MFPU_NEON
+
+float
+dotprod_fff_armv7_a(const float *a, const float *b, size_t n)
+{
+ float sum = 0;
+ size_t i;
+ for (i = 0; i < n; i++){
+ sum += a[i] * b[i];
+ }
+ return sum;
+}
+
+#else
+
+/*
+ * preconditions:
+ *
+ * n > 0 and a multiple of 4
+ * a 4-byte aligned
+ * b 16-byte aligned
+ */
+float
+dotprod_fff_armv7_a(const float *a, const float *b, size_t n)
+{
+ float s = 0;
+
+ asm ("vmov.f32 q8, #0.0 \n\t"
+ "vmov.f32 q9, #0.0 \n\t"
+ "1: \n\t"
+ "subs %3, %3, #8 \n\t"
+ "vld1.32 {d0,d1,d2,d3}, [%1]! \n\t"
+ "vld1.32 {d4,d5,d6,d7}, [%2]! \n\t"
+ "vmla.f32 q8, q0, q2 \n\t"
+ "vmla.f32 q9, q1, q3 \n\t"
+ "bgt 1b \n\t"
+ "vadd.f32 q8, q8, q9 \n\t"
+ "vpadd.f32 d0, d16, d17 \n\t"
+ "vadd.f32 %0, s0, s1 \n\t"
+ : "=w"(s), "+r"(a), "+r"(b), "+r"(n)
+ :: "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7",
+ "d16", "d17", "d18", "d19");
+
+ return s;
+
+}
+
+#endif
diff --git a/gnuradio-core/src/lib/filter/dotprod_fff_armv7_a.h b/gnuradio-core/src/lib/filter/dotprod_fff_armv7_a.h
new file mode 100644
index 000000000..6cea45cea
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/dotprod_fff_armv7_a.h
@@ -0,0 +1,50 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008,2009 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+#ifndef INCLUDED_DOTPROD_FFF_ARMV7_A_H
+#define INCLUDED_DOTPROD_FFF_ARMV7_A_H
+
+#include <gr_core_api.h>
+#include <stddef.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*!
+ * <pre>
+ *
+ * preconditions:
+ *
+ * n > 0 and a multiple of 4
+ * a 4-byte aligned
+ * b 16-byte aligned
+ *
+ * </pre>
+ */
+float
+dotprod_fff_armv7_a(const float *a, const float *b, size_t n);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* INCLUDED_DOTPROD_FFF_ARMV7_A_H */
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
index 000000000..536e46dc1
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/fcomplex_dotprod_3dnow.S
@@ -0,0 +1,176 @@
+#
+# Copyright 2002 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, 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"
+
+#if defined(__linux__) && defined(__ELF__)
+.section .note.GNU-stack,"",%progbits
+#endif
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
index 000000000..d9a695949
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/fcomplex_dotprod_3dnow64.S
@@ -0,0 +1,170 @@
+#
+# 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 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, 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"
+
+#if defined(__linux__) && defined(__ELF__)
+.section .note.GNU-stack,"",%progbits
+#endif
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
index 000000000..4c5e956f2
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/fcomplex_dotprod_sse.S
@@ -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 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, 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 .Lcleanup # 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.
+
+.Lcleanup: # 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"
+
+#if defined(__linux__) && defined(__ELF__)
+.section .note.GNU-stack,"",%progbits
+#endif
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
index 000000000..53a4f25e0
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/fcomplex_dotprod_sse64.S
@@ -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 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, 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 .Lcleanup # 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.
+
+.Lcleanup: # 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"
+
+#if defined(__linux__) && defined(__ELF__)
+.section .note.GNU-stack,"",%progbits
+#endif
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
index 000000000..b7eddf936
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/fcomplex_dotprod_x86.h
@@ -0,0 +1,42 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef _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
index 000000000..12580aa10
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/filter.i
@@ -0,0 +1,70 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2005,2006,2007,2009 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+%{
+#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_fractional_interpolator_ff.h>
+#include <gr_fractional_interpolator_cc.h>
+#include <gr_goertzel_fc.h>
+#include <gr_pfb_channelizer_ccf.h>
+#include <gr_pfb_synthesizer_ccf.h>
+#include <gr_pfb_decimator_ccf.h>
+#include <gr_pfb_interpolator_ccf.h>
+#include <gr_pfb_arb_resampler_ccf.h>
+#include <gr_pfb_arb_resampler_fff.h>
+#include <gr_pfb_clock_sync_ccf.h>
+#include <gr_pfb_clock_sync_fff.h>
+#include <gr_dc_blocker_cc.h>
+#include <gr_dc_blocker_ff.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_fractional_interpolator_ff.i"
+%include "gr_fractional_interpolator_cc.i"
+%include "gr_goertzel_fc.i"
+%include "gr_pfb_channelizer_ccf.i"
+%include "gr_pfb_synthesizer_ccf.i"
+%include "gr_pfb_decimator_ccf.i"
+%include "gr_pfb_interpolator_ccf.i"
+%include "gr_pfb_arb_resampler_ccf.i"
+%include "gr_pfb_arb_resampler_fff.i"
+%include "gr_pfb_decimator_ccf.i"
+%include "gr_pfb_interpolator_ccf.i"
+%include "gr_pfb_arb_resampler_ccf.i"
+%include "gr_pfb_clock_sync_ccf.i"
+%include "gr_pfb_clock_sync_fff.i"
+%include "gr_dc_blocker_cc.i"
+%include "gr_dc_blocker_ff.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
index 000000000..cdebe9bc3
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/float_dotprod_3dnow.S
@@ -0,0 +1,152 @@
+#
+# Copyright 2002 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, 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"
+
+#if defined(__linux__) && defined(__ELF__)
+.section .note.GNU-stack,"",%progbits
+#endif
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
index 000000000..1e859d75a
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/float_dotprod_3dnow64.S
@@ -0,0 +1,149 @@
+#
+# 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 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, 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"
+
+#if defined(__linux__) && defined(__ELF__)
+.section .note.GNU-stack,"",%progbits
+#endif
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
index 000000000..fb9139036
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/float_dotprod_generic.c
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "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
index 000000000..dee967642
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/float_dotprod_generic.h
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef _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
index 000000000..66604526d
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/float_dotprod_sse.S
@@ -0,0 +1,171 @@
+#
+# Copyright 2002 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, 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 .Lcleanup # 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...
+
+.Lcleanup: # 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"
+
+#if defined(__linux__) && defined(__ELF__)
+.section .note.GNU-stack,"",%progbits
+#endif
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
index 000000000..0dd0764c5
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/float_dotprod_sse64.S
@@ -0,0 +1,165 @@
+#
+# 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 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, 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 .Lcleanup # 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...
+
+.Lcleanup: # 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"
+
+#if defined(__linux__) && defined(__ELF__)
+.section .note.GNU-stack,"",%progbits
+#endif
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
index 000000000..fd1a2cc93
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/float_dotprod_x86.h
@@ -0,0 +1,44 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef _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/gcc_x86_cpuid.h b/gnuradio-core/src/lib/filter/gcc_x86_cpuid.h
new file mode 100644
index 000000000..98eeb33a3
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gcc_x86_cpuid.h
@@ -0,0 +1,178 @@
+/*
+ * Copyright (C) 2007, 2008, 2009 Free Software Foundation, Inc.
+ *
+ * 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 3, or (at your option) any
+ * later version.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * Under Section 7 of GPL version 3, you are granted additional
+ * permissions described in the GCC Runtime Library Exception, version
+ * 3.1, as published by the Free Software Foundation.
+ *
+ * You should have received a copy of the GNU General Public License and
+ * a copy of the GCC Runtime Library Exception along with this program;
+ * see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+ * <http://www.gnu.org/licenses/>.
+ */
+
+/* %ecx */
+#define bit_SSE3 (1 << 0)
+#define bit_PCLMUL (1 << 1)
+#define bit_SSSE3 (1 << 9)
+#define bit_FMA (1 << 12)
+#define bit_CMPXCHG16B (1 << 13)
+#define bit_SSE4_1 (1 << 19)
+#define bit_SSE4_2 (1 << 20)
+#define bit_MOVBE (1 << 22)
+#define bit_POPCNT (1 << 23)
+#define bit_AES (1 << 25)
+#define bit_XSAVE (1 << 26)
+#define bit_OSXSAVE (1 << 27)
+#define bit_AVX (1 << 28)
+
+/* %edx */
+#define bit_CMPXCHG8B (1 << 8)
+#define bit_CMOV (1 << 15)
+#define bit_MMX (1 << 23)
+#define bit_FXSAVE (1 << 24)
+#define bit_SSE (1 << 25)
+#define bit_SSE2 (1 << 26)
+
+/* Extended Features */
+/* %ecx */
+#define bit_LAHF_LM (1 << 0)
+#define bit_SSE4a (1 << 6)
+#define bit_SSE5 (1 << 11)
+
+/* %edx */
+#define bit_LM (1 << 29)
+#define bit_3DNOWP (1 << 30)
+#define bit_3DNOW (1 << 31)
+
+
+#if defined(__i386__) && defined(__PIC__)
+/* %ebx may be the PIC register. */
+#if __GNUC__ >= 3
+#define __cpuid(level, a, b, c, d) \
+ __asm__ ("xchg{l}\t{%%}ebx, %1\n\t" \
+ "cpuid\n\t" \
+ "xchg{l}\t{%%}ebx, %1\n\t" \
+ : "=a" (a), "=r" (b), "=c" (c), "=d" (d) \
+ : "0" (level))
+
+#define __cpuid_count(level, count, a, b, c, d) \
+ __asm__ ("xchg{l}\t{%%}ebx, %1\n\t" \
+ "cpuid\n\t" \
+ "xchg{l}\t{%%}ebx, %1\n\t" \
+ : "=a" (a), "=r" (b), "=c" (c), "=d" (d) \
+ : "0" (level), "2" (count))
+#else
+/* Host GCCs older than 3.0 weren't supporting Intel asm syntax
+ nor alternatives in i386 code. */
+#define __cpuid(level, a, b, c, d) \
+ __asm__ ("xchgl\t%%ebx, %1\n\t" \
+ "cpuid\n\t" \
+ "xchgl\t%%ebx, %1\n\t" \
+ : "=a" (a), "=r" (b), "=c" (c), "=d" (d) \
+ : "0" (level))
+
+#define __cpuid_count(level, count, a, b, c, d) \
+ __asm__ ("xchgl\t%%ebx, %1\n\t" \
+ "cpuid\n\t" \
+ "xchgl\t%%ebx, %1\n\t" \
+ : "=a" (a), "=r" (b), "=c" (c), "=d" (d) \
+ : "0" (level), "2" (count))
+#endif
+#else
+#define __cpuid(level, a, b, c, d) \
+ __asm__ ("cpuid\n\t" \
+ : "=a" (a), "=b" (b), "=c" (c), "=d" (d) \
+ : "0" (level))
+
+#define __cpuid_count(level, count, a, b, c, d) \
+ __asm__ ("cpuid\n\t" \
+ : "=a" (a), "=b" (b), "=c" (c), "=d" (d) \
+ : "0" (level), "2" (count))
+#endif
+
+/* Return highest supported input value for cpuid instruction. ext can
+ be either 0x0 or 0x8000000 to return highest supported value for
+ basic or extended cpuid information. Function returns 0 if cpuid
+ is not supported or whatever cpuid returns in eax register. If sig
+ pointer is non-null, then first four bytes of the signature
+ (as found in ebx register) are returned in location pointed by sig. */
+
+static __inline unsigned int
+__get_cpuid_max (unsigned int __ext, unsigned int *__sig)
+{
+ unsigned int __eax, __ebx, __ecx, __edx;
+
+#ifndef __x86_64__
+#if __GNUC__ >= 3
+ /* See if we can use cpuid. On AMD64 we always can. */
+ __asm__ ("pushf{l|d}\n\t"
+ "pushf{l|d}\n\t"
+ "pop{l}\t%0\n\t"
+ "mov{l}\t{%0, %1|%1, %0}\n\t"
+ "xor{l}\t{%2, %0|%0, %2}\n\t"
+ "push{l}\t%0\n\t"
+ "popf{l|d}\n\t"
+ "pushf{l|d}\n\t"
+ "pop{l}\t%0\n\t"
+ "popf{l|d}\n\t"
+ : "=&r" (__eax), "=&r" (__ebx)
+ : "i" (0x00200000));
+#else
+/* Host GCCs older than 3.0 weren't supporting Intel asm syntax
+ nor alternatives in i386 code. */
+ __asm__ ("pushfl\n\t"
+ "pushfl\n\t"
+ "popl\t%0\n\t"
+ "movl\t%0, %1\n\t"
+ "xorl\t%2, %0\n\t"
+ "pushl\t%0\n\t"
+ "popfl\n\t"
+ "pushfl\n\t"
+ "popl\t%0\n\t"
+ "popfl\n\t"
+ : "=&r" (__eax), "=&r" (__ebx)
+ : "i" (0x00200000));
+#endif
+
+ if (!((__eax ^ __ebx) & 0x00200000))
+ return 0;
+#endif
+
+ /* Host supports cpuid. Return highest supported cpuid input value. */
+ __cpuid (__ext, __eax, __ebx, __ecx, __edx);
+
+ if (__sig)
+ *__sig = __ebx;
+
+ return __eax;
+}
+
+/* Return cpuid data for requested cpuid level, as found in returned
+ eax, ebx, ecx and edx registers. The function checks if cpuid is
+ supported and returns 1 for valid cpuid information or 0 for
+ unsupported cpuid level. All pointers are required to be non-null. */
+
+static __inline int
+__get_cpuid (unsigned int __level,
+ unsigned int *__eax, unsigned int *__ebx,
+ unsigned int *__ecx, unsigned int *__edx)
+{
+ unsigned int __ext = __level & 0x80000000;
+
+ if (__get_cpuid_max (__ext, 0) < __level)
+ return 0;
+
+ __cpuid (__level, *__eax, *__ebx, *__ecx, *__edx);
+ return 1;
+}
diff --git a/gnuradio-core/src/lib/filter/generate_all.py b/gnuradio-core/src/lib/filter/generate_all.py
new file mode 100755
index 000000000..1da9f7209
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/generate_all.py
@@ -0,0 +1,48 @@
+#!/usr/bin/env python
+#
+# Copyright 2003 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+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
+import generate_gri_fir_filter_with_buffer_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()
+ generate_gri_fir_filter_with_buffer_XXX.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
index 000000000..cf37fbb24
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/generate_gr_fir_XXX.py
@@ -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 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+import 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
index 000000000..50cc586e5
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/generate_gr_fir_filter_XXX.py
@@ -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 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+import 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
index 000000000..50d819fd1
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/generate_gr_fir_sysconfig.py
@@ -0,0 +1,133 @@
+#!/bin/env python
+# -*- python -*-
+#
+# Copyright 2003,2009 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from generate_utils import *
+
+
+# ----------------------------------------------------------------
+
+def make_gr_fir_sysconfig_h ():
+ out = open_and_log_name ('gr_fir_sysconfig.h', 'w')
+ if not out:
+ return
+
+ 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')
+ if not out:
+ return
+
+ 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
index 000000000..dcbadd30f
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/generate_gr_fir_sysconfig_generic.py
@@ -0,0 +1,186 @@
+#!/bin/env python
+# -*- python -*-
+#
+# Copyright 2003,2009 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from generate_utils import *
+
+
+# ----------------------------------------------------------------
+
+def make_gr_fir_sysconfig_generic_h ():
+ out = open_and_log_name ('gr_fir_sysconfig_generic.h', 'w')
+ if not out:
+ return
+ 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')
+ if not out:
+ return
+ 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
index 000000000..79fa51c27
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/generate_gr_fir_util.py
@@ -0,0 +1,190 @@
+#!/bin/env python
+#
+# Copyright 2003,2009 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from generate_utils import *
+
+def make_info_struct (out, sig):
+ out.write (
+'''
+struct GR_CORE_API 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')
+ if not out:
+ return
+ 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_core_api.h>
+#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_CORE_API 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')
+ if not out:
+ return
+ 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
index 000000000..41c0b2b70
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/generate_gr_freq_xlating_fir_filter_XXX.py
@@ -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 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+import 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
index 000000000..1dcfdaded
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/generate_gr_interp_fir_filter_XXX.py
@@ -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 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+import 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
index 000000000..1dafec3fb
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/generate_gr_rational_resampler_base_XXX.py
@@ -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 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+import 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_gri_fir_filter_with_buffer_XXX.py b/gnuradio-core/src/lib/filter/generate_gri_fir_filter_with_buffer_XXX.py
new file mode 100755
index 000000000..6442fb3dc
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/generate_gri_fir_filter_with_buffer_XXX.py
@@ -0,0 +1,64 @@
+#!/usr/bin/env python
+# -*- python -*-
+#
+# Copyright 2010 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+import re
+from generate_utils import *
+
+roots = ['gri_fir_filter_with_buffer_XXX',]
+
+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['INPUT_CAST'] = code3_to_input_cast (code3)
+ acc_code = code3_to_acc_code (code3)
+ d['ACC_TYPE'] = char_to_type[acc_code]
+ 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_utils.py b/gnuradio-core/src/lib/filter/generate_utils.py
new file mode 100644
index 000000000..212ea95f9
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/generate_utils.py
@@ -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 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, 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_ccc.cc b/gnuradio-core/src/lib/filter/gr_adaptive_fir_ccc.cc
new file mode 100644
index 000000000..da407caa0
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_adaptive_fir_ccc.cc
@@ -0,0 +1,88 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2011 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_adaptive_fir_ccc.h>
+#include <gr_io_signature.h>
+
+gr_adaptive_fir_ccc::gr_adaptive_fir_ccc(const char *name, int decimation,
+ const std::vector<gr_complex> &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_ccc::set_taps(const std::vector<gr_complex> &taps)
+{
+ d_new_taps = taps;
+ d_updated = true;
+}
+
+gr_complex
+gr_adaptive_fir_ccc::filter(gr_complex *x)
+{
+ // Generic dot product of d_taps[] and in[]
+ gr_complex acc(0.0, 0.0);
+ int l = d_taps.size();
+ for (int k = 0; k < l; k++)
+ acc += d_taps[l-k-1] * x[k];
+ return acc;
+}
+
+int
+gr_adaptive_fir_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) {
+ 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++) {
+ out[i] = filter(&in[j]);
+
+ // Adjust taps
+ d_error = error(out[i]);
+ for (k = 0; k < l; k++) {
+ update_tap(d_taps[l-k-1], in[j+k]);
+ }
+
+ j += decimation();
+ }
+
+ return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/filter/gr_adaptive_fir_ccc.h b/gnuradio-core/src/lib/filter/gr_adaptive_fir_ccc.h
new file mode 100644
index 000000000..d144c3eb4
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_adaptive_fir_ccc.h
@@ -0,0 +1,62 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2011 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_ADAPTIVE_FIR_CCC_H
+#define INCLUDED_GR_ADAPTIVE_FIR_CCC_H
+
+#include <gr_core_api.h>
+#include <gr_sync_decimator.h>
+
+/*!
+ * \brief Adaptive FIR filter with gr_complex input, gr_complex output and float taps
+ * \ingroup filter_blk
+ */
+class GR_CORE_API gr_adaptive_fir_ccc : public gr_sync_decimator
+{
+private:
+ std::vector<gr_complex> d_new_taps;
+ bool d_updated;
+
+protected:
+ gr_complex d_error;
+ std::vector<gr_complex> d_taps;
+
+ // Override to calculate error signal per output
+ virtual gr_complex error(const gr_complex &out) = 0;
+
+ // Override to calculate new weight from old, corresponding input
+ virtual void update_tap(gr_complex &tap, const gr_complex &in) = 0;
+
+ gr_complex filter(gr_complex *x);
+
+ gr_adaptive_fir_ccc(const char *name, int decimation,
+ const std::vector<gr_complex> &taps);
+
+public:
+ 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
diff --git a/gnuradio-core/src/lib/filter/gr_adaptive_fir_ccc.i b/gnuradio-core/src/lib/filter/gr_adaptive_fir_ccc.i
new file mode 100644
index 000000000..a3c875a3d
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_adaptive_fir_ccc.i
@@ -0,0 +1,31 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2011 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+class gr_adaptive_fir_ccc : public gr_sync_decimator
+{
+protected:
+ gr_adaptive_fir_ccc(char *name, int decimation,
+ const std::vector<gr_complex> &taps);
+
+public:
+ void set_taps(const std::vector<gr_complex> &taps);
+};
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
index 000000000..045d9faf9
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_adaptive_fir_ccf.cc
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_adaptive_fir_ccf.h>
+#include <gr_io_signature.h>
+
+gr_adaptive_fir_ccf::gr_adaptive_fir_ccf(const 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
index 000000000..7ec78099f
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_adaptive_fir_ccf.h
@@ -0,0 +1,59 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_ADAPTIVE_FIR_CCF_H
+#define INCLUDED_GR_ADAPTIVE_FIR_CCF_H
+
+#include <gr_core_api.h>
+#include <gr_sync_decimator.h>
+
+/*!
+ * \brief Adaptive FIR filter with gr_complex input, gr_complex output and float taps
+ * \ingroup filter_blk
+ */
+class GR_CORE_API 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;
+
+ gr_adaptive_fir_ccf(const char *name, int decimation, const std::vector<float> &taps);
+
+public:
+ 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
index 000000000..346defd4d
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_adaptive_fir_ccf.i
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+class gr_adaptive_fir_ccf : public gr_sync_decimator
+{
+protected:
+ 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_altivec.c b/gnuradio-core/src/lib/filter/gr_altivec.c
new file mode 100644
index 000000000..22a67291d
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_altivec.c
@@ -0,0 +1,38 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <gr_altivec.h>
+
+void
+gr_print_vector_float(FILE *fp, vec_float4 v)
+{
+ union v_float_u u;
+ u.v = v;
+ fprintf(fp, "{ %f, %f, %f, %f }", u.f[0], u.f[1], u.f[2], u.f[3]);
+}
+
+void
+gr_pvf(FILE *fp, const char *label, vec_float4 v)
+{
+ fprintf(fp, "%s = ", label);
+ gr_print_vector_float(fp, v);
+ putc('\n', fp);
+}
diff --git a/gnuradio-core/src/lib/filter/gr_altivec.h b/gnuradio-core/src/lib/filter/gr_altivec.h
new file mode 100644
index 000000000..ed11490f5
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_altivec.h
@@ -0,0 +1,76 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+#ifndef INCLUDED_GR_ALTIVEC_H
+#define INCLUDED_GR_ALTIVEC_H
+
+/*
+ * N.B., always use "vec_float4" et al. instead of "vector float" to
+ * ensure portability across the various powerpc compilers. Some of
+ * them treat "vector" as a context specific keyword, some don't.
+ * Avoid the problem by always using the defines in vec_types.h
+ * (included below)
+ */
+
+#include <gr_core_api.h>
+#include <altivec.h>
+#undef bool // repair namespace pollution
+#undef vector // repair namespace pollution
+
+#ifdef HAVE_VEC_TYPES_H
+#include <vec_types.h> // use system version if we've got it
+#else
+#include <gr_vec_types.h> // fall back to our local copy
+#endif
+#undef qword // repair namespace pollution
+
+#include <stddef.h>
+#include <stdio.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define VS sizeof(vec_float4)
+#define FLOATS_PER_VEC (sizeof(vec_float4)/sizeof(float))
+
+union v_float_u {
+ vec_float4 v;
+ float f[FLOATS_PER_VEC];
+};
+
+GR_CORE_API void gr_print_vector_float(FILE *fp, vec_float4 v);
+GR_CORE_API void gr_pvf(FILE *fp, const char *label, vec_float4 v);
+
+static inline float
+horizontal_add_f(vec_float4 v)
+{
+ union v_float_u u;
+ vec_float4 t0 = vec_add(v, vec_sld(v, v, 8));
+ vec_float4 t1 = vec_add(t0, vec_sld(t0, t0, 4));
+ u.v = t1;
+ return u.f[0];
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* INCLUDED_GR_ALTIVEC_H */
diff --git a/gnuradio-core/src/lib/filter/gr_cpu.h b/gnuradio-core/src/lib/filter/gr_cpu.h
new file mode 100644
index 000000000..35824ac1e
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_cpu.h
@@ -0,0 +1,42 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002,2008,2009 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef _GR_CPU_H_
+#define _GR_CPU_H_
+
+#include <gr_core_api.h>
+
+struct GR_CORE_API gr_cpu {
+ static bool has_mmx ();
+ static bool has_sse ();
+ static bool has_sse2 ();
+ static bool has_sse3 ();
+ static bool has_ssse3 ();
+ static bool has_sse4_1 ();
+ static bool has_sse4_2 ();
+ static bool has_3dnow ();
+ static bool has_3dnowext ();
+ static bool has_altivec ();
+ static bool has_armv7_a ();
+};
+
+#endif /* _GR_CPU_H_ */ \ No newline at end of file
diff --git a/gnuradio-core/src/lib/filter/gr_cpu_armv7_a.cc b/gnuradio-core/src/lib/filter/gr_cpu_armv7_a.cc
new file mode 100644
index 000000000..245049206
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_cpu_armv7_a.cc
@@ -0,0 +1,65 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002,2008,2009 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <gr_cpu.h>
+
+bool
+gr_cpu::has_mmx ()
+{
+ return false;
+}
+
+bool
+gr_cpu::has_sse ()
+{
+ return false;
+}
+
+bool
+gr_cpu::has_sse2 ()
+{
+ return false;
+}
+
+bool
+gr_cpu::has_3dnow ()
+{
+ return false;
+}
+
+bool
+gr_cpu::has_3dnowext ()
+{
+ return false;
+}
+
+bool
+gr_cpu::has_altivec ()
+{
+ return false;
+}
+
+bool
+gr_cpu::has_armv7_a ()
+{
+ return true;
+}
diff --git a/gnuradio-core/src/lib/filter/gr_cpu_powerpc.cc b/gnuradio-core/src/lib/filter/gr_cpu_powerpc.cc
new file mode 100644
index 000000000..d613f0ae4
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_cpu_powerpc.cc
@@ -0,0 +1,65 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002,2008 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <gr_cpu.h>
+
+bool
+gr_cpu::has_mmx ()
+{
+ return false;
+}
+
+bool
+gr_cpu::has_sse ()
+{
+ return false;
+}
+
+bool
+gr_cpu::has_sse2 ()
+{
+ return false;
+}
+
+bool
+gr_cpu::has_3dnow ()
+{
+ return false;
+}
+
+bool
+gr_cpu::has_3dnowext ()
+{
+ return false;
+}
+
+bool
+gr_cpu::has_altivec ()
+{
+ return true; // FIXME assume we've always got it
+}
+
+bool
+gr_cpu::has_armv7_a ()
+{
+ return false;
+}
diff --git a/gnuradio-core/src/lib/filter/gr_cpu_x86.cc b/gnuradio-core/src/lib/filter/gr_cpu_x86.cc
new file mode 100644
index 000000000..3acd694d5
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_cpu_x86.cc
@@ -0,0 +1,119 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002,2009 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <gr_cpu.h>
+#include "gcc_x86_cpuid.h"
+
+/*
+ * execute CPUID instruction, return EAX, EBX, ECX and EDX values in result
+ */
+#define cpuid_x86(op, r) __get_cpuid(op, r+0, r+1, r+2, r+3)
+
+/*
+ * CPUID functions returning a single datum
+ */
+
+static inline unsigned int cpuid_eax(unsigned int op)
+{
+ unsigned int regs[4] = {0,0,0,0};
+ cpuid_x86 (op, regs);
+ return regs[0];
+}
+
+static inline unsigned int cpuid_ebx(unsigned int op)
+{
+ unsigned int regs[4] = {0,0,0,0};
+ cpuid_x86 (op, regs);
+ return regs[1];
+}
+
+static inline unsigned int cpuid_ecx(unsigned int op)
+{
+ unsigned int regs[4] = {0,0,0,0};
+ cpuid_x86 (op, regs);
+ return regs[2];
+}
+
+static inline unsigned int cpuid_edx(unsigned int op)
+{
+ unsigned int regs[4] = {0,0,0,0};
+ 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;
+}
+
+bool
+gr_cpu::has_altivec ()
+{
+ return false;
+}
+
+bool
+gr_cpu::has_armv7_a ()
+{
+ return false;
+}
+
diff --git a/gnuradio-core/src/lib/filter/gr_dc_blocker_cc.cc b/gnuradio-core/src/lib/filter/gr_dc_blocker_cc.cc
new file mode 100644
index 000000000..0438a193f
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_dc_blocker_cc.cc
@@ -0,0 +1,138 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2011 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_dc_blocker_cc.h>
+#include <gr_io_signature.h>
+#include <cstdio>
+
+moving_averager_c::moving_averager_c(int D)
+ : d_length(D), d_out(0), d_out_d1(0), d_out_d2(0)
+{
+ d_delay_line = std::deque<gr_complex>(d_length-1, gr_complex(0,0));
+}
+
+moving_averager_c::~moving_averager_c()
+{
+}
+
+gr_complex
+moving_averager_c::filter(gr_complex x)
+{
+ d_out_d1 = d_out;
+ d_delay_line.push_back(x);
+ d_out = d_delay_line[0];
+ d_delay_line.pop_front();
+
+ gr_complex y = x - d_out_d1 + d_out_d2;
+ d_out_d2 = y;
+
+ return (y / (float)(d_length));
+}
+
+
+
+gr_dc_blocker_cc_sptr gr_make_dc_blocker_cc (int D, bool long_form)
+{
+ return gnuradio::get_initial_sptr(new gr_dc_blocker_cc(D, long_form));
+}
+
+
+gr_dc_blocker_cc::gr_dc_blocker_cc (int D, bool long_form)
+ : gr_sync_block ("dc_blocker_cc",
+ gr_make_io_signature (1, 1, sizeof(gr_complex)),
+ gr_make_io_signature (1, 1, sizeof(gr_complex))),
+ d_length(D), d_long_form(long_form)
+{
+ if(d_long_form) {
+ d_ma_0 = new moving_averager_c(D);
+ d_ma_1 = new moving_averager_c(D);
+ d_ma_2 = new moving_averager_c(D);
+ d_ma_3 = new moving_averager_c(D);
+ d_delay_line = std::deque<gr_complex>(d_length-1, gr_complex(0,0));
+ }
+ else {
+ d_ma_0 = new moving_averager_c(D);
+ d_ma_1 = new moving_averager_c(D);
+ }
+}
+
+gr_dc_blocker_cc::~gr_dc_blocker_cc()
+{
+ if(d_long_form) {
+ delete d_ma_0;
+ delete d_ma_1;
+ delete d_ma_2;
+ delete d_ma_3;
+ }
+ else {
+ delete d_ma_0;
+ delete d_ma_1;
+ }
+}
+
+int
+gr_dc_blocker_cc::get_group_delay()
+{
+ if(d_long_form)
+ return (2*d_length-2);
+ else
+ return d_length - 1;
+}
+
+int
+gr_dc_blocker_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];
+
+ if(d_long_form) {
+ gr_complex y1, y2, y3, y4, d;
+ for(int i = 0; i < noutput_items; i++) {
+ y1 = d_ma_0->filter(in[i]);
+ y2 = d_ma_1->filter(y1);
+ y3 = d_ma_2->filter(y2);
+ y4 = d_ma_3->filter(y3);
+
+ d_delay_line.push_back(d_ma_0->delayed_sig());
+ d = d_delay_line[0];
+ d_delay_line.pop_front();
+
+ out[i] = d - y4;
+ }
+ }
+ else {
+ gr_complex y1, y2;
+ for(int i = 0; i < noutput_items; i++) {
+ y1 = d_ma_0->filter(in[i]);
+ y2 = d_ma_1->filter(y1);
+ out[i] = d_ma_0->delayed_sig() - y2;
+ }
+ }
+
+ return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/filter/gr_dc_blocker_cc.h b/gnuradio-core/src/lib/filter/gr_dc_blocker_cc.h
new file mode 100644
index 000000000..e4d89a775
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_dc_blocker_cc.h
@@ -0,0 +1,111 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2011 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+
+#ifndef INCLUDED_GR_DC_BLOCKER_CC_H
+#define INCLUDED_GR_DC_BLOCKER_CC_H
+
+#include <gr_core_api.h>
+#include <gr_sync_block.h>
+#include <deque>
+
+class GR_CORE_API moving_averager_c
+{
+public:
+ moving_averager_c(int D);
+ ~moving_averager_c();
+
+ gr_complex filter(gr_complex x);
+ gr_complex delayed_sig() { return d_out; }
+
+private:
+ int d_length;
+ gr_complex d_out, d_out_d1, d_out_d2;
+ std::deque<gr_complex> d_delay_line;
+};
+
+class gr_dc_blocker_cc;
+typedef boost::shared_ptr<gr_dc_blocker_cc> gr_dc_blocker_cc_sptr;
+GR_CORE_API gr_dc_blocker_cc_sptr gr_make_dc_blocker_cc (int D=32, bool long_form=true);
+
+/*!
+ * \class gr_dc_blocker_cc
+ * \brief a computationally efficient controllable DC blocker
+ *
+ * \ingroup filter_blk
+ *
+ * This block implements a computationally efficient DC blocker that produces
+ * a tighter notch filter around DC for a smaller group delay than an
+ * equivalent FIR filter or using a single pole IIR filter (though the IIR
+ * filter is computationally cheaper).
+ *
+ * The block defaults to using a delay line of length 32 and the long form
+ * of the filter. Optionally, the delay line length can be changed to alter
+ * the width of the DC notch (longer lines will decrease the width).
+ *
+ * The long form of the filter produces a nearly flat response outside of
+ * the notch but at the cost of a group delay of 2D-2.
+ *
+ * The short form of the filter does not have as flat a response in the
+ * passband but has a group delay of only D-1 and is cheaper to compute.
+ *
+ * The theory behind this block can be found in the paper:
+ *
+ * <B><EM>R. Yates, "DC Blocker Algorithms," IEEE Signal Processing Magazine,
+ * Mar. 2008, pp 132-134.</EM></B>
+ */
+class GR_CORE_API gr_dc_blocker_cc : public gr_sync_block
+{
+ private:
+ /*!
+ * Build the DC blocker.
+ * \param D (int) the length of the delay line
+ * \param long_form (bool) whether to use long (true, default) or short form
+ */
+ friend GR_CORE_API gr_dc_blocker_cc_sptr gr_make_dc_blocker_cc (int D, bool long_form);
+
+ int d_length;
+ bool d_long_form;
+ moving_averager_c *d_ma_0;
+ moving_averager_c *d_ma_1;
+ moving_averager_c *d_ma_2;
+ moving_averager_c *d_ma_3;
+ std::deque<gr_complex> d_delay_line;
+
+ gr_dc_blocker_cc (int D, bool long_form);
+
+public:
+ ~gr_dc_blocker_cc ();
+
+ /*!
+ * Get the blocker's group delay that is based on length of delay lines
+ */
+ int get_group_delay();
+
+ //int set_length(int D);
+
+ 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_dc_blocker_cc.i b/gnuradio-core/src/lib/filter/gr_dc_blocker_cc.i
new file mode 100644
index 000000000..83d05044b
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_dc_blocker_cc.i
@@ -0,0 +1,34 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2011 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,dc_blocker_cc);
+
+gr_dc_blocker_cc_sptr gr_make_dc_blocker_cc (int D=32, bool long_form=true);
+
+class gr_dc_blocker_cc : public gr_sync_block
+{
+ private:
+ gr_dc_blocker_cc (int D, bool long_form);
+
+ public:
+ ~gr_dc_blocker_cc ();
+};
diff --git a/gnuradio-core/src/lib/filter/gr_dc_blocker_ff.cc b/gnuradio-core/src/lib/filter/gr_dc_blocker_ff.cc
new file mode 100644
index 000000000..04ee64879
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_dc_blocker_ff.cc
@@ -0,0 +1,138 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2011 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_dc_blocker_ff.h>
+#include <gr_io_signature.h>
+#include <cstdio>
+
+moving_averager_f::moving_averager_f(int D)
+ : d_length(D), d_out(0), d_out_d1(0), d_out_d2(0)
+{
+ d_delay_line = std::deque<float>(d_length-1, 0);
+}
+
+moving_averager_f::~moving_averager_f()
+{
+}
+
+float
+moving_averager_f::filter(float x)
+{
+ d_out_d1 = d_out;
+ d_delay_line.push_back(x);
+ d_out = d_delay_line[0];
+ d_delay_line.pop_front();
+
+ float y = x - d_out_d1 + d_out_d2;
+ d_out_d2 = y;
+
+ return (y / (float)(d_length));
+}
+
+
+
+gr_dc_blocker_ff_sptr gr_make_dc_blocker_ff (int D, bool long_form)
+{
+ return gnuradio::get_initial_sptr(new gr_dc_blocker_ff(D, long_form));
+}
+
+
+gr_dc_blocker_ff::gr_dc_blocker_ff (int D, bool long_form)
+ : gr_sync_block ("dc_blocker_ff",
+ gr_make_io_signature (1, 1, sizeof(float)),
+ gr_make_io_signature (1, 1, sizeof(float))),
+ d_length(D), d_long_form(long_form)
+{
+ if(d_long_form) {
+ d_ma_0 = new moving_averager_f(D);
+ d_ma_1 = new moving_averager_f(D);
+ d_ma_2 = new moving_averager_f(D);
+ d_ma_3 = new moving_averager_f(D);
+ d_delay_line = std::deque<float>(d_length-1, 0);
+ }
+ else {
+ d_ma_0 = new moving_averager_f(D);
+ d_ma_1 = new moving_averager_f(D);
+ }
+}
+
+gr_dc_blocker_ff::~gr_dc_blocker_ff()
+{
+ if(d_long_form) {
+ delete d_ma_0;
+ delete d_ma_1;
+ delete d_ma_2;
+ delete d_ma_3;
+ }
+ else {
+ delete d_ma_0;
+ delete d_ma_1;
+ }
+}
+
+int
+gr_dc_blocker_ff::get_group_delay()
+{
+ if(d_long_form)
+ return (2*d_length-2);
+ else
+ return d_length - 1;
+}
+
+int
+gr_dc_blocker_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];
+
+ if(d_long_form) {
+ float y1, y2, y3, y4, d;
+ for(int i = 0; i < noutput_items; i++) {
+ y1 = d_ma_0->filter(in[i]);
+ y2 = d_ma_1->filter(y1);
+ y3 = d_ma_2->filter(y2);
+ y4 = d_ma_3->filter(y3);
+
+ d_delay_line.push_back(d_ma_0->delayed_sig());
+ d = d_delay_line[0];
+ d_delay_line.pop_front();
+
+ out[i] = d - y4;
+ }
+ }
+ else {
+ float y1, y2;
+ for(int i = 0; i < noutput_items; i++) {
+ y1 = d_ma_0->filter(in[i]);
+ y2 = d_ma_1->filter(y1);
+ out[i] = d_ma_0->delayed_sig() - y2;
+ }
+ }
+
+ return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/filter/gr_dc_blocker_ff.h b/gnuradio-core/src/lib/filter/gr_dc_blocker_ff.h
new file mode 100644
index 000000000..d69f24835
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_dc_blocker_ff.h
@@ -0,0 +1,112 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2011 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+
+#ifndef INCLUDED_GR_DC_BLOCKER_FF_H
+#define INCLUDED_GR_DC_BLOCKER_FF_H
+
+#include <gr_core_api.h>
+#include <gr_sync_block.h>
+#include <deque>
+
+class GR_CORE_API moving_averager_f
+{
+public:
+ moving_averager_f(int D);
+ ~moving_averager_f();
+
+ float filter(float x);
+ float delayed_sig() { return d_out; }
+
+private:
+ int d_length;
+ float d_out, d_out_d1, d_out_d2;
+ std::deque<float> d_delay_line;
+};
+
+
+class gr_dc_blocker_ff;
+typedef boost::shared_ptr<gr_dc_blocker_ff> gr_dc_blocker_ff_sptr;
+GR_CORE_API gr_dc_blocker_ff_sptr gr_make_dc_blocker_ff (int D=32, bool long_form=true);
+
+/*!
+ * \class gr_dc_blocker_ff
+ * \brief a computationally efficient controllable DC blocker
+ *
+ * \ingroup filter_blk
+ *
+ * This block implements a computationally efficient DC blocker that produces
+ * a tighter notch filter around DC for a smaller group delay than an
+ * equivalent FIR filter or using a single pole IIR filter (though the IIR
+ * filter is computationally cheaper).
+ *
+ * The block defaults to using a delay line of length 32 and the long form
+ * of the filter. Optionally, the delay line length can be changed to alter
+ * the width of the DC notch (longer lines will decrease the width).
+ *
+ * The long form of the filter produces a nearly flat response outside of
+ * the notch but at the cost of a group delay of 2D-2.
+ *
+ * The short form of the filter does not have as flat a response in the
+ * passband but has a group delay of only D-1 and is cheaper to compute.
+ *
+ * The theory behind this block can be found in the paper:
+ *
+ * <B><EM>R. Yates, "DC Blocker Algorithms," IEEE Signal Processing Magazine,
+ * Mar. 2008, pp 132-134.</EM></B>
+ */
+class GR_CORE_API gr_dc_blocker_ff : public gr_sync_block
+{
+ private:
+ /*!
+ * Build the DC blocker.
+ * \param D (int) the length of the delay line
+ * \param long_form (bool) whether to use long (true, default) or short form
+ */
+ friend GR_CORE_API gr_dc_blocker_ff_sptr gr_make_dc_blocker_ff (int D, bool long_form);
+
+ int d_length;
+ bool d_long_form;
+ moving_averager_f *d_ma_0;
+ moving_averager_f *d_ma_1;
+ moving_averager_f *d_ma_2;
+ moving_averager_f *d_ma_3;
+ std::deque<float> d_delay_line;
+
+ gr_dc_blocker_ff (int D, bool long_form);
+
+public:
+ ~gr_dc_blocker_ff ();
+
+ /*!
+ * Get the blocker's group delay that is based on length of delay lines
+ */
+ int get_group_delay();
+
+ //int set_length(int D);
+
+ 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_dc_blocker_ff.i b/gnuradio-core/src/lib/filter/gr_dc_blocker_ff.i
new file mode 100644
index 000000000..065eb441d
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_dc_blocker_ff.i
@@ -0,0 +1,34 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2011 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,dc_blocker_ff);
+
+gr_dc_blocker_ff_sptr gr_make_dc_blocker_ff (int D=32, bool long_form=true);
+
+class gr_dc_blocker_ff : public gr_sync_block
+{
+ private:
+ gr_dc_blocker_ff (int D, bool long_form);
+
+ public:
+ ~gr_dc_blocker_ff ();
+};
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
index 000000000..08e231a44
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_fft_filter_ccc.cc
@@ -0,0 +1,132 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+/*
+ * 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 <gri_fft_filter_ccc_generic.h>
+#include <gr_io_signature.h>
+#include <gri_fft.h>
+#include <math.h>
+#include <assert.h>
+#include <stdexcept>
+#include <gr_firdes.h>
+
+#include <cstdio>
+#include <iostream>
+#include <string.h>
+
+gr_fft_filter_ccc_sptr gr_make_fft_filter_ccc (int decimation,
+ const std::vector<gr_complex> &taps,
+ int nthreads)
+{
+ return gnuradio::get_initial_sptr(new gr_fft_filter_ccc (decimation, taps, nthreads));
+}
+
+
+gr_fft_filter_ccc::gr_fft_filter_ccc (int decimation,
+ const std::vector<gr_complex> &taps,
+ int nthreads)
+ : 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_updated(false)
+{
+ set_history(1);
+
+#if 1 // don't enable the sse version until handling it is worked out
+ d_filter = new gri_fft_filter_ccc_generic(decimation, taps, nthreads);
+#else
+ d_filter = new gri_fft_filter_ccc_sse(decimation, taps);
+#endif
+
+ d_new_taps = taps;
+ d_nsamples = d_filter->set_taps(taps);
+ set_output_multiple(d_nsamples);
+}
+
+gr_fft_filter_ccc::~gr_fft_filter_ccc ()
+{
+ delete d_filter;
+}
+
+void
+gr_fft_filter_ccc::set_taps (const std::vector<gr_complex> &taps)
+{
+ d_new_taps = taps;
+ d_updated = true;
+}
+
+std::vector<gr_complex>
+gr_fft_filter_ccc::taps () const
+{
+ return d_new_taps;
+}
+
+void
+gr_fft_filter_ccc::set_nthreads(int n)
+{
+ if(d_filter)
+ d_filter->set_nthreads(n);
+}
+
+int
+gr_fft_filter_ccc::nthreads() const
+{
+ if(d_filter)
+ return d_filter->nthreads();
+ else
+ return 0;
+}
+
+
+int
+gr_fft_filter_ccc::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];
+
+ if (d_updated){
+ d_nsamples = d_filter->set_taps(d_new_taps);
+ d_updated = false;
+ set_output_multiple(d_nsamples);
+ return 0; // output multiple may have changed
+ }
+
+ assert(noutput_items % d_nsamples == 0);
+
+ d_filter->filter(noutput_items, in, out);
+
+ //assert((out - (gr_complex *) output_items[0]) == noutput_items);
+
+ 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
index 000000000..4b478b65f
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_fft_filter_ccc.h
@@ -0,0 +1,90 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifndef INCLUDED_GR_FFT_FILTER_CCC_H
+#define INCLUDED_GR_FFT_FILTER_CCC_H
+
+#include <gr_core_api.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_CORE_API gr_fft_filter_ccc_sptr
+gr_make_fft_filter_ccc (int decimation, const std::vector<gr_complex> &taps,
+ int nthreads=1);
+
+//class gri_fft_filter_ccc_sse;
+class gri_fft_filter_ccc_generic;
+
+/*!
+ * \brief Fast FFT filter with gr_complex input, gr_complex output and gr_complex taps
+ * \ingroup filter_blk
+ */
+class GR_CORE_API gr_fft_filter_ccc : public gr_sync_decimator
+{
+ private:
+ friend GR_CORE_API gr_fft_filter_ccc_sptr
+ gr_make_fft_filter_ccc (int decimation, const std::vector<gr_complex> &taps,
+ int nthreads);
+
+ int d_nsamples;
+ bool d_updated;
+#if 1 // don't enable the sse version until handling it is worked out
+ gri_fft_filter_ccc_generic *d_filter;
+#else
+ gri_fft_filter_ccc_sse *d_filter;
+#endif
+ std::vector<gr_complex> d_new_taps;
+
+ /*!
+ * Construct a FFT filter with the given taps
+ *
+ * \param decimation >= 1
+ * \param taps complex filter taps
+ * \param nthreads number of threads for the FFT to use
+ */
+ gr_fft_filter_ccc (int decimation, const std::vector<gr_complex> &taps,
+ int nthreads=1);
+
+ public:
+ ~gr_fft_filter_ccc ();
+
+ void set_taps (const std::vector<gr_complex> &taps);
+ std::vector<gr_complex> taps () const;
+
+ /*!
+ * \brief Set number of threads to use.
+ */
+ void set_nthreads(int n);
+
+ /*!
+ * \brief Get number of threads being used.
+ */
+ int nthreads() const;
+
+ 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
index 000000000..76837b582
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_fft_filter_ccc.i
@@ -0,0 +1,46 @@
+/* -*- 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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,fft_filter_ccc)
+
+gr_fft_filter_ccc_sptr
+gr_make_fft_filter_ccc (int decimation,
+ const std::vector<gr_complex> &taps,
+ int nthreads=1
+ ) 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,
+ int nthreads=1);
+
+ public:
+ ~gr_fft_filter_ccc ();
+
+ void set_taps (const std::vector<gr_complex> &taps);
+ std::vector<gr_complex> taps () const;
+
+ void set_nthreads(int n);
+ int nthreads() const;
+
+};
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
index 000000000..a09feb7f1
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_fft_filter_fff.cc
@@ -0,0 +1,123 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_fft_filter_fff.h>
+#include <gri_fft_filter_fff_generic.h>
+#include <gr_io_signature.h>
+#include <assert.h>
+#include <stdexcept>
+
+#include <cstdio>
+#include <iostream>
+#include <string.h>
+
+gr_fft_filter_fff_sptr gr_make_fft_filter_fff (int decimation,
+ const std::vector<float> &taps,
+ int nthreads)
+{
+ return gnuradio::get_initial_sptr(new gr_fft_filter_fff (decimation, taps, nthreads));
+}
+
+
+gr_fft_filter_fff::gr_fft_filter_fff (int decimation,
+ const std::vector<float> &taps,
+ int nthreads)
+ : gr_sync_decimator ("fft_filter_fff",
+ gr_make_io_signature (1, 1, sizeof (float)),
+ gr_make_io_signature (1, 1, sizeof (float)),
+ decimation),
+ d_updated(false)
+{
+ set_history(1);
+
+#if 1 // don't enable the sse version until handling it is worked out
+ d_filter = new gri_fft_filter_fff_generic(decimation, taps, nthreads);
+#else
+ d_filter = new gri_fft_filter_fff_sse(decimation, taps);
+#endif
+
+ d_new_taps = taps;
+ d_nsamples = d_filter->set_taps(taps);
+ set_output_multiple(d_nsamples);
+}
+
+gr_fft_filter_fff::~gr_fft_filter_fff ()
+{
+ delete d_filter;
+}
+
+void
+gr_fft_filter_fff::set_taps (const std::vector<float> &taps)
+{
+ d_new_taps = taps;
+ d_updated = true;
+}
+
+std::vector<float>
+gr_fft_filter_fff::taps () const
+{
+ return d_new_taps;
+}
+
+void
+gr_fft_filter_fff::set_nthreads(int n)
+{
+ if(d_filter)
+ d_filter->set_nthreads(n);
+}
+
+int
+gr_fft_filter_fff::nthreads() const
+{
+ if(d_filter)
+ return d_filter->nthreads();
+ else
+ return 0;
+}
+
+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){
+ d_nsamples = d_filter->set_taps(d_new_taps);
+ d_updated = false;
+ set_output_multiple(d_nsamples);
+ return 0; // output multiple may have changed
+ }
+
+ assert(noutput_items % d_nsamples == 0);
+
+ d_filter->filter(noutput_items, in, out);
+
+ //assert((out - (float *) output_items[0]) == noutput_items);
+
+ 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
index 000000000..309a55135
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_fft_filter_fff.h
@@ -0,0 +1,88 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifndef INCLUDED_GR_FFT_FILTER_FFF_H
+#define INCLUDED_GR_FFT_FILTER_FFF_H
+
+#include <gr_core_api.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_CORE_API gr_fft_filter_fff_sptr
+gr_make_fft_filter_fff (int decimation, const std::vector<float> &taps,
+ int nthreads=1);
+
+class gri_fft_filter_fff_generic;
+//class gri_fft_filter_fff_sse;
+
+/*!
+ * \brief Fast FFT filter with float input, float output and float taps
+ * \ingroup filter_blk
+ */
+class GR_CORE_API gr_fft_filter_fff : public gr_sync_decimator
+{
+ private:
+ friend GR_CORE_API gr_fft_filter_fff_sptr
+ gr_make_fft_filter_fff (int decimation, const std::vector<float> &taps,
+ int nthreads);
+
+ int d_nsamples;
+ bool d_updated;
+#if 1 // don't enable the sse version until handling it is worked out
+ gri_fft_filter_fff_generic *d_filter;
+#else
+ gri_fft_filter_fff_sse *d_filter;
+#endif
+ std::vector<float> d_new_taps;
+
+ /*!
+ * Construct a FFT filter with the given taps
+ *
+ * \param decimation >= 1
+ * \param taps float filter taps
+ * \param nthreads number of threads for the FFT to use
+ */
+ gr_fft_filter_fff (int decimation, const std::vector<float> &taps,
+ int nthreads=1);
+
+ public:
+ ~gr_fft_filter_fff ();
+
+ void set_taps (const std::vector<float> &taps);
+ std::vector<float> taps () const;
+
+ /*!
+ * \brief Set number of threads to use.
+ */
+ void set_nthreads(int n);
+
+ /*!
+ * \brief Get number of threads being used.
+ */
+ int nthreads() const;
+
+ 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
index 000000000..86c554893
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_fft_filter_fff.i
@@ -0,0 +1,45 @@
+/* -*- 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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,fft_filter_fff)
+
+gr_fft_filter_fff_sptr
+gr_make_fft_filter_fff (int decimation,
+ const std::vector<float> &taps,
+ int nthreads=1
+ ) 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,
+ int nthreads=1);
+
+ public:
+ ~gr_fft_filter_fff ();
+
+ void set_taps (const std::vector<float> &taps);
+ std::vector<float> taps () const;
+ void set_nthreads(int n);
+ int nthreads() const;
+
+};
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
index 000000000..af8a8e9e7
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_filter_delay_fc.cc
@@ -0,0 +1,80 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#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 gnuradio::get_initial_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
index 000000000..fee11243a
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_filter_delay_fc.h
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_FILTER_DELAY_FC_H
+#define INCLUDED_GR_FILTER_DELAY_FC_H
+
+#include <gr_core_api.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_CORE_API 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_blk
+ *
+ * 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_CORE_API 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_CORE_API 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
index 000000000..54b721cee
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_filter_delay_fc.i
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,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
index 000000000..2396f0fe6
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_fir_XXX.cc.t
@@ -0,0 +1,30 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#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
index 000000000..197bb3cd2
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_fir_XXX.h.t
@@ -0,0 +1,124 @@
+/* -*- 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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, 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 <gr_core_api.h>
+#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 GR_CORE_API @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
index 000000000..11b4fd50f
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_fir_XXX_generic.cc.t
@@ -0,0 +1,103 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#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
index 000000000..f7382d739
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_fir_XXX_generic.h.t
@@ -0,0 +1,78 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifndef @GUARD_NAME@
+#define @GUARD_NAME@
+
+#include <gr_core_api.h>
+#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 GR_CORE_API @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
index 000000000..d88b696c9
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_fir_ccc_simd.cc
@@ -0,0 +1,142 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002,2007 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <gr_fir_ccc_simd.h>
+
+#include <assert.h>
+#include <malloc16.h>
+#include <iostream>
+#include <stdexcept>
+
+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;
+
+ if (((intptr_t) input & 0x7) != 0)
+ throw std::invalid_argument("gr_complex must be 8-byte aligned");
+
+ // 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
index 000000000..ed7249c91
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_fir_ccc_simd.h
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifndef INCLUDED_GR_FIR_CCC_SIMD_H
+#define INCLUDED_GR_FIR_CCC_SIMD_H
+
+#include <gr_core_api.h>
+#include <gr_fir_ccc_generic.h>
+
+/*!
+ * \brief common base class for SIMD versions of gr_fir_ccc
+ * \ingroup filter_primitive
+ *
+ * This base class handles alignment issues common to SSE and 3DNOW
+ * subclasses.
+ */
+
+class GR_CORE_API 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
index 000000000..28bc008e8
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_fir_ccc_x86.cc
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <gr_fir_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
index 000000000..0a9d2c83c
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_fir_ccc_x86.h
@@ -0,0 +1,56 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_FIR_CCC_X86_H
+#define INCLUDED_GR_FIR_CCC_X86_H
+
+#include <gr_core_api.h>
+#include <gr_fir_ccc_simd.h>
+
+/*!
+ * \brief 3DNow! version of gr_fir_ccc
+ */
+class GR_CORE_API 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_CORE_API 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_CORE_API 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_armv7_a.cc b/gnuradio-core/src/lib/filter/gr_fir_ccf_armv7_a.cc
new file mode 100644
index 000000000..d849c3dd5
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_fir_ccf_armv7_a.cc
@@ -0,0 +1,91 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008,2009,2011 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <gr_fir_ccf_armv7_a.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdexcept>
+#include <assert.h>
+#include <gr_math.h>
+#include <dotprod_ccf_armv7_a.h>
+
+#define FLOATS_PER_VEC 4
+
+gr_fir_ccf_armv7_a::gr_fir_ccf_armv7_a()
+ : gr_fir_ccf_generic(),
+ d_naligned_taps(0), d_aligned_taps(0)
+{
+}
+
+gr_fir_ccf_armv7_a::gr_fir_ccf_armv7_a (const std::vector<float> &new_taps)
+ : gr_fir_ccf_generic(new_taps),
+ d_naligned_taps(0), d_aligned_taps(0)
+{
+ set_taps(new_taps);
+}
+
+gr_fir_ccf_armv7_a::~gr_fir_ccf_armv7_a()
+{
+ if (d_aligned_taps){
+ free(d_aligned_taps);
+ d_aligned_taps = 0;
+ }
+}
+
+void
+gr_fir_ccf_armv7_a::set_taps(const std::vector<float> &inew_taps)
+{
+ gr_fir_ccf_generic::set_taps(inew_taps); // call superclass
+ d_naligned_taps = gr_p2_round_up(ntaps(), FLOATS_PER_VEC);
+
+ if (d_aligned_taps){
+ free(d_aligned_taps);
+ d_aligned_taps = 0;
+ }
+ void *p;
+ int r = posix_memalign(&p, sizeof(float), d_naligned_taps * sizeof(d_aligned_taps[0]));
+ if (r != 0){
+ throw std::bad_alloc();
+ }
+ d_aligned_taps = (float *) p;
+ memcpy(d_aligned_taps, &d_taps[0], ntaps() * sizeof(d_aligned_taps[0]));
+ for (size_t i = ntaps(); i < d_naligned_taps; i++)
+ d_aligned_taps[i] = 0.0;
+}
+
+
+gr_complex
+gr_fir_ccf_armv7_a::filter (const gr_complex input[])
+{
+ if (d_naligned_taps == 0)
+ return 0.0;
+
+ gr_complex result;
+ float *presult = reinterpret_cast<float *>(&result);
+ const float *pinput = reinterpret_cast<const float *>(input);
+
+ dotprod_ccf_armv7_a(pinput, d_aligned_taps, presult, d_naligned_taps);
+ return result;
+}
diff --git a/gnuradio-core/src/lib/filter/gr_fir_ccf_armv7_a.h b/gnuradio-core/src/lib/filter/gr_fir_ccf_armv7_a.h
new file mode 100644
index 000000000..e4844bae1
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_fir_ccf_armv7_a.h
@@ -0,0 +1,45 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008,2009,2011 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+#ifndef INCLUDED_GR_FIR_CCF_ARMV7_A_H
+#define INCLUDED_GR_FIR_CCF_ARMV7_A_H
+
+#include <gr_fir_ccf_generic.h>
+
+/*!
+ * \brief armv7_a using NEON coprocessor version of gr_fir_ccf
+ */
+class gr_fir_ccf_armv7_a : public gr_fir_ccf_generic
+{
+protected:
+
+ size_t d_naligned_taps; // number of taps (multiple of 4)
+ float *d_aligned_taps; // 16-byte aligned, and zero padded to multiple of 4
+
+public:
+ gr_fir_ccf_armv7_a();
+ gr_fir_ccf_armv7_a(const std::vector<float> &taps);
+ ~gr_fir_ccf_armv7_a();
+
+ virtual void set_taps (const std::vector<float> &taps);
+ virtual gr_complex filter (const gr_complex input[]);
+};
+
+#endif /* INCLUDED_GR_FIR_CCF_ARMV7_A*_H */
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
index 000000000..872415e8e
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_fir_ccf_simd.cc
@@ -0,0 +1,141 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002,2007 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <gr_fir_ccf_simd.h>
+
+#include <assert.h>
+#include <malloc16.h>
+#include <iostream>
+#include <stdexcept>
+
+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;
+
+ if (((intptr_t) input & 0x7) != 0)
+ throw std::invalid_argument("gr_complex must be 8-byte aligned");
+
+ // 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
index 000000000..3c3e7e4f5
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_fir_ccf_simd.h
@@ -0,0 +1,66 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifndef INCLUDED_GR_FIR_CCF_SIMD_H
+#define INCLUDED_GR_FIR_CCF_SIMD_H
+
+#include <gr_core_api.h>
+#include <gr_fir_ccf_generic.h>
+
+
+/*!
+ * \brief common base class for SIMD versions of gr_fir_ccf
+ * \ingroup filter_primitive
+ *
+ * This base class handles alignment issues common to SSE and 3DNOW
+ * subclasses.
+ */
+
+class GR_CORE_API 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
index 000000000..f26d4ecc2
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_fir_ccf_x86.cc
@@ -0,0 +1,60 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#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
index 000000000..6b260c3db
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_fir_ccf_x86.h
@@ -0,0 +1,51 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_FIR_CCF_X86_H
+#define INCLUDED_GR_FIR_CCF_X86_H
+
+#include <gr_core_api.h>
+#include <gr_fir_ccf_simd.h>
+
+/*!
+ * \brief 3DNow! version of gr_fir_ccf
+ * \ingroup filter_primitive
+ */
+class GR_CORE_API 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
+ * \ingroup filter_primitive
+ */
+class GR_CORE_API 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
index 000000000..5b75a43fd
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_fir_fcc_simd.cc
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <gr_fir_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
index 000000000..b7463070b
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_fir_fcc_simd.h
@@ -0,0 +1,66 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifndef INCLUDED_GR_FIR_FCC_SIMD_H
+#define INCLUDED_GR_FIR_FCC_SIMD_H
+
+#include <gr_core_api.h>
+#include <gr_fir_fcc_generic.h>
+
+
+/*!
+ * \brief common base class for SIMD versions of gr_fir_fcc
+ * \ingroup filter_primitive
+ *
+ * This base class handles alignment issues common to SSE and 3DNOW
+ * subclasses.
+ */
+
+class GR_CORE_API 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
index 000000000..d9904133c
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_fir_fcc_x86.cc
@@ -0,0 +1,60 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#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
index 000000000..3fc6c4855
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_fir_fcc_x86.h
@@ -0,0 +1,51 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_FIR_FCC_X86_H
+#define INCLUDED_GR_FIR_FCC_X86_H
+
+#include <gr_core_api.h>
+#include <gr_fir_fcc_simd.h>
+
+/*!
+ * \brief 3DNow! version of gr_fir_fcc
+ * \ingroup filter_primitive
+ */
+class GR_CORE_API 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
+ * \ingroup filter_blk
+ */
+class GR_CORE_API 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_altivec.cc b/gnuradio-core/src/lib/filter/gr_fir_fff_altivec.cc
new file mode 100644
index 000000000..b81283ce5
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_fir_fff_altivec.cc
@@ -0,0 +1,84 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <gr_fir_fff_altivec.h>
+#include <stdexcept>
+#include <assert.h>
+#include <gr_math.h>
+#include <gr_altivec.h>
+#include <dotprod_fff_altivec.h>
+#include <string.h>
+#include "posix_memalign.h"
+
+gr_fir_fff_altivec::gr_fir_fff_altivec()
+ : gr_fir_fff_generic(),
+ d_naligned_taps(0), d_aligned_taps(0)
+{
+}
+
+gr_fir_fff_altivec::gr_fir_fff_altivec (const std::vector<float> &new_taps)
+ : gr_fir_fff_generic(new_taps),
+ d_naligned_taps(0), d_aligned_taps(0)
+{
+ set_taps(new_taps);
+}
+
+gr_fir_fff_altivec::~gr_fir_fff_altivec()
+{
+ if (d_aligned_taps){
+ free(d_aligned_taps);
+ d_aligned_taps = 0;
+ }
+}
+
+void
+gr_fir_fff_altivec::set_taps(const std::vector<float> &inew_taps)
+{
+ gr_fir_fff_generic::set_taps(inew_taps); // call superclass
+ d_naligned_taps = gr_p2_round_up(ntaps(), FLOATS_PER_VEC);
+
+ if (d_aligned_taps){
+ free(d_aligned_taps);
+ d_aligned_taps = 0;
+ }
+ void *p;
+ int r = posix_memalign(&p, sizeof(vec_float4), d_naligned_taps * sizeof(d_aligned_taps[0]));
+ if (r != 0){
+ throw std::bad_alloc();
+ }
+ d_aligned_taps = (float *) p;
+ memcpy(d_aligned_taps, &d_taps[0], ntaps() * sizeof(d_aligned_taps[0]));
+ for (size_t i = ntaps(); i < d_naligned_taps; i++)
+ d_aligned_taps[i] = 0.0;
+}
+
+
+float
+gr_fir_fff_altivec::filter (const float input[])
+{
+ if (d_naligned_taps == 0)
+ return 0.0;
+
+ return dotprod_fff_altivec(input, d_aligned_taps, d_naligned_taps);
+}
diff --git a/gnuradio-core/src/lib/filter/gr_fir_fff_altivec.h b/gnuradio-core/src/lib/filter/gr_fir_fff_altivec.h
new file mode 100644
index 000000000..a3d4a2aae
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_fir_fff_altivec.h
@@ -0,0 +1,46 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+#ifndef INCLUDED_GR_FIR_FFF_ALTIVEC_H
+#define INCLUDED_GR_FIR_FFF_ALTIVEC_H
+
+#include <gr_core_api.h>
+#include <gr_fir_fff_generic.h>
+
+/*!
+ * \brief altivec version of gr_fir_fff
+ */
+class GR_CORE_API gr_fir_fff_altivec : public gr_fir_fff_generic
+{
+protected:
+
+ size_t d_naligned_taps; // number of taps (multiple of 4)
+ float *d_aligned_taps; // 16-byte aligned, and zero padded to multiple of 4
+
+public:
+ gr_fir_fff_altivec();
+ gr_fir_fff_altivec(const std::vector<float> &taps);
+ ~gr_fir_fff_altivec();
+
+ virtual void set_taps (const std::vector<float> &taps);
+ virtual float filter (const float input[]);
+};
+
+#endif /* INCLUDED_GR_FIR_FFF_ALTIVEC_H */
diff --git a/gnuradio-core/src/lib/filter/gr_fir_fff_armv7_a.cc b/gnuradio-core/src/lib/filter/gr_fir_fff_armv7_a.cc
new file mode 100644
index 000000000..b43725420
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_fir_fff_armv7_a.cc
@@ -0,0 +1,86 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008,2009 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <gr_fir_fff_armv7_a.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdexcept>
+#include <assert.h>
+#include <gr_math.h>
+#include <dotprod_fff_armv7_a.h>
+
+#define FLOATS_PER_VEC 8
+
+gr_fir_fff_armv7_a::gr_fir_fff_armv7_a()
+ : gr_fir_fff_generic(),
+ d_naligned_taps(0), d_aligned_taps(0)
+{
+}
+
+gr_fir_fff_armv7_a::gr_fir_fff_armv7_a (const std::vector<float> &new_taps)
+ : gr_fir_fff_generic(new_taps),
+ d_naligned_taps(0), d_aligned_taps(0)
+{
+ set_taps(new_taps);
+}
+
+gr_fir_fff_armv7_a::~gr_fir_fff_armv7_a()
+{
+ if (d_aligned_taps){
+ free(d_aligned_taps);
+ d_aligned_taps = 0;
+ }
+}
+
+void
+gr_fir_fff_armv7_a::set_taps(const std::vector<float> &inew_taps)
+{
+ gr_fir_fff_generic::set_taps(inew_taps); // call superclass
+ d_naligned_taps = gr_p2_round_up(ntaps(), FLOATS_PER_VEC);
+
+ if (d_aligned_taps){
+ free(d_aligned_taps);
+ d_aligned_taps = 0;
+ }
+ void *p;
+ int r = posix_memalign(&p, sizeof(float), d_naligned_taps * sizeof(d_aligned_taps[0]));
+ if (r != 0){
+ throw std::bad_alloc();
+ }
+ d_aligned_taps = (float *) p;
+ memcpy(d_aligned_taps, &d_taps[0], ntaps() * sizeof(d_aligned_taps[0]));
+ for (size_t i = ntaps(); i < d_naligned_taps; i++)
+ d_aligned_taps[i] = 0.0;
+}
+
+
+float
+gr_fir_fff_armv7_a::filter (const float input[])
+{
+ if (d_naligned_taps == 0)
+ return 0.0;
+
+ return dotprod_fff_armv7_a(input, d_aligned_taps, d_naligned_taps);
+}
diff --git a/gnuradio-core/src/lib/filter/gr_fir_fff_armv7_a.h b/gnuradio-core/src/lib/filter/gr_fir_fff_armv7_a.h
new file mode 100644
index 000000000..78863d286
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_fir_fff_armv7_a.h
@@ -0,0 +1,46 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008,2009 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+#ifndef INCLUDED_GR_FIR_FFF_ARMV7_A_H
+#define INCLUDED_GR_FIR_FFF_ARMV7_A_H
+
+#include <gr_core_api.h>
+#include <gr_fir_fff_generic.h>
+
+/*!
+ * \brief armv7_a using NEON coprocessor version of gr_fir_fff
+ */
+class GR_CORE_API gr_fir_fff_armv7_a : public gr_fir_fff_generic
+{
+protected:
+
+ size_t d_naligned_taps; // number of taps (multiple of 4)
+ float *d_aligned_taps; // 16-byte aligned, and zero padded to multiple of 4
+
+public:
+ gr_fir_fff_armv7_a();
+ gr_fir_fff_armv7_a(const std::vector<float> &taps);
+ ~gr_fir_fff_armv7_a();
+
+ virtual void set_taps (const std::vector<float> &taps);
+ virtual float filter (const float input[]);
+};
+
+#endif /* INCLUDED_GR_FIR_FFF_ARMV7_A*_H */
diff --git a/gnuradio-core/src/lib/filter/gr_fir_fff_simd.cc b/gnuradio-core/src/lib/filter/gr_fir_fff_simd.cc
new file mode 100644
index 000000000..d6c28ed45
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_fir_fff_simd.cc
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <gr_fir_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
index 000000000..9d6106266
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_fir_fff_simd.h
@@ -0,0 +1,64 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifndef INCLUDED_GR_FIR_FFF_SIMD_H
+#define INCLUDED_GR_FIR_FFF_SIMD_H
+
+#include <gr_core_api.h>
+#include <gr_fir_fff_generic.h>
+
+/*!
+ * \brief common base class for SIMD versions of gr_fir_fff
+ * \ingroup filter_primitive
+ *
+ * This base class handles alignment issues common to SSE and 3DNOW
+ * subclasses.
+ */
+
+class GR_CORE_API 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
index 000000000..40ac266be
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_fir_fff_x86.cc
@@ -0,0 +1,60 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#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
index 000000000..8d451f0c9
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_fir_fff_x86.h
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_FIR_FFF_X86_H
+#define INCLUDED_GR_FIR_FFF_X86_H
+
+#include <gr_core_api.h>
+#include <gr_fir_fff_simd.h>
+
+/*!
+ * \brief 3DNow! version of gr_fir_fff
+ */
+class GR_CORE_API 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_CORE_API 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
index 000000000..39bc75630
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_fir_filter_XXX.cc.t
@@ -0,0 +1,94 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+/*
+ * 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 gnuradio::get_initial_sptr (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;
+}
+
+std::vector<@TAP_TYPE@>
+@NAME@::taps () const
+{
+ return d_new_taps;
+}
+
+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
index 000000000..b32e04bd3
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_fir_filter_XXX.h.t
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, 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_core_api.h>
+#include <gr_sync_decimator.h>
+
+class @NAME@;
+typedef boost::shared_ptr<@NAME@> @SPTR_NAME@;
+GR_CORE_API @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_blk
+ */
+class GR_CORE_API @NAME@ : public gr_sync_decimator
+{
+ private:
+ friend GR_CORE_API @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);
+ std::vector<@TAP_TYPE@> taps () const;
+
+ 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
index 000000000..d9dc86180
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_fir_filter_XXX.i.t
@@ -0,0 +1,42 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, 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);
+ std::vector<@TAP_TYPE@> taps () const;
+};
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
index 000000000..a49503e6a
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_fir_fsf_simd.cc
@@ -0,0 +1,133 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#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
index 000000000..d63e9dd17
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_fir_fsf_simd.h
@@ -0,0 +1,64 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifndef _GR_FIR_FSF_SIMD_H_
+#define _GR_FIR_FSF_SIMD_H_
+
+#include <gr_core_api.h>
+#include <gr_fir_fsf_generic.h>
+
+/*!
+ * \brief common base class for SIMD versions of gr_fir_fsf
+ * \ingroup filter_primitive
+ *
+ * This base class handles alignment issues common to SSE and 3DNOW
+ * subclasses.
+ */
+
+class GR_CORE_API 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
index 000000000..40ba17d3a
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_fir_fsf_x86.cc
@@ -0,0 +1,60 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#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
index 000000000..df664d5e2
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_fir_fsf_x86.h
@@ -0,0 +1,51 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_FIR_FSF_X86_H
+#define INCLUDED_GR_FIR_FSF_X86_H
+
+#include <gr_core_api.h>
+#include <gr_fir_fsf_simd.h>
+
+/*!
+ * \brief 3DNow! version of gr_fir_fsf
+ * \ingroup filter_primitive
+ */
+class GR_CORE_API 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
+ * \ingroup filter_primitive
+ */
+class GR_CORE_API 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
index 000000000..0b2dd7e61
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_fir_scc_simd.cc
@@ -0,0 +1,140 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#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
index 000000000..72c15f93b
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_fir_scc_simd.h
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifndef INCLUDED_GR_FIR_SCC_SIMD_H
+#define INCLUDED_GR_FIR_SCC_SIMD_H
+
+#include <gr_core_api.h>
+#include <gr_fir_scc_generic.h>
+
+
+/*!
+ * \brief common base class for SIMD versions of gr_fir_scc
+ * \ingroup filter_primitive
+ *
+ * This base class handles alignment issues common to SSE and 3DNOW
+ * subclasses.
+ */
+class GR_CORE_API 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
index 000000000..ab0668c63
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_fir_scc_x86.cc
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <gr_fir_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
index 000000000..85a63251b
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_fir_scc_x86.h
@@ -0,0 +1,59 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_FIR_SCC_X86_H
+#define INCLUDED_GR_FIR_SCC_X86_H
+
+#include <gr_core_api.h>
+#include <gr_fir_scc_simd.h>
+
+/*!
+ * \brief 3DNow! version of gr_fir_scc
+ */
+class GR_CORE_API 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_CORE_API 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_CORE_API 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_armv7_a.cc b/gnuradio-core/src/lib/filter/gr_fir_sysconfig_armv7_a.cc
new file mode 100644
index 000000000..70adbc092
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_fir_sysconfig_armv7_a.cc
@@ -0,0 +1,337 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002,2008,2009,2011 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <gr_fir_sysconfig_armv7_a.h>
+#include <gr_cpu.h>
+
+#include <gr_fir_ccf.h>
+#include <gr_fir_ccf_generic.h>
+#include <gr_fir_ccf_armv7_a.h>
+#include <gr_fir_fcc.h>
+#include <gr_fir_fcc_generic.h>
+#include <gr_fir_fff.h>
+#include <gr_fir_fff_generic.h>
+#include <gr_fir_fff_armv7_a.h>
+#include <gr_fir_fsf.h>
+#include <gr_fir_fsf_generic.h>
+#include <gr_fir_ccc.h>
+#include <gr_fir_ccc_generic.h>
+#include <gr_fir_scc.h>
+#include <gr_fir_scc_generic.h>
+
+#include <iostream>
+using std::cerr;
+
+///\todo Remove commented out code for altivec and replace with NEON versions.
+
+/*
+ * ----------------------------------------------------------------
+ * static functions that serve as constructors...
+ * ----------------------------------------------------------------
+ */
+
+static gr_fir_ccf *
+make_gr_fir_ccf_armv7_a (const std::vector<float> &taps)
+{
+ return new gr_fir_ccf_armv7_a(taps);
+}
+
+#if 0
+static gr_fir_fcc *
+make_gr_fir_fcc_altivec(const std::vector<gr_complex> &taps)
+{
+ return new gr_fir_fcc_altivec(taps);
+}
+
+static gr_fir_ccc *
+make_gr_fir_ccc_altivec (const std::vector<gr_complex> &taps)
+{
+ return new gr_fir_ccc_altivec (taps);
+}
+#endif
+
+static gr_fir_fff *
+make_gr_fir_fff_armv7_a (const std::vector<float> &taps)
+{
+ return new gr_fir_fff_armv7_a (taps);
+}
+
+#if 0
+static gr_fir_fsf *
+make_gr_fir_fsf_altivec (const std::vector<float> &taps)
+{
+ return new gr_fir_fsf_altivec (taps);
+}
+
+static gr_fir_scc *
+make_gr_fir_scc_altivec(const std::vector<gr_complex> &taps)
+{
+ return new gr_fir_scc_altivec(taps);
+}
+#endif
+
+/*
+ * ----------------------------------------------------------------
+ * Return instances of the fastest arm versions of these classes.
+ *
+ * check CPUID, if has armv7-a, return armv7-a version,
+ * else return generic version. This will break
+ * when someone makes an armv7-a without a NEON
+ * coprocessor.
+ * ----------------------------------------------------------------
+ */
+
+gr_fir_ccf *
+gr_fir_sysconfig_armv7_a::create_gr_fir_ccf (const std::vector<float> &taps)
+{
+ static bool first = true;
+
+ if (gr_cpu::has_armv7_a ()){
+ if (first){
+ cerr << ">>> gr_fir_ccf: using armv7_a\n";
+ first = false;
+ }
+ return make_gr_fir_ccf_armv7_a (taps);
+ }
+
+ if (0 && first){
+ cerr << ">>> gr_fir_ccf: handing off to parent class\n";
+ first = false;
+ }
+ return gr_fir_sysconfig_generic::create_gr_fir_ccf (taps);
+}
+
+gr_fir_fcc *
+gr_fir_sysconfig_armv7_a::create_gr_fir_fcc (const std::vector<gr_complex> &taps)
+{
+ static bool first = true;
+
+#if 0
+ if (gr_cpu::has_altivec ()){
+ if (first){
+ cerr << ">>> gr_fir_fcc: using altivec\n";
+ first = false;
+ }
+ return make_gr_fir_fcc_altivec (taps);
+ }
+#endif
+
+ if (0 && first){
+ cerr << ">>> gr_fir_fcc: handing off to parent class\n";
+ first = false;
+ }
+ return gr_fir_sysconfig_generic::create_gr_fir_fcc (taps);
+}
+
+gr_fir_ccc *
+gr_fir_sysconfig_armv7_a::create_gr_fir_ccc (const std::vector<gr_complex> &taps)
+{
+ static bool first = true;
+
+#if 0
+ if (gr_cpu::has_altivec ()){
+ if (first){
+ cerr << ">>> gr_fir_ccc: using altivec\n";
+ first = false;
+ }
+ return make_gr_fir_ccc_altivec (taps);
+ }
+#endif
+
+ if (0 && first){
+ cerr << ">>> gr_fir_ccc: handing off to parent class\n";
+ first = false;
+ }
+ return gr_fir_sysconfig_generic::create_gr_fir_ccc (taps);
+}
+
+gr_fir_fff *
+gr_fir_sysconfig_armv7_a::create_gr_fir_fff (const std::vector<float> &taps)
+{
+ static bool first = true;
+
+ if (gr_cpu::has_armv7_a ()){
+ if (first){
+ cerr << ">>> gr_fir_fff: using armv7_a\n";
+ first = false;
+ }
+ return make_gr_fir_fff_armv7_a (taps);
+ }
+
+ if (0 && first){
+ cerr << ">>> gr_fir_fff: handing off to parent class\n";
+ first = false;
+ }
+ return gr_fir_sysconfig_generic::create_gr_fir_fff (taps);
+}
+
+gr_fir_fsf *
+gr_fir_sysconfig_armv7_a::create_gr_fir_fsf (const std::vector<float> &taps)
+{
+ static bool first = true;
+
+#if 0
+ if (gr_cpu::has_altivec ()){
+ if (first){
+ cerr << ">>> gr_fir_fsf: using altivec\n";
+ first = false;
+ }
+ return make_gr_fir_fsf_altivec (taps);
+ }
+#endif
+
+ if (0 && first){
+ cerr << ">>> gr_fir_fsf: handing off to parent class\n";
+ first = false;
+ }
+ return gr_fir_sysconfig_generic::create_gr_fir_fsf (taps);
+}
+
+
+gr_fir_scc *
+gr_fir_sysconfig_armv7_a::create_gr_fir_scc (const std::vector<gr_complex> &taps)
+{
+ static bool first = true;
+
+#if 0
+ if (gr_cpu::has_altivec ()){
+ if (first){
+ cerr << ">>> gr_fir_scc: using altivec\n";
+ first = false;
+ }
+ return make_gr_fir_scc_altivec (taps);
+ }
+#endif
+
+ if (0 && first){
+ cerr << ">>> gr_fir_scc: handing off to parent class\n";
+ first = false;
+ }
+ return gr_fir_sysconfig_generic::create_gr_fir_scc (taps);
+}
+
+/*
+ * ----------------------------------------------------------------
+ * Return info about available implementations
+ * ----------------------------------------------------------------
+ */
+
+void
+gr_fir_sysconfig_armv7_a::get_gr_fir_ccf_info (std::vector<gr_fir_ccf_info> *info)
+{
+ // invoke parent..
+ gr_fir_sysconfig_generic::get_gr_fir_ccf_info (info);
+
+ // add our stuff...
+ gr_fir_ccf_info t;
+ if (gr_cpu::has_armv7_a ()){
+ t.name = "armv7_a";
+ t.create = make_gr_fir_ccf_armv7_a;
+ (*info).push_back (t);
+ }
+}
+
+void
+gr_fir_sysconfig_armv7_a::get_gr_fir_fcc_info (std::vector<gr_fir_fcc_info> *info)
+{
+ // invoke parent..
+ gr_fir_sysconfig_generic::get_gr_fir_fcc_info (info);
+
+#if 0
+ // add our stuff...
+ gr_fir_fcc_info t;
+ if (gr_cpu::has_altivec ()){
+ t.name = "altivec";
+ t.create = make_gr_fir_fcc_altivec;
+ (*info).push_back (t);
+ }
+#endif
+}
+
+void
+gr_fir_sysconfig_armv7_a::get_gr_fir_ccc_info (std::vector<gr_fir_ccc_info> *info)
+{
+ // invoke parent..
+ gr_fir_sysconfig_generic::get_gr_fir_ccc_info (info);
+
+#if 0
+ // add our stuff...
+ gr_fir_ccc_info t;
+ if (gr_cpu::has_altivec ()){
+ t.name = "altivec";
+ t.create = make_gr_fir_ccc_altivec;
+ (*info).push_back (t);
+ }
+#endif
+}
+
+void
+gr_fir_sysconfig_armv7_a::get_gr_fir_fff_info (std::vector<gr_fir_fff_info> *info)
+{
+ // invoke parent..
+ gr_fir_sysconfig_generic::get_gr_fir_fff_info (info);
+
+ // add our stuff...
+ gr_fir_fff_info t;
+ if (gr_cpu::has_armv7_a ()){
+ t.name = "armv7_a";
+ t.create = make_gr_fir_fff_armv7_a;
+ (*info).push_back (t);
+ }
+}
+
+void
+gr_fir_sysconfig_armv7_a::get_gr_fir_fsf_info (std::vector<gr_fir_fsf_info> *info)
+{
+ // invoke parent..
+ gr_fir_sysconfig_generic::get_gr_fir_fsf_info (info);
+
+#if 0
+ // add our stuff...
+ gr_fir_fsf_info t;
+ if (gr_cpu::has_altivec ()){
+ t.name = "altivec";
+ t.create = make_gr_fir_fsf_altivec;
+ (*info).push_back (t);
+ }
+#endif
+}
+
+void
+gr_fir_sysconfig_armv7_a::get_gr_fir_scc_info (std::vector<gr_fir_scc_info> *info)
+{
+ // invoke parent..
+ gr_fir_sysconfig_generic::get_gr_fir_scc_info (info);
+
+#if 0
+ // add our stuff...
+ gr_fir_scc_info t;
+ if (gr_cpu::has_altivec ()){
+ t.name = "altivec";
+ t.create = make_gr_fir_scc_altivec;
+ (*info).push_back (t);
+ }
+#endif
+}
diff --git a/gnuradio-core/src/lib/filter/gr_fir_sysconfig_armv7_a.h b/gnuradio-core/src/lib/filter/gr_fir_sysconfig_armv7_a.h
new file mode 100644
index 000000000..7295475f6
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_fir_sysconfig_armv7_a.h
@@ -0,0 +1,47 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002,2008,2009 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifndef INCLUDED_GR_FIR_SYSCONFIG_ARMV7_A_H
+#define INCLUDED_GR_FIR_SYSCONFIG_ARMV7_A_H
+
+#include <gr_core_api.h>
+#include <gr_fir_sysconfig_generic.h>
+
+class GR_CORE_API gr_fir_sysconfig_armv7_a : public gr_fir_sysconfig_generic {
+public:
+ virtual gr_fir_ccf *create_gr_fir_ccf (const std::vector<float> &taps);
+ virtual gr_fir_fcc *create_gr_fir_fcc (const std::vector<gr_complex> &taps);
+ virtual gr_fir_fff *create_gr_fir_fff (const std::vector<float> &taps);
+ virtual gr_fir_fsf *create_gr_fir_fsf (const std::vector<float> &taps);
+ virtual gr_fir_scc *create_gr_fir_scc (const std::vector<gr_complex> &taps);
+ virtual gr_fir_ccc *create_gr_fir_ccc (const std::vector<gr_complex> &taps);
+//virtual gr_fir_sss *create_gr_fir_sss (const std::vector<short> &taps);
+
+ virtual void get_gr_fir_ccf_info (std::vector<gr_fir_ccf_info> *info);
+ virtual void get_gr_fir_fcc_info (std::vector<gr_fir_fcc_info> *info);
+ virtual void get_gr_fir_fff_info (std::vector<gr_fir_fff_info> *info);
+ virtual void get_gr_fir_fsf_info (std::vector<gr_fir_fsf_info> *info);
+ virtual void get_gr_fir_scc_info (std::vector<gr_fir_scc_info> *info);
+ virtual void get_gr_fir_ccc_info (std::vector<gr_fir_ccc_info> *info);
+//virtual void get_gr_fir_sss_info (std::vector<gr_fir_sss_info> *info);
+};
+
+#endif
diff --git a/gnuradio-core/src/lib/filter/gr_fir_sysconfig_powerpc.cc b/gnuradio-core/src/lib/filter/gr_fir_sysconfig_powerpc.cc
new file mode 100644
index 000000000..f706bd5bf
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_fir_sysconfig_powerpc.cc
@@ -0,0 +1,340 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002,2008 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <gr_fir_sysconfig_powerpc.h>
+#include <gr_cpu.h>
+
+#include <gr_fir_ccf.h>
+#include <gr_fir_ccf_generic.h>
+//#include <gr_fir_ccf_altivec.h>
+#include <gr_fir_fcc.h>
+#include <gr_fir_fcc_generic.h>
+//#include <gr_fir_fcc_altivec.h>
+#include <gr_fir_fff.h>
+#include <gr_fir_fff_generic.h>
+#include <gr_fir_fff_altivec.h>
+#include <gr_fir_fsf.h>
+#include <gr_fir_fsf_generic.h>
+//#include <gr_fir_fsf_powerpc.h>
+#include <gr_fir_ccc.h>
+#include <gr_fir_ccc_generic.h>
+//#include <gr_fir_ccc_altivec.h>
+#include <gr_fir_scc.h>
+#include <gr_fir_scc_generic.h>
+//#include <gr_fir_scc_altivec.h>
+
+#include <iostream>
+using std::cerr;
+
+/*
+ * ----------------------------------------------------------------
+ * static functions that serve as constructors...
+ * ----------------------------------------------------------------
+ */
+
+#if 0
+static gr_fir_ccf *
+make_gr_fir_ccf_altivec(const std::vector<float> &taps)
+{
+ return new gr_fir_ccf_altivec(taps);
+}
+
+static gr_fir_fcc *
+make_gr_fir_fcc_altivec(const std::vector<gr_complex> &taps)
+{
+ return new gr_fir_fcc_altivec(taps);
+}
+
+static gr_fir_ccc *
+make_gr_fir_ccc_altivec (const std::vector<gr_complex> &taps)
+{
+ return new gr_fir_ccc_altivec (taps);
+}
+#endif
+
+static gr_fir_fff *
+make_gr_fir_fff_altivec (const std::vector<float> &taps)
+{
+ return new gr_fir_fff_altivec (taps);
+}
+
+#if 0
+static gr_fir_fsf *
+make_gr_fir_fsf_altivec (const std::vector<float> &taps)
+{
+ return new gr_fir_fsf_altivec (taps);
+}
+
+static gr_fir_scc *
+make_gr_fir_scc_altivec(const std::vector<gr_complex> &taps)
+{
+ return new gr_fir_scc_altivec(taps);
+}
+#endif
+
+/*
+ * ----------------------------------------------------------------
+ * Return instances of the fastest powerpc versions of these classes.
+ *
+ * check CPUID, if has altivec, return altivec version,
+ * else return generic version.
+ * ----------------------------------------------------------------
+ */
+
+gr_fir_ccf *
+gr_fir_sysconfig_powerpc::create_gr_fir_ccf (const std::vector<float> &taps)
+{
+ static bool first = true;
+
+#if 0
+ if (gr_cpu::has_altivec ()){
+ if (first){
+ cerr << ">>> gr_fir_ccf: using altivec\n";
+ first = false;
+ }
+ return make_gr_fir_ccf_altivec (taps);
+ }
+#endif
+
+ if (0 && first){
+ cerr << ">>> gr_fir_ccf: handing off to parent class\n";
+ first = false;
+ }
+ return gr_fir_sysconfig_generic::create_gr_fir_ccf (taps);
+}
+
+gr_fir_fcc *
+gr_fir_sysconfig_powerpc::create_gr_fir_fcc (const std::vector<gr_complex> &taps)
+{
+ static bool first = true;
+
+#if 0
+ if (gr_cpu::has_altivec ()){
+ if (first){
+ cerr << ">>> gr_fir_fcc: using altivec\n";
+ first = false;
+ }
+ return make_gr_fir_fcc_altivec (taps);
+ }
+#endif
+
+ if (0 && first){
+ cerr << ">>> gr_fir_fcc: handing off to parent class\n";
+ first = false;
+ }
+ return gr_fir_sysconfig_generic::create_gr_fir_fcc (taps);
+}
+
+gr_fir_ccc *
+gr_fir_sysconfig_powerpc::create_gr_fir_ccc (const std::vector<gr_complex> &taps)
+{
+ static bool first = true;
+
+#if 0
+ if (gr_cpu::has_altivec ()){
+ if (first){
+ cerr << ">>> gr_fir_ccc: using altivec\n";
+ first = false;
+ }
+ return make_gr_fir_ccc_altivec (taps);
+ }
+#endif
+
+ if (0 && first){
+ cerr << ">>> gr_fir_ccc: handing off to parent class\n";
+ first = false;
+ }
+ return gr_fir_sysconfig_generic::create_gr_fir_ccc (taps);
+}
+
+gr_fir_fff *
+gr_fir_sysconfig_powerpc::create_gr_fir_fff (const std::vector<float> &taps)
+{
+ static bool first = true;
+
+ if (gr_cpu::has_altivec ()){
+ if (first){
+ cerr << ">>> gr_fir_fff: using altivec\n";
+ first = false;
+ }
+ return make_gr_fir_fff_altivec (taps);
+ }
+
+ if (0 && first){
+ cerr << ">>> gr_fir_fff: handing off to parent class\n";
+ first = false;
+ }
+ return gr_fir_sysconfig_generic::create_gr_fir_fff (taps);
+}
+
+gr_fir_fsf *
+gr_fir_sysconfig_powerpc::create_gr_fir_fsf (const std::vector<float> &taps)
+{
+ static bool first = true;
+
+#if 0
+ if (gr_cpu::has_altivec ()){
+ if (first){
+ cerr << ">>> gr_fir_fsf: using altivec\n";
+ first = false;
+ }
+ return make_gr_fir_fsf_altivec (taps);
+ }
+#endif
+
+ if (0 && first){
+ cerr << ">>> gr_fir_fsf: handing off to parent class\n";
+ first = false;
+ }
+ return gr_fir_sysconfig_generic::create_gr_fir_fsf (taps);
+}
+
+
+gr_fir_scc *
+gr_fir_sysconfig_powerpc::create_gr_fir_scc (const std::vector<gr_complex> &taps)
+{
+ static bool first = true;
+
+#if 0
+ if (gr_cpu::has_altivec ()){
+ if (first){
+ cerr << ">>> gr_fir_scc: using altivec\n";
+ first = false;
+ }
+ return make_gr_fir_scc_altivec (taps);
+ }
+#endif
+
+ if (0 && first){
+ cerr << ">>> gr_fir_scc: handing off to parent class\n";
+ first = false;
+ }
+ return gr_fir_sysconfig_generic::create_gr_fir_scc (taps);
+}
+
+/*
+ * ----------------------------------------------------------------
+ * Return info about available implementations
+ * ----------------------------------------------------------------
+ */
+
+void
+gr_fir_sysconfig_powerpc::get_gr_fir_ccf_info (std::vector<gr_fir_ccf_info> *info)
+{
+ // invoke parent..
+ gr_fir_sysconfig_generic::get_gr_fir_ccf_info (info);
+
+#if 0
+ // add our stuff...
+ gr_fir_ccf_info t;
+ if (gr_cpu::has_altivec ()){
+ t.name = "altivec";
+ t.create = make_gr_fir_ccf_altivec;
+ (*info).push_back (t);
+ }
+#endif
+}
+
+void
+gr_fir_sysconfig_powerpc::get_gr_fir_fcc_info (std::vector<gr_fir_fcc_info> *info)
+{
+ // invoke parent..
+ gr_fir_sysconfig_generic::get_gr_fir_fcc_info (info);
+
+#if 0
+ // add our stuff...
+ gr_fir_fcc_info t;
+ if (gr_cpu::has_altivec ()){
+ t.name = "altivec";
+ t.create = make_gr_fir_fcc_altivec;
+ (*info).push_back (t);
+ }
+#endif
+}
+
+void
+gr_fir_sysconfig_powerpc::get_gr_fir_ccc_info (std::vector<gr_fir_ccc_info> *info)
+{
+ // invoke parent..
+ gr_fir_sysconfig_generic::get_gr_fir_ccc_info (info);
+
+#if 0
+ // add our stuff...
+ gr_fir_ccc_info t;
+ if (gr_cpu::has_altivec ()){
+ t.name = "altivec";
+ t.create = make_gr_fir_ccc_altivec;
+ (*info).push_back (t);
+ }
+#endif
+}
+
+void
+gr_fir_sysconfig_powerpc::get_gr_fir_fff_info (std::vector<gr_fir_fff_info> *info)
+{
+ // invoke parent..
+ gr_fir_sysconfig_generic::get_gr_fir_fff_info (info);
+
+ // add our stuff...
+ gr_fir_fff_info t;
+ if (gr_cpu::has_altivec ()){
+ t.name = "altivec";
+ t.create = make_gr_fir_fff_altivec;
+ (*info).push_back (t);
+ }
+}
+
+void
+gr_fir_sysconfig_powerpc::get_gr_fir_fsf_info (std::vector<gr_fir_fsf_info> *info)
+{
+ // invoke parent..
+ gr_fir_sysconfig_generic::get_gr_fir_fsf_info (info);
+
+#if 0
+ // add our stuff...
+ gr_fir_fsf_info t;
+ if (gr_cpu::has_altivec ()){
+ t.name = "altivec";
+ t.create = make_gr_fir_fsf_altivec;
+ (*info).push_back (t);
+ }
+#endif
+}
+
+void
+gr_fir_sysconfig_powerpc::get_gr_fir_scc_info (std::vector<gr_fir_scc_info> *info)
+{
+ // invoke parent..
+ gr_fir_sysconfig_generic::get_gr_fir_scc_info (info);
+
+#if 0
+ // add our stuff...
+ gr_fir_scc_info t;
+ if (gr_cpu::has_altivec ()){
+ t.name = "altivec";
+ t.create = make_gr_fir_scc_altivec;
+ (*info).push_back (t);
+ }
+#endif
+}
diff --git a/gnuradio-core/src/lib/filter/gr_fir_sysconfig_powerpc.h b/gnuradio-core/src/lib/filter/gr_fir_sysconfig_powerpc.h
new file mode 100644
index 000000000..09a7a0ba0
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_fir_sysconfig_powerpc.h
@@ -0,0 +1,47 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002,2008 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifndef INCLUDED_GR_FIR_SYSCONFIG_POWERPC_H
+#define INCLUDED_GR_FIR_SYSCONFIG_POWERPC_H
+
+#include <gr_core_api.h>
+#include <gr_fir_sysconfig_generic.h>
+
+class GR_CORE_API gr_fir_sysconfig_powerpc : 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_fir_sysconfig_x86.cc b/gnuradio-core/src/lib/filter/gr_fir_sysconfig_x86.cc
new file mode 100644
index 000000000..97b810699
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_fir_sysconfig_x86.cc
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <gr_fir_sysconfig_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
index 000000000..ebb399c8b
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_fir_sysconfig_x86.h
@@ -0,0 +1,47 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifndef INCLUDED_GR_FIR_SYSCONFIG_X86_H
+#define INCLUDED_GR_FIR_SYSCONFIG_X86_H
+
+#include <gr_core_api.h>
+#include <gr_fir_sysconfig_generic.h>
+
+class GR_CORE_API 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.cc b/gnuradio-core/src/lib/filter/gr_fractional_interpolator_cc.cc
new file mode 100644
index 000000000..500958e3d
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_fractional_interpolator_cc.cc
@@ -0,0 +1,93 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2007,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_io_signature.h>
+#include <gr_fractional_interpolator_cc.h>
+#include <gri_mmse_fir_interpolator_cc.h>
+#include <stdexcept>
+
+// Public constructor
+gr_fractional_interpolator_cc_sptr gr_make_fractional_interpolator_cc(float phase_shift, float interp_ratio)
+{
+ return gnuradio::get_initial_sptr(new gr_fractional_interpolator_cc(phase_shift, interp_ratio));
+}
+
+gr_fractional_interpolator_cc::gr_fractional_interpolator_cc(float phase_shift, float interp_ratio)
+ : gr_block ("fractional_interpolator_cc",
+ gr_make_io_signature (1, 1, sizeof (gr_complex)),
+ gr_make_io_signature (1, 1, sizeof (gr_complex))),
+ d_mu (phase_shift), d_mu_inc (interp_ratio), d_interp(new gri_mmse_fir_interpolator_cc())
+{
+ 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_cc::~gr_fractional_interpolator_cc()
+{
+ delete d_interp;
+}
+
+void
+gr_fractional_interpolator_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_mu_inc) + d_interp->ntaps());
+}
+
+int
+gr_fractional_interpolator_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
+
+ while (oo < noutput_items) {
+
+ out[oo++] = d_interp->interpolate(&in[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_cc.h b/gnuradio-core/src/lib/filter/gr_fractional_interpolator_cc.h
new file mode 100644
index 000000000..29c67895a
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_fractional_interpolator_cc.h
@@ -0,0 +1,68 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2007 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_FRACTIONAL_INTERPOLATOR_CC_H
+#define INCLUDED_GR_FRACTIONAL_INTERPOLATOR_CC_H
+
+#include <gr_core_api.h>
+#include <gr_block.h>
+
+class gri_mmse_fir_interpolator_cc;
+
+class gr_fractional_interpolator_cc;
+typedef boost::shared_ptr<gr_fractional_interpolator_cc> gr_fractional_interpolator_cc_sptr;
+
+// public constructor
+GR_CORE_API gr_fractional_interpolator_cc_sptr gr_make_fractional_interpolator_cc (float phase_shift, float interp_ratio);
+
+/*!
+ * \brief Interpolating mmse filter with gr_complex input, gr_complex output
+ * \ingroup filter_blk
+ */
+class GR_CORE_API gr_fractional_interpolator_cc : public gr_block
+{
+public:
+ ~gr_fractional_interpolator_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 interp_ratio() const { return d_mu_inc;}
+ void set_mu (float mu) { d_mu = mu; }
+ void set_interp_ratio (float interp_ratio) { d_mu_inc = interp_ratio; }
+
+protected:
+ gr_fractional_interpolator_cc (float phase_shift, float interp_ratio);
+
+private:
+ float d_mu;
+ float d_mu_inc;
+ gri_mmse_fir_interpolator_cc *d_interp;
+
+ friend GR_CORE_API gr_fractional_interpolator_cc_sptr
+ gr_make_fractional_interpolator_cc (float phase_shift, float interp_ratio);
+};
+
+#endif
diff --git a/gnuradio-core/src/lib/filter/gr_fractional_interpolator_cc.i b/gnuradio-core/src/lib/filter/gr_fractional_interpolator_cc.i
new file mode 100644
index 000000000..d7341176a
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_fractional_interpolator_cc.i
@@ -0,0 +1,37 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,fractional_interpolator_cc);
+
+gr_fractional_interpolator_cc_sptr gr_make_fractional_interpolator_cc (float phase_shift, float interp_ratio);
+
+class gr_fractional_interpolator_cc : public gr_block
+{
+private:
+ gr_fractional_interpolator_cc (float phase_shift, float interp_ratio);
+
+public:
+ float mu() const;
+ float interp_ratio() const;
+ void set_mu (float mu);
+ void set_interp_ratio (float interp_ratio);
+};
diff --git a/gnuradio-core/src/lib/filter/gr_fractional_interpolator_ff.cc b/gnuradio-core/src/lib/filter/gr_fractional_interpolator_ff.cc
new file mode 100644
index 000000000..9cbe31635
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_fractional_interpolator_ff.cc
@@ -0,0 +1,93 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2007,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_io_signature.h>
+#include <gr_fractional_interpolator_ff.h>
+#include <gri_mmse_fir_interpolator.h>
+#include <stdexcept>
+
+// Public constructor
+gr_fractional_interpolator_ff_sptr gr_make_fractional_interpolator_ff(float phase_shift, float interp_ratio)
+{
+ return gnuradio::get_initial_sptr(new gr_fractional_interpolator_ff(phase_shift, interp_ratio));
+}
+
+gr_fractional_interpolator_ff::gr_fractional_interpolator_ff(float phase_shift, float interp_ratio)
+ : gr_block ("fractional_interpolator_ff",
+ 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(new gri_mmse_fir_interpolator())
+{
+ 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_ff::~gr_fractional_interpolator_ff()
+{
+ delete d_interp;
+}
+
+void
+gr_fractional_interpolator_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_mu_inc) + d_interp->ntaps());
+}
+
+int
+gr_fractional_interpolator_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
+
+ while (oo < noutput_items) {
+
+ out[oo++] = d_interp->interpolate(&in[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_ff.h b/gnuradio-core/src/lib/filter/gr_fractional_interpolator_ff.h
new file mode 100644
index 000000000..7e000a6d1
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_fractional_interpolator_ff.h
@@ -0,0 +1,68 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2007 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_FRACTIONAL_INTERPOLATOR_FF_H
+#define INCLUDED_GR_FRACTIONAL_INTERPOLATOR_FF_H
+
+#include <gr_core_api.h>
+#include <gr_block.h>
+
+class gri_mmse_fir_interpolator;
+
+class gr_fractional_interpolator_ff;
+typedef boost::shared_ptr<gr_fractional_interpolator_ff> gr_fractional_interpolator_ff_sptr;
+
+// public constructor
+GR_CORE_API gr_fractional_interpolator_ff_sptr gr_make_fractional_interpolator_ff (float phase_shift, float interp_ratio);
+
+/*!
+ * \brief Interpolating mmse filter with float input, float output
+ * \ingroup filter_blk
+ */
+class GR_CORE_API gr_fractional_interpolator_ff : public gr_block
+{
+public:
+ ~gr_fractional_interpolator_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 interp_ratio() const { return d_mu_inc;}
+ void set_mu (float mu) { d_mu = mu; }
+ void set_interp_ratio (float interp_ratio) { d_mu_inc = interp_ratio; }
+
+protected:
+ gr_fractional_interpolator_ff (float phase_shift, float interp_ratio);
+
+private:
+ float d_mu;
+ float d_mu_inc;
+ gri_mmse_fir_interpolator *d_interp;
+
+ friend GR_CORE_API gr_fractional_interpolator_ff_sptr
+ gr_make_fractional_interpolator_ff (float phase_shift, float interp_ratio);
+};
+
+#endif
diff --git a/gnuradio-core/src/lib/filter/gr_fractional_interpolator_ff.i b/gnuradio-core/src/lib/filter/gr_fractional_interpolator_ff.i
new file mode 100644
index 000000000..4ec7c85cf
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_fractional_interpolator_ff.i
@@ -0,0 +1,37 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,fractional_interpolator_ff);
+
+gr_fractional_interpolator_ff_sptr gr_make_fractional_interpolator_ff (float phase_shift, float interp_ratio);
+
+class gr_fractional_interpolator_ff : public gr_block
+{
+private:
+ gr_fractional_interpolator_ff (float phase_shift, float interp_ratio);
+
+public:
+ float mu() const;
+ float interp_ratio() const;
+ void set_mu (float mu);
+ void set_interp_ratio (float interp_ratio);
+};
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
index 000000000..3d65f872e
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_freq_xlating_fir_filter_XXX.cc.t
@@ -0,0 +1,123 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+/*
+ * 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 gnuradio::get_initial_sptr (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;
+ return 0; // history requirements may have changed.
+ }
+
+ 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
index 000000000..97d20e04f
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_freq_xlating_fir_filter_XXX.h.t
@@ -0,0 +1,101 @@
+/* -*- 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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, 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_core_api.h>
+#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.
+ */
+GR_CORE_API @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_blk
+ *
+ * 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 GR_CORE_API @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 GR_CORE_API @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
index 000000000..ac6c8c9e1
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_freq_xlating_fir_filter_XXX.i.t
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, 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
index 000000000..07bed8157
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_goertzel_fc.cc
@@ -0,0 +1,76 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006,2010,2011 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_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 gnuradio::get_initial_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;
+ d_rate = rate;
+ d_freq = freq;
+}
+
+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;
+}
+
+void
+gr_goertzel_fc::set_freq(float freq)
+{
+ d_freq = freq;
+ d_goertzel.gri_setparms(d_rate, d_len, d_freq);
+}
+
+void
+gr_goertzel_fc::set_rate(int rate)
+{
+ d_rate = rate;
+ d_goertzel.gri_setparms(d_rate, d_len, d_freq);
+}
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
index 000000000..5fb6e0ee0
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_goertzel_fc.h
@@ -0,0 +1,61 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006,2011 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_GOERTZEL_FC_H
+#define INCLUDED_GR_GOERTZEL_FC_H
+
+#include <gr_core_api.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_CORE_API gr_goertzel_fc_sptr gr_make_goertzel_fc(int rate, int len, float freq);
+
+/*!
+ * \brief Goertzel single-bin DFT calculation.
+ * \ingroup dft_blk
+ */
+class GR_CORE_API gr_goertzel_fc : public gr_sync_decimator
+{
+private:
+ friend GR_CORE_API 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;
+ float d_freq;
+ int d_rate;
+
+public:
+ int work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+
+ void set_freq (float freq);
+ void set_rate (int rate);
+};
+
+#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
index 000000000..775c78cc8
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_goertzel_fc.i
@@ -0,0 +1,35 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006,2011 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,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();
+
+public:
+ void set_freq (float freq);
+ void set_rate (int rate);
+};
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
index 000000000..385e24ad2
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_hilbert_fc.cc
@@ -0,0 +1,67 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#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 gnuradio::get_initial_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
index 000000000..2bb5ff9e3
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_hilbert_fc.h
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_HILBERT_FC_H
+#define INCLUDED_GR_HILBERT_FC_H
+
+#include <gr_core_api.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_CORE_API gr_hilbert_fc_sptr gr_make_hilbert_fc (unsigned int ntaps);
+
+
+class gr_fir_fff;
+
+/*!
+ * \brief Hilbert transformer.
+ * \ingroup filter_blk
+ *
+ * real output is input appropriately delayed.
+ * imaginary output is hilbert filtered (90 degree phase shift)
+ * version of input.
+ */
+class GR_CORE_API 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_CORE_API 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
index 000000000..91d4e23eb
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_hilbert_fc.i
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,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
index 000000000..4da2aa310
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_iir_filter_ffd.cc
@@ -0,0 +1,82 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#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 gnuradio::get_initial_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)
+{
+
+ 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];
+
+
+ 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
index 000000000..ab7065e92
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_iir_filter_ffd.h
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_IIR_FILTER_FFD_H
+#define INCLUDED_GR_IIR_FILTER_FFD_H
+
+#include <gr_core_api.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_CORE_API 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_blk
+ *
+ * This filter uses the Direct Form I implementation, where
+ * \p fftaps contains the feed-forward taps, and \p fbtaps the feedback ones.
+ *
+ *
+ * The input and output satisfy a difference equation of the form
+ \htmlonly
+ \f{
+ y[n] - \sum_{k=1}^{M} a_k y[n-k] = \sum_{k=0}^{N} b_k x[n-k]
+ \f}
+ \endhtmlonly
+
+ \xmlonly
+ y[n] - \sum_{k=1}^{M} a_k y[n-k] = \sum_{k=0}^{N} b_k x[n-k]
+ \endxmlonly
+
+ * with the corresponding rational system function
+ \htmlonly
+ \f{
+ H(z) = \ frac{\sum_{k=0}^{M} b_k z^{-k}}{1 - \sum_{k=1}^{N} a_k z^{-k}}
+ \f}
+ \endhtmlonly
+
+ \xmlonly
+ H(z) = \ frac{\sum_{k=0}^{M} b_k z^{-k}}{1 - \sum_{k=1}^{N} a_k z^{-k}}
+ \endxmlonly
+
+ * 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_CORE_API gr_iir_filter_ffd : public gr_sync_block
+{
+ private:
+ friend GR_CORE_API 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
index 000000000..0a35ad89e
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_iir_filter_ffd.i
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,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
index 000000000..55297d1eb
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_interp_fir_filter_XXX.cc.t
@@ -0,0 +1,146 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+/*
+ * 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 gnuradio::get_initial_sptr (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
index 000000000..83904dce2
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_interp_fir_filter_XXX.h.t
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, 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_core_api.h>
+#include <gr_sync_interpolator.h>
+
+class @NAME@;
+typedef boost::shared_ptr<@NAME@> @SPTR_NAME@;
+GR_CORE_API @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_blk
+ */
+class GR_CORE_API @NAME@ : public gr_sync_interpolator
+{
+ private:
+ friend GR_CORE_API @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
index 000000000..274753001
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_interp_fir_filter_XXX.i.t
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, 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_pfb_arb_resampler_ccf.cc b/gnuradio-core/src/lib/filter/gr_pfb_arb_resampler_ccf.cc
new file mode 100644
index 000000000..ee09fef44
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_pfb_arb_resampler_ccf.cc
@@ -0,0 +1,210 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2009,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_pfb_arb_resampler_ccf.h>
+#include <gr_fir_ccf.h>
+#include <gr_fir_util.h>
+#include <gr_io_signature.h>
+#include <cstdio>
+
+gr_pfb_arb_resampler_ccf_sptr gr_make_pfb_arb_resampler_ccf (float rate,
+ const std::vector<float> &taps,
+ unsigned int filter_size)
+{
+ return gnuradio::get_initial_sptr(new gr_pfb_arb_resampler_ccf (rate, taps,
+ filter_size));
+}
+
+
+gr_pfb_arb_resampler_ccf::gr_pfb_arb_resampler_ccf (float rate,
+ const std::vector<float> &taps,
+ unsigned int filter_size)
+ : gr_block ("pfb_arb_resampler_ccf",
+ gr_make_io_signature (1, 1, sizeof(gr_complex)),
+ gr_make_io_signature (1, 1, sizeof(gr_complex))),
+ d_updated (false)
+{
+ d_acc = 0; // start accumulator at 0
+
+ /* The number of filters is specified by the user as the filter size;
+ this is also the interpolation rate of the filter. We use it and the
+ rate provided to determine the decimation rate. This acts as a
+ rational resampler. The flt_rate is calculated as the residual
+ between the integer decimation rate and the real decimation rate and
+ will be used to determine to interpolation point of the resampling
+ process.
+ */
+ d_int_rate = filter_size;
+ set_rate(rate);
+
+ // Store the last filter between calls to work
+ d_last_filter = 0;
+
+ d_start_index = 0;
+
+ d_filters = std::vector<gr_fir_ccf*>(d_int_rate);
+ d_diff_filters = std::vector<gr_fir_ccf*>(d_int_rate);
+
+ // Create an FIR filter for each channel and zero out the taps
+ std::vector<float> vtaps(0, d_int_rate);
+ for(unsigned int i = 0; i < d_int_rate; i++) {
+ d_filters[i] = gr_fir_util::create_gr_fir_ccf(vtaps);
+ d_diff_filters[i] = gr_fir_util::create_gr_fir_ccf(vtaps);
+ }
+
+ // Now, actually set the filters' taps
+ std::vector<float> dtaps;
+ create_diff_taps(taps, dtaps);
+ create_taps(taps, d_taps, d_filters);
+ create_taps(dtaps, d_dtaps, d_diff_filters);
+}
+
+gr_pfb_arb_resampler_ccf::~gr_pfb_arb_resampler_ccf ()
+{
+ for(unsigned int i = 0; i < d_int_rate; i++) {
+ delete d_filters[i];
+ delete d_diff_filters[i];
+ }
+}
+
+void
+gr_pfb_arb_resampler_ccf::create_taps (const std::vector<float> &newtaps,
+ std::vector< std::vector<float> > &ourtaps,
+ std::vector<gr_fir_ccf*> &ourfilter)
+{
+ unsigned int ntaps = newtaps.size();
+ d_taps_per_filter = (unsigned int)ceil((double)ntaps/(double)d_int_rate);
+
+ // Create d_numchan vectors to store each channel's taps
+ ourtaps.resize(d_int_rate);
+
+ // Make a vector of the taps plus fill it out with 0's to fill
+ // each polyphase filter with exactly d_taps_per_filter
+ std::vector<float> tmp_taps;
+ tmp_taps = newtaps;
+ while((float)(tmp_taps.size()) < d_int_rate*d_taps_per_filter) {
+ tmp_taps.push_back(0.0);
+ }
+
+ // Partition the filter
+ for(unsigned int i = 0; i < d_int_rate; i++) {
+ // Each channel uses all d_taps_per_filter with 0's if not enough taps to fill out
+ ourtaps[d_int_rate-1-i] = std::vector<float>(d_taps_per_filter, 0);
+ for(unsigned int j = 0; j < d_taps_per_filter; j++) {
+ ourtaps[d_int_rate - 1 - i][j] = tmp_taps[i + j*d_int_rate];
+ }
+
+ // Build a filter for each channel and add it's taps to it
+ ourfilter[i]->set_taps(ourtaps[d_int_rate-1-i]);
+ }
+
+ // Set the history to ensure enough input items for each filter
+ set_history (d_taps_per_filter + 1);
+
+ d_updated = true;
+}
+
+void
+gr_pfb_arb_resampler_ccf::create_diff_taps(const std::vector<float> &newtaps,
+ std::vector<float> &difftaps)
+{
+ // Calculate the differential taps (derivative filter) by taking the difference
+ // between two taps. Duplicate the last one to make both filters the same length.
+ float tap;
+ difftaps.clear();
+ for(unsigned int i = 0; i < newtaps.size()-1; i++) {
+ tap = newtaps[i+1] - newtaps[i];
+ difftaps.push_back(tap);
+ }
+ difftaps.push_back(tap);
+}
+
+void
+gr_pfb_arb_resampler_ccf::print_taps()
+{
+ unsigned int i, j;
+ for(i = 0; i < d_int_rate; i++) {
+ printf("filter[%d]: [", i);
+ for(j = 0; j < d_taps_per_filter; j++) {
+ printf(" %.4e", d_taps[i][j]);
+ }
+ printf("]\n");
+ }
+}
+
+int
+gr_pfb_arb_resampler_ccf::general_work (int noutput_items,
+ gr_vector_int &ninput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ gr_complex *in = (gr_complex *) input_items[0];
+ gr_complex *out = (gr_complex *) output_items[0];
+
+ if (d_updated) {
+ d_updated = false;
+ return 0; // history requirements may have changed.
+ }
+
+ int i = 0, count = d_start_index;
+ unsigned int j;
+ gr_complex o0, o1;
+
+ // Restore the last filter position
+ j = d_last_filter;
+
+ // produce output as long as we can and there are enough input samples
+ int max_input = ninput_items[0]-(int)d_taps_per_filter;
+ while((i < noutput_items) && (count < max_input)) {
+ // start j by wrapping around mod the number of channels
+ while((j < d_int_rate) && (i < noutput_items)) {
+ // Take the current filter and derivative filter output
+ o0 = d_filters[j]->filter(&in[count]);
+ o1 = d_diff_filters[j]->filter(&in[count]);
+
+ out[i] = o0 + o1*d_acc; // linearly interpolate between samples
+ i++;
+
+ // Adjust accumulator and index into filterbank
+ d_acc += d_flt_rate;
+ j += d_dec_rate + (int)floor(d_acc);
+ d_acc = fmodf(d_acc, 1.0);
+ }
+ if(i < noutput_items) { // keep state for next entry
+ float ss = (int)(j / d_int_rate); // number of items to skip ahead by
+ count += ss; // we have fully consumed another input
+ j = j % d_int_rate; // roll filter around
+ }
+ }
+
+ // Store the current filter position and start of next sample
+ d_last_filter = j;
+ d_start_index = std::max(0, count - ninput_items[0]);
+
+ // consume all we've processed but no more than we can
+ consume_each(std::min(count, ninput_items[0]));
+ return i;
+}
diff --git a/gnuradio-core/src/lib/filter/gr_pfb_arb_resampler_ccf.h b/gnuradio-core/src/lib/filter/gr_pfb_arb_resampler_ccf.h
new file mode 100644
index 000000000..d92898a23
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_pfb_arb_resampler_ccf.h
@@ -0,0 +1,178 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2009,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+
+#ifndef INCLUDED_GR_PFB_ARB_RESAMPLER_CCF_H
+#define INCLUDED_GR_PFB_ARB_RESAMPLER_CCF_H
+
+#include <gr_core_api.h>
+#include <gr_block.h>
+
+class gr_pfb_arb_resampler_ccf;
+typedef boost::shared_ptr<gr_pfb_arb_resampler_ccf> gr_pfb_arb_resampler_ccf_sptr;
+GR_CORE_API gr_pfb_arb_resampler_ccf_sptr gr_make_pfb_arb_resampler_ccf (float rate,
+ const std::vector<float> &taps,
+ unsigned int filter_size=32);
+
+class gr_fir_ccf;
+
+/*!
+ * \class gr_pfb_arb_resampler_ccf
+ *
+ * \brief Polyphase filterbank arbitrary resampler with
+ * gr_complex input, gr_complex output and float taps
+ *
+ * \ingroup filter_blk
+ * \ingroup pfb_blk
+ *
+ * This block takes in a signal stream and performs arbitrary
+ * resampling. The resampling rate can be any real
+ * number <EM>r</EM>. The resampling is done by constructing
+ * <EM>N</EM> filters where <EM>N</EM> is the interpolation rate. We
+ * then calculate <EM>D</EM> where <EM>D = floor(N/r)</EM>.
+ *
+ * Using <EM>N</EM> and <EM>D</EM>, we can perform rational resampling
+ * where <EM>N/D</EM> is a rational number close to the input rate
+ * <EM>r</EM> where we have <EM>N</EM> filters and we cycle through
+ * them as a polyphase filterbank with a stride of <EM>D</EM> so that
+ * <EM>i+1 = (i + D) % N</EM>.
+ *
+ * To get the arbitrary rate, we want to interpolate between two
+ * points. For each value out, we take an output from the current
+ * filter, <EM>i</EM>, and the next filter <EM>i+1</EM> and then
+ * linearly interpolate between the two based on the real resampling
+ * rate we want.
+ *
+ * The linear interpolation only provides us with an approximation to
+ * the real sampling rate specified. The error is a quantization error
+ * between the two filters we used as our interpolation points. To
+ * this end, the number of filters, <EM>N</EM>, used determines the
+ * quantization error; the larger <EM>N</EM>, the smaller the
+ * noise. You can design for a specified noise floor by setting the
+ * filter size (parameters <EM>filter_size</EM>). The size defaults to
+ * 32 filters, which is about as good as most implementations need.
+ *
+ * The trick with designing this filter is in how to specify the taps
+ * of the prototype filter. Like the PFB interpolator, the taps are
+ * specified using the interpolated filter rate. In this case, that
+ * rate is the input sample rate multiplied by the number of filters
+ * in the filterbank, which is also the interpolation rate. All other
+ * values should be relative to this rate.
+ *
+ * For example, for a 32-filter arbitrary resampler and using the
+ * GNU Radio's firdes utility to build the filter, we build a low-pass
+ * filter with a sampling rate of <EM>fs</EM>, a 3-dB bandwidth of
+ * <EM>BW</EM> and a transition bandwidth of <EM>TB</EM>. We can also
+ * specify the out-of-band attenuation to use, <EM>ATT</EM>, and the
+ * filter window function (a Blackman-harris window in this case). The
+ * first input is the gain of the filter, which we specify here as the
+ * interpolation rate (<EM>32</EM>).
+ *
+ * <B><EM>self._taps = gr.firdes.low_pass_2(32, 32*fs, BW, TB,
+ * attenuation_dB=ATT, window=gr.firdes.WIN_BLACKMAN_hARRIS)</EM></B>
+ *
+ * The theory behind this block can be found in Chapter 7.5 of
+ * the following book.
+ *
+ * <B><EM>f. harris, "Multirate Signal Processing for Communication
+ * Systems", Upper Saddle River, NJ: Prentice Hall, Inc. 2004.</EM></B>
+ */
+
+class GR_CORE_API gr_pfb_arb_resampler_ccf : public gr_block
+{
+ private:
+ /*!
+ * Build the polyphase filterbank arbitray resampler.
+ * \param rate (float) Specifies the resampling rate to use
+ * \param taps (vector/list of floats) The prototype filter to populate the filterbank. The taps
+ * should be generated at the filter_size sampling rate.
+ * \param filter_size (unsigned int) The number of filters in the filter bank. This is directly
+ related to quantization noise introduced during the resampling.
+ Defaults to 32 filters.
+ */
+ friend GR_CORE_API gr_pfb_arb_resampler_ccf_sptr gr_make_pfb_arb_resampler_ccf (float rate,
+ const std::vector<float> &taps,
+ unsigned int filter_size);
+
+ std::vector<gr_fir_ccf*> d_filters;
+ std::vector<gr_fir_ccf*> d_diff_filters;
+ std::vector< std::vector<float> > d_taps;
+ std::vector< std::vector<float> > d_dtaps;
+ unsigned int d_int_rate; // the number of filters (interpolation rate)
+ unsigned int d_dec_rate; // the stride through the filters (decimation rate)
+ float d_flt_rate; // residual rate for the linear interpolation
+ float d_acc;
+ unsigned int d_last_filter;
+ int d_start_index;
+ unsigned int d_taps_per_filter;
+ bool d_updated;
+
+ /*!
+ * Build the polyphase filterbank arbitray resampler.
+ * \param rate (float) Specifies the resampling rate to use
+ * \param taps (vector/list of floats) The prototype filter to populate the filterbank. The taps
+ * should be generated at the filter_size sampling rate.
+ * \param filter_size (unsigned int) The number of filters in the filter bank. This is directly
+ related to quantization noise introduced during the resampling.
+ Defaults to 32 filters.
+ */
+ gr_pfb_arb_resampler_ccf (float rate,
+ const std::vector<float> &taps,
+ unsigned int filter_size);
+
+ void create_diff_taps(const std::vector<float> &newtaps,
+ std::vector<float> &difftaps);
+
+ /*!
+ * Resets the filterbank's filter taps with the new prototype filter
+ * \param newtaps (vector of floats) The prototype filter to populate the filterbank.
+ * The taps should be generated at the interpolated sampling rate.
+ * \param ourtaps (vector of floats) Reference to our internal member of holding the taps.
+ * \param ourfilter (vector of filters) Reference to our internal filter to set the taps for.
+ */
+ void create_taps (const std::vector<float> &newtaps,
+ std::vector< std::vector<float> > &ourtaps,
+ std::vector<gr_fir_ccf*> &ourfilter);
+
+
+public:
+ ~gr_pfb_arb_resampler_ccf ();
+
+ // FIXME: See about a set_taps function during runtime.
+
+ /*!
+ * Print all of the filterbank taps to screen.
+ */
+ void print_taps();
+ void set_rate (float rate) {
+ d_dec_rate = (unsigned int)floor(d_int_rate/rate);
+ d_flt_rate = (d_int_rate/rate) - d_dec_rate;
+ set_relative_rate(rate);
+ }
+
+ int general_work (int noutput_items,
+ gr_vector_int &ninput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+#endif
diff --git a/gnuradio-core/src/lib/filter/gr_pfb_arb_resampler_ccf.i b/gnuradio-core/src/lib/filter/gr_pfb_arb_resampler_ccf.i
new file mode 100644
index 000000000..da58947e9
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_pfb_arb_resampler_ccf.i
@@ -0,0 +1,42 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2009 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,pfb_arb_resampler_ccf);
+
+gr_pfb_arb_resampler_ccf_sptr gr_make_pfb_arb_resampler_ccf (float rate,
+ const std::vector<float> &taps,
+ unsigned int filter_size=32);
+
+class gr_pfb_arb_resampler_ccf : public gr_block
+{
+ private:
+ gr_pfb_arb_resampler_ccf (float rate,
+ const std::vector<float> &taps,
+ unsigned int filter_size);
+
+ public:
+ ~gr_pfb_arb_resampler_ccf ();
+
+ //void set_taps (const std::vector<float> &taps);
+ void print_taps();
+ void set_rate (float rate);
+};
diff --git a/gnuradio-core/src/lib/filter/gr_pfb_arb_resampler_fff.cc b/gnuradio-core/src/lib/filter/gr_pfb_arb_resampler_fff.cc
new file mode 100644
index 000000000..f01af2e6f
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_pfb_arb_resampler_fff.cc
@@ -0,0 +1,210 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2009-2011 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_pfb_arb_resampler_fff.h>
+#include <gr_fir_fff.h>
+#include <gr_fir_util.h>
+#include <gr_io_signature.h>
+#include <cstdio>
+
+gr_pfb_arb_resampler_fff_sptr gr_make_pfb_arb_resampler_fff (float rate,
+ const std::vector<float> &taps,
+ unsigned int filter_size)
+{
+ return gnuradio::get_initial_sptr(new gr_pfb_arb_resampler_fff (rate, taps,
+ filter_size));
+}
+
+
+gr_pfb_arb_resampler_fff::gr_pfb_arb_resampler_fff (float rate,
+ const std::vector<float> &taps,
+ unsigned int filter_size)
+ : gr_block ("pfb_arb_resampler_fff",
+ gr_make_io_signature (1, 1, sizeof(float)),
+ gr_make_io_signature (1, 1, sizeof(float))),
+ d_updated (false)
+{
+ d_acc = 0; // start accumulator at 0
+
+ /* The number of filters is specified by the user as the filter size;
+ this is also the interpolation rate of the filter. We use it and the
+ rate provided to determine the decimation rate. This acts as a
+ rational resampler. The flt_rate is calculated as the residual
+ between the integer decimation rate and the real decimation rate and
+ will be used to determine to interpolation point of the resampling
+ process.
+ */
+ d_int_rate = filter_size;
+ set_rate(rate);
+
+ // Store the last filter between calls to work
+ d_last_filter = 0;
+
+ d_start_index = 0;
+
+ d_filters = std::vector<gr_fir_fff*>(d_int_rate);
+ d_diff_filters = std::vector<gr_fir_fff*>(d_int_rate);
+
+ // Create an FIR filter for each channel and zero out the taps
+ std::vector<float> vtaps(0, d_int_rate);
+ for(unsigned int i = 0; i < d_int_rate; i++) {
+ d_filters[i] = gr_fir_util::create_gr_fir_fff(vtaps);
+ d_diff_filters[i] = gr_fir_util::create_gr_fir_fff(vtaps);
+ }
+
+ // Now, actually set the filters' taps
+ std::vector<float> dtaps;
+ create_diff_taps(taps, dtaps);
+ create_taps(taps, d_taps, d_filters);
+ create_taps(dtaps, d_dtaps, d_diff_filters);
+}
+
+gr_pfb_arb_resampler_fff::~gr_pfb_arb_resampler_fff ()
+{
+ for(unsigned int i = 0; i < d_int_rate; i++) {
+ delete d_filters[i];
+ delete d_diff_filters[i];
+ }
+}
+
+void
+gr_pfb_arb_resampler_fff::create_taps (const std::vector<float> &newtaps,
+ std::vector< std::vector<float> > &ourtaps,
+ std::vector<gr_fir_fff*> &ourfilter)
+{
+ unsigned int ntaps = newtaps.size();
+ d_taps_per_filter = (unsigned int)ceil((double)ntaps/(double)d_int_rate);
+
+ // Create d_numchan vectors to store each channel's taps
+ ourtaps.resize(d_int_rate);
+
+ // Make a vector of the taps plus fill it out with 0's to fill
+ // each polyphase filter with exactly d_taps_per_filter
+ std::vector<float> tmp_taps;
+ tmp_taps = newtaps;
+ while((float)(tmp_taps.size()) < d_int_rate*d_taps_per_filter) {
+ tmp_taps.push_back(0.0);
+ }
+
+ // Partition the filter
+ for(unsigned int i = 0; i < d_int_rate; i++) {
+ // Each channel uses all d_taps_per_filter with 0's if not enough taps to fill out
+ ourtaps[d_int_rate-1-i] = std::vector<float>(d_taps_per_filter, 0);
+ for(unsigned int j = 0; j < d_taps_per_filter; j++) {
+ ourtaps[d_int_rate - 1 - i][j] = tmp_taps[i + j*d_int_rate];
+ }
+
+ // Build a filter for each channel and add it's taps to it
+ ourfilter[i]->set_taps(ourtaps[d_int_rate-1-i]);
+ }
+
+ // Set the history to ensure enough input items for each filter
+ set_history (d_taps_per_filter + 1);
+
+ d_updated = true;
+}
+
+void
+gr_pfb_arb_resampler_fff::create_diff_taps(const std::vector<float> &newtaps,
+ std::vector<float> &difftaps)
+{
+ // Calculate the differential taps (derivative filter) by taking the difference
+ // between two taps. Duplicate the last one to make both filters the same length.
+ float tap;
+ difftaps.clear();
+ for(unsigned int i = 0; i < newtaps.size()-1; i++) {
+ tap = newtaps[i+1] - newtaps[i];
+ difftaps.push_back(tap);
+ }
+ difftaps.push_back(tap);
+}
+
+void
+gr_pfb_arb_resampler_fff::print_taps()
+{
+ unsigned int i, j;
+ for(i = 0; i < d_int_rate; i++) {
+ printf("filter[%d]: [", i);
+ for(j = 0; j < d_taps_per_filter; j++) {
+ printf(" %.4e", d_taps[i][j]);
+ }
+ printf("]\n");
+ }
+}
+
+int
+gr_pfb_arb_resampler_fff::general_work (int noutput_items,
+ gr_vector_int &ninput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ float *in = (float *) input_items[0];
+ float *out = (float *) output_items[0];
+
+ if (d_updated) {
+ d_updated = false;
+ return 0; // history requirements may have changed.
+ }
+
+ int i = 0, count = d_start_index;
+ unsigned int j;
+ float o0, o1;
+
+ // Restore the last filter position
+ j = d_last_filter;
+
+ // produce output as long as we can and there are enough input samples
+ int max_input = ninput_items[0]-(int)d_taps_per_filter;
+ while((i < noutput_items) && (count < max_input)) {
+ // start j by wrapping around mod the number of channels
+ while((j < d_int_rate) && (i < noutput_items)) {
+ // Take the current filter and derivative filter output
+ o0 = d_filters[j]->filter(&in[count]);
+ o1 = d_diff_filters[j]->filter(&in[count]);
+
+ out[i] = o0 + o1*d_acc; // linearly interpolate between samples
+ i++;
+
+ // Adjust accumulator and index into filterbank
+ d_acc += d_flt_rate;
+ j += d_dec_rate + (int)floor(d_acc);
+ d_acc = fmodf(d_acc, 1.0);
+ }
+ if(i < noutput_items) { // keep state for next entry
+ float ss = (int)(j / d_int_rate); // number of items to skip ahead by
+ count += ss; // we have fully consumed another input
+ j = j % d_int_rate; // roll filter around
+ }
+ }
+
+ // Store the current filter position and start of next sample
+ d_last_filter = j;
+ d_start_index = std::max(0, count - ninput_items[0]);
+
+ // consume all we've processed but no more than we can
+ consume_each(std::min(count, ninput_items[0]));
+ return i;
+}
diff --git a/gnuradio-core/src/lib/filter/gr_pfb_arb_resampler_fff.h b/gnuradio-core/src/lib/filter/gr_pfb_arb_resampler_fff.h
new file mode 100644
index 000000000..d2e375210
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_pfb_arb_resampler_fff.h
@@ -0,0 +1,178 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2009-2011 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+
+#ifndef INCLUDED_GR_PFB_ARB_RESAMPLER_FFF_H
+#define INCLUDED_GR_PFB_ARB_RESAMPLER_FFF_H
+
+#include <gr_core_api.h>
+#include <gr_block.h>
+
+class gr_pfb_arb_resampler_fff;
+typedef boost::shared_ptr<gr_pfb_arb_resampler_fff> gr_pfb_arb_resampler_fff_sptr;
+GR_CORE_API gr_pfb_arb_resampler_fff_sptr gr_make_pfb_arb_resampler_fff (float rate,
+ const std::vector<float> &taps,
+ unsigned int filter_size=32);
+
+class gr_fir_fff;
+
+/*!
+ * \class gr_pfb_arb_resampler_fff
+ *
+ * \brief Polyphase filterbank arbitrary resampler with
+ * float input, float output and float taps
+ *
+ * \ingroup filter_blk
+ * \ingroup pfb_blk
+ *
+ * This block takes in a signal stream and performs arbitrary
+ * resampling. The resampling rate can be any real
+ * number <EM>r</EM>. The resampling is done by constructing
+ * <EM>N</EM> filters where <EM>N</EM> is the interpolation rate. We
+ * then calculate <EM>D</EM> where <EM>D = floor(N/r)</EM>.
+ *
+ * Using <EM>N</EM> and <EM>D</EM>, we can perform rational resampling
+ * where <EM>N/D</EM> is a rational number close to the input rate
+ * <EM>r</EM> where we have <EM>N</EM> filters and we cycle through
+ * them as a polyphase filterbank with a stride of <EM>D</EM> so that
+ * <EM>i+1 = (i + D) % N</EM>.
+ *
+ * To get the arbitrary rate, we want to interpolate between two
+ * points. For each value out, we take an output from the current
+ * filter, <EM>i</EM>, and the next filter <EM>i+1</EM> and then
+ * linearly interpolate between the two based on the real resampling
+ * rate we want.
+ *
+ * The linear interpolation only provides us with an approximation to
+ * the real sampling rate specified. The error is a quantization error
+ * between the two filters we used as our interpolation points. To
+ * this end, the number of filters, <EM>N</EM>, used determines the
+ * quantization error; the larger <EM>N</EM>, the smaller the
+ * noise. You can design for a specified noise floor by setting the
+ * filter size (parameters <EM>filter_size</EM>). The size defaults to
+ * 32 filters, which is about as good as most implementations need.
+ *
+ * The trick with designing this filter is in how to specify the taps
+ * of the prototype filter. Like the PFB interpolator, the taps are
+ * specified using the interpolated filter rate. In this case, that
+ * rate is the input sample rate multiplied by the number of filters
+ * in the filterbank, which is also the interpolation rate. All other
+ * values should be relative to this rate.
+ *
+ * For example, for a 32-filter arbitrary resampler and using the
+ * GNU Radio's firdes utility to build the filter, we build a low-pass
+ * filter with a sampling rate of <EM>fs</EM>, a 3-dB bandwidth of
+ * <EM>BW</EM> and a transition bandwidth of <EM>TB</EM>. We can also
+ * specify the out-of-band attenuation to use, <EM>ATT</EM>, and the
+ * filter window function (a Blackman-harris window in this case). The
+ * first input is the gain of the filter, which we specify here as the
+ * interpolation rate (<EM>32</EM>).
+ *
+ * <B><EM>self._taps = gr.firdes.low_pass_2(32, 32*fs, BW, TB,
+ * attenuation_dB=ATT, window=gr.firdes.WIN_BLACKMAN_hARRIS)</EM></B>
+ *
+ * The theory behind this block can be found in Chapter 7.5 of
+ * the following book.
+ *
+ * <B><EM>f. harris, "Multirate Signal Processing for Communication
+ * Systems", Upper Saddle River, NJ: Prentice Hall, Inc. 2004.</EM></B>
+ */
+
+class GR_CORE_API gr_pfb_arb_resampler_fff : public gr_block
+{
+ private:
+ /*!
+ * Build the polyphase filterbank arbitray resampler.
+ * \param rate (float) Specifies the resampling rate to use
+ * \param taps (vector/list of floats) The prototype filter to populate the filterbank. The taps
+ * should be generated at the filter_size sampling rate.
+ * \param filter_size (unsigned int) The number of filters in the filter bank. This is directly
+ related to quantization noise introduced during the resampling.
+ Defaults to 32 filters.
+ */
+ friend GR_CORE_API gr_pfb_arb_resampler_fff_sptr gr_make_pfb_arb_resampler_fff (float rate,
+ const std::vector<float> &taps,
+ unsigned int filter_size);
+
+ std::vector<gr_fir_fff*> d_filters;
+ std::vector<gr_fir_fff*> d_diff_filters;
+ std::vector< std::vector<float> > d_taps;
+ std::vector< std::vector<float> > d_dtaps;
+ unsigned int d_int_rate; // the number of filters (interpolation rate)
+ unsigned int d_dec_rate; // the stride through the filters (decimation rate)
+ float d_flt_rate; // residual rate for the linear interpolation
+ float d_acc;
+ unsigned int d_last_filter;
+ int d_start_index;
+ unsigned int d_taps_per_filter;
+ bool d_updated;
+
+ /*!
+ * Build the polyphase filterbank arbitray resampler.
+ * \param rate (float) Specifies the resampling rate to use
+ * \param taps (vector/list of floats) The prototype filter to populate the filterbank. The taps
+ * should be generated at the filter_size sampling rate.
+ * \param filter_size (unsigned int) The number of filters in the filter bank. This is directly
+ related to quantization noise introduced during the resampling.
+ Defaults to 32 filters.
+ */
+ gr_pfb_arb_resampler_fff (float rate,
+ const std::vector<float> &taps,
+ unsigned int filter_size);
+
+ void create_diff_taps(const std::vector<float> &newtaps,
+ std::vector<float> &difftaps);
+
+ /*!
+ * Resets the filterbank's filter taps with the new prototype filter
+ * \param newtaps (vector of floats) The prototype filter to populate the filterbank.
+ * The taps should be generated at the interpolated sampling rate.
+ * \param ourtaps (vector of floats) Reference to our internal member of holding the taps.
+ * \param ourfilter (vector of filters) Reference to our internal filter to set the taps for.
+ */
+ void create_taps (const std::vector<float> &newtaps,
+ std::vector< std::vector<float> > &ourtaps,
+ std::vector<gr_fir_fff*> &ourfilter);
+
+
+public:
+ ~gr_pfb_arb_resampler_fff ();
+
+ // FIXME: See about a set_taps function during runtime.
+
+ /*!
+ * Print all of the filterbank taps to screen.
+ */
+ void print_taps();
+ void set_rate (float rate) {
+ d_dec_rate = (unsigned int)floor(d_int_rate/rate);
+ d_flt_rate = (d_int_rate/rate) - d_dec_rate;
+ set_relative_rate(rate);
+ }
+
+ int general_work (int noutput_items,
+ gr_vector_int &ninput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+#endif
diff --git a/gnuradio-core/src/lib/filter/gr_pfb_arb_resampler_fff.i b/gnuradio-core/src/lib/filter/gr_pfb_arb_resampler_fff.i
new file mode 100644
index 000000000..ad0905361
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_pfb_arb_resampler_fff.i
@@ -0,0 +1,42 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2009,2011 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,pfb_arb_resampler_fff);
+
+gr_pfb_arb_resampler_fff_sptr gr_make_pfb_arb_resampler_fff (float rate,
+ const std::vector<float> &taps,
+ unsigned int filter_size=32);
+
+class gr_pfb_arb_resampler_fff : public gr_block
+{
+ private:
+ gr_pfb_arb_resampler_fff (float rate,
+ const std::vector<float> &taps,
+ unsigned int filter_size);
+
+ public:
+ ~gr_pfb_arb_resampler_fff ();
+
+ //void set_taps (const std::vector<float> &taps);
+ void print_taps();
+ void set_rate (float rate);
+};
diff --git a/gnuradio-core/src/lib/filter/gr_pfb_channelizer_ccf.cc b/gnuradio-core/src/lib/filter/gr_pfb_channelizer_ccf.cc
new file mode 100644
index 000000000..a8cb849e2
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_pfb_channelizer_ccf.cc
@@ -0,0 +1,240 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2009,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_pfb_channelizer_ccf.h>
+#include <gr_fir_ccf.h>
+#include <gr_fir_util.h>
+#include <gri_fft.h>
+#include <gr_io_signature.h>
+#include <cstdio>
+#include <cstring>
+
+gr_pfb_channelizer_ccf_sptr gr_make_pfb_channelizer_ccf (unsigned int numchans,
+ const std::vector<float> &taps,
+ float oversample_rate)
+{
+ return gnuradio::get_initial_sptr(new gr_pfb_channelizer_ccf (numchans, taps,
+ oversample_rate));
+}
+
+
+gr_pfb_channelizer_ccf::gr_pfb_channelizer_ccf (unsigned int numchans,
+ const std::vector<float> &taps,
+ float oversample_rate)
+ : gr_block ("pfb_channelizer_ccf",
+ gr_make_io_signature (numchans, numchans, sizeof(gr_complex)),
+ gr_make_io_signature (1, numchans, sizeof(gr_complex))),
+ d_updated (false), d_numchans(numchans), d_oversample_rate(oversample_rate)
+{
+ // The over sampling rate must be rationally related to the number of channels
+ // in that it must be N/i for i in [1,N], which gives an outputsample rate
+ // of [fs/N, fs] where fs is the input sample rate.
+ // This tests the specified input sample rate to see if it conforms to this
+ // requirement within a few significant figures.
+ double intp = 0;
+ double fltp = modf(numchans / oversample_rate, &intp);
+ if(fltp != 0.0)
+ throw std::invalid_argument("gr_pfb_channelizer: oversample rate must be N/i for i in [1, N]");
+
+ set_relative_rate(1.0/intp);
+
+ d_filters = std::vector<gr_fir_ccf*>(d_numchans);
+ d_channel_map.resize(d_numchans);
+
+ // Create an FIR filter for each channel and zero out the taps
+ std::vector<float> vtaps(0, d_numchans);
+ for(unsigned int i = 0; i < d_numchans; i++) {
+ d_filters[i] = gr_fir_util::create_gr_fir_ccf(vtaps);
+ d_channel_map[i] = i;
+ }
+
+ // Now, actually set the filters' taps
+ set_taps(taps);
+
+ // Create the FFT to handle the output de-spinning of the channels
+ d_fft = new gri_fft_complex (d_numchans, false);
+
+ // Although the filters change, we use this look up table
+ // to set the index of the FFT input buffer, which equivalently
+ // performs the FFT shift operation on every other turn.
+ d_rate_ratio = (int)rintf(d_numchans / d_oversample_rate);
+ d_idxlut = new int[d_numchans];
+ for(unsigned int i = 0; i < d_numchans; i++) {
+ d_idxlut[i] = d_numchans - ((i + d_rate_ratio) % d_numchans) - 1;
+ }
+
+ // Calculate the number of filtering rounds to do to evenly
+ // align the input vectors with the output channels
+ d_output_multiple = 1;
+ while((d_output_multiple * d_rate_ratio) % d_numchans != 0)
+ d_output_multiple++;
+ set_output_multiple(d_output_multiple);
+}
+
+gr_pfb_channelizer_ccf::~gr_pfb_channelizer_ccf ()
+{
+ delete d_fft;
+ delete [] d_idxlut;
+
+ for(unsigned int i = 0; i < d_numchans; i++) {
+ delete d_filters[i];
+ }
+}
+
+void
+gr_pfb_channelizer_ccf::set_taps (const std::vector<float> &taps)
+{
+ gruel::scoped_lock guard(d_mutex);
+ unsigned int i,j;
+
+ unsigned int ntaps = taps.size();
+ d_taps_per_filter = (unsigned int)ceil((double)ntaps/(double)d_numchans);
+
+ // Create d_numchan vectors to store each channel's taps
+ d_taps.resize(d_numchans);
+
+ // Make a vector of the taps plus fill it out with 0's to fill
+ // each polyphase filter with exactly d_taps_per_filter
+ std::vector<float> tmp_taps;
+ tmp_taps = taps;
+ while((float)(tmp_taps.size()) < d_numchans*d_taps_per_filter) {
+ tmp_taps.push_back(0.0);
+ }
+
+ // Partition the filter
+ for(i = 0; i < d_numchans; i++) {
+ // Each channel uses all d_taps_per_filter with 0's if not enough taps to fill out
+ d_taps[i] = std::vector<float>(d_taps_per_filter, 0);
+ for(j = 0; j < d_taps_per_filter; j++) {
+ d_taps[i][j] = tmp_taps[i + j*d_numchans]; // add taps to channels in reverse order
+ }
+
+ // Build a filter for each channel and add it's taps to it
+ d_filters[i]->set_taps(d_taps[i]);
+ }
+
+ // Set the history to ensure enough input items for each filter
+ set_history (d_taps_per_filter+1);
+
+ d_updated = true;
+}
+
+void
+gr_pfb_channelizer_ccf::print_taps()
+{
+ unsigned int i, j;
+ for(i = 0; i < d_numchans; i++) {
+ printf("filter[%d]: [", i);
+ for(j = 0; j < d_taps_per_filter; j++) {
+ printf(" %.4e", d_taps[i][j]);
+ }
+ printf("]\n\n");
+ }
+}
+
+std::vector< std::vector<float> >
+gr_pfb_channelizer_ccf::taps() const
+{
+ return d_taps;
+}
+
+void
+gr_pfb_channelizer_ccf::set_channel_map(const std::vector<int> &map)
+{
+ gruel::scoped_lock guard(d_mutex);
+
+ if(map.size() > 0) {
+ unsigned int max = (unsigned int)*std::max_element(map.begin(), map.end());
+ unsigned int min = (unsigned int)*std::min_element(map.begin(), map.end());
+ if((max >= d_numchans) || (min < 0)) {
+ throw std::invalid_argument("gr_pfb_channelizer_ccf::set_channel_map: map range out of bounds.\n");
+ }
+ d_channel_map = map;
+ }
+}
+
+std::vector<int>
+gr_pfb_channelizer_ccf::channel_map() const
+{
+ return d_channel_map;
+}
+
+
+int
+gr_pfb_channelizer_ccf::general_work (int noutput_items,
+ gr_vector_int &ninput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ gruel::scoped_lock guard(d_mutex);
+
+ gr_complex *in = (gr_complex *) input_items[0];
+ gr_complex *out = (gr_complex *) output_items[0];
+
+ if (d_updated) {
+ d_updated = false;
+ return 0; // history requirements may have changed.
+ }
+
+ size_t noutputs = output_items.size();
+
+ int n=1, i=-1, j=0, oo=0, last;
+ int toconsume = (int)rintf(noutput_items/d_oversample_rate);
+ while(n <= toconsume) {
+ j = 0;
+ i = (i + d_rate_ratio) % d_numchans;
+ last = i;
+ while(i >= 0) {
+ in = (gr_complex*)input_items[j];
+ d_fft->get_inbuf()[d_idxlut[j]] = d_filters[i]->filter(&in[n]);
+ j++;
+ i--;
+ }
+
+ i = d_numchans-1;
+ while(i > last) {
+ in = (gr_complex*)input_items[j];
+ d_fft->get_inbuf()[d_idxlut[j]] = d_filters[i]->filter(&in[n-1]);
+ j++;
+ i--;
+ }
+
+ n += (i+d_rate_ratio) >= (int)d_numchans;
+
+ // despin through FFT
+ d_fft->execute();
+
+ // Send to output channels
+ for(unsigned int nn = 0; nn < noutputs; nn++) {
+ out = (gr_complex*)output_items[nn];
+ out[oo] = d_fft->get_outbuf()[d_channel_map[nn]];
+ }
+ oo++;
+ }
+
+ consume_each(toconsume);
+ return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/filter/gr_pfb_channelizer_ccf.h b/gnuradio-core/src/lib/filter/gr_pfb_channelizer_ccf.h
new file mode 100644
index 000000000..79ad322f9
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_pfb_channelizer_ccf.h
@@ -0,0 +1,226 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2009,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+
+#ifndef INCLUDED_GR_PFB_CHANNELIZER_CCF_H
+#define INCLUDED_GR_PFB_CHANNELIZER_CCF_H
+
+#include <gr_core_api.h>
+#include <gr_block.h>
+#include <gruel/thread.h>
+
+class gr_pfb_channelizer_ccf;
+typedef boost::shared_ptr<gr_pfb_channelizer_ccf> gr_pfb_channelizer_ccf_sptr;
+GR_CORE_API gr_pfb_channelizer_ccf_sptr gr_make_pfb_channelizer_ccf (unsigned int numchans,
+ const std::vector<float> &taps,
+ float oversample_rate=1);
+
+class gr_fir_ccf;
+class gri_fft_complex;
+
+
+/*!
+ * \class gr_pfb_channelizer_ccf
+ *
+ * \brief Polyphase filterbank channelizer with
+ * gr_complex input, gr_complex output and float taps
+ *
+ * \ingroup filter_blk
+ * \ingroup pfb_blk
+ *
+ * This block takes in complex inputs and channelizes it to <EM>M</EM>
+ * channels of equal bandwidth. Each of the resulting channels is
+ * decimated to the new rate that is the input sampling rate
+ * <EM>fs</EM> divided by the number of channels, <EM>M</EM>.
+ *
+ * The PFB channelizer code takes the taps generated above and builds
+ * a set of filters. The set contains <EM>M</EM> number of filters
+ * and each filter contains ceil(taps.size()/decim) number of taps.
+ * Each tap from the filter prototype is sequentially inserted into
+ * the next filter. When all of the input taps are used, the remaining
+ * filters in the filterbank are filled out with 0's to make sure each
+ * filter has the same number of taps.
+ *
+ * Each filter operates using the gr_fir filter classs of GNU Radio,
+ * which takes the input stream at <EM>i</EM> and performs the inner
+ * product calculation to <EM>i+(n-1)</EM> where <EM>n</EM> is the
+ * number of filter taps. To efficiently handle this in the GNU Radio
+ * structure, each filter input must come from its own input
+ * stream. So the channelizer must be provided with <EM>M</EM> streams
+ * where the input stream has been deinterleaved. This is most easily
+ * done using the gr_stream_to_streams block.
+ *
+ * The output is then produced as a vector, where index <EM>i</EM> in
+ * the vector is the next sample from the <EM>i</EM>th channel. This
+ * is most easily handled by sending the output to a
+ * gr_vector_to_streams block to handle the conversion and passing
+ * <EM>M</EM> streams out.
+ *
+ * The input and output formatting is done using a hier_block2 called
+ * pfb_channelizer_ccf. This can take in a single stream and outputs
+ * <EM>M</EM> streams based on the behavior described above.
+ *
+ * The filter's taps should be based on the input sampling rate.
+ *
+ * For example, using the GNU Radio's firdes utility to building
+ * filters, we build a low-pass filter with a sampling rate of
+ * <EM>fs</EM>, a 3-dB bandwidth of <EM>BW</EM> and a transition
+ * bandwidth of <EM>TB</EM>. We can also specify the out-of-band
+ * attenuation to use, <EM>ATT</EM>, and the filter window
+ * function (a Blackman-harris window in this case). The first input
+ * is the gain of the filter, which we specify here as unity.
+ *
+ * <B><EM>self._taps = gr.firdes.low_pass_2(1, fs, BW, TB,
+ * attenuation_dB=ATT, window=gr.firdes.WIN_BLACKMAN_hARRIS)</EM></B>
+ *
+ * The filter output can also be overs ampled. The over sampling rate
+ * is the ratio of the the actual output sampling rate to the normal
+ * output sampling rate. It must be rationally related to the number
+ * of channels as N/i for i in [1,N], which gives an outputsample rate
+ * of [fs/N, fs] where fs is the input sample rate and N is the number
+ * of channels.
+ *
+ * For example, for 6 channels with fs = 6000 Hz, the normal rate is
+ * 6000/6 = 1000 Hz. Allowable oversampling rates are 6/6, 6/5, 6/4,
+ * 6/3, 6/2, and 6/1 where the output sample rate of a 6/1 oversample
+ * ratio is 6000 Hz, or 6 times the normal 1000 Hz. A rate of 6/5 = 1.2,
+ * so the output rate would be 1200 Hz.
+ *
+ * The theory behind this block can be found in Chapter 6 of
+ * the following book.
+ *
+ * <B><EM>f. harris, "Multirate Signal Processing for Communication
+ * Systems," Upper Saddle River, NJ: Prentice Hall, Inc. 2004.</EM></B>
+ *
+ */
+
+class GR_CORE_API gr_pfb_channelizer_ccf : public gr_block
+{
+ private:
+ /*!
+ * Build the polyphase filterbank decimator.
+ * \param numchans (unsigned integer) Specifies the number of channels <EM>M</EM>
+ * \param taps (vector/list of floats) The prototype filter to populate the filterbank.
+ * \param oversample_rate (float) The over sampling rate is the ratio of the the actual
+ * output sampling rate to the normal output sampling rate.
+ * It must be rationally related to the number of channels
+ * as N/i for i in [1,N], which gives an outputsample rate
+ * of [fs/N, fs] where fs is the input sample rate and N is
+ * the number of channels.
+ *
+ * For example, for 6 channels with fs = 6000 Hz, the normal
+ * rate is 6000/6 = 1000 Hz. Allowable oversampling rates
+ * are 6/6, 6/5, 6/4, 6/3, 6/2, and 6/1 where the output
+ * sample rate of a 6/1 oversample ratio is 6000 Hz, or
+ * 6 times the normal 1000 Hz.
+ */
+ friend GR_CORE_API gr_pfb_channelizer_ccf_sptr gr_make_pfb_channelizer_ccf (unsigned int numchans,
+ const std::vector<float> &taps,
+ float oversample_rate);
+
+ bool d_updated;
+ unsigned int d_numchans;
+ float d_oversample_rate;
+ std::vector<gr_fir_ccf*> d_filters;
+ std::vector< std::vector<float> > d_taps;
+ unsigned int d_taps_per_filter;
+ gri_fft_complex *d_fft;
+ int *d_idxlut;
+ int d_rate_ratio;
+ int d_output_multiple;
+ std::vector<int> d_channel_map;
+ gruel::mutex d_mutex; // mutex to protect set/work access
+
+ /*!
+ * Build the polyphase filterbank decimator.
+ * \param numchans (unsigned integer) Specifies the number of channels <EM>M</EM>
+ * \param taps (vector/list of floats) The prototype filter to populate the filterbank.
+ * \param oversample_rate (float) The output over sampling rate.
+ */
+ gr_pfb_channelizer_ccf (unsigned int numchans,
+ const std::vector<float> &taps,
+ float oversample_rate);
+
+public:
+ ~gr_pfb_channelizer_ccf ();
+
+ /*!
+ * Resets the filterbank's filter taps with the new prototype filter
+ * \param taps (vector/list of floats) The prototype filter to populate the filterbank.
+ */
+ void set_taps (const std::vector<float> &taps);
+
+ /*!
+ * Print all of the filterbank taps to screen.
+ */
+ void print_taps();
+
+ /*!
+ * Return a vector<vector<>> of the filterbank taps
+ */
+ std::vector<std::vector<float> > taps() const;
+
+ /*!
+ * Set the channel map. Channels are numbers as:
+ *
+ * N/2+1 | ... | N-1 | 0 | 1 | 2 | ... | N/2
+ * <------------------- 0 -------------------->
+ * freq
+ *
+ * So output stream 0 comes from channel 0, etc. Setting a new
+ * channel map allows the user to specify which channel in frequency
+ * he/she wants to got to which output stream.
+ *
+ * The map should have the same number of elements as the number of
+ * output connections from the block. The minimum value of the map
+ * is 0 (for the 0th channel) and the maximum number is N-1 where N
+ * is the number of channels.
+ *
+ * We specify M as the number of output connections made where M <=
+ * N, so only M out of N channels are driven to an output
+ * stream. The number of items in the channel map should be at least
+ * M long. If there are more channels specified, any value in the
+ * map over M-1 will be ignored. If the size of the map is less than
+ * M the behavior is unknown (we don't wish to check every entry
+ * into the work function).
+ *
+ * This means that if the channelizer is splitting the signal up
+ * into N channels but only M channels are specified in the map
+ * (where M <= N), then M output streams must be connected and the
+ * map and the channel numbers used must be less than N-1. Output
+ * channel number can be reused, too. By default, the map is
+ * [0...M-1] with M = N.
+ */
+ void set_channel_map(const std::vector<int> &map);
+
+ /*!
+ * Gets the current channel map.
+ */
+ std::vector<int> channel_map() const;
+
+ int general_work (int noutput_items,
+ gr_vector_int &ninput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+#endif
diff --git a/gnuradio-core/src/lib/filter/gr_pfb_channelizer_ccf.i b/gnuradio-core/src/lib/filter/gr_pfb_channelizer_ccf.i
new file mode 100644
index 000000000..1f2b49452
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_pfb_channelizer_ccf.i
@@ -0,0 +1,45 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2009,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,pfb_channelizer_ccf);
+
+gr_pfb_channelizer_ccf_sptr gr_make_pfb_channelizer_ccf (unsigned int numchans,
+ const std::vector<float> &taps,
+ float oversample_rate=1);
+
+class gr_pfb_channelizer_ccf : public gr_block
+{
+ private:
+ gr_pfb_channelizer_ccf (unsigned int numchans,
+ const std::vector<float> &taps,
+ float oversample_rate);
+
+ public:
+ ~gr_pfb_channelizer_ccf ();
+
+ void set_taps (const std::vector<float> &taps);
+ void print_taps();
+ std::vector<std::vector<float> > taps() const;
+
+ void set_channel_map(const std::vector<int> &map);
+ std::vector<int> channel_map() const;
+};
diff --git a/gnuradio-core/src/lib/filter/gr_pfb_clock_sync_ccf.cc b/gnuradio-core/src/lib/filter/gr_pfb_clock_sync_ccf.cc
new file mode 100644
index 000000000..efe417918
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_pfb_clock_sync_ccf.cc
@@ -0,0 +1,441 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2009-2011 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <cstdio>
+#include <cmath>
+
+#include <gr_pfb_clock_sync_ccf.h>
+#include <gr_fir_ccf.h>
+#include <gr_fir_util.h>
+#include <gr_io_signature.h>
+#include <gr_math.h>
+
+gr_pfb_clock_sync_ccf_sptr gr_make_pfb_clock_sync_ccf (double sps, float loop_bw,
+ const std::vector<float> &taps,
+ unsigned int filter_size,
+ float init_phase,
+ float max_rate_deviation,
+ int osps)
+{
+ return gnuradio::get_initial_sptr(new gr_pfb_clock_sync_ccf (sps, loop_bw, taps,
+ filter_size,
+ init_phase,
+ max_rate_deviation,
+ osps));
+}
+
+static int ios[] = {sizeof(gr_complex), sizeof(float), sizeof(float), sizeof(float)};
+static std::vector<int> iosig(ios, ios+sizeof(ios)/sizeof(int));
+gr_pfb_clock_sync_ccf::gr_pfb_clock_sync_ccf (double sps, float loop_bw,
+ const std::vector<float> &taps,
+ unsigned int filter_size,
+ float init_phase,
+ float max_rate_deviation,
+ int osps)
+ : gr_block ("pfb_clock_sync_ccf",
+ gr_make_io_signature (1, 1, sizeof(gr_complex)),
+ gr_make_io_signaturev (1, 4, iosig)),
+ d_updated (false), d_nfilters(filter_size),
+ d_max_dev(max_rate_deviation),
+ d_osps(osps), d_error(0), d_out_idx(0)
+{
+ d_nfilters = filter_size;
+ d_sps = floor(sps);
+
+ // Set the damping factor for a critically damped system
+ d_damping = sqrtf(2.0f)/2.0f;
+
+ // Set the bandwidth, which will then call update_gains()
+ set_loop_bandwidth(loop_bw);
+
+ // Store the last filter between calls to work
+ // The accumulator keeps track of overflow to increment the stride correctly.
+ // set it here to the fractional difference based on the initial phaes
+ d_k = init_phase;
+ d_rate = (sps-floor(sps))*(double)d_nfilters;
+ d_rate_i = (int)floor(d_rate);
+ d_rate_f = d_rate - (float)d_rate_i;
+ d_filtnum = (int)floor(d_k);
+
+ d_filters = std::vector<gr_fir_ccf*>(d_nfilters);
+ d_diff_filters = std::vector<gr_fir_ccf*>(d_nfilters);
+
+ // Create an FIR filter for each channel and zero out the taps
+ std::vector<float> vtaps(0, d_nfilters);
+ for(int i = 0; i < d_nfilters; i++) {
+ d_filters[i] = gr_fir_util::create_gr_fir_ccf(vtaps);
+ d_diff_filters[i] = gr_fir_util::create_gr_fir_ccf(vtaps);
+ }
+
+ // Now, actually set the filters' taps
+ std::vector<float> dtaps;
+ create_diff_taps(taps, dtaps);
+ set_taps(taps, d_taps, d_filters);
+ set_taps(dtaps, d_dtaps, d_diff_filters);
+}
+
+gr_pfb_clock_sync_ccf::~gr_pfb_clock_sync_ccf ()
+{
+ for(int i = 0; i < d_nfilters; i++) {
+ delete d_filters[i];
+ delete d_diff_filters[i];
+ }
+}
+
+bool
+gr_pfb_clock_sync_ccf::check_topology(int ninputs, int noutputs)
+{
+ return noutputs == 1 || noutputs == 4;
+}
+
+
+
+/*******************************************************************
+ SET FUNCTIONS
+*******************************************************************/
+
+
+void
+gr_pfb_clock_sync_ccf::set_loop_bandwidth(float bw)
+{
+ if(bw < 0) {
+ throw std::out_of_range ("gr_pfb_clock_sync_cc: invalid bandwidth. Must be >= 0.");
+ }
+
+ d_loop_bw = bw;
+ update_gains();
+}
+
+void
+gr_pfb_clock_sync_ccf::set_damping_factor(float df)
+{
+ if(df < 0 || df > 1.0) {
+ throw std::out_of_range ("gr_pfb_clock_sync_cc: invalid damping factor. Must be in [0,1].");
+ }
+
+ d_damping = df;
+ update_gains();
+}
+
+void
+gr_pfb_clock_sync_ccf::set_alpha(float alpha)
+{
+ if(alpha < 0 || alpha > 1.0) {
+ throw std::out_of_range ("gr_pfb_clock_sync_cc: invalid alpha. Must be in [0,1].");
+ }
+ d_alpha = alpha;
+}
+
+void
+gr_pfb_clock_sync_ccf::set_beta(float beta)
+{
+ if(beta < 0 || beta > 1.0) {
+ throw std::out_of_range ("gr_pfb_clock_sync_cc: invalid beta. Must be in [0,1].");
+ }
+ d_beta = beta;
+}
+
+/*******************************************************************
+ GET FUNCTIONS
+*******************************************************************/
+
+
+float
+gr_pfb_clock_sync_ccf::get_loop_bandwidth() const
+{
+ return d_loop_bw;
+}
+
+float
+gr_pfb_clock_sync_ccf::get_damping_factor() const
+{
+ return d_damping;
+}
+
+float
+gr_pfb_clock_sync_ccf::get_alpha() const
+{
+ return d_alpha;
+}
+
+float
+gr_pfb_clock_sync_ccf::get_beta() const
+{
+ return d_beta;
+}
+
+float
+gr_pfb_clock_sync_ccf::get_clock_rate() const
+{
+ return d_rate_f;
+}
+
+/*******************************************************************
+*******************************************************************/
+
+void
+gr_pfb_clock_sync_ccf::update_gains()
+{
+ float denom = (1.0 + 2.0*d_damping*d_loop_bw + d_loop_bw*d_loop_bw);
+ d_alpha = (4*d_damping*d_loop_bw) / denom;
+ d_beta = (4*d_loop_bw*d_loop_bw) / denom;
+}
+
+
+void
+gr_pfb_clock_sync_ccf::set_taps (const std::vector<float> &newtaps,
+ std::vector< std::vector<float> > &ourtaps,
+ std::vector<gr_fir_ccf*> &ourfilter)
+{
+ int i,j;
+
+ unsigned int ntaps = newtaps.size();
+ d_taps_per_filter = (unsigned int)ceil((double)ntaps/(double)d_nfilters);
+
+ // Create d_numchan vectors to store each channel's taps
+ ourtaps.resize(d_nfilters);
+
+ // Make a vector of the taps plus fill it out with 0's to fill
+ // each polyphase filter with exactly d_taps_per_filter
+ std::vector<float> tmp_taps;
+ tmp_taps = newtaps;
+ while((float)(tmp_taps.size()) < d_nfilters*d_taps_per_filter) {
+ tmp_taps.push_back(0.0);
+ }
+
+ // Partition the filter
+ for(i = 0; i < d_nfilters; i++) {
+ // Each channel uses all d_taps_per_filter with 0's if not enough taps to fill out
+ //ourtaps[d_nfilters-1-i] = std::vector<float>(d_taps_per_filter, 0);
+ ourtaps[i] = std::vector<float>(d_taps_per_filter, 0);
+ for(j = 0; j < d_taps_per_filter; j++) {
+ //ourtaps[d_nfilters - 1 - i][j] = tmp_taps[i + j*d_nfilters];
+ ourtaps[i][j] = tmp_taps[i + j*d_nfilters];
+ }
+
+ // Build a filter for each channel and add it's taps to it
+ //ourfilter[i]->set_taps(ourtaps[d_nfilters-1-i]);
+ ourfilter[i]->set_taps(ourtaps[i]);
+ }
+
+ // Set the history to ensure enough input items for each filter
+ set_history (d_taps_per_filter + d_sps);
+
+ // Make sure there is enough output space for d_osps outputs/input.
+ set_output_multiple(d_osps);
+
+ d_updated = true;
+}
+
+void
+gr_pfb_clock_sync_ccf::create_diff_taps(const std::vector<float> &newtaps,
+ std::vector<float> &difftaps)
+{
+ std::vector<float> diff_filter(3);
+ diff_filter[0] = -1;
+ diff_filter[1] = 0;
+ diff_filter[2] = 1;
+
+ float pwr = 0;
+ difftaps.push_back(0);
+ for(unsigned int i = 0; i < newtaps.size()-2; i++) {
+ float tap = 0;
+ for(int j = 0; j < 3; j++) {
+ tap += diff_filter[j]*newtaps[i+j];
+ pwr += fabsf(tap);
+ }
+ difftaps.push_back(tap);
+ }
+ difftaps.push_back(0);
+
+ for(unsigned int i = 0; i < difftaps.size(); i++) {
+ difftaps[i] *= pwr;
+ }
+}
+
+std::string
+gr_pfb_clock_sync_ccf::get_taps_as_string()
+{
+ int i, j;
+ std::stringstream str;
+ str.precision(4);
+ str.setf(std::ios::scientific);
+
+ str << "[ ";
+ for(i = 0; i < d_nfilters; i++) {
+ str << "[" << d_taps[i][0] << ", ";
+ for(j = 1; j < d_taps_per_filter-1; j++) {
+ str << d_taps[i][j] << ", ";
+ }
+ str << d_taps[i][j] << "],";
+ }
+ str << " ]" << std::endl;
+
+ return str.str();
+}
+
+std::string
+gr_pfb_clock_sync_ccf::get_diff_taps_as_string()
+{
+ int i, j;
+ std::stringstream str;
+ str.precision(4);
+ str.setf(std::ios::scientific);
+
+ str << "[ ";
+ for(i = 0; i < d_nfilters; i++) {
+ str << "[" << d_dtaps[i][0] << ", ";
+ for(j = 1; j < d_taps_per_filter-1; j++) {
+ str << d_dtaps[i][j] << ", ";
+ }
+ str << d_dtaps[i][j] << "],";
+ }
+ str << " ]" << std::endl;
+
+ return str.str();
+}
+
+std::vector< std::vector<float> >
+gr_pfb_clock_sync_ccf::get_taps()
+{
+ return d_taps;
+}
+
+std::vector< std::vector<float> >
+gr_pfb_clock_sync_ccf::get_diff_taps()
+{
+ return d_dtaps;
+}
+
+std::vector<float>
+gr_pfb_clock_sync_ccf::get_channel_taps(int channel)
+{
+ std::vector<float> taps;
+ for(int i = 0; i < d_taps_per_filter; i++) {
+ taps.push_back(d_taps[channel][i]);
+ }
+ return taps;
+}
+
+std::vector<float>
+gr_pfb_clock_sync_ccf::get_diff_channel_taps(int channel)
+{
+ std::vector<float> taps;
+ for(int i = 0; i < d_taps_per_filter; i++) {
+ taps.push_back(d_dtaps[channel][i]);
+ }
+ return taps;
+}
+
+
+int
+gr_pfb_clock_sync_ccf::general_work (int noutput_items,
+ gr_vector_int &ninput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ gr_complex *in = (gr_complex *) input_items[0];
+ gr_complex *out = (gr_complex *) output_items[0];
+
+ float *err = NULL, *outrate = NULL, *outk = NULL;
+ if(output_items.size() == 4) {
+ err = (float *) output_items[1];
+ outrate = (float*)output_items[2];
+ outk = (float*)output_items[3];
+ }
+
+ if (d_updated) {
+ d_updated = false;
+ return 0; // history requirements may have changed.
+ }
+
+ // We need this many to process one output
+ int nrequired = ninput_items[0] - d_taps_per_filter - d_osps;
+
+ int i = 0, count = 0;
+ float error_r, error_i;
+
+ // produce output as long as we can and there are enough input samples
+ while((i < noutput_items) && (count < nrequired)) {
+ while(d_out_idx < d_osps) {
+ d_filtnum = (int)floor(d_k);
+
+ // Keep the current filter number in [0, d_nfilters]
+ // If we've run beyond the last filter, wrap around and go to next sample
+ // If we've go below 0, wrap around and go to previous sample
+ while(d_filtnum >= d_nfilters) {
+ d_k -= d_nfilters;
+ d_filtnum -= d_nfilters;
+ count += 1;
+ }
+ while(d_filtnum < 0) {
+ d_k += d_nfilters;
+ d_filtnum += d_nfilters;
+ count -= 1;
+ }
+
+ out[i+d_out_idx] = d_filters[d_filtnum]->filter(&in[count+d_out_idx]);
+ d_k = d_k + d_rate_i + d_rate_f; // update phase
+ d_out_idx++;
+
+ if(output_items.size() == 4) {
+ err[i] = d_error;
+ outrate[i] = d_rate_f;
+ outk[i] = d_k;
+ }
+
+ // We've run out of output items we can create; return now.
+ if(i+d_out_idx >= noutput_items) {
+ consume_each(count);
+ return i;
+ }
+ }
+
+ // reset here; if we didn't complete a full osps samples last time,
+ // the early return would take care of it.
+ d_out_idx = 0;
+
+ // Update the phase and rate estimates for this symbol
+ gr_complex diff = d_diff_filters[d_filtnum]->filter(&in[count]);
+ error_r = out[i].real() * diff.real();
+ error_i = out[i].imag() * diff.imag();
+ d_error = (error_i + error_r) / 2.0; // average error from I&Q channel
+
+ // Run the control loop to update the current phase (k) and
+ // tracking rate estimates based on the error value
+ d_rate_f = d_rate_f + d_beta*d_error;
+ d_k = d_k + d_alpha*d_error;
+
+ // Keep our rate within a good range
+ d_rate_f = gr_branchless_clip(d_rate_f, d_max_dev);
+
+ i+=d_osps;
+ count += (int)floor(d_sps);
+ }
+
+ consume_each(count);
+ return i;
+}
diff --git a/gnuradio-core/src/lib/filter/gr_pfb_clock_sync_ccf.h b/gnuradio-core/src/lib/filter/gr_pfb_clock_sync_ccf.h
new file mode 100644
index 000000000..8715b4b10
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_pfb_clock_sync_ccf.h
@@ -0,0 +1,375 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2009,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+
+#ifndef INCLUDED_GR_PFB_CLOCK_SYNC_CCF_H
+#define INCLUDED_GR_PFB_CLOCK_SYNC_CCF_H
+
+#include <gr_core_api.h>
+#include <gr_block.h>
+
+class gr_pfb_clock_sync_ccf;
+typedef boost::shared_ptr<gr_pfb_clock_sync_ccf> gr_pfb_clock_sync_ccf_sptr;
+GR_CORE_API gr_pfb_clock_sync_ccf_sptr gr_make_pfb_clock_sync_ccf (double sps, float loop_bw,
+ const std::vector<float> &taps,
+ unsigned int filter_size=32,
+ float init_phase=0,
+ float max_rate_deviation=1.5,
+ int osps=1);
+
+class gr_fir_ccf;
+
+/*!
+ * \class gr_pfb_clock_sync_ccf
+ *
+ * \brief Timing synchronizer using polyphase filterbanks
+ *
+ * \ingroup filter_blk
+ * \ingroup pfb_blk
+ *
+ * This block performs timing synchronization for PAM signals by
+ * minimizing the derivative of the filtered signal, which in turn
+ * maximizes the SNR and minimizes ISI.
+ *
+ * This approach works by setting up two filterbanks; one filterbank
+ * contains the signal's pulse shaping matched filter (such as a root
+ * raised cosine filter), where each branch of the filterbank contains
+ * a different phase of the filter. The second filterbank contains
+ * the derivatives of the filters in the first filterbank. Thinking of
+ * this in the time domain, the first filterbank contains filters that
+ * have a sinc shape to them. We want to align the output signal to be
+ * sampled at exactly the peak of the sinc shape. The derivative of
+ * the sinc contains a zero at the maximum point of the sinc (sinc(0)
+ * = 1, sinc(0)' = 0). Furthermore, the region around the zero point
+ * is relatively linear. We make use of this fact to generate the
+ * error signal.
+ *
+ * If the signal out of the derivative filters is d_i[n] for the ith
+ * filter, and the output of the matched filter is x_i[n], we
+ * calculate the error as: e[n] = (Re{x_i[n]} * Re{d_i[n]} +
+ * Im{x_i[n]} * Im{d_i[n]}) / 2.0 This equation averages the error in
+ * the real and imaginary parts. There are two reasons we multiply by
+ * the signal itself. First, if the symbol could be positive or
+ * negative going, but we want the error term to always tell us to go
+ * in the same direction depending on which side of the zero point we
+ * are on. The sign of x_i[n] adjusts the error term to do
+ * this. Second, the magnitude of x_i[n] scales the error term
+ * depending on the symbol's amplitude, so larger signals give us a
+ * stronger error term because we have more confidence in that
+ * symbol's value. Using the magnitude of x_i[n] instead of just the
+ * sign is especially good for signals with low SNR.
+ *
+ * The error signal, e[n], gives us a value proportional to how far
+ * away from the zero point we are in the derivative signal. We want
+ * to drive this value to zero, so we set up a second order loop. We
+ * have two variables for this loop; d_k is the filter number in the
+ * filterbank we are on and d_rate is the rate which we travel through
+ * the filters in the steady state. That is, due to the natural clock
+ * differences between the transmitter and receiver, d_rate represents
+ * that difference and would traverse the filter phase paths to keep
+ * the receiver locked. Thinking of this as a second-order PLL, the
+ * d_rate is the frequency and d_k is the phase. So we update d_rate
+ * and d_k using the standard loop equations based on two error
+ * signals, d_alpha and d_beta. We have these two values set based on
+ * each other for a critically damped system, so in the block
+ * constructor, we just ask for "gain," which is d_alpha while d_beta
+ * is equal to (gain^2)/4.
+ *
+ * The block's parameters are:
+ *
+ * \li \p sps: The clock sync block needs to know the number of samples per
+ * symbol, because it defaults to return a single point representing
+ * the symbol. The sps can be any positive real number and does not
+ * need to be an integer.
+ *
+ * \li \p loop_bw: The loop bandwidth is used to set the gain of the
+ * inner control loop (see:
+ * http://gnuradio.squarespace.com/blog/2011/8/13/control-loop-gain-values.html).
+ * This should be set small (a value of around 2pi/100 is suggested in
+ * that blog post as the step size for the number of radians around
+ * the unit circle to move relative to the error).
+ *
+ * \li \p taps: One of the most important parameters for this block is
+ * the taps of the filter. One of the benefits of this algorithm is
+ * that you can put the matched filter in here as the taps, so you get
+ * both the matched filter and sample timing correction in one go. So
+ * create your normal matched filter. For a typical digital
+ * modulation, this is a root raised cosine filter. The number of taps
+ * of this filter is based on how long you expect the channel to be;
+ * that is, how many symbols do you want to combine to get the current
+ * symbols energy back (there's probably a better way of stating
+ * that). It's usually 5 to 10 or so. That gives you your filter, but
+ * now we need to think about it as a filter with different phase
+ * profiles in each filter. So take this number of taps and multiply
+ * it by the number of filters. This is the number you would use to
+ * create your prototype filter. When you use this in the PFB
+ * filerbank, it segments these taps into the filterbanks in such a
+ * way that each bank now represents the filter at different phases,
+ * equally spaced at 2pi/N, where N is the number of filters.
+ *
+ * \li \p filter_size (default=32): The number of filters can also be
+ * set and defaults to 32. With 32 filters, you get a good enough
+ * resolution in the phase to produce very small, almost unnoticeable,
+ * ISI. Going to 64 filters can reduce this more, but after that
+ * there is very little gained for the extra complexity.
+ *
+ * \li \p init_phase (default=0): The initial phase is another
+ * settable parameter and refers to the filter path the algorithm
+ * initially looks at (i.e., d_k starts at init_phase). This value
+ * defaults to zero, but it might be useful to start at a different
+ * phase offset, such as the mid-point of the filters.
+ *
+ * \li \p max_rate_deviation (default=1.5): The next parameter is the
+ * max_rate_devitation, which defaults to 1.5. This is how far we
+ * allow d_rate to swing, positive or negative, from 0. Constraining
+ * the rate can help keep the algorithm from walking too far away to
+ * lock during times when there is no signal.
+ *
+ * \li \p osps (default=1): The osps is the number of output samples per symbol. By default,
+ * the algorithm produces 1 sample per symbol, sampled at the exact
+ * sample value. This osps value was added to better work with
+ * equalizers, which do a better job of modeling the channel if they
+ * have 2 samps/sym.
+ */
+
+class GR_CORE_API gr_pfb_clock_sync_ccf : public gr_block
+{
+ private:
+ /*!
+ * Build the polyphase filterbank timing synchronizer.
+ * \param sps (double) The number of samples per symbol in the incoming signal
+ * \param loop_bw (float) The bandwidth of the control loop; set's alpha and beta.
+ * \param taps (vector<int>) The filter taps.
+ * \param filter_size (uint) The number of filters in the filterbank (default = 32).
+ * \param init_phase (float) The initial phase to look at, or which filter to start
+ * with (default = 0).
+ * \param max_rate_deviation (float) Distance from 0 d_rate can get (default = 1.5).
+ * \param osps (int) The number of output samples per symbol (default=1).
+ *
+ */
+
+ friend GR_CORE_API gr_pfb_clock_sync_ccf_sptr gr_make_pfb_clock_sync_ccf (double sps, float loop_bw,
+ const std::vector<float> &taps,
+ unsigned int filter_size,
+ float init_phase,
+ float max_rate_deviation,
+ int osps);
+
+ bool d_updated;
+ double d_sps;
+ double d_sample_num;
+ float d_loop_bw;
+ float d_damping;
+ float d_alpha;
+ float d_beta;
+
+ int d_nfilters;
+ int d_taps_per_filter;
+ std::vector<gr_fir_ccf*> d_filters;
+ std::vector<gr_fir_ccf*> d_diff_filters;
+ std::vector< std::vector<float> > d_taps;
+ std::vector< std::vector<float> > d_dtaps;
+
+ float d_k;
+ float d_rate;
+ float d_rate_i;
+ float d_rate_f;
+ float d_max_dev;
+ int d_filtnum;
+ int d_osps;
+ float d_error;
+ int d_out_idx;
+
+ /*!
+ * Build the polyphase filterbank timing synchronizer.
+ */
+ gr_pfb_clock_sync_ccf (double sps, float loop_bw,
+ const std::vector<float> &taps,
+ unsigned int filter_size,
+ float init_phase,
+ float max_rate_deviation,
+ int osps);
+
+ void create_diff_taps(const std::vector<float> &newtaps,
+ std::vector<float> &difftaps);
+
+public:
+ ~gr_pfb_clock_sync_ccf ();
+
+ /*! \brief update the system gains from omega and eta
+ *
+ * This function updates the system gains based on the loop
+ * bandwidth and damping factor of the system.
+ * These two factors can be set separately through their own
+ * set functions.
+ */
+ void update_gains();
+
+ /*!
+ * Resets the filterbank's filter taps with the new prototype filter
+ */
+ void set_taps (const std::vector<float> &taps,
+ std::vector< std::vector<float> > &ourtaps,
+ std::vector<gr_fir_ccf*> &ourfilter);
+
+ /*!
+ * Returns all of the taps of the matched filter
+ */
+ std::vector< std::vector<float> > get_taps();
+
+ /*!
+ * Returns all of the taps of the derivative filter
+ */
+ std::vector< std::vector<float> > get_diff_taps();
+
+ /*!
+ * Returns the taps of the matched filter for a particular channel
+ */
+ std::vector<float> get_channel_taps(int channel);
+
+ /*!
+ * Returns the taps in the derivative filter for a particular channel
+ */
+ std::vector<float> get_diff_channel_taps(int channel);
+
+ /*!
+ * Return the taps as a formatted string for printing
+ */
+ std::string get_taps_as_string();
+
+ /*!
+ * Return the derivative filter taps as a formatted string for printing
+ */
+ std::string get_diff_taps_as_string();
+
+
+ /*******************************************************************
+ SET FUNCTIONS
+ *******************************************************************/
+
+
+ /*!
+ * \brief Set the loop bandwidth
+ *
+ * Set the loop filter's bandwidth to \p bw. This should be between
+ * 2*pi/200 and 2*pi/100 (in rads/samp). It must also be a positive
+ * number.
+ *
+ * When a new damping factor is set, the gains, alpha and beta, of the loop
+ * are recalculated by a call to update_gains().
+ *
+ * \param bw (float) new bandwidth
+ *
+ */
+ void set_loop_bandwidth(float bw);
+
+ /*!
+ * \brief Set the loop damping factor
+ *
+ * Set the loop filter's damping factor to \p df. The damping factor
+ * should be sqrt(2)/2.0 for critically damped systems.
+ * Set it to anything else only if you know what you are doing. It must
+ * be a number between 0 and 1.
+ *
+ * When a new damping factor is set, the gains, alpha and beta, of the loop
+ * are recalculated by a call to update_gains().
+ *
+ * \param df (float) new damping factor
+ *
+ */
+ void set_damping_factor(float df);
+
+ /*!
+ * \brief Set the loop gain alpha
+ *
+ * Set's the loop filter's alpha gain parameter.
+ *
+ * This value should really only be set by adjusting the loop bandwidth
+ * and damping factor.
+ *
+ * \param alpha (float) new alpha gain
+ *
+ */
+ void set_alpha(float alpha);
+
+ /*!
+ * \brief Set the loop gain beta
+ *
+ * Set's the loop filter's beta gain parameter.
+ *
+ * This value should really only be set by adjusting the loop bandwidth
+ * and damping factor.
+ *
+ * \param beta (float) new beta gain
+ *
+ */
+ void set_beta(float beta);
+
+ /*!
+ * Set the maximum deviation from 0 d_rate can have
+ */
+ void set_max_rate_deviation(float m)
+ {
+ d_max_dev = m;
+ }
+
+ /*******************************************************************
+ GET FUNCTIONS
+ *******************************************************************/
+
+ /*!
+ * \brief Returns the loop bandwidth
+ */
+ float get_loop_bandwidth() const;
+
+ /*!
+ * \brief Returns the loop damping factor
+ */
+ float get_damping_factor() const;
+
+ /*!
+ * \brief Returns the loop gain alpha
+ */
+ float get_alpha() const;
+
+ /*!
+ * \brief Returns the loop gain beta
+ */
+ float get_beta() const;
+
+ /*!
+ * \brief Returns the current clock rate
+ */
+ float get_clock_rate() const;
+
+ /*******************************************************************
+ *******************************************************************/
+
+ bool check_topology(int ninputs, int noutputs);
+
+ int general_work (int noutput_items,
+ gr_vector_int &ninput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+#endif
diff --git a/gnuradio-core/src/lib/filter/gr_pfb_clock_sync_ccf.i b/gnuradio-core/src/lib/filter/gr_pfb_clock_sync_ccf.i
new file mode 100644
index 000000000..85915196f
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_pfb_clock_sync_ccf.i
@@ -0,0 +1,67 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2009 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,pfb_clock_sync_ccf);
+
+gr_pfb_clock_sync_ccf_sptr gr_make_pfb_clock_sync_ccf (double sps, float loop_bw,
+ const std::vector<float> &taps,
+ unsigned int filter_size=32,
+ float init_phase=0,
+ float max_rate_deviation=1.5,
+ int osps=1);
+
+class gr_pfb_clock_sync_ccf : public gr_block
+{
+ private:
+ gr_pfb_clock_sync_ccf (double sps, float loop_bw,
+ const std::vector<float> &taps,
+ unsigned int filter_size,
+ float init_phase,
+ float max_rate_deviation,
+ int osps);
+
+ public:
+ ~gr_pfb_clock_sync_ccf ();
+
+ void set_taps (const std::vector<float> &taps,
+ std::vector< std::vector<float> > &ourtaps,
+ std::vector<gr_fir_ccf*> &ourfilter);
+
+ std::vector< std::vector<float> > get_taps();
+ std::vector< std::vector<float> > get_diff_taps();
+ std::vector<float> get_channel_taps(int channel);
+ std::vector<float> get_diff_channel_taps(int channel);
+ std::string get_taps_as_string();
+ std::string get_diff_taps_as_string();
+
+ void set_loop_bandwidth(float bw);
+ void set_damping_factor(float df);
+ void set_alpha(float alpha);
+ void set_beta(float beta);
+ void set_max_rate_deviation(float m);
+
+ float get_loop_bandwidth() const;
+ float get_damping_factor() const;
+ float get_alpha() const;
+ float get_beta() const;
+ float get_clock_rate() const;
+};
diff --git a/gnuradio-core/src/lib/filter/gr_pfb_clock_sync_fff.cc b/gnuradio-core/src/lib/filter/gr_pfb_clock_sync_fff.cc
new file mode 100644
index 000000000..886f98913
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_pfb_clock_sync_fff.cc
@@ -0,0 +1,288 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2009,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <cstdio>
+#include <cmath>
+
+#include <gr_pfb_clock_sync_fff.h>
+#include <gr_fir_fff.h>
+#include <gr_fir_util.h>
+#include <gr_io_signature.h>
+#include <gr_math.h>
+
+gr_pfb_clock_sync_fff_sptr gr_make_pfb_clock_sync_fff (double sps, float gain,
+ const std::vector<float> &taps,
+ unsigned int filter_size,
+ float init_phase,
+ float max_rate_deviation)
+{
+ return gnuradio::get_initial_sptr(new gr_pfb_clock_sync_fff (sps, gain, taps,
+ filter_size,
+ init_phase,
+ max_rate_deviation));
+}
+
+static int ios[] = {sizeof(float), sizeof(float), sizeof(float), sizeof(float)};
+static std::vector<int> iosig(ios, ios+sizeof(ios)/sizeof(int));
+gr_pfb_clock_sync_fff::gr_pfb_clock_sync_fff (double sps, float gain,
+ const std::vector<float> &taps,
+ unsigned int filter_size,
+ float init_phase,
+ float max_rate_deviation)
+ : gr_block ("pfb_clock_sync_fff",
+ gr_make_io_signature (1, 1, sizeof(float)),
+ gr_make_io_signaturev (1, 4, iosig)),
+ d_updated (false), d_nfilters(filter_size),
+ d_max_dev(max_rate_deviation)
+{
+ d_nfilters = filter_size;
+ d_sps = floor(sps);
+
+ // Store the last filter between calls to work
+ // The accumulator keeps track of overflow to increment the stride correctly.
+ // set it here to the fractional difference based on the initial phaes
+ set_alpha(gain);
+ set_beta(0.25*gain*gain);
+ d_k = init_phase;
+ d_rate = (sps-floor(sps))*(double)d_nfilters;
+ d_rate_i = (int)floor(d_rate);
+ d_rate_f = d_rate - (float)d_rate_i;
+ d_filtnum = (int)floor(d_k);
+
+ d_filters = std::vector<gr_fir_fff*>(d_nfilters);
+ d_diff_filters = std::vector<gr_fir_fff*>(d_nfilters);
+
+ // Create an FIR filter for each channel and zero out the taps
+ std::vector<float> vtaps(0, d_nfilters);
+ for(int i = 0; i < d_nfilters; i++) {
+ d_filters[i] = gr_fir_util::create_gr_fir_fff(vtaps);
+ d_diff_filters[i] = gr_fir_util::create_gr_fir_fff(vtaps);
+ }
+
+ // Now, actually set the filters' taps
+ std::vector<float> dtaps;
+ create_diff_taps(taps, dtaps);
+ set_taps(taps, d_taps, d_filters);
+ set_taps(dtaps, d_dtaps, d_diff_filters);
+}
+
+gr_pfb_clock_sync_fff::~gr_pfb_clock_sync_fff ()
+{
+ for(int i = 0; i < d_nfilters; i++) {
+ delete d_filters[i];
+ delete d_diff_filters[i];
+ }
+}
+
+bool
+gr_pfb_clock_sync_fff::check_topology(int ninputs, int noutputs)
+{
+ return noutputs == 1 || noutputs == 4;
+}
+
+void
+gr_pfb_clock_sync_fff::set_taps (const std::vector<float> &newtaps,
+ std::vector< std::vector<float> > &ourtaps,
+ std::vector<gr_fir_fff*> &ourfilter)
+{
+ int i,j;
+
+ unsigned int ntaps = newtaps.size();
+ d_taps_per_filter = (unsigned int)ceil((double)ntaps/(double)d_nfilters);
+
+ // Create d_numchan vectors to store each channel's taps
+ ourtaps.resize(d_nfilters);
+
+ // Make a vector of the taps plus fill it out with 0's to fill
+ // each polyphase filter with exactly d_taps_per_filter
+ std::vector<float> tmp_taps;
+ tmp_taps = newtaps;
+ while((float)(tmp_taps.size()) < d_nfilters*d_taps_per_filter) {
+ tmp_taps.push_back(0.0);
+ }
+
+ // Partition the filter
+ for(i = 0; i < d_nfilters; i++) {
+ // Each channel uses all d_taps_per_filter with 0's if not enough taps to fill out
+ ourtaps[d_nfilters-1-i] = std::vector<float>(d_taps_per_filter, 0);
+ for(j = 0; j < d_taps_per_filter; j++) {
+ ourtaps[d_nfilters - 1 - i][j] = tmp_taps[i + j*d_nfilters];
+ }
+
+ // Build a filter for each channel and add it's taps to it
+ ourfilter[i]->set_taps(ourtaps[d_nfilters-1-i]);
+ }
+
+ // Set the history to ensure enough input items for each filter
+ set_history (d_taps_per_filter + d_sps);
+
+ d_updated = true;
+}
+
+void
+gr_pfb_clock_sync_fff::create_diff_taps(const std::vector<float> &newtaps,
+ std::vector<float> &difftaps)
+{
+ float maxtap = 1e-20;
+ difftaps.clear();
+ difftaps.push_back(0); //newtaps[0]);
+ for(unsigned int i = 1; i < newtaps.size()-1; i++) {
+ float tap = newtaps[i+1] - newtaps[i-1];
+ difftaps.push_back(tap);
+ if(tap > maxtap) {
+ maxtap = tap;
+ }
+ }
+ difftaps.push_back(0);//-newtaps[newtaps.size()-1]);
+
+ // Scale the differential taps; helps scale error term to better update state
+ // FIXME: should this be scaled this way or use the same gain as the taps?
+ for(unsigned int i = 0; i < difftaps.size(); i++) {
+ difftaps[i] /= maxtap;
+ }
+}
+
+void
+gr_pfb_clock_sync_fff::print_taps()
+{
+ int i, j;
+ printf("[ ");
+ for(i = 0; i < d_nfilters; i++) {
+ printf("[%.4e, ", d_taps[i][0]);
+ for(j = 1; j < d_taps_per_filter-1; j++) {
+ printf("%.4e,", d_taps[i][j]);
+ }
+ printf("%.4e],", d_taps[i][j]);
+ }
+ printf(" ]\n");
+}
+
+void
+gr_pfb_clock_sync_fff::print_diff_taps()
+{
+ int i, j;
+ printf("[ ");
+ for(i = 0; i < d_nfilters; i++) {
+ printf("[%.4e, ", d_dtaps[i][0]);
+ for(j = 1; j < d_taps_per_filter-1; j++) {
+ printf("%.4e,", d_dtaps[i][j]);
+ }
+ printf("%.4e],", d_dtaps[i][j]);
+ }
+ printf(" ]\n");
+}
+
+
+std::vector<float>
+gr_pfb_clock_sync_fff::channel_taps(int channel)
+{
+ std::vector<float> taps;
+ for(int i = 0; i < d_taps_per_filter; i++) {
+ taps.push_back(d_taps[channel][i]);
+ }
+ return taps;
+}
+
+std::vector<float>
+gr_pfb_clock_sync_fff::diff_channel_taps(int channel)
+{
+ std::vector<float> taps;
+ for(int i = 0; i < d_taps_per_filter; i++) {
+ taps.push_back(d_dtaps[channel][i]);
+ }
+ return taps;
+}
+
+
+int
+gr_pfb_clock_sync_fff::general_work (int noutput_items,
+ gr_vector_int &ninput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ float *in = (float *) input_items[0];
+ float *out = (float *) output_items[0];
+
+ float *err = 0, *outrate = 0, *outk = 0;
+ if(output_items.size() == 4) {
+ err = (float *) output_items[1];
+ outrate = (float*)output_items[2];
+ outk = (float*)output_items[3];
+ }
+
+ if (d_updated) {
+ d_updated = false;
+ return 0; // history requirements may have changed.
+ }
+
+ // We need this many to process one output
+ int nrequired = ninput_items[0] - d_taps_per_filter;
+
+ int i = 0, count = 0;
+ float error;
+
+ // produce output as long as we can and there are enough input samples
+ while((i < noutput_items) && (count < nrequired)) {
+ d_filtnum = (int)floor(d_k);
+
+ // Keep the current filter number in [0, d_nfilters]
+ // If we've run beyond the last filter, wrap around and go to next sample
+ // If we've go below 0, wrap around and go to previous sample
+ while(d_filtnum >= d_nfilters) {
+ d_k -= d_nfilters;
+ d_filtnum -= d_nfilters;
+ count += 1;
+ }
+ while(d_filtnum < 0) {
+ d_k += d_nfilters;
+ d_filtnum += d_nfilters;
+ count -= 1;
+ }
+
+ out[i] = d_filters[d_filtnum]->filter(&in[count]);
+ float diff = d_diff_filters[d_filtnum]->filter(&in[count]);
+ error = out[i] * diff;
+
+ // Run the control loop to update the current phase (k) and tracking rate
+ d_k = d_k + d_alpha*error + d_rate_i + d_rate_f;
+ d_rate_f = d_rate_f + d_beta*error;
+
+ // Keep our rate within a good range
+ d_rate_f = gr_branchless_clip(d_rate_f, d_max_dev);
+
+ i++;
+ count += (int)floor(d_sps);
+
+ if(output_items.size() == 4) {
+ err[i] = error;
+ outrate[i] = d_rate_f;
+ outk[i] = d_k;
+ }
+ }
+ consume_each(count);
+
+ return i;
+}
diff --git a/gnuradio-core/src/lib/filter/gr_pfb_clock_sync_fff.h b/gnuradio-core/src/lib/filter/gr_pfb_clock_sync_fff.h
new file mode 100644
index 000000000..4909d556b
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_pfb_clock_sync_fff.h
@@ -0,0 +1,266 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2009,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+
+#ifndef INCLUDED_GR_PFB_CLOCK_SYNC_FFF_H
+#define INCLUDED_GR_PFB_CLOCK_SYNC_FFF_H
+
+#include <gr_core_api.h>
+#include <gr_block.h>
+
+class gr_pfb_clock_sync_fff;
+typedef boost::shared_ptr<gr_pfb_clock_sync_fff> gr_pfb_clock_sync_fff_sptr;
+GR_CORE_API gr_pfb_clock_sync_fff_sptr gr_make_pfb_clock_sync_fff (double sps, float gain,
+ const std::vector<float> &taps,
+ unsigned int filter_size=32,
+ float init_phase=0,
+ float max_rate_deviation=1.5);
+
+class gr_fir_fff;
+
+/*!
+ * \class gr_pfb_clock_sync_fff
+ *
+ * \brief Timing synchronizer using polyphase filterbanks
+ *
+ * \ingroup filter_blk
+ * \ingroup pfb_blk
+ *
+ * This block performs timing synchronization for PAM signals by
+ * minimizing the derivative of the filtered signal, which in turn
+ * maximizes the SNR and minimizes ISI.
+ *
+ * This approach works by setting up two filterbanks; one filterbank
+ * contains the signal's pulse shaping matched filter (such as a root
+ * raised cosine filter), where each branch of the filterbank contains
+ * a different phase of the filter. The second filterbank contains
+ * the derivatives of the filters in the first filterbank. Thinking of
+ * this in the time domain, the first filterbank contains filters that
+ * have a sinc shape to them. We want to align the output signal to be
+ * sampled at exactly the peak of the sinc shape. The derivative of
+ * the sinc contains a zero at the maximum point of the sinc (sinc(0)
+ * = 1, sinc(0)' = 0). Furthermore, the region around the zero point
+ * is relatively linear. We make use of this fact to generate the
+ * error signal.
+ *
+ * If the signal out of the derivative filters is d_i[n] for the ith
+ * filter, and the output of the matched filter is x_i[n], we
+ * calculate the error as: e[n] = (Re{x_i[n]} * Re{d_i[n]} +
+ * Im{x_i[n]} * Im{d_i[n]}) / 2.0 This equation averages the error in
+ * the real and imaginary parts. There are two reasons we multiply by
+ * the signal itself. First, if the symbol could be positive or
+ * negative going, but we want the error term to always tell us to go
+ * in the same direction depending on which side of the zero point we
+ * are on. The sign of x_i[n] adjusts the error term to do
+ * this. Second, the magnitude of x_i[n] scales the error term
+ * depending on the symbol's amplitude, so larger signals give us a
+ * stronger error term because we have more confidence in that
+ * symbol's value. Using the magnitude of x_i[n] instead of just the
+ * sign is especially good for signals with low SNR.
+ *
+ * The error signal, e[n], gives us a value proportional to how far
+ * away from the zero point we are in the derivative signal. We want
+ * to drive this value to zero, so we set up a second order loop. We
+ * have two variables for this loop; d_k is the filter number in the
+ * filterbank we are on and d_rate is the rate which we travel through
+ * the filters in the steady state. That is, due to the natural clock
+ * differences between the transmitter and receiver, d_rate represents
+ * that difference and would traverse the filter phase paths to keep
+ * the receiver locked. Thinking of this as a second-order PLL, the
+ * d_rate is the frequency and d_k is the phase. So we update d_rate
+ * and d_k using the standard loop equations based on two error
+ * signals, d_alpha and d_beta. We have these two values set based on
+ * each other for a critically damped system, so in the block
+ * constructor, we just ask for "gain," which is d_alpha while d_beta
+ * is equal to (gain^2)/4.
+ *
+ * The block's parameters are:
+ *
+ * \li \p sps: The clock sync block needs to know the number of samples per
+ * symbol, because it defaults to return a single point representing
+ * the symbol. The sps can be any positive real number and does not
+ * need to be an integer.
+ *
+ * \li \p loop_bw: The loop bandwidth is used to set the gain of the
+ * inner control loop (see:
+ * http://gnuradio.squarespace.com/blog/2011/8/13/control-loop-gain-values.html).
+ * This should be set small (a value of around 2pi/100 is suggested in
+ * that blog post as the step size for the number of radians around
+ * the unit circle to move relative to the error).
+ *
+ * \li \p taps: One of the most important parameters for this block is
+ * the taps of the filter. One of the benefits of this algorithm is
+ * that you can put the matched filter in here as the taps, so you get
+ * both the matched filter and sample timing correction in one go. So
+ * create your normal matched filter. For a typical digital
+ * modulation, this is a root raised cosine filter. The number of taps
+ * of this filter is based on how long you expect the channel to be;
+ * that is, how many symbols do you want to combine to get the current
+ * symbols energy back (there's probably a better way of stating
+ * that). It's usually 5 to 10 or so. That gives you your filter, but
+ * now we need to think about it as a filter with different phase
+ * profiles in each filter. So take this number of taps and multiply
+ * it by the number of filters. This is the number you would use to
+ * create your prototype filter. When you use this in the PFB
+ * filerbank, it segments these taps into the filterbanks in such a
+ * way that each bank now represents the filter at different phases,
+ * equally spaced at 2pi/N, where N is the number of filters.
+ *
+ * \li \p filter_size (default=32): The number of filters can also be
+ * set and defaults to 32. With 32 filters, you get a good enough
+ * resolution in the phase to produce very small, almost unnoticeable,
+ * ISI. Going to 64 filters can reduce this more, but after that
+ * there is very little gained for the extra complexity.
+ *
+ * \li \p init_phase (default=0): The initial phase is another
+ * settable parameter and refers to the filter path the algorithm
+ * initially looks at (i.e., d_k starts at init_phase). This value
+ * defaults to zero, but it might be useful to start at a different
+ * phase offset, such as the mid-point of the filters.
+ *
+ * \li \p max_rate_deviation (default=1.5): The next parameter is the
+ * max_rate_devitation, which defaults to 1.5. This is how far we
+ * allow d_rate to swing, positive or negative, from 0. Constraining
+ * the rate can help keep the algorithm from walking too far away to
+ * lock during times when there is no signal.
+ *
+ * \li \p osps: note that unlike the ccf version of this algorithm,
+ * this block does \a not have a setting for the number of output
+ * samples per symbol. This is mostly because it should not be
+ * necessary as the reason for having multiple output sps is to
+ * perform equalization and the equalizers will take in complex
+ * numbers in order to do magnitude and phase correction.
+ */
+
+class GR_CORE_API gr_pfb_clock_sync_fff : public gr_block
+{
+ private:
+ /*!
+ * Build the polyphase filterbank timing synchronizer.
+ * \param sps (double) The number of samples per second in the incoming signal
+ * \param gain (float) The alpha gain of the control loop; beta = (gain^2)/4 by default.
+ * \param taps (vector<int>) The filter taps.
+ * \param filter_size (uint) The number of filters in the filterbank (default = 32).
+ * \param init_phase (float) The initial phase to look at, or which filter to start
+ * with (default = 0).
+ * \param max_rate_deviation (float) Distance from 0 d_rate can get (default = 1.5).
+ *
+ */
+ friend GR_CORE_API gr_pfb_clock_sync_fff_sptr gr_make_pfb_clock_sync_fff (double sps, float gain,
+ const std::vector<float> &taps,
+ unsigned int filter_size,
+ float init_phase,
+ float max_rate_deviation);
+
+ bool d_updated;
+ double d_sps;
+ double d_sample_num;
+ float d_alpha;
+ float d_beta;
+ int d_nfilters;
+ std::vector<gr_fir_fff*> d_filters;
+ std::vector<gr_fir_fff*> d_diff_filters;
+ std::vector< std::vector<float> > d_taps;
+ std::vector< std::vector<float> > d_dtaps;
+ float d_k;
+ float d_rate;
+ float d_rate_i;
+ float d_rate_f;
+ float d_max_dev;
+ int d_filtnum;
+ int d_taps_per_filter;
+
+ /*!
+ * Build the polyphase filterbank timing synchronizer.
+ */
+ gr_pfb_clock_sync_fff (double sps, float gain,
+ const std::vector<float> &taps,
+ unsigned int filter_size,
+ float init_phase,
+ float max_rate_deviation);
+
+ void create_diff_taps(const std::vector<float> &newtaps,
+ std::vector<float> &difftaps);
+
+public:
+ ~gr_pfb_clock_sync_fff ();
+
+ /*!
+ * Resets the filterbank's filter taps with the new prototype filter
+ */
+ void set_taps (const std::vector<float> &taps,
+ std::vector< std::vector<float> > &ourtaps,
+ std::vector<gr_fir_fff*> &ourfilter);
+
+ /*!
+ * Returns the taps of the matched filter
+ */
+ std::vector<float> channel_taps(int channel);
+
+ /*!
+ * Returns the taps in the derivative filter
+ */
+ std::vector<float> diff_channel_taps(int channel);
+
+ /*!
+ * Print all of the filterbank taps to screen.
+ */
+ void print_taps();
+
+ /*!
+ * Print all of the filterbank taps of the derivative filter to screen.
+ */
+ void print_diff_taps();
+
+ /*!
+ * Set the gain value alpha for the control loop
+ */
+ void set_alpha(float alpha)
+ {
+ d_alpha = alpha;
+ }
+
+ /*!
+ * Set the gain value beta for the control loop
+ */
+ void set_beta(float beta)
+ {
+ d_beta = beta;
+ }
+
+ /*!
+ * Set the maximum deviation from 0 d_rate can have
+ */
+ void set_max_rate_deviation(float m)
+ {
+ d_max_dev = m;
+ }
+
+ bool check_topology(int ninputs, int noutputs);
+
+ int general_work (int noutput_items,
+ gr_vector_int &ninput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+#endif
diff --git a/gnuradio-core/src/lib/filter/gr_pfb_clock_sync_fff.i b/gnuradio-core/src/lib/filter/gr_pfb_clock_sync_fff.i
new file mode 100644
index 000000000..754af1a87
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_pfb_clock_sync_fff.i
@@ -0,0 +1,54 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2009 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,pfb_clock_sync_fff);
+
+gr_pfb_clock_sync_fff_sptr gr_make_pfb_clock_sync_fff (double sps, float gain,
+ const std::vector<float> &taps,
+ unsigned int filter_size=32,
+ float init_phase=0,
+ float max_rate_deviation=1.5);
+
+class gr_pfb_clock_sync_fff : public gr_block
+{
+ private:
+ gr_pfb_clock_sync_fff (double sps, float gain,
+ const std::vector<float> &taps,
+ unsigned int filter_size,
+ float init_phase,
+ float max_rate_deviation);
+
+ public:
+ ~gr_pfb_clock_sync_fff ();
+
+ void set_taps (const std::vector<float> &taps,
+ std::vector< std::vector<float> > &ourtaps,
+ std::vector<gr_fir_fff*> &ourfilter);
+
+ std::vector<float> channel_taps(int channel);
+ std::vector<float> diff_channel_taps(int channel);
+ void print_taps();
+ void print_diff_taps();
+ void set_alpha(float alpha);
+ void set_beta(float beta);
+ void set_max_rate_deviation(float m);
+};
diff --git a/gnuradio-core/src/lib/filter/gr_pfb_decimator_ccf.cc b/gnuradio-core/src/lib/filter/gr_pfb_decimator_ccf.cc
new file mode 100644
index 000000000..e563daa51
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_pfb_decimator_ccf.cc
@@ -0,0 +1,176 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2009,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_pfb_decimator_ccf.h>
+#include <gr_fir_ccf.h>
+#include <gr_fir_util.h>
+#include <gri_fft.h>
+#include <gr_io_signature.h>
+#include <gr_expj.h>
+#include <cstdio>
+
+gr_pfb_decimator_ccf_sptr gr_make_pfb_decimator_ccf (unsigned int decim,
+ const std::vector<float> &taps,
+ unsigned int channel)
+{
+ return gnuradio::get_initial_sptr(new gr_pfb_decimator_ccf (decim, taps, channel));
+}
+
+
+gr_pfb_decimator_ccf::gr_pfb_decimator_ccf (unsigned int decim,
+ const std::vector<float> &taps,
+ unsigned int channel)
+ : gr_sync_block ("pfb_decimator_ccf",
+ gr_make_io_signature (decim, decim, sizeof(gr_complex)),
+ gr_make_io_signature (1, 1, sizeof(gr_complex))),
+ d_updated (false)
+{
+ d_rate = decim;
+ d_filters = std::vector<gr_fir_ccf*>(d_rate);
+ d_chan = channel;
+ d_rotator = new gr_complex[d_rate];
+
+ // Create an FIR filter for each channel and zero out the taps
+ std::vector<float> vtaps(0, d_rate);
+ for(unsigned int i = 0; i < d_rate; i++) {
+ d_filters[i] = gr_fir_util::create_gr_fir_ccf(vtaps);
+ d_rotator[i] = gr_expj(i*2*M_PI*d_chan/d_rate);
+ }
+
+ // Now, actually set the filters' taps
+ set_taps(taps);
+
+ // Create the FFT to handle the output de-spinning of the channels
+ d_fft = new gri_fft_complex (d_rate, false);
+}
+
+gr_pfb_decimator_ccf::~gr_pfb_decimator_ccf ()
+{
+ delete d_fft;
+ for(unsigned int i = 0; i < d_rate; i++) {
+ delete d_filters[i];
+ }
+}
+
+void
+gr_pfb_decimator_ccf::set_taps (const std::vector<float> &taps)
+{
+ unsigned int i,j;
+
+ unsigned int ntaps = taps.size();
+ d_taps_per_filter = (unsigned int)ceil((double)ntaps/(double)d_rate);
+
+ // Create d_numchan vectors to store each channel's taps
+ d_taps.resize(d_rate);
+
+ // Make a vector of the taps plus fill it out with 0's to fill
+ // each polyphase filter with exactly d_taps_per_filter
+ std::vector<float> tmp_taps;
+ tmp_taps = taps;
+ while((float)(tmp_taps.size()) < d_rate*d_taps_per_filter) {
+ tmp_taps.push_back(0.0);
+ }
+
+ // Partition the filter
+ for(i = 0; i < d_rate; i++) {
+ // Each channel uses all d_taps_per_filter with 0's if not enough taps to fill out
+ d_taps[i] = std::vector<float>(d_taps_per_filter, 0);
+ for(j = 0; j < d_taps_per_filter; j++) {
+ d_taps[i][j] = tmp_taps[i + j*d_rate]; // add taps to channels in reverse order
+ }
+
+ // Build a filter for each channel and add it's taps to it
+ d_filters[i]->set_taps(d_taps[i]);
+ }
+
+ // Set the history to ensure enough input items for each filter
+ set_history (d_taps_per_filter);
+
+ d_updated = true;
+}
+
+void
+gr_pfb_decimator_ccf::print_taps()
+{
+ unsigned int i, j;
+ for(i = 0; i < d_rate; i++) {
+ printf("filter[%d]: [", i);
+ for(j = 0; j < d_taps_per_filter; j++) {
+ printf(" %.4e", d_taps[i][j]);
+ }
+ printf("]\n\n");
+ }
+}
+
+#define ROTATEFFT
+
+int
+gr_pfb_decimator_ccf::work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ gr_complex *in;
+ gr_complex *out = (gr_complex *) output_items[0];
+
+ if (d_updated) {
+ d_updated = false;
+ return 0; // history requirements may have changed.
+ }
+
+ int i;
+ for(i = 0; i < noutput_items; i++) {
+ // Move through filters from bottom to top
+ out[i] = 0;
+ for(int j = d_rate-1; j >= 0; j--) {
+ // Take in the items from the first input stream to d_rate
+ in = (gr_complex*)input_items[d_rate - 1 - j];
+
+ // Filter current input stream from bottom filter to top
+ // The rotate them by expj(j*k*2pi/M) where M is the number of filters
+ // (the decimation rate) and k is the channel number to extract
+
+ // This is the real math that goes on; we abuse the FFT to do this quickly
+ // for decimation rates > N where N is a small number (~5):
+ // out[i] += d_filters[j]->filter(&in[i])*gr_expj(j*d_chan*2*M_PI/d_rate);
+#ifdef ROTATEFFT
+ d_fft->get_inbuf()[j] = d_filters[j]->filter(&in[i]);
+#else
+ out[i] += d_filters[j]->filter(&in[i])*d_rotator[i];
+#endif
+ }
+
+#ifdef ROTATEFFT
+ // Perform the FFT to do the complex multiply despinning for all channels
+ d_fft->execute();
+
+ // Select only the desired channel out
+ out[i] = d_fft->get_outbuf()[d_chan];
+#endif
+
+ }
+
+ return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/filter/gr_pfb_decimator_ccf.h b/gnuradio-core/src/lib/filter/gr_pfb_decimator_ccf.h
new file mode 100644
index 000000000..a2b347ae2
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_pfb_decimator_ccf.h
@@ -0,0 +1,150 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2009 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+
+#ifndef INCLUDED_GR_PFB_DECIMATOR_CCF_H
+#define INCLUDED_GR_PFB_DECIMATOR_CCF_H
+
+#include <gr_core_api.h>
+#include <gr_sync_block.h>
+
+class gr_pfb_decimator_ccf;
+typedef boost::shared_ptr<gr_pfb_decimator_ccf> gr_pfb_decimator_ccf_sptr;
+GR_CORE_API gr_pfb_decimator_ccf_sptr gr_make_pfb_decimator_ccf (unsigned int decim,
+ const std::vector<float> &taps,
+ unsigned int channel=0);
+
+class gr_fir_ccf;
+class gri_fft_complex;
+
+/*!
+ * \class gr_pfb_decimator_ccf
+ * \brief Polyphase filterbank bandpass decimator with gr_complex
+ * input, gr_complex output and float taps
+ *
+ * \ingroup filter_blk
+ * \ingroup pfb_blk
+ *
+ * This block takes in a signal stream and performs interger down-
+ * sampling (decimation) with a polyphase filterbank. The first input
+ * is the integer specifying how much to decimate by. The second
+ * input is a vector (Python list) of floating-point taps of the
+ * prototype filter. The third input specifies the channel to extract.
+ * By default, the zeroth channel is used, which is the baseband
+ * channel (first Nyquist zone).
+ *
+ * The <EM>channel</EM> parameter specifies which channel to use since
+ * this class is capable of bandpass decimation. Given a complex input
+ * stream at a sampling rate of <EM>fs</EM> and a decimation rate of
+ * <EM>decim</EM>, the input frequency domain is split into
+ * <EM>decim</EM> channels that represent the Nyquist zones. Using the
+ * polyphase filterbank, we can select any one of these channels to
+ * decimate.
+ *
+ * The output signal will be the basebanded and decimated signal from
+ * that channel. This concept is very similar to the PFB channelizer
+ * (see #gr_pfb_channelizer_ccf) where only a single channel is
+ * extracted at a time.
+ *
+ * The filter's taps should be based on the sampling rate before
+ * decimation.
+ *
+ * For example, using the GNU Radio's firdes utility to building
+ * filters, we build a low-pass filter with a sampling rate of
+ * <EM>fs</EM>, a 3-dB bandwidth of <EM>BW</EM> and a transition
+ * bandwidth of <EM>TB</EM>. We can also specify the out-of-band
+ * attenuation to use, <EM>ATT</EM>, and the filter window
+ * function (a Blackman-harris window in this case). The first input
+ * is the gain of the filter, which we specify here as unity.
+ *
+ * <B><EM>self._taps = gr.firdes.low_pass_2(1, fs, BW, TB,
+ * attenuation_dB=ATT, window=gr.firdes.WIN_BLACKMAN_hARRIS)</EM></B>
+ *
+ * The PFB decimator code takes the taps generated above and builds a
+ * set of filters. The set contains <EM>decim</EM> number of filters
+ * and each filter contains ceil(taps.size()/decim) number of taps.
+ * Each tap from the filter prototype is sequentially inserted into
+ * the next filter. When all of the input taps are used, the remaining
+ * filters in the filterbank are filled out with 0's to make sure each
+ * filter has the same number of taps.
+ *
+ * The theory behind this block can be found in Chapter 6 of
+ * the following book.
+ *
+ * <B><EM>f. harris, "Multirate Signal Processing for Communication
+ * Systems," Upper Saddle River, NJ: Prentice Hall, Inc. 2004.</EM></B>
+ */
+
+class GR_CORE_API gr_pfb_decimator_ccf : public gr_sync_block
+{
+ private:
+ /*!
+ * Build the polyphase filterbank decimator.
+ * \param decim (unsigned integer) Specifies the decimation rate to use
+ * \param taps (vector/list of floats) The prototype filter to populate the filterbank.
+ * \param channel (unsigned integer) Selects the channel to return [default=0].
+ */
+ friend GR_CORE_API gr_pfb_decimator_ccf_sptr gr_make_pfb_decimator_ccf (unsigned int decim,
+ const std::vector<float> &taps,
+ unsigned int channel);
+
+ std::vector<gr_fir_ccf*> d_filters;
+ std::vector< std::vector<float> > d_taps;
+ gri_fft_complex *d_fft;
+ unsigned int d_rate;
+ unsigned int d_chan;
+ unsigned int d_taps_per_filter;
+ bool d_updated;
+ gr_complex *d_rotator;
+
+ /*!
+ * Build the polyphase filterbank decimator.
+ * \param decim (unsigned integer) Specifies the decimation rate to use
+ * \param taps (vector/list of floats) The prototype filter to populate the filterbank.
+ * \param channel (unsigned integer) Selects the channel to return [default=0].
+ */
+ gr_pfb_decimator_ccf (unsigned int decim,
+ const std::vector<float> &taps,
+ unsigned int channel);
+
+public:
+ ~gr_pfb_decimator_ccf ();
+
+ /*!
+ * Resets the filterbank's filter taps with the new prototype filter
+ * \param taps (vector/list of floats) The prototype filter to populate the filterbank.
+ */
+ void set_taps (const std::vector<float> &taps);
+
+ /*!
+ * Print all of the filterbank taps to screen.
+ */
+ void print_taps();
+
+ //void set_channel (unsigned int channel);
+
+ int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+#endif
diff --git a/gnuradio-core/src/lib/filter/gr_pfb_decimator_ccf.i b/gnuradio-core/src/lib/filter/gr_pfb_decimator_ccf.i
new file mode 100644
index 000000000..e40d00fa9
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_pfb_decimator_ccf.i
@@ -0,0 +1,41 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2009 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,pfb_decimator_ccf);
+
+gr_pfb_decimator_ccf_sptr gr_make_pfb_decimator_ccf (unsigned int decim,
+ const std::vector<float> &taps,
+ unsigned int channel);
+
+class gr_pfb_decimator_ccf : public gr_sync_block
+{
+ private:
+ gr_pfb_decimator_ccf (unsigned int decim,
+ const std::vector<float> &taps,
+ unsigned int channel);
+
+ public:
+ ~gr_pfb_decimator_ccf ();
+
+ void set_taps (const std::vector<float> &taps);
+ //void set_channel (unsigned int channel);
+};
diff --git a/gnuradio-core/src/lib/filter/gr_pfb_interpolator_ccf.cc b/gnuradio-core/src/lib/filter/gr_pfb_interpolator_ccf.cc
new file mode 100644
index 000000000..9c8e734ea
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_pfb_interpolator_ccf.cc
@@ -0,0 +1,143 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2009,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_pfb_interpolator_ccf.h>
+#include <gr_fir_ccf.h>
+#include <gr_fir_util.h>
+#include <gr_io_signature.h>
+#include <cstdio>
+
+gr_pfb_interpolator_ccf_sptr gr_make_pfb_interpolator_ccf (unsigned int interp,
+ const std::vector<float> &taps)
+{
+ return gnuradio::get_initial_sptr(new gr_pfb_interpolator_ccf (interp, taps));
+}
+
+
+gr_pfb_interpolator_ccf::gr_pfb_interpolator_ccf (unsigned int interp,
+ const std::vector<float> &taps)
+ : gr_sync_interpolator ("pfb_interpolator_ccf",
+ gr_make_io_signature (1, 1, sizeof(gr_complex)),
+ gr_make_io_signature (1, 1, sizeof(gr_complex)),
+ interp),
+ d_updated (false)
+{
+ d_rate = interp;
+ d_filters = std::vector<gr_fir_ccf*>(d_rate);
+
+ // Create an FIR filter for each channel and zero out the taps
+ std::vector<float> vtaps(0, d_rate);
+ for(unsigned int i = 0; i < d_rate; i++) {
+ d_filters[i] = gr_fir_util::create_gr_fir_ccf(vtaps);
+ }
+
+ // Now, actually set the filters' taps
+ set_taps(taps);
+}
+
+gr_pfb_interpolator_ccf::~gr_pfb_interpolator_ccf ()
+{
+ for(unsigned int i = 0; i < d_rate; i++) {
+ delete d_filters[i];
+ }
+}
+
+void
+gr_pfb_interpolator_ccf::set_taps (const std::vector<float> &taps)
+{
+ unsigned int i,j;
+
+ unsigned int ntaps = taps.size();
+ d_taps_per_filter = (unsigned int)ceil((double)ntaps/(double)d_rate);
+
+ // Create d_numchan vectors to store each channel's taps
+ //std::vector< std::vector<float> > vtaps(d_rate);
+ d_taps.resize(d_rate);
+
+ // Make a vector of the taps plus fill it out with 0's to fill
+ // each polyphase filter with exactly d_taps_per_filter
+ std::vector<float> tmp_taps;
+ tmp_taps = taps;
+ while((float)(tmp_taps.size()) < d_rate*d_taps_per_filter) {
+ tmp_taps.push_back(0.0);
+ }
+
+ // Partition the filter
+ for(i = 0; i < d_rate; i++) {
+ // Each channel uses all d_taps_per_filter with 0's if not enough taps to fill out
+ d_taps[i] = std::vector<float>(d_taps_per_filter, 0);
+ for(j = 0; j < d_taps_per_filter; j++) {
+ d_taps[i][j] = tmp_taps[i + j*d_rate]; // add taps to channels in reverse order
+ }
+
+ // Build a filter for each channel and add it's taps to it
+ d_filters[i]->set_taps(d_taps[i]);
+ }
+
+ // Set the history to ensure enough input items for each filter
+ set_history (d_taps_per_filter);
+
+ d_updated = true;
+}
+
+void
+gr_pfb_interpolator_ccf::print_taps()
+{
+ unsigned int i, j;
+ for(i = 0; i < d_rate; i++) {
+ printf("filter[%d]: [", i);
+ for(j = 0; j < d_taps_per_filter; j++) {
+ printf(" %.4e", d_taps[i][j]);
+ }
+ printf("]\n\n");
+ }
+}
+
+int
+gr_pfb_interpolator_ccf::work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ gr_complex *in = (gr_complex *) input_items[0];
+ gr_complex *out = (gr_complex *) output_items[0];
+
+ if (d_updated) {
+ d_updated = false;
+ return 0; // history requirements may have changed.
+ }
+
+ int i = 0, count = 0;
+
+ while(i < noutput_items) {
+ for(unsigned int j = 0; j < d_rate; j++) {
+ out[i] = d_filters[j]->filter(&in[count]);
+ i++;
+ }
+ count++;
+ }
+
+ return i;
+}
diff --git a/gnuradio-core/src/lib/filter/gr_pfb_interpolator_ccf.h b/gnuradio-core/src/lib/filter/gr_pfb_interpolator_ccf.h
new file mode 100644
index 000000000..aeae86e40
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_pfb_interpolator_ccf.h
@@ -0,0 +1,131 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2009 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+
+#ifndef INCLUDED_GR_PFB_INTERPOLATOR_CCF_H
+#define INCLUDED_GR_PFB_INTERPOLATOR_CCF_H
+
+#include <gr_core_api.h>
+#include <gr_sync_interpolator.h>
+
+class gr_pfb_interpolator_ccf;
+typedef boost::shared_ptr<gr_pfb_interpolator_ccf> gr_pfb_interpolator_ccf_sptr;
+GR_CORE_API gr_pfb_interpolator_ccf_sptr gr_make_pfb_interpolator_ccf (unsigned int interp,
+ const std::vector<float> &taps);
+
+class gr_fir_ccf;
+
+/*!
+ * \class gr_pfb_interpolator_ccf
+ * \brief Polyphase filterbank interpolator with gr_complex input,
+ * gr_complex output and float taps
+ *
+ * \ingroup filter_blk
+ * \ingroup pfb_blk
+ *
+ * This block takes in a signal stream and performs interger up-
+ * sampling (interpolation) with a polyphase filterbank. The first
+ * input is the integer specifying how much to interpolate by. The
+ * second input is a vector (Python list) of floating-point taps of
+ * the prototype filter.
+ *
+ * The filter's taps should be based on the interpolation rate
+ * specified. That is, the bandwidth specified is relative to the
+ * bandwidth after interpolation.
+ *
+ * For example, using the GNU Radio's firdes utility to building
+ * filters, we build a low-pass filter with a sampling rate of
+ * <EM>fs</EM>, a 3-dB bandwidth of <EM>BW</EM> and a transition
+ * bandwidth of <EM>TB</EM>. We can also specify the out-of-band
+ * attenuation to use, ATT, and the filter window function (a
+ * Blackman-harris window in this case). The first input is the gain,
+ * which is also specified as the interpolation rate so that the
+ * output levels are the same as the input (this creates an overall
+ * increase in power).
+ *
+ * <B><EM>self._taps = gr.firdes.low_pass_2(interp, interp*fs, BW, TB,
+ * attenuation_dB=ATT, window=gr.firdes.WIN_BLACKMAN_hARRIS)</EM></B>
+ *
+ * The PFB interpolator code takes the taps generated above and builds
+ * a set of filters. The set contains <EM>interp</EM> number of
+ * filters and each filter contains ceil(taps.size()/interp) number of
+ * taps. Each tap from the filter prototype is sequentially inserted
+ * into the next filter. When all of the input taps are used, the
+ * remaining filters in the filterbank are filled out with 0's to make
+ * sure each filter has the same number of taps.
+ *
+ * The theory behind this block can be found in Chapter 7.1 of the
+ * following book.
+ *
+ * <B><EM>f. harris, "Multirate Signal Processing for Communication
+ * Systems</EM>," Upper Saddle River, NJ: Prentice Hall,
+ * Inc. 2004.</EM></B>
+ */
+
+class GR_CORE_API gr_pfb_interpolator_ccf : public gr_sync_interpolator
+{
+ private:
+ /*!
+ * Build the polyphase filterbank interpolator.
+ * \param interp (unsigned integer) Specifies the interpolation rate to use
+ * \param taps (vector/list of floats) The prototype filter to populate the filterbank. The taps
+ * should be generated at the interpolated sampling rate.
+ */
+ friend GR_CORE_API gr_pfb_interpolator_ccf_sptr gr_make_pfb_interpolator_ccf (unsigned int interp,
+ const std::vector<float> &taps);
+
+ std::vector<gr_fir_ccf*> d_filters;
+ std::vector< std::vector<float> > d_taps;
+ unsigned int d_rate;
+ unsigned int d_taps_per_filter;
+ bool d_updated;
+
+ /*!
+ * Construct a Polyphase filterbank interpolator
+ * \param interp (unsigned integer) Specifies the interpolation rate to use
+ * \param taps (vector/list of floats) The prototype filter to populate the filterbank. The taps
+ * should be generated at the interpolated sampling rate.
+ */
+ gr_pfb_interpolator_ccf (unsigned int interp,
+ const std::vector<float> &taps);
+
+public:
+ ~gr_pfb_interpolator_ccf ();
+
+ /*!
+ * Resets the filterbank's filter taps with the new prototype filter
+ * \param taps (vector/list of floats) The prototype filter to populate the filterbank. The taps
+ * should be generated at the interpolated sampling rate.
+ */
+ void set_taps (const std::vector<float> &taps);
+
+ /*!
+ * Print all of the filterbank taps to screen.
+ */
+ void print_taps();
+
+ int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+#endif
diff --git a/gnuradio-core/src/lib/filter/gr_pfb_interpolator_ccf.i b/gnuradio-core/src/lib/filter/gr_pfb_interpolator_ccf.i
new file mode 100644
index 000000000..427f1b913
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_pfb_interpolator_ccf.i
@@ -0,0 +1,39 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2009 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,pfb_interpolator_ccf);
+
+gr_pfb_interpolator_ccf_sptr gr_make_pfb_interpolator_ccf (unsigned int interp,
+ const std::vector<float> &taps);
+
+class gr_pfb_interpolator_ccf : public gr_sync_interpolator
+{
+ private:
+ gr_pfb_interpolator_ccf (unsigned int interp,
+ const std::vector<float> &taps);
+
+ public:
+ ~gr_pfb_interpolator_ccf ();
+
+ void set_taps (const std::vector<float> &taps);
+ void print_taps();
+};
diff --git a/gnuradio-core/src/lib/filter/gr_pfb_synthesizer_ccf.cc b/gnuradio-core/src/lib/filter/gr_pfb_synthesizer_ccf.cc
new file mode 100644
index 000000000..cd01aaff5
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_pfb_synthesizer_ccf.cc
@@ -0,0 +1,287 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2010,2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_pfb_synthesizer_ccf.h>
+#include <gri_fft.h>
+#include <gr_io_signature.h>
+#include <cstdio>
+#include <cstring>
+
+gr_pfb_synthesizer_ccf_sptr gr_make_pfb_synthesizer_ccf
+ (unsigned int numchans, const std::vector<float> &taps, bool twox)
+{
+ return gr_pfb_synthesizer_ccf_sptr
+ (new gr_pfb_synthesizer_ccf (numchans, taps, twox));
+}
+
+
+gr_pfb_synthesizer_ccf::gr_pfb_synthesizer_ccf
+ (unsigned int numchans, const std::vector<float> &taps, bool twox)
+ : gr_sync_interpolator ("pfb_synthesizer_ccf",
+ gr_make_io_signature (1, numchans, sizeof(gr_complex)),
+ gr_make_io_signature (1, 1, sizeof(gr_complex)),
+ numchans),
+ d_updated (false), d_numchans(numchans), d_state(0)
+{
+ // set up 2x multiplier; if twox==True, set to 2, otherwise to 1
+ d_twox = (twox ? 2 : 1);
+ if(d_numchans % d_twox != 0) {
+ throw std::invalid_argument("gr_pfb_synthesizer_ccf: number of channels must be even for 2x oversampling.\n");
+ }
+
+ d_filters = std::vector<gri_fir_filter_with_buffer_ccf*>(d_twox*d_numchans);
+ d_channel_map.resize(d_twox*d_numchans);
+
+ // Create an FIR filter for each channel and zero out the taps
+ std::vector<float> vtaps(0, d_twox*d_numchans);
+ for(unsigned int i = 0; i < d_twox*d_numchans; i++) {
+ d_filters[i] = new gri_fir_filter_with_buffer_ccf(vtaps);
+ d_channel_map[i] = i;
+ }
+
+ // Now, actually set the filters' taps
+ set_taps(taps);
+
+ // Create the IFFT to handle the input channel rotations
+ d_fft = new gri_fft_complex (d_twox*d_numchans, false);
+ memset(d_fft->get_inbuf(), 0, d_twox*d_numchans*sizeof(gr_complex));
+
+ set_output_multiple(d_numchans);
+}
+
+gr_pfb_synthesizer_ccf::~gr_pfb_synthesizer_ccf ()
+{
+ delete d_fft;
+ for(unsigned int i = 0; i < d_twox*d_numchans; i++) {
+ delete d_filters[i];
+ }
+}
+
+void
+gr_pfb_synthesizer_ccf::set_taps(const std::vector<float> &taps)
+{
+ gruel::scoped_lock guard(d_mutex);
+ if(d_twox == 1)
+ set_taps1(taps);
+ else
+ set_taps2(taps);
+}
+
+void
+gr_pfb_synthesizer_ccf::set_taps1(const std::vector<float> &taps)
+{
+ unsigned int i,j;
+
+ unsigned int ntaps = taps.size();
+ d_taps_per_filter = (unsigned int)ceil((double)ntaps/(double)d_numchans);
+
+ // Create d_numchan vectors to store each channel's taps
+ d_taps.resize(d_numchans);
+
+ // Make a vector of the taps plus fill it out with 0's to fill
+ // each polyphase filter with exactly d_taps_per_filter
+ std::vector<float> tmp_taps;
+ tmp_taps = taps;
+ while((float)(tmp_taps.size()) < d_numchans*d_taps_per_filter) {
+ tmp_taps.push_back(0.0);
+ }
+
+ // Partition the filter
+ for(i = 0; i < d_numchans; i++) {
+ // Each channel uses all d_taps_per_filter with 0's if not enough taps to fill out
+ d_taps[i] = std::vector<float>(d_taps_per_filter, 0);
+ for(j = 0; j < d_taps_per_filter; j++) {
+ d_taps[i][j] = tmp_taps[i + j*d_numchans]; // add taps to channels in reverse order
+ }
+
+ // Build a filter for each channel and add it's taps to it
+ d_filters[i]->set_taps(d_taps[i]);
+ }
+
+ // Set the history to ensure enough input items for each filter
+ set_history (d_taps_per_filter+1);
+
+ d_updated = true;
+}
+
+void
+gr_pfb_synthesizer_ccf::set_taps2 (const std::vector<float> &taps)
+{
+ unsigned int i,j;
+ int state = 0;
+
+ unsigned int ntaps = taps.size();
+ d_taps_per_filter = (unsigned int)ceil((double)ntaps/(double)d_numchans);
+
+ // Create d_numchan vectors to store each channel's taps
+ d_taps.resize(d_twox*d_numchans);
+
+ // Make a vector of the taps plus fill it out with 0's to fill
+ // each polyphase filter with exactly d_taps_per_filter
+ std::vector<float> tmp_taps;
+ tmp_taps = taps;
+ while((float)(tmp_taps.size()) < d_numchans*d_taps_per_filter) {
+ tmp_taps.push_back(0.0);
+ }
+
+ // Partition the filter
+ for(i = 0; i < d_numchans; i++) {
+ // Each channel uses all d_taps_per_filter with 0's if not enough taps to fill out
+ d_taps[i] = std::vector<float>(d_taps_per_filter, 0);
+ d_taps[d_numchans+i] = std::vector<float>(d_taps_per_filter, 0);
+ state = 0;
+ for(j = 0; j < d_taps_per_filter; j++) {
+ // add taps to channels in reverse order
+ // Zero out every other tap
+ if(state == 0) {
+ d_taps[i][j] = tmp_taps[i + j*d_numchans];
+ d_taps[d_numchans + i][j] = 0;
+ state = 1;
+ }
+ else {
+ d_taps[i][j] = 0;
+ d_taps[d_numchans + i][j] = tmp_taps[i + j*d_numchans];
+ state = 0;
+ }
+ }
+
+ // Build a filter for each channel and add it's taps to it
+ d_filters[i]->set_taps(d_taps[i]);
+ d_filters[d_numchans + i]->set_taps(d_taps[d_numchans + i]);
+ }
+
+ // Set the history to ensure enough input items for each filter
+ set_history (d_taps_per_filter+1);
+
+ d_updated = true;
+}
+
+void
+gr_pfb_synthesizer_ccf::print_taps()
+{
+ unsigned int i, j;
+ for(i = 0; i < d_twox*d_numchans; i++) {
+ printf("filter[%d]: [", i);
+ for(j = 0; j < d_taps_per_filter; j++) {
+ printf(" %.4e", d_taps[i][j]);
+ }
+ printf("]\n\n");
+ }
+}
+
+
+std::vector< std::vector<float> >
+gr_pfb_synthesizer_ccf::taps() const
+{
+ return d_taps;
+}
+
+void
+gr_pfb_synthesizer_ccf::set_channel_map(const std::vector<int> &map)
+{
+ gruel::scoped_lock guard(d_mutex);
+
+ if(map.size() > 0) {
+ unsigned int max = (unsigned int)*std::max_element(map.begin(), map.end());
+ unsigned int min = (unsigned int)*std::min_element(map.begin(), map.end());
+ if((max >= d_twox*d_numchans) || (min < 0)) {
+ throw std::invalid_argument("gr_pfb_synthesizer_ccf::set_channel_map: map range out of bounds.\n");
+ }
+ d_channel_map = map;
+
+ // Zero out fft buffer so that unused channels are always 0
+ memset(d_fft->get_inbuf(), 0,d_twox*d_numchans*sizeof(gr_complex));
+ }
+}
+
+std::vector<int>
+gr_pfb_synthesizer_ccf::channel_map() const
+{
+ return d_channel_map;
+}
+
+int
+gr_pfb_synthesizer_ccf::work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ gruel::scoped_lock guard(d_mutex);
+
+ gr_complex *in = (gr_complex*) input_items[0];
+ gr_complex *out = (gr_complex *) output_items[0];
+
+ if (d_updated) {
+ d_updated = false;
+ return 0; // history requirements may have changed.
+ }
+
+ unsigned int n, i;
+ size_t ninputs = input_items.size();
+
+ // Algoritm for critically sampled channels
+ if(d_twox == 1) {
+ for(n = 0; n < noutput_items/d_numchans; n++) {
+ for(i = 0; i < ninputs; i++) {
+ in = (gr_complex*)input_items[i];
+ d_fft->get_inbuf()[d_channel_map[i]] = in[n];
+ }
+
+ // spin through IFFT
+ d_fft->execute();
+
+ for(i = 0; i < d_numchans; i++) {
+ out[i] = d_filters[i]->filter(d_fft->get_outbuf()[i]);
+ }
+ out += d_numchans;
+ }
+ }
+
+ // Algorithm for oversampling by 2x
+ else {
+ for(n = 0; n < noutput_items/d_numchans; n++) {
+ for(i = 0; i < ninputs; i++) {
+ in = (gr_complex*)input_items[i];
+ d_fft->get_inbuf()[d_channel_map[i]] = in[n];
+ }
+
+ // spin through IFFT
+ d_fft->execute();
+
+ // Output is sum of two filters, but the input buffer to the filters must be circularly
+ // shifted by numchans every time through, done by using d_state to determine which IFFT
+ // buffer position to pull from.
+ for(i = 0; i < d_numchans; i++) {
+ out[i] = d_filters[i]->filter(d_fft->get_outbuf()[d_state*d_numchans+i]);
+ out[i] += d_filters[d_numchans+i]->filter(d_fft->get_outbuf()[(d_state^1)*d_numchans+i]);
+ }
+ d_state ^= 1;
+
+ out += d_numchans;
+ }
+ }
+
+ return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/filter/gr_pfb_synthesizer_ccf.h b/gnuradio-core/src/lib/filter/gr_pfb_synthesizer_ccf.h
new file mode 100644
index 000000000..9e4f85497
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_pfb_synthesizer_ccf.h
@@ -0,0 +1,147 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2010,2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+
+#ifndef INCLUDED_GR_PFB_SYNTHESIZER_CCF_H
+#define INCLUDED_GR_PFB_SYNTHESIZER_CCF_H
+
+#include <gr_core_api.h>
+#include <gr_sync_interpolator.h>
+#include <gri_fir_filter_with_buffer_ccf.h>
+#include <gruel/thread.h>
+
+class gr_pfb_synthesizer_ccf;
+typedef boost::shared_ptr<gr_pfb_synthesizer_ccf> gr_pfb_synthesizer_ccf_sptr;
+GR_CORE_API gr_pfb_synthesizer_ccf_sptr gr_make_pfb_synthesizer_ccf
+ (unsigned int numchans, const std::vector<float> &taps, bool twox=false);
+
+class gri_fft_complex;
+
+
+/*!
+ * \class gr_pfb_synthesizer_ccf
+ *
+ * \brief Polyphase synthesis filterbank with
+ * gr_complex input, gr_complex output and float taps
+ *
+ * \ingroup filter_blk
+ * \ingroup pfb_blk
+ */
+
+class GR_CORE_API gr_pfb_synthesizer_ccf : public gr_sync_interpolator
+{
+ private:
+ /*!
+ * Build the polyphase synthesis filterbank.
+ * \param numchans (unsigned integer) Specifies the number of
+ channels <EM>M</EM>
+ * \param taps (vector/list of floats) The prototype filter to
+ populate the filterbank.
+ * \param twox (bool) use 2x oversampling or not (default is no)
+ */
+ friend GR_CORE_API gr_pfb_synthesizer_ccf_sptr gr_make_pfb_synthesizer_ccf
+ (unsigned int numchans, const std::vector<float> &taps, bool twox);
+
+ bool d_updated;
+ unsigned int d_numchans;
+ unsigned int d_taps_per_filter;
+ gri_fft_complex *d_fft;
+ std::vector< gri_fir_filter_with_buffer_ccf*> d_filters;
+ std::vector< std::vector<float> > d_taps;
+ int d_state;
+ std::vector<int> d_channel_map;
+ unsigned int d_twox;
+ gruel::mutex d_mutex; // mutex to protect set/work access
+
+ /*!
+ * \brief Tap setting algorithm for critically sampled channels
+ */
+ void set_taps1(const std::vector<float> &taps);
+
+ /*!
+ * \brief Tap setting algorithm for 2x over-sampled channels
+ */
+ void set_taps2(const std::vector<float> &taps);
+
+ /*!
+ * Build the polyphase synthesis filterbank.
+ * \param numchans (unsigned integer) Specifies the number of
+ channels <EM>M</EM>
+ * \param taps (vector/list of floats) The prototype filter
+ to populate the filterbank.
+ * \param twox (bool) use 2x oversampling or not (default is no)
+ */
+ gr_pfb_synthesizer_ccf (unsigned int numchans,
+ const std::vector<float> &taps,
+ bool twox);
+
+public:
+ ~gr_pfb_synthesizer_ccf ();
+
+ /*!
+ * Resets the filterbank's filter taps with the new prototype filter
+ * \param taps (vector/list of floats) The prototype filter to
+ populate the filterbank.
+ */
+ void set_taps (const std::vector<float> &taps);
+
+ /*!
+ * Print all of the filterbank taps to screen.
+ */
+ void print_taps();
+
+ /*!
+ * Return a vector<vector<>> of the filterbank taps
+ */
+ std::vector<std::vector<float> > taps() const;
+
+ /*!
+ * Set the channel map. Channels are numbers as:
+ * N/2+1 | ... | N-1 | 0 | 1 | 2 | ... | N/2
+ * <------------------- 0 -------------------->
+ * freq
+ *
+ * So input stream 0 goes to channel 0, etc. Setting a new channel
+ * map allows the user to specify where in frequency he/she wants
+ * the input stream to go. This is especially useful to avoid
+ * putting signals into the channels on the edge of the spectrum
+ * which can either wrap around (in the case of odd number of
+ * channels) and be affected by filter rolloff in the transmitter.
+ *
+ * The map must be at least the number of streams being sent to the
+ * block. Less and the algorithm will not have enough data to
+ * properly setup the buffers. Any more channels specified will be
+ * ignored.
+ */
+ void set_channel_map(const std::vector<int> &map);
+
+ /*!
+ * Gets the current channel map.
+ */
+ std::vector<int> channel_map() const;
+
+ int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+#endif
diff --git a/gnuradio-core/src/lib/filter/gr_pfb_synthesizer_ccf.i b/gnuradio-core/src/lib/filter/gr_pfb_synthesizer_ccf.i
new file mode 100644
index 000000000..c186ae355
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_pfb_synthesizer_ccf.i
@@ -0,0 +1,44 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2010,2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,pfb_synthesizer_ccf);
+
+gr_pfb_synthesizer_ccf_sptr gr_make_pfb_synthesizer_ccf
+ (unsigned int numchans, const std::vector<float> &taps, bool twox=false);
+
+class gr_pfb_synthesizer_ccf : public gr_sync_interpolator
+{
+ private:
+ gr_pfb_synthesizer_ccf (unsigned int numchans,
+ const std::vector<float> &taps,
+ bool twox=false);
+
+ public:
+ ~gr_pfb_synthesizer_ccf ();
+
+ void set_taps (const std::vector<float> &taps);
+ void print_taps();
+ std::vector< std::vector<float> > taps() const;
+
+ void set_channel_map(const std::vector<int> &map);
+ std::vector<int> channel_map() const;
+};
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
index 000000000..445834dda
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_rational_resampler_base_XXX.cc.t
@@ -0,0 +1,172 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+/*
+ * 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 gnuradio::get_initial_sptr (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
index 000000000..3eb85a979
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_rational_resampler_base_XXX.h.t
@@ -0,0 +1,88 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+/*
+ * 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_core_api.h>
+#include <gr_block.h>
+
+class @NAME@;
+typedef boost::shared_ptr<@NAME@> @SPTR_NAME@;
+GR_CORE_API @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_blk
+ */
+class GR_CORE_API @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 GR_CORE_API @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
index 000000000..1f789b0a3
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_rational_resampler_base_XXX.i.t
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, 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
index 000000000..e31be6ee6
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_rotator.h
@@ -0,0 +1,54 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003,2008 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef _GR_ROTATOR_H_
+#define _GR_ROTATOR_H_
+
+#include <gr_core_api.h>
+#include <gr_complex.h>
+
+class GR_CORE_API gr_rotator {
+ gr_complex d_phase;
+ gr_complex d_phase_incr;
+ unsigned int d_counter;
+
+ public:
+ gr_rotator () : d_phase (1), d_phase_incr (1), d_counter(0) { }
+
+ void set_phase (gr_complex phase) { d_phase = phase / abs(phase); }
+ void set_phase_incr (gr_complex incr) { d_phase_incr = incr / abs(incr); }
+
+ gr_complex rotate (gr_complex in){
+ d_counter++;
+
+ gr_complex z = in * d_phase; // rotate in by phase
+ d_phase *= d_phase_incr; // incr our phase (complex mult == add phases)
+
+ if ((d_counter % 512) == 0)
+ d_phase /= abs(d_phase); // Normalize to ensure multiplication is rotation
+
+ return z;
+ }
+
+};
+
+#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
index 000000000..a8d01b0da
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_sincos.c
@@ -0,0 +1,83 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE // ask for GNU extensions if available
+#endif
+
+#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
index 000000000..516f43437
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_sincos.h
@@ -0,0 +1,41 @@
+/* -*- 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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_SINCOS_H
+#define INCLUDED_GR_SINCOS_H
+
+#include <gr_core_api.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// compute sine and cosine at the same time
+
+GR_CORE_API void gr_sincos (double x, double *sin, double *cos);
+GR_CORE_API 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_iir.h b/gnuradio-core/src/lib/filter/gr_single_pole_iir.h
new file mode 100644
index 000000000..d73ee857d
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_single_pole_iir.h
@@ -0,0 +1,191 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002,2006 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifndef _GR_SINGLE_POLE_IIR_H_
+#define _GR_SINGLE_POLE_IIR_H_
+
+#include <gr_core_api.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;
+ }
+
+ o_type prev_output () const { return d_prev_output; }
+
+protected:
+ tap_type d_alpha;
+ tap_type d_one_minus_alpha;
+ o_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)
+{
+ o_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 () const { 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
index 000000000..ae4f654dd
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_single_pole_iir_filter_cc.cc
@@ -0,0 +1,81 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2006,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_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 gnuradio::get_initial_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
index 000000000..13c595826
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_single_pole_iir_filter_cc.h
@@ -0,0 +1,88 @@
+/* -*- 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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_SINGLE_POLE_IIR_FILTER_CC_H
+#define INCLUDED_GR_SINGLE_POLE_IIR_FILTER_CC_H
+
+#include <gr_core_api.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_CORE_API 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_blk
+ *
+ * The input and output satisfy a difference equation of the form
+ \htmlonly
+ \f{
+ y[n] - (1-alpha) y[n-1] = alpha x[n]
+ \f}
+ \endhtmlonly
+
+ \xmlonly
+ y[n] - (1-alpha) y[n-1] = alpha x[n]
+ \endxmlonly
+
+ * with the corresponding rational system function
+ \htmlonly
+ \f{
+ H(z) = \frac{alpha}{1 - (1-alpha) z^{-1}}
+ \f}
+ \endhtmlonly
+
+ \xmlonly
+ H(z) = \ frac{alpha}{1 - (1-alpha) z^{-1}}
+ \endxmlonly
+
+ * 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_CORE_API gr_single_pole_iir_filter_cc : public gr_sync_block
+{
+ private:
+ friend GR_CORE_API 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
index 000000000..2f1f285de
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_single_pole_iir_filter_cc.i
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,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
index 000000000..047b2ba25
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_single_pole_iir_filter_ff.cc
@@ -0,0 +1,81 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#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 gnuradio::get_initial_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
index 000000000..8dcdad2c9
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_single_pole_iir_filter_ff.h
@@ -0,0 +1,87 @@
+/* -*- 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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_SINGLE_POLE_IIR_FILTER_FF_H
+#define INCLUDED_GR_SINGLE_POLE_IIR_FILTER_FF_H
+
+#include <gr_core_api.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_CORE_API 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_blk
+ *
+ * The input and output satisfy a difference equation of the form
+ \htmlonly
+ \f{
+ y[n] - (1-alpha) y[n-1] = alpha x[n]
+ \f}
+ \endhtmlonly
+
+ \xmlonly
+ y[n] - (1-alpha) y[n-1] = alpha x[n]
+ \endxmlonly
+
+ * with the corresponding rational system function
+ \htmlonly
+ \f{
+ H(z) = \frac{alpha}{1 - (1-alpha) z^{-1}}
+ \f}
+ \endhtmlonly
+
+ \xmlonly
+H(z) = \ frac{alpha}{1 - (1-alpha) z^{-1}}
+ \endxmlonly
+
+ * 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_CORE_API gr_single_pole_iir_filter_ff : public gr_sync_block
+{
+ private:
+ friend GR_CORE_API 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
index 000000000..a835fabb2
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_single_pole_iir_filter_ff.i
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,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_vec_types.h b/gnuradio-core/src/lib/filter/gr_vec_types.h
new file mode 100644
index 000000000..2bcec44bf
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_vec_types.h
@@ -0,0 +1,54 @@
+/* Cell single token vector types
+ Copyright (C) 2007 Free Software Foundation, Inc.
+
+ 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 file is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this file; see the file COPYING. If not, write to the Free
+ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA. */
+
+/* As a special exception, if you include this header file into source files
+ compiled by GCC, this header file does not by itself cause the resulting
+ executable to be covered by the GNU General Public License. This exception
+ does not however invalidate any other reasons why the executable file might be
+ covered by the GNU General Public License. */
+
+/* Single token vector data types for the PowerPC SIMD/Vector Multi-media
+ eXtension */
+
+#ifndef INCLUDED_GR_VEC_TYPES_H
+#define INCLUDED_GR_VEC_TYPES_H
+
+#define qword __vector unsigned char
+
+#define vec_uchar16 __vector unsigned char
+#define vec_char16 __vector signed char
+#define vec_bchar16 __vector bool char
+
+#define vec_ushort8 __vector unsigned short
+#define vec_short8 __vector signed short
+#define vec_bshort8 __vector bool short
+
+#define vec_pixel8 __vector pixel
+
+#define vec_uint4 __vector unsigned int
+#define vec_int4 __vector signed int
+#define vec_bint4 __vector bool int
+
+#define vec_float4 __vector float
+
+#define vec_ullong2 __vector bool char
+#define vec_llong2 __vector bool short
+
+#define vec_double2 __vector bool int
+
+#endif /* INCLUDED_GR_VEC_TYPES_H */
diff --git a/gnuradio-core/src/lib/filter/gri_fft_filter_ccc_generic.cc b/gnuradio-core/src/lib/filter/gri_fft_filter_ccc_generic.cc
new file mode 100644
index 000000000..e958c5061
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gri_fft_filter_ccc_generic.cc
@@ -0,0 +1,184 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gri_fft_filter_ccc_generic.h>
+#include <gri_fft.h>
+#include <volk/volk.h>
+#include <assert.h>
+#include <stdexcept>
+#include <cstdio>
+#include <cstring>
+#include <fftw3.h>
+
+gri_fft_filter_ccc_generic::gri_fft_filter_ccc_generic (int decimation,
+ const std::vector<gr_complex> &taps,
+ int nthreads)
+ : d_fftsize(-1), d_decimation(decimation), d_fwdfft(0), d_invfft(0), d_nthreads(nthreads)
+{
+ set_taps(taps);
+}
+
+gri_fft_filter_ccc_generic::~gri_fft_filter_ccc_generic ()
+{
+ delete d_fwdfft;
+ delete d_invfft;
+ gri_fft_free(d_xformed_taps);
+}
+
+#if 0
+static void
+print_vector_complex(const std::string label, const std::vector<gr_complex> &x)
+{
+ std::cout << label;
+ for (unsigned i = 0; i < x.size(); i++)
+ std::cout << x[i] << " ";
+ std::cout << "\n";
+}
+#endif
+
+
+/*
+ * determines d_ntaps, d_nsamples, d_fftsize, d_xformed_taps
+ */
+int
+gri_fft_filter_ccc_generic::set_taps (const std::vector<gr_complex> &taps)
+{
+ int i = 0;
+ compute_sizes(taps.size());
+
+ d_tail.resize(tailsize());
+ for (i = 0; i < tailsize(); i++)
+ d_tail[i] = 0;
+
+ gr_complex *in = d_fwdfft->get_inbuf();
+ gr_complex *out = d_fwdfft->get_outbuf();
+
+ float scale = 1.0 / d_fftsize;
+
+ // Compute forward xform of taps.
+ // Copy taps into first ntaps slots, then pad with zeros
+ for (i = 0; i < d_ntaps; i++)
+ in[i] = taps[i] * scale;
+
+ for (; i < d_fftsize; i++)
+ in[i] = 0;
+
+ d_fwdfft->execute(); // do the xform
+
+ // now copy output to d_xformed_taps
+ for (i = 0; i < d_fftsize; i++)
+ d_xformed_taps[i] = out[i];
+
+ return d_nsamples;
+}
+
+// determine and set d_ntaps, d_nsamples, d_fftsize
+
+void
+gri_fft_filter_ccc_generic::compute_sizes(int ntaps)
+{
+ int old_fftsize = d_fftsize;
+ d_ntaps = ntaps;
+ d_fftsize = (int) (2 * pow(2.0, ceil(log(double(ntaps)) / log(2.0))));
+ d_nsamples = d_fftsize - d_ntaps + 1;
+
+ if (0)
+ fprintf(stderr, "gri_fft_filter_ccc_generic: ntaps = %d, fftsize = %d, nsamples = %d\n",
+ d_ntaps, d_fftsize, d_nsamples);
+
+ assert(d_fftsize == d_ntaps + d_nsamples -1 );
+
+ if (d_fftsize != old_fftsize){ // compute new plans
+ delete d_fwdfft;
+ delete d_invfft;
+ d_fwdfft = new gri_fft_complex(d_fftsize, true, d_nthreads);
+ d_invfft = new gri_fft_complex(d_fftsize, false, d_nthreads);
+ d_xformed_taps = gri_fft_malloc_complex(d_fftsize);
+ }
+}
+
+void
+gri_fft_filter_ccc_generic::set_nthreads(int n)
+{
+ d_nthreads = n;
+ if(d_fwdfft)
+ d_fwdfft->set_nthreads(n);
+ if(d_invfft)
+ d_invfft->set_nthreads(n);
+}
+
+int
+gri_fft_filter_ccc_generic::nthreads() const
+{
+ return d_nthreads;
+}
+
+int
+gri_fft_filter_ccc_generic::filter (int nitems, const gr_complex *input, gr_complex *output)
+{
+ int dec_ctr = 0;
+ int j = 0;
+ int ninput_items = nitems * d_decimation;
+
+ for (int i = 0; i < ninput_items; i += d_nsamples){
+
+ memcpy(d_fwdfft->get_inbuf(), &input[i], d_nsamples * sizeof(gr_complex));
+
+ for (j = d_nsamples; j < d_fftsize; j++)
+ d_fwdfft->get_inbuf()[j] = 0;
+
+ d_fwdfft->execute(); // compute fwd xform
+
+ gr_complex *a = d_fwdfft->get_outbuf();
+ gr_complex *b = d_xformed_taps;
+ gr_complex *c = d_invfft->get_inbuf();
+
+ volk_32fc_x2_multiply_32fc_a(c, a, b, d_fftsize);
+
+ d_invfft->execute(); // compute inv xform
+
+ // add in the overlapping tail
+
+ for (j = 0; j < tailsize(); j++)
+ d_invfft->get_outbuf()[j] += d_tail[j];
+
+ // copy nsamples to output
+ j = dec_ctr;
+ while (j < d_nsamples) {
+ *output++ = d_invfft->get_outbuf()[j];
+ j += d_decimation;
+ }
+ dec_ctr = (j - d_nsamples);
+
+ // stash the tail
+ memcpy(&d_tail[0], d_invfft->get_outbuf() + d_nsamples,
+ tailsize() * sizeof(gr_complex));
+ }
+
+ assert(dec_ctr == 0);
+
+ return nitems;
+}
diff --git a/gnuradio-core/src/lib/filter/gri_fft_filter_ccc_generic.h b/gnuradio-core/src/lib/filter/gri_fft_filter_ccc_generic.h
new file mode 100644
index 000000000..648c2b8c5
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gri_fft_filter_ccc_generic.h
@@ -0,0 +1,96 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GRI_FFT_FILTER_CCC_GENERIC_H
+#define INCLUDED_GRI_FFT_FILTER_CCC_GENERIC_H
+
+#include <gr_core_api.h>
+#include <gr_complex.h>
+#include <vector>
+
+class gri_fft_complex;
+
+/*!
+ * \brief Fast FFT filter with gr_complex input, gr_complex output and gr_complex taps
+ * \ingroup filter_blk
+ */
+class GR_CORE_API gri_fft_filter_ccc_generic
+{
+ private:
+ int d_ntaps;
+ int d_nsamples;
+ int d_fftsize; // fftsize = ntaps + nsamples - 1
+ int d_decimation;
+ gri_fft_complex *d_fwdfft; // forward "plan"
+ gri_fft_complex *d_invfft; // inverse "plan"
+ int d_nthreads; // number of FFTW threads to use
+ std::vector<gr_complex> d_tail; // state carried between blocks for overlap-add
+ std::vector<gr_complex> d_new_taps;
+ gr_complex *d_xformed_taps; // Fourier xformed taps
+
+ void compute_sizes(int ntaps);
+ int tailsize() const { return d_ntaps - 1; }
+
+ public:
+ /*!
+ * \brief Construct an FFT filter for complex vectors with the given taps and decimation rate.
+ *
+ * This is the basic implementation for performing FFT filter for fast convolution
+ * in other blocks for complex vectors (such as gr_fft_filter_ccc).
+ * \param decimation The decimation rate of the filter (int)
+ * \param taps The filter taps (complex)
+ * \param nthreads The number of threads for the FFT to use (int)
+ */
+ gri_fft_filter_ccc_generic (int decimation, const std::vector<gr_complex> &taps,
+ int nthreads=1);
+ ~gri_fft_filter_ccc_generic ();
+
+ /*!
+ * \brief Set new taps for the filter.
+ *
+ * Sets new taps and resets the class properties to handle different sizes
+ * \param taps The filter taps (complex)
+ */
+ int set_taps (const std::vector<gr_complex> &taps);
+
+ /*!
+ * \brief Set number of threads to use.
+ */
+ void set_nthreads(int n);
+
+ /*!
+ * \brief Get number of threads being used.
+ */
+ int nthreads() const;
+
+ /*!
+ * \brief Perform the filter operation
+ *
+ * \param nitems The number of items to produce
+ * \param input The input vector to be filtered
+ * \param output The result of the filter operation
+ */
+ int filter (int nitems, const gr_complex *input, gr_complex *output);
+
+};
+
+#endif /* INCLUDED_GRI_FFT_FILTER_CCC_GENERIC_H */
diff --git a/gnuradio-core/src/lib/filter/gri_fft_filter_ccc_sse.cc b/gnuradio-core/src/lib/filter/gri_fft_filter_ccc_sse.cc
new file mode 100644
index 000000000..bfc939869
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gri_fft_filter_ccc_sse.cc
@@ -0,0 +1,186 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gri_fft_filter_ccc_sse.h>
+#include <gri_fft.h>
+#include <assert.h>
+#include <stdexcept>
+#include <cstdio>
+#include <xmmintrin.h>
+#include <fftw3.h>
+
+gri_fft_filter_ccc_sse::gri_fft_filter_ccc_sse (int decimation,
+ const std::vector<gr_complex> &taps)
+ : d_fftsize(-1), d_decimation(decimation), d_fwdfft(0), d_invfft(0)
+{
+ d_xformed_taps = (gr_complex*)fftwf_malloc(1*sizeof(gr_complex));
+ set_taps(taps);
+}
+
+gri_fft_filter_ccc_sse::~gri_fft_filter_ccc_sse ()
+{
+ fftwf_free(d_xformed_taps);
+ delete d_fwdfft;
+ delete d_invfft;
+}
+
+#if 0
+static void
+print_vector_complex(const std::string label, const std::vector<gr_complex> &x)
+{
+ std::cout << label;
+ for (unsigned i = 0; i < x.size(); i++)
+ std::cout << x[i] << " ";
+ std::cout << "\n";
+}
+#endif
+
+
+/*
+ * determines d_ntaps, d_nsamples, d_fftsize, d_xformed_taps
+ */
+int
+gri_fft_filter_ccc_sse::set_taps (const std::vector<gr_complex> &taps)
+{
+ int i = 0;
+ compute_sizes(taps.size());
+
+ d_tail.resize(tailsize());
+ for (i = 0; i < tailsize(); i++)
+ d_tail[i] = 0;
+
+ gr_complex *in = d_fwdfft->get_inbuf();
+ gr_complex *out = d_fwdfft->get_outbuf();
+
+ float scale = 1.0 / d_fftsize;
+
+ // Compute forward xform of taps.
+ // Copy taps into first ntaps slots, then pad with zeros
+ for (i = 0; i < d_ntaps; i++)
+ in[i] = taps[i] * scale;
+
+ for (; i < d_fftsize; i++)
+ in[i] = 0;
+
+ d_fwdfft->execute(); // do the xform
+
+ // now copy output to d_xformed_taps
+ for (i = 0; i < d_fftsize; i++)
+ d_xformed_taps[i] = out[i];
+
+ return d_nsamples;
+}
+
+// determine and set d_ntaps, d_nsamples, d_fftsize
+
+void
+gri_fft_filter_ccc_sse::compute_sizes(int ntaps)
+{
+ int old_fftsize = d_fftsize;
+ d_ntaps = ntaps;
+ d_fftsize = (int) (2 * pow(2.0, ceil(log(ntaps) / log(2))));
+ d_nsamples = d_fftsize - d_ntaps + 1;
+
+ if (0)
+ fprintf(stderr, "gri_fft_filter_ccc_sse: ntaps = %d, fftsize = %d, nsamples = %d\n",
+ d_ntaps, d_fftsize, d_nsamples);
+
+ assert(d_fftsize == d_ntaps + d_nsamples -1 );
+
+ if (d_fftsize != old_fftsize){ // compute new plans
+ delete d_fwdfft;
+ delete d_invfft;
+ d_fwdfft = new gri_fft_complex(d_fftsize, true);
+ d_invfft = new gri_fft_complex(d_fftsize, false);
+
+ fftwf_free(d_xformed_taps);
+ d_xformed_taps = (gr_complex*)fftwf_malloc((d_fftsize)*sizeof(gr_complex));
+ }
+}
+
+int
+gri_fft_filter_ccc_sse::filter (int nitems, const gr_complex *input, gr_complex *output)
+{
+ int dec_ctr = 0;
+ int j = 0;
+ int ninput_items = nitems * d_decimation;
+
+ for (int i = 0; i < ninput_items; i += d_nsamples){
+
+ memcpy(d_fwdfft->get_inbuf(), &input[i], d_nsamples * sizeof(gr_complex));
+
+ for (j = d_nsamples; j < d_fftsize; j++)
+ d_fwdfft->get_inbuf()[j] = 0;
+
+ d_fwdfft->execute(); // compute fwd xform
+
+ float *a = (float*)(d_fwdfft->get_outbuf());
+ float *b = (float*)(&d_xformed_taps[0]);
+ float *c = (float*)(d_invfft->get_inbuf());
+
+ __m128 x0, x1, x2, t0, t1, m;
+ m = _mm_set_ps(-1, 1, -1, 1);
+ for (j = 0; j < 2*d_fftsize; j+=4) { // filter in the freq domain
+ x0 = _mm_load_ps(&a[j]);
+ t0 = _mm_load_ps(&b[j]);
+
+ t1 = _mm_shuffle_ps(t0, t0, _MM_SHUFFLE(3, 3, 1, 1));
+ t0 = _mm_shuffle_ps(t0, t0, _MM_SHUFFLE(2, 2, 0, 0));
+ t1 = _mm_mul_ps(t1, m);
+
+ x1 = _mm_mul_ps(x0, t0);
+ x2 = _mm_mul_ps(x0, t1);
+
+ x2 = _mm_shuffle_ps(x2, x2, _MM_SHUFFLE(2, 3, 0, 1));
+ x2 = _mm_add_ps(x1, x2);
+
+ _mm_store_ps(&c[j], x2);
+ }
+
+ d_invfft->execute(); // compute inv xform
+
+ // add in the overlapping tail
+
+ for (j = 0; j < tailsize(); j++)
+ d_invfft->get_outbuf()[j] += d_tail[j];
+
+ // copy nsamples to output
+ j = dec_ctr;
+ while (j < d_nsamples) {
+ *output++ = d_invfft->get_outbuf()[j];
+ j += d_decimation;
+ }
+ dec_ctr = (j - d_nsamples);
+
+ // stash the tail
+ memcpy(&d_tail[0], d_invfft->get_outbuf() + d_nsamples,
+ tailsize() * sizeof(gr_complex));
+ }
+
+ assert(dec_ctr == 0);
+
+ return nitems;
+}
diff --git a/gnuradio-core/src/lib/filter/gri_fft_filter_ccc_sse.h b/gnuradio-core/src/lib/filter/gri_fft_filter_ccc_sse.h
new file mode 100644
index 000000000..64b8c0c15
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gri_fft_filter_ccc_sse.h
@@ -0,0 +1,83 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GRI_FFT_FILTER_CCC_SSE_H
+#define INCLUDED_GRI_FFT_FILTER_CCC_SSE_H
+
+#include <gr_core_api.h>
+#include <gr_complex.h>
+#include <vector>
+
+class gri_fft_complex;
+
+/*!
+ * \brief Fast FFT filter with gr_complex input, gr_complex output and gr_complex taps
+ * \ingroup filter_blk
+ */
+class GR_CORE_API gri_fft_filter_ccc_sse
+{
+ private:
+ int d_ntaps;
+ int d_nsamples;
+ int d_fftsize; // fftsize = ntaps + nsamples - 1
+ int d_decimation;
+ gri_fft_complex *d_fwdfft; // forward "plan"
+ gri_fft_complex *d_invfft; // inverse "plan"
+ std::vector<gr_complex> d_tail; // state carried between blocks for overlap-add
+ gr_complex *d_xformed_taps;
+ std::vector<gr_complex> d_new_taps;
+
+ void compute_sizes(int ntaps);
+ int tailsize() const { return d_ntaps - 1; }
+
+ public:
+ /*!
+ * \brief Construct an FFT filter for complex vectors with the given taps and decimation rate.
+ *
+ * This is the basic implementation for performing FFT filter for fast convolution
+ * in other blocks for complex vectors (such as gr_fft_filter_ccc).
+ * \param decimation The decimation rate of the filter (int)
+ * \param taps The filter taps (complex)
+ */
+ gri_fft_filter_ccc_sse (int decimation, const std::vector<gr_complex> &taps);
+ ~gri_fft_filter_ccc_sse ();
+
+ /*!
+ * \brief Set new taps for the filter.
+ *
+ * Sets new taps and resets the class properties to handle different sizes
+ * \param taps The filter taps (complex)
+ */
+ int set_taps (const std::vector<gr_complex> &taps);
+
+ /*!
+ * \brief Perform the filter operation
+ *
+ * \param nitems The number of items to produce
+ * \param input The input vector to be filtered
+ * \param output The result of the filter operation
+ */
+ int filter (int nitems, const gr_complex *input, gr_complex *output);
+
+};
+
+#endif /* INCLUDED_GRI_FFT_FILTER_CCC_SSE_H */
diff --git a/gnuradio-core/src/lib/filter/gri_fft_filter_fff_generic.cc b/gnuradio-core/src/lib/filter/gri_fft_filter_fff_generic.cc
new file mode 100644
index 000000000..c6e923ee1
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gri_fft_filter_fff_generic.cc
@@ -0,0 +1,175 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gri_fft_filter_fff_generic.h>
+#include <gri_fft.h>
+#include <volk/volk.h>
+#include <assert.h>
+#include <stdexcept>
+#include <cstdio>
+#include <cstring>
+
+gri_fft_filter_fff_generic::gri_fft_filter_fff_generic (int decimation,
+ const std::vector<float> &taps,
+ int nthreads)
+ : d_fftsize(-1), d_decimation(decimation), d_fwdfft(0), d_invfft(0), d_nthreads(nthreads)
+{
+ set_taps(taps);
+}
+
+gri_fft_filter_fff_generic::~gri_fft_filter_fff_generic ()
+{
+ delete d_fwdfft;
+ delete d_invfft;
+ gri_fft_free(d_xformed_taps);
+}
+
+/*
+ * determines d_ntaps, d_nsamples, d_fftsize, d_xformed_taps
+ */
+int
+gri_fft_filter_fff_generic::set_taps (const std::vector<float> &taps)
+{
+ int i = 0;
+ compute_sizes(taps.size());
+
+ d_tail.resize(tailsize());
+ for (i = 0; i < tailsize(); i++)
+ d_tail[i] = 0;
+
+ float *in = d_fwdfft->get_inbuf();
+ gr_complex *out = d_fwdfft->get_outbuf();
+
+ float scale = 1.0 / d_fftsize;
+
+ // Compute forward xform of taps.
+ // Copy taps into first ntaps slots, then pad with zeros
+ for (i = 0; i < d_ntaps; i++)
+ in[i] = taps[i] * scale;
+
+ for (; i < d_fftsize; i++)
+ in[i] = 0;
+
+ d_fwdfft->execute(); // do the xform
+
+ // now copy output to d_xformed_taps
+ for (i = 0; i < d_fftsize/2+1; i++)
+ d_xformed_taps[i] = out[i];
+
+ return d_nsamples;
+}
+
+// determine and set d_ntaps, d_nsamples, d_fftsize
+
+void
+gri_fft_filter_fff_generic::compute_sizes(int ntaps)
+{
+ int old_fftsize = d_fftsize;
+ d_ntaps = ntaps;
+ d_fftsize = (int) (2 * pow(2.0, ceil(log(double(ntaps)) / log(2.0))));
+ d_nsamples = d_fftsize - d_ntaps + 1;
+
+ if (0)
+ fprintf(stderr, "gri_fft_filter_fff_generic: ntaps = %d, fftsize = %d, nsamples = %d\n",
+ d_ntaps, d_fftsize, d_nsamples);
+
+ assert(d_fftsize == d_ntaps + d_nsamples -1 );
+
+ if (d_fftsize != old_fftsize){ // compute new plans
+ delete d_fwdfft;
+ delete d_invfft;
+ d_fwdfft = new gri_fft_real_fwd(d_fftsize);
+ d_invfft = new gri_fft_real_rev(d_fftsize);
+ d_xformed_taps = gri_fft_malloc_complex(d_fftsize/2+1);
+ }
+}
+
+void
+gri_fft_filter_fff_generic::set_nthreads(int n)
+{
+ d_nthreads = n;
+ if(d_fwdfft)
+ d_fwdfft->set_nthreads(n);
+ if(d_invfft)
+ d_invfft->set_nthreads(n);
+}
+
+int
+gri_fft_filter_fff_generic::nthreads() const
+{
+ return d_nthreads;
+}
+
+int
+gri_fft_filter_fff_generic::filter (int nitems, const float *input, float *output)
+{
+ int dec_ctr = 0;
+ int j = 0;
+ int ninput_items = nitems * d_decimation;
+
+ for (int i = 0; i < ninput_items; i += d_nsamples){
+
+ memcpy(d_fwdfft->get_inbuf(), &input[i], d_nsamples * sizeof(float));
+
+ for (j = d_nsamples; j < d_fftsize; j++)
+ d_fwdfft->get_inbuf()[j] = 0;
+
+ d_fwdfft->execute(); // compute fwd xform
+
+ gr_complex *a = d_fwdfft->get_outbuf();
+ gr_complex *b = d_xformed_taps;
+ gr_complex *c = d_invfft->get_inbuf();
+
+ volk_32fc_x2_multiply_32fc_a(c, a, b, d_fftsize/2+1);
+
+ d_invfft->execute(); // compute inv xform
+
+ // add in the overlapping tail
+
+ for (j = 0; j < tailsize(); j++)
+ d_invfft->get_outbuf()[j] += d_tail[j];
+
+ // copy nsamples to output
+
+ //memcpy(out, d_invfft->get_outbuf(), d_nsamples * sizeof(float));
+ //out += d_nsamples;
+
+ j = dec_ctr;
+ while (j < d_nsamples) {
+ *output++ = d_invfft->get_outbuf()[j];
+ j += d_decimation;
+ }
+ dec_ctr = (j - d_nsamples);
+
+ // stash the tail
+ memcpy(&d_tail[0], d_invfft->get_outbuf() + d_nsamples,
+ tailsize() * sizeof(float));
+ }
+
+ assert(dec_ctr == 0);
+
+ return nitems;
+}
diff --git a/gnuradio-core/src/lib/filter/gri_fft_filter_fff_generic.h b/gnuradio-core/src/lib/filter/gri_fft_filter_fff_generic.h
new file mode 100644
index 000000000..528bf5dd7
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gri_fft_filter_fff_generic.h
@@ -0,0 +1,94 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GRI_FFT_FILTER_FFF_GENERIC_H
+#define INCLUDED_GRI_FFT_FILTER_FFF_GENERIC_H
+
+#include <gr_core_api.h>
+#include <gr_complex.h>
+#include <vector>
+
+class gri_fft_real_fwd;
+class gri_fft_real_rev;
+
+class GR_CORE_API gri_fft_filter_fff_generic
+{
+ private:
+ int d_ntaps;
+ int d_nsamples;
+ int d_fftsize; // fftsize = ntaps + nsamples - 1
+ int d_decimation;
+ gri_fft_real_fwd *d_fwdfft; // forward "plan"
+ gri_fft_real_rev *d_invfft; // inverse "plan"
+ int d_nthreads; // number of FFTW threads to use
+ std::vector<float> d_tail; // state carried between blocks for overlap-add
+ std::vector<float> d_new_taps;
+ gr_complex *d_xformed_taps; // Fourier xformed taps
+
+
+ void compute_sizes(int ntaps);
+ int tailsize() const { return d_ntaps - 1; }
+
+ public:
+ /*!
+ * \brief Construct a FFT filter for float vectors with the given taps and decimation rate.
+ *
+ * This is the basic implementation for performing FFT filter for fast convolution
+ * in other blocks for floating point vectors (such as gr_fft_filter_fff).
+ * \param decimation The decimation rate of the filter (int)
+ * \param taps The filter taps (float)
+ * \param nthreads The number of threads for the FFT to use (int)
+ */
+ gri_fft_filter_fff_generic (int decimation, const std::vector<float> &taps,
+ int nthreads=1);
+ ~gri_fft_filter_fff_generic ();
+
+ /*!
+ * \brief Set new taps for the filter.
+ *
+ * Sets new taps and resets the class properties to handle different sizes
+ * \param taps The filter taps (float)
+ */
+ int set_taps (const std::vector<float> &taps);
+
+ /*!
+ * \brief Set number of threads to use.
+ */
+ void set_nthreads(int n);
+
+ /*!
+ * \brief Get number of threads being used.
+ */
+ int nthreads() const;
+
+ /*!
+ * \brief Perform the filter operation
+ *
+ * \param nitems The number of items to produce
+ * \param input The input vector to be filtered
+ * \param output The result of the filter operation
+ */
+ int filter (int nitems, const float *input, float *output);
+
+};
+
+#endif /* INCLUDED_GRI_FFT_FILTER_FFF_GENERIC_H */
diff --git a/gnuradio-core/src/lib/filter/gri_fft_filter_fff_sse.cc b/gnuradio-core/src/lib/filter/gri_fft_filter_fff_sse.cc
new file mode 100644
index 000000000..84fcfa438
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gri_fft_filter_fff_sse.cc
@@ -0,0 +1,184 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gri_fft_filter_fff_sse.h>
+#include <gri_fft.h>
+#include <assert.h>
+#include <stdexcept>
+#include <cstdio>
+#include <xmmintrin.h>
+#include <fftw3.h>
+
+gri_fft_filter_fff_sse::gri_fft_filter_fff_sse (int decimation,
+ const std::vector<float> &taps)
+ : d_fftsize(-1), d_decimation(decimation), d_fwdfft(0), d_invfft(0)
+{
+ d_xformed_taps = (gr_complex*)fftwf_malloc(1*sizeof(gr_complex));
+ set_taps(taps);
+}
+
+gri_fft_filter_fff_sse::~gri_fft_filter_fff_sse ()
+{
+ fftwf_free(d_xformed_taps);
+ delete d_fwdfft;
+ delete d_invfft;
+}
+
+/*
+ * determines d_ntaps, d_nsamples, d_fftsize, d_xformed_taps
+ */
+int
+gri_fft_filter_fff_sse::set_taps (const std::vector<float> &taps)
+{
+ int i = 0;
+ compute_sizes(taps.size());
+
+ d_tail.resize(tailsize());
+ for (i = 0; i < tailsize(); i++)
+ d_tail[i] = 0;
+
+ float *in = d_fwdfft->get_inbuf();
+ gr_complex *out = d_fwdfft->get_outbuf();
+
+ float scale = 1.0 / d_fftsize;
+
+ // Compute forward xform of taps.
+ // Copy taps into first ntaps slots, then pad with zeros
+ for (i = 0; i < d_ntaps; i++)
+ in[i] = taps[i] * scale;
+
+ for (; i < d_fftsize; i++)
+ in[i] = 0;
+
+ d_fwdfft->execute(); // do the xform
+
+ // now copy output to d_xformed_taps
+ for (i = 0; i < d_fftsize/2+1; i++)
+ d_xformed_taps[i] = out[i];
+
+ return d_nsamples;
+}
+
+// determine and set d_ntaps, d_nsamples, d_fftsize
+
+void
+gri_fft_filter_fff_sse::compute_sizes(int ntaps)
+{
+ int old_fftsize = d_fftsize;
+ d_ntaps = ntaps;
+ d_fftsize = (int) (2 * pow(2.0, ceil(log(ntaps) / log(2))));
+ d_nsamples = d_fftsize - d_ntaps + 1;
+
+ if (0)
+ fprintf(stderr, "gri_fft_filter_fff_sse: ntaps = %d, fftsize = %d, nsamples = %d\n",
+ d_ntaps, d_fftsize, d_nsamples);
+
+ assert(d_fftsize == d_ntaps + d_nsamples -1 );
+
+ if (d_fftsize != old_fftsize){ // compute new plans
+ delete d_fwdfft;
+ delete d_invfft;
+ d_fwdfft = new gri_fft_real_fwd(d_fftsize);
+ d_invfft = new gri_fft_real_rev(d_fftsize);
+ //d_xformed_taps.resize(d_fftsize/2+1);
+
+ fftwf_free(d_xformed_taps);
+ d_xformed_taps = (gr_complex*)fftwf_malloc((d_fftsize/2+1)*sizeof(gr_complex));
+ }
+}
+
+int
+gri_fft_filter_fff_sse::filter (int nitems, const float *input, float *output)
+{
+ int dec_ctr = 0;
+ int j = 0;
+ int ninput_items = nitems * d_decimation;
+
+ for (int i = 0; i < ninput_items; i += d_nsamples){
+
+ memcpy(d_fwdfft->get_inbuf(), &input[i], d_nsamples * sizeof(float));
+
+ for (j = d_nsamples; j < d_fftsize; j++)
+ d_fwdfft->get_inbuf()[j] = 0;
+
+ d_fwdfft->execute(); // compute fwd xform
+
+ float *a = (float*)(d_fwdfft->get_outbuf());
+ float *b = (float*)(&d_xformed_taps[0]);
+ float *c = (float*)(d_invfft->get_inbuf());
+
+ __m128 x0, x1, x2, t0, t1, m;
+ m = _mm_set_ps(-1, 1, -1, 1);
+ for (j = 0; j < d_fftsize; j+=4) { // filter in the freq domain
+ x0 = _mm_load_ps(&a[j]);
+ t0 = _mm_load_ps(&b[j]);
+
+ t1 = _mm_shuffle_ps(t0, t0, _MM_SHUFFLE(3, 3, 1, 1));
+ t0 = _mm_shuffle_ps(t0, t0, _MM_SHUFFLE(2, 2, 0, 0));
+ t1 = _mm_mul_ps(t1, m);
+
+ x1 = _mm_mul_ps(x0, t0);
+ x2 = _mm_mul_ps(x0, t1);
+
+ x2 = _mm_shuffle_ps(x2, x2, _MM_SHUFFLE(2, 3, 0, 1));
+ x2 = _mm_add_ps(x1, x2);
+
+ _mm_store_ps(&c[j], x2);
+ }
+
+ // Finish off the last one; do the complex multiply as floats
+ j = d_fftsize/2;
+ c[j] = (a[j] * b[j]) - (a[j+1] * b[j+1]);
+ c[j+1] = (a[j] * b[j+1]) + (a[j+1] * b[j]);
+
+ d_invfft->execute(); // compute inv xform
+
+ // add in the overlapping tail
+
+ for (j = 0; j < tailsize(); j++)
+ d_invfft->get_outbuf()[j] += d_tail[j];
+
+ // copy nsamples to output
+
+ //memcpy(out, d_invfft->get_outbuf(), d_nsamples * sizeof(float));
+ //out += d_nsamples;
+
+ j = dec_ctr;
+ while (j < d_nsamples) {
+ *output++ = d_invfft->get_outbuf()[j];
+ j += d_decimation;
+ }
+ dec_ctr = (j - d_nsamples);
+
+ // stash the tail
+ memcpy(&d_tail[0], d_invfft->get_outbuf() + d_nsamples,
+ tailsize() * sizeof(float));
+ }
+
+ assert(dec_ctr == 0);
+
+ return nitems;
+}
diff --git a/gnuradio-core/src/lib/filter/gri_fft_filter_fff_sse.h b/gnuradio-core/src/lib/filter/gri_fft_filter_fff_sse.h
new file mode 100644
index 000000000..b6086562d
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gri_fft_filter_fff_sse.h
@@ -0,0 +1,82 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GRI_FFT_FILTER_FFF_SSE_H
+#define INCLUDED_GRI_FFT_FILTER_FFF_SSE_H
+
+#include <gr_core_api.h>
+#include <gr_complex.h>
+#include <vector>
+
+class gri_fft_real_fwd;
+class gri_fft_real_rev;
+
+class GR_CORE_API gri_fft_filter_fff_sse
+{
+ private:
+ int d_ntaps;
+ int d_nsamples;
+ int d_fftsize; // fftsize = ntaps + nsamples - 1
+ int d_decimation;
+ gri_fft_real_fwd *d_fwdfft; // forward "plan"
+ gri_fft_real_rev *d_invfft; // inverse "plan"
+ std::vector<float> d_tail; // state carried between blocks for overlap-add
+ //std::vector<gr_complex> d_xformed_taps; // Fourier xformed taps
+ gr_complex *d_xformed_taps;
+ std::vector<float> d_new_taps;
+
+
+ void compute_sizes(int ntaps);
+ int tailsize() const { return d_ntaps - 1; }
+
+ public:
+ /*!
+ * \brief Construct a FFT filter for float vectors with the given taps and decimation rate.
+ *
+ * This is the basic implementation for performing FFT filter for fast convolution
+ * in other blocks for floating point vectors (such as gr_fft_filter_fff).
+ * \param decimation The decimation rate of the filter (int)
+ * \param taps The filter taps (float)
+ */
+ gri_fft_filter_fff_sse (int decimation, const std::vector<float> &taps);
+ ~gri_fft_filter_fff_sse ();
+
+ /*!
+ * \brief Set new taps for the filter.
+ *
+ * Sets new taps and resets the class properties to handle different sizes
+ * \param taps The filter taps (float)
+ */
+ int set_taps (const std::vector<float> &taps);
+
+ /*!
+ * \brief Perform the filter operation
+ *
+ * \param nitems The number of items to produce
+ * \param input The input vector to be filtered
+ * \param output The result of the filter operation
+ */
+ int filter (int nitems, const float *input, float *output);
+
+};
+
+#endif /* INCLUDED_GRI_FFT_FILTER_FFF_SSE_H */
diff --git a/gnuradio-core/src/lib/filter/gri_fir_filter_with_buffer_XXX.cc.t b/gnuradio-core/src/lib/filter/gri_fir_filter_with_buffer_XXX.cc.t
new file mode 100644
index 000000000..0ae644cc6
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gri_fir_filter_with_buffer_XXX.cc.t
@@ -0,0 +1,121 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <@NAME@.h>
+
+@NAME@::@NAME@(const std::vector<@TAP_TYPE@> &taps)
+{
+ d_buffer = NULL;
+ set_taps(taps);
+}
+
+@NAME@::~@NAME@()
+{
+ if(d_buffer != NULL)
+ free(d_buffer);
+}
+
+void
+@NAME@::set_taps (const std::vector<@TAP_TYPE@> &taps)
+{
+ d_taps = gr_reverse(taps);
+
+ if(d_buffer != NULL) {
+ free(d_buffer);
+ d_buffer = NULL;
+ }
+
+ // FIXME: memalign this to 16-byte boundaries for SIMD later
+ size_t t = sizeof(@I_TYPE@) * 2 * d_taps.size();
+ d_buffer = (@I_TYPE@*)malloc(t);
+ memset(d_buffer, 0x00, t);
+ d_idx = 0;
+}
+
+@O_TYPE@
+@NAME@::filter (@I_TYPE@ input)
+{
+ unsigned int i;
+
+ d_buffer[d_idx] = input;
+ d_buffer[d_idx+ntaps()] = input;
+
+ // using the later for the case when ntaps=0;
+ // profiling shows this doesn't make a difference
+ //d_idx = (d_idx + 1) % ntaps();
+ d_idx++;
+ if(d_idx >= ntaps())
+ d_idx = 0;
+
+ @ACC_TYPE@ out = 0;
+ for(i = 0; i < ntaps(); i++) {
+ out += @INPUT_CAST@ d_buffer[d_idx + i] * d_taps[i];
+ }
+ return (@O_TYPE@)out;
+}
+
+@O_TYPE@
+@NAME@::filter (const @I_TYPE@ input[], unsigned long dec)
+{
+ unsigned int i;
+
+ for(i = 0; i < dec; i++) {
+ d_buffer[d_idx] = input[i];
+ d_buffer[d_idx+ntaps()] = input[i];
+ d_idx++;
+ if(d_idx >= ntaps())
+ d_idx = 0;
+ }
+
+ @ACC_TYPE@ out = 0;
+ for(i = 0; i < ntaps(); i++) {
+ out += @INPUT_CAST@ d_buffer[d_idx + i] * d_taps[i];
+ }
+ return (@O_TYPE@)out;
+}
+
+void
+@NAME@::filterN (@O_TYPE@ output[],
+ const @I_TYPE@ input[],
+ unsigned long n)
+{
+ for(unsigned long i = 0; i < n; i++) {
+ output[i] = filter(input[i]);
+ }
+}
+
+void
+@NAME@::filterNdec (@O_TYPE@ output[],
+ const @I_TYPE@ input[],
+ unsigned long n,
+ unsigned long decimate)
+{
+ unsigned long j = 0;
+ for(unsigned long i = 0; i < n; i++) {
+ output[i] = filter(&input[j], decimate);
+ j += decimate;
+ }
+}
diff --git a/gnuradio-core/src/lib/filter/gri_fir_filter_with_buffer_XXX.h.t b/gnuradio-core/src/lib/filter/gri_fir_filter_with_buffer_XXX.h.t
new file mode 100644
index 000000000..efb314bed
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gri_fir_filter_with_buffer_XXX.h.t
@@ -0,0 +1,132 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+/*
+ * WARNING: This file is automatically generated by generate_gri_fir_XXX.py
+ * Any changes made to this file will be overwritten.
+ */
+
+
+#ifndef @GUARD_NAME@
+#define @GUARD_NAME@
+
+#include <gr_core_api.h>
+#include <vector>
+#include <gr_types.h>
+#include <gr_reverse.h>
+#include <string.h>
+#include <cstdio>
+
+/*!
+ * \brief FIR with internal buffer for @I_TYPE@ input,
+ @O_TYPE@ output and @TAP_TYPE@ taps
+ * \ingroup filter
+ *
+ */
+
+class GR_CORE_API @NAME@ {
+
+protected:
+ std::vector<@TAP_TYPE@> d_taps; // reversed taps
+ @I_TYPE@ *d_buffer;
+ unsigned int d_idx;
+
+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.
+ */
+ @NAME@ (const std::vector<@TAP_TYPE@> &taps);
+
+ ~@NAME@ ();
+
+ // MANIPULATORS
+
+ /*!
+ * \brief compute a single output value.
+ *
+ * \p input is a single input value of the filter type
+ *
+ * \returns the filtered input value.
+ */
+ @O_TYPE@ filter (@I_TYPE@ input);
+
+
+ /*!
+ * \brief compute a single output value; designed for decimating filters.
+ *
+ * \p input is a single input value of the filter type. The value of dec is the
+ * decimating value of the filter, so input[] must have dec valid values.
+ * The filter pushes dec number of items onto the circ. buffer before computing
+ * a single output.
+ *
+ * \returns the filtered input value.
+ */
+ @O_TYPE@ filter (const @I_TYPE@ input[], unsigned long dec);
+
+ /*!
+ * \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.
+ */
+ 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.
+ */
+ void filterNdec (@O_TYPE@ output[], const @I_TYPE@ input[],
+ unsigned long n, unsigned long decimate);
+
+ /*!
+ * \brief install \p new_taps as the current taps.
+ */
+ void set_taps (const std::vector<@TAP_TYPE@> &taps);
+
+ // ACCESSORS
+
+ /*!
+ * \return number of taps in filter.
+ */
+ unsigned ntaps () const { return d_taps.size (); }
+
+ /*!
+ * \return current taps
+ */
+ const std::vector<@TAP_TYPE@> get_taps () const
+ {
+ return gr_reverse(d_taps);
+ }
+};
+
+#endif /* @GUARD_NAME@ */
diff --git a/gnuradio-core/src/lib/filter/gri_goertzel.cc b/gnuradio-core/src/lib/filter/gri_goertzel.cc
new file mode 100644
index 000000000..2fbdd3b13
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gri_goertzel.cc
@@ -0,0 +1,75 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002,2011 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <cmath>
+
+#include <gri_goertzel.h>
+
+gri_goertzel::gri_goertzel(int rate, int len, float freq)
+{
+ gri_setparms(rate, len, freq);
+}
+
+void
+gri_goertzel::gri_setparms(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
index 000000000..e28cb21a8
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gri_goertzel.h
@@ -0,0 +1,57 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006,2011 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GRI_GOERTZEL_H
+#define INCLUDED_GRI_GOERTZEL_H
+
+#include <gr_core_api.h>
+#include <gr_types.h>
+
+/*!
+ * \brief Implements Goertzel single-bin DFT calculation
+ * \ingroup misc
+ */
+class GR_CORE_API gri_goertzel
+{
+public:
+ gri_goertzel() {}
+ gri_goertzel(int rate, int len, float freq);
+ void gri_setparms(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
index 000000000..86345f6c0
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gri_iir.h
@@ -0,0 +1,177 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GRI_IIR_H
+#define INCLUDED_GRI_IIR_H
+
+#include <gr_core_api.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}^{M} a_k y[n-k] = \sum_{k=0}^{N} b_k x[n-k]
+ \f]
+
+ * with the corresponding rational system function
+
+ \f[
+ H(z) = \frac{\sum_{k=0}^{N} b_k z^{-k}}{1 - \sum_{k=1}^{M} 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_n(0),d_latest_m(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_ff () const { return d_fftaps.size (); }
+ unsigned ntaps_fb () const { return d_fbtaps.size (); }
+
+ /*!
+ * \brief install new taps.
+ */
+ void set_taps (const std::vector<tap_type> &fftaps,
+ const std::vector<tap_type> &fbtaps) throw (std::invalid_argument)
+ {
+
+
+ d_latest_n = 0;
+ d_latest_m = 0;
+ d_fftaps = fftaps;
+ d_fbtaps = fbtaps;
+
+ int n = fftaps.size ();
+ int m = fbtaps.size ();
+ d_prev_input.resize (2 * n);
+ d_prev_output.resize (2 * m);
+
+ for (int i = 0; i < 2 * n; i++){
+ d_prev_input[i] = 0;
+ }
+ for (int i = 0; i < 2 * m; i++){
+ d_prev_output[i] = 0;
+ }
+ }
+
+protected:
+ std::vector<tap_type> d_fftaps;
+ std::vector<tap_type> d_fbtaps;
+ int d_latest_n;
+ int d_latest_m;
+ 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_ff ();
+ unsigned m = ntaps_fb ();
+
+ if (n == 0)
+ return (o_type) 0;
+
+ int latest_n = d_latest_n;
+ int latest_m = d_latest_m;
+
+ acc = d_fftaps[0] * input;
+ for (i = 1; i < n; i ++)
+ acc += (d_fftaps[i] * d_prev_input[latest_n + i]);
+ for (i = 1; i < m; i ++)
+ acc += (d_fbtaps[i] * d_prev_output[latest_m + i]);
+
+ // store the values twice to avoid having to handle wrap-around in the loop
+ d_prev_output[latest_m] = acc;
+ d_prev_output[latest_m+m] = acc;
+ d_prev_input[latest_n] = input;
+ d_prev_input[latest_n+n] = input;
+
+ latest_n--;
+ latest_m--;
+ if (latest_n < 0)
+ latest_n += n;
+ if (latest_m < 0)
+ latest_m += m;
+
+ d_latest_m = latest_m;
+ d_latest_n = latest_n;
+ 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
index 000000000..52098bf1a
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gri_mmse_fir_interpolator.cc
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <gri_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
index 000000000..f479169bc
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gri_mmse_fir_interpolator.h
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifndef _GRI_MMSE_FIR_INTERPOLATOR_H_
+#define _GRI_MMSE_FIR_INTERPOLATOR_H_
+
+#include <gr_core_api.h>
+#include <vector>
+
+class gr_fir_fff;
+
+/*!
+ * \brief Compute intermediate samples between signal samples x(k*Ts)
+ * \ingroup filter_primitive
+ *
+ * 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.
+ *
+ * For more information, in the GNU Radio source code, see:
+ * \li gnuradio-core/src/gen_interpolator_taps/README
+ * \li gnuradio-core/src/gen_interpolator_taps/praxis.txt
+ */
+
+class GR_CORE_API 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
index 000000000..174378c22
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gri_mmse_fir_interpolator_cc.cc
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <gri_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
index 000000000..bacd9ed92
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gri_mmse_fir_interpolator_cc.h
@@ -0,0 +1,74 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002,2007 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifndef _GRI_MMSE_FIR_INTERPOLATOR_CC_H_
+#define _GRI_MMSE_FIR_INTERPOLATOR_CC_H_
+
+#include <gr_core_api.h>
+#include <gr_complex.h>
+#include <vector>
+
+class gr_fir_ccf;
+
+/*!
+ * \brief Compute intermediate samples between signal samples x(k*Ts)
+ * \ingroup filter_primitive
+ *
+ * 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.
+ *
+ * For more information, in the GNU Radio source code, see:
+ * \li gnuradio-core/src/gen_interpolator_taps/README
+ * \li gnuradio-core/src/gen_interpolator_taps/praxis.txt
+ */
+
+class GR_CORE_API 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 and be 8-byte aligned.
+ * input[0] .. input[ntaps() - 1] are referenced to compute the output value.
+ * \throws std::invalid_argument if input is not 8-byte aligned.
+ *
+ * \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
index 000000000..76702b63f
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/interpolator_taps.h
@@ -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
index 000000000..0d7b878da
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/qa_ccomplex_dotprod_x86.cc
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <cppunit/TestAssert.h>
+#include <qa_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
index 000000000..d24561c72
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/qa_ccomplex_dotprod_x86.h
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifndef _QA_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
index 000000000..a21b95f63
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/qa_complex_dotprod_x86.cc
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <cppunit/TestAssert.h>
+#include <qa_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
index 000000000..9f9b46039
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/qa_complex_dotprod_x86.h
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifndef _QA_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
index 000000000..bd5ba8f3a
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/qa_dotprod.h
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifndef _QA_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_armv7_a.cc b/gnuradio-core/src/lib/filter/qa_dotprod_armv7_a.cc
new file mode 100644
index 000000000..1e1ded7ea
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/qa_dotprod_armv7_a.cc
@@ -0,0 +1,32 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003,2009 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+#include "qa_dotprod.h"
+
+CppUnit::TestSuite *
+qa_dotprod_suite ()
+{
+ CppUnit::TestSuite *s = new CppUnit::TestSuite ("dotprod");
+
+ // empty test suite
+
+ return s;
+}
diff --git a/gnuradio-core/src/lib/filter/qa_dotprod_generic.cc b/gnuradio-core/src/lib/filter/qa_dotprod_generic.cc
new file mode 100644
index 000000000..2c49d1d28
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/qa_dotprod_generic.cc
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+#include "qa_dotprod.h"
+
+CppUnit::TestSuite *
+qa_dotprod_suite ()
+{
+ CppUnit::TestSuite *s = new CppUnit::TestSuite ("dotprod");
+
+ // empty test suite
+
+ return s;
+}
diff --git a/gnuradio-core/src/lib/filter/qa_dotprod_powerpc.cc b/gnuradio-core/src/lib/filter/qa_dotprod_powerpc.cc
new file mode 100644
index 000000000..2c49d1d28
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/qa_dotprod_powerpc.cc
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+#include "qa_dotprod.h"
+
+CppUnit::TestSuite *
+qa_dotprod_suite ()
+{
+ CppUnit::TestSuite *s = new CppUnit::TestSuite ("dotprod");
+
+ // empty test suite
+
+ return s;
+}
diff --git a/gnuradio-core/src/lib/filter/qa_dotprod_x86.cc b/gnuradio-core/src/lib/filter/qa_dotprod_x86.cc
new file mode 100644
index 000000000..ec5625f10
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/qa_dotprod_x86.cc
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+#include "qa_dotprod.h"
+#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
index 000000000..629635084
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/qa_filter.cc
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2002,2007 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+/*
+ * 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>
+#include <qa_gri_mmse_fir_interpolator_cc.h>
+#include <qa_gr_rotator.h>
+#include <qa_gri_fir_filter_with_buffer_ccf.h>
+#include <qa_gri_fir_filter_with_buffer_ccc.h>
+#include <qa_gri_fir_filter_with_buffer_fcc.h>
+#include <qa_gri_fir_filter_with_buffer_fff.h>
+#include <qa_gri_fir_filter_with_buffer_fsf.h>
+#include <qa_gri_fir_filter_with_buffer_scc.h>
+
+CppUnit::TestSuite *
+qa_filter::suite ()
+{
+ CppUnit::TestSuite *s = new CppUnit::TestSuite ("filter");
+
+ s->addTest (qa_dotprod_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 ());
+ s->addTest (qa_gri_mmse_fir_interpolator::suite ());
+ s->addTest (qa_gri_mmse_fir_interpolator_cc::suite ());
+ s->addTest (qa_gr_rotator::suite ());
+ s->addTest (qa_gri_fir_filter_with_buffer_ccf::suite ());
+ s->addTest (qa_gri_fir_filter_with_buffer_ccc::suite ());
+ s->addTest (qa_gri_fir_filter_with_buffer_fcc::suite ());
+ s->addTest (qa_gri_fir_filter_with_buffer_fff::suite ());
+ s->addTest (qa_gri_fir_filter_with_buffer_fsf::suite ());
+ s->addTest (qa_gri_fir_filter_with_buffer_scc::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
index 000000000..740d05ce4
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/qa_filter.h
@@ -0,0 +1,38 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef _QA_FILTER_H_
+#define _QA_FILTER_H_
+
+#include <gruel/attributes.h>
+#include <cppunit/TestSuite.h>
+
+//! collect all the tests for the gr directory
+
+class __GR_ATTR_EXPORT 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
index 000000000..f8752d071
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/qa_float_dotprod_x86.cc
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <cppunit/TestAssert.h>
+#include <qa_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
index 000000000..38d6104fa
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/qa_float_dotprod_x86.h
@@ -0,0 +1,69 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifndef _QA_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
index 000000000..7474b76e2
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/qa_gr_fir_ccc.cc
@@ -0,0 +1,184 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, 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>
+#include <string.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++){
+ CPPUNIT_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
index 000000000..0535e6652
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/qa_gr_fir_ccc.h
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifndef _QA_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
index 000000000..84cb924ae
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/qa_gr_fir_ccf.cc
@@ -0,0 +1,184 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, 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>
+#include <string.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++){
+ CPPUNIT_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
index 000000000..bda79cc2f
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/qa_gr_fir_ccf.h
@@ -0,0 +1,43 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifndef _QA_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
index 000000000..4c77a5e5c
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/qa_gr_fir_fcc.cc
@@ -0,0 +1,181 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, 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>
+#include <string.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++){
+ CPPUNIT_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
index 000000000..23706fd9c
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/qa_gr_fir_fcc.h
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifndef _QA_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
index 000000000..80ed67465
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/qa_gr_fir_fff.cc
@@ -0,0 +1,226 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <qa_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>
+#include <string.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 = 32;
+ 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]) * 9e-3);
+ }
+
+ 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
index 000000000..c89672896
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/qa_gr_fir_fff.h
@@ -0,0 +1,43 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifndef _QA_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
index 000000000..3f4a7be2c
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/qa_gr_fir_scc.cc
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, 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++){
+ CPPUNIT_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
index 000000000..4b5ffdae3
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/qa_gr_fir_scc.h
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifndef _QA_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_gr_rotator.cc b/gnuradio-core/src/lib/filter/qa_gr_rotator.cc
new file mode 100644
index 000000000..b2885a12d
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/qa_gr_rotator.cc
@@ -0,0 +1,75 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <gruel/attributes.h>
+#include <cppunit/TestAssert.h>
+#include <qa_gr_rotator.h>
+#include <gr_rotator.h>
+#include <stdio.h>
+#include <cmath>
+#include <gr_expj.h>
+
+
+// error vector magnitude
+__GR_ATTR_UNUSED static float
+error_vector_mag(gr_complex a, gr_complex b)
+{
+ return abs(a-b);
+}
+
+void
+qa_gr_rotator::t1 ()
+{
+ static const unsigned int N = 100000;
+
+ gr_rotator r;
+
+ double phase_incr = 2*M_PI / 1003;
+ double phase = 0;
+
+ // Old code: We increment then return the rotated value, thus we need to start one tick back
+ // r.set_phase(gr_complex(1,0) * conj(gr_expj(phase_incr)));
+
+ r.set_phase(gr_complex(1,0));
+ r.set_phase_incr(gr_expj(phase_incr));
+
+ for (unsigned i = 0; i < N; i++){
+ gr_complex expected = gr_expj(phase);
+ gr_complex actual = r.rotate(gr_complex(1, 0));
+
+#if 0
+ float evm = error_vector_mag(expected, actual);
+ printf("[%6d] expected: (%8.6f, %8.6f) actual: (%8.6f, %8.6f) evm: %8.6f\n",
+ i, expected.real(), expected.imag(), actual.real(), actual.imag(), evm);
+#endif
+
+ CPPUNIT_ASSERT_COMPLEXES_EQUAL(expected, actual, 0.0001);
+
+ phase += phase_incr;
+ if (phase >= 2*M_PI)
+ phase -= 2*M_PI;
+ }
+}
diff --git a/gnuradio-core/src/lib/filter/qa_gr_rotator.h b/gnuradio-core/src/lib/filter/qa_gr_rotator.h
new file mode 100644
index 000000000..739b23f8c
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/qa_gr_rotator.h
@@ -0,0 +1,39 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifndef _QA_GR_ROTATOR_H_
+#define _QA_GR_ROTATOR_H_
+
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/TestCase.h>
+
+class qa_gr_rotator : public CppUnit::TestCase {
+
+ CPPUNIT_TEST_SUITE (qa_gr_rotator);
+ CPPUNIT_TEST (t1);
+ CPPUNIT_TEST_SUITE_END ();
+
+ private:
+ void t1 ();
+
+};
+
+#endif /* _QA_GR_ROTATOR_H_ */
diff --git a/gnuradio-core/src/lib/filter/qa_gri_fir_filter_with_buffer_ccc.cc b/gnuradio-core/src/lib/filter/qa_gri_fir_filter_with_buffer_ccc.cc
new file mode 100644
index 000000000..cfdbc53eb
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/qa_gri_fir_filter_with_buffer_ccc.cc
@@ -0,0 +1,161 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <gr_types.h>
+#include <qa_gri_fir_filter_with_buffer_ccc.h>
+#include <gri_fir_filter_with_buffer_ccc.h>
+#include <string.h>
+#include <iostream>
+#include <cmath>
+#include <cppunit/TestAssert.h>
+#include <random.h>
+#include <malloc16.h>
+#include <string.h>
+
+typedef gr_complex i_type;
+typedef gr_complex o_type;
+typedef gr_complex tap_type;
+typedef gr_complex acc_type;
+
+using std::vector;
+
+#define MAX_DATA (32767)
+#define ERR_DELTA (1e-5)
+
+#define NELEM(x) (sizeof (x) / sizeof (x[0]))
+
+static float
+uniform ()
+{
+ return 2.0 * ((float) random () / RANDOM_MAX - 0.5); // uniformly (-1, 1)
+}
+
+static void
+random_complex (gr_complex *buf, unsigned n)
+{
+ for (unsigned i = 0; i < n; i++){
+ float re = rint (uniform () * MAX_DATA);
+ float im = rint (uniform () * MAX_DATA);
+ 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[i];
+ }
+
+ return sum;
+}
+
+void
+qa_gri_fir_filter_with_buffer_ccc::t1 ()
+{
+ test_decimate(1);
+}
+
+void
+qa_gri_fir_filter_with_buffer_ccc::t2 ()
+{
+ test_decimate(2);
+}
+
+void
+qa_gri_fir_filter_with_buffer_ccc::t3 ()
+{
+ test_decimate(5);
+}
+
+//
+// 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.
+//
+void
+qa_gri_fir_filter_with_buffer_ccc::test_decimate(unsigned int decimate)
+{
+ const int MAX_TAPS = 9;
+ const int OUTPUT_LEN = 17;
+ const int INPUT_LEN = MAX_TAPS + OUTPUT_LEN;
+
+ // Mem aligned buffer not really necessary, but why not?
+ i_type *input = (i_type *)malloc16Align(INPUT_LEN * sizeof(i_type));
+ i_type *dline = (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
+ memset(dline, 0, INPUT_LEN*sizeof(i_type));
+
+ 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_complex (taps, MAX_TAPS);
+
+ // compute expected output values
+ memset(dline, 0, INPUT_LEN*sizeof(i_type));
+ for (int o = 0; o < (int)(ol/decimate); o++){
+ // use an actual delay line for this test
+ for(int dd = 0; dd < (int)decimate; dd++) {
+ for(int oo = INPUT_LEN-1; oo > 0; oo--)
+ dline[oo] = dline[oo-1];
+ dline[0] = input[decimate*o+dd];
+ }
+ expected_output[o] = ref_dotprod (dline, taps, n);
+ }
+
+ // build filter
+ vector<tap_type> f1_taps(&taps[0], &taps[n]);
+ gri_fir_filter_with_buffer_ccc *f1 = new gri_fir_filter_with_buffer_ccc(f1_taps);
+
+ // zero the output, then do the filtering
+ memset (actual_output, 0, sizeof (actual_output));
+ f1->filterNdec (actual_output, input, ol/decimate, decimate);
+
+ // 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 < (int)(ol/decimate); o++){
+ CPPUNIT_ASSERT_COMPLEXES_EQUAL(expected_output[o], actual_output[o],
+ sqrt((float)n)*0.25*MAX_DATA*MAX_DATA * ERR_DELTA);
+ }
+ delete f1;
+ }
+ }
+ free16Align(input);
+}
diff --git a/gnuradio-core/src/lib/filter/qa_gri_fir_filter_with_buffer_ccc.h b/gnuradio-core/src/lib/filter/qa_gri_fir_filter_with_buffer_ccc.h
new file mode 100644
index 000000000..c1f2df10c
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/qa_gri_fir_filter_with_buffer_ccc.h
@@ -0,0 +1,46 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifndef _QA_GRI_FIR_FILTER_WITH_BUFFER_CCC_H_
+#define _QA_GRI_FIR_FILTER_WITH_BUFFER_CCC_H_
+
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/TestCase.h>
+
+class qa_gri_fir_filter_with_buffer_ccc : public CppUnit::TestCase {
+
+ CPPUNIT_TEST_SUITE (qa_gri_fir_filter_with_buffer_ccc);
+ CPPUNIT_TEST (t1);
+ CPPUNIT_TEST (t2);
+ CPPUNIT_TEST (t3);
+ CPPUNIT_TEST_SUITE_END ();
+
+ private:
+ void test_decimate(unsigned int decimate);
+
+ void t1 ();
+ void t2 ();
+ void t3 ();
+
+};
+
+
+#endif /* _QA_GR_FIR_FILTER_WITH_BUFFER_CCC_H_ */
diff --git a/gnuradio-core/src/lib/filter/qa_gri_fir_filter_with_buffer_ccf.cc b/gnuradio-core/src/lib/filter/qa_gri_fir_filter_with_buffer_ccf.cc
new file mode 100644
index 000000000..9a5be0351
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/qa_gri_fir_filter_with_buffer_ccf.cc
@@ -0,0 +1,167 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <gr_types.h>
+#include <qa_gri_fir_filter_with_buffer_ccf.h>
+#include <gri_fir_filter_with_buffer_ccf.h>
+#include <string.h>
+#include <iostream>
+#include <cmath>
+#include <cppunit/TestAssert.h>
+#include <random.h>
+#include <malloc16.h>
+#include <string.h>
+
+typedef gr_complex i_type;
+typedef gr_complex o_type;
+typedef float tap_type;
+typedef gr_complex acc_type;
+
+using std::vector;
+
+#define ERR_DELTA (1e-5)
+
+#define NELEM(x) (sizeof (x) / sizeof (x[0]))
+
+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[i];
+ }
+
+ return sum;
+}
+
+void
+qa_gri_fir_filter_with_buffer_ccf::t1 ()
+{
+ test_decimate(1);
+}
+
+void
+qa_gri_fir_filter_with_buffer_ccf::t2 ()
+{
+ test_decimate(2);
+}
+
+void
+qa_gri_fir_filter_with_buffer_ccf::t3 ()
+{
+ test_decimate(5);
+}
+
+//
+// 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.
+//
+void
+qa_gri_fir_filter_with_buffer_ccf::test_decimate (unsigned int decimate)
+{
+ const int MAX_TAPS = 9;
+ const int OUTPUT_LEN = 17;
+ const int INPUT_LEN = MAX_TAPS + OUTPUT_LEN;
+
+ // Mem aligned buffer not really necessary, but why not?
+ i_type *input = (i_type *)malloc16Align(INPUT_LEN * sizeof(i_type));
+ i_type *dline = (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
+ memset(dline, 0, INPUT_LEN*sizeof(i_type));
+
+ 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
+ memset(dline, 0, INPUT_LEN*sizeof(i_type));
+ for (int o = 0; o < (int)(ol/decimate); o++){
+ // use an actual delay line for this test
+ for(int dd = 0; dd < (int)decimate; dd++) {
+ for(int oo = INPUT_LEN-1; oo > 0; oo--)
+ dline[oo] = dline[oo-1];
+ dline[0] = input[decimate*o+dd];
+ }
+ expected_output[o] = ref_dotprod (dline, taps, n);
+ }
+
+ // build filter
+ vector<tap_type> f1_taps(&taps[0], &taps[n]);
+ gri_fir_filter_with_buffer_ccf *f1 = new gri_fir_filter_with_buffer_ccf(f1_taps);
+
+ // zero the output, then do the filtering
+ memset (actual_output, 0, sizeof (actual_output));
+ f1->filterNdec (actual_output, input, ol/decimate, decimate);
+
+ // 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 < (int)(ol/decimate); o++){
+ CPPUNIT_ASSERT_COMPLEXES_EQUAL(expected_output[o], actual_output[o],
+ abs (expected_output[o]) * ERR_DELTA);
+ }
+ delete f1;
+ }
+ }
+ free16Align(input);
+}
diff --git a/gnuradio-core/src/lib/filter/qa_gri_fir_filter_with_buffer_ccf.h b/gnuradio-core/src/lib/filter/qa_gri_fir_filter_with_buffer_ccf.h
new file mode 100644
index 000000000..686bc8541
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/qa_gri_fir_filter_with_buffer_ccf.h
@@ -0,0 +1,46 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifndef _QA_GRI_FIR_FILTER_WITH_BUFFER_CCF_H_
+#define _QA_GRI_FIR_FILTER_WITH_BUFFER_CCF_H_
+
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/TestCase.h>
+
+class qa_gri_fir_filter_with_buffer_ccf : public CppUnit::TestCase {
+
+ CPPUNIT_TEST_SUITE (qa_gri_fir_filter_with_buffer_ccf);
+ CPPUNIT_TEST (t1);
+ CPPUNIT_TEST (t2);
+ CPPUNIT_TEST (t3);
+ CPPUNIT_TEST_SUITE_END ();
+
+ private:
+ void test_decimate(unsigned int decimate);
+
+ void t1 ();
+ void t2 ();
+ void t3 ();
+
+};
+
+
+#endif /* _QA_GR_FIR_FILTER_WITH_BUFFER_CCF_H_ */
diff --git a/gnuradio-core/src/lib/filter/qa_gri_fir_filter_with_buffer_fcc.cc b/gnuradio-core/src/lib/filter/qa_gri_fir_filter_with_buffer_fcc.cc
new file mode 100644
index 000000000..583697165
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/qa_gri_fir_filter_with_buffer_fcc.cc
@@ -0,0 +1,168 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <gr_types.h>
+#include <qa_gri_fir_filter_with_buffer_fcc.h>
+#include <gri_fir_filter_with_buffer_fcc.h>
+#include <string.h>
+#include <iostream>
+#include <cmath>
+#include <cppunit/TestAssert.h>
+#include <random.h>
+#include <malloc16.h>
+#include <string.h>
+
+typedef float i_type;
+typedef gr_complex o_type;
+typedef gr_complex tap_type;
+typedef gr_complex acc_type;
+
+using std::vector;
+
+#define ERR_DELTA (1e-5)
+
+#define NELEM(x) (sizeof (x) / sizeof (x[0]))
+
+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[i];
+ }
+
+ return sum;
+}
+
+void
+qa_gri_fir_filter_with_buffer_fcc::t1()
+{
+ test_decimate(1);
+}
+
+void
+qa_gri_fir_filter_with_buffer_fcc::t2()
+{
+ test_decimate(2);
+}
+
+void
+qa_gri_fir_filter_with_buffer_fcc::t3()
+{
+ test_decimate(5);
+}
+
+
+//
+// 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.
+//
+void
+qa_gri_fir_filter_with_buffer_fcc::test_decimate(unsigned int decimate)
+{
+ const int MAX_TAPS = 9;
+ const int OUTPUT_LEN = 17;
+ const int INPUT_LEN = MAX_TAPS + OUTPUT_LEN;
+
+ // Mem aligned buffer not really necessary, but why not?
+ i_type *input = (i_type *)malloc16Align(INPUT_LEN * sizeof(i_type));
+ i_type *dline = (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
+ memset(dline, 0, INPUT_LEN*sizeof(i_type));
+
+ 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_complex (taps, MAX_TAPS);
+
+ // compute expected output values
+ memset(dline, 0, INPUT_LEN*sizeof(i_type));
+ for (int o = 0; o < (int)(ol/decimate); o++){
+ // use an actual delay line for this test
+ for(int dd = 0; dd < (int)decimate; dd++) {
+ for(int oo = INPUT_LEN-1; oo > 0; oo--)
+ dline[oo] = dline[oo-1];
+ dline[0] = input[decimate*o+dd];
+ }
+ expected_output[o] = ref_dotprod (dline, taps, n);
+ }
+
+ // build filter
+ vector<tap_type> f1_taps(&taps[0], &taps[n]);
+ gri_fir_filter_with_buffer_fcc *f1 = new gri_fir_filter_with_buffer_fcc(f1_taps);
+
+ // zero the output, then do the filtering
+ memset (actual_output, 0, sizeof (actual_output));
+ f1->filterNdec (actual_output, input, ol/decimate, decimate);
+
+ // 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 < (int)(ol/decimate); o++){
+ CPPUNIT_ASSERT_COMPLEXES_EQUAL(expected_output[o], actual_output[o],
+ abs (expected_output[o]) * ERR_DELTA);
+ }
+ delete f1;
+ }
+ }
+ free16Align(input);
+}
diff --git a/gnuradio-core/src/lib/filter/qa_gri_fir_filter_with_buffer_fcc.h b/gnuradio-core/src/lib/filter/qa_gri_fir_filter_with_buffer_fcc.h
new file mode 100644
index 000000000..64eed25d3
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/qa_gri_fir_filter_with_buffer_fcc.h
@@ -0,0 +1,46 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifndef _QA_GRI_FIR_FILTER_WITH_BUFFER_FCC_H_
+#define _QA_GRI_FIR_FILTER_WITH_BUFFER_FCC_H_
+
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/TestCase.h>
+
+class qa_gri_fir_filter_with_buffer_fcc : public CppUnit::TestCase {
+
+ CPPUNIT_TEST_SUITE (qa_gri_fir_filter_with_buffer_fcc);
+ CPPUNIT_TEST (t1);
+ CPPUNIT_TEST (t2);
+ CPPUNIT_TEST (t3);
+ CPPUNIT_TEST_SUITE_END ();
+
+ private:
+ void test_decimate(unsigned int decimate);
+
+ void t1 ();
+ void t2 ();
+ void t3 ();
+
+};
+
+
+#endif /* _QA_GR_FIR_FILTER_WITH_BUFFER_FCC_H_ */
diff --git a/gnuradio-core/src/lib/filter/qa_gri_fir_filter_with_buffer_fff.cc b/gnuradio-core/src/lib/filter/qa_gri_fir_filter_with_buffer_fff.cc
new file mode 100644
index 000000000..208ae01db
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/qa_gri_fir_filter_with_buffer_fff.cc
@@ -0,0 +1,156 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <gr_types.h>
+#include <qa_gri_fir_filter_with_buffer_fff.h>
+#include <gri_fir_filter_with_buffer_fff.h>
+#include <string.h>
+#include <iostream>
+#include <cmath>
+#include <cppunit/TestAssert.h>
+#include <random.h>
+#include <malloc16.h>
+#include <string.h>
+
+typedef float i_type;
+typedef float o_type;
+typedef float tap_type;
+typedef float acc_type;
+
+using std::vector;
+
+#define ERR_DELTA (1e-5)
+
+#define NELEM(x) (sizeof (x) / sizeof (x[0]))
+
+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 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[i];
+ }
+ return sum;
+}
+
+void
+qa_gri_fir_filter_with_buffer_fff::t1 ()
+{
+ test_decimate(1);
+}
+
+void
+qa_gri_fir_filter_with_buffer_fff::t2 ()
+{
+ test_decimate(2);
+}
+
+void
+qa_gri_fir_filter_with_buffer_fff::t3 ()
+{
+ test_decimate(5);
+}
+
+//
+// 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.
+//
+void
+qa_gri_fir_filter_with_buffer_fff::test_decimate(unsigned int decimate)
+{
+ const int MAX_TAPS = 9;
+ const int OUTPUT_LEN = 17;
+ const int INPUT_LEN = MAX_TAPS + OUTPUT_LEN;
+
+ // Mem aligned buffer not really necessary, but why not?
+ i_type *input = (i_type *)malloc16Align(INPUT_LEN * sizeof(i_type));
+ i_type *dline = (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
+ memset(dline, 0, INPUT_LEN*sizeof(i_type));
+
+ 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
+ memset(dline, 0, INPUT_LEN*sizeof(i_type));
+ for (int o = 0; o < (int)(ol/decimate); o++){
+ // use an actual delay line for this test
+ for(int dd = 0; dd < (int)decimate; dd++) {
+ for(int oo = INPUT_LEN-1; oo > 0; oo--)
+ dline[oo] = dline[oo-1];
+ dline[0] = input[decimate*o+dd];
+ }
+ expected_output[o] = ref_dotprod (dline, taps, n);
+ }
+
+ // build filter
+ vector<tap_type> f1_taps(&taps[0], &taps[n]);
+ gri_fir_filter_with_buffer_fff *f1 = new gri_fir_filter_with_buffer_fff(f1_taps);
+
+ // zero the output, then do the filtering
+ memset (actual_output, 0, sizeof (actual_output));
+ f1->filterNdec (actual_output, input, ol/decimate, decimate);
+
+ // 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 < (int)(ol/decimate); o++){
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(expected_output[o], actual_output[o],
+ fabsf (expected_output[o]) * ERR_DELTA);
+ }
+ delete f1;
+ }
+ }
+ free16Align(input);
+}
diff --git a/gnuradio-core/src/lib/filter/qa_gri_fir_filter_with_buffer_fff.h b/gnuradio-core/src/lib/filter/qa_gri_fir_filter_with_buffer_fff.h
new file mode 100644
index 000000000..d219ec72d
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/qa_gri_fir_filter_with_buffer_fff.h
@@ -0,0 +1,46 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifndef _QA_GRI_FIR_FILTER_WITH_BUFFER_FFF_H_
+#define _QA_GRI_FIR_FILTER_WITH_BUFFER_FFF_H_
+
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/TestCase.h>
+
+class qa_gri_fir_filter_with_buffer_fff : public CppUnit::TestCase {
+
+ CPPUNIT_TEST_SUITE (qa_gri_fir_filter_with_buffer_fff);
+ CPPUNIT_TEST (t1);
+ CPPUNIT_TEST (t2);
+ CPPUNIT_TEST (t3);
+ CPPUNIT_TEST_SUITE_END ();
+
+ private:
+ void test_decimate(unsigned int decimate);
+
+ void t1 ();
+ void t2 ();
+ void t3 ();
+
+};
+
+
+#endif /* _QA_GR_FIR_FILTER_WITH_BUFFER_FFF_H_ */
diff --git a/gnuradio-core/src/lib/filter/qa_gri_fir_filter_with_buffer_fsf.cc b/gnuradio-core/src/lib/filter/qa_gri_fir_filter_with_buffer_fsf.cc
new file mode 100644
index 000000000..e2b6fb04f
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/qa_gri_fir_filter_with_buffer_fsf.cc
@@ -0,0 +1,147 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <gr_types.h>
+#include <qa_gri_fir_filter_with_buffer_fsf.h>
+#include <gri_fir_filter_with_buffer_fsf.h>
+#include <string.h>
+#include <iostream>
+#include <cmath>
+#include <cppunit/TestAssert.h>
+#include <random.h>
+#include <malloc16.h>
+#include <string.h>
+
+typedef float i_type;
+typedef short o_type;
+typedef float tap_type;
+typedef float acc_type;
+
+using std::vector;
+
+#define NELEM(x) (sizeof (x) / sizeof (x[0]))
+
+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 () * 128);
+}
+
+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[i];
+ }
+ return (o_type)sum;
+}
+
+void
+qa_gri_fir_filter_with_buffer_fsf::t1 ()
+{
+ test_decimate(1);
+}
+
+void
+qa_gri_fir_filter_with_buffer_fsf::t2 ()
+{
+ test_decimate(2);
+}
+
+void
+qa_gri_fir_filter_with_buffer_fsf::t3 ()
+{
+ test_decimate(5);
+}
+
+//
+// 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.
+//
+void
+qa_gri_fir_filter_with_buffer_fsf::test_decimate (unsigned int decimate)
+{
+ const int MAX_TAPS = 9;
+ const int OUTPUT_LEN = 17;
+ const int INPUT_LEN = MAX_TAPS + OUTPUT_LEN;
+
+ // Mem aligned buffer not really necessary, but why not?
+ i_type *input = (i_type *)malloc16Align(INPUT_LEN * sizeof(i_type));
+ i_type *dline = (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
+ memset(dline, 0, INPUT_LEN*sizeof(i_type));
+
+ 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
+ memset(dline, 0, INPUT_LEN*sizeof(i_type));
+ for (int o = 0; o < (int)(ol/decimate); o++){
+ // use an actual delay line for this test
+ for(int dd = 0; dd < (int)decimate; dd++) {
+ for(int oo = INPUT_LEN-1; oo > 0; oo--)
+ dline[oo] = dline[oo-1];
+ dline[0] = input[decimate*o+dd];
+ }
+ expected_output[o] = ref_dotprod (dline, taps, n);
+ }
+
+ // build filter
+ vector<tap_type> f1_taps(&taps[0], &taps[n]);
+ gri_fir_filter_with_buffer_fsf *f1 = new gri_fir_filter_with_buffer_fsf(f1_taps);
+
+ // zero the output, then do the filtering
+ memset (actual_output, 0, sizeof (actual_output));
+ f1->filterNdec (actual_output, input, ol/decimate, decimate);
+
+ // check results
+ for (int o = 0; o < (int)(ol/decimate); o++){
+ CPPUNIT_ASSERT_EQUAL(expected_output[o], actual_output[o]);
+ }
+ delete f1;
+ }
+ }
+ free16Align(input);
+}
diff --git a/gnuradio-core/src/lib/filter/qa_gri_fir_filter_with_buffer_fsf.h b/gnuradio-core/src/lib/filter/qa_gri_fir_filter_with_buffer_fsf.h
new file mode 100644
index 000000000..70030a072
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/qa_gri_fir_filter_with_buffer_fsf.h
@@ -0,0 +1,46 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifndef _QA_GRI_FIR_FILTER_WITH_BUFFER_FSF_H_
+#define _QA_GRI_FIR_FILTER_WITH_BUFFER_FSF_H_
+
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/TestCase.h>
+
+class qa_gri_fir_filter_with_buffer_fsf : public CppUnit::TestCase {
+
+ CPPUNIT_TEST_SUITE (qa_gri_fir_filter_with_buffer_fsf);
+ CPPUNIT_TEST (t1);
+ CPPUNIT_TEST (t2);
+ CPPUNIT_TEST (t3);
+ CPPUNIT_TEST_SUITE_END ();
+
+ private:
+ void test_decimate(unsigned int decimate);
+
+ void t1 ();
+ void t2 ();
+ void t3 ();
+
+};
+
+
+#endif /* _QA_GR_FIR_FILTER_WITH_BUFFER_FSF_H_ */
diff --git a/gnuradio-core/src/lib/filter/qa_gri_fir_filter_with_buffer_scc.cc b/gnuradio-core/src/lib/filter/qa_gri_fir_filter_with_buffer_scc.cc
new file mode 100644
index 000000000..15f8b1f95
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/qa_gri_fir_filter_with_buffer_scc.cc
@@ -0,0 +1,167 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <gr_types.h>
+#include <qa_gri_fir_filter_with_buffer_scc.h>
+#include <gri_fir_filter_with_buffer_scc.h>
+#include <string.h>
+#include <iostream>
+#include <cmath>
+#include <cppunit/TestAssert.h>
+#include <random.h>
+#include <malloc16.h>
+#include <string.h>
+
+typedef short i_type;
+typedef gr_complex o_type;
+typedef gr_complex tap_type;
+typedef gr_complex acc_type;
+
+using std::vector;
+
+#define ERR_DELTA (1e-5)
+
+#define NELEM(x) (sizeof (x) / sizeof (x[0]))
+
+static float
+uniform ()
+{
+ return 2.0 * ((float) random () / RANDOM_MAX - 0.5); // uniformly (-1, 1)
+}
+
+static void
+random_shorts (short *buf, unsigned n)
+{
+ for (unsigned i = 0; i < n; i++)
+ buf[i] = (short) rint (uniform () * 16384);
+}
+
+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[i];
+ }
+
+ return sum;
+}
+
+void
+qa_gri_fir_filter_with_buffer_scc::t1 ()
+{
+ test_decimate(1);
+}
+
+void
+qa_gri_fir_filter_with_buffer_scc::t2 ()
+{
+ test_decimate(2);
+}
+
+void
+qa_gri_fir_filter_with_buffer_scc::t3 ()
+{
+ test_decimate(5);
+}
+
+//
+// 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.
+//
+void
+qa_gri_fir_filter_with_buffer_scc::test_decimate (unsigned int decimate)
+{
+ const int MAX_TAPS = 9;
+ const int OUTPUT_LEN = 17;
+ const int INPUT_LEN = MAX_TAPS + OUTPUT_LEN;
+
+ // Mem aligned buffer not really necessary, but why not?
+ i_type *input = (i_type *)malloc16Align(INPUT_LEN * sizeof(i_type));
+ i_type *dline = (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
+ memset(dline, 0, INPUT_LEN*sizeof(i_type));
+
+ 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_shorts (input, INPUT_LEN);
+ random_complex (taps, MAX_TAPS);
+
+ // compute expected output values
+ memset(dline, 0, INPUT_LEN*sizeof(i_type));
+ for (int o = 0; o < (int)(ol/decimate); o++){
+ // use an actual delay line for this test
+ for(int dd = 0; dd < (int)decimate; dd++) {
+ for(int oo = INPUT_LEN-1; oo > 0; oo--)
+ dline[oo] = dline[oo-1];
+ dline[0] = input[decimate*o+dd];
+ }
+ expected_output[o] = ref_dotprod (dline, taps, n);
+ }
+
+ // build filter
+ vector<tap_type> f1_taps(&taps[0], &taps[n]);
+ gri_fir_filter_with_buffer_scc *f1 = new gri_fir_filter_with_buffer_scc(f1_taps);
+
+ // zero the output, then do the filtering
+ memset (actual_output, 0, sizeof (actual_output));
+ f1->filterNdec (actual_output, input, ol/decimate, decimate);
+
+ // 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 < (int)(ol/decimate); o++){
+ CPPUNIT_ASSERT_COMPLEXES_EQUAL(expected_output[o], actual_output[o],
+ abs (expected_output[o]) * ERR_DELTA);
+ }
+ delete f1;
+ }
+ }
+ free16Align(input);
+}
diff --git a/gnuradio-core/src/lib/filter/qa_gri_fir_filter_with_buffer_scc.h b/gnuradio-core/src/lib/filter/qa_gri_fir_filter_with_buffer_scc.h
new file mode 100644
index 000000000..f80056189
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/qa_gri_fir_filter_with_buffer_scc.h
@@ -0,0 +1,46 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifndef _QA_GRI_FIR_FILTER_WITH_BUFFER_SCC_H_
+#define _QA_GRI_FIR_FILTER_WITH_BUFFER_SCC_H_
+
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/TestCase.h>
+
+class qa_gri_fir_filter_with_buffer_scc : public CppUnit::TestCase {
+
+ CPPUNIT_TEST_SUITE (qa_gri_fir_filter_with_buffer_scc);
+ CPPUNIT_TEST (t1);
+ CPPUNIT_TEST (t2);
+ CPPUNIT_TEST (t3);
+ CPPUNIT_TEST_SUITE_END ();
+
+ private:
+ void test_decimate(unsigned int decimate);
+
+ void t1 ();
+ void t2 ();
+ void t3 ();
+
+};
+
+
+#endif /* _QA_GR_FIR_FILTER_WITH_BUFFER_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
index 000000000..7dca65b9a
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/qa_gri_mmse_fir_interpolator.cc
@@ -0,0 +1,66 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#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
index 000000000..3f4dec7c2
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/qa_gri_mmse_fir_interpolator.h
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifndef _QA_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/qa_gri_mmse_fir_interpolator_cc.cc b/gnuradio-core/src/lib/filter/qa_gri_mmse_fir_interpolator_cc.cc
new file mode 100644
index 000000000..1f70d7f42
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/qa_gri_mmse_fir_interpolator_cc.cc
@@ -0,0 +1,124 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002,2007 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <gruel/attributes.h>
+#include <cppunit/TestAssert.h>
+#include <qa_gri_mmse_fir_interpolator_cc.h>
+#include <gri_mmse_fir_interpolator_cc.h>
+#include <stdio.h>
+#include <cmath>
+#include <stdexcept>
+#include <unistd.h>
+
+#define NELEM(x) (sizeof (x) / sizeof (x[0]))
+
+
+static float
+test_fcn_sin(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));
+}
+
+static float
+test_fcn_cos(double index)
+{
+ return (2 * cos (index * 0.25 * 2 * M_PI + 0.125 * M_PI)
+ + 3 * cos (index * 0.077 * 2 * M_PI + 0.3 * M_PI));
+}
+
+static gr_complex
+test_fcn(double index)
+{
+ return gr_complex(test_fcn_cos(index), test_fcn_sin(index));
+}
+
+
+void
+qa_gri_mmse_fir_interpolator_cc::t1()
+{
+ static const unsigned N = 100;
+ __GR_ATTR_ALIGNED(8) gr_complex input[N + 10];
+
+ for (unsigned i = 0; i < NELEM(input); i++)
+ input[i] = test_fcn ((double) i);
+
+ gri_mmse_fir_interpolator_cc intr;
+ float inv_nsteps = 1.0 / intr.nsteps ();
+
+ for (unsigned i = 0; i < N; i++){
+ for (unsigned imu = 0; imu <= intr.nsteps (); imu += 1){
+ gr_complex expected = test_fcn ((i + 3) + imu * inv_nsteps);
+ gr_complex actual = intr.interpolate (&input[i], imu * inv_nsteps);
+
+ CPPUNIT_ASSERT_COMPLEXES_EQUAL (expected, actual, 0.004);
+ // printf ("%9.6f %9.6f %9.6f\n", expected, actual, expected - actual);
+ }
+ }
+}
+
+
+/*
+ * Force bad alignment and confirm that it raises an exception
+ */
+void
+qa_gri_mmse_fir_interpolator_cc::t2_body()
+{
+ static const unsigned N = 100;
+ float float_input[2*(N+10) + 1];
+ gr_complex *input;
+
+ // We require that gr_complex be aligned on an 8-byte boundary.
+ // Ensure that we ARE NOT ;)
+
+ if (((intptr_t) float_input & 0x7) == 0)
+ input = reinterpret_cast<gr_complex *>(&float_input[1]);
+ else
+ input = reinterpret_cast<gr_complex *>(&float_input[0]);
+
+
+ for (unsigned i = 0; i < (N+10); i++)
+ input[i] = test_fcn ((double) i);
+
+ gri_mmse_fir_interpolator_cc intr;
+ float inv_nsteps = 1.0 / intr.nsteps ();
+
+ for (unsigned i = 0; i < N; i++){
+ for (unsigned imu = 0; imu <= intr.nsteps (); imu += 1){
+ gr_complex expected = test_fcn ((i + 3) + imu * inv_nsteps);
+ gr_complex actual = intr.interpolate (&input[i], imu * inv_nsteps);
+
+ CPPUNIT_ASSERT_COMPLEXES_EQUAL (expected, actual, 0.004);
+ // printf ("%9.6f %9.6f %9.6f\n", expected, actual, expected - actual);
+ }
+ }
+}
+
+void
+qa_gri_mmse_fir_interpolator_cc::t2()
+{
+ CPPUNIT_ASSERT_THROW(t2_body(), std::invalid_argument);
+}
diff --git a/gnuradio-core/src/lib/filter/qa_gri_mmse_fir_interpolator_cc.h b/gnuradio-core/src/lib/filter/qa_gri_mmse_fir_interpolator_cc.h
new file mode 100644
index 000000000..6be3d9743
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/qa_gri_mmse_fir_interpolator_cc.h
@@ -0,0 +1,42 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002,2007 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifndef _QA_GRI_MMSE_FIR_INTERPOLATOR_CC_H_
+#define _QA_GRI_MMSE_FIR_INTERPOLATOR_CC_H_
+
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/TestCase.h>
+
+class qa_gri_mmse_fir_interpolator_cc : public CppUnit::TestCase {
+
+ CPPUNIT_TEST_SUITE(qa_gri_mmse_fir_interpolator_cc);
+ CPPUNIT_TEST(t1);
+ // CPPUNIT_TEST(t2);
+ CPPUNIT_TEST_SUITE_END();
+
+ private:
+ void t1();
+ void t2();
+ void t2_body();
+
+};
+
+#endif /* _QA_GRI_MMSE_FIR_INTERPOLATOR_CC_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
index 000000000..49a9c0483
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/short_dotprod_generic.c
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "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
index 000000000..e7d977a00
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/short_dotprod_generic.h
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef _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
index 000000000..0f6801e4b
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/short_dotprod_mmx.S
@@ -0,0 +1,117 @@
+#
+# Copyright 2002 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, 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"
+
+#if defined(__linux__) && defined(__ELF__)
+.section .note.GNU-stack,"",%progbits
+#endif
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
index 000000000..bafd0e04e
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/short_dotprod_mmx64.S
@@ -0,0 +1,105 @@
+#
+# 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 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, 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"
+
+#if defined(__linux__) && defined(__ELF__)
+.section .note.GNU-stack,"",%progbits
+#endif
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
index 000000000..13d5ae2a3
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/short_dotprod_x86.h
@@ -0,0 +1,44 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef _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
index 000000000..870cc0543
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/sse_debug.c
@@ -0,0 +1,62 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+#include <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
index 000000000..b19b4e646
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/sse_debug.h
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef _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_armv7_a.cc b/gnuradio-core/src/lib/filter/sysconfig_armv7_a.cc
new file mode 100644
index 000000000..2c415863b
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/sysconfig_armv7_a.cc
@@ -0,0 +1,39 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002,2008,2009 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <gr_fir_sysconfig_armv7_a.h>
+
+gr_fir_sysconfig *
+gr_fir_sysconfig_singleton ()
+{
+ static gr_fir_sysconfig *singleton = 0;
+
+ if (singleton)
+ return singleton;
+
+ singleton = new gr_fir_sysconfig_armv7_a ();
+ return singleton;
+}
diff --git a/gnuradio-core/src/lib/filter/sysconfig_generic.cc b/gnuradio-core/src/lib/filter/sysconfig_generic.cc
new file mode 100644
index 000000000..88508f62b
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/sysconfig_generic.cc
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <gr_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_powerpc.cc b/gnuradio-core/src/lib/filter/sysconfig_powerpc.cc
new file mode 100644
index 000000000..911beae2a
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/sysconfig_powerpc.cc
@@ -0,0 +1,38 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002,2008 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <gr_fir_sysconfig_powerpc.h>
+
+gr_fir_sysconfig *
+gr_fir_sysconfig_singleton ()
+{
+ static gr_fir_sysconfig *singleton = 0;
+
+ if (singleton)
+ return singleton;
+
+ singleton = new gr_fir_sysconfig_powerpc ();
+ 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
index 000000000..582df0ab7
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/sysconfig_x86.cc
@@ -0,0 +1,38 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#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/general/CMakeLists.txt b/gnuradio-core/src/lib/general/CMakeLists.txt
new file mode 100644
index 000000000..ce9a80f37
--- /dev/null
+++ b/gnuradio-core/src/lib/general/CMakeLists.txt
@@ -0,0 +1,312 @@
+# Copyright 2010-2012 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+
+########################################################################
+# This file included, use CMake directory variables
+########################################################################
+
+########################################################################
+# Handle the generated sine table
+########################################################################
+add_custom_command(
+ OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/sine_table.h
+ DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/gen_sine_table.py
+ COMMAND ${PYTHON_EXECUTABLE}
+ ${CMAKE_CURRENT_SOURCE_DIR}/gen_sine_table.py >
+ ${CMAKE_CURRENT_BINARY_DIR}/sine_table.h
+)
+
+include(AddFileDependencies)
+ADD_FILE_DEPENDENCIES(${CMAKE_CURRENT_SOURCE_DIR}/gr_fxpt.cc
+ ${CMAKE_CURRENT_BINARY_DIR}/sine_table.h
+)
+
+add_custom_target(general_generated DEPENDS
+ ${CMAKE_CURRENT_BINARY_DIR}/sine_table.h
+)
+
+########################################################################
+# Handle the generated constants
+########################################################################
+execute_process(COMMAND ${PYTHON_EXECUTABLE} -c
+ "import time;print time.strftime('%a, %d %b %Y %H:%M:%S', time.gmtime())"
+ OUTPUT_VARIABLE BUILD_DATE OUTPUT_STRIP_TRAILING_WHITESPACE
+)
+message(STATUS "Loading build date ${BUILD_DATE} into gr_constants...")
+
+message(STATUS "Loading version ${VERSION} into gr_constants...")
+
+#double escape for windows backslash path separators
+string(REPLACE "\\" "\\\\" prefix ${prefix})
+string(REPLACE "\\" "\\\\" SYSCONFDIR ${SYSCONFDIR})
+string(REPLACE "\\" "\\\\" GR_PREFSDIR ${GR_PREFSDIR})
+
+configure_file(
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_constants.cc.in
+ ${CMAKE_CURRENT_BINARY_DIR}/gr_constants.cc
+@ONLY)
+
+list(APPEND gnuradio_core_sources ${CMAKE_CURRENT_BINARY_DIR}/gr_constants.cc)
+
+########################################################################
+# Append gnuradio-core library sources
+########################################################################
+list(APPEND gnuradio_core_sources
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_circular_file.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_count_bits.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_fast_atan2f.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_fft_vcc_fftw.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_fxpt.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_misc.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_random.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_reverse.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/gri_add_const_ss_generic.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/gri_char_to_float.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/gri_control_loop.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/gri_debugger_hook.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/gri_fft.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/gri_float_to_char.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/gri_float_to_int.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/gri_float_to_short.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/gri_float_to_uchar.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/gri_glfsr.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/gri_interleaved_short_to_complex.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/gri_int_to_float.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/gri_short_to_float.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/gri_uchar_to_float.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/malloc16.c
+)
+
+########################################################################
+# Append gnuradio-core test sources
+########################################################################
+list(APPEND test_gnuradio_core_sources
+ ${CMAKE_CURRENT_SOURCE_DIR}/qa_general.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/qa_gr_circular_file.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/qa_gr_cpm.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/qa_gr_firdes.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/qa_gr_fxpt.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/qa_gr_fxpt_nco.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/qa_gr_fxpt_vco.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/qa_gr_math.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/qa_gri_lfsr.cc
+)
+
+########################################################################
+# Install runtime headers
+########################################################################
+install(FILES
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_core_api.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_circular_file.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_constants.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_count_bits.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_expj.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_fft_vcc_fftw.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_fxpt.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_fxpt_nco.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_fxpt_vco.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_log2_const.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_math.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_misc.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_nco.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_random.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_reverse.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_simple_framer_sync.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_test_types.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_vco.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/gri_add_const_ss.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/gri_agc_cc.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/gri_agc_ff.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/gri_agc2_cc.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/gri_agc2_ff.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/gri_char_to_float.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/gri_control_loop.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/gri_debugger_hook.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/gri_fft.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/gri_float_to_char.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/gri_float_to_int.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/gri_float_to_short.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/gri_float_to_uchar.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/gri_lfsr.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/gri_glfsr.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/gri_interleaved_short_to_complex.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/gri_lfsr_15_1_0.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/gri_lfsr_32k.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/gri_int_to_float.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/gri_short_to_float.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/gri_uchar_to_float.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/malloc16.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/random.h
+ DESTINATION ${GR_INCLUDE_DIR}/gnuradio
+ COMPONENT "core_devel"
+)
+
+########################################################################
+# Install swig headers
+########################################################################
+if(ENABLE_PYTHON)
+install(FILES
+ ${CMAKE_CURRENT_SOURCE_DIR}/general.i
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_constants.i
+ ${CMAKE_CURRENT_SOURCE_DIR}/gri_agc_cc.i
+ ${CMAKE_CURRENT_SOURCE_DIR}/gri_agc_ff.i
+ ${CMAKE_CURRENT_SOURCE_DIR}/gri_agc2_cc.i
+ ${CMAKE_CURRENT_SOURCE_DIR}/gri_agc2_ff.i
+ ${CMAKE_CURRENT_SOURCE_DIR}/gri_control_loop.i
+ DESTINATION ${GR_INCLUDE_DIR}/gnuradio/swig
+ COMPONENT "core_swig"
+)
+endif(ENABLE_PYTHON)
+
+########################################################################
+# Handle triple-threat files that have cc, h, and i
+########################################################################
+set(gr_core_general_triple_threats
+ complex_vec_test
+ gr_add_ff
+ gr_additive_scrambler_bb
+ gr_agc_cc
+ gr_agc_ff
+ gr_agc2_cc
+ gr_agc2_ff
+ gr_align_on_samplenumbers_ss
+ gr_bin_statistics_f
+ gr_block_gateway
+ gr_bytes_to_syms
+ gr_char_to_float
+ gr_char_to_short
+ gr_check_counting_s
+ gr_check_lfsr_32k_s
+ gr_complex_to_interleaved_short
+ gr_complex_to_xxx
+ gr_conjugate_cc
+ gr_copy
+ gr_cpfsk_bc
+ gr_cpm
+ gr_ctcss_squelch_ff
+ gr_decode_ccsds_27_fb
+ gr_diff_decoder_bb
+ gr_diff_encoder_bb
+ gr_diff_phasor_cc
+ gr_dpll_bb
+ gr_deinterleave
+ gr_delay
+ gr_encode_ccsds_27_bb
+ gr_endian_swap
+ gr_fake_channel_coder_pp
+ gr_feedforward_agc_cc
+ gr_feval
+ gr_fft_vcc
+ gr_fft_vfc
+ gr_firdes
+ gr_float_to_char
+ gr_float_to_complex
+ gr_float_to_int
+ gr_float_to_short
+ gr_float_to_uchar
+ gr_fmdet_cf
+ gr_frequency_modulator_fc
+ gr_framer_sink_1
+ gr_glfsr_source_b
+ gr_glfsr_source_f
+ gr_head
+ gr_int_to_float
+ gr_interleave
+ gr_interleaved_short_to_complex
+ gr_iqcomp_cc
+ gr_keep_one_in_n
+ gr_keep_m_in_n
+ gr_kludge_copy
+ gr_lfsr_32k_source_s
+ gr_map_bb
+ gr_multiply_cc
+ gr_multiply_ff
+ gr_multiply_const_cc
+ gr_multiply_const_ff
+ gr_multiply_conjugate_cc
+ gr_nlog10_ff
+ gr_nop
+ gr_null_sink
+ gr_null_source
+ gr_pa_2x2_phase_combiner
+ gr_packet_sink
+ gr_peak_detector2_fb
+ gr_phase_modulator_fc
+ gr_pll_carriertracking_cc
+ gr_pll_freqdet_cf
+ gr_pll_refout_cc
+ gr_pn_correlator_cc
+ gr_prefs
+ gr_probe_avg_mag_sqrd_c
+ gr_probe_avg_mag_sqrd_cf
+ gr_probe_avg_mag_sqrd_f
+ gr_pwr_squelch_cc
+ gr_pwr_squelch_ff
+ gr_quadrature_demod_cf
+ gr_random_pdu
+ gr_rail_ff
+ gr_regenerate_bb
+ gr_remez
+ gr_rms_cf
+ gr_rms_ff
+ gr_repeat
+ gr_short_to_float
+ gr_short_to_char
+ gr_simple_correlator
+ gr_simple_framer
+ gr_simple_squelch_cc
+ gr_skiphead
+ gr_squelch_base_cc
+ gr_squelch_base_ff
+ gr_stream_mux
+ gr_stream_to_streams
+ gr_stream_to_vector
+ gr_streams_to_stream
+ gr_streams_to_vector
+ gr_stretch_ff
+ gr_test
+ gr_threshold_ff
+ gr_throttle
+ gr_transcendental
+ gr_uchar_to_float
+ gr_vco_f
+ gr_vector_map
+ gr_vector_to_stream
+ gr_vector_to_streams
+ gr_unpack_k_bits_bb
+ gr_pack_k_bits_bb
+ gr_descrambler_bb
+ gr_scrambler_bb
+ gr_probe_density_b
+ gr_annotator_alltoall
+ gr_annotator_1to1
+ gr_annotator_raw
+ gr_burst_tagger
+ gr_correlate_access_code_tag_bb
+ gr_tag_debug
+ gr_message_strobe
+)
+
+foreach(file_tt ${gr_core_general_triple_threats})
+ list(APPEND gnuradio_core_sources ${CMAKE_CURRENT_SOURCE_DIR}/${file_tt}.cc)
+ install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/${file_tt}.h DESTINATION ${GR_INCLUDE_DIR}/gnuradio COMPONENT "core_devel")
+ if(ENABLE_PYTHON)
+ install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/${file_tt}.i DESTINATION ${GR_INCLUDE_DIR}/gnuradio/swig COMPONENT "core_swig")
+ endif(ENABLE_PYTHON)
+endforeach(file_tt ${gr_core_general_triple_threats})
diff --git a/gnuradio-core/src/lib/general/README b/gnuradio-core/src/lib/general/README
new file mode 100644
index 000000000..5fa18d7f6
--- /dev/null
+++ b/gnuradio-core/src/lib/general/README
@@ -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
index 000000000..3dc87bb0b
--- /dev/null
+++ b/gnuradio-core/src/lib/general/atsc_rrc1x.dat
@@ -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
index 000000000..94445e96e
--- /dev/null
+++ b/gnuradio-core/src/lib/general/atsc_rrc20.dat
@@ -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
index 000000000..8eae94d77
--- /dev/null
+++ b/gnuradio-core/src/lib/general/atsc_rrc2x.dat
@@ -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/complex_vec_test.cc b/gnuradio-core/src/lib/general/complex_vec_test.cc
new file mode 100644
index 000000000..99acc2f35
--- /dev/null
+++ b/gnuradio-core/src/lib/general/complex_vec_test.cc
@@ -0,0 +1,82 @@
+#include <complex_vec_test.h>
+#include <stddef.h>
+
+std::vector<std::complex<float> >
+complex_vec_test0()
+{
+ std::vector<std::complex<float> > r(5);
+
+ for (size_t i = 0; i < r.size(); i++)
+ r[i] = std::complex<float>(i, i);
+
+ return r;
+}
+
+std::vector<std::complex<float> >
+complex_vec_test1(const std::vector<std::complex<float> > &input)
+{
+ std::vector<std::complex<float> > r(input.size());
+
+ for (size_t i = 0; i < input.size(); i++)
+ r[i] = std::complex<float>(input[i].real()+0.5, input[i].imag()-0.5);
+
+ return r;
+}
+
+std::complex<float>
+complex_scalar_test0()
+{
+ return std::complex<float>(5, 5);
+}
+
+std::complex<float>
+complex_scalar_test1(std::complex<float> input)
+{
+ return std::complex<float>(input.real()+0.5, input.imag()-0.5);
+}
+
+
+std::vector<float>
+float_vec_test0()
+{
+ std::vector<float> r(5);
+
+ for (size_t i = 0; i < r.size(); i++)
+ r[i] = (float) i;
+
+ return r;
+}
+
+std::vector<float>
+float_vec_test1(const std::vector<float> &input)
+{
+ std::vector<float> r(input.size());
+
+ for (size_t i = 0; i < input.size(); i++)
+ r[i] = input[i] + 0.5;
+
+ return r;
+}
+
+std::vector<int>
+int_vec_test0()
+{
+ std::vector<int> r(5);
+
+ for (size_t i = 0; i < r.size(); i++)
+ r[i] = (int) i;
+
+ return r;
+}
+
+std::vector<int>
+int_vec_test1(const std::vector<int> &input)
+{
+ std::vector<int> r(input.size());
+
+ for (size_t i = 0; i < input.size(); i++)
+ r[i] = input[i] + 1;
+
+ return r;
+}
+
diff --git a/gnuradio-core/src/lib/general/complex_vec_test.h b/gnuradio-core/src/lib/general/complex_vec_test.h
new file mode 100644
index 000000000..be4de41fb
--- /dev/null
+++ b/gnuradio-core/src/lib/general/complex_vec_test.h
@@ -0,0 +1,28 @@
+#include <gr_core_api.h>
+#include <vector>
+#include <complex>
+
+GR_CORE_API std::vector<std::complex<float> >
+complex_vec_test0();
+
+GR_CORE_API std::vector<std::complex<float> >
+complex_vec_test1(const std::vector<std::complex<float> > &input);
+
+GR_CORE_API std::complex<float>
+complex_scalar_test0();
+
+GR_CORE_API std::complex<float>
+complex_scalar_test1(std::complex<float> input);
+
+GR_CORE_API std::vector<int>
+int_vec_test0();
+
+GR_CORE_API std::vector<int>
+int_vec_test1(const std::vector<int> &input);
+
+GR_CORE_API std::vector<float>
+float_vec_test0();
+
+GR_CORE_API std::vector<float>
+float_vec_test1(const std::vector<float> &input);
+
diff --git a/gnuradio-core/src/lib/general/complex_vec_test.i b/gnuradio-core/src/lib/general/complex_vec_test.i
new file mode 100644
index 000000000..4b95633be
--- /dev/null
+++ b/gnuradio-core/src/lib/general/complex_vec_test.i
@@ -0,0 +1,25 @@
+
+std::vector<std::complex<float> >
+complex_vec_test0();
+
+std::vector<std::complex<float> >
+complex_vec_test1(const std::vector<std::complex<float> > &input);
+
+std::complex<float>
+complex_scalar_test0();
+
+std::complex<float>
+complex_scalar_test1(std::complex<float> input);
+
+std::vector<int>
+int_vec_test0();
+
+std::vector<int>
+int_vec_test1(const std::vector<int> &input);
+
+std::vector<float>
+float_vec_test0();
+
+std::vector<float>
+float_vec_test1(const std::vector<float> &input);
+
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
index 000000000..d7d11eff1
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gen_sine_table.py
@@ -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 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+import math
+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
index 000000000..b727bc8a6
--- /dev/null
+++ b/gnuradio-core/src/lib/general/general.i
@@ -0,0 +1,273 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004-2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+%{
+
+#include <gri_control_loop.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_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_keep_m_in_n.h>
+#include <gr_fft_vcc.h>
+#include <gr_fft_vfc.h>
+#include <gr_float_to_int.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_short_to_char.h>
+#include <gr_int_to_float.h>
+#include <gr_char_to_float.h>
+#include <gr_char_to_short.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_endian_swap.h>
+#include <gr_firdes.h>
+#include <gr_interleave.h>
+#include <gr_deinterleave.h>
+#include <gr_delay.h>
+#include <gr_simple_squelch_cc.h>
+#include <gr_agc_ff.h>
+#include <gr_agc_cc.h>
+#include <gr_agc2_ff.h>
+#include <gr_agc2_cc.h>
+#include <gr_random_pdu.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_transcendental.h>
+#include <gr_stream_mux.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_threshold_ff.h>
+#include <gr_packet_sink.h>
+#include <gr_dpll_bb.h>
+#include <gr_fmdet_cf.h>
+#include <gr_pll_freqdet_cf.h>
+#include <gr_pll_refout_cc.h>
+#include <gr_pll_carriertracking_cc.h>
+#include <gr_pn_correlator_cc.h>
+#include <gr_probe_avg_mag_sqrd_c.h>
+#include <gr_probe_avg_mag_sqrd_cf.h>
+#include <gr_probe_avg_mag_sqrd_f.h>
+#include <gr_regenerate_bb.h>
+#include <gr_pa_2x2_phase_combiner.h>
+#include <gr_kludge_copy.h>
+#include <gr_prefs.h>
+#include <gr_constants.h>
+#include <gr_test_types.h>
+#include <gr_test.h>
+#include <gr_unpack_k_bits_bb.h>
+#include <gr_pack_k_bits_bb.h>
+#include <gr_diff_phasor_cc.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_multiply_cc.h>
+#include <gr_multiply_ff.h>
+#include <gr_multiply_const_cc.h>
+#include <gr_multiply_const_ff.h>
+#include <gr_multiply_conjugate_cc.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_feedforward_agc_cc.h>
+#include <gr_bin_statistics_f.h>
+#include <gr_glfsr_source_b.h>
+#include <gr_glfsr_source_f.h>
+#include <gr_peak_detector2_fb.h>
+#include <gr_repeat.h>
+#include <gr_cpfsk_bc.h>
+#include <gr_encode_ccsds_27_bb.h>
+#include <gr_decode_ccsds_27_fb.h>
+#include <gr_descrambler_bb.h>
+#include <gr_scrambler_bb.h>
+#include <gr_probe_density_b.h>
+#include <gr_rail_ff.h>
+#include <gr_stretch_ff.h>
+#include <gr_copy.h>
+#include <gr_additive_scrambler_bb.h>
+#include <complex_vec_test.h>
+#include <gr_annotator_alltoall.h>
+#include <gr_annotator_1to1.h>
+#include <gr_annotator_raw.h>
+#include <gr_burst_tagger.h>
+#include <gr_cpm.h>
+#include <gr_correlate_access_code_tag_bb.h>
+#include <gr_add_ff.h>
+#include <gr_vector_map.h>
+#include <gr_tag_debug.h>
+#include <gr_message_strobe.h>
+%}
+
+%include "gri_control_loop.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_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_keep_m_in_n.i"
+%include "gr_fft_vcc.i"
+%include "gr_fft_vfc.i"
+%include "gr_float_to_int.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_short_to_char.i"
+%include "gr_int_to_float.i"
+%include "gr_char_to_float.i"
+%include "gr_char_to_short.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_endian_swap.i"
+%include "gr_interleaved_short_to_complex.i"
+%include "gr_firdes.i"
+%include "gr_interleave.i"
+%include "gr_deinterleave.i"
+%include "gr_delay.i"
+%include "gr_simple_squelch_cc.i"
+%include "gr_agc_ff.i"
+%include "gr_agc_cc.i"
+%include "gr_agc2_ff.i"
+%include "gr_agc2_cc.i"
+%include "gr_random_pdu.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_transcendental.i"
+%include "gr_stream_mux.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_threshold_ff.i"
+%include "gr_packet_sink.i"
+%include "gr_dpll_bb.i"
+%include "gr_fmdet_cf.i"
+%include "gr_pll_freqdet_cf.i"
+%include "gr_pll_refout_cc.i"
+%include "gr_pll_carriertracking_cc.i"
+%include "gr_pn_correlator_cc.i"
+%include "gr_probe_avg_mag_sqrd_c.i"
+%include "gr_probe_avg_mag_sqrd_cf.i"
+%include "gr_probe_avg_mag_sqrd_f.i"
+%include "gr_regenerate_bb.i"
+%include "gr_pa_2x2_phase_combiner.i"
+%include "gr_kludge_copy.i"
+%include "gr_prefs.i"
+%include "gr_constants.i"
+%include "gr_test_types.h"
+%include "gr_test.i"
+%include "gr_unpack_k_bits_bb.i"
+%include "gr_pack_k_bits_bb.i"
+%include "gr_diff_phasor_cc.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_multiply_cc.i"
+%include "gr_multiply_ff.i"
+%include "gr_multiply_const_cc.i"
+%include "gr_multiply_const_ff.i"
+%include "gr_multiply_conjugate_cc.i"
+%include "gr_feval.i"
+%include "gr_pwr_squelch_cc.i"
+%include "gr_pwr_squelch_ff.i"
+%include "gr_ctcss_squelch_ff.i"
+%include "gr_feedforward_agc_cc.i"
+%include "gr_bin_statistics_f.i"
+%include "gr_glfsr_source_b.i"
+%include "gr_glfsr_source_f.i"
+%include "gr_peak_detector2_fb.i"
+%include "gr_repeat.i"
+%include "gr_cpfsk_bc.i"
+%include "gr_encode_ccsds_27_bb.i"
+%include "gr_decode_ccsds_27_fb.i"
+%include "gr_descrambler_bb.i"
+%include "gr_scrambler_bb.i"
+%include "gr_probe_density_b.i"
+%include "gr_rail_ff.i"
+%include "gr_stretch_ff.i"
+%include "gr_copy.i"
+%include "gr_additive_scrambler_bb.i"
+%include "complex_vec_test.i"
+%include "gr_annotator_alltoall.i"
+%include "gr_annotator_1to1.i"
+%include "gr_annotator_raw.i"
+%include "gr_burst_tagger.i"
+%include "gr_cpm.i"
+%include "gr_correlate_access_code_tag_bb.i"
+%include "gr_add_ff.i"
+%include "gr_vector_map.i"
+%include "gr_tag_debug.i"
+%include "gr_block_gateway.i"
+%include "gr_message_strobe.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
index 000000000..89b7e1776
--- /dev/null
+++ b/gnuradio-core/src/lib/general/general_generated.i
@@ -0,0 +1,166 @@
+//
+// 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_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_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_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_probe_signal_b.h>
+#include <gr_probe_signal_s.h>
+#include <gr_probe_signal_i.h>
+#include <gr_probe_signal_f.h>
+#include <gr_probe_signal_c.h>
+#include <gr_probe_signal_vb.h>
+#include <gr_probe_signal_vs.h>
+#include <gr_probe_signal_vi.h>
+#include <gr_probe_signal_vf.h>
+#include <gr_probe_signal_vc.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_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_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_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_probe_signal_b.i>
+%include <gr_probe_signal_s.i>
+%include <gr_probe_signal_i.i>
+%include <gr_probe_signal_f.i>
+%include <gr_probe_signal_c.i>
+%include <gr_probe_signal_vb.i>
+%include <gr_probe_signal_vs.i>
+%include <gr_probe_signal_vi.i>
+%include <gr_probe_signal_vf.i>
+%include <gr_probe_signal_vc.i>
+%include <gr_sig_source_c.i>
+%include <gr_sig_source_f.i>
+%include <gr_sig_source_i.i>
+%include <gr_sig_source_s.i>
+%include <gr_sub_cc.i>
+%include <gr_sub_ff.i>
+%include <gr_sub_ii.i>
+%include <gr_sub_ss.i>
+%include <gr_unpacked_to_packed_bb.i>
+%include <gr_unpacked_to_packed_ii.i>
+%include <gr_unpacked_to_packed_ss.i>
+%include <gr_vector_sink_b.i>
+%include <gr_vector_sink_c.i>
+%include <gr_vector_sink_f.i>
+%include <gr_vector_sink_i.i>
+%include <gr_vector_sink_s.i>
+%include <gr_vector_source_b.i>
+%include <gr_vector_source_c.i>
+%include <gr_vector_source_f.i>
+%include <gr_vector_source_i.i>
+%include <gr_vector_source_s.i>
diff --git a/gnuradio-core/src/lib/general/gr_add_ff.cc b/gnuradio-core/src/lib/general/gr_add_ff.cc
new file mode 100644
index 000000000..5f6676bb7
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_add_ff.cc
@@ -0,0 +1,66 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_add_ff.h>
+#include <gr_io_signature.h>
+#include <volk/volk.h>
+
+gr_add_ff_sptr
+gr_make_add_ff(size_t vlen)
+{
+ return gnuradio::get_initial_sptr(new gr_add_ff(vlen));
+}
+
+gr_add_ff::gr_add_ff (size_t vlen)
+ : gr_sync_block("add_ff",
+ gr_make_io_signature (1, -1, sizeof(float)*vlen),
+ gr_make_io_signature (1, 1, sizeof(float)*vlen)),
+ d_vlen (vlen)
+{
+ const int alignment_multiple =
+ volk_get_alignment() / sizeof(float);
+ set_alignment(std::max(1,alignment_multiple));
+}
+
+int
+gr_add_ff::work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ float *out = (float *) output_items[0];
+ int noi = d_vlen*noutput_items;
+
+ memcpy(out, input_items[0], noi*sizeof(float));
+ if(is_unaligned()) {
+ for(size_t i = 1; i < input_items.size(); i++)
+ volk_32f_x2_add_32f_u(out, out, (const float*)input_items[i], noi);
+ }
+ else {
+ for(size_t i = 1; i < input_items.size(); i++)
+ volk_32f_x2_add_32f_a(out, out, (const float*)input_items[i], noi);
+ }
+ return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_add_ff.h b/gnuradio-core/src/lib/general/gr_add_ff.h
new file mode 100644
index 000000000..ff5604c97
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_add_ff.h
@@ -0,0 +1,56 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_ADD_FF_H
+#define INCLUDED_GR_ADD_FF_H
+
+#include <gr_core_api.h>
+#include <gr_sync_block.h>
+
+class gr_add_ff;
+typedef boost::shared_ptr<gr_add_ff> gr_add_ff_sptr;
+
+GR_CORE_API gr_add_ff_sptr
+gr_make_add_ff (size_t vlen=1);
+
+/*!
+ * \brief Add streams of complex values
+ * \ingroup math_blk
+ */
+
+class GR_CORE_API gr_add_ff : public gr_sync_block
+{
+ private:
+ friend GR_CORE_API gr_add_ff_sptr
+ gr_make_add_ff (size_t vlen);
+ gr_add_ff (size_t vlen);
+
+ size_t 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_ADD_FF_H */
diff --git a/gnuradio-core/src/lib/general/gr_add_ff.i b/gnuradio-core/src/lib/general/gr_add_ff.i
new file mode 100644
index 000000000..75a87651f
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_add_ff.i
@@ -0,0 +1,32 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,add_ff)
+
+gr_add_ff_sptr
+gr_make_add_ff (size_t vlen=1);
+
+class gr_add_ff : public gr_sync_block
+{
+public:
+
+};
diff --git a/gnuradio-core/src/lib/general/gr_additive_scrambler_bb.cc b/gnuradio-core/src/lib/general/gr_additive_scrambler_bb.cc
new file mode 100644
index 000000000..35cbb9572
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_additive_scrambler_bb.cc
@@ -0,0 +1,65 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_additive_scrambler_bb.h>
+#include <gr_io_signature.h>
+
+gr_additive_scrambler_bb_sptr
+gr_make_additive_scrambler_bb(int mask, int seed, int len, int count)
+{
+ return gnuradio::get_initial_sptr(new gr_additive_scrambler_bb(mask, seed, len, count));
+}
+
+gr_additive_scrambler_bb::gr_additive_scrambler_bb(int mask, int seed, int len, int count)
+ : gr_sync_block("additive_scrambler_bb",
+ gr_make_io_signature (1, 1, sizeof (unsigned char)),
+ gr_make_io_signature (1, 1, sizeof (unsigned char))),
+ d_lfsr(mask, seed, len),
+ d_count(count),
+ d_bits(0)
+{
+}
+
+int
+gr_additive_scrambler_bb::work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ const unsigned char *in = (const unsigned char *) input_items[0];
+ unsigned char *out = (unsigned char *) output_items[0];
+
+ for (int i = 0; i < noutput_items; i++) {
+ out[i] = in[i]^d_lfsr.next_bit();
+ if (d_count > 0) {
+ if (++d_bits == d_count) {
+ d_lfsr.reset();
+ d_bits = 0;
+ }
+ }
+ }
+
+ return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_additive_scrambler_bb.h b/gnuradio-core/src/lib/general/gr_additive_scrambler_bb.h
new file mode 100644
index 000000000..1c336306d
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_additive_scrambler_bb.h
@@ -0,0 +1,68 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifndef INCLUDED_GR_ADDITIVE_SCRAMBLER_BB_H
+#define INCLUDED_GR_ADDITIVE_SCRAMBLER_BB_H
+
+#include <gr_core_api.h>
+#include <gr_sync_block.h>
+#include "gri_lfsr.h"
+
+class gr_additive_scrambler_bb;
+typedef boost::shared_ptr<gr_additive_scrambler_bb> gr_additive_scrambler_bb_sptr;
+
+GR_CORE_API gr_additive_scrambler_bb_sptr gr_make_additive_scrambler_bb(int mask, int seed, int len, int count=0);
+
+/*!
+ * Scramble an input stream using an LFSR. This block works on the LSB only
+ * of the input data stream, i.e., on an "unpacked binary" stream, and
+ * produces the same format on its output.
+ *
+ * \param mask Polynomial mask for LFSR
+ * \param seed Initial shift register contents
+ * \param len Shift register length
+ * \param count Number of bits after which shift register is reset, 0=never
+ *
+ * The scrambler works by XORing the incoming bit stream by the output of
+ * the LFSR. Optionally, after 'count' bits have been processed, the shift
+ * register is reset to the seed value. This allows processing fixed length
+ * vectors of samples.
+ *
+ * \ingroup coding_blk
+ */
+
+class GR_CORE_API gr_additive_scrambler_bb : public gr_sync_block
+{
+ friend GR_CORE_API gr_additive_scrambler_bb_sptr gr_make_additive_scrambler_bb(int mask, int seed, int len, int count);
+
+ gri_lfsr d_lfsr;
+ int d_count;
+ int d_bits;
+
+ gr_additive_scrambler_bb(int mask, int seed, int len, int count);
+
+public:
+ int work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+#endif /* INCLUDED_GR_ADDITIVE_SCRAMBLER_BB_H */
diff --git a/gnuradio-core/src/lib/general/gr_additive_scrambler_bb.i b/gnuradio-core/src/lib/general/gr_additive_scrambler_bb.i
new file mode 100644
index 000000000..acf9e8c47
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_additive_scrambler_bb.i
@@ -0,0 +1,31 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,additive_scrambler_bb);
+
+gr_additive_scrambler_bb_sptr gr_make_additive_scrambler_bb(int mask, int seed, int len, int count=0);
+
+class gr_additive_scrambler_bb : public gr_sync_block
+{
+private:
+ gr_additive_scrambler_bb(int mask, int seed, int len, int count);
+};
diff --git a/gnuradio-core/src/lib/general/gr_agc2_cc.cc b/gnuradio-core/src/lib/general/gr_agc2_cc.cc
new file mode 100644
index 000000000..5097babc9
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_agc2_cc.cc
@@ -0,0 +1,56 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_agc2_cc.h>
+#include <gr_io_signature.h>
+#include <gri_agc2_cc.h>
+
+gr_agc2_cc_sptr
+gr_make_agc2_cc (float attack_rate, float decay_rate, float reference,
+ float gain, float max_gain)
+{
+ return gnuradio::get_initial_sptr(new gr_agc2_cc (attack_rate, decay_rate, reference, gain, max_gain));
+}
+
+gr_agc2_cc::gr_agc2_cc (float attack_rate, float decay_rate, float reference,
+ float gain, float max_gain)
+ : gr_sync_block ("gr_agc2_cc",
+ gr_make_io_signature (1, 1, sizeof (gr_complex)),
+ gr_make_io_signature (1, 1, sizeof (gr_complex))),
+ gri_agc2_cc (attack_rate, decay_rate, reference, gain, max_gain)
+{
+}
+
+int
+gr_agc2_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_agc2_cc.h b/gnuradio-core/src/lib/general/gr_agc2_cc.h
new file mode 100644
index 000000000..54bae1aae
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_agc2_cc.h
@@ -0,0 +1,56 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_AGC2_CC_H
+#define INCLUDED_GR_AGC2_CC_H
+
+#include <gr_core_api.h>
+#include <gr_sync_block.h>
+#include <gri_agc2_cc.h>
+
+class gr_agc2_cc;
+typedef boost::shared_ptr<gr_agc2_cc> gr_agc2_cc_sptr;
+
+GR_CORE_API gr_agc2_cc_sptr
+gr_make_agc2_cc (float attack_rate = 1e-1, float decay_rate = 1e-2, float reference = 1.0,
+ float gain = 1.0, float max_gain = 0.0);
+/*!
+ * \brief high performance Automatic Gain Control class
+ * \ingroup level_blk
+ *
+ * For Power the absolute value of the complex number is used.
+ */
+
+class GR_CORE_API gr_agc2_cc : public gr_sync_block, public gri_agc2_cc
+{
+ friend GR_CORE_API gr_agc2_cc_sptr gr_make_agc2_cc (float attack_rate, float decay_rate, float reference,
+ float gain, float max_gain);
+ gr_agc2_cc (float attack_rate, float decay_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_AGC2_CC_H */
diff --git a/gnuradio-core/src/lib/general/gr_agc2_cc.i b/gnuradio-core/src/lib/general/gr_agc2_cc.i
new file mode 100644
index 000000000..6d7b22101
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_agc2_cc.i
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,agc2_cc)
+
+%include <gri_agc2_cc.i>
+
+gr_agc2_cc_sptr
+gr_make_agc2_cc (float attack_rate = 1e-1, float decay_rate = 1e-2, float reference = 1.0,
+ float gain = 1.0, float max_gain = 0.0);
+
+class gr_agc2_cc : public gr_sync_block , public gri_agc2_cc
+{
+ gr_agc2_cc (float attack_rate, float decay_rate, float reference,
+ float gain, float max_gain);
+};
diff --git a/gnuradio-core/src/lib/general/gr_agc2_ff.cc b/gnuradio-core/src/lib/general/gr_agc2_ff.cc
new file mode 100644
index 000000000..792ee1c6b
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_agc2_ff.cc
@@ -0,0 +1,57 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005,2006,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_agc2_ff.h>
+#include <gr_io_signature.h>
+#include <gri_agc2_ff.h>
+
+gr_agc2_ff_sptr
+gr_make_agc2_ff (float attack_rate, float decay_rate, float reference,
+ float gain, float max_gain)
+{
+ return gnuradio::get_initial_sptr(new gr_agc2_ff (attack_rate, decay_rate, reference,
+ gain, max_gain));
+}
+
+gr_agc2_ff::gr_agc2_ff (float attack_rate, float decay_rate, float reference,
+ float gain, float max_gain)
+ : gr_sync_block ("gr_agc2_ff",
+ gr_make_io_signature (1, 1, sizeof (float)),
+ gr_make_io_signature (1, 1, sizeof (float)))
+ , gri_agc2_ff (attack_rate, decay_rate, reference, gain, max_gain)
+{
+}
+
+int
+gr_agc2_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_agc2_ff.h b/gnuradio-core/src/lib/general/gr_agc2_ff.h
new file mode 100644
index 000000000..48529948c
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_agc2_ff.h
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_AGC2_FF_H
+#define INCLUDED_GR_AGC2_FF_H
+
+#include <gr_core_api.h>
+#include <gr_sync_block.h>
+#include <gri_agc2_ff.h>
+class gr_agc2_ff;
+typedef boost::shared_ptr<gr_agc2_ff> gr_agc2_ff_sptr;
+
+GR_CORE_API gr_agc2_ff_sptr
+gr_make_agc2_ff (float attack_rate = 1e-1, float decay_rate = 1e-2, float reference = 1.0,
+ float gain = 1.0, float max_gain = 0.0);
+/*!
+ * \brief high performance Automatic Gain Control class
+ *
+ * \ingroup level_blk
+ * Power is approximated by absolute value
+ */
+
+class GR_CORE_API gr_agc2_ff : public gr_sync_block, public gri_agc2_ff
+{
+ friend GR_CORE_API gr_agc2_ff_sptr gr_make_agc2_ff (float attack_rate, float decay_rate,
+ float reference, float gain, float max_gain);
+ gr_agc2_ff (float attack_rate, float decay_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_AGC2_FF_H */
diff --git a/gnuradio-core/src/lib/general/gr_agc2_ff.i b/gnuradio-core/src/lib/general/gr_agc2_ff.i
new file mode 100644
index 000000000..646391aa7
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_agc2_ff.i
@@ -0,0 +1,35 @@
+/* -*- 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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,agc2_ff)
+
+%include <gri_agc2_ff.i>
+
+gr_agc2_ff_sptr
+gr_make_agc2_ff (float attack_rate = 1e-1, float decay_rate = 1e-2, float reference = 1.0,
+ float gain = 1.0, float max_gain = 0.0);
+
+class gr_agc2_ff : public gr_sync_block , public gri_agc2_ff
+{
+ gr_agc2_ff (float attack_rate, float decay_rate, float reference,
+ float gain, float max_gain);
+};
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
index 000000000..e98f3a303
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_agc_cc.cc
@@ -0,0 +1,56 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_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 gnuradio::get_initial_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
index 000000000..9f35350db
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_agc_cc.h
@@ -0,0 +1,55 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_AGC_CC_H
+#define INCLUDED_GR_AGC_CC_H
+
+#include <gr_core_api.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_CORE_API 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
+ * \ingroup level_blk
+ *
+ * For Power the absolute value of the complex number is used.
+ */
+
+class GR_CORE_API gr_agc_cc : public gr_sync_block, public gri_agc_cc
+{
+ friend GR_CORE_API 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
index 000000000..f942713b0
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_agc_cc.i
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,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
index 000000000..6050dc7f0
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_agc_ff.cc
@@ -0,0 +1,54 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005,2006,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_agc_ff.h>
+#include <gr_io_signature.h>
+#include <gri_agc_ff.h>
+
+gr_agc_ff_sptr
+gr_make_agc_ff (float rate, float reference, float gain, float max_gain)
+{
+ return gnuradio::get_initial_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_ff (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
index 000000000..dc618213b
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_agc_ff.h
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_AGC_FF_H
+#define INCLUDED_GR_AGC_FF_H
+
+#include <gr_core_api.h>
+#include <gr_sync_block.h>
+#include <gri_agc_ff.h>
+class gr_agc_ff;
+typedef boost::shared_ptr<gr_agc_ff> gr_agc_ff_sptr;
+
+GR_CORE_API 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
+ * \ingroup level_blk
+ *
+ * Power is approximated by absolute value
+ */
+
+class GR_CORE_API gr_agc_ff : public gr_sync_block, public gri_agc_ff
+{
+ friend GR_CORE_API 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
index 000000000..03c571e1a
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_agc_ff.i
@@ -0,0 +1,34 @@
+/* -*- 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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,agc_ff)
+
+%include <gri_agc_ff.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_ff
+{
+ 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
index 000000000..472853396
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_align_on_samplenumbers_ss.cc
@@ -0,0 +1,464 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_align_on_samplenumbers_ss.h>
+#include <gr_io_signature.h>
+#include <assert.h>
+#include <stdexcept>
+#include <string.h>
+#include <cstdio>
+
+//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 gnuradio::get_initial_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
index 000000000..1b71a3f4b
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_align_on_samplenumbers_ss.h
@@ -0,0 +1,92 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_ALIGN_ON_SAMPLE_NUMBERS_SS_H
+#define INCLUDED_GR_ALIGN_ON_SAMPLE_NUMBERS_SS_H
+
+#include <gr_core_api.h>
+#include <gr_block.h>
+
+/*!
+ * \brief align several complex short (interleaved short) input channels with corresponding unsigned 32 bit sample_counters (provided as interleaved 16 bit values)
+ * \ingroup misc
+ * \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;
+typedef boost::shared_ptr<gr_align_on_samplenumbers_ss> gr_align_on_samplenumbers_ss_sptr;
+
+GR_CORE_API gr_align_on_samplenumbers_ss_sptr gr_make_align_on_samplenumbers_ss (int nchan=2, int align_interval=128);
+
+
+
+
+class GR_CORE_API 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 GR_CORE_API 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_CORE_API 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
index 000000000..471f74301
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_align_on_samplenumbers_ss.i
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,align_on_samplenumbers_ss);
+
+gr_align_on_samplenumbers_ss_sptr
+gr_make_align_on_samplenumbers_ss(int nchan=2, int align_interval=128) throw (std::exception);
+
+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_annotator_1to1.cc b/gnuradio-core/src/lib/general/gr_annotator_1to1.cc
new file mode 100644
index 000000000..963af9202
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_annotator_1to1.cc
@@ -0,0 +1,107 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_annotator_1to1.h>
+#include <gr_io_signature.h>
+#include <string.h>
+#include <iostream>
+#include <iomanip>
+
+gr_annotator_1to1_sptr
+gr_make_annotator_1to1 (int when, size_t sizeof_stream_item)
+{
+ return gnuradio::get_initial_sptr (new gr_annotator_1to1
+ (when, sizeof_stream_item));
+}
+
+gr_annotator_1to1::gr_annotator_1to1 (int when, size_t sizeof_stream_item)
+ : gr_sync_block ("annotator_1to1",
+ gr_make_io_signature (1, -1, sizeof_stream_item),
+ gr_make_io_signature (1, -1, sizeof_stream_item)),
+ d_itemsize(sizeof_stream_item), d_when((uint64_t)when)
+{
+ set_tag_propagation_policy(TPP_ONE_TO_ONE);
+
+ d_tag_counter = 0;
+ set_relative_rate(1.0);
+}
+
+gr_annotator_1to1::~gr_annotator_1to1 ()
+{
+}
+
+int
+gr_annotator_1to1::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];
+
+ std::stringstream str;
+ str << name() << unique_id();
+
+ uint64_t abs_N = 0;
+ int ninputs = input_items.size();
+ for(int i = 0; i < ninputs; i++) {
+ abs_N = nitems_read(i);
+
+ std::vector<gr_tag_t> all_tags;
+ get_tags_in_range(all_tags, i, abs_N, abs_N + noutput_items);
+
+ std::vector<gr_tag_t>::iterator itr;
+ for(itr = all_tags.begin(); itr != all_tags.end(); itr++) {
+ d_stored_tags.push_back(*itr);
+ }
+ }
+
+ // Storing the current noutput_items as the value to the "noutput_items" key
+ pmt::pmt_t srcid = pmt::pmt_string_to_symbol(str.str());
+ pmt::pmt_t key = pmt::pmt_string_to_symbol("seq");
+
+ // Work does nothing to the data stream; just copy all inputs to outputs
+ // Adds a new tag when the number of items read is a multiple of d_when
+ abs_N = nitems_read(0);
+ int noutputs = output_items.size();
+ for(int j = 0; j < noutput_items; j++) {
+ // the min() is a hack to make sure this doesn't segfault if there are a
+ // different number of ins and outs. This is specifically designed to test
+ // the 1-to-1 propagation policy.
+ for(int i = 0; i < std::min(noutputs, ninputs); i++) {
+ if(abs_N % d_when == 0) {
+ pmt::pmt_t value = pmt::pmt_from_uint64(d_tag_counter++);
+ add_item_tag(i, abs_N, key, value, srcid);
+ }
+
+ in = (const float*)input_items[i];
+ out = (float*)output_items[i];
+ out[j] = in[j];
+ }
+ abs_N++;
+ }
+
+ return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_annotator_1to1.h b/gnuradio-core/src/lib/general/gr_annotator_1to1.h
new file mode 100644
index 000000000..57e572014
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_annotator_1to1.h
@@ -0,0 +1,75 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_ANNOTATOR_1TO1_H
+#define INCLUDED_GR_ANNOTATOR_1TO1_H
+
+#include <gr_core_api.h>
+#include <gr_sync_block.h>
+
+class gr_annotator_1to1;
+typedef boost::shared_ptr<gr_annotator_1to1> gr_annotator_1to1_sptr;
+
+// public constructor
+GR_CORE_API gr_annotator_1to1_sptr
+gr_make_annotator_1to1 (int when, size_t sizeof_stream_item);
+
+/*!
+ * \brief 1-to-1 stream annotator testing block. FOR TESTING PURPOSES ONLY.
+ *
+ * This block creates tags to be sent downstream every 10,000 items it sees. The
+ * tags contain the name and ID of the instantiated block, use "seq" as a key,
+ * and have a counter that increments by 1 for every tag produced that is used
+ * as the tag's value. The tags are propagated using the 1-to-1 policy.
+ *
+ * It also stores a copy of all tags it sees flow past it. These tags can be
+ * recalled externally with the data() member.
+ *
+ * This block is only meant for testing and showing how to use the tags.
+ */
+class GR_CORE_API gr_annotator_1to1 : public gr_sync_block
+{
+ public:
+ ~gr_annotator_1to1 ();
+ int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+
+ std::vector<gr_tag_t> data() const
+ {
+ return d_stored_tags;
+ }
+
+protected:
+ gr_annotator_1to1 (int when, size_t sizeof_stream_item);
+
+ private:
+ size_t d_itemsize;
+ uint64_t d_when;
+ uint64_t d_tag_counter;
+ std::vector<gr_tag_t> d_stored_tags;
+
+ friend GR_CORE_API gr_annotator_1to1_sptr
+ gr_make_annotator_1to1 (int when, size_t sizeof_stream_item);
+};
+
+#endif
diff --git a/gnuradio-core/src/lib/general/gr_annotator_1to1.i b/gnuradio-core/src/lib/general/gr_annotator_1to1.i
new file mode 100644
index 000000000..2637b8d27
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_annotator_1to1.i
@@ -0,0 +1,25 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2010-2011 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,annotator_1to1);
+
+%include <gr_annotator_1to1.h>
diff --git a/gnuradio-core/src/lib/general/gr_annotator_alltoall.cc b/gnuradio-core/src/lib/general/gr_annotator_alltoall.cc
new file mode 100644
index 000000000..01bdd3064
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_annotator_alltoall.cc
@@ -0,0 +1,110 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_annotator_alltoall.h>
+#include <gr_io_signature.h>
+#include <string.h>
+#include <iostream>
+#include <iomanip>
+
+gr_annotator_alltoall_sptr
+gr_make_annotator_alltoall (int when, size_t sizeof_stream_item)
+{
+ return gnuradio::get_initial_sptr (new gr_annotator_alltoall
+ (when, sizeof_stream_item));
+}
+
+gr_annotator_alltoall::gr_annotator_alltoall (int when,
+ size_t sizeof_stream_item)
+ : gr_sync_block ("annotator_alltoall",
+ gr_make_io_signature (1, -1, sizeof_stream_item),
+ gr_make_io_signature (1, -1, sizeof_stream_item)),
+ d_itemsize(sizeof_stream_item), d_when((uint64_t)when)
+{
+ set_tag_propagation_policy(TPP_ALL_TO_ALL);
+
+ d_tag_counter = 0;
+}
+
+gr_annotator_alltoall::~gr_annotator_alltoall ()
+{
+}
+
+int
+gr_annotator_alltoall::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];
+
+ std::stringstream str;
+ str << name() << unique_id();
+
+ uint64_t abs_N = 0, end_N;
+ int ninputs = input_items.size();
+ for(int i = 0; i < ninputs; i++) {
+ abs_N = nitems_read(i);
+ end_N = abs_N + (uint64_t)(noutput_items);
+
+ std::vector<gr_tag_t> all_tags;
+ get_tags_in_range(all_tags, i, abs_N, end_N);
+
+ std::vector<gr_tag_t>::iterator itr;
+ for(itr = all_tags.begin(); itr != all_tags.end(); itr++) {
+ d_stored_tags.push_back(*itr);
+ }
+ }
+
+ // Source ID and key for any tag that might get applied from this block
+ pmt::pmt_t srcid = pmt::pmt_string_to_symbol(str.str());
+ pmt::pmt_t key = pmt::pmt_string_to_symbol("seq");
+
+ // Work does nothing to the data stream; just copy all inputs to outputs
+ // Adds a new tag when the number of items read is a multiple of d_when
+ abs_N = nitems_written(0);
+ int noutputs = output_items.size();
+
+ for(int j = 0; j < noutput_items; j++) {
+ for(int i = 0; i < noutputs; i++) {
+ if(abs_N % d_when == 0) {
+ pmt::pmt_t value = pmt::pmt_from_uint64(d_tag_counter++);
+ add_item_tag(i, abs_N, key, value, srcid);
+ }
+
+ // Sum all of the inputs together for each output. Just 'cause.
+ out = (float*)output_items[i];
+ out[j] = 0;
+ for(int ins = 0; ins < ninputs; ins++) {
+ in = (const float*)input_items[ins];
+ out[j] += in[j];
+ }
+ }
+ abs_N++;
+ }
+
+ return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_annotator_alltoall.h b/gnuradio-core/src/lib/general/gr_annotator_alltoall.h
new file mode 100644
index 000000000..deb5874a4
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_annotator_alltoall.h
@@ -0,0 +1,76 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_ANNOTATOR_ALLTOALL_H
+#define INCLUDED_GR_ANNOTATOR_ALLTOALL_H
+
+#include <gr_core_api.h>
+#include <gr_sync_block.h>
+
+class gr_annotator_alltoall;
+typedef boost::shared_ptr<gr_annotator_alltoall> gr_annotator_alltoall_sptr;
+
+// public constructor
+GR_CORE_API gr_annotator_alltoall_sptr
+gr_make_annotator_alltoall (int when, size_t sizeof_stream_item);
+
+/*!
+ * \brief All-to-all stream annotator testing block. FOR TESTING PURPOSES ONLY.
+ *
+ * This block creates tags to be sent downstream every 10,000 items it sees. The
+ * tags contain the name and ID of the instantiated block, use "seq" as a key,
+ * and have a counter that increments by 1 for every tag produced that is used
+ * as the tag's value. The tags are propagated using the all-to-all policy.
+ *
+ * It also stores a copy of all tags it sees flow past it. These tags can be
+ * recalled externally with the data() member.
+ *
+ * This block is only meant for testing and showing how to use the tags.
+ */
+class GR_CORE_API gr_annotator_alltoall : public gr_sync_block
+{
+ public:
+ ~gr_annotator_alltoall ();
+
+ int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+
+ std::vector<gr_tag_t> data() const
+ {
+ return d_stored_tags;
+ }
+
+protected:
+ gr_annotator_alltoall (int when, size_t sizeof_stream_item);
+
+ private:
+ size_t d_itemsize;
+ uint64_t d_when;
+ uint64_t d_tag_counter;
+ std::vector<gr_tag_t> d_stored_tags;
+
+ friend GR_CORE_API gr_annotator_alltoall_sptr
+ gr_make_annotator_alltoall (int when, size_t sizeof_stream_item);
+};
+
+#endif
diff --git a/gnuradio-core/src/lib/general/gr_annotator_alltoall.i b/gnuradio-core/src/lib/general/gr_annotator_alltoall.i
new file mode 100644
index 000000000..35190a3d1
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_annotator_alltoall.i
@@ -0,0 +1,25 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2010-2011 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,annotator_alltoall);
+
+%include <gr_annotator_alltoall.h>
diff --git a/gnuradio-core/src/lib/general/gr_annotator_raw.cc b/gnuradio-core/src/lib/general/gr_annotator_raw.cc
new file mode 100644
index 000000000..d3dcce73a
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_annotator_raw.cc
@@ -0,0 +1,106 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_annotator_raw.h>
+#include <gr_io_signature.h>
+#include <string.h>
+#include <iostream>
+#include <iomanip>
+#include <stdexcept>
+
+using namespace pmt;
+
+gr_annotator_raw_sptr
+gr_make_annotator_raw(size_t sizeof_stream_item)
+{
+ return gnuradio::get_initial_sptr(new gr_annotator_raw
+ (sizeof_stream_item));
+}
+
+gr_annotator_raw::gr_annotator_raw(size_t sizeof_stream_item)
+ : gr_sync_block("annotator_raw",
+ gr_make_io_signature(1, 1, sizeof_stream_item),
+ gr_make_io_signature(1, 1, sizeof_stream_item)),
+ d_itemsize(sizeof_stream_item)
+{
+ set_tag_propagation_policy(TPP_ONE_TO_ONE);
+ set_relative_rate(1.0);
+}
+
+void gr_annotator_raw::add_tag(uint64_t offset, pmt_t key, pmt_t val)
+{
+ gruel::scoped_lock l(d_mutex);
+
+ gr_tag_t tag;
+ tag.srcid = pmt::pmt_intern(name());
+ tag.key = key;
+ tag.value = val;
+ tag.offset = offset;
+
+ // add our new tag
+ d_queued_tags.push_back(tag);
+ // make sure our tags are in offset order
+ std::sort(d_queued_tags.begin(), d_queued_tags.end(),
+ gr_tag_t::offset_compare);
+ // make sure we are not adding an item in the past!
+ if(tag.offset > nitems_read(0)) {
+ throw std::runtime_error("gr_annotator_raw::add_tag: item added too far in the past\n.");
+ }
+}
+
+gr_annotator_raw::~gr_annotator_raw()
+{
+}
+
+int
+gr_annotator_raw::work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ gruel::scoped_lock l(d_mutex);
+
+ const char *in = (const char*)input_items[0];
+ char *out = (char*)output_items[0];
+
+ uint64_t start_N = nitems_read(0);
+ uint64_t end_N = start_N + (uint64_t)(noutput_items);
+
+ // locate queued tags that fall in this range and insert them when appropriate
+ std::vector<gr_tag_t>::iterator i = d_queued_tags.begin();
+ while( i != d_queued_tags.end() ) {
+ if( (*i).offset >= start_N && (*i).offset < end_N) {
+ add_item_tag(0, (*i).offset,(*i).key, (*i).value, (*i).srcid);
+ i = d_queued_tags.erase(i);
+ }
+ else {
+ break;
+ }
+ }
+
+ // copy data across
+ memcpy(out, in, noutput_items*d_itemsize);
+ return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_annotator_raw.h b/gnuradio-core/src/lib/general/gr_annotator_raw.h
new file mode 100644
index 000000000..02d061908
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_annotator_raw.h
@@ -0,0 +1,69 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_ANNOTATOR_RAW_H
+#define INCLUDED_GR_ANNOTATOR_RAW_H
+
+#include <gr_core_api.h>
+#include <gr_sync_block.h>
+#include <gr_tags.h>
+#include <gruel/thread.h>
+
+class gr_annotator_raw;
+typedef boost::shared_ptr<gr_annotator_raw> gr_annotator_raw_sptr;
+
+// public constructor
+GR_CORE_API gr_annotator_raw_sptr
+gr_make_annotator_raw(size_t sizeof_stream_item);
+
+/*!
+ * \brief raw stream annotator testing block.
+ *
+ * This block creates arbitrary tags to be sent downstream
+ * blocks to be sent are set manually via accessor methods and are sent only once.
+ *
+ * This block is intended for testing of tag related blocks
+ */
+class GR_CORE_API gr_annotator_raw : public gr_sync_block
+{
+ public:
+ ~gr_annotator_raw();
+ int work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+
+ // insert a tag to be added
+ void add_tag(uint64_t offset, pmt::pmt_t key, pmt::pmt_t val);
+
+protected:
+ gr_annotator_raw(size_t sizeof_stream_item);
+
+ private:
+ size_t d_itemsize;
+ std::vector<gr_tag_t> d_queued_tags;
+ gruel::mutex d_mutex;
+
+ friend GR_CORE_API gr_annotator_raw_sptr
+ gr_make_annotator_raw(size_t sizeof_stream_item);
+};
+
+#endif
diff --git a/gnuradio-core/src/lib/general/gr_annotator_raw.i b/gnuradio-core/src/lib/general/gr_annotator_raw.i
new file mode 100644
index 000000000..4a58fe7c7
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_annotator_raw.i
@@ -0,0 +1,26 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2010-2011 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,annotator_raw);
+
+%include <gr_tags.i>
+%include <gr_annotator_raw.h>
diff --git a/gnuradio-core/src/lib/general/gr_bin_statistics_f.cc b/gnuradio-core/src/lib/general/gr_bin_statistics_f.cc
new file mode 100644
index 000000000..3938f2b48
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_bin_statistics_f.cc
@@ -0,0 +1,174 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_bin_statistics_f.h>
+#include <gr_io_signature.h>
+#include <string.h>
+
+gr_bin_statistics_f_sptr
+gr_make_bin_statistics_f(unsigned int vlen,
+ gr_msg_queue_sptr msgq,
+ gr_feval_dd *tune,
+ size_t tune_delay,
+ size_t dwell_delay)
+{
+ return gnuradio::get_initial_sptr(new gr_bin_statistics_f(vlen,
+ msgq,
+ tune,
+ tune_delay,
+ dwell_delay));
+}
+
+gr_bin_statistics_f::gr_bin_statistics_f(unsigned int vlen,
+ gr_msg_queue_sptr msgq,
+ gr_feval_dd *tune,
+ size_t tune_delay,
+ size_t dwell_delay)
+ : gr_sync_block("bin_statistics_f",
+ gr_make_io_signature(1, 1, sizeof(float) * vlen),
+ gr_make_io_signature(0, 0, 0)),
+ d_vlen(vlen), d_msgq(msgq), d_tune(tune),
+ d_tune_delay(tune_delay), d_dwell_delay(dwell_delay),
+ d_center_freq(0), d_delay(0),
+ d_max(vlen)
+{
+ enter_init();
+}
+
+gr_bin_statistics_f::~gr_bin_statistics_f()
+{
+ // NOP
+}
+
+void
+gr_bin_statistics_f::enter_init()
+{
+ d_state = ST_INIT;
+ d_delay = 0;
+}
+
+void
+gr_bin_statistics_f::enter_tune_delay()
+{
+ d_state = ST_TUNE_DELAY;
+ d_delay = d_tune_delay;
+ d_center_freq = d_tune->calleval(0);
+}
+
+void
+gr_bin_statistics_f::enter_dwell_delay()
+{
+ d_state = ST_DWELL_DELAY;
+ d_delay = d_dwell_delay;
+ reset_stats();
+}
+
+void
+gr_bin_statistics_f::leave_dwell_delay()
+{
+ send_stats();
+}
+
+int
+gr_bin_statistics_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];
+ size_t vlen = d_max.size();
+
+ int n = 0;
+ int t;
+
+ while (n < noutput_items){
+ switch (d_state){
+
+ case ST_INIT:
+ enter_tune_delay();
+ break;
+
+ case ST_TUNE_DELAY:
+ t = std::min(noutput_items - n, int(d_delay));
+ n += t;
+ d_delay -= t;
+ assert(d_delay >= 0);
+ if (d_delay == 0)
+ enter_dwell_delay();
+ break;
+
+ case ST_DWELL_DELAY:
+ t = std::min(noutput_items - n, int(d_delay));
+ for (int i = 0; i < t; i++){
+ accrue_stats(&input[n * vlen]);
+ n++;
+ }
+ d_delay -= t;
+ assert(d_delay >= 0);
+ if (d_delay == 0){
+ leave_dwell_delay();
+ enter_tune_delay();
+ }
+ break;
+
+ default:
+ assert(0);
+ }
+ }
+
+ return noutput_items;
+}
+
+//////////////////////////////////////////////////////////////////////////
+// virtual methods for gathering stats
+//////////////////////////////////////////////////////////////////////////
+
+void
+gr_bin_statistics_f::reset_stats()
+{
+ for (size_t i = 0; i < vlen(); i++){
+ d_max[i] = 0;
+ }
+}
+
+void
+gr_bin_statistics_f::accrue_stats(const float *input)
+{
+ for (size_t i = 0; i < vlen(); i++){
+ d_max[i] = std::max(d_max[i], input[i]); // compute per bin maxima
+ }
+}
+
+void
+gr_bin_statistics_f::send_stats()
+{
+ if (msgq()->full_p()) // if the queue is full, don't block, drop the data...
+ return;
+
+ // build & send a message
+ gr_message_sptr msg = gr_make_message(0, center_freq(), vlen(), vlen() * sizeof(float));
+ memcpy(msg->msg(), &d_max[0], vlen() * sizeof(float));
+ msgq()->insert_tail(msg);
+}
diff --git a/gnuradio-core/src/lib/general/gr_bin_statistics_f.h b/gnuradio-core/src/lib/general/gr_bin_statistics_f.h
new file mode 100644
index 000000000..dd1075909
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_bin_statistics_f.h
@@ -0,0 +1,100 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_BIN_STATISTICS_F_H
+#define INCLUDED_GR_BIN_STATISTICS_F_H
+
+
+#include <gr_core_api.h>
+#include <gr_sync_block.h>
+#include <gr_feval.h>
+#include <gr_message.h>
+#include <gr_msg_queue.h>
+
+class gr_bin_statistics_f;
+typedef boost::shared_ptr<gr_bin_statistics_f> gr_bin_statistics_f_sptr;
+
+
+GR_CORE_API gr_bin_statistics_f_sptr
+gr_make_bin_statistics_f(unsigned int vlen, // vector length
+ gr_msg_queue_sptr msgq,
+ gr_feval_dd *tune, // callback
+ size_t tune_delay, // samples
+ size_t dwell_delay); // samples
+
+/*!
+ * \brief control scanning and record frequency domain statistics
+ * \ingroup sink_blk
+ */
+class GR_CORE_API gr_bin_statistics_f : public gr_sync_block
+{
+ friend GR_CORE_API gr_bin_statistics_f_sptr
+ gr_make_bin_statistics_f(unsigned int vlen, // vector length
+ gr_msg_queue_sptr msgq,
+ gr_feval_dd *tune, // callback
+ size_t tune_delay, // samples
+ size_t dwell_delay); // samples
+
+ enum state_t { ST_INIT, ST_TUNE_DELAY, ST_DWELL_DELAY };
+
+ size_t d_vlen;
+ gr_msg_queue_sptr d_msgq;
+ gr_feval_dd *d_tune;
+ size_t d_tune_delay;
+ size_t d_dwell_delay;
+ double d_center_freq;
+
+ state_t d_state;
+ size_t d_delay; // nsamples remaining to state transition
+
+ gr_bin_statistics_f(unsigned int vlen,
+ gr_msg_queue_sptr msgq,
+ gr_feval_dd *tune,
+ size_t tune_delay,
+ size_t dwell_delay);
+
+ void enter_init();
+ void enter_tune_delay();
+ void enter_dwell_delay();
+ void leave_dwell_delay();
+
+protected:
+ std::vector<float> d_max; // per bin maxima
+
+ size_t vlen() const { return d_vlen; }
+ double center_freq() const { return d_center_freq; }
+ gr_msg_queue_sptr msgq() const { return d_msgq; }
+
+ virtual void reset_stats();
+ virtual void accrue_stats(const float *input);
+ virtual void send_stats();
+
+public:
+ ~gr_bin_statistics_f();
+
+ 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_bin_statistics_f.i b/gnuradio-core/src/lib/general/gr_bin_statistics_f.i
new file mode 100644
index 000000000..94a3db69a
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_bin_statistics_f.i
@@ -0,0 +1,47 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+// Directors are only supported in Python, Java and C#. gr_feval_dd uses directors
+#ifdef SWIGPYTHON
+
+GR_SWIG_BLOCK_MAGIC(gr,bin_statistics_f);
+
+gr_bin_statistics_f_sptr
+gr_make_bin_statistics_f(unsigned int vlen, // vector length
+ gr_msg_queue_sptr msgq,
+ gr_feval_dd *tune, // callback
+ size_t tune_delay, // samples
+ size_t dwell_delay); // samples
+
+
+class gr_bin_statistics_f : public gr_sync_block
+{
+private:
+ gr_bin_statistics_f(unsigned int vlen,
+ gr_msg_queue_sptr msgq,
+ gr_feval_dd *tune,
+ size_t tune_delay,
+ size_t dwell_delay);
+public:
+ ~gr_bin_statistics_f();
+};
+
+#endif
diff --git a/gnuradio-core/src/lib/general/gr_block_gateway.cc b/gnuradio-core/src/lib/general/gr_block_gateway.cc
new file mode 100644
index 000000000..79b42803a
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_block_gateway.cc
@@ -0,0 +1,184 @@
+/*
+ * Copyright 2011-2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <gr_block_gateway.h>
+#include <gr_io_signature.h>
+#include <iostream>
+#include <boost/bind.hpp>
+
+/***********************************************************************
+ * Helper routines
+ **********************************************************************/
+template <typename OutType, typename InType>
+void copy_pointers(OutType &out, const InType &in){
+ out.resize(in.size());
+ for (size_t i = 0; i < in.size(); i++){
+ out[i] = (void *)(in[i]);
+ }
+}
+
+/***********************************************************************
+ * The gr_block gateway implementation class
+ **********************************************************************/
+class gr_block_gateway_impl : public gr_block_gateway{
+public:
+ gr_block_gateway_impl(
+ gr_feval_ll *handler,
+ const std::string &name,
+ gr_io_signature_sptr in_sig,
+ gr_io_signature_sptr out_sig,
+ const gr_block_gw_work_type work_type,
+ const unsigned factor
+ ):
+ gr_block(name, in_sig, out_sig),
+ _handler(handler),
+ _work_type(work_type)
+ {
+ switch(_work_type){
+ case GR_BLOCK_GW_WORK_GENERAL:
+ _decim = 1; //not relevant, but set anyway
+ _interp = 1; //not relevant, but set anyway
+ break;
+
+ case GR_BLOCK_GW_WORK_SYNC:
+ _decim = 1;
+ _interp = 1;
+ this->set_fixed_rate(true);
+ break;
+
+ case GR_BLOCK_GW_WORK_DECIM:
+ _decim = factor;
+ _interp = 1;
+ break;
+
+ case GR_BLOCK_GW_WORK_INTERP:
+ _decim = 1;
+ _interp = factor;
+ this->set_output_multiple(_interp);
+ break;
+ }
+ }
+
+ /*******************************************************************
+ * Overloads for various scheduler-called functions
+ ******************************************************************/
+ void forecast(
+ int noutput_items,
+ gr_vector_int &ninput_items_required
+ ){
+ switch(_work_type){
+ case GR_BLOCK_GW_WORK_GENERAL:
+ _message.action = gr_block_gw_message_type::ACTION_FORECAST;
+ _message.forecast_args_noutput_items = noutput_items;
+ _message.forecast_args_ninput_items_required = ninput_items_required;
+ _handler->calleval(0);
+ ninput_items_required = _message.forecast_args_ninput_items_required;
+ return;
+
+ default:
+ unsigned ninputs = ninput_items_required.size();
+ for (unsigned i = 0; i < ninputs; i++)
+ ninput_items_required[i] = fixed_rate_noutput_to_ninput(noutput_items);
+ return;
+ }
+ }
+
+ int general_work(
+ int noutput_items,
+ gr_vector_int &ninput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items
+ ){
+ switch(_work_type){
+ case GR_BLOCK_GW_WORK_GENERAL:
+ _message.action = gr_block_gw_message_type::ACTION_GENERAL_WORK;
+ _message.general_work_args_noutput_items = noutput_items;
+ _message.general_work_args_ninput_items = ninput_items;
+ copy_pointers(_message.general_work_args_input_items, input_items);
+ _message.general_work_args_output_items = output_items;
+ _handler->calleval(0);
+ return _message.general_work_args_return_value;
+
+ default:
+ int r = work (noutput_items, input_items, output_items);
+ if (r > 0) consume_each(r*_decim/_interp);
+ return r;
+ }
+ }
+
+ int work(
+ int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items
+ ){
+ _message.action = gr_block_gw_message_type::ACTION_WORK;
+ _message.work_args_ninput_items = fixed_rate_noutput_to_ninput(noutput_items);
+ if (_message.work_args_ninput_items == 0) return -1;
+ _message.work_args_noutput_items = noutput_items;
+ copy_pointers(_message.work_args_input_items, input_items);
+ _message.work_args_output_items = output_items;
+ _handler->calleval(0);
+ return _message.work_args_return_value;
+ }
+
+ int fixed_rate_noutput_to_ninput(int noutput_items){
+ return (noutput_items*_decim/_interp) + history() - 1;
+ }
+
+ int fixed_rate_ninput_to_noutput(int ninput_items){
+ return std::max(0, ninput_items - (int)history() + 1)*_interp/_decim;
+ }
+
+ bool start(void){
+ _message.action = gr_block_gw_message_type::ACTION_START;
+ _handler->calleval(0);
+ return _message.start_args_return_value;
+ }
+
+ bool stop(void){
+ _message.action = gr_block_gw_message_type::ACTION_STOP;
+ _handler->calleval(0);
+ return _message.stop_args_return_value;
+ }
+
+ gr_block_gw_message_type &gr_block_message(void){
+ return _message;
+ }
+
+private:
+ gr_feval_ll *_handler;
+ gr_block_gw_message_type _message;
+ const gr_block_gw_work_type _work_type;
+ unsigned _decim, _interp;
+};
+
+boost::shared_ptr<gr_block_gateway> gr_make_block_gateway(
+ gr_feval_ll *handler,
+ const std::string &name,
+ gr_io_signature_sptr in_sig,
+ gr_io_signature_sptr out_sig,
+ const gr_block_gw_work_type work_type,
+ const unsigned factor
+){
+ return boost::shared_ptr<gr_block_gateway>(
+ new gr_block_gateway_impl(handler, name, in_sig, out_sig, work_type, factor)
+ );
+}
diff --git a/gnuradio-core/src/lib/general/gr_block_gateway.h b/gnuradio-core/src/lib/general/gr_block_gateway.h
new file mode 100644
index 000000000..2452b1045
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_block_gateway.h
@@ -0,0 +1,264 @@
+/*
+ * Copyright 2011-2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GRBLOCK_GATEWAY_H
+#define INCLUDED_GRBLOCK_GATEWAY_H
+
+#include <gr_core_api.h>
+#include <gr_block.h>
+#include <gr_feval.h>
+
+/*!
+ * The work type enum tells the gateway what kind of block to implement.
+ * The choices are familiar gnuradio block overloads (sync, decim, interp).
+ */
+enum gr_block_gw_work_type{
+ GR_BLOCK_GW_WORK_GENERAL,
+ GR_BLOCK_GW_WORK_SYNC,
+ GR_BLOCK_GW_WORK_DECIM,
+ GR_BLOCK_GW_WORK_INTERP,
+};
+
+/*!
+ * Shared message structure between python and gateway.
+ * Each action type represents a scheduler-called function.
+ */
+struct gr_block_gw_message_type{
+ enum action_type{
+ ACTION_GENERAL_WORK, //dispatch work
+ ACTION_WORK, //dispatch work
+ ACTION_FORECAST, //dispatch forecast
+ ACTION_START, //dispatch start
+ ACTION_STOP, //dispatch stop
+ };
+
+ action_type action;
+
+ int general_work_args_noutput_items;
+ std::vector<int> general_work_args_ninput_items;
+ std::vector<void *> general_work_args_input_items; //TODO this should be const void*, but swig cant int cast it right
+ std::vector<void *> general_work_args_output_items;
+ int general_work_args_return_value;
+
+ int work_args_ninput_items;
+ int work_args_noutput_items;
+ std::vector<void *> work_args_input_items; //TODO this should be const void*, but swig cant int cast it right
+ std::vector<void *> work_args_output_items;
+ int work_args_return_value;
+
+ int forecast_args_noutput_items;
+ std::vector<int> forecast_args_ninput_items_required;
+
+ bool start_args_return_value;
+
+ bool stop_args_return_value;
+};
+
+/*!
+ * The gateway block which performs all the magic.
+ *
+ * The gateway provides access to all the gr_block routines.
+ * The methods prefixed with gr_block__ are renamed
+ * to class methods without the prefix in python.
+ */
+class GR_CORE_API gr_block_gateway : virtual public gr_block{
+public:
+ //! Provide access to the shared message object
+ virtual gr_block_gw_message_type &gr_block_message(void) = 0;
+
+ long gr_block__unique_id(void) const{
+ return gr_block::unique_id();
+ }
+
+ std::string gr_block__name(void) const{
+ return gr_block::name();
+ }
+
+ unsigned gr_block__history(void) const{
+ return gr_block::history();
+ }
+
+ void gr_block__set_history(unsigned history){
+ return gr_block::set_history(history);
+ }
+
+ void gr_block__set_fixed_rate(bool fixed_rate){
+ return gr_block::set_fixed_rate(fixed_rate);
+ }
+
+ bool gr_block__fixed_rate(void) const{
+ return gr_block::fixed_rate();
+ }
+
+ void gr_block__set_output_multiple(int multiple){
+ return gr_block::set_output_multiple(multiple);
+ }
+
+ int gr_block__output_multiple(void) const{
+ return gr_block::output_multiple();
+ }
+
+ void gr_block__consume(int which_input, int how_many_items){
+ return gr_block::consume(which_input, how_many_items);
+ }
+
+ void gr_block__consume_each(int how_many_items){
+ return gr_block::consume_each(how_many_items);
+ }
+
+ void gr_block__produce(int which_output, int how_many_items){
+ return gr_block::produce(which_output, how_many_items);
+ }
+
+ void gr_block__set_relative_rate(double relative_rate){
+ return gr_block::set_relative_rate(relative_rate);
+ }
+
+ double gr_block__relative_rate(void) const{
+ return gr_block::relative_rate();
+ }
+
+ uint64_t gr_block__nitems_read(unsigned int which_input){
+ return gr_block::nitems_read(which_input);
+ }
+
+ uint64_t gr_block__nitems_written(unsigned int which_output){
+ return gr_block::nitems_written(which_output);
+ }
+
+ gr_block::tag_propagation_policy_t gr_block__tag_propagation_policy(void){
+ return gr_block::tag_propagation_policy();
+ }
+
+ void gr_block__set_tag_propagation_policy(gr_block::tag_propagation_policy_t p){
+ return gr_block::set_tag_propagation_policy(p);
+ }
+
+ void gr_block__add_item_tag(
+ unsigned int which_output, const gr_tag_t &tag
+ ){
+ return gr_block::add_item_tag(which_output, tag);
+ }
+
+ void gr_block__add_item_tag(
+ unsigned int which_output,
+ uint64_t abs_offset,
+ const pmt::pmt_t &key,
+ const pmt::pmt_t &value,
+ const pmt::pmt_t &srcid=pmt::PMT_F
+ ){
+ return gr_block::add_item_tag(which_output, abs_offset, key, value, srcid);
+ }
+
+ std::vector<gr_tag_t> gr_block__get_tags_in_range(
+ unsigned int which_input,
+ uint64_t abs_start,
+ uint64_t abs_end
+ ){
+ std::vector<gr_tag_t> tags;
+ gr_block::get_tags_in_range(tags, which_input, abs_start, abs_end);
+ return tags;
+ }
+
+ std::vector<gr_tag_t> gr_block__get_tags_in_range(
+ unsigned int which_input,
+ uint64_t abs_start,
+ uint64_t abs_end,
+ const pmt::pmt_t &key
+ ){
+ std::vector<gr_tag_t> tags;
+ gr_block::get_tags_in_range(tags, which_input, abs_start, abs_end, key);
+ return tags;
+ }
+
+ /* Message passing interface */
+ void gr_block__message_port_register_in(pmt::pmt_t port_id){
+ gr_block::message_port_register_in(port_id);
+ }
+
+ void gr_block__message_port_register_out(pmt::pmt_t port_id){
+ gr_block::message_port_register_out(port_id);
+ }
+
+ void gr_block__message_port_pub(pmt::pmt_t port_id, pmt::pmt_t msg){
+ gr_block::message_port_pub(port_id, msg);
+ }
+
+ void gr_block__message_port_sub(pmt::pmt_t port_id, pmt::pmt_t target){
+ gr_block::message_port_sub(port_id, target);
+ }
+
+ void gr_block__message_port_unsub(pmt::pmt_t port_id, pmt::pmt_t target){
+ gr_block::message_port_unsub(port_id, target);
+ }
+
+ pmt::pmt_t gr_block__message_ports_in(){
+ return gr_block::message_ports_in();
+ }
+
+ pmt::pmt_t gr_block__message_ports_out(){
+ return gr_block::message_ports_out();
+ }
+
+ void set_msg_handler_feval(pmt::pmt_t which_port, gr_feval_p *msg_handler)
+ {
+ if(msg_queue.find(which_port) == msg_queue.end()){
+ throw std::runtime_error("attempt to set_msg_handler_feval() on bad input message port!");
+ }
+ d_msg_handlers_feval[which_port] = msg_handler;
+ }
+
+protected:
+ typedef std::map<pmt::pmt_t, gr_feval_p *, pmt::pmt_comperator> msg_handlers_feval_t;
+ msg_handlers_feval_t d_msg_handlers_feval;
+
+ void dispatch_msg(pmt::pmt_t which_port, pmt::pmt_t msg){
+ // Is there a handler?
+ if (d_msg_handlers_feval.find(which_port) != d_msg_handlers_feval.end()){
+ d_msg_handlers_feval[which_port]->calleval(msg); // Yes, invoke it.
+ }
+ else {
+ // Pass to generic dispatcher if not found
+ gr_block::dispatch_msg(which_port, msg);
+ }
+ }
+};
+
+/*!
+ * Make a new gateway block.
+ * \param handler the swig director object with callback
+ * \param name the name of the block (Ex: "Shirley")
+ * \param in_sig the input signature for this block
+ * \param out_sig the output signature for this block
+ * \param work_type the type of block overload to implement
+ * \param factor the decimation or interpolation factor
+ * \return a new gateway block
+ */
+GR_CORE_API boost::shared_ptr<gr_block_gateway> gr_make_block_gateway(
+ gr_feval_ll *handler,
+ const std::string &name,
+ gr_io_signature_sptr in_sig,
+ gr_io_signature_sptr out_sig,
+ const gr_block_gw_work_type work_type,
+ const unsigned factor
+);
+
+#endif /* INCLUDED_GRBLOCK_GATEWAY_H */
diff --git a/gnuradio-core/src/lib/general/gr_block_gateway.i b/gnuradio-core/src/lib/general/gr_block_gateway.i
new file mode 100644
index 000000000..8adafdfea
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_block_gateway.i
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2011-2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+////////////////////////////////////////////////////////////////////////
+// standard includes
+////////////////////////////////////////////////////////////////////////
+%include <gnuradio.i>
+%include <gr_tags.i>
+%include <gr_feval.i>
+
+////////////////////////////////////////////////////////////////////////
+// block headers
+////////////////////////////////////////////////////////////////////////
+%{
+#include <gr_block_gateway.h>
+%}
+
+////////////////////////////////////////////////////////////////////////
+// data type support
+////////////////////////////////////////////////////////////////////////
+%template(int_vector_t) std::vector<int>;
+%template(void_star_vector_t) std::vector<void *>;
+
+////////////////////////////////////////////////////////////////////////
+// block magic
+////////////////////////////////////////////////////////////////////////
+GR_SWIG_BLOCK_MAGIC(gr,block_gateway);
+%include <gr_block_gateway.h>
diff --git a/gnuradio-core/src/lib/general/gr_burst_tagger.cc b/gnuradio-core/src/lib/general/gr_burst_tagger.cc
new file mode 100644
index 000000000..83e84bfa0
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_burst_tagger.cc
@@ -0,0 +1,109 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_burst_tagger.h>
+#include <gr_io_signature.h>
+#include <string.h>
+
+gr_burst_tagger_sptr
+gr_make_burst_tagger(size_t itemsize)
+{
+ return gnuradio::get_initial_sptr(new gr_burst_tagger(itemsize));
+}
+
+gr_burst_tagger::gr_burst_tagger(size_t itemsize)
+ : gr_sync_block ("burst_tagger",
+ gr_make_io_signature2 (2, 2, itemsize, sizeof(short)),
+ gr_make_io_signature (1, 1, itemsize)),
+ d_itemsize(itemsize), d_state(false)
+{
+ std::stringstream str;
+ str << name() << unique_id();
+
+ d_true_key = pmt::pmt_string_to_symbol("burst");
+ d_true_value = pmt::PMT_T;
+
+ d_false_key = pmt::pmt_string_to_symbol("burst");
+ d_false_value = pmt::PMT_F;
+
+ d_id = pmt::pmt_string_to_symbol(str.str());
+}
+
+void
+gr_burst_tagger::set_true_tag (const std::string &key, bool value)
+{
+ d_true_key = pmt::pmt_string_to_symbol(key);
+ if(value == true) {
+ d_true_value = pmt::PMT_T;
+ }
+ else {
+ d_true_value = pmt::PMT_F;
+ }
+}
+
+void
+gr_burst_tagger::set_false_tag (const std::string &key, bool value)
+{
+ d_false_key = pmt::pmt_string_to_symbol(key);
+ if(value == true) {
+ d_false_value = pmt::PMT_T;
+ }
+ else {
+ d_false_value = pmt::PMT_F;
+ }
+}
+
+gr_burst_tagger::~gr_burst_tagger()
+{
+}
+
+int
+gr_burst_tagger::work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ const char *signal = (const char*)input_items[0];
+ const short *trigger = (const short*)input_items[1];
+ char *out = (char*)output_items[0];
+
+ memcpy(out, signal, noutput_items * d_itemsize);
+
+ for(int i = 0; i < noutput_items; i++) {
+ if(trigger[i] > 0) {
+ if(d_state == false) {
+ d_state = true;
+ add_item_tag(0, nitems_written(0)+i, d_true_key, d_true_value, d_id);
+ }
+ }
+ else {
+ if(d_state == true) {
+ d_state = false;
+ add_item_tag(0, nitems_written(0)+i, d_false_key, d_false_value, d_id);
+ }
+ }
+ }
+ return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_burst_tagger.h b/gnuradio-core/src/lib/general/gr_burst_tagger.h
new file mode 100644
index 000000000..9a7898b04
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_burst_tagger.h
@@ -0,0 +1,64 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_BURST_TAGGER_H
+#define INCLUDED_GR_BURST_TAGGER_H
+
+#include <gr_core_api.h>
+#include <gr_sync_block.h>
+
+class gr_burst_tagger;
+typedef boost::shared_ptr<gr_burst_tagger> gr_burst_tagger_sptr;
+
+GR_CORE_API gr_burst_tagger_sptr gr_make_burst_tagger(size_t itemsize);
+
+/*!
+ * \brief output[i] = input[i]
+ * \ingroup misc_blk
+ *
+ */
+class GR_CORE_API gr_burst_tagger : public gr_sync_block
+{
+ size_t d_itemsize;
+ bool d_state;
+ pmt::pmt_t d_true_key;
+ pmt::pmt_t d_true_value;
+
+ pmt::pmt_t d_false_key;
+ pmt::pmt_t d_false_value;
+
+ pmt::pmt_t d_id;
+
+ friend GR_CORE_API gr_burst_tagger_sptr gr_make_burst_tagger(size_t itemsize);
+ gr_burst_tagger(size_t itemsize);
+
+ public:
+ ~gr_burst_tagger();
+ void set_true_tag (const std::string &key, bool value);
+ void set_false_tag (const std::string &key, bool value);
+
+ 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_burst_tagger.i b/gnuradio-core/src/lib/general/gr_burst_tagger.i
new file mode 100644
index 000000000..a5511e48a
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_burst_tagger.i
@@ -0,0 +1,35 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,burst_tagger)
+
+gr_burst_tagger_sptr gr_make_burst_tagger(size_t itemsize);
+
+class gr_burst_tagger : public gr_sync_block
+{
+ private:
+ gr_burst_tagger(size_t itemsize);
+
+ public:
+ void set_true_tag(const std::string &key, bool value);
+ void set_false_tag(const std::string &key, bool value);
+};
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
index 000000000..7dafa29f9
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_bytes_to_syms.cc
@@ -0,0 +1,74 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#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 gnuradio::get_initial_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
index 000000000..23e5c6b91
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_bytes_to_syms.h
@@ -0,0 +1,61 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifndef INCLUDED_GR_BYTES_TO_SYMS_H
+#define INCLUDED_GR_BYTES_TO_SYMS_H
+
+#include <gr_core_api.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_CORE_API gr_bytes_to_syms_sptr gr_make_bytes_to_syms ();
+
+/*!
+ * \brief Convert stream of bytes to stream of +/- 1 symbols
+ * \ingroup converter_blk
+ *
+ * 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_CORE_API gr_bytes_to_syms : public gr_sync_interpolator
+{
+ friend GR_CORE_API 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
index 000000000..185e7cd29
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_bytes_to_syms.i
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,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
index 000000000..f63aa5b16
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_char_to_float.cc
@@ -0,0 +1,72 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_char_to_float.h>
+#include <gr_io_signature.h>
+#include <volk/volk.h>
+
+gr_char_to_float_sptr
+gr_make_char_to_float (size_t vlen, float scale)
+{
+ return gnuradio::get_initial_sptr(new gr_char_to_float (vlen, scale));
+}
+
+gr_char_to_float::gr_char_to_float (size_t vlen, float scale)
+ : gr_sync_block ("gr_char_to_float",
+ gr_make_io_signature (1, 1, sizeof (char)*vlen),
+ gr_make_io_signature (1, 1, sizeof (float)*vlen)),
+ d_vlen(vlen), d_scale(scale)
+{
+ const int alignment_multiple =
+ volk_get_alignment() / sizeof(float);
+ set_alignment(std::max(1,alignment_multiple));
+}
+
+float
+gr_char_to_float::scale() const
+{
+ return d_scale;
+}
+
+void
+gr_char_to_float::set_scale(float scale)
+{
+ d_scale = scale;
+}
+
+int
+gr_char_to_float::work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ const int8_t *in = (const int8_t *) input_items[0];
+ float *out = (float *) output_items[0];
+
+ // Note: the unaligned benchmarked much faster than the aligned
+ volk_8i_s32f_convert_32f_u(out, in, d_scale, d_vlen*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
index 000000000..5170c618c
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_char_to_float.h
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_CHAR_TO_FLOAT_H
+#define INCLUDED_GR_CHAR_TO_FLOAT_H
+
+#include <gr_core_api.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_CORE_API gr_char_to_float_sptr
+gr_make_char_to_float (size_t vlen=1, float scale=1);
+
+/*!
+ * \brief Convert stream of chars to a stream of float
+ * \ingroup converter_blk
+ *
+ * \param vlen vector length of data streams.
+ * \param scale a scalar divider to change the output signal scale.
+ */
+
+class GR_CORE_API gr_char_to_float : public gr_sync_block
+{
+ private:
+ friend GR_CORE_API gr_char_to_float_sptr
+ gr_make_char_to_float (size_t vlen, float scale);
+ gr_char_to_float (size_t vlen, float scale);
+
+ size_t d_vlen;
+ float d_scale;
+
+ public:
+ /*!
+ * Get the scalar divider value.
+ */
+ float scale() const;
+
+ /*!
+ * Set the scalar divider value.
+ */
+ void set_scale(float scale);
+
+ 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
index 000000000..c0b3d75fe
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_char_to_float.i
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,char_to_float)
+
+gr_char_to_float_sptr
+gr_make_char_to_float (size_t vlen=1, float scale=1);
+
+class gr_char_to_float : public gr_sync_block
+{
+public:
+ float scale() const;
+ void set_scale(float scale);
+};
diff --git a/gnuradio-core/src/lib/general/gr_char_to_short.cc b/gnuradio-core/src/lib/general/gr_char_to_short.cc
new file mode 100644
index 000000000..bb9bd8909
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_char_to_short.cc
@@ -0,0 +1,64 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2011,2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_char_to_short.h>
+#include <gr_io_signature.h>
+#include <volk/volk.h>
+
+gr_char_to_short_sptr
+gr_make_char_to_short (size_t vlen)
+{
+ return gnuradio::get_initial_sptr(new gr_char_to_short (vlen));
+}
+
+gr_char_to_short::gr_char_to_short (size_t vlen)
+ : gr_sync_block ("gr_char_to_short",
+ gr_make_io_signature (1, 1, sizeof (char)*vlen),
+ gr_make_io_signature (1, 1, sizeof (short)*vlen)),
+ d_vlen(vlen)
+{
+ const int alignment_multiple =
+ volk_get_alignment() / sizeof(char);
+ set_alignment(std::max(1,alignment_multiple));
+}
+
+int
+gr_char_to_short::work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ const int8_t *in = (const int8_t *) input_items[0];
+ int16_t *out = (int16_t *) output_items[0];
+
+ if(is_unaligned()) {
+ volk_8i_convert_16i_u(out, in, d_vlen*noutput_items);
+ }
+ else {
+ volk_8i_convert_16i_a(out, in, d_vlen*noutput_items);
+ }
+
+ return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_char_to_short.h b/gnuradio-core/src/lib/general/gr_char_to_short.h
new file mode 100644
index 000000000..7ac5e97b9
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_char_to_short.h
@@ -0,0 +1,58 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2011,2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_CHAR_TO_SHORT_H
+#define INCLUDED_GR_CHAR_TO_SHORT_H
+
+#include <gr_core_api.h>
+#include <gr_sync_block.h>
+
+class gr_char_to_short;
+typedef boost::shared_ptr<gr_char_to_short> gr_char_to_short_sptr;
+
+GR_CORE_API gr_char_to_short_sptr
+gr_make_char_to_short (size_t vlen=1);
+
+/*!
+ * \brief Convert stream of chars to a stream of float
+ * \ingroup converter_blk
+ *
+ * \param vlen vector length of data streams.
+ */
+
+class GR_CORE_API gr_char_to_short : public gr_sync_block
+{
+ private:
+ friend GR_CORE_API gr_char_to_short_sptr
+ gr_make_char_to_short (size_t vlen);
+ gr_char_to_short (size_t vlen);
+
+ size_t 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_CHAR_TO_SHORT_H */
diff --git a/gnuradio-core/src/lib/general/gr_char_to_short.i b/gnuradio-core/src/lib/general/gr_char_to_short.i
new file mode 100644
index 000000000..a53a0990e
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_char_to_short.i
@@ -0,0 +1,30 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2011 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,char_to_short)
+
+gr_char_to_short_sptr gr_make_char_to_short (size_t vlen=1);
+
+class gr_char_to_short : public gr_sync_block
+{
+
+};
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
index 000000000..c3288f481
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_check_counting_s.cc
@@ -0,0 +1,190 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#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 gnuradio::get_initial_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
index 000000000..996fa3259
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_check_counting_s.h
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifndef INCLUDED_GR_CHECK_COUNTING_S_H
+#define INCLUDED_GR_CHECK_COUNTING_S_H
+
+#include <gr_core_api.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_CORE_API 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_blk
+ *
+ * This sink is typically used to test the USRP "Counting Mode" or "Counting mode 32 bit".
+ */
+class GR_CORE_API gr_check_counting_s : public gr_sync_block
+{
+ friend GR_CORE_API 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
index 000000000..0275dad9d
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_check_counting_s.i
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,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
index 000000000..088b8c38a
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_check_lfsr_32k_s.cc
@@ -0,0 +1,169 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#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 gnuradio::get_initial_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
index 000000000..2f980b427
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_check_lfsr_32k_s.h
@@ -0,0 +1,103 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifndef INCLUDED_GR_CHECK_LFSR_32K_S_H
+#define INCLUDED_GR_CHECK_LFSR_32K_S_H
+
+#include <gr_core_api.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_CORE_API 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_blk
+ *
+ * This sink is typically used along with gr_lfsr_32k_source_s to test
+ * the USRP using its digital loopback mode.
+ */
+class GR_CORE_API gr_check_lfsr_32k_s : public gr_sync_block
+{
+ friend GR_CORE_API 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
index 000000000..34d4a0b0c
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_check_lfsr_32k_s.i
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,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_circular_file.cc b/gnuradio-core/src/lib/general/gr_circular_file.cc
new file mode 100644
index 000000000..6f710c49b
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_circular_file.cc
@@ -0,0 +1,203 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <gr_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>
+#include <stdio.h>
+#include <string.h>
+
+#ifdef HAVE_IO_H
+#include <io.h>
+#endif
+
+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 */
+ if(ftruncate (d_fd, size + HEADER_SIZE) != 0) {
+ perror (filename);
+ exit (1);
+ }
+#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
index 000000000..ca1f793f3
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_circular_file.h
@@ -0,0 +1,60 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef _GR_CIRCULAR_FILE_H_
+#define _GR_CIRCULAR_FILE_H_
+
+#include <gr_core_api.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_CORE_API 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_ */ \ No newline at end of file
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
index 000000000..596c14996
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_complex_to_interleaved_short.cc
@@ -0,0 +1,62 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2005,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_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 gnuradio::get_initial_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
index 000000000..66503413f
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_complex_to_interleaved_short.h
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_COMPLEX_TO_INTERLEAVED_SHORT_H
+#define INCLUDED_GR_COMPLEX_TO_INTERLEAVED_SHORT_H
+
+#include <gr_core_api.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_CORE_API 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_blk
+ */
+
+class GR_CORE_API gr_complex_to_interleaved_short : public gr_sync_interpolator
+{
+ friend GR_CORE_API 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
index 000000000..19c01b7c6
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_complex_to_interleaved_short.i
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,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
index 000000000..cdf6d7f3a
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_complex_to_xxx.cc
@@ -0,0 +1,280 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2008,2010,2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_complex_to_xxx.h>
+#include <gr_io_signature.h>
+#include <gr_math.h>
+#include <volk/volk.h>
+
+// ----------------------------------------------------------------
+
+gr_complex_to_float_sptr
+gr_make_complex_to_float (unsigned int vlen)
+{
+ return gnuradio::get_initial_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)
+{
+ const int alignment_multiple =
+ volk_get_alignment() / sizeof(float);
+ set_alignment(std::max(1,alignment_multiple));
+}
+
+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;
+ int noi = noutput_items * d_vlen;
+
+ switch (output_items.size ()){
+ case 1:
+ if(is_unaligned()) {
+ for (int i = 0; i < noi; i++){
+ out0[i] = in[i].real ();
+ }
+ }
+ else {
+ volk_32fc_deinterleave_real_32f_a(out0, in, noi);
+ }
+ break;
+
+ case 2:
+ out1 = (float *) output_items[1];
+ if(is_unaligned()) {
+ for (int i = 0; i < noi; i++){
+ out0[i] = in[i].real ();
+ out1[i] = in[i].imag ();
+ }
+ }
+ else {
+ volk_32fc_deinterleave_32f_x2_a(out0, out1, in, noi);
+ }
+ break;
+
+ default:
+ abort ();
+ }
+
+ return noutput_items;
+}
+
+// ----------------------------------------------------------------
+
+gr_complex_to_real_sptr
+gr_make_complex_to_real (unsigned int vlen)
+{
+ return gnuradio::get_initial_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)
+{
+ const int alignment_multiple =
+ volk_get_alignment() / sizeof(float);
+ set_alignment(std::max(1,alignment_multiple));
+}
+
+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;
+
+ if(is_unaligned()) {
+ for (int i = 0; i < noi; i++){
+ out[i] = in[i].real ();
+ }
+ }
+ else {
+ volk_32fc_deinterleave_real_32f_a(out, in, noi);
+ }
+
+ return noutput_items;
+}
+
+// ----------------------------------------------------------------
+
+gr_complex_to_imag_sptr
+gr_make_complex_to_imag (unsigned int vlen)
+{
+ return gnuradio::get_initial_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)
+{
+ const int alignment_multiple =
+ volk_get_alignment() / sizeof(float);
+ set_alignment(std::max(1,alignment_multiple));
+}
+
+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;
+
+ if(is_unaligned()) {
+ for (int i = 0; i < noi; i++){
+ out[i] = in[i].imag ();
+ }
+ }
+ else {
+ volk_32fc_deinterleave_imag_32f_a(out, in, noi);
+ }
+
+ return noutput_items;
+}
+
+// ----------------------------------------------------------------
+
+gr_complex_to_mag_sptr
+gr_make_complex_to_mag (unsigned int vlen)
+{
+ return gnuradio::get_initial_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)
+{
+ const int alignment_multiple =
+ volk_get_alignment() / sizeof(float);
+ set_alignment(std::max(1,alignment_multiple));
+}
+
+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;
+
+ // turned out to be faster than aligned/unaligned switching
+ volk_32fc_magnitude_32f_u(out, in, noi);
+
+ return noutput_items;
+}
+
+// ----------------------------------------------------------------
+
+gr_complex_to_mag_squared_sptr
+gr_make_complex_to_mag_squared (unsigned int vlen)
+{
+ return gnuradio::get_initial_sptr(new gr_complex_to_mag_squared (vlen));
+}
+
+gr_complex_to_mag_squared::gr_complex_to_mag_squared (unsigned int vlen)
+ : gr_sync_block ("complex_to_mag_squared",
+ gr_make_io_signature (1, 1, sizeof (gr_complex) * vlen),
+ gr_make_io_signature (1, 1, sizeof (float) * vlen)),
+ d_vlen(vlen)
+{
+ const int alignment_multiple =
+ volk_get_alignment() / sizeof(float);
+ set_alignment(std::max(1,alignment_multiple));
+}
+
+int
+gr_complex_to_mag_squared::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;
+
+ if(is_unaligned()) {
+ volk_32fc_magnitude_squared_32f_u(out, in, noi);
+ }
+ else {
+ volk_32fc_magnitude_squared_32f_a(out, in, noi);
+ }
+
+ return noutput_items;
+}
+
+// ----------------------------------------------------------------
+
+gr_complex_to_arg_sptr
+gr_make_complex_to_arg (unsigned int vlen)
+{
+ return gnuradio::get_initial_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)
+{
+ const int alignment_multiple =
+ volk_get_alignment() / sizeof(float);
+ set_alignment(std::max(1,alignment_multiple));
+}
+
+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;
+
+ // The fast_atan2f is faster than Volk
+ for (int i = 0; i < noi; i++){
+ // out[i] = std::arg (in[i]);
+ out[i] = gr_fast_atan2f(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
index 000000000..a2f06ea28
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_complex_to_xxx.h
@@ -0,0 +1,160 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_COMPLEX_TO_XXX_H
+#define INCLUDED_GR_COMPLEX_TO_XXX_H
+
+#include <gr_core_api.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_mag_squared;
+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_mag_squared> gr_complex_to_mag_squared_sptr;
+typedef boost::shared_ptr<gr_complex_to_arg> gr_complex_to_arg_sptr;
+
+GR_CORE_API gr_complex_to_float_sptr gr_make_complex_to_float (unsigned int vlen=1);
+GR_CORE_API gr_complex_to_real_sptr gr_make_complex_to_real (unsigned int vlen=1);
+GR_CORE_API gr_complex_to_imag_sptr gr_make_complex_to_imag (unsigned int vlen=1);
+GR_CORE_API gr_complex_to_mag_sptr gr_make_complex_to_mag (unsigned int vlen=1);
+GR_CORE_API gr_complex_to_mag_squared_sptr gr_make_complex_to_mag_squared (unsigned int vlen=1);
+GR_CORE_API 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_blk
+ * \param vlen vector len (default 1)
+ */
+class GR_CORE_API gr_complex_to_float : public gr_sync_block
+{
+ friend GR_CORE_API 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_blk
+ * \param vlen vector len (default 1)
+ */
+class GR_CORE_API gr_complex_to_real : public gr_sync_block
+{
+ friend GR_CORE_API 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_blk
+ * \param vlen vector len (default 1)
+ */
+class GR_CORE_API gr_complex_to_imag : public gr_sync_block
+{
+ friend GR_CORE_API 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_blk
+ * \param vlen vector len (default 1)
+ */
+class GR_CORE_API gr_complex_to_mag : public gr_sync_block
+{
+ friend GR_CORE_API 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, magnitude squared out (float)
+ * \ingroup converter_blk
+ * \param vlen vector len (default 1)
+ */
+class GR_CORE_API gr_complex_to_mag_squared : public gr_sync_block
+{
+ friend GR_CORE_API gr_complex_to_mag_squared_sptr gr_make_complex_to_mag_squared (unsigned int vlen);
+ gr_complex_to_mag_squared (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_blk
+ * \param vlen vector len (default 1)
+ */
+class GR_CORE_API gr_complex_to_arg : public gr_sync_block
+{
+ friend GR_CORE_API 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
index 000000000..372b0e8b5
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_complex_to_xxx.i
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,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_mag_squared);
+gr_complex_to_mag_squared_sptr gr_make_complex_to_mag_squared (unsigned int vlen=1);
+class gr_complex_to_mag_squared : public gr_sync_block
+{
+ gr_complex_to_mag_squared (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
index 000000000..94ac3e162
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_conjugate_cc.cc
@@ -0,0 +1,65 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+// 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>
+#include <volk/volk.h>
+
+gr_conjugate_cc_sptr
+gr_make_conjugate_cc ()
+{
+ return gnuradio::get_initial_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)))
+{
+ const int alignment_multiple =
+ volk_get_alignment() / sizeof(gr_complex);
+ set_alignment(std::max(1,alignment_multiple));
+}
+
+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];
+
+ if(is_unaligned()) {
+ volk_32fc_conjugate_32fc_u(optr, iptr, noutput_items);
+ }
+ else {
+ volk_32fc_conjugate_32fc_a(optr, iptr, noutput_items);
+ }
+
+ 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
index 000000000..e0a2af716
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_conjugate_cc.h
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, 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_core_api.h>
+#include <gr_sync_block.h>
+
+class gr_conjugate_cc;
+typedef boost::shared_ptr<gr_conjugate_cc> gr_conjugate_cc_sptr;
+
+GR_CORE_API gr_conjugate_cc_sptr gr_make_conjugate_cc ();
+
+/*!
+ * \brief output = complex conjugate of input
+ * \ingroup math_blk
+ */
+class GR_CORE_API gr_conjugate_cc : public gr_sync_block
+{
+ friend GR_CORE_API 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
index 000000000..444ebb1b8
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_conjugate_cc.i
@@ -0,0 +1,33 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+// 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_constants.cc.in b/gnuradio-core/src/lib/general/gr_constants.cc.in
new file mode 100644
index 000000000..b94f254d6
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_constants.cc.in
@@ -0,0 +1,57 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006,2009 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <gr_constants.h>
+
+const std::string
+gr_prefix()
+{
+ return "@prefix@";
+}
+
+const std::string
+gr_sysconfdir()
+{
+ return "@SYSCONFDIR@";
+}
+
+const std::string
+gr_prefsdir()
+{
+ return "@GR_PREFSDIR@";
+}
+
+const std::string
+gr_build_date()
+{
+ return "@BUILD_DATE@";
+}
+
+const std::string
+gr_version()
+{
+ return "@VERSION@";
+}
diff --git a/gnuradio-core/src/lib/general/gr_constants.h b/gnuradio-core/src/lib/general/gr_constants.h
new file mode 100644
index 000000000..00ed9463d
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_constants.h
@@ -0,0 +1,53 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006,2009 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifndef INCLUDED_GR_CONSTANTS_H
+#define INCLUDED_GR_CONSTANTS_H
+
+#include <gr_core_api.h>
+#include <string>
+
+/*!
+ * \brief return ./configure --prefix argument. Typically /usr/local
+ */
+GR_CORE_API const std::string gr_prefix();
+
+/*!
+ * \brief return ./configure --sysconfdir argument. Typically $prefix/etc or /etc
+ */
+GR_CORE_API const std::string gr_sysconfdir();
+
+/*!
+ * \brief return preferences file directory. Typically $sysconfdir/etc/conf.d
+ */
+GR_CORE_API const std::string gr_prefsdir();
+
+/*!
+ * \brief return date/time of build, as set when 'bootstrap' is run
+ */
+GR_CORE_API const std::string gr_build_date();
+
+/*!
+ * \brief return version string defined in configure.ac
+ */
+GR_CORE_API const std::string gr_version();
+
+#endif /* INCLUDED_GR_CONSTANTS_H */
diff --git a/gnuradio-core/src/lib/general/gr_constants.i b/gnuradio-core/src/lib/general/gr_constants.i
new file mode 100644
index 000000000..a5aef1492
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_constants.i
@@ -0,0 +1,13 @@
+/* -*- c++ -*- */
+
+%rename(prefix) gr_prefix;
+%rename(sysconfdir) gr_sysconfdir;
+%rename(prefsdir) gr_prefsdir;
+%rename(build_date) gr_build_date;
+%rename(version) gr_version;
+
+const std::string gr_prefix();
+const std::string gr_sysconfdir();
+const std::string gr_prefsdir();
+const std::string gr_build_date();
+const std::string gr_version();
diff --git a/gnuradio-core/src/lib/general/gr_copy.cc b/gnuradio-core/src/lib/general/gr_copy.cc
new file mode 100644
index 000000000..0a6f721f9
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_copy.cc
@@ -0,0 +1,71 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006,2009 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_copy.h>
+#include <gr_io_signature.h>
+#include <string.h>
+
+gr_copy_sptr
+gr_make_copy(size_t itemsize)
+{
+ return gnuradio::get_initial_sptr(new gr_copy(itemsize));
+}
+
+gr_copy::gr_copy(size_t itemsize)
+ : gr_block ("copy",
+ gr_make_io_signature (1, 1, itemsize),
+ gr_make_io_signature (1, 1, itemsize)),
+ d_itemsize(itemsize),
+ d_enabled(true)
+{
+}
+
+bool
+gr_copy::check_topology(int ninputs, int noutputs)
+{
+ return ninputs == noutputs;
+}
+
+int
+gr_copy::general_work(int noutput_items,
+ gr_vector_int &ninput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ const uint8_t *in = (const uint8_t *) input_items[0];
+ uint8_t *out = (uint8_t *) output_items[0];
+
+ int n = std::min<int>(ninput_items[0], noutput_items);
+ int j = 0;
+
+ if (d_enabled) {
+ memcpy(out, in, n*d_itemsize);
+ j = n;
+ }
+
+ consume_each(n);
+ return j;
+}
diff --git a/gnuradio-core/src/lib/general/gr_copy.h b/gnuradio-core/src/lib/general/gr_copy.h
new file mode 100644
index 000000000..b0769fa2b
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_copy.h
@@ -0,0 +1,63 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006,2009 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_COPY_H
+#define INCLUDED_GR_COPY_H
+
+#include <gr_core_api.h>
+#include <gr_block.h>
+
+class gr_copy;
+typedef boost::shared_ptr<gr_copy> gr_copy_sptr;
+
+GR_CORE_API gr_copy_sptr gr_make_copy(size_t itemsize);
+
+/*!
+ * \brief output[i] = input[i]
+ * \ingroup misc_blk
+ *
+ * When enabled (default), this block copies its input to its output.
+ * When disabled, this block drops its input on the floor.
+ *
+ */
+class GR_CORE_API gr_copy : public gr_block
+{
+ size_t d_itemsize;
+ bool d_enabled;
+
+ friend GR_CORE_API gr_copy_sptr gr_make_copy(size_t itemsize);
+ gr_copy(size_t itemsize);
+
+ public:
+
+ bool check_topology(int ninputs, int noutputs);
+
+ void set_enabled(bool enable) { d_enabled = enable; }
+ bool enabled() const { return d_enabled;}
+
+ int general_work(int noutput_items,
+ gr_vector_int &ninput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+#endif
diff --git a/gnuradio-core/src/lib/general/gr_copy.i b/gnuradio-core/src/lib/general/gr_copy.i
new file mode 100644
index 000000000..12ddce6aa
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_copy.i
@@ -0,0 +1,36 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006,2009 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,copy)
+
+gr_copy_sptr gr_make_copy(size_t itemsize);
+
+class gr_copy : public gr_block
+{
+ private:
+ gr_copy(size_t itemsize);
+
+public:
+
+ void set_enabled(bool enabled);
+ bool enabled();
+};
diff --git a/gnuradio-core/src/lib/general/gr_core_api.h b/gnuradio-core/src/lib/general/gr_core_api.h
new file mode 100644
index 000000000..74c802857
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_core_api.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2010-2011 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_CORE_API_H
+#define INCLUDED_GR_CORE_API_H
+
+#include <gruel/attributes.h>
+
+#ifdef gnuradio_core_EXPORTS
+# define GR_CORE_API __GR_ATTR_EXPORT
+#else
+# define GR_CORE_API __GR_ATTR_IMPORT
+#endif
+
+#endif /* INCLUDED_GR_CORE_API_H */
diff --git a/gnuradio-core/src/lib/general/gr_correlate_access_code_tag_bb.cc b/gnuradio-core/src/lib/general/gr_correlate_access_code_tag_bb.cc
new file mode 100644
index 000000000..73ded3c8b
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_correlate_access_code_tag_bb.cc
@@ -0,0 +1,129 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2006,2010,2011 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_correlate_access_code_tag_bb.h>
+#include <gr_io_signature.h>
+#include <stdexcept>
+#include <gr_count_bits.h>
+#include <cstdio>
+#include <iostream>
+
+#define VERBOSE 0
+
+
+gr_correlate_access_code_tag_bb_sptr
+gr_make_correlate_access_code_tag_bb (const std::string &access_code, int threshold, const std::string &tag_name)
+{
+ return gnuradio::get_initial_sptr(new gr_correlate_access_code_tag_bb (access_code, threshold, tag_name));
+}
+
+
+gr_correlate_access_code_tag_bb::gr_correlate_access_code_tag_bb (
+ const std::string &access_code, int threshold, const std::string &tag_name)
+ : gr_sync_block ("correlate_access_code_tag_bb",
+ gr_make_io_signature (1, 1, sizeof(char)),
+ gr_make_io_signature (1, 1, sizeof(char))),
+ d_data_reg(0), d_mask(0),
+ d_threshold(threshold), d_len(0)
+
+{
+ if (!set_access_code(access_code)){
+ fprintf(stderr, "gr_correlate_access_code_tag_bb: access_code is > 64 bits\n");
+ throw std::out_of_range ("access_code is > 64 bits");
+ }
+
+ std::stringstream str;
+ str << name() << unique_id();
+ d_me = pmt::pmt_string_to_symbol(str.str());
+ d_key = pmt::pmt_string_to_symbol(tag_name);
+}
+
+gr_correlate_access_code_tag_bb::~gr_correlate_access_code_tag_bb ()
+{
+}
+
+bool
+gr_correlate_access_code_tag_bb::set_access_code(
+ const std::string &access_code)
+{
+ d_len = access_code.length(); // # of bytes in string
+ if (d_len > 64)
+ return false;
+
+ // set len top bits to 1.
+ d_mask = ((~0ULL) >> (64 - d_len)) << (64 - d_len);
+
+ d_access_code = 0;
+ for (unsigned i=0; i < 64; i++){
+ d_access_code <<= 1;
+ if (i < d_len)
+ d_access_code |= access_code[i] & 1; // look at LSB only
+ }
+
+ return true;
+}
+
+int
+gr_correlate_access_code_tag_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];
+
+ uint64_t abs_out_sample_cnt = nitems_written(0);
+
+ for (int i = 0; i < noutput_items; i++){
+
+ out[i] = in[i];
+
+ // 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
+ new_flag = (nwrong <= d_threshold);
+
+ // shift in new data and new flag
+ d_data_reg = (d_data_reg << 1) | (in[i] & 0x1);
+ if (new_flag) {
+ if(VERBOSE) std::cout << "writing tag at sample " << abs_out_sample_cnt + i << std::endl;
+ add_item_tag(0, //stream ID
+ abs_out_sample_cnt + i - 64 + d_len, //sample
+ d_key, //frame info
+ pmt::pmt_t(), //data (unused)
+ d_me //block src id
+ );
+ }
+ }
+
+ return noutput_items;
+}
+
diff --git a/gnuradio-core/src/lib/general/gr_correlate_access_code_tag_bb.h b/gnuradio-core/src/lib/general/gr_correlate_access_code_tag_bb.h
new file mode 100644
index 000000000..345d3004a
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_correlate_access_code_tag_bb.h
@@ -0,0 +1,87 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005,2006,2011 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_gr_correlate_access_code_tag_bb_H
+#define INCLUDED_gr_correlate_access_code_tag_bb_H
+
+#include <gr_core_api.h>
+#include <gr_sync_block.h>
+#include <string>
+
+class gr_correlate_access_code_tag_bb;
+typedef boost::shared_ptr<gr_correlate_access_code_tag_bb> gr_correlate_access_code_tag_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
+ * \param tag_name key of the tag inserted into the tag stream
+ */
+GR_CORE_API gr_correlate_access_code_tag_bb_sptr
+gr_make_correlate_access_code_tag_bb (const std::string &access_code, int threshold,
+ const std::string &tag_name);
+
+/*!
+ * \brief Examine input for specified access code, one bit at a time.
+ * \ingroup sync_blk
+ *
+ * input: stream of bits, 1 bit per input byte (data in LSB)
+ * output: unaltered stream of bits (plus tags)
+ *
+ * This block annotates the input stream with tags. The tags have key
+ * name [tag_name], specified in the constructor. Used for searching
+ * an input data stream for preambles, etc.
+ */
+class GR_CORE_API gr_correlate_access_code_tag_bb : public gr_sync_block
+{
+ friend GR_CORE_API gr_correlate_access_code_tag_bb_sptr
+ gr_make_correlate_access_code_tag_bb (const std::string &access_code, int threshold,
+ const std::string &tag_name);
+ 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_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_len; //the length of the access code
+
+ pmt::pmt_t d_key, d_me; //d_key is the tag name, d_me is the block name + unique ID
+
+ protected:
+ gr_correlate_access_code_tag_bb(const std::string &access_code, int threshold,
+ const std::string &tag_name);
+
+ public:
+ ~gr_correlate_access_code_tag_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_tag_bb_H */
diff --git a/gnuradio-core/src/lib/general/gr_correlate_access_code_tag_bb.i b/gnuradio-core/src/lib/general/gr_correlate_access_code_tag_bb.i
new file mode 100644
index 000000000..f7ca4bea7
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_correlate_access_code_tag_bb.i
@@ -0,0 +1,60 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,correlate_access_code_tag_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_tag_bb_sptr
+gr_make_correlate_access_code_tag_bb (const std::string &access_code, int threshold, const std::string &tag_name)
+ 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_tag_bb : public gr_sync_block
+{
+ friend gr_correlate_access_code_tag_bb_sptr
+ gr_make_correlate_access_code_tag_bb (const std::string &access_code, int threshold, const std::string &tag_name);
+ protected:
+ gr_correlate_access_code_tag_bb(const std::string &access_code, int threshold, const std::string &tag_name);
+
+ public:
+ ~gr_correlate_access_code_tag_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_count_bits.cc b/gnuradio-core/src/lib/general/gr_count_bits.cc
new file mode 100644
index 000000000..4776fe61a
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_count_bits.cc
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <gr_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
index 000000000..76d0173eb
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_count_bits.h
@@ -0,0 +1,33 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef _GR_COUNT_BITS_H_
+#define _GR_COUNT_BITS_H_
+
+#include <gr_core_api.h>
+
+GR_CORE_API unsigned int gr_count_bits8(unsigned int x); // return number of set bits in the low 8 bits of x
+GR_CORE_API unsigned int gr_count_bits16(unsigned int x); // return number of set bits in the low 16 bits of x
+GR_CORE_API unsigned int gr_count_bits32(unsigned int x); // return number of set bits in the low 32 bits of x
+GR_CORE_API unsigned int gr_count_bits64(unsigned long long int x);
+
+#endif /* _GR_COUNT_BITS_H_ */
diff --git a/gnuradio-core/src/lib/general/gr_cpfsk_bc.cc b/gnuradio-core/src/lib/general/gr_cpfsk_bc.cc
new file mode 100644
index 000000000..24f0edd5c
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_cpfsk_bc.cc
@@ -0,0 +1,78 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008,2010 Free Software Foundation, Inc.
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_cpfsk_bc.h>
+#include <gr_io_signature.h>
+#include <gr_expj.h>
+
+#define M_TWOPI (2*M_PI)
+
+gr_cpfsk_bc_sptr
+gr_make_cpfsk_bc(float k, float ampl, int samples_per_sym)
+{
+ return gnuradio::get_initial_sptr(new gr_cpfsk_bc(k, ampl, samples_per_sym));
+}
+
+gr_cpfsk_bc::gr_cpfsk_bc(float k, float ampl, int samples_per_sym)
+ : gr_sync_interpolator("cpfsk_bc",
+ gr_make_io_signature(1, 1, sizeof(char)),
+ gr_make_io_signature(1, 1, sizeof(gr_complex)),
+ samples_per_sym)
+{
+ d_samples_per_sym = samples_per_sym;
+ d_freq = k*M_PI/samples_per_sym;
+ d_ampl = ampl;
+ d_phase = 0.0;
+}
+
+gr_cpfsk_bc::~gr_cpfsk_bc()
+{
+}
+
+int
+gr_cpfsk_bc::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];
+ gr_complex *out = (gr_complex *)output_items[0];
+
+ for (int i = 0; i < noutput_items/d_samples_per_sym; i++) {
+ for (int j = 0; j < d_samples_per_sym; j++) {
+ if (in[i] == 1)
+ d_phase += d_freq;
+ else
+ d_phase -= d_freq;
+
+ while (d_phase > M_TWOPI)
+ d_phase -= M_TWOPI;
+ while (d_phase < -M_TWOPI)
+ d_phase += M_TWOPI;
+
+ *out++ = gr_expj(d_phase)*d_ampl;
+ }
+ }
+
+ return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_cpfsk_bc.h b/gnuradio-core/src/lib/general/gr_cpfsk_bc.h
new file mode 100644
index 000000000..6ad2774b3
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_cpfsk_bc.h
@@ -0,0 +1,64 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008 Free Software Foundation, Inc.
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifndef INCLUDED_GR_CPFSK_BC_H
+#define INCLUDED_GR_CPFSK_BC_H
+
+#include <gr_core_api.h>
+#include <gr_sync_interpolator.h>
+
+class gr_cpfsk_bc;
+
+typedef boost::shared_ptr<gr_cpfsk_bc> gr_cpfsk_bc_sptr;
+
+GR_CORE_API gr_cpfsk_bc_sptr gr_make_cpfsk_bc(float k, float ampl, int samples_per_sym);
+
+/*!
+ * \brief Perform continuous phase 2-level frequency shift keying modulation
+ * on an input stream of unpacked bits.
+ * \ingroup modulation_blk
+ *
+ * \param k modulation index
+ * \param ampl output amplitude
+ * \param samples_per_sym number of output samples per input bit
+ */
+
+class GR_CORE_API gr_cpfsk_bc : public gr_sync_interpolator
+{
+private:
+ friend GR_CORE_API gr_cpfsk_bc_sptr gr_make_cpfsk_bc(float k, float ampl, int samples_per_sym);
+
+ gr_cpfsk_bc(float k, float ampl, int samples_per_sym);
+
+ int d_samples_per_sym; // Samples per symbol, square pulse
+ float d_freq; // Modulation index*pi/samples_per_sym
+ float d_ampl; // Output amplitude
+ float d_phase; // Current phase
+
+ public:
+ ~gr_cpfsk_bc();
+
+ void set_amplitude(float amplitude) { d_ampl = amplitude; }
+
+ int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+#endif /* INCLUDED_GR_CPFSK_BC_H */
diff --git a/gnuradio-core/src/lib/general/gr_cpfsk_bc.i b/gnuradio-core/src/lib/general/gr_cpfsk_bc.i
new file mode 100644
index 000000000..b86dfb81b
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_cpfsk_bc.i
@@ -0,0 +1,34 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,cpfsk_bc);
+
+gr_cpfsk_bc_sptr gr_make_cpfsk_bc(float k, float ampl, int samples_per_sym);
+
+class gr_cpfsk_bc : public gr_sync_interpolator
+{
+private:
+ gr_cpfsk_bc(float k, float ampl, int samples_per_sym);
+
+public:
+ void set_amplitude(float amplitude);
+};
diff --git a/gnuradio-core/src/lib/general/gr_cpm.cc b/gnuradio-core/src/lib/general/gr_cpm.cc
new file mode 100644
index 000000000..32ce6502d
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_cpm.cc
@@ -0,0 +1,218 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2010 Free Software Foundation, Inc.
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+// Calculate the taps for the CPM phase responses
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <cmath>
+#include <cfloat>
+#include <gr_cpm.h>
+
+//gives us erf on compilers without it
+#include <boost/math/special_functions/erf.hpp>
+namespace bm = boost::math;
+
+#ifndef M_TWOPI
+# define M_TWOPI (2*M_PI)
+#endif
+
+//! Normalised sinc function, sinc(x)=sin(pi*x)/pi*x
+inline double
+sinc(double x)
+{
+ if (x == 0) {
+ return 1.0;
+ }
+
+ return sin(M_PI * x) / (M_PI * x);
+}
+
+
+//! Taps for L-RC CPM (Raised cosine of length L symbols)
+std::vector<float>
+generate_cpm_lrc_taps(unsigned samples_per_sym, unsigned L)
+{
+ std::vector<float> taps(samples_per_sym * L, 1.0/L/samples_per_sym);
+ for (unsigned i = 0; i < samples_per_sym * L; i++) {
+ taps[i] *= 1 - cos(M_TWOPI * i / L / samples_per_sym);
+ }
+
+ return taps;
+}
+
+
+/*! Taps for L-SRC CPM (Spectral raised cosine of length L symbols).
+ *
+ * L-SRC has a time-continuous phase response function of
+ *
+ * g(t) = 1/LT * sinc(2t/LT) * cos(beta * 2pi t / LT) / (1 - (4beta / LT * t)^2)
+ *
+ * which is the Fourier transform of a cos-rolloff function with rolloff
+ * beta, and looks like a sinc-function, multiplied with a rolloff term.
+ * We return the main lobe of the sinc, i.e., everything between the
+ * zero crossings.
+ * The time-discrete IR is thus
+ *
+ * g(k) = 1/Ls * sinc(2k/Ls) * cos(beta * pi k / Ls) / (1 - (4beta / Ls * k)^2)
+ * where k = 0...Ls-1
+ * and s = samples per symbol.
+ */
+std::vector<float>
+generate_cpm_lsrc_taps(unsigned samples_per_sym, unsigned L, double beta)
+{
+ double Ls = (double) L * samples_per_sym;
+ std::vector<double> taps_d(L * samples_per_sym, 0.0);
+ std::vector<float> taps(L * samples_per_sym, 0.0);
+
+ double sum = 0;
+ for (unsigned i = 0; i < samples_per_sym * L; i++) {
+ double k = i - Ls/2; // Causal to acausal
+
+ taps_d[i] = 1.0 / Ls * sinc(2.0 * k / Ls);
+
+ // For k = +/-Ls/4*beta, the rolloff term's cos-function becomes zero
+ // and the whole thing converges to PI/4 (to prove this, use de
+ // l'hopital's rule).
+ if (fabs(fabs(k) - Ls/4/beta) < 2*DBL_EPSILON) {
+ taps_d[i] *= M_PI_4;
+ } else {
+ double tmp = 4.0 * beta * k / Ls;
+ taps_d[i] *= cos(beta * M_TWOPI * k / Ls) / (1 - tmp * tmp);
+ }
+ sum += taps_d[i];
+ }
+ for (unsigned i = 0; i < samples_per_sym * L; i++) {
+ taps[i] = (float) taps_d[i] / sum;
+ }
+
+ return taps;
+}
+
+
+//! Taps for L-REC CPM (Rectangular pulse shape of length L symbols)
+std::vector<float>
+generate_cpm_lrec_taps(unsigned samples_per_sym, unsigned L)
+{
+ return std::vector<float>(samples_per_sym * L, 1.0/L/samples_per_sym);
+}
+
+
+//! Helper function for TFM
+double tfm_g0(double k, double sps)
+{
+ if (fabs(k) < 2 * DBL_EPSILON) {
+ return 1.145393004159143; // 1 + pi^2/48 / sqrt(2)
+ }
+
+ const double pi2_24 = 0.411233516712057; // pi^2/24
+ double f = M_PI * k / sps;
+ return sinc(k/sps) - pi2_24 * (2 * sin(f) - 2*f*cos(f) - f*f*sin(f)) / (f*f*f);
+}
+
+
+//! Taps for TFM CPM (Tamed frequency modulation)
+//
+// See [2, Chapter 2.7.2].
+//
+// [2]: Anderson, Aulin and Sundberg; Digital Phase Modulation
+std::vector<float>
+generate_cpm_tfm_taps(unsigned sps, unsigned L)
+{
+ unsigned causal_shift = sps * L / 2;
+ std::vector<double> taps_d(sps * L, 0.0);
+ std::vector<float> taps(sps * L, 0.0);
+
+ double sum = 0;
+ for (unsigned i = 0; i < sps * L; i++) {
+ double k = (double)(((int)i) - ((int)causal_shift)); // Causal to acausal
+
+ taps_d[i] = tfm_g0(k - sps, sps) +
+ 2 * tfm_g0(k, sps) +
+ tfm_g0(k + sps, sps);
+ sum += taps_d[i];
+ }
+ for (unsigned i = 0; i < sps * L; i++) {
+ taps[i] = (float) taps_d[i] / sum;
+ }
+
+ return taps;
+}
+
+
+//! Taps for Gaussian CPM. Phase response is truncated after \p L symbols.
+// \p bt sets the 3dB-time-bandwidth product.
+//
+// Note: for h = 0.5, this is the phase response for GMSK.
+//
+// This C99-compatible formula for the taps is taken straight
+// from [1, Chapter 9.2.3].
+// A version in Q-notation can be found in [2, Chapter 2.7.2].
+//
+// [1]: Karl-Dirk Kammeyer; Nachrichtenübertragung, 4th Edition.
+// [2]: Anderson, Aulin and Sundberg; Digital Phase Modulation
+//
+std::vector<float>
+generate_cpm_gaussian_taps(unsigned samples_per_sym, unsigned L, double bt)
+{
+ double Ls = (double) L * samples_per_sym;
+ std::vector<double> taps_d(L * samples_per_sym, 0.0);
+ std::vector<float> taps(L * samples_per_sym, 0.0);
+
+ // alpha = sqrt(2/ln(2)) * pi * BT
+ double alpha = 5.336446256636997 * bt;
+ for (unsigned i = 0; i < samples_per_sym * L; i++) {
+ double k = i - Ls/2; // Causal to acausal
+ taps_d[i] = (bm::erf(alpha * (k / samples_per_sym + 0.5)) -
+ bm::erf(alpha * (k / samples_per_sym - 0.5)))
+ * 0.5 / samples_per_sym;
+ taps[i] = (float) taps_d[i];
+ }
+
+ return taps;
+}
+
+
+std::vector<float>
+gr_cpm::phase_response(cpm_type type, unsigned samples_per_sym, unsigned L, double beta)
+{
+ switch (type) {
+ case LRC:
+ return generate_cpm_lrc_taps(samples_per_sym, L);
+
+ case LSRC:
+ return generate_cpm_lsrc_taps(samples_per_sym, L, beta);
+
+ case LREC:
+ return generate_cpm_lrec_taps(samples_per_sym, L);
+
+ case TFM:
+ return generate_cpm_tfm_taps(samples_per_sym, L);
+
+ case GAUSSIAN:
+ return generate_cpm_gaussian_taps(samples_per_sym, L, beta);
+
+ default:
+ return generate_cpm_lrec_taps(samples_per_sym, 1);
+ }
+}
+
diff --git a/gnuradio-core/src/lib/general/gr_cpm.h b/gnuradio-core/src/lib/general/gr_cpm.h
new file mode 100644
index 000000000..ef2ff8414
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_cpm.h
@@ -0,0 +1,81 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2010 Free Software Foundation, Inc.
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+
+#ifndef INCLUDED_GR_CPM_H
+#define INCLUDED_GR_CPM_H
+
+#include <gr_core_api.h>
+#include <vector>
+
+class GR_CORE_API gr_cpm
+{
+ public:
+ enum cpm_type {
+ LRC,
+ LSRC,
+ LREC,
+ TFM,
+ GAUSSIAN,
+ GENERIC = 999
+ };
+
+ /*! \brief Return the taps for an interpolating FIR filter (gr_interp_fir_filter_fff).
+ *
+ * These taps represent the phase response \f$g(k)\f$ for use in a CPM modulator,
+ * see also gr_cpmmod_bc.
+ *
+ * \param type The CPM type (Rectangular, Raised Cosine, Spectral Raised Cosine,
+ * Tamed FM or Gaussian).
+ * \param samples_per_sym Samples per symbol.
+ * \param L The length of the phase response in symbols.
+ * \param beta For Spectral Raised Cosine, this is the rolloff factor. For Gaussian
+ * phase responses, this the 3dB-time-bandwidth product. For all other
+ * cases, it is ignored.
+ *
+ * Output: returns a vector of length \a K = \p samples_per_sym x \p L.
+ * This can be used directly in an interpolating FIR filter such as
+ * gr_interp_fir_filter_fff with interpolation factor \p samples_per_sym.
+ *
+ * All phase responses are normalised s.t. \f$ \sum_{k=0}^{K-1} g(k) = 1\f$; this will cause
+ * a maximum phase change of \f$ h \cdot \pi\f$ between two symbols, where \a h is the
+ * modulation index.
+ *
+ * The following phase responses can be generated:
+ * - LREC: Rectangular phase response.
+ * - LRC: Raised cosine phase response, looks like 1 - cos(x).
+ * - LSRC: Spectral raised cosine. This requires a rolloff factor beta.
+ * The phase response is the Fourier transform of raised cosine
+ * function.
+ * - TFM: Tamed frequency modulation. This scheme minimizes phase change for
+ * rapidly varying input symbols.
+ * - GAUSSIAN: A Gaussian phase response. For a modulation index h = 1/2, this
+ * results in GMSK.
+ *
+ * A short description of all these phase responses can be found in [1].
+ *
+ * [1]: Anderson, Aulin and Sundberg; Digital Phase Modulation
+ */
+ static std::vector<float>
+ phase_response(cpm_type type, unsigned samples_per_sym, unsigned L, double beta=0.3);
+};
+
+#endif /* INCLUDED_GR_CPM_H */
+
diff --git a/gnuradio-core/src/lib/general/gr_cpm.i b/gnuradio-core/src/lib/general/gr_cpm.i
new file mode 100644
index 000000000..6c077687d
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_cpm.i
@@ -0,0 +1,40 @@
+/* -*- C++ -*- */
+/*
+ * Copyright 2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+%rename(cpm) gr_cpm;
+
+class gr_cpm
+{
+ public:
+ enum cpm_type {
+ LRC,
+ LSRC,
+ LREC,
+ TFM,
+ GAUSSIAN,
+ GENERIC = 999
+ };
+
+ static std::vector<float>
+ phase_response(cpm_type type, unsigned samples_per_sym, unsigned L, double beta=0.3);
+};
+
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
index 000000000..d31763a6b
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_ctcss_squelch_ff.cc
@@ -0,0 +1,112 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2006,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_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 gnuradio::get_initial_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
index 000000000..ef3d13ba7
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_ctcss_squelch_ff.h
@@ -0,0 +1,68 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_CTCSS_SQUELCH_FF_H
+#define INCLUDED_GR_CTCSS_SQUELCH_FF_H
+
+#include <gr_core_api.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_CORE_API 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 level_blk
+ */
+class GR_CORE_API 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_CORE_API 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
index 000000000..b160c5dfd
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_ctcss_squelch_ff.i
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,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_decode_ccsds_27_fb.cc b/gnuradio-core/src/lib/general/gr_decode_ccsds_27_fb.cc
new file mode 100644
index 000000000..319aceeaa
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_decode_ccsds_27_fb.cc
@@ -0,0 +1,86 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008,2010 Free Software Foundation, Inc.
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_decode_ccsds_27_fb.h>
+#include <gr_io_signature.h>
+
+gr_decode_ccsds_27_fb_sptr
+gr_make_decode_ccsds_27_fb()
+{
+ return gnuradio::get_initial_sptr(new gr_decode_ccsds_27_fb());
+}
+
+gr_decode_ccsds_27_fb::gr_decode_ccsds_27_fb()
+ : gr_sync_decimator("decode_ccsds_27_fb",
+ gr_make_io_signature(1, 1, sizeof(float)),
+ gr_make_io_signature(1, 1, sizeof(char)),
+ 2*8) // Rate 1/2 code, unpacked to packed translation
+{
+ float RATE = 0.5;
+ float ebn0 = 12.0;
+ float esn0 = RATE*pow(10.0, ebn0/10.0);
+
+ gen_met(d_mettab, 100, esn0, 0.0, 256);
+ viterbi_chunks_init(d_state0);
+}
+
+gr_decode_ccsds_27_fb::~gr_decode_ccsds_27_fb()
+{
+}
+
+int
+gr_decode_ccsds_27_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*16; i++) {
+ // Translate and clip [-1.0..1.0] to [28..228]
+ float sample = in[i]*100.0+128.0;
+ if (sample > 255.0)
+ sample = 255.0;
+ else if (sample < 0.0)
+ sample = 0.0;
+ unsigned char sym = (unsigned char)(floor(sample));
+
+ d_viterbi_in[d_count % 4] = sym;
+ if ((d_count % 4) == 3) {
+ // Every fourth symbol, perform butterfly operation
+ viterbi_butterfly2(d_viterbi_in, d_mettab, d_state0, d_state1);
+
+ // Every sixteenth symbol, read out a byte
+ if (d_count % 16 == 11) {
+ // long metric =
+ viterbi_get_output(d_state0, out++);
+ // printf("%li\n", *(out-1), metric);
+ }
+ }
+
+ d_count++;
+ }
+
+ return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_decode_ccsds_27_fb.h b/gnuradio-core/src/lib/general/gr_decode_ccsds_27_fb.h
new file mode 100644
index 000000000..df8e6f449
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_decode_ccsds_27_fb.h
@@ -0,0 +1,78 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008 Free Software Foundation, Inc.
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifndef INCLUDED_GR_DECODE_CCSDS_27_FB_H
+#define INCLUDED_GR_DECODE_CCSDS_27_FB_H
+
+#include <gr_core_api.h>
+#include <gr_sync_decimator.h>
+
+extern "C" {
+#include <viterbi.h>
+}
+
+class gr_decode_ccsds_27_fb;
+
+typedef boost::shared_ptr<gr_decode_ccsds_27_fb> gr_decode_ccsds_27_fb_sptr;
+
+GR_CORE_API gr_decode_ccsds_27_fb_sptr gr_make_decode_ccsds_27_fb();
+
+/*! \brief A rate 1/2, k=7 convolutional decoder for the CCSDS standard
+ * \ingroup ecc
+ *
+ * This block performs soft-decision convolutional decoding using the Viterbi
+ * algorithm.
+ *
+ * The input is a stream of (possibly noise corrupted) floating point values
+ * nominally spanning [-1.0, 1.0], representing the encoded channel symbols
+ * 0 (-1.0) and 1 (1.0), with erased symbols at 0.0.
+ *
+ * The output is MSB first packed bytes of decoded values.
+ *
+ * As a rate 1/2 code, there will be one output byte for every 16 input symbols.
+ *
+ * This block is designed for continuous data streaming, not packetized data.
+ * The first 32 bits out will be zeroes, with the output delayed four bytes
+ * from the corresponding inputs.
+ */
+
+class GR_CORE_API gr_decode_ccsds_27_fb : public gr_sync_decimator
+{
+private:
+ friend GR_CORE_API gr_decode_ccsds_27_fb_sptr gr_make_decode_ccsds_27_fb();
+
+ gr_decode_ccsds_27_fb();
+
+ // Viterbi state
+ int d_mettab[2][256];
+ struct viterbi_state d_state0[64];
+ struct viterbi_state d_state1[64];
+ unsigned char d_viterbi_in[16];
+
+ int d_count;
+
+public:
+ ~gr_decode_ccsds_27_fb();
+
+ int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+#endif /* INCLUDED_GR_DECODE_CCSDS_27_FB_H */
diff --git a/gnuradio-core/src/lib/general/gr_decode_ccsds_27_fb.i b/gnuradio-core/src/lib/general/gr_decode_ccsds_27_fb.i
new file mode 100644
index 000000000..f2e13b593
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_decode_ccsds_27_fb.i
@@ -0,0 +1,31 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,decode_ccsds_27_fb);
+
+gr_decode_ccsds_27_fb_sptr gr_make_decode_ccsds_27_fb ();
+
+class gr_decode_ccsds_27_fb : public gr_sync_decimator
+{
+private:
+ gr_decode_ccsds_27_fb();
+};
diff --git a/gnuradio-core/src/lib/general/gr_deinterleave.cc b/gnuradio-core/src/lib/general/gr_deinterleave.cc
new file mode 100644
index 000000000..e22db60c1
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_deinterleave.cc
@@ -0,0 +1,78 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#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 gnuradio::get_initial_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
index 000000000..0eecc44d1
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_deinterleave.h
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_DEINTERLEAVE_H
+#define INCLUDED_GR_DEINTERLEAVE_H
+
+#include <gr_core_api.h>
+#include <gr_sync_decimator.h>
+
+class gr_deinterleave;
+typedef boost::shared_ptr<gr_deinterleave> gr_deinterleave_sptr;
+
+GR_CORE_API gr_deinterleave_sptr gr_make_deinterleave (size_t itemsize);
+
+/*!
+ * \brief deinterleave a single input into N outputs
+ * \ingroup slicedice_blk
+ */
+class GR_CORE_API gr_deinterleave : public gr_sync_decimator
+{
+ friend GR_CORE_API 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
index 000000000..a70ce6c52
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_deinterleave.i
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,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_delay.cc b/gnuradio-core/src/lib/general/gr_delay.cc
new file mode 100644
index 000000000..8f728948d
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_delay.cc
@@ -0,0 +1,129 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007,2010,2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_delay.h>
+#include <gr_io_signature.h>
+#include <string.h>
+
+gr_delay_sptr
+gr_make_delay (size_t itemsize, int delay)
+{
+ return gnuradio::get_initial_sptr(new gr_delay (itemsize, delay));
+}
+
+gr_delay::gr_delay (size_t itemsize, int delay)
+ : gr_block ("delay",
+ gr_make_io_signature (1, -1, itemsize),
+ gr_make_io_signature (1, -1, itemsize)),
+ d_itemsize(itemsize)
+{
+ set_delay(delay);
+ d_delta = 0;
+}
+
+void
+gr_delay::forecast (int noutput_items, gr_vector_int &ninput_items_required)
+{
+ // make sure all inputs have noutput_items available
+ unsigned ninputs = ninput_items_required.size ();
+ for (unsigned i = 0; i < ninputs; i++)
+ ninput_items_required[i] = noutput_items;
+}
+
+void
+gr_delay::set_delay (int d)
+{
+ // only set a new delta if there is a change in the delay; this
+ // protects from quickly-repeated calls to this function that would
+ // end with d_delta=0.
+ if(d != delay()) {
+ gruel::scoped_lock l(d_mutex_delay);
+ int old = delay();
+ set_history(d+1);
+ d_delta += delay() - old;
+ }
+}
+
+int
+gr_delay::general_work (int noutput_items,
+ gr_vector_int &ninput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ gruel::scoped_lock l(d_mutex_delay);
+ assert(input_items.size() == output_items.size());
+
+ const char *iptr;
+ char *optr;
+ int cons, ret;
+
+ // No change in delay; just memcpy ins to outs
+ if(d_delta == 0) {
+ for(size_t i = 0; i < input_items.size(); i++) {
+ iptr = (const char *) input_items[i];
+ optr = (char *) output_items[i];
+ std::memcpy(optr, iptr, noutput_items*d_itemsize);
+ }
+ cons = noutput_items;
+ ret = noutput_items;
+ }
+
+ // Skip over d_delta items on the input
+ else if(d_delta < 0) {
+ int n_to_copy, n_adj;
+ int delta = -d_delta;
+ n_to_copy = std::max(0, noutput_items-delta);
+ n_adj = std::min(delta, noutput_items);
+ for(size_t i = 0; i < input_items.size(); i++) {
+ iptr = (const char *) input_items[i];
+ optr = (char *) output_items[i];
+ std::memcpy(optr, iptr+delta*d_itemsize, n_to_copy*d_itemsize);
+ }
+ cons = noutput_items;
+ ret = n_to_copy;
+ delta -= n_adj;
+ d_delta = -delta;
+ }
+
+ //produce but not consume (inserts zeros)
+ else { // d_delta > 0
+ int n_from_input, n_padding;
+ n_from_input = std::max(0, noutput_items-d_delta);
+ n_padding = std::min(d_delta, noutput_items);
+ for(size_t i = 0; i < input_items.size(); i++) {
+ iptr = (const char *) input_items[i];
+ optr = (char *) output_items[i];
+ std::memset(optr, 0, n_padding*d_itemsize);
+ std::memcpy(optr, iptr, n_from_input*d_itemsize);
+ }
+ cons = n_from_input;
+ ret = noutput_items;
+ d_delta -= n_padding;
+ }
+
+ consume_each(cons);
+ return ret;
+}
diff --git a/gnuradio-core/src/lib/general/gr_delay.h b/gnuradio-core/src/lib/general/gr_delay.h
new file mode 100644
index 000000000..ed05c47f4
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_delay.h
@@ -0,0 +1,61 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007,2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_DELAY_H
+#define INCLUDED_GR_DELAY_H
+
+#include <gr_core_api.h>
+#include <gr_block.h>
+#include <gruel/thread.h>
+
+class gr_delay;
+typedef boost::shared_ptr<gr_delay> gr_delay_sptr;
+
+GR_CORE_API gr_delay_sptr gr_make_delay (size_t itemsize, int delay);
+
+/*!
+ * \brief delay the input by a certain number of samples
+ * \ingroup misc_blk
+ */
+class GR_CORE_API gr_delay : public gr_block
+{
+ friend GR_CORE_API gr_delay_sptr gr_make_delay (size_t itemsize, int delay);
+
+ gr_delay (size_t itemsize, int delay);
+
+ void forecast (int noutput_items, gr_vector_int &ninput_items_required);
+
+ size_t d_itemsize;
+ int d_delta;
+ gruel::mutex d_mutex_delay;
+
+ public:
+ int delay () const { return history()-1; }
+ void set_delay (int delay);
+
+ int general_work (int noutput_items,
+ gr_vector_int &ninput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+#endif
diff --git a/gnuradio-core/src/lib/general/gr_delay.i b/gnuradio-core/src/lib/general/gr_delay.i
new file mode 100644
index 000000000..f3d49891d
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_delay.i
@@ -0,0 +1,35 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,delay)
+
+ gr_delay_sptr gr_make_delay (size_t itemsize, int delay);
+
+class gr_delay : public gr_block
+{
+ private:
+ gr_delay (size_t itemsize, int delay);
+
+ public:
+ int delay() const { return history()-1; }
+ void set_delay (int delay) { set_history(delay+1); }
+};
diff --git a/gnuradio-core/src/lib/general/gr_descrambler_bb.cc b/gnuradio-core/src/lib/general/gr_descrambler_bb.cc
new file mode 100644
index 000000000..b5ae28fa9
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_descrambler_bb.cc
@@ -0,0 +1,56 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_descrambler_bb.h>
+#include <gr_io_signature.h>
+
+gr_descrambler_bb_sptr
+gr_make_descrambler_bb(int mask, int seed, int len)
+{
+ return gnuradio::get_initial_sptr(new gr_descrambler_bb(mask, seed, len));
+}
+
+gr_descrambler_bb::gr_descrambler_bb(int mask, int seed, int len)
+ : gr_sync_block("descrambler_bb",
+ gr_make_io_signature (1, 1, sizeof (unsigned char)),
+ gr_make_io_signature (1, 1, sizeof (unsigned char))),
+ d_lfsr(mask, seed, len)
+{
+}
+
+int
+gr_descrambler_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_lfsr.next_bit_descramble(in[i]);
+
+ return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_descrambler_bb.h b/gnuradio-core/src/lib/general/gr_descrambler_bb.h
new file mode 100644
index 000000000..333593caa
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_descrambler_bb.h
@@ -0,0 +1,60 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifndef INCLUDED_GR_DESCRAMBLER_BB_H
+#define INCLUDED_GR_DESCRAMBLER_BB_H
+
+#include <gr_core_api.h>
+#include <gr_sync_block.h>
+#include "gri_lfsr.h"
+
+class gr_descrambler_bb;
+typedef boost::shared_ptr<gr_descrambler_bb> gr_descrambler_bb_sptr;
+
+GR_CORE_API gr_descrambler_bb_sptr gr_make_descrambler_bb(int mask, int seed, int len);
+
+/*!
+ * Descramble an input stream using an LFSR. This block works on the LSB only
+ * of the input data stream, i.e., on an "unpacked binary" stream, and
+ * produces the same format on its output.
+ *
+ * \param mask Polynomial mask for LFSR
+ * \param seed Initial shift register contents
+ * \param len Shift register length
+ *
+ * \ingroup coding_blk
+ */
+
+class GR_CORE_API gr_descrambler_bb : public gr_sync_block
+{
+ friend GR_CORE_API gr_descrambler_bb_sptr gr_make_descrambler_bb(int mask, int seed, int len);
+
+ gri_lfsr d_lfsr;
+
+ gr_descrambler_bb(int mask, int seed, int len);
+
+public:
+ int work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+#endif /* INCLUDED_GR_DESCRAMBLER_BB_H */
diff --git a/gnuradio-core/src/lib/general/gr_descrambler_bb.i b/gnuradio-core/src/lib/general/gr_descrambler_bb.i
new file mode 100644
index 000000000..c6cd0a285
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_descrambler_bb.i
@@ -0,0 +1,31 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,descrambler_bb);
+
+gr_descrambler_bb_sptr gr_make_descrambler_bb(int mask, int seed, int len);
+
+class gr_descrambler_bb : public gr_sync_block
+{
+private:
+ gr_descrambler_bb(int mask, int seed, int len);
+};
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
index 000000000..74324a62e
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_diff_decoder_bb.cc
@@ -0,0 +1,61 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_diff_decoder_bb.h>
+#include <gr_io_signature.h>
+
+gr_diff_decoder_bb_sptr
+gr_make_diff_decoder_bb (unsigned int modulus)
+{
+ return gnuradio::get_initial_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
index 000000000..c4ebbc476
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_diff_decoder_bb.h
@@ -0,0 +1,53 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_DIFF_DECODER_BB_H
+#define INCLUDED_GR_DIFF_DECODER_BB_H
+
+#include <gr_core_api.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_CORE_API gr_diff_decoder_bb_sptr gr_make_diff_decoder_bb (unsigned int modulus);
+
+/*!
+ * \brief y[0] = (x[0] - x[-1]) % M
+ * \ingroup coding_blk
+ *
+ * Differential decoder
+ */
+class GR_CORE_API gr_diff_decoder_bb : public gr_sync_block
+{
+ friend GR_CORE_API 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
index 000000000..3dddb17c3
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_diff_decoder_bb.i
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,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
index 000000000..98492c746
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_diff_encoder_bb.cc
@@ -0,0 +1,62 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_diff_encoder_bb.h>
+#include <gr_io_signature.h>
+
+gr_diff_encoder_bb_sptr
+gr_make_diff_encoder_bb (unsigned int modulus)
+{
+ return gnuradio::get_initial_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
index 000000000..e98876b70
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_diff_encoder_bb.h
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_DIFF_ENCODER_BB_H
+#define INCLUDED_GR_DIFF_ENCODER_BB_H
+
+#include <gr_core_api.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_CORE_API gr_diff_encoder_bb_sptr gr_make_diff_encoder_bb (unsigned int modulus);
+
+/*!
+ * \brief y[0] = (x[0] + y[-1]) % M
+ * \ingroup coding_blk
+ *
+ * Differential encoder
+ */
+class GR_CORE_API gr_diff_encoder_bb : public gr_sync_block
+{
+ friend GR_CORE_API 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
index 000000000..96dadaca5
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_diff_encoder_bb.i
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,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
index 000000000..89fa2041e
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_diff_phasor_cc.cc
@@ -0,0 +1,61 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_diff_phasor_cc.h>
+#include <gr_io_signature.h>
+
+gr_diff_phasor_cc_sptr
+gr_make_diff_phasor_cc ()
+{
+ return gnuradio::get_initial_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
index 000000000..21c4f616d
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_diff_phasor_cc.h
@@ -0,0 +1,53 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_DIFF_PHASOR_CC_H
+#define INCLUDED_GR_DIFF_PHASOR_CC_H
+
+#include <gr_core_api.h>
+#include <gr_sync_block.h>
+
+/*!
+ * \brief Please fix my documentation!
+ * \ingroup misc
+ */
+class gr_diff_phasor_cc;
+typedef boost::shared_ptr<gr_diff_phasor_cc> gr_diff_phasor_cc_sptr;
+
+GR_CORE_API gr_diff_phasor_cc_sptr gr_make_diff_phasor_cc ();
+
+
+class GR_CORE_API gr_diff_phasor_cc : public gr_sync_block
+{
+ friend GR_CORE_API 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
index 000000000..8aecd5cc7
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_diff_phasor_cc.i
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,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_dpll_bb.cc b/gnuradio-core/src/lib/general/gr_dpll_bb.cc
new file mode 100644
index 000000000..1d5a0d4fd
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_dpll_bb.cc
@@ -0,0 +1,84 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007,2009,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_dpll_bb.h>
+#include <gr_io_signature.h>
+#include <cstdio>
+
+gr_dpll_bb_sptr
+gr_make_dpll_bb (float period, float gain)
+{
+ return gnuradio::get_initial_sptr(new gr_dpll_bb (period, gain));
+}
+
+gr_dpll_bb::gr_dpll_bb (float period, float gain)
+ : gr_sync_block ("dpll_bb",
+ gr_make_io_signature (1, 1, sizeof (char)),
+ gr_make_io_signature (1, 1, sizeof (char))),
+ d_restart(0),d_pulse_phase(0)
+{
+ d_pulse_frequency = 1.0/period;
+ d_gain = gain;
+ d_decision_threshold = 1.0 - 0.5*d_pulse_frequency;
+#if 1
+ fprintf(stderr,"frequency = %f period = %f gain = %f threshold = %f\n",
+ d_pulse_frequency,
+ period,
+ d_gain,
+ d_decision_threshold);
+#endif
+}
+
+int
+gr_dpll_bb::work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ const char *iptr = (const char *) input_items[0];
+ char *optr = (char *) output_items[0];
+
+ for (int i = 0; i < noutput_items; i++){
+ optr[i]= 0;
+ if(iptr[i] == 1) {
+ if (d_restart == 0) {
+ d_pulse_phase = 1;
+ } else {
+ if (d_pulse_phase > 0.5) d_pulse_phase += d_gain*(1.0-d_pulse_phase);
+ else d_pulse_phase -= d_gain*d_pulse_phase;
+ }
+ d_restart = 3;
+ }
+ if (d_pulse_phase > d_decision_threshold) {
+ d_pulse_phase -= 1.0;
+ if (d_restart > 0) {
+ d_restart -= 1;
+ optr[i] = 1;
+ }
+ }
+ d_pulse_phase += d_pulse_frequency;
+ }
+ return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_dpll_bb.h b/gnuradio-core/src/lib/general/gr_dpll_bb.h
new file mode 100644
index 000000000..a7df974fb
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_dpll_bb.h
@@ -0,0 +1,58 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_DPLL_BB_H
+#define INCLUDED_GR_DPLL_BB_H
+
+#include <gr_core_api.h>
+#include <gr_sync_block.h>
+
+class gr_dpll_bb;
+typedef boost::shared_ptr<gr_dpll_bb> gr_dpll_bb_sptr;
+
+GR_CORE_API gr_dpll_bb_sptr gr_make_dpll_bb (float period, float gain);
+
+/*!
+ * \brief Detect the peak of a signal
+ * \ingroup level_blk
+ *
+ * If a peak is detected, this block outputs a 1,
+ * or it outputs 0's.
+ */
+class GR_CORE_API gr_dpll_bb : public gr_sync_block
+{
+ friend GR_CORE_API gr_dpll_bb_sptr gr_make_dpll_bb (float period, float gain);
+
+ gr_dpll_bb (float period, float gain);
+
+ private:
+ unsigned char d_restart;
+ float d_pulse_phase, d_pulse_frequency,d_gain,d_decision_threshold;
+
+ 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_dpll_bb.i b/gnuradio-core/src/lib/general/gr_dpll_bb.i
new file mode 100644
index 000000000..f31a87374
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_dpll_bb.i
@@ -0,0 +1,31 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,dpll_bb)
+
+ gr_dpll_bb_sptr gr_make_dpll_bb (float period, float gain);
+
+class gr_dpll_bb : public gr_sync_block
+{
+ private:
+ gr_dpll_bb (float period, float gain);
+};
diff --git a/gnuradio-core/src/lib/general/gr_encode_ccsds_27_bb.cc b/gnuradio-core/src/lib/general/gr_encode_ccsds_27_bb.cc
new file mode 100644
index 000000000..4a92d113a
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_encode_ccsds_27_bb.cc
@@ -0,0 +1,62 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2008,2010 Free Software Foundation, Inc.
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_encode_ccsds_27_bb.h>
+#include <gr_io_signature.h>
+
+extern "C" {
+#include <../viterbi/viterbi.h>
+}
+
+gr_encode_ccsds_27_bb_sptr
+gr_make_encode_ccsds_27_bb()
+{
+ return gnuradio::get_initial_sptr(new gr_encode_ccsds_27_bb());
+}
+
+gr_encode_ccsds_27_bb::gr_encode_ccsds_27_bb()
+ : gr_sync_interpolator("encode_ccsds_27_bb",
+ gr_make_io_signature(1, 1, sizeof(char)),
+ gr_make_io_signature(1, 1, sizeof(char)),
+ 16) // Rate 1/2 code, packed to unpacked conversion
+{
+ d_encstate = 0;
+}
+
+gr_encode_ccsds_27_bb::~gr_encode_ccsds_27_bb()
+{
+}
+
+int
+gr_encode_ccsds_27_bb::work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ unsigned char *in = (unsigned char *)input_items[0];
+ unsigned char *out = (unsigned char *)output_items[0];
+
+ d_encstate = encode(out, in, noutput_items/16, d_encstate);
+
+ return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_encode_ccsds_27_bb.h b/gnuradio-core/src/lib/general/gr_encode_ccsds_27_bb.h
new file mode 100644
index 000000000..94e9c33f1
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_encode_ccsds_27_bb.h
@@ -0,0 +1,64 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008 Free Software Foundation, Inc.
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifndef INCLUDED_GR_ENCODE_CCSDS_27_BB_H
+#define INCLUDED_GR_ENCODE_CCSDS_27_BB_H
+
+#include <gr_core_api.h>
+#include <gr_sync_interpolator.h>
+
+class gr_encode_ccsds_27_bb;
+
+typedef boost::shared_ptr<gr_encode_ccsds_27_bb> gr_encode_ccsds_27_bb_sptr;
+
+GR_CORE_API gr_encode_ccsds_27_bb_sptr gr_make_encode_ccsds_27_bb();
+
+/*! \brief A rate 1/2, k=7 convolutional encoder for the CCSDS standard
+ * \ingroup ecc
+ *
+ * This block performs convolutional encoding using the CCSDS standard
+ * polynomial ("Voyager").
+ *
+ * The input is an MSB first packed stream of bits.
+ *
+ * The output is a stream of symbols 0 or 1 representing the encoded data.
+ *
+ * As a rate 1/2 code, there will be 16 output symbols for every input byte.
+ *
+ * This block is designed for continuous data streaming, not packetized data.
+ * There is no provision to "flush" the encoder.
+ */
+
+class GR_CORE_API gr_encode_ccsds_27_bb : public gr_sync_interpolator
+{
+private:
+ friend GR_CORE_API gr_encode_ccsds_27_bb_sptr gr_make_encode_ccsds_27_bb();
+
+ gr_encode_ccsds_27_bb();
+ unsigned char d_encstate;
+
+ public:
+ ~gr_encode_ccsds_27_bb();
+
+ int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+#endif /* INCLUDED_GR_ENCODE_CCSDS_27_BB_H */
diff --git a/gnuradio-core/src/lib/general/gr_encode_ccsds_27_bb.i b/gnuradio-core/src/lib/general/gr_encode_ccsds_27_bb.i
new file mode 100644
index 000000000..e74e9174a
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_encode_ccsds_27_bb.i
@@ -0,0 +1,31 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,encode_ccsds_27_bb);
+
+gr_encode_ccsds_27_bb_sptr gr_make_encode_ccsds_27_bb ();
+
+class gr_encode_ccsds_27_bb : public gr_sync_interpolator
+{
+private:
+ gr_encode_ccsds_27_bb();
+};
diff --git a/gnuradio-core/src/lib/general/gr_endian_swap.cc b/gnuradio-core/src/lib/general/gr_endian_swap.cc
new file mode 100644
index 000000000..8bea0ca30
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_endian_swap.cc
@@ -0,0 +1,101 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2010,2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_endian_swap.h>
+#include <gr_io_signature.h>
+#include <volk/volk.h>
+
+gr_endian_swap_sptr
+gr_make_endian_swap (size_t item_size_bytes)
+{
+ return gnuradio::get_initial_sptr(new gr_endian_swap (item_size_bytes));
+}
+
+gr_endian_swap::gr_endian_swap (size_t item_size_bytes)
+ : gr_sync_block ("gr_endian_swap",
+ gr_make_io_signature (1, 1, item_size_bytes),
+ gr_make_io_signature (1, 1, item_size_bytes))
+{
+ const int alignment_multiple = volk_get_alignment();
+ set_alignment(std::max(1,alignment_multiple));
+}
+
+int
+gr_endian_swap::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];
+
+ int nbytes( output_signature()->sizeof_stream_item(0) );
+ if(is_unaligned()) {
+ switch(nbytes){
+ case 1:
+ memcpy(out,in,noutput_items);
+ break;
+ case 2:
+ memcpy(out,in,2*noutput_items);
+ volk_16u_byteswap_u((uint16_t*)out,noutput_items);
+ break;
+ case 4:
+ memcpy(out,in,4*noutput_items);
+ volk_32u_byteswap_u((uint32_t*)out,noutput_items);
+ break;
+ case 8:
+ memcpy(out,in,8*noutput_items);
+ volk_64u_byteswap_u((uint64_t*)out,noutput_items);
+ break;
+ default:
+ throw std::runtime_error("itemsize is not valid for gr_endian_swap!");
+ }
+ } else {
+ switch(nbytes){
+ case 1:
+ memcpy(out,in,noutput_items);
+ break;
+ case 2:
+ memcpy(out,in,2*noutput_items);
+ volk_16u_byteswap_a((uint16_t*)out,noutput_items);
+ break;
+ case 4:
+ memcpy(out,in,4*noutput_items);
+ volk_32u_byteswap_a((uint32_t*)out,noutput_items);
+ break;
+ case 8:
+ memcpy(out,in,8*noutput_items);
+ volk_64u_byteswap_a((uint64_t*)out,noutput_items);
+ break;
+ default:
+ throw std::runtime_error("itemsize is not valid for gr_endian_swap!");
+ }
+ }
+
+ return noutput_items;
+}
+
+
+
diff --git a/gnuradio-core/src/lib/general/gr_endian_swap.h b/gnuradio-core/src/lib/general/gr_endian_swap.h
new file mode 100644
index 000000000..0baa3f338
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_endian_swap.h
@@ -0,0 +1,57 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_ENDIAN_SWAP_H
+#define INCLUDED_GR_ENDIAN_SWAP_H
+
+#include <gr_core_api.h>
+#include <gr_sync_block.h>
+
+class gr_endian_swap;
+typedef boost::shared_ptr<gr_endian_swap> gr_endian_swap_sptr;
+
+GR_CORE_API gr_endian_swap_sptr
+gr_make_endian_swap (size_t item_size_bytes=1);
+
+/*!
+ * \brief Convert stream of items into thier byte swapped version
+ *
+ * \param item_size_bytes number of bytes per item, 1=no-op,2=uint16_t,4=uint32_t,8=uint64_t
+ */
+
+class GR_CORE_API gr_endian_swap : public gr_sync_block
+{
+ private:
+ friend GR_CORE_API gr_endian_swap_sptr
+ gr_make_endian_swap (size_t item_size_bytes);
+ gr_endian_swap (size_t item_size_bytes);
+
+ size_t item_size_bytes;
+
+ public:
+ virtual int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+
+#endif /* INCLUDED_GR_ENDIAN_SWAP_H */
diff --git a/gnuradio-core/src/lib/general/gr_endian_swap.i b/gnuradio-core/src/lib/general/gr_endian_swap.i
new file mode 100644
index 000000000..6058b9de7
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_endian_swap.i
@@ -0,0 +1,31 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,endian_swap)
+
+gr_endian_swap_sptr
+gr_make_endian_swap (size_t bytes_per_item=1);
+
+class gr_endian_swap : public gr_sync_block
+{
+public:
+};
diff --git a/gnuradio-core/src/lib/general/gr_expj.h b/gnuradio-core/src/lib/general/gr_expj.h
new file mode 100644
index 000000000..1d8633242
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_expj.h
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifndef INCLUDED_GR_EXPJ_H
+#define INCLUDED_GR_EXPJ_H
+
+#include <gr_core_api.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
index 000000000..c1c3883c5
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_fake_channel_coder_pp.cc
@@ -0,0 +1,113 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_fake_channel_coder_pp.h>
+#include <gr_io_signature.h>
+#include <string.h>
+#include <stdexcept>
+#include <string.h>
+
+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 gnuradio::get_initial_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 gnuradio::get_initial_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
index 000000000..45808752d
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_fake_channel_coder_pp.h
@@ -0,0 +1,91 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_FAKE_CHANNEL_CODER_PP_H
+#define INCLUDED_GR_FAKE_CHANNEL_CODER_PP_H
+
+#include <gr_core_api.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_CORE_API 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 coding_blk
+ *
+ * input: stream of byte vectors; output: stream of byte vectors
+ */
+class GR_CORE_API 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_CORE_API 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_CORE_API 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 coding_blk
+ *
+ * input: stream of byte vectors; output: stream of byte vectors
+ */
+class GR_CORE_API 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_CORE_API 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
index 000000000..123c84e47
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_fake_channel_coder_pp.i
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,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
index 000000000..8b7bfea12
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_fast_atan2f.cc
@@ -0,0 +1,199 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#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_feedforward_agc_cc.cc b/gnuradio-core/src/lib/general/gr_feedforward_agc_cc.cc
new file mode 100644
index 000000000..147b64e9b
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_feedforward_agc_cc.cc
@@ -0,0 +1,91 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_feedforward_agc_cc.h>
+#include <gr_io_signature.h>
+#include <stdexcept>
+
+gr_feedforward_agc_cc_sptr
+gr_make_feedforward_agc_cc(int nsamples, float reference)
+{
+ return gnuradio::get_initial_sptr(new gr_feedforward_agc_cc (nsamples, reference));
+}
+
+gr_feedforward_agc_cc::gr_feedforward_agc_cc (int nsamples, float reference)
+ : gr_sync_block ("gr_feedforward_agc_cc",
+ gr_make_io_signature (1, 1, sizeof (gr_complex)),
+ gr_make_io_signature (1, 1, sizeof (gr_complex))),
+ d_nsamples(nsamples), d_reference(reference)
+{
+ if (nsamples < 1)
+ throw std::invalid_argument("gr_feedforward_agc_cc: nsamples must be >= 1");
+
+ set_history(nsamples);
+}
+
+gr_feedforward_agc_cc::~gr_feedforward_agc_cc()
+{
+}
+
+inline static float
+mag_squared(gr_complex x)
+{
+ return x.real() * x.real() + x.imag() * x.imag();
+}
+
+// approximate sqrt(x^2 + y^2)
+inline static float
+envelope(gr_complex x)
+{
+ float r_abs = std::fabs(x.real());
+ float i_abs = std::fabs(x.imag());
+
+ if (r_abs > i_abs)
+ return r_abs + 0.4 * i_abs;
+ else
+ return i_abs + 0.4 * r_abs;
+}
+
+int
+gr_feedforward_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];
+ int nsamples = d_nsamples;
+ float gain;
+
+ for (int i = 0; i < noutput_items; i++){
+ //float max_env = 1e-12; // avoid divide by zero
+ float max_env = 1e-4; // avoid divide by zero, indirectly set max gain
+ for (int j = 0; j < nsamples; j++)
+ max_env = std::max(max_env, envelope(in[i+j]));
+ gain = d_reference / max_env;
+ out[i] = gain * in[i];
+ }
+ return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_feedforward_agc_cc.h b/gnuradio-core/src/lib/general/gr_feedforward_agc_cc.h
new file mode 100644
index 000000000..63e5e4c43
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_feedforward_agc_cc.h
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_FEEDFORWARD_AGC_CC_H
+#define INCLUDED_GR_FEEDFORWARD_AGC_CC_H
+
+#include <gr_core_api.h>
+#include <gr_sync_block.h>
+
+class gr_feedforward_agc_cc;
+typedef boost::shared_ptr<gr_feedforward_agc_cc> gr_feedforward_agc_cc_sptr;
+
+GR_CORE_API gr_feedforward_agc_cc_sptr
+gr_make_feedforward_agc_cc(int nsamples, float reference = 1.0);
+
+/*!
+ * \brief Non-causal AGC which computes required gain based on max absolute value over nsamples
+ * \ingroup level_blk
+ */
+class GR_CORE_API gr_feedforward_agc_cc : public gr_sync_block
+{
+ friend GR_CORE_API gr_feedforward_agc_cc_sptr
+ gr_make_feedforward_agc_cc(int nsamples, float reference);
+
+ int d_nsamples;
+ float d_reference;
+
+ gr_feedforward_agc_cc(int nsamples, float reference);
+
+ public:
+ ~gr_feedforward_agc_cc();
+
+ int work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+#endif /* INCLUDED_GR_FEEDFORWARD_AGC_CC_H */
diff --git a/gnuradio-core/src/lib/general/gr_feedforward_agc_cc.i b/gnuradio-core/src/lib/general/gr_feedforward_agc_cc.i
new file mode 100644
index 000000000..1fd5a2c26
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_feedforward_agc_cc.i
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,feedforward_agc_cc);
+
+gr_feedforward_agc_cc_sptr
+gr_make_feedforward_agc_cc(int nsamples, float reference = 1.0);
+
+class gr_feedforward_agc_cc : public gr_sync_block
+{
+ gr_feedforward_agc_cc(int nsamples, float reference);
+
+ public:
+ ~gr_feedforward_agc_cc();
+};
diff --git a/gnuradio-core/src/lib/general/gr_feval.cc b/gnuradio-core/src/lib/general/gr_feval.cc
new file mode 100644
index 000000000..89f09984c
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_feval.cc
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <gr_feval.h>
+
+gr_feval_dd::~gr_feval_dd(){}
+
+double
+gr_feval_dd::eval(double x)
+{
+ return 0;
+}
+
+double
+gr_feval_dd::calleval(double x)
+{
+ return eval(x);
+}
+
+// ----------------------------------------------------------------
+
+gr_feval_cc::~gr_feval_cc(){}
+
+gr_complex
+gr_feval_cc::eval(gr_complex x)
+{
+ return 0;
+}
+
+gr_complex
+gr_feval_cc::calleval(gr_complex x)
+{
+ return eval(x);
+}
+
+// ----------------------------------------------------------------
+
+gr_feval_ll::~gr_feval_ll(){}
+
+long
+gr_feval_ll::eval(long x)
+{
+ return 0;
+}
+
+long
+gr_feval_ll::calleval(long x)
+{
+ return eval(x);
+}
+
+// ----------------------------------------------------------------
+
+gr_feval::~gr_feval(){}
+
+void
+gr_feval::eval(void)
+{
+ // nop
+}
+
+void
+gr_feval::calleval(void)
+{
+ eval();
+}
+
+// ----------------------------------------------------------------
+
+gr_feval_p::~gr_feval_p(){}
+
+void
+gr_feval_p::eval(pmt::pmt_t x)
+{
+ // nop
+}
+
+void
+gr_feval_p::calleval(pmt::pmt_t x)
+{
+ eval(x);
+}
+
+/*
+ * Trivial examples showing C++ (transparently) calling Python
+ */
+double
+gr_feval_dd_example(gr_feval_dd *f, double x)
+{
+ return f->calleval(x);
+}
+
+gr_complex
+gr_feval_cc_example(gr_feval_cc *f, gr_complex x)
+{
+ return f->calleval(x);
+}
+
+long
+gr_feval_ll_example(gr_feval_ll *f, long x)
+{
+ return f->calleval(x);
+}
+
+void
+gr_feval_example(gr_feval *f)
+{
+ f->calleval();
+}
diff --git a/gnuradio-core/src/lib/general/gr_feval.h b/gnuradio-core/src/lib/general/gr_feval.h
new file mode 100644
index 000000000..a9bccfe51
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_feval.h
@@ -0,0 +1,177 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifndef INCLUDED_GR_FEVAL_H
+#define INCLUDED_GR_FEVAL_H
+
+#include <gr_core_api.h>
+#include <gr_complex.h>
+#include <gruel/pmt.h>
+
+/*!
+ * \brief base class for evaluating a function: double -> double
+ * \ingroup misc
+ *
+ * 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.
+ *
+ * Override eval to define the behavior.
+ * Use calleval to invoke eval (this kludge is required to allow a
+ * python specific "shim" to be inserted.
+ */
+class GR_CORE_API gr_feval_dd
+{
+protected:
+ /*!
+ * \brief override this to define the function
+ */
+ virtual double eval(double x);
+
+public:
+ gr_feval_dd() {}
+ virtual ~gr_feval_dd();
+
+ virtual double calleval(double x); // invoke "eval"
+};
+
+/*!
+ * \brief base class for evaluating a function: complex -> complex
+ * \ingroup misc
+ *
+ * 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.
+ *
+ * Override eval to define the behavior.
+ * Use calleval to invoke eval (this kludge is required to allow a
+ * python specific "shim" to be inserted.
+ */
+class GR_CORE_API gr_feval_cc
+{
+protected:
+ /*!
+ * \brief override this to define the function
+ */
+ virtual gr_complex eval(gr_complex x);
+
+public:
+ gr_feval_cc() {}
+ virtual ~gr_feval_cc();
+
+ virtual gr_complex calleval(gr_complex x); // invoke "eval"
+};
+
+/*!
+ * \brief base class for evaluating a function: long -> long
+ * \ingroup misc
+ *
+ * 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.
+ *
+ * Override eval to define the behavior.
+ * Use calleval to invoke eval (this kludge is required to allow a
+ * python specific "shim" to be inserted.
+ */
+class GR_CORE_API gr_feval_ll
+{
+protected:
+ /*!
+ * \brief override this to define the function
+ */
+ virtual long eval(long x);
+
+public:
+ gr_feval_ll() {}
+ virtual ~gr_feval_ll();
+
+ virtual long calleval(long x); // invoke "eval"
+};
+
+/*!
+ * \brief base class for evaluating a function: void -> void
+ * \ingroup misc
+ *
+ * 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.
+ *
+ * Override eval to define the behavior.
+ * Use calleval to invoke eval (this kludge is required to allow a
+ * python specific "shim" to be inserted.
+ */
+class GR_CORE_API gr_feval
+{
+protected:
+ /*!
+ * \brief override this to define the function
+ */
+ virtual void eval();
+
+public:
+ gr_feval() {}
+ virtual ~gr_feval();
+
+ virtual void calleval(); // invoke "eval"
+};
+
+/*!
+ * \brief base class for evaluating a function: pmt -> void
+ * \ingroup misc
+ *
+ * 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.
+ *
+ * Override eval to define the behavior.
+ * Use calleval to invoke eval (this kludge is required to allow a
+ * python specific "shim" to be inserted.
+ */
+class GR_CORE_API gr_feval_p
+{
+protected:
+ /*!
+ * \brief override this to define the function
+ */
+ virtual void eval(pmt::pmt_t x);
+
+public:
+ gr_feval_p() {}
+ virtual ~gr_feval_p();
+
+ virtual void calleval(pmt::pmt_t x); // invoke "eval"
+};
+
+/*!
+ * \brief trivial examples / test cases showing C++ calling Python code
+ */
+GR_CORE_API double gr_feval_dd_example(gr_feval_dd *f, double x);
+GR_CORE_API gr_complex gr_feval_cc_example(gr_feval_cc *f, gr_complex x);
+GR_CORE_API long gr_feval_ll_example(gr_feval_ll *f, long x);
+GR_CORE_API void gr_feval_example(gr_feval *f);
+
+#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
index 000000000..c8b7e54da
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_feval.i
@@ -0,0 +1,233 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+
+/*
+ * N.B., this is a _very_ non-standard SWIG .i file
+ *
+ * It contains a bunch of magic that is required to ensure that when
+ * these classes are used as base classes for python code,
+ * everything works when calling back from C++ into Python.
+ *
+ * The gist of the problem is that our C++ code is usually not holding
+ * the Python Global Interpreter Lock (GIL). Thus if we invoke a
+ * "director" method from C++, we'll end up in Python not holding the
+ * GIL. Disaster (SIGSEGV) will result. To avoid this we insert a
+ * "shim" that grabs and releases the GIL.
+ *
+ * If you don't understand SWIG "directors" or the Python GIL,
+ * don't bother trying to understand what's going on in here.
+ *
+ * [We could eliminate a bunch of this hair by requiring SWIG 1.3.29
+ * or later and some additional magic declarations, but many systems
+ * aren't shipping that version yet. Thus we kludge...]
+ */
+
+
+// Directors are only supported in Python, Java and C#
+#ifdef SWIGPYTHON
+%import "pmt_swig.i"
+using namespace pmt;
+
+// Enable SWIG directors for these classes
+%feature("director") gr_py_feval_dd;
+%feature("director") gr_py_feval_cc;
+%feature("director") gr_py_feval_ll;
+%feature("director") gr_py_feval;
+%feature("director") gr_py_feval_p;
+
+%feature("nodirector") gr_py_feval_dd::calleval;
+%feature("nodirector") gr_py_feval_cc::calleval;
+%feature("nodirector") gr_py_feval_ll::calleval;
+%feature("nodirector") gr_py_feval::calleval;
+%feature("nodirector") gr_py_feval_p::calleval;
+
+
+%rename(feval_dd) gr_py_feval_dd;
+%rename(feval_cc) gr_py_feval_cc;
+%rename(feval_ll) gr_py_feval_ll;
+%rename(feval) gr_py_feval;
+%rename(feval_p) gr_py_feval_p;
+
+//%exception {
+// try { $action }
+// catch (Swig::DirectorException &e) { std::cerr << e.getMessage(); SWIG_fail; }
+//}
+
+%{
+
+// class that ensures we acquire and release the Python GIL
+
+class ensure_py_gil_state {
+ PyGILState_STATE d_gstate;
+public:
+ ensure_py_gil_state() { d_gstate = PyGILState_Ensure(); }
+ ~ensure_py_gil_state() { PyGILState_Release(d_gstate); }
+};
+
+%}
+
+/*
+ * These are the real C++ base classes, however we don't want these exposed.
+ */
+%ignore gr_feval_dd;
+class gr_feval_dd
+{
+protected:
+ virtual double eval(double x);
+
+public:
+ gr_feval_dd() {}
+ virtual ~gr_feval_dd();
+
+ virtual double calleval(double x);
+};
+
+%ignore gr_feval_cc;
+class gr_feval_cc
+{
+protected:
+ virtual gr_complex eval(gr_complex x);
+
+public:
+ gr_feval_cc() {}
+ virtual ~gr_feval_cc();
+
+ virtual gr_complex calleval(gr_complex x);
+};
+
+%ignore gr_feval_ll;
+class gr_feval_ll
+{
+protected:
+ virtual long eval(long x);
+
+public:
+ gr_feval_ll() {}
+ virtual ~gr_feval_ll();
+
+ virtual long calleval(long x);
+};
+
+%ignore gr_feval;
+class gr_feval
+{
+protected:
+ virtual void eval();
+
+public:
+ gr_feval() {}
+ virtual ~gr_feval();
+
+ virtual void calleval();
+};
+
+%ignore gr_feval_p;
+class gr_feval_p
+{
+protected:
+ virtual void eval(pmt_t x);
+
+public:
+ gr_feval_p() {}
+ virtual ~gr_feval_p();
+
+ virtual void calleval(pmt_t x);
+};
+
+/*
+ * These are the ones to derive from in Python. They have the magic shim
+ * that ensures that we're holding the Python GIL when we enter Python land...
+ */
+
+%inline %{
+#include <gruel/pmt.h>
+
+class gr_py_feval_dd : public gr_feval_dd
+{
+ public:
+ double calleval(double x)
+ {
+ ensure_py_gil_state _lock;
+ return eval(x);
+ }
+};
+
+class gr_py_feval_cc : public gr_feval_cc
+{
+ public:
+ gr_complex calleval(gr_complex x)
+ {
+ ensure_py_gil_state _lock;
+ return eval(x);
+ }
+};
+
+class gr_py_feval_ll : public gr_feval_ll
+{
+ public:
+ long calleval(long x)
+ {
+ ensure_py_gil_state _lock;
+ return eval(x);
+ }
+};
+
+class gr_py_feval : public gr_feval
+{
+ public:
+ void calleval()
+ {
+ ensure_py_gil_state _lock;
+ eval();
+ }
+};
+
+class gr_py_feval_p : public gr_feval_p
+{
+ public:
+ void calleval(pmt::pmt_t x)
+ {
+ ensure_py_gil_state _lock;
+ eval(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);
+
+%rename(feval_example) gr_feval_example;
+void gr_feval_example(gr_feval *f);
+
+#endif // SWIGPYTHON
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
index 000000000..addcddb64
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_fft_vcc.cc
@@ -0,0 +1,80 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2007,2008,2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_fft_vcc.h> // abstract class
+#include <gr_fft_vcc_fftw.h> // concrete class
+#include <gr_io_signature.h>
+#include <gri_fft.h>
+#include <math.h>
+#include <string.h>
+
+gr_fft_vcc_sptr
+gr_make_fft_vcc (int fft_size, bool forward,
+ const std::vector<float> &window,
+ bool shift, int nthreads)
+{
+ return gr_make_fft_vcc_fftw(fft_size, forward,
+ window, shift, nthreads);
+}
+
+gr_fft_vcc::gr_fft_vcc (const std::string &name,
+ int fft_size, bool forward, const std::vector<float> &window,
+ bool shift)
+ : gr_sync_block (name,
+ 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_forward(forward), d_shift(shift)
+{
+ set_window(window);
+}
+
+gr_fft_vcc::~gr_fft_vcc ()
+{
+}
+
+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;
+}
+
+void
+gr_fft_vcc::set_nthreads(int n)
+{
+ throw std::runtime_error("gr_fft_vcc::set_nthreads not implemented.");
+}
+
+int
+gr_fft_vcc::nthreads() const
+{
+ throw std::runtime_error("gr_fft_vcc::nthreads not implemented.");
+ return 0;
+}
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
index 000000000..db5690d41
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_fft_vcc.h
@@ -0,0 +1,68 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2007,2008,2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_FFT_VCC_H
+#define INCLUDED_GR_FFT_VCC_H
+
+#include <gr_core_api.h>
+#include <gr_sync_block.h>
+
+class gr_fft_vcc;
+typedef boost::shared_ptr<gr_fft_vcc> gr_fft_vcc_sptr;
+
+GR_CORE_API gr_fft_vcc_sptr
+gr_make_fft_vcc (int fft_size, bool forward,
+ const std::vector<float> &window,
+ bool shift=false, int nthreads=1);
+
+/*!
+ * \brief Compute forward or reverse FFT. complex vector in / complex vector out.
+ * \ingroup dft_blk
+ *
+ * Abstract base class
+ */
+class GR_CORE_API gr_fft_vcc : public gr_sync_block
+{
+protected:
+ friend GR_CORE_API gr_fft_vcc_sptr
+ gr_make_fft_vcc (int fft_size, bool forward,
+ const std::vector<float> &window,
+ bool shift);
+
+ unsigned int d_fft_size;
+ std::vector<float> d_window;
+ bool d_forward;
+ bool d_shift;
+
+ gr_fft_vcc (const std::string &name, int fft_size, bool forward,
+ const std::vector<float> &window, bool shift);
+
+ public:
+ ~gr_fft_vcc ();
+
+ virtual void set_nthreads(int n);
+ virtual int nthreads() const;
+
+ 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
index 000000000..f9caae7d8
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_fft_vcc.i
@@ -0,0 +1,41 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2007,2008,2010,2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr, fft_vcc)
+
+gr_fft_vcc_sptr
+gr_make_fft_vcc (int fft_size, bool forward,
+ const std::vector<float> &window,
+ bool shift=false, int nthreads=1);
+
+class gr_fft_vcc : public gr_sync_block
+{
+ protected:
+ gr_fft_vcc (int fft_size, bool forward,
+ const std::vector<float> &window,
+ bool shift);
+
+ public:
+ bool set_window(const std::vector<float> &window);
+ void set_nthreads(int n);
+ int nthreads() const;
+};
diff --git a/gnuradio-core/src/lib/general/gr_fft_vcc_fftw.cc b/gnuradio-core/src/lib/general/gr_fft_vcc_fftw.cc
new file mode 100644
index 000000000..891173bcd
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_fft_vcc_fftw.cc
@@ -0,0 +1,130 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2007,2008,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_fft_vcc_fftw.h>
+#include <gr_io_signature.h>
+#include <gri_fft.h>
+#include <math.h>
+#include <string.h>
+
+gr_fft_vcc_sptr
+gr_make_fft_vcc_fftw (int fft_size, bool forward,
+ const std::vector<float> &window,
+ bool shift, int nthreads)
+{
+ return gnuradio::get_initial_sptr(new gr_fft_vcc_fftw
+ (fft_size, forward, window,
+ shift, nthreads));
+}
+
+gr_fft_vcc_fftw::gr_fft_vcc_fftw (int fft_size, bool forward,
+ const std::vector<float> &window,
+ bool shift, int nthreads)
+ : gr_fft_vcc("fft_vcc_fftw", fft_size, forward, window, shift)
+{
+ d_fft = new gri_fft_complex (d_fft_size, forward, nthreads);
+}
+
+gr_fft_vcc_fftw::~gr_fft_vcc_fftw ()
+{
+ delete d_fft;
+}
+
+void
+gr_fft_vcc_fftw::set_nthreads(int n)
+{
+ d_fft->set_nthreads(n);
+}
+
+int
+gr_fft_vcc_fftw::nthreads() const
+{
+ return d_fft->nthreads();
+}
+
+int
+gr_fft_vcc_fftw::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();
+ if(!d_forward && d_shift){
+ unsigned int offset = (!d_forward && d_shift)?(d_fft_size/2):0;
+ int fft_m_offset = d_fft_size - offset;
+ for (unsigned int i = 0; i < offset; i++) // apply window
+ dst[i+fft_m_offset] = in[i] * d_window[i];
+ for (unsigned int i = offset; i < d_fft_size; i++) // apply window
+ dst[i-offset] = in[i] * d_window[i];
+ } else {
+ for (unsigned int i = 0; i < d_fft_size; i++) // apply window
+ dst[i] = in[i] * d_window[i];
+ }
+ }
+ else {
+ if(!d_forward && d_shift) { // apply an ifft shift on the data
+ gr_complex *dst = d_fft->get_inbuf();
+ unsigned int len = (unsigned int)(floor(d_fft_size/2.0)); // half length of complex array
+ memcpy(&dst[0], &in[len], sizeof(gr_complex)*(d_fft_size - len));
+ memcpy(&dst[d_fft_size - len], &in[0], sizeof(gr_complex)*len);
+ }
+ else {
+ memcpy (d_fft->get_inbuf(), in, input_data_size);
+ }
+ }
+
+ // compute the fft
+ d_fft->execute ();
+
+ // copy result to our output
+ if(d_forward && d_shift) { // apply a fft shift on the data
+ unsigned int len = (unsigned int)(ceil(d_fft_size/2.0));
+ memcpy(&out[0], &d_fft->get_outbuf()[len], sizeof(gr_complex)*(d_fft_size - len));
+ memcpy(&out[d_fft_size - len], &d_fft->get_outbuf()[0], sizeof(gr_complex)*len);
+ }
+ else {
+ memcpy (out, d_fft->get_outbuf (), output_data_size);
+ }
+
+ in += d_fft_size;
+ out += d_fft_size;
+ }
+
+ return noutput_items;
+}
+
diff --git a/gnuradio-core/src/lib/general/gr_fft_vcc_fftw.h b/gnuradio-core/src/lib/general/gr_fft_vcc_fftw.h
new file mode 100644
index 000000000..967ceaefb
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_fft_vcc_fftw.h
@@ -0,0 +1,67 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2007,2008 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_FFT_VCC_FFTW_H
+#define INCLUDED_GR_FFT_VCC_FFTW_H
+
+#include <gr_core_api.h>
+#include <gr_fft_vcc.h>
+
+class gri_fft_complex;
+
+GR_CORE_API gr_fft_vcc_sptr
+gr_make_fft_vcc_fftw (int fft_size, bool forward,
+ const std::vector<float> &window,
+ bool shift=false, int nthreads=1);
+
+/*!
+ * \brief Compute forward or reverse FFT. complex vector in / complex vector out.
+ * \ingroup dft_blk
+ *
+ * Concrete class that uses FFTW.
+ */
+class GR_CORE_API gr_fft_vcc_fftw : public gr_fft_vcc
+{
+ friend GR_CORE_API gr_fft_vcc_sptr
+ gr_make_fft_vcc_fftw (int fft_size, bool forward,
+ const std::vector<float> &window,
+ bool shift, int nthreads);
+
+ gri_fft_complex *d_fft;
+
+ gr_fft_vcc_fftw (int fft_size, bool forward,
+ const std::vector<float> &window,
+ bool shift, int nthreads=1);
+
+ public:
+ ~gr_fft_vcc_fftw ();
+
+ void set_nthreads(int n);
+ int nthreads() const;
+
+ int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+
+#endif /* INCLUDED_GR_FFT_VCC_FFTW_H */
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
index 000000000..2396055b9
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_fft_vfc.cc
@@ -0,0 +1,135 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2010,2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_fft_vfc.h>
+#include <gr_io_signature.h>
+#include <gri_fft.h>
+#include <math.h>
+#include <stdexcept>
+#include <string.h>
+#include <cstdio>
+
+
+// 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,
+ int nthreads)
+{
+ return gnuradio::get_initial_sptr(new gr_fft_vfc (fft_size, forward,
+ window, nthreads));
+}
+
+gr_fft_vfc::gr_fft_vfc (int fft_size, bool forward,
+ const std::vector<float> &window,
+ int nthreads)
+ : 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, nthreads);
+
+ set_window(window);
+}
+
+gr_fft_vfc::~gr_fft_vfc ()
+{
+ delete d_fft;
+}
+
+void
+gr_fft_vfc::set_nthreads(int n)
+{
+ d_fft->set_nthreads(n);
+}
+
+int
+gr_fft_vfc::nthreads() const
+{
+ return d_fft->nthreads();
+}
+
+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
index 000000000..35b95313d
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_fft_vfc.h
@@ -0,0 +1,72 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2010,2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_FFT_VFC_H
+#define INCLUDED_GR_FFT_VFC_H
+
+#include <gr_core_api.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_CORE_API gr_fft_vfc_sptr
+gr_make_fft_vfc (int fft_size, bool forward,
+ const std::vector<float> &window,
+ int nthreads=1);
+
+/*!
+ * \brief Compute forward FFT. float vector in / complex vector out.
+ * \ingroup dft_blk
+ */
+
+class GR_CORE_API gr_fft_vfc : public gr_sync_block
+{
+ friend GR_CORE_API gr_fft_vfc_sptr
+ gr_make_fft_vfc (int fft_size, bool forward,
+ const std::vector<float> &window,
+ int nthreads);
+
+ 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,
+ int nthreads=1);
+
+ public:
+ ~gr_fft_vfc ();
+
+ void set_nthreads(int n);
+ int nthreads() const;
+
+ 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
index 000000000..d387ae155
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_fft_vfc.i
@@ -0,0 +1,42 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2010,2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr, fft_vfc)
+
+gr_fft_vfc_sptr
+gr_make_fft_vfc (int fft_size, bool forward,
+ const std::vector<float> &window,
+ int nthreads=1)
+throw(std::exception);
+
+class gr_fft_vfc : public gr_sync_block
+{
+ protected:
+ gr_fft_vfc (int fft_size, bool forward,
+ const std::vector<float> &window,
+ int nthreads=1);
+
+ public:
+ bool set_window(const std::vector<float> &window);
+ void set_nthreads(int n);
+ int nthreads() const;
+};
diff --git a/gnuradio-core/src/lib/general/gr_firdes.cc b/gnuradio-core/src/lib/general/gr_firdes.cc
new file mode 100644
index 000000000..4c7237141
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_firdes.cc
@@ -0,0 +1,840 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002,2007,2008 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#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_2(double gain,
+ double sampling_freq, // Hz
+ double cutoff_freq, // Hz BEGINNING of transition band
+ double transition_width, // Hz width of transition band
+ double attenuation_dB, // attenuation dB
+ win_type window_type,
+ double beta) // used only with Kaiser
+{
+ sanity_check_1f (sampling_freq, cutoff_freq, transition_width);
+
+ int ntaps = compute_ntaps_windes (sampling_freq, transition_width,
+ attenuation_dB);
+
+ // 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;
+}
+
+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_2 (double gain,
+ double sampling_freq,
+ double cutoff_freq, // Hz center of transition band
+ double transition_width, // Hz width of transition band
+ double attenuation_dB, // attenuation dB
+ win_type window_type,
+ double beta) // used only with Kaiser
+{
+ sanity_check_1f (sampling_freq, cutoff_freq, transition_width);
+
+ int ntaps = compute_ntaps_windes (sampling_freq, transition_width,
+ attenuation_dB);
+
+ // 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;
+}
+
+
+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_2 (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
+ double attenuation_dB, // attenuation dB
+ 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_windes (sampling_freq, transition_width,
+ attenuation_dB);
+
+ 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;
+}
+
+
+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_2 (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
+ double attenuation_dB, // attenuation dB
+ 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_windes (sampling_freq, transition_width,
+ attenuation_dB);
+
+
+
+ vector<gr_complex> taps(ntaps);
+ vector<float> lptaps(ntaps);
+ vector<float> w = window (window_type, ntaps, beta);
+
+ lptaps = low_pass_2(gain,sampling_freq,(high_cutoff_freq - low_cutoff_freq)/2,transition_width,attenuation_dB,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;
+}
+
+
+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_2 (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
+ double attenuation_dB, // attenuation dB
+ 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_windes (sampling_freq, transition_width,
+ attenuation_dB);
+
+ // 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;
+}
+
+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.0)) / (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_windes(double sampling_freq,
+ double transition_width, // this is frequency, not relative frequency
+ double attenuation_dB)
+{
+ // Based on formula from Multirate Signal Processing for
+ // Communications Systems, fredric j harris
+ int ntaps = (int)(attenuation_dB*sampling_freq/(22.0*transition_width));
+ if ((ntaps & 1) == 0) // if even...
+ ntaps++; // ...make odd
+ return ntaps;
+}
+
+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;
+
+ case WIN_BLACKMAN_hARRIS:
+ for (int n = -ntaps/2; n < ntaps/2; n++)
+ taps[n+ntaps/2] = 0.35875 + 0.48829*cos((2*M_PI * n) / (float)M) +
+ 0.14128*cos((4*M_PI * n) / (float)M) + 0.01168*cos((6*M_PI * n) / (float)M);
+ 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::out_of_range ("gr_firdes:window: type out of range");
+ }
+
+ 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
index 000000000..8d98ebe0a
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_firdes.h
@@ -0,0 +1,373 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002,2008 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef _GR_FIRDES_H_
+#define _GR_FIRDES_H_
+
+#include <gr_core_api.h>
+#include <vector>
+#include <cmath>
+#include <gr_complex.h>
+
+/*!
+ * \brief Finite Impulse Response (FIR) filter design functions.
+ * \ingroup filter_design
+ */
+
+class GR_CORE_API 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
+ WIN_BLACKMAN_hARRIS = 5,
+ WIN_BLACKMAN_HARRIS = 5, // alias for capitalization consistency
+ };
+
+
+ // ... 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 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).
+ * \p attenuation_dB required stopband attenuation
+ * The normalized width of the transition
+ * band and the required stop band
+ * attenuation is what sets the number of taps
+ * required. Narrow --> more taps
+ * More attenuatin --> 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_2 (double gain,
+ double sampling_freq,
+ double cutoff_freq, // Hz beginning transition band
+ double transition_width, // Hz width of transition band
+ double attenuation_dB, // out of band attenuation dB
+ 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 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).
+ * \p attenuation_dB out of band attenuation
+ * The normalized width of the transition
+ * band and the required stop band
+ * attenuation is what sets the number of taps
+ * required. Narrow --> more taps
+ * More attenuation --> 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_2 (double gain,
+ double sampling_freq,
+ double cutoff_freq, // Hz center of transition band
+ double transition_width, // Hz width of transition band
+ double attenuation_dB, // out of band attenuation dB
+ 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-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).
+ * \p attenuation_dB out of band attenuation
+ * The normalized width of the transition
+ * band and the required stop band
+ * attenuation is what sets the number of taps
+ * required. Narrow --> more taps
+ * More attenuation --> 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_2 (double gain,
+ double sampling_freq,
+ double low_cutoff_freq, // Hz beginning transition band
+ double high_cutoff_freq, // Hz beginning transition band
+ double transition_width, // Hz width of transition band
+ double attenuation_dB, // out of band attenuation dB
+ 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 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).
+ * \p attenuation_dB out of band attenuation
+ * The normalized width of the transition
+ * band and the required stop band
+ * attenuation is what sets the number of taps
+ * required. Narrow --> more taps
+ * More attenuation --> 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_2 (double gain,
+ double sampling_freq,
+ double low_cutoff_freq, // Hz beginning transition band
+ double high_cutoff_freq, // Hz beginning transition band
+ double transition_width, // Hz width of transition band
+ double attenuation_dB, // out of band attenuation dB
+ 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 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).
+ * \p attenuation_dB out of band attenuation
+ * The normalized width of the transition
+ * band and the required stop band
+ * attenuation is what sets the number of taps
+ * required. Narrow --> more taps
+ * More attenuation --> 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_2 (double gain,
+ double sampling_freq,
+ double low_cutoff_freq, // Hz beginning transition band
+ double high_cutoff_freq, // Hz beginning transition band
+ double transition_width, // Hz width of transition band
+ double attenuation_dB, // out of band attenuation dB
+ 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 = 19,
+ 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);
+
+ static int compute_ntaps_windes (double sampling_freq,
+ double transition_width,
+ double attenuation_dB);
+};
+
+#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
index 000000000..0493db617
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_firdes.i
@@ -0,0 +1,360 @@
+/* -*- C++ -*- */
+/*
+ * Copyright 2002,2008 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+/*!
+ * \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
+ WIN_BLACKMAN_hARRIS = 5,
+ };
+
+ // ... 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
+ ) throw(std::out_of_range);
+
+ /*!
+ * \brief use "window method" to design a low-pass FIR filter
+ * using alternative design criteria
+ * \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).
+ * \p attenuation_dB out of band attenuation
+ * The normalized width of the transition
+ * band and the required stop band
+ * attenuation is what sets the number of taps
+ * required. Narrow --> more taps
+ * More attenuation --> 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_2 (double gain,
+ double sampling_freq,
+ double cutoff_freq, // Hz center of transition band
+ double transition_width, // Hz width of transition band
+ double attenuation_dB, // out of band attenuation
+ win_type window = WIN_HAMMING,
+ double beta = 6.76 // used only with Kaiser
+ ) throw(std::out_of_range);
+
+ /*!
+ * \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
+ ) throw(std::out_of_range);
+
+ /*!
+ * \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).
+ * \p attenuation_dB out of band attenuation
+ * The normalized width of the transition
+ * band and the required stop band
+ * attenuation is what sets the number of taps
+ * required. Narrow --> more taps
+ * More attenuation --> 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_2 (double gain,
+ double sampling_freq,
+ double cutoff_freq, // Hz center of transition band
+ double transition_width, // Hz width of transition band
+ double attenuation_dB, // out of band attenuation dB
+ 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
+ ) throw(std::out_of_range);
+
+
+ /*!
+ * \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).
+ * \p attenuation_dB out of band attenuation
+ * The normalized width of the transition
+ * band and the required stop band
+ * attenuation is what sets the number of taps
+ * required. Narrow --> more taps
+ * More attenuation --> 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_2 (double gain,
+ double sampling_freq,
+ double low_cutoff_freq, // Hz beginning transition band
+ double high_cutoff_freq, // Hz beginning transition band
+ double transition_width, // Hz width of transition band
+ double attenuation_dB, // out of band attenuation dB
+ 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<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, // used only with Kaiser
+ double beta = 6.76
+ ) throw(std::out_of_range);
+
+
+ /*!
+ * \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).
+ * \p attenuation_dB out of band attenuation
+ * The normalized width of the transition
+ * band and the required stop band
+ * attenuation is what sets the number of taps
+ * required. Narrow --> more taps
+ * More attenuation --> 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_2 (double gain,
+ double sampling_freq,
+ double low_cutoff_freq, // Hz beginning transition band
+ double high_cutoff_freq, // Hz beginning transition band
+ double transition_width, // Hz width of transition band
+ double attenuation_dB, // out of band attenuation dB
+ 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, // used only with Kaiser
+ double beta = 6.76
+ ) throw(std::out_of_range);
+
+
+ /*!
+ * \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).
+ * \p attenuation_dB out of band attenuation
+ * The normalized width of the transition
+ * band and the required stop band
+ * attenuation is what sets the number of taps
+ * required. Narrow --> more taps
+ * More attenuation --> 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_2 (double gain,
+ double sampling_freq,
+ double low_cutoff_freq, // Hz beginning transition band
+ double high_cutoff_freq, // Hz beginning transition band
+ double transition_width, // Hz width of transition band
+ double attenuation_dB, // out of band attenuation dB
+ 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 = 19,
+ win_type windowtype = WIN_RECTANGULAR,
+ double beta = 6.76
+ ) throw(std::out_of_range);
+
+ /*!
+ * \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) throw(std::out_of_range);
+
+ /*!
+ * \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) throw(std::out_of_range);
+
+ /*!
+ * Return window given type, ntaps and optional beta.
+ */
+ static std::vector<float> gr_firdes::window (win_type type, int ntaps, double beta)
+ throw(std::runtime_error);
+};
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
index 000000000..d67ded3ea
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_float_to_char.cc
@@ -0,0 +1,79 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2010,2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_float_to_char.h>
+#include <gr_io_signature.h>
+#include <volk/volk.h>
+
+gr_float_to_char_sptr
+gr_make_float_to_char (size_t vlen, float scale)
+{
+ return gnuradio::get_initial_sptr(new gr_float_to_char (vlen, scale));
+}
+
+gr_float_to_char::gr_float_to_char (size_t vlen, float scale)
+ : gr_sync_block ("gr_float_to_char",
+ gr_make_io_signature (1, 1, sizeof (float)*vlen),
+ gr_make_io_signature (1, 1, sizeof (char)*vlen)),
+ d_vlen(vlen), d_scale(scale)
+{
+ const int alignment_multiple =
+ volk_get_alignment() / sizeof(char);
+ set_alignment(std::max(1,alignment_multiple));
+}
+
+float
+gr_float_to_char::scale() const
+{
+ return d_scale;
+}
+
+void
+gr_float_to_char::set_scale(float scale)
+{
+ d_scale = scale;
+}
+
+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];
+ int8_t *out = (int8_t *) output_items[0];
+
+ if(is_unaligned()) {
+ volk_32f_s32f_convert_8i_u(out, in, d_scale, d_vlen*noutput_items);
+ }
+ else {
+ volk_32f_s32f_convert_8i_a(out, in, d_scale, d_vlen*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
index 000000000..2df50f18d
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_float_to_char.h
@@ -0,0 +1,70 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_FLOAT_TO_CHAR_H
+#define INCLUDED_GR_FLOAT_TO_CHAR_H
+
+#include <gr_core_api.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_CORE_API gr_float_to_char_sptr
+gr_make_float_to_char (size_t vlen=1, float scale=1);
+
+/*!
+ * \brief Convert stream of float to a stream of char
+ * \ingroup converter_blk
+ *
+ * \param vlen vector length of data streams.
+ * \param scale a scalar multiplier to change the output signal scale.
+ */
+
+class GR_CORE_API gr_float_to_char : public gr_sync_block
+{
+ private:
+ friend GR_CORE_API gr_float_to_char_sptr gr_make_float_to_char
+ (size_t vlen, float scale);
+ gr_float_to_char (size_t vlen, float scale);
+
+ size_t d_vlen;
+ float d_scale;
+
+ public:
+ /*!
+ * Get the scalar multiplier value.
+ */
+ float scale() const;
+
+ /*!
+ * Set the scalar multiplier value.
+ */
+ void set_scale(float scale);
+
+ 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
index 000000000..b40389ede
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_float_to_char.i
@@ -0,0 +1,33 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,float_to_char)
+
+gr_float_to_char_sptr
+gr_make_float_to_char (size_t vlen=1, float scale=1);
+
+class gr_float_to_char : public gr_sync_block
+{
+public:
+ float scale() const;
+ void set_scale(float scale);
+};
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
index 000000000..c68eac8c7
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_float_to_complex.cc
@@ -0,0 +1,72 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004, 2009,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_float_to_complex.h>
+#include <gr_io_signature.h>
+
+gr_float_to_complex_sptr
+gr_make_float_to_complex (size_t vlen)
+{
+ return gnuradio::get_initial_sptr(new gr_float_to_complex (vlen));
+}
+
+gr_float_to_complex::gr_float_to_complex (size_t vlen)
+ : gr_sync_block ("gr_float_to_complex",
+ gr_make_io_signature (1, 2, sizeof (float) * vlen),
+ gr_make_io_signature (1, 1, sizeof (gr_complex) * vlen)),
+ d_vlen (vlen)
+{
+}
+
+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 (size_t j = 0; j < noutput_items*d_vlen; j++)
+ out[j] = gr_complex (r[j], 0);
+ break;
+
+ case 2:
+ for (size_t j = 0; j < noutput_items*d_vlen; 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
index 000000000..628b4a954
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_float_to_complex.h
@@ -0,0 +1,55 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004, 2009 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_FLOAT_TO_COMPLEX_H
+#define INCLUDED_GR_FLOAT_TO_COMPLEX_H
+
+#include <gr_core_api.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_CORE_API gr_float_to_complex_sptr
+gr_make_float_to_complex (size_t vlen = 1);
+
+/*!
+ * \brief Convert 1 or 2 streams of float to a stream of gr_complex
+ * \ingroup converter_blk
+ */
+
+class GR_CORE_API gr_float_to_complex : public gr_sync_block
+{
+ friend GR_CORE_API gr_float_to_complex_sptr gr_make_float_to_complex (size_t vlen);
+ gr_float_to_complex (size_t vlen);
+
+ size_t 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_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
index 000000000..ed5ad128b
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_float_to_complex.i
@@ -0,0 +1,30 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004, 2009 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,float_to_complex)
+
+gr_float_to_complex_sptr gr_make_float_to_complex (size_t vlen = 1);
+
+class gr_float_to_complex : public gr_sync_block
+{
+ gr_float_to_complex (size_t vlen);
+};
diff --git a/gnuradio-core/src/lib/general/gr_float_to_int.cc b/gnuradio-core/src/lib/general/gr_float_to_int.cc
new file mode 100644
index 000000000..43b851895
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_float_to_int.cc
@@ -0,0 +1,89 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2011,2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_float_to_int.h>
+#include <gr_io_signature.h>
+#include <gri_float_to_int.h>
+#include <volk/volk.h>
+
+gr_float_to_int_sptr
+gr_make_float_to_int (size_t vlen, float scale)
+{
+ return gnuradio::get_initial_sptr(new gr_float_to_int (vlen, scale));
+}
+
+gr_float_to_int::gr_float_to_int (size_t vlen, float scale)
+ : gr_sync_block ("gr_float_to_int",
+ gr_make_io_signature (1, 1, sizeof (float)*vlen),
+ gr_make_io_signature (1, 1, sizeof (int)*vlen)),
+ d_vlen(vlen), d_scale(scale)
+{
+ const int alignment_multiple =
+ volk_get_alignment() / sizeof(int);
+ set_alignment(std::max(1,alignment_multiple));
+}
+
+float
+gr_float_to_int::scale() const
+{
+ return d_scale;
+}
+
+void
+gr_float_to_int::set_scale(float scale)
+{
+ d_scale = scale;
+}
+int
+gr_float_to_int::work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ // Disable the Volk for now. There is a problem for large 32-bit ints that
+ // are not properly represented by the precisions of a single float, which
+ // can cause wrapping from large, positive numbers to negative.
+ // In gri_float_to_int, the value is first promoted to a 64-bit
+ // value, clipped, then converted to a float.
+#if 0
+ const float *in = (const float *) input_items[0];
+ int32_t *out = (int32_t *) output_items[0];
+
+ if(is_unaligned()) {
+ volk_32f_s32f_convert_32i_u(out, in, d_scale, d_vlen*noutput_items);
+ }
+ else {
+ volk_32f_s32f_convert_32i_a(out, in, d_scale, d_vlen*noutput_items);
+ }
+#else
+ const float *in = (const float *) input_items[0];
+ int *out = (int *) output_items[0];
+
+ gri_float_to_int (in, out, d_scale, d_vlen*noutput_items);
+
+#endif
+
+ return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_float_to_int.h b/gnuradio-core/src/lib/general/gr_float_to_int.h
new file mode 100644
index 000000000..c10ea739d
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_float_to_int.h
@@ -0,0 +1,70 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2011,2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_FLOAT_TO_INT_H
+#define INCLUDED_GR_FLOAT_TO_INT_H
+
+#include <gr_core_api.h>
+#include <gr_sync_block.h>
+
+class gr_float_to_int;
+typedef boost::shared_ptr<gr_float_to_int> gr_float_to_int_sptr;
+
+GR_CORE_API gr_float_to_int_sptr
+gr_make_float_to_int (size_t vlen=1, float scale=1);
+
+/*!
+ * \brief Convert stream of float to a stream of short
+ * \ingroup converter_blk
+ *
+ * \param vlen vector length of data streams.
+ * \param scale a scalar multiplier to change the output signal scale.
+ */
+
+class GR_CORE_API gr_float_to_int : public gr_sync_block
+{
+ private:
+ friend GR_CORE_API
+ gr_float_to_int_sptr gr_make_float_to_int (size_t vlen, float scale);
+ gr_float_to_int (size_t vlen, float scale);
+
+ size_t d_vlen;
+ float d_scale;
+
+ public:
+ /*!
+ * Get the scalar multiplier value.
+ */
+ float scale() const;
+
+ /*!
+ * Set the scalar multiplier value.
+ */
+ void set_scale(float scale);
+
+ virtual int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+
+#endif /* INCLUDED_GR_FLOAT_TO_INT_H */
diff --git a/gnuradio-core/src/lib/general/gr_float_to_int.i b/gnuradio-core/src/lib/general/gr_float_to_int.i
new file mode 100644
index 000000000..e2a2c53ce
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_float_to_int.i
@@ -0,0 +1,33 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2011,2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,float_to_int)
+
+gr_float_to_int_sptr
+gr_make_float_to_int (size_t vlen=1, float scale=1);
+
+class gr_float_to_int : public gr_sync_block
+{
+public:
+ float scale() const;
+ void set_scale(float scale);
+};
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
index 000000000..ab720168b
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_float_to_short.cc
@@ -0,0 +1,79 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2010,2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_float_to_short.h>
+#include <gr_io_signature.h>
+#include <volk/volk.h>
+
+gr_float_to_short_sptr
+gr_make_float_to_short (size_t vlen, float scale)
+{
+ return gnuradio::get_initial_sptr(new gr_float_to_short (vlen, scale));
+}
+
+gr_float_to_short::gr_float_to_short (size_t vlen, float scale)
+ : gr_sync_block ("gr_float_to_short",
+ gr_make_io_signature (1, 1, sizeof (float)*vlen),
+ gr_make_io_signature (1, 1, sizeof (short)*vlen)),
+ d_vlen(vlen), d_scale(scale)
+{
+ const int alignment_multiple =
+ volk_get_alignment() / sizeof(short);
+ set_alignment(std::max(1,alignment_multiple));
+}
+
+float
+gr_float_to_short::scale() const
+{
+ return d_scale;
+}
+
+void
+gr_float_to_short::set_scale(float scale)
+{
+ d_scale = scale;
+}
+
+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];
+
+ if(is_unaligned()) {
+ volk_32f_s32f_convert_16i_u(out, in, d_scale, d_vlen*noutput_items);
+ }
+ else {
+ volk_32f_s32f_convert_16i_a(out, in, d_scale, d_vlen*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
index 000000000..9e43804f5
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_float_to_short.h
@@ -0,0 +1,69 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_FLOAT_TO_SHORT_H
+#define INCLUDED_GR_FLOAT_TO_SHORT_H
+
+#include <gr_core_api.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_CORE_API gr_float_to_short_sptr
+gr_make_float_to_short (size_t vlen=1, float scale=1);
+
+/*!
+ * \brief Convert stream of float to a stream of short
+ * \ingroup converter_blk
+ *
+ * \param vlen vector length of data streams.
+ * \param scale a scalar multiplier to change the output signal scale.
+ */
+
+class GR_CORE_API gr_float_to_short : public gr_sync_block
+{
+ friend GR_CORE_API
+ gr_float_to_short_sptr gr_make_float_to_short (size_t vlen, float scale);
+ gr_float_to_short (size_t vlen, float scale);
+
+ size_t d_vlen;
+ float d_scale;
+
+ public:
+ /*!
+ * Get the scalar multiplier value.
+ */
+ float scale() const;
+
+ /*!
+ * Set the scalar multiplier value.
+ */
+ void set_scale(float scale);
+
+ 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
index 000000000..ea59a388e
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_float_to_short.i
@@ -0,0 +1,33 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,float_to_short)
+
+gr_float_to_short_sptr
+gr_make_float_to_short (size_t vlen=1, float scale=1);
+
+class gr_float_to_short : public gr_sync_block
+{
+public:
+ float scale() const;
+ void set_scale(float scale);
+};
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
index 000000000..5aec73b71
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_float_to_uchar.cc
@@ -0,0 +1,58 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_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 gnuradio::get_initial_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
index 000000000..7fd947048
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_float_to_uchar.h
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_FLOAT_TO_UCHAR_H
+#define INCLUDED_GR_FLOAT_TO_UCHAR_H
+
+#include <gr_core_api.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_CORE_API gr_float_to_uchar_sptr
+gr_make_float_to_uchar ();
+
+/*!
+ * \brief Convert stream of float to a stream of unsigned char
+ * \ingroup converter_blk
+ */
+
+class GR_CORE_API gr_float_to_uchar : public gr_sync_block
+{
+ friend GR_CORE_API 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
index 000000000..b35979213
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_float_to_uchar.i
@@ -0,0 +1,30 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+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_fmdet_cf.cc b/gnuradio-core/src/lib/general/gr_fmdet_cf.cc
new file mode 100644
index 000000000..f02036292
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_fmdet_cf.cc
@@ -0,0 +1,105 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_fmdet_cf.h>
+#include <gr_io_signature.h>
+#include <math.h>
+#include <gr_math.h>
+
+#define M_TWOPI (2*M_PI)
+
+gr_fmdet_cf_sptr
+gr_make_fmdet_cf (float samplerate, float freq_low, float freq_high, float scl)
+{
+ return gnuradio::get_initial_sptr(new gr_fmdet_cf (samplerate, freq_low, freq_high, scl));
+}
+
+gr_fmdet_cf::gr_fmdet_cf (float samplerate, float freq_low, float freq_high, float scl)
+ : gr_sync_block ("fmdet_cf",
+ gr_make_io_signature (1, 1, sizeof (gr_complex)),
+ gr_make_io_signature (1, 1, sizeof (float))),
+ d_S1(0.1),d_S2(0.1),
+ d_S3(0.1),d_S4(0.1)
+{
+ const float h[]={0.003118678733, -0.012139843428, 0.027270898036, -0.051318579352,
+ 0.090406910552, -0.162926865366, 0.361885392563, 0.000000000000,
+ -0.361885392563, 0.162926865366, -0.090406910552, 0.051318579352,
+ -0.027270898036, 0.012139843428, -0.003118678733};
+
+
+
+
+ float delta;
+ std::vector<float> taps(15);
+
+ d_freqhi = freq_high;
+ d_freqlo = freq_low;
+ delta = (d_freqhi - d_freqlo);
+ d_scl = scl;
+ d_bias = 0.5*scl*(d_freqhi+d_freqlo)/delta;
+ for (int i=0;i<15;i++) taps[i] = h[i];
+ // d_filter = gr_fir_util::create_gr_fir_ccf(taps);
+
+}
+
+int
+gr_fmdet_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];
+ // const gr_complex *scaleiptr = (gr_complex *) input_items[0];
+
+ int size = noutput_items;
+
+ gr_complex Sdot,S0,S1=d_S1,S2=d_S2,S3=d_S3,S4=d_S4;
+ float d_8 = 8.0;
+
+ while (size-- > 0) {
+ S0=*iptr++;
+
+
+ Sdot = d_scl * (-S0+d_8*S1-d_8*S1+S4);
+
+ d_freq = (S2.real()*Sdot.imag()-S2.imag()*Sdot.real())/
+ (S2.real()*S2.real()+S2.imag()*S2.imag());
+
+ S4=S3;
+ S3=S2;
+ S2=S1;
+ S1=S0;
+
+
+ *optr++ = d_freq-d_bias;
+ }
+ d_S1=S1;
+ d_S2=S2;
+ d_S3=S3;
+ d_S4=S4;
+ return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_fmdet_cf.h b/gnuradio-core/src/lib/general/gr_fmdet_cf.h
new file mode 100644
index 000000000..f85630f2f
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_fmdet_cf.h
@@ -0,0 +1,63 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_FMDET_CF_H
+#define INCLUDED_GR_FMDET_CF_H
+
+#include <gr_core_api.h>
+#include <gr_sync_block.h>
+
+class gr_fmdet_cf;
+typedef boost::shared_ptr<gr_fmdet_cf> gr_fmdet_cf_sptr;
+
+GR_CORE_API gr_fmdet_cf_sptr gr_make_fmdet_cf (float samplerate, float freq_low, float freq_high, float scl);
+
+class gr_fir_ccf;
+
+
+/*!
+ * \brief Implements an IQ slope detector
+ *
+ *
+ * input: stream of complex; output: stream of floats
+ *
+ * This implements a limiting slope detector. The limiter is in the
+ * normalization by the magnitude of the sample
+ */
+
+class GR_CORE_API gr_fmdet_cf : public gr_sync_block
+{
+ friend GR_CORE_API gr_fmdet_cf_sptr gr_make_fmdet_cf (float samplerate, float freq_low,
+ float freq_high, float scl);
+
+ gr_complex d_S1,d_S2,d_S3,d_S4;
+ float d_freq,d_freqlo,d_freqhi,d_scl,d_bias;
+ gr_fir_ccf* d_filter;
+ gr_fmdet_cf (float samplerate, float freq_low, float freq_high, float scl);
+
+ int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+
+};
+
+#endif
diff --git a/gnuradio-core/src/lib/general/gr_fmdet_cf.i b/gnuradio-core/src/lib/general/gr_fmdet_cf.i
new file mode 100644
index 000000000..2db596b7a
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_fmdet_cf.i
@@ -0,0 +1,31 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,fmdet_cf)
+
+gr_fmdet_cf_sptr gr_make_fmdet_cf (float samplerate, float freq_low, float freq_high, float scl);
+
+class gr_fmdet_cf : public gr_sync_block
+{
+ private:
+ gr_fmdet_cf (float samplerate, float freq_low, float freq_high, float scl);
+};
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
index 000000000..64a0af6a0
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_framer_sink_1.cc
@@ -0,0 +1,190 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2006,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_framer_sink_1.h>
+#include <gr_io_signature.h>
+#include <cstdio>
+#include <stdexcept>
+#include <string.h>
+
+#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, int whitener_offset)
+{
+ if (VERBOSE)
+ fprintf(stderr, "@ enter_have_header (payload_len = %d) (offset = %d)\n", payload_len, whitener_offset);
+
+ d_state = STATE_HAVE_HEADER;
+ d_packetlen = payload_len;
+ d_packet_whitener_offset = whitener_offset;
+ 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 gnuradio::get_initial_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;
+ int whitener_offset;
+ header_payload(&payload_len, &whitener_offset);
+ enter_have_header(payload_len, whitener_offset);
+
+ if (d_packetlen == 0){ // check for zero-length payload
+ // build a zero-length message
+ // NOTE: passing header field as arg1 is not scalable
+ gr_message_sptr msg =
+ gr_make_message(0, d_packet_whitener_offset, 0, 0);
+
+ d_target_queue->insert_tail(msg); // send it
+ msg.reset(); // free it up
+
+ enter_search();
+ }
+ }
+ else
+ enter_search(); // bad header
+ 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
+ // NOTE: passing header field as arg1 is not scalable
+ gr_message_sptr msg =
+ gr_make_message(0, d_packet_whitener_offset, 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
index 000000000..93e41745f
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_framer_sink_1.h
@@ -0,0 +1,107 @@
+/* -*- 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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_FRAMER_SINK_1_H
+#define INCLUDED_GR_FRAMER_SINK_1_H
+
+#include <gr_core_api.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_CORE_API 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_blk
+ *
+ * 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_CORE_API gr_framer_sink_1 : public gr_sync_block
+{
+ friend GR_CORE_API 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_packet_whitener_offset; // offset into whitener string to use
+ 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, int whitener_offset);
+
+ bool header_ok()
+ {
+ // confirm that two copies of header info are identical
+ return ((d_header >> 16) ^ (d_header & 0xffff)) == 0;
+ }
+
+ void header_payload(int *len, int *offset)
+ {
+ // header consists of two 16-bit shorts in network byte order
+ // payload length is lower 12 bits
+ // whitener offset is upper 4 bits
+ *len = (d_header >> 16) & 0x0fff;
+ *offset = (d_header >> 28) & 0x000f;
+ }
+
+ 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
index 000000000..06281b138
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_framer_sink_1.i
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,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
index 000000000..5c4daec58
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_frequency_modulator_fc.cc
@@ -0,0 +1,71 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2010,2011 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_frequency_modulator_fc.h>
+#include <gr_io_signature.h>
+#include <gr_fxpt.h>
+#include <math.h>
+#include <boost/math/special_functions/trunc.hpp>
+
+
+gr_frequency_modulator_fc_sptr gr_make_frequency_modulator_fc (double sensitivity)
+{
+ return gnuradio::get_initial_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];
+
+ while (d_phase > (float)(M_PI))
+ d_phase -= (float)(2.0 * M_PI);
+ while (d_phase < (float)(-M_PI))
+ d_phase += (float)(2.0 * M_PI);
+
+ float oi, oq;
+
+ gr_int32 angle = gr_fxpt::float_to_fixed (d_phase);
+ gr_fxpt::sincos (angle, &oq, &oi);
+ out[i] = gr_complex (oi, oq);
+ }
+
+ 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
index 000000000..c680e9648
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_frequency_modulator_fc.h
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_FREQUENCY_MODULATOR_FC_H
+#define INCLUDED_GR_FREQUENCY_MODULATOR_FC_H
+
+#include <gr_core_api.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_CORE_API gr_frequency_modulator_fc_sptr gr_make_frequency_modulator_fc (double sensitivity);
+
+/*!
+ * \brief Frequency modulator block
+ * \ingroup modulation_blk
+ *
+ * float input; complex baseband output
+ */
+class GR_CORE_API gr_frequency_modulator_fc : public gr_sync_block
+{
+ float d_sensitivity;
+ float d_phase;
+
+ friend GR_CORE_API gr_frequency_modulator_fc_sptr
+ gr_make_frequency_modulator_fc (double sensitivity);
+
+ gr_frequency_modulator_fc (double sensitivity);
+
+ public:
+ void set_sensitivity(float sens) { d_sensitivity = sens; }
+ float sensitivity() const { return d_sensitivity; }
+
+ 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
index 000000000..9a740583b
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_frequency_modulator_fc.i
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,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);
+public:
+ void set_sensitivity(float sens) { d_sensitivity = sens; }
+ float sensitivity() const { return d_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
index 000000000..2ea8520e6
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_fxpt.cc
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_fxpt.h>
+
+const float gr_fxpt::s_sine_table[1 << NBITS][2] = {
+#include "sine_table.h"
+};
+
+const float gr_fxpt::PI = 3.14159265358979323846;
+const float gr_fxpt::TWO_TO_THE_31 = 2147483648.0;
+
diff --git a/gnuradio-core/src/lib/general/gr_fxpt.h b/gnuradio-core/src/lib/general/gr_fxpt.h
new file mode 100644
index 000000000..9de6c0c18
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_fxpt.h
@@ -0,0 +1,104 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifndef INCLUDED_GR_FXPT_H
+#define INCLUDED_GR_FXPT_H
+
+#include <gr_core_api.h>
+#include <gr_types.h>
+
+/*!
+ * \brief fixed point sine and cosine and friends.
+ * \ingroup misc
+ *
+ * fixed pt radians
+ * --------- --------
+ * -2**31 -pi
+ * 0 0
+ * 2**31-1 pi - epsilon
+ *
+ */
+class GR_CORE_API 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;
+ static const float TWO_TO_THE_31;
+public:
+
+ static gr_int32
+ float_to_fixed (float x)
+ {
+ // Fold x into -PI to PI.
+ int d = (int)floor(x/2/PI+0.5);
+ x -= d*2*PI;
+ // And convert to an integer.
+ 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];
+ }
+
+ /*
+ * \brief Given a fixedpoint angle x, return float cos(x) and sin (x)
+ */
+ static void sincos(gr_int32 x, float *s, float *c)
+ {
+ gr_uint32 ux = x;
+ int sin_index = ux >> (WORDBITS - NBITS);
+ *s = s_sine_table[sin_index][0] * (ux >> 1) + s_sine_table[sin_index][1];
+
+ ux = x + 0x40000000;
+ int cos_index = ux >> (WORDBITS - NBITS);
+ *c = s_sine_table[cos_index][0] * (ux >> 1) + s_sine_table[cos_index][1];
+
+ return;
+ }
+
+};
+
+#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
index 000000000..9473e6ddb
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_fxpt_nco.h
@@ -0,0 +1,153 @@
+/* -*- 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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifndef INCLUDED_GR_FXPT_NCO_H
+#define INCLUDED_GR_FXPT_NCO_H
+
+#include <gr_core_api.h>
+#include <gr_fxpt.h>
+#include <gr_complex.h>
+
+/*!
+ * \brief Numerically Controlled Oscillator (NCO)
+ * \ingroup misc
+ */
+class GR_CORE_API gr_fxpt_nco {
+ gr_uint32 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
index 000000000..09c649de7
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_fxpt_vco.h
@@ -0,0 +1,73 @@
+/* -*- 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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifndef INCLUDED_GR_FXPT_VCO_H
+#define INCLUDED_GR_FXPT_VCO_H
+
+#include <gr_core_api.h>
+#include <gr_fxpt.h>
+#include <gr_complex.h>
+
+/*!
+ * \brief Voltage Controlled Oscillator (VCO)
+ * \ingroup misc
+ */
+class GR_CORE_API 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_glfsr_source_b.cc b/gnuradio-core/src/lib/general/gr_glfsr_source_b.cc
new file mode 100644
index 000000000..fcfeb80dc
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_glfsr_source_b.cc
@@ -0,0 +1,84 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <gr_glfsr_source_b.h>
+#include <gri_glfsr.h>
+#include <gr_io_signature.h>
+#include <stdexcept>
+
+gr_glfsr_source_b_sptr
+gr_make_glfsr_source_b(int degree, bool repeat, int mask, int seed)
+{
+ return gnuradio::get_initial_sptr(new gr_glfsr_source_b(degree, repeat, mask, seed));
+}
+
+gr_glfsr_source_b::gr_glfsr_source_b(int degree, bool repeat, int mask, int seed)
+ : gr_sync_block ("glfsr_source_b",
+ gr_make_io_signature (0, 0, 0),
+ gr_make_io_signature (1, 1, sizeof(unsigned char))),
+ d_repeat(repeat),
+ d_index(0)
+{
+ if (degree < 1 || degree > 32)
+ throw std::runtime_error("gr_glfsr_source_b: degree must be between 1 and 32 inclusive");
+ d_length = (unsigned int)((1ULL << degree)-1);
+
+ if (mask == 0)
+ mask = gri_glfsr::glfsr_mask(degree);
+ d_glfsr = new gri_glfsr(mask, seed);
+}
+
+gr_glfsr_source_b::~gr_glfsr_source_b()
+{
+ delete d_glfsr;
+}
+
+int
+gr_glfsr_source_b::work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ char *out = (char *) output_items[0];
+ if ((d_index > d_length) && d_repeat == false)
+ return -1; /* once through the sequence */
+
+ int i;
+ for (i = 0; i < noutput_items; i++) {
+ out[i] = d_glfsr->next_bit();
+ d_index++;
+ if (d_index > d_length && d_repeat == false)
+ break;
+ }
+
+ return i;
+}
+
+int
+gr_glfsr_source_b::mask() const
+{
+ return d_glfsr->mask();
+}
diff --git a/gnuradio-core/src/lib/general/gr_glfsr_source_b.h b/gnuradio-core/src/lib/general/gr_glfsr_source_b.h
new file mode 100644
index 000000000..7549a76b3
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_glfsr_source_b.h
@@ -0,0 +1,66 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_GLFSR_SOURCE_B_H
+#define INCLUDED_GR_GLFSR_SOURCE_B_H
+
+#include <gr_core_api.h>
+#include <gr_sync_block.h>
+
+class gri_glfsr;
+
+class gr_glfsr_source_b;
+typedef boost::shared_ptr<gr_glfsr_source_b> gr_glfsr_source_b_sptr;
+
+GR_CORE_API gr_glfsr_source_b_sptr gr_make_glfsr_source_b(int degree, bool repeat=true, int mask=0, int seed=1);
+
+/*!
+ * \brief Galois LFSR pseudo-random source
+ * \ingroup source_blk
+ */
+class GR_CORE_API gr_glfsr_source_b : public gr_sync_block
+{
+ private:
+ friend GR_CORE_API gr_glfsr_source_b_sptr
+ gr_make_glfsr_source_b(int degree, bool repeat, int mask, int seed);
+
+ gri_glfsr *d_glfsr;
+
+ bool d_repeat;
+ unsigned int d_index;
+ unsigned int d_length;
+
+ gr_glfsr_source_b(int degree, bool repeat, int mask, int seed);
+
+ public:
+
+ ~gr_glfsr_source_b();
+
+ int work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+
+ unsigned int period() const { return d_length; }
+ int mask() const;
+};
+
+#endif /* INCLUDED_GR_GLFSR_SOURCE_B_H */
diff --git a/gnuradio-core/src/lib/general/gr_glfsr_source_b.i b/gnuradio-core/src/lib/general/gr_glfsr_source_b.i
new file mode 100644
index 000000000..ffdd52ddb
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_glfsr_source_b.i
@@ -0,0 +1,37 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,glfsr_source_b);
+
+gr_glfsr_source_b_sptr
+gr_make_glfsr_source_b(int degree, bool repeat=true, int mask=0, int seed=1)
+ throw (std::runtime_error);
+
+class gr_glfsr_source_b : public gr_sync_block
+{
+protected:
+ gr_glfsr_source_b(int degree, bool repeat, int mask, int seed);
+
+public:
+ unsigned int period() const;
+ int mask() const;
+};
diff --git a/gnuradio-core/src/lib/general/gr_glfsr_source_f.cc b/gnuradio-core/src/lib/general/gr_glfsr_source_f.cc
new file mode 100644
index 000000000..a9efc8a70
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_glfsr_source_f.cc
@@ -0,0 +1,84 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <gr_glfsr_source_f.h>
+#include <gri_glfsr.h>
+#include <gr_io_signature.h>
+#include <stdexcept>
+
+gr_glfsr_source_f_sptr
+gr_make_glfsr_source_f(int degree, bool repeat, int mask, int seed)
+{
+ return gnuradio::get_initial_sptr(new gr_glfsr_source_f(degree, repeat, mask, seed));
+}
+
+gr_glfsr_source_f::gr_glfsr_source_f(int degree, bool repeat, int mask, int seed)
+ : gr_sync_block ("glfsr_source_f",
+ gr_make_io_signature (0, 0, 0),
+ gr_make_io_signature (1, 1, sizeof(float))),
+ d_repeat(repeat),
+ d_index(0)
+{
+ if (degree < 1 || degree > 32)
+ throw std::runtime_error("gr_glfsr_source_f: degree must be between 1 and 32 inclusive");
+ d_length = (unsigned int)((1ULL << degree)-1);
+
+ if (mask == 0)
+ mask = gri_glfsr::glfsr_mask(degree);
+ d_glfsr = new gri_glfsr(mask, seed);
+}
+
+gr_glfsr_source_f::~gr_glfsr_source_f()
+{
+ delete d_glfsr;
+}
+
+int
+gr_glfsr_source_f::work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ float *out = (float *) output_items[0];
+ if ((d_index > d_length) && d_repeat == false)
+ return -1; /* once through the sequence */
+
+ int i;
+ for (i = 0; i < noutput_items; i++) {
+ out[i] = (float)d_glfsr->next_bit()*2.0-1.0;
+ d_index++;
+ if (d_index > d_length && d_repeat == false)
+ break;
+ }
+
+ return i;
+}
+
+int
+gr_glfsr_source_f::mask() const
+{
+ return d_glfsr->mask();
+}
diff --git a/gnuradio-core/src/lib/general/gr_glfsr_source_f.h b/gnuradio-core/src/lib/general/gr_glfsr_source_f.h
new file mode 100644
index 000000000..3549e3e5d
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_glfsr_source_f.h
@@ -0,0 +1,66 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_GLFSR_SOURCE_F_H
+#define INCLUDED_GR_GLFSR_SOURCE_F_H
+
+#include <gr_core_api.h>
+#include <gr_sync_block.h>
+
+class gri_glfsr;
+
+class gr_glfsr_source_f;
+typedef boost::shared_ptr<gr_glfsr_source_f> gr_glfsr_source_f_sptr;
+
+GR_CORE_API gr_glfsr_source_f_sptr gr_make_glfsr_source_f(int degree, bool repeat=true, int mask=0, int seed=1);
+
+/*!
+ * \brief Galois LFSR pseudo-random source generating float outputs -1.0 - 1.0
+ * \ingroup source_blk
+ */
+class GR_CORE_API gr_glfsr_source_f : public gr_sync_block
+{
+ private:
+ friend GR_CORE_API gr_glfsr_source_f_sptr
+ gr_make_glfsr_source_f(int degree, bool repeat, int mask, int seed);
+
+ gri_glfsr *d_glfsr;
+
+ bool d_repeat;
+ unsigned int d_index;
+ unsigned int d_length;
+
+ gr_glfsr_source_f(int degree, bool repeat, int mask, int seed);
+
+ public:
+
+ ~gr_glfsr_source_f();
+
+ int work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+
+ unsigned int period() const { return d_length; }
+ int mask() const;
+};
+
+#endif /* INCLUDED_GR_GLFSR_SOURCE_F_H */
diff --git a/gnuradio-core/src/lib/general/gr_glfsr_source_f.i b/gnuradio-core/src/lib/general/gr_glfsr_source_f.i
new file mode 100644
index 000000000..2f84387c2
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_glfsr_source_f.i
@@ -0,0 +1,37 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,glfsr_source_f);
+
+gr_glfsr_source_f_sptr
+gr_make_glfsr_source_f(int degree, bool repeat=true, int mask=0, int seed=1)
+ throw (std::runtime_error);
+
+class gr_glfsr_source_f : public gr_sync_block
+{
+protected:
+ gr_glfsr_source_f(int degree, bool repeat, int mask, int seed);
+
+public:
+ unsigned int period() const;
+ int mask() const;
+};
diff --git a/gnuradio-core/src/lib/general/gr_head.cc b/gnuradio-core/src/lib/general/gr_head.cc
new file mode 100644
index 000000000..cb07c84dd
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_head.cc
@@ -0,0 +1,61 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2009 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <gr_head.h>
+#include <gr_io_signature.h>
+#include <string.h>
+
+gr_head::gr_head (size_t sizeof_stream_item, unsigned long long nitems)
+ : gr_sync_block ("head",
+ gr_make_io_signature (1, 1, sizeof_stream_item),
+ gr_make_io_signature (1, 1, sizeof_stream_item)),
+ d_nitems (nitems), d_ncopied_items (0)
+{
+}
+
+gr_head_sptr
+gr_make_head (size_t sizeof_stream_item, unsigned long long nitems)
+{
+ return gnuradio::get_initial_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, (unsigned long long) 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
index 000000000..48415892d
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_head.h
@@ -0,0 +1,61 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2009,2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_HEAD_H
+#define INCLUDED_GR_HEAD_H
+
+#include <gr_core_api.h>
+#include <gr_sync_block.h>
+#include <stddef.h> // size_t
+
+class gr_head;
+typedef boost::shared_ptr<gr_head> gr_head_sptr;
+
+/*!
+ * \brief copies the first N items to the output then signals done
+ * \ingroup slicedice_blk
+ *
+ * Useful for building test cases
+ */
+
+class GR_CORE_API gr_head : public gr_sync_block
+{
+ friend GR_CORE_API gr_head_sptr gr_make_head (size_t sizeof_stream_item, unsigned long long nitems);
+ gr_head (size_t sizeof_stream_item, unsigned long long nitems);
+
+ unsigned long long d_nitems;
+ unsigned long long d_ncopied_items;
+
+ public:
+ int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+
+ void reset() { d_ncopied_items = 0; }
+ void set_length(int nitems) { d_nitems = nitems; }
+};
+
+GR_CORE_API gr_head_sptr
+gr_make_head (size_t sizeof_stream_item, unsigned long long 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
index 000000000..11f3331d4
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_head.i
@@ -0,0 +1,33 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2009,2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,head);
+
+gr_head_sptr gr_make_head(size_t sizeof_stream_item, unsigned long long nitems);
+
+class gr_head : public gr_block {
+ gr_head();
+public:
+ void reset();
+ void set_length(int nitems);
+};
+
diff --git a/gnuradio-core/src/lib/general/gr_int_to_float.cc b/gnuradio-core/src/lib/general/gr_int_to_float.cc
new file mode 100644
index 000000000..a7fb24dc6
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_int_to_float.cc
@@ -0,0 +1,67 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2011,2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_int_to_float.h>
+#include <gr_io_signature.h>
+#include <volk/volk.h>
+
+gr_int_to_float_sptr
+gr_make_int_to_float (size_t vlen, float scale)
+{
+ return gnuradio::get_initial_sptr(new gr_int_to_float (vlen, scale));
+}
+
+gr_int_to_float::gr_int_to_float (size_t vlen, float scale)
+ : gr_sync_block ("gr_int_to_float",
+ gr_make_io_signature (1, 1, sizeof (int32_t)*vlen),
+ gr_make_io_signature (1, 1, sizeof (float)*vlen)),
+ d_vlen(vlen), d_scale(scale)
+{
+ const int alignment_multiple =
+ volk_get_alignment() / sizeof(float);
+ set_alignment(std::max(1,alignment_multiple));
+}
+
+int
+gr_int_to_float::work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ const int32_t *in = (const int32_t *) input_items[0];
+ float *out = (float *) output_items[0];
+
+ if(is_unaligned()) {
+ volk_32i_s32f_convert_32f_u(out, in, d_scale, d_vlen*noutput_items);
+ }
+ else {
+ volk_32i_s32f_convert_32f_a(out, in, d_scale, d_vlen*noutput_items);
+ }
+
+ return noutput_items;
+}
+
+
+
diff --git a/gnuradio-core/src/lib/general/gr_int_to_float.h b/gnuradio-core/src/lib/general/gr_int_to_float.h
new file mode 100644
index 000000000..6200c5be7
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_int_to_float.h
@@ -0,0 +1,70 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2011,2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_INT_TO_FLOAT_H
+#define INCLUDED_GR_INT_TO_FLOAT_H
+
+#include <gr_core_api.h>
+#include <gr_sync_block.h>
+
+class gr_int_to_float;
+typedef boost::shared_ptr<gr_int_to_float> gr_int_to_float_sptr;
+
+GR_CORE_API gr_int_to_float_sptr
+gr_make_int_to_float (size_t vlen=1, float scale=1);
+
+/*!
+ * \brief Convert stream of int to a stream of float
+ * \ingroup converter_blk
+ *
+ * \param vlen vector length of data streams.
+ * \param scale a scalar divider to change the output signal scale.
+ */
+
+class GR_CORE_API gr_int_to_float : public gr_sync_block
+{
+ private:
+ friend GR_CORE_API gr_int_to_float_sptr
+ gr_make_int_to_float (size_t vlen, float scale);
+ gr_int_to_float (size_t vlen, float scale);
+
+ size_t d_vlen;
+ float d_scale;
+
+ public:
+ /*!
+ * Get the scalar divider value.
+ */
+ float scale() const;
+
+ /*!
+ * Set the scalar divider value.
+ */
+ void set_scale(float scale);
+
+ virtual int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+
+#endif /* INCLUDED_GR_INT_TO_FLOAT_H */
diff --git a/gnuradio-core/src/lib/general/gr_int_to_float.i b/gnuradio-core/src/lib/general/gr_int_to_float.i
new file mode 100644
index 000000000..f3781ac8a
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_int_to_float.i
@@ -0,0 +1,32 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2011,2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,int_to_float)
+
+gr_int_to_float_sptr
+gr_make_int_to_float (size_t vlen=1, float scale=1);
+
+class gr_int_to_float : public gr_sync_block
+{
+ float scale() const;
+ void set_scale(float scale);
+};
diff --git a/gnuradio-core/src/lib/general/gr_interleave.cc b/gnuradio-core/src/lib/general/gr_interleave.cc
new file mode 100644
index 000000000..5d572871e
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_interleave.cc
@@ -0,0 +1,77 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#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 gnuradio::get_initial_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
index 000000000..3b0202d00
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_interleave.h
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_INTERLEAVE_H
+#define INCLUDED_GR_INTERLEAVE_H
+
+#include <gr_core_api.h>
+#include <gr_sync_interpolator.h>
+
+class gr_interleave;
+typedef boost::shared_ptr<gr_interleave> gr_interleave_sptr;
+
+GR_CORE_API gr_interleave_sptr gr_make_interleave (size_t itemsize);
+
+/*!
+ * \brief interleave N inputs to a single output
+ * \ingroup slicedice_blk
+ */
+class GR_CORE_API gr_interleave : public gr_sync_interpolator
+{
+ friend GR_CORE_API 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
index 000000000..09a57c886
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_interleave.i
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,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
index 000000000..e7d375a35
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_interleaved_short_to_complex.cc
@@ -0,0 +1,59 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#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 gnuradio::get_initial_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
index 000000000..159d107b3
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_interleaved_short_to_complex.h
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_INTERLEAVED_SHORT_TO_COMPLEX_H
+#define INCLUDED_GR_INTERLEAVED_SHORT_TO_COMPLEX_H
+
+#include <gr_core_api.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_CORE_API 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_blk
+ */
+
+class GR_CORE_API gr_interleaved_short_to_complex : public gr_sync_decimator
+{
+ friend GR_CORE_API 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
index 000000000..797710550
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_interleaved_short_to_complex.i
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,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_iqcomp_cc.cc b/gnuradio-core/src/lib/general/gr_iqcomp_cc.cc
new file mode 100644
index 000000000..599b25b72
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_iqcomp_cc.cc
@@ -0,0 +1,62 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_iqcomp_cc.h>
+#include <gr_io_signature.h>
+
+gr_iqcomp_cc_sptr
+gr_make_iqcomp_cc (float mu)
+{
+ return gnuradio::get_initial_sptr(new gr_iqcomp_cc (mu));
+}
+
+gr_iqcomp_cc::gr_iqcomp_cc (float mu)
+ : gr_sync_block ("iqcomp_cc",
+ gr_make_io_signature (1, 1, sizeof (gr_complex)),
+ gr_make_io_signature (1, 1, sizeof (gr_complex))),
+ d_mu (mu)
+{
+ d_wi=0.0;
+ d_wq=0.0;
+}
+
+int
+gr_iqcomp_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];
+
+ for(int i = 0 ; i < noutput_items ; i++) {
+ float i_out = iptr[i].real() - iptr[i].imag() * d_wq;
+ float q_out = iptr[i].imag() - iptr[i].real() * d_wi;
+ d_wi += d_mu * q_out * iptr[i].real();
+ d_wq += d_mu * i_out * iptr[i].imag();
+ }
+ return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_iqcomp_cc.h b/gnuradio-core/src/lib/general/gr_iqcomp_cc.h
new file mode 100644
index 000000000..2f5a44ebf
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_iqcomp_cc.h
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+
+#ifndef INCLUDED_GR_IQCOMP_CC_H
+#define INCLUDED_GR_IQCOMP_CC_H
+
+#include <gr_core_api.h>
+#include <gr_sync_block.h>
+
+class gr_iqcomp_cc;
+typedef boost::shared_ptr<gr_iqcomp_cc> gr_iqcomp_cc_sptr;
+
+GR_CORE_API gr_iqcomp_cc_sptr gr_make_iqcomp_cc (float mu);
+
+/*!
+ * \brief
+ * \ingroup misc_blk
+ */
+class GR_CORE_API gr_iqcomp_cc : public gr_sync_block
+{
+ friend GR_CORE_API gr_iqcomp_cc_sptr gr_make_iqcomp_cc (float mu);
+
+ float d_mu, d_wi, d_wq;
+ gr_iqcomp_cc (float mu);
+
+ public:
+ float mu () const { return d_mu; }
+ void set_mu (float mu) { d_mu = mu; }
+
+ 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_iqcomp_cc.i b/gnuradio-core/src/lib/general/gr_iqcomp_cc.i
new file mode 100644
index 000000000..5cca59dd5
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_iqcomp_cc.i
@@ -0,0 +1,36 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+
+GR_SWIG_BLOCK_MAGIC(gr,iqcomp_cc)
+
+gr_iqcomp_cc_sptr gr_make_iqcomp_cc (float mu);
+
+class gr_iqcomp_cc : public gr_sync_block
+{
+ private:
+ gr_iqcomp_cc (float mu);
+
+ public:
+ float mu () const { return d_mu; }
+ void set_mu (float mu) { d_mu = mu; }
+};
diff --git a/gnuradio-core/src/lib/general/gr_keep_m_in_n.cc b/gnuradio-core/src/lib/general/gr_keep_m_in_n.cc
new file mode 100644
index 000000000..1becbfa11
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_keep_m_in_n.cc
@@ -0,0 +1,98 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_keep_m_in_n.h>
+#include <gr_io_signature.h>
+#include <string.h>
+#include <stdio.h>
+
+gr_keep_m_in_n_sptr
+gr_make_keep_m_in_n(size_t item_size, int m, int n, int offset)
+{
+ return gnuradio::get_initial_sptr(new gr_keep_m_in_n(item_size, m, n, offset));
+}
+
+
+/*
+*
+* offset = 0, starts with 0th item
+* offset = 1, starts with 1st item, etc...
+*
+* we take m items out of each n
+*/
+gr_keep_m_in_n::gr_keep_m_in_n(size_t item_size, int m, int n, int offset)
+ : gr_block("keep_m_in_n",
+ gr_make_io_signature(1, 1, item_size),
+ gr_make_io_signature(1, 1, item_size)),
+ d_n(n),
+ d_m(m),
+ d_offset(offset),
+ d_itemsize(item_size)
+{
+ // sanity checking
+ assert(d_m > 0);
+ assert(d_n > 0);
+ assert(d_m <= d_n);
+ assert(d_offset <= (d_n-d_m));
+
+ set_output_multiple(m);
+}
+
+
+void
+gr_keep_m_in_n::forecast(int noutput_items, gr_vector_int &ninput_items_required)
+{
+ ninput_items_required[0] = d_n*(noutput_items/d_m);
+}
+
+void
+gr_keep_m_in_n::set_offset(int offset)
+{
+ d_offset = offset;
+}
+
+int
+gr_keep_m_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)
+{
+ uint8_t* out = (uint8_t*)output_items[0];
+ const uint8_t* in = (const uint8_t*)input_items[0];
+
+ // iterate over data blocks of size {n, input : m, output}
+ int blks = std::min(noutput_items/d_m, ninput_items[0]/d_n);
+ for(int i=0; i<blks; i++) {
+ // set up copy pointers
+ const uint8_t* iptr = &in[(i*d_n + d_offset)*d_itemsize];
+ uint8_t* optr = &out[i*d_m*d_itemsize];
+ // perform copy
+ memcpy( optr, iptr, d_m*d_itemsize );
+ }
+
+ consume_each(d_n);
+ return d_m;
+}
diff --git a/gnuradio-core/src/lib/general/gr_keep_m_in_n.h b/gnuradio-core/src/lib/general/gr_keep_m_in_n.h
new file mode 100644
index 000000000..c6bf40ecf
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_keep_m_in_n.h
@@ -0,0 +1,67 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_KEEP_M_IN_N_H
+#define INCLUDED_GR_KEEP_M_IN_N_H
+
+#include <gr_core_api.h>
+#include <gr_block.h>
+
+class gr_keep_m_in_n;
+typedef boost::shared_ptr<gr_keep_m_in_n> gr_keep_m_in_n_sptr;
+
+GR_CORE_API gr_keep_m_in_n_sptr
+gr_make_keep_m_in_n (size_t item_size, int m, int n, int offset);
+
+
+/*!
+ * \brief decimate a stream, keeping one item out of every n.
+ * \ingroup slicedice_blk
+ */
+class GR_CORE_API gr_keep_m_in_n : public gr_block
+{
+ friend GR_CORE_API gr_keep_m_in_n_sptr
+ gr_make_keep_m_in_n (size_t item_size, int m, int n, int offset);
+
+ int d_n;
+ int d_m;
+ int d_count;
+ int d_offset;
+ int d_itemsize;
+
+ protected:
+ gr_keep_m_in_n (size_t item_size, int m, int n, int offset);
+ void forecast (int noutput_items, gr_vector_int &ninput_items_required);
+
+ 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_offset(int offset);
+ void set_n(int n){ d_n = n; }
+ void set_m(int m){ d_m = m; }
+
+};
+
+#endif /* INCLUDED_GR_KEEP_M_IN_N_H */
diff --git a/gnuradio-core/src/lib/general/gr_keep_m_in_n.i b/gnuradio-core/src/lib/general/gr_keep_m_in_n.i
new file mode 100644
index 000000000..f280c0248
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_keep_m_in_n.i
@@ -0,0 +1,35 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,keep_m_in_n)
+
+gr_keep_m_in_n_sptr
+gr_make_keep_m_in_n (size_t itemsize, int m, int n, int offset);
+
+class gr_keep_m_in_n : public gr_sync_block
+{
+ protected:
+ gr_keep_m_in_n (size_t itemsize, int m, int n, int offset);
+ public:
+ void set_offset(int offset);
+
+};
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
index 000000000..fbba9e91c
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_keep_one_in_n.cc
@@ -0,0 +1,105 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_keep_one_in_n.h>
+#include <gr_io_signature.h>
+#include <string.h>
+
+gr_keep_one_in_n_sptr
+gr_make_keep_one_in_n (size_t item_size, int n)
+{
+ return gnuradio::get_initial_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_count(n)
+{
+ // To avoid bad behavior with using set_relative_rate in this block with
+ // VERY large values of n, we will keep track of things ourselves. Using
+ // this to turn off automatic tag propagation, which will be handled
+ // locally in general_work().
+ set_tag_propagation_policy(TPP_DONT);
+
+ set_n(n);
+}
+
+void
+gr_keep_one_in_n::set_n(int n)
+{
+ if (n < 1)
+ n = 1;
+
+ d_n = n;
+ d_count = n;
+
+ // keep our internal understanding of the relative rate of this block
+ // don't set the relative rate, though, and we will handle our own
+ // tag propagation.
+ d_decim_rate = 1.0/(float)d_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++;
+ }
+
+ // Because we have set TPP_DONT, we have to propagate the tags here manually.
+ // Adjustment of the tag sample value is done using the float d_decim_rate.
+ std::vector<gr_tag_t> tags;
+ std::vector<gr_tag_t>::iterator t;
+ get_tags_in_range(tags, 0, nitems_read(0), nitems_read(0)+ni);
+ for(t = tags.begin(); t != tags.end(); t++) {
+ gr_tag_t new_tag = *t;
+ new_tag.offset *= d_decim_rate;
+ add_item_tag(0, new_tag);
+ }
+
+ 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
index 000000000..f37475204
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_keep_one_in_n.h
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_KEEP_ONE_IN_N_H
+#define INCLUDED_GR_KEEP_ONE_IN_N_H
+
+#include <gr_core_api.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_CORE_API 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 slicedice_blk
+ */
+class GR_CORE_API gr_keep_one_in_n : public gr_block
+{
+ friend GR_CORE_API gr_keep_one_in_n_sptr
+ gr_make_keep_one_in_n (size_t item_size, int n);
+
+ int d_n;
+ int d_count;
+ float d_decim_rate;
+
+ 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
index 000000000..534098cde
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_keep_one_in_n.i
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,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
index 000000000..f6a8d8af6
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_kludge_copy.cc
@@ -0,0 +1,64 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#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 gnuradio::get_initial_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, itemsize),
+ gr_make_io_signature (1, -1, itemsize)),
+ 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
index 000000000..0bcf14469
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_kludge_copy.h
@@ -0,0 +1,56 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_KLUDGE_COPY_H
+#define INCLUDED_GR_KLUDGE_COPY_H
+
+#include <gr_core_api.h>
+#include <gr_sync_block.h>
+
+class gr_kludge_copy;
+typedef boost::shared_ptr<gr_kludge_copy> gr_kludge_copy_sptr;
+
+GR_CORE_API gr_kludge_copy_sptr gr_make_kludge_copy(size_t itemsize);
+
+/*!
+ * \brief output[i] = input[i]
+ * \ingroup misc_blk
+ *
+ * This is a short term kludge to work around a problem with the hierarchical block impl.
+ */
+class GR_CORE_API gr_kludge_copy : public gr_sync_block
+{
+ size_t d_itemsize;
+
+ friend GR_CORE_API 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
index 000000000..7ff2b5736
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_kludge_copy.i
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,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
index 000000000..c9a874248
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_lfsr_32k_source_s.cc
@@ -0,0 +1,70 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+
+#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 gnuradio::get_initial_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
index 000000000..db107652a
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_lfsr_32k_source_s.h
@@ -0,0 +1,61 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_LFSR_32K_SOURCE_S_H
+#define INCLUDED_GR_LFSR_32K_SOURCE_S_H
+
+#include <gr_core_api.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_CORE_API 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_blk
+ *
+ * This source is typically used along with gr_check_lfsr_32k_s to test
+ * the USRP using its digital loopback mode.
+ */
+class GR_CORE_API gr_lfsr_32k_source_s : public gr_sync_block
+{
+ friend GR_CORE_API 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
index 000000000..c2dc1c61b
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_lfsr_32k_source_s.i
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,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_log2_const.h b/gnuradio-core/src/lib/general/gr_log2_const.h
new file mode 100644
index 000000000..40afcf8b8
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_log2_const.h
@@ -0,0 +1,47 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+
+/*
+ * a bit of template hackery...
+ */
+#ifndef INCLUDED_GR_LOG2_CONST_H
+#define INCLUDED_GR_LOG2_CONST_H
+
+#include <gr_core_api.h>
+#include <assert.h>
+
+template<unsigned int k> static inline int gr_log2_const() { assert(0); return 0; }
+
+template<> inline int gr_log2_const<1>() { return 0; }
+template<> inline int gr_log2_const<2>() { return 1; }
+template<> inline int gr_log2_const<4>() { return 2; }
+template<> inline int gr_log2_const<8>() { return 3; }
+template<> inline int gr_log2_const<16>() { return 4; }
+template<> inline int gr_log2_const<32>() { return 5; }
+template<> inline int gr_log2_const<64>() { return 6; }
+template<> inline int gr_log2_const<128>() { return 7; }
+template<> inline int gr_log2_const<256>() { return 8; }
+template<> inline int gr_log2_const<512>() { return 9; }
+template<> 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
index 000000000..7deb8971a
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_map_bb.cc
@@ -0,0 +1,61 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006,2007,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_map_bb.h>
+#include <gr_io_signature.h>
+
+gr_map_bb_sptr
+gr_make_map_bb (const std::vector<int> &map)
+{
+ return gnuradio::get_initial_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::min((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
index 000000000..0a2f5a45f
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_map_bb.h
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifndef INCLUDED_GR_MAP_BB_H
+#define INCLUDED_GR_MAP_BB_H
+
+#include <gr_core_api.h>
+#include <gr_sync_block.h>
+
+class gr_map_bb;
+typedef boost::shared_ptr<gr_map_bb> gr_map_bb_sptr;
+
+GR_CORE_API gr_map_bb_sptr gr_make_map_bb(const std::vector<int> &map);
+
+/*!
+ * \brief output[i] = map[input[i]]
+ * \ingroup coding_blk
+ */
+
+class GR_CORE_API gr_map_bb : public gr_sync_block
+{
+ friend GR_CORE_API 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
index 000000000..9c8bff644
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_map_bb.i
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,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.h b/gnuradio-core/src/lib/general/gr_math.h
new file mode 100644
index 000000000..b9a802da8
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_math.h
@@ -0,0 +1,209 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003,2005,2008 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+/*
+ * mathematical odds and ends.
+ */
+
+#ifndef _GR_MATH_H_
+#define _GR_MATH_H_
+
+#include <gr_core_api.h>
+#include <gr_complex.h>
+
+static inline bool
+gr_is_power_of_2(long x)
+{
+ return x != 0 && (x & (x-1)) == 0;
+}
+
+/*!
+ * \brief Fast arc tangent using table lookup and linear interpolation
+ * \ingroup misc
+ *
+ * \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.
+ */
+GR_CORE_API float gr_fast_atan2f(float y, float x);
+
+static inline float gr_fast_atan2f(gr_complex z)
+{
+ return gr_fast_atan2f(z.imag(), z.real());
+}
+
+/* This bounds x by +/- clip without a branch */
+static inline float gr_branchless_clip(float x, float clip)
+{
+ float x1 = fabsf(x+clip);
+ float x2 = fabsf(x-clip);
+ x1 -= x2;
+ return 0.5*x1;
+}
+
+static inline float gr_clip(float x, float clip)
+{
+ float y = x;
+ if(x > clip)
+ y = clip;
+ else if(x < -clip)
+ y = -clip;
+ return y;
+}
+
+// Slicer Functions
+static inline unsigned int gr_binary_slicer(float x)
+{
+ if(x >= 0)
+ return 1;
+ else
+ return 0;
+}
+
+static inline unsigned int gr_quad_45deg_slicer(float r, float i)
+{
+ unsigned int ret = 0;
+ if((r >= 0) && (i >= 0))
+ ret = 0;
+ else if((r < 0) && (i >= 0))
+ ret = 1;
+ else if((r < 0) && (i < 0))
+ ret = 2;
+ else
+ ret = 3;
+ return ret;
+}
+
+static inline unsigned int gr_quad_0deg_slicer(float r, float i)
+{
+ unsigned int ret = 0;
+ if(fabsf(r) > fabsf(i)) {
+ if(r > 0)
+ ret = 0;
+ else
+ ret = 2;
+ }
+ else {
+ if(i > 0)
+ ret = 1;
+ else
+ ret = 3;
+ }
+
+ return ret;
+}
+
+static inline unsigned int gr_quad_45deg_slicer(gr_complex x)
+{
+ return gr_quad_45deg_slicer(x.real(), x.imag());
+}
+
+static inline unsigned int gr_quad_0deg_slicer(gr_complex x)
+{
+ return gr_quad_0deg_slicer(x.real(), x.imag());
+}
+
+// Branchless Slicer Functions
+static inline unsigned int gr_branchless_binary_slicer(float x)
+{
+ return (x >= 0);
+}
+
+static inline unsigned int gr_branchless_quad_0deg_slicer(float r, float i)
+{
+ unsigned int ret = 0;
+ ret = (fabsf(r) > fabsf(i)) * (((r < 0) << 0x1)); // either 0 (00) or 2 (10)
+ ret |= (fabsf(i) > fabsf(r)) * (((i < 0) << 0x1) | 0x1); // either 1 (01) or 3 (11)
+
+ return ret;
+}
+
+static inline unsigned int gr_branchless_quad_0deg_slicer(gr_complex x)
+{
+ return gr_branchless_quad_0deg_slicer(x.real(), x.imag());
+}
+
+static inline unsigned int gr_branchless_quad_45deg_slicer(float r, float i)
+{
+ char ret = (r <= 0);
+ ret |= ((i <= 0) << 1);
+ return (ret ^ ((ret & 0x2) >> 0x1));
+}
+
+static inline unsigned int gr_branchless_quad_45deg_slicer(gr_complex x)
+{
+ return gr_branchless_quad_45deg_slicer(x.real(), x.imag());
+}
+
+/*!
+ * \param x any value
+ * \param pow2 must be a power of 2
+ * \returns \p x rounded down to a multiple of \p pow2.
+ */
+static inline size_t
+gr_p2_round_down(size_t x, size_t pow2)
+{
+ return x & -pow2;
+}
+
+/*!
+ * \param x any value
+ * \param pow2 must be a power of 2
+ * \returns \p x rounded up to a multiple of \p pow2.
+ */
+static inline size_t
+gr_p2_round_up(size_t x, size_t pow2)
+{
+ return gr_p2_round_down(x + pow2 - 1, pow2);
+}
+
+/*!
+ * \param x any value
+ * \param pow2 must be a power of 2
+ * \returns \p x modulo \p pow2.
+ */
+static inline size_t
+gr_p2_modulo(size_t x, size_t pow2)
+{
+ return x & (pow2 - 1);
+}
+
+/*!
+ * \param x any value
+ * \param pow2 must be a power of 2
+ * \returns \p pow2 - (\p x modulo \p pow2).
+ */
+static inline size_t
+gr_p2_modulo_neg(size_t x, size_t pow2)
+{
+ return pow2 - gr_p2_modulo(x, pow2);
+}
+
+#endif /* _GR_MATH_H_ */
diff --git a/gnuradio-core/src/lib/general/gr_message_strobe.cc b/gnuradio-core/src/lib/general/gr_message_strobe.cc
new file mode 100644
index 000000000..6a9f807d1
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_message_strobe.cc
@@ -0,0 +1,75 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_message_strobe.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 <string.h>
+#include <iostream>
+
+// public constructor that returns a shared_ptr
+
+gr_message_strobe_sptr
+gr_make_message_strobe (pmt::pmt_t msg, float period_ms)
+{
+ return gnuradio::get_initial_sptr(new gr_message_strobe(msg, period_ms));
+}
+
+gr_message_strobe::gr_message_strobe (pmt::pmt_t msg, float period_ms)
+ : gr_block("message_strobe",
+ gr_make_io_signature(0, 0, 0),
+ gr_make_io_signature(0, 0, 0)),
+ d_finished(false),
+ d_period_ms(period_ms),
+ d_msg(msg)
+{
+ message_port_register_out(pmt::mp("strobe"));
+ d_thread = boost::shared_ptr<boost::thread>(new boost::thread(boost::bind(&gr_message_strobe::run, this)));
+
+ message_port_register_in(pmt::mp("set_msg"));
+ set_msg_handler(pmt::mp("set_msg"), boost::bind(&gr_message_strobe::set_msg, this, _1));
+}
+
+gr_message_strobe::~gr_message_strobe()
+{
+ d_finished = true;
+ d_thread->interrupt();
+ d_thread->join();
+}
+
+void gr_message_strobe::run(){
+ while(!d_finished) {
+ boost::this_thread::sleep(boost::posix_time::milliseconds(d_period_ms));
+ if(d_finished){ return; }
+
+ message_port_pub( pmt::mp("strobe"), d_msg );
+ }
+}
diff --git a/gnuradio-core/src/lib/general/gr_message_strobe.h b/gnuradio-core/src/lib/general/gr_message_strobe.h
new file mode 100644
index 000000000..89046ffc0
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_message_strobe.h
@@ -0,0 +1,62 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_MESSAGE_STROBE_H
+#define INCLUDED_GR_MESSAGE_STROBE_H
+
+#include <gr_core_api.h>
+#include <gr_block.h>
+#include <gr_message.h>
+#include <gr_msg_queue.h>
+
+class gr_message_strobe;
+typedef boost::shared_ptr<gr_message_strobe> gr_message_strobe_sptr;
+
+GR_CORE_API gr_message_strobe_sptr gr_make_message_strobe (pmt::pmt_t msg, float period_ms);
+
+/*!
+ * \brief Send message at defined interval
+ * \ingroup msg_blk
+ */
+class GR_CORE_API gr_message_strobe : public gr_block
+{
+ private:
+ friend GR_CORE_API gr_message_strobe_sptr
+ gr_make_message_strobe(pmt::pmt_t msg, float period_ms);
+
+ boost::shared_ptr<boost::thread> d_thread;
+ bool d_finished;
+ float d_period_ms;
+ pmt::pmt_t d_msg;
+
+ void run();
+
+ protected:
+ gr_message_strobe (pmt::pmt_t msg, float period_ms);
+
+ public:
+ ~gr_message_strobe ();
+
+ void set_msg(pmt::pmt_t msg){ d_msg = msg; }
+};
+
+#endif /* INCLUDED_GR_MESSAGE_STROBE_H */
diff --git a/gnuradio-core/src/lib/general/gr_message_strobe.i b/gnuradio-core/src/lib/general/gr_message_strobe.i
new file mode 100644
index 000000000..490aa8e8a
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_message_strobe.i
@@ -0,0 +1,30 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,message_strobe);
+
+%{
+#include <gr_message_strobe.h>
+%}
+
+%include "gr_message_strobe.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
index 000000000..1ed2a03d7
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_misc.cc
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include <gr_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
index 000000000..0c790e90c
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_misc.h
@@ -0,0 +1,39 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_MISC_H
+#define INCLUDED_GR_MISC_H
+
+#include <gr_core_api.h>
+#include <gr_types.h>
+
+GR_CORE_API unsigned int
+gr_rounduppow2(unsigned int n);
+
+// FIXME should be template
+GR_CORE_API void gr_zero_vector(std::vector<float> &v);
+GR_CORE_API void gr_zero_vector(std::vector<double> &v);
+GR_CORE_API void gr_zero_vector(std::vector<int> &v);
+GR_CORE_API void gr_zero_vector(std::vector<gr_complex> &v);
+
+
+#endif /* INCLUDED_GR_MISC_H */
diff --git a/gnuradio-core/src/lib/general/gr_multiply_cc.cc b/gnuradio-core/src/lib/general/gr_multiply_cc.cc
new file mode 100644
index 000000000..4a3751419
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_multiply_cc.cc
@@ -0,0 +1,69 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_multiply_cc.h>
+#include <gr_io_signature.h>
+#include <volk/volk.h>
+
+gr_multiply_cc_sptr
+gr_make_multiply_cc (size_t vlen)
+{
+ return gnuradio::get_initial_sptr(new gr_multiply_cc (vlen));
+}
+
+gr_multiply_cc::gr_multiply_cc (size_t vlen)
+ : gr_sync_block ("gr_multiply_cc",
+ gr_make_io_signature (1, -1, sizeof (gr_complex)*vlen),
+ gr_make_io_signature (1, 1, sizeof (gr_complex)*vlen)),
+ d_vlen(vlen)
+{
+ const int alignment_multiple =
+ volk_get_alignment() / sizeof(gr_complex);
+ set_alignment(std::max(1,alignment_multiple));
+}
+
+int
+gr_multiply_cc::work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ gr_complex *out = (gr_complex *) output_items[0];
+ int noi = d_vlen*noutput_items;
+
+ memcpy(out, input_items[0], noi*sizeof(gr_complex));
+ if(is_unaligned()) {
+ for(size_t i = 1; i < input_items.size(); i++)
+ volk_32fc_x2_multiply_32fc_u(out, out, (gr_complex*)input_items[i], noi);
+ }
+ else {
+ for(size_t i = 1; i < input_items.size(); i++)
+ volk_32fc_x2_multiply_32fc_a(out, out, (gr_complex*)input_items[i], noi);
+ }
+ return noutput_items;
+}
+
+
+
diff --git a/gnuradio-core/src/lib/general/gr_multiply_cc.h b/gnuradio-core/src/lib/general/gr_multiply_cc.h
new file mode 100644
index 000000000..d25935b4c
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_multiply_cc.h
@@ -0,0 +1,56 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_MULTIPLY_CC_H
+#define INCLUDED_GR_MULTIPLY_CC_H
+
+#include <gr_core_api.h>
+#include <gr_sync_block.h>
+
+class gr_multiply_cc;
+typedef boost::shared_ptr<gr_multiply_cc> gr_multiply_cc_sptr;
+
+GR_CORE_API gr_multiply_cc_sptr
+gr_make_multiply_cc (size_t vlen=1);
+
+/*!
+ * \brief Multiply streams of complex values
+ * \ingroup math_blk
+ */
+
+class GR_CORE_API gr_multiply_cc : public gr_sync_block
+{
+ private:
+ friend GR_CORE_API gr_multiply_cc_sptr
+ gr_make_multiply_cc (size_t vlen);
+ gr_multiply_cc (size_t vlen);
+
+ size_t 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_MULTIPLY_CC_H */
diff --git a/gnuradio-core/src/lib/general/gr_multiply_cc.i b/gnuradio-core/src/lib/general/gr_multiply_cc.i
new file mode 100644
index 000000000..f0faa3594
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_multiply_cc.i
@@ -0,0 +1,32 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,multiply_cc)
+
+gr_multiply_cc_sptr
+gr_make_multiply_cc (size_t vlen=1);
+
+class gr_multiply_cc : public gr_sync_block
+{
+public:
+
+};
diff --git a/gnuradio-core/src/lib/general/gr_multiply_conjugate_cc.cc b/gnuradio-core/src/lib/general/gr_multiply_conjugate_cc.cc
new file mode 100644
index 000000000..0c5fb4a92
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_multiply_conjugate_cc.cc
@@ -0,0 +1,69 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_multiply_conjugate_cc.h>
+#include <gr_io_signature.h>
+#include <volk/volk.h>
+
+gr_multiply_conjugate_cc_sptr
+gr_make_multiply_conjugate_cc (size_t vlen)
+{
+ return gnuradio::get_initial_sptr(new gr_multiply_conjugate_cc (vlen));
+}
+
+gr_multiply_conjugate_cc::gr_multiply_conjugate_cc (size_t vlen)
+ : gr_sync_block ("gr_multiply_conjugate_cc",
+ gr_make_io_signature (2, 2, sizeof (gr_complex)*vlen),
+ gr_make_io_signature (1, 1, sizeof (gr_complex)*vlen)),
+ d_vlen(vlen)
+{
+ const int alignment_multiple =
+ volk_get_alignment() / sizeof(gr_complex);
+ set_alignment(std::max(1,alignment_multiple));
+}
+
+int
+gr_multiply_conjugate_cc::work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ gr_complex *in0 = (gr_complex *) input_items[0];
+ gr_complex *in1 = (gr_complex *) input_items[1];
+ gr_complex *out = (gr_complex *) output_items[0];
+ int noi = d_vlen*noutput_items;
+
+ if(is_unaligned()) {
+ volk_32fc_x2_multiply_conjugate_32fc_u(out, in0, in1, noi);
+ }
+ else {
+ volk_32fc_x2_multiply_conjugate_32fc_a(out, in0, in1, noi);
+ }
+
+ return noutput_items;
+}
+
+
+
diff --git a/gnuradio-core/src/lib/general/gr_multiply_conjugate_cc.h b/gnuradio-core/src/lib/general/gr_multiply_conjugate_cc.h
new file mode 100644
index 000000000..826e28771
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_multiply_conjugate_cc.h
@@ -0,0 +1,57 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_MULTIPLY_CONJUGATE_CC_H
+#define INCLUDED_GR_MULTIPLY_CONJUGATE_CC_H
+
+#include <gr_core_api.h>
+#include <gr_sync_block.h>
+
+class gr_multiply_conjugate_cc;
+typedef boost::shared_ptr<gr_multiply_conjugate_cc>
+gr_multiply_conjugate_cc_sptr;
+
+GR_CORE_API gr_multiply_conjugate_cc_sptr
+gr_make_multiply_conjugate_cc (size_t vlen=1);
+
+/*!
+ * \brief Multiplies a stream by the conjugate of the second stream
+ * \ingroup math_blk
+ */
+
+class GR_CORE_API gr_multiply_conjugate_cc : public gr_sync_block
+{
+ private:
+ friend GR_CORE_API gr_multiply_conjugate_cc_sptr
+ gr_make_multiply_conjugate_cc (size_t vlen);
+ gr_multiply_conjugate_cc (size_t vlen);
+
+ size_t 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_MULTIPLY_CONJUGATE_CC_H */
diff --git a/gnuradio-core/src/lib/general/gr_multiply_conjugate_cc.i b/gnuradio-core/src/lib/general/gr_multiply_conjugate_cc.i
new file mode 100644
index 000000000..e7979dbcd
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_multiply_conjugate_cc.i
@@ -0,0 +1,32 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,multiply_conjugate_cc)
+
+gr_multiply_conjugate_cc_sptr
+gr_make_multiply_conjugate_cc (size_t vlen=1);
+
+class gr_multiply_conjugate_cc : public gr_sync_block
+{
+public:
+
+};
diff --git a/gnuradio-core/src/lib/general/gr_multiply_const_cc.cc b/gnuradio-core/src/lib/general/gr_multiply_const_cc.cc
new file mode 100644
index 000000000..bd4511937
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_multiply_const_cc.cc
@@ -0,0 +1,80 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_multiply_const_cc.h>
+#include <gr_io_signature.h>
+#include <volk/volk.h>
+
+gr_multiply_const_cc_sptr
+gr_make_multiply_const_cc (gr_complex k, size_t vlen)
+{
+ return gnuradio::get_initial_sptr(new gr_multiply_const_cc (k, vlen));
+}
+
+gr_multiply_const_cc::gr_multiply_const_cc (gr_complex k, size_t vlen)
+ : gr_sync_block ("gr_multiply_const_cc",
+ gr_make_io_signature (1, 1, sizeof (gr_complex)*vlen),
+ gr_make_io_signature (1, 1, sizeof (gr_complex)*vlen)),
+ d_k(k), d_vlen(vlen)
+{
+ const int alignment_multiple =
+ volk_get_alignment() / sizeof(gr_complex);
+ set_alignment(std::max(1,alignment_multiple));
+}
+
+gr_complex
+gr_multiply_const_cc::k() const
+{
+ return d_k;
+}
+
+void
+gr_multiply_const_cc::set_k(gr_complex k)
+{
+ d_k = k;
+}
+
+int
+gr_multiply_const_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];
+ int noi = d_vlen*noutput_items;
+
+ if(is_unaligned()) {
+ volk_32fc_s32fc_multiply_32fc_u(out, in, d_k, noi);
+ }
+ else {
+ volk_32fc_s32fc_multiply_32fc_a(out, in, d_k, noi);
+ }
+
+ return noutput_items;
+}
+
+
+
diff --git a/gnuradio-core/src/lib/general/gr_multiply_const_cc.h b/gnuradio-core/src/lib/general/gr_multiply_const_cc.h
new file mode 100644
index 000000000..97962abc7
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_multiply_const_cc.h
@@ -0,0 +1,60 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_MULTIPLY_CONST_CC_H
+#define INCLUDED_GR_MULTIPLY_CONST_CC_H
+
+#include <gr_core_api.h>
+#include <gr_sync_block.h>
+
+class gr_multiply_const_cc;
+typedef boost::shared_ptr<gr_multiply_const_cc> gr_multiply_const_cc_sptr;
+
+GR_CORE_API gr_multiply_const_cc_sptr
+gr_make_multiply_const_cc (gr_complex k, size_t vlen=1);
+
+/*!
+ * \brief Multiply stream of complex values with a constant \p k
+ * \ingroup math_blk
+ */
+
+class GR_CORE_API gr_multiply_const_cc : public gr_sync_block
+{
+ private:
+ friend GR_CORE_API gr_multiply_const_cc_sptr
+ gr_make_multiply_const_cc (gr_complex k, size_t vlen);
+ gr_multiply_const_cc (gr_complex k, size_t vlen);
+
+ gr_complex d_k;
+ size_t d_vlen;
+
+ public:
+ gr_complex k() const;
+ void set_k(gr_complex k);
+
+ virtual int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+
+#endif /* INCLUDED_GR_MULTIPLY_CONST_CC_H */
diff --git a/gnuradio-core/src/lib/general/gr_multiply_const_cc.i b/gnuradio-core/src/lib/general/gr_multiply_const_cc.i
new file mode 100644
index 000000000..c2f3cbed3
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_multiply_const_cc.i
@@ -0,0 +1,33 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,multiply_const_cc)
+
+gr_multiply_const_cc_sptr
+gr_make_multiply_const_cc (gr_complex k, size_t vlen=1);
+
+class gr_multiply_const_cc : public gr_sync_block
+{
+public:
+ gr_complex k() const;
+ void set_k(gr_complex k);
+};
diff --git a/gnuradio-core/src/lib/general/gr_multiply_const_ff.cc b/gnuradio-core/src/lib/general/gr_multiply_const_ff.cc
new file mode 100644
index 000000000..16ba39df9
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_multiply_const_ff.cc
@@ -0,0 +1,80 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_multiply_const_ff.h>
+#include <gr_io_signature.h>
+#include <volk/volk.h>
+
+gr_multiply_const_ff_sptr
+gr_make_multiply_const_ff (float k, size_t vlen)
+{
+ return gnuradio::get_initial_sptr(new gr_multiply_const_ff (k, vlen));
+}
+
+gr_multiply_const_ff::gr_multiply_const_ff (float k, size_t vlen)
+ : gr_sync_block ("gr_multiply_const_ff",
+ gr_make_io_signature (1, 1, sizeof (float)*vlen),
+ gr_make_io_signature (1, 1, sizeof (float)*vlen)),
+ d_k(k), d_vlen(vlen)
+{
+ const int alignment_multiple =
+ volk_get_alignment() / sizeof(float);
+ set_alignment(std::max(1,alignment_multiple));
+}
+
+float
+gr_multiply_const_ff::k() const
+{
+ return d_k;
+}
+
+void
+gr_multiply_const_ff::set_k(float k)
+{
+ d_k = k;
+}
+
+int
+gr_multiply_const_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 = d_vlen*noutput_items;
+
+ if(is_unaligned()) {
+ volk_32f_s32f_multiply_32f_u(out, in, d_k, noi);
+ }
+ else {
+ volk_32f_s32f_multiply_32f_a(out, in, d_k, noi);
+ }
+
+ return noutput_items;
+}
+
+
+
diff --git a/gnuradio-core/src/lib/general/gr_multiply_const_ff.h b/gnuradio-core/src/lib/general/gr_multiply_const_ff.h
new file mode 100644
index 000000000..fac73f88a
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_multiply_const_ff.h
@@ -0,0 +1,60 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_MULTIPLY_CONST_FF_H
+#define INCLUDED_GR_MULTIPLY_CONST_FF_H
+
+#include <gr_core_api.h>
+#include <gr_sync_block.h>
+
+class gr_multiply_const_ff;
+typedef boost::shared_ptr<gr_multiply_const_ff> gr_multiply_const_ff_sptr;
+
+GR_CORE_API gr_multiply_const_ff_sptr
+gr_make_multiply_const_ff (float k, size_t vlen=1);
+
+/*!
+ * \brief Multiply stream of float values with a constant \p k
+ * \ingroup math_blk
+ */
+
+class GR_CORE_API gr_multiply_const_ff : public gr_sync_block
+{
+ private:
+ friend GR_CORE_API gr_multiply_const_ff_sptr
+ gr_make_multiply_const_ff (float k, size_t vlen);
+ gr_multiply_const_ff (float k, size_t vlen);
+
+ float d_k;
+ size_t d_vlen;
+
+ public:
+ float k() const;
+ void set_k(float k);
+
+ virtual int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+
+#endif /* INCLUDED_GR_MULTIPLY_CONST_FF_H */
diff --git a/gnuradio-core/src/lib/general/gr_multiply_const_ff.i b/gnuradio-core/src/lib/general/gr_multiply_const_ff.i
new file mode 100644
index 000000000..343f67cd2
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_multiply_const_ff.i
@@ -0,0 +1,33 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,multiply_const_ff)
+
+gr_multiply_const_ff_sptr
+gr_make_multiply_const_ff (float k, size_t vlen=1);
+
+class gr_multiply_const_ff : public gr_sync_block
+{
+public:
+ float k() const;
+ void set_k(float k);
+};
diff --git a/gnuradio-core/src/lib/general/gr_multiply_ff.cc b/gnuradio-core/src/lib/general/gr_multiply_ff.cc
new file mode 100644
index 000000000..bb7bd0755
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_multiply_ff.cc
@@ -0,0 +1,69 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_multiply_ff.h>
+#include <gr_io_signature.h>
+#include <volk/volk.h>
+
+gr_multiply_ff_sptr
+gr_make_multiply_ff (size_t vlen)
+{
+ return gnuradio::get_initial_sptr(new gr_multiply_ff (vlen));
+}
+
+gr_multiply_ff::gr_multiply_ff (size_t vlen)
+ : gr_sync_block ("gr_multiply_ff",
+ gr_make_io_signature (1, -1, sizeof (float)*vlen),
+ gr_make_io_signature (1, 1, sizeof (float)*vlen)),
+ d_vlen(vlen)
+{
+ const int alignment_multiple =
+ volk_get_alignment() / sizeof(float);
+ set_alignment(std::max(1,alignment_multiple));
+}
+
+int
+gr_multiply_ff::work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ float *out = (float *) output_items[0];
+ int noi = d_vlen*noutput_items;
+
+ memcpy(out, input_items[0], noi*sizeof(float));
+ if(is_unaligned()) {
+ for(size_t i = 1; i < input_items.size(); i++)
+ volk_32f_x2_multiply_32f_u(out, out, (const float*)input_items[i], noi);
+ }
+ else {
+ for(size_t i = 1; i < input_items.size(); i++)
+ volk_32f_x2_multiply_32f_a(out, out, (const float*)input_items[i], noi);
+ }
+ return noutput_items;
+}
+
+
+
diff --git a/gnuradio-core/src/lib/general/gr_multiply_ff.h b/gnuradio-core/src/lib/general/gr_multiply_ff.h
new file mode 100644
index 000000000..ed628385c
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_multiply_ff.h
@@ -0,0 +1,56 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_MULTIPLY_FF_H
+#define INCLUDED_GR_MULTIPLY_FF_H
+
+#include <gr_core_api.h>
+#include <gr_sync_block.h>
+
+class gr_multiply_ff;
+typedef boost::shared_ptr<gr_multiply_ff> gr_multiply_ff_sptr;
+
+GR_CORE_API gr_multiply_ff_sptr
+gr_make_multiply_ff (size_t vlen=1);
+
+/*!
+ * \brief Multiply streams of complex values
+ * \ingroup math_blk
+ */
+
+class GR_CORE_API gr_multiply_ff : public gr_sync_block
+{
+ private:
+ friend GR_CORE_API gr_multiply_ff_sptr
+ gr_make_multiply_ff (size_t vlen);
+ gr_multiply_ff (size_t vlen);
+
+ size_t 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_MULTIPLY_FF_H */
diff --git a/gnuradio-core/src/lib/general/gr_multiply_ff.i b/gnuradio-core/src/lib/general/gr_multiply_ff.i
new file mode 100644
index 000000000..e5fdea348
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_multiply_ff.i
@@ -0,0 +1,32 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,multiply_ff)
+
+gr_multiply_ff_sptr
+gr_make_multiply_ff (size_t vlen=1);
+
+class gr_multiply_ff : public gr_sync_block
+{
+public:
+
+};
diff --git a/gnuradio-core/src/lib/general/gr_nco.h b/gnuradio-core/src/lib/general/gr_nco.h
new file mode 100644
index 000000000..fb51106aa
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_nco.h
@@ -0,0 +1,198 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifndef _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)
+ * \ingroup misc
+ */
+
+
+//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
index 000000000..24cfe25fb
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_nlog10_ff.cc
@@ -0,0 +1,64 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_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 gnuradio::get_initial_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
index 000000000..cfeba3fee
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_nlog10_ff.h
@@ -0,0 +1,56 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifndef INCLUDED_GR_NLOG10_FF_H
+#define INCLUDED_GR_NLOG10_FF_H
+
+#include <gr_core_api.h>
+#include <gr_sync_block.h>
+
+class gr_nlog10_ff;
+typedef boost::shared_ptr<gr_nlog10_ff> gr_nlog10_ff_sptr;
+
+GR_CORE_API 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 math_blk
+ */
+class GR_CORE_API gr_nlog10_ff : public gr_sync_block
+{
+ friend GR_CORE_API 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
index 000000000..73da59793
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_nlog10_ff.i
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,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_nop.cc b/gnuradio-core/src/lib/general/gr_nop.cc
new file mode 100644
index 000000000..edfe1d76d
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_nop.cc
@@ -0,0 +1,66 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <gr_nop.h>
+#include <gr_io_signature.h>
+#include <boost/bind.hpp>
+
+gr_nop_sptr
+gr_make_nop (size_t sizeof_stream_item)
+{
+ return gnuradio::get_initial_sptr (new gr_nop (sizeof_stream_item));
+}
+
+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)),
+ d_nmsgs_recvd(0)
+{
+ // Arrange to have count_received_msgs called when messages are received.
+ message_port_register_in(pmt::mp("port"));
+ set_msg_handler(pmt::mp("port"), boost::bind(&gr_nop::count_received_msgs, this, _1));
+}
+
+// Trivial message handler that just counts them.
+// (N.B., This feature is used in qa_set_msg_handler)
+void
+gr_nop::count_received_msgs(pmt::pmt_t msg)
+{
+ d_nmsgs_recvd++;
+}
+
+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
index 000000000..e0d59280f
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_nop.h
@@ -0,0 +1,61 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_NOP_H
+#define INCLUDED_GR_NOP_H
+
+#include <gr_core_api.h>
+#include <gr_block.h>
+#include <stddef.h> // size_t
+
+class gr_nop;
+typedef boost::shared_ptr<gr_nop> gr_nop_sptr;
+
+GR_CORE_API gr_nop_sptr
+gr_make_nop (size_t sizeof_stream_item);
+
+/*!
+ * \brief Does nothing. Used for testing only.
+ * \ingroup misc_blk
+ */
+class GR_CORE_API gr_nop : public gr_block
+{
+ friend GR_CORE_API gr_nop_sptr gr_make_nop (size_t sizeof_stream_item);
+ gr_nop (size_t sizeof_stream_item);
+
+protected:
+ int d_nmsgs_recvd;
+
+ // Method that just counts any received messages.
+ void count_received_msgs(pmt::pmt_t msg);
+
+ 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);
+
+ int nmsgs_received() const { return d_nmsgs_recvd; }
+
+};
+
+#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
index 000000000..977a15d18
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_nop.i
@@ -0,0 +1,31 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,nop)
+
+gr_nop_sptr gr_make_nop (size_t sizeof_stream_item);
+
+class gr_nop : public gr_block {
+private:
+ gr_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
index 000000000..183665502
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_null_sink.cc
@@ -0,0 +1,49 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#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_null_sink_sptr
+gr_make_null_sink (size_t sizeof_stream_item)
+{
+ return gnuradio::get_initial_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
index 000000000..737429329
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_null_sink.h
@@ -0,0 +1,53 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_NULL_SINK_H
+#define INCLUDED_GR_NULL_SINK_H
+
+#include <gr_core_api.h>
+#include <gr_sync_block.h>
+#include <stddef.h> // size_t
+
+class gr_null_sink;
+typedef boost::shared_ptr<gr_null_sink> gr_null_sink_sptr;
+
+GR_CORE_API gr_null_sink_sptr
+gr_make_null_sink (size_t sizeof_stream_item);
+
+/*!
+ * \brief Bit bucket
+ * \ingroup sink_blk
+ */
+class GR_CORE_API gr_null_sink : public gr_sync_block
+{
+ friend GR_CORE_API gr_null_sink_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);
+
+};
+
+#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
index 000000000..80411f9b7
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_null_sink.i
@@ -0,0 +1,31 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,null_sink)
+
+gr_null_sink_sptr gr_make_null_sink (size_t sizeof_stream_item);
+
+class gr_null_sink : public gr_sync_block {
+private:
+ gr_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
index 000000000..1ad5c351d
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_null_source.cc
@@ -0,0 +1,52 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_null_source.h>
+#include <gr_io_signature.h>
+#include <string.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_null_source_sptr
+gr_make_null_source (size_t sizeof_stream_item)
+{
+ return gnuradio::get_initial_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
index 000000000..1c64e8bd9
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_null_source.h
@@ -0,0 +1,52 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_NULL_SOURCE_H
+#define INCLUDED_GR_NULL_SOURCE_H
+
+#include <gr_core_api.h>
+#include <gr_sync_block.h>
+
+class gr_null_source;
+typedef boost::shared_ptr<gr_null_source> gr_null_source_sptr;
+
+GR_CORE_API gr_null_source_sptr
+gr_make_null_source (size_t sizeof_stream_item);
+
+/*!
+ * \brief A source of zeros.
+ * \ingroup source_blk
+ */
+class GR_CORE_API gr_null_source : public gr_sync_block
+{
+ friend GR_CORE_API gr_null_source_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);
+
+};
+
+#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
index 000000000..120a59999
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_null_source.i
@@ -0,0 +1,31 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,null_source)
+
+gr_null_source_sptr gr_make_null_source (size_t sizeof_stream_item);
+
+class gr_null_source : public gr_sync_block {
+private:
+ gr_null_source (size_t sizeof_stream_item);
+};
+
diff --git a/gnuradio-core/src/lib/general/gr_ofdm_bpsk_demapper.cc b/gnuradio-core/src/lib/general/gr_ofdm_bpsk_demapper.cc
new file mode 100644
index 000000000..2b718e5ce
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_ofdm_bpsk_demapper.cc
@@ -0,0 +1,97 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_ofdm_bpsk_demapper.h>
+#include <gr_io_signature.h>
+
+gr_ofdm_bpsk_demapper_sptr
+gr_make_ofdm_bpsk_demapper (unsigned int occupied_carriers)
+{
+ return gnuradio::get_initial_sptr(new gr_ofdm_bpsk_demapper (occupied_carriers));
+}
+
+gr_ofdm_bpsk_demapper::gr_ofdm_bpsk_demapper (unsigned occupied_carriers)
+ : gr_block ("ofdm_bpsk_demapper",
+ gr_make_io_signature (1, 1, sizeof(gr_complex)*occupied_carriers),
+ gr_make_io_signature (1, 1, sizeof(unsigned char))),
+ d_occupied_carriers(occupied_carriers),
+ d_byte_offset(0), d_partial_byte(0)
+{
+}
+
+gr_ofdm_bpsk_demapper::~gr_ofdm_bpsk_demapper(void)
+{
+}
+
+unsigned char gr_ofdm_bpsk_demapper::slicer(gr_complex x)
+{
+ return (unsigned char)(x.real() > 0 ? 1 : 0);
+}
+
+void
+gr_ofdm_bpsk_demapper::forecast (int noutput_items, gr_vector_int &ninput_items_required)
+{
+ unsigned ninputs = ninput_items_required.size ();
+ for (unsigned i = 0; i < ninputs; i++)
+ ninput_items_required[i] = 1;
+}
+
+int
+gr_ofdm_bpsk_demapper::general_work(int noutput_items,
+ gr_vector_int &ninput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ const gr_complex *in = (const gr_complex *)input_items[0];
+ unsigned char *out = (unsigned char *) output_items[0];
+
+ unsigned int i=0, bytes_produced=0;
+
+ while(i < d_occupied_carriers) {
+
+ while((d_byte_offset < 8) && (i < d_occupied_carriers)) {
+ //fprintf(stderr, "%f+j%f\n", in[i].real(), in[i].imag());
+ d_partial_byte |= slicer(in[i++]) << (d_byte_offset++);
+ }
+
+ if(d_byte_offset == 8) {
+ out[bytes_produced++] = d_partial_byte;
+ d_byte_offset = 0;
+ d_partial_byte = 0;
+ }
+ }
+
+#if 0
+printf("demod out: ");
+ for(i = 0; i < bytes_produced; i++) {
+ printf("%4x", out[i]);
+ }
+ printf(" \tlen: %d\n", i);
+#endif
+
+ consume_each(1);
+ return bytes_produced;
+}
diff --git a/gnuradio-core/src/lib/general/gr_ofdm_bpsk_demapper.h b/gnuradio-core/src/lib/general/gr_ofdm_bpsk_demapper.h
new file mode 100644
index 000000000..d69d427ed
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_ofdm_bpsk_demapper.h
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_OFDM_BPSK_DEMAPPER_H
+#define INCLUDED_GR_OFDM_BPSK_DEMAPPER_H
+
+
+#include <gr_core_api.h>
+#include <gr_block.h>
+#include <vector>
+
+class gr_ofdm_bpsk_demapper;
+typedef boost::shared_ptr<gr_ofdm_bpsk_demapper> gr_ofdm_bpsk_demapper_sptr;
+
+GR_CORE_API gr_ofdm_bpsk_demapper_sptr
+gr_make_ofdm_bpsk_demapper (unsigned int occupied_carriers);
+
+
+/*!
+ * \brief take a vector of complex constellation points in from an FFT
+ * and demodulate to a stream of bits. Simple BPSK version.
+ * \ingroup ofdm_blk
+ */
+class GR_CORE_API gr_ofdm_bpsk_demapper : public gr_block
+{
+ friend GR_CORE_API gr_ofdm_bpsk_demapper_sptr
+ gr_make_ofdm_bpsk_demapper (unsigned int occupied_carriers);
+
+ protected:
+ gr_ofdm_bpsk_demapper (unsigned int occupied_carriers);
+
+ private:
+ unsigned char slicer(gr_complex x);
+
+ unsigned int d_occupied_carriers;
+ unsigned int d_byte_offset;
+ unsigned char d_partial_byte;
+
+ void forecast(int noutput_items, gr_vector_int &ninput_items_required);
+
+ public:
+ ~gr_ofdm_bpsk_demapper(void);
+ int general_work(int noutput_items,
+ gr_vector_int &ninput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+
+#endif
diff --git a/gnuradio-core/src/lib/general/gr_ofdm_bpsk_demapper.i b/gnuradio-core/src/lib/general/gr_ofdm_bpsk_demapper.i
new file mode 100644
index 000000000..e58a4e40c
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_ofdm_bpsk_demapper.i
@@ -0,0 +1,40 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2006 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <vector>
+
+GR_SWIG_BLOCK_MAGIC(gr,ofdm_bpsk_demapper)
+
+gr_ofdm_bpsk_demapper_sptr
+gr_make_ofdm_bpsk_demapper (unsigned int occupied_carriers);
+
+class gr_ofdm_bpsk_demapper : public gr_sync_decimator
+{
+ protected:
+ gr_ofdm_bpsk_demapper (unsigned int occupied_carriers);
+
+ public:
+ int general_work(int noutput_items,
+ gr_vector_int &ninput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
diff --git a/gnuradio-core/src/lib/general/gr_ofdm_frame_sink2.cc b/gnuradio-core/src/lib/general/gr_ofdm_frame_sink2.cc
new file mode 100644
index 000000000..eb1232756
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_ofdm_frame_sink2.cc
@@ -0,0 +1,374 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007,2008,2010,2011 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_ofdm_frame_sink2.h>
+#include <gr_io_signature.h>
+#include <gr_expj.h>
+#include <gr_math.h>
+#include <math.h>
+#include <cstdio>
+#include <stdexcept>
+#include <iostream>
+#include <string.h>
+#include <gr_constellation.h>
+
+#define VERBOSE 0
+
+inline void
+gr_ofdm_frame_sink2::enter_search()
+{
+ if (VERBOSE)
+ fprintf(stderr, "@ enter_search\n");
+
+ d_state = STATE_SYNC_SEARCH;
+
+}
+
+inline void
+gr_ofdm_frame_sink2::enter_have_sync()
+{
+ if (VERBOSE)
+ fprintf(stderr, "@ enter_have_sync\n");
+
+ d_state = STATE_HAVE_SYNC;
+
+ // clear state of demapper
+ d_byte_offset = 0;
+ d_partial_byte = 0;
+
+ d_header = 0;
+ d_headerbytelen_cnt = 0;
+
+ // Resetting PLL
+ d_freq = 0.0;
+ d_phase = 0.0;
+ fill(d_dfe.begin(), d_dfe.end(), gr_complex(1.0,0.0));
+}
+
+inline void
+gr_ofdm_frame_sink2::enter_have_header()
+{
+ d_state = STATE_HAVE_HEADER;
+
+ // header consists of two 16-bit shorts in network byte order
+ // payload length is lower 12 bits
+ // whitener offset is upper 4 bits
+ d_packetlen = (d_header >> 16) & 0x0fff;
+ d_packet_whitener_offset = (d_header >> 28) & 0x000f;
+ d_packetlen_cnt = 0;
+
+ if (VERBOSE)
+ fprintf(stderr, "@ enter_have_header (payload_len = %d) (offset = %d)\n",
+ d_packetlen, d_packet_whitener_offset);
+}
+
+
+unsigned int gr_ofdm_frame_sink2::demapper(const gr_complex *in,
+ unsigned char *out)
+{
+ unsigned int i=0, bytes_produced=0;
+ gr_complex carrier;
+
+ carrier=gr_expj(d_phase);
+
+ gr_complex accum_error = 0.0;
+ //while(i < d_occupied_carriers) {
+ while(i < d_subcarrier_map.size()) {
+ if(d_nresid > 0) {
+ d_partial_byte |= d_resid;
+ d_byte_offset += d_nresid;
+ d_nresid = 0;
+ d_resid = 0;
+ }
+
+ //while((d_byte_offset < 8) && (i < d_occupied_carriers)) {
+ while((d_byte_offset < 8) && (i < d_subcarrier_map.size())) {
+ //gr_complex sigrot = in[i]*carrier*d_dfe[i];
+ gr_complex sigrot = in[d_subcarrier_map[i]]*carrier*d_dfe[i];
+
+ if(d_derotated_output != NULL){
+ d_derotated_output[i] = sigrot;
+ }
+
+ unsigned char bits = d_constell->decision_maker(&sigrot);
+
+ gr_complex closest_sym = d_constell->points()[bits];
+
+ accum_error += sigrot * conj(closest_sym);
+
+ // FIX THE FOLLOWING STATEMENT
+ if (norm(sigrot)> 0.001) d_dfe[i] += d_eq_gain*(closest_sym/sigrot-d_dfe[i]);
+
+ i++;
+
+ if((8 - d_byte_offset) >= d_nbits) {
+ d_partial_byte |= bits << (d_byte_offset);
+ d_byte_offset += d_nbits;
+ }
+ else {
+ d_nresid = d_nbits-(8-d_byte_offset);
+ int mask = ((1<<(8-d_byte_offset))-1);
+ d_partial_byte |= (bits & mask) << d_byte_offset;
+ d_resid = bits >> (8-d_byte_offset);
+ d_byte_offset += (d_nbits - d_nresid);
+ }
+ //printf("demod symbol: %.4f + j%.4f bits: %x partial_byte: %x byte_offset: %d resid: %x nresid: %d\n",
+ // in[i-1].real(), in[i-1].imag(), bits, d_partial_byte, d_byte_offset, d_resid, d_nresid);
+ }
+
+ if(d_byte_offset == 8) {
+ //printf("demod byte: %x \n\n", d_partial_byte);
+ out[bytes_produced++] = d_partial_byte;
+ d_byte_offset = 0;
+ d_partial_byte = 0;
+ }
+ }
+ //std::cerr << "accum_error " << accum_error << std::endl;
+
+ float angle = arg(accum_error);
+
+ d_freq = d_freq - d_freq_gain*angle;
+ d_phase = d_phase + d_freq - d_phase_gain*angle;
+ if (d_phase >= 2*M_PI) d_phase -= 2*M_PI;
+ if (d_phase <0) d_phase += 2*M_PI;
+
+ //if(VERBOSE)
+ // std::cerr << angle << "\t" << d_freq << "\t" << d_phase << "\t" << std::endl;
+
+ return bytes_produced;
+}
+
+
+gr_ofdm_frame_sink2_sptr
+gr_make_ofdm_frame_sink2(gr_constellation_sptr constell,
+ gr_msg_queue_sptr target_queue, unsigned int occupied_carriers,
+ float phase_gain, float freq_gain)
+{
+ return gnuradio::get_initial_sptr(new gr_ofdm_frame_sink2(constell,
+ target_queue, occupied_carriers,
+ phase_gain, freq_gain));
+}
+
+
+gr_ofdm_frame_sink2::gr_ofdm_frame_sink2(gr_constellation_sptr constell,
+ gr_msg_queue_sptr target_queue, unsigned int occupied_carriers,
+ float phase_gain, float freq_gain)
+ : gr_sync_block ("ofdm_frame_sink2",
+ gr_make_io_signature2 (2, 2, sizeof(gr_complex)*occupied_carriers, sizeof(char)),
+ gr_make_io_signature (1, 1, sizeof(gr_complex)*occupied_carriers)),
+ d_constell(constell),
+ d_target_queue(target_queue), d_occupied_carriers(occupied_carriers),
+ d_byte_offset(0), d_partial_byte(0),
+ d_resid(0), d_nresid(0),d_phase(0),d_freq(0),d_phase_gain(phase_gain),d_freq_gain(freq_gain),
+ d_eq_gain(0.05)
+{
+ if (d_constell->dimensionality() != 1)
+ throw std::runtime_error ("This receiver only works with constellations of dimension 1.");
+
+ std::string carriers = "FE7F";
+
+ // A bit hacky to fill out carriers to occupied_carriers length
+ int diff = (d_occupied_carriers - 4*carriers.length());
+ while(diff > 7) {
+ carriers.insert(0, "f");
+ carriers.insert(carriers.length(), "f");
+ diff -= 8;
+ }
+
+ // if there's extras left to be processed
+ // divide remaining to put on either side of current map
+ // all of this is done to stick with the concept of a carrier map string that
+ // can be later passed by the user, even though it'd be cleaner to just do this
+ // on the carrier map itself
+ int diff_left=0;
+ int diff_right=0;
+
+ // dictionary to convert from integers to ascii hex representation
+ char abc[16] = {'0', '1', '2', '3', '4', '5', '6', '7',
+ '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
+ if(diff > 0) {
+ char c[2] = {0,0};
+
+ diff_left = (int)ceil((float)diff/2.0f); // number of carriers to put on the left side
+ c[0] = abc[(1 << diff_left) - 1]; // convert to bits and move to ASCI integer
+ carriers.insert(0, c);
+
+ diff_right = diff - diff_left; // number of carriers to put on the right side
+ c[0] = abc[0xF^((1 << diff_right) - 1)]; // convert to bits and move to ASCI integer
+ carriers.insert(carriers.length(), c);
+ }
+
+ // It seemed like such a good idea at the time...
+ // because we are only dealing with the occupied_carriers
+ // at this point, the diff_left in the following compensates
+ // for any offset from the 0th carrier introduced
+ unsigned int i,j,k;
+ for(i = 0; i < (d_occupied_carriers/4)+diff_left; i++) {
+ char c = carriers[i];
+ for(j = 0; j < 4; j++) {
+ k = (strtol(&c, NULL, 16) >> (3-j)) & 0x1;
+ if(k) {
+ d_subcarrier_map.push_back(4*i + j - diff_left);
+ }
+ }
+ }
+
+ // make sure we stay in the limit currently imposed by the occupied_carriers
+ if(d_subcarrier_map.size() > d_occupied_carriers) {
+ throw std::invalid_argument("gr_ofdm_mapper_bcv: subcarriers allocated exceeds size of occupied carriers");
+ }
+
+ d_bytes_out = new unsigned char[d_occupied_carriers];
+ d_dfe.resize(occupied_carriers);
+ fill(d_dfe.begin(), d_dfe.end(), gr_complex(1.0,0.0));
+
+ d_nbits = d_constell->bits_per_symbol();
+
+ enter_search();
+}
+
+gr_ofdm_frame_sink2::~gr_ofdm_frame_sink2 ()
+{
+ delete [] d_bytes_out;
+}
+
+
+int
+gr_ofdm_frame_sink2::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];
+ const char *sig = (const char *) input_items[1];
+ unsigned int j = 0;
+ unsigned int bytes=0;
+
+ // If the output is connected, send it the derotated symbols
+ if(output_items.size() >= 1)
+ d_derotated_output = (gr_complex *)output_items[0];
+ else
+ d_derotated_output = NULL;
+
+ if (VERBOSE)
+ fprintf(stderr,">>> Entering state machine\n");
+
+ 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);
+
+ if (sig[0]) { // Found it, set up for header decode
+ enter_have_sync();
+ }
+ break;
+
+ case STATE_HAVE_SYNC:
+ // only demod after getting the preamble signal; otherwise, the
+ // equalizer taps will screw with the PLL performance
+ bytes = demapper(&in[0], d_bytes_out);
+
+ if (VERBOSE) {
+ if(sig[0])
+ printf("ERROR -- Found SYNC in HAVE_SYNC\n");
+ fprintf(stderr,"Header Search bitcnt=%d, header=0x%08x\n",
+ d_headerbytelen_cnt, d_header);
+ }
+
+ j = 0;
+ while(j < bytes) {
+ d_header = (d_header << 8) | (d_bytes_out[j] & 0xFF);
+ j++;
+
+ if (++d_headerbytelen_cnt == HEADERBYTELEN) {
+
+ 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()){
+ enter_have_header();
+
+ if (VERBOSE)
+ printf("\nPacket Length: %d\n", d_packetlen);
+
+ while((j < bytes) && (d_packetlen_cnt < d_packetlen)) {
+ d_packet[d_packetlen_cnt++] = d_bytes_out[j++];
+ }
+
+ if(d_packetlen_cnt == d_packetlen) {
+ gr_message_sptr msg =
+ gr_make_message(0, d_packet_whitener_offset, 0, d_packetlen);
+ memcpy(msg->msg(), d_packet, d_packetlen_cnt);
+ d_target_queue->insert_tail(msg); // send it
+ msg.reset(); // free it up
+
+ enter_search();
+ }
+ }
+ else {
+ enter_search(); // bad header
+ }
+ }
+ }
+ break;
+
+ case STATE_HAVE_HEADER:
+ bytes = demapper(&in[0], d_bytes_out);
+
+ if (VERBOSE) {
+ if(sig[0])
+ printf("ERROR -- Found SYNC in HAVE_HEADER at %d, length of %d\n", d_packetlen_cnt, d_packetlen);
+ fprintf(stderr,"Packet Build\n");
+ }
+
+ j = 0;
+ while(j < bytes) {
+ d_packet[d_packetlen_cnt++] = d_bytes_out[j++];
+
+ if (d_packetlen_cnt == d_packetlen){ // packet is filled
+ // build a message
+ // NOTE: passing header field as arg1 is not scalable
+ gr_message_sptr msg =
+ gr_make_message(0, d_packet_whitener_offset, 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
+
+ return 1;
+}
diff --git a/gnuradio-core/src/lib/general/gr_ofdm_frame_sink2.h b/gnuradio-core/src/lib/general/gr_ofdm_frame_sink2.h
new file mode 100644
index 000000000..a743e8c5a
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_ofdm_frame_sink2.h
@@ -0,0 +1,121 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007,2011 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_OFDM_FRAME_SINK2_H
+#define INCLUDED_GR_OFDM_FRAME_SINK2_H
+
+#include <gr_core_api.h>
+#include <gr_sync_block.h>
+#include <gr_msg_queue.h>
+#include <gr_constellation.h>
+
+class gr_ofdm_frame_sink2;
+typedef boost::shared_ptr<gr_ofdm_frame_sink2> gr_ofdm_frame_sink2_sptr;
+
+GR_CORE_API gr_ofdm_frame_sink2_sptr
+gr_make_ofdm_frame_sink2 (gr_constellation_sptr constell,
+ gr_msg_queue_sptr target_queue, unsigned int occupied_tones,
+ float phase_gain=0.25, float freq_gain=0.25*0.25/4.0);
+
+/*!
+ * \brief Takes an OFDM symbol in, demaps it into bits of 0's and 1's, packs
+ * them into packets, and sends to to a message queue sink.
+ * \ingroup sink_blk
+ * \ingroup ofdm_blk
+ *
+ * NOTE: The mod input parameter simply chooses a pre-defined demapper/slicer. Eventually,
+ * we want to be able to pass in a reference to an object to do the demapping and slicing
+ * for a given modulation type.
+ */
+class GR_CORE_API gr_ofdm_frame_sink2 : public gr_sync_block
+{
+ friend GR_CORE_API gr_ofdm_frame_sink2_sptr
+ gr_make_ofdm_frame_sink2 (gr_constellation_sptr constell,
+ gr_msg_queue_sptr target_queue, unsigned int occupied_tones,
+ float phase_gain, float freq_gain);
+
+ private:
+ enum state_t {STATE_SYNC_SEARCH, STATE_HAVE_SYNC, STATE_HAVE_HEADER};
+
+ static const int MAX_PKT_LEN = 4096;
+ static const int HEADERBYTELEN = 4;
+
+ 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_headerbytelen_cnt; // how many so far
+
+ unsigned char *d_bytes_out; // hold the current bytes produced by the demapper
+
+ unsigned int d_occupied_carriers;
+ unsigned int d_byte_offset;
+ unsigned int d_partial_byte;
+
+ unsigned char d_packet[MAX_PKT_LEN]; // assembled payload
+ int d_packetlen; // length of packet
+ int d_packet_whitener_offset; // offset into whitener string to use
+ int d_packetlen_cnt; // how many so far
+
+ gr_complex * d_derotated_output; // Pointer to output stream to send deroated symbols out
+
+ gr_constellation_sptr d_constell;
+ std::vector<gr_complex> d_dfe;
+ unsigned int d_nbits;
+
+ unsigned char d_resid;
+ unsigned int d_nresid;
+ float d_phase;
+ float d_freq;
+ float d_phase_gain;
+ float d_freq_gain;
+ float d_eq_gain;
+
+ std::vector<int> d_subcarrier_map;
+
+ protected:
+ gr_ofdm_frame_sink2(gr_constellation_sptr constell,
+ gr_msg_queue_sptr target_queue, unsigned int occupied_tones,
+ float phase_gain, float freq_gain);
+
+ void enter_search();
+ void enter_have_sync();
+ void enter_have_header();
+
+ bool header_ok()
+ {
+ // confirm that two copies of header info are identical
+ return ((d_header >> 16) ^ (d_header & 0xffff)) == 0;
+ }
+
+ unsigned char slicer(const gr_complex x);
+ unsigned int demapper(const gr_complex *in,
+ unsigned char *out);
+
+ public:
+ ~gr_ofdm_frame_sink2();
+
+ int work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+#endif /* INCLUDED_GR_OFDM_FRAME_SINK2_H */
diff --git a/gnuradio-core/src/lib/general/gr_ofdm_frame_sink2.i b/gnuradio-core/src/lib/general/gr_ofdm_frame_sink2.i
new file mode 100644
index 000000000..8c04d1e16
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_ofdm_frame_sink2.i
@@ -0,0 +1,39 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007,2011 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,ofdm_frame_sink2);
+
+gr_ofdm_frame_sink2_sptr
+gr_make_ofdm_frame_sink2(gr_constellation_sptr constell,
+ gr_msg_queue_sptr target_queue, unsigned int occupied_tones,
+ float phase_gain=0.25, float freq_gain=0.25*0.25/4);
+
+class gr_ofdm_frame_sink2 : public gr_sync_block
+{
+ protected:
+ gr_ofdm_frame_sink2(gr_constellation_sptr constell,
+ gr_msg_queue_sptr target_queue, unsigned int occupied_tones,
+ float phase_gain, float freq_gain);
+
+ public:
+ ~gr_ofdm_frame_sink2();
+};
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
index 000000000..318753672
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_pa_2x2_phase_combiner.cc
@@ -0,0 +1,74 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_pa_2x2_phase_combiner.h>
+#include <gr_io_signature.h>
+
+gr_pa_2x2_phase_combiner_sptr
+gr_make_pa_2x2_phase_combiner()
+{
+ return gnuradio::get_initial_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
index 000000000..d430d154f
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_pa_2x2_phase_combiner.h
@@ -0,0 +1,63 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifndef INCLUDED_GR_PA_2X2_PHASE_COMBINER_H
+#define INCLUDED_GR_PA_2X2_PHASE_COMBINER_H
+
+#include <gr_core_api.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_CORE_API gr_pa_2x2_phase_combiner_sptr gr_make_pa_2x2_phase_combiner ();
+
+/*!
+ * \brief pa_2x2 phase combiner
+ * \ingroup misc_blk
+ *
+ * Anntenas are arranged like this:
+ *
+ * 2 3
+ * 0 1
+ *
+ * dx and dy are lambda/2.
+ */
+class GR_CORE_API 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_CORE_API 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
index 000000000..2cd373a5e
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_pa_2x2_phase_combiner.i
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,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_pack_k_bits_bb.cc b/gnuradio-core/src/lib/general/gr_pack_k_bits_bb.cc
new file mode 100644
index 000000000..0ea0c9e38
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_pack_k_bits_bb.cc
@@ -0,0 +1,69 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_pack_k_bits_bb.h>
+#include <gr_io_signature.h>
+#include <stdexcept>
+#include <iostream>
+
+gr_pack_k_bits_bb_sptr gr_make_pack_k_bits_bb(unsigned k)
+{
+ return gnuradio::get_initial_sptr(new gr_pack_k_bits_bb(k));
+}
+
+
+gr_pack_k_bits_bb::gr_pack_k_bits_bb (unsigned k)
+ : gr_sync_decimator("pack_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_pack_k_bits_bb::~gr_pack_k_bits_bb()
+{
+}
+
+int
+gr_pack_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];
+
+ for(int i = 0; i < noutput_items; i++) {
+ out[i] = 0x00;
+ for(unsigned int j = 0; j < d_k; j++) {
+ out[i] |= (0x01 & in[i*d_k+j])<<(d_k-j-1);
+ }
+ }
+
+ return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_pack_k_bits_bb.h b/gnuradio-core/src/lib/general/gr_pack_k_bits_bb.h
new file mode 100644
index 000000000..8e1508c78
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_pack_k_bits_bb.h
@@ -0,0 +1,56 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_PACK_K_BITS_BB_H
+#define INCLUDED_GR_PACK_K_BITS_BB_H
+
+#include <gr_core_api.h>
+#include <gr_sync_decimator.h>
+
+class gr_pack_k_bits_bb;
+typedef boost::shared_ptr<gr_pack_k_bits_bb> gr_pack_k_bits_bb_sptr;
+GR_CORE_API gr_pack_k_bits_bb_sptr gr_make_pack_k_bits_bb (unsigned k);
+
+class gr_pack_k_bits_bb;
+
+/*!
+ * \brief Converts a stream of bytes with 1 bit in the LSB to a byte with k relevent bits.
+ * \ingroup converter_blk
+ */
+class GR_CORE_API gr_pack_k_bits_bb : public gr_sync_decimator
+{
+ private:
+ friend GR_CORE_API gr_pack_k_bits_bb_sptr gr_make_pack_k_bits_bb (unsigned k);
+
+ gr_pack_k_bits_bb (unsigned k);
+
+ unsigned d_k; // number of relevent bits to pack from k input bytes
+
+ public:
+ ~gr_pack_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_pack_k_bits_bb.i b/gnuradio-core/src/lib/general/gr_pack_k_bits_bb.i
new file mode 100644
index 000000000..6ae2095ec
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_pack_k_bits_bb.i
@@ -0,0 +1,34 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,pack_k_bits_bb)
+
+gr_pack_k_bits_bb_sptr gr_make_pack_k_bits_bb (int k) throw(std::exception);
+
+class gr_pack_k_bits_bb : public gr_sync_decimator
+{
+ private:
+ gr_pack_k_bits_bb (int k);
+
+ public:
+ ~gr_pack_k_bits_bb ();
+};
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
index 000000000..19a8c5fc2
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_packet_sink.cc
@@ -0,0 +1,207 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#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>
+#include <string.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 gnuradio::get_initial_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
index 000000000..b4cb0b0f6
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_packet_sink.h
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_PACKET_SINK_H
+#define INCLUDED_GR_PACKET_SINK_H
+
+#include <gr_core_api.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_CORE_API 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_blk
+ */
+class GR_CORE_API gr_packet_sink : public gr_sync_block
+{
+ friend GR_CORE_API 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
index 000000000..d1290f9d3
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_packet_sink.i
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,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_peak_detector2_fb.cc b/gnuradio-core/src/lib/general/gr_peak_detector2_fb.cc
new file mode 100644
index 000000000..a4179a8c2
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_peak_detector2_fb.cc
@@ -0,0 +1,107 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_peak_detector2_fb.h>
+#include <gr_io_signature.h>
+#include <string.h>
+
+gr_peak_detector2_fb_sptr
+gr_make_peak_detector2_fb (float threshold_factor_rise,
+ int look_ahead, float alpha)
+{
+ return gnuradio::get_initial_sptr(new gr_peak_detector2_fb (threshold_factor_rise,
+ look_ahead, alpha));
+}
+
+gr_peak_detector2_fb::gr_peak_detector2_fb (float threshold_factor_rise,
+ int look_ahead, float alpha)
+ : gr_sync_block ("peak_detector2_fb",
+ gr_make_io_signature (1, 1, sizeof(float)),
+ gr_make_io_signature2 (1, 2, sizeof(char), sizeof(float))),
+ d_threshold_factor_rise(threshold_factor_rise),
+ d_look_ahead(look_ahead), d_alpha(alpha), d_avg(0.0f), d_found(false)
+{
+}
+
+int
+gr_peak_detector2_fb::work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items) {
+ float *iptr = (float *) input_items[0];
+ char *optr = (char *) output_items[0];
+
+ assert(noutput_items >= 2);
+
+ memset(optr, 0, noutput_items*sizeof(char));
+
+ for (int i = 0; i < noutput_items; i++) {
+
+ if (!d_found) {
+ // Have not yet detected presence of peak
+ if (iptr[i] > d_avg * (1.0f + d_threshold_factor_rise)) {
+ d_found = true;
+ d_look_ahead_remaining = d_look_ahead;
+ d_peak_val = -(float)INFINITY;
+ }
+ else {
+ d_avg = d_alpha*iptr[i] + (1.0f - d_alpha)*d_avg;
+ }
+ }
+ else {
+ // Detected presence of peak
+ if (iptr[i] > d_peak_val) {
+ d_peak_val = iptr[i];
+ d_peak_ind = i;
+ }
+ else if (d_look_ahead_remaining <= 0) {
+ optr[d_peak_ind] = 1;
+ d_found = false;
+ d_avg = iptr[i];
+ }
+
+ // Have not yet located peak, loop and keep searching.
+ d_look_ahead_remaining--;
+ }
+
+ // Every iteration of the loop, write debugging signal out if
+ // connected:
+ if (output_items.size() == 2) {
+ float *sigout = (float *) output_items[1];
+ sigout[i] = d_avg;
+ }
+ } // loop
+
+ if (!d_found)
+ return noutput_items;
+
+ // else if detected presence, keep searching during the next call to work.
+ int tmp = d_peak_ind;
+ d_peak_ind = 1;
+
+ return tmp - 1;
+}
+
+
diff --git a/gnuradio-core/src/lib/general/gr_peak_detector2_fb.h b/gnuradio-core/src/lib/general/gr_peak_detector2_fb.h
new file mode 100644
index 000000000..665a6b882
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_peak_detector2_fb.h
@@ -0,0 +1,109 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_gr_peak_detector2_FB_H
+#define INCLUDED_gr_peak_detector2_FB_H
+
+#include <gr_core_api.h>
+#include <gr_sync_block.h>
+
+class gr_peak_detector2_fb;
+typedef boost::shared_ptr<gr_peak_detector2_fb> gr_peak_detector2_fb_sptr;
+
+GR_CORE_API gr_peak_detector2_fb_sptr gr_make_peak_detector2_fb (float threshold_factor_rise = 7,
+ int look_ahead = 1000,
+ float alpha = 0.001);
+
+/*!
+ * \brief Detect the peak of a signal
+ * \ingroup level_blk
+ *
+ * If a peak is detected, this block outputs a 1,
+ * or it outputs 0's. A separate debug output may be connected, to
+ * view the internal EWMA described below.
+ *
+ * \param threshold_factor_rise The threshold factor determins when a peak
+ * is present. An EWMA average of the signal is calculated and when the
+ * value of the signal goes over threshold_factor_rise*average, we
+ * call the peak.
+ * \param look_ahead The look-ahead value is used when the threshold is
+ * found to locate the peak within this range.
+ * \param alpha The gain value of a single-pole moving average filter
+ */
+
+class GR_CORE_API gr_peak_detector2_fb : public gr_sync_block
+{
+ friend GR_CORE_API gr_peak_detector2_fb_sptr
+ gr_make_peak_detector2_fb (float threshold_factor_rise, int look_ahead, float alpha);
+
+ gr_peak_detector2_fb (float threshold_factor_rise, int look_ahead, float alpha);
+
+private:
+ float d_threshold_factor_rise;
+ int d_look_ahead;
+ int d_look_ahead_remaining;
+ int d_peak_ind;
+ float d_peak_val;
+ float d_alpha;
+ float d_avg;
+ bool d_found;
+
+public:
+
+ /*! \brief Set the threshold factor value for the rise time
+ * \param thr new threshold factor
+ */
+ void set_threshold_factor_rise(float thr) { d_threshold_factor_rise = thr; }
+
+ /*! \brief Set the look-ahead factor
+ * \param look new look-ahead factor
+ */
+ void set_look_ahead(int look) { d_look_ahead = look; }
+
+ /*! \brief Set the running average alpha
+ * \param alpha new alpha for running average
+ */
+ void set_alpha(int alpha) { d_alpha = alpha; }
+
+ /*! \brief Get the threshold factor value for the rise time
+ * \return threshold factor
+ */
+ float threshold_factor_rise() { return d_threshold_factor_rise; }
+
+ /*! \brief Get the look-ahead factor value
+ * \return look-ahead factor
+ */
+ int look_ahead() { return d_look_ahead; }
+
+ /*! \brief Get the alpha value of the running average
+ * \return alpha
+ */
+ float alpha() { return d_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/general/gr_peak_detector2_fb.i b/gnuradio-core/src/lib/general/gr_peak_detector2_fb.i
new file mode 100644
index 000000000..ec7227e69
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_peak_detector2_fb.i
@@ -0,0 +1,45 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+
+GR_SWIG_BLOCK_MAGIC(gr,peak_detector2_fb)
+
+ gr_peak_detector2_fb_sptr gr_make_peak_detector2_fb (float threshold_factor_rise = 7,
+ int look_ahead = 1000,
+ float alpha=0.001);
+
+class gr_peak_detector2_fb : public gr_sync_block
+{
+private:
+ gr_peak_detector2_fb (float threshold_factor_rise, int look_ahead, float alpha);
+
+public:
+ void set_threshold_factor_rise(float thr) { d_threshold_factor_rise = thr; }
+ void set_look_ahead(int look) { d_look_ahead = look; }
+ void set_alpha(int alpha) { d_avg_alpha = alpha; }
+
+ float threshold_factor_rise() { return d_threshold_factor_rise; }
+ int look_ahead() { return d_look_ahead; }
+ float alpha() { return d_avg_alpha; }
+};
+
+
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
index 000000000..fb05c85a5
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_phase_modulator_fc.cc
@@ -0,0 +1,62 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005,2006,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_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 gnuradio::get_initial_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
index 000000000..07f3b82d4
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_phase_modulator_fc.h
@@ -0,0 +1,56 @@
+/* -*- 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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_PHASE_MODULATOR_FC_H
+#define INCLUDED_GR_PHASE_MODULATOR_FC_H
+
+#include <gr_core_api.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_CORE_API gr_phase_modulator_fc_sptr gr_make_phase_modulator_fc (double sensitivity);
+
+/*!
+ * \brief Phase modulator block
+ * \ingroup modulation_blk
+ * output=complex(cos(in*sensitivity),sin(in*sensitivity))
+ */
+class GR_CORE_API gr_phase_modulator_fc : public gr_sync_block
+{
+ double d_sensitivity;
+ double d_phase;
+
+ friend GR_CORE_API 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
index 000000000..c1816c647
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_phase_modulator_fc.i
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,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
index 000000000..b7b1291a3
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_pll_carriertracking_cc.cc
@@ -0,0 +1,120 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006,2010,2011 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_pll_carriertracking_cc.h>
+#include <gr_io_signature.h>
+#include <gr_sincos.h>
+#include <math.h>
+#include <gr_math.h>
+
+#ifndef M_TWOPI
+#define M_TWOPI (2.0f*M_PI)
+#endif
+
+gr_pll_carriertracking_cc_sptr
+gr_make_pll_carriertracking_cc (float loop_bw, float max_freq, float min_freq)
+{
+ return gnuradio::get_initial_sptr(new gr_pll_carriertracking_cc (loop_bw, max_freq, min_freq));
+}
+
+gr_pll_carriertracking_cc::gr_pll_carriertracking_cc (float loop_bw,
+ 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))),
+ gri_control_loop(loop_bw, max_freq, min_freq),
+ 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());
+ sample_phase = gr_fast_atan2f(sample.imag(),sample.real());
+ return mod_2pi(sample_phase-ref_phase);
+}
+
+bool
+gr_pll_carriertracking_cc::lock_detector(void)
+{
+ return (fabsf(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++){
+ gr_sincosf(d_phase, &t_imag, &t_real);
+ optr[i] = iptr[i] * gr_complex(t_real, -t_imag);
+
+ error = phase_detector(iptr[i],d_phase);
+
+ advance_loop(error);
+ phase_wrap();
+ frequency_limit();
+
+ 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
index 000000000..b3bc5ddd0
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_pll_carriertracking_cc.h
@@ -0,0 +1,74 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2006,2011 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_PLL_CARRIERTRACKING_CC_H
+#define INCLUDED_GR_PLL_CARRIERTRACKING_CC_H
+
+#include <gr_core_api.h>
+#include <gr_sync_block.h>
+#include <gri_control_loop.h>
+
+class gr_pll_carriertracking_cc;
+typedef boost::shared_ptr<gr_pll_carriertracking_cc> gr_pll_carriertracking_cc_sptr;
+
+GR_CORE_API gr_pll_carriertracking_cc_sptr gr_make_pll_carriertracking_cc (float loop_bw,
+ 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 sync_blk
+ *
+ * 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. The loop bandwidth determins the lock range and should be set
+ * around pi/200 -- 2pi/100.
+ * \sa gr_pll_freqdet_cf, gr_pll_carriertracking_cc
+ */
+
+class GR_CORE_API gr_pll_carriertracking_cc : public gr_sync_block, public gri_control_loop
+{
+ friend GR_CORE_API gr_pll_carriertracking_cc_sptr gr_make_pll_carriertracking_cc (float loop_bw,
+ float max_freq,
+ float min_freq);
+
+ float d_locksig,d_lock_threshold;
+ bool d_squelch_enable;
+ gr_pll_carriertracking_cc (float loop_bw, 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
index 000000000..a20adf7e2
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_pll_carriertracking_cc.i
@@ -0,0 +1,39 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005,2011 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,pll_carriertracking_cc);
+
+gr_pll_carriertracking_cc_sptr
+gr_make_pll_carriertracking_cc (float loop_bw,
+ float max_freq,
+ float min_freq);
+
+class gr_pll_carriertracking_cc : public gr_sync_block, public gri_control_loop
+{
+ private:
+ gr_pll_carriertracking_cc (float loop_bw, 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
index 000000000..f80f4ed07
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_pll_freqdet_cf.cc
@@ -0,0 +1,90 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2010,2011 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_pll_freqdet_cf.h>
+#include <gr_io_signature.h>
+#include <math.h>
+#include <gr_math.h>
+
+#ifndef M_TWOPI
+#define M_TWOPI (2.0f*M_PI)
+#endif
+
+gr_pll_freqdet_cf_sptr
+gr_make_pll_freqdet_cf (float loop_bw, float max_freq, float min_freq)
+{
+ return gnuradio::get_initial_sptr(new gr_pll_freqdet_cf (loop_bw, max_freq, min_freq));
+}
+
+gr_pll_freqdet_cf::gr_pll_freqdet_cf (float loop_bw, 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))),
+ gri_control_loop(loop_bw, max_freq, min_freq)
+{
+}
+
+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 = gr_fast_atan2f(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) {
+ *optr++ = d_freq;
+
+ error = phase_detector(*iptr++,d_phase);
+
+ advance_loop(error);
+ phase_wrap();
+ frequency_limit();
+ }
+ 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
index 000000000..3dfc8d709
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_pll_freqdet_cf.h
@@ -0,0 +1,67 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2011 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_PLL_FREQDET_CF_H
+#define INCLUDED_GR_PLL_FREQDET_CF_H
+
+#include <gr_core_api.h>
+#include <gr_sync_block.h>
+#include <gri_control_loop.h>
+
+class gr_pll_freqdet_cf;
+typedef boost::shared_ptr<gr_pll_freqdet_cf> gr_pll_freqdet_cf_sptr;
+
+GR_CORE_API gr_pll_freqdet_cf_sptr gr_make_pll_freqdet_cf (float loop_bw,
+ 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 sync_blk
+ *
+ * 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. The loop bandwidth determins the lock range and should be set
+ * around pi/200 -- 2pi/100.
+ * \sa gr_pll_refout_cc, gr_pll_carriertracking_cc
+ */
+
+class GR_CORE_API gr_pll_freqdet_cf : public gr_sync_block, public gri_control_loop
+{
+ friend GR_CORE_API gr_pll_freqdet_cf_sptr gr_make_pll_freqdet_cf (float loop_bw,
+ float max_freq,
+ float min_freq);
+
+ float mod_2pi (float in);
+ gr_pll_freqdet_cf (float loop_bw, 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 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
index 000000000..87e515adb
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_pll_freqdet_cf.i
@@ -0,0 +1,33 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005,2011 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,pll_freqdet_cf)
+
+ gr_pll_freqdet_cf_sptr gr_make_pll_freqdet_cf (float loop_bw,
+ float max_freq,
+ float min_freq);
+
+class gr_pll_freqdet_cf : public gr_sync_block, public gri_control_loop
+{
+ private:
+ gr_pll_freqdet_cf (float loop_bw, 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
index 000000000..9f95c3f64
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_pll_refout_cc.cc
@@ -0,0 +1,93 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2010,2011 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_pll_refout_cc.h>
+#include <gr_io_signature.h>
+#include <gr_sincos.h>
+#include <math.h>
+#include <gr_math.h>
+
+#ifndef M_TWOPI
+#define M_TWOPI (2.0f*M_PI)
+#endif
+
+gr_pll_refout_cc_sptr
+gr_make_pll_refout_cc (float loop_bw, float max_freq, float min_freq)
+{
+ return gnuradio::get_initial_sptr(new gr_pll_refout_cc (loop_bw, max_freq, min_freq));
+}
+
+gr_pll_refout_cc::gr_pll_refout_cc (float loop_bw, 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))),
+ gri_control_loop(loop_bw, max_freq, min_freq)
+{
+}
+
+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 = gr_fast_atan2f(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) {
+ gr_sincosf(d_phase,&t_imag,&t_real);
+ *optr++ = gr_complex(t_real,t_imag);
+
+ error = phase_detector(*iptr++,d_phase);
+
+ advance_loop(error);
+ phase_wrap();
+ frequency_limit();
+ }
+ 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
index 000000000..ef5cd31e2
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_pll_refout_cc.h
@@ -0,0 +1,65 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2011 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_PLL_REFOUT_CC_H
+#define INCLUDED_GR_PLL_REFOUT_CC_H
+
+#include <gr_core_api.h>
+#include <gr_sync_block.h>
+#include <gri_control_loop.h>
+
+class gr_pll_refout_cc;
+typedef boost::shared_ptr<gr_pll_refout_cc> gr_pll_refout_cc_sptr;
+
+GR_CORE_API gr_pll_refout_cc_sptr gr_make_pll_refout_cc (float loop_bw,
+ float max_freq, float min_freq);
+/*!
+ * \brief Implements a PLL which locks to the input frequency and outputs a carrier
+ * \ingroup sync_blk
+ *
+ * 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. The loop bandwidth determins the lock range and should be set
+ * around pi/200 -- 2pi/100.
+ * \sa gr_pll_freqdet_cf, gr_pll_carriertracking_cc
+ */
+class GR_CORE_API gr_pll_refout_cc : public gr_sync_block, public gri_control_loop
+{
+ friend GR_CORE_API gr_pll_refout_cc_sptr gr_make_pll_refout_cc (float loop_bw,
+ float max_freq, float min_freq);
+
+ gr_pll_refout_cc (float loop_bw, 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
index 000000000..630c0444f
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_pll_refout_cc.i
@@ -0,0 +1,32 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005,2011 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,pll_refout_cc)
+
+gr_pll_refout_cc_sptr gr_make_pll_refout_cc (float loop_bw,
+ float max_freq, float min_freq);
+
+class gr_pll_refout_cc : public gr_sync_block, public gri_control_loop
+{
+ private:
+ gr_pll_refout_cc (float loop_bw, float max_freq, float min_freq);
+};
diff --git a/gnuradio-core/src/lib/general/gr_pn_correlator_cc.cc b/gnuradio-core/src/lib/general/gr_pn_correlator_cc.cc
new file mode 100644
index 000000000..818e48c34
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_pn_correlator_cc.cc
@@ -0,0 +1,77 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_pn_correlator_cc.h>
+#include <gr_io_signature.h>
+
+gr_pn_correlator_cc_sptr
+gr_make_pn_correlator_cc(int degree, int mask, int seed)
+{
+ return gnuradio::get_initial_sptr(new gr_pn_correlator_cc(degree, mask, seed));
+}
+
+gr_pn_correlator_cc::gr_pn_correlator_cc(int degree, int mask, int seed)
+ : gr_sync_decimator ("pn_correlator_cc",
+ gr_make_io_signature (1, 1, sizeof(gr_complex)),
+ gr_make_io_signature (1, 1, sizeof(gr_complex)),
+ (unsigned int)((1ULL << degree)-1)) // PN code length
+{
+ d_len = (unsigned int)((1ULL << degree)-1);
+ if (mask == 0)
+ mask = gri_glfsr::glfsr_mask(degree);
+ d_reference = new gri_glfsr(mask, seed);
+ for (int i = 0; i < d_len; i++) // initialize to last value in sequence
+ d_pn = 2.0*d_reference->next_bit()-1.0;
+}
+
+gr_pn_correlator_cc::~gr_pn_correlator_cc()
+{
+ delete d_reference;
+}
+
+int
+gr_pn_correlator_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];
+ gr_complex sum;
+
+ for (int i = 0; i < noutput_items; i++) {
+ sum = 0.0;
+
+ for (int j = 0; j < d_len; j++) {
+ if (j != 0) // retard PN generator one sample per period
+ d_pn = 2.0*d_reference->next_bit()-1.0; // no conditionals
+ sum += *in++ * d_pn;
+ }
+
+ *out++ = sum*gr_complex(1.0/d_len, 0.0);
+ }
+
+ return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_pn_correlator_cc.h b/gnuradio-core/src/lib/general/gr_pn_correlator_cc.h
new file mode 100644
index 000000000..69bd2c502
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_pn_correlator_cc.h
@@ -0,0 +1,62 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_PN_CORRELATOR_CC_H
+#define INCLUDED_GR_PN_CORRELATOR_CC_H
+
+#include <gr_core_api.h>
+#include <gr_sync_decimator.h>
+#include <gri_glfsr.h>
+
+class gr_pn_correlator_cc;
+typedef boost::shared_ptr<gr_pn_correlator_cc> gr_pn_correlator_cc_sptr;
+
+GR_CORE_API gr_pn_correlator_cc_sptr
+gr_make_pn_correlator_cc(int degree, int mask=0, int seed=1);
+/*!
+ * \brief PN code sequential search correlator
+ *
+ * \ingroup sync_blk
+ * Receives complex baseband signal, outputs complex correlation against
+ * reference PN code, one sample per PN code period
+ */
+
+class GR_CORE_API gr_pn_correlator_cc : public gr_sync_decimator
+{
+ friend GR_CORE_API gr_pn_correlator_cc_sptr gr_make_pn_correlator_cc(int degree, int mask, int seed);
+
+ int d_len;
+ float d_pn;
+ gri_glfsr *d_reference;
+
+ protected:
+ gr_pn_correlator_cc(int degree, int mask, int seed);
+
+ public:
+ virtual int work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+
+ ~gr_pn_correlator_cc();
+};
+
+#endif /* INCLUDED_GR_PN_CORRELATOR_CC_H */
diff --git a/gnuradio-core/src/lib/general/gr_pn_correlator_cc.i b/gnuradio-core/src/lib/general/gr_pn_correlator_cc.i
new file mode 100644
index 000000000..e992f33a7
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_pn_correlator_cc.i
@@ -0,0 +1,32 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,pn_correlator_cc)
+
+gr_pn_correlator_cc_sptr
+gr_make_pn_correlator_cc(int degree, int mask=0, int seed=1);
+
+class gr_pn_correlator_cc : public gr_sync_decimator
+{
+ protected:
+ gr_pn_correlator_cc();
+};
diff --git a/gnuradio-core/src/lib/general/gr_prefs.cc b/gnuradio-core/src/lib/general/gr_prefs.cc
new file mode 100644
index 000000000..9705eed4f
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_prefs.cc
@@ -0,0 +1,229 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <gr_prefs.h>
+#include <gr_sys_paths.h>
+#include <gr_constants.h>
+#include <algorithm>
+
+#include <boost/filesystem/operations.hpp>
+#include <boost/filesystem/path.hpp>
+#include <boost/filesystem/fstream.hpp>
+namespace fs = boost::filesystem;
+
+/*
+ * 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()
+{
+ _read_files();
+}
+
+gr_prefs::~gr_prefs()
+{
+ // nop
+}
+
+std::vector<std::string>
+gr_prefs::_sys_prefs_filenames()
+{
+ std::vector<std::string> fnames;
+
+ fs::path dir = gr_prefsdir();
+ if(!fs::is_directory(dir))
+ return fnames;
+
+ fs::directory_iterator diritr(dir);
+ while(diritr != fs::directory_iterator()) {
+ fs::path p = *diritr++;
+ fnames.push_back(p.string());
+ }
+ std::sort(fnames.begin(), fnames.end());
+
+ // Find if there is a ~/.gnuradio/config file and add this to the
+ // beginning of the file list to override any preferences in the
+ // installed path config files.
+ fs::path homedir = fs::path(gr_appdata_path());
+ homedir = homedir/".gnuradio/config.conf";
+ if(fs::exists(homedir)) {
+ fnames.insert(fnames.begin(), homedir.string());
+ }
+
+ return fnames;
+}
+
+void
+gr_prefs::_read_files()
+{
+ std::vector<std::string> filenames = _sys_prefs_filenames();
+ std::vector<std::string>::iterator sitr;
+ char tmp[1024];
+ for(sitr = filenames.begin(); sitr != filenames.end(); sitr++) {
+ fs::ifstream fin(*sitr);
+ while(!fin.eof()) {
+ fin.getline(tmp, 1024);
+ std::string t(tmp);
+ // ignore empty lines or lines of just comments
+ if((t.size() > 0) && (t[0] != '#')) {
+ // remove any comments in the line
+ size_t hash = t.find("#");
+
+ // Use hash marks at the end of each segment as a delimiter
+ d_configs += t.substr(0, hash) + '#';
+ }
+ }
+ fin.close();
+ }
+
+ // Remove all whitespace
+ d_configs.erase(std::remove_if(d_configs.begin(), d_configs.end(), ::isspace), d_configs.end());
+}
+
+bool
+gr_prefs::has_section(const std::string &section)
+{
+ size_t t = d_configs.find("[" + section + "]#");
+ return t != std::string::npos;
+}
+
+bool
+gr_prefs::has_option(const std::string &section, const std::string &option)
+{
+ if(has_section(section)) {
+ size_t sec = d_configs.find("[" + section + "]#");
+ size_t opt = d_configs.find("#" + option + "=", sec);
+ return opt != std::string::npos;
+ }
+ else {
+ return false;
+ }
+}
+
+const std::string
+gr_prefs::get_string(const std::string &section, const std::string &option,
+ const std::string &default_val)
+{
+ std::stringstream envname;
+ std::string secname=section, optname=option;
+
+ std::transform(section.begin(), section.end(), secname.begin(), ::toupper);
+ std::transform(option.begin(), option.end(), optname.begin(), ::toupper);
+ envname << "GR_CONF_" << secname << "_" << optname;
+
+ char *v = getenv(envname.str().c_str());
+ if(v) {
+ return std::string(v);
+ }
+
+ if(has_option(section, option)) {
+ std::string optname = "#" + option + "=";
+ size_t sec = d_configs.find("[" + section + "]#");
+ size_t opt = d_configs.find(optname, sec);
+
+ size_t start = opt + optname.size();
+ size_t end = d_configs.find("#", start);
+ size_t len = end - start;
+
+ return d_configs.substr(start, len);
+ }
+ else {
+ return default_val;
+ }
+}
+
+bool
+gr_prefs::get_bool(const std::string &section, const std::string &option, bool default_val)
+{
+ if(has_option(section, option)) {
+ std::string str = get_string(section, option, "");
+ if(str == "") {
+ return default_val;
+ }
+ std::transform(str.begin(), str.end(), str.begin(), ::tolower);
+ if((str == "true") || (str == "on") || (str == "1"))
+ return true;
+ else if((str == "false") || (str == "off") || (str == "0"))
+ return false;
+ else
+ return default_val;
+ }
+ else {
+ return default_val;
+ }
+}
+
+long
+gr_prefs::get_long(const std::string &section, const std::string &option, long default_val)
+{
+ if(has_option(section, option)) {
+ std::string str = get_string(section, option, "");
+ if(str == "") {
+ return default_val;
+ }
+ std::stringstream sstr(str);
+ long n;
+ sstr >> n;
+ return n;
+ }
+ else {
+ return default_val;
+ }
+}
+
+double
+gr_prefs::get_double(const std::string &section, const std::string &option, double default_val)
+{
+ if(has_option(section, option)) {
+ std::string str = get_string(section, option, "");
+ if(str == "") {
+ return default_val;
+ }
+ std::stringstream sstr(str);
+ double n;
+ sstr >> n;
+ return n;
+ }
+ else {
+ 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
index 000000000..dc2745d16
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_prefs.h
@@ -0,0 +1,94 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifndef INCLUDED_GR_PREFS_H
+#define INCLUDED_GR_PREFS_H
+
+#include <gr_core_api.h>
+#include <string>
+#include <gruel/thread.h>
+
+/*!
+ * \brief Base class for representing user preferences a la windows INI files.
+ * \ingroup misc
+ *
+ * The real implementation is in Python, and is accessable from C++
+ * via the magic of SWIG directors.
+ */
+
+class GR_CORE_API gr_prefs
+{
+public:
+ static gr_prefs *singleton();
+ static void set_singleton(gr_prefs *p);
+
+ gr_prefs();
+ 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);
+
+ protected:
+ virtual std::vector<std::string> _sys_prefs_filenames();
+ virtual void _read_files();
+
+ private:
+ gruel::mutex d_mutex;
+ std::string d_configs;
+};
+
+
+#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
index 000000000..b21d47f3b
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_prefs.i
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+class 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
index 000000000..6430d2753
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_probe_avg_mag_sqrd_c.cc
@@ -0,0 +1,84 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include <gr_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 gnuradio::get_initial_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
index 000000000..2811677cf
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_probe_avg_mag_sqrd_c.h
@@ -0,0 +1,75 @@
+/* -*- 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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifndef INCLUDED_GR_PROBE_AVG_MAG_SQRD_C_H
+#define INCLUDED_GR_PROBE_AVG_MAG_SQRD_C_H
+
+#include <gr_core_api.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_CORE_API 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_blk
+ *
+ * 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_CORE_API 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_CORE_API 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
index 000000000..bce244c12
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_probe_avg_mag_sqrd_c.i
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,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_cf.cc b/gnuradio-core/src/lib/general/gr_probe_avg_mag_sqrd_cf.cc
new file mode 100644
index 000000000..b5946283b
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_probe_avg_mag_sqrd_cf.cc
@@ -0,0 +1,86 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005,2007,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include <gr_probe_avg_mag_sqrd_cf.h>
+#include <gr_io_signature.h>
+#include <cmath>
+
+gr_probe_avg_mag_sqrd_cf_sptr
+gr_make_probe_avg_mag_sqrd_cf(double threshold_db, double alpha)
+{
+ return gnuradio::get_initial_sptr(new gr_probe_avg_mag_sqrd_cf(threshold_db, alpha));
+}
+
+gr_probe_avg_mag_sqrd_cf::gr_probe_avg_mag_sqrd_cf (double threshold_db, double alpha)
+ : gr_sync_block ("probe_avg_mag_sqrd_cf",
+ gr_make_io_signature(1, 1, sizeof(gr_complex)),
+ gr_make_io_signature(1, 1, sizeof(float))),
+ d_iir(alpha), d_unmuted(false), d_level(0)
+{
+ set_threshold (threshold_db);
+}
+
+gr_probe_avg_mag_sqrd_cf::~gr_probe_avg_mag_sqrd_cf()
+{
+}
+
+
+int
+gr_probe_avg_mag_sqrd_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++){
+ out[i] = d_iir.prev_output();
+ 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_cf::threshold() const
+{
+ return 10 * std::log10(d_threshold);
+}
+
+void
+gr_probe_avg_mag_sqrd_cf::set_threshold(double decibels)
+{
+ // convert to absolute threshold (mag squared)
+ d_threshold = std::pow(10.0, decibels/10);
+}
+
+void
+gr_probe_avg_mag_sqrd_cf::set_alpha(double alpha)
+{
+ d_iir.set_taps(alpha);
+}
diff --git a/gnuradio-core/src/lib/general/gr_probe_avg_mag_sqrd_cf.h b/gnuradio-core/src/lib/general/gr_probe_avg_mag_sqrd_cf.h
new file mode 100644
index 000000000..bb5d1ebf9
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_probe_avg_mag_sqrd_cf.h
@@ -0,0 +1,77 @@
+/* -*- 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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifndef INCLUDED_GR_PROBE_AVG_MAG_SQRD_CF_H
+#define INCLUDED_GR_PROBE_AVG_MAG_SQRD_CF_H
+
+#include <gr_core_api.h>
+#include <gr_sync_block.h>
+#include <gr_single_pole_iir.h>
+
+class gr_probe_avg_mag_sqrd_cf;
+typedef boost::shared_ptr<gr_probe_avg_mag_sqrd_cf> gr_probe_avg_mag_sqrd_cf_sptr;
+
+GR_CORE_API gr_probe_avg_mag_sqrd_cf_sptr
+gr_make_probe_avg_mag_sqrd_cf (double threshold_db, double alpha = 0.0001);
+
+/*!
+ * \brief compute avg magnitude squared.
+ * \ingroup sink_blk
+ *
+ * input: gr_complex
+ * output: gr_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_CORE_API gr_probe_avg_mag_sqrd_cf : public gr_sync_block
+{
+ double d_threshold;
+ gr_single_pole_iir<double,double,double> d_iir;
+ bool d_unmuted;
+ double d_level;
+
+ friend GR_CORE_API gr_probe_avg_mag_sqrd_cf_sptr
+ gr_make_probe_avg_mag_sqrd_cf (double threshold_db, double alpha);
+
+ gr_probe_avg_mag_sqrd_cf (double threshold_db, double alpha);
+
+public:
+ ~gr_probe_avg_mag_sqrd_cf ();
+
+ 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_CF_H */
diff --git a/gnuradio-core/src/lib/general/gr_probe_avg_mag_sqrd_cf.i b/gnuradio-core/src/lib/general/gr_probe_avg_mag_sqrd_cf.i
new file mode 100644
index 000000000..bf76d973b
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_probe_avg_mag_sqrd_cf.i
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,probe_avg_mag_sqrd_cf);
+
+gr_probe_avg_mag_sqrd_cf_sptr
+gr_make_probe_avg_mag_sqrd_cf (double threshold_db, double alpha = 0.0001);
+
+class gr_probe_avg_mag_sqrd_cf : 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
index 000000000..4ed40743f
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_probe_avg_mag_sqrd_f.cc
@@ -0,0 +1,84 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include <gr_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 gnuradio::get_initial_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
index 000000000..b2efcc64e
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_probe_avg_mag_sqrd_f.h
@@ -0,0 +1,75 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifndef INCLUDED_GR_PROBE_AVG_MAG_SQRD_F_H
+#define INCLUDED_GR_PROBE_AVG_MAG_SQRD_F_H
+
+#include <gr_core_api.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_CORE_API 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_blk
+ *
+ * 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_CORE_API 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_CORE_API 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
index 000000000..1c63ae8e9
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_probe_avg_mag_sqrd_f.i
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,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_density_b.cc b/gnuradio-core/src/lib/general/gr_probe_density_b.cc
new file mode 100644
index 000000000..31661780a
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_probe_density_b.cc
@@ -0,0 +1,68 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008,2010 Free Software Foundation, Inc.
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <gr_probe_density_b.h>
+#include <gr_io_signature.h>
+#include <stdexcept>
+#include <iostream>
+
+gr_probe_density_b_sptr
+gr_make_probe_density_b(double alpha)
+{
+ return gnuradio::get_initial_sptr(new gr_probe_density_b(alpha));
+}
+
+gr_probe_density_b::gr_probe_density_b(double alpha)
+ : gr_sync_block("density_b",
+ gr_make_io_signature(1, 1, sizeof(char)),
+ gr_make_io_signature(0, 0, 0))
+{
+ set_alpha(alpha);
+ d_density = 1.0;
+}
+
+gr_probe_density_b::~gr_probe_density_b()
+{
+}
+
+int
+gr_probe_density_b::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];
+
+ for (int i = 0; i < noutput_items; i++)
+ d_density = d_alpha*(double)in[i] + d_beta*d_density;
+
+ return noutput_items;
+}
+
+void
+gr_probe_density_b::set_alpha(double alpha)
+{
+ d_alpha = alpha;
+ d_beta = 1.0-d_alpha;
+}
+
diff --git a/gnuradio-core/src/lib/general/gr_probe_density_b.h b/gnuradio-core/src/lib/general/gr_probe_density_b.h
new file mode 100644
index 000000000..ab84a63a9
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_probe_density_b.h
@@ -0,0 +1,73 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008 Free Software Foundation, Inc.
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifndef INCLUDED_GR_PROBE_DENSITY_B_H
+#define INCLUDED_GR_PROBE_DENSITY_B_H
+
+#include <gr_core_api.h>
+#include <gr_sync_block.h>
+
+class gr_probe_density_b;
+
+typedef boost::shared_ptr<gr_probe_density_b> gr_probe_density_b_sptr;
+
+GR_CORE_API gr_probe_density_b_sptr gr_make_probe_density_b(double alpha);
+
+/*!
+ * This block maintains a running average of the input stream and
+ * makes it available as an accessor function. The input stream
+ * is type unsigned char.
+ *
+ * If you send this block a stream of unpacked bytes, it will tell
+ * you what the bit density is.
+ *
+ * \param alpha Average filter constant
+ *
+ */
+
+class GR_CORE_API gr_probe_density_b : public gr_sync_block
+{
+private:
+ friend GR_CORE_API gr_probe_density_b_sptr gr_make_probe_density_b(double alpha);
+
+ double d_alpha;
+ double d_beta;
+ double d_density;
+
+ gr_probe_density_b(double alpha);
+
+public:
+ ~gr_probe_density_b();
+
+ /*!
+ * \brief Returns the current density value
+ */
+ double density() const { return d_density; }
+
+ /*!
+ * \brief Set the average filter constant
+ */
+ void set_alpha(double alpha);
+
+ int work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+#endif /* INCLUDED_GR_PROBE_DENSITY_B_H */
diff --git a/gnuradio-core/src/lib/general/gr_probe_density_b.i b/gnuradio-core/src/lib/general/gr_probe_density_b.i
new file mode 100644
index 000000000..ca65708af
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_probe_density_b.i
@@ -0,0 +1,36 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,probe_density_b);
+
+gr_probe_density_b_sptr gr_make_probe_density_b(double alpha);
+
+class gr_probe_density_b : public gr_sync_block
+{
+public:
+ double density() const;
+
+ void set_alpha(double alpha);
+
+private:
+ gr_probe_density_b();
+};
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
index 000000000..90eab13eb
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_pwr_squelch_cc.cc
@@ -0,0 +1,55 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2006,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_pwr_squelch_cc.h>
+
+gr_pwr_squelch_cc_sptr
+gr_make_pwr_squelch_cc(double threshold, double alpha, int ramp, bool gate)
+{
+ return gnuradio::get_initial_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
index 000000000..b2b4624f5
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_pwr_squelch_cc.h
@@ -0,0 +1,63 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_PWR_SQUELCH_CC_H
+#define INCLUDED_GR_PWR_SQUELCH_CC_H
+
+#include <gr_core_api.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_CORE_API 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 level_blk
+ */
+class GR_CORE_API 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_CORE_API 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
index 000000000..c8cafd7aa
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_pwr_squelch_cc.i
@@ -0,0 +1,42 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006,2009 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,pwr_squelch_cc);
+
+// retrieve info on the base class, without generating wrappers since
+// the base class has a pure virual method.
+%import "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
index 000000000..cfa867243
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_pwr_squelch_ff.cc
@@ -0,0 +1,55 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2006,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_pwr_squelch_ff.h>
+
+gr_pwr_squelch_ff_sptr
+gr_make_pwr_squelch_ff(double threshold, double alpha, int ramp, bool gate)
+{
+ return gnuradio::get_initial_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
index 000000000..d5148c409
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_pwr_squelch_ff.h
@@ -0,0 +1,63 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_PWR_SQUELCH_FF_H
+#define INCLUDED_GR_PWR_SQUELCH_FF_H
+
+#include <gr_core_api.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_CORE_API 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 level_blk
+ */
+class GR_CORE_API 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_CORE_API 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
index 000000000..2682f2758
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_pwr_squelch_ff.i
@@ -0,0 +1,42 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006,2009 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,pwr_squelch_ff);
+
+// retrieve info on the base class, without generating wrappers since
+// the base class has a pure virual method.
+%import "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
index 000000000..fa0958276
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_quadrature_demod_cf.cc
@@ -0,0 +1,62 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2005,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_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 gnuradio::get_initial_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
index 000000000..9f5976c97
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_quadrature_demod_cf.h
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_QUADRATURE_DEMOD_CF_H
+#define INCLUDED_GR_QUADRATURE_DEMOD_CF_H
+
+#include <gr_core_api.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_CORE_API gr_quadrature_demod_cf_sptr gr_make_quadrature_demod_cf (float gain);
+
+/*!
+ * \brief quadrature demodulator: complex in, float out
+ * \ingroup demodulation_blk
+ *
+ * This can be used to demod FM, FSK, GMSK, etc.
+ * The input is complex baseband.
+ */
+class GR_CORE_API gr_quadrature_demod_cf : public gr_sync_block
+{
+ friend GR_CORE_API gr_quadrature_demod_cf_sptr gr_make_quadrature_demod_cf (float gain);
+ gr_quadrature_demod_cf (float gain);
+
+ float d_gain;
+
+ public:
+ void set_gain(float gain) { d_gain = gain; }
+ float gain() const { return d_gain; }
+
+ 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
index 000000000..4c9168e64
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_quadrature_demod_cf.i
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC (gr, 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);
+
+public:
+ void set_gain(float gain) { d_gain = gain; }
+ float gain() const { return d_gain; }
+};
diff --git a/gnuradio-core/src/lib/general/gr_rail_ff.cc b/gnuradio-core/src/lib/general/gr_rail_ff.cc
new file mode 100644
index 000000000..cd33c10d3
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_rail_ff.cc
@@ -0,0 +1,62 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_rail_ff.h>
+#include <gr_io_signature.h>
+
+gr_rail_ff_sptr
+gr_make_rail_ff(float lo, float hi)
+{
+ return gnuradio::get_initial_sptr(new gr_rail_ff(lo, hi));
+}
+
+gr_rail_ff::gr_rail_ff(float lo, float hi)
+ : gr_sync_block("rail_ff",
+ gr_make_io_signature(1, 1, sizeof(float)),
+ gr_make_io_signature(1, 1, sizeof(float))),
+ d_lo(lo), d_hi(hi)
+{
+}
+
+int
+gr_rail_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_lo)
+ out[i] = d_lo;
+ else if (in[i] > d_hi)
+ out[i] = d_hi;
+ else
+ out[i] = in[i];
+ }
+
+ return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_rail_ff.h b/gnuradio-core/src/lib/general/gr_rail_ff.h
new file mode 100644
index 000000000..29db5b1fa
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_rail_ff.h
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_RAIL_FF_H_
+# define INCLUDED_GR_RAIL_FF_H_
+
+#include <gr_core_api.h>
+#include <gr_sync_block.h>
+
+/*!
+ * \brief clips input values to min, max
+ * \ingroup misc
+ */
+
+class gr_rail_ff;
+typedef boost::shared_ptr<gr_rail_ff> gr_rail_ff_sptr;
+
+GR_CORE_API gr_rail_ff_sptr gr_make_rail_ff(float lo, float hi);
+
+class GR_CORE_API gr_rail_ff : public gr_sync_block
+{
+ friend GR_CORE_API gr_rail_ff_sptr gr_make_rail_ff (float lo, float hi);
+
+ float d_lo, d_hi; // the constant
+ gr_rail_ff(float lo, float hi);
+
+ 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; }
+
+ 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_rail_ff.i b/gnuradio-core/src/lib/general/gr_rail_ff.i
new file mode 100644
index 000000000..bdc453516
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_rail_ff.i
@@ -0,0 +1,30 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,rail_ff);
+
+gr_rail_ff_sptr gr_make_rail_ff(float lo, float hi);
+
+class gr_rail_ff : public gr_sync_block
+{
+private:
+ gr_rail_ff(float lo, float hi);
+};
diff --git a/gnuradio-core/src/lib/general/gr_random.cc b/gnuradio-core/src/lib/general/gr_random.cc
new file mode 100644
index 000000000..323839acc
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_random.cc
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, 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.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#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
index 000000000..96a8f4418
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_random.h
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_RANDOM_H
+#define INCLUDED_GR_RANDOM_H
+
+#include <gr_core_api.h>
+#include <gr_complex.h>
+
+/*!
+ * \brief pseudo random number generator
+ * \ingroup math_blk
+ */
+class GR_CORE_API 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_random_pdu.cc b/gnuradio-core/src/lib/general/gr_random_pdu.cc
new file mode 100644
index 000000000..6d8c13614
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_random_pdu.cc
@@ -0,0 +1,84 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_random_pdu.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 <string.h>
+#include <iostream>
+#include <vector>
+
+// public constructor that returns a shared_ptr
+
+gr_random_pdu_sptr
+gr_make_random_pdu (int items_min, int items_max)
+{
+ return gnuradio::get_initial_sptr(new gr_random_pdu(items_min, items_max));
+}
+
+gr_random_pdu::gr_random_pdu (int items_min, int items_max)
+ : gr_block("random_pdu",
+ gr_make_io_signature(0, 0, 0),
+ gr_make_io_signature(0, 0, 0)),
+ urange(items_min, items_max),
+ brange(0, 255),
+ rvar(rng, urange),
+ bvar(rng, brange)
+{
+ message_port_register_out(pmt::mp("pdus"));
+ message_port_register_in(pmt::mp("generate"));
+ set_msg_handler(pmt::mp("generate"), boost::bind(&gr_random_pdu::generate_pdu, this, _1));
+}
+
+bool gr_random_pdu::start(){
+ output_random();
+ return true;
+}
+
+void gr_random_pdu::output_random(){
+
+ // pick a random vector length
+ int len = rvar();
+
+ // fill it with random bytes
+ std::vector<unsigned char> vec;
+ for(int i=0; i<len; i++){
+ vec.push_back((unsigned char) bvar());
+ }
+
+ // send the vector
+ pmt::pmt_t vecpmt( pmt::pmt_make_blob( &vec[0], len ) );
+ pmt::pmt_t pdu( pmt::pmt_cons( pmt::PMT_NIL, vecpmt ) );
+ message_port_pub( pmt::mp("pdus"), pdu );
+
+ std::cout << "sending new random vector of length " << len << "\n";
+}
+
diff --git a/gnuradio-core/src/lib/general/gr_random_pdu.h b/gnuradio-core/src/lib/general/gr_random_pdu.h
new file mode 100644
index 000000000..e6457d21b
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_random_pdu.h
@@ -0,0 +1,64 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_RANDOM_PDU_H
+#define INCLUDED_GR_RANDOM_PDU_H
+
+#include <gr_core_api.h>
+#include <gr_block.h>
+#include <gr_message.h>
+#include <gr_msg_queue.h>
+
+#include <boost/random.hpp>
+#include <boost/generator_iterator.hpp>
+
+class gr_random_pdu;
+typedef boost::shared_ptr<gr_random_pdu> gr_random_pdu_sptr;
+
+GR_CORE_API gr_random_pdu_sptr gr_make_random_pdu (int mintime, int maxtime);
+
+/*!
+ * \brief Send message at defined interval
+ * \ingroup msg_blk
+ */
+class GR_CORE_API gr_random_pdu : public gr_block
+{
+ private:
+ friend GR_CORE_API gr_random_pdu_sptr
+ gr_make_random_pdu(int mintime, int maxtime);
+
+ void output_random();
+
+ boost::mt19937 rng;
+ boost::uniform_int<> urange;
+ boost::uniform_int<> brange;
+ boost::variate_generator< boost::mt19937, boost::uniform_int<> > rvar; // pdu length
+ boost::variate_generator< boost::mt19937, boost::uniform_int<> > bvar; // pdu contents
+
+ public:
+ gr_random_pdu (int, int);
+ bool start();
+ void generate_pdu(pmt::pmt_t msg){ output_random(); }
+ void generate_pdu(){ output_random(); }
+};
+
+#endif /* INCLUDED_GR_RANDOM_PDU_H */
diff --git a/gnuradio-core/src/lib/general/gr_random_pdu.i b/gnuradio-core/src/lib/general/gr_random_pdu.i
new file mode 100644
index 000000000..045a33060
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_random_pdu.i
@@ -0,0 +1,30 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,random_pdu);
+
+%{
+#include <gr_random_pdu.h>
+%}
+
+%include "gr_random_pdu.h"
+
diff --git a/gnuradio-core/src/lib/general/gr_regenerate_bb.cc b/gnuradio-core/src/lib/general/gr_regenerate_bb.cc
new file mode 100644
index 000000000..c96cf247d
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_regenerate_bb.cc
@@ -0,0 +1,90 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_regenerate_bb.h>
+#include <gr_io_signature.h>
+
+gr_regenerate_bb_sptr
+gr_make_regenerate_bb (int period, unsigned int max_regen)
+{
+ return gnuradio::get_initial_sptr(new gr_regenerate_bb (period, max_regen));
+}
+
+gr_regenerate_bb::gr_regenerate_bb (int period, unsigned int max_regen)
+ : gr_sync_block ("regenerate_bb",
+ gr_make_io_signature (1, 1, sizeof (char)),
+ gr_make_io_signature (1, 1, sizeof (char))),
+ d_period(period),
+ d_countdown(0),
+ d_max_regen(max_regen),
+ d_regen_count(max_regen)
+{
+}
+
+void gr_regenerate_bb::set_max_regen(unsigned int regen)
+{
+ d_max_regen = regen;
+ d_countdown = 0;
+ d_regen_count = d_max_regen;
+}
+
+void gr_regenerate_bb::set_period(int period)
+{
+ d_period = period;
+ d_countdown = 0;
+ d_regen_count = d_max_regen;
+}
+
+int
+gr_regenerate_bb::work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ const char *iptr = (const char *) input_items[0];
+ char *optr = (char *) output_items[0];
+
+ for (int i = 0; i < noutput_items; i++){
+ optr[i] = 0;
+
+ if(d_regen_count < d_max_regen) {
+ d_countdown--;
+
+ if(d_countdown == 0) {
+ optr[i] = 1;
+ d_countdown = d_period;
+ d_regen_count++;
+ }
+ }
+
+ if(iptr[i] == 1) {
+ d_countdown = d_period;
+ optr[i] = 1;
+ d_regen_count = 0;
+ }
+
+ }
+ return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_regenerate_bb.h b/gnuradio-core/src/lib/general/gr_regenerate_bb.h
new file mode 100644
index 000000000..e820db69e
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_regenerate_bb.h
@@ -0,0 +1,76 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_REGENERATE_BB_H
+#define INCLUDED_GR_REGENERATE_BB_H
+
+#include <gr_core_api.h>
+#include <gr_sync_block.h>
+
+class gr_regenerate_bb;
+typedef boost::shared_ptr<gr_regenerate_bb> gr_regenerate_bb_sptr;
+
+GR_CORE_API gr_regenerate_bb_sptr gr_make_regenerate_bb (int period, unsigned int max_regen=500);
+
+/*!
+ * \brief Detect the peak of a signal and repeat every period samples
+ * \ingroup level_blk
+ *
+ * If a peak is detected, this block outputs a 1 repeated every period samples
+ * until reset by detection of another 1 on the input or stopped after max_regen
+ * regenerations have occurred.
+ *
+ * Note that if max_regen=(-1)/ULONG_MAX then the regeneration will run forever.
+ */
+class GR_CORE_API gr_regenerate_bb : public gr_sync_block
+{
+ /*!
+ * \brief Make a regenerate block
+ * \param period The number of samples between regenerations
+ * \param max_regen The maximum number of regenerations to perform; if set to
+ * ULONG_MAX, it will regenerate continuously.
+ */
+ friend GR_CORE_API gr_regenerate_bb_sptr gr_make_regenerate_bb (int period, unsigned int max_regen);
+
+ gr_regenerate_bb (int period, unsigned int max_regen);
+
+ private:
+ int d_period;
+ int d_countdown;
+ unsigned int d_max_regen;
+ unsigned int d_regen_count;
+
+ public:
+ /*! \brief Reset the maximum regeneration count; this will reset the current regen.
+ */
+ void set_max_regen(unsigned int regen);
+
+ /*! \brief Reset the period of regenerations; this will reset the current regen.
+ */
+ void set_period(int period);
+
+ 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_regenerate_bb.i b/gnuradio-core/src/lib/general/gr_regenerate_bb.i
new file mode 100644
index 000000000..064b0a278
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_regenerate_bb.i
@@ -0,0 +1,38 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,regenerate_bb)
+
+gr_regenerate_bb_sptr gr_make_regenerate_bb (int period, unsigned int max_regen=500);
+
+class gr_regenerate_bb : public gr_sync_block
+{
+ private:
+ gr_regenerate_bb (int period, unsigned int max_regen);
+
+public:
+ void set_max_regen(unsigned int regen);
+
+ /*! \brief Reset the period of regenerations; this will reset the current regen.
+ */
+ void set_period(int period);
+};
diff --git a/gnuradio-core/src/lib/general/gr_remez.cc b/gnuradio-core/src/lib/general/gr_remez.cc
new file mode 100644
index 000000000..db4789e43
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_remez.cc
@@ -0,0 +1,1033 @@
+/**************************************************************************
+ * 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., 51 Franklin Street, Boston, MA 02110-1301 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]");
+
+ // Divide by 2 to fit with the implementation that uses a
+ // sample rate of [0, 0.5] instead of [0, 1.0]
+ for (int i = 0; i < 2 * numbands; i++)
+ bands[i] = arg_bands[i] / 2;
+
+ 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
index 000000000..d875b8822
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_remez.h
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_REMEZ_H
+#define INCLUDED_GR_REMEZ_H
+
+#include <gr_core_api.h>
+#include <gr_types.h>
+#include <string>
+#include <stdexcept>
+
+/*!
+ * \brief Parks-McClellan FIR filter design.
+ *
+ * \ingroup 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.
+ */
+
+GR_CORE_API 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
index 000000000..fe3eea20d
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_remez.i
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, 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_repeat.cc b/gnuradio-core/src/lib/general/gr_repeat.cc
new file mode 100644
index 000000000..2fa82cd94
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_repeat.cc
@@ -0,0 +1,69 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_repeat.h>
+#include <gr_io_signature.h>
+#include <string.h>
+
+gr_repeat_sptr
+gr_make_repeat(size_t itemsize, int interp)
+{
+ return gnuradio::get_initial_sptr(new gr_repeat(itemsize, interp));
+}
+
+gr_repeat::gr_repeat(size_t itemsize, int interp)
+ : gr_sync_interpolator("extend",
+ gr_make_io_signature(1, 1, itemsize),
+ gr_make_io_signature(1, 1, itemsize),
+ interp),
+ d_interp(interp),
+ d_itemsize(itemsize)
+{
+}
+
+gr_repeat::~gr_repeat()
+{
+}
+
+int
+gr_repeat::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];
+
+ for (int i = 0; i < noutput_items/d_interp; i++) {
+ for (int j = 0; j < d_interp; j++) {
+ memcpy(out, in, d_itemsize);
+ out += d_itemsize;
+ }
+
+ in += d_itemsize;
+ }
+
+ return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_repeat.h b/gnuradio-core/src/lib/general/gr_repeat.h
new file mode 100644
index 000000000..548ca79f4
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_repeat.h
@@ -0,0 +1,57 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifndef INCLUDED_GR_REPEAT_H
+#define INCLUDED_GR_REPEAT_H
+
+#include <gr_core_api.h>
+#include <gr_sync_interpolator.h>
+
+class gr_repeat;
+
+typedef boost::shared_ptr<gr_repeat> gr_repeat_sptr;
+
+GR_CORE_API gr_repeat_sptr gr_make_repeat(size_t itemsize, int interp);
+
+/*!
+ * \brief Repeat a sample 'interp' times in output stream
+ * \ingroup misc_blk
+ */
+
+class GR_CORE_API gr_repeat : public gr_sync_interpolator
+{
+private:
+ friend GR_CORE_API gr_repeat_sptr gr_make_repeat(size_t itemsize, int interp);
+
+ gr_repeat(size_t itemsize, int interp);
+
+ int d_interp;
+ int d_itemsize;
+
+ public:
+ ~gr_repeat();
+
+ int work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+#endif /* INCLUDED_GR_REPEAT_H */
diff --git a/gnuradio-core/src/lib/general/gr_repeat.i b/gnuradio-core/src/lib/general/gr_repeat.i
new file mode 100644
index 000000000..c657a4906
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_repeat.i
@@ -0,0 +1,11 @@
+/* -*- c++ -*- */
+
+GR_SWIG_BLOCK_MAGIC(gr,repeat);
+
+gr_repeat_sptr gr_make_repeat(size_t itemsize, int interp);
+
+class gr_repeat : public gr_sync_interpolator
+{
+private:
+ gr_repeat();
+};
diff --git a/gnuradio-core/src/lib/general/gr_reverse.cc b/gnuradio-core/src/lib/general/gr_reverse.cc
new file mode 100644
index 000000000..08c588cb5
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_reverse.cc
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_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
index 000000000..15bf3cb73
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_reverse.h
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifndef INCLUDED_GR_REVERSE_H
+#define INCLUDED_GR_REVERSE_H
+
+#include <gr_core_api.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
index 000000000..44eb2221e
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_rms_cf.cc
@@ -0,0 +1,71 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include <gr_rms_cf.h>
+#include <gr_io_signature.h>
+#include <cmath>
+
+gr_rms_cf_sptr
+gr_make_rms_cf(double alpha)
+{
+ return gnuradio::get_initial_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
index 000000000..9e701aa6a
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_rms_cf.h
@@ -0,0 +1,61 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifndef INCLUDED_GR_RMS_CF_H
+#define INCLUDED_GR_RMS_CF_H
+
+#include <gr_core_api.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_CORE_API gr_rms_cf_sptr
+gr_make_rms_cf (double alpha = 0.0001);
+
+/*!
+ * \brief RMS average power
+ * \ingroup math_blk
+ */
+class GR_CORE_API gr_rms_cf : public gr_sync_block
+{
+ gr_single_pole_iir<double,double,double> d_iir;
+ bool d_unmuted;
+
+ friend GR_CORE_API 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
index 000000000..a668200ee
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_rms_cf.i
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,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
index 000000000..233f419cd
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_rms_ff.cc
@@ -0,0 +1,71 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include <gr_rms_ff.h>
+#include <gr_io_signature.h>
+#include <cmath>
+
+gr_rms_ff_sptr
+gr_make_rms_ff(double alpha)
+{
+ return gnuradio::get_initial_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
index 000000000..30cf7f9d9
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_rms_ff.h
@@ -0,0 +1,61 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifndef INCLUDED_GR_RMS_FF_H
+#define INCLUDED_GR_RMS_FF_H
+
+#include <gr_core_api.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_CORE_API gr_rms_ff_sptr
+gr_make_rms_ff (double alpha = 0.0001);
+
+/*!
+ * \brief RMS average power
+ * \ingroup math_blk
+ */
+class GR_CORE_API gr_rms_ff : public gr_sync_block
+{
+ gr_single_pole_iir<double,double,double> d_iir;
+ bool d_unmuted;
+
+ friend GR_CORE_API 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
index 000000000..00b03f5d4
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_rms_ff.i
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,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_scrambler_bb.cc b/gnuradio-core/src/lib/general/gr_scrambler_bb.cc
new file mode 100644
index 000000000..31eb19207
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_scrambler_bb.cc
@@ -0,0 +1,56 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_scrambler_bb.h>
+#include <gr_io_signature.h>
+
+gr_scrambler_bb_sptr
+gr_make_scrambler_bb(int mask, int seed, int len)
+{
+ return gnuradio::get_initial_sptr(new gr_scrambler_bb(mask, seed, len));
+}
+
+gr_scrambler_bb::gr_scrambler_bb(int mask, int seed, int len)
+ : gr_sync_block("scrambler_bb",
+ gr_make_io_signature (1, 1, sizeof (unsigned char)),
+ gr_make_io_signature (1, 1, sizeof (unsigned char))),
+ d_lfsr(mask, seed, len)
+{
+}
+
+int
+gr_scrambler_bb::work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ const unsigned char *in = (const unsigned char *) input_items[0];
+ unsigned char *out = (unsigned char *) output_items[0];
+
+ for (int i = 0; i < noutput_items; i++)
+ out[i] = d_lfsr.next_bit_scramble(in[i]);
+
+ return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_scrambler_bb.h b/gnuradio-core/src/lib/general/gr_scrambler_bb.h
new file mode 100644
index 000000000..edb429e0a
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_scrambler_bb.h
@@ -0,0 +1,60 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifndef INCLUDED_GR_SCRAMBLER_BB_H
+#define INCLUDED_GR_SCRAMBLER_BB_H
+
+#include <gr_core_api.h>
+#include <gr_sync_block.h>
+#include "gri_lfsr.h"
+
+class gr_scrambler_bb;
+typedef boost::shared_ptr<gr_scrambler_bb> gr_scrambler_bb_sptr;
+
+GR_CORE_API gr_scrambler_bb_sptr gr_make_scrambler_bb(int mask, int seed, int len);
+
+/*!
+ * Scramble an input stream using an LFSR. This block works on the LSB only
+ * of the input data stream, i.e., on an "unpacked binary" stream, and
+ * produces the same format on its output.
+ *
+ * \param mask Polynomial mask for LFSR
+ * \param seed Initial shift register contents
+ * \param len Shift register length
+ *
+ * \ingroup coding_blk
+ */
+
+class GR_CORE_API gr_scrambler_bb : public gr_sync_block
+{
+ friend GR_CORE_API gr_scrambler_bb_sptr gr_make_scrambler_bb(int mask, int seed, int len);
+
+ gri_lfsr d_lfsr;
+
+ gr_scrambler_bb(int mask, int seed, int len);
+
+public:
+ int work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+#endif /* INCLUDED_GR_SCRAMBLER_BB_H */
diff --git a/gnuradio-core/src/lib/general/gr_scrambler_bb.i b/gnuradio-core/src/lib/general/gr_scrambler_bb.i
new file mode 100644
index 000000000..a7ef7b364
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_scrambler_bb.i
@@ -0,0 +1,31 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,scrambler_bb);
+
+gr_scrambler_bb_sptr gr_make_scrambler_bb(int mask, int seed, int len);
+
+class gr_scrambler_bb : public gr_sync_block
+{
+private:
+ gr_scrambler_bb(int mask, int seed, int len);
+};
diff --git a/gnuradio-core/src/lib/general/gr_short_to_char.cc b/gnuradio-core/src/lib/general/gr_short_to_char.cc
new file mode 100644
index 000000000..8c146a351
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_short_to_char.cc
@@ -0,0 +1,67 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2011,2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_short_to_char.h>
+#include <gr_io_signature.h>
+#include <volk/volk.h>
+
+gr_short_to_char_sptr
+gr_make_short_to_char (size_t vlen)
+{
+ return gnuradio::get_initial_sptr(new gr_short_to_char (vlen));
+}
+
+gr_short_to_char::gr_short_to_char (size_t vlen)
+ : gr_sync_block ("gr_short_to_char",
+ gr_make_io_signature (1, 1, sizeof (short)*vlen),
+ gr_make_io_signature (1, 1, sizeof (char)*vlen)),
+ d_vlen(vlen)
+{
+ const int alignment_multiple =
+ volk_get_alignment() / sizeof(char);
+ set_alignment(std::max(1,alignment_multiple));
+}
+
+int
+gr_short_to_char::work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ const int16_t *in = (const int16_t *) input_items[0];
+ int8_t *out = (int8_t *) output_items[0];
+
+ if(is_unaligned()) {
+ volk_16i_convert_8i_u(out, in, d_vlen*noutput_items);
+ }
+ else {
+ volk_16i_convert_8i_a(out, in, d_vlen*noutput_items);
+ }
+
+ return noutput_items;
+}
+
+
+
diff --git a/gnuradio-core/src/lib/general/gr_short_to_char.h b/gnuradio-core/src/lib/general/gr_short_to_char.h
new file mode 100644
index 000000000..bf96211c7
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_short_to_char.h
@@ -0,0 +1,58 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2011,2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_SHORT_TO_CHAR_H
+#define INCLUDED_GR_SHORT_TO_CHAR_H
+
+#include <gr_core_api.h>
+#include <gr_sync_block.h>
+
+class gr_short_to_char;
+typedef boost::shared_ptr<gr_short_to_char> gr_short_to_char_sptr;
+
+GR_CORE_API gr_short_to_char_sptr
+gr_make_short_to_char (size_t vlen=1);
+
+/*!
+ * \brief Convert stream of short to a stream of float
+ * \ingroup converter_blk
+ *
+ * \param vlen vector length of data streams.
+ */
+
+class GR_CORE_API gr_short_to_char : public gr_sync_block
+{
+ private:
+ friend GR_CORE_API gr_short_to_char_sptr
+ gr_make_short_to_char (size_t vlen);
+ gr_short_to_char (size_t vlen);
+
+ size_t 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_SHORT_TO_CHAR_H */
diff --git a/gnuradio-core/src/lib/general/gr_short_to_char.i b/gnuradio-core/src/lib/general/gr_short_to_char.i
new file mode 100644
index 000000000..7389ed10b
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_short_to_char.i
@@ -0,0 +1,31 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2011,2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,short_to_char)
+
+gr_short_to_char_sptr
+gr_make_short_to_char (size_t vlen=1);
+
+class gr_short_to_char : public gr_sync_block
+{
+
+};
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
index 000000000..093d6024f
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_short_to_float.cc
@@ -0,0 +1,78 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2010,2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_short_to_float.h>
+#include <gr_io_signature.h>
+#include <volk/volk.h>
+
+gr_short_to_float_sptr
+gr_make_short_to_float (size_t vlen, float scale)
+{
+ return gnuradio::get_initial_sptr(new gr_short_to_float (vlen, scale));
+}
+
+gr_short_to_float::gr_short_to_float (size_t vlen, float scale)
+ : gr_sync_block ("gr_short_to_float",
+ gr_make_io_signature (1, 1, sizeof (short)*vlen),
+ gr_make_io_signature (1, 1, sizeof (float)*vlen)),
+ d_vlen(vlen), d_scale(scale)
+{
+ const int alignment_multiple =
+ volk_get_alignment() / sizeof(float);
+ set_alignment(std::max(1,alignment_multiple));
+}
+
+float
+gr_short_to_float::scale() const
+{
+ return d_scale;
+}
+
+void
+gr_short_to_float::set_scale(float scale)
+{
+ d_scale = scale;
+}
+
+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];
+
+ if(is_unaligned()) {
+ volk_16i_s32f_convert_32f_u(out, in, d_scale, d_vlen*noutput_items);
+ }
+ else {
+ volk_16i_s32f_convert_32f_a(out, in, d_scale, d_vlen*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
index 000000000..362549e70
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_short_to_float.h
@@ -0,0 +1,70 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_SHORT_TO_FLOAT_H
+#define INCLUDED_GR_SHORT_TO_FLOAT_H
+
+#include <gr_core_api.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_CORE_API gr_short_to_float_sptr
+gr_make_short_to_float (size_t vlen=1, float scale=1);
+
+/*!
+ * \brief Convert stream of short to a stream of float
+ * \ingroup converter_blk
+ *
+ * \param vlen vector length of data streams.
+ * \param scale a scalar divider to change the output signal scale.
+ */
+
+class GR_CORE_API gr_short_to_float : public gr_sync_block
+{
+ private:
+ friend GR_CORE_API gr_short_to_float_sptr
+ gr_make_short_to_float (size_t vlen, float scale);
+ gr_short_to_float (size_t vlen, float scale);
+
+ size_t d_vlen;
+ float d_scale;
+
+ public:
+ /*!
+ * Get the scalar divider value.
+ */
+ float scale() const;
+
+ /*!
+ * Set the scalar divider value.
+ */
+ void set_scale(float scale);
+
+ 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
index 000000000..e781e292c
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_short_to_float.i
@@ -0,0 +1,33 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,short_to_float)
+
+gr_short_to_float_sptr
+gr_make_short_to_float (size_t vlen=1, float scale=1);
+
+class gr_short_to_float : public gr_sync_block
+{
+public:
+ float scale() const;
+ void set_scale(float scale);
+};
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
index 000000000..b9209e74f
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_simple_correlator.cc
@@ -0,0 +1,237 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#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>
+#include <string.h>
+#include <cstdio>
+
+
+static const int THRESHOLD = 3;
+
+gr_simple_correlator_sptr
+gr_make_simple_correlator (int payload_bytesize)
+{
+ return gnuradio::get_initial_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_pktbuf (new unsigned char [d_bblen/GRSF_BITS_PER_BYTE]),
+ 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;
+ delete [] d_pktbuf;
+}
+
+
+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;
+
+#ifdef DEBUG_SIMPLE_CORRELATOR
+ struct debug_data {
+ float raw_data;
+ float sampled;
+ float enter_locked;
+ } debug_data;
+#endif
+
+ 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");
+ packit (d_pktbuf, d_bitbuf, d_bbi);
+ printf ("seqno %3d\n", d_pktbuf[0]);
+ memcpy (out, &d_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 ();
+#ifdef DEBUG_SIMPLE_CORRELATOR
+ debug_data.enter_locked = 1.0;
+#endif
+ }
+ 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
index 000000000..37d00c125
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_simple_correlator.h
@@ -0,0 +1,111 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_SIMPLE_CORRELATOR_H
+#define INCLUDED_GR_SIMPLE_CORRELATOR_H
+
+#include <gr_core_api.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_CORE_API gr_simple_correlator_sptr gr_make_simple_correlator (int payload_bytesize);
+
+/*!
+ * \brief inverse of gr_simple_framer (more or less)
+ * \ingroup sync_blk
+ */
+class GR_CORE_API 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
+ unsigned char *d_pktbuf; // temp packet buf
+ 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_CORE_API 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
index 000000000..24d133072
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_simple_correlator.i
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,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
index 000000000..506603bb7
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_simple_framer.cc
@@ -0,0 +1,101 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#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>
+#include <string.h>
+
+
+gr_simple_framer_sptr
+gr_make_simple_framer (int payload_bytesize)
+{
+ return gnuradio::get_initial_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
index 000000000..76a4b7bab
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_simple_framer.h
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_SIMPLE_FRAMER_H
+#define INCLUDED_GR_SIMPLE_FRAMER_H
+
+#include <gr_core_api.h>
+#include <gr_block.h>
+
+class gr_simple_framer;
+typedef boost::shared_ptr<gr_simple_framer> gr_simple_framer_sptr;
+
+GR_CORE_API gr_simple_framer_sptr gr_make_simple_framer (int payload_bytesize);
+
+/*!
+ * \brief add sync field, seq number and command field to payload
+ * \ingroup sync_blk
+ */
+class GR_CORE_API 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_CORE_API 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
index 000000000..c13ead87b
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_simple_framer.i
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,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
index 000000000..66173be42
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_simple_framer_sync.h
@@ -0,0 +1,51 @@
+/* -*- 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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_SIMPLE_FRAMER_SYNC_H
+#define INCLUDED_GR_SIMPLE_FRAMER_SYNC_H
+
+/*!
+ * \brief Here are a couple of maximum length sequences (m-sequences) that were generated by the
+ * the "mseq" matlab/octave code downloaded from:
+ * <a href="http://www.mathworks.com/matlabcentral/fileexchange/990">http://www.mathworks.com/matlabcentral/fileexchange/990</a>
+ *
+ * <pre>
+ * 31-bit m-sequence:
+ * 0110100100001010111011000111110
+ * 0x690AEC76 (padded on right with a zero)
+ *
+ * 63-bit m-sequence:
+ * 101011001101110110100100111000101111001010001100001000001111110
+ * 0xACDDA4E2F28C20FC (padded on right with a zero)
+ * </pre>
+ */
+
+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
index 000000000..5d90a3da4
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_simple_squelch_cc.cc
@@ -0,0 +1,99 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include <gr_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 gnuradio::get_initial_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
index 000000000..4bf62c7ec
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_simple_squelch_cc.h
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifndef INCLUDED_GR_SIMPLE_SQUELCH_CC_H
+#define INCLUDED_GR_SIMPLE_SQUELCH_CC_H
+
+#include <gr_core_api.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_CORE_API 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.
+ * \ingroup level_blk
+ */
+class GR_CORE_API 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_CORE_API 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
index 000000000..17b469e15
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_simple_squelch_cc.i
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,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
index 000000000..7b441bea9
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_skiphead.cc
@@ -0,0 +1,83 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005,2007,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <gr_skiphead.h>
+#include <gr_io_signature.h>
+#include <string.h>
+
+gr_skiphead::gr_skiphead (size_t itemsize, uint64_t nitems_to_skip)
+ : gr_block ("skiphead",
+ gr_make_io_signature(1, 1, itemsize),
+ gr_make_io_signature(1, 1, itemsize)),
+ d_nitems_to_skip(nitems_to_skip), d_nitems(0)
+{
+}
+
+gr_skiphead_sptr
+gr_make_skiphead (size_t itemsize, uint64_t nitems_to_skip)
+{
+ return gnuradio::get_initial_sptr(new gr_skiphead (itemsize, nitems_to_skip));
+}
+
+int
+gr_skiphead::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];
+
+ int ninput_items = std::min(ninput_items_[0], noutput_items);
+ int ii = 0; // input index
+
+ while (ii < ninput_items){
+
+ uint64_t ni_total = ii + d_nitems; // total items processed so far
+ if (ni_total < d_nitems_to_skip){ // need to skip some more
+
+ int n_to_skip = (int) std::min(d_nitems_to_skip - ni_total,
+ (uint64_t)(ninput_items - ii));
+ ii += n_to_skip;
+ }
+
+ else { // nothing left to skip. copy away
+
+ int n_to_copy = ninput_items - ii;
+ if (n_to_copy > 0){
+ size_t itemsize = output_signature()->sizeof_stream_item(0);
+ memcpy(out, in + (ii*itemsize), n_to_copy*itemsize);
+ }
+
+ d_nitems += ninput_items;
+ consume_each(ninput_items);
+ return n_to_copy;
+ }
+ }
+
+ d_nitems += ninput_items;
+ consume_each(ninput_items);
+ return 0;
+}
diff --git a/gnuradio-core/src/lib/general/gr_skiphead.h b/gnuradio-core/src/lib/general/gr_skiphead.h
new file mode 100644
index 000000000..899b40f27
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_skiphead.h
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_SKIPHEAD_H
+#define INCLUDED_GR_SKIPHEAD_H
+
+#include <gr_core_api.h>
+#include <gr_sync_block.h>
+#include <stddef.h> // size_t
+
+class gr_skiphead;
+typedef boost::shared_ptr<gr_skiphead> gr_skiphead_sptr;
+
+GR_CORE_API gr_skiphead_sptr
+gr_make_skiphead (size_t itemsize, uint64_t nitems_to_skip);
+
+
+/*!
+ * \brief skips the first N items, from then on copies items to the output
+ * \ingroup slicedice_blk
+ *
+ * Useful for building test cases and sources which have metadata or junk at the start
+ */
+
+class GR_CORE_API gr_skiphead : public gr_block
+{
+ friend GR_CORE_API gr_skiphead_sptr gr_make_skiphead (size_t itemsize, uint64_t nitems_to_skip);
+ gr_skiphead (size_t itemsize, uint64_t nitems_to_skip);
+
+ uint64_t d_nitems_to_skip;
+ uint64_t d_nitems; // total items seen
+
+ public:
+
+ int general_work(int noutput_items,
+ gr_vector_int &ninput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+#endif /* INCLUDED_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
index 000000000..3246db970
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_skiphead.i
@@ -0,0 +1,30 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005,2007,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,skiphead);
+
+gr_skiphead_sptr gr_make_skiphead (size_t itemsize, uint64_t nitems_to_skip);
+
+class gr_skiphead : public gr_block {
+ friend gr_skiphead_sptr gr_make_skiphead (size_t itemsize, uint64_t nitems_to_skip);
+ gr_skiphead (size_t itemsize, uint64_t nitems_to_skip);
+};
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
index 000000000..b32a0a695
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_squelch_base_cc.cc
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_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
index 000000000..f1814473f
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_squelch_base_cc.h
@@ -0,0 +1,59 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_SQUELCH_BASE_CC_H
+#define INCLUDED_GR_SQUELCH_BASE_CC_H
+
+#include <gr_core_api.h>
+#include <gr_block.h>
+
+class GR_CORE_API 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
index 000000000..6501b7d2b
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_squelch_base_cc.i
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <gr_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
index 000000000..4bf8cff97
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_squelch_base_ff.cc
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_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
index 000000000..eb52635b4
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_squelch_base_ff.h
@@ -0,0 +1,59 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_SQUELCH_BASE_FF_H
+#define INCLUDED_GR_SQUELCH_BASE_FF_H
+
+#include <gr_core_api.h>
+#include <gr_block.h>
+
+class GR_CORE_API 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
index 000000000..a4e5c7115
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_squelch_base_ff.i
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <gr_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_mux.cc b/gnuradio-core/src/lib/general/gr_stream_mux.cc
new file mode 100644
index 000000000..978d960b2
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_stream_mux.cc
@@ -0,0 +1,124 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_stream_mux.h>
+#include <gr_io_signature.h>
+#include <string.h>
+#include <cstdio>
+
+#define VERBOSE 0
+
+gr_stream_mux_sptr
+gr_make_stream_mux (size_t itemsize, const std::vector<int> &lengths)
+{
+ return gnuradio::get_initial_sptr(new gr_stream_mux (itemsize, lengths));
+}
+
+gr_stream_mux::gr_stream_mux (size_t itemsize, const std::vector<int> &lengths)
+ : gr_block ("stream_mux",
+ gr_make_io_signature (1, -1, itemsize),
+ gr_make_io_signature (1, 1, itemsize)),
+ d_itemsize(itemsize),
+ d_stream(0),
+ d_residual(0),
+ d_lengths(lengths)
+{
+ if(d_lengths[d_stream] == 0) {
+ increment_stream();
+ }
+ d_residual = d_lengths[d_stream];
+}
+
+gr_stream_mux::~gr_stream_mux(void)
+{
+}
+
+void
+gr_stream_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] = (d_lengths[i] == 0 ? 0 : 1);
+}
+
+void gr_stream_mux::increment_stream()
+{
+ do {
+ d_stream = (d_stream+1) % d_lengths.size();
+ } while(d_lengths[d_stream] == 0);
+
+ d_residual = d_lengths[d_stream];
+}
+
+int
+gr_stream_mux::general_work(int noutput_items,
+ gr_vector_int &ninput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ char *out = (char *) output_items[0];
+ const char *in;
+ int out_index = 0;
+ std::vector<int> input_index(d_lengths.size(), 0);
+
+ if(VERBOSE) {
+ printf("mux: nouput_items: %d d_stream: %d\n", noutput_items, d_stream);
+ for(size_t i = 0; i < d_lengths.size(); i++)
+ printf("\tninput_items[%zu]: %d\n", i, ninput_items[i]);
+ }
+
+ while (1) {
+ int r = std::min(noutput_items - out_index,
+ std::min(d_residual,
+ ninput_items[d_stream] - input_index[d_stream]));
+ if(VERBOSE) {
+ printf("mux: r=%d\n", r);
+ printf("\tnoutput_items - out_index: %d\n",
+ noutput_items - out_index);
+ printf("\td_residual: %d\n",
+ d_residual);
+ printf("\tninput_items[d_stream] - input_index[d_stream]: %d\n",
+ ninput_items[d_stream] - input_index[d_stream]);
+ }
+
+ if(r <= 0) {
+ return out_index;
+ }
+
+ in = (const char *) input_items[d_stream] + input_index[d_stream]*d_itemsize;
+
+ memcpy(&out[out_index*d_itemsize], in, r*d_itemsize);
+ out_index += r;
+ input_index[d_stream] += r;
+ d_residual -= r;
+
+ consume(d_stream, r);
+
+ if(d_residual == 0) {
+ increment_stream();
+ }
+ }
+}
diff --git a/gnuradio-core/src/lib/general/gr_stream_mux.h b/gnuradio-core/src/lib/general/gr_stream_mux.h
new file mode 100644
index 000000000..742bf082d
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_stream_mux.h
@@ -0,0 +1,93 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_STREAM_MUX_H
+#define INCLUDED_GR_STREAM_MUX_H
+
+
+#include <gr_core_api.h>
+#include <gr_block.h>
+#include <vector>
+
+/*!
+ * \brief Creates a stream muxing block to multiplex many streams into
+ * one with a specified format.
+ * \ingroup converter_blk
+ *
+ * \param itemsize the item size of the stream
+ * \param length a vector (list/tuple) specifying the number of
+ * items from each stream the mux together.
+ * Warning: this requires that at least as many items
+ * per stream are available or the system will wait
+ * indefinitely for the items.
+ *
+ */
+class gr_stream_mux;
+typedef boost::shared_ptr<gr_stream_mux> gr_stream_mux_sptr;
+
+
+
+GR_CORE_API gr_stream_mux_sptr
+gr_make_stream_mux (size_t itemsize, const std::vector<int> &lengths);
+
+
+/*!
+ * \brief Stream muxing block to multiplex many streams into
+ * one with a specified format.
+ *
+ * Muxes N streams together producing an output stream that
+ * contains N0 items from the first stream, N1 items from the second,
+ * etc. and repeats:
+ *
+ * [N0, N1, N2, ..., Nm, N0, N1, ...]
+ */
+
+class GR_CORE_API gr_stream_mux : public gr_block
+{
+ friend GR_CORE_API gr_stream_mux_sptr
+ gr_make_stream_mux (size_t itemsize, const std::vector<int> &lengths);
+
+ protected:
+ gr_stream_mux (size_t itemsize, const std::vector<int> &lengths);
+
+ private:
+ size_t d_itemsize;
+ unsigned int d_stream; // index of currently selected stream
+ int d_residual; // number if items left to put into current stream
+ gr_vector_int d_lengths; // number if items to pack per stream
+
+ void increment_stream();
+
+ public:
+ ~gr_stream_mux(void);
+
+ 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/general/gr_stream_mux.i b/gnuradio-core/src/lib/general/gr_stream_mux.i
new file mode 100644
index 000000000..7cc116a23
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_stream_mux.i
@@ -0,0 +1,42 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2006 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <vector>
+
+GR_SWIG_BLOCK_MAGIC(gr,stream_mux)
+
+gr_stream_mux_sptr
+gr_make_stream_mux (size_t itemsize,
+ const std::vector<int> &lengths);
+
+class gr_stream_mux : public gr_block
+{
+ protected:
+ gr_make_stream_mux (size_t itemsize,
+ const std::vector<int> &lengths);
+
+ 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);
+};
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
index 000000000..de72adb1d
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_stream_to_streams.cc
@@ -0,0 +1,66 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_stream_to_streams.h>
+#include <gr_io_signature.h>
+#include <string.h>
+
+gr_stream_to_streams_sptr
+gr_make_stream_to_streams (size_t item_size, size_t nstreams)
+{
+ return gnuradio::get_initial_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
index 000000000..117f57bf5
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_stream_to_streams.h
@@ -0,0 +1,56 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifndef INCLUDED_GR_STREAM_TO_STREAMS_H
+#define INCLUDED_GR_STREAM_TO_STREAMS_H
+
+#include <gr_core_api.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_CORE_API 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 slicedice_blk
+ *
+ * Converts a stream of N items into N streams of 1 item.
+ * Repeat ad infinitum.
+ */
+class GR_CORE_API gr_stream_to_streams : public gr_sync_decimator
+{
+ friend GR_CORE_API 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
index 000000000..4d324372e
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_stream_to_streams.i
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,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
index 000000000..d38cdd434
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_stream_to_vector.cc
@@ -0,0 +1,58 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2005,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_stream_to_vector.h>
+#include <gr_io_signature.h>
+#include <string.h>
+
+gr_stream_to_vector_sptr
+gr_make_stream_to_vector (size_t item_size, size_t nitems_per_block)
+{
+ return gnuradio::get_initial_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
index 000000000..362349965
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_stream_to_vector.h
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_STREAM_TO_VECTOR_H
+#define INCLUDED_GR_STREAM_TO_VECTOR_H
+
+#include <gr_core_api.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_CORE_API 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 slicedice_blk
+ */
+class GR_CORE_API gr_stream_to_vector : public gr_sync_decimator
+{
+ friend GR_CORE_API 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
index 000000000..ef867012a
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_stream_to_vector.i
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,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
index 000000000..8bce74722
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_streams_to_stream.cc
@@ -0,0 +1,68 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_streams_to_stream.h>
+#include <gr_io_signature.h>
+#include <string.h>
+
+gr_streams_to_stream_sptr
+gr_make_streams_to_stream (size_t item_size, size_t nstreams)
+{
+ return gnuradio::get_initial_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
index 000000000..f63683767
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_streams_to_stream.h
@@ -0,0 +1,56 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifndef INCLUDED_GR_STREAMS_TO_STREAM_H
+#define INCLUDED_GR_STREAMS_TO_STREAM_H
+
+#include <gr_core_api.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_CORE_API 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 slicedice_blk
+ *
+ * Convert N streams of 1 item into 1 stream of N items.
+ * Repeat ad infinitum.
+ */
+class GR_CORE_API gr_streams_to_stream : public gr_sync_interpolator
+{
+ friend GR_CORE_API 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
index 000000000..a09ded071
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_streams_to_stream.i
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,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
index 000000000..cf862ca95
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_streams_to_vector.cc
@@ -0,0 +1,64 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2005,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_streams_to_vector.h>
+#include <gr_io_signature.h>
+#include <string.h>
+
+gr_streams_to_vector_sptr
+gr_make_streams_to_vector (size_t item_size, size_t nstreams)
+{
+ return gnuradio::get_initial_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
index 000000000..1df289099
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_streams_to_vector.h
@@ -0,0 +1,54 @@
+/* -*- 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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_STREAMS_TO_VECTOR_H
+#define INCLUDED_GR_STREAMS_TO_VECTOR_H
+
+#include <gr_core_api.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_CORE_API 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 slicedice_blk
+ */
+class GR_CORE_API gr_streams_to_vector : public gr_sync_block
+{
+ friend GR_CORE_API 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
index 000000000..4d5eca45e
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_streams_to_vector.i
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,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_stretch_ff.cc b/gnuradio-core/src/lib/general/gr_stretch_ff.cc
new file mode 100644
index 000000000..e89eadf8b
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_stretch_ff.cc
@@ -0,0 +1,74 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_stretch_ff.h>
+#include <gr_io_signature.h>
+
+gr_stretch_ff_sptr
+gr_make_stretch_ff(float lo, size_t vlen)
+{
+ return gnuradio::get_initial_sptr(new gr_stretch_ff(lo, vlen));
+}
+
+gr_stretch_ff::gr_stretch_ff(float lo, size_t vlen)
+ : gr_sync_block("stretch_ff",
+ gr_make_io_signature(1, 1, vlen * sizeof(float)),
+ gr_make_io_signature(1, 1, vlen * sizeof(float))),
+ d_lo(lo), d_vlen(vlen)
+{
+}
+
+int
+gr_stretch_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 count = 0; count < noutput_items; count++) {
+ float vmax = in[0] - d_lo;
+
+ for (unsigned int i = 1; i < d_vlen; i++) {
+ float vtmp = in[i] - d_lo;
+ if (vtmp > vmax)
+ vmax = vtmp;
+ }
+
+ if (vmax != 0.0)
+ for (unsigned int i = 0; i < d_vlen; i++)
+ out[i] = d_lo * (1.0 - (in[i] - d_lo) / vmax);
+ else
+ for (unsigned int i = 0; i < d_vlen; i++)
+ out[i] = in[i];
+
+ in += d_vlen;
+ out += d_vlen;
+ }
+
+ return noutput_items;
+}
+
diff --git a/gnuradio-core/src/lib/general/gr_stretch_ff.h b/gnuradio-core/src/lib/general/gr_stretch_ff.h
new file mode 100644
index 000000000..f592c94a7
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_stretch_ff.h
@@ -0,0 +1,60 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_STRETCH_FF_H_
+# define INCLUDED_GR_STRETCH_FF_H_
+
+#include <gr_core_api.h>
+#include <gr_sync_block.h>
+
+/*!
+ * \brief adjust y-range of an input vector by mapping to range
+ * (max-of-input, stipulated-min). Primarily for spectral signature
+ * matching by normalizing spectrum dynamic ranges.
+ * \ingroup misc_blk
+ */
+
+
+class gr_stretch_ff;
+typedef boost::shared_ptr<gr_stretch_ff> gr_stretch_ff_sptr;
+
+GR_CORE_API gr_stretch_ff_sptr gr_make_stretch_ff(float lo, size_t vlen);
+
+class GR_CORE_API gr_stretch_ff : public gr_sync_block
+{
+ friend GR_CORE_API gr_stretch_ff_sptr gr_make_stretch_ff(float lo, size_t vlen);
+
+ float d_lo; // the constant
+ size_t d_vlen;
+ gr_stretch_ff(float lo, size_t vlen);
+
+ public:
+ float lo() const { return d_lo; }
+ void set_lo(float lo) { d_lo = lo; }
+ size_t vlen() const { return d_vlen; }
+
+ 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_stretch_ff.i b/gnuradio-core/src/lib/general/gr_stretch_ff.i
new file mode 100644
index 000000000..81366655e
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_stretch_ff.i
@@ -0,0 +1,31 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,stretch_ff);
+
+gr_stretch_ff_sptr gr_make_stretch_ff(float lo, size_t vlen);
+
+class gr_stretch_ff : public gr_sync_block
+{
+private:
+ gr_stretch_ff(float lo, size_t vlen);
+};
+
diff --git a/gnuradio-core/src/lib/general/gr_tag_debug.cc b/gnuradio-core/src/lib/general/gr_tag_debug.cc
new file mode 100644
index 000000000..ecf1b65e1
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_tag_debug.cc
@@ -0,0 +1,104 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_tag_debug.h>
+#include <gr_io_signature.h>
+#include <iostream>
+#include <iomanip>
+
+gr_tag_debug_sptr
+gr_make_tag_debug(size_t sizeof_stream_item, const std::string &name)
+{
+ return gnuradio::get_initial_sptr
+ (new gr_tag_debug(sizeof_stream_item, name));
+}
+
+gr_tag_debug::gr_tag_debug(size_t sizeof_stream_item, const std::string &name)
+ : gr_sync_block("tag_debug",
+ gr_make_io_signature(1, -1, sizeof_stream_item),
+ gr_make_io_signature(0, 0, 0)),
+ d_name(name), d_display(true)
+{
+}
+
+std::vector<gr_tag_t>
+gr_tag_debug::current_tags()
+{
+ gruel::scoped_lock l(d_mutex);
+ return d_tags;
+}
+
+void
+gr_tag_debug::set_display(bool d)
+{
+ gruel::scoped_lock l(d_mutex);
+ d_display = d;
+}
+
+int
+gr_tag_debug::work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ gruel::scoped_lock l(d_mutex);
+
+ std::stringstream sout;
+ if(d_display) {
+ sout << std::endl
+ << "----------------------------------------------------------------------";
+ sout << std::endl << "Tag Debug: " << d_name << std::endl;
+ }
+
+ uint64_t abs_N, end_N;
+ for(size_t i = 0; i < input_items.size(); i++) {
+ abs_N = nitems_read(i);
+ end_N = abs_N + (uint64_t)(noutput_items);
+
+ d_tags.clear();
+ get_tags_in_range(d_tags, i, abs_N, end_N);
+
+ if(d_display) {
+ sout << "Input Stream: " << std::setw(2) << std::setfill('0') << i << std::setfill(' ') << std::endl;
+ for(d_tags_itr = d_tags.begin(); d_tags_itr != d_tags.end(); d_tags_itr++) {
+ sout << std::setw(10) << "Offset: " << d_tags_itr->offset
+ << std::setw(10) << "Source: " << (pmt::pmt_is_symbol(d_tags_itr->srcid) ? pmt::pmt_symbol_to_string(d_tags_itr->srcid) : "n/a")
+ << std::setw(10) << "Key: " << pmt::pmt_symbol_to_string(d_tags_itr->key)
+ << std::setw(10) << "Value: ";
+ sout << d_tags_itr->value << std::endl;
+ }
+ }
+ }
+
+ if(d_display) {
+ sout << "----------------------------------------------------------------------";
+ sout << std::endl;
+
+ if(d_tags.size() > 0)
+ std::cout << sout.str();
+ }
+
+ return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_tag_debug.h b/gnuradio-core/src/lib/general/gr_tag_debug.h
new file mode 100644
index 000000000..57578884a
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_tag_debug.h
@@ -0,0 +1,85 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_TAG_DEBUG_H
+#define INCLUDED_GR_TAG_DEBUG_H
+
+#include <gr_core_api.h>
+#include <gr_sync_block.h>
+#include <gruel/thread.h>
+#include <stddef.h>
+
+class gr_tag_debug;
+typedef boost::shared_ptr<gr_tag_debug> gr_tag_debug_sptr;
+
+GR_CORE_API gr_tag_debug_sptr
+gr_make_tag_debug(size_t sizeof_stream_item, const std::string &name);
+
+/*!
+ * \brief Bit bucket that prints out any tag received.
+ * \ingroup sink_blk
+ *
+ * This block collects all tags sent to it on all input ports and
+ * displays them to stdout in a formatted way. The \p name parameter
+ * is used to identify which debug sink generated the tag, so when
+ * connecting a block to this debug sink, an appropriate name is
+ * something that identifies the input block.
+ *
+ * This block otherwise acts as a NULL sink in that items from the
+ * input stream are ignored. It is designed to be able to attach to
+ * any block and watch all tags streaming out of that block for
+ * debugging purposes.
+ *
+ * The tags from the last call to this work function are stored and
+ * can be retrieved using the function 'current_tags'.
+ */
+class GR_CORE_API gr_tag_debug : public gr_sync_block
+{
+ private:
+ friend GR_CORE_API gr_tag_debug_sptr
+ gr_make_tag_debug(size_t sizeof_stream_item, const std::string &name);
+ gr_tag_debug(size_t sizeof_stream_item, const std::string &name);
+
+ std::string d_name;
+ std::vector<gr_tag_t> d_tags;
+ std::vector<gr_tag_t>::iterator d_tags_itr;
+ bool d_display;
+ gruel::mutex d_mutex;
+
+ public:
+ /*!
+ * \brief Returns a vector of gr_tag_t items as of the last call to
+ * work.
+ */
+ std::vector<gr_tag_t> current_tags();
+
+ /*!
+ * \brief Set the display of tags to stdout on/off.
+ */
+ void set_display(bool d);
+
+ int work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+#endif /* INCLUDED_GR_TAG_DEBUG_H */
diff --git a/gnuradio-core/src/lib/general/gr_tag_debug.i b/gnuradio-core/src/lib/general/gr_tag_debug.i
new file mode 100644
index 000000000..3af1bdcfe
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_tag_debug.i
@@ -0,0 +1,35 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,tag_debug)
+
+%include <gr_tags.i>
+
+gr_tag_debug_sptr
+gr_make_tag_debug(size_t sizeof_stream_item, const std::string &name);
+
+class gr_tag_debug : public gr_sync_block
+{
+public:
+ std::vector<gr_tag_t> current_tags();
+ void set_display(bool d);
+};
diff --git a/gnuradio-core/src/lib/general/gr_test.cc b/gnuradio-core/src/lib/general/gr_test.cc
new file mode 100644
index 000000000..cd5ef8361
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_test.cc
@@ -0,0 +1,177 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006,2008,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_test.h>
+#include <gr_io_signature.h>
+#include <stdexcept>
+#include <iostream>
+#include <string.h>
+
+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 gnuradio::get_initial_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 until 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
index 000000000..caeba4c51
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_test.h
@@ -0,0 +1,195 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_TEST_H
+#define INCLUDED_GR_TEST_H
+
+#include <gr_core_api.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_CORE_API 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 misc
+ *
+ * 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_CORE_API 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_CORE_API 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
index 000000000..d81025011
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_test.i
@@ -0,0 +1,64 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+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
index 000000000..04f38f7b2
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_test_types.h
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifndef INCLUDED_GR_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
index 000000000..952613151
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_threshold_ff.cc
@@ -0,0 +1,67 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+// 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 gnuradio::get_initial_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
index 000000000..678f8b1d2
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_threshold_ff.h
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_THRESHOLD_FF_H
+#define INCLUDED_GR_THRESHOLD_FF_H
+
+#include <gr_core_api.h>
+#include <gr_sync_block.h>
+
+class gr_threshold_ff;
+typedef boost::shared_ptr<gr_threshold_ff> gr_threshold_ff_sptr;
+
+GR_CORE_API gr_threshold_ff_sptr gr_make_threshold_ff (float lo, float hi, float initial_state=0);
+
+/*!
+ * \brief Please fix my documentation
+ * \ingroup misc_blk
+ */
+class GR_CORE_API gr_threshold_ff : public gr_sync_block
+{
+ friend GR_CORE_API 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
index 000000000..7584feea8
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_threshold_ff.i
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,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
index 000000000..040ab5220
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_throttle.cc
@@ -0,0 +1,89 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005-2011 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_throttle.h>
+#include <gr_io_signature.h>
+#include <cstring>
+#include <boost/thread/thread.hpp>
+
+class gr_throttle_impl : public gr_throttle{
+public:
+ gr_throttle_impl(size_t itemsize):
+ gr_sync_block("throttle",
+ gr_make_io_signature(1, 1, itemsize),
+ gr_make_io_signature(1, 1, itemsize)),
+ d_itemsize(itemsize)
+ {
+ /* NOP */
+ }
+
+ void set_sample_rate(double rate){
+ //changing the sample rate performs a reset of state params
+ d_start = boost::get_system_time();
+ d_total_samples = 0;
+ d_samps_per_tick = rate/boost::posix_time::time_duration::ticks_per_second();
+ d_samps_per_us = rate/1e6;
+ }
+
+ int work (
+ int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items
+ ){
+ //calculate the expected number of samples to have passed through
+ boost::system_time now = boost::get_system_time();
+ boost::int64_t ticks = (now - d_start).ticks();
+ uint64_t expected_samps = uint64_t(d_samps_per_tick*ticks);
+
+ //if the expected samples was less, we need to throttle back
+ if (d_total_samples > expected_samps){
+ boost::this_thread::sleep(boost::posix_time::microseconds(
+ long((d_total_samples - expected_samps)/d_samps_per_us)
+ ));
+ }
+
+ //copy all samples output[i] <= input[i]
+ const char *in = (const char *) input_items[0];
+ char *out = (char *) output_items[0];
+ std::memcpy(out, in, noutput_items * d_itemsize);
+ d_total_samples += noutput_items;
+ return noutput_items;
+ }
+
+private:
+ boost::system_time d_start;
+ size_t d_itemsize;
+ uint64_t d_total_samples;
+ double d_samps_per_tick, d_samps_per_us;
+};
+
+gr_throttle::sptr
+gr_make_throttle(size_t itemsize, double samples_per_sec)
+{
+ gr_throttle::sptr throttle(new gr_throttle_impl(itemsize));
+ throttle->set_sample_rate(samples_per_sec);
+ return throttle;
+}
diff --git a/gnuradio-core/src/lib/general/gr_throttle.h b/gnuradio-core/src/lib/general/gr_throttle.h
new file mode 100644
index 000000000..876d6d826
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_throttle.h
@@ -0,0 +1,50 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005-2011 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifndef INCLUDED_GR_THROTTLE_H
+#define INCLUDED_GR_THROTTLE_H
+
+#include <gr_core_api.h>
+#include <gr_sync_block.h>
+
+/*!
+ * \brief throttle flow of samples such that the average rate does not exceed samples_per_sec.
+ * \ingroup misc_blk
+ *
+ * input: one stream of itemsize; output: one stream of itemsize
+ *
+ * N.B. this should only be used in GUI apps where there is no other
+ * rate limiting block. It is not intended nor effective at precisely
+ * controlling the rate of samples. That should be controlled by a
+ * source or sink tied to sample clock. E.g., a USRP or audio card.
+ */
+class GR_CORE_API gr_throttle : virtual public gr_sync_block
+{
+public:
+ typedef boost::shared_ptr<gr_throttle> sptr;
+
+ //! Sets the sample rate in samples per second
+ virtual void set_sample_rate(double rate) = 0;
+};
+
+GR_CORE_API gr_throttle::sptr gr_make_throttle(size_t itemsize, double samples_per_sec);
+
+#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
index 000000000..5ba32de6e
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_throttle.i
@@ -0,0 +1,29 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005-2011 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+%{
+#include <gr_throttle.h>
+%}
+
+GR_SWIG_BLOCK_MAGIC(gr,throttle);
+
+%include <gr_throttle.h>
diff --git a/gnuradio-core/src/lib/general/gr_transcendental.cc b/gnuradio-core/src/lib/general/gr_transcendental.cc
new file mode 100644
index 000000000..c1482491b
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_transcendental.cc
@@ -0,0 +1,153 @@
+/*
+ * Copyright 2011 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <gr_transcendental.h>
+#include <gr_io_signature.h>
+#include <stdexcept>
+#include <complex> //complex math
+#include <cmath> //real math
+#include <map>
+
+/***********************************************************************
+ * work function creation and registration
+ **********************************************************************/
+typedef int(*work_fcn_type)(int, gr_vector_const_void_star &, gr_vector_void_star &);
+struct map_val_type{
+ work_fcn_type work_fcn;
+ size_t io_size;
+};
+typedef std::map<std::string, map_val_type> map_type;
+
+//construct map on first use idiom
+static map_type &get_map(void){
+ static map_type map;
+ return map;
+}
+
+//static initialization of this object registers a function
+struct gr_transcendental_registrant{
+ gr_transcendental_registrant(
+ const std::string &key,
+ const work_fcn_type &work_fcn,
+ const size_t io_size
+ ){
+ map_val_type val;
+ val.work_fcn = work_fcn;
+ val.io_size = io_size;
+ get_map()[key] = val;
+ }
+};
+
+//macro to create a work function and register it
+#define REGISTER_FUNCTION(__fcn__, __type__, __key__) \
+ static int __key__ ## _work( \
+ int noutput_items, \
+ gr_vector_const_void_star &input_items, \
+ gr_vector_void_star &output_items \
+ ){ \
+ const __type__ *in = (const __type__ *) input_items[0]; \
+ __type__ *out = (__type__ *) output_items[0]; \
+ for (size_t i = 0; i < size_t(noutput_items); i++){ \
+ out[i] = std::__fcn__(in[i]); \
+ } \
+ return noutput_items; \
+ } \
+ gr_transcendental_registrant __key__ ## _registrant(#__key__, &__key__ ## _work, sizeof(__type__));
+
+//register work functions for real types
+#define REGISTER_REAL_FUNCTIONS(__fcn__) \
+ REGISTER_FUNCTION(__fcn__, float, __fcn__ ## _float) \
+ REGISTER_FUNCTION(__fcn__, double, __fcn__ ## _double)
+
+//register work functions for complex types
+#define REGISTER_COMPLEX_FUNCTIONS(__fcn__) \
+ REGISTER_FUNCTION(__fcn__, std::complex<float>, __fcn__ ## _complex_float) \
+ REGISTER_FUNCTION(__fcn__, std::complex<double>, __fcn__ ## _complex_double)
+
+//register both complex and real
+#define REGISTER_FUNCTIONS(__fcn__) \
+ REGISTER_REAL_FUNCTIONS(__fcn__) \
+ REGISTER_COMPLEX_FUNCTIONS(__fcn__)
+
+//create and register transcendental work functions
+REGISTER_FUNCTIONS(cos)
+REGISTER_FUNCTIONS(sin)
+REGISTER_FUNCTIONS(tan)
+REGISTER_REAL_FUNCTIONS(acos)
+REGISTER_REAL_FUNCTIONS(asin)
+REGISTER_REAL_FUNCTIONS(atan)
+REGISTER_FUNCTIONS(cosh)
+REGISTER_FUNCTIONS(sinh)
+REGISTER_FUNCTIONS(tanh)
+REGISTER_FUNCTIONS(exp)
+REGISTER_FUNCTIONS(log)
+REGISTER_FUNCTIONS(log10)
+REGISTER_FUNCTIONS(sqrt)
+
+/***********************************************************************
+ * implementation block simply calls into the function pointer
+ **********************************************************************/
+class gr_transcendental_impl : public gr_transcendental{
+public:
+ gr_transcendental_impl(
+ const work_fcn_type &work_fcn, const size_t io_size
+ ):
+ gr_sync_block(
+ "transcendental",
+ gr_make_io_signature(1, 1, io_size),
+ gr_make_io_signature(1, 1, io_size)
+ ),
+ _work_fcn(work_fcn)
+ {
+ // NOP
+ }
+
+ int work(
+ int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items
+ ){
+ return _work_fcn(noutput_items, input_items, output_items);
+ }
+
+private:
+ const work_fcn_type &_work_fcn;
+};
+
+/***********************************************************************
+ * factory function to make transcendental block
+ **********************************************************************/
+gr_transcendental::sptr gr_make_transcendental(
+ const std::string &name,
+ const std::string &type
+){
+ //search for an entry in the map
+ const std::string key = name + "_" + type;
+ const bool has_key = get_map().count(key) != 0;
+ if (!has_key) throw std::runtime_error(
+ "could not find transcendental function for " + key
+ );
+
+ //make a new block with found work function
+ return gr_transcendental::sptr(new gr_transcendental_impl(
+ get_map()[key].work_fcn, get_map()[key].io_size
+ ));
+}
diff --git a/gnuradio-core/src/lib/general/gr_transcendental.h b/gnuradio-core/src/lib/general/gr_transcendental.h
new file mode 100644
index 000000000..9841a53e9
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_transcendental.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2011 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_TRANSCENDENTAL_H
+#define INCLUDED_GR_TRANSCENDENTAL_H
+
+#include <gr_core_api.h>
+#include <gr_sync_block.h>
+#include <string>
+
+/*!
+ * \brief A block that performs various transcendental math operations.
+ *
+ * Possible function names can be found in the cmath library.
+ * IO may be either complex or real, double or single precision.
+ *
+ * Possible type strings: float, double, complex_float, complex_double
+ *
+ * output[i] = trans_fcn(input[i])
+ */
+class GR_CORE_API gr_transcendental : virtual public gr_sync_block{
+public:
+ typedef boost::shared_ptr<gr_transcendental> sptr;
+};
+
+GR_CORE_API gr_transcendental::sptr gr_make_transcendental(
+ const std::string &name,
+ const std::string &type = "float"
+);
+
+#endif /* INCLUDED_GR_TRANSCENDENTAL_H */
diff --git a/gnuradio-core/src/lib/general/gr_transcendental.i b/gnuradio-core/src/lib/general/gr_transcendental.i
new file mode 100644
index 000000000..6acdb10b7
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_transcendental.i
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2011 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+////////////////////////////////////////////////////////////////////////
+// block headers
+////////////////////////////////////////////////////////////////////////
+%{
+#include <gr_transcendental.h>
+%}
+
+////////////////////////////////////////////////////////////////////////
+// block magic
+////////////////////////////////////////////////////////////////////////
+GR_SWIG_BLOCK_MAGIC(gr,transcendental)
+%include <gr_transcendental.h>
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
index 000000000..981a93440
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_uchar_to_float.cc
@@ -0,0 +1,55 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_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 gnuradio::get_initial_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
index 000000000..c02601cca
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_uchar_to_float.h
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_UCHAR_TO_FLOAT_H
+#define INCLUDED_GR_UCHAR_TO_FLOAT_H
+
+#include <gr_core_api.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_CORE_API gr_uchar_to_float_sptr
+gr_make_uchar_to_float ();
+
+/*!
+ * \brief Convert stream of unsigned chars to a stream of float
+ * \ingroup converter_blk
+ */
+
+class GR_CORE_API gr_uchar_to_float : public gr_sync_block
+{
+ friend GR_CORE_API 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
index 000000000..b6cc35329
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_uchar_to_float.i
@@ -0,0 +1,30 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+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
index 000000000..00b88e972
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_unpack_k_bits_bb.cc
@@ -0,0 +1,70 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#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 gnuradio::get_initial_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
index 000000000..c3ea28d3f
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_unpack_k_bits_bb.h
@@ -0,0 +1,56 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_UNPACK_K_BITS_BB_H
+#define INCLUDED_GR_UNPACK_K_BITS_BB_H
+
+#include <gr_core_api.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_CORE_API 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.
+ * \ingroup converter_blk
+ */
+class GR_CORE_API gr_unpack_k_bits_bb : public gr_sync_interpolator
+{
+ private:
+ friend GR_CORE_API 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
index 000000000..de0f4b33e
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_unpack_k_bits_bb.i
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,unpack_k_bits_bb)
+
+gr_unpack_k_bits_bb_sptr gr_make_unpack_k_bits_bb (int k) throw(std::exception);
+
+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_vco.h b/gnuradio-core/src/lib/general/gr_vco.h
new file mode 100644
index 000000000..3ceaf15dd
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_vco.h
@@ -0,0 +1,94 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifndef _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)
+ * \ingroup misc
+ */
+
+//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
index 000000000..0899bc77e
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_vco_f.cc
@@ -0,0 +1,58 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_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 gnuradio::get_initial_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
index 000000000..83f6a9773
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_vco_f.h
@@ -0,0 +1,75 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifndef INCLUDED_GR_VCO_F_H
+#define INCLUDED_GR_VCO_F_H
+
+#include <gr_core_api.h>
+#include <gr_sync_block.h>
+#include <gr_fxpt_vco.h>
+
+/*!
+ * \brief VCO - Voltage controlled oscillator
+ * \ingroup misc
+ *
+ * \param sampling_rate sampling rate (Hz)
+ * \param sensitivity units are radians/sec/volt
+ * \param amplitude output amplitude
+ */
+class gr_vco_f;
+typedef boost::shared_ptr<gr_vco_f> gr_vco_f_sptr;
+
+
+GR_CORE_API gr_vco_f_sptr gr_make_vco_f(double sampling_rate, double sensitivity, double amplitude);
+
+/*!
+ * \brief VCO - Voltage controlled oscillator
+ * \ingroup modulator_blk
+ *
+ * input: float stream of control voltages; output: float oscillator output
+ */
+class GR_CORE_API gr_vco_f : public gr_sync_block
+{
+ friend GR_CORE_API 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
index 000000000..8ecf31411
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_vco_f.i
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,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_map.cc b/gnuradio-core/src/lib/general/gr_vector_map.cc
new file mode 100644
index 000000000..2a13efb06
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_vector_map.cc
@@ -0,0 +1,117 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_vector_map.h>
+#include <gr_io_signature.h>
+#include <string.h>
+
+std::vector<int>
+get_in_sizeofs(size_t item_size, std::vector<size_t> in_vlens)
+{
+ std::vector<int> in_sizeofs;
+ for(unsigned int i = 0; i < in_vlens.size(); i++) {
+ in_sizeofs.push_back(in_vlens[i]*item_size);
+ }
+ return in_sizeofs;
+}
+
+std::vector<int>
+get_out_sizeofs(size_t item_size,
+ std::vector< std::vector< std::vector<size_t> > > mapping)
+{
+ std::vector<int> out_sizeofs;
+ for(unsigned int i = 0; i < mapping.size(); i++) {
+ out_sizeofs.push_back(mapping[i].size()*item_size);
+ }
+ return out_sizeofs;
+}
+
+gr_vector_map_sptr
+gr_make_vector_map (size_t item_size, std::vector<size_t> in_vlens,
+ std::vector< std::vector< std::vector<size_t> > > mapping)
+{
+ return gnuradio::get_initial_sptr(new gr_vector_map(item_size,
+ in_vlens,
+ mapping));
+}
+
+gr_vector_map::gr_vector_map(size_t item_size, std::vector<size_t> in_vlens,
+ std::vector< std::vector< std::vector<size_t> > > mapping)
+ : gr_sync_block("vector_map",
+ gr_make_io_signaturev(in_vlens.size(), in_vlens.size(),
+ get_in_sizeofs(item_size, in_vlens)),
+ gr_make_io_signaturev(mapping.size(), mapping.size(),
+ get_out_sizeofs(item_size, mapping))),
+ d_item_size(item_size), d_in_vlens(in_vlens)
+{
+ set_mapping(mapping);
+}
+
+void
+gr_vector_map::set_mapping(std::vector< std::vector< std::vector<size_t> > > mapping) {
+ // Make sure the contents of the mapping vectors are possible.
+ for(unsigned int i=0; i<mapping.size(); i++) {
+ for(unsigned int j=0; j<mapping[i].size(); j++) {
+ if(mapping[i][j].size() != 2) {
+ throw std::runtime_error("Mapping must be of the form (out_mapping_stream1, out_mapping_stream2, ...), where out_mapping_stream1 is of the form (mapping_element1, mapping_element2, ...), where mapping_element1 is of the form (input_stream, input_element). This error is raised because a mapping_element vector does not contain exactly 2 items.");
+ }
+ unsigned int s = mapping[i][j][0];
+ unsigned int index = mapping[i][j][1];
+ if(s >= d_in_vlens.size()) {
+ throw std::runtime_error("Stream numbers in mapping must be less than the number of input streams.");
+ }
+ if((index < 0) || (index >= d_in_vlens[s])) {
+ throw std::runtime_error ("Indices in mapping must be greater than 0 and less than the input vector lengths.");
+ }
+ }
+ }
+ gruel::scoped_lock guard(d_mutex);
+ d_mapping = mapping;
+}
+
+int
+gr_vector_map::work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ const char **inv = (const char **) &input_items[0];
+ char **outv = (char **) &output_items[0];
+
+ for(unsigned int n = 0; n < (unsigned int)(noutput_items); n++) {
+ for(unsigned int i = 0; i < d_mapping.size(); i++) {
+ unsigned int out_vlen = d_mapping[i].size();
+ for(unsigned int j = 0; j < out_vlen; j++) {
+ unsigned int s = d_mapping[i][j][0];
+ unsigned int k = d_mapping[i][j][1];
+ memcpy(outv[i] + out_vlen*d_item_size*n +
+ d_item_size*j, inv[s] + d_in_vlens[s]*d_item_size*n +
+ k*d_item_size, d_item_size);
+ }
+ }
+ }
+
+ return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_vector_map.h b/gnuradio-core/src/lib/general/gr_vector_map.h
new file mode 100644
index 000000000..f5492b1e3
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_vector_map.h
@@ -0,0 +1,83 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_VECTOR_MAP_H
+#define INCLUDED_GR_VECTOR_MAP_H
+
+#include <vector>
+#include <gr_core_api.h>
+#include <gr_sync_interpolator.h>
+#include <gruel/thread.h>
+
+class gr_vector_map;
+typedef boost::shared_ptr<gr_vector_map> gr_vector_map_sptr;
+
+GR_CORE_API gr_vector_map_sptr
+gr_make_vector_map (size_t item_size, std::vector<size_t> in_vlens,
+ std::vector< std::vector< std::vector<size_t> > > mapping);
+
+/*!
+ * \brief Maps elements from a set of input vectors to a set of output vectors.
+ *
+ * If in[i] is the input vector in the i'th stream then the output
+ * vector in the j'th stream is:
+ *
+ * out[j][k] = in[mapping[j][k][0]][mapping[j][k][1]]
+ *
+ * That is mapping is of the form (out_stream1_mapping,
+ * out_stream2_mapping, ...) and out_stream1_mapping is of the form
+ * (element1_mapping, element2_mapping, ...) and element1_mapping is
+ * of the form (in_stream, in_element).
+ *
+ * \param item_size (integer) size of vector elements
+ *
+ * \param in_vlens (vector of integers) number of elements in each
+ * input vector
+ *
+ * \param mapping (vector of vectors of vectors of integers) how to
+ * map elements from input to output vectors
+ *
+ * \ingroup slicedice_blk
+ */
+class GR_CORE_API gr_vector_map : public gr_sync_block
+{
+ friend GR_CORE_API gr_vector_map_sptr
+ gr_make_vector_map(size_t item_size, std::vector<size_t> in_vlens,
+ std::vector< std::vector< std::vector<size_t> > > mapping);
+ size_t d_item_size;
+ std::vector<size_t> d_in_vlens;
+ std::vector< std::vector< std::vector<size_t> > > d_mapping;
+ gruel::mutex d_mutex; // mutex to protect set/work access
+
+ protected:
+ gr_vector_map(size_t item_size, std::vector<size_t> in_vlens,
+ std::vector< std::vector< std::vector<size_t> > > mapping);
+
+ public:
+ int work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+
+ void set_mapping(std::vector< std::vector< std::vector<size_t> > > mapping);
+};
+
+#endif /* INCLUDED_GR_VECTOR_MAP_H */
diff --git a/gnuradio-core/src/lib/general/gr_vector_map.i b/gnuradio-core/src/lib/general/gr_vector_map.i
new file mode 100644
index 000000000..e9fa3f27e
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_vector_map.i
@@ -0,0 +1,28 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr, vector_map);
+
+%template() std::vector<size_t>;
+%template() std::vector< std::vector< std::vector<size_t> > >;
+
+%include "gr_vector_map.h"
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
index 000000000..621b7ec58
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_vector_to_stream.cc
@@ -0,0 +1,58 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2006,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_vector_to_stream.h>
+#include <gr_io_signature.h>
+#include <string.h>
+
+gr_vector_to_stream_sptr
+gr_make_vector_to_stream (size_t item_size, size_t nitems_per_block)
+{
+ return gnuradio::get_initial_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
index 000000000..9fc8030f5
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_vector_to_stream.h
@@ -0,0 +1,54 @@
+/* -*- 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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_VECTOR_TO_STREAM_H
+#define INCLUDED_GR_VECTOR_TO_STREAM_H
+
+#include <gr_core_api.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_CORE_API 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 slicedice_blk
+ */
+class GR_CORE_API gr_vector_to_stream : public gr_sync_interpolator
+{
+ friend GR_CORE_API 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
index 000000000..99776eeb8
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_vector_to_stream.i
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,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
index 000000000..7ab352a4f
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_vector_to_streams.cc
@@ -0,0 +1,64 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2005,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_vector_to_streams.h>
+#include <gr_io_signature.h>
+#include <string.h>
+
+gr_vector_to_streams_sptr
+gr_make_vector_to_streams (size_t item_size, size_t nstreams)
+{
+ return gnuradio::get_initial_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
index 000000000..8db423053
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_vector_to_streams.h
@@ -0,0 +1,54 @@
+/* -*- 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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_VECTOR_TO_STREAMS_H
+#define INCLUDED_GR_VECTOR_TO_STREAMS_H
+
+#include <gr_core_api.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_CORE_API 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 slicedice_blk
+ */
+class GR_CORE_API gr_vector_to_streams : public gr_sync_block
+{
+ friend GR_CORE_API 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
index 000000000..d4123135b
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_vector_to_streams.i
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,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
index 000000000..7433ee41b
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gri_add_const_ss.h
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GRI_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
index 000000000..3b5ee1824
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gri_add_const_ss_generic.cc
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gri_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_agc2_cc.h b/gnuradio-core/src/lib/general/gri_agc2_cc.h
new file mode 100644
index 000000000..55aa19b9a
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gri_agc2_cc.h
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef _GRI_AGC2_CC_H_
+#define _GRI_AGC2_CC_H_
+
+#include <gr_core_api.h>
+#include <math.h>
+
+/*!
+ * \brief high performance Automatic Gain Control class
+ *
+ * For Power the absolute value of the complex number is used.
+ */
+class GR_CORE_API gri_agc2_cc {
+
+ public:
+ gri_agc2_cc (float attack_rate = 1e-1, float decay_rate = 1e-2, float reference = 1.0,
+ float gain = 1.0, float max_gain = 0.0)
+ : _attack_rate(attack_rate), _decay_rate(decay_rate), _reference(reference),
+ _gain(gain), _max_gain(max_gain) {};
+
+ float decay_rate () const { return _decay_rate; }
+ float attack_rate () const { return _attack_rate; }
+ float reference () const { return _reference; }
+ float gain () const { return _gain; }
+ float max_gain() const { return _max_gain; }
+
+ void set_decay_rate (float rate) { _decay_rate = rate; }
+ void set_attack_rate (float rate) { _attack_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;
+
+ float tmp = -_reference + sqrt(output.real()*output.real() +
+ output.imag()*output.imag());
+ float rate = _decay_rate;
+ if((tmp) > _gain)
+ rate = _attack_rate;
+ _gain -= tmp*rate;
+
+#if 0
+ fprintf(stdout, "rate = %f\ttmp = %f\t gain = %f\n", rate, tmp, _gain);
+#endif
+
+ // Not sure about this; will blow up if _gain < 0 (happens when rates are too high),
+ // but is this the solution?
+ if (_gain < 0.0)
+ _gain = 10e-5;
+
+ 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 _attack_rate; // attack rate for fast changing signals
+ float _decay_rate; // decay rate for slow changing signals
+ float _reference; // reference value
+ float _gain; // current gain
+ float _max_gain; // max allowable gain
+};
+
+#endif /* _GRI_AGC2_CC_H_ */
diff --git a/gnuradio-core/src/lib/general/gri_agc2_cc.i b/gnuradio-core/src/lib/general/gri_agc2_cc.i
new file mode 100644
index 000000000..08716c6ed
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gri_agc2_cc.i
@@ -0,0 +1,47 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <math.h>
+
+/*!
+ * \brief high performance Automatic Gain Control class with attack and decay rates
+ *
+ * For Power the absolute value of the complex number is used.
+ */
+
+
+class gri_agc2_cc {
+
+ public:
+ gri_agc2_cc (float attack_rate = 1e-1, float decay_rate = 1e-2, float reference = 1.0,
+ float gain = 1.0, float max_gain = 0.0);
+ float decay_rate ();
+ float attack_rate ();
+ float reference ();
+ float gain ();
+ float max_gain ();
+ void set_decay_rate (float rate);
+ void set_attack_rate (float rate);
+ void set_reference (float reference);
+ void set_gain (float gain);
+ void set_max_gain(float max_gain);
+ };
diff --git a/gnuradio-core/src/lib/general/gri_agc2_ff.h b/gnuradio-core/src/lib/general/gri_agc2_ff.h
new file mode 100644
index 000000000..a8b46bec5
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gri_agc2_ff.h
@@ -0,0 +1,90 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002,2006 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef _GRI_AGC2_FF_H_
+#define _GRI_AGC2_FF_H_
+
+#include <gr_core_api.h>
+#include <math.h>
+
+/*!
+ * \brief high performance Automatic Gain Control class with attack and decay rate
+ *
+ * Power is approximated by absolute value
+ */
+
+class GR_CORE_API gri_agc2_ff {
+
+ public:
+ gri_agc2_ff (float attack_rate = 1e-1, float decay_rate = 1e-2, float reference = 1.0,
+ float gain = 1.0, float max_gain = 0.0)
+ : _attack_rate(attack_rate), _decay_rate(decay_rate), _reference(reference),
+ _gain(gain), _max_gain(max_gain) {};
+
+ float attack_rate () const { return _attack_rate; }
+ float decay_rate () const { return _decay_rate; }
+ float reference () const { return _reference; }
+ float gain () const { return _gain; }
+ float max_gain () const { return _max_gain; }
+
+ void set_attack_rate (float rate) { _attack_rate = rate; }
+ void set_decay_rate (float rate) { _decay_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;
+
+ float tmp = (fabsf(output)) - _reference;
+ float rate = _decay_rate;
+ if(fabsf(tmp) > _gain)
+ rate = _attack_rate;
+ _gain -= tmp*rate;
+
+#if 0
+ fprintf(stdout, "rate = %f\ttmp = %f\t gain = %f\n", rate, tmp, _gain);
+#endif
+
+ // Not sure about this
+ if (_gain < 0.0)
+ _gain = 10e-5;
+
+ 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 _attack_rate; // attack_rate for fast changing signals
+ float _decay_rate; // decay rate for slow changing signals
+ float _reference; // reference value
+ float _gain; // current gain
+ float _max_gain; // maximum gain
+};
+
+#endif /* _GRI_AGC2_FF_H_ */
diff --git a/gnuradio-core/src/lib/general/gri_agc2_ff.i b/gnuradio-core/src/lib/general/gri_agc2_ff.i
new file mode 100644
index 000000000..9f97d8f0d
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gri_agc2_ff.i
@@ -0,0 +1,47 @@
+/* -*- 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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <math.h>
+
+/*!
+ * \brief high performance Automatic Gain Control class
+ *
+ * Power is approximated by absolute value
+ */
+
+
+class gri_agc2_ff {
+
+ public:
+ gri_agc2_ff (float attack_rate = 1e-1, float decay_rate = 1e-2,
+ float reference = 1.0, float gain = 1.0, float max_gain = 0.0);
+ float attack_rate ();
+ float decay_rate ();
+ float reference ();
+ float gain ();
+ float max_gain ();
+ void set_attack_rate (float rate);
+ void set_decay_rate (float rate);
+ void set_reference (float reference);
+ void set_gain (float gain);
+ void set_max_gain (float max_gain);
+ };
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
index 000000000..90edc5dcd
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gri_agc_cc.h
@@ -0,0 +1,75 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GRI_AGC_CC_H
+#define INCLUDED_GRI_AGC_CC_H
+
+#include <gr_core_api.h>
+#include <math.h>
+
+/*!
+ * \brief high performance Automatic Gain Control class
+ *
+ * For Power the absolute value of the complex number is used.
+ */
+
+class GR_CORE_API 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 += _rate * (_reference - sqrt(output.real()*output.real() +
+ output.imag()*output.imag()));
+ 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 /* INCLUDED_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
index 000000000..d3dd9b61b
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gri_agc_cc.i
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <math.h>
+
+/*!
+ * \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_agc_ff.h b/gnuradio-core/src/lib/general/gri_agc_ff.h
new file mode 100644
index 000000000..1c233c746
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gri_agc_ff.h
@@ -0,0 +1,72 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002,2006 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GRI_AGC_FF_H
+#define INCLUDED_GRI_AGC_FF_H
+
+#include <gr_core_api.h>
+#include <math.h>
+
+/*!
+ * \brief high performance Automatic Gain Control class
+ *
+ * Power is approximated by absolute value
+ */
+class GR_CORE_API gri_agc_ff {
+
+ public:
+ gri_agc_ff (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 /* INCLUDED_GRI_AGC_FF_H */
+
diff --git a/gnuradio-core/src/lib/general/gri_agc_ff.i b/gnuradio-core/src/lib/general/gri_agc_ff.i
new file mode 100644
index 000000000..df4acf7af
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gri_agc_ff.i
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <math.h>
+
+/*!
+ * \brief high performance Automatic Gain Control class
+ *
+ * Power is approximated by absolute value
+ */
+
+class gri_agc_ff {
+
+ public:
+ gri_agc_ff (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_char_to_float.cc b/gnuradio-core/src/lib/general/gri_char_to_float.cc
new file mode 100644
index 000000000..fd9a6636a
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gri_char_to_float.cc
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <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
index 000000000..8bd3bfde7
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gri_char_to_float.h
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GRI_CHAR_TO_FLOAT_H
+#define INCLUDED_GRI_CHAR_TO_FLOAT_H
+
+#include <gr_core_api.h>
+
+/*
+ * convert array of chars to floats
+ */
+GR_CORE_API void gri_char_to_float (const char *in, float *out, int nsamples);
+
+
+#endif /* INCLUDED_GRI_CHAR_TO_FLOAT_H */ \ No newline at end of file
diff --git a/gnuradio-core/src/lib/general/gri_control_loop.cc b/gnuradio-core/src/lib/general/gri_control_loop.cc
new file mode 100644
index 000000000..bb3c4a326
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gri_control_loop.cc
@@ -0,0 +1,210 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2011 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gri_control_loop.h>
+#include <gr_math.h>
+#include <stdexcept>
+
+#define M_TWOPI (2.0f*M_PI)
+
+gri_control_loop::gri_control_loop(float loop_bw,
+ float max_freq, float min_freq)
+ : d_phase(0), d_freq(0), d_max_freq(max_freq), d_min_freq(min_freq)
+{
+ // Set the damping factor for a critically damped system
+ d_damping = sqrtf(2.0f)/2.0f;
+
+ // Set the bandwidth, which will then call update_gains()
+ set_loop_bandwidth(loop_bw);
+}
+
+gri_control_loop::~gri_control_loop()
+{
+}
+
+void
+gri_control_loop::update_gains()
+{
+ float denom = (1.0 + 2.0*d_damping*d_loop_bw + d_loop_bw*d_loop_bw);
+ d_alpha = (4*d_damping*d_loop_bw) / denom;
+ d_beta = (4*d_loop_bw*d_loop_bw) / denom;
+}
+
+void
+gri_control_loop::advance_loop(float error)
+{
+ d_freq = d_freq + d_beta * error;
+ d_phase = d_phase + d_freq + d_alpha * error;
+}
+
+
+void
+gri_control_loop::phase_wrap()
+{
+ while(d_phase>M_TWOPI)
+ d_phase -= M_TWOPI;
+ while(d_phase<-M_TWOPI)
+ d_phase += M_TWOPI;
+}
+
+void
+gri_control_loop::frequency_limit()
+{
+ if (d_freq > d_max_freq)
+ d_freq = d_max_freq;
+ else if (d_freq < d_min_freq)
+ d_freq = d_min_freq;
+}
+
+/*******************************************************************
+ SET FUNCTIONS
+*******************************************************************/
+
+void
+gri_control_loop::set_loop_bandwidth(float bw)
+{
+ if(bw < 0) {
+ throw std::out_of_range ("gri_control_loop: invalid bandwidth. Must be >= 0.");
+ }
+
+ d_loop_bw = bw;
+ update_gains();
+}
+
+void
+gri_control_loop::set_damping_factor(float df)
+{
+ if(df < 0 || df > 1.0) {
+ throw std::out_of_range ("gri_control_loop: invalid damping factor. Must be in [0,1].");
+ }
+
+ d_damping = df;
+ update_gains();
+}
+
+void
+gri_control_loop::set_alpha(float alpha)
+{
+ if(alpha < 0 || alpha > 1.0) {
+ throw std::out_of_range ("gri_control_loop: invalid alpha. Must be in [0,1].");
+ }
+ d_alpha = alpha;
+}
+
+void
+gri_control_loop::set_beta(float beta)
+{
+ if(beta < 0 || beta > 1.0) {
+ throw std::out_of_range ("gri_control_loop: invalid beta. Must be in [0,1].");
+ }
+ d_beta = beta;
+}
+
+void
+gri_control_loop::set_frequency(float freq)
+{
+ if(freq > d_max_freq)
+ d_freq = d_min_freq;
+ else if(freq < d_min_freq)
+ d_freq = d_max_freq;
+ else
+ d_freq = freq;
+}
+
+void
+gri_control_loop::set_phase(float phase)
+{
+ d_phase = phase;
+ while(d_phase>M_TWOPI)
+ d_phase -= M_TWOPI;
+ while(d_phase<-M_TWOPI)
+ d_phase += M_TWOPI;
+}
+
+void
+gri_control_loop::set_max_freq(float freq)
+{
+ d_max_freq = freq;
+}
+
+void
+gri_control_loop::set_min_freq(float freq)
+{
+ d_min_freq = freq;
+}
+
+/*******************************************************************
+ GET FUNCTIONS
+*******************************************************************/
+
+
+float
+gri_control_loop::get_loop_bandwidth() const
+{
+ return d_loop_bw;
+}
+
+float
+gri_control_loop::get_damping_factor() const
+{
+ return d_damping;
+}
+
+float
+gri_control_loop::get_alpha() const
+{
+ return d_alpha;
+}
+
+float
+gri_control_loop::get_beta() const
+{
+ return d_beta;
+}
+
+float
+gri_control_loop::get_frequency() const
+{
+ return d_freq;
+}
+
+float
+gri_control_loop::get_phase() const
+{
+ return d_phase;
+}
+
+float
+gri_control_loop::get_max_freq() const
+{
+ return d_max_freq;
+}
+
+float
+gri_control_loop::get_min_freq() const
+{
+ return d_min_freq;
+}
diff --git a/gnuradio-core/src/lib/general/gri_control_loop.h b/gnuradio-core/src/lib/general/gri_control_loop.h
new file mode 100644
index 000000000..304857ac7
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gri_control_loop.h
@@ -0,0 +1,230 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2011 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef GRI_CONTROL_LOOP
+#define GRI_CONTROL_LOOP
+
+#include <gr_core_api.h>
+
+class GR_CORE_API gri_control_loop
+{
+ protected:
+ float d_phase, d_freq;
+ float d_max_freq, d_min_freq;
+ float d_damping, d_loop_bw;
+ float d_alpha, d_beta;
+
+ public:
+ gri_control_loop(float loop_bw, float max_freq, float min_freq);
+ virtual ~gri_control_loop();
+
+ /*! \brief update the system gains from the loop bandwidth and damping factor
+ *
+ * This function updates the system gains based on the loop
+ * bandwidth and damping factor of the system.
+ * These two factors can be set separately through their own
+ * set functions.
+ */
+ void update_gains();
+
+ /*! \brief update the system gains from the loop bandwidth and damping factor
+ *
+ * This function updates the system gains based on the loop
+ * bandwidth and damping factor of the system.
+ * These two factors can be set separately through their own
+ * set functions.
+ */
+ void advance_loop(float error);
+
+ /*! \brief Keep the phase between -2pi and 2pi
+ *
+ * This function keeps the phase between -2pi and 2pi. If the phase
+ * is greater than 2pi by d, it wraps around to be -2pi+d; similarly if
+ * it is less than -2pi by d, it wraps around to 2pi-d.
+ *
+ * This function should be called after advance_loop to keep the phase
+ * in a good operating region. It is set as a separate method in case
+ * another way is desired as this is fairly heavy-handed.
+ */
+ void phase_wrap();
+
+ /*! \brief Keep the frequency between d_min_freq and d_max_freq
+ *
+ * This function keeps the frequency between d_min_freq and d_max_freq.
+ * If the frequency is greater than d_max_freq, it is set to d_max_freq.
+ * If the frequency is less than d_min_freq, it is set to d_min_freq.
+ *
+ * This function should be called after advance_loop to keep the frequency
+ * in the specified region. It is set as a separate method in case
+ * another way is desired as this is fairly heavy-handed.
+ */
+ void frequency_limit();
+
+ /*******************************************************************
+ SET FUNCTIONS
+ *******************************************************************/
+
+ /*!
+ * \brief Set the loop bandwidth
+ *
+ * Set the loop filter's bandwidth to \p bw. This should be between
+ * 2*pi/200 and 2*pi/100 (in rads/samp). It must also be a positive
+ * number.
+ *
+ * When a new damping factor is set, the gains, alpha and beta, of the loop
+ * are recalculated by a call to update_gains().
+ *
+ * \param bw (float) new bandwidth
+ *
+ */
+ void set_loop_bandwidth(float bw);
+
+ /*!
+ * \brief Set the loop damping factor
+ *
+ * Set the loop filter's damping factor to \p df. The damping factor
+ * should be sqrt(2)/2.0 for critically damped systems.
+ * Set it to anything else only if you know what you are doing. It must
+ * be a number between 0 and 1.
+ *
+ * When a new damping factor is set, the gains, alpha and beta, of the loop
+ * are recalculated by a call to update_gains().
+ *
+ * \param df (float) new damping factor
+ *
+ */
+ void set_damping_factor(float df);
+
+ /*!
+ * \brief Set the loop gain alpha
+ *
+ * Set's the loop filter's alpha gain parameter.
+ *
+ * This value should really only be set by adjusting the loop bandwidth
+ * and damping factor.
+ *
+ * \param alpha (float) new alpha gain
+ *
+ */
+ void set_alpha(float alpha);
+
+ /*!
+ * \brief Set the loop gain beta
+ *
+ * Set's the loop filter's beta gain parameter.
+ *
+ * This value should really only be set by adjusting the loop bandwidth
+ * and damping factor.
+ *
+ * \param beta (float) new beta gain
+ *
+ */
+ void set_beta(float beta);
+
+ /*!
+ * \brief Set the control loop's frequency.
+ *
+ * Set's the control loop's frequency. While this is normally updated by the
+ * inner loop of the algorithm, it could be useful to manually initialize,
+ * set, or reset this under certain circumstances.
+ *
+ * \param freq (float) new frequency
+ *
+ */
+ void set_frequency(float freq);
+
+ /*!
+ * \brief Set the control loop's phase.
+ *
+ * Set's the control loop's phase. While this is normally updated by the
+ * inner loop of the algorithm, it could be useful to manually initialize,
+ * set, or reset this under certain circumstances.
+ *
+ * \param phase (float) new phase
+ *
+ */
+ void set_phase(float phase);
+
+ /*!
+ * \brief Set the control loop's maximum frequency.
+ *
+ * Set the maximum frequency the control loop can track.
+ *
+ * \param freq (float) new max frequency
+ */
+ void set_max_freq(float freq);
+
+ /*!
+ * \brief Set the control loop's minimum frequency.
+ *
+ * Set the minimum frequency the control loop can track.
+ *
+ * \param freq (float) new min frequency
+ */
+ void set_min_freq(float freq);
+
+ /*******************************************************************
+ GET FUNCTIONS
+ *******************************************************************/
+
+ /*!
+ * \brief Returns the loop bandwidth
+ */
+ float get_loop_bandwidth() const;
+
+ /*!
+ * \brief Returns the loop damping factor
+ */
+ float get_damping_factor() const;
+
+ /*!
+ * \brief Returns the loop gain alpha
+ */
+ float get_alpha() const;
+
+ /*!
+ * \brief Returns the loop gain beta
+ */
+ float get_beta() const;
+
+ /*!
+ * \brief Get the control loop's frequency estimate
+ */
+ float get_frequency() const;
+
+ /*!
+ * \brief Get the control loop's phase estimate
+ */
+ float get_phase() const;
+
+ /*!
+ * \brief Get the control loop's maximum frequency.
+ */
+ float get_max_freq() const;
+
+ /*!
+ * \brief Get the control loop's minimum frequency.
+ */
+ float get_min_freq() const;
+};
+
+#endif /* GRI_CONTROL_LOOP */
diff --git a/gnuradio-core/src/lib/general/gri_control_loop.i b/gnuradio-core/src/lib/general/gri_control_loop.i
new file mode 100644
index 000000000..8a23207e5
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gri_control_loop.i
@@ -0,0 +1,57 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2011 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+
+class gri_control_loop
+{
+ public:
+ gri_control_loop(float loop_bw, float max_freq, float min_freq);
+ virtual ~gri_control_loop();
+
+ void update_gains();
+ void advance_loop(float error);
+ void phase_wrap();
+ void frequency_limit();
+
+ /*******************************************************************
+ SET FUNCTIONS
+ *******************************************************************/
+
+ void set_loop_bandwidth(float bw);
+ void set_damping_factor(float df);
+ void set_alpha(float alpha);
+ void set_beta(float beta);
+ void set_frequency(float freq);
+ void set_phase(float phase);
+
+
+ /*******************************************************************
+ GET FUNCTIONS
+ *******************************************************************/
+
+ float get_loop_bandwidth() const;
+ float get_damping_factor() const;
+ float get_alpha() const;
+ float get_beta() const;
+ float get_frequency() const;
+ float get_phase() const;
+};
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
index 000000000..d9270c435
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gri_debugger_hook.cc
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <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
index 000000000..c871c7bf6
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gri_debugger_hook.h
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GRI_DEBUGGER_HOOK_H
+#define INCLUDED_GRI_DEBUGGER_HOOK_H
+
+#include <gr_core_api.h>
+
+GR_CORE_API void gri_debugger_hook ();
+
+#endif /* INCLUDED_GRI_DEBUGGER_HOOK_H */ \ No newline at end of file
diff --git a/gnuradio-core/src/lib/general/gri_fft.cc b/gnuradio-core/src/lib/general/gri_fft.cc
new file mode 100644
index 000000000..68e7e6951
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gri_fft.cc
@@ -0,0 +1,330 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003,2008,2011 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <gri_fft.h>
+#include <gr_sys_paths.h>
+#include <fftw3.h>
+
+#ifdef _MSC_VER //http://www.fftw.org/install/windows.html#DLLwisdom
+static void my_fftw_write_char(char c, void *f) { fputc(c, (FILE *) f); }
+#define fftw_export_wisdom_to_file(f) fftw_export_wisdom(my_fftw_write_char, (void*) (f))
+#define fftwf_export_wisdom_to_file(f) fftwf_export_wisdom(my_fftw_write_char, (void*) (f))
+#define fftwl_export_wisdom_to_file(f) fftwl_export_wisdom(my_fftw_write_char, (void*) (f))
+
+static int my_fftw_read_char(void *f) { return fgetc((FILE *) f); }
+#define fftw_import_wisdom_from_file(f) fftw_import_wisdom(my_fftw_read_char, (void*) (f))
+#define fftwf_import_wisdom_from_file(f) fftwf_import_wisdom(my_fftw_read_char, (void*) (f))
+#define fftwl_import_wisdom_from_file(f) fftwl_import_wisdom(my_fftw_read_char, (void*) (f))
+#endif //_MSC_VER
+
+#include <gr_complex.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <cassert>
+#include <stdexcept>
+
+#include <boost/filesystem/operations.hpp>
+#include <boost/filesystem/path.hpp>
+namespace fs = boost::filesystem;
+
+gr_complex *
+gri_fft_malloc_complex(int size)
+{
+ return (gr_complex*)fftwf_malloc(sizeof(gr_complex)*size);
+}
+
+float *
+gri_fft_malloc_float(int size)
+{
+ return (float*)fftwf_malloc(sizeof(float)*size);
+}
+
+void
+gri_fft_free(void *b)
+{
+ fftwf_free(b);
+}
+
+boost::mutex &
+gri_fft_planner::mutex()
+{
+ static boost::mutex s_planning_mutex;
+
+ return s_planning_mutex;
+}
+
+static const char *
+wisdom_filename ()
+{
+ static fs::path path;
+ path = fs::path(gr_appdata_path()) / ".gr_fftw_wisdom";
+ return path.string().c_str();
+}
+
+static void
+gri_fftw_import_wisdom ()
+{
+ const 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);
+ }
+ }
+}
+
+static void
+gri_fftw_config_threading (int nthreads)
+{
+ static int fftw_threads_inited = 0;
+
+#ifdef FFTW3F_THREADS
+ if (fftw_threads_inited == 0)
+ {
+ fftw_threads_inited = 1;
+ fftwf_init_threads();
+ }
+
+ fftwf_plan_with_nthreads(nthreads);
+#endif
+}
+
+static void
+gri_fftw_export_wisdom ()
+{
+ const 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);
+ }
+}
+
+// ----------------------------------------------------------------
+
+gri_fft_complex::gri_fft_complex (int fft_size, bool forward, int nthreads)
+{
+ // Hold global mutex during plan construction and destruction.
+ gri_fft_planner::scoped_lock lock(gri_fft_planner::mutex());
+
+ 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");
+ }
+
+ d_nthreads = nthreads;
+ gri_fftw_config_threading (nthreads);
+ 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 ()
+{
+ // Hold global mutex during plan construction and destruction.
+ gri_fft_planner::scoped_lock lock(gri_fft_planner::mutex());
+
+ fftwf_destroy_plan ((fftwf_plan) d_plan);
+ fftwf_free (d_inbuf);
+ fftwf_free (d_outbuf);
+}
+
+void
+gri_fft_complex::set_nthreads(int n)
+{
+ if (n <= 0)
+ throw std::out_of_range ("gri_fftw: invalid number of threads");
+ d_nthreads = n;
+
+#ifdef FFTW3F_THREADS
+ fftwf_plan_with_nthreads(d_nthreads);
+#endif
+}
+
+void
+gri_fft_complex::execute ()
+{
+ fftwf_execute ((fftwf_plan) d_plan);
+}
+
+// ----------------------------------------------------------------
+
+gri_fft_real_fwd::gri_fft_real_fwd (int fft_size, int nthreads)
+{
+ // Hold global mutex during plan construction and destruction.
+ gri_fft_planner::scoped_lock lock(gri_fft_planner::mutex());
+
+ 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");
+ }
+
+ d_nthreads = nthreads;
+ gri_fftw_config_threading (nthreads);
+ 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 ()
+{
+ // Hold global mutex during plan construction and destruction.
+ gri_fft_planner::scoped_lock lock(gri_fft_planner::mutex());
+
+ fftwf_destroy_plan ((fftwf_plan) d_plan);
+ fftwf_free (d_inbuf);
+ fftwf_free (d_outbuf);
+}
+
+void
+gri_fft_real_fwd::set_nthreads(int n)
+{
+ if (n <= 0)
+ throw std::out_of_range ("gri_fftw: invalid number of threads");
+ d_nthreads = n;
+
+#ifdef FFTW3F_THREADS
+ fftwf_plan_with_nthreads(d_nthreads);
+#endif
+}
+
+void
+gri_fft_real_fwd::execute ()
+{
+ fftwf_execute ((fftwf_plan) d_plan);
+}
+
+// ----------------------------------------------------------------
+
+gri_fft_real_rev::gri_fft_real_rev (int fft_size, int nthreads)
+{
+ // Hold global mutex during plan construction and destruction.
+ gri_fft_planner::scoped_lock lock(gri_fft_planner::mutex());
+
+ 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");
+ }
+
+ d_nthreads = nthreads;
+ gri_fftw_config_threading (nthreads);
+ gri_fftw_import_wisdom (); // load prior wisdom from disk
+
+ // 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.
+ 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::set_nthreads(int n)
+{
+ if (n <= 0)
+ throw std::out_of_range ("gri_fftw: invalid number of threads");
+ d_nthreads = n;
+
+#ifdef FFTW3F_THREADS
+ fftwf_plan_with_nthreads(d_nthreads);
+#endif
+}
+
+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
index 000000000..65e9d046e
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gri_fft.h
@@ -0,0 +1,185 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003,2008 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifndef _GRI_FFT_H_
+#define _GRI_FFT_H_
+
+/*
+ * Wrappers for FFTW single precision 1d dft
+ */
+
+#include <gr_core_api.h>
+#include <gr_complex.h>
+#include <boost/thread.hpp>
+
+/*! \brief Helper function for allocating complex fft buffers
+ */
+gr_complex* gri_fft_malloc_complex(int size);
+
+/*! \brief Helper function for allocating float fft buffers
+ */
+float* gri_fft_malloc_float(int size);
+
+/*! \brief Helper function for freeing fft buffers
+ */
+void gri_fft_free(void *b);
+
+
+/*!
+ * \brief Export reference to planner mutex for those apps that
+ * want to use FFTW w/o using the gri_fftw* classes.
+ */
+class GR_CORE_API gri_fft_planner {
+public:
+ typedef boost::mutex::scoped_lock scoped_lock;
+ /*!
+ * Return reference to planner mutex
+ */
+ static boost::mutex &mutex();
+};
+
+/*!
+ * \brief FFT: complex in, complex out
+ * \ingroup misc
+ */
+class GR_CORE_API gri_fft_complex {
+ int d_fft_size;
+ int d_nthreads;
+ gr_complex *d_inbuf;
+ gr_complex *d_outbuf;
+ void *d_plan;
+
+public:
+ gri_fft_complex (int fft_size, bool forward = true, int nthreads=1);
+ 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; }
+
+ /*!
+ * Set the number of threads to use for caclulation.
+ */
+ void set_nthreads(int n);
+
+ /*!
+ * Get the number of threads being used by FFTW
+ */
+ int nthreads() const { return d_nthreads; }
+
+ /*!
+ * compute FFT. The input comes from inbuf, the output is placed in outbuf.
+ */
+ void execute ();
+};
+
+/*!
+ * \brief FFT: real in, complex out
+ * \ingroup misc
+ */
+class GR_CORE_API gri_fft_real_fwd {
+ int d_fft_size;
+ int d_nthreads;
+ float *d_inbuf;
+ gr_complex *d_outbuf;
+ void *d_plan;
+
+public:
+ gri_fft_real_fwd (int fft_size, int nthreads=1);
+ 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; }
+
+ /*!
+ * Set the number of threads to use for caclulation.
+ */
+ void set_nthreads(int n);
+
+ /*!
+ * Get the number of threads being used by FFTW
+ */
+ int nthreads() const { return d_nthreads; }
+
+ /*!
+ * compute FFT. The input comes from inbuf, the output is placed in outbuf.
+ */
+ void execute ();
+};
+
+/*!
+ * \brief FFT: complex in, float out
+ * \ingroup misc
+ */
+class GR_CORE_API gri_fft_real_rev {
+ int d_fft_size;
+ int d_nthreads;
+ gr_complex *d_inbuf;
+ float *d_outbuf;
+ void *d_plan;
+
+public:
+ gri_fft_real_rev (int fft_size, int nthreads=1);
+ 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; }
+
+ /*!
+ * Set the number of threads to use for caclulation.
+ */
+ void set_nthreads(int n);
+
+ /*!
+ * Get the number of threads being used by FFTW
+ */
+ int nthreads() const { return d_nthreads; }
+
+ /*!
+ * 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
index 000000000..3e779b0e7
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gri_float_to_char.cc
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#define _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
index 000000000..172a7da65
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gri_float_to_char.h
@@ -0,0 +1,33 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GRI_FLOAT_TO_CHAR_H
+#define INCLUDED_GRI_FLOAT_TO_CHAR_H
+
+#include <gr_core_api.h>
+
+/*!
+ * convert array of floats to chars with rounding and saturation.
+ */
+GR_CORE_API 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_int.cc b/gnuradio-core/src/lib/general/gri_float_to_int.cc
new file mode 100644
index 000000000..525ea675d
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gri_float_to_int.cc
@@ -0,0 +1,47 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2011 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#define _ISOC9X_SOURCE
+#include <gri_float_to_int.h>
+#include <math.h>
+#include <stdint.h>
+
+static const int64_t MAX_INT = 2147483647; // (2^31)-1
+static const int64_t MIN_INT = -2147483647; // -(2^31)-1
+
+
+void
+gri_float_to_int (const float *in, int *out, float scale, int nsamples)
+{
+ for (int i = 0; i < nsamples; i++){
+ int64_t r = llrintf(scale * in[i]);
+ if (r < MIN_INT)
+ r = MIN_INT;
+ else if (r > MAX_INT)
+ r = MAX_INT;
+ out[i] = static_cast<int>(r);
+ }
+}
diff --git a/gnuradio-core/src/lib/general/gri_float_to_int.h b/gnuradio-core/src/lib/general/gri_float_to_int.h
new file mode 100644
index 000000000..84f72a420
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gri_float_to_int.h
@@ -0,0 +1,33 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2011 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GRI_FLOAT_TO_INT_H
+#define INCLUDED_GRI_FLOAT_TO_INT_H
+
+#include <gr_core_api.h>
+
+/*!
+ * convert array of floats to int with rounding and saturation.
+ */
+GR_CORE_API void gri_float_to_int (const float *in, int *out, float scale, int nsamples);
+
+#endif /* INCLUDED_GRI_FLOAT_TO_INT_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
index 000000000..4508e37a7
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gri_float_to_short.cc
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#define _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
index 000000000..b9cdf685b
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gri_float_to_short.h
@@ -0,0 +1,33 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GRI_FLOAT_TO_SHORT_H
+#define INCLUDED_GRI_FLOAT_TO_SHORT_H
+
+#include <gr_core_api.h>
+
+/*!
+ * convert array of floats to shorts with rounding and saturation.
+ */
+GR_CORE_API 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
index 000000000..9ea42a31b
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gri_float_to_uchar.cc
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#define _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
index 000000000..e24b1973f
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gri_float_to_uchar.h
@@ -0,0 +1,33 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GRI_FLOAT_TO_UCHAR_H
+#define INCLUDED_GRI_FLOAT_TO_UCHAR_H
+
+#include <gr_core_api.h>
+
+/*!
+ * convert array of floats to unsigned chars with rounding and saturation.
+ */
+GR_CORE_API 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_glfsr.cc b/gnuradio-core/src/lib/general/gri_glfsr.cc
new file mode 100644
index 000000000..ba6951882
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gri_glfsr.cc
@@ -0,0 +1,67 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <gri_glfsr.h>
+#include <stdexcept>
+
+static int s_polynomial_masks[] = {
+ 0x00000000,
+ 0x00000001, // x^1 + 1
+ 0x00000003, // x^2 + x^1 + 1
+ 0x00000005, // x^3 + x^1 + 1
+ 0x00000009, // x^4 + x^1 + 1
+ 0x00000012, // x^5 + x^2 + 1
+ 0x00000021, // x^6 + x^1 + 1
+ 0x00000041, // x^7 + x^1 + 1
+ 0x0000008E, // x^8 + x^4 + x^3 + x^2 + 1
+ 0x00000108, // x^9 + x^4 + 1
+ 0x00000204, // x^10 + x^4 + 1
+ 0x00000402, // x^11 + x^2 + 1
+ 0x00000829, // x^12 + x^6 + x^4 + x^1 + 1
+ 0x0000100D, // x^13 + x^4 + x^3 + x^1 + 1
+ 0x00002015, // x^14 + x^5 + x^3 + x^1 + 1
+ 0x00004001, // x^15 + x^1 + 1
+ 0x00008016, // x^16 + x^5 + x^3 + x^2 + 1
+ 0x00010004, // x^17 + x^3 + 1
+ 0x00020013, // x^18 + x^5 + x^2 + x^1 + 1
+ 0x00040013, // x^19 + x^5 + x^2 + x^1 + 1
+ 0x00080004, // x^20 + x^3 + 1
+ 0x00100002, // x^21 + x^2 + 1
+ 0x00200001, // x^22 + x^1 + 1
+ 0x00400010, // x^23 + x^5 + 1
+ 0x0080000D, // x^24 + x^4 + x^3 + x^1 + 1
+ 0x01000004, // x^25 + x^3 + 1
+ 0x02000023, // x^26 + x^6 + x^2 + x^1 + 1
+ 0x04000013, // x^27 + x^5 + x^2 + x^1 + 1
+ 0x08000004, // x^28 + x^3 + 1
+ 0x10000002, // x^29 + x^2 + 1
+ 0x20000029, // x^30 + x^4 + x^1 + 1
+ 0x40000004, // x^31 + x^3 + 1
+ 0x80000057 // x^32 + x^7 + x^5 + x^3 + x^2 + x^1 + 1
+};
+
+int gri_glfsr::glfsr_mask(int degree)
+{
+ if (degree < 1 || degree > 32)
+ throw std::runtime_error("gri_glfsr::glfsr_mask(): degree must be between 1 and 32 inclusive");
+ return s_polynomial_masks[degree];
+}
diff --git a/gnuradio-core/src/lib/general/gri_glfsr.h b/gnuradio-core/src/lib/general/gri_glfsr.h
new file mode 100644
index 000000000..9aae2d9f1
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gri_glfsr.h
@@ -0,0 +1,57 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GRI_GLFSR_H
+#define INCLUDED_GRI_GLFSR_H
+
+#include <gr_core_api.h>
+
+/*!
+ * \brief Galois Linear Feedback Shift Register using specified polynomial mask
+ * \ingroup misc
+ *
+ * Generates a maximal length pseudo-random sequence of length 2^degree-1
+ */
+
+class GR_CORE_API gri_glfsr
+{
+ private:
+ int d_shift_register;
+ int d_mask;
+
+ public:
+
+ gri_glfsr(int mask, int seed) { d_shift_register = seed; d_mask = mask; }
+ static int glfsr_mask(int degree);
+
+ unsigned char next_bit() {
+ unsigned char bit = d_shift_register & 1;
+ d_shift_register >>= 1;
+ if (bit)
+ d_shift_register ^= d_mask;
+ return bit;
+ }
+
+ int mask() const { return d_mask; }
+};
+
+#endif /* INCLUDED_GRI_GLFSR_H */ \ No newline at end of file
diff --git a/gnuradio-core/src/lib/general/gri_int_to_float.cc b/gnuradio-core/src/lib/general/gri_int_to_float.cc
new file mode 100644
index 000000000..91da08897
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gri_int_to_float.cc
@@ -0,0 +1,37 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2011 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#define _ISOC9X_SOURCE
+#include <gri_int_to_float.h>
+#include <math.h>
+
+void
+gri_int_to_float (const int *in, float *out, int nsamples)
+{
+ for (int i = 0; i < nsamples; i++){
+ out[i] = static_cast<float>(in[i]);
+ }
+}
diff --git a/gnuradio-core/src/lib/general/gri_int_to_float.h b/gnuradio-core/src/lib/general/gri_int_to_float.h
new file mode 100644
index 000000000..4b08b7c6b
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gri_int_to_float.h
@@ -0,0 +1,34 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2011 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GRI_INT_TO_FLOAT_H
+#define INCLUDED_GRI_INT_TO_FLOAT_H
+
+#include <gr_core_api.h>
+
+/*
+ * convert array of ints to floats
+ */
+GR_CORE_API void gri_int_to_float (const int *in, float *out, int nsamples);
+
+
+#endif /* INCLUDED_GRI_INT_TO_FLOAT_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
index 000000000..7d0af0fc7
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gri_interleaved_short_to_complex.cc
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gri_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
index 000000000..8d8a0d16e
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gri_interleaved_short_to_complex.h
@@ -0,0 +1,38 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GRI_INTERLEAVED_SHORT_TO_COMPLEX_H
+#define INCLUDED_GRI_INTERLEAVED_SHORT_TO_COMPLEX_H
+
+#include <gr_core_api.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.
+ */
+GR_CORE_API 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.h b/gnuradio-core/src/lib/general/gri_lfsr.h
new file mode 100644
index 000000000..420236077
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gri_lfsr.h
@@ -0,0 +1,152 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GRI_LFSR_H
+#define INCLUDED_GRI_LFSR_H
+
+#include <gr_core_api.h>
+#include <stdexcept>
+#include <stdint.h>
+
+/*!
+ * \brief Fibonacci Linear Feedback Shift Register using specified polynomial mask
+ * \ingroup misc
+ *
+ * Generates a maximal length pseudo-random sequence of length 2^degree-1
+ *
+ * Constructor: gri_lfsr(int mask, int seed, int reg_len);
+ *
+ * mask - polynomial coefficients representing the locations
+ * of feedback taps from a shift register which are xor'ed
+ * together to form the new high order bit.
+ *
+ * Some common masks might be:
+ * x^4 + x^3 + x^0 = 0x19
+ * x^5 + x^3 + x^0 = 0x29
+ * x^6 + x^5 + x^0 = 0x61
+ *
+ * seed - the initialization vector placed into the register
+ * durring initialization. Low order bit corresponds
+ * to x^0 coefficient -- the first to be shifted as output.
+ *
+ * reg_len - specifies the length of the feedback shift register
+ * to be used. Durring each iteration, the register
+ * is rightshifted one and the new bit is placed in bit reg_len.
+ * reg_len should generally be at least order(mask) + 1
+ *
+ *
+ * see http://en.wikipedia.org/wiki/Linear_feedback_shift_register
+ * for more explanation.
+ *
+ *
+ *
+ * next_bit() - Standard LFSR operation
+ *
+ * Perform one cycle of the LFSR. The output bit is taken from
+ * the shift register LSB. The shift register MSB is assigned from
+ * the modulo 2 sum of the masked shift register.
+ *
+ * next_bit_scramble(unsigned char input) - Scramble an input stream
+ *
+ * Perform one cycle of the LFSR. The output bit is taken from
+ * the shift register LSB. The shift register MSB is assigned from
+ * the modulo 2 sum of the masked shift register and the input LSB.
+ *
+ * next_bit_descramble(unsigned char input) - Descramble an input stream
+ *
+ * Perform one cycle of the LFSR. The output bit is taken from
+ * the modulo 2 sum of the masked shift register and the input LSB.
+ * The shift register MSB is assigned from the LSB of the input.
+ *
+ * See http://en.wikipedia.org/wiki/Scrambler for operation of these
+ * last two functions (see multiplicative scrambler.)
+ *
+ */
+
+class GR_CORE_API gri_lfsr
+{
+ private:
+ uint32_t d_shift_register;
+ uint32_t d_mask;
+ uint32_t d_seed;
+ uint32_t d_shift_register_length; // less than 32
+
+ static uint32_t
+ popCount(uint32_t x)
+ {
+ uint32_t r = x - ((x >> 1) & 033333333333)
+ - ((x >> 2) & 011111111111);
+ return ((r + (r >> 3)) & 030707070707) % 63;
+ }
+
+ public:
+
+ gri_lfsr(uint32_t mask, uint32_t seed, uint32_t reg_len)
+ : d_shift_register(seed),
+ d_mask(mask),
+ d_seed(seed),
+ d_shift_register_length(reg_len)
+ {
+ if (reg_len > 31)
+ throw std::invalid_argument("reg_len must be <= 31");
+ }
+
+ unsigned char next_bit() {
+ unsigned char output = d_shift_register & 1;
+ unsigned char newbit = popCount( d_shift_register & d_mask )%2;
+ d_shift_register = ((d_shift_register>>1) | (newbit<<d_shift_register_length));
+ return output;
+ }
+
+ unsigned char next_bit_scramble(unsigned char input) {
+ unsigned char output = d_shift_register & 1;
+ unsigned char newbit = (popCount( d_shift_register & d_mask )%2)^(input & 1);
+ d_shift_register = ((d_shift_register>>1) | (newbit<<d_shift_register_length));
+ return output;
+ }
+
+ unsigned char next_bit_descramble(unsigned char input) {
+ unsigned char output = (popCount( d_shift_register & d_mask )%2)^(input & 1);
+ unsigned char newbit = input & 1;
+ d_shift_register = ((d_shift_register>>1) | (newbit<<d_shift_register_length));
+ return output;
+ }
+
+ /*!
+ * Reset shift register to initial seed value
+ */
+ void reset() { d_shift_register = d_seed; }
+
+ /*!
+ * Rotate the register through x number of bits
+ * where we are just throwing away the results to get queued up correctly
+ */
+ void pre_shift(int num){
+ for(int i=0; i<num; i++){
+ next_bit();
+ }
+ }
+
+ int mask() const { return d_mask; }
+};
+
+#endif /* INCLUDED_GRI_LFSR_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
index 000000000..578739f7e
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gri_lfsr_15_1_0.h
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GRI_LFSR_15_1_0_H
+#define INCLUDED_GRI_LFSR_15_1_0_H
+
+#include <gr_core_api.h>
+
+/*!
+ * \brief Linear Feedback Shift Register using primitive polynomial x^15 + x + 1
+ * \ingroup misc
+ *
+ * Generates a maximal length pseudo-random sequence of length 2^15 - 1 bits.
+ */
+
+class GR_CORE_API 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 */ \ No newline at end of file
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
index 000000000..e84512b9a
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gri_lfsr_32k.h
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GRI_LFSR_32k_H
+#define INCLUDED_GRI_LFSR_32k_H
+
+#include <gr_core_api.h>
+#include <gri_lfsr_15_1_0.h>
+
+/*!
+ * \brief generate pseudo-random sequence of length 32768 bits.
+ * \ingroup misc
+ *
+ * This is based on gri_lfsr_15_1_0 with an extra 0 added at the end
+ * of the sequence.
+ */
+
+class GR_CORE_API 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
index 000000000..d5d0e786e
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gri_short_to_float.cc
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <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
index 000000000..2ffdbb45b
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gri_short_to_float.h
@@ -0,0 +1,34 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GRI_SHORT_TO_FLOAT_H
+#define INCLUDED_GRI_SHORT_TO_FLOAT_H
+
+#include <gr_core_api.h>
+
+/*
+ * convert array of shorts to floats
+ */
+GR_CORE_API void gri_short_to_float (const short *in, float *out, int nsamples);
+
+
+#endif /* INCLUDED_GRI_SHORT_TO_FLOAT_H */ \ No newline at end of file
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
index 000000000..91f3e7336
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gri_uchar_to_float.cc
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <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
index 000000000..633c5d4ce
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gri_uchar_to_float.h
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GRI_UCHAR_TO_FLOAT_H
+#define INCLUDED_GRI_UCHAR_TO_FLOAT_H
+
+#include <gr_core_api.h>
+
+/*
+ * convert array of unsigned chars to floats
+ */
+GR_CORE_API void gri_uchar_to_float (const unsigned char *in, float *out, int nsamples);
+
+
+#endif /* INCLUDED_GRI_UCHAR_TO_FLOAT_H */ \ No newline at end of file
diff --git a/gnuradio-core/src/lib/general/malloc16.c b/gnuradio-core/src/lib/general/malloc16.c
new file mode 100644
index 000000000..2cc6135e7
--- /dev/null
+++ b/gnuradio-core/src/lib/general/malloc16.c
@@ -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
index 000000000..eaa32c625
--- /dev/null
+++ b/gnuradio-core/src/lib/general/malloc16.h
@@ -0,0 +1,37 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <gr_core_api.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdlib.h>
+
+GR_CORE_API void *malloc16Align(int size);
+GR_CORE_API void *calloc16Align(size_t nmemb,size_t size);
+GR_CORE_API 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
index 000000000..26b21983e
--- /dev/null
+++ b/gnuradio-core/src/lib/general/qa_general.cc
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+/*
+ * This class gathers together all the test cases for the 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_cpm.h>
+#include <qa_gr_fxpt.h>
+#include <qa_gr_fxpt_nco.h>
+#include <qa_gr_fxpt_vco.h>
+#include <qa_gr_math.h>
+#include <qa_gri_lfsr.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_cpm::suite ());
+ s->addTest (qa_gr_fxpt::suite ());
+ s->addTest (qa_gr_fxpt_nco::suite ());
+ s->addTest (qa_gr_fxpt_vco::suite ());
+ s->addTest (qa_gr_math::suite ());
+ s->addTest (qa_gri_lfsr::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
index 000000000..bf52cddc1
--- /dev/null
+++ b/gnuradio-core/src/lib/general/qa_general.h
@@ -0,0 +1,38 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef _QA_GENERAL_H_
+#define _QA_GENERAL_H_
+
+#include <gruel/attributes.h>
+#include <cppunit/TestSuite.h>
+
+//! collect all the tests for the gr directory
+
+class __GR_ATTR_EXPORT 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
index 000000000..243e44784
--- /dev/null
+++ b/gnuradio-core/src/lib/general/qa_gr_circular_file.cc
@@ -0,0 +1,72 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#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
index 000000000..df35ab077
--- /dev/null
+++ b/gnuradio-core/src/lib/general/qa_gr_circular_file.h
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifndef _QA_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_cpm.cc b/gnuradio-core/src/lib/general/qa_gr_cpm.cc
new file mode 100644
index 000000000..ee3e2bdea
--- /dev/null
+++ b/gnuradio-core/src/lib/general/qa_gr_cpm.cc
@@ -0,0 +1,140 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <qa_gr_cpm.h>
+#include <gr_cpm.h>
+#include <cppunit/TestAssert.h>
+
+const double DELTA = 1e-5;
+const int L = 5;
+const int samples_per_sym = 4;
+const float taps_lrc[20] = {
+ 0, 0.002447174185242, 0.009549150281253, 0.020610737385376,
+ 0.034549150281253, 0.050000000000000, 0.065450849718747, 0.079389262614624,
+ 0.090450849718747, 0.097552825814758, 0.100000000000000, 0.097552825814758,
+ 0.090450849718747, 0.079389262614624, 0.065450849718747, 0.050000000000000,
+ 0.034549150281253, 0.020610737385376, 0.009549150281253, 0.002447174185242
+};
+
+
+const float taps_lsrc[20] = { // beta = 0.2
+ 0.000000000000000, 0.009062686687436, 0.019517618142920, 0.030875041875917,
+ 0.042552315421249, 0.053912556756416, 0.064308860403517, 0.073130584159352,
+ 0.079847961304114, 0.084051371489937, 0.085482007518284, 0.084051371489937,
+ 0.079847961304114, 0.073130584159352, 0.064308860403517, 0.053912556756416,
+ 0.042552315421249, 0.030875041875917, 0.019517618142920, 0.009062686687436
+};
+
+
+const float taps_tfm[20] = {
+ -0.003946522220317, -0.005147757690530, -0.003171631690177, 0.003959659609805,
+ 0.017498721302356, 0.037346982678383, 0.062251889790391, 0.087364237065604,
+ 0.110049050955117, 0.125677762224511, 0.132288693729399, 0.125677762224511,
+ 0.110049050955117, 0.087364237065604, 0.062251889790391, 0.037346982678383,
+ 0.017498721302356, 0.003959659609805, -0.003171631690177, -0.005147757690530
+};
+
+
+const float taps_gaussian[20] = { // BT = 0.3
+ 0.000000743866524, 0.000009286258371, 0.000085441834550, 0.000581664421923,
+ 0.002945540765422, 0.011178079812344, 0.032117220937421, 0.070841188736816,
+ 0.122053715366673, 0.167389736919915, 0.185594670675172, 0.167389736919915,
+ 0.122053715366673, 0.070841188736816, 0.032117220937421, 0.011178079812344,
+ 0.002945540765422, 0.000581664421923, 0.000085441834550, 0.000009286258371
+};
+
+
+// Check LREC phase response
+void
+qa_gr_cpm::t1 ()
+{
+ std::vector<float> taps(gr_cpm::phase_response(gr_cpm::LREC, samples_per_sym, L));
+
+ for (int i = 0; i < L * samples_per_sym; i++) {
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(taps[i], 0.05, DELTA);
+ }
+}
+
+
+// Check LRC phase response
+void
+qa_gr_cpm::t2 ()
+{
+ std::vector<float> taps(gr_cpm::phase_response(gr_cpm::LRC, samples_per_sym, L));
+ float sum = 0;
+
+ for (int i = 0; i < L * samples_per_sym; i++) {
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(taps[i], taps_lrc[i], DELTA);
+ sum += taps[i];
+ }
+
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(sum, 1.0, DELTA);
+}
+
+
+// Check LSRC phase response
+void
+qa_gr_cpm::t3 ()
+{
+ std::vector<float> taps(gr_cpm::phase_response(gr_cpm::LSRC, samples_per_sym, L, 0.2));
+ float sum = 0;
+
+ for (int i = 0; i < L * samples_per_sym; i++) {
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(taps[i], taps_lsrc[i], DELTA);
+ sum += taps[i];
+ }
+
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(sum, 1.0, DELTA);
+}
+
+
+// Check the TFM phase response
+void
+qa_gr_cpm::t4 ()
+{
+ std::vector<float> taps(gr_cpm::phase_response(gr_cpm::TFM, samples_per_sym, L));
+ float sum = 0;
+
+ for (int i = 0; i < L * samples_per_sym; i++) {
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(taps[i], taps_tfm[i], DELTA);
+ sum += taps[i];
+ }
+
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(sum, 1.0, DELTA);
+}
+
+
+// Check the Gaussian phase response
+void
+qa_gr_cpm::t5 ()
+{
+ std::vector<float> taps(gr_cpm::phase_response(gr_cpm::GAUSSIAN, samples_per_sym, L, 0.3));
+ float sum = 0;
+
+ for (int i = 0; i < L * samples_per_sym; i++) {
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(taps[i], taps_gaussian[i], DELTA);
+ sum += taps[i];
+ }
+
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(sum, 1.0, DELTA);
+}
+
diff --git a/gnuradio-core/src/lib/general/qa_gr_cpm.h b/gnuradio-core/src/lib/general/qa_gr_cpm.h
new file mode 100644
index 000000000..2f46b42a7
--- /dev/null
+++ b/gnuradio-core/src/lib/general/qa_gr_cpm.h
@@ -0,0 +1,49 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifndef _QA_GR_CPM_H
+#define _QA_GR_CPM_H
+
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/TestCase.h>
+
+class qa_gr_cpm : public CppUnit::TestCase {
+
+ CPPUNIT_TEST_SUITE (qa_gr_cpm);
+ CPPUNIT_TEST (t1);
+ CPPUNIT_TEST (t2);
+ CPPUNIT_TEST (t3);
+ CPPUNIT_TEST (t4);
+ CPPUNIT_TEST (t5);
+ CPPUNIT_TEST_SUITE_END ();
+
+ private:
+ void t1 ();
+ void t2 ();
+ void t3 ();
+ void t4 ();
+ void t5 ();
+
+};
+
+
+#endif /* _QA_GR_CPM_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
index 000000000..877b4bd56
--- /dev/null
+++ b/gnuradio-core/src/lib/general/qa_gr_firdes.cc
@@ -0,0 +1,618 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <qa_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;
+
+#if 0
+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]);
+ }
+}
+#endif
+
+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
+};
+
+
+const static float t4_exp[] = { // low pass
+ 0.001059958362,
+0.0002263929928,
+-0.001277606934,
+-0.0009675776237,
+ 0.001592264394,
+ 0.00243603508,
+-0.001451682881,
+-0.004769335967,
+5.281541594e-18,
+ 0.007567512803,
+ 0.003658855334,
+-0.009761494584,
+ -0.01011830103,
+ 0.009636915289,
+ 0.0193619132,
+-0.004935568199,
+ -0.03060629964,
+-0.007267376408,
+ 0.04236677289,
+ 0.03197422624,
+ -0.05274848267,
+ -0.0850463286,
+ 0.05989059806,
+ 0.31065014,
+ 0.4370569289,
+ 0.31065014,
+ 0.05989059806,
+ -0.0850463286,
+ -0.05274848267,
+ 0.03197422624,
+ 0.04236677289,
+-0.007267376408,
+ -0.03060629964,
+-0.004935568199,
+ 0.0193619132,
+ 0.009636915289,
+ -0.01011830103,
+-0.009761494584,
+ 0.003658855334,
+ 0.007567512803,
+5.281541594e-18,
+-0.004769335967,
+-0.001451682881,
+ 0.00243603508,
+ 0.001592264394,
+-0.0009675776237,
+-0.001277606934,
+0.0002263929928,
+ 0.001059958362,
+};
+
+
+const static float t5_exp[] = { //high pass
+-0.001062123571,
+-0.0002268554381,
+ 0.001280216733,
+ 0.000969554123,
+-0.001595516922,
+-0.002441011136,
+ 0.001454648213,
+ 0.004779078532,
+-5.292330097e-18,
+-0.007582970895,
+ -0.00366632943,
+ 0.009781434201,
+ 0.01013896987,
+-0.009656600654,
+ -0.01940146461,
+ 0.004945650231,
+ 0.03066881932,
+ 0.00728222169,
+ -0.04245331511,
+ -0.03203954175,
+ 0.05285623297,
+ 0.08522006124,
+ -0.06001294032,
+ -0.3112847209,
+ 0.5630782247,
+ -0.3112847209,
+ -0.06001294032,
+ 0.08522006124,
+ 0.05285623297,
+ -0.03203954175,
+ -0.04245331511,
+ 0.00728222169,
+ 0.03066881932,
+ 0.004945650231,
+ -0.01940146461,
+-0.009656600654,
+ 0.01013896987,
+ 0.009781434201,
+ -0.00366632943,
+-0.007582970895,
+-5.292330097e-18,
+ 0.004779078532,
+ 0.001454648213,
+-0.002441011136,
+-0.001595516922,
+ 0.000969554123,
+ 0.001280216733,
+-0.0002268554381,
+-0.001062123571,
+};
+
+const static float t6_exp[] = { // bandpass
+0.0002809273137,
+-0.001047327649,
+7.936541806e-05,
+-0.0004270860809,
+0.0007595835486,
+0.0008966081077,
+-0.0004236323002,
+0.0002423936094,
+-0.002212299034,
+0.0004807534278,
+0.0002620361629,
+ 0.001443728455,
+ 0.002229931997,
+-0.002720607212,
+5.731141573e-05,
+-0.004297634587,
+ 0.001878833398,
+ 0.003217151389,
+ 0.001357055153,
+ 0.003965090029,
+-0.008576190099,
+-0.0003257228818,
+-0.004805727862,
+ 0.004721920472,
+ 0.01007549558,
+-0.002688719891,
+ 0.004467967432,
+ -0.01837076992,
+5.119658377e-17,
+ 0.001125075156,
+ 0.008071650751,
+ 0.02113764361,
+ -0.01602453552,
+ 0.001618095324,
+ -0.03004053794,
+ 0.003163811285,
+ 0.0219683405,
+ 0.007950295694,
+ 0.03682873398,
+ -0.05142467469,
+ -0.00794606097,
+ -0.03965795785,
+ 0.01544955093,
+ 0.09681399167,
+ -0.01610304788,
+ 0.08297294378,
+ -0.2811714709,
+ -0.1094062924,
+ 0.5275565982,
+ -0.1094062924,
+ -0.2811714709,
+ 0.08297294378,
+ -0.01610304788,
+ 0.09681399167,
+ 0.01544955093,
+ -0.03965795785,
+ -0.00794606097,
+ -0.05142467469,
+ 0.03682873398,
+ 0.007950295694,
+ 0.0219683405,
+ 0.003163811285,
+ -0.03004053794,
+ 0.001618095324,
+ -0.01602453552,
+ 0.02113764361,
+ 0.008071650751,
+ 0.001125075156,
+5.119658377e-17,
+ -0.01837076992,
+ 0.004467967432,
+-0.002688719891,
+ 0.01007549558,
+ 0.004721920472,
+-0.004805727862,
+-0.0003257228818,
+-0.008576190099,
+ 0.003965090029,
+ 0.001357055153,
+ 0.003217151389,
+ 0.001878833398,
+-0.004297634587,
+5.731141573e-05,
+-0.002720607212,
+ 0.002229931997,
+ 0.001443728455,
+0.0002620361629,
+0.0004807534278,
+-0.002212299034,
+0.0002423936094,
+-0.0004236323002,
+0.0008966081077,
+0.0007595835486,
+-0.0004270860809,
+7.936541806e-05,
+-0.001047327649,
+0.0002809273137,
+};
+
+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 ()
+{
+ vector<float> taps =
+ gr_firdes::low_pass_2 ( 1.0,
+ 8000,
+ 1750,
+ 500,
+ 66,
+ gr_firdes::WIN_HAMMING);
+
+ // std::cout << "ntaps: " << taps.size () << std::endl;
+ // print_taps (std::cout, taps);
+
+ CPPUNIT_ASSERT_EQUAL (NELEM (t4_exp), taps.size ());
+ for (unsigned int i = 0; i < taps.size (); i++)
+ CPPUNIT_ASSERT_DOUBLES_EQUAL (t4_exp[i], taps[i], 1e-9);
+
+
+ check_symmetry (taps);
+}
+
+void
+qa_gr_firdes::t5 ()
+{
+ vector<float> taps =
+ gr_firdes::high_pass_2 ( 1.0,
+ 8000,
+ 1750,
+ 500,
+ 66,
+ gr_firdes::WIN_HAMMING);
+
+ // std::cout << "ntaps: " << taps.size () << std::endl;
+ // print_taps (std::cout, taps);
+
+ CPPUNIT_ASSERT_EQUAL (NELEM (t5_exp), taps.size ());
+
+ for (unsigned int i = 0; i < taps.size (); i++)
+ CPPUNIT_ASSERT_DOUBLES_EQUAL (t5_exp[i], taps[i], 1e-9);
+
+ check_symmetry (taps);
+}
+
+void
+qa_gr_firdes::t6 ()
+{
+ vector<float> taps =
+ gr_firdes::band_pass_2 ( 1.0,
+ 20e6,
+ 5.75e6 - (5.28e6/2),
+ 5.75e6 + (5.28e6/2),
+ 0.62e6,
+ 66,
+ gr_firdes::WIN_HAMMING);
+
+ // std::cout << "ntaps: " << taps.size () << std::endl;
+ // print_taps (std::cout, taps);
+
+ CPPUNIT_ASSERT_EQUAL (NELEM (t6_exp), taps.size ());
+
+ for (unsigned int i = 0; i < taps.size (); i++)
+ CPPUNIT_ASSERT_DOUBLES_EQUAL (t6_exp[i], taps[i], 1e-7);
+
+ check_symmetry (taps);
+}
+
+void
+qa_gr_firdes::t7 ()
+{
+}
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
index 000000000..98cee99b9
--- /dev/null
+++ b/gnuradio-core/src/lib/general/qa_gr_firdes.h
@@ -0,0 +1,52 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifndef _QA_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 (t5);
+ CPPUNIT_TEST (t6);
+ CPPUNIT_TEST (t7);
+ CPPUNIT_TEST_SUITE_END ();
+
+ private:
+ void t1 ();
+ void t2 ();
+ void t3 ();
+ void t4 ();
+ void t5 ();
+ void t6 ();
+ void t7 ();
+
+};
+
+
+#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
index 000000000..7eac0d896
--- /dev/null
+++ b/gnuradio-core/src/lib/general/qa_gr_fxpt.cc
@@ -0,0 +1,103 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <qa_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 ()
+{
+ for (float p = -M_PI; p < M_PI; p += 2 * M_PI / 3600){
+ float expected_sin = sin (p);
+ float expected_cos = cos (p);
+ float actual_sin;
+ float actual_cos;
+ gr_fxpt::sincos (gr_fxpt::float_to_fixed (p), &actual_sin, &actual_cos);
+ CPPUNIT_ASSERT_DOUBLES_EQUAL (expected_sin, actual_sin, SIN_COS_TOLERANCE);
+ CPPUNIT_ASSERT_DOUBLES_EQUAL (expected_cos, actual_cos, SIN_COS_TOLERANCE);
+ }
+}
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
index 000000000..72211563e
--- /dev/null
+++ b/gnuradio-core/src/lib/general/qa_gr_fxpt.h
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifndef INCLUDED_QA_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
index 000000000..6f208eac8
--- /dev/null
+++ b/gnuradio-core/src/lib/general/qa_gr_fxpt_nco.cc
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <qa_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
index 000000000..8998922bb
--- /dev/null
+++ b/gnuradio-core/src/lib/general/qa_gr_fxpt_nco.h
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifndef INCLUDED_QA_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
index 000000000..5b6993a30
--- /dev/null
+++ b/gnuradio-core/src/lib/general/qa_gr_fxpt_vco.cc
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <qa_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(double(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(double(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
index 000000000..fab8022e3
--- /dev/null
+++ b/gnuradio-core/src/lib/general/qa_gr_fxpt_vco.h
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifndef INCLUDED_QA_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/qa_gr_math.cc b/gnuradio-core/src/lib/general/qa_gr_math.cc
new file mode 100644
index 000000000..74d51b536
--- /dev/null
+++ b/gnuradio-core/src/lib/general/qa_gr_math.cc
@@ -0,0 +1,105 @@
+/*
+ * Copyright 2008 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <gr_math.h>
+#include <qa_gr_math.h>
+#include <cppunit/TestAssert.h>
+#include <stdio.h>
+
+void
+qa_gr_math::test_binary_slicer1 ()
+{
+ float x[5] = {-1, -0.5, 0, 0.5, 1.0};
+ unsigned int z[5] = {0, 0, 1, 1, 1};
+ unsigned int y;
+
+ //printf("\nBinary\n");
+ for (unsigned int i = 0; i < 5; i++) {
+ y = gr_binary_slicer(x[i]);
+ //printf("in: %f out: %d desired: %d\n", x[i], y, z[i]);
+
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(y, z[i], 1e-9);
+ }
+
+ //printf("\nBranchless Binary\n");
+ for (unsigned int i = 0; i < 5; i++) {
+ y = gr_branchless_binary_slicer(x[i]);
+ //printf("in: %f out: %d desired: %d\n", x[i], y, z[i]);
+
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(y, z[i], 1e-9);
+ }
+}
+
+void
+qa_gr_math::test_quad_0deg_slicer1 ()
+{
+ gr_complex x[4] = {gr_complex(1, 0),
+ gr_complex(0, 1),
+ gr_complex(-1, 0),
+ gr_complex(0, -1)};
+
+ unsigned int z[4] = {0, 1, 2, 3};
+ unsigned int y;
+
+ //printf("\nQuad0\n");
+ for (unsigned int i = 0; i < 4; i++) {
+ y = gr_quad_0deg_slicer(x[i]);
+ //printf("in: %.4f+j%.4f out: %d desired: %d\n", x[i].real(), x[i].imag(), y, z[i]);
+
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(y, z[i], 1e-9);
+ }
+
+ //printf("\nBranchless Quad0\n");
+ for (unsigned int i = 0; i < 4; i++) {
+ y = gr_branchless_quad_0deg_slicer(x[i]);
+ //printf("in: %.4f+j%.4f out: %d desired: %d\n", x[i].real(), x[i].imag(), y, z[i]);
+
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(y, z[i], 1e-9);
+ }
+}
+
+void
+qa_gr_math::test_quad_45deg_slicer1 ()
+{
+ gr_complex x[4] = {gr_complex(0.707, 0.707),
+ gr_complex(-0.707, 0.707),
+ gr_complex(-0.707, -0.707),
+ gr_complex(0.707, -0.707)};
+
+ unsigned int z[4] = {0, 1, 2, 3};
+ unsigned int y;
+
+ //printf("\nQuad45\n");
+ for (unsigned int i = 0; i < 4; i++) {
+ y = gr_quad_45deg_slicer(x[i]);
+ //printf("in: %.4f+j%.4f out: %d desired: %d\n", x[i].real(), x[i].imag(), y, z[i]);
+
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(y, z[i], 1e-9);
+ }
+
+ //printf("\nBranchless Quad45\n");
+ for (unsigned int i = 0; i < 4; i++) {
+ y = gr_branchless_quad_45deg_slicer(x[i]);
+ //printf("in: %.4f+j%.4f out: %d desired: %d\n", x[i].real(), x[i].imag(), y, z[i]);
+
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(y, z[i], 1e-9);
+ }
+}
diff --git a/gnuradio-core/src/lib/general/qa_gr_math.h b/gnuradio-core/src/lib/general/qa_gr_math.h
new file mode 100644
index 000000000..86858c03d
--- /dev/null
+++ b/gnuradio-core/src/lib/general/qa_gr_math.h
@@ -0,0 +1,42 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifndef _QA_GR_MATH_H_
+#define _QA_GR_MATH_H_
+
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/TestCase.h>
+
+class qa_gr_math : public CppUnit::TestCase {
+
+ CPPUNIT_TEST_SUITE(qa_gr_math);
+ CPPUNIT_TEST(test_binary_slicer1);
+ CPPUNIT_TEST(test_quad_0deg_slicer1);
+ CPPUNIT_TEST(test_quad_45deg_slicer1);
+ CPPUNIT_TEST_SUITE_END();
+
+ private:
+ void test_binary_slicer1();
+ void test_quad_0deg_slicer1();
+ void test_quad_45deg_slicer1();
+};
+
+#endif /* _QA_GR_MATH_H_ */
diff --git a/gnuradio-core/src/lib/general/qa_gri_lfsr.cc b/gnuradio-core/src/lib/general/qa_gri_lfsr.cc
new file mode 100644
index 000000000..87d610df6
--- /dev/null
+++ b/gnuradio-core/src/lib/general/qa_gri_lfsr.cc
@@ -0,0 +1,142 @@
+/*
+ * Copyright 2008 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <gri_lfsr.h>
+#include <qa_gri_lfsr.h>
+#include <cppunit/TestAssert.h>
+#include <stdio.h>
+#include <string.h>
+#include <vector>
+
+void
+qa_gri_lfsr::test_lfsr ()
+{
+ int mask = 0x19;
+ int seed = 0x01;
+ int length = 5;
+
+ gri_lfsr lfsr1(mask,seed,length);
+ gri_lfsr lfsr2(mask,seed,length);
+
+ unsigned char expected[] = {1, 0, 1, 1, 0, 1, 0, 1, 0, 0};
+
+ for(unsigned int i=0; i<31; i++){
+ lfsr1.next_bit();
+ }
+
+ // test that after one lfsr cycle we still match out uncycled lfsr
+ for (unsigned int i = 0; i < 41; i++) {
+ CPPUNIT_ASSERT_EQUAL((int) lfsr1.next_bit(), (int) lfsr2.next_bit());
+ }
+
+ // test the known correct values at the given shift offset
+ for(unsigned int i=0; i<10; i++){
+ CPPUNIT_ASSERT_EQUAL((int) lfsr1.next_bit(), (int) expected[i]);
+ }
+
+ // test for register length too long
+ CPPUNIT_ASSERT_THROW(gri_lfsr(mask, seed, 32), std::invalid_argument);
+}
+
+void
+qa_gri_lfsr::test_scrambler()
+{
+ // CCSDS 7-bit scrambler
+ int mask = 0x8A;
+ int seed = 0x7F;
+ int length = 7;
+
+ gri_lfsr scrambler(mask, seed, length);
+
+ // Impulse (1 and 126 more zeroes)
+ unsigned char src[] =
+ { 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, 0, 0, 0, 0, 0 }; // flush bits
+
+ // Impulse response (including leading bits)
+ unsigned char expected[] =
+ { 1, 1, 1, 1, 1, 1, 1,
+ 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 0,
+ 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1,
+ 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1,
+ 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0,
+ 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 0, 0,
+ 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0,
+ 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, };
+
+ int len = sizeof(src);
+ std::vector<unsigned char> actual(len);
+
+ for (int i = 0; i < len; i++)
+ actual[i] = scrambler.next_bit_scramble(src[i]);
+
+ CPPUNIT_ASSERT(memcmp(expected, &actual[0], len) == 0);
+}
+
+void
+qa_gri_lfsr::test_descrambler()
+{
+ // CCSDS 7-bit scrambler
+ int mask = 0x8A;
+ int seed = 0x7F;
+ int length = 7;
+
+ gri_lfsr descrambler(mask, seed, length);
+
+ // Scrambled sequence (impulse response)
+ unsigned char src[] =
+ { 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 0,
+ 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1,
+ 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1,
+ 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0,
+ 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 0, 0,
+ 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0,
+ 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0 };
+
+ // Original (garbage while synchronizing, them impulse)
+ unsigned char expected[] =
+ { 0, 1, 0, 0, 1, 0,
+ 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 };
+
+ int len = sizeof(src);
+ std::vector<unsigned char> actual(len);
+
+ for (int i = 0; i < len; i++)
+ actual[i] = descrambler.next_bit_descramble(src[i]);
+
+ CPPUNIT_ASSERT(memcmp(expected, &actual[0], len) == 0);
+}
diff --git a/gnuradio-core/src/lib/general/qa_gri_lfsr.h b/gnuradio-core/src/lib/general/qa_gri_lfsr.h
new file mode 100644
index 000000000..e91843bbb
--- /dev/null
+++ b/gnuradio-core/src/lib/general/qa_gri_lfsr.h
@@ -0,0 +1,42 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifndef _QA_GRI_LFSR_H_
+#define _QA_GRI_LFSR_H_
+
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/TestCase.h>
+
+class qa_gri_lfsr : public CppUnit::TestCase {
+
+ CPPUNIT_TEST_SUITE(qa_gri_lfsr);
+ CPPUNIT_TEST(test_lfsr);
+ CPPUNIT_TEST(test_scrambler);
+ CPPUNIT_TEST(test_descrambler);
+ CPPUNIT_TEST_SUITE_END();
+
+ private:
+ void test_lfsr();
+ void test_scrambler();
+ void test_descrambler();
+};
+
+#endif /* _QA_GRI_LFSR_H_ */
diff --git a/gnuradio-core/src/lib/general/random.h b/gnuradio-core/src/lib/general/random.h
new file mode 100644
index 000000000..c643c3e42
--- /dev/null
+++ b/gnuradio-core/src/lib/general/random.h
@@ -0,0 +1,38 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003, 2008 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef _RANDOM_H_
+#define _RANDOM_H_
+
+// While rand(3) specifies RAND_MAX, random(3) says that the output
+// ranges from 0 to 2^31-1 but does not specify a macro to denote
+// this. We define RANDOM_MAX for cleanliness. We must omit the
+// definition for systems that have made the same choice. (Note that
+// random(3) is from 4.2BSD, and not specified by POSIX.)
+
+#ifndef RANDOM_MAX
+static const int RANDOM_MAX = 2147483647; // 2^31-1
+#endif /* RANDOM_MAX */
+
+#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
index 000000000..69834943b
--- /dev/null
+++ b/gnuradio-core/src/lib/general/sine_table.h
@@ -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/gengen/CMakeLists.txt b/gnuradio-core/src/lib/gengen/CMakeLists.txt
new file mode 100644
index 000000000..db3103a26
--- /dev/null
+++ b/gnuradio-core/src/lib/gengen/CMakeLists.txt
@@ -0,0 +1,175 @@
+# Copyright 2010-2011 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+
+########################################################################
+# This file included, use CMake directory variables
+########################################################################
+include(GrPython)
+
+########################################################################
+# generate the python helper script which calls into the build utils
+########################################################################
+file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/generate_helper.py "
+#!${PYTHON_EXECUTABLE}
+
+import sys, os, re
+sys.path.append('${GR_CORE_PYTHONPATH}')
+os.environ['srcdir'] = '${CMAKE_CURRENT_SOURCE_DIR}'
+os.chdir('${CMAKE_CURRENT_BINARY_DIR}')
+
+if __name__ == '__main__':
+ import build_utils
+ root, inp = sys.argv[1:3]
+ for sig in sys.argv[3:]:
+ name = re.sub ('X+', sig, root)
+ d = build_utils.standard_dict(name, sig)
+ build_utils.expand_template(d, inp)
+
+")
+
+########################################################################
+# generation helper macro to generate various files from template
+########################################################################
+macro(expand_h_cc_i root)
+
+ foreach(ext h cc i)
+ #make a list of all the generated files
+ unset(expanded_files_${ext})
+ foreach(sig ${ARGN})
+ string(REGEX REPLACE "X+" ${sig} name ${root})
+ list(APPEND expanded_files_${ext} ${CMAKE_CURRENT_BINARY_DIR}/${name}.${ext})
+ endforeach(sig)
+
+ #create a command to generate the files
+ add_custom_command(
+ OUTPUT ${expanded_files_${ext}}
+ DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${root}.${ext}.t
+ COMMAND ${PYTHON_EXECUTABLE} ${PYTHON_DASH_B}
+ ${CMAKE_CURRENT_BINARY_DIR}/generate_helper.py
+ ${root} ${root}.${ext}.t ${ARGN}
+ )
+ endforeach(ext)
+
+ #make source files depends on headers to force generation
+ set_source_files_properties(${expanded_files_cc}
+ PROPERTIES OBJECT_DEPENDS "${expanded_files_h}"
+ )
+
+ #install rules for the generated cc, h, and i files
+ list(APPEND generated_gengen_sources ${expanded_files_cc})
+ list(APPEND generated_gengen_includes ${expanded_files_h})
+ list(APPEND generated_gengen_swigs ${expanded_files_i})
+
+endmacro(expand_h_cc_i)
+
+########################################################################
+# Invoke macro to generate various sources
+########################################################################
+expand_h_cc_i(gr_vector_source_X b s i f c)
+expand_h_cc_i(gr_vector_insert_X b)
+expand_h_cc_i(gr_vector_sink_X b s i f c)
+expand_h_cc_i(gr_noise_source_X s i f c)
+expand_h_cc_i(gr_fastnoise_source_X s i f c)
+expand_h_cc_i(gr_sig_source_X s i f c)
+expand_h_cc_i(gr_probe_signal_X b s i f c)
+expand_h_cc_i(gr_probe_signal_vX b s i f c)
+
+expand_h_cc_i(gr_add_const_XX bb ss ii ff cc sf)
+expand_h_cc_i(gr_multiply_const_XX ss ii)
+expand_h_cc_i(gr_add_XX ss ii cc)
+expand_h_cc_i(gr_sub_XX ss ii ff cc)
+expand_h_cc_i(gr_multiply_XX ss ii)
+expand_h_cc_i(gr_divide_XX ss ii ff cc)
+expand_h_cc_i(gr_mute_XX ss ii ff cc)
+expand_h_cc_i(gr_add_const_vXX ss ii ff cc)
+expand_h_cc_i(gr_multiply_const_vXX ss ii ff cc)
+expand_h_cc_i(gr_integrate_XX ss ii ff cc)
+expand_h_cc_i(gr_moving_average_XX ss ii ff cc)
+
+expand_h_cc_i(gr_chunks_to_symbols_XX bf bc sf sc if ic)
+expand_h_cc_i(gr_unpacked_to_packed_XX bb ss ii)
+expand_h_cc_i(gr_packed_to_unpacked_XX bb ss ii)
+expand_h_cc_i(gr_xor_XX bb ss ii)
+expand_h_cc_i(gr_and_XX bb ss ii)
+expand_h_cc_i(gr_and_const_XX bb ss ii)
+expand_h_cc_i(gr_or_XX bb ss ii)
+expand_h_cc_i(gr_not_XX bb ss ii)
+expand_h_cc_i(gr_sample_and_hold_XX bb ss ii ff)
+expand_h_cc_i(gr_argmax_XX fs is ss)
+expand_h_cc_i(gr_max_XX ff ii ss)
+expand_h_cc_i(gr_peak_detector_XX fb ib sb)
+
+add_custom_target(gengen_generated DEPENDS
+ ${generated_gengen_includes}
+ ${generated_gengen_swigs}
+)
+
+########################################################################
+# Create the master gengen swig include files
+########################################################################
+set(generated_index ${CMAKE_CURRENT_BINARY_DIR}/gengen_generated.i.in)
+file(WRITE ${generated_index} "
+//
+// This file is machine generated. All edits will be overwritten
+//
+")
+
+file(APPEND ${generated_index} "%{\n")
+foreach(swig_file ${generated_gengen_swigs})
+ get_filename_component(name ${swig_file} NAME_WE)
+ file(APPEND ${generated_index} "#include<${name}.h>\n")
+endforeach(swig_file)
+file(APPEND ${generated_index} "%}\n")
+
+foreach(swig_file ${generated_gengen_swigs})
+ get_filename_component(name ${swig_file} NAME)
+ file(APPEND ${generated_index} "%include<${name}>\n")
+endforeach(swig_file)
+
+execute_process(
+ COMMAND ${CMAKE_COMMAND} -E copy_if_different
+ ${generated_index} ${CMAKE_CURRENT_BINARY_DIR}/gengen_generated.i
+)
+
+########################################################################
+# Handle the generated sources + a few non-generated ones
+########################################################################
+list(APPEND gnuradio_core_sources
+ ${generated_gengen_sources}
+)
+
+install(FILES
+ ${generated_gengen_includes}
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_endianness.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_noise_type.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_sig_source_waveform.h
+ DESTINATION ${GR_INCLUDE_DIR}/gnuradio
+ COMPONENT "core_devel"
+)
+
+if(ENABLE_PYTHON)
+ install(FILES
+ ${generated_gengen_swigs}
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_endianness.i
+ ${CMAKE_CURRENT_SOURCE_DIR}/gengen.i
+ ${CMAKE_CURRENT_BINARY_DIR}/gengen_generated.i
+ DESTINATION ${GR_INCLUDE_DIR}/gnuradio/swig
+ COMPONENT "core_swig"
+ )
+endif(ENABLE_PYTHON)
diff --git a/gnuradio-core/src/lib/gengen/generate_all.py b/gnuradio-core/src/lib/gengen/generate_all.py
new file mode 100755
index 000000000..6b0f20f05
--- /dev/null
+++ b/gnuradio-core/src/lib/gengen/generate_all.py
@@ -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 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from build_utils import output_glue
+
+import generate_common
+
+def generate_all ():
+ generate_common.generate ()
+ output_glue ('gengen')
+
+
+if __name__ == '__main__':
+ generate_all ()
diff --git a/gnuradio-core/src/lib/gengen/generate_common.py b/gnuradio-core/src/lib/gengen/generate_common.py
new file mode 100755
index 000000000..13d01b0f9
--- /dev/null
+++ b/gnuradio-core/src/lib/gengen/generate_common.py
@@ -0,0 +1,106 @@
+#!/usr/bin/env python
+#
+# Copyright 2004,2006,2007,2008,2009 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from 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',
+ 'gr_probe_signal_X',
+ 'gr_probe_signal_vX'
+ ]
+
+# regular blocks
+reg_signatures = ['ss', 'ii', 'ff', 'cc']
+
+reg_roots = [
+ 'gr_add_const_XX',
+ 'gr_sub_XX',
+ 'gr_divide_XX',
+ 'gr_mute_XX',
+ 'gr_add_const_vXX',
+ 'gr_multiply_const_vXX',
+ 'gr_integrate_XX',
+ 'gr_moving_average_XX',
+ ]
+
+# 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')),
+ ('gr_xor_XX', ('bb','ss','ii')),
+ ('gr_and_XX', ('bb','ss','ii')),
+ ('gr_and_const_XX', ('bb','ss','ii')),
+ ('gr_or_XX', ('bb','ss','ii')),
+ ('gr_not_XX', ('bb','ss','ii')),
+ ('gr_sample_and_hold_XX', ('bb','ss','ii','ff')),
+ ('gr_argmax_XX', ('fs','is','ss')),
+ ('gr_max_XX', ('ff','ii','ss')),
+ ('gr_peak_detector_XX', ('fb','ib','sb')),
+ ('gr_multiply_XX', ('ss','ii')),
+ ('gr_multiply_const_XX', ('ss','ii')),
+ ('gr_add_XX', ('ss','cc','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')
+ expand_h_cc_i ('gr_probe_signal_X', 'b')
+ expand_h_cc_i ('gr_probe_signal_vX', '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/gengen/gengen.i b/gnuradio-core/src/lib/gengen/gengen.i
new file mode 100644
index 000000000..d1895bfa8
--- /dev/null
+++ b/gnuradio-core/src/lib/gengen/gengen.i
@@ -0,0 +1,33 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2009 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+%{
+#include "gr_endianness.h"
+#include "gr_sig_source_waveform.h"
+#include "gr_noise_type.h"
+%}
+
+%include "gr_endianness.i"
+%include "gr_sig_source_waveform.h"
+%include "gr_noise_type.h"
+
+%include "gengen_generated.i"
diff --git a/gnuradio-core/src/lib/gengen/gr_add_XX.cc.t b/gnuradio-core/src/lib/gengen/gr_add_XX.cc.t
new file mode 100644
index 000000000..5a888125b
--- /dev/null
+++ b/gnuradio-core/src/lib/gengen/gr_add_XX.cc.t
@@ -0,0 +1,63 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004, 2009,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+// @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 vlen)
+{
+ return gnuradio::get_initial_sptr (new @NAME@ (vlen));
+}
+
+@NAME@::@NAME@ (size_t vlen)
+ : gr_sync_block ("@BASE_NAME@",
+ gr_make_io_signature (1, -1, sizeof (@I_TYPE@)*vlen),
+ gr_make_io_signature (1, 1, sizeof (@O_TYPE@)*vlen)),
+ d_vlen (vlen)
+{
+}
+
+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 (size_t i = 0; i < noutput_items*d_vlen; 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/gengen/gr_add_XX.h.t b/gnuradio-core/src/lib/gengen/gr_add_XX.h.t
new file mode 100644
index 000000000..cd6d80cd9
--- /dev/null
+++ b/gnuradio-core/src/lib/gengen/gr_add_XX.h.t
@@ -0,0 +1,57 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004, 2009 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+// @WARNING@
+
+#ifndef @GUARD_NAME@
+#define @GUARD_NAME@
+
+#include <gr_core_api.h>
+#include <gr_sync_block.h>
+
+class @NAME@;
+typedef boost::shared_ptr<@NAME@> @SPTR_NAME@;
+
+GR_CORE_API @SPTR_NAME@ gr_make_@BASE_NAME@ (size_t vlen = 1);
+
+/*!
+ * \brief output = sum (input_0, input_1, ...)
+ * \ingroup math_blk
+ *
+ * Add across all input streams.
+ */
+class GR_CORE_API @NAME@ : public gr_sync_block
+{
+ friend GR_CORE_API @SPTR_NAME@ gr_make_@BASE_NAME@ (size_t vlen);
+
+ @NAME@ (size_t vlen);
+
+ size_t d_vlen;
+
+ 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/gengen/gr_add_XX.i.t b/gnuradio-core/src/lib/gengen/gr_add_XX.i.t
new file mode 100644
index 000000000..b2c510610
--- /dev/null
+++ b/gnuradio-core/src/lib/gengen/gr_add_XX.i.t
@@ -0,0 +1,33 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004, 2009 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+// @WARNING@
+
+GR_SWIG_BLOCK_MAGIC(gr,@BASE_NAME@)
+
+@SPTR_NAME@ gr_make_@BASE_NAME@ (size_t vlen = 1);
+
+class @NAME@ : public gr_sync_block
+{
+ private:
+ @NAME@ (size_t vlen);
+};
diff --git a/gnuradio-core/src/lib/gengen/gr_add_const_XX.cc.t b/gnuradio-core/src/lib/gengen/gr_add_const_XX.cc.t
new file mode 100644
index 000000000..3dccc86b8
--- /dev/null
+++ b/gnuradio-core/src/lib/gengen/gr_add_const_XX.cc.t
@@ -0,0 +1,72 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+// @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 gnuradio::get_initial_sptr (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/gengen/gr_add_const_XX.h.t b/gnuradio-core/src/lib/gengen/gr_add_const_XX.h.t
new file mode 100644
index 000000000..00d2c9b58
--- /dev/null
+++ b/gnuradio-core/src/lib/gengen/gr_add_const_XX.h.t
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+// @WARNING@
+
+#ifndef @GUARD_NAME@
+#define @GUARD_NAME@
+
+#include <gr_core_api.h>
+#include <gr_sync_block.h>
+
+class @NAME@;
+typedef boost::shared_ptr<@NAME@> @SPTR_NAME@;
+
+GR_CORE_API @SPTR_NAME@ gr_make_@BASE_NAME@ (@O_TYPE@ k);
+
+/*!
+ * \brief output = input + constant
+ * \ingroup math_blk
+ */
+class GR_CORE_API @NAME@ : public gr_sync_block
+{
+ friend GR_CORE_API @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/gengen/gr_add_const_XX.i.t b/gnuradio-core/src/lib/gengen/gr_add_const_XX.i.t
new file mode 100644
index 000000000..b7921554e
--- /dev/null
+++ b/gnuradio-core/src/lib/gengen/gr_add_const_XX.i.t
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, 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/gengen/gr_add_const_vXX.cc.t b/gnuradio-core/src/lib/gengen/gr_add_const_vXX.cc.t
new file mode 100755
index 000000000..b29f3014d
--- /dev/null
+++ b/gnuradio-core/src/lib/gengen/gr_add_const_vXX.cc.t
@@ -0,0 +1,61 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2006,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+// @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 gnuradio::get_initial_sptr (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/gengen/gr_add_const_vXX.h.t b/gnuradio-core/src/lib/gengen/gr_add_const_vXX.h.t
new file mode 100644
index 000000000..438a84bfd
--- /dev/null
+++ b/gnuradio-core/src/lib/gengen/gr_add_const_vXX.h.t
@@ -0,0 +1,56 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2006,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+// @WARNING@
+
+#ifndef @GUARD_NAME@
+#define @GUARD_NAME@
+
+#include <gr_core_api.h>
+#include <gr_sync_block.h>
+
+class @NAME@;
+typedef boost::shared_ptr<@NAME@> @SPTR_NAME@;
+
+GR_CORE_API @SPTR_NAME@ gr_make_@BASE_NAME@ (const std::vector<@I_TYPE@> &k);
+
+/*!
+ * \brief output vector = input vector + constant vector
+ * \ingroup math_blk
+ */
+class GR_CORE_API @NAME@ : public gr_sync_block
+{
+ friend GR_CORE_API @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/gengen/gr_add_const_vXX.i.t b/gnuradio-core/src/lib/gengen/gr_add_const_vXX.i.t
new file mode 100755
index 000000000..e0e6ae905
--- /dev/null
+++ b/gnuradio-core/src/lib/gengen/gr_add_const_vXX.i.t
@@ -0,0 +1,37 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2006,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+// @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/gengen/gr_and_XX.cc.t b/gnuradio-core/src/lib/gengen/gr_and_XX.cc.t
new file mode 100644
index 000000000..9d60e092a
--- /dev/null
+++ b/gnuradio-core/src/lib/gengen/gr_and_XX.cc.t
@@ -0,0 +1,62 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2008,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+// @WARNING@
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <@NAME@.h>
+#include <gr_io_signature.h>
+
+@SPTR_NAME@
+gr_make_@BASE_NAME@ ()
+{
+ return gnuradio::get_initial_sptr (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 = acc & ((@I_TYPE@ *) input_items[j])[i];
+
+ *optr++ = (@O_TYPE@) acc;
+ }
+ return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/gengen/gr_and_XX.h.t b/gnuradio-core/src/lib/gengen/gr_and_XX.h.t
new file mode 100644
index 000000000..224778096
--- /dev/null
+++ b/gnuradio-core/src/lib/gengen/gr_and_XX.h.t
@@ -0,0 +1,55 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2008 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+// @WARNING@
+
+#ifndef @GUARD_NAME@
+#define @GUARD_NAME@
+
+#include <gr_core_api.h>
+#include <gr_sync_block.h>
+
+class @NAME@;
+typedef boost::shared_ptr<@NAME@> @SPTR_NAME@;
+
+GR_CORE_API @SPTR_NAME@ gr_make_@BASE_NAME@ ();
+
+/*!
+ * \brief output = input_0 & input_1 & , ... & input_N)
+ * \ingroup math_blk
+ *
+ * bitwise boolean and across all input streams.
+ */
+class GR_CORE_API @NAME@ : public gr_sync_block
+{
+ friend GR_CORE_API @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/gengen/gr_and_XX.i.t b/gnuradio-core/src/lib/gengen/gr_and_XX.i.t
new file mode 100644
index 000000000..06db5ca59
--- /dev/null
+++ b/gnuradio-core/src/lib/gengen/gr_and_XX.i.t
@@ -0,0 +1,33 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2008 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+// @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/gengen/gr_and_const_XX.cc.t b/gnuradio-core/src/lib/gengen/gr_and_const_XX.cc.t
new file mode 100644
index 000000000..d4f9a4b61
--- /dev/null
+++ b/gnuradio-core/src/lib/gengen/gr_and_const_XX.cc.t
@@ -0,0 +1,72 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2009,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+// @WARNING@
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <@NAME@.h>
+#include <gr_io_signature.h>
+
+@SPTR_NAME@
+gr_make_@BASE_NAME@ (@I_TYPE@ k)
+{
+ return gnuradio::get_initial_sptr (new @NAME@ (k));
+};
+
+@NAME@::@NAME@ (@I_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/gengen/gr_and_const_XX.h.t b/gnuradio-core/src/lib/gengen/gr_and_const_XX.h.t
new file mode 100644
index 000000000..b331f33cc
--- /dev/null
+++ b/gnuradio-core/src/lib/gengen/gr_and_const_XX.h.t
@@ -0,0 +1,58 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2009 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+// @WARNING@
+
+#ifndef @GUARD_NAME@
+#define @GUARD_NAME@
+
+#include <gr_core_api.h>
+#include <gr_sync_block.h>
+
+class @NAME@;
+typedef boost::shared_ptr<@NAME@> @SPTR_NAME@;
+
+GR_CORE_API @SPTR_NAME@ gr_make_@BASE_NAME@ (@O_TYPE@ k);
+
+/*!
+ * \brief output_N = input_N & value
+ * \ingroup math_blk
+ *
+ * bitwise boolean and of const to the data stream.
+ */
+class GR_CORE_API @NAME@ : public gr_sync_block
+{
+ friend GR_CORE_API @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/gengen/gr_and_const_XX.i.t b/gnuradio-core/src/lib/gengen/gr_and_const_XX.i.t
new file mode 100644
index 000000000..c797c45eb
--- /dev/null
+++ b/gnuradio-core/src/lib/gengen/gr_and_const_XX.i.t
@@ -0,0 +1,37 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2009 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+// @WARNING@
+
+GR_SWIG_BLOCK_MAGIC(gr,@BASE_NAME@)
+
+@SPTR_NAME@ gr_make_@BASE_NAME@ (@O_TYPE@ k);
+
+class @NAME@ : public gr_sync_block
+{
+ private:
+ @NAME@ (@O_TYPE@ k);
+
+ public:
+ @O_TYPE@ k () const { return d_k; }
+ void set_k (@O_TYPE@ k) { d_k = k; }
+};
diff --git a/gnuradio-core/src/lib/gengen/gr_argmax_XX.cc.t b/gnuradio-core/src/lib/gengen/gr_argmax_XX.cc.t
new file mode 100644
index 000000000..f780bd811
--- /dev/null
+++ b/gnuradio-core/src/lib/gengen/gr_argmax_XX.cc.t
@@ -0,0 +1,79 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+// @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 vlen )
+{
+ return @SPTR_NAME@ ( new @NAME@(vlen));
+}
+
+@NAME@::@NAME@( size_t vlen)
+ : gr_sync_block ( "@BASE_NAME@",
+ gr_make_io_signature (1, -1, vlen*sizeof (@I_TYPE@)),
+ gr_make_io_signature (2, 2, sizeof (@O_TYPE@))),
+ d_vlen(vlen)
+{
+}
+
+
+int
+@NAME@::work( int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+
+ int ninputs = input_items.size ();
+
+ @O_TYPE@ *x_optr = (@O_TYPE@ *) output_items[0];
+ @O_TYPE@ *y_optr = (@O_TYPE@ *) output_items[1];
+
+ for (int i=0; i<noutput_items; i++) {
+
+ @I_TYPE@ max = ((@I_TYPE@ *) input_items[0])[i*d_vlen];
+ int x = 0;
+ int y = 0;
+
+ for (int j=0; j < (int) d_vlen; j++ ) {
+ for (int k=0; k<ninputs; k++) {
+ if ( ((@I_TYPE@ *) input_items[k])[i*d_vlen + j] > max) {
+ max = ((@I_TYPE@ *) input_items[k])[i*d_vlen + j];
+ x = j;
+ y = k;
+ }
+ }
+ }
+
+ *x_optr++ = (@O_TYPE@) x;
+ *y_optr++ = (@O_TYPE@) y;
+ }
+ return noutput_items;
+}
+
diff --git a/gnuradio-core/src/lib/gengen/gr_argmax_XX.h.t b/gnuradio-core/src/lib/gengen/gr_argmax_XX.h.t
new file mode 100644
index 000000000..a706221fb
--- /dev/null
+++ b/gnuradio-core/src/lib/gengen/gr_argmax_XX.h.t
@@ -0,0 +1,52 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+// @WARNING@
+
+#ifndef @GUARD_NAME@
+#define @GUARD_NAME@
+
+#include <gr_core_api.h>
+#include <gr_sync_block.h>
+
+class @NAME@;
+typedef boost::shared_ptr<@NAME@> @SPTR_NAME@;
+
+GR_CORE_API @SPTR_NAME@ gr_make_@BASE_NAME@ (size_t vlen);
+
+
+class GR_CORE_API @NAME@ : public gr_sync_block
+{
+ friend GR_CORE_API @SPTR_NAME@ gr_make_@BASE_NAME@ (size_t vlen);
+
+ @NAME@ (size_t vlen);
+ size_t d_vlen;
+
+ 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/gengen/gr_argmax_XX.i.t b/gnuradio-core/src/lib/gengen/gr_argmax_XX.i.t
new file mode 100644
index 000000000..233551ad9
--- /dev/null
+++ b/gnuradio-core/src/lib/gengen/gr_argmax_XX.i.t
@@ -0,0 +1,34 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+// @WARNING@
+
+GR_SWIG_BLOCK_MAGIC(gr,@BASE_NAME@)
+
+@SPTR_NAME@ gr_make_@BASE_NAME@ (size_t vlen);
+
+class @NAME@ : public gr_sync_block
+{
+ private:
+ @NAME@ (size_t vlen);
+ size_t d_vlen;
+};
diff --git a/gnuradio-core/src/lib/gengen/gr_chunks_to_symbols_XX.cc.t b/gnuradio-core/src/lib/gengen/gr_chunks_to_symbols_XX.cc.t
new file mode 100644
index 000000000..4a642c13e
--- /dev/null
+++ b/gnuradio-core/src/lib/gengen/gr_chunks_to_symbols_XX.cc.t
@@ -0,0 +1,74 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+// @WARNING@
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <@NAME@.h>
+#include <gr_io_signature.h>
+#include <assert.h>
+#include <iostream>
+#include <string.h>
+
+@SPTR_NAME@
+gr_make_@BASE_NAME@ (const std::vector<@O_TYPE@> &symbol_table, const int D)
+{
+ return gnuradio::get_initial_sptr (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_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/gengen/gr_chunks_to_symbols_XX.h.t b/gnuradio-core/src/lib/gengen/gr_chunks_to_symbols_XX.h.t
new file mode 100644
index 000000000..17d5688b8
--- /dev/null
+++ b/gnuradio-core/src/lib/gengen/gr_chunks_to_symbols_XX.h.t
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+// @WARNING@
+
+#ifndef @GUARD_NAME@
+#define @GUARD_NAME@
+
+#include <gr_core_api.h>
+#include <gr_sync_interpolator.h>
+
+class @NAME@;
+typedef boost::shared_ptr<@NAME@> @SPTR_NAME@;
+
+GR_CORE_API @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 converter_blk
+ *
+ * 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 GR_CORE_API @NAME@ : public gr_sync_interpolator
+{
+ friend GR_CORE_API @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/gengen/gr_chunks_to_symbols_XX.i.t b/gnuradio-core/src/lib/gengen/gr_chunks_to_symbols_XX.i.t
new file mode 100644
index 000000000..14c8be486
--- /dev/null
+++ b/gnuradio-core/src/lib/gengen/gr_chunks_to_symbols_XX.i.t
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, 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/gengen/gr_divide_XX.cc.t b/gnuradio-core/src/lib/gengen/gr_divide_XX.cc.t
new file mode 100644
index 000000000..63450cb3d
--- /dev/null
+++ b/gnuradio-core/src/lib/gengen/gr_divide_XX.cc.t
@@ -0,0 +1,72 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004, 2009,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+// @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 vlen)
+{
+ return gnuradio::get_initial_sptr (new @NAME@ (vlen));
+}
+
+@NAME@::@NAME@ (size_t vlen)
+ : gr_sync_block ("@BASE_NAME@",
+ gr_make_io_signature (1, -1, sizeof (@I_TYPE@)*vlen),
+ gr_make_io_signature (1, 1, sizeof (@O_TYPE@)*vlen)),
+ d_vlen (vlen)
+{
+}
+
+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 (size_t i = 0; i < noutput_items*d_vlen; i++)
+ *optr++ = (@O_TYPE@) ((@O_TYPE@) 1 /
+ ((@I_TYPE@ *) input_items[0])[i]);
+ }
+
+ else {
+ for (size_t i = 0; i < noutput_items*d_vlen; 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/gengen/gr_divide_XX.h.t b/gnuradio-core/src/lib/gengen/gr_divide_XX.h.t
new file mode 100644
index 000000000..40ee27a51
--- /dev/null
+++ b/gnuradio-core/src/lib/gengen/gr_divide_XX.h.t
@@ -0,0 +1,57 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004, 2009 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+// @WARNING@
+
+#ifndef @GUARD_NAME@
+#define @GUARD_NAME@
+
+#include <gr_core_api.h>
+#include <gr_sync_block.h>
+
+class @NAME@;
+typedef boost::shared_ptr<@NAME@> @SPTR_NAME@;
+
+GR_CORE_API @SPTR_NAME@ gr_make_@BASE_NAME@ (size_t vlen = 1);
+
+/*!
+ * \brief output = input_0 / input_1 / input_x ...)
+ * \ingroup math_blk
+ *
+ * Divide across all input streams.
+ */
+class GR_CORE_API @NAME@ : public gr_sync_block
+{
+ friend GR_CORE_API @SPTR_NAME@ gr_make_@BASE_NAME@ (size_t vlen);
+
+ @NAME@ (size_t vlen);
+
+ size_t d_vlen;
+
+ 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/gengen/gr_divide_XX.i.t b/gnuradio-core/src/lib/gengen/gr_divide_XX.i.t
new file mode 100644
index 000000000..b2c510610
--- /dev/null
+++ b/gnuradio-core/src/lib/gengen/gr_divide_XX.i.t
@@ -0,0 +1,33 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004, 2009 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+// @WARNING@
+
+GR_SWIG_BLOCK_MAGIC(gr,@BASE_NAME@)
+
+@SPTR_NAME@ gr_make_@BASE_NAME@ (size_t vlen = 1);
+
+class @NAME@ : public gr_sync_block
+{
+ private:
+ @NAME@ (size_t vlen);
+};
diff --git a/gnuradio-core/src/lib/gengen/gr_endianness.h b/gnuradio-core/src/lib/gengen/gr_endianness.h
new file mode 100644
index 000000000..c4ecb1383
--- /dev/null
+++ b/gnuradio-core/src/lib/gengen/gr_endianness.h
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifndef INCLUDED_GR_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/gengen/gr_endianness.i b/gnuradio-core/src/lib/gengen/gr_endianness.i
new file mode 100644
index 000000000..572b7a42f
--- /dev/null
+++ b/gnuradio-core/src/lib/gengen/gr_endianness.i
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+%include <gr_endianness.h>
diff --git a/gnuradio-core/src/lib/gengen/gr_fastnoise_source_X.cc.t b/gnuradio-core/src/lib/gengen/gr_fastnoise_source_X.cc.t
new file mode 100644
index 000000000..7be7bdde8
--- /dev/null
+++ b/gnuradio-core/src/lib/gengen/gr_fastnoise_source_X.cc.t
@@ -0,0 +1,116 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+// @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, long samples)
+{
+ return gnuradio::get_initial_sptr(new @NAME@ (type, ampl, seed, samples));
+}
+
+
+@NAME@::@NAME@ (gr_noise_type_t type, float ampl, long seed, long samples)
+ : 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)
+{
+ d_samples.resize(samples);
+ generate();
+}
+
+void
+@NAME@::generate()
+{
+ int noutput_items = d_samples.size();
+ switch (d_type){
+#if @IS_COMPLEX@ // complex?
+
+ case GR_UNIFORM:
+ for (int i = 0; i < noutput_items; i++)
+ d_samples[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++)
+ d_samples[i] = d_ampl * d_rng.rayleigh_complex ();
+ break;
+
+#else // nope...
+
+ case GR_UNIFORM:
+ for (int i = 0; i < noutput_items; i++)
+ d_samples[i] = (@TYPE@)(d_ampl * ((d_rng.ran1 () * 2.0) - 1.0));
+ break;
+
+ case GR_GAUSSIAN:
+ for (int i = 0; i < noutput_items; i++)
+ d_samples[i] = (@TYPE@)(d_ampl * d_rng.gasdev ());
+ break;
+
+ case GR_LAPLACIAN:
+ for (int i = 0; i < noutput_items; i++)
+ d_samples[i] = (@TYPE@)(d_ampl * d_rng.laplacian ());
+ break;
+
+ case GR_IMPULSE: // FIXME changeable impulse settings
+ for (int i = 0; i < noutput_items; i++)
+ d_samples[i] = (@TYPE@)(d_ampl * d_rng.impulse (9));
+ break;
+#endif
+
+ default:
+ throw std::runtime_error ("invalid type");
+ }
+
+}
+
+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];
+
+ for(int i=0; i<noutput_items; i++){
+#ifdef __USE_GNU
+ size_t idx = lrand48() % d_samples.size();
+#else
+ size_t idx = rand() % d_samples.size();
+#endif
+ out[i] = d_samples[idx];
+ }
+
+ return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/gengen/gr_fastnoise_source_X.h.t b/gnuradio-core/src/lib/gengen/gr_fastnoise_source_X.h.t
new file mode 100644
index 000000000..007e44975
--- /dev/null
+++ b/gnuradio-core/src/lib/gengen/gr_fastnoise_source_X.h.t
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+// @WARNING@
+
+#ifndef @GUARD_NAME@
+#define @GUARD_NAME@
+
+#include <gr_core_api.h>
+#include <gr_sync_block.h>
+#include <gr_noise_type.h>
+#include <gr_random.h>
+
+
+class @NAME@;
+typedef boost::shared_ptr<@NAME@> @NAME@_sptr;
+
+/*! \brief Make a noise source
+ * \param type the random distribution to use (see gr_noise_type.h)
+ * \param ampl a scaling factor for the output
+ * \param seed seed for random generators. Note that for uniform and
+ * Gaussian distributions, this should be a negative number.
+ * \param samples number of samples to pre-generate.
+ */
+GR_CORE_API @NAME@_sptr
+gr_make_@BASE_NAME@ (gr_noise_type_t type, float ampl, long seed = 0, long samples=1024*16);
+
+/*!
+ * \brief Random number source
+ * \ingroup source_blk
+ *
+ * \details
+ * Generate random values from different distributions.
+ * Currently, only Gaussian and uniform are enabled.
+ *
+ * \param type the random distribution to use (see gr_noise_type.h)
+ * \param ampl a scaling factor for the output
+ * \param seed seed for random generators. Note that for uniform and
+ * Gaussian distributions, this should be a negative number.
+ * \param samples number of samples to pre-generate.
+ */
+class GR_CORE_API @NAME@ : public gr_sync_block {
+ friend GR_CORE_API @NAME@_sptr
+
+ gr_make_@BASE_NAME@ (gr_noise_type_t type, float ampl, long seed, long samples);
+
+ gr_noise_type_t d_type;
+ float d_ampl;
+ gr_random d_rng;
+ std::vector<@TYPE@> d_samples;
+
+ @NAME@ (gr_noise_type_t type, float ampl, long seed = 0, long samples=1024*16);
+
+ public:
+ void set_type (gr_noise_type_t type) { d_type = type; generate(); }
+ void set_amplitude (float ampl) { d_ampl = ampl; generate(); }
+ void generate();
+
+ gr_noise_type_t type () const { return d_type; }
+ float amplitude () const { return d_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/gengen/gr_fastnoise_source_X.i.t b/gnuradio-core/src/lib/gengen/gr_fastnoise_source_X.i.t
new file mode 100644
index 000000000..e1f7c775b
--- /dev/null
+++ b/gnuradio-core/src/lib/gengen/gr_fastnoise_source_X.i.t
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+// @WARNING@
+
+GR_SWIG_BLOCK_MAGIC(gr,@BASE_NAME@);
+
+@NAME@_sptr
+gr_make_@BASE_NAME@ (gr_noise_type_t type, float ampl, long seed = 0, long samples = 1024*16);
+
+class @NAME@ : public gr_block {
+ private:
+ @NAME@ (gr_noise_type_t type, float ampl, long seed = 0, long samples = 1024*16);
+
+ public:
+ void set_type (gr_noise_type_t type) { d_type = type; }
+ void set_amplitude (float ampl) { d_ampl = ampl; }
+
+ gr_noise_type_t type () const { return d_type; }
+ float amplitude () const { return d_ampl; }
+};
diff --git a/gnuradio-core/src/lib/gengen/gr_integrate_XX.cc.t b/gnuradio-core/src/lib/gengen/gr_integrate_XX.cc.t
new file mode 100644
index 000000000..1dbee49db
--- /dev/null
+++ b/gnuradio-core/src/lib/gengen/gr_integrate_XX.cc.t
@@ -0,0 +1,67 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+// @WARNING@
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <@NAME@.h>
+#include <gr_io_signature.h>
+
+@SPTR_NAME@
+gr_make_@BASE_NAME@ (int decim)
+{
+ return gnuradio::get_initial_sptr (new @NAME@ (decim));
+}
+
+@NAME@::@NAME@ (int decim)
+ : gr_sync_decimator ("@BASE_NAME@",
+ gr_make_io_signature (1, 1, sizeof (@I_TYPE@)),
+ gr_make_io_signature (1, 1, sizeof (@O_TYPE@)),
+ decim),
+ d_decim(decim),
+ d_count(0)
+{
+}
+
+@NAME@::~@NAME@ ()
+{
+}
+
+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];
+
+ for (int i = 0; i < noutput_items; i++) {
+ out[i] = (@O_TYPE@)0;
+ for (int j = 0; j < d_decim; j++)
+ out[i] += in[i*d_decim+j];
+ }
+
+ return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/gengen/gr_integrate_XX.h.t b/gnuradio-core/src/lib/gengen/gr_integrate_XX.h.t
new file mode 100644
index 000000000..abb13ea90
--- /dev/null
+++ b/gnuradio-core/src/lib/gengen/gr_integrate_XX.h.t
@@ -0,0 +1,61 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+// @WARNING@
+
+#ifndef @GUARD_NAME@
+#define @GUARD_NAME@
+
+#include <gr_core_api.h>
+#include <gr_sync_decimator.h>
+
+class @NAME@;
+
+typedef boost::shared_ptr<@NAME@> @SPTR_NAME@;
+
+GR_CORE_API @SPTR_NAME@ gr_make_@BASE_NAME@ (int decim);
+
+/*!
+ * \brief output = sum(input[0]...input[n])
+ * \ingroup math_blk
+ *
+ * Integrate successive samples in input stream and decimate
+ */
+class GR_CORE_API @NAME@ : public gr_sync_decimator
+{
+private:
+ friend GR_CORE_API @SPTR_NAME@ gr_make_@BASE_NAME@(int decim);
+
+ @NAME@ (int decim);
+
+ int d_decim;
+ int d_count;
+
+public:
+ ~@NAME@ ();
+
+ int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+#endif /* @GUARD_NAME@ */
diff --git a/gnuradio-core/src/lib/gengen/gr_integrate_XX.i.t b/gnuradio-core/src/lib/gengen/gr_integrate_XX.i.t
new file mode 100644
index 000000000..a96e5fd29
--- /dev/null
+++ b/gnuradio-core/src/lib/gengen/gr_integrate_XX.i.t
@@ -0,0 +1,33 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+// @WARNING@
+
+GR_SWIG_BLOCK_MAGIC(gr,@BASE_NAME@);
+
+@SPTR_NAME@ gr_make_@BASE_NAME@ (int decim);
+
+class @NAME@ : public gr_sync_decimator
+{
+private:
+ @NAME@ ();
+};
diff --git a/gnuradio-core/src/lib/gengen/gr_max_XX.cc.t b/gnuradio-core/src/lib/gengen/gr_max_XX.cc.t
new file mode 100644
index 000000000..c53820cd6
--- /dev/null
+++ b/gnuradio-core/src/lib/gengen/gr_max_XX.cc.t
@@ -0,0 +1,71 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+// @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 vlen )
+{
+ return @SPTR_NAME@ ( new @NAME@(vlen));
+}
+
+@NAME@::@NAME@( size_t vlen)
+ : gr_sync_block ( "@BASE_NAME@",
+ gr_make_io_signature (1, -1, vlen*sizeof (@I_TYPE@)),
+ gr_make_io_signature (1, 1, sizeof (@O_TYPE@))),
+ d_vlen(vlen)
+{
+}
+
+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@ max = ((@I_TYPE@ *) input_items[0])[i*d_vlen];
+
+ for (int j=0; j < (int) d_vlen; j++ ) {
+ for (int k=0; k<ninputs; k++) {
+ if ( ((@I_TYPE@ *) input_items[k])[i*d_vlen + j] > max) {
+ max = ((@I_TYPE@*) input_items[k])[i*d_vlen + j];
+ }
+ }
+ }
+
+ *optr++ = (@O_TYPE@) max;
+ }
+ return noutput_items;
+}
+
diff --git a/gnuradio-core/src/lib/gengen/gr_max_XX.h.t b/gnuradio-core/src/lib/gengen/gr_max_XX.h.t
new file mode 100644
index 000000000..a706221fb
--- /dev/null
+++ b/gnuradio-core/src/lib/gengen/gr_max_XX.h.t
@@ -0,0 +1,52 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+// @WARNING@
+
+#ifndef @GUARD_NAME@
+#define @GUARD_NAME@
+
+#include <gr_core_api.h>
+#include <gr_sync_block.h>
+
+class @NAME@;
+typedef boost::shared_ptr<@NAME@> @SPTR_NAME@;
+
+GR_CORE_API @SPTR_NAME@ gr_make_@BASE_NAME@ (size_t vlen);
+
+
+class GR_CORE_API @NAME@ : public gr_sync_block
+{
+ friend GR_CORE_API @SPTR_NAME@ gr_make_@BASE_NAME@ (size_t vlen);
+
+ @NAME@ (size_t vlen);
+ size_t d_vlen;
+
+ 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/gengen/gr_max_XX.i.t b/gnuradio-core/src/lib/gengen/gr_max_XX.i.t
new file mode 100644
index 000000000..233551ad9
--- /dev/null
+++ b/gnuradio-core/src/lib/gengen/gr_max_XX.i.t
@@ -0,0 +1,34 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+// @WARNING@
+
+GR_SWIG_BLOCK_MAGIC(gr,@BASE_NAME@)
+
+@SPTR_NAME@ gr_make_@BASE_NAME@ (size_t vlen);
+
+class @NAME@ : public gr_sync_block
+{
+ private:
+ @NAME@ (size_t vlen);
+ size_t d_vlen;
+};
diff --git a/gnuradio-core/src/lib/gengen/gr_moving_average_XX.cc.t b/gnuradio-core/src/lib/gengen/gr_moving_average_XX.cc.t
new file mode 100644
index 000000000..ddee30bd7
--- /dev/null
+++ b/gnuradio-core/src/lib/gengen/gr_moving_average_XX.cc.t
@@ -0,0 +1,93 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+// @WARNING@
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <@NAME@.h>
+#include <gr_io_signature.h>
+
+@SPTR_NAME@
+gr_make_@BASE_NAME@ (int length, @O_TYPE@ scale, int max_iter)
+{
+ return gnuradio::get_initial_sptr (new @NAME@ (length, scale, max_iter));
+}
+
+@NAME@::@NAME@ (int length, @O_TYPE@ scale, int max_iter)
+ : gr_sync_block ("@BASE_NAME@",
+ gr_make_io_signature (1, 1, sizeof (@I_TYPE@)),
+ gr_make_io_signature (1, 1, sizeof (@O_TYPE@))),
+ d_length(length),
+ d_scale(scale),
+ d_max_iter(max_iter),
+ d_new_length(length),
+ d_new_scale(scale),
+ d_updated(false)
+{
+ set_history(length);
+}
+
+@NAME@::~@NAME@ ()
+{
+}
+
+void
+@NAME@::set_length_and_scale(int length, @O_TYPE@ scale)
+{
+ d_new_length = length;
+ d_new_scale = scale;
+ d_updated = true;
+}
+
+int
+@NAME@::work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ if (d_updated) {
+ d_length = d_new_length;
+ d_scale = d_new_scale;
+ set_history(d_length);
+ d_updated = false;
+ return 0; // history requirements might have changed
+ }
+
+ const @I_TYPE@ *in = (const @I_TYPE@ *) input_items[0];
+ @O_TYPE@ *out = (@O_TYPE@ *) output_items[0];
+
+ @I_TYPE@ sum = 0;
+ int num_iter = (noutput_items>d_max_iter) ? d_max_iter : noutput_items;
+ for (int i = 0; i < d_length-1 ; i++) {
+ sum += in[i];
+ }
+
+ for (int i = 0; i < num_iter; i++) {
+ sum += in[i+d_length-1];
+ out[i] = sum * d_scale;
+ sum -= in[i];
+ }
+
+ return num_iter;
+}
diff --git a/gnuradio-core/src/lib/gengen/gr_moving_average_XX.h.t b/gnuradio-core/src/lib/gengen/gr_moving_average_XX.h.t
new file mode 100644
index 000000000..37678abe1
--- /dev/null
+++ b/gnuradio-core/src/lib/gengen/gr_moving_average_XX.h.t
@@ -0,0 +1,72 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+// @WARNING@
+
+#ifndef @GUARD_NAME@
+#define @GUARD_NAME@
+
+#include <gr_core_api.h>
+#include <gr_sync_block.h>
+
+class @NAME@;
+
+typedef boost::shared_ptr<@NAME@> @SPTR_NAME@;
+
+GR_CORE_API @SPTR_NAME@ gr_make_@BASE_NAME@ (int length, @O_TYPE@ scale, int max_iter = 4096);
+
+/*!
+ * \brief output is the moving sum of the last N samples, scaled by the scale factor
+ * \ingroup filter_blk
+ *
+ * max_iter limits how long we go without flushing the accumulator
+ * This is necessary to avoid numerical instability for float and complex.
+ */
+class GR_CORE_API @NAME@ : public gr_sync_block
+{
+private:
+ friend GR_CORE_API @SPTR_NAME@ gr_make_@BASE_NAME@(int length, @O_TYPE@ scale, int max_iter);
+
+ @NAME@ (int length, @O_TYPE@ scale, int max_iter = 4096);
+
+ int d_length;
+ @O_TYPE@ d_scale;
+ int d_max_iter;
+
+ int d_new_length;
+ @O_TYPE@ d_new_scale;
+ bool d_updated;
+
+public:
+ ~@NAME@ ();
+
+ int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+
+ int length() const { return d_new_length; }
+ @O_TYPE@ scale() const { return d_new_scale; }
+
+ void set_length_and_scale(int length, @O_TYPE@ scale);
+};
+
+#endif /* @GUARD_NAME@ */
diff --git a/gnuradio-core/src/lib/gengen/gr_moving_average_XX.i.t b/gnuradio-core/src/lib/gengen/gr_moving_average_XX.i.t
new file mode 100644
index 000000000..6e3b9ca9b
--- /dev/null
+++ b/gnuradio-core/src/lib/gengen/gr_moving_average_XX.i.t
@@ -0,0 +1,38 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+// @WARNING@
+
+GR_SWIG_BLOCK_MAGIC(gr,@BASE_NAME@);
+
+@SPTR_NAME@ gr_make_@BASE_NAME@ (int length, @O_TYPE@ scale, int max_iter=4096);
+
+class @NAME@ : public gr_sync_block
+{
+private:
+ @NAME@ ();
+
+ public:
+ int length() const;
+ @O_TYPE@ scale() const;
+ void set_length_and_scale(int length, @O_TYPE@ scale);
+};
diff --git a/gnuradio-core/src/lib/gengen/gr_multiply_XX.cc.t b/gnuradio-core/src/lib/gengen/gr_multiply_XX.cc.t
new file mode 100644
index 000000000..a60118e14
--- /dev/null
+++ b/gnuradio-core/src/lib/gengen/gr_multiply_XX.cc.t
@@ -0,0 +1,63 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004, 2009,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+// @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 vlen)
+{
+ return gnuradio::get_initial_sptr (new @NAME@ (vlen));
+}
+
+@NAME@::@NAME@ (size_t vlen)
+ : gr_sync_block ("@BASE_NAME@",
+ gr_make_io_signature (1, -1, sizeof (@I_TYPE@)*vlen),
+ gr_make_io_signature (1, 1, sizeof (@O_TYPE@)*vlen)),
+ d_vlen (vlen)
+{
+}
+
+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 (size_t i = 0; i < noutput_items*d_vlen; 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/gengen/gr_multiply_XX.h.t b/gnuradio-core/src/lib/gengen/gr_multiply_XX.h.t
new file mode 100644
index 000000000..18ec6d0be
--- /dev/null
+++ b/gnuradio-core/src/lib/gengen/gr_multiply_XX.h.t
@@ -0,0 +1,57 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004, 2009 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+// @WARNING@
+
+#ifndef @GUARD_NAME@
+#define @GUARD_NAME@
+
+#include <gr_core_api.h>
+#include <gr_sync_block.h>
+
+class @NAME@;
+typedef boost::shared_ptr<@NAME@> @SPTR_NAME@;
+
+GR_CORE_API @SPTR_NAME@ gr_make_@BASE_NAME@ (size_t vlen = 1);
+
+/*!
+ * \brief output = prod (input_0, input_1, ...)
+ * \ingroup math_blk
+ *
+ * Multiply across all input streams.
+ */
+class GR_CORE_API @NAME@ : public gr_sync_block
+{
+ friend GR_CORE_API @SPTR_NAME@ gr_make_@BASE_NAME@ (size_t vlen);
+
+ @NAME@ (size_t vlen);
+
+ size_t d_vlen;
+
+ 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/gengen/gr_multiply_XX.i.t b/gnuradio-core/src/lib/gengen/gr_multiply_XX.i.t
new file mode 100644
index 000000000..b2c510610
--- /dev/null
+++ b/gnuradio-core/src/lib/gengen/gr_multiply_XX.i.t
@@ -0,0 +1,33 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004, 2009 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+// @WARNING@
+
+GR_SWIG_BLOCK_MAGIC(gr,@BASE_NAME@)
+
+@SPTR_NAME@ gr_make_@BASE_NAME@ (size_t vlen = 1);
+
+class @NAME@ : public gr_sync_block
+{
+ private:
+ @NAME@ (size_t vlen);
+};
diff --git a/gnuradio-core/src/lib/gengen/gr_multiply_const_XX.cc.t b/gnuradio-core/src/lib/gengen/gr_multiply_const_XX.cc.t
new file mode 100644
index 000000000..424b62412
--- /dev/null
+++ b/gnuradio-core/src/lib/gengen/gr_multiply_const_XX.cc.t
@@ -0,0 +1,72 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+// @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 gnuradio::get_initial_sptr (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/gengen/gr_multiply_const_XX.h.t b/gnuradio-core/src/lib/gengen/gr_multiply_const_XX.h.t
new file mode 100644
index 000000000..274fc3b99
--- /dev/null
+++ b/gnuradio-core/src/lib/gengen/gr_multiply_const_XX.h.t
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+// @WARNING@
+
+#ifndef @GUARD_NAME@
+#define @GUARD_NAME@
+
+#include <gr_core_api.h>
+#include <gr_sync_block.h>
+
+class @NAME@;
+typedef boost::shared_ptr<@NAME@> @SPTR_NAME@;
+
+GR_CORE_API @SPTR_NAME@ gr_make_@BASE_NAME@ (@O_TYPE@ k);
+
+/*!
+ * \brief output = input * constant
+ * \ingroup math_blk
+ */
+class GR_CORE_API @NAME@ : public gr_sync_block
+{
+ friend GR_CORE_API @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/gengen/gr_multiply_const_XX.i.t b/gnuradio-core/src/lib/gengen/gr_multiply_const_XX.i.t
new file mode 100644
index 000000000..b7921554e
--- /dev/null
+++ b/gnuradio-core/src/lib/gengen/gr_multiply_const_XX.i.t
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, 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/gengen/gr_multiply_const_vXX.cc.t b/gnuradio-core/src/lib/gengen/gr_multiply_const_vXX.cc.t
new file mode 100755
index 000000000..eb896dee5
--- /dev/null
+++ b/gnuradio-core/src/lib/gengen/gr_multiply_const_vXX.cc.t
@@ -0,0 +1,61 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2006,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+// @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 gnuradio::get_initial_sptr (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/gengen/gr_multiply_const_vXX.h.t b/gnuradio-core/src/lib/gengen/gr_multiply_const_vXX.h.t
new file mode 100644
index 000000000..2c6edd364
--- /dev/null
+++ b/gnuradio-core/src/lib/gengen/gr_multiply_const_vXX.h.t
@@ -0,0 +1,56 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2006,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+// @WARNING@
+
+#ifndef @GUARD_NAME@
+#define @GUARD_NAME@
+
+#include <gr_core_api.h>
+#include <gr_sync_block.h>
+
+class @NAME@;
+typedef boost::shared_ptr<@NAME@> @SPTR_NAME@;
+
+GR_CORE_API @SPTR_NAME@ gr_make_@BASE_NAME@ (const std::vector<@I_TYPE@> &k);
+
+/*!
+ * \brief output vector = input vector * constant vector (element-wise)
+ * \ingroup math_blk
+ */
+class GR_CORE_API @NAME@ : public gr_sync_block
+{
+ friend GR_CORE_API @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/gengen/gr_multiply_const_vXX.i.t b/gnuradio-core/src/lib/gengen/gr_multiply_const_vXX.i.t
new file mode 100755
index 000000000..e0e6ae905
--- /dev/null
+++ b/gnuradio-core/src/lib/gengen/gr_multiply_const_vXX.i.t
@@ -0,0 +1,37 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2006,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+// @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/gengen/gr_mute_XX.cc.t b/gnuradio-core/src/lib/gengen/gr_mute_XX.cc.t
new file mode 100644
index 000000000..4b8ff8415
--- /dev/null
+++ b/gnuradio-core/src/lib/gengen/gr_mute_XX.cc.t
@@ -0,0 +1,79 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+// @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 gnuradio::get_initial_sptr (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/gengen/gr_mute_XX.h.t b/gnuradio-core/src/lib/gengen/gr_mute_XX.h.t
new file mode 100644
index 000000000..ca23904e9
--- /dev/null
+++ b/gnuradio-core/src/lib/gengen/gr_mute_XX.h.t
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+// @WARNING@
+
+#ifndef @GUARD_NAME@
+#define @GUARD_NAME@
+
+#include <gr_core_api.h>
+#include <gr_sync_block.h>
+
+class @NAME@;
+typedef boost::shared_ptr<@NAME@> @SPTR_NAME@;
+
+GR_CORE_API @SPTR_NAME@ gr_make_@BASE_NAME@ (bool mute=false);
+
+/*!
+ * \brief output = input or zero if muted.
+ * \ingroup level_blk
+ */
+class GR_CORE_API @NAME@ : public gr_sync_block
+{
+ friend GR_CORE_API @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/gengen/gr_mute_XX.i.t b/gnuradio-core/src/lib/gengen/gr_mute_XX.i.t
new file mode 100644
index 000000000..ffcfac8a6
--- /dev/null
+++ b/gnuradio-core/src/lib/gengen/gr_mute_XX.i.t
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, 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/gengen/gr_noise_source_X.cc.t b/gnuradio-core/src/lib/gengen/gr_noise_source_X.cc.t
new file mode 100644
index 000000000..3078f6366
--- /dev/null
+++ b/gnuradio-core/src/lib/gengen/gr_noise_source_X.cc.t
@@ -0,0 +1,99 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+// @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 gnuradio::get_initial_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/gengen/gr_noise_source_X.h.t b/gnuradio-core/src/lib/gengen/gr_noise_source_X.h.t
new file mode 100644
index 000000000..31ffb2b16
--- /dev/null
+++ b/gnuradio-core/src/lib/gengen/gr_noise_source_X.h.t
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+// @WARNING@
+
+#ifndef @GUARD_NAME@
+#define @GUARD_NAME@
+
+#include <gr_core_api.h>
+#include <gr_sync_block.h>
+#include <gr_noise_type.h>
+#include <gr_random.h>
+
+
+class @NAME@;
+typedef boost::shared_ptr<@NAME@> @NAME@_sptr;
+
+/*! \brief Make a noise source
+ * \param type the random distribution to use (see gr_noise_type.h)
+ * \param ampl a scaling factor for the output
+ * \param seed seed for random generators. Note that for uniform and
+ * Gaussian distributions, this should be a negative number.
+ */
+GR_CORE_API @NAME@_sptr
+gr_make_@BASE_NAME@ (gr_noise_type_t type, float ampl, long seed = 0);
+
+/*!
+ * \brief Random number source
+ * \ingroup source_blk
+ *
+ * \details
+ * Generate random values from different distributions.
+ * Currently, only Gaussian and uniform are enabled.
+ *
+ * \param type the random distribution to use (see gr_noise_type.h)
+ * \param ampl a scaling factor for the output
+ * \param seed seed for random generators. Note that for uniform and
+ * Gaussian distributions, this should be a negative number.
+ */
+class GR_CORE_API @NAME@ : public gr_sync_block {
+ friend GR_CORE_API @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 = 0);
+
+ public:
+ void set_type (gr_noise_type_t type) { d_type = type; }
+ void set_amplitude (float ampl) { d_ampl = ampl; }
+
+ gr_noise_type_t type () const { return d_type; }
+ float amplitude () const { return d_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/gengen/gr_noise_source_X.i.t b/gnuradio-core/src/lib/gengen/gr_noise_source_X.i.t
new file mode 100644
index 000000000..df27ab79b
--- /dev/null
+++ b/gnuradio-core/src/lib/gengen/gr_noise_source_X.i.t
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+// @WARNING@
+
+GR_SWIG_BLOCK_MAGIC(gr,@BASE_NAME@);
+
+@NAME@_sptr
+gr_make_@BASE_NAME@ (gr_noise_type_t type, float ampl, long seed = 0);
+
+class @NAME@ : public gr_block {
+ private:
+ @NAME@ (gr_noise_type_t type, float ampl, long seed = 0);
+
+ public:
+ void set_type (gr_noise_type_t type) { d_type = type; }
+ void set_amplitude (float ampl) { d_ampl = ampl; }
+
+ gr_noise_type_t type () const { return d_type; }
+ float amplitude () const { return d_ampl; }
+};
diff --git a/gnuradio-core/src/lib/gengen/gr_noise_type.h b/gnuradio-core/src/lib/gengen/gr_noise_type.h
new file mode 100644
index 000000000..d2aba9b0c
--- /dev/null
+++ b/gnuradio-core/src/lib/gengen/gr_noise_type.h
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_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/gengen/gr_not_XX.cc.t b/gnuradio-core/src/lib/gengen/gr_not_XX.cc.t
new file mode 100644
index 000000000..4806b142f
--- /dev/null
+++ b/gnuradio-core/src/lib/gengen/gr_not_XX.cc.t
@@ -0,0 +1,58 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2008,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+// @WARNING@
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <@NAME@.h>
+#include <gr_io_signature.h>
+
+@SPTR_NAME@
+gr_make_@BASE_NAME@ ()
+{
+ return gnuradio::get_initial_sptr (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];
+ const @I_TYPE@ *inptr = (const @I_TYPE@ *) input_items[0];
+
+
+ for (int i = 0; i < noutput_items; i++) {
+ *optr++ = ~(inptr[i]);
+ }
+ return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/gengen/gr_not_XX.h.t b/gnuradio-core/src/lib/gengen/gr_not_XX.h.t
new file mode 100644
index 000000000..aff421109
--- /dev/null
+++ b/gnuradio-core/src/lib/gengen/gr_not_XX.h.t
@@ -0,0 +1,55 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2008 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+// @WARNING@
+
+#ifndef @GUARD_NAME@
+#define @GUARD_NAME@
+
+#include <gr_core_api.h>
+#include <gr_sync_block.h>
+
+class @NAME@;
+typedef boost::shared_ptr<@NAME@> @SPTR_NAME@;
+
+GR_CORE_API @SPTR_NAME@ gr_make_@BASE_NAME@ ();
+
+/*!
+ * \brief output = ~input_0
+ * \ingroup math_blk
+ *
+ * bitwise boolean not across input stream.
+ */
+class GR_CORE_API @NAME@ : public gr_sync_block
+{
+ friend GR_CORE_API @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/gengen/gr_not_XX.i.t b/gnuradio-core/src/lib/gengen/gr_not_XX.i.t
new file mode 100644
index 000000000..06db5ca59
--- /dev/null
+++ b/gnuradio-core/src/lib/gengen/gr_not_XX.i.t
@@ -0,0 +1,33 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2008 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+// @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/gengen/gr_or_XX.cc.t b/gnuradio-core/src/lib/gengen/gr_or_XX.cc.t
new file mode 100644
index 000000000..ee55eedda
--- /dev/null
+++ b/gnuradio-core/src/lib/gengen/gr_or_XX.cc.t
@@ -0,0 +1,62 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2008,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+// @WARNING@
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <@NAME@.h>
+#include <gr_io_signature.h>
+
+@SPTR_NAME@
+gr_make_@BASE_NAME@ ()
+{
+ return gnuradio::get_initial_sptr (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 = acc | ((@I_TYPE@ *) input_items[j])[i];
+
+ *optr++ = (@O_TYPE@) acc;
+ }
+ return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/gengen/gr_or_XX.h.t b/gnuradio-core/src/lib/gengen/gr_or_XX.h.t
new file mode 100644
index 000000000..8860eedd5
--- /dev/null
+++ b/gnuradio-core/src/lib/gengen/gr_or_XX.h.t
@@ -0,0 +1,55 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2008 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+// @WARNING@
+
+#ifndef @GUARD_NAME@
+#define @GUARD_NAME@
+
+#include <gr_core_api.h>
+#include <gr_sync_block.h>
+
+class @NAME@;
+typedef boost::shared_ptr<@NAME@> @SPTR_NAME@;
+
+GR_CORE_API @SPTR_NAME@ gr_make_@BASE_NAME@ ();
+
+/*!
+ * \brief output = input_0 | input_1 | , ... | input_N)
+ * \ingroup math_blk
+ *
+ * bitwise boolean or across all input streams.
+ */
+class GR_CORE_API @NAME@ : public gr_sync_block
+{
+ friend GR_CORE_API @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/gengen/gr_or_XX.i.t b/gnuradio-core/src/lib/gengen/gr_or_XX.i.t
new file mode 100644
index 000000000..06db5ca59
--- /dev/null
+++ b/gnuradio-core/src/lib/gengen/gr_or_XX.i.t
@@ -0,0 +1,33 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2008 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+// @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/gengen/gr_packed_to_unpacked_XX.cc.t b/gnuradio-core/src/lib/gengen/gr_packed_to_unpacked_XX.cc.t
new file mode 100644
index 000000000..75e53c4ca
--- /dev/null
+++ b/gnuradio-core/src/lib/gengen/gr_packed_to_unpacked_XX.cc.t
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, 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)
+{
+ unsigned int index_tmp = d_index;
+
+ 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];
+ index_tmp = d_index;
+
+ // 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++, index_tmp++)
+ x = (x<<1) | get_bit_be(in, index_tmp);
+ 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++, index_tmp++)
+ x = (x<<1) | get_bit_le(in, index_tmp);
+ 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));
+ }
+
+ d_index = index_tmp;
+ 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/gengen/gr_packed_to_unpacked_XX.h.t b/gnuradio-core/src/lib/gengen/gr_packed_to_unpacked_XX.h.t
new file mode 100644
index 000000000..e95771b37
--- /dev/null
+++ b/gnuradio-core/src/lib/gengen/gr_packed_to_unpacked_XX.h.t
@@ -0,0 +1,85 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+// @WARNING@
+
+#ifndef @GUARD_NAME@
+#define @GUARD_NAME@
+
+#include <gr_core_api.h>
+#include <gr_block.h>
+#include <gr_endianness.h>
+
+class @NAME@;
+typedef boost::shared_ptr<@NAME@> @SPTR_NAME@;
+
+GR_CORE_API @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 converter_blk
+ *
+ * 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 GR_CORE_API @NAME@ : public gr_block
+{
+ friend GR_CORE_API @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/gengen/gr_packed_to_unpacked_XX.i.t b/gnuradio-core/src/lib/gengen/gr_packed_to_unpacked_XX.i.t
new file mode 100644
index 000000000..1e978956a
--- /dev/null
+++ b/gnuradio-core/src/lib/gengen/gr_packed_to_unpacked_XX.i.t
@@ -0,0 +1,33 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+// @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/gengen/gr_peak_detector_XX.cc.t b/gnuradio-core/src/lib/gengen/gr_peak_detector_XX.cc.t
new file mode 100644
index 000000000..54af3c0cd
--- /dev/null
+++ b/gnuradio-core/src/lib/gengen/gr_peak_detector_XX.cc.t
@@ -0,0 +1,111 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+// @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@ (float threshold_factor_rise,
+ float threshold_factor_fall,
+ int look_ahead, float alpha)
+{
+ return gnuradio::get_initial_sptr (new @NAME@ (threshold_factor_rise,
+ threshold_factor_fall,
+ look_ahead, alpha));
+}
+
+@NAME@::@NAME@ (float threshold_factor_rise,
+ float threshold_factor_fall,
+ int look_ahead, float alpha)
+ : gr_sync_block ("@BASE_NAME@",
+ gr_make_io_signature (1, 1, sizeof (@I_TYPE@)),
+ gr_make_io_signature (1, 1, sizeof (char))),
+ d_threshold_factor_rise(threshold_factor_rise),
+ d_threshold_factor_fall(threshold_factor_fall),
+ d_look_ahead(look_ahead), d_avg_alpha(alpha), d_avg(0), d_found(0)
+{
+}
+
+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];
+ char *optr = (char *) output_items[0];
+
+ memset(optr, 0, noutput_items*sizeof(char));
+
+ @I_TYPE@ peak_val = -(@I_TYPE@)INFINITY;
+ int peak_ind = 0;
+ unsigned char state = 0;
+ int i = 0;
+
+ //printf("noutput_items %d\n",noutput_items);
+ while(i < noutput_items) {
+ if(state == 0) { // below threshold
+ if(iptr[i] > d_avg*d_threshold_factor_rise) {
+ state = 1;
+ }
+ else {
+ d_avg = (d_avg_alpha)*iptr[i] + (1-d_avg_alpha)*d_avg;
+ i++;
+ }
+ }
+ else if(state == 1) { // above threshold, have not found peak
+ //printf("Entered State 1: %f i: %d noutput_items: %d\n", iptr[i], i, noutput_items);
+ if(iptr[i] > peak_val) {
+ peak_val = iptr[i];
+ peak_ind = i;
+ d_avg = (d_avg_alpha)*iptr[i] + (1-d_avg_alpha)*d_avg;
+ i++;
+ }
+ else if (iptr[i] > d_avg*d_threshold_factor_fall) {
+ d_avg = (d_avg_alpha)*iptr[i] + (1-d_avg_alpha)*d_avg;
+ i++;
+ }
+ else {
+ optr[peak_ind] = 1;
+ state = 0;
+ peak_val = -(@I_TYPE@)INFINITY;
+ //printf("Leaving State 1: Peak: %f Peak Ind: %d i: %d noutput_items: %d\n",
+ //peak_val, peak_ind, i, noutput_items);
+ }
+ }
+ }
+
+ if(state == 0) {
+ //printf("Leave in State 0, produced %d\n",noutput_items);
+ return noutput_items;
+ }
+ else { // only return up to passing the threshold
+ //printf("Leave in State 1, only produced %d of %d\n",peak_ind,noutput_items);
+ return peak_ind+1;
+ }
+}
diff --git a/gnuradio-core/src/lib/gengen/gr_peak_detector_XX.h.t b/gnuradio-core/src/lib/gengen/gr_peak_detector_XX.h.t
new file mode 100644
index 000000000..3e05594fb
--- /dev/null
+++ b/gnuradio-core/src/lib/gengen/gr_peak_detector_XX.h.t
@@ -0,0 +1,126 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+// @WARNING@
+
+#ifndef @GUARD_NAME@
+#define @GUARD_NAME@
+
+#include <gr_core_api.h>
+#include <gr_sync_block.h>
+
+class @NAME@;
+typedef boost::shared_ptr<@NAME@> @SPTR_NAME@;
+
+GR_CORE_API @SPTR_NAME@ gr_make_@BASE_NAME@ (float threshold_factor_rise = 0.25,
+ float threshold_factor_fall = 0.40,
+ int look_ahead = 10,
+ float alpha = 0.001);
+
+/*!
+ * \brief Detect the peak of a signal
+ * \ingroup level_blk
+ *
+ * If a peak is detected, this block outputs a 1,
+ * or it outputs 0's.
+ *
+ * \param threshold_factor_rise The threshold factor determins when a peak
+ * has started. An average of the signal is calculated and when the
+ * value of the signal goes over threshold_factor_rise*average, we
+ * start looking for a peak.
+ * \param threshold_factor_fall The threshold factor determins when a peak
+ * has ended. An average of the signal is calculated and when the
+ * value of the signal goes bellow threshold_factor_fall*average, we
+ * stop looking for a peak.
+ * \param look_ahead The look-ahead value is used when the threshold is
+ * found to look if there another peak within this step range.
+ * If there is a larger value, we set that as the peak and look ahead
+ * again. This is continued until the highest point is found with
+ * This look-ahead range.
+ * \param alpha The gain value of a moving average filter
+ */
+class GR_CORE_API @NAME@ : public gr_sync_block
+{
+ friend GR_CORE_API @SPTR_NAME@ gr_make_@BASE_NAME@ (float threshold_factor_rise,
+ float threshold_factor_fall,
+ int look_ahead, float alpha);
+
+ @NAME@ (float threshold_factor_rise,
+ float threshold_factor_fall,
+ int look_ahead, float alpha);
+
+ private:
+ float d_threshold_factor_rise;
+ float d_threshold_factor_fall;
+ int d_look_ahead;
+ float d_avg_alpha;
+ float d_avg;
+ unsigned char d_found;
+
+ public:
+
+ /*! \brief Set the threshold factor value for the rise time
+ * \param thr new threshold factor
+ */
+ void set_threshold_factor_rise(float thr) { d_threshold_factor_rise = thr; }
+
+ /*! \brief Set the threshold factor value for the fall time
+ * \param thr new threshold factor
+ */
+ void set_threshold_factor_fall(float thr) { d_threshold_factor_fall = thr; }
+
+ /*! \brief Set the look-ahead factor
+ * \param look new look-ahead factor
+ */
+ void set_look_ahead(int look) { d_look_ahead = look; }
+
+ /*! \brief Set the running average alpha
+ * \param alpha new alpha for running average
+ */
+ void set_alpha(int alpha) { d_avg_alpha = alpha; }
+
+ /*! \brief Get the threshold factor value for the rise time
+ * \return threshold factor
+ */
+ float threshold_factor_rise() { return d_threshold_factor_rise; }
+
+ /*! \brief Get the threshold factor value for the fall time
+ * \return threshold factor
+ */
+ float threshold_factor_fall() { return d_threshold_factor_fall; }
+
+ /*! \brief Get the look-ahead factor value
+ * \return look-ahead factor
+ */
+ int look_ahead() { return d_look_ahead; }
+
+ /*! \brief Get the alpha value of the running average
+ * \return alpha
+ */
+ float alpha() { return d_avg_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/gengen/gr_peak_detector_XX.i.t b/gnuradio-core/src/lib/gengen/gr_peak_detector_XX.i.t
new file mode 100644
index 000000000..212ce0c94
--- /dev/null
+++ b/gnuradio-core/src/lib/gengen/gr_peak_detector_XX.i.t
@@ -0,0 +1,49 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+// @WARNING@
+
+GR_SWIG_BLOCK_MAGIC(gr,@BASE_NAME@)
+
+@SPTR_NAME@ gr_make_@BASE_NAME@ (float threshold_factor_rise = 0.25,
+ float threshold_factor_fall = 0.40,
+ int look_ahead = 10,
+ float alpha=0.001);
+
+class @NAME@ : public gr_sync_block
+{
+ private:
+ @NAME@ (float threshold_factor_rise,
+ float threshold_factor_fall,
+ int look_ahead, float alpha);
+
+ public:
+ void set_threshold_factor_rise(float thr) { d_threshold_factor_rise = thr; }
+ void set_threshold_factor_fall(float thr) { d_threshold_factor_fall = thr; }
+ void set_look_ahead(int look) { d_look_ahead = look; }
+ void set_alpha(int alpha) { d_avg_alpha = alpha; }
+
+ float threshold_factor_rise() { return d_threshold_factor_rise; }
+ float threshold_factor_fall() { return d_threshold_factor_fall; }
+ int look_ahead() { return d_look_ahead; }
+ float alpha() { return d_avg_alpha; }
+};
diff --git a/gnuradio-core/src/lib/gengen/gr_probe_signal_X.cc.t b/gnuradio-core/src/lib/gengen/gr_probe_signal_X.cc.t
new file mode 100644
index 000000000..9a10bab59
--- /dev/null
+++ b/gnuradio-core/src/lib/gengen/gr_probe_signal_X.cc.t
@@ -0,0 +1,59 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005,2010,2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include <@NAME@.h>
+#include <gr_io_signature.h>
+
+@NAME@_sptr
+gr_make_@BASE_NAME@()
+{
+ return gnuradio::get_initial_sptr(new @NAME@());
+}
+
+@NAME@::@NAME@ ()
+: gr_sync_block ("@BASE_NAME@",
+ gr_make_io_signature(1, 1, sizeof(@TYPE@)),
+ gr_make_io_signature(0, 0, 0)),
+ d_level(0)
+{
+}
+
+@NAME@::~@NAME@()
+{
+}
+
+
+int
+@NAME@::work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ const @TYPE@ *in = (const @TYPE@ *) input_items[0];
+
+ if (noutput_items > 0)
+ d_level = in[noutput_items-1];
+
+ return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/gengen/gr_probe_signal_X.h.t b/gnuradio-core/src/lib/gengen/gr_probe_signal_X.h.t
new file mode 100644
index 000000000..936f437f1
--- /dev/null
+++ b/gnuradio-core/src/lib/gengen/gr_probe_signal_X.h.t
@@ -0,0 +1,58 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005, 2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifndef @GUARD_NAME@
+#define @GUARD_NAME@
+
+#include <gr_core_api.h>
+#include <gr_sync_block.h>
+
+class @NAME@;
+typedef boost::shared_ptr<@NAME@> @NAME@_sptr;
+
+GR_CORE_API @NAME@_sptr
+gr_make_@BASE_NAME@ ();
+
+/*!
+ * \brief Sink that allows a sample to be grabbed from Python.
+ * \ingroup sink_blk
+ */
+class GR_CORE_API @NAME@ : public gr_sync_block
+{
+ @TYPE@ d_level;
+
+ friend GR_CORE_API @NAME@_sptr
+ gr_make_@BASE_NAME@();
+
+ @NAME@();
+
+public:
+ ~@NAME@();
+
+ int work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+
+ @TYPE@ level() const { return d_level; }
+
+};
+
+#endif /* @GUARD_NAME@ */
diff --git a/gnuradio-core/src/lib/gengen/gr_probe_signal_X.i.t b/gnuradio-core/src/lib/gengen/gr_probe_signal_X.i.t
new file mode 100644
index 000000000..ec9643686
--- /dev/null
+++ b/gnuradio-core/src/lib/gengen/gr_probe_signal_X.i.t
@@ -0,0 +1,32 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005, 2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,@BASE_NAME@);
+
+@NAME@_sptr
+gr_make_@BASE_NAME@ ();
+
+class @NAME@ : public gr_sync_block
+{
+public:
+ @TYPE@ level ();
+};
diff --git a/gnuradio-core/src/lib/gengen/gr_probe_signal_vX.cc.t b/gnuradio-core/src/lib/gengen/gr_probe_signal_vX.cc.t
new file mode 100644
index 000000000..1aedca4ec
--- /dev/null
+++ b/gnuradio-core/src/lib/gengen/gr_probe_signal_vX.cc.t
@@ -0,0 +1,59 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005,2010,2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include <@NAME@.h>
+#include <gr_io_signature.h>
+#include <iostream>
+
+@NAME@_sptr
+gr_make_@BASE_NAME@(size_t size)
+{
+ return gnuradio::get_initial_sptr(new @NAME@(size));
+}
+
+@NAME@::@NAME@ (size_t size)
+: gr_sync_block ("@BASE_NAME@",
+ gr_make_io_signature(1, 1, size*sizeof(@TYPE@)),
+ gr_make_io_signature(0, 0, 0)),
+ d_level(size, 0), d_size(size)
+{
+}
+
+@NAME@::~@NAME@()
+{
+}
+
+int
+@NAME@::work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ const @TYPE@ *in = (const @TYPE@ *) input_items[0];
+
+ for (size_t i=0; i<d_size; i++)
+ d_level[i] = in[(noutput_items-1)*d_size+i];
+
+ return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/gengen/gr_probe_signal_vX.h.t b/gnuradio-core/src/lib/gengen/gr_probe_signal_vX.h.t
new file mode 100644
index 000000000..ee673c14a
--- /dev/null
+++ b/gnuradio-core/src/lib/gengen/gr_probe_signal_vX.h.t
@@ -0,0 +1,62 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005, 2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifndef @GUARD_NAME@
+#define @GUARD_NAME@
+
+#include <vector>
+
+#include <gr_core_api.h>
+#include <gr_sync_block.h>
+
+class @NAME@;
+typedef boost::shared_ptr<@NAME@> @NAME@_sptr;
+
+GR_CORE_API @NAME@_sptr
+gr_make_@BASE_NAME@ (size_t size);
+
+/*!
+ * \brief Sink that allows a sample to be grabbed from Python.
+ * \ingroup sink_blk
+ */
+class GR_CORE_API @NAME@ : public gr_sync_block
+{
+ std::vector<@TYPE@> d_level;
+
+ friend GR_CORE_API @NAME@_sptr
+ gr_make_@BASE_NAME@(size_t size);
+
+ @NAME@(size_t size);
+
+ size_t d_size;
+
+public:
+ ~@NAME@();
+
+ int work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+
+ std::vector<@TYPE@> level() const { return d_level; }
+
+};
+
+#endif /* @GUARD_NAME@ */
diff --git a/gnuradio-core/src/lib/gengen/gr_probe_signal_vX.i.t b/gnuradio-core/src/lib/gengen/gr_probe_signal_vX.i.t
new file mode 100644
index 000000000..b7de09125
--- /dev/null
+++ b/gnuradio-core/src/lib/gengen/gr_probe_signal_vX.i.t
@@ -0,0 +1,32 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005, 2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,@BASE_NAME@);
+
+@NAME@_sptr
+gr_make_@BASE_NAME@ (size_t size);
+
+class @NAME@ : public gr_sync_block
+{
+public:
+ std::vector<@TYPE@> level ();
+};
diff --git a/gnuradio-core/src/lib/gengen/gr_sample_and_hold_XX.cc.t b/gnuradio-core/src/lib/gengen/gr_sample_and_hold_XX.cc.t
new file mode 100644
index 000000000..68f4d544e
--- /dev/null
+++ b/gnuradio-core/src/lib/gengen/gr_sample_and_hold_XX.cc.t
@@ -0,0 +1,62 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+// @WARNING@
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <@NAME@.h>
+#include <gr_io_signature.h>
+
+@SPTR_NAME@
+gr_make_@BASE_NAME@ ()
+{
+ return gnuradio::get_initial_sptr (new @NAME@ ());
+}
+
+@NAME@::@NAME@ ()
+ : gr_sync_block ("@BASE_NAME@",
+ gr_make_io_signature2 (2, 2, sizeof (@I_TYPE@), sizeof(char)),
+ gr_make_io_signature (1, 1, sizeof (@O_TYPE@))),
+ d_data(0)
+{
+}
+
+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];
+ const char *ctrl = (const char *) input_items[1];
+ @O_TYPE@ *optr = (@O_TYPE@ *) output_items[0];
+
+ for (int i = 0; i < noutput_items; i++){
+ if(ctrl[i]) {
+ d_data = iptr[i];
+ }
+ optr[i] = d_data;
+ }
+ return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/gengen/gr_sample_and_hold_XX.h.t b/gnuradio-core/src/lib/gengen/gr_sample_and_hold_XX.h.t
new file mode 100644
index 000000000..0364941cb
--- /dev/null
+++ b/gnuradio-core/src/lib/gengen/gr_sample_and_hold_XX.h.t
@@ -0,0 +1,58 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+// @WARNING@
+
+#ifndef @GUARD_NAME@
+#define @GUARD_NAME@
+
+#include <gr_core_api.h>
+#include <gr_sync_block.h>
+
+class @NAME@;
+typedef boost::shared_ptr<@NAME@> @SPTR_NAME@;
+
+GR_CORE_API @SPTR_NAME@ gr_make_@BASE_NAME@ ();
+
+/*!
+ * \brief sample and hold circuit
+ * \ingroup level_blk
+ *
+ * Samples the data stream (input stream 0) and holds the value
+ * if the control signal is 1 (intput stream 1).
+ */
+class GR_CORE_API @NAME@ : public gr_sync_block
+{
+ friend GR_CORE_API @SPTR_NAME@ gr_make_@BASE_NAME@ ();
+
+ @NAME@ ();
+
+ private:
+ @O_TYPE@ d_data;
+
+ 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/gengen/gr_sample_and_hold_XX.i.t b/gnuradio-core/src/lib/gengen/gr_sample_and_hold_XX.i.t
new file mode 100644
index 000000000..4620b0f2c
--- /dev/null
+++ b/gnuradio-core/src/lib/gengen/gr_sample_and_hold_XX.i.t
@@ -0,0 +1,33 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+// @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/gengen/gr_sig_source_X.cc.t b/gnuradio-core/src/lib/gengen/gr_sig_source_X.cc.t
new file mode 100644
index 000000000..6959eac82
--- /dev/null
+++ b/gnuradio-core/src/lib/gengen/gr_sig_source_X.cc.t
@@ -0,0 +1,241 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+// @WARNING@
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <@NAME@.h>
+#include <algorithm>
+#include <gr_io_signature.h>
+#include <stdexcept>
+#include <algorithm>
+#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 gnuradio::get_initial_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;
+ std::fill_n(optr, noutput_items, 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;
+
+ /* Implements a real square wave high from -PI to 0.
+ * The imaginary square wave leads by 90 deg.
+ */
+ case GR_SQR_WAVE:
+ for (int i = 0; i < noutput_items; i++){
+ if (d_nco.get_phase() < -1*M_PI/2)
+ optr[i] = gr_complex(d_ampl, 0)+d_offset;
+ else if (d_nco.get_phase() < 0)
+ optr[i] = gr_complex(d_ampl, d_ampl)+d_offset;
+ else if (d_nco.get_phase() < M_PI/2)
+ optr[i] = gr_complex(0, d_ampl)+d_offset;
+ else
+ optr[i] = d_offset;
+ d_nco.step();
+ }
+ break;
+
+ /* Implements a real triangle wave rising from -PI to 0 and
+ * falling from 0 to PI. The imaginary triangle wave leads by 90 deg.
+ */
+ case GR_TRI_WAVE:
+ for (int i = 0; i < noutput_items; i++){
+ if (d_nco.get_phase() < -1*M_PI/2){
+ optr[i] = gr_complex(d_ampl*d_nco.get_phase()/M_PI + d_ampl,
+ -1*d_ampl*d_nco.get_phase()/M_PI - d_ampl/2)+d_offset;
+ }
+ else if (d_nco.get_phase() < 0){
+ optr[i] = gr_complex(d_ampl*d_nco.get_phase()/M_PI + d_ampl,
+ d_ampl*d_nco.get_phase()/M_PI + d_ampl/2)+d_offset;
+ }
+ else if (d_nco.get_phase() < M_PI/2){
+ optr[i] = gr_complex(-1*d_ampl*d_nco.get_phase()/M_PI + d_ampl,
+ d_ampl*d_nco.get_phase()/M_PI + d_ampl/2)+d_offset;
+ }
+ else{
+ optr[i] = gr_complex(-1*d_ampl*d_nco.get_phase()/M_PI + d_ampl,
+ -1*d_ampl*d_nco.get_phase()/M_PI + 3*d_ampl/2)+d_offset;
+ }
+ d_nco.step();
+ }
+ break;
+
+ /* Implements a real saw tooth wave rising from -PI to PI.
+ * The imaginary saw tooth wave leads by 90 deg.
+ */
+ case GR_SAW_WAVE:
+ for (int i = 0; i < noutput_items; i++){
+ if (d_nco.get_phase() < -1*M_PI/2){
+ optr[i] = gr_complex(d_ampl*d_nco.get_phase()/(2*M_PI) + d_ampl/2,
+ d_ampl*d_nco.get_phase()/(2*M_PI) + 5*d_ampl/4)+d_offset;
+ }
+ else{
+ optr[i] = gr_complex(d_ampl*d_nco.get_phase()/(2*M_PI) + d_ampl/2,
+ d_ampl*d_nco.get_phase()/(2*M_PI) + d_ampl/4)+d_offset;
+ }
+ d_nco.step();
+ }
+ break;
+
+#else // nope...
+
+ case GR_CONST_WAVE:
+ t = (@TYPE@) d_ampl + d_offset;
+ std::fill_n(optr, noutput_items, 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;
+
+ /* The square wave is high from -PI to 0. */
+ case GR_SQR_WAVE:
+ t = (@TYPE@) d_ampl + d_offset;
+ for (int i = 0; i < noutput_items; i++){
+ if (d_nco.get_phase() < 0)
+ optr[i] = t;
+ else
+ optr[i] = d_offset;
+ d_nco.step();
+ }
+ break;
+
+ /* The triangle wave rises from -PI to 0 and falls from 0 to PI. */
+ case GR_TRI_WAVE:
+ for (int i = 0; i < noutput_items; i++){
+ double t = d_ampl*d_nco.get_phase()/M_PI;
+ if (d_nco.get_phase() < 0)
+ optr[i] = static_cast<@TYPE@>(t + d_ampl + d_offset);
+ else
+ optr[i] = static_cast<@TYPE@>(-1*t + d_ampl + d_offset);
+ d_nco.step();
+ }
+ break;
+
+ /* The saw tooth wave rises from -PI to PI. */
+ case GR_SAW_WAVE:
+ for (int i = 0; i < noutput_items; i++){
+ t = static_cast<@TYPE@>(d_ampl*d_nco.get_phase()/(2*M_PI) + d_ampl/2 + d_offset);
+ optr[i] = t;
+ d_nco.step();
+ }
+ 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/gengen/gr_sig_source_X.h.t b/gnuradio-core/src/lib/gengen/gr_sig_source_X.h.t
new file mode 100644
index 000000000..baa82dbe2
--- /dev/null
+++ b/gnuradio-core/src/lib/gengen/gr_sig_source_X.h.t
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+// @WARNING@
+
+#ifndef @GUARD_NAME@
+#define @GUARD_NAME@
+
+#include <gr_core_api.h>
+#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_blk
+ */
+
+class GR_CORE_API @NAME@ : public gr_sync_block {
+ friend GR_CORE_API @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);
+};
+
+GR_CORE_API @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/gengen/gr_sig_source_X.i.t b/gnuradio-core/src/lib/gengen/gr_sig_source_X.i.t
new file mode 100644
index 000000000..7bd85fcb8
--- /dev/null
+++ b/gnuradio-core/src/lib/gengen/gr_sig_source_X.i.t
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, 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/gengen/gr_sig_source_waveform.h b/gnuradio-core/src/lib/gengen/gr_sig_source_waveform.h
new file mode 100644
index 000000000..9fe233ba4
--- /dev/null
+++ b/gnuradio-core/src/lib/gengen/gr_sig_source_waveform.h
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifndef INCLUDED_GR_SIG_SOURCE_WAVEFORM_H
+#define INCLUDED_GR_SIG_SOURCE_WAVEFORM_H
+
+typedef enum {
+ GR_CONST_WAVE = 100, GR_SIN_WAVE, GR_COS_WAVE, GR_SQR_WAVE, GR_TRI_WAVE, GR_SAW_WAVE
+} gr_waveform_t;
+
+#endif /* INCLUDED_GR_SIG_SOURCE_WAVEFORM_H */
diff --git a/gnuradio-core/src/lib/gengen/gr_sub_XX.cc.t b/gnuradio-core/src/lib/gengen/gr_sub_XX.cc.t
new file mode 100644
index 000000000..11eb7440e
--- /dev/null
+++ b/gnuradio-core/src/lib/gengen/gr_sub_XX.cc.t
@@ -0,0 +1,71 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004, 2009,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+// @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 vlen)
+{
+ return gnuradio::get_initial_sptr (new @NAME@ (vlen));
+}
+
+@NAME@::@NAME@ (size_t vlen)
+ : gr_sync_block ("@BASE_NAME@",
+ gr_make_io_signature (1, -1, sizeof (@I_TYPE@)*vlen),
+ gr_make_io_signature (1, 1, sizeof (@O_TYPE@)*vlen)),
+ d_vlen (vlen)
+{
+}
+
+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 (size_t i = 0; i < noutput_items*d_vlen; i++)
+ *optr++ = (@O_TYPE@) -((@I_TYPE@ *) input_items[0])[i];
+ }
+
+ else {
+ for (size_t i = 0; i < noutput_items*d_vlen; 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/gengen/gr_sub_XX.h.t b/gnuradio-core/src/lib/gengen/gr_sub_XX.h.t
new file mode 100644
index 000000000..f96c93484
--- /dev/null
+++ b/gnuradio-core/src/lib/gengen/gr_sub_XX.h.t
@@ -0,0 +1,57 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004, 2009 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+// @WARNING@
+
+#ifndef @GUARD_NAME@
+#define @GUARD_NAME@
+
+#include <gr_core_api.h>
+#include <gr_sync_block.h>
+
+class @NAME@;
+typedef boost::shared_ptr<@NAME@> @SPTR_NAME@;
+
+GR_CORE_API @SPTR_NAME@ gr_make_@BASE_NAME@ (size_t vlen = 1);
+
+/*!
+ * \brief output = input_0 - input_1 - ...)
+ * \ingroup math_blk
+ *
+ * Subtract across all input streams.
+ */
+class GR_CORE_API @NAME@ : public gr_sync_block
+{
+ friend GR_CORE_API @SPTR_NAME@ gr_make_@BASE_NAME@ (size_t vlen);
+
+ @NAME@ (size_t vlen);
+
+ size_t d_vlen;
+
+ 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/gengen/gr_sub_XX.i.t b/gnuradio-core/src/lib/gengen/gr_sub_XX.i.t
new file mode 100644
index 000000000..b2c510610
--- /dev/null
+++ b/gnuradio-core/src/lib/gengen/gr_sub_XX.i.t
@@ -0,0 +1,33 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004, 2009 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+// @WARNING@
+
+GR_SWIG_BLOCK_MAGIC(gr,@BASE_NAME@)
+
+@SPTR_NAME@ gr_make_@BASE_NAME@ (size_t vlen = 1);
+
+class @NAME@ : public gr_sync_block
+{
+ private:
+ @NAME@ (size_t vlen);
+};
diff --git a/gnuradio-core/src/lib/gengen/gr_unpacked_to_packed_XX.cc.t b/gnuradio-core/src/lib/gengen/gr_unpacked_to_packed_XX.cc.t
new file mode 100644
index 000000000..ed2b713db
--- /dev/null
+++ b/gnuradio-core/src/lib/gengen/gr_unpacked_to_packed_XX.cc.t
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, 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)
+{
+ unsigned int index_tmp = d_index;
+
+ 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];
+ index_tmp=d_index;
+
+ // 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,index_tmp,d_bits_per_chunk);
+ index_tmp++;
+ }
+ 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,index_tmp,d_bits_per_chunk)<<(BITS_PER_TYPE-1));
+ index_tmp++;
+ }
+ out[i] = tmp;
+ }
+ break;
+
+ default:
+ assert(0);
+ }
+ }
+
+ d_index = index_tmp;
+ 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/gengen/gr_unpacked_to_packed_XX.h.t b/gnuradio-core/src/lib/gengen/gr_unpacked_to_packed_XX.h.t
new file mode 100644
index 000000000..a7b7b54df
--- /dev/null
+++ b/gnuradio-core/src/lib/gengen/gr_unpacked_to_packed_XX.h.t
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+// @WARNING@
+
+#ifndef @GUARD_NAME@
+#define @GUARD_NAME@
+
+#include <gr_core_api.h>
+#include <gr_block.h>
+#include <gr_endianness.h>
+
+class @NAME@;
+typedef boost::shared_ptr<@NAME@> @NAME@_sptr;
+
+GR_CORE_API @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 converter_blk
+ *
+ * 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 GR_CORE_API @NAME@ : public gr_block
+{
+ friend GR_CORE_API @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/gengen/gr_unpacked_to_packed_XX.i.t b/gnuradio-core/src/lib/gengen/gr_unpacked_to_packed_XX.i.t
new file mode 100644
index 000000000..1e978956a
--- /dev/null
+++ b/gnuradio-core/src/lib/gengen/gr_unpacked_to_packed_XX.i.t
@@ -0,0 +1,33 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+// @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/gengen/gr_vector_insert_X.cc.t b/gnuradio-core/src/lib/gengen/gr_vector_insert_X.cc.t
new file mode 100644
index 000000000..20968afe2
--- /dev/null
+++ b/gnuradio-core/src/lib/gengen/gr_vector_insert_X.cc.t
@@ -0,0 +1,100 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+// @WARNING@
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <@NAME@.h>
+#include <algorithm>
+#include <gr_io_signature.h>
+#include <stdexcept>
+
+#include <stdio.h>
+
+@NAME@::@NAME@(const std::vector<@TYPE@> &data, int periodicity, int offset)
+ : gr_block("@BASE_NAME@",
+ gr_make_io_signature (1, 1, sizeof(@TYPE@)),
+ gr_make_io_signature (1, 1, sizeof(@TYPE@))),
+ d_data(data),
+ d_offset(offset),
+ d_periodicity(periodicity)
+{
+ //printf("INITIAL: periodicity = %d, offset = %d\n", periodicity, offset);
+ // some sanity checks
+ assert(offset < periodicity);
+ assert(offset >= 0);
+ assert((size_t)periodicity > data.size());
+}
+
+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)
+{
+ @TYPE@ *out = (@TYPE@ *)output_items[0];
+ const @TYPE@ *in = (const @TYPE@ *)input_items[0];
+
+ int ii(0), oo(0);
+
+ while((oo < noutput_items) && (ii < ninput_items[0])) {
+
+ //printf("oo = %d, ii = %d, d_offset = %d, noutput_items = %d, ninput_items[0] = %d", oo, ii, d_offset, noutput_items, ninput_items[0]);
+ //printf(", d_periodicity = %d\n", d_periodicity);
+
+ if(d_offset >= ((int)d_data.size())) { // if we are in the copy region
+ int max_copy = std::min( std::min( noutput_items - oo, ninput_items[0] - ii ), d_periodicity - d_offset );
+ //printf("copy %d from input\n", max_copy);
+ memcpy( &out[oo], &in[ii], sizeof(@TYPE@)*max_copy );
+ //printf(" * memcpy returned.\n");
+ ii += max_copy;
+ oo += max_copy;
+ d_offset = (d_offset + max_copy)%d_periodicity;
+
+ }
+ else { // if we are in the insertion region
+ int max_copy = std::min( noutput_items - oo, ((int)d_data.size()) - d_offset );
+ //printf("copy %d from d_data[%d] to out[%d]\n", max_copy, d_offset, oo);
+ memcpy( &out[oo], &d_data[d_offset], sizeof(@TYPE@)*max_copy );
+ //printf(" * memcpy returned.\n");
+ oo += max_copy;
+ d_offset = (d_offset + max_copy)%d_periodicity;
+ //printf(" ## (inelse) oo = %d, d_offset = %d\n", oo, d_offset);
+ }
+
+ //printf(" # exit else, on to next loop.\n");
+ }
+ //printf(" # got out of loop\n");
+
+ //printf("consume = %d, produce = %d\n", ii, oo);
+ consume_each(ii);
+ return oo;
+}
+
+@NAME@_sptr
+gr_make_@BASE_NAME@ (const std::vector<@TYPE@> &data, int periodicity, int offset)
+{
+ return gnuradio::get_initial_sptr(new @NAME@ (data, periodicity, offset));
+}
+
diff --git a/gnuradio-core/src/lib/gengen/gr_vector_insert_X.h.t b/gnuradio-core/src/lib/gengen/gr_vector_insert_X.h.t
new file mode 100644
index 000000000..26f851700
--- /dev/null
+++ b/gnuradio-core/src/lib/gengen/gr_vector_insert_X.h.t
@@ -0,0 +1,61 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+// @WARNING@
+
+#ifndef @GUARD_NAME@
+#define @GUARD_NAME@
+
+#include <gr_core_api.h>
+#include <gr_block.h>
+
+class GR_CORE_API @NAME@;
+typedef boost::shared_ptr<@NAME@> @NAME@_sptr;
+
+/*!
+ * \brief source of @TYPE@'s that gets its data from a vector
+ * \ingroup source_blk
+ */
+
+class @NAME@ : public gr_block {
+ friend GR_CORE_API @NAME@_sptr
+ gr_make_@BASE_NAME@(const std::vector<@TYPE@> &data, int periodicity, int offset);
+
+ std::vector<@TYPE@> d_data;
+ int d_offset;
+ int d_periodicity;
+
+ @NAME@(const std::vector<@TYPE@> &data, int periodicity, int offset);
+
+ public:
+ void rewind() {d_offset=0;}
+ 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);
+ void set_data(const std::vector<@TYPE@> &data){ d_data = data; rewind(); }
+};
+
+GR_CORE_API @NAME@_sptr
+gr_make_@BASE_NAME@(const std::vector<@TYPE@> &data, int periodicity, int offset=0);
+
+#endif
diff --git a/gnuradio-core/src/lib/gengen/gr_vector_insert_X.i.t b/gnuradio-core/src/lib/gengen/gr_vector_insert_X.i.t
new file mode 100644
index 000000000..f3341eec4
--- /dev/null
+++ b/gnuradio-core/src/lib/gengen/gr_vector_insert_X.i.t
@@ -0,0 +1,37 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+// @WARNING@
+
+GR_SWIG_BLOCK_MAGIC(gr,@BASE_NAME@);
+
+@NAME@_sptr
+gr_make_@BASE_NAME@ (const std::vector<@TYPE@> &data, int periodicity, int offset = 0)
+ throw(std::invalid_argument);
+
+class @NAME@ : public gr_block {
+ public:
+ void rewind();
+ void set_data(const std::vector<@TYPE@> &data);
+ private:
+ @NAME@ (const std::vector<@TYPE@> &data, int periodicity, int offset = 0);
+};
diff --git a/gnuradio-core/src/lib/gengen/gr_vector_sink_X.cc.t b/gnuradio-core/src/lib/gengen/gr_vector_sink_X.cc.t
new file mode 100644
index 000000000..a9e3a0a3e
--- /dev/null
+++ b/gnuradio-core/src/lib/gengen/gr_vector_sink_X.cc.t
@@ -0,0 +1,64 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2008,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+// @WARNING@
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <@NAME@.h>
+#include <algorithm>
+#include <gr_io_signature.h>
+
+
+@NAME@::@NAME@ (int vlen)
+ : gr_sync_block ("@BASE_NAME@",
+ gr_make_io_signature (1, 1, sizeof (@TYPE@) * vlen),
+ gr_make_io_signature (0, 0, 0)),
+ d_vlen(vlen)
+{
+}
+
+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 * d_vlen; i++)
+ d_data.push_back (iptr[i]);
+
+ return noutput_items;
+}
+
+
+@NAME@_sptr
+gr_make_@BASE_NAME@ (int vlen)
+{
+ return gnuradio::get_initial_sptr(new @NAME@ (vlen));
+}
+
+std::vector<@TYPE@>
+@NAME@::data () const
+{
+ return d_data;
+}
diff --git a/gnuradio-core/src/lib/gengen/gr_vector_sink_X.h.t b/gnuradio-core/src/lib/gengen/gr_vector_sink_X.h.t
new file mode 100644
index 000000000..b9126dc7b
--- /dev/null
+++ b/gnuradio-core/src/lib/gengen/gr_vector_sink_X.h.t
@@ -0,0 +1,59 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2008,2009 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+// @WARNING@
+
+#ifndef @GUARD_NAME@
+#define @GUARD_NAME@
+
+#include <gr_core_api.h>
+#include <gr_sync_block.h>
+
+class @NAME@;
+typedef boost::shared_ptr<@NAME@> @NAME@_sptr;
+
+GR_CORE_API @NAME@_sptr
+gr_make_@BASE_NAME@ (int vlen = 1);
+
+
+/*!
+ * \brief @TYPE@ sink that writes to a vector
+ * \ingroup sink_blk
+ */
+
+class GR_CORE_API @NAME@ : public gr_sync_block {
+ friend GR_CORE_API @NAME@_sptr gr_make_@BASE_NAME@ (int vlen);
+ std::vector<@TYPE@> d_data;
+ int d_vlen;
+ @NAME@ (int vlen);
+
+ public:
+ virtual int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+
+ void reset() {d_data.clear();}
+ void clear() {reset(); } // deprecated
+ std::vector<@TYPE@> data () const;
+};
+
+#endif
diff --git a/gnuradio-core/src/lib/gengen/gr_vector_sink_X.i.t b/gnuradio-core/src/lib/gengen/gr_vector_sink_X.i.t
new file mode 100644
index 000000000..d4a940911
--- /dev/null
+++ b/gnuradio-core/src/lib/gengen/gr_vector_sink_X.i.t
@@ -0,0 +1,39 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2008,2009 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+// @WARNING@
+
+
+GR_SWIG_BLOCK_MAGIC(gr,@BASE_NAME@);
+
+@SPTR_NAME@ gr_make_@BASE_NAME@ (int vlen = 1);
+
+class @NAME@ : public gr_sync_block {
+ private:
+ @NAME@ (int vlen);
+
+ public:
+ void clear(); // deprecated
+ void reset();
+ std::vector<@TYPE@> data () const;
+};
+
diff --git a/gnuradio-core/src/lib/gengen/gr_vector_source_X.cc.t b/gnuradio-core/src/lib/gengen/gr_vector_source_X.cc.t
new file mode 100644
index 000000000..9f68f9cf1
--- /dev/null
+++ b/gnuradio-core/src/lib/gengen/gr_vector_source_X.cc.t
@@ -0,0 +1,89 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2008,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+// @WARNING@
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <@NAME@.h>
+#include <algorithm>
+#include <gr_io_signature.h>
+#include <stdexcept>
+
+
+@NAME@::@NAME@ (const std::vector<@TYPE@> &data, bool repeat, int vlen)
+ : gr_sync_block ("@BASE_NAME@",
+ gr_make_io_signature (0, 0, 0),
+ gr_make_io_signature (1, 1, sizeof (@TYPE@) * vlen)),
+ d_data (data),
+ d_repeat (repeat),
+ d_offset (0),
+ d_vlen (vlen)
+{
+ if ((data.size() % vlen) != 0)
+ throw std::invalid_argument("data length must be a multiple of vlen");
+}
+
+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*d_vlen; 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*d_vlen);
+ for (unsigned i = 0; i < n; i++)
+ optr[i] = d_data[d_offset + i];
+
+ d_offset += n;
+ return n/d_vlen;
+ }
+}
+
+@NAME@_sptr
+gr_make_@BASE_NAME@ (const std::vector<@TYPE@> &data, bool repeat, int vlen)
+{
+ return gnuradio::get_initial_sptr(new @NAME@ (data, repeat, vlen));
+}
+
diff --git a/gnuradio-core/src/lib/gengen/gr_vector_source_X.h.t b/gnuradio-core/src/lib/gengen/gr_vector_source_X.h.t
new file mode 100644
index 000000000..fe02c1346
--- /dev/null
+++ b/gnuradio-core/src/lib/gengen/gr_vector_source_X.h.t
@@ -0,0 +1,61 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2008,2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+// @WARNING@
+
+#ifndef @GUARD_NAME@
+#define @GUARD_NAME@
+
+#include <gr_core_api.h>
+#include <gr_sync_block.h>
+
+class GR_CORE_API @NAME@;
+typedef boost::shared_ptr<@NAME@> @NAME@_sptr;
+
+/*!
+ * \brief source of @TYPE@'s that gets its data from a vector
+ * \ingroup source_blk
+ */
+
+class @NAME@ : public gr_sync_block {
+ friend GR_CORE_API @NAME@_sptr
+ gr_make_@BASE_NAME@ (const std::vector<@TYPE@> &data, bool repeat, int vlen);
+
+ std::vector<@TYPE@> d_data;
+ bool d_repeat;
+ unsigned int d_offset;
+ int d_vlen;
+
+ @NAME@ (const std::vector<@TYPE@> &data, bool repeat, int vlen);
+
+ public:
+ void rewind() {d_offset=0;}
+ virtual int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+ void set_data(const std::vector<@TYPE@> &data){ d_data = data; rewind(); }
+};
+
+GR_CORE_API @NAME@_sptr
+gr_make_@BASE_NAME@ (const std::vector<@TYPE@> &data, bool repeat = false, int vlen = 1);
+
+#endif
diff --git a/gnuradio-core/src/lib/gengen/gr_vector_source_X.i.t b/gnuradio-core/src/lib/gengen/gr_vector_source_X.i.t
new file mode 100644
index 000000000..4986c68a3
--- /dev/null
+++ b/gnuradio-core/src/lib/gengen/gr_vector_source_X.i.t
@@ -0,0 +1,37 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2008,2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+// @WARNING@
+
+GR_SWIG_BLOCK_MAGIC(gr,@BASE_NAME@);
+
+@NAME@_sptr
+gr_make_@BASE_NAME@ (const std::vector<@TYPE@> &data, bool repeat = false, int vlen = 1)
+ throw(std::invalid_argument);
+
+class @NAME@ : public gr_sync_block {
+ public:
+ void rewind();
+ void set_data(const std::vector<@TYPE@> &data);
+ private:
+ @NAME@ (const std::vector<@TYPE@> &data, int vlen);
+};
diff --git a/gnuradio-core/src/lib/gengen/gr_xor_XX.cc.t b/gnuradio-core/src/lib/gengen/gr_xor_XX.cc.t
new file mode 100644
index 000000000..d6990aa4f
--- /dev/null
+++ b/gnuradio-core/src/lib/gengen/gr_xor_XX.cc.t
@@ -0,0 +1,62 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2008,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+// @WARNING@
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <@NAME@.h>
+#include <gr_io_signature.h>
+
+@SPTR_NAME@
+gr_make_@BASE_NAME@ ()
+{
+ return gnuradio::get_initial_sptr (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 = acc ^ ((@I_TYPE@ *) input_items[j])[i];
+
+ *optr++ = (@O_TYPE@) acc;
+ }
+ return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/gengen/gr_xor_XX.h.t b/gnuradio-core/src/lib/gengen/gr_xor_XX.h.t
new file mode 100644
index 000000000..8fe47d9e0
--- /dev/null
+++ b/gnuradio-core/src/lib/gengen/gr_xor_XX.h.t
@@ -0,0 +1,55 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2008 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+// @WARNING@
+
+#ifndef @GUARD_NAME@
+#define @GUARD_NAME@
+
+#include <gr_core_api.h>
+#include <gr_sync_block.h>
+
+class @NAME@;
+typedef boost::shared_ptr<@NAME@> @SPTR_NAME@;
+
+GR_CORE_API @SPTR_NAME@ gr_make_@BASE_NAME@ ();
+
+/*!
+ * \brief output = input_0 ^ input_1 ^ , ... ^ input_N)
+ * \ingroup math_blk
+ *
+ * bitwise boolean xor across all input streams.
+ */
+class GR_CORE_API @NAME@ : public gr_sync_block
+{
+ friend GR_CORE_API @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/gengen/gr_xor_XX.i.t b/gnuradio-core/src/lib/gengen/gr_xor_XX.i.t
new file mode 100644
index 000000000..06db5ca59
--- /dev/null
+++ b/gnuradio-core/src/lib/gengen/gr_xor_XX.i.t
@@ -0,0 +1,33 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2008 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+// @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/gnuradio-config-info.cc b/gnuradio-core/src/lib/gnuradio-config-info.cc
new file mode 100644
index 000000000..d3e6454fd
--- /dev/null
+++ b/gnuradio-core/src/lib/gnuradio-config-info.cc
@@ -0,0 +1,72 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2009 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <gr_constants.h>
+#include <boost/program_options.hpp>
+#include <iostream>
+
+namespace po = boost::program_options;
+
+int
+main(int argc, char **argv)
+{
+ po::options_description desc("Program options: gnuradio [options]");
+ po::variables_map vm;
+
+ desc.add_options()
+ ("help,h", "print help message")
+ ("prefix", "print gnuradio installation prefix")
+ ("sysconfdir", "print gnuradio system configuration directory")
+ ("prefsdir", "print gnuradio preferences directory")
+ ("builddate", "print gnuradio build date (RFC2822 format)")
+ ("version,v", "print gnuradio version")
+ ;
+
+ po::store(po::parse_command_line(argc, argv, desc), vm);
+ po::notify(vm);
+
+ if (vm.size() == 0 || vm.count("help")) {
+ std::cout << desc << std::endl;
+ return 1;
+ }
+
+ if (vm.count("prefix"))
+ std::cout << gr_prefix() << std::endl;
+
+ if (vm.count("sysconfdir"))
+ std::cout << gr_sysconfdir() << std::endl;
+
+ if (vm.count("prefsdir"))
+ std::cout << gr_prefsdir() << std::endl;
+
+ if (vm.count("builddate"))
+ std::cout << gr_build_date() << std::endl;
+
+ if (vm.count("version"))
+ std::cout << gr_version() << std::endl;
+
+ return 0;
+}
diff --git a/gnuradio-core/src/lib/hier/CMakeLists.txt b/gnuradio-core/src/lib/hier/CMakeLists.txt
new file mode 100644
index 000000000..192dd5939
--- /dev/null
+++ b/gnuradio-core/src/lib/hier/CMakeLists.txt
@@ -0,0 +1,42 @@
+# Copyright 2010-2011 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+
+########################################################################
+# This file included, use CMake directory variables
+########################################################################
+include_directories(${CMAKE_CURRENT_SOURCE_DIR})
+
+list(APPEND gnuradio_core_sources
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_channel_model.cc
+)
+
+install(FILES
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_channel_model.h
+ DESTINATION ${GR_INCLUDE_DIR}/gnuradio
+ COMPONENT "core_devel"
+)
+
+if(ENABLE_PYTHON)
+ install(FILES
+ ${CMAKE_CURRENT_SOURCE_DIR}/hier.i
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_channel_model.i
+ DESTINATION ${GR_INCLUDE_DIR}/gnuradio/swig
+ COMPONENT "core_swig"
+ )
+endif(ENABLE_PYTHON)
diff --git a/gnuradio-core/src/lib/hier/gr_channel_model.cc b/gnuradio-core/src/lib/hier/gr_channel_model.cc
new file mode 100644
index 000000000..7da357809
--- /dev/null
+++ b/gnuradio-core/src/lib/hier/gr_channel_model.cc
@@ -0,0 +1,126 @@
+/*
+ * Copyright 2009 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <gr_channel_model.h>
+#include <gr_io_signature.h>
+#include <gr_sig_source_f.h>
+#include <iostream>
+
+// Shared pointer constructor
+gr_channel_model_sptr
+gr_make_channel_model(double noise_voltage,
+ double frequency_offset,
+ double epsilon,
+ const std::vector<gr_complex> &taps,
+ double noise_seed)
+{
+ return gnuradio::get_initial_sptr(new gr_channel_model(noise_voltage,
+ frequency_offset,
+ epsilon,
+ taps,
+ noise_seed));
+}
+
+// Hierarchical block constructor
+gr_channel_model::gr_channel_model(double noise_voltage,
+ double frequency_offset,
+ double epsilon,
+ const std::vector<gr_complex> &taps,
+ double noise_seed)
+ : gr_hier_block2("gr_channel_model",
+ gr_make_io_signature(1, 1, sizeof(gr_complex)),
+ gr_make_io_signature(1, 1, sizeof(gr_complex)))
+{
+ d_taps = taps;
+ while(d_taps.size() < 2) {
+ d_taps.push_back(0);
+ }
+
+ d_timing_offset = gr_make_fractional_interpolator_cc(0, epsilon);
+
+ d_multipath = gr_make_fir_filter_ccc(1, d_taps);
+
+ d_noise_adder = gr_make_add_cc();
+ d_noise = gr_make_fastnoise_source_c(GR_GAUSSIAN, noise_voltage, noise_seed, 1024*8);
+ d_freq_offset = gr_make_sig_source_c(1, GR_SIN_WAVE, frequency_offset, 1.0, 0.0);
+ d_mixer_offset = gr_make_multiply_cc();
+
+ connect(self(), 0, d_timing_offset, 0);
+ connect(d_timing_offset, 0, d_multipath, 0);
+ connect(d_multipath, 0, d_mixer_offset, 0);
+ connect(d_freq_offset, 0, d_mixer_offset, 1);
+ connect(d_mixer_offset, 0, d_noise_adder, 1);
+ connect(d_noise, 0, d_noise_adder, 0);
+ connect(d_noise_adder, 0, self(), 0);
+}
+
+void
+gr_channel_model::set_noise_voltage(double noise_voltage)
+{
+ d_noise->set_amplitude(noise_voltage);
+}
+
+void
+gr_channel_model::set_frequency_offset(double frequency_offset)
+{
+ d_freq_offset->set_frequency(frequency_offset);
+}
+
+void
+gr_channel_model::set_taps(const std::vector<gr_complex> &taps)
+{
+ d_taps = taps;
+ while(d_taps.size() < 2) {
+ d_taps.push_back(0);
+ }
+ d_multipath->set_taps(d_taps);
+}
+
+void
+gr_channel_model::set_timing_offset(double epsilon)
+{
+ d_timing_offset->set_interp_ratio(epsilon);
+}
+
+
+double
+gr_channel_model::noise_voltage() const
+{
+ return d_noise->amplitude();
+}
+
+double
+gr_channel_model::frequency_offset() const
+{
+ return d_freq_offset->frequency();
+}
+
+std::vector<gr_complex>
+gr_channel_model::taps() const
+{
+ return d_multipath->taps();
+}
+
+double
+gr_channel_model::timing_offset() const
+{
+ return d_timing_offset->interp_ratio();
+}
diff --git a/gnuradio-core/src/lib/hier/gr_channel_model.h b/gnuradio-core/src/lib/hier/gr_channel_model.h
new file mode 100644
index 000000000..5796a6db2
--- /dev/null
+++ b/gnuradio-core/src/lib/hier/gr_channel_model.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright 2009 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <gr_core_api.h>
+#include <gr_top_block.h>
+#include <gr_fractional_interpolator_cc.h>
+#include <gr_sig_source_c.h>
+#include <gr_fir_filter_ccc.h>
+#include <gr_add_cc.h>
+#include <gr_fastnoise_source_c.h>
+#include <gr_multiply_cc.h>
+
+class gr_channel_model;
+typedef boost::shared_ptr<gr_channel_model> gr_channel_model_sptr;
+
+
+GR_CORE_API gr_channel_model_sptr gr_make_channel_model(double noise_voltage=0.0,
+ double frequency_offset=0.0,
+ double epsilon=1.0,
+ const std::vector<gr_complex> &taps=std::vector<gr_complex>(1, 1),
+ double noise_seed=0);
+
+/*!
+ * \brief channel simulator
+ * \ingroup misc_blk
+ */
+class GR_CORE_API gr_channel_model : public gr_hier_block2
+{
+ private:
+ gr_channel_model(double noise_voltage,
+ double frequency_offset,
+ double epsilon,
+ const std::vector<gr_complex> &taps,
+ double noise_seed);
+
+ friend GR_CORE_API gr_channel_model_sptr gr_make_channel_model(double noise_voltage,
+ double frequency_offset,
+ double epsilon,
+ const std::vector<gr_complex> &taps,
+ double noise_seed);
+
+ gr_fractional_interpolator_cc_sptr d_timing_offset;
+ gr_sig_source_c_sptr d_freq_offset;
+ gr_fir_filter_ccc_sptr d_multipath;
+ gr_add_cc_sptr d_noise_adder;
+ gr_fastnoise_source_c_sptr d_noise;
+ gr_multiply_cc_sptr d_mixer_offset;
+
+ std::vector<gr_complex> d_taps;
+
+ public:
+ void set_noise_voltage(double noise_voltage);
+ void set_frequency_offset(double frequency_offset);
+ void set_taps(const std::vector<gr_complex> &taps);
+ void set_timing_offset(double epsilon);
+
+ double noise_voltage() const;
+ double frequency_offset() const;
+ std::vector<gr_complex> taps() const;
+ double timing_offset() const;
+};
diff --git a/gnuradio-core/src/lib/hier/gr_channel_model.i b/gnuradio-core/src/lib/hier/gr_channel_model.i
new file mode 100644
index 000000000..9aa6ebf5b
--- /dev/null
+++ b/gnuradio-core/src/lib/hier/gr_channel_model.i
@@ -0,0 +1,50 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2009 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,channel_model)
+
+gr_channel_model_sptr gr_make_channel_model(double noise_voltage=0.0,
+ double frequency_offset=0.0,
+ double epsilon=1.0,
+ const std::vector<gr_complex> &taps=std::vector<gr_complex>(1, 1),
+ double noise_seed=0);
+
+class gr_channel_model : public gr_hier_block2
+{
+ private:
+ gr_channel_model(double noise_voltage,
+ double frequency_offset,
+ double epsilon,
+ const std::vector<gr_complex> &taps,
+ double noise_seed);
+
+ public:
+ void set_noise_voltage(double noise_voltage);
+ void set_frequency_offset(double frequency_offset);
+ void set_taps(const std::vector<gr_complex> &taps);
+ void set_timing_offset(double epsilon);
+
+ double noise_voltage() const;
+ double frequency_offset() const;
+ std::vector<gr_complex> taps() const;
+ double timing_offset() const;
+};
diff --git a/gnuradio-core/src/lib/hier/hier.i b/gnuradio-core/src/lib/hier/hier.i
new file mode 100644
index 000000000..82044415e
--- /dev/null
+++ b/gnuradio-core/src/lib/hier/hier.i
@@ -0,0 +1,32 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2009 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+%{
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_channel_model.h>
+%}
+
+%include "gr_channel_model.i"
+
diff --git a/gnuradio-core/src/lib/io/CMakeLists.txt b/gnuradio-core/src/lib/io/CMakeLists.txt
new file mode 100644
index 000000000..59ca06b5a
--- /dev/null
+++ b/gnuradio-core/src/lib/io/CMakeLists.txt
@@ -0,0 +1,118 @@
+# Copyright 2010-2011 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+
+########################################################################
+# This file included, use CMake directory variables
+########################################################################
+
+########################################################################
+# Append gnuradio-core library sources
+########################################################################
+list(APPEND gnuradio_core_sources
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_histo_sink_f.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_oscope_guts.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_oscope_sink_f.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_oscope_sink_x.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/i2c.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/i2c_bitbang.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/i2c_bbio.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/i2c_bbio_pp.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/microtune_4702.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/microtune_4937.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/microtune_xxxx.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/ppio_ppdev.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/gri_wavfile.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_pdu.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_stream_pdu_base.cc
+)
+
+########################################################################
+# Install runtime headers
+########################################################################
+install(FILES
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_histo_sink_f.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_oscope_guts.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_oscope_sink_f.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_oscope_sink_x.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_trigger_mode.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/i2c.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/i2c_bitbang.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/i2c_bbio.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/i2c_bbio_pp.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/microtune_4702.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/microtune_4937.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/microtune_eval_board_defs.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/microtune_xxxx.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/ppio_ppdev.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/gri_wavfile.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_pdu.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_stream_pdu_base.h
+ DESTINATION ${GR_INCLUDE_DIR}/gnuradio
+ COMPONENT "core_devel"
+)
+
+########################################################################
+# Install swig headers
+########################################################################
+if(ENABLE_PYTHON)
+install(FILES
+ ${CMAKE_CURRENT_SOURCE_DIR}/io.i
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_histo_sink.i
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_oscope_sink.i
+ DESTINATION ${GR_INCLUDE_DIR}/gnuradio/swig
+ COMPONENT "core_swig"
+)
+endif(ENABLE_PYTHON)
+
+########################################################################
+# Handle triple-threat files that have cc, h, and i
+########################################################################
+set(gr_core_io_triple_threats
+ gr_file_sink
+ gr_file_sink_base
+ gr_file_source
+ gr_file_descriptor_sink
+ gr_file_descriptor_source
+ gr_message_debug
+ gr_message_sink
+ gr_message_source
+ gr_message_burst_source
+ gr_pdu_to_tagged_stream
+ microtune_xxxx_eval_board
+ microtune_4702_eval_board
+ microtune_4937_eval_board
+ ppio
+ sdr_1000
+ gr_udp_sink
+ gr_udp_source
+ gr_wavfile_source
+ gr_wavfile_sink
+ gr_tagged_file_sink
+ gr_tagged_stream_to_pdu
+ gr_tuntap_pdu
+ gr_socket_pdu
+)
+
+foreach(file_tt ${gr_core_io_triple_threats})
+ list(APPEND gnuradio_core_sources ${CMAKE_CURRENT_SOURCE_DIR}/${file_tt}.cc)
+ install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/${file_tt}.h DESTINATION ${GR_INCLUDE_DIR}/gnuradio COMPONENT "core_devel")
+ if(ENABLE_PYTHON)
+ install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/${file_tt}.i DESTINATION ${GR_INCLUDE_DIR}/gnuradio/swig COMPONENT "core_swig")
+ endif(ENABLE_PYTHON)
+endforeach(file_tt ${gr_core_io_triple_threats})
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
index 000000000..099d46dbd
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_file_descriptor_sink.cc
@@ -0,0 +1,87 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#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>
+#include <stdio.h>
+
+#ifdef HAVE_IO_H
+#include <io.h>
+#endif
+
+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 gnuradio::get_initial_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
index 000000000..3b1c1167f
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_file_descriptor_sink.h
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_FILE_DESCRIPTOR_SINK_H
+#define INCLUDED_GR_FILE_DESCRIPTOR_SINK_H
+
+#include <gr_core_api.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_CORE_API gr_file_descriptor_sink_sptr gr_make_file_descriptor_sink (size_t itemsize, int fd);
+
+/*!
+ * \brief Write stream to file descriptor.
+ * \ingroup sink_blk
+ */
+
+class GR_CORE_API gr_file_descriptor_sink : public gr_sync_block
+{
+ friend GR_CORE_API 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
index 000000000..2c256e44d
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_file_descriptor_sink.i
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,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
index 000000000..a63abf96b
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_file_descriptor_source.cc
@@ -0,0 +1,151 @@
+/* -*- 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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_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>
+#include <stdio.h>
+#include <string.h>
+
+#ifdef HAVE_IO_H
+#include <io.h>
+#endif
+
+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
index 000000000..ebabd81ed
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_file_descriptor_source.h
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_FILE_DESCRIPTOR_SOURCE_H
+#define INCLUDED_GR_FILE_DESCRIPTOR_SOURCE_H
+
+#include <gr_core_api.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_CORE_API 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_blk
+ */
+
+class GR_CORE_API gr_file_descriptor_source : public gr_sync_block
+{
+ friend GR_CORE_API 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
index 000000000..3ca082522
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_file_descriptor_source.i
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,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
index 000000000..10c8360cb
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_file_sink.cc
@@ -0,0 +1,84 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2006,2007,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_file_sink.h>
+#include <gr_io_signature.h>
+#include <stdexcept>
+
+
+gr_file_sink_sptr
+gr_make_file_sink (size_t itemsize, const char *filename)
+{
+ return gnuradio::get_initial_sptr(new gr_file_sink (itemsize, filename));
+}
+
+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)),
+ gr_file_sink_base(filename, true),
+ d_itemsize(itemsize)
+{
+}
+
+gr_file_sink::~gr_file_sink ()
+{
+}
+
+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;
+
+ do_update(); // update d_fp is reqd
+
+ if(!d_fp)
+ return noutput_items; // drop output on the floor
+
+ while(nwritten < noutput_items) {
+ int count = fwrite(inbuf, d_itemsize, noutput_items - nwritten, d_fp);
+ if(count == 0) {
+ if(ferror(d_fp)) {
+ std::stringstream s;
+ s << "file_sink write failed with error " << fileno(d_fp) << std::endl;
+ throw std::runtime_error(s.str());
+ }
+ else { // is EOF
+ break;
+ }
+ }
+ nwritten += count;
+ inbuf += count * d_itemsize;
+ }
+
+ if(d_unbuffered)
+ fflush (d_fp);
+
+ 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
index 000000000..e40ec9ab8
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_file_sink.h
@@ -0,0 +1,58 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2007 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_FILE_SINK_H
+#define INCLUDED_GR_FILE_SINK_H
+
+#include <gr_core_api.h>
+#include <gr_sync_block.h>
+#include <gr_file_sink_base.h>
+
+class gr_file_sink;
+typedef boost::shared_ptr<gr_file_sink> gr_file_sink_sptr;
+
+GR_CORE_API gr_file_sink_sptr gr_make_file_sink(size_t itemsize, const char *filename);
+
+/*!
+ * \brief Write stream to file.
+ * \ingroup sink_blk
+ */
+
+class GR_CORE_API gr_file_sink : public gr_sync_block, public gr_file_sink_base
+{
+ friend GR_CORE_API gr_file_sink_sptr gr_make_file_sink(size_t itemsize, const char *filename);
+
+ private:
+ size_t d_itemsize;
+
+ protected:
+ gr_file_sink(size_t itemsize, const char *filename);
+
+ public:
+ ~gr_file_sink();
+
+ 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
index 000000000..47ab9e964
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_file_sink.i
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,file_sink)
+
+gr_file_sink_sptr
+gr_make_file_sink (size_t itemsize, const char *filename);
+
+class gr_file_sink : public gr_sync_block, public gr_file_sink_base
+{
+ 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_sink_base.cc b/gnuradio-core/src/lib/io/gr_file_sink_base.cc
new file mode 100644
index 000000000..d0aca418e
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_file_sink_base.cc
@@ -0,0 +1,125 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2006,2007,2009 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_file_sink_base.h>
+#include <cstdio>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdexcept>
+#include <stdio.h>
+#include <gruel/thread.h>
+
+// 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_base::gr_file_sink_base(const char *filename, bool is_binary)
+ : d_fp(0), d_new_fp(0), d_updated(false), d_is_binary(is_binary)
+{
+ if (!open(filename))
+ throw std::runtime_error ("can't open file");
+}
+
+gr_file_sink_base::~gr_file_sink_base ()
+{
+ close();
+ if (d_fp){
+ fclose(d_fp);
+ d_fp = 0;
+ }
+}
+
+bool
+gr_file_sink_base::open(const char *filename)
+{
+ gruel::scoped_lock guard(d_mutex); // hold mutex for duration of this function
+
+ // we use the open system call to get access to the O_LARGEFILE flag.
+ int fd;
+ 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(d_new_fp);
+ d_new_fp = 0;
+ }
+
+ if ((d_new_fp = fdopen (fd, d_is_binary ? "wb" : "w")) == 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_base::close()
+{
+ gruel::scoped_lock guard(d_mutex); // hold mutex for duration of this function
+
+ if (d_new_fp){
+ fclose(d_new_fp);
+ d_new_fp = 0;
+ }
+ d_updated = true;
+}
+
+void
+gr_file_sink_base::do_update()
+{
+ if (d_updated){
+ gruel::scoped_lock guard(d_mutex); // hold mutex for duration of this block
+ if (d_fp)
+ fclose(d_fp);
+ d_fp = d_new_fp; // install new file pointer
+ d_new_fp = 0;
+ d_updated = false;
+ }
+}
+
+void
+gr_file_sink_base::set_unbuffered(bool unbuffered)
+{
+ d_unbuffered = unbuffered;
+}
diff --git a/gnuradio-core/src/lib/io/gr_file_sink_base.h b/gnuradio-core/src/lib/io/gr_file_sink_base.h
new file mode 100644
index 000000000..8a70cee76
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_file_sink_base.h
@@ -0,0 +1,75 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2007,2008 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_FILE_SINK_BASE_H
+#define INCLUDED_GR_FILE_SINK_BASE_H
+
+#include <gr_core_api.h>
+#include <boost/thread.hpp>
+#include <cstdio>
+
+/*!
+ * \brief Common base class for file sinks
+ */
+class GR_CORE_API gr_file_sink_base
+{
+ protected:
+ FILE *d_fp; // current FILE pointer
+ FILE *d_new_fp; // new FILE pointer
+ bool d_updated; // is there a new FILE pointer?
+ bool d_is_binary;
+ boost::mutex d_mutex;
+ bool d_unbuffered;
+
+ protected:
+ gr_file_sink_base(const char *filename, bool is_binary);
+
+ public:
+ ~gr_file_sink_base();
+
+ /*!
+ * \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();
+
+ /*!
+ * \brief if we've had an update, do it now.
+ */
+ void do_update();
+
+
+ /*!
+ * \brief turn on unbuffered writes for slower outputs
+ */
+ void set_unbuffered(bool unbuffered);
+};
+
+
+#endif /* INCLUDED_GR_FILE_SINK_BASE_H */
diff --git a/gnuradio-core/src/lib/io/gr_file_sink_base.i b/gnuradio-core/src/lib/io/gr_file_sink_base.i
new file mode 100644
index 000000000..993dba277
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_file_sink_base.i
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You 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.
+ */
+class gr_file_sink_base
+{
+ protected:
+ gr_file_sink_base(const char *filename, bool is_binary);
+
+ public:
+ ~gr_file_sink_base();
+
+ /*!
+ * \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();
+
+ /*!
+ * \brief if we've had an update, do it now.
+ */
+ void do_update();
+
+ /*!
+ *\brief turn on unbuffered mode for slow outputs
+ */
+ void set_unbuffered(bool unbuffered);
+};
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
index 000000000..6da7abac2
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_file_source.cc
@@ -0,0 +1,192 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gruel/thread.h>
+#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>
+#include <stdio.h>
+
+// 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_new_fp (0), d_repeat(repeat),
+ d_updated(false)
+{
+ open(filename, repeat);
+}
+
+// public constructor that returns a shared_ptr
+
+gr_file_source_sptr
+gr_make_file_source (size_t itemsize, const char *filename, bool repeat)
+{
+ return gnuradio::get_initial_sptr(new gr_file_source (itemsize, filename, repeat));
+}
+
+gr_file_source::~gr_file_source ()
+{
+ close();
+ if(d_fp) {
+ fclose(d_fp);
+ d_fp = 0;
+ }
+}
+
+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;
+
+ do_update(); // update d_fp is reqd
+ if(d_fp == NULL)
+ throw std::runtime_error("work with file not open");
+
+ gruel::scoped_lock lock(fp_mutex); // hold for the rest of this function
+ 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) {
+ std::stringstream s;
+ s << "[" << __FILE__ << "]" << " fseek failed" << std::endl;
+ throw std::runtime_error(s.str());
+ }
+ }
+
+ 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)
+{
+ // obtain exclusive access for duration of this function
+ gruel::scoped_lock lock(fp_mutex);
+ return fseek((FILE *) d_fp, seek_point * d_itemsize, whence) == 0;
+}
+
+void
+gr_file_source::open(const char *filename, bool repeat)
+{
+ // obtain exclusive access for duration of this function
+ gruel::scoped_lock lock(fp_mutex);
+
+ int fd;
+
+ // we use "open" to use to the O_LARGEFILE flag
+ 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_new_fp) {
+ fclose(d_new_fp);
+ d_new_fp = 0;
+ }
+
+ if((d_new_fp = fdopen (fd, "rb")) == NULL) {
+ perror(filename);
+ ::close(fd); // don't leak file descriptor if fdopen fails
+ throw std::runtime_error("can't open file");
+ }
+
+ d_updated = true;
+ d_repeat = repeat;
+}
+
+void
+gr_file_source::close()
+{
+ // obtain exclusive access for duration of this function
+ gruel::scoped_lock lock(fp_mutex);
+
+ if(d_new_fp != NULL) {
+ fclose(d_new_fp);
+ d_new_fp = NULL;
+ }
+ d_updated = true;
+}
+
+void
+gr_file_source::do_update()
+{
+ if(d_updated) {
+ gruel::scoped_lock lock(fp_mutex); // hold while in scope
+
+ if(d_fp)
+ fclose(d_fp);
+
+ d_fp = d_new_fp; // install new file pointer
+ d_new_fp = 0;
+ d_updated = false;
+ }
+}
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
index 000000000..0478fba04
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_file_source.h
@@ -0,0 +1,107 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_FILE_SOURCE_H
+#define INCLUDED_GR_FILE_SOURCE_H
+
+#include <gr_core_api.h>
+#include <gr_sync_block.h>
+#include <boost/thread/mutex.hpp>
+
+class gr_file_source;
+typedef boost::shared_ptr<gr_file_source> gr_file_source_sptr;
+
+GR_CORE_API gr_file_source_sptr
+gr_make_file_source (size_t itemsize, const char *filename, bool repeat = false);
+
+/*!
+ * \brief Read stream from file
+ * \ingroup source_blk
+ */
+
+class GR_CORE_API gr_file_source : public gr_sync_block
+{
+ private:
+ size_t d_itemsize;
+ FILE *d_fp;
+ FILE *d_new_fp;
+ bool d_repeat;
+ bool d_updated;
+
+ protected:
+ gr_file_source(size_t itemsize, const char *filename, bool repeat);
+
+ void do_update();
+
+ boost::mutex fp_mutex;
+
+ public:
+ /*!
+ * \brief Create a file source.
+ *
+ * Opens \p filename as a source of items into a flowgraph. The data
+ * is expected to be in binary format, item after item. The \p
+ * itemsize of the block determines the conversion from bits to
+ * items.
+ *
+ * If \p repeat is turned on, the file will repeat the file after
+ * it's reached the end.
+ *
+ * \param itemsize the size of each item in the file, in bytes
+ * \param filename name of the file to source from
+ * \param repeat repeat file from start
+ */
+ friend GR_CORE_API gr_file_source_sptr
+ gr_make_file_source(size_t itemsize,
+ const char *filename,
+ bool repeat);
+
+ ~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);
+
+ /*!
+ * \brief Opens a new file.
+ *
+ * \param filename name of the file to source from
+ * \param repeat repeat file from start
+ */
+ void open(const char *filename, bool repeat);
+
+ /*!
+ * \brief Close the file handle.
+ */
+ void close();
+
+};
+
+#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
index 000000000..e71cef0d1
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_file_source.i
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, 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);
+ void open (const char *filename, bool repeat);
+ void close();
+};
diff --git a/gnuradio-core/src/lib/io/gr_histo_sink.i b/gnuradio-core/src/lib/io/gr_histo_sink.i
new file mode 100644
index 000000000..14079e190
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_histo_sink.i
@@ -0,0 +1,39 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2009 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+
+GR_SWIG_BLOCK_MAGIC(gr,histo_sink_f)
+
+gr_histo_sink_f_sptr gr_make_histo_sink_f (gr_msg_queue_sptr msgq);
+
+class gr_histo_sink_f : public gr_sync_block
+{
+public:
+ ~gr_histo_sink_f (void);
+
+ unsigned int get_frame_size(void);
+ unsigned int get_num_bins(void);
+
+ void set_frame_size(unsigned int frame_size);
+ void set_num_bins(unsigned int num_bins);
+
+};
diff --git a/gnuradio-core/src/lib/io/gr_histo_sink_f.cc b/gnuradio-core/src/lib/io/gr_histo_sink_f.cc
new file mode 100644
index 000000000..fc0c12ce6
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_histo_sink_f.cc
@@ -0,0 +1,165 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2009,2010,2011 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_histo_sink_f.h>
+#include <gr_io_signature.h>
+#include <boost/math/special_functions/round.hpp>
+
+static float get_clean_num(float num){
+ if (num == 0) return 0;
+ /* extract sign and exponent from num */
+ int sign = (num < 0) ? -1 : 1; num = fabs(num);
+ float exponent = floor(log10(num));
+ /* search for closest number with base 1, 2, 5, 10 */
+ float closest_num = 10*pow(10, exponent);
+ if (fabs(num - 1*pow(10, exponent)) < fabs(num - closest_num))
+ closest_num = 1*pow(10, exponent);
+ if (fabs(num - 2*pow(10, exponent)) < fabs(num - closest_num))
+ closest_num = 2*pow(10, exponent);
+ if (fabs(num - 5*pow(10, exponent)) < fabs(num - closest_num))
+ closest_num = 5*pow(10, exponent);
+ return sign*closest_num;
+}
+
+gr_histo_sink_f_sptr
+gr_make_histo_sink_f (gr_msg_queue_sptr msgq)
+{
+ return gnuradio::get_initial_sptr(new gr_histo_sink_f (msgq));
+}
+
+gr_histo_sink_f::gr_histo_sink_f (gr_msg_queue_sptr msgq)
+ : gr_sync_block ("histo_sink_f", gr_make_io_signature (1, 1, sizeof (float)), gr_make_io_signature (0, 0, 0)),
+ d_msgq (msgq), d_num_bins(11), d_frame_size(1000), d_sample_count(0), d_bins(NULL), d_samps(NULL)
+{
+ //allocate arrays and clear
+ set_num_bins(d_num_bins);
+ set_frame_size(d_frame_size);
+}
+
+gr_histo_sink_f::~gr_histo_sink_f (void)
+{
+ delete [] d_samps;
+ delete [] d_bins;
+}
+
+int
+gr_histo_sink_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];
+ gruel::scoped_lock guard(d_mutex); // hold mutex for duration of this function
+ for (unsigned int i = 0; i < (unsigned int)noutput_items; i++){
+ d_samps[d_sample_count] = in[i];
+ d_sample_count++;
+ /* processed a frame? */
+ if (d_sample_count == d_frame_size){
+ send_frame();
+ clear();
+ }
+ }
+ return noutput_items;
+}
+
+void
+gr_histo_sink_f::send_frame(void){
+ /* output queue full, drop the data */
+ if (d_msgq->full_p()) return;
+ /* find the minimum and maximum */
+ float minimum = d_samps[0];
+ float maximum = d_samps[0];
+ for (unsigned int i = 0; i < d_frame_size; i++){
+ if (d_samps[i] < minimum) minimum = d_samps[i];
+ if (d_samps[i] > maximum) maximum = d_samps[i];
+ }
+ minimum = get_clean_num(minimum);
+ maximum = get_clean_num(maximum);
+ if (minimum == maximum || minimum > maximum) return; //useless data or screw up?
+ /* load the bins */
+ int index;
+ float bin_width = (maximum - minimum)/(d_num_bins-1);
+ for (unsigned int i = 0; i < d_sample_count; i++){
+ index = boost::math::iround((d_samps[i] - minimum)/bin_width);
+ /* ensure the index range in case a small floating point error is involed */
+ if (index < 0) index = 0;
+ if (index >= (int)d_num_bins) index = d_num_bins-1;
+ d_bins[index]++;
+ }
+ /* Build a message to hold the output records */
+ gr_message_sptr msg = gr_make_message(0, minimum, maximum, d_num_bins*sizeof(float));
+ float *out = (float *)msg->msg(); // get pointer to raw message buffer
+ /* normalize the bins and put into message */
+ for (unsigned int i = 0; i < d_num_bins; i++){
+ out[i] = ((float)d_bins[i])/d_frame_size;
+ }
+ /* send the message */
+ d_msgq->handle(msg);
+}
+
+void
+gr_histo_sink_f::clear(void){
+ d_sample_count = 0;
+ /* zero the bins */
+ for (unsigned int i = 0; i < d_num_bins; i++){
+ d_bins[i] = 0;
+ }
+}
+
+/**************************************************
+ * Getters
+ **************************************************/
+unsigned int
+gr_histo_sink_f::get_frame_size(void){
+ return d_frame_size;
+}
+
+unsigned int
+gr_histo_sink_f::get_num_bins(void){
+ return d_num_bins;
+}
+
+/**************************************************
+ * Setters
+ **************************************************/
+void
+gr_histo_sink_f::set_frame_size(unsigned int frame_size){
+ gruel::scoped_lock guard(d_mutex); // hold mutex for duration of this function
+ d_frame_size = frame_size;
+ /* allocate a new sample array */
+ delete [] d_samps;
+ d_samps = new float[d_frame_size];
+ clear();
+}
+
+void
+gr_histo_sink_f::set_num_bins(unsigned int num_bins){
+ gruel::scoped_lock guard(d_mutex); // hold mutex for duration of this function
+ d_num_bins = num_bins;
+ /* allocate a new bin array */
+ delete [] d_bins;
+ d_bins = new unsigned int[d_num_bins];
+ clear();
+}
diff --git a/gnuradio-core/src/lib/io/gr_histo_sink_f.h b/gnuradio-core/src/lib/io/gr_histo_sink_f.h
new file mode 100644
index 000000000..934066ba2
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_histo_sink_f.h
@@ -0,0 +1,71 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2009 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_HISTO_SINK_F_H
+#define INCLUDED_GR_HISTO_SINK_F_H
+
+#include <gr_core_api.h>
+#include <gr_sync_block.h>
+#include <gr_msg_queue.h>
+#include <gruel/thread.h>
+
+class gr_histo_sink_f;
+typedef boost::shared_ptr<gr_histo_sink_f> gr_histo_sink_f_sptr;
+
+GR_CORE_API gr_histo_sink_f_sptr gr_make_histo_sink_f (gr_msg_queue_sptr msgq);
+
+/*!
+ * \brief Histogram module.
+ * \ingroup sink_blk
+ */
+class GR_CORE_API gr_histo_sink_f : public gr_sync_block
+{
+private:
+ gr_msg_queue_sptr d_msgq;
+ unsigned int d_num_bins;
+ unsigned int d_frame_size;
+ unsigned int d_sample_count;
+ unsigned int *d_bins;
+ float *d_samps;
+ gruel::mutex d_mutex;
+
+ friend GR_CORE_API gr_histo_sink_f_sptr gr_make_histo_sink_f (gr_msg_queue_sptr msgq);
+ gr_histo_sink_f (gr_msg_queue_sptr msgq);
+ void send_frame(void);
+ void clear(void);
+
+public:
+ ~gr_histo_sink_f (void);
+
+ int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+
+ unsigned int get_frame_size(void);
+ unsigned int get_num_bins(void);
+
+ void set_frame_size(unsigned int frame_size);
+ void set_num_bins(unsigned int num_bins);
+
+};
+
+#endif /* INCLUDED_GR_HISTO_SINK_F_H */
diff --git a/gnuradio-core/src/lib/io/gr_message_burst_source.cc b/gnuradio-core/src/lib/io/gr_message_burst_source.cc
new file mode 100644
index 000000000..e9e2dfd4d
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_message_burst_source.cc
@@ -0,0 +1,144 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_message_burst_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>
+#include <string.h>
+#include <gr_tags.h>
+
+// public constructor that returns a shared_ptr
+
+gr_message_burst_source_sptr
+gr_make_message_burst_source(size_t itemsize, int msgq_limit)
+{
+ return gnuradio::get_initial_sptr(new gr_message_burst_source(itemsize, msgq_limit));
+}
+
+// public constructor that takes existing message queue
+gr_message_burst_source_sptr
+gr_make_message_burst_source(size_t itemsize, gr_msg_queue_sptr msgq)
+{
+ return gnuradio::get_initial_sptr(new gr_message_burst_source(itemsize, msgq));
+}
+
+gr_message_burst_source::gr_message_burst_source (size_t itemsize, int msgq_limit)
+ : gr_sync_block("message_burst_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)
+{
+ std::stringstream id;
+ id << name() << unique_id();
+ d_me = pmt::pmt_string_to_symbol(id.str());
+}
+
+gr_message_burst_source::gr_message_burst_source (size_t itemsize, gr_msg_queue_sptr msgq)
+ : gr_sync_block("message_burst_source",
+ gr_make_io_signature(0, 0, 0),
+ gr_make_io_signature(1, 1, itemsize)),
+ d_itemsize(itemsize), d_msgq(msgq), d_msg_offset(0), d_eof(false)
+{
+ std::stringstream id;
+ id << name() << unique_id();
+ d_me = pmt::pmt_string_to_symbol(id.str());
+}
+
+gr_message_burst_source::~gr_message_burst_source()
+{
+}
+
+int
+gr_message_burst_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;
+
+ uint64_t abs_sample_count = nitems_written(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();
+ //tag end of burst
+ add_item_tag(0, //stream ID
+ abs_sample_count+nn-1, //sample number
+ pmt::pmt_string_to_symbol("tx_eob"),
+ pmt::pmt_from_bool(1),
+ d_me //block src id
+ );
+ }
+ }
+ 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;
+ //tag start of burst
+ add_item_tag(0, //stream ID
+ abs_sample_count+nn, //sample number
+ pmt::pmt_string_to_symbol("tx_sob"),
+ pmt::pmt_from_bool(1),
+ d_me //block src id
+ );
+
+
+ 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_burst_source.h b/gnuradio-core/src/lib/io/gr_message_burst_source.h
new file mode 100644
index 000000000..63e220113
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_message_burst_source.h
@@ -0,0 +1,71 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_MESSAGE_BURST_SOURCE_H
+#define INCLUDED_GR_MESSAGE_BURST_SOURCE_H
+
+#include <gr_core_api.h>
+#include <gr_sync_block.h>
+#include <gr_message.h>
+#include <gr_msg_queue.h>
+
+class gr_message_burst_source;
+typedef boost::shared_ptr<gr_message_burst_source> gr_message_burst_source_sptr;
+
+GR_CORE_API gr_message_burst_source_sptr gr_make_message_burst_source (size_t itemsize, int msgq_limit=0);
+GR_CORE_API gr_message_burst_source_sptr gr_make_message_burst_source (size_t itemsize, gr_msg_queue_sptr msgq);
+
+/*!
+ * \brief Turn received messages into a stream and tag them for UHD to send.
+ * \ingroup source_blk
+ */
+class GR_CORE_API gr_message_burst_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;
+
+ pmt::pmt_t d_me;
+
+ friend GR_CORE_API gr_message_burst_source_sptr
+ gr_make_message_burst_source(size_t itemsize, int msgq_limit);
+ friend GR_CORE_API gr_message_burst_source_sptr
+ gr_make_message_burst_source(size_t itemsize, gr_msg_queue_sptr msgq);
+
+ protected:
+ gr_message_burst_source (size_t itemsize, int msgq_limit);
+ gr_message_burst_source (size_t itemsize, gr_msg_queue_sptr msgq);
+
+ public:
+ ~gr_message_burst_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_burst_source_H */
diff --git a/gnuradio-core/src/lib/io/gr_message_burst_source.i b/gnuradio-core/src/lib/io/gr_message_burst_source.i
new file mode 100644
index 000000000..f7ad840c2
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_message_burst_source.i
@@ -0,0 +1,38 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,message_burst_source);
+
+gr_message_burst_source_sptr gr_make_message_burst_source (size_t itemsize, int msgq_limit=0);
+gr_message_burst_source_sptr gr_make_message_burst_source (size_t itemsize, gr_msg_queue_sptr msgq);
+
+class gr_message_burst_source : public gr_sync_block
+{
+ protected:
+ gr_message_burst_source (size_t itemsize, int msgq_limit);
+ gr_message_burst_source (size_t itemsize, gr_msg_queue_sptr msgq);
+
+ public:
+ ~gr_message_burst_source ();
+
+ gr_msg_queue_sptr msgq() const;
+};
diff --git a/gnuradio-core/src/lib/io/gr_message_debug.cc b/gnuradio-core/src/lib/io/gr_message_debug.cc
new file mode 100644
index 000000000..9eb1bb639
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_message_debug.cc
@@ -0,0 +1,120 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005,2010,2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_message_debug.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 <string.h>
+#include <iostream>
+
+// public constructor that returns a shared_ptr
+
+gr_message_debug_sptr
+gr_make_message_debug ()
+{
+ return gnuradio::get_initial_sptr(new gr_message_debug());
+}
+
+void
+gr_message_debug::print(pmt::pmt_t msg)
+{
+ std::cout << "******* MESSAGE DEBUG PRINT ********\n";
+ pmt::pmt_print(msg);
+ std::cout << "************************************\n";
+}
+
+void
+gr_message_debug::store(pmt::pmt_t msg)
+{
+ gruel::scoped_lock guard(d_mutex);
+ d_messages.push_back(msg);
+}
+
+void
+gr_message_debug::print_pdu(pmt::pmt_t pdu)
+{
+ pmt::pmt_t meta = pmt::pmt_car(pdu);
+ pmt::pmt_t vector = pmt::pmt_cdr(pdu);
+ std::cout << "* MESSAGE DEBUG PRINT PDU VERBOSE *\n";
+ pmt::pmt_print(meta);
+ size_t len = pmt::pmt_length(vector);
+ std::cout << "pdu_length = " << len << std::endl;
+ std::cout << "contents = " << std::endl;
+ size_t offset(0);
+ const uint8_t* d = (const uint8_t*) pmt_uniform_vector_elements(vector, offset);
+ for(size_t i=0; i<len; i+=16){
+ printf("%04x: ", ((unsigned int)i));
+ for(size_t j=i; j<std::min(i+16,len); j++){
+ printf("%02x ",d[j] );
+ }
+
+ std::cout << std::endl;
+ }
+
+ std::cout << "***********************************\n";
+}
+
+int
+gr_message_debug::num_messages()
+{
+ return (int)d_messages.size();
+}
+
+pmt::pmt_t
+gr_message_debug::get_message(int i)
+{
+ gruel::scoped_lock guard(d_mutex);
+
+ if((size_t)i >= d_messages.size()) {
+ throw std::runtime_error("gr_message_debug: index for message out of bounds.\n");
+ }
+
+ return d_messages[i];
+}
+
+gr_message_debug::gr_message_debug()
+ : gr_block("message_debug",
+ gr_make_io_signature(0, 0, 0),
+ gr_make_io_signature(0, 0, 0))
+{
+ message_port_register_in(pmt::mp("print"));
+ set_msg_handler(pmt::mp("print"), boost::bind(&gr_message_debug::print, this, _1));
+
+ message_port_register_in(pmt::mp("store"));
+ set_msg_handler(pmt::mp("store"), boost::bind(&gr_message_debug::store, this, _1));
+
+ message_port_register_in(pmt::mp("print_pdu"));
+ set_msg_handler(pmt::mp("print_pdu"), boost::bind(&gr_message_debug::print_pdu, this, _1));
+}
+
+gr_message_debug::~gr_message_debug()
+{
+}
diff --git a/gnuradio-core/src/lib/io/gr_message_debug.h b/gnuradio-core/src/lib/io/gr_message_debug.h
new file mode 100644
index 000000000..f1374e806
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_message_debug.h
@@ -0,0 +1,114 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005,2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_MESSAGE_DEBUG_H
+#define INCLUDED_GR_MESSAGE_DEBUG_H
+
+#include <gr_core_api.h>
+#include <gr_block.h>
+#include <gr_message.h>
+#include <gr_msg_queue.h>
+#include <gruel/thread.h>
+
+class gr_message_debug;
+typedef boost::shared_ptr<gr_message_debug> gr_message_debug_sptr;
+
+GR_CORE_API gr_message_debug_sptr gr_make_message_debug();
+
+/*!
+ * \brief Print received messages to stdout
+ * \ingroup sink_blk
+ */
+class GR_CORE_API gr_message_debug : public gr_block
+{
+ private:
+ friend GR_CORE_API gr_message_debug_sptr
+ gr_make_message_debug();
+
+ /*!
+ * \brief Messages received in this port are printed to stdout.
+ *
+ * This port receives messages from the scheduler's message handling
+ * mechanism and prints it to stdout. This message handler function
+ * is only meant to be used by the scheduler to handle messages
+ * posted to port 'print'.
+ *
+ * \param msg A pmt message passed from the scheduler's message handling.
+ */
+ void print(pmt::pmt_t msg);
+
+ /*!
+ * \brief PDU formatted messages received in this port are printed to stdout.
+ *
+ * This port receives messages from the scheduler's message handling
+ * mechanism and prints it to stdout. This message handler function
+ * is only meant to be used by the scheduler to handle messages
+ * posted to port 'print'.
+ *
+ * \param pdu A PDU message passed from the scheduler's message handling.
+ */
+ void print_pdu(pmt::pmt_t pdu);
+
+ /*!
+ * \brief Messages received in this port are stored in a vector.
+ *
+ * This port receives messages from the scheduler's message handling
+ * mechanism and stores it in a vector. Messages can be retrieved
+ * later using the 'get_message' function. This message handler
+ * function is only meant to be used by the scheduler to handle
+ * messages posted to port 'store'.
+ *
+ * \param msg A pmt message passed from the scheduler's message handling.
+ */
+ void store(pmt::pmt_t msg);
+
+ gruel::mutex d_mutex;
+ std::vector<pmt::pmt_t> d_messages;
+
+ protected:
+ gr_message_debug ();
+
+ public:
+ ~gr_message_debug ();
+
+ /*!
+ * \brief Reports the number of messages received by this block.
+ */
+ int num_messages();
+
+ /*!
+ * \brief Get a message (as a PMT) from the message vector at index \p i.
+ *
+ * Messages passed to the 'store' port will be stored in a
+ * vector. This function retrieves those messages by index. They are
+ * index in order of when they were received (all messages are just
+ * pushed onto the back of a vector). This is mostly useful in
+ * debugging message passing graphs and in QA code.
+ *
+ * \param i The index in the vector for the message to retrieve.
+ *
+ * \return a message at index \p i as a pmt_t.
+ */
+ pmt::pmt_t get_message(int i);
+};
+
+#endif /* INCLUDED_GR_MESSAGE_DEBUG_H */
diff --git a/gnuradio-core/src/lib/io/gr_message_debug.i b/gnuradio-core/src/lib/io/gr_message_debug.i
new file mode 100644
index 000000000..65d3bfc4a
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_message_debug.i
@@ -0,0 +1,30 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,message_debug);
+
+%{
+#include <gr_message_debug.h>
+%}
+
+%include "gr_message_debug.h"
+
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
index 000000000..ae0b5c764
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_message_sink.cc
@@ -0,0 +1,79 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_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>
+#include <string.h>
+
+
+// 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 gnuradio::get_initial_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
index 000000000..84005694a
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_message_sink.h
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_MESSAGE_SINK_H
+#define INCLUDED_GR_MESSAGE_SINK_H
+
+#include <gr_core_api.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_CORE_API 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_blk
+ */
+class GR_CORE_API gr_message_sink : public gr_sync_block
+{
+ private:
+ size_t d_itemsize;
+ gr_msg_queue_sptr d_msgq;
+ bool d_dont_block;
+
+ friend GR_CORE_API 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
index 000000000..8415cbd66
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_message_sink.i
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,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
index 000000000..fb3da89a8
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_message_source.cc
@@ -0,0 +1,120 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_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>
+#include <string.h>
+
+
+// public constructor that returns a shared_ptr
+
+gr_message_source_sptr
+gr_make_message_source(size_t itemsize, int msgq_limit)
+{
+ return gnuradio::get_initial_sptr(new gr_message_source(itemsize, msgq_limit));
+}
+
+// public constructor that takes existing message queue
+gr_message_source_sptr
+gr_make_message_source(size_t itemsize, gr_msg_queue_sptr msgq)
+{
+ return gnuradio::get_initial_sptr(new gr_message_source(itemsize, msgq));
+}
+
+gr_message_source::gr_message_source (size_t itemsize, int msgq_limit)
+ : gr_sync_block("message_source",
+ gr_make_io_signature(0, 0, 0),
+ 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 (size_t itemsize, gr_msg_queue_sptr msgq)
+ : gr_sync_block("message_source",
+ gr_make_io_signature(0, 0, 0),
+ gr_make_io_signature(1, 1, itemsize)),
+ d_itemsize(itemsize), d_msgq(msgq), d_msg_offset(0), d_eof(false)
+{
+}
+
+gr_message_source::~gr_message_source()
+{
+}
+
+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
index 000000000..c510d1775
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_message_source.h
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_MESSAGE_SOURCE_H
+#define INCLUDED_GR_MESSAGE_SOURCE_H
+
+#include <gr_core_api.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_CORE_API gr_message_source_sptr gr_make_message_source (size_t itemsize, int msgq_limit=0);
+GR_CORE_API gr_message_source_sptr gr_make_message_source (size_t itemsize, gr_msg_queue_sptr msgq);
+
+/*!
+ * \brief Turn received messages into a stream
+ * \ingroup source_blk
+ */
+class GR_CORE_API 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_CORE_API gr_message_source_sptr
+ gr_make_message_source(size_t itemsize, int msgq_limit);
+ friend GR_CORE_API gr_message_source_sptr
+ gr_make_message_source(size_t itemsize, gr_msg_queue_sptr msgq);
+
+ protected:
+ gr_message_source (size_t itemsize, int msgq_limit);
+ gr_message_source (size_t itemsize, gr_msg_queue_sptr msgq);
+
+ public:
+ ~gr_message_source ();
+
+ 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
index 000000000..9ee9157e8
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_message_source.i
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,message_source);
+
+gr_message_source_sptr gr_make_message_source (size_t itemsize, int msgq_limit=0);
+gr_message_source_sptr gr_make_message_source (size_t itemsize, gr_msg_queue_sptr msgq);
+
+class gr_message_source : public gr_sync_block
+{
+ protected:
+ gr_message_source (size_t itemsize, int msgq_limit);
+ gr_message_source (size_t itemsize, gr_msg_queue_sptr msgq);
+
+ public:
+ ~gr_message_source ();
+
+ 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
index 000000000..a5ea3002a
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_oscope_guts.cc
@@ -0,0 +1,437 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003,2005 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <gr_oscope_guts.h>
+#include <stdexcept>
+#include <stdio.h>
+#include <algorithm>
+#include <unistd.h>
+#include <math.h>
+#include <assert.h>
+
+/*
+ * Bad performance if it's large, and flaky triggering if it's too small
+ */
+static const int OUTPUT_RECORD_SIZE = 1024; // Must be power of 2
+
+/*
+ * For (slow-updated) STRIPCHART triggering, we make the record size larger, since we
+ * potentially want to be able to "see" hours of data. This works as long as the
+ * update rates to a STRIPCHART are low, which they generally are--that's rather what
+ * a stripchart is all about!
+ */
+static const int SCHART_MULT = 8;
+
+
+static inline int
+wrap_bi (int buffer_index, int mx) // wrap buffer index
+{
+ return buffer_index & (mx - 1);
+}
+
+static inline int
+incr_bi (int buffer_index, int mx) // increment buffer index
+{
+ return wrap_bi (buffer_index + 1, mx);
+}
+
+static inline int
+decr_bi (int buffer_index, int mx) // decrement buffer index
+{
+ return wrap_bi (buffer_index - 1, mx);
+}
+
+gr_oscope_guts::gr_oscope_guts (double sample_rate, gr_msg_queue_sptr msgq)
+ : d_nchannels (1),
+ d_msgq (msgq),
+ d_trigger_mode (gr_TRIG_MODE_AUTO),
+ d_trigger_slope (gr_TRIG_SLOPE_POS),
+ d_trigger_channel (0),
+ d_sample_rate (sample_rate),
+ d_update_rate (20),
+ d_trigger_level (0),
+ d_obi (0),
+ d_state (HOLD_OFF),
+ d_decimator_count (0),
+ d_decimator_count_init (1),
+ d_hold_off_count (0),
+ d_hold_off_count_init (OUTPUT_RECORD_SIZE/2-1),
+ d_pre_trigger_count (0),
+ d_post_trigger_count (0),
+ d_post_trigger_count_init (OUTPUT_RECORD_SIZE/2)
+{
+ for (int i = 0; i < MAX_CHANNELS; i++)
+ d_buffer[i] = 0;
+
+ for (int i = 0; i < MAX_CHANNELS; i++){
+ d_buffer[i] = new float [OUTPUT_RECORD_SIZE*SCHART_MULT];
+ for (int j = 0; j < OUTPUT_RECORD_SIZE*SCHART_MULT; j++)
+ d_buffer[i][j] = 0.0;
+ }
+
+ // be sure buffer is full before first write
+ enter_hold_off ();
+ update_rate_or_decimation_changed ();
+}
+
+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;
+
+ if (d_trigger_mode != gr_TRIG_MODE_STRIPCHART)
+ {
+ for (int i = 0; i < d_nchannels; i++)
+ d_buffer[i][d_obi] = channel_data[i]; // copy data into buffer
+
+ 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:
+ if (found_trigger ())
+ enter_post_trigger ();
+ 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, OUTPUT_RECORD_SIZE);
+ }
+ else
+ {
+ for (int i = 0; i < d_nchannels; i++)
+ {
+ for (int j = (OUTPUT_RECORD_SIZE*SCHART_MULT)-1; j > 0; j--)
+ {
+ d_buffer[i][j] = d_buffer[i][j-1];
+ }
+ d_buffer[i][0] = channel_data[i];
+ }
+ d_trigger_off = 0;
+ write_output_records();
+ }
+}
+
+/*
+ * 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_pre_trigger_count = 0;
+ d_state = LOOK_FOR_TRIGGER;
+}
+
+void
+gr_oscope_guts::enter_post_trigger ()
+{
+ d_state = POST_TRIGGER;
+ d_post_trigger_count = d_post_trigger_count_init;
+ //ensure that the trigger offset is no more than than half a sample
+ if (d_trigger_off > .5) d_trigger_off -= 1;
+ else d_post_trigger_count--;
+}
+
+// ----------------------------------------------------------------
+// returns true if trigger found
+
+bool
+gr_oscope_guts::found_trigger ()
+{
+ int mx = d_trigger_mode == gr_TRIG_MODE_STRIPCHART ? OUTPUT_RECORD_SIZE*SCHART_MULT :
+ OUTPUT_RECORD_SIZE;
+
+ float prev_sample = d_buffer[d_trigger_channel][decr_bi(d_obi, mx)];
+ float new_sample = d_buffer[d_trigger_channel][d_obi];
+
+ switch (d_trigger_mode){
+
+ case gr_TRIG_MODE_AUTO: //too many samples without a trigger
+ d_pre_trigger_count++;
+ if (d_pre_trigger_count > OUTPUT_RECORD_SIZE/2) return true;
+
+ case gr_TRIG_MODE_NORM: //look for trigger
+ switch (d_trigger_slope){
+
+ case gr_TRIG_SLOPE_POS: //trigger point in pos slope?
+ if (new_sample < d_trigger_level || prev_sample >= d_trigger_level) return false;
+ break;
+
+ case gr_TRIG_SLOPE_NEG: //trigger point in neg slope?
+ if (new_sample > d_trigger_level || prev_sample <= d_trigger_level) return false;
+ break;
+ }
+
+ //calculate the trigger offset in % sample
+ d_trigger_off = (d_trigger_level - prev_sample)/(new_sample - prev_sample);
+ return true;
+
+ case gr_TRIG_MODE_FREE: //free run mode, always trigger
+ d_trigger_off = 0;
+ return true;
+
+ default:
+ assert (0);
+ return false;
+ }
+}
+
+// ----------------------------------------------------------------
+// write output records (duh!)
+
+void
+gr_oscope_guts::write_output_records ()
+{
+ int mx;
+
+ mx = d_trigger_mode == gr_TRIG_MODE_STRIPCHART ?
+ OUTPUT_RECORD_SIZE*SCHART_MULT : OUTPUT_RECORD_SIZE;
+
+ // if the output queue if full, drop the data like its hot.
+ 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
+ mx, // arg2 for other side
+ ((d_nchannels * mx) + 1) * 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 + 1 points at the oldest sample in the buffer
+ for (int i = 0; i < mx; i++){
+ out[i] = d_buffer[ch][wrap_bi(d_obi + 1 + i, mx)];
+ }
+ out += mx;
+ }
+ //Set the last sample as the trigger offset:
+ // The non gl scope sink will not look at this last sample.
+ // The gl scope sink will use this last sample as an offset.
+ out[0] = d_trigger_off;
+ 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)
+{
+ d_trigger_mode = mode;
+ trigger_changed ();
+ return true;
+}
+
+bool
+gr_oscope_guts::set_trigger_slope (gr_trigger_slope slope)
+{
+ d_trigger_slope = slope;
+ trigger_changed ();
+ return true;
+}
+
+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]);
+ }
+ return set_trigger_level((min_v + max_v) * 0.5);
+}
+
+bool
+gr_oscope_guts::set_num_channels(int nchannels)
+{
+ if (nchannels > 0 && nchannels <= MAX_CHANNELS){
+ d_nchannels = nchannels;
+ return true;
+ }
+ return false;
+}
+
+
+void
+gr_oscope_guts::trigger_changed ()
+{
+ 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;
+}
+
+gr_trigger_slope
+gr_oscope_guts::get_trigger_slope () const
+{
+ return d_trigger_slope;
+}
+
+double
+gr_oscope_guts::get_trigger_level () const
+{
+ return d_trigger_level;
+}
+
+int
+gr_oscope_guts::get_samples_per_output_record () const
+{
+ int mx;
+
+ mx = OUTPUT_RECORD_SIZE;
+ if (d_trigger_mode == gr_TRIG_MODE_STRIPCHART)
+ {
+ mx = OUTPUT_RECORD_SIZE*SCHART_MULT;
+ }
+ return mx;
+}
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
index 000000000..bc9513c7e
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_oscope_guts.h
@@ -0,0 +1,123 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003,2005 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+
+#ifndef INCLUDED_GR_OSCOPE_GUTS_H
+#define INCLUDED_GR_OSCOPE_GUTS_H
+
+#include <gr_core_api.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_CORE_API gr_oscope_guts {
+public:
+ static const int MAX_CHANNELS = 8;
+private:
+ 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;
+ gr_trigger_slope d_trigger_slope;
+ 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_pre_trigger_count;
+ int d_post_trigger_count;
+ int d_post_trigger_count_init;
+ float d_trigger_off; //%sample trigger is off
+
+ // 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 ();
+ bool found_trigger (); // returns true if found
+ 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 (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_slope (gr_trigger_slope slope);
+ bool set_trigger_level (double trigger_level);
+ bool set_trigger_level_auto (); // set to 50% level
+ bool set_sample_rate(double sample_rate);
+ bool set_num_channels(int nchannels);
+
+
+ // 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;
+ gr_trigger_slope get_trigger_slope () 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
index 000000000..3d7072ed4
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_oscope_sink.i
@@ -0,0 +1,77 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+%include gr_trigger_mode.h
+
+// 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_slope (gr_trigger_slope slope);
+ 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;
+ gr_trigger_slope get_trigger_slope () 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
index 000000000..493a25e81
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_oscope_sink_f.cc
@@ -0,0 +1,78 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003,2004,2005,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_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 gnuradio::get_initial_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, gr_oscope_guts::MAX_CHANNELS, sizeof (float)),
+ sampling_rate),
+ d_msgq(msgq)
+{
+ d_guts = new gr_oscope_guts (d_sampling_rate, d_msgq);
+}
+
+
+bool
+gr_oscope_sink_f::check_topology (int ninputs, int noutputs)
+{
+ return d_guts->set_num_channels(ninputs);
+}
+
+
+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[gr_oscope_guts::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
index 000000000..8d434d2bc
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_oscope_sink_f.h
@@ -0,0 +1,63 @@
+/* -*- 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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_OSCOPE_SINK_F_H
+#define INCLUDED_GR_OSCOPE_SINK_F_H
+
+#include <gr_core_api.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_CORE_API 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_blk
+ *
+ * Accepts multiple float streams.
+ */
+class GR_CORE_API gr_oscope_sink_f : public gr_oscope_sink_x
+{
+private:
+ friend GR_CORE_API 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
index 000000000..9580dbf6a
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_oscope_sink_x.cc
@@ -0,0 +1,156 @@
+/* -*- 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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_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_slope (gr_trigger_slope slope)
+{
+ return d_guts->set_trigger_slope (slope);
+}
+
+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);
+}
+
+bool
+gr_oscope_sink_x::set_num_channels (int nchannels)
+{
+ return d_guts->set_num_channels (nchannels);
+}
+
+// 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 ();
+}
+
+gr_trigger_slope
+gr_oscope_sink_x::get_trigger_slope () const
+{
+ return d_guts->get_trigger_slope ();
+}
+
+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
index 000000000..153d0937a
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_oscope_sink_x.h
@@ -0,0 +1,77 @@
+/* -*- 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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_OSCOPE_SINK_X_H
+#define INCLUDED_GR_OSCOPE_SINK_X_H
+
+#include <gr_core_api.h>
+#include <gr_sync_block.h>
+#include <gr_trigger_mode.h>
+
+class gr_oscope_guts;
+
+/*!
+ * \brief Abstract class for python oscilloscope module.
+ * \ingroup sink_blk
+ *
+ * Don't instantiate this. Use gr_oscope_sink_f or gr_oscope_sink_c instead.
+ */
+class GR_CORE_API 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_slope (gr_trigger_slope slope);
+ bool set_trigger_level (double trigger_level);
+ bool set_trigger_level_auto (); // set to 50% level
+ bool set_sample_rate(double sample_rate);
+ bool set_num_channels (int nchannels);
+
+
+ // 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;
+ gr_trigger_slope get_trigger_slope () 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_pdu.cc b/gnuradio-core/src/lib/io/gr_pdu.cc
new file mode 100644
index 000000000..302fd7b9b
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_pdu.cc
@@ -0,0 +1,79 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_pdu.h>
+
+size_t
+gr_pdu_itemsize(gr_pdu_vector_type type){
+ switch(type){
+ case pdu_byte:
+ return 1;
+ case pdu_float:
+ return sizeof(float);
+ case pdu_complex:
+ return sizeof(gr_complex);
+ default:
+ throw std::runtime_error("bad type!");
+ }
+}
+
+bool
+gr_pdu_type_matches(gr_pdu_vector_type type, pmt::pmt_t v){
+ switch(type){
+ case pdu_byte:
+ return pmt::pmt_is_u8vector(v);
+ case pdu_float:
+ return pmt::pmt_is_f32vector(v);
+ case pdu_complex:
+ return pmt::pmt_is_c32vector(v);
+ default:
+ throw std::runtime_error("bad type!");
+ }
+}
+
+pmt::pmt_t
+gr_pdu_make_vector(gr_pdu_vector_type type, const uint8_t* buf, size_t items){
+ switch(type){
+ case pdu_byte:
+ return pmt::pmt_init_u8vector(items, buf);
+ case pdu_float:
+ return pmt::pmt_init_f32vector(items, (const float*)buf);
+ case pdu_complex:
+ return pmt::pmt_init_c32vector(items, (const gr_complex*)buf);
+ default:
+ throw std::runtime_error("bad type!");
+ }
+}
+
+gr_pdu_vector_type type_from_pmt(pmt::pmt_t vector){
+ if(pmt_is_u8vector(vector))
+ return pdu_byte;
+ if(pmt_is_f32vector(vector))
+ return pdu_float;
+ if(pmt_is_c32vector(vector))
+ return pdu_complex;
+ throw std::runtime_error("bad type!");
+}
diff --git a/gnuradio-core/src/lib/io/gr_pdu.h b/gnuradio-core/src/lib/io/gr_pdu.h
new file mode 100644
index 000000000..a5ae87db7
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_pdu.h
@@ -0,0 +1,39 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef GR_PDU_H
+#define GR_PDU_H
+
+#include <gr_complex.h>
+#include <gruel/pmt.h>
+
+#define pdu_port_id pmt::mp("pdus")
+#define pdu_length_tag pmt::mp("pdu_length")
+
+enum gr_pdu_vector_type { pdu_byte, pdu_float, pdu_complex };
+
+size_t gr_pdu_itemsize(gr_pdu_vector_type type);
+bool gr_pdu_type_matches(gr_pdu_vector_type type, pmt::pmt_t v);
+pmt::pmt_t gr_pdu_make_vector(gr_pdu_vector_type type, const uint8_t* buf, size_t items);
+gr_pdu_vector_type type_from_pmt(pmt::pmt_t vector);
+
+#endif
diff --git a/gnuradio-core/src/lib/io/gr_pdu.i b/gnuradio-core/src/lib/io/gr_pdu.i
new file mode 100644
index 000000000..ada3a63a7
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_pdu.i
@@ -0,0 +1,30 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+%{
+#include <gr_pdu.h>
+%}
+
+enum gr_pdu_vector_type { pdu_byte, pdu_float, pdu_complex };
+
+
+
diff --git a/gnuradio-core/src/lib/io/gr_pdu_to_tagged_stream.cc b/gnuradio-core/src/lib/io/gr_pdu_to_tagged_stream.cc
new file mode 100644
index 000000000..5c319dc39
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_pdu_to_tagged_stream.cc
@@ -0,0 +1,132 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_pdu_to_tagged_stream.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 <string.h>
+
+
+// public constructor that returns a shared_ptr
+
+gr_pdu_to_tagged_stream_sptr
+gr_make_pdu_to_tagged_stream(gr_pdu_vector_type t)
+{
+ return gnuradio::get_initial_sptr(new gr_pdu_to_tagged_stream(t));
+}
+
+gr_pdu_to_tagged_stream::gr_pdu_to_tagged_stream (gr_pdu_vector_type t)
+ : gr_sync_block("pdu_to_tagged_stream",
+ gr_make_io_signature(0, 0, 0),
+ gr_make_io_signature(1, 1, gr_pdu_itemsize(t))),
+ d_vectortype(t), d_itemsize(gr_pdu_itemsize(t))
+{
+ message_port_register_in(pdu_port_id);
+}
+
+gr_pdu_to_tagged_stream::~gr_pdu_to_tagged_stream()
+{
+}
+
+int
+gr_pdu_to_tagged_stream::work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ char *out = (char *) output_items[0];
+ int nout = 0;
+
+ // if we have remaining output, send it
+ if(d_remain.size() > 0){
+ nout = std::min((size_t)d_remain.size()/d_itemsize, (size_t)noutput_items);
+ memcpy(out, &d_remain[0], nout*d_itemsize);
+ d_remain.erase( d_remain.begin(), d_remain.begin()+nout);
+ noutput_items -= nout;
+ out += nout*d_itemsize;
+ }
+
+ // if we have space for at least one item output as much as we can
+ if(noutput_items > 0){
+
+ // grab a message if one exists
+ //pmt::pmt_t msg( delete_head_nowait( pdu_port_id ) );
+ pmt::pmt_t msg( delete_head_blocking( pdu_port_id ) );
+ if(msg.get() == NULL ){
+ return nout;
+ }
+
+ // make sure type is valid
+ if(!pmt::pmt_is_pair(msg)){
+ throw std::runtime_error("received a malformed pdu message!");
+ }
+
+// printf("got a msg\n");
+// pmt::pmt_print(msg);
+
+ // grab the components of the pdu message
+ pmt::pmt_t meta(pmt::pmt_car(msg)); // make sure this is NIL || Dict ?
+ pmt::pmt_t vect(pmt::pmt_cdr(msg)); // make sure this is a vector?
+
+ // compute offset for output tag
+ uint64_t offset = nitems_written(0) + nout;
+
+ // add a tag for pdu length
+ add_item_tag(0, offset, pdu_length_tag, pmt::pmt_from_long( pmt::pmt_length(vect) ), pmt::mp(alias()));
+
+ // if we recieved metadata add it as tags
+ if( !pmt_eq(meta, pmt::PMT_NIL) ){
+ pmt::pmt_t pair(pmt::pmt_dict_keys( meta ));
+ while( !pmt_eq(pair, pmt::PMT_NIL) ){
+ pmt::pmt_t k(pmt::pmt_cdr(pair));
+ pmt::pmt_t v(pmt::pmt_dict_ref(meta, k, pmt::PMT_NIL));
+ add_item_tag(0, offset, k, v, pmt::mp(alias()));
+ }
+ }
+
+ // copy vector output
+ size_t ncopy = std::min((size_t)noutput_items, (size_t)pmt::pmt_length(vect));
+ size_t nsave = pmt::pmt_length(vect) - ncopy;
+
+ // copy output
+ size_t io(0);
+ nout += ncopy;
+ memcpy(out, pmt_uniform_vector_elements(vect,io), ncopy*d_itemsize);
+
+ // save leftover items if needed for next work call
+ if(nsave > 0){
+ d_remain.resize(nsave*d_itemsize, 0);
+ memcpy(&d_remain[0], pmt_uniform_vector_elements(vect,ncopy), nsave*d_itemsize);
+ }
+
+ }
+
+ return nout;
+}
diff --git a/gnuradio-core/src/lib/io/gr_pdu_to_tagged_stream.h b/gnuradio-core/src/lib/io/gr_pdu_to_tagged_stream.h
new file mode 100644
index 000000000..3105a3d38
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_pdu_to_tagged_stream.h
@@ -0,0 +1,63 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_PDU_TO_TAGGED_STREAM_H
+#define INCLUDED_GR_PDU_TO_TAGGED_STREAM_H
+
+#include <gr_core_api.h>
+#include <gr_sync_block.h>
+#include <gr_message.h>
+#include <gr_msg_queue.h>
+#include <gr_pdu.h>
+
+class gr_pdu_to_tagged_stream;
+typedef boost::shared_ptr<gr_pdu_to_tagged_stream> gr_pdu_to_tagged_stream_sptr;
+
+GR_CORE_API gr_pdu_to_tagged_stream_sptr gr_make_pdu_to_tagged_stream (gr_pdu_vector_type t);
+
+/*!
+ * \brief Turn received messages into a stream
+ * \ingroup source_blk
+ */
+class GR_CORE_API gr_pdu_to_tagged_stream : public gr_sync_block
+{
+ private:
+ gr_pdu_vector_type d_vectortype;
+ size_t d_itemsize;
+ std::vector<uint8_t> d_remain;
+
+ friend GR_CORE_API gr_pdu_to_tagged_stream_sptr
+ gr_make_pdu_to_tagged_stream(gr_pdu_vector_type t);
+
+ protected:
+ gr_pdu_to_tagged_stream (gr_pdu_vector_type t);
+
+ public:
+ ~gr_pdu_to_tagged_stream ();
+
+ int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+
+};
+
+#endif /* INCLUDED_GR_PDU_TO_TAGGED_SOURCE_H */
diff --git a/gnuradio-core/src/lib/io/gr_pdu_to_tagged_stream.i b/gnuradio-core/src/lib/io/gr_pdu_to_tagged_stream.i
new file mode 100644
index 000000000..ec760b309
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_pdu_to_tagged_stream.i
@@ -0,0 +1,31 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,pdu_to_tagged_stream);
+
+%{
+#include <gr_pdu_to_tagged_stream.h>
+%}
+
+%include <gr_pdu_to_tagged_stream.h>
+
+
diff --git a/gnuradio-core/src/lib/io/gr_socket_pdu.cc b/gnuradio-core/src/lib/io/gr_socket_pdu.cc
new file mode 100644
index 000000000..bb374b300
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_socket_pdu.cc
@@ -0,0 +1,157 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_socket_pdu.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 <string.h>
+#include <iostream>
+#include <gr_pdu.h>
+#include <boost/format.hpp>
+
+// public constructor that returns a shared_ptr
+gr_socket_pdu_sptr
+gr_make_socket_pdu (std::string type, std::string addr, std::string port, int MTU)
+{
+ return gnuradio::get_initial_sptr(new gr_socket_pdu(type,addr,port,MTU));
+}
+
+gr_socket_pdu::gr_socket_pdu (std::string type, std::string addr, std::string port, int MTU)
+ : gr_stream_pdu_base(MTU)
+{
+
+ if( (type == "TCP_SERVER") || (type == "TCP_CLIENT")){
+ boost::asio::ip::tcp::resolver resolver(_io_service);
+ boost::asio::ip::tcp::resolver::query query(boost::asio::ip::tcp::v4(), addr, port);
+ _tcp_endpoint = *resolver.resolve(query);
+ }
+ if( (type == "UDP_SERVER") || (type == "UDP_CLIENT")){
+ boost::asio::ip::udp::resolver resolver(_io_service);
+ boost::asio::ip::udp::resolver::query query(boost::asio::ip::udp::v4(), addr, port);
+ if( (type == "UDP_SERVER") ){
+ _udp_endpoint = *resolver.resolve(query);
+ } else {
+ _udp_endpoint_other = *resolver.resolve(query);
+ }
+ }
+
+ // register ports
+ message_port_register_out(pmt::mp("pdus"));
+ message_port_register_in(pmt::mp("pdus"));
+
+ // set up socketry
+ if (type == "TCP_SERVER"){
+ _acceptor_tcp.reset(new boost::asio::ip::tcp::acceptor(_io_service, _tcp_endpoint));
+ _acceptor_tcp->set_option(boost::asio::ip::tcp::acceptor::reuse_address(true));
+ start_tcp_accept();
+ // bind tcp server send handler
+ set_msg_handler(pmt::mp("pdus"), boost::bind(&gr_socket_pdu::tcp_server_send, this, _1));
+ } else if(type =="TCP_CLIENT"){
+ boost::system::error_code error = boost::asio::error::host_not_found;
+ _tcp_socket.reset(new boost::asio::ip::tcp::socket(_io_service));
+ _tcp_socket->connect(_tcp_endpoint, error);
+ if(error){
+ throw boost::system::system_error(error);
+ }
+ set_msg_handler(pmt::mp("pdus"), boost::bind(&gr_socket_pdu::tcp_client_send, this, _1));
+ _tcp_socket->async_read_some(
+ boost::asio::buffer(rxbuf),
+ boost::bind(&gr_socket_pdu::handle_tcp_read, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred));
+
+ } else if(type =="UDP_SERVER"){
+ _udp_socket.reset(new boost::asio::ip::udp::socket(_io_service, _udp_endpoint));
+ _udp_socket->async_receive_from( boost::asio::buffer(rxbuf), _udp_endpoint_other,
+ boost::bind(&gr_socket_pdu::handle_udp_read, this,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred));
+ set_msg_handler(pmt::mp("pdus"), boost::bind(&gr_socket_pdu::udp_send, this, _1));
+ } else if(type =="UDP_CLIENT"){
+ _udp_socket.reset(new boost::asio::ip::udp::socket(_io_service, _udp_endpoint));
+ _udp_socket->async_receive_from( boost::asio::buffer(rxbuf), _udp_endpoint_other,
+ boost::bind(&gr_socket_pdu::handle_udp_read, this,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred));
+ set_msg_handler(pmt::mp("pdus"), boost::bind(&gr_socket_pdu::udp_send, this, _1));
+ } else {
+ throw std::runtime_error("unknown socket type!");
+ }
+
+ // start thread for io_service
+ d_thread = boost::shared_ptr<boost::thread>(new boost::thread(boost::bind(&gr_socket_pdu::run_io_service, this)));
+ d_started = true;
+}
+
+void tcp_connection::handle_read(const boost::system::error_code& error/*error*/, size_t bytes_transferred)
+ {
+ if(!error)
+ {
+ pmt::pmt_t vector = pmt::pmt_init_u8vector(bytes_transferred, (const uint8_t*)&buf[0]);
+ pmt::pmt_t pdu = pmt::pmt_cons( pmt::PMT_NIL, vector);
+
+ d_block->message_port_pub( pmt::mp("pdus"), pdu );
+
+ socket_.async_read_some(
+ boost::asio::buffer(buf),
+ boost::bind(&tcp_connection::handle_read, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred));
+
+ } else {
+ std::cout << "error occurred\n";
+ }
+
+ }
+
+
+void gr_socket_pdu::tcp_server_send(pmt::pmt_t msg){
+ pmt::pmt_t vector = pmt::pmt_cdr(msg);
+ for(size_t i=0; i<d_tcp_connections.size(); i++){
+ d_tcp_connections[i]->send(vector);
+ }
+}
+
+void gr_socket_pdu::tcp_client_send(pmt::pmt_t msg){
+ pmt::pmt_t vector = pmt::pmt_cdr(msg);
+ size_t len = pmt::pmt_length(vector);
+ size_t offset(0);
+ boost::array<char, 10000> txbuf;
+ memcpy(&txbuf[0], pmt::pmt_uniform_vector_elements(vector, offset), len);
+ _tcp_socket->send(boost::asio::buffer(txbuf,len));
+}
+
+void gr_socket_pdu::udp_send(pmt::pmt_t msg){
+ pmt::pmt_t vector = pmt::pmt_cdr(msg);
+ size_t len = pmt::pmt_length(vector);
+ size_t offset(0);
+ boost::array<char, 10000> txbuf;
+ memcpy(&txbuf[0], pmt::pmt_uniform_vector_elements(vector, offset), len);
+ if(_udp_endpoint_other.address().to_string() != "0.0.0.0")
+ _udp_socket->send_to(boost::asio::buffer(txbuf,len), _udp_endpoint_other);
+}
diff --git a/gnuradio-core/src/lib/io/gr_socket_pdu.h b/gnuradio-core/src/lib/io/gr_socket_pdu.h
new file mode 100644
index 000000000..2fedb317d
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_socket_pdu.h
@@ -0,0 +1,203 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_SOCKET_PDU_H
+#define INCLUDED_GR_SOCKET_PDU_H
+
+#include <gr_core_api.h>
+#include <gr_sync_block.h>
+#include <gr_message.h>
+#include <gr_msg_queue.h>
+#include <gr_stream_pdu_base.h>
+#include <boost/array.hpp>
+#include <boost/asio.hpp>
+#include <iostream>
+
+class gr_socket_pdu;
+typedef boost::shared_ptr<gr_socket_pdu> gr_socket_pdu_sptr;
+
+GR_CORE_API gr_socket_pdu_sptr gr_make_socket_pdu (std::string type, std::string addr, std::string port, int MTU=10000);
+
+class tcp_connection
+ : public boost::enable_shared_from_this<tcp_connection>
+{
+public:
+ typedef boost::shared_ptr<tcp_connection> pointer;
+ gr_socket_pdu *d_block;
+ boost::array<char, 10000> buf;
+
+ static pointer create(boost::asio::io_service& io_service)
+ {
+ return pointer(new tcp_connection(io_service));
+ }
+
+ boost::asio::ip::tcp::socket& socket()
+ {
+ return socket_;
+ }
+
+ void start(gr_socket_pdu* parent)
+ {
+ d_block = parent;
+// message_ = "connected to gr_socket_pdu\n";
+// boost::asio::async_write(socket_, boost::asio::buffer(message_),
+// boost::bind(&tcp_connection::handle_write, shared_from_this(),
+// boost::asio::placeholders::error,
+// boost::asio::placeholders::bytes_transferred));
+
+ socket_.async_read_some(
+ boost::asio::buffer(buf),
+ boost::bind(&tcp_connection::handle_read, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred));
+ }
+ void send(pmt::pmt_t vector){
+ size_t len = pmt::pmt_length(vector);
+ size_t offset(0);
+ boost::array<char, 10000> txbuf;
+ memcpy(&txbuf[0], pmt::pmt_uniform_vector_elements(vector, offset), len);
+ boost::asio::async_write(socket_, boost::asio::buffer(txbuf, len),
+ boost::bind(&tcp_connection::handle_write, shared_from_this(),
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred));
+ }
+
+ ~tcp_connection(){
+// std::cout << "tcp_connection destroyed\n";
+ }
+
+private:
+ tcp_connection(boost::asio::io_service& io_service)
+ : socket_(io_service)
+ {
+ }
+
+ void handle_read(const boost::system::error_code& error/*error*/, size_t bytes_transferred);
+
+ void handle_write(const boost::system::error_code& /*error*/,
+ size_t /*bytes_transferred*/)
+ {
+ }
+
+ boost::asio::ip::tcp::socket socket_;
+ std::string message_;
+};
+
+
+/*!
+ * \brief Gather received items into messages and insert into msgq
+ * \ingroup sink_blk
+ */
+class GR_CORE_API gr_socket_pdu : public gr_stream_pdu_base
+{
+ private:
+ friend GR_CORE_API gr_socket_pdu_sptr
+ gr_make_socket_pdu(std::string type, std::string addr, std::string port, int MTU);
+
+ boost::asio::io_service _io_service;
+
+ boost::array<char, 10000> rxbuf;
+
+ // tcp specific
+ boost::asio::ip::tcp::endpoint _tcp_endpoint;
+
+ // specific to tcp server
+ boost::shared_ptr<boost::asio::ip::tcp::acceptor> _acceptor_tcp;
+ std::vector<tcp_connection::pointer> d_tcp_connections;
+ void tcp_server_send(pmt::pmt_t msg);
+ void tcp_client_send(pmt::pmt_t msg);
+ void udp_send(pmt::pmt_t msg);
+
+ // specific to tcp client
+ boost::shared_ptr<boost::asio::ip::tcp::socket> _tcp_socket;
+
+ // specific to udp client/server
+ boost::asio::ip::udp::endpoint _udp_endpoint;
+ boost::asio::ip::udp::endpoint _udp_endpoint_other;
+ boost::shared_ptr<boost::asio::ip::udp::socket> _udp_socket;
+
+ void handle_receive(const boost::system::error_code& error, std::size_t ){
+ }
+
+ void start_tcp_accept(){
+ tcp_connection::pointer new_connection =
+ tcp_connection::create(_acceptor_tcp->get_io_service());
+
+ _acceptor_tcp->async_accept(new_connection->socket(),
+ boost::bind(&gr_socket_pdu::handle_tcp_accept, this, new_connection,
+ boost::asio::placeholders::error));
+ }
+
+ void handle_tcp_accept(tcp_connection::pointer new_connection, const boost::system::error_code& error){
+ if (!error)
+ {
+ new_connection->start(this);
+ d_tcp_connections.push_back(new_connection);
+ start_tcp_accept();
+ } else {
+ std::cout << error << std::endl;
+ }
+ }
+
+ void run_io_service(){
+ _io_service.run();
+ }
+
+ void handle_udp_read(const boost::system::error_code& error/*error*/, size_t bytes_transferred){
+ if(!error){
+ pmt::pmt_t vector = pmt::pmt_init_u8vector(bytes_transferred, (const uint8_t*)&rxbuf[0]);
+ pmt::pmt_t pdu = pmt::pmt_cons( pmt::PMT_NIL, vector);
+
+ message_port_pub( pmt::mp("pdus"), pdu );
+
+ _udp_socket->async_receive_from( boost::asio::buffer(rxbuf), _udp_endpoint_other,
+ boost::bind(&gr_socket_pdu::handle_udp_read, this,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred));
+ } else {
+ throw boost::system::system_error(error);
+// std::cout << "error occurred\n";
+ }
+ }
+ void handle_tcp_read(const boost::system::error_code& error/*error*/, size_t bytes_transferred){
+ if(!error)
+ {
+ pmt::pmt_t vector = pmt::pmt_init_u8vector(bytes_transferred, (const uint8_t*)&rxbuf[0]);
+ pmt::pmt_t pdu = pmt::pmt_cons( pmt::PMT_NIL, vector);
+
+ message_port_pub( pmt::mp("pdus"), pdu );
+
+ _tcp_socket->async_read_some(
+ boost::asio::buffer(rxbuf),
+ boost::bind(&gr_socket_pdu::handle_tcp_read, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred));
+
+ } else {
+ //std::cout << "error occurred\n";
+ throw boost::system::system_error(error);
+ }
+ }
+
+ protected:
+ gr_socket_pdu (std::string type, std::string addr, std::string port, int MTU=10000);
+ public:
+ ~gr_socket_pdu () {}
+};
+
+#endif /* INCLUDED_GR_TUNTAP_PDU_H */
diff --git a/gnuradio-core/src/lib/io/gr_socket_pdu.i b/gnuradio-core/src/lib/io/gr_socket_pdu.i
new file mode 100644
index 000000000..3e20b63e2
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_socket_pdu.i
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,socket_pdu);
+
+%ignore tcp_connection;
+
+%{
+#include <gr_socket_pdu.h>
+%}
+
+%include "gr_stream_pdu_base.h"
+%include "gr_socket_pdu.h"
+
diff --git a/gnuradio-core/src/lib/io/gr_stream_pdu_base.cc b/gnuradio-core/src/lib/io/gr_stream_pdu_base.cc
new file mode 100644
index 000000000..7250c33e5
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_stream_pdu_base.cc
@@ -0,0 +1,123 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <ciso646>
+#include <gr_stream_pdu_base.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 <string.h>
+#include <iostream>
+#include <gr_pdu.h>
+#include <boost/asio.hpp>
+#include <boost/format.hpp>
+
+#ifdef HAVE_IO_H
+#include <io.h>
+#endif
+
+static const long timeout_us = 100*1000; //100ms
+
+gr_stream_pdu_base::gr_stream_pdu_base (int MTU)
+ : gr_sync_block("stream_pdu_base",
+ gr_make_io_signature(0, 0, 0),
+ gr_make_io_signature(0, 0, 0)),
+ d_finished(false), d_started(false), d_fd(-1)
+{
+ // reserve space for rx buffer
+ d_rxbuf.resize(MTU,0);
+}
+
+gr_stream_pdu_base::~gr_stream_pdu_base()
+{
+ stop_rxthread();
+}
+
+void gr_stream_pdu_base::stop_rxthread(){
+ d_finished = true;
+ if(d_started){
+ d_thread->interrupt();
+ d_thread->join();
+ }
+ }
+
+void gr_stream_pdu_base::start_rxthread(pmt::pmt_t _rxport){
+ rxport = _rxport;
+ d_thread = boost::shared_ptr<boost::thread>(new boost::thread(boost::bind(&gr_stream_pdu_base::run, this)));
+ d_started = true;
+ }
+
+void gr_stream_pdu_base::run(){
+ while(!d_finished) {
+ if(not wait_ready()){ continue; }
+ const int result = read( d_fd, &d_rxbuf[0], d_rxbuf.size() );
+ if(result <= 0){ throw std::runtime_error("gr_stream_pdu_base, bad socket read!"); }
+ pmt::pmt_t vector = pmt::pmt_init_u8vector(result, &d_rxbuf[0]);
+ pmt::pmt_t pdu = pmt::pmt_cons( pmt::PMT_NIL, vector);
+ message_port_pub(rxport, pdu);
+ }
+}
+
+void gr_stream_pdu_base::send(pmt::pmt_t msg){
+ pmt::pmt_t vector = pmt::pmt_cdr(msg);
+ size_t offset(0);
+ size_t itemsize(gr_pdu_itemsize(type_from_pmt(vector)));
+ int len( pmt::pmt_length(vector)*itemsize );
+
+ const int rv = write(d_fd, pmt::pmt_uniform_vector_elements(vector, offset), len);
+ if(rv != len){
+ std::cerr << boost::format("WARNING: gr_stream_pdu_base::send(pdu) write failed! (d_fd=%d, len=%d, rv=%d)")
+ % d_fd % len % rv << std::endl;
+ }
+}
+
+int
+gr_stream_pdu_base::work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ throw std::runtime_error("should not be called.\n");
+ return 0;
+}
+
+bool gr_stream_pdu_base::wait_ready(){
+ //setup timeval for timeout
+ timeval tv;
+ tv.tv_sec = 0;
+ tv.tv_usec = timeout_us;
+
+ //setup rset for timeout
+ fd_set rset;
+ FD_ZERO(&rset);
+ FD_SET(d_fd, &rset);
+
+ //call select with timeout on receive socket
+ return ::select(d_fd+1, &rset, NULL, NULL, &tv) > 0;
+}
diff --git a/gnuradio-core/src/lib/io/gr_stream_pdu_base.h b/gnuradio-core/src/lib/io/gr_stream_pdu_base.h
new file mode 100644
index 000000000..35bacf523
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_stream_pdu_base.h
@@ -0,0 +1,59 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_STREAM_PDU_BASE_H
+#define INCLUDED_GR_STREAM_PDU_BASE_H
+
+#include <gr_core_api.h>
+#include <gr_sync_block.h>
+#include <gr_message.h>
+#include <gr_msg_queue.h>
+
+/*!
+ * \brief Gather received items into messages and insert into msgq
+ * \ingroup sink_blk
+ */
+class GR_CORE_API gr_stream_pdu_base : public gr_sync_block
+{
+ public:
+ boost::shared_ptr<boost::thread> d_thread;
+ bool d_finished;
+ bool d_started;
+ std::vector<uint8_t> d_rxbuf;
+ void run();
+ int d_fd;
+ gr_stream_pdu_base (int MTU=10000);
+ ~gr_stream_pdu_base ();
+ void send(pmt::pmt_t msg);
+ bool wait_ready();
+ int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+ void start_rxthread(pmt::pmt_t _rxport);
+ void stop_rxthread();
+ private:
+ pmt::pmt_t rxport;
+};
+
+typedef boost::shared_ptr<gr_stream_pdu_base> gr_stream_pdu_base_sptr;
+
+#endif /* INCLUDED_GR_TUNTAP_PDU_H */
diff --git a/gnuradio-core/src/lib/io/gr_tagged_file_sink.cc b/gnuradio-core/src/lib/io/gr_tagged_file_sink.cc
new file mode 100644
index 000000000..6d642088e
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_tagged_file_sink.cc
@@ -0,0 +1,216 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_tagged_file_sink.h>
+#include <gr_io_signature.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdexcept>
+#include <iostream>
+
+#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_tagged_file_sink::gr_tagged_file_sink (size_t itemsize, double samp_rate)
+ : gr_sync_block ("tagged_file_sink",
+ gr_make_io_signature (1, 1, itemsize),
+ gr_make_io_signature (0, 0, 0)),
+ d_itemsize (itemsize), d_n(0), d_sample_rate(samp_rate)
+{
+ d_state = NOT_IN_BURST;
+ d_last_N = 0;
+ d_timeval = 0;
+}
+
+gr_tagged_file_sink_sptr
+gr_make_tagged_file_sink (size_t itemsize, double samp_rate)
+{
+ return gnuradio::get_initial_sptr(new gr_tagged_file_sink (itemsize, samp_rate));
+}
+
+gr_tagged_file_sink::~gr_tagged_file_sink ()
+{
+}
+
+int
+gr_tagged_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];
+
+ uint64_t start_N = nitems_read(0);
+ uint64_t end_N = start_N + (uint64_t)(noutput_items);
+ pmt::pmt_t bkey = pmt::pmt_string_to_symbol("burst");
+ //pmt::pmt_t tkey = pmt::pmt_string_to_symbol("time"); // use gr_tags::key_time
+
+ std::vector<gr_tag_t> all_tags;
+ get_tags_in_range(all_tags, 0, start_N, end_N);
+
+ std::sort(all_tags.begin(), all_tags.end(), gr_tag_t::offset_compare);
+
+ std::vector<gr_tag_t>::iterator vitr = all_tags.begin();
+
+ int idx = 0, idx_stop = 0;
+ while(idx < noutput_items) {
+ if(d_state == NOT_IN_BURST) {
+ while(vitr != all_tags.end()) {
+ if((pmt::pmt_eqv((*vitr).key, bkey)) &&
+ pmt::pmt_is_true((*vitr).value)) {
+
+ uint64_t N = (*vitr).offset;
+ idx = (int)(N - start_N);
+
+ //std::cout << std::endl << "Found start of burst: "
+ // << idx << ", " << N << std::endl;
+
+ // Find time burst occurred by getting latest time tag and extrapolating
+ // to new time based on sample rate of this block.
+ std::vector<gr_tag_t> time_tags;
+ //get_tags_in_range(time_tags, 0, d_last_N, N, gr_tags::key_time);
+ get_tags_in_range(time_tags, 0, d_last_N, N,
+ pmt::pmt_string_to_symbol("time"));
+ if(time_tags.size() > 0) {
+ const gr_tag_t tag = time_tags[time_tags.size()-1];
+
+ uint64_t time_nitems = tag.offset;
+
+ // Get time based on last time tag from USRP
+ pmt::pmt_t time = tag.value;
+ int tsecs = pmt::pmt_to_long(pmt::pmt_tuple_ref(time, 0));
+ double tfrac = pmt::pmt_to_double(pmt::pmt_tuple_ref(time, 1));
+
+ // Get new time from last time tag + difference in time to when
+ // burst tag occured based on the sample rate
+ double delta = (double)(N - time_nitems) / d_sample_rate;
+ d_timeval = (double)tsecs + tfrac + delta;
+
+ //std::cout.setf(std::ios::fixed, std::ios::floatfield);
+ //std::cout.precision(8);
+ //std::cout << "Time found: " << (double)tsecs + tfrac << std::endl;
+ //std::cout << " time: " << d_timeval << std::endl;
+ //std::cout << " time at N = " << time_nitems << " burst N = " << N << std::endl;
+ }
+ else {
+ // if no time tag, use last seen tag and update time based on
+ // sample rate of the block
+ d_timeval += (double)(N - d_last_N) / d_sample_rate;
+ //std::cout << "Time not found" << std::endl;
+ //std::cout << " time: " << d_timeval << std::endl;
+ }
+ d_last_N = N;
+
+ std::stringstream filename;
+ filename.setf(std::ios::fixed, std::ios::floatfield);
+ filename.precision(8);
+ filename << "file" << unique_id() << "_" << d_n << "_" << d_timeval << ".dat";
+ d_n++;
+
+ int fd;
+ if ((fd = ::open (filename.str().c_str(),
+ O_WRONLY|O_CREAT|O_TRUNC|OUR_O_LARGEFILE|OUR_O_BINARY,
+ 0664)) < 0){
+ perror (filename.str().c_str());
+ return -1;
+ }
+
+ // FIXME:
+ //if ((d_handle = fdopen (fd, d_is_binary ? "wb" : "w")) == NULL){
+ if ((d_handle = fdopen (fd, "wb")) == NULL){
+ perror (filename.str().c_str());
+ ::close(fd); // don't leak file descriptor if fdopen fails.
+ }
+
+ //std::cout << "Created new file: " << filename.str() << std::endl;
+
+ d_state = IN_BURST;
+ break;
+ }
+
+ vitr++;
+ }
+ if(d_state == NOT_IN_BURST)
+ return noutput_items;
+ }
+ else { // In burst
+ while(vitr != all_tags.end()) {
+ if((pmt::pmt_eqv((*vitr).key, bkey)) &&
+ pmt::pmt_is_false((*vitr).value)) {
+ uint64_t N = (*vitr).offset;
+ idx_stop = (int)N - start_N;
+
+ //std::cout << "Found end of burst: "
+ // << idx_stop << ", " << N << std::endl;
+
+ int count = fwrite (&inbuf[d_itemsize*idx], d_itemsize,
+ idx_stop-idx, d_handle);
+ if (count == 0) {
+ if(ferror(d_handle)) {
+ perror("gr_tagged_file_sink: error writing file");
+ }
+ }
+ idx = idx_stop;
+ d_state = NOT_IN_BURST;
+ vitr++;
+ fclose(d_handle);
+ break;
+ }
+ else {
+ vitr++;
+ }
+ }
+ if(d_state == IN_BURST) {
+ int count = fwrite (&inbuf[d_itemsize*idx], d_itemsize,
+ noutput_items-idx, d_handle);
+ if (count == 0) {
+ if(ferror(d_handle)) {
+ perror("gr_tagged_file_sink: error writing file");
+ }
+ }
+ idx = noutput_items;
+ }
+ }
+ }
+
+ return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/io/gr_tagged_file_sink.h b/gnuradio-core/src/lib/io/gr_tagged_file_sink.h
new file mode 100644
index 000000000..d6f931a67
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_tagged_file_sink.h
@@ -0,0 +1,72 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_TAGGED_FILE_SINK_H
+#define INCLUDED_GR_TAGGED_FILE_SINK_H
+
+#include <gr_core_api.h>
+#include <gr_sync_block.h>
+#include <cstdio> // for FILE
+
+class gr_tagged_file_sink;
+typedef boost::shared_ptr<gr_tagged_file_sink> gr_tagged_file_sink_sptr;
+
+GR_CORE_API gr_tagged_file_sink_sptr gr_make_tagged_file_sink (size_t itemsize,
+ double samp_rate);
+
+/*!
+ * \brief Write stream to file descriptor.
+ * \ingroup sink_blk
+ */
+
+class GR_CORE_API gr_tagged_file_sink : public gr_sync_block
+{
+ friend GR_CORE_API gr_tagged_file_sink_sptr gr_make_tagged_file_sink (size_t itemsize,
+ double samp_rate);
+
+ private:
+ enum {
+ NOT_IN_BURST = 0,
+ IN_BURST
+ };
+
+ size_t d_itemsize;
+ int d_state;
+ FILE *d_handle;
+ int d_n;
+ double d_sample_rate;
+ uint64_t d_last_N;
+ double d_timeval;
+
+ protected:
+ gr_tagged_file_sink (size_t itemsize, double samp_rate);
+
+ public:
+ ~gr_tagged_file_sink ();
+
+ int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+
+#endif /* INCLUDED_GR_TAGGED_FILE_SINK_H */
diff --git a/gnuradio-core/src/lib/io/gr_tagged_file_sink.i b/gnuradio-core/src/lib/io/gr_tagged_file_sink.i
new file mode 100644
index 000000000..2f2596e12
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_tagged_file_sink.i
@@ -0,0 +1,35 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,tagged_file_sink)
+
+gr_tagged_file_sink_sptr
+gr_make_tagged_file_sink (size_t itemsize, double samp_rate);
+
+class gr_tagged_file_sink : public gr_sync_block
+{
+ protected:
+ gr_tagged_file_sink (size_t itemsize, double samp_rate);
+
+ public:
+ ~gr_tagged_file_sink ();
+};
diff --git a/gnuradio-core/src/lib/io/gr_tagged_stream_to_pdu.cc b/gnuradio-core/src/lib/io/gr_tagged_stream_to_pdu.cc
new file mode 100644
index 000000000..8211b7672
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_tagged_stream_to_pdu.cc
@@ -0,0 +1,137 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_tagged_stream_to_pdu.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 <string.h>
+
+// public constructor that returns a shared_ptr
+
+gr_tagged_stream_to_pdu_sptr
+gr_make_tagged_stream_to_pdu(gr_pdu_vector_type t)
+{
+ return gnuradio::get_initial_sptr(new gr_tagged_stream_to_pdu(t));
+}
+
+gr_tagged_stream_to_pdu::gr_tagged_stream_to_pdu (gr_pdu_vector_type t)
+ : gr_sync_block("tagged_stream_to_pdu",
+ gr_make_io_signature(1, 1, gr_pdu_itemsize(t)),
+ gr_make_io_signature(0, 0, 0)),
+ d_vectortype(t), d_itemsize(gr_pdu_itemsize(t)), d_inpdu(false),
+ d_pdu_meta(pmt::PMT_NIL), d_pdu_vector(pmt::PMT_NIL)
+{
+ message_port_register_out(pdu_port_id);
+}
+
+gr_tagged_stream_to_pdu::~gr_tagged_stream_to_pdu()
+{
+ printf("destructor running\n");
+}
+
+int
+gr_tagged_stream_to_pdu::work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ const uint8_t *in = (const uint8_t*) input_items[0];
+ uint64_t abs_N = nitems_read(0);
+
+ // if we are not in a pdu already, start a new one
+ if(!d_inpdu){
+ get_tags_in_range(d_tags, 0, abs_N, abs_N+1);
+ bool found_length_tag(false);
+ for(d_tags_itr = d_tags.begin(); (d_tags_itr != d_tags.end()) && (!found_length_tag); d_tags_itr++){
+ if( pmt::pmt_equal( (*d_tags_itr).key, pdu_length_tag ) ){
+ if( (*d_tags_itr).offset != abs_N ){
+ throw std::runtime_error("expected next pdu length tag on a different item...");
+ }
+ found_length_tag = true;
+ d_pdu_length = pmt::pmt_to_long( (*d_tags_itr).value );
+ d_pdu_remain = d_pdu_length;
+ d_pdu_meta = pmt::pmt_make_dict();
+ break;
+ } // if have length tag
+ } // iter over tags
+ if(!found_length_tag){
+ throw std::runtime_error("tagged stream does not contain a pdu_length tag!");
+ }
+ }
+
+ size_t ncopy = std::min((size_t)noutput_items, d_pdu_remain);
+
+ // copy any tags in this range into our meta object
+ get_tags_in_range(d_tags, 0, abs_N, abs_N+ncopy);
+ for(d_tags_itr = d_tags.begin(); d_tags_itr != d_tags.end(); d_tags_itr++){
+ if( ! pmt_equal( (*d_tags_itr).key, pdu_length_tag ) ){
+ d_pdu_meta = pmt_dict_add(d_pdu_meta, (*d_tags_itr).key, (*d_tags_itr).value);
+ }
+ }
+
+ // copy samples for this vector into either a pmt or our save buffer
+ if(ncopy == d_pdu_remain){ // we will send this pdu
+ if(d_save.size() == 0){
+ d_pdu_vector = gr_pdu_make_vector(d_vectortype, in, ncopy);
+ send_message();
+ } else {
+ size_t oldsize = d_save.size();
+ d_save.resize((oldsize + ncopy)*d_itemsize, 0);
+ memcpy( &d_save[oldsize*d_itemsize], in, ncopy*d_itemsize );
+ d_pdu_vector = gr_pdu_make_vector(d_vectortype, &d_save[0], d_pdu_length);
+ send_message();
+ d_save.clear();
+ }
+ } else {
+ d_inpdu = true;
+ size_t oldsize = d_save.size();
+ d_save.resize( (oldsize+ncopy)*d_itemsize );
+ memcpy( &d_save[oldsize*d_itemsize], in, ncopy*d_itemsize );
+ d_pdu_remain -= ncopy;
+ }
+
+ return ncopy;
+}
+
+void gr_tagged_stream_to_pdu::send_message(){
+
+ if(pmt::pmt_length(d_pdu_vector) != d_pdu_length){
+ throw std::runtime_error("msg length not correct");
+ }
+
+ pmt::pmt_t msg = pmt::pmt_cons( d_pdu_meta, d_pdu_vector );
+ message_port_pub( pdu_port_id, msg );
+
+ d_pdu_meta = pmt::PMT_NIL;
+ d_pdu_vector = pmt::PMT_NIL;
+ d_pdu_length = 0;
+ d_pdu_remain = 0;
+ d_inpdu = false;
+}
diff --git a/gnuradio-core/src/lib/io/gr_tagged_stream_to_pdu.h b/gnuradio-core/src/lib/io/gr_tagged_stream_to_pdu.h
new file mode 100644
index 000000000..c3fff3581
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_tagged_stream_to_pdu.h
@@ -0,0 +1,76 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_TAGGED_STREAM_TO_PDU_H
+#define INCLUDED_GR_TAGGED_STREAM_TO_PDU_H
+
+#include <gr_core_api.h>
+#include <gr_sync_block.h>
+#include <gr_message.h>
+#include <gr_msg_queue.h>
+#include <gr_pdu.h>
+
+class gr_tagged_stream_to_pdu;
+typedef boost::shared_ptr<gr_tagged_stream_to_pdu> gr_tagged_stream_to_pdu_sptr;
+
+GR_CORE_API gr_tagged_stream_to_pdu_sptr gr_make_tagged_stream_to_pdu (gr_pdu_vector_type t);
+
+/*!
+ * \brief Turn received messages into a stream
+ * \ingroup source_blk
+ */
+class GR_CORE_API gr_tagged_stream_to_pdu : public gr_sync_block
+{
+ private:
+ gr_pdu_vector_type d_vectortype;
+ size_t d_itemsize;
+
+ std::vector<uint8_t> d_save;
+
+ std::vector<gr_tag_t> d_tags;
+ std::vector<gr_tag_t>::iterator d_tags_itr;
+
+ bool d_inpdu;
+
+ size_t d_pdu_length;
+ size_t d_pdu_remain;
+ pmt::pmt_t d_pdu_meta;
+ pmt::pmt_t d_pdu_vector;
+
+ friend GR_CORE_API gr_tagged_stream_to_pdu_sptr
+ gr_make_tagged_stream_to_pdu(gr_pdu_vector_type t);
+
+ protected:
+ gr_tagged_stream_to_pdu (gr_pdu_vector_type t);
+
+ public:
+ ~gr_tagged_stream_to_pdu ();
+
+ int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+
+ void send_message();
+
+};
+
+#endif /* INCLUDED_GR_PDU_TO_TAGGED_SOURCE_H */
diff --git a/gnuradio-core/src/lib/io/gr_tagged_stream_to_pdu.i b/gnuradio-core/src/lib/io/gr_tagged_stream_to_pdu.i
new file mode 100644
index 000000000..f12987b74
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_tagged_stream_to_pdu.i
@@ -0,0 +1,31 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,tagged_stream_to_pdu);
+
+%{
+#include <gr_tagged_stream_to_pdu.h>
+%}
+
+%include <gr_tagged_stream_to_pdu.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
index 000000000..be131686b
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_trigger_mode.h
@@ -0,0 +1,38 @@
+/* -*- 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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_TRIGGER_MODE_H
+#define INCLUDED_GR_TRIGGER_MODE_H
+
+enum gr_trigger_mode {
+ gr_TRIG_MODE_FREE,
+ gr_TRIG_MODE_AUTO,
+ gr_TRIG_MODE_NORM,
+ gr_TRIG_MODE_STRIPCHART,
+};
+
+enum gr_trigger_slope {
+ gr_TRIG_SLOPE_POS,
+ gr_TRIG_SLOPE_NEG,
+};
+
+#endif /* INCLUDED_GR_TRIGGER_MODE_H */
diff --git a/gnuradio-core/src/lib/io/gr_tuntap_pdu.cc b/gnuradio-core/src/lib/io/gr_tuntap_pdu.cc
new file mode 100644
index 000000000..8dd4b18a1
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_tuntap_pdu.cc
@@ -0,0 +1,145 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_tuntap_pdu.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 <string.h>
+#include <iostream>
+#include <gr_pdu.h>
+#include <boost/format.hpp>
+
+#if (defined(linux) || defined(__linux) || defined(__linux__))
+
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#include <arpa/inet.h>
+#include <linux/if.h>
+
+
+// public constructor that returns a shared_ptr
+
+gr_tuntap_pdu_sptr
+gr_make_tuntap_pdu (std::string dev, int MTU)
+{
+ return gnuradio::get_initial_sptr(new gr_tuntap_pdu(dev, MTU));
+}
+
+gr_tuntap_pdu::gr_tuntap_pdu (std::string dev, int MTU)
+ : gr_stream_pdu_base(MTU)
+{
+
+ // make the tuntap
+ char dev_cstr[1024];
+ memset(dev_cstr, 0x00, 1024);
+ strncpy(dev_cstr, dev.c_str(), std::min(sizeof(dev_cstr), dev.size()));
+ d_fd = tun_alloc(dev_cstr);
+ if(d_fd <= 0){
+ throw std::runtime_error("TunTap make: tun_alloc failed (are you running as root?)");
+ }
+
+ std::cout << boost::format(
+ "Allocated virtual ethernet interface: %s\n"
+ "You must now use ifconfig to set its IP address. E.g.,\n"
+ " $ sudo ifconfig %s 192.168.200.1\n"
+ "Be sure to use a different address in the same subnet for each machine.\n"
+ ) % dev % dev << std::endl;
+
+ // set up output message port
+ message_port_register_out(pmt::mp("pdus"));
+ start_rxthread(pmt::mp("pdus"));
+
+ // set up input message port
+ message_port_register_in(pmt::mp("pdus"));
+ set_msg_handler(pmt::mp("pdus"), boost::bind(&gr_tuntap_pdu::send, this, _1));
+}
+
+
+int gr_tuntap_pdu::tun_alloc(char *dev, int flags) {
+ struct ifreq ifr;
+ int fd, err;
+ const char *clonedev = "/dev/net/tun";
+
+ /* Arguments taken by the function:
+ *
+ * char *dev: the name of an interface (or '\0'). MUST have enough
+ * space to hold the interface name if '\0' is passed
+ * int flags: interface flags (eg, IFF_TUN etc.)
+ */
+
+ /* open the clone device */
+ if( (fd = open(clonedev, O_RDWR)) < 0 ) {
+ return fd;
+ }
+
+ /* preparation of the struct ifr, of type "struct ifreq" */
+ memset(&ifr, 0, sizeof(ifr));
+
+ ifr.ifr_flags = flags; /* IFF_TUN or IFF_TAP, plus maybe IFF_NO_PI */
+
+ if (*dev) {
+ /* if a device name was specified, put it in the structure; otherwise,
+ * the kernel will try to allocate the "next" device of the
+ * specified type */
+ strncpy(ifr.ifr_name, dev, IFNAMSIZ);
+ }
+
+ /* try to create the device */
+ if( (err = ioctl(fd, TUNSETIFF, (void *) &ifr)) < 0 ) {
+ close(fd);
+ return err;
+ }
+
+ /* if the operation was successful, write back the name of the
+ * interface to the variable "dev", so the caller can know
+ * it. Note that the caller MUST reserve space in *dev (see calling
+ * code below) */
+ strcpy(dev, ifr.ifr_name);
+
+ /* this is the special file descriptor that the caller will use to talk
+ * with the virtual interface */
+ return fd;
+}
+
+#else //if not linux
+
+gr_block_sptr
+gr_make_tuntap_pdu(std::string dev, int MTU)
+{
+ gr_block_sptr rv;
+ throw std::runtime_error("tuntap only implemented on linux");
+ return rv;
+}
+
+#endif
diff --git a/gnuradio-core/src/lib/io/gr_tuntap_pdu.h b/gnuradio-core/src/lib/io/gr_tuntap_pdu.h
new file mode 100644
index 000000000..18c83f42b
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_tuntap_pdu.h
@@ -0,0 +1,74 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_TUNTAP_PDU_H
+#define INCLUDED_GR_TUNTAP_PDU_H
+
+#include <gr_core_api.h>
+#include <gr_sync_block.h>
+#include <gr_message.h>
+#include <gr_msg_queue.h>
+#include <gr_stream_pdu_base.h>
+
+#if (defined(linux) || defined(__linux) || defined(__linux__))
+
+#include <linux/if_tun.h>
+
+class gr_tuntap_pdu;
+typedef boost::shared_ptr<gr_tuntap_pdu> gr_tuntap_pdu_sptr;
+
+GR_CORE_API gr_tuntap_pdu_sptr gr_make_tuntap_pdu (std::string dev, int MTU=10000);
+
+/*!
+ * \brief Gather received items into messages and insert into msgq
+ * \ingroup sink_blk
+ */
+class GR_CORE_API gr_tuntap_pdu : public gr_stream_pdu_base
+{
+ private:
+ friend GR_CORE_API gr_tuntap_pdu_sptr
+ gr_make_tuntap_pdu(std::string dev, int MTU);
+ int tun_alloc(char* dev, int flags = IFF_TAP | IFF_NO_PI);
+ std::string d_dev;
+ protected:
+ gr_tuntap_pdu (std::string dev, int MTU=10000);
+
+ public:
+ ~gr_tuntap_pdu () {}
+
+};
+
+#else // if not linux
+
+class gr_tuntap_pdu
+{
+private:
+ gr_tuntap_pdu() {};
+public:
+ ~gr_tuntap_pdu() {};
+};
+
+GR_CORE_API gr_block_sptr gr_make_tuntap_pdu (std::string dev, int MTU=0);
+
+#endif
+
+#endif /* INCLUDED_GR_TUNTAP_PDU_H */
diff --git a/gnuradio-core/src/lib/io/gr_tuntap_pdu.i b/gnuradio-core/src/lib/io/gr_tuntap_pdu.i
new file mode 100644
index 000000000..589bbc385
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_tuntap_pdu.i
@@ -0,0 +1,30 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,tuntap_pdu);
+
+%{
+#include <gr_tuntap_pdu.h>
+%}
+
+%include "gr_tuntap_pdu.h"
+
diff --git a/gnuradio-core/src/lib/io/gr_udp_sink.cc b/gnuradio-core/src/lib/io/gr_udp_sink.cc
new file mode 100644
index 000000000..6b1d34ef7
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_udp_sink.cc
@@ -0,0 +1,304 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007,2008,2009,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <boost/asio.hpp>
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include <gr_udp_sink.h>
+#include <gr_io_signature.h>
+#include <stdexcept>
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#if defined(HAVE_NETDB_H)
+#include <netdb.h>
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h> //usually included by <netdb.h>?
+#endif
+typedef void* optval_t;
+#elif defined(HAVE_WINDOWS_H)
+// if not posix, assume winsock
+#define USING_WINSOCK
+#include <winsock2.h>
+#include <ws2tcpip.h>
+#define SHUT_RDWR 2
+typedef char* optval_t;
+#endif
+
+#include <gruel/thread.h>
+
+#define SNK_VERBOSE 0
+
+static int is_error( int perr )
+{
+ // Compare error to posix error code; return nonzero if match.
+#if defined(USING_WINSOCK)
+#define ENOPROTOOPT 109
+#define ECONNREFUSED 111
+ // All codes to be checked for must be defined below
+ int werr = WSAGetLastError();
+ switch( werr ) {
+ case WSAETIMEDOUT:
+ return( perr == EAGAIN );
+ case WSAENOPROTOOPT:
+ return( perr == ENOPROTOOPT );
+ case WSAECONNREFUSED:
+ return( perr == ECONNREFUSED );
+ default:
+ fprintf(stderr,"gr_udp_source/is_error: unknown error %d\n", perr );
+ throw std::runtime_error("internal error");
+ }
+ return 0;
+#else
+ return( perr == errno );
+#endif
+}
+
+static void report_error( const char *msg1, const char *msg2 )
+{
+ // Deal with errors, both posix and winsock
+#if defined(USING_WINSOCK)
+ int werr = WSAGetLastError();
+ fprintf(stderr, "%s: winsock error %d\n", msg1, werr );
+#else
+ perror(msg1);
+#endif
+ if( msg2 != NULL )
+ throw std::runtime_error(msg2);
+ return;
+}
+
+gr_udp_sink::gr_udp_sink (size_t itemsize,
+ const char *host, unsigned short port,
+ int payload_size, bool eof)
+ : gr_sync_block ("udp_sink",
+ gr_make_io_signature (1, 1, itemsize),
+ gr_make_io_signature (0, 0, 0)),
+ d_itemsize (itemsize), d_payload_size(payload_size), d_eof(eof),
+ d_socket(-1), d_connected(false)
+{
+#if defined(USING_WINSOCK) // for Windows (with MinGW)
+ // initialize winsock DLL
+ WSADATA wsaData;
+ int iResult = WSAStartup( MAKEWORD(2,2), &wsaData );
+ if( iResult != NO_ERROR ) {
+ report_error( "gr_udp_source WSAStartup", "can't open socket" );
+ }
+#endif
+
+ // create socket
+ d_socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
+ if(d_socket == -1) {
+ report_error("socket open","can't open socket");
+ }
+
+ // Don't wait when shutting down
+ linger lngr;
+ lngr.l_onoff = 1;
+ lngr.l_linger = 0;
+ if(setsockopt(d_socket, SOL_SOCKET, SO_LINGER, (optval_t)&lngr, sizeof(linger)) == -1) {
+ if( !is_error(ENOPROTOOPT) ) { // no SO_LINGER for SOCK_DGRAM on Windows
+ report_error("SO_LINGER","can't set socket option SO_LINGER");
+ }
+ }
+
+ // Get the destination address
+ connect(host, port);
+}
+
+// public constructor that returns a shared_ptr
+
+gr_udp_sink_sptr
+gr_make_udp_sink (size_t itemsize,
+ const char *host, unsigned short port,
+ int payload_size, bool eof)
+{
+ return gnuradio::get_initial_sptr(new gr_udp_sink (itemsize,
+ host, port,
+ payload_size, eof));
+}
+
+gr_udp_sink::~gr_udp_sink ()
+{
+ if (d_connected)
+ disconnect();
+
+ if (d_socket != -1){
+ shutdown(d_socket, SHUT_RDWR);
+#if defined(USING_WINSOCK)
+ closesocket(d_socket);
+#else
+ ::close(d_socket);
+#endif
+ d_socket = -1;
+ }
+
+#if defined(USING_WINSOCK) // for Windows (with MinGW)
+ // free winsock resources
+ WSACleanup();
+#endif
+}
+
+int
+gr_udp_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];
+ ssize_t r=0, bytes_sent=0, bytes_to_send=0;
+ ssize_t total_size = noutput_items*d_itemsize;
+
+ #if SNK_VERBOSE
+ printf("Entered udp_sink\n");
+ #endif
+
+ gruel::scoped_lock guard(d_mutex); // protect d_socket
+
+ while(bytes_sent < total_size) {
+ bytes_to_send = std::min((ssize_t)d_payload_size, (total_size-bytes_sent));
+
+ if(d_connected) {
+ r = send(d_socket, (in+bytes_sent), bytes_to_send, 0);
+ if(r == -1) { // error on send command
+ if( is_error(ECONNREFUSED) )
+ r = bytes_to_send; // discard data until receiver is started
+ else {
+ report_error("udp_sink",NULL); // there should be no error case where
+ return -1; // this function should not exit immediately
+ }
+ }
+ }
+ else
+ r = bytes_to_send; // discarded for lack of connection
+ bytes_sent += r;
+
+ #if SNK_VERBOSE
+ printf("\tbyte sent: %d bytes\n", r);
+ #endif
+ }
+
+ #if SNK_VERBOSE
+ printf("Sent: %d bytes (noutput_items: %d)\n", bytes_sent, noutput_items);
+ #endif
+
+ return noutput_items;
+}
+
+void gr_udp_sink::connect( const char *host, unsigned short port )
+{
+ if(d_connected)
+ disconnect();
+
+ if(host != NULL ) {
+ // Get the destination address
+ struct addrinfo *ip_dst;
+ struct addrinfo hints;
+ memset( (void*)&hints, 0, sizeof(hints) );
+ hints.ai_family = AF_INET;
+ hints.ai_socktype = SOCK_DGRAM;
+ hints.ai_protocol = IPPROTO_UDP;
+ char port_str[12];
+ sprintf( port_str, "%d", port );
+
+ // FIXME leaks if report_error throws below
+ int ret = getaddrinfo( host, port_str, &hints, &ip_dst );
+ if( ret != 0 )
+ report_error("gr_udp_source/getaddrinfo",
+ "can't initialize destination socket" );
+
+ // don't need d_mutex lock when !d_connected
+ if(::connect(d_socket, ip_dst->ai_addr, ip_dst->ai_addrlen) == -1) {
+ report_error("socket connect","can't connect to socket");
+ }
+ d_connected = true;
+
+ freeaddrinfo(ip_dst);
+ }
+
+ return;
+}
+
+void gr_udp_sink::disconnect()
+{
+ if(!d_connected)
+ return;
+
+ #if SNK_VERBOSE
+ printf("gr_udp_sink disconnecting\n");
+ #endif
+
+ gruel::scoped_lock guard(d_mutex); // protect d_socket from work()
+
+ // Send a few zero-length packets to signal receiver we are done
+ if(d_eof) {
+ int i;
+ for( i = 0; i < 3; i++ )
+ (void) send( d_socket, NULL, 0, 0 ); // ignore errors
+ }
+
+ // Sending EOF can produce ERRCONNREFUSED errors that won't show up
+ // until the next send or recv, which might confuse us if it happens
+ // on a new connection. The following does a nonblocking recv to
+ // clear any such errors.
+ timeval timeout;
+ timeout.tv_sec = 0; // zero time for immediate return
+ timeout.tv_usec = 0;
+ fd_set readfds;
+ FD_ZERO(&readfds);
+ FD_SET(d_socket, &readfds);
+ int r = select(FD_SETSIZE, &readfds, NULL, NULL, &timeout);
+ if(r < 0) {
+ #if SNK_VERBOSE
+ report_error("udp_sink/select",NULL);
+ #endif
+ }
+ else if(r > 0) { // call recv() to get error return
+ r = recv(d_socket, (char*)&readfds, sizeof(readfds), 0);
+ if(r < 0) {
+ #if SNK_VERBOSE
+ report_error("udp_sink/recv",NULL);
+ #endif
+ }
+ }
+
+ // Since I can't find any way to disconnect a datagram socket in Cygwin,
+ // we just leave it connected but disable sending.
+#if 0
+ // zeroed address structure should reset connection
+ struct sockaddr addr;
+ memset( (void*)&addr, 0, sizeof(addr) );
+ // addr.sa_family = AF_UNSPEC; // doesn't work on Cygwin
+ // addr.sa_family = AF_INET; // doesn't work on Cygwin
+
+ if(::connect(d_socket, &addr, sizeof(addr)) == -1)
+ report_error("socket connect","can't connect to socket");
+#endif
+
+ d_connected = false;
+
+ return;
+}
diff --git a/gnuradio-core/src/lib/io/gr_udp_sink.h b/gnuradio-core/src/lib/io/gr_udp_sink.h
new file mode 100644
index 000000000..bf042a6d1
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_udp_sink.h
@@ -0,0 +1,112 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007,2008,2009,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_UDP_SINK_H
+#define INCLUDED_GR_UDP_SINK_H
+
+#include <gr_core_api.h>
+#include <gr_sync_block.h>
+#include <gruel/thread.h>
+
+class gr_udp_sink;
+typedef boost::shared_ptr<gr_udp_sink> gr_udp_sink_sptr;
+
+GR_CORE_API gr_udp_sink_sptr
+gr_make_udp_sink (size_t itemsize,
+ const char *host, unsigned short port,
+ int payload_size=1472, bool eof=true);
+
+/*!
+ * \brief Write stream to an UDP socket.
+ * \ingroup sink_blk
+ *
+ * \param itemsize The size (in bytes) of the item datatype
+ * \param host The name or IP address of the receiving host; use
+ * NULL or None for no connection
+ * \param port Destination port to connect to on receiving host
+ * \param payload_size UDP payload size by default set to 1472 =
+ * (1500 MTU - (8 byte UDP header) - (20 byte IP header))
+ * \param eof Send zero-length packet on disconnect
+ */
+
+class GR_CORE_API gr_udp_sink : public gr_sync_block
+{
+ friend GR_CORE_API gr_udp_sink_sptr gr_make_udp_sink (size_t itemsize,
+ const char *host,
+ unsigned short port,
+ int payload_size, bool eof);
+ private:
+ size_t d_itemsize;
+
+ int d_payload_size; // maximum transmission unit (packet length)
+ bool d_eof; // send zero-length packet on disconnect
+ int d_socket; // handle to socket
+ bool d_connected; // are we connected?
+ gruel::mutex d_mutex; // protects d_socket and d_connected
+
+ protected:
+ /*!
+ * \brief UDP Sink Constructor
+ *
+ * \param itemsize The size (in bytes) of the item datatype
+ * \param host The name or IP address of the receiving host; use
+ * NULL or None for no connection
+ * \param port Destination port to connect to on receiving host
+ * \param payload_size UDP payload size by default set to
+ * 1472 = (1500 MTU - (8 byte UDP header) - (20 byte IP header))
+ * \param eof Send zero-length packet on disconnect
+ */
+ gr_udp_sink (size_t itemsize,
+ const char *host, unsigned short port,
+ int payload_size, bool eof);
+
+ public:
+ ~gr_udp_sink ();
+
+ /*! \brief return the PAYLOAD_SIZE of the socket */
+ int payload_size() { return d_payload_size; }
+
+ /*! \brief Change the connection to a new destination
+ *
+ * \param host The name or IP address of the receiving host; use
+ * NULL or None to break the connection without closing
+ * \param port Destination port to connect to on receiving host
+ *
+ * Calls disconnect() to terminate any current connection first.
+ */
+ void connect( const char *host, unsigned short port );
+
+ /*! \brief Send zero-length packet (if eof is requested) then stop sending
+ *
+ * Zero-byte packets can be interpreted as EOF by gr_udp_source. Note that
+ * disconnect occurs automatically when the sink is destroyed, but not when
+ * its top_block stops.*/
+ void disconnect();
+
+ // should we export anything else?
+
+ int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+#endif /* INCLUDED_GR_UDP_SINK_H */
diff --git a/gnuradio-core/src/lib/io/gr_udp_sink.i b/gnuradio-core/src/lib/io/gr_udp_sink.i
new file mode 100644
index 000000000..ba7043937
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_udp_sink.i
@@ -0,0 +1,46 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+
+GR_SWIG_BLOCK_MAGIC(gr,udp_sink)
+
+gr_udp_sink_sptr
+gr_make_udp_sink (size_t itemsize,
+ const char *host, unsigned short port,
+ int payload_size=1472, bool eof=true) throw (std::runtime_error);
+
+class gr_udp_sink : public gr_sync_block
+{
+ protected:
+ gr_udp_sink (size_t itemsize,
+ const char *host, unsigned short port,
+ int payload_size, bool eof)
+ throw (std::runtime_error);
+
+ public:
+ ~gr_udp_sink ();
+
+ int payload_size() { return d_payload_size; }
+ void connect( const char *host, unsigned short port );
+ void disconnect();
+
+};
diff --git a/gnuradio-core/src/lib/io/gr_udp_source.cc b/gnuradio-core/src/lib/io/gr_udp_source.cc
new file mode 100644
index 000000000..eca8e89d0
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_udp_source.cc
@@ -0,0 +1,374 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007,2008,2009,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include <gr_udp_source.h>
+#include <gr_io_signature.h>
+#include <stdexcept>
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+
+#if defined(HAVE_NETDB_H)
+#include <netdb.h>
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+typedef void* optval_t;
+
+// ntohs() on FreeBSD may require both netinet/in.h and arpa/inet.h, in order
+#if defined(HAVE_NETINET_IN_H)
+#include <netinet/in.h>
+#endif
+#if defined(HAVE_ARPA_INET_H)
+#include <arpa/inet.h>
+#endif
+
+#elif defined(HAVE_WINDOWS_H)
+// if not posix, assume winsock
+#define USING_WINSOCK
+#include <winsock2.h>
+#include <ws2tcpip.h>
+#define SHUT_RDWR 2
+typedef char* optval_t;
+#endif
+
+#define USE_SELECT 1 // non-blocking receive on all platforms
+#define USE_RCV_TIMEO 0 // non-blocking receive on all but Cygwin
+#define SRC_VERBOSE 0
+
+static int is_error( int perr )
+{
+ // Compare error to posix error code; return nonzero if match.
+#if defined(USING_WINSOCK)
+#define ENOPROTOOPT 109
+ // All codes to be checked for must be defined below
+ int werr = WSAGetLastError();
+ switch( werr ) {
+ case WSAETIMEDOUT:
+ return( perr == EAGAIN );
+ case WSAENOPROTOOPT:
+ return( perr == ENOPROTOOPT );
+ default:
+ fprintf(stderr,"gr_udp_source/is_error: unknown error %d\n", perr );
+ throw std::runtime_error("internal error");
+ }
+ return 0;
+#else
+ return( perr == errno );
+#endif
+}
+
+static void report_error( const char *msg1, const char *msg2 )
+{
+ // Deal with errors, both posix and winsock
+#if defined(USING_WINSOCK)
+ int werr = WSAGetLastError();
+ fprintf(stderr, "%s: winsock error %d\n", msg1, werr );
+#else
+ perror(msg1);
+#endif
+ if( msg2 != NULL )
+ throw std::runtime_error(msg2);
+ return;
+}
+
+gr_udp_source::gr_udp_source(size_t itemsize, const char *host,
+ unsigned short port, int payload_size,
+ bool eof, bool wait)
+ : gr_sync_block ("udp_source",
+ gr_make_io_signature(0, 0, 0),
+ gr_make_io_signature(1, 1, itemsize)),
+ d_itemsize(itemsize), d_payload_size(payload_size),
+ d_eof(eof), d_wait(wait), d_socket(-1), d_residual(0), d_temp_offset(0)
+{
+ int ret = 0;
+
+#if defined(USING_WINSOCK) // for Windows (with MinGW)
+ // initialize winsock DLL
+ WSADATA wsaData;
+ int iResult = WSAStartup( MAKEWORD(2,2), &wsaData );
+ if( iResult != NO_ERROR ) {
+ report_error( "gr_udp_source WSAStartup", "can't open socket" );
+ }
+#endif
+
+ // Set up the address stucture for the source address and port numbers
+ // Get the source IP address from the host name
+ struct addrinfo *ip_src; // store the source IP address to use
+ struct addrinfo hints;
+ memset( (void*)&hints, 0, sizeof(hints) );
+ hints.ai_family = AF_INET;
+ hints.ai_socktype = SOCK_DGRAM;
+ hints.ai_protocol = IPPROTO_UDP;
+ hints.ai_flags = AI_PASSIVE;
+ char port_str[12];
+ sprintf( port_str, "%d", port );
+
+ // FIXME leaks if report_error throws below
+ ret = getaddrinfo( host, port_str, &hints, &ip_src );
+ if( ret != 0 )
+ report_error("gr_udp_source/getaddrinfo",
+ "can't initialize source socket" );
+
+ // FIXME leaks if report_error throws below
+ d_temp_buff = new char[d_payload_size]; // allow it to hold up to payload_size bytes
+
+ // create socket
+ d_socket = socket(ip_src->ai_family, ip_src->ai_socktype,
+ ip_src->ai_protocol);
+ if(d_socket == -1) {
+ report_error("socket open","can't open socket");
+ }
+
+ // Turn on reuse address
+ int opt_val = 1;
+ if(setsockopt(d_socket, SOL_SOCKET, SO_REUSEADDR, (optval_t)&opt_val, sizeof(int)) == -1) {
+ report_error("SO_REUSEADDR","can't set socket option SO_REUSEADDR");
+ }
+
+ // Don't wait when shutting down
+ linger lngr;
+ lngr.l_onoff = 1;
+ lngr.l_linger = 0;
+ if(setsockopt(d_socket, SOL_SOCKET, SO_LINGER, (optval_t)&lngr, sizeof(linger)) == -1) {
+ if( !is_error(ENOPROTOOPT) ) { // no SO_LINGER for SOCK_DGRAM on Windows
+ report_error("SO_LINGER","can't set socket option SO_LINGER");
+ }
+ }
+
+#if USE_RCV_TIMEO
+ // Set a timeout on the receive function to not block indefinitely
+ // This value can (and probably should) be changed
+ // Ignored on Cygwin
+#if defined(USING_WINSOCK)
+ DWORD timeout = 1000; // milliseconds
+#else
+ timeval timeout;
+ timeout.tv_sec = 1;
+ timeout.tv_usec = 0;
+#endif
+ if(setsockopt(d_socket, SOL_SOCKET, SO_RCVTIMEO, (optval_t)&timeout, sizeof(timeout)) == -1) {
+ report_error("SO_RCVTIMEO","can't set socket option SO_RCVTIMEO");
+ }
+#endif // USE_RCV_TIMEO
+
+ // bind socket to an address and port number to listen on
+ if(bind (d_socket, ip_src->ai_addr, ip_src->ai_addrlen) == -1) {
+ report_error("socket bind","can't bind socket");
+ }
+ freeaddrinfo(ip_src);
+
+}
+
+gr_udp_source_sptr
+gr_make_udp_source (size_t itemsize, const char *ipaddr,
+ unsigned short port, int payload_size, bool eof, bool wait)
+{
+ return gnuradio::get_initial_sptr(new gr_udp_source (itemsize, ipaddr,
+ port, payload_size, eof, wait));
+}
+
+gr_udp_source::~gr_udp_source ()
+{
+ delete [] d_temp_buff;
+
+ if (d_socket != -1){
+ shutdown(d_socket, SHUT_RDWR);
+#if defined(USING_WINSOCK)
+ closesocket(d_socket);
+#else
+ ::close(d_socket);
+#endif
+ d_socket = -1;
+ }
+
+#if defined(USING_WINSOCK) // for Windows (with MinGW)
+ // free winsock resources
+ WSACleanup();
+#endif
+}
+
+int
+gr_udp_source::work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ char *out = (char *) output_items[0];
+ ssize_t r=0, nbytes=0, bytes_received=0;
+ ssize_t total_bytes = (ssize_t)(d_itemsize*noutput_items);
+
+ #if SRC_VERBOSE
+ printf("\nEntered udp_source\n");
+ #endif
+
+ // Remove items from temp buffer if they are in there
+ if(d_residual) {
+ nbytes = std::min(d_residual, total_bytes);
+ memcpy(out, d_temp_buff+d_temp_offset, nbytes);
+ bytes_received = nbytes;
+
+ #if SRC_VERBOSE
+ printf("\tTemp buff size: %d offset: %d (bytes_received: %d) (noutput_items: %d)\n",
+ d_residual, d_temp_offset, bytes_received, noutput_items);
+ #endif
+
+ // Increment pointer
+ out += bytes_received;
+
+ // Update indexing of amount of bytes left in the buffer
+ d_residual -= nbytes;
+ d_temp_offset += nbytes;
+
+ // Return now with what we've got.
+ assert(nbytes % d_itemsize == 0);
+ return nbytes/d_itemsize;
+ }
+
+ while(1) {
+ // get the data into our output buffer and record the number of bytes
+
+#if USE_SELECT
+ // RCV_TIMEO doesn't work on all systems (e.g., Cygwin)
+ // use select() instead of, or in addition to RCV_TIMEO
+ fd_set readfds;
+ timeval timeout;
+ timeout.tv_sec = 1; // Init timeout each iteration. Select can modify it.
+ timeout.tv_usec = 0;
+ FD_ZERO(&readfds);
+ FD_SET(d_socket, &readfds);
+ r = select(FD_SETSIZE, &readfds, NULL, NULL, &timeout);
+ if(r < 0) {
+ report_error("udp_source/select",NULL);
+ return -1;
+ }
+ else if(r == 0 ) { // timed out
+ if( d_wait ) {
+ // Allow boost thread interrupt, then try again
+ //boost::this_thread::interruption_point();
+ //continue;
+ return 0;
+ }
+ else
+ return -1;
+ }
+#endif // USE_SELECT
+
+ // This is a non-blocking call with a timeout set in the constructor
+ r = recv(d_socket, d_temp_buff, d_payload_size, 0); // get the entire payload or the what's available
+
+ // If r > 0, round it down to a multiple of d_itemsize
+ // (If sender is broken, don't propagate problem)
+ if (r > 0)
+ r = (r/d_itemsize) * d_itemsize;
+
+ // Check if there was a problem; forget it if the operation just timed out
+ if(r == -1) {
+ if( is_error(EAGAIN) ) { // handle non-blocking call timeout
+ #if SRC_VERBOSE
+ printf("UDP receive timed out\n");
+ #endif
+
+ if( d_wait ) {
+ // Allow boost thread interrupt, then try again
+ //boost::this_thread::interruption_point();
+ //continue;
+ return 0;
+ }
+ else
+ return -1;
+ }
+ else {
+ report_error("udp_source/recv",NULL);
+ return -1;
+ }
+ }
+ else if(r==0) {
+ if(d_eof) {
+ // zero-length packet interpreted as EOF
+
+ #if SNK_VERBOSE
+ printf("\tzero-length packet received; returning EOF\n");
+ #endif
+
+ return -1;
+ }
+ else{
+ // do we need to allow boost thread interrupt?
+ boost::this_thread::interruption_point();
+ continue;
+ }
+ }
+ else {
+ // Calculate the number of bytes we can take from the buffer in this call
+ nbytes = std::min(r, total_bytes-bytes_received);
+
+ // adjust the total number of bytes we have to round down to nearest integer of an itemsize
+ nbytes -= ((bytes_received+nbytes) % d_itemsize);
+
+ // copy the number of bytes we want to look at here
+ memcpy(out, d_temp_buff, nbytes);
+
+ d_residual = r - nbytes; // save the number of bytes stored
+ d_temp_offset=nbytes; // reset buffer index
+
+ // keep track of the total number of bytes received
+ bytes_received += nbytes;
+
+ // increment the pointer
+ out += nbytes;
+
+ // Immediately return when data comes in
+ break;
+ }
+
+ #if SNK_VERBOSE
+ printf("\tbytes received: %d bytes (nbytes: %d)\n", bytes, nbytes);
+ #endif
+ }
+
+ #if SRC_VERBOSE
+ printf("Total Bytes Received: %d (bytes_received / noutput_items = %d / %d)\n",
+ bytes_received, bytes_received, noutput_items);
+ #endif
+
+ // bytes_received is already set to some integer multiple of itemsize
+ return bytes_received/d_itemsize;
+}
+
+// Return port number of d_socket
+int gr_udp_source::get_port(void)
+{
+ sockaddr_in name;
+ socklen_t len = sizeof(name);
+ int ret = getsockname( d_socket, (sockaddr*)&name, &len );
+ if( ret ) {
+ report_error("gr_udp_source/getsockname",NULL);
+ return -1;
+ }
+ return ntohs(name.sin_port);
+}
diff --git a/gnuradio-core/src/lib/io/gr_udp_source.h b/gnuradio-core/src/lib/io/gr_udp_source.h
new file mode 100644
index 000000000..56dcb3c0a
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_udp_source.h
@@ -0,0 +1,110 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007,2008,2009,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_UDP_SOURCE_H
+#define INCLUDED_GR_UDP_SOURCE_H
+
+#include <gr_core_api.h>
+#include <gr_sync_block.h>
+#include <gruel/thread.h>
+
+class gr_udp_source;
+typedef boost::shared_ptr<gr_udp_source> gr_udp_source_sptr;
+
+GR_CORE_API gr_udp_source_sptr gr_make_udp_source(size_t itemsize, const char *host,
+ unsigned short port,
+ int payload_size=1472,
+ bool eof=true, bool wait=true);
+
+/*!
+ * \brief Read stream from an UDP socket.
+ * \ingroup source_blk
+ *
+ * \param itemsize The size (in bytes) of the item datatype
+ * \param host The name or IP address of the receiving host; can be
+ * NULL, None, or "0.0.0.0" to allow reading from any
+ * interface on the host
+ * \param port The port number on which to receive data; use 0 to
+ * have the system assign an unused port number
+ * \param payload_size UDP payload size by default set to 1472 =
+ * (1500 MTU - (8 byte UDP header) - (20 byte IP header))
+ * \param eof Interpret zero-length packet as EOF (default: true)
+ * \param wait Wait for data if not immediately available
+ * (default: true)
+ *
+*/
+
+class GR_CORE_API gr_udp_source : public gr_sync_block
+{
+ friend GR_CORE_API gr_udp_source_sptr gr_make_udp_source(size_t itemsize,
+ const char *host,
+ unsigned short port,
+ int payload_size,
+ bool eof, bool wait);
+
+ private:
+ size_t d_itemsize;
+ int d_payload_size; // maximum transmission unit (packet length)
+ bool d_eof; // zero-length packet is EOF
+ bool d_wait; // wait if data if not immediately available
+ int d_socket; // handle to socket
+ char *d_temp_buff; // hold buffer between calls
+ ssize_t d_residual; // hold information about number of bytes stored in the temp buffer
+ size_t d_temp_offset; // point to temp buffer location offset
+
+ protected:
+ /*!
+ * \brief UDP Source Constructor
+ *
+ * \param itemsize The size (in bytes) of the item datatype
+ * \param host The name or IP address of the receiving host; can be
+ * NULL, None, or "0.0.0.0" to allow reading from any
+ * interface on the host
+ * \param port The port number on which to receive data; use 0 to
+ * have the system assign an unused port number
+ * \param payload_size UDP payload size by default set to 1472 =
+ * (1500 MTU - (8 byte UDP header) - (20 byte IP header))
+ * \param eof Interpret zero-length packet as EOF (default: true)
+ * \param wait Wait for data if not immediately available
+ * (default: true)
+ */
+ gr_udp_source(size_t itemsize, const char *host, unsigned short port,
+ int payload_size, bool eof, bool wait);
+
+ public:
+ ~gr_udp_source();
+
+ /*! \brief return the PAYLOAD_SIZE of the socket */
+ int payload_size() { return d_payload_size; }
+
+ /*! \brief return the port number of the socket */
+ int get_port();
+
+ // should we export anything else?
+
+ int work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+
+#endif /* INCLUDED_GR_UDP_SOURCE_H */
diff --git a/gnuradio-core/src/lib/io/gr_udp_source.i b/gnuradio-core/src/lib/io/gr_udp_source.i
new file mode 100644
index 000000000..18823a356
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_udp_source.i
@@ -0,0 +1,41 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,udp_source)
+
+gr_udp_source_sptr
+gr_make_udp_source (size_t itemsize, const char *host,
+ unsigned short port, int payload_size=1472,
+ bool eof=true, bool wait=true) throw (std::runtime_error);
+
+class gr_udp_source : public gr_sync_block
+{
+ protected:
+ gr_udp_source (size_t itemsize, const char *host,
+ unsigned short port, int payload_size, bool eof, bool wait) throw (std::runtime_error);
+
+ public:
+ ~gr_udp_source ();
+
+ int payload_size() { return d_payload_size; }
+ int get_port();
+};
diff --git a/gnuradio-core/src/lib/io/gr_wavfile_sink.cc b/gnuradio-core/src/lib/io/gr_wavfile_sink.cc
new file mode 100644
index 000000000..8526032f6
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_wavfile_sink.cc
@@ -0,0 +1,280 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2006,2007,2008,2009,2010,2011 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_wavfile_sink.h>
+#include <gr_io_signature.h>
+#include <gri_wavfile.h>
+#include <stdexcept>
+#include <climits>
+#include <cstring>
+#include <cmath>
+#include <fcntl.h>
+#include <gruel/thread.h>
+#include <boost/math/special_functions/round.hpp>
+
+// 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_wavfile_sink_sptr
+gr_make_wavfile_sink(const char *filename,
+ int n_channels,
+ unsigned int sample_rate,
+ int bits_per_sample)
+{
+ return gnuradio::get_initial_sptr(new gr_wavfile_sink (filename,
+ n_channels,
+ sample_rate,
+ bits_per_sample));
+}
+
+gr_wavfile_sink::gr_wavfile_sink(const char *filename,
+ int n_channels,
+ unsigned int sample_rate,
+ int bits_per_sample)
+ : gr_sync_block ("wavfile_sink",
+ gr_make_io_signature(1, n_channels, sizeof(float)),
+ gr_make_io_signature(0, 0, 0)),
+ d_sample_rate(sample_rate), d_nchans(n_channels),
+ d_fp(0), d_new_fp(0), d_updated(false)
+{
+ if (bits_per_sample != 8 && bits_per_sample != 16) {
+ throw std::runtime_error("Invalid bits per sample (supports 8 and 16)");
+ }
+ d_bytes_per_sample = bits_per_sample / 8;
+ d_bytes_per_sample_new = d_bytes_per_sample;
+
+ if (!open(filename)) {
+ throw std::runtime_error ("can't open file");
+ }
+
+ if (bits_per_sample == 8) {
+ d_max_sample_val = 0xFF;
+ d_min_sample_val = 0;
+ d_normalize_fac = d_max_sample_val/2;
+ d_normalize_shift = 1;
+ } else {
+ d_max_sample_val = 0x7FFF;
+ d_min_sample_val = -0x7FFF;
+ d_normalize_fac = d_max_sample_val;
+ d_normalize_shift = 0;
+ if (bits_per_sample != 16) {
+ fprintf(stderr, "Invalid bits per sample value requested, using 16");
+ }
+ }
+}
+
+
+bool
+gr_wavfile_sink::open(const char* filename)
+{
+ gruel::scoped_lock guard(d_mutex);
+
+ // 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(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.
+ return false;
+ }
+ d_updated = true;
+
+ if (!gri_wavheader_write(d_new_fp,
+ d_sample_rate,
+ d_nchans,
+ d_bytes_per_sample_new)) {
+ fprintf(stderr, "[%s] could not write to WAV file\n", __FILE__);
+ exit(-1);
+ }
+
+ return true;
+}
+
+
+void
+gr_wavfile_sink::close()
+{
+ gruel::scoped_lock guard(d_mutex);
+
+ if (!d_fp)
+ return;
+
+ close_wav();
+}
+
+void gr_wavfile_sink::close_wav()
+{
+ unsigned int byte_count = d_sample_count * d_bytes_per_sample;
+
+ gri_wavheader_complete(d_fp, byte_count);
+
+ fclose(d_fp);
+ d_fp = NULL;
+}
+
+
+gr_wavfile_sink::~gr_wavfile_sink ()
+{
+ if (d_new_fp) {
+ fclose(d_new_fp);
+ }
+
+ close();
+}
+
+
+int
+gr_wavfile_sink::work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ float **in = (float **) &input_items[0];
+ int n_in_chans = input_items.size();
+
+ short int sample_buf_s;
+
+ int nwritten;
+
+ gruel::scoped_lock guard(d_mutex); // hold mutex for duration of this block
+ do_update(); // update: d_fp is reqd
+ if (!d_fp) // drop output on the floor
+ return noutput_items;
+
+ for (nwritten = 0; nwritten < noutput_items; nwritten++) {
+ for (int chan = 0; chan < d_nchans; chan++) {
+ // Write zeros to channels which are in the WAV file
+ // but don't have any inputs here
+ if (chan < n_in_chans) {
+ sample_buf_s =
+ convert_to_short(in[chan][nwritten]);
+ } else {
+ sample_buf_s = 0;
+ }
+
+ gri_wav_write_sample(d_fp, sample_buf_s, d_bytes_per_sample);
+
+ if (feof(d_fp) || ferror(d_fp)) {
+ fprintf(stderr, "[%s] file i/o error\n", __FILE__);
+ close();
+ exit(-1);
+ }
+ d_sample_count++;
+ }
+ }
+
+ return nwritten;
+}
+
+
+short int
+gr_wavfile_sink::convert_to_short(float sample)
+{
+ sample += d_normalize_shift;
+ sample *= d_normalize_fac;
+ if (sample > d_max_sample_val) {
+ sample = d_max_sample_val;
+ } else if (sample < d_min_sample_val) {
+ sample = d_min_sample_val;
+ }
+
+ return (short int) boost::math::iround(sample);
+}
+
+
+void
+gr_wavfile_sink::set_bits_per_sample(int bits_per_sample)
+{
+ gruel::scoped_lock guard(d_mutex);
+ if (bits_per_sample == 8 || bits_per_sample == 16) {
+ d_bytes_per_sample_new = bits_per_sample / 8;
+ }
+}
+
+
+void
+gr_wavfile_sink::set_sample_rate(unsigned int sample_rate)
+{
+ gruel::scoped_lock guard(d_mutex);
+ d_sample_rate = sample_rate;
+}
+
+
+void
+gr_wavfile_sink::do_update()
+{
+ if (!d_updated) {
+ return;
+ }
+
+ if (d_fp) {
+ close_wav();
+ }
+
+ d_fp = d_new_fp; // install new file pointer
+ d_new_fp = 0;
+ d_sample_count = 0;
+ d_bytes_per_sample = d_bytes_per_sample_new;
+
+ if (d_bytes_per_sample == 1) {
+ d_max_sample_val = UCHAR_MAX;
+ d_min_sample_val = 0;
+ d_normalize_fac = d_max_sample_val/2;
+ d_normalize_shift = 1;
+ } else if (d_bytes_per_sample == 2) {
+ d_max_sample_val = SHRT_MAX;
+ d_min_sample_val = SHRT_MIN;
+ d_normalize_fac = d_max_sample_val;
+ d_normalize_shift = 0;
+ }
+
+ d_updated = false;
+}
diff --git a/gnuradio-core/src/lib/io/gr_wavfile_sink.h b/gnuradio-core/src/lib/io/gr_wavfile_sink.h
new file mode 100644
index 000000000..162151b7a
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_wavfile_sink.h
@@ -0,0 +1,138 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008,2009 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_WAVFILE_SINK_H
+#define INCLUDED_GR_WAVFILE_SINK_H
+
+#include <gr_core_api.h>
+#include <gr_sync_block.h>
+#include <gr_file_sink_base.h>
+#include <boost/thread.hpp>
+
+class gr_wavfile_sink;
+typedef boost::shared_ptr<gr_wavfile_sink> gr_wavfile_sink_sptr;
+
+/*
+ * \p filename The .wav file to be opened
+ * \p n_channels Number of channels (2 = stereo or I/Q output)
+ * \p sample_rate Sample rate [S/s]
+ * \p bits_per_sample 16 or 8 bit, default is 16
+ */
+GR_CORE_API gr_wavfile_sink_sptr
+gr_make_wavfile_sink (const char *filename,
+ int n_channels,
+ unsigned int sample_rate,
+ int bits_per_sample = 16);
+
+/*!
+ * \brief Write stream to a Microsoft PCM (.wav) file.
+ *
+ * Values must be floats within [-1;1].
+ * Check gr_make_wavfile_sink() for extra info.
+ *
+ * \ingroup sink_blk
+ */
+class GR_CORE_API gr_wavfile_sink : public gr_sync_block
+{
+private:
+ friend GR_CORE_API gr_wavfile_sink_sptr gr_make_wavfile_sink (const char *filename,
+ int n_channels,
+ unsigned int sample_rate,
+ int bits_per_sample);
+
+ gr_wavfile_sink(const char *filename,
+ int n_channels,
+ unsigned int sample_rate,
+ int bits_per_sample);
+
+ unsigned d_sample_rate;
+ int d_nchans;
+ unsigned d_sample_count;
+ int d_bytes_per_sample;
+ int d_bytes_per_sample_new;
+ int d_max_sample_val;
+ int d_min_sample_val;
+ int d_normalize_shift;
+ int d_normalize_fac;
+
+ FILE *d_fp;
+ FILE *d_new_fp;
+ bool d_updated;
+ boost::mutex d_mutex;
+
+ /*!
+ * \brief Convert a sample value within [-1;+1] to a corresponding
+ * short integer value
+ */
+ short convert_to_short(float sample);
+
+ /*!
+ * \brief If any file changes have occurred, update now. This is called
+ * internally by work() and thus doesn't usually need to be called by
+ * hand.
+ */
+ void do_update();
+
+ /*!
+ * \brief Writes information to the WAV header which is not available
+ * a-priori (chunk size etc.) and closes the file. Not thread-safe and
+ * assumes d_fp is a valid file pointer, should thus only be called by
+ * other methods.
+ */
+ void close_wav();
+
+public:
+ ~gr_wavfile_sink ();
+
+ /*!
+ * \brief Opens a new file and writes a WAV header. Thread-safe.
+ */
+ bool open(const char* filename);
+
+ /*!
+ * \brief Closes the currently active file and completes the WAV
+ * header. Thread-safe.
+ */
+ void close();
+
+ /*!
+ * \brief Set the sample rate. This will not affect the WAV file
+ * currently opened. Any following open() calls will use this new
+ * sample rate.
+ */
+ void set_sample_rate(unsigned int sample_rate);
+
+ /*!
+ * \brief Set bits per sample. This will not affect the WAV file
+ * currently opened (see set_sample_rate()). If the value is neither
+ * 8 nor 16, the call is ignored and the current value is kept.
+ */
+ void set_bits_per_sample(int bits_per_sample);
+
+
+ int work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+
+};
+
+#endif /* INCLUDED_GR_WAVFILE_SINK_H */
diff --git a/gnuradio-core/src/lib/io/gr_wavfile_sink.i b/gnuradio-core/src/lib/io/gr_wavfile_sink.i
new file mode 100644
index 000000000..48d1130bd
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_wavfile_sink.i
@@ -0,0 +1,47 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+
+GR_SWIG_BLOCK_MAGIC(gr,wavfile_sink);
+
+gr_wavfile_sink_sptr
+gr_make_wavfile_sink (const char *filename,
+ int n_channels,
+ unsigned int sample_rate,
+ int bits_per_sample = 16) throw (std::runtime_error);
+
+class gr_wavfile_sink : public gr_sync_block
+{
+protected:
+ gr_wavfile_sink(const char *filename,
+ int n_channels,
+ unsigned int sample_rate,
+ int bits_per_sample) throw (std::runtime_error);
+
+public:
+ ~gr_wavfile_sink ();
+ bool open(const char* filename);
+ void close();
+ void set_sample_rate(unsigned int sample_rate);
+ void set_bits_per_sample(int bits_per_sample);
+};
+
diff --git a/gnuradio-core/src/lib/io/gr_wavfile_source.cc b/gnuradio-core/src/lib/io/gr_wavfile_source.cc
new file mode 100644
index 000000000..c8372868b
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_wavfile_source.cc
@@ -0,0 +1,171 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2008,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_wavfile_source.h>
+#include <gr_io_signature.h>
+#include <gri_wavfile.h>
+#include <sys/types.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_wavfile_source_sptr
+gr_make_wavfile_source (const char *filename, bool repeat)
+{
+ return gnuradio::get_initial_sptr(new gr_wavfile_source (filename, repeat));
+}
+
+
+gr_wavfile_source::gr_wavfile_source (const char *filename, bool repeat)
+ : gr_sync_block ("wavfile_source",
+ gr_make_io_signature (0, 0, 0),
+ gr_make_io_signature (1, 2, sizeof(float))),
+ d_fp(NULL), d_repeat(repeat),
+ d_sample_rate(1), d_nchans(1), d_bytes_per_sample(2), d_first_sample_pos(0),
+ d_samples_per_chan(0), d_sample_idx(0)
+{
+ // 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");
+ }
+
+ // Scan headers, check file validity
+ if (!gri_wavheader_parse(d_fp,
+ d_sample_rate,
+ d_nchans,
+ d_bytes_per_sample,
+ d_first_sample_pos,
+ d_samples_per_chan)) {
+ throw std::runtime_error("is not a valid wav file");
+ }
+
+ if (d_samples_per_chan == 0) {
+ throw std::runtime_error("WAV file does not contain any samples");
+ }
+
+ if (d_bytes_per_sample == 1) {
+ d_normalize_fac = 128;
+ d_normalize_shift = 1;
+ } else {
+ d_normalize_fac = 0x7FFF;
+ d_normalize_shift = 0;
+ }
+
+ // Re-set the output signature
+ set_output_signature(gr_make_io_signature(1, d_nchans, sizeof(float)));
+}
+
+
+gr_wavfile_source::~gr_wavfile_source ()
+{
+ fclose(d_fp);
+}
+
+
+int
+gr_wavfile_source::work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ float **out = (float **) &output_items[0];
+ int n_out_chans = output_items.size();
+
+ int i;
+ short sample;
+
+ for (i = 0; i < noutput_items; i++) {
+ if (d_sample_idx >= d_samples_per_chan) {
+ if (!d_repeat) {
+ // if nothing was read at all, say we're done.
+ return i ? i : -1;
+ }
+
+ if (fseek (d_fp, d_first_sample_pos, SEEK_SET) == -1) {
+ fprintf(stderr, "[%s] fseek failed\n", __FILE__);
+ exit(-1);
+ }
+
+ d_sample_idx = 0;
+ }
+
+ for (int chan = 0; chan < d_nchans; chan++) {
+ sample = gri_wav_read_sample(d_fp, d_bytes_per_sample);
+
+ if (chan < n_out_chans) {
+ out[chan][i] = convert_to_float(sample);
+ }
+ }
+
+ d_sample_idx++;
+
+ // OK, EOF is not necessarily an error. But we're not going to
+ // deal with handling corrupt wav files, so if they give us any
+ // trouble they won't be processed. Serves them bloody right.
+ if (feof(d_fp) || ferror(d_fp)) {
+ if (i == 0) {
+ fprintf(stderr, "[%s] WAV file has corrupted header or i/o error\n", __FILE__);
+ return -1;
+ }
+ return i;
+ }
+ }
+
+ return noutput_items;
+}
+
+
+float
+gr_wavfile_source::convert_to_float(short int sample)
+{
+ float sample_out = (float) sample;
+ sample_out /= d_normalize_fac;
+ sample_out -= d_normalize_shift;
+ return sample_out;
+}
diff --git a/gnuradio-core/src/lib/io/gr_wavfile_source.h b/gnuradio-core/src/lib/io/gr_wavfile_source.h
new file mode 100644
index 000000000..02e6e3678
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_wavfile_source.h
@@ -0,0 +1,95 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2008 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_WAVFILE_SOURCE_H
+#define INCLUDED_GR_WAVFILE_SOURCE_H
+
+#include <gr_core_api.h>
+#include <gr_sync_block.h>
+#include <cstdio> // for FILE
+
+class gr_wavfile_source;
+typedef boost::shared_ptr<gr_wavfile_source> gr_wavfile_source_sptr;
+
+GR_CORE_API gr_wavfile_source_sptr
+gr_make_wavfile_source (const char *filename, bool repeat = false);
+
+/*!
+ * \brief Read stream from a Microsoft PCM (.wav) file, output floats
+ *
+ * Unless otherwise called, values are within [-1;1].
+ * Check gr_make_wavfile_source() for extra info.
+ *
+ * \ingroup source_blk
+ */
+
+class GR_CORE_API gr_wavfile_source : public gr_sync_block
+{
+private:
+ friend GR_CORE_API gr_wavfile_source_sptr gr_make_wavfile_source (const char *filename,
+ bool repeat);
+ gr_wavfile_source(const char *filename, bool repeat);
+
+ FILE *d_fp;
+ bool d_repeat;
+
+ unsigned d_sample_rate;
+ int d_nchans;
+ int d_bytes_per_sample;
+ int d_first_sample_pos;
+ unsigned d_samples_per_chan;
+ unsigned d_sample_idx;
+ int d_normalize_shift;
+ int d_normalize_fac;
+
+ /*!
+ * \brief Convert an integer sample value to a float value within [-1;1]
+ */
+ float convert_to_float(short int sample);
+
+public:
+ ~gr_wavfile_source ();
+
+ int work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+
+ /*!
+ * \brief Read the sample rate as specified in the wav file header
+ */
+ unsigned int sample_rate() const { return d_sample_rate; };
+
+ /*!
+ * \brief Return the number of bits per sample as specified in the wav
+ * file header. Only 8 or 16 bit are supported here.
+ */
+ int bits_per_sample() const { return d_bytes_per_sample * 8; };
+
+ /*!
+ * \brief Return the number of channels in the wav file as specified in
+ * the wav file header. This is also the max number of outputs you can
+ * have.
+ */
+ int channels() const { return d_nchans; };
+};
+
+#endif /* INCLUDED_GR_WAVFILE_SOURCE_H */
diff --git a/gnuradio-core/src/lib/io/gr_wavfile_source.i b/gnuradio-core/src/lib/io/gr_wavfile_source.i
new file mode 100644
index 000000000..5af2224f1
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_wavfile_source.i
@@ -0,0 +1,42 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,wavfile_source);
+
+gr_wavfile_source_sptr
+gr_make_wavfile_source (const char *filename,
+ bool repeat = false) throw (std::runtime_error);
+
+class gr_wavfile_source : public gr_sync_block
+{
+private:
+ gr_wavfile_source(const char *filename,
+ bool repeat) throw (std::runtime_error);
+
+public:
+ ~gr_wavfile_source();
+
+ unsigned int sample_rate();
+ int bits_per_sample();
+ int channels();
+};
+
diff --git a/gnuradio-core/src/lib/io/gri_wavfile.cc b/gnuradio-core/src/lib/io/gri_wavfile.cc
new file mode 100644
index 000000000..277e6b7b0
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gri_wavfile.cc
@@ -0,0 +1,251 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2008,2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gri_wavfile.h>
+#include <cstring>
+#include <stdint.h>
+#include <boost/detail/endian.hpp> //BOOST_BIG_ENDIAN
+
+# define VALID_COMPRESSION_TYPE 0x0001
+
+// Basically, this is the opposite of htonx() and ntohx()
+// Define host to/from worknet (little endian) short and long
+#ifdef BOOST_BIG_ENDIAN
+
+ static inline uint16_t __gri_wav_bs16(uint16_t x)
+ {
+ return (x>>8) | (x<<8);
+ }
+
+ static inline uint32_t __gri_wav_bs32(uint32_t x)
+ {
+ return (uint32_t(__gri_wav_bs16(uint16_t(x&0xfffful)))<<16) | (__gri_wav_bs16(uint16_t(x>>16)));
+ }
+
+ #define htowl(x) __gri_wav_bs32(x)
+ #define wtohl(x) __gri_wav_bs32(x)
+ #define htows(x) __gri_wav_bs16(x)
+ #define wtohs(x) __gri_wav_bs16(x)
+
+#else
+
+ #define htowl(x) uint32_t(x)
+ #define wtohl(x) uint32_t(x)
+ #define htows(x) uint16_t(x)
+ #define wtohs(x) uint16_t(x)
+
+#endif // BOOST_BIG_ENDIAN
+
+// WAV files are always little-endian, so we need some byte switching macros
+static inline uint32_t host_to_wav(uint32_t x) { return htowl(x); }
+static inline uint16_t host_to_wav(uint16_t x) { return htows(x); }
+static inline int16_t host_to_wav(int16_t x) { return htows(x); }
+static inline uint32_t wav_to_host(uint32_t x) { return wtohl(x); }
+static inline uint16_t wav_to_host(uint16_t x) { return wtohs(x); }
+static inline int16_t wav_to_host(int16_t x) { return wtohs(x); }
+
+bool
+gri_wavheader_parse(FILE *fp,
+ unsigned int &sample_rate_o,
+ int &nchans_o,
+ int &bytes_per_sample_o,
+ int &first_sample_pos_o,
+ unsigned int &samples_per_chan_o)
+{
+ // _o variables take return values
+ char str_buf[8] = {0};
+
+ uint32_t file_size;
+ uint32_t fmt_hdr_skip;
+ uint16_t compression_type;
+ uint16_t nchans;
+ uint32_t sample_rate;
+ uint32_t avg_bytes_per_sec;
+ uint16_t block_align;
+ uint16_t bits_per_sample;
+ uint32_t chunk_size;
+
+ size_t fresult;
+
+ fresult = fread(str_buf, 1, 4, fp);
+ if (fresult != 4 || strncmp(str_buf, "RIFF", 4) || feof(fp)) {
+ return false;
+ }
+
+ fresult = fread(&file_size, 1, 4, fp);
+
+ fresult = fread(str_buf, 1, 8, fp);
+ if (fresult != 8 || strncmp(str_buf, "WAVEfmt ", 8) || feof(fp)) {
+ return false;
+ }
+
+ fresult = fread(&fmt_hdr_skip, 1, 4, fp);
+
+ fresult = fread(&compression_type, 1, 2, fp);
+ if (wav_to_host(compression_type) != VALID_COMPRESSION_TYPE) {
+ return false;
+ }
+
+ fresult = fread(&nchans, 1, 2, fp);
+ fresult = fread(&sample_rate, 1, 4, fp);
+ fresult = fread(&avg_bytes_per_sec, 1, 4, fp);
+ fresult = fread(&block_align, 1, 2, fp);
+ fresult = fread(&bits_per_sample, 1, 2, fp);
+
+ if (ferror(fp)) {
+ return false;
+ }
+
+ fmt_hdr_skip = wav_to_host(fmt_hdr_skip);
+ nchans = wav_to_host(nchans);
+ sample_rate = wav_to_host(sample_rate);
+ bits_per_sample = wav_to_host(bits_per_sample);
+
+ if (bits_per_sample != 8 && bits_per_sample != 16) {
+ return false;
+ }
+
+ fmt_hdr_skip -= 16;
+ if (fmt_hdr_skip) {
+ fseek(fp, fmt_hdr_skip, SEEK_CUR);
+ }
+
+ // data chunk
+ fresult = fread(str_buf, 1, 4, fp);
+ if (strncmp(str_buf, "data", 4)) {
+ return false;
+ }
+
+ fresult = fread(&chunk_size, 1, 4, fp);
+ if (ferror(fp)) {
+ return false;
+ }
+
+ // More byte swapping
+ chunk_size = wav_to_host(chunk_size);
+
+ // Output values
+ sample_rate_o = (unsigned) sample_rate;
+ nchans_o = (int) nchans;
+ bytes_per_sample_o = (int) (bits_per_sample / 8);
+ first_sample_pos_o = (int) ftell(fp);
+ samples_per_chan_o = (unsigned) (chunk_size / (bytes_per_sample_o * nchans));
+ return true;
+}
+
+
+short int
+gri_wav_read_sample(FILE *fp, int bytes_per_sample)
+{
+ int16_t buf_16bit;
+
+ if(!fread(&buf_16bit, bytes_per_sample, 1, fp)) {
+ return 0;
+ }
+ if(bytes_per_sample == 1) {
+ return (short) buf_16bit;
+ }
+ return (short)wav_to_host(buf_16bit);
+}
+
+
+bool
+gri_wavheader_write(FILE *fp,
+ unsigned int sample_rate,
+ int nchans,
+ int bytes_per_sample)
+{
+ const int header_len = 44;
+ char wav_hdr[header_len] = "RIFF\0\0\0\0WAVEfmt \0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0data\0\0\0";
+ uint16_t nchans_f = (uint16_t) nchans;
+ uint32_t sample_rate_f = (uint32_t) sample_rate;
+ uint16_t block_align = bytes_per_sample * nchans;
+ uint32_t avg_bytes = sample_rate * block_align;
+ uint16_t bits_per_sample = bytes_per_sample * 8;
+
+ nchans_f = host_to_wav(nchans_f);
+ sample_rate_f = host_to_wav(sample_rate_f);
+ block_align = host_to_wav(block_align);
+ avg_bytes = host_to_wav(avg_bytes);
+ bits_per_sample = host_to_wav(bits_per_sample);
+
+ wav_hdr[16] = 0x10; // no extra bytes
+ wav_hdr[20] = 0x01; // no compression
+ memcpy((void *) (wav_hdr + 22), (void *) &nchans_f, 2);
+ memcpy((void *) (wav_hdr + 24), (void *) &sample_rate_f, 4);
+ memcpy((void *) (wav_hdr + 28), (void *) &avg_bytes, 4);
+ memcpy((void *) (wav_hdr + 32), (void *) &block_align, 2);
+ memcpy((void *) (wav_hdr + 34), (void *) &bits_per_sample, 2);
+
+ fwrite(&wav_hdr, 1, header_len, fp);
+ if (ferror(fp)) {
+ return false;
+ }
+
+ return true;
+}
+
+
+void
+gri_wav_write_sample(FILE *fp, short int sample, int bytes_per_sample)
+{
+ void *data_ptr;
+ unsigned char buf_8bit;
+ int16_t buf_16bit;
+
+ if (bytes_per_sample == 1) {
+ buf_8bit = (unsigned char) sample;
+ data_ptr = (void *) &buf_8bit;
+ } else {
+ buf_16bit = host_to_wav((int16_t) sample);
+ data_ptr = (void *) &buf_16bit;
+ }
+
+ fwrite(data_ptr, 1, bytes_per_sample, fp);
+}
+
+
+bool
+gri_wavheader_complete(FILE *fp, unsigned int byte_count)
+{
+ uint32_t chunk_size = (uint32_t) byte_count;
+ chunk_size = host_to_wav(chunk_size);
+
+ fseek(fp, 40, SEEK_SET);
+ fwrite(&chunk_size, 1, 4, fp);
+
+ chunk_size = (uint32_t) byte_count + 36; // fmt chunk and data header
+ chunk_size = host_to_wav(chunk_size);
+ fseek(fp, 4, SEEK_SET);
+
+ fwrite(&chunk_size, 1, 4, fp);
+
+ if (ferror(fp)) {
+ return false;
+ }
+
+ return true;
+}
diff --git a/gnuradio-core/src/lib/io/gri_wavfile.h b/gnuradio-core/src/lib/io/gri_wavfile.h
new file mode 100644
index 000000000..16280e34a
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gri_wavfile.h
@@ -0,0 +1,96 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+// This file stores all the RIFF file type knowledge for the gr_wavfile_*
+// blocks.
+
+#include <gr_core_api.h>
+#include <cstdio>
+
+/*!
+ * \brief Read signal information from a given WAV file.
+ *
+ * \param[in] fp File pointer to an opened, empty file.
+ * \param[out] sample_rate Stores the sample rate [S/s]
+ * \param[out] nchans Number of channels
+ * \param[out] bytes_per_sample Bytes per sample, can either be 1 or 2 (corresponding o
+ * 8 or 16 bit samples, respectively)
+ * \param[out] first_sample_pos Number of the first byte containing a sample. Use this
+ * with fseek() to jump from the end of the file to the
+ * first sample when in repeat mode.
+ * \param[out] samples_per_chan Number of samples per channel
+ * \return True on a successful read, false if the file could not be read or is
+ * not a valid WAV file.
+ */
+bool
+gri_wavheader_parse(FILE *fp,
+ unsigned int &sample_rate,
+ int &nchans,
+ int &bytes_per_sample,
+ int &first_sample_pos,
+ unsigned int &samples_per_chan);
+
+
+/*!
+ * \brief Read one sample from an open WAV file at the current position.
+ *
+ * Takes care of endianness.
+ */
+short int
+gri_wav_read_sample(FILE *fp, int bytes_per_sample);
+
+
+/*!
+ * \brief Write a valid RIFF file header
+ *
+ * Note: Some header values are kept blank because they're usually not known
+ * a-priori (file and chunk lengths). Use gri_wavheader_complete() to fill
+ * these in.
+ */
+bool
+gri_wavheader_write(FILE *fp,
+ unsigned int sample_rate,
+ int nchans,
+ int bytes_per_sample);
+
+/*!
+ * \brief Write one sample to an open WAV file at the current position.
+ *
+ * Takes care of endianness.
+ */
+void
+gri_wav_write_sample(FILE *fp, short int sample, int bytes_per_sample);
+
+
+/*!
+ * \brief Complete a WAV header
+ *
+ * Note: The stream position is changed during this function. If anything
+ * needs to be written to the WAV file after calling this function (which
+ * shouldn't happen), you need to fseek() to the end of the file (or
+ * whereever).
+ *
+ * \param[in] fp File pointer to an open WAV file with a blank header
+ * \param[in] byte_count Length of all samples written to the file in bytes.
+ */
+bool
+gri_wavheader_complete(FILE *fp, unsigned int byte_count);
diff --git a/gnuradio-core/src/lib/io/i2c.cc b/gnuradio-core/src/lib/io/i2c.cc
new file mode 100644
index 000000000..02dd47b53
--- /dev/null
+++ b/gnuradio-core/src/lib/io/i2c.cc
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "i2c.h"
+
+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
index 000000000..6b7f25a29
--- /dev/null
+++ b/gnuradio-core/src/lib/io/i2c.h
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_I2C_H
+#define INCLUDED_I2C_H
+
+#include <gr_core_api.h>
+#include <boost/shared_ptr.hpp>
+
+class i2c;
+typedef boost::shared_ptr<i2c> i2c_sptr;
+
+/*!
+ * \brief abstract class for controlling i2c bus
+ */
+class GR_CORE_API 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
index 000000000..ddd00290d
--- /dev/null
+++ b/gnuradio-core/src/lib/io/i2c_bbio.cc
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "i2c_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
index 000000000..6bf47b9cd
--- /dev/null
+++ b/gnuradio-core/src/lib/io/i2c_bbio.h
@@ -0,0 +1,51 @@
+/* -*- 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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_I2C_BBIO_H
+#define INCLUDED_I2C_BBIO_H
+
+#include <gr_core_api.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.
+ * \ingroup base
+ */
+class GR_CORE_API 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
index 000000000..382bb6b37
--- /dev/null
+++ b/gnuradio-core/src/lib/io/i2c_bbio_pp.cc
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "i2c_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
index 000000000..2391bc1fc
--- /dev/null
+++ b/gnuradio-core/src/lib/io/i2c_bbio_pp.h
@@ -0,0 +1,57 @@
+/* -*- 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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_I2C_BBIO_PP_H
+#define INCLUDED_I2C_BBIO_PP_H
+
+#include <gr_core_api.h>
+#include "i2c_bbio.h"
+#include "ppio.h"
+
+/*!
+ * \brief concrete class that bit bangs eval board i2c bus using parallel port
+ *
+ * \ingroup base
+ * 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 GR_CORE_API i2c_bbio_pp : public i2c_bbio {
+ friend GR_CORE_API 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;
+};
+
+GR_CORE_API 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
index 000000000..eb801c68f
--- /dev/null
+++ b/gnuradio-core/src/lib/io/i2c_bitbang.cc
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "i2c_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
index 000000000..1d6fe5044
--- /dev/null
+++ b/gnuradio-core/src/lib/io/i2c_bitbang.h
@@ -0,0 +1,65 @@
+/* -*- 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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_I2C_BITBANG_H
+#define INCLUDED_I2C_BITBANG_H
+
+#include <gr_core_api.h>
+#include <i2c.h>
+#include <i2c_bbio.h>
+
+/*!
+ * \brief class for controlling i2c bus
+ * \ingroup base
+ */
+class GR_CORE_API i2c_bitbang : public i2c {
+ friend GR_CORE_API 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;
+};
+
+GR_CORE_API 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
index 000000000..e2de4eb97
--- /dev/null
+++ b/gnuradio-core/src/lib/io/io.i
@@ -0,0 +1,83 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2007 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+%{
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_file_sink.h>
+#include <gr_file_source.h>
+#include <gr_file_descriptor_sink.h>
+#include <gr_file_descriptor_source.h>
+#include <gr_histo_sink_f.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_burst_source.h>
+#include <gr_message_sink.h>
+#include <gr_udp_sink.h>
+#include <gr_udp_source.h>
+#include <gr_wavfile_sink.h>
+#include <gr_wavfile_source.h>
+#include <gr_tagged_file_sink.h>
+#include <gr_pdu_to_tagged_stream.h>
+#include <gr_tagged_stream_to_pdu.h>
+#include <gr_message_debug.h>
+#include <gr_pdu.h>
+#include <gr_tuntap_pdu.h>
+#include <gr_socket_pdu.h>
+%}
+
+%include "gr_file_sink_base.i"
+%include "gr_file_sink.i"
+%include "gr_file_source.i"
+%include "gr_file_descriptor_sink.i"
+%include "gr_file_descriptor_source.i"
+%include "gr_histo_sink.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_burst_source.i"
+%include "gr_message_sink.i"
+%include "gr_udp_sink.i"
+%include "gr_udp_source.i"
+%include "gr_wavfile_sink.i"
+%include "gr_wavfile_source.i"
+%include "gr_tagged_file_sink.i"
+%include "gr_pdu_to_tagged_stream.i"
+%include "gr_tagged_stream_to_pdu.i"
+%include "gr_message_debug.i"
+%include "gr_pdu.i"
+%include "gr_tuntap_pdu.i"
+%include "gr_socket_pdu.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
index 000000000..3ec072d51
--- /dev/null
+++ b/gnuradio-core/src/lib/io/microtune_4702.cc
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "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
index 000000000..ccc66db71
--- /dev/null
+++ b/gnuradio-core/src/lib/io/microtune_4702.h
@@ -0,0 +1,71 @@
+/* -*- 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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_MICROTUNE_4702_H
+#define INCLUDED_MICROTUNE_4702_H
+
+#include <gr_core_api.h>
+#include <microtune_xxxx.h>
+
+/*!
+ * \brief class for controlling microtune 4702 tuner module
+ * \ingroup hardware
+ */
+
+class GR_CORE_API 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
index 000000000..f6c68726b
--- /dev/null
+++ b/gnuradio-core/src/lib/io/microtune_4702_eval_board.cc
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "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
index 000000000..d866a4b94
--- /dev/null
+++ b/gnuradio-core/src/lib/io/microtune_4702_eval_board.h
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_MICROTUNE_4702_EVAL_BOARD_H
+#define INCLUDED_MICROTUNE_4702_EVAL_BOARD_H
+
+#include <gr_core_api.h>
+#include "microtune_xxxx_eval_board.h"
+
+/*!
+ * \brief control microtune 4702 eval board
+ * \ingroup hardware
+ */
+
+class GR_CORE_API 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
index 000000000..fc085a975
--- /dev/null
+++ b/gnuradio-core/src/lib/io/microtune_4702_eval_board.i
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+class 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
index 000000000..72ddd4bb6
--- /dev/null
+++ b/gnuradio-core/src/lib/io/microtune_4937.cc
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "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
index 000000000..be8657c95
--- /dev/null
+++ b/gnuradio-core/src/lib/io/microtune_4937.h
@@ -0,0 +1,68 @@
+/* -*- 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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_MICROTUNE_4937_H
+#define INCLUDED_MICROTUNE_4937_H
+
+#include <gr_core_api.h>
+#include <microtune_xxxx.h>
+
+/*!
+ * \brief class for controlling microtune 4937 tuner module
+ * \ingroup hardware
+ */
+class GR_CORE_API 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
index 000000000..a25b8addf
--- /dev/null
+++ b/gnuradio-core/src/lib/io/microtune_4937_eval_board.cc
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "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
index 000000000..3abd9084e
--- /dev/null
+++ b/gnuradio-core/src/lib/io/microtune_4937_eval_board.h
@@ -0,0 +1,50 @@
+/* -*- 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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_MICROTUNE_4937_EVAL_BOARD_H
+#define INCLUDED_MICROTUNE_4937_EVAL_BOARD_H
+
+#include <gr_core_api.h>
+#include "microtune_xxxx_eval_board.h"
+
+/*!
+ * \brief control microtune 4937 eval board
+ * \ingroup hardware
+ */
+
+class GR_CORE_API 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
index 000000000..e261416f7
--- /dev/null
+++ b/gnuradio-core/src/lib/io/microtune_4937_eval_board.i
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+class 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
index 000000000..f77ef47b4
--- /dev/null
+++ b/gnuradio-core/src/lib/io/microtune_eval_board.i
@@ -0,0 +1,95 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+/*
+ * SWIG interface defs for Microtune 4937 and eval board with Eric's daughterboard
+ */
+
+/*!
+ * \brief abstract class for controlling microtune 4937 tuner module
+ */
+class microtune_4937 {
+public:
+ microtune_4937 ();
+
+ virtual ~microtune_4937 ();
+
+ // returns actual freq or 0 if error (easier interface for SWIG)
+ double set_RF_freq (double freq);
+
+ /*!
+ * \returns true iff PLL is locked
+ */
+ bool pll_locked_p ();
+
+ /*!
+ * \returns the output frequency (IF center freq) of the tuner in Hz.
+ */
+ double get_output_freq ();
+
+
+ private:
+ //! \returns true iff successful
+ virtual bool i2c_write (int addr, const unsigned char *buf, int nbytes) = 0;
+
+ //! \returns number of bytes read or -1 if error
+ virtual int i2c_read (int addr, unsigned char *buf, int max_bytes) = 0;
+
+ int d_reference_divider;
+ bool d_fast_tuning_p; /* if set, higher charge pump current:
+ faster tuning, worse phase noise
+ for distance < 10kHz to the carrier */
+};
+
+/*!
+ * \brief concrete class for controlling microtune 4937 eval board attached to parallel port
+ */
+class microtune_eval_board : public microtune_4937 {
+public:
+ microtune_eval_board (int which_pp = 0);
+ ~microtune_eval_board ();
+
+ //! is the eval board present?
+ bool board_present_p ();
+
+ /*!
+ * \brief set RF and IF AGC control voltages ([0, 5] volts)
+ */
+ void set_RF_AGC_voltage (float volts);
+ void set_IF_AGC_voltage (float volts);
+
+ /*!
+ * \brief set RF and IF AGC levels together (scale [0, 1000])
+ *
+ * This provides a simple linear interface for adjusting both
+ * the RF and IF gain in consort. This is the easy to use interface.
+ * 0 corresponds to minimum gain. 1000 corresponds to maximum gain.
+ */
+ void set_AGC (float value_0_1000);
+
+private:
+ //! \returns true iff successful
+ virtual bool i2c_write (int addr, const unsigned char *buf, int nbytes);
+
+ //! \returns number of bytes read or -1 if error
+ virtual int i2c_read (int addr, unsigned char *buf, int max_bytes);
+};
diff --git a/gnuradio-core/src/lib/io/microtune_eval_board_defs.h b/gnuradio-core/src/lib/io/microtune_eval_board_defs.h
new file mode 100644
index 000000000..61c52364f
--- /dev/null
+++ b/gnuradio-core/src/lib/io/microtune_eval_board_defs.h
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef _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
index 000000000..3d55f534a
--- /dev/null
+++ b/gnuradio-core/src/lib/io/microtune_xxxx.cc
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "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
index 000000000..b2646d39f
--- /dev/null
+++ b/gnuradio-core/src/lib/io/microtune_xxxx.h
@@ -0,0 +1,66 @@
+/* -*- 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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_MICROTUNE_XXXX_H
+#define INCLUDED_MICROTUNE_XXXX_H
+
+#include <gr_core_api.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
+ * \ingroup base
+ */
+class GR_CORE_API 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
index 000000000..35600ff06
--- /dev/null
+++ b/gnuradio-core/src/lib/io/microtune_xxxx_eval_board.cc
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "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
index 000000000..7fd784ade
--- /dev/null
+++ b/gnuradio-core/src/lib/io/microtune_xxxx_eval_board.h
@@ -0,0 +1,98 @@
+/* -*- 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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_MICROTUNE_XXXX_EVAL_BOARD_H
+#define INCLUDED_MICROTUNE_XXXX_EVAL_BOARD_H
+
+#include <gr_core_api.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
+ * \ingroup hardware
+ */
+class GR_CORE_API 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
index 000000000..8a8a59742
--- /dev/null
+++ b/gnuradio-core/src/lib/io/microtune_xxxx_eval_board.i
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+class 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
index 000000000..a5edc539c
--- /dev/null
+++ b/gnuradio-core/src/lib/io/ppio.cc
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <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
index 000000000..d99f7bf79
--- /dev/null
+++ b/gnuradio-core/src/lib/io/ppio.h
@@ -0,0 +1,63 @@
+/* -*- 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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_PPIO_H
+#define INCLUDED_PPIO_H
+
+#include <gr_core_api.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
+ * \ingroup hardware
+ */
+
+class GR_CORE_API 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
+ */
+
+GR_CORE_API 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
index 000000000..6b95dcf88
--- /dev/null
+++ b/gnuradio-core/src/lib/io/ppio.i
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+class 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
index 000000000..f52845958
--- /dev/null
+++ b/gnuradio-core/src/lib/io/ppio_ppdev.cc
@@ -0,0 +1,321 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2001,2003,2004,2008 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#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>
+#if defined(HAVE_LINUX_PPDEV_H)
+#include <sys/ioctl.h>
+#include <linux/ppdev.h>
+#include <linux/parport.h>
+#include <sstream>
+#elif defined(HAVE_DEV_PPBUS_PPI_H)
+#include <sys/ioctl.h>
+#include <dev/ppbus/ppi.h>
+#include <dev/ppbus/ppbconf.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;
+
+#if defined(HAVE_LINUX_PPDEV_H)
+
+// The real Linux 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");
+ }
+}
+
+#elif defined(HAVE_DEV_PPBUS_PPI_H)
+
+// The real FreeBSD code... (Could work on other BSDs as well)
+
+ppio_ppdev::ppio_ppdev (int which)
+{
+ std::ostringstream filename;
+ filename << "/dev/ppi" << 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);
+ throw std::runtime_error ("open");
+ }
+
+#if 0
+ int mode = IEEE1284_MODE_COMPAT;
+ if (ioctl (d_fd, PPSETMODE, &mode) != 0){
+ perror ("ppio_ppdev: PPSETMODE");
+ close (d_fd);
+ throw std::runtime_error ("PPSETMODE");
+ }
+#endif
+}
+
+ppio_ppdev::~ppio_ppdev ()
+{
+ close (d_fd);
+}
+
+
+void
+ppio_ppdev::write_data (unsigned char v)
+{
+ if (ioctl (d_fd, PPISDATA, &v) != 0){
+ perror ("ppio_ppdev: PPISDATA");
+ throw std::runtime_error ("PPISDATA");
+ }
+}
+
+unsigned char
+ppio_ppdev::read_data ()
+{
+ unsigned char v;
+
+ if (ioctl (d_fd, PPIGDATA, &v) != 0){
+ perror ("ppio_ppdev: PPIGDATA");
+ throw std::runtime_error ("PPIGDATA");
+ }
+ return v;
+}
+
+void
+ppio_ppdev::write_control (unsigned char v)
+{
+ unsigned char ctrl = v ^ CP_ACTIVE_LOW_BITS;
+ if (ioctl (d_fd, PPISCTRL, &ctrl) != 0){
+ perror ("ppio_ppdev: PPISCTRL");
+ throw std::runtime_error ("PPISCTRL");
+ }
+}
+
+unsigned char
+ppio_ppdev::read_control ()
+{
+ unsigned char ctrl;
+ if (ioctl (d_fd, PPIGCTRL, &ctrl) != 0){
+ perror ("ppio_ppdev: PPIGCTRL");
+ throw std::runtime_error ("PPIGCTRL");
+ }
+
+ return ctrl ^ CP_ACTIVE_LOW_BITS;
+}
+
+unsigned char
+ppio_ppdev::read_status ()
+{
+ unsigned char status;
+ if (ioctl (d_fd, PPIGSTATUS, &status) != 0){
+ perror ("ppio_ppdev: PPIGSTATUS");
+ throw std::runtime_error ("PPIGSTATUS");
+ }
+ return status ^ SP_ACTIVE_LOW_BITS;
+}
+
+void
+ppio_ppdev::lock ()
+{
+}
+
+void
+ppio_ppdev::unlock ()
+{
+}
+#else
+/* Apparently, non real code */
+
+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 ()
+{
+}
+
+#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
index 000000000..1f86d7e04
--- /dev/null
+++ b/gnuradio-core/src/lib/io/ppio_ppdev.h
@@ -0,0 +1,62 @@
+/* -*- 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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_PPIO_PPDEV_H
+#define INCLUDED_PPIO_PPDEV_H
+
+#include <gr_core_api.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
+ * \ingroup hardware
+ */
+
+class GR_CORE_API ppio_ppdev : public ppio {
+ friend GR_CORE_API 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
index 000000000..a8c2555e0
--- /dev/null
+++ b/gnuradio-core/src/lib/io/sdr_1000.cc
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <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
index 000000000..c00608a3a
--- /dev/null
+++ b/gnuradio-core/src/lib/io/sdr_1000.h
@@ -0,0 +1,53 @@
+/* -*- 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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_SDR_1000_H
+#define INCLUDED_SDR_1000_H
+
+#include <gr_core_api.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.
+ * \ingroup hardware
+ */
+class GR_CORE_API 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
index 000000000..c9b1ef560
--- /dev/null
+++ b/gnuradio-core/src/lib/io/sdr_1000.i
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, 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/CMakeLists.txt b/gnuradio-core/src/lib/missing/CMakeLists.txt
new file mode 100644
index 000000000..85267ee48
--- /dev/null
+++ b/gnuradio-core/src/lib/missing/CMakeLists.txt
@@ -0,0 +1,32 @@
+# Copyright 2010 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+
+########################################################################
+# This file included, use CMake directory variables
+########################################################################
+
+list(APPEND gnuradio_core_sources
+ ${CMAKE_CURRENT_SOURCE_DIR}/bug_work_around_8.cc
+)
+
+if(CMAKE_SYSTEM_PROCESSOR MATCHES "^(powerpc|ppc)")
+ list(APPEND gnuradio_core_sources
+ ${CMAKE_CURRENT_SOURCE_DIR}/posix_memalign.cc
+ )
+endif(CMAKE_SYSTEM_PROCESSOR MATCHES "^(powerpc|ppc)")
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
index 000000000..5e431a210
--- /dev/null
+++ b/gnuradio-core/src/lib/missing/bug_work_around_8.cc
@@ -0,0 +1,3 @@
+// if libmisc has no sources, it doesn't get built correctly
+#include <gruel/attributes.h>
+static int gr_bug_work_around_8 __GR_ATTR_UNUSED;
diff --git a/gnuradio-core/src/lib/missing/getopt.c b/gnuradio-core/src/lib/missing/getopt.c
new file mode 100644
index 000000000..69c7c16f7
--- /dev/null
+++ b/gnuradio-core/src/lib/missing/getopt.c
@@ -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 3, or (at your option) any
+ later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+/* 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;
+
+#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. */
+
+/* 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;
+}
+
+/* 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__. */
+
+#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
index 000000000..067908147
--- /dev/null
+++ b/gnuradio-core/src/lib/missing/getopt.h
@@ -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 3, or (at your option) any
+ later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, 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
index 000000000..a53e47ed9
--- /dev/null
+++ b/gnuradio-core/src/lib/missing/gettimeofday.c
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <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/posix_memalign.cc b/gnuradio-core/src/lib/missing/posix_memalign.cc
new file mode 100644
index 000000000..aaeff7804
--- /dev/null
+++ b/gnuradio-core/src/lib/missing/posix_memalign.cc
@@ -0,0 +1,114 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008,2009 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "posix_memalign.h"
+
+#ifdef HAVE_MALLOC_H
+// for Cygwin valloc () prototype
+#include <malloc.h>
+#endif
+
+#ifndef HAVE_POSIX_MEMALIGN
+
+/* emulate posix_memalign functionality, to some degree */
+
+#include <errno.h>
+#include "gr_pagesize.h"
+
+int posix_memalign
+(void **memptr, size_t alignment, size_t size)
+{
+ /* emulate posix_memalign functionality, to some degree */
+
+ /* make sure the return handle is valid; return "bad address" if not valid */
+ if (memptr == 0)
+ return (EFAULT);
+ *memptr = (void*) 0;
+
+ /* make sure 'alignment' is a power of 2
+ * and multiple of sizeof (void*)
+ */
+
+ /* make sure 'alignment' is a multiple of sizeof (void*) */
+ if ((alignment % sizeof (void*)) != 0)
+ return (EINVAL);
+
+ /* make sure 'alignment' is a power of 2 */
+ if ((alignment & (alignment - 1)) != 0)
+ return (EINVAL);
+
+ /* good alignment */
+
+#if (ALIGNED_MALLOC != 0)
+
+ /* if 'malloc' is known to be aligned, and the desired 'alignment'
+ * matches is <= that provided by 'malloc', then use 'malloc'. This
+ * works on, e.g., Darwin 8 & 9: for which malloc is 16-byte aligned.
+ */
+ size_t am = (size_t) ALIGNED_MALLOC;
+ if (alignment <= am) {
+ /* make sure ALIGNED_MALLOC is a power of 2, to guarantee that the
+ * alignment is correct (since 'alignment' must be a power of 2).
+ */
+ if ((am & (am - 1)) != 0)
+ return (EINVAL);
+ /* good malloc alignment */
+ *memptr = malloc (size);
+ }
+
+#endif /* (ALIGNED_MALLOC != 0) */
+#ifdef HAVE_VALLOC
+
+ if (*memptr == (void*) 0) {
+ /* try valloc if it exists */
+ /* cheap and easy way to make sure alignment is met, so long as it
+ * is <= pagesize () */
+ if (alignment <= (size_t) gr_pagesize ()) {
+ *memptr = valloc (size);
+ }
+ }
+
+#endif /* HAVE_VALLOC */
+
+#if (ALIGNED_MALLOC == 0) && !defined (HAVE_VALLOC)
+ /* no posix_memalign, valloc, and malloc isn't known to be aligned
+ * (enough for the input arguments); no idea what to do.
+ */
+
+#error gnuradio-core/src/libmissing/posix_memalign.cc: Cannot find a way to alloc aligned memory.
+
+#endif
+
+ /* if the pointer wasn't allocated properly, return that there was
+ * not enough memory to allocate; otherwise, return OK (0).
+ */
+ if (*memptr == (void*) 0)
+ return (ENOMEM);
+ else
+ return (0);
+};
+
+#endif /* ! HAVE_POSIX_MEMALIGN */
diff --git a/gnuradio-core/src/lib/missing/posix_memalign.h b/gnuradio-core/src/lib/missing/posix_memalign.h
new file mode 100644
index 000000000..ea79ced2e
--- /dev/null
+++ b/gnuradio-core/src/lib/missing/posix_memalign.h
@@ -0,0 +1,42 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef _POSIX_MEMALIGN_H_
+#define _POSIX_MEMALIGN_H_
+
+#include <stdlib.h>
+
+#ifndef HAVE_POSIX_MEMALIGN
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern int posix_memalign (void** memptr, size_t alignment, size_t size);
+
+#ifdef __cplusplus
+};
+#endif
+
+#endif /* ! HAVE_POSIX_MEMALIGN */
+
+#endif /* _POSIX_MEMALIGN_H_ */
diff --git a/gnuradio-core/src/lib/missing/usleep.c b/gnuradio-core/src/lib/missing/usleep.c
new file mode 100644
index 000000000..b1d7dad47
--- /dev/null
+++ b/gnuradio-core/src/lib/missing/usleep.c
@@ -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 3 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/reed-solomon/CMakeLists.txt b/gnuradio-core/src/lib/reed-solomon/CMakeLists.txt
new file mode 100644
index 000000000..f073249f6
--- /dev/null
+++ b/gnuradio-core/src/lib/reed-solomon/CMakeLists.txt
@@ -0,0 +1,62 @@
+# Copyright 2010-2011 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+
+########################################################################
+# This file included, use CMake directory variables
+########################################################################
+#MSVC workaround: we cant have dynamically sized arrays.
+#So ifdef a max array bounds that is larger than NN and NROOTS
+#Its a bit of a hack, but if you look at the code, its so full of ifdefs,
+#and lacks optimization where it should be pre-allocating these arrays.
+if(MSVC)
+ set_source_files_properties(
+ ${CMAKE_CURRENT_SOURCE_DIR}/exercise.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/decode_rs.c
+ PROPERTIES COMPILE_DEFINITIONS "MAX_ARRAY=256;"
+ )
+endif(MSVC)
+
+set(gr_core_rs_sources
+ ${CMAKE_CURRENT_SOURCE_DIR}/encode_rs.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/decode_rs.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/init_rs.c
+)
+
+########################################################################
+# Setup sources and includes
+########################################################################
+list(APPEND gnuradio_core_sources ${gr_core_rs_sources})
+
+install(
+ FILES ${CMAKE_CURRENT_SOURCE_DIR}/rs.h
+ DESTINATION ${GR_INCLUDE_DIR}/gnuradio
+ COMPONENT "core_devel"
+)
+
+########################################################################
+# Register unit tests
+########################################################################
+if(ENABLE_TESTING)
+add_executable(gr_core_rstest
+ ${gr_core_rs_sources}
+ ${CMAKE_CURRENT_SOURCE_DIR}/rstest.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/exercise.c
+)
+add_test(gr-core-reed-solomon-test gr_core_rstest)
+endif(ENABLE_TESTING)
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
index 000000000..8550b4158
--- /dev/null
+++ b/gnuradio-core/src/lib/reed-solomon/Makefile.in.karn
@@ -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
index 000000000..341832dbd
--- /dev/null
+++ b/gnuradio-core/src/lib/reed-solomon/README
@@ -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
index 000000000..f30644ffe
--- /dev/null
+++ b/gnuradio-core/src/lib/reed-solomon/README.karn
@@ -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
index 000000000..0f2bde618
--- /dev/null
+++ b/gnuradio-core/src/lib/reed-solomon/ccsds.h
@@ -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
index 000000000..7b2030a0b
--- /dev/null
+++ b/gnuradio-core/src/lib/reed-solomon/char.h
@@ -0,0 +1,57 @@
+/* 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
+
+#include <gr_core_api.h>
+
+/* 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 unsigned int modnn(struct rs *rs, unsigned 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
+
+GR_CORE_API void ENCODE_RS(void *p,DTYPE *data,DTYPE *parity);
+GR_CORE_API int DECODE_RS(void *p,DTYPE *data,int *eras_pos,int no_eras);
+GR_CORE_API void *INIT_RS(unsigned int symsize,unsigned int gfpoly,unsigned int fcr,
+ unsigned int prim,unsigned int nroots);
+GR_CORE_API 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
index 000000000..f9438cf26
--- /dev/null
+++ b/gnuradio-core/src/lib/reed-solomon/decode_rs.c
@@ -0,0 +1,270 @@
+/* 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;
+#ifdef MAX_ARRAY
+ DTYPE u,q,tmp,num1,num2,den,discr_r;
+ DTYPE lambda[MAX_ARRAY], s[MAX_ARRAY]; /* Err+Eras Locator poly
+ * and syndrome poly */
+ DTYPE b[MAX_ARRAY], t[MAX_ARRAY], omega[MAX_ARRAY];
+ DTYPE root[MAX_ARRAY], reg[MAX_ARRAY], loc[MAX_ARRAY];
+#else
+ 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];
+#endif
+ int syn_error, count;
+
+ /* form the syndromes; i.e., evaluate data(x) at roots of g(x) */
+ for(i=0;(unsigned int)i<NROOTS;i++)
+ s[i] = data[0];
+
+ for(j=1;(unsigned int)j<NN;j++){
+ for(i=0;(unsigned int)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;(unsigned int)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;(unsigned int)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 ((unsigned int)(++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 ; (unsigned int)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; (unsigned int)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;(unsigned int)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; (unsigned int)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; (unsigned int)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 = (int)min((unsigned int)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
index 000000000..2543d3a64
--- /dev/null
+++ b/gnuradio-core/src/lib/reed-solomon/decode_rs_ccsds.c
@@ -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
index 000000000..cd31f32c6
--- /dev/null
+++ b/gnuradio-core/src/lib/reed-solomon/encode_rs.c
@@ -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
+ unsigned 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
index 000000000..a748b3468
--- /dev/null
+++ b/gnuradio-core/src/lib/reed-solomon/encode_rs_ccsds.c
@@ -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
index 000000000..de33a6bff
--- /dev/null
+++ b/gnuradio-core/src/lib/reed-solomon/exercise.c
@@ -0,0 +1,134 @@
+/* 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
+#if MAX_ARRAY
+ DTYPE block[MAX_ARRAY],tblock[MAX_ARRAY];
+ unsigned int i;
+ int errors;
+ int errlocs[MAX_ARRAY];
+ int derrlocs[MAX_ARRAY];
+#else
+ DTYPE block[NN],tblock[NN];
+ unsigned int i;
+ int errors;
+ int errlocs[NN];
+ int derrlocs[NROOTS];
+#endif
+ 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;(unsigned int)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<(unsigned int)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<(unsigned int)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
index 000000000..30091e7bf
--- /dev/null
+++ b/gnuradio-core/src/lib/reed-solomon/fixed.h
@@ -0,0 +1,40 @@
+/* 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
+
+#include <gr_core_api.h>
+
+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
+
+GR_CORE_API void ENCODE_RS(DTYPE *data,DTYPE *parity);
+GR_CORE_API int DECODE_RS(DTYPE *data, int *eras_pos, int no_eras); \ No newline at end of file
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
index 000000000..1e4e4f536
--- /dev/null
+++ b/gnuradio-core/src/lib/reed-solomon/gen_ccsds.c
@@ -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
index 000000000..9dde18917
--- /dev/null
+++ b/gnuradio-core/src/lib/reed-solomon/gen_ccsds_tal.c
@@ -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
index 000000000..4ec77cd72
--- /dev/null
+++ b/gnuradio-core/src/lib/reed-solomon/init_rs.c
@@ -0,0 +1,129 @@
+/* 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 sr,root,iprim;
+ unsigned int i, j;
+
+ if(symsize > 8*sizeof(DTYPE))
+ return NULL; /* Need version with ints rather than chars */
+
+ if(fcr >= (1u<<symsize))
+ return NULL;
+ if(prim == 0 || prim >= (1u<<symsize))
+ return NULL;
+ if(nroots >= (1u<<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
index 000000000..403d68757
--- /dev/null
+++ b/gnuradio-core/src/lib/reed-solomon/int.h
@@ -0,0 +1,55 @@
+/* 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
+
+#include <gr_core_api.h>
+
+/* Reed-Solomon codec control block */
+struct GR_CORE_API 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
+
+GR_CORE_API void ENCODE_RS(void *p,DTYPE *data,DTYPE *parity);
+GR_CORE_API 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);
+GR_CORE_API 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
index 000000000..c3953ce57
--- /dev/null
+++ b/gnuradio-core/src/lib/reed-solomon/rs.3
@@ -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
index 000000000..97e78769e
--- /dev/null
+++ b/gnuradio-core/src/lib/reed-solomon/rs.h
@@ -0,0 +1,31 @@
+#include <gr_core_api.h>
+/* 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 */
+GR_CORE_API void encode_rs_char(void *rs,unsigned char *data,unsigned char *parity);
+GR_CORE_API int decode_rs_char(void *rs,unsigned char *data,int *eras_pos,
+ int no_eras);
+GR_CORE_API void *init_rs_char(unsigned int symsize,unsigned int gfpoly,
+ unsigned int fcr,unsigned int prim,unsigned int nroots);
+GR_CORE_API void free_rs_char(void *rs);
+
+/* General purpose RS codec, integer symbols */
+GR_CORE_API void encode_rs_int(void *rs,int *data,int *parity);
+GR_CORE_API int decode_rs_int(void *rs,int *data,int *eras_pos,int no_eras);
+GR_CORE_API void *init_rs_int(unsigned int symsize,unsigned int gfpoly,unsigned int fcr,
+ unsigned int prim,unsigned int nroots);
+GR_CORE_API void free_rs_int(void *rs);
+
+/* CCSDS standard (255,223) RS codec with conventional (*not* dual-basis)
+ * symbol representation
+ */
+GR_CORE_API void encode_rs_8(unsigned char *data,unsigned char *parity);
+GR_CORE_API 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
index 000000000..d8fc5448a
--- /dev/null
+++ b/gnuradio-core/src/lib/reed-solomon/rstest.c
@@ -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/CMakeLists.txt b/gnuradio-core/src/lib/runtime/CMakeLists.txt
new file mode 100644
index 000000000..5f2c317c4
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/CMakeLists.txt
@@ -0,0 +1,187 @@
+# Copyright 2010-2010 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+
+########################################################################
+# This file included, use CMake directory variables
+########################################################################
+
+########################################################################
+# Control availability of vmcircbuf methods.
+# For now, only allows disabling of shm methods, which cause uncatchable
+# segmentation faults on Cygwin with gcc 4.x (x <= 5)
+# Usage:
+# GR_VMCIRCBUF()
+#
+# Will set TRY_SHM_VMCIRCBUF to 1 by default except on Windows machines.
+# Can manually set with -DTRY_SHM_VMCIRCBUF=0|1
+########################################################################
+
+ if(WIN32)
+ OPTION(TRY_SHM_VMCIRCBUF "Try SHM VMCIRCBUF" OFF)
+ else(WIN32)
+ OPTION(TRY_SHM_VMCIRCBUF "Try SHM VMCIRCBUF" ON)
+ endif(WIN32)
+
+ message(STATUS "TRY_SHM_VMCIRCBUF set to ${TRY_SHM_VMCIRCBUF}.")
+
+ if(TRY_SHM_VMCIRCBUF)
+ add_definitions( -DTRY_SHM_VMCIRCBUF )
+ endif(TRY_SHM_VMCIRCBUF)
+
+########################################################################
+# Append gnuradio-core library sources
+########################################################################
+list(APPEND gnuradio_core_sources
+ #${CMAKE_CURRENT_SOURCE_DIR}/gr_basic_block.cc
+ #${CMAKE_CURRENT_SOURCE_DIR}/gr_flowgraph.cc
+ #${CMAKE_CURRENT_SOURCE_DIR}/gr_flat_flowgraph.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_block.cc
+ #${CMAKE_CURRENT_SOURCE_DIR}/gr_block_detail.cc
+ #${CMAKE_CURRENT_SOURCE_DIR}/gr_block_executor.cc
+ #${CMAKE_CURRENT_SOURCE_DIR}/gr_block_registry.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_hier_block2.cc
+ #${CMAKE_CURRENT_SOURCE_DIR}/gr_hier_block2_detail.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_buffer.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_dispatcher.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_error_handler.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_io_signature.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_local_sighandler.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_message.cc
+ #${CMAKE_CURRENT_SOURCE_DIR}/gr_msg_accepter.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_msg_handler.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_msg_queue.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_pagesize.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_preferences.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_realtime.cc
+ #${CMAKE_CURRENT_SOURCE_DIR}/gr_scheduler.cc
+ #${CMAKE_CURRENT_SOURCE_DIR}/gr_scheduler_sts.cc
+ #${CMAKE_CURRENT_SOURCE_DIR}/gr_scheduler_tpb.cc
+ #${CMAKE_CURRENT_SOURCE_DIR}/gr_single_threaded_scheduler.cc
+ #${CMAKE_CURRENT_SOURCE_DIR}/gr_sptr_magic.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_sync_block.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_sync_decimator.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_sync_interpolator.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_sys_paths.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_top_block.cc
+ #${CMAKE_CURRENT_SOURCE_DIR}/gr_top_block_impl.cc
+ #${CMAKE_CURRENT_SOURCE_DIR}/gr_tpb_detail.cc
+ #${CMAKE_CURRENT_SOURCE_DIR}/gr_tpb_thread_body.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_vmcircbuf.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_vmcircbuf_mmap_shm_open.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_vmcircbuf_mmap_tmpfile.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_vmcircbuf_createfilemapping.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_vmcircbuf_sysv_shm.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_select_handler.cc
+)
+
+########################################################################
+# Append gnuradio-core test sources
+########################################################################
+list(APPEND test_gnuradio_core_sources
+ ${CMAKE_CURRENT_SOURCE_DIR}/qa_gr_block.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/qa_gr_hier_block2.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/qa_gr_hier_block2_derived.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/qa_gr_buffer.cc
+ #${CMAKE_CURRENT_SOURCE_DIR}/qa_gr_flowgraph.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/qa_gr_top_block.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/qa_gr_io_signature.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/qa_gr_vmcircbuf.cc
+ #${CMAKE_CURRENT_SOURCE_DIR}/qa_block_tags.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/qa_runtime.cc
+ #${CMAKE_CURRENT_SOURCE_DIR}/qa_set_msg_handler.cc
+)
+
+########################################################################
+# Install runtime headers
+########################################################################
+install(FILES
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_basic_block.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_flowgraph.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_flat_flowgraph.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_block.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_block_detail.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_block_executor.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_block_registry.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_hier_block2.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_hier_block2_detail.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_buffer.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_complex.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_dispatcher.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_error_handler.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_io_signature.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_local_sighandler.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_message.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_msg_accepter.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_msg_handler.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_msg_queue.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_pagesize.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_preferences.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_realtime.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_runtime_types.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_scheduler.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_scheduler_sts.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_scheduler_tpb.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_select_handler.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_single_threaded_scheduler.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_sptr_magic.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_sync_block.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_sync_decimator.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_sync_interpolator.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_top_block.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_top_block_impl.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_tpb_detail.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_tpb_thread_body.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_timer.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_sys_paths.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_types.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_unittests.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_vmcircbuf.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_tags.h
+ DESTINATION ${GR_INCLUDE_DIR}/gnuradio
+ COMPONENT "core_devel"
+)
+
+########################################################################
+# Install swig headers
+########################################################################
+if(ENABLE_PYTHON)
+install(FILES
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_basic_block.i
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_block.i
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_block_detail.i
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_hier_block2.i
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_buffer.i
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_dispatcher.i
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_error_handler.i
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_io_signature.i
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_message.i
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_msg_handler.i
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_msg_queue.i
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_realtime.i
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_single_threaded_scheduler.i
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_sync_block.i
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_sync_decimator.i
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_sync_interpolator.i
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_tags.i
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_top_block.i
+ ${CMAKE_CURRENT_SOURCE_DIR}/runtime.i
+ DESTINATION ${GR_INCLUDE_DIR}/gnuradio/swig
+ COMPONENT "core_swig"
+)
+endif(ENABLE_PYTHON)
diff --git a/gnuradio-core/src/lib/runtime/gr_basic_block.cc b/gnuradio-core/src/lib/runtime/gr_basic_block.cc
new file mode 100644
index 000000000..6ff57a1d6
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_basic_block.cc
@@ -0,0 +1,227 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006,2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_basic_block.h>
+#include <gr_block_registry.h>
+#include <stdexcept>
+#include <sstream>
+#include <iostream>
+
+using namespace pmt;
+
+static long s_next_id = 0;
+static long s_ncurrently_allocated = 0;
+
+long
+gr_basic_block_ncurrently_allocated()
+{
+ return s_ncurrently_allocated;
+}
+
+gr_basic_block::gr_basic_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_unique_id(s_next_id++),
+ d_symbolic_id(global_block_registry.block_register(this)),
+ d_symbol_name(global_block_registry.register_symbolic_name(this)),
+ d_color(WHITE),
+ message_subscribers(pmt::pmt_make_dict())
+{
+ s_ncurrently_allocated++;
+}
+
+gr_basic_block::~gr_basic_block()
+{
+ s_ncurrently_allocated--;
+ global_block_registry.block_unregister(this);
+}
+
+gr_basic_block_sptr
+gr_basic_block::to_basic_block()
+{
+ return shared_from_this();
+}
+
+void
+gr_basic_block::set_block_alias(std::string name)
+{
+ global_block_registry.register_symbolic_name(this, name);
+}
+
+// ** Message passing interface **
+
+// - register a new input message port
+void
+gr_basic_block::message_port_register_in(pmt::pmt_t port_id)
+{
+ if(!pmt::pmt_is_symbol(port_id)) {
+ throw std::runtime_error("message_port_register_in: bad port id");
+ }
+ msg_queue[port_id] = msg_queue_t();
+ msg_queue_ready[port_id] = boost::shared_ptr<boost::condition_variable>(new boost::condition_variable());
+}
+
+pmt::pmt_t
+gr_basic_block::message_ports_in()
+{
+ pmt::pmt_t port_names = pmt::pmt_make_vector(msg_queue.size(), pmt::PMT_NIL);
+ msg_queue_map_itr itr = msg_queue.begin();
+ for(size_t i = 0; i < msg_queue.size(); i++) {
+ pmt::pmt_vector_set(port_names, i, (*itr).first);
+ itr++;
+ }
+ return port_names;
+}
+
+// - register a new output message port
+void
+gr_basic_block::message_port_register_out(pmt::pmt_t port_id)
+{
+ if(!pmt::pmt_is_symbol(port_id)) {
+ throw std::runtime_error("message_port_register_out: bad port id");
+ }
+ if(pmt::pmt_dict_has_key(message_subscribers, port_id)) {
+ throw std::runtime_error("message_port_register_out: port already in use");
+ }
+ message_subscribers = pmt::pmt_dict_add(message_subscribers, port_id, pmt::PMT_NIL);
+}
+
+pmt::pmt_t
+gr_basic_block::message_ports_out()
+{
+ size_t len = pmt::pmt_length(message_subscribers);
+ pmt::pmt_t port_names = pmt::pmt_make_vector(len, pmt::PMT_NIL);
+ pmt::pmt_t keys = pmt::pmt_dict_keys(message_subscribers);
+ for(size_t i = 0; i < len; i++) {
+ pmt::pmt_vector_set(port_names, i, pmt::pmt_nth(i, keys));
+ }
+ return port_names;
+}
+
+// - publish a message on a message port
+void gr_basic_block::message_port_pub(pmt::pmt_t port_id, pmt::pmt_t msg)
+{
+ if(!pmt::pmt_dict_has_key(message_subscribers, port_id)) {
+ throw std::runtime_error("port does not exist");
+ }
+
+ pmt::pmt_t currlist = pmt::pmt_dict_ref(message_subscribers, port_id, pmt::PMT_NIL);
+ // iterate through subscribers on port
+ while(pmt::pmt_is_pair(currlist)) {
+ pmt::pmt_t target = pmt::pmt_car(currlist);
+
+ pmt::pmt_t block = pmt::pmt_car(target);
+ pmt::pmt_t port = pmt::pmt_cdr(target);
+
+ currlist = pmt::pmt_cdr(currlist);
+ gr_basic_block_sptr blk = global_block_registry.block_lookup(block);
+ //blk->post(msg);
+ blk->post(port, msg);
+ }
+}
+
+// - subscribe to a message port
+void
+gr_basic_block::message_port_sub(pmt::pmt_t port_id, pmt::pmt_t target){
+ if(!pmt::pmt_dict_has_key(message_subscribers, port_id)){
+ std::stringstream ss;
+ ss << "Port does not exist: \"" << pmt::pmt_write_string(port_id) << "\" on block: " << pmt::pmt_write_string(target) << std::endl;
+ throw std::runtime_error(ss.str());
+ }
+ pmt::pmt_t currlist = pmt::pmt_dict_ref(message_subscribers,port_id,pmt::PMT_NIL);
+
+ // ignore re-adds of the same target
+ if(!pmt::pmt_list_has(currlist, target))
+ message_subscribers = pmt::pmt_dict_add(message_subscribers,port_id,pmt::pmt_list_add(currlist,target));
+}
+
+void
+gr_basic_block::message_port_unsub(pmt::pmt_t port_id, pmt::pmt_t target){
+ if(!pmt::pmt_dict_has_key(message_subscribers, port_id)){
+ std::stringstream ss;
+ ss << "Port does not exist: \"" << pmt::pmt_write_string(port_id) << "\" on block: " << pmt::pmt_write_string(target) << std::endl;
+ throw std::runtime_error(ss.str());
+ }
+
+ // ignore unsubs of unknown targets
+ pmt::pmt_t currlist = pmt::pmt_dict_ref(message_subscribers,port_id,pmt::PMT_NIL);
+ message_subscribers = pmt::pmt_dict_add(message_subscribers,port_id,pmt::pmt_list_rm(currlist,target));
+}
+
+void
+gr_basic_block::_post(pmt_t which_port, pmt_t msg)
+{
+ insert_tail(which_port, msg);
+}
+
+void
+gr_basic_block::insert_tail(pmt::pmt_t which_port, pmt::pmt_t msg)
+{
+ gruel::scoped_lock guard(mutex);
+
+ if( (msg_queue.find(which_port) == msg_queue.end()) || (msg_queue_ready.find(which_port) == msg_queue_ready.end())){
+ std::cout << "target port = " << pmt::pmt_symbol_to_string(which_port) << std::endl;
+ throw std::runtime_error("attempted to insert_tail on invalid queue!");
+ }
+
+ msg_queue[which_port].push_back(msg);
+ msg_queue_ready[which_port]->notify_one();
+
+ // wake up thread if BLKD_IN or BLKD_OUT
+ global_block_registry.notify_blk(alias());
+}
+
+pmt_t
+gr_basic_block::delete_head_nowait(pmt::pmt_t which_port)
+{
+ gruel::scoped_lock guard(mutex);
+
+ if (empty_p(which_port)){
+ return pmt::pmt_t();
+ }
+
+ pmt_t m(msg_queue[which_port].front());
+ msg_queue[which_port].pop_front();
+
+ return m;
+}
+
+pmt_t
+gr_basic_block::delete_head_blocking(pmt::pmt_t which_port)
+{
+ gruel::scoped_lock guard(mutex);
+
+ while (empty_p(which_port)){
+ msg_queue_ready[which_port]->wait(guard);
+ }
+
+ pmt_t m(msg_queue[which_port].front());
+ msg_queue[which_port].pop_front();
+ return m;
+}
diff --git a/gnuradio-core/src/lib/runtime/gr_basic_block.h b/gnuradio-core/src/lib/runtime/gr_basic_block.h
new file mode 100644
index 000000000..024159c4c
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_basic_block.h
@@ -0,0 +1,299 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006,2008,2009,2011 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_BASIC_BLOCK_H
+#define INCLUDED_GR_BASIC_BLOCK_H
+
+#include <gr_core_api.h>
+#include <gr_runtime_types.h>
+#include <gr_sptr_magic.h>
+#include <boost/enable_shared_from_this.hpp>
+#include <boost/function.hpp>
+#include <gr_msg_accepter.h>
+#include <string>
+#include <deque>
+#include <map>
+#include <gr_io_signature.h>
+#include <gruel/thread.h>
+#include <boost/foreach.hpp>
+#include <boost/thread/condition_variable.hpp>
+#include <iostream>
+
+/*!
+ * \brief The abstract base class for all signal processing blocks.
+ * \ingroup internal
+ *
+ * Basic blocks are the bare abstraction of an entity that has a name,
+ * a set of inputs and outputs, and a message queue. These are never instantiated
+ * directly; rather, this is the abstract parent class of both gr_hier_block,
+ * which is a recursive container, and gr_block, which implements actual
+ * signal processing functions.
+ */
+
+class GR_CORE_API gr_basic_block : public gr_msg_accepter, public boost::enable_shared_from_this<gr_basic_block>
+{
+ typedef boost::function<void(pmt::pmt_t)> msg_handler_t;
+
+ private:
+
+ //msg_handler_t d_msg_handler;
+ typedef std::map<pmt::pmt_t , msg_handler_t, pmt::pmt_comperator> d_msg_handlers_t;
+ d_msg_handlers_t d_msg_handlers;
+
+ typedef std::deque<pmt::pmt_t> msg_queue_t;
+ typedef std::map<pmt::pmt_t, msg_queue_t, pmt::pmt_comperator> msg_queue_map_t;
+ typedef std::map<pmt::pmt_t, msg_queue_t, pmt::pmt_comperator>::iterator msg_queue_map_itr;
+ std::map<pmt::pmt_t, boost::shared_ptr<boost::condition_variable>, pmt::pmt_comperator> msg_queue_ready;
+
+ gruel::mutex mutex; //< protects all vars
+
+ protected:
+ friend class gr_flowgraph;
+ friend class gr_flat_flowgraph; // TODO: will be redundant
+ friend class gr_tpb_thread_body;
+
+ enum vcolor { WHITE, GREY, BLACK };
+
+ std::string d_name;
+ gr_io_signature_sptr d_input_signature;
+ gr_io_signature_sptr d_output_signature;
+ long d_unique_id;
+ long d_symbolic_id;
+ std::string d_symbol_name;
+ std::string d_symbol_alias;
+ vcolor d_color;
+ msg_queue_map_t msg_queue;
+
+ gr_basic_block(void){} //allows pure virtual interface sub-classes
+
+ //! Protected constructor prevents instantiation by non-derived classes
+ gr_basic_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;
+ }
+
+ /*!
+ * \brief Allow the flowgraph to set for sorting and partitioning
+ */
+ void set_color(vcolor color) { d_color = color; }
+ vcolor color() const { return d_color; }
+
+ /*!
+ * \brief Tests if there is a handler attached to port \p which_port
+ */
+ bool has_msg_handler(pmt::pmt_t which_port) {
+ return (d_msg_handlers.find(which_port) != d_msg_handlers.end());
+ }
+
+ /*
+ * This function is called by the runtime system to dispatch messages.
+ *
+ * The thread-safety guarantees mentioned in set_msg_handler are implemented
+ * by the callers of this method.
+ */
+ virtual void dispatch_msg(pmt::pmt_t which_port, pmt::pmt_t msg)
+ {
+ // AA Update this
+ if(has_msg_handler(which_port)) { // Is there a handler?
+ d_msg_handlers[which_port](msg); // Yes, invoke it.
+ }
+ }
+
+ // Message passing interface
+ pmt::pmt_t message_subscribers;
+
+ public:
+ virtual ~gr_basic_block();
+ long unique_id() const { return d_unique_id; }
+ long symbolic_id() const { return d_symbolic_id; }
+ std::string name() const { return d_name; }
+ std::string symbol_name() const { return d_symbol_name; }
+ gr_io_signature_sptr input_signature() const { return d_input_signature; }
+ gr_io_signature_sptr output_signature() const { return d_output_signature; }
+ gr_basic_block_sptr to_basic_block(); // Needed for Python type coercion
+ bool alias_set() { return !d_symbol_alias.empty(); }
+ std::string alias(){ return alias_set()?d_symbol_alias:symbol_name(); }
+ pmt::pmt_t alias_pmt(){ return pmt::pmt_intern(alias()); }
+ void set_block_alias(std::string name);
+
+ // ** Message passing interface **
+ void message_port_register_in(pmt::pmt_t port_id);
+ void message_port_register_out(pmt::pmt_t port_id);
+ void message_port_pub(pmt::pmt_t port_id, pmt::pmt_t msg);
+ void message_port_sub(pmt::pmt_t port_id, pmt::pmt_t target);
+ void message_port_unsub(pmt::pmt_t port_id, pmt::pmt_t target);
+
+ virtual bool message_port_is_hier(pmt::pmt_t port_id) { (void) port_id; std::cout << "is_hier\n"; return false; }
+ virtual bool message_port_is_hier_in(pmt::pmt_t port_id) { (void) port_id; std::cout << "is_hier_in\n"; return false; }
+ virtual bool message_port_is_hier_out(pmt::pmt_t port_id) { (void) port_id; std::cout << "is_hier_out\n"; return false; }
+
+ /*!
+ * \brief Get input message port names.
+ *
+ * Returns the available input message ports for a block. The
+ * return object is a PMT vector that is filled with PMT symbols.
+ */
+ pmt::pmt_t message_ports_in();
+
+ /*!
+ * \brief Get output message port names.
+ *
+ * Returns the available output message ports for a block. The
+ * return object is a PMT vector that is filled with PMT symbols.
+ */
+ pmt::pmt_t message_ports_out();
+
+ /*!
+ * Accept msg, place in queue, arrange for thread to be awakened if it's not already.
+ */
+ void _post(pmt::pmt_t which_port, pmt::pmt_t msg);
+
+ //! is the queue empty?
+ //bool empty_p(const pmt::pmt_t &which_port) const { return msg_queue[which_port].empty(); }
+ bool empty_p(pmt::pmt_t which_port) {
+ if(msg_queue.find(which_port) == msg_queue.end())
+ throw std::runtime_error("port does not exist!");
+ return msg_queue[which_port].empty();
+ }
+ bool empty_p() {
+ bool rv = true;
+ BOOST_FOREACH(msg_queue_map_t::value_type &i, msg_queue) {
+ rv &= msg_queue[i.first].empty();
+ }
+ return rv;
+ }
+
+ //! How many messages in the queue?
+ size_t nmsgs(pmt::pmt_t which_port) {
+ if(msg_queue.find(which_port) == msg_queue.end())
+ throw std::runtime_error("port does not exist!");
+ return msg_queue[which_port].size();
+ }
+
+ //| Acquires and release the mutex
+ void insert_tail( pmt::pmt_t which_port, pmt::pmt_t msg);
+ /*!
+ * \returns returns pmt at head of queue or pmt_t() if empty.
+ */
+ pmt::pmt_t delete_head_nowait( pmt::pmt_t which_port);
+
+ /*!
+ * \returns returns pmt at head of queue or pmt_t() if empty.
+ */
+ pmt::pmt_t delete_head_blocking( pmt::pmt_t which_port);
+
+ msg_queue_t::iterator get_iterator(pmt::pmt_t which_port){
+ return msg_queue[which_port].begin();
+ }
+
+ void erase_msg(pmt::pmt_t which_port, msg_queue_t::iterator it){
+ msg_queue[which_port].erase(it);
+ }
+
+ virtual bool has_msg_port(pmt::pmt_t which_port){
+ if(msg_queue.find(which_port) != msg_queue.end()){
+ return true;
+ }
+ if(pmt::pmt_dict_has_key(message_subscribers, which_port)){
+ return true;
+ }
+ return false;
+ }
+
+
+ /*!
+ * \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) { (void) ninputs; (void) noutputs; return true; }
+
+ /*!
+ * \brief Set the callback that is fired when messages are available.
+ *
+ * \p msg_handler can be any kind of function pointer or function object
+ * that has the signature:
+ * <pre>
+ * void msg_handler(pmt::pmt msg);
+ * </pre>
+ *
+ * (You may want to use boost::bind to massage your callable into the
+ * correct form. See gr_nop.{h,cc} for an example that sets up a class
+ * method as the callback.)
+ *
+ * Blocks that desire to handle messages must call this method in their
+ * constructors to register the handler that will be invoked when messages
+ * are available.
+ *
+ * If the block inherits from gr_block, the runtime system will ensure that
+ * msg_handler is called in a thread-safe manner, such that work and
+ * msg_handler will never be called concurrently. This allows msg_handler
+ * to update state variables without having to worry about thread-safety
+ * issues with work, general_work or another invocation of msg_handler.
+ *
+ * If the block inherits from gr_hier_block2, the runtime system will
+ * ensure that no reentrant calls are made to msg_handler.
+ */
+ //template <typename T> void set_msg_handler(T msg_handler){
+ // d_msg_handler = msg_handler_t(msg_handler);
+ //}
+ template <typename T> void set_msg_handler(pmt::pmt_t which_port, T msg_handler){
+ if(msg_queue.find(which_port) == msg_queue.end()){
+ throw std::runtime_error("attempt to set_msg_handler() on bad input message port!"); }
+ d_msg_handlers[which_port] = msg_handler_t(msg_handler);
+ }
+};
+
+inline bool operator<(gr_basic_block_sptr lhs, gr_basic_block_sptr rhs)
+{
+ return lhs->unique_id() < rhs->unique_id();
+}
+
+typedef std::vector<gr_basic_block_sptr> gr_basic_block_vector_t;
+typedef std::vector<gr_basic_block_sptr>::iterator gr_basic_block_viter_t;
+
+GR_CORE_API long gr_basic_block_ncurrently_allocated();
+
+inline std::ostream &operator << (std::ostream &os, gr_basic_block_sptr basic_block)
+{
+ os << basic_block->name() << "(" << basic_block->unique_id() << ")";
+ return os;
+}
+
+#endif /* INCLUDED_GR_BASIC_BLOCK_H */
diff --git a/gnuradio-core/src/lib/runtime/gr_basic_block.i b/gnuradio-core/src/lib/runtime/gr_basic_block.i
new file mode 100644
index 000000000..91f3d2cfc
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_basic_block.i
@@ -0,0 +1,62 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+class gr_basic_block;
+typedef boost::shared_ptr<gr_basic_block> gr_basic_block_sptr;
+%template(gr_basic_block_sptr) boost::shared_ptr<gr_basic_block>;
+%import "pmt_swig.i"
+using namespace pmt;
+
+// support vectors of these...
+namespace std {
+ %template(x_vector_gr_basic_block_sptr) vector<gr_basic_block_sptr>;
+};
+
+class gr_basic_block
+{
+protected:
+ gr_basic_block();
+
+public:
+ virtual ~gr_basic_block();
+ std::string name() const;
+ std::string symbol_name() const;
+ gr_io_signature_sptr input_signature() const;
+ gr_io_signature_sptr output_signature() const;
+ long unique_id() const;
+ gr_basic_block_sptr to_basic_block();
+ bool check_topology (int ninputs, int noutputs);
+ std::string alias();
+ void set_block_alias(std::string name);
+ void _post(pmt_t which_port, pmt_t msg);
+ pmt_t message_ports_in();
+ pmt_t message_ports_out();
+};
+
+%rename(block_ncurrently_allocated) gr_basic_block_ncurrently_allocated;
+long gr_basic_block_ncurrently_allocated();
+
+#ifdef SWIGPYTHON
+%pythoncode %{
+gr_basic_block_sptr.__repr__ = lambda self: "<gr_basic_block %s (%d)>" % (self.name(), self.unique_id ())
+%}
+#endif
diff --git a/gnuradio-core/src/lib/runtime/gr_block.cc b/gnuradio-core/src/lib/runtime/gr_block.cc
new file mode 100644
index 000000000..443ac8f64
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_block.cc
@@ -0,0 +1,459 @@
+/*
+ * Copyright 2012-2013 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "pmx_helper.hpp"
+#include <gr_block.h>
+#include <boost/foreach.hpp>
+#include <iostream>
+#include <boost/detail/atomic_count.hpp>
+
+static boost::detail::atomic_count unique_id_pool(0);
+
+gr_block::gr_block(void)
+{
+ //NOP
+}
+
+gr_block::gr_block(
+ const std::string &name,
+ gr_io_signature_sptr input_signature,
+ gr_io_signature_sptr output_signature
+):
+ gras::Block(name),
+ _unique_id(++unique_id_pool),
+ _name(name)
+{
+ //this initializes private vars, order matters
+ this->set_fixed_rate(false);
+ this->set_output_multiple(1);
+ this->set_history(1);
+ this->set_relative_rate(1.0);
+ this->set_decimation(1);
+ this->set_interpolation(1);
+ this->set_tag_propagation_policy(TPP_ALL_TO_ALL);
+ this->set_input_signature(input_signature);
+ this->set_output_signature(output_signature);
+}
+
+gr_io_signature_sptr gr_block::input_signature(void) const
+{
+ return _in_sig;
+}
+
+gr_io_signature_sptr gr_block::output_signature(void) const
+{
+ return _out_sig;
+}
+
+void gr_block::set_input_signature(gr_io_signature_sptr sig)
+{
+ for (size_t i = 0; i < sig->sizeof_stream_items().size(); i++)
+ {
+ this->input_config(i).item_size = sig->sizeof_stream_items().at(i);
+ }
+ _in_sig = sig;
+}
+
+void gr_block::set_output_signature(gr_io_signature_sptr sig)
+{
+ for (size_t i = 0; i < sig->sizeof_stream_items().size(); i++)
+ {
+ this->output_config(i).item_size = sig->sizeof_stream_items().at(i);
+ }
+ _out_sig = sig;
+}
+
+gr_block::~gr_block(void)
+{
+ //NOP
+}
+
+void gr_block::notify_active(void)
+{
+ this->start();
+}
+
+bool gr_block::start(void)
+{
+ return true;
+}
+
+void gr_block::notify_inactive(void)
+{
+ this->stop();
+}
+
+bool gr_block::stop(void)
+{
+ return true;
+}
+
+void gr_block::notify_topology(const size_t num_inputs, const size_t num_outputs)
+{
+ _num_outputs = num_outputs;
+ _fcast_ninput_items.resize(num_inputs);
+ _work_ninput_items.resize(num_inputs);
+ this->check_topology(num_inputs, num_outputs);
+}
+
+bool gr_block::check_topology(int, int)
+{
+ return true;
+}
+
+void gr_block::work(
+ const InputItems &input_items,
+ const OutputItems &output_items
+){
+ _work_io_ptr_mask = 0;
+ #define REALLY_BIG size_t(1 << 30)
+ const size_t num_inputs = input_items.size();
+ const size_t num_outputs = output_items.size();
+
+ //------------------------------------------------------------------
+ //-- initialize input buffers before work
+ //------------------------------------------------------------------
+ size_t num_input_items = input_items.min();
+ if (_enable_fixed_rate) num_input_items -= _input_history_items;
+ for (size_t i = 0; i < num_inputs; i++)
+ {
+ _work_ninput_items[i] = input_items[i].size();
+ _work_io_ptr_mask |= ptrdiff_t(input_items.vec()[i]);
+ if GRAS_UNLIKELY(_enable_fixed_rate and input_items[i].size() <= _input_history_items)
+ {
+ return this->mark_input_fail(i);
+ }
+ }
+
+ //------------------------------------------------------------------
+ //-- initialize output buffers before work
+ //------------------------------------------------------------------
+ size_t num_output_items = output_items.min();
+ num_output_items /= _output_multiple_items;
+ num_output_items *= _output_multiple_items;
+ for (size_t i = 0; i < num_outputs; i++)
+ {
+ _work_io_ptr_mask |= ptrdiff_t(output_items.vec()[i]);
+ }
+
+ //------------------------------------------------------------------
+ //-- calculate the work_noutput_items given:
+ //-- min of num_input_items
+ //-- min of num_output_items
+ //-- relative rate and output multiple items
+ //------------------------------------------------------------------
+ size_t work_noutput_items = num_output_items;
+ if (num_inputs and (_enable_fixed_rate or not num_outputs))
+ {
+ size_t calc_output_items = size_t(num_input_items*_relative_rate);
+ calc_output_items += _output_multiple_items-1;
+ calc_output_items /= _output_multiple_items;
+ calc_output_items *= _output_multiple_items;
+ if (calc_output_items and calc_output_items < work_noutput_items)
+ work_noutput_items = calc_output_items;
+ }
+
+ //------------------------------------------------------------------
+ //-- forecast
+ //------------------------------------------------------------------
+ if (num_inputs or num_outputs)
+ {
+ forecast_again_you_jerk:
+ _fcast_ninput_items = _work_ninput_items; //init for NOP case
+ this->forecast(work_noutput_items, _fcast_ninput_items);
+ for (size_t i = 0; i < input_items.size(); i++)
+ {
+ if GRAS_LIKELY(_fcast_ninput_items[i] <= _work_ninput_items[i]) continue;
+
+ //handle the case of forecast failing
+ if GRAS_UNLIKELY(work_noutput_items <= _output_multiple_items)
+ {
+ return this->mark_input_fail(i);
+ }
+
+ work_noutput_items = work_noutput_items/2; //backoff regime
+ work_noutput_items += _output_multiple_items-1;
+ work_noutput_items /= _output_multiple_items;
+ work_noutput_items *= _output_multiple_items;
+ goto forecast_again_you_jerk;
+ }
+ }
+
+ const int work_ret = this->general_work(
+ work_noutput_items,
+ _work_ninput_items,
+ const_cast<InputItems &>(input_items).vec(),
+ const_cast<OutputItems &>(output_items).vec()
+ );
+
+ if GRAS_LIKELY(work_ret > 0) for (size_t i = 0; i < num_outputs; i++)
+ {
+ this->produce(i, work_ret);
+ }
+
+ if GRAS_UNLIKELY(work_ret == -1) this->mark_done();
+}
+
+static inline unsigned long long myullround(const double x)
+{
+ return (unsigned long long)(x + 0.5);
+}
+
+void gr_block::propagate_tags(const size_t which_input, const gras::TagIter &iter)
+{
+ switch (_tag_prop_policy)
+ {
+ case TPP_DONT: break; //well that was ez
+ case TPP_ALL_TO_ALL:
+ for (size_t out_i = 0; out_i < _num_outputs; out_i++)
+ {
+ BOOST_FOREACH(gras::Tag t, iter)
+ {
+ t.offset = myullround(t.offset * _relative_rate);
+ this->post_output_tag(out_i, t);
+ }
+ }
+ break;
+ case TPP_ONE_TO_ONE:
+ if (which_input < _num_outputs)
+ {
+ BOOST_FOREACH(gras::Tag t, iter)
+ {
+ t.offset = myullround(t.offset * _relative_rate);
+ this->post_output_tag(which_input, t);
+ }
+ }
+ break;
+ };
+}
+
+void gr_block::forecast(int noutput_items, std::vector<int> &ninputs_req)
+{
+ for (size_t i = 0; i < ninputs_req.size(); i++)
+ {
+ ninputs_req[i] = fixed_rate_noutput_to_ninput(noutput_items);
+ }
+}
+
+int gr_block::general_work(
+ int noutput_items,
+ gr_vector_int &ninput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items
+){
+ throw std::runtime_error("gr_block subclasses must overload general_work!");
+}
+
+void gr_block::set_alignment(const size_t)
+{
+ //TODO
+ //probably dont need this since buffers always start aligned
+ //and therefore alignment is always re-acheived
+}
+
+size_t gr_block::fixed_rate_noutput_to_ninput(const size_t noutput_items)
+{
+ return ((decimation()*noutput_items)/interpolation()) + _input_history_items;
+}
+
+void gr_block::set_interpolation(const size_t interp)
+{
+ _interp = interp;
+ this->set_relative_rate(1.0*interp);
+ this->set_output_multiple(interp);
+}
+
+void gr_block::set_decimation(const size_t decim)
+{
+ _decim = decim;
+ this->set_relative_rate(1.0/decim);
+}
+
+unsigned gr_block::history(void) const
+{
+ //implement off-by-one history compat
+ return _input_history_items+1;
+}
+
+void gr_block::set_history(unsigned history)
+{
+ //implement off-by-one history compat
+ if (history == 0) history++;
+ _input_history_items = history-1;
+ this->input_config(0).preload_items = _input_history_items;
+ this->commit_config();
+}
+
+void gr_block::set_fixed_rate(const bool fixed_rate)
+{
+ _enable_fixed_rate = fixed_rate;
+}
+
+bool gr_block::fixed_rate(void) const
+{
+ return _enable_fixed_rate;
+}
+
+void gr_block::_update_input_reserve(void)
+{
+ /*!
+ * Set an input reserve for fixed rate blocks.
+ *
+ * FIXME: Also do this when output multiple is large,
+ * This makes gr-trellis pass under conditions where not fixed rate set,
+ * but the output multiple is so large that default input isnt sufficient.
+ */
+ if (_enable_fixed_rate or _output_multiple_items > 1024)
+ {
+ const size_t reserve = size_t(0.5 + _output_multiple_items/_relative_rate);
+ if (reserve) this->input_config(0).reserve_items = reserve;
+ }
+}
+
+void gr_block::set_output_multiple(const size_t multiple)
+{
+ _output_multiple_items = multiple;
+ this->output_config(0).reserve_items = multiple;
+ this->_update_input_reserve();
+}
+
+size_t gr_block::output_multiple(void) const
+{
+ return _output_multiple_items;
+}
+
+void gr_block::set_relative_rate(double relative_rate)
+{
+ _relative_rate = relative_rate;
+ this->_update_input_reserve();
+}
+
+double gr_block::relative_rate(void) const
+{
+ return _relative_rate;
+}
+
+int gr_block::max_noutput_items(void) const
+{
+ return this->output_config(0).maximum_items;
+}
+
+void gr_block::set_max_noutput_items(int max_items)
+{
+ this->output_config(0).maximum_items = max_items;
+}
+
+void gr_block::unset_max_noutput_items(void)
+{
+ this->set_max_noutput_items(0);
+}
+
+bool gr_block::is_set_max_noutput_items(void) const
+{
+ return this->max_noutput_items() != 0;
+}
+
+static gr_tag_t Tag2gr_tag(const gras::Tag &tag)
+{
+ gr_tag_t t;
+ t.offset = tag.offset;
+ const gras::StreamTag &st = tag.object.as<gras::StreamTag>();
+ t.key = pmt::pmc_to_pmt(st.key);
+ t.value = pmt::pmc_to_pmt(st.val);
+ t.srcid = pmt::pmc_to_pmt(st.src);
+ return t;
+}
+
+static gras::Tag gr_tag2Tag(const gr_tag_t &tag)
+{
+ return gras::Tag
+ (
+ tag.offset,
+ PMC_M(gras::StreamTag(
+ pmt::pmt_to_pmc(tag.key),
+ pmt::pmt_to_pmc(tag.value),
+ pmt::pmt_to_pmc(tag.srcid)
+ ))
+ );
+}
+
+void gr_block::add_item_tag(
+ const size_t which_output, const gr_tag_t &tag
+){
+ this->post_output_tag(which_output, gr_tag2Tag(tag));
+}
+
+void gr_block::add_item_tag(
+ const size_t which_output,
+ uint64_t abs_offset,
+ const pmt::pmt_t &key,
+ const pmt::pmt_t &value,
+ const pmt::pmt_t &srcid
+){
+ gr_tag_t t;
+ t.offset = abs_offset;
+ t.key = key;
+ t.value = value;
+ t.srcid = srcid;
+ this->add_item_tag(which_output, t);
+}
+
+void gr_block::get_tags_in_range(
+ std::vector<gr_tag_t> &tags,
+ const size_t which_input,
+ uint64_t abs_start,
+ uint64_t abs_end,
+ const pmt::pmt_t &key
+){
+ tags.clear();
+ BOOST_FOREACH(const gras::Tag &tag, this->get_input_tags(which_input))
+ {
+ if (tag.offset >= abs_start and tag.offset <= abs_end)
+ {
+ gr_tag_t t = Tag2gr_tag(tag);
+ if (not key or pmt::pmt_equal(t.key, key)) tags.push_back(t);
+ }
+ }
+}
+
+gr_block::tag_propagation_policy_t gr_block::tag_propagation_policy(void)
+{
+ return _tag_prop_policy;
+}
+
+void gr_block::set_tag_propagation_policy(gr_block::tag_propagation_policy_t p)
+{
+ _tag_prop_policy = p;
+}
+
+gras::BufferQueueSptr gr_block::input_buffer_allocator(const size_t, const gras::SBufferConfig &config)
+{
+ if (_input_history_items)
+ {
+ return gras::BufferQueue::make_circ(config, 32/*many*/);
+ }
+ return gras::BufferQueueSptr();
+}
+
+gras::BufferQueueSptr gr_block::output_buffer_allocator(const size_t which, const gras::SBufferConfig &config)
+{
+ return gras::Block::output_buffer_allocator(which, config);
+}
diff --git a/gnuradio-core/src/lib/runtime/gr_block.h b/gnuradio-core/src/lib/runtime/gr_block.h
new file mode 100644
index 000000000..bd085100b
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_block.h
@@ -0,0 +1,437 @@
+/*
+ * Copyright 2012-2013 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GNURADIO_GR_BLOCK_H
+#define INCLUDED_GNURADIO_GR_BLOCK_H
+
+#include <gr_core_api.h>
+#include <gras/block.hpp>
+#include <gr_io_signature.h>
+#include <gr_types.h>
+#include <gr_tags.h>
+#include <string>
+#include <deque>
+#include <map>
+#include <boost/foreach.hpp>
+#include <gruel/thread.h>
+#include <gr_sptr_magic.h>
+
+struct GR_CORE_API gr_block : gras::Block
+{
+
+ gr_block(void);
+
+ gr_block(
+ const std::string &name,
+ gr_io_signature_sptr input_signature,
+ gr_io_signature_sptr output_signature
+ );
+
+ long unique_id(void) const{return _unique_id;}
+ std::string name(void) const{return _name;}
+ long _unique_id;
+ std::string _name;
+
+ virtual ~gr_block(void);
+
+ gr_io_signature_sptr input_signature(void) const;
+ gr_io_signature_sptr output_signature(void) const;
+
+ void set_input_signature(gr_io_signature_sptr sig);
+ void set_output_signature(gr_io_signature_sptr sig);
+
+ virtual bool check_topology(int ninputs, int noutputs);
+
+ //! Overload me! I am the forecast
+ virtual void forecast(int, std::vector<int> &);
+
+ //! Return options for the work call
+ enum
+ {
+ WORK_CALLED_PRODUCE = -2,
+ WORK_DONE = -1
+ };
+
+ /*!
+ * \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
+ );
+
+ virtual bool start(void);
+ virtual bool stop(void);
+
+ //! Call during work to consume items
+ void consume_each(const int how_many_items);
+
+ void consume(const size_t i, const int how_many_items);
+
+ void produce(const size_t o, const int how_many_items);
+
+ //! Get absolute count of all items consumed on the given input port
+ uint64_t nitems_read(const size_t which_input = 0);
+
+ //! Get absolute count of all items produced on the given output port
+ uint64_t nitems_written(const size_t which_output = 0);
+
+ void add_item_tag(
+ const size_t which_output, const gr_tag_t &tag
+ );
+
+ void add_item_tag(
+ const size_t which_output,
+ uint64_t abs_offset,
+ const pmt::pmt_t &key,
+ const pmt::pmt_t &value,
+ const pmt::pmt_t &srcid=pmt::PMT_F
+ );
+
+ void get_tags_in_range(
+ std::vector<gr_tag_t> &tags,
+ const size_t which_input,
+ uint64_t abs_start,
+ uint64_t abs_end,
+ const pmt::pmt_t &key = pmt::pmt_t()
+ );
+
+ void set_alignment(const size_t alignment);
+
+ bool is_unaligned(void);
+
+ size_t fixed_rate_noutput_to_ninput(const size_t noutput_items);
+
+ size_t interpolation(void) const;
+
+ void set_interpolation(const size_t);
+
+ size_t decimation(void) const;
+
+ void set_decimation(const size_t);
+
+ int max_noutput_items(void) const;
+
+ void set_max_noutput_items(int);
+
+ void unset_max_noutput_items(void);
+
+ bool is_set_max_noutput_items(void) const;
+
+ /*******************************************************************
+ * Deal with input and output port configuration
+ ******************************************************************/
+
+ unsigned history(void) const;
+
+ void set_history(unsigned history);
+
+ /*!
+ * Enable fixed rate logic.
+ * When enabled, relative rate is assumed to be set,
+ * and forecast is automatically called.
+ * Also, consume will be called automatically.
+ */
+ void set_fixed_rate(const bool fixed_rate);
+
+ //! Get the fixed rate setting
+ bool fixed_rate(void) const;
+
+ /*!
+ * The relative rate can be thought of as interpolation/decimation.
+ * In other words, relative rate is the ratio of output items to input items.
+ */
+ void set_relative_rate(const double relative_rate);
+
+ //! Get the relative rate setting
+ double relative_rate(void) const;
+
+ /*!
+ * The output multiple setting controls work output buffer sizes.
+ * Buffers will be number of items modulo rounted to the multiple.
+ */
+ void set_output_multiple(const size_t multiple);
+
+ //! Get the output multiple setting
+ size_t output_multiple(void) const;
+
+ /*******************************************************************
+ * Deal with tag handling and tag configuration
+ ******************************************************************/
+
+ enum tag_propagation_policy_t
+ {
+ TPP_DONT = 0,
+ TPP_ALL_TO_ALL = 1,
+ TPP_ONE_TO_ONE = 2
+ };
+
+ tag_propagation_policy_t tag_propagation_policy(void);
+
+ void set_tag_propagation_policy(tag_propagation_policy_t p);
+
+ ///////////// TODO //////////////////////
+ void set_max_output_buffer(long){}
+ void set_max_output_buffer(int, long){}
+ long max_output_buffer(size_t){return 0;}
+ void set_min_output_buffer(long){}
+ void set_min_output_buffer(int, long){}
+ long min_output_buffer(size_t){return 0;}
+
+ ///////////// ALIAS stuff - is it used? //////////////////////
+ std::string d_symbol_alias;
+ std::string d_symbol_name;
+ std::string symbol_name() const { return d_symbol_name; }
+ bool alias_set() { return !d_symbol_alias.empty(); }
+ std::string alias(){ return alias_set()?d_symbol_alias:symbol_name(); }
+ pmt::pmt_t alias_pmt(){ return pmt::pmt_intern(alias()); }
+ void set_block_alias(std::string name){d_symbol_alias = name;}
+
+ ///////////// MSG stuff not implemented //////////////////////
+ typedef std::deque<pmt::pmt_t> msg_queue_t;
+ typedef std::map<pmt::pmt_t, msg_queue_t, pmt::pmt_comperator> msg_queue_map_t;
+ typedef std::map<pmt::pmt_t, msg_queue_t, pmt::pmt_comperator>::iterator msg_queue_map_itr;
+ msg_queue_map_t msg_queue;
+ pmt::pmt_t message_subscribers;
+
+ typedef boost::function<void(pmt::pmt_t)> msg_handler_t;
+ typedef std::map<pmt::pmt_t , msg_handler_t, pmt::pmt_comperator> d_msg_handlers_t;
+ d_msg_handlers_t d_msg_handlers;
+
+ template <typename T> void set_msg_handler(pmt::pmt_t which_port, T msg_handler){}
+
+ void message_port_register_in(pmt::pmt_t /*port_id*/){}
+ void message_port_register_out(pmt::pmt_t /*port_id*/){}
+ void message_port_pub(pmt::pmt_t /*port_id*/, pmt::pmt_t /*msg*/){}
+ void message_port_sub(pmt::pmt_t /*port_id*/, pmt::pmt_t /*target*/){}
+ void message_port_unsub(pmt::pmt_t /*port_id*/, pmt::pmt_t /*target*/){}
+
+ virtual bool message_port_is_hier(pmt::pmt_t port_id) { (void) port_id; /*std::cout << "is_hier\n";*/ return false; }
+ virtual bool message_port_is_hier_in(pmt::pmt_t port_id) { (void) port_id; /*std::cout << "is_hier_in\n";*/ return false; }
+ virtual bool message_port_is_hier_out(pmt::pmt_t port_id) { (void) port_id; /*std::cout << "is_hier_out\n";*/ return false; }
+
+ /*!
+ * \brief Get input message port names.
+ *
+ * Returns the available input message ports for a block. The
+ * return object is a PMT vector that is filled with PMT symbols.
+ */
+ pmt::pmt_t message_ports_in(){return pmt::PMT_NIL;}
+
+ /*!
+ * \brief Get output message port names.
+ *
+ * Returns the available output message ports for a block. The
+ * return object is a PMT vector that is filled with PMT symbols.
+ */
+ pmt::pmt_t message_ports_out(){return pmt::PMT_NIL;}
+
+ //! is the queue empty?
+ bool empty_p(pmt::pmt_t which_port) {
+ if(msg_queue.find(which_port) == msg_queue.end())
+ throw std::runtime_error("port does not exist!");
+ return msg_queue[which_port].empty();
+ }
+ bool empty_p() {
+ bool rv = true;
+ BOOST_FOREACH(msg_queue_map_t::value_type &i, msg_queue){ rv &= msg_queue[i.first].empty(); }
+ return rv;
+ }
+
+ //| Acquires and release the mutex
+ void insert_tail( pmt::pmt_t /*which_port*/, pmt::pmt_t /*msg*/){}
+ /*!
+ * \returns returns pmt at head of queue or pmt_t() if empty.
+ */
+ pmt::pmt_t delete_head_nowait( pmt::pmt_t /*which_port*/){return pmt::PMT_NIL;}
+
+ /*!
+ * \returns returns pmt at head of queue or pmt_t() if empty.
+ */
+ pmt::pmt_t delete_head_blocking( pmt::pmt_t /*which_port*/){return pmt::PMT_NIL;}
+
+ msg_queue_t::iterator get_iterator(pmt::pmt_t which_port){
+ return msg_queue[which_port].begin();
+ }
+
+ void erase_msg(pmt::pmt_t which_port, msg_queue_t::iterator it){
+ msg_queue[which_port].erase(it);
+ }
+
+ virtual bool has_msg_port(pmt::pmt_t which_port){
+ if(msg_queue.find(which_port) != msg_queue.end()){
+ return true;
+ }
+ if(pmt::pmt_dict_has_key(message_subscribers, which_port)){
+ return true;
+ }
+ return false;
+ }
+
+ /*!
+ * \brief Tests if there is a handler attached to port \p which_port
+ */
+ bool has_msg_handler(pmt::pmt_t which_port) {
+ return (d_msg_handlers.find(which_port) != d_msg_handlers.end());
+ }
+
+ /*
+ * This function is called by the runtime system to dispatch messages.
+ *
+ * The thread-safety guarantees mentioned in set_msg_handler are implemented
+ * by the callers of this method.
+ */
+ virtual void dispatch_msg(pmt::pmt_t which_port, pmt::pmt_t msg)
+ {
+ // AA Update this
+ if(has_msg_handler(which_port)) { // Is there a handler?
+ d_msg_handlers[which_port](msg); // Yes, invoke it.
+ }
+ }
+
+ /*! Used by block's setters and work functions to make
+ * setting/resetting of parameters thread-safe.
+ *
+ * Used by calling gruel::scoped_lock l(d_setlock);
+ */
+ gruel::mutex d_setlock;
+
+ // ----------------------------------------------------------------------------
+ // Functions to handle thread affinity
+ std::vector<int> d_affinity; // thread affinity proc. mask
+
+ /*!
+ * \brief Set the thread's affinity to processor core \p n.
+ *
+ * \param mask a vector of unsigned ints of the core numbers available to this block.
+ */
+ void set_processor_affinity(const std::vector<int> &mask){d_affinity=mask;}
+
+ /*!
+ * \brief Remove processor affinity to a specific core.
+ */
+ void unset_processor_affinity(){}
+
+ /*!
+ * \brief Get the current processor affinity.
+ */
+ std::vector<int> processor_affinity() { return d_affinity; }
+
+ ///////////////// private vars //////////////////////
+
+ gr_vector_int _work_ninput_items;
+ gr_vector_int _fcast_ninput_items;
+ size_t _num_outputs;
+ ptrdiff_t _work_io_ptr_mask;
+ size_t _output_multiple_items;
+ double _relative_rate;
+ bool _enable_fixed_rate;
+ size_t _input_history_items;
+ tag_propagation_policy_t _tag_prop_policy;
+ size_t _interp, _decim;
+ gr_io_signature_sptr _in_sig, _out_sig;
+
+ ///////////////// the Block overloads //////////////////////
+
+ //! implements work -> calls general work
+ void work(const InputItems &, const OutputItems &);
+
+ //! notifications of new topological commits
+ void notify_topology(const size_t, const size_t);
+
+ //! start notification
+ void notify_active(void);
+
+ //! stop notification
+ void notify_inactive(void);
+
+ //! implements tag_propagation_policy()
+ virtual void propagate_tags(const size_t, const gras::TagIter &);
+
+ void _update_input_reserve(void);
+
+ gras::BufferQueueSptr input_buffer_allocator(const size_t, const gras::SBufferConfig &);
+ gras::BufferQueueSptr output_buffer_allocator(const size_t, const gras::SBufferConfig &);
+
+};
+
+typedef boost::shared_ptr<gr_block> gr_block_sptr;
+
+GRAS_FORCE_INLINE void gr_block::consume_each(const int how_many_items)
+{
+ if GRAS_UNLIKELY(how_many_items < 0) return;
+ gras::Block::consume(size_t(how_many_items));
+}
+
+GRAS_FORCE_INLINE void gr_block::consume(const size_t i, const int how_many_items)
+{
+ if GRAS_UNLIKELY(how_many_items < 0) return;
+ gras::Block::consume(i, size_t(how_many_items));
+}
+
+GRAS_FORCE_INLINE void gr_block::produce(const size_t o, const int how_many_items)
+{
+ if GRAS_UNLIKELY(how_many_items < 0) return;
+ gras::Block::produce(o, size_t(how_many_items));
+}
+
+GRAS_FORCE_INLINE uint64_t gr_block::nitems_read(const size_t which_input)
+{
+ return Block::get_consumed(which_input);
+}
+
+GRAS_FORCE_INLINE uint64_t gr_block::nitems_written(const size_t which_output)
+{
+ return Block::get_produced(which_output);
+}
+
+GRAS_FORCE_INLINE size_t gr_block::interpolation(void) const
+{
+ return _interp;
+}
+
+GRAS_FORCE_INLINE size_t gr_block::decimation(void) const
+{
+ return _decim;
+}
+
+GRAS_FORCE_INLINE bool gr_block::is_unaligned(void)
+{
+ //TODO
+ //probably dont need this since volk dispatcher checks alignment
+ //32 byte aligned is good enough for you
+ return (_work_io_ptr_mask & ptrdiff_t(GRAS_MAX_ALIGNMENT-1)) != 0;
+}
+
+#endif /*INCLUDED_GNURADIO_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
index 000000000..a53489f9a
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_block.i
@@ -0,0 +1,93 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+%include <gr_basic_block.i>
+
+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 : public gr_basic_block {
+ protected:
+ gr_block (const std::string &name,
+ gr_io_signature_sptr input_signature,
+ gr_io_signature_sptr output_signature);
+
+ public:
+
+ virtual ~gr_block ();
+
+ unsigned history () const;
+
+ int output_multiple () const;
+ double relative_rate () const;
+
+ bool start();
+ bool stop();
+
+ uint64_t nitems_read(unsigned int which_input);
+ uint64_t nitems_written(unsigned int which_output);
+
+ // Methods to manage the block's max_noutput_items size.
+ int max_noutput_items();
+ void set_max_noutput_items(int m);
+ void unset_max_noutput_items();
+ bool is_set_max_noutput_items();
+
+ // Methods to manage block's min/max buffer sizes.
+ long max_output_buffer(int i);
+ void set_max_output_buffer(long max_output_buffer);
+ void set_max_output_buffer(int port, long max_output_buffer);
+ long min_output_buffer(int i);
+ void set_min_output_buffer(long min_output_buffer);
+ void set_min_output_buffer(int port, long min_output_buffer);
+
+ // Methods to access performance counters
+ float pc_noutput_items();
+ float pc_noutput_items_var();
+ float pc_nproduced();
+ float pc_nproduced_var();
+ float pc_input_buffers_full(int which);
+ float pc_input_buffers_full_var(int which);
+ std::vector<float> pc_input_buffers_full();
+ std::vector<float> pc_input_buffers_full_var();
+ float pc_output_buffers_full(int which);
+ float pc_output_buffers_full_var(int which);
+ std::vector<float> pc_output_buffers_full();
+ std::vector<float> pc_output_buffers_full_var();
+ float pc_work_time();
+ float pc_work_time_var();
+
+ // Methods to manage processor affinity.
+ void set_processor_affinity(const std::vector<int> &mask);
+ void unset_processor_affinity();
+ std::vector<int> processor_affinity();
+
+ // internal use
+ gr_block_detail_sptr detail () const { return d_detail; }
+ void set_detail (gr_block_detail_sptr detail) { d_detail = detail; }
+};
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
index 000000000..4922ea083
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_block_detail.cc
@@ -0,0 +1,414 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2009,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_block_detail.h>
+#include <gr_buffer.h>
+#include <iostream>
+
+using namespace pmt;
+
+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_produce_or(0),
+ d_ninputs (ninputs), d_noutputs (noutputs),
+ d_input (ninputs), d_output (noutputs),
+ d_done (false),
+ d_avg_noutput_items(0),
+ d_var_noutput_items(0),
+ d_avg_nproduced(0),
+ d_var_nproduced(0),
+ d_avg_input_buffers_full(ninputs, 0),
+ d_var_input_buffers_full(ninputs, 0),
+ d_avg_output_buffers_full(noutputs, 0),
+ d_var_output_buffers_full(noutputs, 0),
+ d_avg_work_time(0),
+ d_var_work_time(0),
+ d_pc_counter(0)
+{
+ 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 (int which_output, int how_many_items)
+{
+ if (how_many_items > 0){
+ d_output[which_output]->update_write_pointer (how_many_items);
+ d_produce_or |= how_many_items;
+ }
+}
+
+void
+gr_block_detail::produce_each (int how_many_items)
+{
+ if (how_many_items > 0) {
+ for (int i = 0; i < noutputs (); i++) {
+ d_output[i]->update_write_pointer (how_many_items);
+ }
+ d_produce_or |= how_many_items;
+ }
+}
+
+
+uint64_t
+gr_block_detail::nitems_read(unsigned int which_input)
+{
+ if(which_input >= d_ninputs)
+ throw std::invalid_argument ("gr_block_detail::n_input_items");
+ return d_input[which_input]->nitems_read();
+}
+
+uint64_t
+gr_block_detail::nitems_written(unsigned int which_output)
+{
+ if(which_output >= d_noutputs)
+ throw std::invalid_argument ("gr_block_detail::n_output_items");
+ return d_output[which_output]->nitems_written();
+}
+
+void
+gr_block_detail::add_item_tag(unsigned int which_output, const gr_tag_t &tag)
+{
+ if(!pmt_is_symbol(tag.key)) {
+ throw pmt_wrong_type("gr_block_detail::add_item_tag key", tag.key);
+ }
+ else {
+ // Add tag to gr_buffer's deque tags
+ d_output[which_output]->add_item_tag(tag);
+ }
+}
+
+void
+gr_block_detail::remove_item_tag(unsigned int which_input, const gr_tag_t &tag)
+{
+ if(!pmt_is_symbol(tag.key)) {
+ throw pmt_wrong_type("gr_block_detail::add_item_tag key", tag.key);
+ }
+ else {
+ // Add tag to gr_buffer's deque tags
+ d_input[which_input]->buffer()->remove_item_tag(tag);
+ }
+}
+
+void
+gr_block_detail::get_tags_in_range(std::vector<gr_tag_t> &v,
+ unsigned int which_input,
+ uint64_t abs_start,
+ uint64_t abs_end)
+{
+ // get from gr_buffer_reader's deque of tags
+ d_input[which_input]->get_tags_in_range(v, abs_start, abs_end);
+}
+
+void
+gr_block_detail::get_tags_in_range(std::vector<gr_tag_t> &v,
+ unsigned int which_input,
+ uint64_t abs_start,
+ uint64_t abs_end,
+ const pmt_t &key)
+{
+ std::vector<gr_tag_t> found_items;
+
+ v.resize(0);
+
+ // get from gr_buffer_reader's deque of tags
+ d_input[which_input]->get_tags_in_range(found_items, abs_start, abs_end);
+
+ // Filter further by key name
+ pmt_t itemkey;
+ std::vector<gr_tag_t>::iterator itr;
+ for(itr = found_items.begin(); itr != found_items.end(); itr++) {
+ itemkey = (*itr).key;
+ if(pmt_eqv(key, itemkey)) {
+ v.push_back(*itr);
+ }
+ }
+}
+
+void
+gr_block_detail::set_processor_affinity(const std::vector<int> &mask)
+{
+ if(threaded) {
+ try {
+ gruel::thread_bind_to_processor(thread, mask);
+ }
+ catch (std::runtime_error e) {
+ std::cerr << "set_processor_affinity: invalid mask." << std::endl;;
+ }
+ }
+}
+
+void
+gr_block_detail::unset_processor_affinity()
+{
+ if(threaded) {
+ gruel::thread_unbind(thread);
+ }
+}
+
+void
+gr_block_detail::start_perf_counters()
+{
+ d_start_of_work = gruel::high_res_timer_now();
+}
+
+void
+gr_block_detail::stop_perf_counters(int noutput_items, int nproduced)
+{
+ d_end_of_work = gruel::high_res_timer_now();
+ gruel::high_res_timer_type diff = d_end_of_work - d_start_of_work;
+
+ if(d_pc_counter == 0) {
+ d_avg_work_time = diff;
+ d_var_work_time = 0;
+ d_avg_nproduced = nproduced;
+ d_var_nproduced = 0;
+ d_avg_noutput_items = noutput_items;
+ d_var_noutput_items = 0;
+ for(size_t i=0; i < d_input.size(); i++) {
+ float pfull = static_cast<float>(d_input[i]->items_available()) /
+ static_cast<float>(d_input[i]->max_possible_items_available());
+ d_avg_input_buffers_full[i] = pfull;
+ d_var_input_buffers_full[i] = 0;
+ }
+ for(size_t i=0; i < d_output.size(); i++) {
+ gruel::scoped_lock guard(*d_output[i]->mutex());
+ float pfull = 1.0f - static_cast<float>(d_output[i]->space_available()) /
+ static_cast<float>(d_output[i]->bufsize());
+ d_avg_output_buffers_full[i] = pfull;
+ d_var_output_buffers_full[i] = 0;
+ }
+ }
+ else {
+ float d = diff - d_avg_work_time;
+ d_avg_work_time = d_avg_work_time + d/d_pc_counter;
+ d_var_work_time = d_var_work_time + d*d;
+
+ d = nproduced - d_avg_nproduced;
+ d_avg_nproduced = d_avg_nproduced + d/d_pc_counter;
+ d_var_nproduced = d_var_nproduced + d*d;
+
+ d = noutput_items - d_avg_noutput_items;
+ d_avg_noutput_items = d_avg_noutput_items + d/d_pc_counter;
+ d_var_noutput_items = d_var_noutput_items + d*d;
+
+ for(size_t i=0; i < d_input.size(); i++) {
+ float pfull = static_cast<float>(d_input[i]->items_available()) /
+ static_cast<float>(d_input[i]->max_possible_items_available());
+
+ d = pfull - d_avg_input_buffers_full[i];
+ d_avg_input_buffers_full[i] = d_avg_input_buffers_full[i] + d/d_pc_counter;
+ d_var_input_buffers_full[i] = d_var_input_buffers_full[i] + d*d;
+ }
+
+ for(size_t i=0; i < d_output.size(); i++) {
+ gruel::scoped_lock guard(*d_output[i]->mutex());
+ float pfull = 1.0f - static_cast<float>(d_output[i]->space_available()) /
+ static_cast<float>(d_output[i]->bufsize());
+
+ d = pfull - d_avg_output_buffers_full[i];
+ d_avg_output_buffers_full[i] = d_avg_output_buffers_full[i] + d/d_pc_counter;
+ d_var_output_buffers_full[i] = d_var_output_buffers_full[i] + d*d;
+ }
+ }
+
+ d_pc_counter++;
+}
+
+void
+gr_block_detail::reset_perf_counters()
+{
+ d_pc_counter = 0;
+}
+
+float
+gr_block_detail::pc_noutput_items()
+{
+ return d_avg_noutput_items;
+}
+
+float
+gr_block_detail::pc_nproduced()
+{
+ return d_avg_nproduced;
+}
+
+float
+gr_block_detail::pc_input_buffers_full(size_t which)
+{
+ if(which < d_avg_input_buffers_full.size())
+ return d_avg_input_buffers_full[which];
+ else
+ return 0;
+}
+
+std::vector<float>
+gr_block_detail::pc_input_buffers_full()
+{
+ return d_avg_input_buffers_full;
+}
+
+float
+gr_block_detail::pc_output_buffers_full(size_t which)
+{
+ if(which < d_avg_output_buffers_full.size())
+ return d_avg_output_buffers_full[which];
+ else
+ return 0;
+}
+
+std::vector<float>
+gr_block_detail::pc_output_buffers_full()
+{
+ return d_avg_output_buffers_full;
+}
+
+float
+gr_block_detail::pc_work_time()
+{
+ return d_avg_work_time;
+}
+
+
+float
+gr_block_detail::pc_noutput_items_var()
+{
+ return d_var_noutput_items/(d_pc_counter-1);
+}
+
+float
+gr_block_detail::pc_nproduced_var()
+{
+ return d_var_nproduced/(d_pc_counter-1);
+}
+
+float
+gr_block_detail::pc_input_buffers_full_var(size_t which)
+{
+ if(which < d_avg_input_buffers_full.size())
+ return d_var_input_buffers_full[which]/(d_pc_counter-1);
+ else
+ return 0;
+}
+
+std::vector<float>
+gr_block_detail::pc_input_buffers_full_var()
+{
+ std::vector<float> var(d_avg_input_buffers_full.size(), 0);
+ for(size_t i = 0; i < d_avg_input_buffers_full.size(); i++)
+ var[i] = d_avg_input_buffers_full[i]/(d_pc_counter-1);
+ return var;
+}
+
+float
+gr_block_detail::pc_output_buffers_full_var(size_t which)
+{
+ if(which < d_avg_output_buffers_full.size())
+ return d_var_output_buffers_full[which]/(d_pc_counter-1);
+ else
+ return 0;
+}
+
+std::vector<float>
+gr_block_detail::pc_output_buffers_full_var()
+{
+ std::vector<float> var(d_avg_output_buffers_full.size(), 0);
+ for(size_t i = 0; i < d_avg_output_buffers_full.size(); i++)
+ var[i] = d_avg_output_buffers_full[i]/(d_pc_counter-1);
+ return var;
+}
+
+float
+gr_block_detail::pc_work_time_var()
+{
+ return d_var_work_time/(d_pc_counter-1);
+}
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
index 000000000..15d85135a
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_block_detail.h
@@ -0,0 +1,235 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2009,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more 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., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_BLOCK_DETAIL_H
+#define INCLUDED_GR_BLOCK_DETAIL_H
+
+#include <gr_core_api.h>
+#include <gr_runtime_types.h>
+#include <gr_tpb_detail.h>
+#include <gr_tags.h>
+#include <gruel/high_res_timer.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_CORE_API 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);
+
+ /*!
+ * \brief Tell the scheduler \p how_many_items were produced on output stream \p which_output.
+ */
+ void produce (int which_output, int how_many_items);
+
+ /*!
+ * \brief Tell the scheduler \p how_many_items were produced on each output stream.
+ */
+ void produce_each (int how_many_items);
+
+ // Return the number of items read on input stream which_input
+ uint64_t nitems_read(unsigned int which_input);
+
+ // Return the number of items written on output stream which_output
+ uint64_t nitems_written(unsigned int which_output);
+
+
+ /*!
+ * \brief Adds a new tag to the given output stream.
+ *
+ * Calls gr_buffer::add_item_tag(),
+ * which appends the tag onto its deque.
+ *
+ * \param which_output an integer of which output stream to attach the tag
+ * \param tag the tag object to add
+ */
+ void add_item_tag(unsigned int which_output, const gr_tag_t &tag);
+
+ /*!
+ * \brief Removes a tag from the given input stream.
+ *
+ * Calls gr_buffer::remove_item_tag(), which removes the tag from its deque.
+ *
+ * \param which_input an integer of which input stream to remove the tag from
+ * \param tag the tag object to add
+ */
+ void remove_item_tag(unsigned int which_input, const gr_tag_t &tag);
+
+ /*!
+ * \brief Given a [start,end), returns a vector of all tags in the range.
+ *
+ * Pass-through function to gr_buffer_reader to get a vector of tags
+ * in given range. Range of counts is from start to end-1.
+ *
+ * Tags are tuples of:
+ * (item count, source id, key, value)
+ *
+ * \param v a vector reference to return tags into
+ * \param which_input an integer of which input stream to pull from
+ * \param abs_start a uint64 count of the start of the range of interest
+ * \param abs_end a uint64 count of the end of the range of interest
+ */
+ void get_tags_in_range(std::vector<gr_tag_t> &v,
+ unsigned int which_input,
+ uint64_t abs_start,
+ uint64_t abs_end);
+
+ /*!
+ * \brief Given a [start,end), returns a vector of all tags in the range
+ * with a given key.
+ *
+ * Calls get_tags_in_range(which_input, abs_start, abs_end) to get a vector of
+ * tags from the buffers. This function then provides a secondary filter to
+ * the tags to extract only tags with the given 'key'.
+ *
+ * Tags are tuples of:
+ * (item count, source id, key, value)
+ *
+ * \param v a vector reference to return tags into
+ * \param which_input an integer of which input stream to pull from
+ * \param abs_start a uint64 count of the start of the range of interest
+ * \param abs_end a uint64 count of the end of the range of interest
+ * \param key a PMT symbol to select only tags of this key
+ */
+ void get_tags_in_range(std::vector<gr_tag_t> &v,
+ unsigned int which_input,
+ uint64_t abs_start,
+ uint64_t abs_end,
+ const pmt::pmt_t &key);
+
+ /*!
+ * \brief Set core affinity of block to the cores in the vector mask.
+ *
+ * \param mask a vector of ints of the core numbers available to this block.
+ */
+ void set_processor_affinity(const std::vector<int> &mask);
+
+ /*!
+ * \brief Unset core affinity.
+ */
+ void unset_processor_affinity();
+
+ bool threaded; // set if thread is currently running.
+ gruel::gr_thread_t thread; // portable thread handle
+
+ void start_perf_counters();
+ void stop_perf_counters(int noutput_items, int nproduced);
+ void reset_perf_counters();
+
+ // Calls to get performance counter items
+ float pc_noutput_items();
+ float pc_nproduced();
+ float pc_input_buffers_full(size_t which);
+ std::vector<float> pc_input_buffers_full();
+ float pc_output_buffers_full(size_t which);
+ std::vector<float> pc_output_buffers_full();
+ float pc_work_time();
+
+ float pc_noutput_items_var();
+ float pc_nproduced_var();
+ float pc_input_buffers_full_var(size_t which);
+ std::vector<float> pc_input_buffers_full_var();
+ float pc_output_buffers_full_var(size_t which);
+ std::vector<float> pc_output_buffers_full_var();
+ float pc_work_time_var();
+
+ gr_tpb_detail d_tpb; // used by thread-per-block scheduler
+ int d_produce_or;
+
+ // ----------------------------------------------------------------------------
+
+ 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;
+
+ // Performance counters
+ float d_avg_noutput_items;
+ float d_var_noutput_items;
+ float d_avg_nproduced;
+ float d_var_nproduced;
+ std::vector<float> d_avg_input_buffers_full;
+ std::vector<float> d_var_input_buffers_full;
+ std::vector<float> d_avg_output_buffers_full;
+ std::vector<float> d_var_output_buffers_full;
+ gruel::high_res_timer_type d_start_of_work, d_end_of_work;
+ float d_avg_work_time;
+ float d_var_work_time;
+ float d_pc_counter;
+
+ gr_block_detail (unsigned int ninputs, unsigned int noutputs);
+
+ friend struct gr_tpb_detail;
+
+ friend GR_CORE_API gr_block_detail_sptr
+ gr_make_block_detail (unsigned int ninputs, unsigned int noutputs);
+};
+
+GR_CORE_API gr_block_detail_sptr
+gr_make_block_detail (unsigned int ninputs, unsigned int noutputs);
+
+GR_CORE_API 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
index 000000000..74ff46360
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_block_detail.i
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+class 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_block_executor.cc b/gnuradio-core/src/lib/runtime/gr_block_executor.cc
new file mode 100644
index 000000000..e070f3c50
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_block_executor.cc
@@ -0,0 +1,487 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2008,2009,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_block_executor.h>
+#include <gr_block.h>
+#include <gr_block_detail.h>
+#include <gr_buffer.h>
+#include <gr_prefs.h>
+#include <boost/thread.hpp>
+#include <boost/format.hpp>
+#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;
+
+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_noutput_items)
+{
+ int min_space = std::numeric_limits<int>::max();
+ if (min_noutput_items == 0)
+ min_noutput_items = 1;
+ for (int i = 0; i < d->noutputs (); i++){
+ gruel::scoped_lock guard(*d->output(i)->mutex());
+ int avail_n = round_down(d->output(i)->space_available(), output_multiple);
+ int best_n = round_down(d->output(i)->bufsize()/2, output_multiple);
+ if (best_n < min_noutput_items)
+ throw std::runtime_error("Buffer too small for min_noutput_items");
+ int n = std::min(avail_n, best_n);
+ if (n < min_noutput_items){ // 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;
+}
+
+static bool
+propagate_tags(gr_block::tag_propagation_policy_t policy, gr_block_detail *d,
+ const std::vector<uint64_t> &start_nitems_read, double rrate,
+ std::vector<gr_tag_t> &rtags)
+{
+ // Move tags downstream
+ // if a sink, we don't need to move downstream
+ if(d->sink_p()) {
+ return true;
+ }
+
+ switch(policy) {
+ case gr_block::TPP_DONT:
+ return true;
+ break;
+ case gr_block::TPP_ALL_TO_ALL:
+ // every tag on every input propogates to everyone downstream
+ for(int i = 0; i < d->ninputs(); i++) {
+ d->get_tags_in_range(rtags, i, start_nitems_read[i],
+ d->nitems_read(i));
+
+ std::vector<gr_tag_t>::iterator t;
+ if(rrate == 1.0) {
+ for(t = rtags.begin(); t != rtags.end(); t++) {
+ for(int o = 0; o < d->noutputs(); o++)
+ d->output(o)->add_item_tag(*t);
+ }
+ }
+ else {
+ for(t = rtags.begin(); t != rtags.end(); t++) {
+ gr_tag_t new_tag = *t;
+ new_tag.offset *= rrate;
+ for(int o = 0; o < d->noutputs(); o++)
+ d->output(o)->add_item_tag(new_tag);
+ }
+ }
+ }
+ break;
+ case gr_block::TPP_ONE_TO_ONE:
+ // tags from input i only go to output i
+ // this requires d->ninputs() == d->noutputs; this is checked when this
+ // type of tag-propagation system is selected in gr_block_detail
+ if(d->ninputs() == d->noutputs()) {
+ for(int i = 0; i < d->ninputs(); i++) {
+ d->get_tags_in_range(rtags, i, start_nitems_read[i],
+ d->nitems_read(i));
+
+ std::vector<gr_tag_t>::iterator t;
+ for(t = rtags.begin(); t != rtags.end(); t++) {
+ gr_tag_t new_tag = *t;
+ new_tag.offset *= rrate;
+ d->output(i)->add_item_tag(new_tag);
+ }
+ }
+ }
+ else {
+ std::cerr << "Error: gr_block_executor: propagation_policy 'ONE-TO-ONE' requires ninputs == noutputs" << std::endl;
+ return false;
+ }
+
+ break;
+ default:
+ return true;
+ }
+ return true;
+}
+
+gr_block_executor::gr_block_executor (gr_block_sptr block, int max_noutput_items)
+ : d_block(block), d_log(0), d_max_noutput_items(max_noutput_items)
+{
+ if (ENABLE_LOGGING){
+ std::string name = str(boost::format("sst-%03d.log") % which_scheduler++);
+ d_log = new std::ofstream(name.c_str());
+ std::unitbuf(*d_log); // make it unbuffered...
+ *d_log << "gr_block_executor: "
+ << d_block << std::endl;
+ }
+
+#ifdef GR_PERFORMANCE_COUNTERS
+ gr_prefs *prefs = gr_prefs::singleton();
+ d_use_pc = prefs->get_bool("PerfCounters", "on", false);
+#endif /* GR_PERFORMANCE_COUNTERS */
+
+ d_block->start(); // enable any drivers, etc.
+}
+
+gr_block_executor::~gr_block_executor ()
+{
+ if (ENABLE_LOGGING)
+ delete d_log;
+
+ d_block->stop(); // stop any drivers, etc.
+}
+
+gr_block_executor::state
+gr_block_executor::run_one_iteration()
+{
+ int noutput_items;
+ int max_items_avail;
+ int max_noutput_items = d_max_noutput_items;
+ int new_alignment=0;
+ int alignment_state=-1;
+
+ gr_block *m = d_block.get();
+ gr_block_detail *d = m->detail().get();
+
+ LOG(*d_log << std::endl << m);
+
+ if (d->done()){
+ assert(0);
+ return DONE;
+ }
+
+ if (d->source_p ()){
+ d_ninput_items_required.resize (0);
+ d_ninput_items.resize (0);
+ d_input_items.resize (0);
+ d_input_done.resize(0);
+ d_output_items.resize (d->noutputs ());
+ d_start_nitems_read.resize(0);
+
+ // determine the minimum available output space
+ noutput_items = min_available_space (d, m->output_multiple (), m->min_noutput_items ());
+ noutput_items = std::min(noutput_items, max_noutput_items);
+ 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");
+ return BLKD_OUT;
+ }
+
+ goto setup_call_to_work; // jump to common code
+ }
+
+ else if (d->sink_p ()){
+ d_ninput_items_required.resize (d->ninputs ());
+ d_ninput_items.resize (d->ninputs ());
+ d_input_items.resize (d->ninputs ());
+ d_input_done.resize(d->ninputs());
+ d_output_items.resize (0);
+ d_start_nitems_read.resize(d->ninputs());
+ LOG(*d_log << " sink\n");
+
+ max_items_avail = 0;
+ for (int i = 0; i < d->ninputs (); i++){
+ {
+ /*
+ * Acquire the mutex and grab local copies of items_available and done.
+ */
+ gruel::scoped_lock guard(*d->input(i)->mutex());
+ d_ninput_items[i] = d->input(i)->items_available();
+ d_input_done[i] = d->input(i)->done();
+ }
+
+ LOG(*d_log << " d_ninput_items[" << i << "] = " << d_ninput_items[i] << std::endl);
+ LOG(*d_log << " d_input_done[" << i << "] = " << d_input_done[i] << std::endl);
+
+ if (d_ninput_items[i] < m->output_multiple() && d_input_done[i])
+ goto were_done;
+
+ max_items_avail = std::max (max_items_avail, d_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 ());
+ noutput_items = std::min(noutput_items, max_noutput_items);
+ 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");
+ return BLKD_IN;
+ }
+
+ goto try_again; // Jump to code shared with regular case.
+ }
+
+ else {
+ // do the regular thing
+ d_ninput_items_required.resize (d->ninputs ());
+ d_ninput_items.resize (d->ninputs ());
+ d_input_items.resize (d->ninputs ());
+ d_input_done.resize(d->ninputs());
+ d_output_items.resize (d->noutputs ());
+ d_start_nitems_read.resize(d->ninputs());
+
+ max_items_avail = 0;
+ for (int i = 0; i < d->ninputs (); i++){
+ {
+ /*
+ * Acquire the mutex and grab local copies of items_available and done.
+ */
+ gruel::scoped_lock guard(*d->input(i)->mutex());
+ d_ninput_items[i] = d->input(i)->items_available ();
+ d_input_done[i] = d->input(i)->done();
+ }
+ max_items_avail = std::max (max_items_avail, d_ninput_items[i]);
+ }
+
+ // determine the minimum available output space
+ noutput_items = min_available_space (d, m->output_multiple (), m->min_noutput_items ());
+ 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");
+ return BLKD_OUT;
+ }
+
+ 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);
+
+ // only test this if we specifically set the output_multiple
+ if(m->output_multiple_set())
+ reqd_noutput_items = round_down(reqd_noutput_items, m->output_multiple());
+
+ if (reqd_noutput_items > 0 && reqd_noutput_items <= noutput_items)
+ noutput_items = reqd_noutput_items;
+
+ // if we need this many outputs, overrule the max_noutput_items setting
+ max_noutput_items = std::max(m->output_multiple(), max_noutput_items);
+ }
+ noutput_items = std::min(noutput_items, max_noutput_items);
+
+ // Check if we're still unaligned; use up items until we're
+ // aligned again. Otherwise, make sure we set the alignment
+ // requirement.
+ if(!m->output_multiple_set()) {
+ if(m->is_unaligned()) {
+ // When unaligned, don't just set noutput_items to the remaining
+ // samples to meet alignment; this causes too much overhead in
+ // requiring a premature call back here. Set the maximum amount
+ // of samples to handle unalignment and get us back aligned.
+ if(noutput_items >= m->unaligned()) {
+ noutput_items = round_up(noutput_items, m->alignment()) \
+ - (m->alignment() - m->unaligned());
+ new_alignment = 0;
+ }
+ else {
+ new_alignment = m->unaligned() - noutput_items;
+ }
+ alignment_state = 0;
+ }
+ else if(noutput_items < m->alignment()) {
+ // if we don't have enough for an aligned call, keep track of
+ // misalignment, set unaligned flag, and proceed.
+ new_alignment = m->alignment() - noutput_items;
+ m->set_unaligned(new_alignment);
+ m->set_is_unaligned(true);
+ alignment_state = 1;
+ }
+ else {
+ // enough to round down to the nearest alignment and process.
+ noutput_items = round_down(noutput_items, m->alignment());
+ m->set_is_unaligned(false);
+ alignment_state = 2;
+ }
+ }
+
+ // ask the block how much input they need to produce noutput_items
+ m->forecast (noutput_items, d_ninput_items_required);
+
+ // See if we've got sufficient input available
+
+ int i;
+ for (i = 0; i < d->ninputs (); i++)
+ if (d_ninput_items_required[i] > d_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_done[i]) // If the upstream block is done, we're done
+ goto were_done;
+
+ // Is it possible to ever fulfill this request?
+ if (d_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 = "
+ << d_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;
+ }
+
+ // If we were made unaligned in this round but return here without
+ // processing; reset the unalignment claim before next entry.
+ if(alignment_state == 1) {
+ m->set_unaligned(0);
+ m->set_is_unaligned(false);
+ }
+ return BLKD_IN;
+ }
+
+ // 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++)
+ d_input_items[i] = d->input(i)->read_pointer();
+
+ setup_call_to_work:
+
+ d->d_produce_or = 0;
+ for (int i = 0; i < d->noutputs (); i++)
+ d_output_items[i] = d->output(i)->write_pointer();
+
+ // determine where to start looking for new tags
+ for (int i = 0; i < d->ninputs(); i++)
+ d_start_nitems_read[i] = d->nitems_read(i);
+
+#ifdef GR_PERFORMANCE_COUNTERS
+ if(d_use_pc)
+ d->start_perf_counters();
+#endif /* GR_PERFORMANCE_COUNTERS */
+
+ // Do the actual work of the block
+ int n = m->general_work (noutput_items, d_ninput_items,
+ d_input_items, d_output_items);
+
+#ifdef GR_PERFORMANCE_COUNTERS
+ if(d_use_pc)
+ d->stop_perf_counters(noutput_items, n);
+#endif /* GR_PERFORMANCE_COUNTERS */
+
+ LOG(*d_log << " general_work: noutput_items = " << noutput_items
+ << " result = " << n << std::endl);
+
+ // Adjust number of unaligned items left to process
+ if(m->is_unaligned()) {
+ m->set_unaligned(new_alignment);
+ m->set_is_unaligned(m->unaligned() != 0);
+ }
+
+ if(!propagate_tags(m->tag_propagation_policy(), d,
+ d_start_nitems_read, m->relative_rate(),
+ d_returned_tags))
+ goto were_done;
+
+ if (n == gr_block::WORK_DONE)
+ goto were_done;
+
+ if (n != gr_block::WORK_CALLED_PRODUCE)
+ d->produce_each (n); // advance write pointers
+
+ if (d->d_produce_or > 0) // block produced something
+ return READY;
+
+ // We didn't produce any output even though we called general_work.
+ // We have (most likely) consumed some input.
+
+ /*
+ // If this is a source, it's broken.
+ if (d->source_p()){
+ std::cerr << "gr_block_executor: source " << m
+ << " produced no output. We're marking it DONE.\n";
+ // FIXME maybe we ought to raise an exception...
+ goto were_done;
+ }
+ */
+
+ // Have the caller try again...
+ return READY_NO_OUTPUT;
+ }
+ assert (0);
+
+ were_done:
+ LOG(*d_log << " were_done\n");
+ d->set_done (true);
+ return DONE;
+}
diff --git a/gnuradio-core/src/lib/runtime/gr_block_executor.h b/gnuradio-core/src/lib/runtime/gr_block_executor.h
new file mode 100644
index 000000000..fb7f9c269
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_block_executor.h
@@ -0,0 +1,78 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2008 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_BLOCK_EXECUTOR_H
+#define INCLUDED_GR_BLOCK_EXECUTOR_H
+
+#include <gr_core_api.h>
+#include <gr_runtime_types.h>
+#include <fstream>
+#include <gr_tags.h>
+
+//class gr_block_executor;
+//typedef boost::shared_ptr<gr_block_executor> gr_block_executor_sptr;
+
+
+/*!
+ * \brief Manage the execution of a single block.
+ * \ingroup internal
+ */
+
+class GR_CORE_API gr_block_executor {
+protected:
+ gr_block_sptr d_block; // The block we're trying to run
+ std::ofstream *d_log;
+
+ // These are allocated here so we don't have to on each iteration
+
+ gr_vector_int d_ninput_items_required;
+ gr_vector_int d_ninput_items;
+ gr_vector_const_void_star d_input_items;
+ std::vector<bool> d_input_done;
+ gr_vector_void_star d_output_items;
+ std::vector<uint64_t> d_start_nitems_read; //stores where tag counts are before work
+ std::vector<gr_tag_t> d_returned_tags;
+ int d_max_noutput_items;
+
+#ifdef GR_PERFORMANCE_COUNTERS
+ bool d_use_pc;
+#endif /* GR_PERFORMANCE_COUNTERS */
+
+ public:
+ gr_block_executor(gr_block_sptr block, int max_noutput_items=100000);
+ ~gr_block_executor ();
+
+ enum state {
+ READY, // We made progress; everything's cool.
+ READY_NO_OUTPUT, // We consumed some input, but produced no output.
+ BLKD_IN, // no progress; we're blocked waiting for input data.
+ BLKD_OUT, // no progress; we're blocked waiting for output buffer space.
+ DONE, // we're done; don't call me again.
+ };
+
+ /*
+ * \brief Run one iteration.
+ */
+ state run_one_iteration();
+};
+
+#endif /* INCLUDED_GR_BLOCK_EXECUTOR_H */
diff --git a/gnuradio-core/src/lib/runtime/gr_block_registry.cc b/gnuradio-core/src/lib/runtime/gr_block_registry.cc
new file mode 100644
index 000000000..ff23d97eb
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_block_registry.cc
@@ -0,0 +1,76 @@
+#include <gr_basic_block.h>
+#include <gr_block_registry.h>
+#include <gr_tpb_detail.h>
+#include <gr_block_detail.h>
+#include <gr_block.h>
+#include <stdio.h>
+
+gr_block_registry global_block_registry;
+
+gr_block_registry::gr_block_registry(){
+ d_ref_map = pmt::pmt_make_dict();
+}
+
+long gr_block_registry::block_register(gr_basic_block* block){
+ if(d_map.find(block->name()) == d_map.end()){
+ d_map[block->name()] = blocksubmap_t();
+ d_map[block->name()][0] = block;
+ return 0;
+ } else {
+ for(size_t i=0; i<=d_map[block->name()].size(); i++){
+ if(d_map[block->name()].find(i) == d_map[block->name()].end()){
+ d_map[block->name()][i] = block;
+ return i;
+ }
+ }
+ }
+ throw std::runtime_error("should not reach this");
+}
+
+void gr_block_registry::block_unregister(gr_basic_block* block){
+ d_map[block->name()].erase( d_map[block->name()].find(block->symbolic_id()));
+ d_ref_map = pmt::pmt_dict_delete(d_ref_map, pmt::pmt_intern(block->symbol_name()));
+ if(block->alias_set()){
+ d_ref_map = pmt::pmt_dict_delete(d_ref_map, pmt::pmt_intern(block->alias()));
+ }
+}
+
+std::string gr_block_registry::register_symbolic_name(gr_basic_block* block){
+ std::stringstream ss;
+ ss << block->name() << block->symbolic_id();
+ //std::cout << "register_symbolic_name: " << ss.str() << std::endl;
+ register_symbolic_name(block, ss.str());
+ return ss.str();
+}
+
+void gr_block_registry::register_symbolic_name(gr_basic_block* block, std::string name){
+ if(pmt_dict_has_key(d_ref_map, pmt::pmt_intern(name))){
+ throw std::runtime_error("symbol already exists, can not re-use!");
+ }
+ d_ref_map = pmt_dict_add(d_ref_map, pmt::pmt_intern(name), pmt::pmt_make_any(block));
+}
+
+gr_basic_block_sptr gr_block_registry::block_lookup(pmt::pmt_t symbol){
+ pmt::pmt_t ref = pmt_dict_ref(d_ref_map, symbol, pmt::PMT_NIL);
+ if(pmt::pmt_eq(ref, pmt::PMT_NIL)){
+ throw std::runtime_error("block lookup failed! block not found!");
+ }
+ gr_basic_block* blk = boost::any_cast<gr_basic_block*>( pmt::pmt_any_ref(ref) );
+ return blk->shared_from_this();
+}
+
+
+void gr_block_registry::register_primitive(std::string blk, gr_block* ref){
+ primitive_map[blk] = ref;
+}
+
+void gr_block_registry::unregister_primitive(std::string blk){
+ primitive_map.erase(primitive_map.find(blk));
+}
+
+void gr_block_registry::notify_blk(std::string blk){
+ if(primitive_map.find(blk) == primitive_map.end()){ return; }
+ if(primitive_map[blk]->detail().get())
+ primitive_map[blk]->detail()->d_tpb.notify_msg();
+}
+
diff --git a/gnuradio-core/src/lib/runtime/gr_block_registry.h b/gnuradio-core/src/lib/runtime/gr_block_registry.h
new file mode 100644
index 000000000..3a9d9868f
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_block_registry.h
@@ -0,0 +1,43 @@
+#ifndef GR_BLOCK_REGISTRY_H
+#define GR_BLOCK_REGISTRY_H
+
+#include <map>
+#include <gr_basic_block.h>
+
+#ifndef GR_BASIC_BLOCK_H
+class gr_basic_block;
+class gr_block;
+#endif
+
+class gr_block_registry {
+ public:
+ gr_block_registry();
+
+ long block_register(gr_basic_block* block);
+ void block_unregister(gr_basic_block* block);
+
+ std::string register_symbolic_name(gr_basic_block* block);
+ void register_symbolic_name(gr_basic_block* block, std::string name);
+
+ gr_basic_block_sptr block_lookup(pmt::pmt_t symbol);
+
+ void register_primitive(std::string blk, gr_block* ref);
+ void unregister_primitive(std::string blk);
+ void notify_blk(std::string blk);
+
+ private:
+
+ //typedef std::map< long, gr_basic_block_sptr > blocksubmap_t;
+ typedef std::map< long, gr_basic_block* > blocksubmap_t;
+ typedef std::map< std::string, blocksubmap_t > blockmap_t;
+
+ blockmap_t d_map;
+ pmt::pmt_t d_ref_map;
+ std::map< std::string, gr_block*> primitive_map;
+
+};
+
+extern gr_block_registry global_block_registry;
+
+#endif
+
diff --git a/gnuradio-core/src/lib/runtime/gr_buffer.cc b/gnuradio-core/src/lib/runtime/gr_buffer.cc
new file mode 100644
index 000000000..369959d65
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_buffer.cc
@@ -0,0 +1,347 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2009,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_buffer.h>
+#include <gr_vmcircbuf.h>
+#include <gr_math.h>
+#include <stdexcept>
+#include <iostream>
+#include <assert.h>
+#include <algorithm>
+#include <boost/math/common_factor_rt.hpp>
+
+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 / boost::math::gcd (type_size, page_size);
+}
+
+
+gr_buffer::gr_buffer (int nitems, size_t sizeof_item, gr_block_sptr link)
+ : d_base (0), d_bufsize (0), d_vmcircbuf (0),
+ d_sizeof_item (sizeof_item), d_link(link),
+ d_write_index (0), d_abs_write_offset(0), d_done (false),
+ d_last_min_items_read(0)
+{
+ 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, gr_block_sptr link)
+{
+ return gr_buffer_sptr (new gr_buffer (nitems, sizeof_item, link));
+}
+
+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 ()
+{
+ 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 ();
+ uint64_t min_items_read = d_readers[0]->nitems_read();
+ for (size_t i = 1; i < d_readers.size (); i++) {
+ most_data = std::max (most_data, d_readers[i]->items_available ());
+ min_items_read = std::min(min_items_read, d_readers[i]->nitems_read());
+ }
+
+ if(min_items_read != d_last_min_items_read) {
+ prune_tags(d_last_min_items_read);
+ d_last_min_items_read = min_items_read;
+ }
+
+ // 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)
+{
+ gruel::scoped_lock guard(*mutex());
+ d_write_index = index_add (d_write_index, nitems);
+ d_abs_write_offset += nitems;
+}
+
+void
+gr_buffer::set_done (bool done)
+{
+ gruel::scoped_lock guard(*mutex());
+ d_done = done;
+}
+
+gr_buffer_reader_sptr
+gr_buffer_add_reader (gr_buffer_sptr buf, int nzero_preload, gr_block_sptr link)
+{
+ if (nzero_preload < 0)
+ throw std::invalid_argument("gr_buffer_add_reader: nzero_preload must be >= 0");
+
+ gr_buffer_reader_sptr r (new gr_buffer_reader (buf,
+ buf->index_sub(buf->d_write_index,
+ nzero_preload),
+ link));
+ 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);
+}
+
+void
+gr_buffer::add_item_tag(const gr_tag_t &tag)
+{
+ gruel::scoped_lock guard(*mutex());
+ d_item_tags.push_back(tag);
+}
+
+void
+gr_buffer::remove_item_tag(const gr_tag_t &tag)
+{
+ gruel::scoped_lock guard(*mutex());
+ for (std::deque<gr_tag_t>::iterator it = d_item_tags.begin(); it != d_item_tags.end(); ++it) {
+ if (*it == tag) {
+ d_item_tags.erase(it);
+ break;
+ }
+ }
+}
+
+void
+gr_buffer::prune_tags(uint64_t max_time)
+{
+ /* NOTE: this function _should_ lock the mutex before editing
+ d_item_tags. In practice, this function is only called at
+ runtime by min_available_space in gr_block_executor.cc,
+ which locks the mutex itself.
+
+ If this function is used elsewhere, remember to lock the
+ buffer's mutex al la the scoped_lock line below.
+ */
+ //gruel::scoped_lock guard(*mutex());
+ std::deque<gr_tag_t>::iterator itr = d_item_tags.begin();
+
+ uint64_t item_time;
+
+ // Since tags are not guarenteed to be in any particular order,
+ // we need to erase here instead of pop_front. An erase in the
+ // middle invalidates all iterators; so this resets the iterator
+ // to find more. Mostly, we wil be erasing from the front and
+ // therefore lose little time this way.
+ while(itr != d_item_tags.end()) {
+ item_time = (*itr).offset;
+ if(item_time < max_time) {
+ d_item_tags.erase(itr);
+ itr = d_item_tags.begin();
+ }
+ else
+ itr++;
+ }
+}
+
+long
+gr_buffer_ncurrently_allocated ()
+{
+ return s_buffer_count;
+}
+
+// ----------------------------------------------------------------------------
+
+gr_buffer_reader::gr_buffer_reader(gr_buffer_sptr buffer, unsigned int read_index,
+ gr_block_sptr link)
+ : d_buffer(buffer), d_read_index(read_index), d_abs_read_offset(0), d_link(link)
+{
+ 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)
+{
+ gruel::scoped_lock guard(*mutex());
+ d_read_index = d_buffer->index_add (d_read_index, nitems);
+ d_abs_read_offset += nitems;
+}
+
+void
+gr_buffer_reader::get_tags_in_range(std::vector<gr_tag_t> &v,
+ uint64_t abs_start,
+ uint64_t abs_end)
+{
+ gruel::scoped_lock guard(*mutex());
+
+ v.resize(0);
+ std::deque<gr_tag_t>::iterator itr = d_buffer->get_tags_begin();
+
+ uint64_t item_time;
+ while(itr != d_buffer->get_tags_end()) {
+ item_time = (*itr).offset;
+
+ if((item_time >= abs_start) && (item_time < abs_end)) {
+ v.push_back(*itr);
+ }
+
+ itr++;
+ }
+}
+
+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
index 000000000..28ea97726
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_buffer.h
@@ -0,0 +1,309 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2009,2010,2011 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_BUFFER_H
+#define INCLUDED_GR_BUFFER_H
+
+#include <gr_core_api.h>
+#include <gr_runtime_types.h>
+#include <boost/weak_ptr.hpp>
+#include <gruel/thread.h>
+#include <gr_tags.h>
+#include <deque>
+
+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.
+ *
+ * \param nitems is the minimum number of items the buffer will hold.
+ * \param sizeof_item is the size of an item in bytes.
+ * \param link is the block that writes to this buffer.
+ */
+GR_CORE_API gr_buffer_sptr gr_make_buffer (int nitems, size_t sizeof_item, gr_block_sptr link=gr_block_sptr());
+
+
+/*!
+ * \brief Single writer, multiple reader fifo.
+ * \ingroup internal
+ */
+class GR_CORE_API gr_buffer {
+ public:
+
+ virtual ~gr_buffer ();
+
+ /*!
+ * \brief return number of items worth of space available for writing
+ */
+ int space_available ();
+
+ /*!
+ * \brief return size of this buffer in items
+ */
+ int bufsize() const { return d_bufsize; }
+
+ /*!
+ * \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);
+ bool done () const { return d_done; }
+
+ /*!
+ * \brief Return the block that writes to this buffer.
+ */
+ gr_block_sptr link() { return gr_block_sptr(d_link); }
+
+ size_t nreaders() const { return d_readers.size(); }
+ gr_buffer_reader* reader(size_t index) { return d_readers[index]; }
+
+ gruel::mutex *mutex() { return &d_mutex; }
+
+ uint64_t nitems_written() { return d_abs_write_offset; }
+
+ size_t get_sizeof_item() { return d_sizeof_item; }
+
+ /*!
+ * \brief Adds a new tag to the buffer.
+ *
+ * \param tag the new tag
+ */
+ void add_item_tag(const gr_tag_t &tag);
+
+ /*!
+ * \brief Removes an existing tag from the buffer.
+ *
+ * If no such tag is found, does nothing.
+ *
+ * \param tag the tag that needs to be removed
+ */
+ void remove_item_tag(const gr_tag_t &tag);
+
+ /*!
+ * \brief Removes all tags before \p max_time from buffer
+ *
+ * \param max_time the time (item number) to trim up until.
+ */
+ void prune_tags(uint64_t max_time);
+
+ std::deque<gr_tag_t>::iterator get_tags_begin() { return d_item_tags.begin(); }
+ std::deque<gr_tag_t>::iterator get_tags_end() { return d_item_tags.end(); }
+
+ // -------------------------------------------------------------------------
+
+ private:
+
+ friend class gr_buffer_reader;
+ friend GR_CORE_API gr_buffer_sptr gr_make_buffer (int nitems, size_t sizeof_item, gr_block_sptr link);
+ friend GR_CORE_API gr_buffer_reader_sptr gr_buffer_add_reader (gr_buffer_sptr buf, int nzero_preload, gr_block_sptr link);
+
+ 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
+ std::vector<gr_buffer_reader *> d_readers;
+ boost::weak_ptr<gr_block> d_link; // block that writes to this buffer
+
+ //
+ // The mutex protects d_write_index, d_abs_write_offset, d_done, d_item_tags
+ // and the d_read_index's and d_abs_read_offset's in the buffer readers.
+ //
+ gruel::mutex d_mutex;
+ unsigned int d_write_index; // in items [0,d_bufsize)
+ uint64_t d_abs_write_offset; // num items written since the start
+ bool d_done;
+ std::deque<gr_tag_t> d_item_tags;
+ uint64_t d_last_min_items_read;
+
+ 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.
+ *
+ * \param nitems is the minimum number of items the buffer will hold.
+ * \param sizeof_item is the size of an item in bytes.
+ * \param link is the block that writes to this buffer.
+ *
+ * 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, gr_block_sptr link);
+
+ /*!
+ * \brief disassociate \p reader from this buffer
+ */
+ void drop_reader (gr_buffer_reader *reader);
+
+};
+
+/*!
+ * \brief Create a new gr_buffer_reader and attach it to buffer \p buf
+ * \param buf is the buffer the \p gr_buffer_reader reads from.
+ * \param nzero_preload -- number of zero items to "preload" into buffer.
+ * \param link is the block that reads from the buffer using this gr_buffer_reader.
+ */
+GR_CORE_API gr_buffer_reader_sptr
+gr_buffer_add_reader (gr_buffer_sptr buf, int nzero_preload, gr_block_sptr link=gr_block_sptr());
+
+//! returns # of gr_buffers currently allocated
+GR_CORE_API long gr_buffer_ncurrently_allocated ();
+
+
+// ---------------------------------------------------------------------------
+
+/*!
+ * \brief How we keep track of the readers of a gr_buffer.
+ * \ingroup internal
+ */
+
+class GR_CORE_API gr_buffer_reader {
+ public:
+
+ ~gr_buffer_reader ();
+
+ /*!
+ * \brief Return number of items available for reading.
+ */
+ int items_available () const;
+
+ /*!
+ * \brief Return buffer this reader reads from.
+ */
+ gr_buffer_sptr buffer () const { return d_buffer; }
+
+
+ /*!
+ * \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 (); }
+
+ gruel::mutex *mutex() { return d_buffer->mutex(); }
+
+
+ uint64_t nitems_read() { return d_abs_read_offset; }
+
+ size_t get_sizeof_item() { return d_buffer->get_sizeof_item(); }
+
+ /*!
+ * \brief Return the block that reads via this reader.
+ *
+ */
+ gr_block_sptr link() { return gr_block_sptr(d_link); }
+
+
+ /*!
+ * \brief Given a [start,end), returns a vector all tags in the range.
+ *
+ * Get a vector of tags in given range. Range of counts is from start to end-1.
+ *
+ * Tags are tuples of:
+ * (item count, source id, key, value)
+ *
+ * \param v a vector reference to return tags into
+ * \param abs_start a uint64 count of the start of the range of interest
+ * \param abs_end a uint64 count of the end of the range of interest
+ */
+ void get_tags_in_range(std::vector<gr_tag_t> &v,
+ uint64_t abs_start,
+ uint64_t abs_end);
+
+ // -------------------------------------------------------------------------
+
+ private:
+
+ friend class gr_buffer;
+ friend GR_CORE_API gr_buffer_reader_sptr
+ gr_buffer_add_reader (gr_buffer_sptr buf, int nzero_preload, gr_block_sptr link);
+
+
+ gr_buffer_sptr d_buffer;
+ unsigned int d_read_index; // in items [0,d->buffer.d_bufsize)
+ uint64_t d_abs_read_offset; // num items seen since the start
+ boost::weak_ptr<gr_block> d_link; // block that reads via this buffer reader
+
+ //! constructor is private. Use gr_buffer::add_reader to create instances
+ gr_buffer_reader (gr_buffer_sptr buffer, unsigned int read_index, gr_block_sptr link);
+};
+
+//! returns # of gr_buffer_readers currently allocated
+GR_CORE_API 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
index 000000000..390a94e05
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_buffer.i
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+class 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, gr_block_sptr link);
+
+class gr_buffer {
+ public:
+ ~gr_buffer ();
+
+ private:
+ gr_buffer (int nitems, size_t sizeof_item, gr_block_sptr link);
+};
+
+
+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 nzero_preload, gr_block_sptr link);
+
+class gr_buffer_reader {
+ public:
+ ~gr_buffer_reader ();
+
+ private:
+ friend class gr_buffer;
+ gr_buffer_reader (gr_buffer_sptr buffer, unsigned int read_index, gr_block_sptr link);
+};
+
+
+%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
index 000000000..58d1525b4
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_complex.h
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifndef INCLUDED_GR_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) { (void) x; return true;}
+inline bool is_complex (gr_complexd x) { (void) x; return true;}
+inline bool is_complex (float x) { (void) x; return false;}
+inline bool is_complex (double x) { (void) x; return false;}
+inline bool is_complex (int x) { (void) x; return false;}
+inline bool is_complex (char x) { (void) x; return false;}
+inline bool is_complex (short x) { (void) x; return false;}
+
+
+// this doesn't really belong here, but there are worse places for it...
+
+#define CPPUNIT_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
index 000000000..96ebe9ad8
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_dispatcher.cc
@@ -0,0 +1,193 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_dispatcher.h>
+#include <math.h>
+#include <errno.h>
+#include <stdio.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
index 000000000..72a0b0176
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_dispatcher.h
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_DISPATCHER_H
+#define INCLUDED_GR_DISPATCHER_H
+
+#include <gr_core_api.h>
+#include <gr_select_handler.h>
+#include <vector>
+
+class gr_dispatcher;
+typedef boost::shared_ptr<gr_dispatcher> gr_dispatcher_sptr;
+
+GR_CORE_API gr_dispatcher_sptr gr_dispatcher_singleton();
+GR_CORE_API gr_dispatcher_sptr gr_make_dispatcher();
+
+/*!
+ * \brief invoke callbacks based on select.
+ * \ingroup internal
+ *
+ * \sa gr_select_handler
+ */
+class GR_CORE_API gr_dispatcher
+{
+ gr_dispatcher();
+ friend GR_CORE_API 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
index 000000000..28737cd31
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_dispatcher.i
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+class 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
index 000000000..448682966
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_error_handler.cc
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+/*
+ * This code 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
index 000000000..569c01c45
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_error_handler.h
@@ -0,0 +1,117 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+/*
+ * 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 <gr_core_api.h>
+#include <stdarg.h>
+#include <string>
+#include <cstdio> // for FILE
+
+/*!
+ * \brief abstract error handler
+ * \ingroup base
+ */
+class GR_CORE_API 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_CORE_API 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_CORE_API 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
index 000000000..072394a72
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_error_handler.i
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, 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_flat_flowgraph.cc b/gnuradio-core/src/lib/runtime/gr_flat_flowgraph.cc
new file mode 100644
index 000000000..9294a5dca
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_flat_flowgraph.cc
@@ -0,0 +1,403 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_flat_flowgraph.h>
+#include <gr_block_detail.h>
+#include <gr_io_signature.h>
+#include <gr_buffer.h>
+#include <volk/volk.h>
+#include <iostream>
+#include <map>
+#include <boost/format.hpp>
+
+#define GR_FLAT_FLOWGRAPH_DEBUG 0
+
+// 32Kbyte buffer size between blocks
+#define GR_FIXED_BUFFER_SIZE (32*(1L<<10))
+
+static const unsigned int s_fixed_buffer_size = GR_FIXED_BUFFER_SIZE;
+
+gr_flat_flowgraph_sptr
+gr_make_flat_flowgraph()
+{
+ return gr_flat_flowgraph_sptr(new gr_flat_flowgraph());
+}
+
+gr_flat_flowgraph::gr_flat_flowgraph()
+{
+}
+
+gr_flat_flowgraph::~gr_flat_flowgraph()
+{
+}
+
+void
+gr_flat_flowgraph::setup_connections()
+{
+ gr_basic_block_vector_t blocks = calc_used_blocks();
+
+ // Assign block details to blocks
+ for (gr_basic_block_viter_t p = blocks.begin(); p != blocks.end(); p++)
+ cast_to_block_sptr(*p)->set_detail(allocate_block_detail(*p));
+
+ // Connect inputs to outputs for each block
+ for(gr_basic_block_viter_t p = blocks.begin(); p != blocks.end(); p++) {
+ connect_block_inputs(*p);
+
+ gr_block_sptr block = cast_to_block_sptr(*p);
+ block->set_unaligned(0);
+ block->set_is_unaligned(false);
+ }
+
+ // Connect message ports connetions
+ for(gr_msg_edge_viter_t i = d_msg_edges.begin(); i != d_msg_edges.end(); i++){
+ if(GR_FLAT_FLOWGRAPH_DEBUG)
+ std::cout << boost::format("flat_fg connecting msg primitives: (%s, %s)->(%s, %s)\n") %
+ i->src().block() % i->src().port() %
+ i->dst().block() % i->dst().port();
+ i->src().block()->message_port_sub( i->src().port(), pmt::pmt_cons(i->dst().block()->alias_pmt(), i->dst().port()) );
+ }
+
+}
+
+gr_block_detail_sptr
+gr_flat_flowgraph::allocate_block_detail(gr_basic_block_sptr block)
+{
+ int ninputs = calc_used_ports(block, true).size();
+ int noutputs = calc_used_ports(block, false).size();
+ gr_block_detail_sptr detail = gr_make_block_detail(ninputs, noutputs);
+
+ gr_block_sptr grblock = cast_to_block_sptr(block);
+ if(!grblock)
+ throw std::runtime_error("allocate_block_detail found non-gr_block");
+
+ if (GR_FLAT_FLOWGRAPH_DEBUG)
+ std::cout << "Creating block detail for " << block << std::endl;
+
+ for (int i = 0; i < noutputs; i++) {
+ grblock->expand_minmax_buffer(i);
+
+ gr_buffer_sptr buffer = allocate_buffer(block, i);
+ if (GR_FLAT_FLOWGRAPH_DEBUG)
+ std::cout << "Allocated buffer for output " << block << ":" << i << std::endl;
+ detail->set_output(i, buffer);
+
+ // Update the block's max_output_buffer based on what was actually allocated.
+ grblock->set_max_output_buffer(i, buffer->bufsize());
+ }
+
+ return detail;
+}
+
+gr_buffer_sptr
+gr_flat_flowgraph::allocate_buffer(gr_basic_block_sptr block, int port)
+{
+ gr_block_sptr grblock = cast_to_block_sptr(block);
+ if (!grblock)
+ throw std::runtime_error("allocate_buffer found non-gr_block");
+ int item_size = block->output_signature()->sizeof_stream_item(port);
+
+ // *2 because we're now only filling them 1/2 way in order to
+ // increase the available parallelism when using the TPB scheduler.
+ // (We're double buffering, where we used to single buffer)
+ int nitems = s_fixed_buffer_size * 2 / item_size;
+
+ // Make sure there are at least twice the output_multiple no. of items
+ if (nitems < 2*grblock->output_multiple()) // Note: this means output_multiple()
+ nitems = 2*grblock->output_multiple(); // can't be changed by block dynamically
+
+ // If any downstream blocks are decimators and/or have a large output_multiple,
+ // ensure we have a buffer at least twice their decimation factor*output_multiple
+ gr_basic_block_vector_t blocks = calc_downstream_blocks(block, port);
+
+ // limit buffer size if indicated
+ if(grblock->max_output_buffer(port) > 0) {
+// std::cout << "constraining output items to " << block->max_output_buffer(port) << "\n";
+ nitems = std::min((long)nitems, (long)grblock->max_output_buffer(port));
+ nitems -= nitems%grblock->output_multiple();
+ if( nitems < 1 )
+ throw std::runtime_error("problems allocating a buffer with the given max output buffer constraint!");
+ }
+ else if(grblock->min_output_buffer(port) > 0) {
+ nitems = std::max((long)nitems, (long)grblock->min_output_buffer(port));
+ nitems -= nitems%grblock->output_multiple();
+ if( nitems < 1 )
+ throw std::runtime_error("problems allocating a buffer with the given min output buffer constraint!");
+ }
+
+ for (gr_basic_block_viter_t p = blocks.begin(); p != blocks.end(); p++) {
+ gr_block_sptr dgrblock = cast_to_block_sptr(*p);
+ if (!dgrblock)
+ throw std::runtime_error("allocate_buffer found non-gr_block");
+
+ double decimation = (1.0/dgrblock->relative_rate());
+ int multiple = dgrblock->output_multiple();
+ int history = dgrblock->history();
+ nitems = std::max(nitems, static_cast<int>(2*(decimation*multiple+history)));
+ }
+
+// std::cout << "gr_make_buffer(" << nitems << ", " << item_size << ", " << grblock << "\n";
+ return gr_make_buffer(nitems, item_size, grblock);
+}
+
+void
+gr_flat_flowgraph::connect_block_inputs(gr_basic_block_sptr block)
+{
+ gr_block_sptr grblock = cast_to_block_sptr(block);
+ if (!grblock)
+ throw std::runtime_error("connect_block_inputs found non-gr_block");
+
+ // Get its detail and edges that feed into it
+ gr_block_detail_sptr detail = grblock->detail();
+ gr_edge_vector_t in_edges = calc_upstream_edges(block);
+
+ // For each edge that feeds into it
+ for (gr_edge_viter_t e = in_edges.begin(); e != in_edges.end(); e++) {
+ // Set the buffer reader on the destination port to the output
+ // buffer on the source port
+ int dst_port = e->dst().port();
+ int src_port = e->src().port();
+ gr_basic_block_sptr src_block = e->src().block();
+ gr_block_sptr src_grblock = cast_to_block_sptr(src_block);
+ if (!src_grblock)
+ throw std::runtime_error("connect_block_inputs found non-gr_block");
+ gr_buffer_sptr src_buffer = src_grblock->detail()->output(src_port);
+
+ if (GR_FLAT_FLOWGRAPH_DEBUG)
+ std::cout << "Setting input " << dst_port << " from edge " << (*e) << std::endl;
+
+ detail->set_input(dst_port, gr_buffer_add_reader(src_buffer, grblock->history()-1, grblock));
+ }
+}
+
+void
+gr_flat_flowgraph::merge_connections(gr_flat_flowgraph_sptr old_ffg)
+{
+ // Allocate block details if needed. Only new blocks that aren't pruned out
+ // by flattening will need one; existing blocks still in the new flowgraph will
+ // already have one.
+ for (gr_basic_block_viter_t p = d_blocks.begin(); p != d_blocks.end(); p++) {
+ gr_block_sptr block = cast_to_block_sptr(*p);
+
+ if (!block->detail()) {
+ if (GR_FLAT_FLOWGRAPH_DEBUG)
+ std::cout << "merge: allocating new detail for block " << (*p) << std::endl;
+ block->set_detail(allocate_block_detail(block));
+ }
+ else
+ if (GR_FLAT_FLOWGRAPH_DEBUG)
+ std::cout << "merge: reusing original detail for block " << (*p) << std::endl;
+ }
+
+ // Calculate the old edges that will be going away, and clear the buffer readers
+ // on the RHS.
+ for (gr_edge_viter_t old_edge = old_ffg->d_edges.begin(); old_edge != old_ffg->d_edges.end(); old_edge++) {
+ if (GR_FLAT_FLOWGRAPH_DEBUG)
+ std::cout << "merge: testing old edge " << (*old_edge) << "...";
+
+ gr_edge_viter_t new_edge;
+ for (new_edge = d_edges.begin(); new_edge != d_edges.end(); new_edge++)
+ if (new_edge->src() == old_edge->src() &&
+ new_edge->dst() == old_edge->dst())
+ break;
+
+ if (new_edge == d_edges.end()) { // not found in new edge list
+ if (GR_FLAT_FLOWGRAPH_DEBUG)
+ std::cout << "not in new edge list" << std::endl;
+ // zero the buffer reader on RHS of old edge
+ gr_block_sptr block(cast_to_block_sptr(old_edge->dst().block()));
+ int port = old_edge->dst().port();
+ block->detail()->set_input(port, gr_buffer_reader_sptr());
+ }
+ else {
+ if (GR_FLAT_FLOWGRAPH_DEBUG)
+ std::cout << "found in new edge list" << std::endl;
+ }
+ }
+
+ // Now connect inputs to outputs, reusing old buffer readers if they exist
+ for (gr_basic_block_viter_t p = d_blocks.begin(); p != d_blocks.end(); p++) {
+ gr_block_sptr block = cast_to_block_sptr(*p);
+
+ if (GR_FLAT_FLOWGRAPH_DEBUG)
+ std::cout << "merge: merging " << (*p) << "...";
+
+ if (old_ffg->has_block_p(*p)) {
+ // Block exists in old flow graph
+ if (GR_FLAT_FLOWGRAPH_DEBUG)
+ std::cout << "used in old flow graph" << std::endl;
+ gr_block_detail_sptr detail = block->detail();
+
+ // Iterate through the inputs and see what needs to be done
+ int ninputs = calc_used_ports(block, true).size(); // Might be different now
+ for (int i = 0; i < ninputs; i++) {
+ if (GR_FLAT_FLOWGRAPH_DEBUG)
+ std::cout << "Checking input " << block << ":" << i << "...";
+ gr_edge edge = calc_upstream_edge(*p, i);
+
+ // Fish out old buffer reader and see if it matches correct buffer from edge list
+ gr_block_sptr src_block = cast_to_block_sptr(edge.src().block());
+ gr_block_detail_sptr src_detail = src_block->detail();
+ gr_buffer_sptr src_buffer = src_detail->output(edge.src().port());
+ gr_buffer_reader_sptr old_reader;
+ if (i < detail->ninputs()) // Don't exceed what the original detail has
+ old_reader = detail->input(i);
+
+ // If there's a match, use it
+ if (old_reader && (src_buffer == old_reader->buffer())) {
+ if (GR_FLAT_FLOWGRAPH_DEBUG)
+ std::cout << "matched, reusing" << std::endl;
+ }
+ else {
+ if (GR_FLAT_FLOWGRAPH_DEBUG)
+ std::cout << "needs a new reader" << std::endl;
+
+ // Create new buffer reader and assign
+ detail->set_input(i, gr_buffer_add_reader(src_buffer, block->history()-1, block));
+ }
+ }
+ }
+ else {
+ // Block is new, it just needs buffer readers at this point
+ if (GR_FLAT_FLOWGRAPH_DEBUG)
+ std::cout << "new block" << std::endl;
+ connect_block_inputs(block);
+
+ // Make sure all buffers are aligned
+ setup_buffer_alignment(block);
+ }
+
+ // Now deal with the fact that the block details might have changed numbers of
+ // inputs and outputs vs. in the old flowgraph.
+ }
+}
+
+void
+gr_flat_flowgraph::setup_buffer_alignment(gr_block_sptr block)
+{
+ const int alignment = volk_get_alignment();
+ for(int i = 0; i < block->detail()->ninputs(); i++) {
+ void *r = (void*)block->detail()->input(i)->read_pointer();
+ unsigned long int ri = (unsigned long int)r % alignment;
+ //std::cerr << "reader: " << r << " alignment: " << ri << std::endl;
+ if(ri != 0) {
+ size_t itemsize = block->detail()->input(i)->get_sizeof_item();
+ block->detail()->input(i)->update_read_pointer(alignment-ri/itemsize);
+ }
+ block->set_unaligned(0);
+ block->set_is_unaligned(false);
+ }
+
+ for(int i = 0; i < block->detail()->noutputs(); i++) {
+ void *w = (void*)block->detail()->output(i)->write_pointer();
+ unsigned long int wi = (unsigned long int)w % alignment;
+ //std::cerr << "writer: " << w << " alignment: " << wi << std::endl;
+ if(wi != 0) {
+ size_t itemsize = block->detail()->output(i)->get_sizeof_item();
+ block->detail()->output(i)->update_write_pointer(alignment-wi/itemsize);
+ }
+ block->set_unaligned(0);
+ block->set_is_unaligned(false);
+ }
+}
+
+void gr_flat_flowgraph::dump()
+{
+ for (gr_edge_viter_t e = d_edges.begin(); e != d_edges.end(); e++)
+ std::cout << " edge: " << (*e) << std::endl;
+
+ for (gr_basic_block_viter_t p = d_blocks.begin(); p != d_blocks.end(); p++) {
+ std::cout << " block: " << (*p) << std::endl;
+ gr_block_detail_sptr detail = cast_to_block_sptr(*p)->detail();
+ std::cout << " detail @" << detail << ":" << std::endl;
+
+ int ni = detail->ninputs();
+ int no = detail->noutputs();
+ for (int i = 0; i < no; i++) {
+ gr_buffer_sptr buffer = detail->output(i);
+ std::cout << " output " << i << ": " << buffer << std::endl;
+ }
+
+ for (int i = 0; i < ni; i++) {
+ gr_buffer_reader_sptr reader = detail->input(i);
+ std::cout << " reader " << i << ": " << reader
+ << " reading from buffer=" << reader->buffer() << std::endl;
+ }
+ }
+
+}
+
+gr_block_vector_t
+gr_flat_flowgraph::make_block_vector(gr_basic_block_vector_t &blocks)
+{
+ gr_block_vector_t result;
+ for (gr_basic_block_viter_t p = blocks.begin(); p != blocks.end(); p++) {
+ result.push_back(cast_to_block_sptr(*p));
+ }
+
+ return result;
+}
+
+
+void gr_flat_flowgraph::clear_endpoint(const gr_msg_endpoint &e, bool is_src){
+ for(size_t i=0; i<d_msg_edges.size(); i++){
+ if(is_src){
+ if(d_msg_edges[i].src() == e){
+ d_msg_edges.erase(d_msg_edges.begin() + i);
+ i--;
+ }
+ } else {
+ if(d_msg_edges[i].dst() == e){
+ d_msg_edges.erase(d_msg_edges.begin() + i);
+ i--;
+ }
+ }
+ }
+}
+
+void gr_flat_flowgraph::replace_endpoint(const gr_msg_endpoint &e, const gr_msg_endpoint &r, bool is_src){
+ size_t n_replr(0);
+ if(GR_FLAT_FLOWGRAPH_DEBUG)
+ std::cout << boost::format("gr_flat_flowgraph::replace_endpoint( %s, %s, %d )\n") % e.block()% r.block()% is_src;
+ for(size_t i=0; i<d_msg_edges.size(); i++){
+ if(is_src){
+ if(d_msg_edges[i].src() == e){
+ if(GR_FLAT_FLOWGRAPH_DEBUG)
+ std::cout << boost::format("gr_flat_flowgraph::replace_endpoint() flattening to ( %s, %s )\n") % r.block()% d_msg_edges[i].dst().block();
+ d_msg_edges.push_back( gr_msg_edge(r, d_msg_edges[i].dst() ) );
+ n_replr++;
+ }
+ } else {
+ if(d_msg_edges[i].dst() == e){
+ if(GR_FLAT_FLOWGRAPH_DEBUG)
+ std::cout << boost::format("gr_flat_flowgraph::replace_endpoint() flattening to ( %s, %s )\n") % r.block()% d_msg_edges[i].dst().block();
+ d_msg_edges.push_back( gr_msg_edge(d_msg_edges[i].src(), r ) );
+ n_replr++;
+ }
+ }
+ }
+}
+
diff --git a/gnuradio-core/src/lib/runtime/gr_flat_flowgraph.h b/gnuradio-core/src/lib/runtime/gr_flat_flowgraph.h
new file mode 100644
index 000000000..5c8268d7d
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_flat_flowgraph.h
@@ -0,0 +1,80 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006,2007 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_FLAT_FLOWGRAPH_H
+#define INCLUDED_GR_FLAT_FLOWGRAPH_H
+
+#include <gr_core_api.h>
+#include <gr_flowgraph.h>
+#include <gr_block.h>
+
+// Create a shared pointer to a heap allocated gr_flat_flowgraph
+// (types defined in gr_runtime_types.h)
+GR_CORE_API gr_flat_flowgraph_sptr gr_make_flat_flowgraph();
+
+/*!
+ *\brief Class specializing gr_flat_flowgraph that has all nodes
+ * as gr_blocks, with no hierarchy
+ * \ingroup internal
+ */
+class GR_CORE_API gr_flat_flowgraph : public gr_flowgraph
+{
+public:
+ friend GR_CORE_API gr_flat_flowgraph_sptr gr_make_flat_flowgraph();
+
+ // Destruct an arbitrary gr_flat_flowgraph
+ ~gr_flat_flowgraph();
+
+ // Wire gr_blocks together in new flat_flowgraph
+ void setup_connections();
+
+ // Merge applicable connections from existing flat flowgraph
+ void merge_connections(gr_flat_flowgraph_sptr sfg);
+
+ void dump();
+
+ /*!
+ * Make a vector of gr_block from a vector of gr_basic_block
+ */
+ static gr_block_vector_t make_block_vector(gr_basic_block_vector_t &blocks);
+
+ void replace_endpoint(const gr_msg_endpoint &e, const gr_msg_endpoint &r, bool is_src);
+ void clear_endpoint(const gr_msg_endpoint &e, bool is_src);
+
+private:
+ gr_flat_flowgraph();
+
+ gr_block_detail_sptr allocate_block_detail(gr_basic_block_sptr block);
+ gr_buffer_sptr allocate_buffer(gr_basic_block_sptr block, int port);
+ void connect_block_inputs(gr_basic_block_sptr block);
+
+ /* When reusing a flowgraph's blocks, this call makes sure all of the
+ * buffer's are aligned at the machine's alignment boundary and tells
+ * the blocks that they are aligned.
+ *
+ * Called from both setup_connections and merge_connections for
+ * start and restarts.
+ */
+ void setup_buffer_alignment(gr_block_sptr block);
+};
+
+#endif /* INCLUDED_GR_FLAT_FLOWGRAPH_H */
diff --git a/gnuradio-core/src/lib/runtime/gr_flowgraph.cc b/gnuradio-core/src/lib/runtime/gr_flowgraph.cc
new file mode 100644
index 000000000..63a208480
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_flowgraph.cc
@@ -0,0 +1,515 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007,2011 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_flowgraph.h>
+#include <gr_io_signature.h>
+#include <stdexcept>
+#include <sstream>
+#include <iterator>
+
+#define GR_FLOWGRAPH_DEBUG 0
+
+gr_edge::~gr_edge()
+{
+}
+
+gr_flowgraph_sptr gr_make_flowgraph()
+{
+ return gr_flowgraph_sptr(new gr_flowgraph());
+}
+
+gr_flowgraph::gr_flowgraph()
+{
+}
+
+gr_flowgraph::~gr_flowgraph()
+{
+}
+
+// FIXME: move to libgruel as a utility function
+template<class T>
+static
+std::vector<T>
+unique_vector(std::vector<T> v)
+{
+ std::vector<T> result;
+ std::insert_iterator<std::vector<T> > inserter(result, result.begin());
+
+ sort(v.begin(), v.end());
+ unique_copy(v.begin(), v.end(), inserter);
+ return result;
+}
+
+void
+gr_flowgraph::connect(const gr_endpoint &src, const gr_endpoint &dst)
+{
+ check_valid_port(src.block()->output_signature(), src.port());
+ check_valid_port(dst.block()->input_signature(), dst.port());
+ check_dst_not_used(dst);
+ check_type_match(src, dst);
+
+ // All ist klar, Herr Kommisar
+ d_edges.push_back(gr_edge(src,dst));
+}
+
+void
+gr_flowgraph::disconnect(const gr_endpoint &src, const gr_endpoint &dst)
+{
+ for (gr_edge_viter_t p = d_edges.begin(); p != d_edges.end(); p++) {
+ if (src == p->src() && dst == p->dst()) {
+ d_edges.erase(p);
+ return;
+ }
+ }
+
+ std::stringstream msg;
+ msg << "cannot disconnect edge " << gr_edge(src, dst) << ", not found";
+ throw std::invalid_argument(msg.str());
+}
+
+void
+gr_flowgraph::validate()
+{
+ d_blocks = calc_used_blocks();
+
+ for (gr_basic_block_viter_t p = d_blocks.begin(); p != d_blocks.end(); p++) {
+ std::vector<int> used_ports;
+ int ninputs, noutputs;
+
+ if (GR_FLOWGRAPH_DEBUG)
+ std::cout << "Validating block: " << (*p) << std::endl;
+
+ used_ports = calc_used_ports(*p, true); // inputs
+ ninputs = used_ports.size();
+ check_contiguity(*p, used_ports, true); // inputs
+
+ used_ports = calc_used_ports(*p, false); // outputs
+ noutputs = used_ports.size();
+ check_contiguity(*p, used_ports, false); // outputs
+
+ if (!((*p)->check_topology(ninputs, noutputs))) {
+ std::stringstream msg;
+ msg << "check topology failed on " << (*p)
+ << " using ninputs=" << ninputs
+ << ", noutputs=" << noutputs;
+ throw std::runtime_error(msg.str());
+ }
+ }
+}
+
+void
+gr_flowgraph::clear()
+{
+ // Boost shared pointers will deallocate as needed
+ d_blocks.clear();
+ d_edges.clear();
+}
+
+void
+gr_flowgraph::check_valid_port(gr_io_signature_sptr sig, int port)
+{
+ std::stringstream msg;
+
+ if (port < 0) {
+ msg << "negative port number " << port << " is invalid";
+ throw std::invalid_argument(msg.str());
+ }
+
+ int max = sig->max_streams();
+ if (max != gr_io_signature::IO_INFINITE && port >= max) {
+ msg << "port number " << port << " exceeds max of ";
+ if (max == 0)
+ msg << "(none)";
+ else
+ msg << max-1;
+ throw std::invalid_argument(msg.str());
+ }
+}
+
+void
+gr_flowgraph::check_valid_port(const gr_msg_endpoint &e)
+{
+ if (GR_FLOWGRAPH_DEBUG)
+ std::cout << "check_valid_port( " << e.block() << ", " << e.port() << ")\n";
+
+ if(!e.block()->has_msg_port(e.port()))
+ throw std::invalid_argument("invalid msg port in connect() or disconnect()");
+}
+
+void
+gr_flowgraph::check_dst_not_used(const gr_endpoint &dst)
+{
+ // A destination is in use if it is already on the edge list
+ for (gr_edge_viter_t p = d_edges.begin(); p != d_edges.end(); p++)
+ if (p->dst() == dst) {
+ std::stringstream msg;
+ msg << "destination already in use by edge " << (*p);
+ throw std::invalid_argument(msg.str());
+ }
+}
+
+void
+gr_flowgraph::check_type_match(const gr_endpoint &src, const gr_endpoint &dst)
+{
+ int src_size = src.block()->output_signature()->sizeof_stream_item(src.port());
+ int dst_size = dst.block()->input_signature()->sizeof_stream_item(dst.port());
+
+ if (src_size != dst_size) {
+ std::stringstream msg;
+ msg << "itemsize mismatch: " << src << " using " << src_size
+ << ", " << dst << " using " << dst_size;
+ throw std::invalid_argument(msg.str());
+ }
+}
+
+gr_basic_block_vector_t
+gr_flowgraph::calc_used_blocks()
+{
+ gr_basic_block_vector_t tmp;
+
+ // make sure free standing message blocks are included
+ for (gr_msg_edge_viter_t p = d_msg_edges.begin(); p != d_msg_edges.end(); p++) {
+// for now only blocks receiving messages get a thread context - uncomment to allow senders to also obtain one
+// tmp.push_back(p->src().block());
+ tmp.push_back(p->dst().block());
+ }
+
+ // Collect all blocks in the edge list
+ for (gr_edge_viter_t p = d_edges.begin(); p != d_edges.end(); p++) {
+ tmp.push_back(p->src().block());
+ tmp.push_back(p->dst().block());
+ }
+
+ return unique_vector<gr_basic_block_sptr>(tmp);
+}
+
+std::vector<int>
+gr_flowgraph::calc_used_ports(gr_basic_block_sptr block, bool check_inputs)
+{
+ std::vector<int> tmp;
+
+ // Collect all seen ports
+ gr_edge_vector_t edges = calc_connections(block, check_inputs);
+ for (gr_edge_viter_t p = edges.begin(); p != edges.end(); p++) {
+ if (check_inputs == true)
+ tmp.push_back(p->dst().port());
+ else
+ tmp.push_back(p->src().port());
+ }
+
+ return unique_vector<int>(tmp);
+}
+
+gr_edge_vector_t
+gr_flowgraph::calc_connections(gr_basic_block_sptr block, bool check_inputs)
+{
+ gr_edge_vector_t result;
+
+ for (gr_edge_viter_t p = d_edges.begin(); p != d_edges.end(); p++) {
+ if (check_inputs) {
+ if (p->dst().block() == block)
+ result.push_back(*p);
+ }
+ else {
+ if (p->src().block() == block)
+ result.push_back(*p);
+ }
+ }
+
+ return result; // assumes no duplicates
+}
+
+void
+gr_flowgraph::check_contiguity(gr_basic_block_sptr block,
+ const std::vector<int> &used_ports,
+ bool check_inputs)
+{
+ std::stringstream msg;
+
+ gr_io_signature_sptr sig =
+ check_inputs ? block->input_signature() : block->output_signature();
+
+ int nports = used_ports.size();
+ int min_ports = sig->min_streams();
+ int max_ports = sig->max_streams();
+
+ if (nports == 0 && min_ports == 0)
+ return;
+
+ if (nports < min_ports) {
+ msg << block << ": insufficient connected "
+ << (check_inputs ? "input ports " : "output ports ")
+ << "(" << min_ports << " needed, " << nports << " connected)";
+ throw std::runtime_error(msg.str());
+ }
+
+ if (nports > max_ports && max_ports != gr_io_signature::IO_INFINITE) {
+ msg << block << ": too many connected "
+ << (check_inputs ? "input ports " : "output ports ")
+ << "(" << max_ports << " allowed, " << nports << " connected)";
+ throw std::runtime_error(msg.str());
+ }
+
+ if (used_ports[nports-1]+1 != nports) {
+ for (int i = 0; i < nports; i++) {
+ if (used_ports[i] != i) {
+ msg << block << ": missing connection "
+ << (check_inputs ? "to input port " : "from output port ")
+ << i;
+ throw std::runtime_error(msg.str());
+ }
+ }
+ }
+}
+
+gr_basic_block_vector_t
+gr_flowgraph::calc_downstream_blocks(gr_basic_block_sptr block, int port)
+{
+ gr_basic_block_vector_t tmp;
+
+ for (gr_edge_viter_t p = d_edges.begin(); p != d_edges.end(); p++)
+ if (p->src() == gr_endpoint(block, port))
+ tmp.push_back(p->dst().block());
+
+ return unique_vector<gr_basic_block_sptr>(tmp);
+}
+
+gr_basic_block_vector_t
+gr_flowgraph::calc_downstream_blocks(gr_basic_block_sptr block)
+{
+ gr_basic_block_vector_t tmp;
+
+ for (gr_edge_viter_t p = d_edges.begin(); p != d_edges.end(); p++)
+ if (p->src().block() == block)
+ tmp.push_back(p->dst().block());
+
+ return unique_vector<gr_basic_block_sptr>(tmp);
+}
+
+gr_edge_vector_t
+gr_flowgraph::calc_upstream_edges(gr_basic_block_sptr block)
+{
+ gr_edge_vector_t result;
+
+ for (gr_edge_viter_t p = d_edges.begin(); p != d_edges.end(); p++)
+ if (p->dst().block() == block)
+ result.push_back(*p);
+
+ return result; // Assume no duplicates
+}
+
+bool
+gr_flowgraph::has_block_p(gr_basic_block_sptr block)
+{
+ gr_basic_block_viter_t result;
+ result = std::find(d_blocks.begin(), d_blocks.end(), block);
+ return (result != d_blocks.end());
+}
+
+gr_edge
+gr_flowgraph::calc_upstream_edge(gr_basic_block_sptr block, int port)
+{
+ gr_edge result;
+
+ for (gr_edge_viter_t p = d_edges.begin(); p != d_edges.end(); p++) {
+ if (p->dst() == gr_endpoint(block, port)) {
+ result = (*p);
+ break;
+ }
+ }
+
+ return result;
+}
+
+std::vector<gr_basic_block_vector_t>
+gr_flowgraph::partition()
+{
+ std::vector<gr_basic_block_vector_t> result;
+ gr_basic_block_vector_t blocks = calc_used_blocks();
+ gr_basic_block_vector_t graph;
+
+ while (blocks.size() > 0) {
+ graph = calc_reachable_blocks(blocks[0], blocks);
+ assert(graph.size());
+ result.push_back(topological_sort(graph));
+
+ for (gr_basic_block_viter_t p = graph.begin(); p != graph.end(); p++)
+ blocks.erase(find(blocks.begin(), blocks.end(), *p));
+ }
+
+ return result;
+}
+
+gr_basic_block_vector_t
+gr_flowgraph::calc_reachable_blocks(gr_basic_block_sptr block, gr_basic_block_vector_t &blocks)
+{
+ gr_basic_block_vector_t result;
+
+ // Mark all blocks as unvisited
+ for (gr_basic_block_viter_t p = blocks.begin(); p != blocks.end(); p++)
+ (*p)->set_color(gr_basic_block::WHITE);
+
+ // Recursively mark all reachable blocks
+ reachable_dfs_visit(block, blocks);
+
+ // Collect all the blocks that have been visited
+ for (gr_basic_block_viter_t p = blocks.begin(); p != blocks.end(); p++)
+ if ((*p)->color() == gr_basic_block::BLACK)
+ result.push_back(*p);
+
+ return result;
+}
+
+// Recursively mark all reachable blocks from given block and block list
+void
+gr_flowgraph::reachable_dfs_visit(gr_basic_block_sptr block, gr_basic_block_vector_t &blocks)
+{
+ // Mark the current one as visited
+ block->set_color(gr_basic_block::BLACK);
+
+ // Recurse into adjacent vertices
+ gr_basic_block_vector_t adjacent = calc_adjacent_blocks(block, blocks);
+
+ for (gr_basic_block_viter_t p = adjacent.begin(); p != adjacent.end(); p++)
+ if ((*p)->color() == gr_basic_block::WHITE)
+ reachable_dfs_visit(*p, blocks);
+}
+
+// Return a list of block adjacent to a given block along any edge
+gr_basic_block_vector_t
+gr_flowgraph::calc_adjacent_blocks(gr_basic_block_sptr block, gr_basic_block_vector_t &blocks)
+{
+ gr_basic_block_vector_t tmp;
+
+ // Find any blocks that are inputs or outputs
+ for (gr_edge_viter_t p = d_edges.begin(); p != d_edges.end(); p++) {
+ if (p->src().block() == block)
+ tmp.push_back(p->dst().block());
+ if (p->dst().block() == block)
+ tmp.push_back(p->src().block());
+ }
+
+ return unique_vector<gr_basic_block_sptr>(tmp);
+}
+
+gr_basic_block_vector_t
+gr_flowgraph::topological_sort(gr_basic_block_vector_t &blocks)
+{
+ gr_basic_block_vector_t tmp;
+ gr_basic_block_vector_t result;
+ tmp = sort_sources_first(blocks);
+
+ // Start 'em all white
+ for (gr_basic_block_viter_t p = tmp.begin(); p != tmp.end(); p++)
+ (*p)->set_color(gr_basic_block::WHITE);
+
+ for (gr_basic_block_viter_t p = tmp.begin(); p != tmp.end(); p++) {
+ if ((*p)->color() == gr_basic_block::WHITE)
+ topological_dfs_visit(*p, result);
+ }
+
+ reverse(result.begin(), result.end());
+ return result;
+}
+
+gr_basic_block_vector_t
+gr_flowgraph::sort_sources_first(gr_basic_block_vector_t &blocks)
+{
+ gr_basic_block_vector_t sources, nonsources, result;
+
+ for (gr_basic_block_viter_t p = blocks.begin(); p != blocks.end(); p++) {
+ if (source_p(*p))
+ sources.push_back(*p);
+ else
+ nonsources.push_back(*p);
+ }
+
+ for (gr_basic_block_viter_t p = sources.begin(); p != sources.end(); p++)
+ result.push_back(*p);
+
+ for (gr_basic_block_viter_t p = nonsources.begin(); p != nonsources.end(); p++)
+ result.push_back(*p);
+
+ return result;
+}
+
+bool
+gr_flowgraph::source_p(gr_basic_block_sptr block)
+{
+ return (calc_upstream_edges(block).size() == 0);
+}
+
+void
+gr_flowgraph::topological_dfs_visit(gr_basic_block_sptr block, gr_basic_block_vector_t &output)
+{
+ block->set_color(gr_basic_block::GREY);
+ gr_basic_block_vector_t blocks(calc_downstream_blocks(block));
+
+ for (gr_basic_block_viter_t p = blocks.begin(); p != blocks.end(); p++) {
+ switch ((*p)->color()) {
+ case gr_basic_block::WHITE:
+ topological_dfs_visit(*p, output);
+ break;
+
+ case gr_basic_block::GREY:
+ throw std::runtime_error("flow graph has loops!");
+
+ case gr_basic_block::BLACK:
+ continue;
+
+ default:
+ throw std::runtime_error("invalid color on block!");
+ }
+ }
+
+ block->set_color(gr_basic_block::BLACK);
+ output.push_back(block);
+}
+
+void gr_flowgraph::connect(const gr_msg_endpoint &src, const gr_msg_endpoint &dst){
+ check_valid_port(src);
+ check_valid_port(dst);
+ for (gr_msg_edge_viter_t p = d_msg_edges.begin(); p != d_msg_edges.end(); p++) {
+ if(p->src() == src && p->dst() == dst){
+ throw std::runtime_error("connect called on already connected edge!");
+ }
+ }
+ d_msg_edges.push_back(gr_msg_edge(src,dst));
+}
+
+void gr_flowgraph::disconnect(const gr_msg_endpoint &src, const gr_msg_endpoint &dst){
+ check_valid_port(src);
+ check_valid_port(dst);
+ for (gr_msg_edge_viter_t p = d_msg_edges.begin(); p != d_msg_edges.end(); p++) {
+ if(p->src() == src && p->dst() == dst){
+ d_msg_edges.erase(p);
+ return;
+ }
+ }
+ throw std::runtime_error("disconnect called on non-connected edge!");
+}
+
+
diff --git a/gnuradio-core/src/lib/runtime/gr_flowgraph.h b/gnuradio-core/src/lib/runtime/gr_flowgraph.h
new file mode 100644
index 000000000..bef70f626
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_flowgraph.h
@@ -0,0 +1,251 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006,2007 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_FLOWGRAPH_H
+#define INCLUDED_GR_FLOWGRAPH_H
+
+#include <gr_core_api.h>
+#include <gr_basic_block.h>
+#include <iostream>
+
+/*!
+ * \brief Class representing a specific input or output graph endpoint
+ * \ingroup internal
+ */
+class GR_CORE_API gr_endpoint
+{
+private:
+ gr_basic_block_sptr d_basic_block;
+ int d_port;
+
+public:
+ gr_endpoint() : d_basic_block(), d_port(0) { }
+ gr_endpoint(gr_basic_block_sptr block, int port) { d_basic_block = block; d_port = port; }
+ gr_basic_block_sptr block() const { return d_basic_block; }
+ int port() const { return d_port; }
+
+ bool operator==(const gr_endpoint &other) const;
+};
+
+inline bool gr_endpoint::operator==(const gr_endpoint &other) const
+{
+ return (d_basic_block == other.d_basic_block &&
+ d_port == other.d_port);
+}
+
+class GR_CORE_API gr_msg_endpoint
+{
+private:
+ gr_basic_block_sptr d_basic_block;
+ pmt::pmt_t d_port;
+ bool d_is_hier;
+public:
+ gr_msg_endpoint() : d_basic_block(), d_port(pmt::PMT_NIL) { }
+ gr_msg_endpoint(gr_basic_block_sptr block, pmt::pmt_t port, bool is_hier=false){ d_basic_block = block; d_port = port; d_is_hier = is_hier;}
+ gr_basic_block_sptr block() const { return d_basic_block; }
+ pmt::pmt_t port() const { return d_port; }
+ bool is_hier() const { return d_is_hier; }
+ void set_hier(bool h) { d_is_hier = h; }
+
+ bool operator==(const gr_msg_endpoint &other) const;
+
+};
+
+inline bool gr_msg_endpoint::operator==(const gr_msg_endpoint &other) const
+{
+ return (d_basic_block == other.d_basic_block &&
+ pmt::pmt_equal(d_port, other.d_port));
+}
+
+
+// Hold vectors of gr_endpoint objects
+typedef std::vector<gr_endpoint> gr_endpoint_vector_t;
+typedef std::vector<gr_endpoint>::iterator gr_endpoint_viter_t;
+
+/*!
+ *\brief Class representing a connection between to graph endpoints
+ *
+ */
+class GR_CORE_API gr_edge
+{
+public:
+ gr_edge() : d_src(), d_dst() { };
+ gr_edge(const gr_endpoint &src, const gr_endpoint &dst) : d_src(src), d_dst(dst) { }
+ ~gr_edge();
+
+ const gr_endpoint &src() const { return d_src; }
+ const gr_endpoint &dst() const { return d_dst; }
+
+private:
+ gr_endpoint d_src;
+ gr_endpoint d_dst;
+};
+
+
+// Hold vectors of gr_edge objects
+typedef std::vector<gr_edge> gr_edge_vector_t;
+typedef std::vector<gr_edge>::iterator gr_edge_viter_t;
+
+
+/*!
+ *\brief Class representing a msg connection between to graph msg endpoints
+ *
+ */
+class GR_CORE_API gr_msg_edge
+{
+public:
+ gr_msg_edge() : d_src(), d_dst() { };
+ gr_msg_edge(const gr_msg_endpoint &src, const gr_msg_endpoint &dst) : d_src(src), d_dst(dst) { }
+ ~gr_msg_edge() {}
+
+ const gr_msg_endpoint &src() const { return d_src; }
+ const gr_msg_endpoint &dst() const { return d_dst; }
+
+private:
+ gr_msg_endpoint d_src;
+ gr_msg_endpoint d_dst;
+};
+
+// Hold vectors of gr_edge objects
+typedef std::vector<gr_msg_edge> gr_msg_edge_vector_t;
+typedef std::vector<gr_msg_edge>::iterator gr_msg_edge_viter_t;
+
+// Create a shared pointer to a heap allocated flowgraph
+// (types defined in gr_runtime_types.h)
+GR_CORE_API gr_flowgraph_sptr gr_make_flowgraph();
+
+/*!
+ * \brief Class representing a directed, acyclic graph of basic blocks
+ * \ingroup internal
+ */
+class GR_CORE_API gr_flowgraph
+{
+public:
+ friend GR_CORE_API gr_flowgraph_sptr gr_make_flowgraph();
+
+ // Destruct an arbitrary flowgraph
+ ~gr_flowgraph();
+
+ // Connect two endpoints
+ void connect(const gr_endpoint &src, const gr_endpoint &dst);
+
+ // Disconnect two endpoints
+ void disconnect(const gr_endpoint &src, const gr_endpoint &dst);
+
+ // Connect an output port to an input port (convenience)
+ void connect(gr_basic_block_sptr src_block, int src_port,
+ gr_basic_block_sptr dst_block, int dst_port);
+
+ // Disconnect an input port from an output port (convenience)
+ void disconnect(gr_basic_block_sptr src_block, int src_port,
+ gr_basic_block_sptr dst_block, int dst_port);
+
+ // Connect two msg endpoints
+ void connect(const gr_msg_endpoint &src, const gr_msg_endpoint &dst);
+
+ // Disconnect two msg endpoints
+ void disconnect(const gr_msg_endpoint &src, const gr_msg_endpoint &dst);
+
+ // Validate connectivity, raise exception if invalid
+ void validate();
+
+ // Clear existing flowgraph
+ void clear();
+
+ // Return vector of edges
+ const gr_edge_vector_t &edges() const { return d_edges; }
+
+ // Return vector of msg edges
+ const gr_msg_edge_vector_t &msg_edges() const { return d_msg_edges; }
+
+ // Return vector of connected blocks
+ gr_basic_block_vector_t calc_used_blocks();
+
+ // Return toplogically sorted vector of blocks. All the sources come first.
+ gr_basic_block_vector_t topological_sort(gr_basic_block_vector_t &blocks);
+
+ // Return vector of vectors of disjointly connected blocks, topologically
+ // sorted.
+ std::vector<gr_basic_block_vector_t> partition();
+
+protected:
+ gr_basic_block_vector_t d_blocks;
+ gr_edge_vector_t d_edges;
+ gr_msg_edge_vector_t d_msg_edges;
+
+ gr_flowgraph();
+ std::vector<int> calc_used_ports(gr_basic_block_sptr block, bool check_inputs);
+ gr_basic_block_vector_t calc_downstream_blocks(gr_basic_block_sptr block, int port);
+ gr_edge_vector_t calc_upstream_edges(gr_basic_block_sptr block);
+ bool has_block_p(gr_basic_block_sptr block);
+ gr_edge calc_upstream_edge(gr_basic_block_sptr block, int port);
+
+private:
+
+ void check_valid_port(gr_io_signature_sptr sig, int port);
+ void check_valid_port(const gr_msg_endpoint &e);
+ void check_dst_not_used(const gr_endpoint &dst);
+ void check_type_match(const gr_endpoint &src, const gr_endpoint &dst);
+ gr_edge_vector_t calc_connections(gr_basic_block_sptr block, bool check_inputs); // false=use outputs
+ void check_contiguity(gr_basic_block_sptr block, const std::vector<int> &used_ports, bool check_inputs);
+
+ gr_basic_block_vector_t calc_downstream_blocks(gr_basic_block_sptr block);
+ gr_basic_block_vector_t calc_reachable_blocks(gr_basic_block_sptr block, gr_basic_block_vector_t &blocks);
+ void reachable_dfs_visit(gr_basic_block_sptr block, gr_basic_block_vector_t &blocks);
+ gr_basic_block_vector_t calc_adjacent_blocks(gr_basic_block_sptr block, gr_basic_block_vector_t &blocks);
+ gr_basic_block_vector_t sort_sources_first(gr_basic_block_vector_t &blocks);
+ bool source_p(gr_basic_block_sptr block);
+ void topological_dfs_visit(gr_basic_block_sptr block, gr_basic_block_vector_t &output);
+};
+
+// Convenience functions
+inline
+void gr_flowgraph::connect(gr_basic_block_sptr src_block, int src_port,
+ gr_basic_block_sptr dst_block, int dst_port)
+{
+ connect(gr_endpoint(src_block, src_port),
+ gr_endpoint(dst_block, dst_port));
+}
+
+inline
+void gr_flowgraph::disconnect(gr_basic_block_sptr src_block, int src_port,
+ gr_basic_block_sptr dst_block, int dst_port)
+{
+ disconnect(gr_endpoint(src_block, src_port),
+ gr_endpoint(dst_block, dst_port));
+}
+
+inline std::ostream&
+operator <<(std::ostream &os, const gr_endpoint endp)
+{
+ os << endp.block() << ":" << endp.port();
+ return os;
+}
+
+inline std::ostream&
+operator <<(std::ostream &os, const gr_edge edge)
+{
+ os << edge.src() << "->" << edge.dst();
+ return os;
+}
+
+#endif /* INCLUDED_GR_FLOWGRAPH_H */
diff --git a/gnuradio-core/src/lib/runtime/gr_hier_block2.cc b/gnuradio-core/src/lib/runtime/gr_hier_block2.cc
new file mode 100644
index 000000000..04eb60fc6
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_hier_block2.cc
@@ -0,0 +1,77 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006,2007,2008 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_hier_block2.h>
+#include <boost/detail/atomic_count.hpp>
+
+static boost::detail::atomic_count unique_id_pool(0);
+
+
+gr_hier_block2::gr_hier_block2(void)
+{
+ //NOP
+}
+
+gr_hier_block2::gr_hier_block2(
+ const std::string &name,
+ gr_io_signature_sptr input_signature,
+ gr_io_signature_sptr output_signature
+):
+ gras::HierBlock(name),
+ _unique_id(++unique_id_pool),
+ _name(name)
+{
+ this->set_input_signature(input_signature);
+ this->set_output_signature(output_signature);
+}
+
+gr_hier_block2_sptr gr_make_hier_block2(
+ const std::string &name,
+ gr_io_signature_sptr input_signature,
+ gr_io_signature_sptr output_signature
+){
+ return gr_hier_block2_sptr(new gr_hier_block2(name, input_signature, output_signature));
+}
+
+gr_io_signature_sptr gr_hier_block2::input_signature(void) const
+{
+ return _in_sig;
+}
+
+gr_io_signature_sptr gr_hier_block2::output_signature(void) const
+{
+ return _out_sig;
+}
+
+void gr_hier_block2::set_input_signature(gr_io_signature_sptr sig)
+{
+ _in_sig = sig;
+}
+
+void gr_hier_block2::set_output_signature(gr_io_signature_sptr sig)
+{
+ _out_sig = sig;
+}
diff --git a/gnuradio-core/src/lib/runtime/gr_hier_block2.h b/gnuradio-core/src/lib/runtime/gr_hier_block2.h
new file mode 100644
index 000000000..d393c42cb
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_hier_block2.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2012-2013 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GNURADIO_GR_HIER_BLOCK2_H
+#define INCLUDED_GNURADIO_GR_HIER_BLOCK2_H
+
+#include <gr_core_api.h>
+#include <gras/hier_block.hpp>
+#include <gr_io_signature.h>
+
+struct GR_CORE_API gr_hier_block2 : gras::HierBlock
+{
+
+ gr_hier_block2(void);
+
+ gr_hier_block2(
+ const std::string &name,
+ gr_io_signature_sptr input_signature,
+ gr_io_signature_sptr output_signature
+ );
+
+ long unique_id(void) const{return _unique_id;}
+ std::string name(void) const{return _name;}
+ long _unique_id;
+ std::string _name;
+
+ const gr_hier_block2 &self(void) const
+ {
+ return *this;
+ }
+
+ gr_io_signature_sptr input_signature(void) const;
+ gr_io_signature_sptr output_signature(void) const;
+
+ void set_input_signature(gr_io_signature_sptr sig);
+ void set_output_signature(gr_io_signature_sptr sig);
+
+ inline void lock(void){}
+
+ inline void unlock(void){this->commit();}
+
+ gr_io_signature_sptr _in_sig, _out_sig;
+};
+
+typedef boost::shared_ptr<gr_hier_block2> gr_hier_block2_sptr;
+
+GR_CORE_API gr_hier_block2_sptr gr_make_hier_block2(
+ const std::string &name,
+ gr_io_signature_sptr input_signature,
+ gr_io_signature_sptr output_signature
+);
+
+#endif /*INCLUDED_GNURADIO_GR_HIER_BLOCK2_H*/
diff --git a/gnuradio-core/src/lib/runtime/gr_hier_block2.i b/gnuradio-core/src/lib/runtime/gr_hier_block2.i
new file mode 100644
index 000000000..a857394ca
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_hier_block2.i
@@ -0,0 +1,88 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005,2006,2007 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+%include <gr_basic_block.i>
+
+class gr_hier_block2;
+typedef boost::shared_ptr<gr_hier_block2> gr_hier_block2_sptr;
+%template(gr_hier_block2_sptr) boost::shared_ptr<gr_hier_block2>;
+
+// Hack to have a Python shim implementation of gr.hier_block2
+// that instantiates one of these and passes through calls
+%rename(hier_block2_swig) gr_make_hier_block2;
+gr_hier_block2_sptr gr_make_hier_block2(const std::string name,
+ gr_io_signature_sptr input_signature,
+ gr_io_signature_sptr output_signature)
+ throw (std::runtime_error);
+
+// Rename connect and disconnect so that we can more easily build a
+// better interface in scripting land.
+%rename(primitive_connect) gr_hier_block2::connect;
+%rename(primitive_disconnect) gr_hier_block2::disconnect;
+%rename(primitive_msg_connect) gr_hier_block2::msg_connect;
+%rename(primitive_msg_disconnect) gr_hier_block2::msg_disconnect;
+%rename(primitive_message_port_register_hier_in) gr_hier_block2::message_port_register_hier_in;
+%rename(primitive_message_port_register_hier_out) gr_hier_block2::message_port_register_hier_out;
+
+class gr_hier_block2 : public gr_basic_block
+{
+private:
+ gr_hier_block2(const std::string name,
+ gr_io_signature_sptr input_signature,
+ gr_io_signature_sptr output_signature);
+
+public:
+ ~gr_hier_block2 ();
+
+ void connect(gr_basic_block_sptr block)
+ throw (std::invalid_argument);
+ void connect(gr_basic_block_sptr src, int src_port,
+ gr_basic_block_sptr dst, int dst_port)
+ throw (std::invalid_argument);
+ void msg_connect(gr_basic_block_sptr src, pmt::pmt_t srcport,
+ gr_basic_block_sptr dst, pmt::pmt_t dstport)
+ throw (std::runtime_error);
+ void msg_connect(gr_basic_block_sptr src, std::string srcport,
+ gr_basic_block_sptr dst, std::string dstport)
+ throw (std::runtime_error);
+ void msg_disconnect(gr_basic_block_sptr src, pmt::pmt_t srcport,
+ gr_basic_block_sptr dst, pmt::pmt_t dstport)
+ throw (std::runtime_error);
+ void msg_disconnect(gr_basic_block_sptr src, std::string srcport,
+ gr_basic_block_sptr dst, std::string dstport)
+ throw (std::runtime_error);
+
+ void disconnect(gr_basic_block_sptr block)
+ throw (std::invalid_argument);
+ void disconnect(gr_basic_block_sptr src, int src_port,
+ gr_basic_block_sptr dst, int dst_port)
+ throw (std::invalid_argument);
+ void disconnect_all();
+ void lock();
+ void unlock();
+
+ void message_port_register_hier_in(pmt::pmt_t port_id);
+ void message_port_register_hier_out(pmt::pmt_t port_id);
+
+
+ gr_hier_block2_sptr to_hier_block2(); // Needed for Python type coercion
+};
diff --git a/gnuradio-core/src/lib/runtime/gr_hier_block2_detail.cc b/gnuradio-core/src/lib/runtime/gr_hier_block2_detail.cc
new file mode 100644
index 000000000..add6da024
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_hier_block2_detail.cc
@@ -0,0 +1,615 @@
+/*
+ * Copyright 2006,2007,2009 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_hier_block2_detail.h>
+#include <gr_io_signature.h>
+#include <stdexcept>
+#include <sstream>
+#include <boost/format.hpp>
+
+#define GR_HIER_BLOCK2_DETAIL_DEBUG 0
+
+gr_hier_block2_detail::gr_hier_block2_detail(gr_hier_block2 *owner) :
+ d_owner(owner),
+ d_parent_detail(0),
+ d_fg(gr_make_flowgraph())
+{
+ int min_inputs = owner->input_signature()->min_streams();
+ int max_inputs = owner->input_signature()->max_streams();
+ int min_outputs = owner->output_signature()->min_streams();
+ int max_outputs = owner->output_signature()->max_streams();
+
+ if (max_inputs == gr_io_signature::IO_INFINITE ||
+ max_outputs == gr_io_signature::IO_INFINITE ||
+ (min_inputs != max_inputs) ||(min_outputs != max_outputs) ) {
+ std::stringstream msg;
+ msg << "Hierarchical blocks do not yet support arbitrary or"
+ << " variable numbers of inputs or outputs (" << d_owner->name() << ")";
+ throw std::runtime_error(msg.str());
+ }
+
+ d_inputs = std::vector<gr_endpoint_vector_t>(max_inputs);
+ d_outputs = gr_endpoint_vector_t(max_outputs);
+}
+
+
+gr_hier_block2_detail::~gr_hier_block2_detail()
+{
+ d_owner = 0; // Don't use delete, we didn't allocate
+}
+
+void
+gr_hier_block2_detail::connect(gr_basic_block_sptr block)
+{
+ std::stringstream msg;
+
+ // Check if duplicate
+ if (std::find(d_blocks.begin(), d_blocks.end(), block) != d_blocks.end()) {
+ msg << "Block " << block << " already connected.";
+ throw std::invalid_argument(msg.str());
+ }
+
+ // Check if has inputs or outputs
+ if (block->input_signature()->max_streams() != 0 ||
+ block->output_signature()->max_streams() != 0) {
+ msg << "Block " << block << " must not have any input or output ports";
+ throw std::invalid_argument(msg.str());
+ }
+
+ gr_hier_block2_sptr hblock(cast_to_hier_block2_sptr(block));
+
+ if (hblock && hblock.get() != d_owner) {
+ if (GR_HIER_BLOCK2_DETAIL_DEBUG)
+ std::cout << "connect: block is hierarchical, setting parent to " << this << std::endl;
+ hblock->d_detail->d_parent_detail = this;
+ }
+
+ d_blocks.push_back(block);
+}
+
+void
+gr_hier_block2_detail::connect(gr_basic_block_sptr src, int src_port,
+ gr_basic_block_sptr dst, int dst_port)
+{
+ std::stringstream msg;
+
+ if (GR_HIER_BLOCK2_DETAIL_DEBUG)
+ std::cout << "connecting: " << gr_endpoint(src, src_port)
+ << " -> " << gr_endpoint(dst, dst_port) << std::endl;
+
+ if (src.get() == dst.get())
+ throw std::invalid_argument("connect: src and destination blocks cannot be the same");
+
+ gr_hier_block2_sptr src_block(cast_to_hier_block2_sptr(src));
+ gr_hier_block2_sptr dst_block(cast_to_hier_block2_sptr(dst));
+
+ if (src_block && src.get() != d_owner) {
+ if (GR_HIER_BLOCK2_DETAIL_DEBUG)
+ std::cout << "connect: src is hierarchical, setting parent to " << this << std::endl;
+ src_block->d_detail->d_parent_detail = this;
+ }
+
+ if (dst_block && dst.get() != d_owner) {
+ if (GR_HIER_BLOCK2_DETAIL_DEBUG)
+ std::cout << "connect: dst is hierarchical, setting parent to " << this << std::endl;
+ dst_block->d_detail->d_parent_detail = this;
+ }
+
+ // Connections to block inputs or outputs
+ int max_port;
+ if (src.get() == d_owner) {
+ max_port = src->input_signature()->max_streams();
+ if ((max_port != -1 && (src_port >= max_port)) || src_port < 0) {
+ msg << "source port " << src_port << " out of range for " << src;
+ throw std::invalid_argument(msg.str());
+ }
+
+ return connect_input(src_port, dst_port, dst);
+ }
+
+ if (dst.get() == d_owner) {
+ max_port = dst->output_signature()->max_streams();
+ if ((max_port != -1 && (dst_port >= max_port)) || dst_port < 0) {
+ msg << "destination port " << dst_port << " out of range for " << dst;
+ throw std::invalid_argument(msg.str());
+ }
+
+ return connect_output(dst_port, src_port, src);
+ }
+
+ // Internal connections
+ d_fg->connect(src, src_port, dst, dst_port);
+
+ // TODO: connects to NC
+}
+
+void
+gr_hier_block2_detail::msg_connect(gr_basic_block_sptr src, pmt::pmt_t srcport,
+ gr_basic_block_sptr dst, pmt::pmt_t dstport)
+{
+ if (GR_HIER_BLOCK2_DETAIL_DEBUG)
+ std::cout << "connecting message port..." << std::endl;
+
+ // register the subscription
+// this is done later...
+// src->message_port_sub(srcport, pmt::pmt_cons(dst->alias_pmt(), dstport));
+
+ // add block uniquely to list to internal blocks
+ if (std::find(d_blocks.begin(), d_blocks.end(), dst) == d_blocks.end()){
+ d_blocks.push_back(src);
+ d_blocks.push_back(dst);
+ }
+
+ bool hier_out = (d_owner == src.get()) && src->message_port_is_hier_out(srcport);;
+ bool hier_in = (d_owner == dst.get()) && dst->message_port_is_hier_in(dstport);
+
+ gr_hier_block2_sptr src_block(cast_to_hier_block2_sptr(src));
+ gr_hier_block2_sptr dst_block(cast_to_hier_block2_sptr(dst));
+
+ if (src_block && src.get() != d_owner) {
+ if (GR_HIER_BLOCK2_DETAIL_DEBUG)
+ std::cout << "connect: src is hierarchical, setting parent to " << this << std::endl;
+ src_block->d_detail->d_parent_detail = this;
+ }
+
+ if (dst_block && dst.get() != d_owner) {
+ if (GR_HIER_BLOCK2_DETAIL_DEBUG)
+ std::cout << "connect: dst is hierarchical, setting parent to " << this << std::endl;
+ dst_block->d_detail->d_parent_detail = this;
+ }
+
+ // add edge for this message connection
+ if(GR_HIER_BLOCK2_DETAIL_DEBUG)
+ std::cout << boost::format("connect( (%s, %s, %d), (%s, %s, %d) )\n") %
+ src % srcport % hier_out %
+ dst % dstport % hier_in;
+ d_fg->connect( gr_msg_endpoint(src, srcport, hier_out), gr_msg_endpoint(dst, dstport, hier_in));
+}
+
+void
+gr_hier_block2_detail::msg_disconnect(gr_basic_block_sptr src, pmt::pmt_t srcport,
+ gr_basic_block_sptr dst, pmt::pmt_t dstport)
+{
+ if (GR_HIER_BLOCK2_DETAIL_DEBUG)
+ std::cout << "disconnecting message port..." << std::endl;
+
+ // unregister the subscription - if already subscribed
+ src->message_port_unsub(srcport, pmt::pmt_cons(dst->alias_pmt(), dstport));
+
+ // remove edge for this message connection
+ bool hier_out = (d_owner == src.get()) && src->message_port_is_hier_out(srcport);;
+ bool hier_in = (d_owner == dst.get()) && dst->message_port_is_hier_in(dstport);
+ d_fg->disconnect( gr_msg_endpoint(src, srcport, hier_out), gr_msg_endpoint(dst, dstport, hier_in));
+}
+
+void
+gr_hier_block2_detail::disconnect(gr_basic_block_sptr block)
+{
+ // Check on singleton list
+ for (gr_basic_block_viter_t p = d_blocks.begin(); p != d_blocks.end(); p++) {
+ if (*p == block) {
+ d_blocks.erase(p);
+
+ gr_hier_block2_sptr hblock(cast_to_hier_block2_sptr(block));
+ if (block && block.get() != d_owner) {
+ if (GR_HIER_BLOCK2_DETAIL_DEBUG)
+ std::cout << "disconnect: block is hierarchical, clearing parent" << std::endl;
+ hblock->d_detail->d_parent_detail = 0;
+ }
+
+ return;
+ }
+ }
+
+ // Otherwise find all edges containing block
+ gr_edge_vector_t edges, tmp = d_fg->edges();
+ gr_edge_vector_t::iterator p;
+ for (p = tmp.begin(); p != tmp.end(); p++) {
+ if ((*p).src().block() == block || (*p).dst().block() == block) {
+ edges.push_back(*p);
+
+ if (GR_HIER_BLOCK2_DETAIL_DEBUG)
+ std::cout << "disconnect: block found in edge " << (*p) << std::endl;
+ }
+ }
+
+ if (edges.size() == 0) {
+ std::stringstream msg;
+ msg << "cannot disconnect block " << block << ", not found";
+ throw std::invalid_argument(msg.str());
+ }
+
+ for (p = edges.begin(); p != edges.end(); p++) {
+ disconnect((*p).src().block(), (*p).src().port(),
+ (*p).dst().block(), (*p).dst().port());
+ }
+}
+
+void
+gr_hier_block2_detail::disconnect(gr_basic_block_sptr src, int src_port,
+ gr_basic_block_sptr dst, int dst_port)
+{
+ if (GR_HIER_BLOCK2_DETAIL_DEBUG)
+ std::cout << "disconnecting: " << gr_endpoint(src, src_port)
+ << " -> " << gr_endpoint(dst, dst_port) << std::endl;
+
+ if (src.get() == dst.get())
+ throw std::invalid_argument("disconnect: source and destination blocks cannot be the same");
+
+ gr_hier_block2_sptr src_block(cast_to_hier_block2_sptr(src));
+ gr_hier_block2_sptr dst_block(cast_to_hier_block2_sptr(dst));
+
+ if (src_block && src.get() != d_owner) {
+ if (GR_HIER_BLOCK2_DETAIL_DEBUG)
+ std::cout << "disconnect: src is hierarchical, clearing parent" << std::endl;
+ src_block->d_detail->d_parent_detail = 0;
+ }
+
+ if (dst_block && dst.get() != d_owner) {
+ if (GR_HIER_BLOCK2_DETAIL_DEBUG)
+ std::cout << "disconnect: dst is hierarchical, clearing parent" << std::endl;
+ dst_block->d_detail->d_parent_detail = 0;
+ }
+
+ if (src.get() == d_owner)
+ return disconnect_input(src_port, dst_port, dst);
+
+ if (dst.get() == d_owner)
+ return disconnect_output(dst_port, src_port, src);
+
+ // Internal connections
+ d_fg->disconnect(src, src_port, dst, dst_port);
+}
+
+void
+gr_hier_block2_detail::connect_input(int my_port, int port, gr_basic_block_sptr block)
+{
+ std::stringstream msg;
+
+ if (my_port < 0 || my_port >= (signed)d_inputs.size()) {
+ msg << "input port " << my_port << " out of range for " << block;
+ throw std::invalid_argument(msg.str());
+ }
+
+ gr_endpoint_vector_t &endps = d_inputs[my_port];
+ gr_endpoint endp(block, port);
+
+ gr_endpoint_viter_t p = std::find(endps.begin(), endps.end(), endp);
+ if (p != endps.end()) {
+ msg << "external input port " << my_port << " already wired to " << endp;
+ throw std::invalid_argument(msg.str());
+ }
+
+ endps.push_back(endp);
+}
+
+void
+gr_hier_block2_detail::connect_output(int my_port, int port, gr_basic_block_sptr block)
+{
+ std::stringstream msg;
+
+ if (my_port < 0 || my_port >= (signed)d_outputs.size()) {
+ msg << "output port " << my_port << " out of range for " << block;
+ throw std::invalid_argument(msg.str());
+ }
+
+ if (d_outputs[my_port].block()) {
+ msg << "external output port " << my_port << " already connected from "
+ << d_outputs[my_port];
+ throw std::invalid_argument(msg.str());
+ }
+
+ d_outputs[my_port] = gr_endpoint(block, port);
+}
+
+void
+gr_hier_block2_detail::disconnect_input(int my_port, int port, gr_basic_block_sptr block)
+{
+ std::stringstream msg;
+
+ if (my_port < 0 || my_port >= (signed)d_inputs.size()) {
+ msg << "input port number " << my_port << " out of range for " << block;
+ throw std::invalid_argument(msg.str());
+ }
+
+ gr_endpoint_vector_t &endps = d_inputs[my_port];
+ gr_endpoint endp(block, port);
+
+ gr_endpoint_viter_t p = std::find(endps.begin(), endps.end(), endp);
+ if (p == endps.end()) {
+ msg << "external input port " << my_port << " not connected to " << endp;
+ throw std::invalid_argument(msg.str());
+ }
+
+ endps.erase(p);
+}
+
+void
+gr_hier_block2_detail::disconnect_output(int my_port, int port, gr_basic_block_sptr block)
+{
+ std::stringstream msg;
+
+ if (my_port < 0 || my_port >= (signed)d_outputs.size()) {
+ msg << "output port number " << my_port << " out of range for " << block;
+ throw std::invalid_argument(msg.str());
+ }
+
+ if (d_outputs[my_port].block() != block) {
+ msg << "block " << block << " not assigned to output "
+ << my_port << ", can't disconnect";
+ throw std::invalid_argument(msg.str());
+ }
+
+ d_outputs[my_port] = gr_endpoint();
+}
+
+gr_endpoint_vector_t
+gr_hier_block2_detail::resolve_port(int port, bool is_input)
+{
+ std::stringstream msg;
+
+ if (GR_HIER_BLOCK2_DETAIL_DEBUG)
+ std::cout << "Resolving port " << port << " as an "
+ << (is_input ? "input" : "output")
+ << " of " << d_owner->name() << std::endl;
+
+ gr_endpoint_vector_t result;
+
+ if (is_input) {
+ if (port < 0 || port >= (signed)d_inputs.size()) {
+ msg << "resolve_port: hierarchical block '" << d_owner->name()
+ << "': input " << port << " is out of range";
+ throw std::runtime_error(msg.str());
+ }
+
+ if (d_inputs[port].empty()) {
+ msg << "resolve_port: hierarchical block '" << d_owner->name()
+ << "': input " << port << " is not connected internally";
+ throw std::runtime_error(msg.str());
+ }
+
+ gr_endpoint_vector_t &endps = d_inputs[port];
+ gr_endpoint_viter_t p;
+ for (p = endps.begin(); p != endps.end(); p++) {
+ gr_endpoint_vector_t tmp = resolve_endpoint(*p, true);
+ std::copy(tmp.begin(), tmp.end(), back_inserter(result));
+ }
+ }
+ else {
+ if (port < 0 || port >= (signed)d_outputs.size()) {
+ msg << "resolve_port: hierarchical block '" << d_owner->name()
+ << "': output " << port << " is out of range";
+ throw std::runtime_error(msg.str());
+ }
+
+ if (d_outputs[port] == gr_endpoint()) {
+ msg << "resolve_port: hierarchical block '" << d_owner->name()
+ << "': output " << port << " is not connected internally";
+ throw std::runtime_error(msg.str());
+ }
+
+ result = resolve_endpoint(d_outputs[port], false);
+ }
+
+ if (result.empty()) {
+ msg << "resolve_port: hierarchical block '" << d_owner->name()
+ << "': unable to resolve "
+ << (is_input ? "input port " : "output port ")
+ << port;
+ throw std::runtime_error(msg.str());
+ }
+
+ return result;
+}
+
+void
+gr_hier_block2_detail::disconnect_all()
+{
+ d_fg->clear();
+ d_blocks.clear();
+ d_inputs.clear();
+ d_outputs.clear();
+}
+
+gr_endpoint_vector_t
+gr_hier_block2_detail::resolve_endpoint(const gr_endpoint &endp, bool is_input) const
+{
+ std::stringstream msg;
+ gr_endpoint_vector_t result;
+
+ // Check if endpoint is a leaf node
+ if (cast_to_block_sptr(endp.block())) {
+ if (GR_HIER_BLOCK2_DETAIL_DEBUG)
+ std::cout << "Block " << endp.block() << " is a leaf node, returning." << std::endl;
+ result.push_back(endp);
+ return result;
+ }
+
+ // Check if endpoint is a hierarchical block
+ gr_hier_block2_sptr hier_block2(cast_to_hier_block2_sptr(endp.block()));
+ if (hier_block2) {
+ if (GR_HIER_BLOCK2_DETAIL_DEBUG)
+ std::cout << "Resolving endpoint " << endp << " as an "
+ << (is_input ? "input" : "output")
+ << ", recursing" << std::endl;
+ return hier_block2->d_detail->resolve_port(endp.port(), is_input);
+ }
+
+ msg << "unable to resolve" << (is_input ? " input " : " output ")
+ << "endpoint " << endp;
+ throw std::runtime_error(msg.str());
+}
+
+void
+gr_hier_block2_detail::flatten_aux(gr_flat_flowgraph_sptr sfg) const
+{
+ if (GR_HIER_BLOCK2_DETAIL_DEBUG)
+ std::cout << " ** Flattening " << d_owner->name() << std::endl;
+
+ // Add my edges to the flow graph, resolving references to actual endpoints
+ gr_edge_vector_t edges = d_fg->edges();
+ gr_msg_edge_vector_t msg_edges = d_fg->msg_edges();
+ gr_edge_viter_t p;
+ gr_msg_edge_viter_t q,u;
+
+ if (GR_HIER_BLOCK2_DETAIL_DEBUG)
+ std::cout << "Flattening stream connections: " << std::endl;
+
+ for (p = edges.begin(); p != edges.end(); p++) {
+ if (GR_HIER_BLOCK2_DETAIL_DEBUG)
+ std::cout << "Flattening edge " << (*p) << std::endl;
+
+ gr_endpoint_vector_t src_endps = resolve_endpoint(p->src(), false);
+ gr_endpoint_vector_t dst_endps = resolve_endpoint(p->dst(), true);
+
+ gr_endpoint_viter_t s, d;
+ for (s = src_endps.begin(); s != src_endps.end(); s++) {
+ for (d = dst_endps.begin(); d != dst_endps.end(); d++) {
+ if (GR_HIER_BLOCK2_DETAIL_DEBUG)
+ std::cout << (*s) << "->" << (*d) << std::endl;
+ sfg->connect(*s, *d);
+ }
+ }
+ }
+
+ // loop through flattening hierarchical connections
+ if (GR_HIER_BLOCK2_DETAIL_DEBUG)
+ std::cout << "Flattening msg connections: " << std::endl;
+
+
+ std::vector<std::pair<gr_msg_endpoint, bool> > resolved_endpoints;
+ for(q = msg_edges.begin(); q != msg_edges.end(); q++) {
+ if (GR_HIER_BLOCK2_DETAIL_DEBUG)
+ std::cout << boost::format(" flattening edge ( %s, %s, %d) -> ( %s, %s, %d)\n") % q->src().block() % q->src().port() % q->src().is_hier() % q->dst().block() % q->dst().port() % q->dst().is_hier();
+
+ bool normal_connection = true;
+
+ // resolve existing connections to hier ports
+ if(q->dst().is_hier()){
+ if (GR_HIER_BLOCK2_DETAIL_DEBUG)
+ std::cout << boost::format(" resolve hier output (%s, %s)") % q->dst().block() % q->dst().port() << std::endl;
+ sfg->replace_endpoint( q->dst(), q->src(), true );
+ resolved_endpoints.push_back(std::pair<gr_msg_endpoint, bool>(q->dst(),true));
+ normal_connection = false;
+ }
+
+ if(q->src().is_hier()){
+ if (GR_HIER_BLOCK2_DETAIL_DEBUG)
+ std::cout << boost::format(" resolve hier input (%s, %s)") % q->src().block() % q->src().port() << std::endl;
+ sfg->replace_endpoint( q->src(), q->dst(), false );
+ resolved_endpoints.push_back(std::pair<gr_msg_endpoint, bool>(q->src(),false));
+ normal_connection = false;
+ }
+
+ // propogate non hier connections through
+ if(normal_connection){
+ sfg->connect( q->src(), q->dst() );
+ }
+ }
+ for(std::vector<std::pair<gr_msg_endpoint, bool> >::iterator it = resolved_endpoints.begin(); it != resolved_endpoints.end(); it++){
+ sfg->clear_endpoint( (*it).first, (*it).second );
+ }
+
+/* // connect primitive edges in the new fg
+ for(q = msg_edges.begin(); q != msg_edges.end(); q++) {
+ if( (!q->src().is_hier()) && (!q->dst().is_hier()) ){
+ sfg->connect( q->src(), q->dst() );
+ } else {
+ std::cout << "not connecting hier connection!" << std::endl;
+ }
+ }*/
+
+ // Construct unique list of blocks used either in edges, inputs,
+ // outputs, or by themselves. I still hate STL.
+ gr_basic_block_vector_t blocks; // unique list of used blocks
+ gr_basic_block_vector_t tmp = d_fg->calc_used_blocks();
+
+ // First add the list of singleton blocks
+ std::vector<gr_basic_block_sptr>::const_iterator b; // Because flatten_aux is const
+ for (b = d_blocks.begin(); b != d_blocks.end(); b++)
+ tmp.push_back(*b);
+
+ // Now add the list of connected input blocks
+ std::stringstream msg;
+ for (unsigned int i = 0; i < d_inputs.size(); i++) {
+ if (d_inputs[i].size() == 0) {
+ msg << "In hierarchical block " << d_owner->name() << ", input " << i
+ << " is not connected internally";
+ throw std::runtime_error(msg.str());
+ }
+
+ for (unsigned int j = 0; j < d_inputs[i].size(); j++)
+ tmp.push_back(d_inputs[i][j].block());
+ }
+
+ for (unsigned int i = 0; i < d_outputs.size(); i++) {
+ gr_basic_block_sptr blk = d_outputs[i].block();
+ if (!blk) {
+ msg << "In hierarchical block " << d_owner->name() << ", output " << i
+ << " is not connected internally";
+ throw std::runtime_error(msg.str());
+ }
+ tmp.push_back(blk);
+ }
+ sort(tmp.begin(), tmp.end());
+
+ std::insert_iterator<gr_basic_block_vector_t> inserter(blocks, blocks.begin());
+ unique_copy(tmp.begin(), tmp.end(), inserter);
+
+ // Recurse hierarchical children
+ for (gr_basic_block_viter_t p = blocks.begin(); p != blocks.end(); p++) {
+ gr_hier_block2_sptr hier_block2(cast_to_hier_block2_sptr(*p));
+ if (hier_block2 && (hier_block2.get() != d_owner)) {
+ if (GR_HIER_BLOCK2_DETAIL_DEBUG)
+ std::cout << "flatten_aux: recursing into hierarchical block " << hier_block2 << std::endl;
+ hier_block2->d_detail->flatten_aux(sfg);
+ }
+ }
+}
+
+void
+gr_hier_block2_detail::lock()
+{
+ if (GR_HIER_BLOCK2_DETAIL_DEBUG)
+ std::cout << "lock: entered in " << this << std::endl;
+
+ if (d_parent_detail)
+ d_parent_detail->lock();
+ else
+ d_owner->lock();
+}
+
+void
+gr_hier_block2_detail::unlock()
+{
+ if (GR_HIER_BLOCK2_DETAIL_DEBUG)
+ std::cout << "unlock: entered in " << this << std::endl;
+
+ if (d_parent_detail)
+ d_parent_detail->unlock();
+ else
+ d_owner->unlock();
+}
+
diff --git a/gnuradio-core/src/lib/runtime/gr_hier_block2_detail.h b/gnuradio-core/src/lib/runtime/gr_hier_block2_detail.h
new file mode 100644
index 000000000..b38dae301
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_hier_block2_detail.h
@@ -0,0 +1,74 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006,2007,2009 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifndef INCLUDED_GR_HIER_BLOCK2_DETAIL_H
+#define INCLUDED_GR_HIER_BLOCK2_DETAIL_H
+
+#include <gr_core_api.h>
+#include <gr_hier_block2.h>
+#include <gr_flat_flowgraph.h>
+#include <boost/utility.hpp>
+
+/*!
+ * \ingroup internal
+ */
+class GR_CORE_API gr_hier_block2_detail : boost::noncopyable
+{
+public:
+ gr_hier_block2_detail(gr_hier_block2 *owner);
+ ~gr_hier_block2_detail();
+
+ void connect(gr_basic_block_sptr block);
+ void connect(gr_basic_block_sptr src, int src_port,
+ gr_basic_block_sptr dst, int dst_port);
+ void msg_connect(gr_basic_block_sptr src, pmt::pmt_t srcport,
+ gr_basic_block_sptr dst, pmt::pmt_t dstport);
+ void msg_disconnect(gr_basic_block_sptr src, pmt::pmt_t srcport,
+ gr_basic_block_sptr dst, pmt::pmt_t dstport);
+ void disconnect(gr_basic_block_sptr block);
+ void disconnect(gr_basic_block_sptr, int src_port,
+ gr_basic_block_sptr, int dst_port);
+ void disconnect_all();
+ void lock();
+ void unlock();
+ void flatten_aux(gr_flat_flowgraph_sptr sfg) const;
+
+private:
+
+ // Private implementation data
+ gr_hier_block2 *d_owner;
+ gr_hier_block2_detail *d_parent_detail;
+ gr_flowgraph_sptr d_fg;
+ std::vector<gr_endpoint_vector_t> d_inputs; // Multiple internal endpoints per external input
+ gr_endpoint_vector_t d_outputs; // Single internal endpoint per external output
+ gr_basic_block_vector_t d_blocks;
+
+
+ void connect_input(int my_port, int port, gr_basic_block_sptr block);
+ void connect_output(int my_port, int port, gr_basic_block_sptr block);
+ void disconnect_input(int my_port, int port, gr_basic_block_sptr block);
+ void disconnect_output(int my_port, int port, gr_basic_block_sptr block);
+
+ gr_endpoint_vector_t resolve_port(int port, bool is_input);
+ gr_endpoint_vector_t resolve_endpoint(const gr_endpoint &endp, bool is_input) const;
+};
+
+#endif /* INCLUDED_GR_HIER_BLOCK2_DETAIL_H */
diff --git a/gnuradio-core/src/lib/runtime/gr_io_signature.cc b/gnuradio-core/src/lib/runtime/gr_io_signature.cc
new file mode 100644
index 000000000..6ac9acd17
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_io_signature.cc
@@ -0,0 +1,112 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2007 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <gr_io_signature.h>
+#include <stdexcept>
+#include <iostream>
+
+gr_io_signature_sptr
+gr_make_io_signaturev(int min_streams, int max_streams,
+ const std::vector<int> &sizeof_stream_items)
+{
+ return gr_io_signature_sptr (new gr_io_signature (min_streams, max_streams,
+ sizeof_stream_items));
+}
+
+gr_io_signature_sptr
+gr_make_io_signature(int min_streams, int max_streams,
+ int sizeof_stream_item)
+{
+ std::vector<int> sizeof_items(1);
+ sizeof_items[0] = sizeof_stream_item;
+ return gr_make_io_signaturev(min_streams, max_streams, sizeof_items);
+}
+
+gr_io_signature_sptr
+gr_make_io_signature2(int min_streams, int max_streams,
+ int sizeof_stream_item1,
+ int sizeof_stream_item2)
+{
+ std::vector<int> sizeof_items(2);
+ sizeof_items[0] = sizeof_stream_item1;
+ sizeof_items[1] = sizeof_stream_item2;
+ return gr_make_io_signaturev(min_streams, max_streams, sizeof_items);
+}
+
+gr_io_signature_sptr
+gr_make_io_signature3(int min_streams, int max_streams,
+ int sizeof_stream_item1,
+ int sizeof_stream_item2,
+ int sizeof_stream_item3)
+{
+ std::vector<int> sizeof_items(3);
+ sizeof_items[0] = sizeof_stream_item1;
+ sizeof_items[1] = sizeof_stream_item2;
+ sizeof_items[2] = sizeof_stream_item3;
+ return gr_make_io_signaturev(min_streams, max_streams, sizeof_items);
+}
+
+// ------------------------------------------------------------------------
+
+
+gr_io_signature::gr_io_signature (int min_streams, int max_streams,
+ const std::vector<int> &sizeof_stream_items)
+{
+ if (min_streams < 0
+ || (max_streams != IO_INFINITE && max_streams < min_streams))
+ throw std::invalid_argument ("gr_io_signature(1)");
+
+ if (sizeof_stream_items.size() < 1)
+ throw std::invalid_argument("gr_io_signature(2)");
+
+ for (size_t i = 0; i < sizeof_stream_items.size(); i++){
+ if (max_streams != 0 && sizeof_stream_items[i] < 1)
+ throw std::invalid_argument("gr_io_signature(3)");
+ }
+
+ d_min_streams = min_streams;
+ d_max_streams = max_streams;
+ d_sizeof_stream_item = sizeof_stream_items;
+}
+
+gr_io_signature::~gr_io_signature ()
+{
+}
+
+int
+gr_io_signature::sizeof_stream_item (int _index) const
+{
+ if (_index < 0)
+ throw std::invalid_argument ("gr_io_signature::sizeof_stream_item");
+
+ size_t index = _index;
+ return d_sizeof_stream_item[std::min(index, d_sizeof_stream_item.size() - 1)];
+}
+
+std::vector<int>
+gr_io_signature::sizeof_stream_items() const
+{
+ return d_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
index 000000000..fd1825797
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_io_signature.h
@@ -0,0 +1,117 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2007 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_IO_SIGNATURE_H
+#define INCLUDED_IO_SIGNATURE_H
+
+#include <gr_core_api.h>
+#include <gr_runtime_types.h>
+
+/*!
+ * \brief Create an i/o signature
+ *
+ * \ingroup internal
+ * \param min_streams specify minimum number of streams (>= 0)
+ * \param max_streams specify maximum number of streams (>= min_streams or -1 -> infinite)
+ * \param sizeof_stream_item specify the size of the items in each stream
+ */
+GR_CORE_API gr_io_signature_sptr
+gr_make_io_signature(int min_streams, int max_streams,
+ int sizeof_stream_item);
+
+/*!
+ * \brief Create an i/o signature
+ *
+ * \param min_streams specify minimum number of streams (>= 0)
+ * \param max_streams specify maximum number of streams (>= min_streams or -1 -> infinite)
+ * \param sizeof_stream_item1 specify the size of the items in the first stream
+ * \param sizeof_stream_item2 specify the size of the items in the second and subsequent streams
+ */
+GR_CORE_API gr_io_signature_sptr
+gr_make_io_signature2(int min_streams, int max_streams,
+ int sizeof_stream_item1,
+ int sizeof_stream_item2
+ );
+
+/*!
+ * \brief Create an i/o signature
+ *
+ * \param min_streams specify minimum number of streams (>= 0)
+ * \param max_streams specify maximum number of streams (>= min_streams or -1 -> infinite)
+ * \param sizeof_stream_item1 specify the size of the items in the first stream
+ * \param sizeof_stream_item2 specify the size of the items in the second stream
+ * \param sizeof_stream_item3 specify the size of the items in the third and subsequent streams
+ */
+GR_CORE_API gr_io_signature_sptr
+gr_make_io_signature3(int min_streams, int max_streams,
+ int sizeof_stream_item1,
+ int sizeof_stream_item2,
+ int sizeof_stream_item3
+ );
+
+/*!
+ * \brief Create an i/o signature
+ *
+ * \param min_streams specify minimum number of streams (>= 0)
+ * \param max_streams specify maximum number of streams (>= min_streams or -1 -> infinite)
+ * \param sizeof_stream_items specify the size of the items in the streams
+ *
+ * If there are more streams than there are entries in sizeof_stream_items, the
+ * value of the last entry in sizeof_stream_items is used for the missing values.
+ * sizeof_stream_items must contain at least 1 entry.
+ */
+GR_CORE_API gr_io_signature_sptr
+gr_make_io_signaturev(int min_streams, int max_streams,
+ const std::vector<int> &sizeof_stream_items);
+
+
+/*!
+ * \brief i/o signature for input and output ports.
+ * \brief misc
+ */
+class GR_CORE_API gr_io_signature {
+ int d_min_streams;
+ int d_max_streams;
+ std::vector<int> d_sizeof_stream_item;
+
+ gr_io_signature(int min_streams, int max_streams,
+ const std::vector<int> &sizeof_stream_items);
+
+ friend GR_CORE_API gr_io_signature_sptr
+ gr_make_io_signaturev(int min_streams,
+ int max_streams,
+ const std::vector<int> &sizeof_stream_items);
+
+ 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; }
+ int sizeof_stream_item (int index) const;
+ std::vector<int> sizeof_stream_items() const;
+};
+
+
+#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
index 000000000..fe1707e41
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_io_signature.i
@@ -0,0 +1,73 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2005,2007 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+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;
+%rename(io_signature2) gr_make_io_signature2;
+%rename(io_signature3) gr_make_io_signature3;
+%rename(io_signaturev) gr_make_io_signaturev;
+
+
+gr_io_signature_sptr
+gr_make_io_signature(int min_streams, int max_streams,
+ int sizeof_stream_item);
+
+gr_io_signature_sptr
+gr_make_io_signature2(int min_streams, int max_streams,
+ int sizeof_stream_item1,
+ int sizeof_stream_item2
+ );
+gr_io_signature_sptr
+gr_make_io_signature3(int min_streams, int max_streams,
+ int sizeof_stream_item1,
+ int sizeof_stream_item2,
+ int sizeof_stream_item3
+ );
+gr_io_signature_sptr
+gr_make_io_signaturev(int min_streams, int max_streams,
+ const std::vector<int> &sizeof_stream_items);
+
+
+class gr_io_signature {
+ gr_io_signature (int min_streams, int max_streams, int sizeof_stream_item);
+
+ friend gr_io_signature_sptr
+ gr_make_io_signaturev(int min_streams,
+ int max_streams,
+ const std::vector<int> &sizeof_stream_item);
+
+ 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; }
+ int sizeof_stream_item (int index) const;
+ std::vector<int> sizeof_stream_items() const;
+};
+
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
index 000000000..fb31742e1
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_local_sighandler.cc
@@ -0,0 +1,187 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_local_sighandler.h>
+#include <stdexcept>
+#include <stdio.h>
+#include <string.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
index 000000000..a30e2c13a
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_local_sighandler.h
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_LOCAL_SIGHANDLER_H
+#define INCLUDED_GR_LOCAL_SIGHANDLER_H
+
+#ifdef HAVE_SIGNAL_H
+#include <signal.h>
+#endif
+
+#include <gr_core_api.h>
+#include <string>
+
+/*!
+ * \brief Get and set signal handler.
+ *
+ * \ingroup internal
+ * Constructor installs new handler, destructor reinstalls
+ * original value.
+ */
+class GR_CORE_API 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_CORE_API 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
index 000000000..a99dcd765
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_message.cc
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include <gr_message.h>
+#include <assert.h>
+#include <string.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
index 000000000..d386ca009
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_message.h
@@ -0,0 +1,91 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifndef INCLUDED_GR_MESSAGE_H
+#define INCLUDED_GR_MESSAGE_H
+
+#include <gr_core_api.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_CORE_API gr_message_sptr
+gr_make_message(long type = 0, double arg1 = 0, double arg2 = 0, size_t length = 0);
+
+GR_CORE_API gr_message_sptr
+gr_make_message_from_string(const std::string s, long type = 0, double arg1 = 0, double arg2 = 0);
+
+/*!
+ * \brief Message class.
+ *
+ * \ingroup misc
+ * The ideas and method names for adjustable message length were
+ * lifted from the click modular router "Packet" class.
+ */
+class GR_CORE_API 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_CORE_API gr_message_sptr
+ gr_make_message (long type, double arg1, double arg2, size_t length);
+
+ friend GR_CORE_API 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;
+
+};
+
+GR_CORE_API 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
index 000000000..356bba5b5
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_message.i
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+class 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_accepter.cc b/gnuradio-core/src/lib/runtime/gr_msg_accepter.cc
new file mode 100644
index 000000000..93d5fb20e
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_msg_accepter.cc
@@ -0,0 +1,59 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2009 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <gr_msg_accepter.h>
+#include <gr_block.h>
+#include <gr_block_detail.h>
+#include <gr_hier_block2.h>
+#include <stdexcept>
+
+using namespace pmt;
+
+gr_msg_accepter::gr_msg_accepter()
+{
+}
+
+gr_msg_accepter::~gr_msg_accepter()
+{
+ // NOP, required as virtual destructor
+}
+
+void
+gr_msg_accepter::post(pmt_t which_port, pmt_t msg)
+{
+ // Notify derived class, handled case by case
+ gr_block *p = dynamic_cast<gr_block *>(this);
+ if (p) {
+ p->_post(which_port,msg);
+ return;
+ }
+ gr_hier_block2 *p2 = dynamic_cast<gr_hier_block2 *>(this);
+ if (p2){
+ // FIXME do the right thing
+ return;
+ }
+
+ throw std::runtime_error("unknown derived class");
+}
diff --git a/gnuradio-core/src/lib/runtime/gr_msg_accepter.h b/gnuradio-core/src/lib/runtime/gr_msg_accepter.h
new file mode 100644
index 000000000..a497ba6e7
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_msg_accepter.h
@@ -0,0 +1,43 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2009 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef INCLUDED_GR_MSG_ACCEPTER_H
+#define INCLUDED_GR_MSG_ACCEPTER_H
+
+#include <gr_core_api.h>
+#include <gruel/msg_accepter.h>
+#include <gruel/pmt.h>
+
+/*!
+ * \brief Accepts messages and inserts them into a message queue, then notifies
+ * subclass gr_basic_block there is a message pending.
+ */
+class GR_CORE_API gr_msg_accepter : public gruel::msg_accepter
+{
+public:
+ gr_msg_accepter();
+ ~gr_msg_accepter();
+
+ void post(pmt::pmt_t which_port, pmt::pmt_t msg);
+
+};
+
+#endif /* INCLUDED_GR_MSG_ACCEPTER_H */
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
index 000000000..0f9349708
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_msg_handler.cc
@@ -0,0 +1,30 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include <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
index 000000000..57e8a95d6
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_msg_handler.h
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifndef INCLUDED_GR_MSG_HANDLER_H
+#define INCLUDED_GR_MSG_HANDLER_H
+
+#include <gr_core_api.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
+ * \ingroup base
+ */
+class GR_CORE_API 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
index 000000000..f493dac1b
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_msg_handler.i
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, 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
index 000000000..0cf046771
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_msg_queue.cc
@@ -0,0 +1,125 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005,2009 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#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_not_full(),
+ /*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");
+
+ gruel::scoped_lock guard(d_mutex);
+
+ while (full_p())
+ d_not_full.wait(guard);
+
+ 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.notify_one();
+}
+
+gr_message_sptr
+gr_msg_queue::delete_head()
+{
+ gruel::scoped_lock guard(d_mutex);
+ gr_message_sptr m;
+
+ while ((m = d_head) == 0)
+ d_not_empty.wait(guard);
+
+ 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.notify_one();
+ return m;
+}
+
+gr_message_sptr
+gr_msg_queue::delete_head_nowait()
+{
+ gruel::scoped_lock guard(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.notify_one();
+ 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
index 000000000..86440bbb0
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_msg_queue.h
@@ -0,0 +1,92 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005,2009 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifndef INCLUDED_GR_MSG_QUEUE_H
+#define INCLUDED_GR_MSG_QUEUE_H
+
+#include <gr_core_api.h>
+#include <gr_msg_handler.h>
+#include <gruel/thread.h>
+
+class gr_msg_queue;
+typedef boost::shared_ptr<gr_msg_queue> gr_msg_queue_sptr;
+
+GR_CORE_API gr_msg_queue_sptr gr_make_msg_queue(unsigned int limit=0);
+
+/*!
+ * \brief thread-safe message queue
+ * \ingroup misc
+ */
+class GR_CORE_API gr_msg_queue : public gr_msg_handler {
+
+ gruel::mutex d_mutex;
+ gruel::condition_variable d_not_empty;
+ gruel::condition_variable d_not_full;
+ gr_message_sptr d_head;
+ gr_message_sptr d_tail;
+ unsigned int d_count; // # of messages in queue.
+ unsigned int d_limit; // max # of messages in queue. 0 -> unbounded
+
+public:
+ gr_msg_queue(unsigned int limit);
+ ~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
index 000000000..65cbe782b
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_msg_queue.i
@@ -0,0 +1,107 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005,2009,2010,2011 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+class 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 {
+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();
+
+ //! 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...)
+ */
+#ifdef SWIGPYTHON
+%inline %{
+ gr_message_sptr gr_py_msg_queue__delete_head(gr_msg_queue_sptr q) {
+ gr_message_sptr msg;
+ GR_PYTHON_BLOCKING_CODE(
+ msg = q->delete_head();
+ )
+ return msg;
+ }
+
+ void gr_py_msg_queue__insert_tail(gr_msg_queue_sptr q, gr_message_sptr msg) {
+ GR_PYTHON_BLOCKING_CODE(
+ q->insert_tail(msg);
+ )
+ }
+%}
+
+// 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
+%}
+#endif // SWIGPYTHON
diff --git a/gnuradio-core/src/lib/runtime/gr_pagesize.cc b/gnuradio-core/src/lib/runtime/gr_pagesize.cc
new file mode 100644
index 000000000..e31e05ca7
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_pagesize.cc
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_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
index 000000000..3e2daa925
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_pagesize.h
@@ -0,0 +1,34 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifndef _GR_PAGESIZE_H_
+#define _GR_PAGESIZE_H_
+
+#include <gr_core_api.h>
+
+/*!
+ * \brief return the page size in bytes
+ */
+
+GR_CORE_API int gr_pagesize ();
+
+
+#endif /* _GR_PAGESIZE_H_ */ \ No newline at end of file
diff --git a/gnuradio-core/src/lib/runtime/gr_preferences.cc b/gnuradio-core/src/lib/runtime/gr_preferences.cc
new file mode 100644
index 000000000..a0f561660
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_preferences.cc
@@ -0,0 +1,108 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003,2010,2011 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_preferences.h>
+#include <gr_sys_paths.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <string.h>
+
+#include <boost/filesystem/operations.hpp>
+#include <boost/filesystem/path.hpp>
+namespace fs = boost::filesystem;
+
+/*
+ * 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 fs::path path;
+ path = fs::path(gr_appdata_path()) / ".gnuradio" / "prefs" / key;
+ return path.string().c_str();
+}
+
+static void
+ensure_dir_path ()
+{
+ fs::path path = fs::path(gr_appdata_path()) / ".gnuradio";
+ if (!fs::is_directory(path)) fs::create_directory(path);
+
+ path = path / "prefs";
+ if (!fs::is_directory(path)) fs::create_directory(path);
+}
+
+const char *
+gr_preferences::get (const char *key)
+{
+ static char buf[1024];
+
+ FILE *fp = fopen (pathname (key), "r");
+ if (fp == 0) {
+ perror (pathname (key));
+ return 0;
+ }
+
+ memset (buf, 0, sizeof (buf));
+ size_t ret = fread (buf, 1, sizeof (buf) - 1, fp);
+ if(ret == 0) {
+ if(ferror(fp) != 0) {
+ perror (pathname (key));
+ fclose (fp);
+ return 0;
+ }
+ }
+ 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;
+ }
+
+ size_t ret = fwrite (value, 1, strlen (value), fp);
+ if(ret == 0) {
+ if(ferror(fp) != 0) {
+ perror (pathname (key));
+ fclose (fp);
+ return;
+ }
+ }
+ 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
index 000000000..bfcc0424b
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_preferences.h
@@ -0,0 +1,34 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef _GR_PREFERENCES_H_
+#define _GR_PREFERENCES_H_
+
+#include <gr_core_api.h>
+
+class GR_CORE_API gr_preferences {
+ public:
+ static const char *get (const char *key);
+ static void set (const char *key, const char *value);
+};
+
+#endif /* _GR_PREFERENCES_H_ */ \ No newline at end of file
diff --git a/gnuradio-core/src/lib/runtime/gr_realtime.cc b/gnuradio-core/src/lib/runtime/gr_realtime.cc
new file mode 100644
index 000000000..75b497999
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_realtime.cc
@@ -0,0 +1,32 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006,2007,2008 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <gr_realtime.h>
+
+gr_rt_status_t
+gr_enable_realtime_scheduling()
+{
+ return gruel::enable_realtime_scheduling();
+}
diff --git a/gnuradio-core/src/lib/runtime/gr_realtime.h b/gnuradio-core/src/lib/runtime/gr_realtime.h
new file mode 100644
index 000000000..fe6549039
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_realtime.h
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_REALTIME_H
+#define INCLUDED_GR_REALTIME_H
+
+#include <gr_core_api.h>
+#include <gruel/realtime.h>
+
+typedef gruel::rt_status_t gr_rt_status_t;
+
+/*!
+ * \brief If possible, enable high-priority "real time" scheduling.
+ * \ingroup misc
+ */
+GR_CORE_API 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
index 000000000..1051d3e2b
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_realtime.i
@@ -0,0 +1,44 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+%rename(enable_realtime_scheduling) gr_enable_realtime_scheduling;
+
+// NOTE: This is duplicated from gruel/src/include/gruel/gr_realtime.h,
+// and must be kept in sync with it. This is the least evil workaround
+// for allowing 3rd party code builds to work when GNU Radio is
+// installed from binary packages into the standard system directories.
+// Otherwise, they can't find #include <gruel/gr_realtime.h>, since
+// pkg-config strips -I/usr/include from the --cflags path.
+
+namespace gruel {
+
+ typedef enum {
+ RT_OK = 0,
+ RT_NOT_IMPLEMENTED,
+ RT_NO_PRIVS,
+ RT_OTHER_ERROR
+ } rt_status_t;
+
+}
+
+typedef gruel::rt_status_t gr_rt_status_t;
+gr_rt_status_t gr_enable_realtime_scheduling();
diff --git a/gnuradio-core/src/lib/runtime/gr_runtime_types.h b/gnuradio-core/src/lib/runtime/gr_runtime_types.h
new file mode 100644
index 000000000..0d6149288
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_runtime_types.h
@@ -0,0 +1,56 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2007 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_RUNTIME_TYPES_H
+#define INCLUDED_GR_RUNTIME_TYPES_H
+
+#include <gr_core_api.h>
+#include <gr_types.h>
+
+/*
+ * typedefs for smart pointers we use throughout the runtime system
+ */
+
+class gr_basic_block;
+class gr_block;
+class gr_block_detail;
+class gr_hier_block2;
+class gr_io_signature;
+class gr_buffer;
+class gr_buffer_reader;
+class gr_flowgraph;
+class gr_flat_flowgraph;
+class gr_top_block;
+class gr_top_block_detail;
+
+typedef boost::shared_ptr<gr_basic_block> gr_basic_block_sptr;
+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_hier_block2> gr_hier_block2_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;
+typedef boost::shared_ptr<gr_flowgraph> gr_flowgraph_sptr;
+typedef boost::shared_ptr<gr_flat_flowgraph> gr_flat_flowgraph_sptr;
+typedef boost::shared_ptr<gr_top_block> gr_top_block_sptr;
+
+#endif /* INCLUDED_GR_RUNTIME_TYPES_H */
diff --git a/gnuradio-core/src/lib/runtime/gr_scheduler.cc b/gnuradio-core/src/lib/runtime/gr_scheduler.cc
new file mode 100644
index 000000000..c691f5d99
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_scheduler.cc
@@ -0,0 +1,33 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <gr_scheduler.h>
+
+gr_scheduler::gr_scheduler(gr_flat_flowgraph_sptr ffg, int max_noutput_items)
+{
+}
+
+gr_scheduler::~gr_scheduler()
+{
+}
diff --git a/gnuradio-core/src/lib/runtime/gr_scheduler.h b/gnuradio-core/src/lib/runtime/gr_scheduler.h
new file mode 100644
index 000000000..6d130327f
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_scheduler.h
@@ -0,0 +1,65 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef INCLUDED_GR_SCHEDULER_H
+#define INCLUDED_GR_SCHEDULER_H
+
+#include <gr_core_api.h>
+#include <boost/utility.hpp>
+#include <gr_block.h>
+#include <gr_flat_flowgraph.h>
+
+
+class gr_scheduler;
+typedef boost::shared_ptr<gr_scheduler> gr_scheduler_sptr;
+
+
+/*!
+ * \brief Abstract scheduler that takes a flattened flow graph and runs it.
+ *
+ * Preconditions: details, buffers and buffer readers have been assigned.
+ */
+class GR_CORE_API gr_scheduler : boost::noncopyable
+{
+
+public:
+ /*!
+ * \brief Construct a scheduler and begin evaluating the graph.
+ *
+ * The scheduler will continue running until all blocks until they
+ * report that they are done or the stop method is called.
+ */
+ gr_scheduler(gr_flat_flowgraph_sptr ffg, int max_noutput_items);
+
+ virtual ~gr_scheduler();
+
+ /*!
+ * \brief Tell the scheduler to stop executing.
+ */
+ virtual void stop() = 0;
+
+ /*!
+ * \brief Block until the graph is done.
+ */
+ virtual void wait() = 0;
+};
+
+#endif /* INCLUDED_GR_SCHEDULER_H */
diff --git a/gnuradio-core/src/lib/runtime/gr_scheduler_sts.cc b/gnuradio-core/src/lib/runtime/gr_scheduler_sts.cc
new file mode 100644
index 000000000..2c96def6d
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_scheduler_sts.cc
@@ -0,0 +1,87 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <gr_scheduler_sts.h>
+#include <gr_single_threaded_scheduler.h>
+#include <gruel/thread_body_wrapper.h>
+
+class sts_container
+{
+ gr_block_vector_t d_blocks;
+
+public:
+
+ sts_container(gr_block_vector_t blocks)
+ : d_blocks(blocks) {}
+
+ void operator()()
+ {
+ gr_make_single_threaded_scheduler(d_blocks)->run();
+ }
+};
+
+
+gr_scheduler_sptr
+gr_scheduler_sts::make(gr_flat_flowgraph_sptr ffg, int max_noutput_items)
+{
+ return gr_scheduler_sptr(new gr_scheduler_sts(ffg, max_noutput_items));
+}
+
+gr_scheduler_sts::gr_scheduler_sts(gr_flat_flowgraph_sptr ffg, int max_noutput_items)
+ : gr_scheduler(ffg, max_noutput_items)
+{
+ // Split the flattened flow graph into discrete partitions, each
+ // of which is topologically sorted.
+
+ std::vector<gr_basic_block_vector_t> graphs = ffg->partition();
+
+ // For each partition, create a thread to evaluate it using
+ // an instance of the gr_single_threaded_scheduler
+
+ for (std::vector<gr_basic_block_vector_t>::iterator p = graphs.begin();
+ p != graphs.end(); p++) {
+
+ gr_block_vector_t blocks = gr_flat_flowgraph::make_block_vector(*p);
+ d_threads.create_thread(
+ gruel::thread_body_wrapper<sts_container>(sts_container(blocks),
+ "single-threaded-scheduler"));
+ }
+}
+
+gr_scheduler_sts::~gr_scheduler_sts()
+{
+ stop();
+}
+
+void
+gr_scheduler_sts::stop()
+{
+ d_threads.interrupt_all();
+}
+
+void
+gr_scheduler_sts::wait()
+{
+ d_threads.join_all();
+}
diff --git a/gnuradio-core/src/lib/runtime/gr_scheduler_sts.h b/gnuradio-core/src/lib/runtime/gr_scheduler_sts.h
new file mode 100644
index 000000000..011874ec0
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_scheduler_sts.h
@@ -0,0 +1,63 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+#ifndef INCLUDED_GR_SCHEDULER_STS_H
+#define INCLUDED_GR_SCHEDULER_STS_H
+
+#include <gr_core_api.h>
+#include <gr_scheduler.h>
+#include <gruel/thread_group.h>
+
+/*!
+ * \brief Concrete scheduler that uses the single_threaded_scheduler
+ */
+class GR_CORE_API gr_scheduler_sts : public gr_scheduler
+{
+ gruel::thread_group d_threads;
+
+protected:
+ /*!
+ * \brief Construct a scheduler and begin evaluating the graph.
+ *
+ * The scheduler will continue running until all blocks until they
+ * report that they are done or the stop method is called.
+ */
+ gr_scheduler_sts(gr_flat_flowgraph_sptr ffg, int max_noutput_items);
+
+public:
+ static gr_scheduler_sptr make(gr_flat_flowgraph_sptr ffg, int max_noutput_items);
+
+ ~gr_scheduler_sts();
+
+ /*!
+ * \brief Tell the scheduler to stop executing.
+ */
+ void stop();
+
+ /*!
+ * \brief Block until the graph is done.
+ */
+ void wait();
+};
+
+
+
+
+#endif /* INCLUDED_GR_SCHEDULER_STS_H */
diff --git a/gnuradio-core/src/lib/runtime/gr_scheduler_tpb.cc b/gnuradio-core/src/lib/runtime/gr_scheduler_tpb.cc
new file mode 100644
index 000000000..2824eb1b3
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_scheduler_tpb.cc
@@ -0,0 +1,103 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <gr_scheduler_tpb.h>
+#include <gr_tpb_thread_body.h>
+#include <gruel/thread_body_wrapper.h>
+#include <sstream>
+
+/*
+ * You know, a lambda expression would be sooo much easier...
+ */
+class tpb_container
+{
+ gr_block_sptr d_block;
+ int d_max_noutput_items;
+
+public:
+ tpb_container(gr_block_sptr block, int max_noutput_items)
+ : d_block(block), d_max_noutput_items(max_noutput_items) {}
+
+ void operator()()
+ {
+ gr_tpb_thread_body body(d_block, d_max_noutput_items);
+ }
+};
+
+
+gr_scheduler_sptr
+gr_scheduler_tpb::make(gr_flat_flowgraph_sptr ffg, int max_noutput_items)
+{
+ return gr_scheduler_sptr(new gr_scheduler_tpb(ffg, max_noutput_items));
+}
+
+gr_scheduler_tpb::gr_scheduler_tpb(gr_flat_flowgraph_sptr ffg, int max_noutput_items)
+ : gr_scheduler(ffg, max_noutput_items)
+{
+ // Get a topologically sorted vector of all the blocks in use.
+ // Being topologically sorted probably isn't going to matter, but
+ // there's a non-zero chance it might help...
+
+ gr_basic_block_vector_t used_blocks = ffg->calc_used_blocks();
+ used_blocks = ffg->topological_sort(used_blocks);
+ gr_block_vector_t blocks = gr_flat_flowgraph::make_block_vector(used_blocks);
+
+ // Ensure that the done flag is clear on all blocks
+
+ for (size_t i = 0; i < blocks.size(); i++){
+ blocks[i]->detail()->set_done(false);
+ }
+
+ // Fire off a thead for each block
+
+ for (size_t i = 0; i < blocks.size(); i++){
+ std::stringstream name;
+ name << "thread-per-block[" << i << "]: " << blocks[i];
+
+ // If set, use internal value instead of global value
+ if(blocks[i]->is_set_max_noutput_items())
+ max_noutput_items = blocks[i]->max_noutput_items();
+
+ d_threads.create_thread(
+ gruel::thread_body_wrapper<tpb_container>(tpb_container(blocks[i], max_noutput_items),
+ name.str()));
+ }
+}
+
+gr_scheduler_tpb::~gr_scheduler_tpb()
+{
+ stop();
+}
+
+void
+gr_scheduler_tpb::stop()
+{
+ d_threads.interrupt_all();
+}
+
+void
+gr_scheduler_tpb::wait()
+{
+ d_threads.join_all();
+}
diff --git a/gnuradio-core/src/lib/runtime/gr_scheduler_tpb.h b/gnuradio-core/src/lib/runtime/gr_scheduler_tpb.h
new file mode 100644
index 000000000..a9b3abcfa
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_scheduler_tpb.h
@@ -0,0 +1,61 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+#ifndef INCLUDED_GR_SCHEDULER_TPB_H
+#define INCLUDED_GR_SCHEDULER_TPB_H
+
+#include <gr_core_api.h>
+#include <gr_scheduler.h>
+#include <gruel/thread_group.h>
+
+/*!
+ * \brief Concrete scheduler that uses a kernel thread-per-block
+ */
+class GR_CORE_API gr_scheduler_tpb : public gr_scheduler
+{
+ gruel::thread_group d_threads;
+
+protected:
+ /*!
+ * \brief Construct a scheduler and begin evaluating the graph.
+ *
+ * The scheduler will continue running until all blocks until they
+ * report that they are done or the stop method is called.
+ */
+ gr_scheduler_tpb(gr_flat_flowgraph_sptr ffg, int max_noutput_items);
+
+public:
+ static gr_scheduler_sptr make(gr_flat_flowgraph_sptr ffg, int max_noutput_items=100000);
+
+ ~gr_scheduler_tpb();
+
+ /*!
+ * \brief Tell the scheduler to stop executing.
+ */
+ void stop();
+
+ /*!
+ * \brief Block until the graph is done.
+ */
+ void wait();
+};
+
+
+#endif /* INCLUDED_GR_SCHEDULER_TPB_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
index 000000000..0fc86354a
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_select_handler.cc
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_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
index 000000000..c4c359213
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_select_handler.h
@@ -0,0 +1,85 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_SELECT_HANDLER_H
+#define INCLUDED_GR_SELECT_HANDLER_H
+
+#include <gr_core_api.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.
+ * \ingroup base
+ *
+ * \sa gr_dispatcher
+ */
+class GR_CORE_API 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
index 000000000..1bb9e9b0a
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_single_threaded_scheduler.cc
@@ -0,0 +1,364 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_single_threaded_scheduler.h>
+#include <gr_block.h>
+#include <gr_block_detail.h>
+#include <gr_buffer.h>
+#include <boost/thread.hpp>
+#include <boost/format.hpp>
+#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;
+
+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){
+ std::string name = str(boost::format("sst-%d.log") % which_scheduler++);
+ d_log = new std::ofstream(name.c_str());
+ *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; // KLUDGE
+ main_loop ();
+}
+
+void
+gr_single_threaded_scheduler::stop ()
+{
+ if (0)
+ std::cout << "gr_singled_threaded_scheduler::stop() "
+ << this << std::endl;
+ d_enabled = false;
+}
+
+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){
+
+ if (boost::this_thread::interruption_requested())
+ break;
+
+ 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
index 000000000..3a95c7194
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_single_threaded_scheduler.h
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_SINGLE_THREADED_SCHEDULER_H
+#define INCLUDED_GR_SINGLE_THREADED_SCHEDULER_H
+
+#include <gr_core_api.h>
+#include <gr_runtime_types.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_CORE_API gr_single_threaded_scheduler {
+ public:
+ ~gr_single_threaded_scheduler ();
+
+ void run ();
+ void stop ();
+
+ 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_CORE_API gr_single_threaded_scheduler_sptr
+ gr_make_single_threaded_scheduler (const std::vector<gr_block_sptr> &blocks);
+};
+
+GR_CORE_API 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
index 000000000..7305cc9ad
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_single_threaded_scheduler.i
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <gr_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);
+};
+
+#ifdef SWIGPYTHON
+%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
+ }
+%}
+#endif
+
diff --git a/gnuradio-core/src/lib/runtime/gr_sptr_magic.cc b/gnuradio-core/src/lib/runtime/gr_sptr_magic.cc
new file mode 100644
index 000000000..7fdadf24a
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_sptr_magic.cc
@@ -0,0 +1,72 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008,2009 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <gr_sptr_magic.h>
+#include <gr_hier_block2.h>
+#include <map>
+#include <stdexcept>
+
+
+#include <gruel/thread.h>
+
+namespace gnuradio {
+
+ static gruel::mutex s_mutex;
+ typedef std::map<gr_basic_block*, gr_basic_block_sptr> sptr_map;
+ static sptr_map s_map;
+
+ void
+ detail::sptr_magic::create_and_stash_initial_sptr(gr_hier_block2 *p)
+ {
+ gr_basic_block_sptr sptr(p);
+ gruel::scoped_lock guard(s_mutex);
+ s_map.insert(sptr_map::value_type(static_cast<gr_basic_block *>(p), sptr));
+ }
+
+
+ gr_basic_block_sptr
+ detail::sptr_magic::fetch_initial_sptr(gr_basic_block *p)
+ {
+ /*
+ * If p isn't a subclass of gr_hier_block2, just create the
+ * shared ptr and return it.
+ */
+ gr_hier_block2 *hb2 = dynamic_cast<gr_hier_block2 *>(p);
+ if (!hb2){
+ return gr_basic_block_sptr(p);
+ }
+
+ /*
+ * p is a subclass of gr_hier_block2, thus we've already created the shared pointer
+ * and stashed it away. Fish it out and return it.
+ */
+ gruel::scoped_lock guard(s_mutex);
+ sptr_map::iterator pos = s_map.find(static_cast<gr_basic_block *>(p));
+ if (pos == s_map.end())
+ throw std::invalid_argument("gr_sptr_magic: invalid pointer!");
+
+ gr_basic_block_sptr sptr = pos->second;
+ s_map.erase(pos);
+ return sptr;
+ }
+};
diff --git a/gnuradio-core/src/lib/runtime/gr_sptr_magic.h b/gnuradio-core/src/lib/runtime/gr_sptr_magic.h
new file mode 100644
index 000000000..d9c7f26c4
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_sptr_magic.h
@@ -0,0 +1,52 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+#ifndef INCLUDED_GR_SPTR_MAGIC_H
+#define INCLUDED_GR_SPTR_MAGIC_H
+
+#include <gr_core_api.h>
+#include <boost/shared_ptr.hpp>
+
+class gr_basic_block;
+class gr_hier_block2;
+
+namespace gnuradio {
+
+ namespace detail {
+
+ class GR_CORE_API sptr_magic {
+ public:
+ static boost::shared_ptr<gr_basic_block> fetch_initial_sptr(gr_basic_block *p);
+ static void create_and_stash_initial_sptr(gr_hier_block2 *p);
+ };
+ };
+
+ /*
+ * \brief New! Improved! Standard method to get/create the boost::shared_ptr for a block.
+ */
+ template<class T>
+ boost::shared_ptr<T>
+ get_initial_sptr(T *p)
+ {
+ return boost::shared_ptr<T>(p);//return boost::dynamic_pointer_cast<T, gr_basic_block>(detail::sptr_magic::fetch_initial_sptr(p));
+ }
+};
+
+#endif /* INCLUDED_GR_SPTR_MAGIC_H */
diff --git a/gnuradio-core/src/lib/runtime/gr_sync_block.cc b/gnuradio-core/src/lib/runtime/gr_sync_block.cc
new file mode 100644
index 000000000..3c79e630d
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_sync_block.cc
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_sync_block.h>
+
+gr_sync_block::gr_sync_block(void)
+{
+ //NOP
+}
+
+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)
+{
+ this->set_fixed_rate(true);
+}
+
+gr_sync_block::~gr_sync_block(void)
+{
+ //NOP
+}
+
+int gr_sync_block::work(
+ int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items
+){
+ throw std::runtime_error("gr_block subclasses must overload general_work!");
+}
diff --git a/gnuradio-core/src/lib/runtime/gr_sync_block.h b/gnuradio-core/src/lib/runtime/gr_sync_block.h
new file mode 100644
index 000000000..0f3daccf2
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_sync_block.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2012-2013 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GNURADIO_GR_SYNC_BLOCK_H
+#define INCLUDED_GNURADIO_GR_SYNC_BLOCK_H
+
+#include <gr_block.h>
+
+struct GR_CORE_API gr_sync_block : public gr_block
+{
+ gr_sync_block(void);
+
+ gr_sync_block(
+ const std::string &name,
+ gr_io_signature_sptr input_signature,
+ gr_io_signature_sptr output_signature
+ );
+
+ virtual ~gr_sync_block(void);
+
+ //! implements work -> calls work
+ int general_work(
+ int noutput_items,
+ gr_vector_int &ninput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items
+ );
+
+ /*!
+ * \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
+ );
+
+};
+
+GRAS_FORCE_INLINE 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
+){
+ const int work_ret = this->work(noutput_items, input_items, output_items);
+ if (work_ret > 0)
+ {
+ this->consume_each((decimation()*size_t(work_ret))/interpolation());
+ }
+ return work_ret;
+}
+
+#endif /*INCLUDED_GNURADIO_GR_SYNC_BLOCK_H*/
diff --git a/gnuradio-core/src/lib/runtime/gr_sync_block.i b/gnuradio-core/src/lib/runtime/gr_sync_block.i
new file mode 100644
index 000000000..d3e1bb957
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_sync_block.i
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+class 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/runtime/gr_sync_decimator.cc b/gnuradio-core/src/lib/runtime/gr_sync_decimator.cc
new file mode 100644
index 000000000..a39c53b09
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_sync_decimator.cc
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_sync_decimator.h>
+
+gr_sync_decimator::gr_sync_decimator(void)
+{
+ //NOP
+}
+
+gr_sync_decimator::gr_sync_decimator(
+ const std::string &name,
+ gr_io_signature_sptr input_signature,
+ gr_io_signature_sptr output_signature,
+ const size_t decim_rate
+):
+ gr_sync_block(name, input_signature, output_signature)
+{
+ this->set_decimation(decim_rate);
+}
+
+gr_sync_decimator::~gr_sync_decimator(void)
+{
+ //NOP
+}
diff --git a/gnuradio-core/src/lib/runtime/gr_sync_decimator.h b/gnuradio-core/src/lib/runtime/gr_sync_decimator.h
new file mode 100644
index 000000000..32edfd78e
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_sync_decimator.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2012-2013 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GNURADIO_GR_SYNC_DECIMATOR_H
+#define INCLUDED_GNURADIO_GR_SYNC_DECIMATOR_H
+
+#include <gr_sync_block.h>
+
+struct GR_CORE_API gr_sync_decimator : gr_sync_block
+{
+
+ gr_sync_decimator(void);
+
+ gr_sync_decimator(
+ const std::string &name,
+ gr_io_signature_sptr input_signature,
+ gr_io_signature_sptr output_signature,
+ const size_t decim_rate
+ );
+
+ virtual ~gr_sync_decimator(void);
+
+};
+
+#endif /*INCLUDED_GNURADIO_GR_SYNC_DECIMATOR_H*/
diff --git a/gnuradio-core/src/lib/runtime/gr_sync_decimator.i b/gnuradio-core/src/lib/runtime/gr_sync_decimator.i
new file mode 100644
index 000000000..af4574b19
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_sync_decimator.i
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+class 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/runtime/gr_sync_interpolator.cc b/gnuradio-core/src/lib/runtime/gr_sync_interpolator.cc
new file mode 100644
index 000000000..17f60e613
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_sync_interpolator.cc
@@ -0,0 +1,48 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2008 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_sync_interpolator.h>
+
+gr_sync_interpolator::gr_sync_interpolator(void)
+{
+ //NOP
+}
+
+gr_sync_interpolator::gr_sync_interpolator(
+ const std::string &name,
+ gr_io_signature_sptr input_signature,
+ gr_io_signature_sptr output_signature,
+ const size_t interp_rate
+):
+ gr_sync_block(name, input_signature, output_signature)
+{
+ this->set_interpolation(interp_rate);
+}
+
+gr_sync_interpolator::~gr_sync_interpolator(void)
+{
+ //NOP
+}
diff --git a/gnuradio-core/src/lib/runtime/gr_sync_interpolator.h b/gnuradio-core/src/lib/runtime/gr_sync_interpolator.h
new file mode 100644
index 000000000..81c17c18e
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_sync_interpolator.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2012-2013 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GNURADIO_GR_SYNC_INTERPOLATOR_H
+#define INCLUDED_GNURADIO_GR_SYNC_INTERPOLATOR_H
+
+#include <gr_sync_block.h>
+
+struct GR_CORE_API gr_sync_interpolator : gr_sync_block
+{
+
+ gr_sync_interpolator(void);
+
+ gr_sync_interpolator(
+ const std::string &name,
+ gr_io_signature_sptr input_signature,
+ gr_io_signature_sptr output_signature,
+ const size_t interp_rate
+ );
+
+ virtual ~gr_sync_interpolator(void);
+
+};
+
+#endif /*INCLUDED_GNURADIO_GR_SYNC_INTERPOLATOR_H*/
diff --git a/gnuradio-core/src/lib/runtime/gr_sync_interpolator.i b/gnuradio-core/src/lib/runtime/gr_sync_interpolator.i
new file mode 100644
index 000000000..6f8b08252
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_sync_interpolator.i
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+class 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/runtime/gr_sys_paths.cc b/gnuradio-core/src/lib/runtime/gr_sys_paths.cc
new file mode 100644
index 000000000..b4918af33
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_sys_paths.cc
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2011 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <gr_sys_paths.h>
+#include <cstdlib> //getenv
+#include <cstdio> //P_tmpdir (maybe)
+
+const char *gr_tmp_path(){
+ const char *path;
+
+ //first case, try TMP environment variable
+ path = getenv("TMP");
+ if (path) return path;
+
+ //second case, try P_tmpdir when its defined
+ #ifdef P_tmpdir
+ if (P_tmpdir) return P_tmpdir;
+ #endif /*P_tmpdir*/
+
+ //fall-through case, nothing worked
+ return "/tmp";
+}
+
+const char *gr_appdata_path(){
+ const char *path;
+
+ //first case, try HOME environment variable (unix)
+ path = getenv("HOME");
+ if (path) return path;
+
+ //second case, try APPDATA environment variable (windows)
+ path = getenv("APPDATA");
+ if (path) return path;
+
+ //fall-through case, nothing worked
+ return gr_tmp_path();
+}
diff --git a/gnuradio-core/src/lib/runtime/gr_sys_paths.h b/gnuradio-core/src/lib/runtime/gr_sys_paths.h
new file mode 100644
index 000000000..bd51ebdf9
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_sys_paths.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2011 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef _GR_SYS_PATHS_H_
+#define _GR_SYS_PATHS_H_
+
+#include <gr_core_api.h>
+
+//! directory to create temporary files
+GR_CORE_API const char *gr_tmp_path();
+
+//! directory to store application data
+GR_CORE_API const char *gr_appdata_path();
+
+#endif /* _GR_SYS_PATHS_H_ */
diff --git a/gnuradio-core/src/lib/runtime/gr_tags.h b/gnuradio-core/src/lib/runtime/gr_tags.h
new file mode 100644
index 000000000..a9ca90235
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_tags.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2011 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_TAGS_H
+#define INCLUDED_GR_TAGS_H
+
+#include <gr_core_api.h>
+#include <gruel/pmt.h>
+
+struct GR_CORE_API gr_tag_t{
+
+ //! the item \p tag occurred at (as a uint64_t)
+ uint64_t offset;
+
+ //! the key of \p tag (as a PMT symbol)
+ pmt::pmt_t key;
+
+ //! the value of \p tag (as a PMT)
+ pmt::pmt_t value;
+
+ //! the source ID of \p tag (as a PMT)
+ pmt::pmt_t srcid;
+
+ //! Comparison function to test which tag, \p x or \p y, came first in time
+ static inline bool offset_compare(
+ const gr_tag_t &x, const gr_tag_t &y
+ ){
+ return x.offset < y.offset;
+ }
+
+ inline bool operator == (const gr_tag_t &t) const
+ {
+ return (t.key == key) && (t.value == value) && (t.srcid == srcid) && (t.offset == offset);
+ }
+};
+
+#endif /*INCLUDED_GR_TAGS_H*/
diff --git a/gnuradio-core/src/lib/runtime/gr_tags.i b/gnuradio-core/src/lib/runtime/gr_tags.i
new file mode 100644
index 000000000..f2ee69ce8
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_tags.i
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2011 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+%{
+#include <gr_tags.h>
+%}
+
+%import <pmt_swig.i> //for pmt support
+
+%include <gr_tags.h>
+
+//gives support for a vector of tags (get tags in range)
+%include "std_vector.i"
+%template(tags_vector_t) std::vector<gr_tag_t>;
diff --git a/gnuradio-core/src/lib/runtime/gr_timer.h b/gnuradio-core/src/lib/runtime/gr_timer.h
new file mode 100644
index 000000000..e0b4cc437
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_timer.h
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifndef INCLUDED_GR_TIMER_H
+#define INCLUDED_GR_TIMER_H
+
+#include <gr_core_api.h>
+#include <gr_types.h>
+
+class gr_timer;
+
+typedef boost::shared_ptr<gr_timer> gr_timer_sptr;
+
+GR_CORE_API typedef void (*gr_timer_hook)(gr_timer *, void *);
+
+/*!
+ * \brief create a timeout.
+ *
+ * \ingroup misc
+ * gr_timer_hook is called when timer fires.
+ */
+GR_CORE_API gr_timer_sptr gr_make_timer (gr_timer_hook, void *);
+
+/*!
+ * \brief implement timeouts
+ */
+class GR_CORE_API gr_timer {
+ double d_expiry;
+ double d_period;
+ gr_timer_hook d_hook;
+ void *d_hook_arg;
+
+ friend GR_CORE_API 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_top_block.cc b/gnuradio-core/src/lib/runtime/gr_top_block.cc
new file mode 100644
index 000000000..fa090b4ef
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_top_block.cc
@@ -0,0 +1,95 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <unistd.h>
+#include <gr_top_block.h>
+#include <boost/detail/atomic_count.hpp>
+
+static boost::detail::atomic_count unique_id_pool(0);
+
+gr_top_block::gr_top_block(void):
+ //cannot make a null top block, use name constructor
+ gras::TopBlock("top"),
+ _unique_id(++unique_id_pool),
+ _name("top")
+{
+ //NOP
+}
+
+gr_top_block::gr_top_block(const std::string &name):
+ gras::TopBlock(name),
+ _unique_id(++unique_id_pool),
+ _name(name)
+{
+ //NOP
+}
+
+gr_top_block_sptr gr_make_top_block(const std::string &name)
+{
+ return gr_top_block_sptr(new gr_top_block(name));
+}
+
+void gr_top_block::start(const size_t max_items)
+{
+ this->set_max_noutput_items(max_items);
+ this->start();
+}
+
+void gr_top_block::run(const size_t max_items)
+{
+ this->set_max_noutput_items(max_items);
+ this->run();
+}
+
+int gr_top_block::max_noutput_items(void) const
+{
+ return this->global_config().maximum_output_items;
+}
+
+void gr_top_block::set_max_noutput_items(int max_items)
+{
+ this->global_config().maximum_output_items = max_items;
+}
+
+void gr_top_block::run(void)
+{
+ gras::TopBlock::run();
+}
+
+void gr_top_block::start(void)
+{
+ gras::TopBlock::start();
+}
+
+void gr_top_block::stop(void)
+{
+ gras::TopBlock::stop();
+}
+
+void gr_top_block::wait(void)
+{
+ gras::TopBlock::wait();
+}
diff --git a/gnuradio-core/src/lib/runtime/gr_top_block.h b/gnuradio-core/src/lib/runtime/gr_top_block.h
new file mode 100644
index 000000000..4e4becd1f
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_top_block.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2012-2013 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GNURADIO_GR_TOP_BLOCK_H
+#define INCLUDED_GNURADIO_GR_TOP_BLOCK_H
+
+#include <gr_core_api.h>
+#include <gras/top_block.hpp>
+#include <gr_hier_block2.h>
+
+struct GR_CORE_API gr_top_block : gras::TopBlock
+{
+
+ gr_top_block(void);
+
+ gr_top_block(const std::string &name);
+
+ long unique_id(void) const{return _unique_id;}
+ std::string name(void) const{return _name;}
+ long _unique_id;
+ std::string _name;
+
+ void start(const size_t max_items);
+
+ void run(const size_t max_items);
+
+ int max_noutput_items(void) const;
+
+ void set_max_noutput_items(int max_items);
+
+ void run(void);
+
+ virtual void start(void);
+
+ virtual void stop(void);
+
+ virtual void wait(void);
+
+ inline void lock(void){}
+
+ inline void unlock(void){this->commit();}
+
+};
+
+typedef boost::shared_ptr<gr_top_block> gr_top_block_sptr;
+
+GR_CORE_API gr_top_block_sptr gr_make_top_block(const std::string &name);
+
+#endif /*INCLUDED_GNURADIO_GR_TOP_BLOCK_H*/
diff --git a/gnuradio-core/src/lib/runtime/gr_top_block.i b/gnuradio-core/src/lib/runtime/gr_top_block.i
new file mode 100644
index 000000000..6ae4c65a9
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_top_block.i
@@ -0,0 +1,73 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007,2008,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+class gr_top_block;
+typedef boost::shared_ptr<gr_top_block> gr_top_block_sptr;
+%template(gr_top_block_sptr) boost::shared_ptr<gr_top_block>;
+
+// Hack to have a Python shim implementation of gr.top_block
+// that instantiates one of these and passes through calls
+%rename(top_block_swig) gr_make_top_block;
+gr_top_block_sptr gr_make_top_block(const std::string name)
+ throw (std::logic_error);
+
+class gr_top_block : public gr_hier_block2
+{
+private:
+ gr_top_block(const std::string &name);
+
+public:
+ ~gr_top_block();
+
+ void start(int max_noutput_items=100000) throw (std::runtime_error);
+ void stop();
+ //void wait();
+ //void run() throw (std::runtime_error);
+ void lock();
+ void unlock() throw (std::runtime_error);
+ void dump();
+
+ int max_noutput_items();
+ void set_max_noutput_items(int nmax);
+
+ gr_top_block_sptr to_top_block(); // Needed for Python type coercion
+};
+
+#ifdef SWIGPYTHON
+
+%inline %{
+void top_block_run_unlocked(gr_top_block_sptr r) throw (std::runtime_error)
+{
+ Py_BEGIN_ALLOW_THREADS; // release global interpreter lock
+ r->run();
+ Py_END_ALLOW_THREADS; // acquire global interpreter lock
+}
+
+void top_block_wait_unlocked(gr_top_block_sptr r) throw (std::runtime_error)
+{
+ Py_BEGIN_ALLOW_THREADS; // release global interpreter lock
+ r->wait();
+ Py_END_ALLOW_THREADS; // acquire global interpreter lock
+}
+%}
+
+#endif
diff --git a/gnuradio-core/src/lib/runtime/gr_top_block_impl.cc b/gnuradio-core/src/lib/runtime/gr_top_block_impl.cc
new file mode 100644
index 000000000..4a3694163
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_top_block_impl.cc
@@ -0,0 +1,195 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007,2008 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_top_block.h>
+#include <gr_top_block_impl.h>
+#include <gr_flat_flowgraph.h>
+#include <gr_scheduler_sts.h>
+#include <gr_scheduler_tpb.h>
+
+#include <stdexcept>
+#include <iostream>
+#include <string.h>
+#include <unistd.h>
+#include <stdlib.h>
+
+#define GR_TOP_BLOCK_IMPL_DEBUG 0
+
+
+typedef gr_scheduler_sptr (*scheduler_maker)(gr_flat_flowgraph_sptr ffg,
+ int max_noutput_items);
+
+static struct scheduler_table {
+ const char *name;
+ scheduler_maker f;
+} scheduler_table[] = {
+ { "TPB", gr_scheduler_tpb::make }, // first entry is default
+ { "STS", gr_scheduler_sts::make }
+};
+
+static gr_scheduler_sptr
+make_scheduler(gr_flat_flowgraph_sptr ffg, int max_noutput_items)
+{
+ static scheduler_maker factory = 0;
+
+ if (factory == 0){
+ char *v = getenv("GR_SCHEDULER");
+ if (!v)
+ factory = scheduler_table[0].f; // use default
+ else {
+ for (size_t i = 0; i < sizeof(scheduler_table)/sizeof(scheduler_table[0]); i++){
+ if (strcmp(v, scheduler_table[i].name) == 0){
+ factory = scheduler_table[i].f;
+ break;
+ }
+ }
+ if (factory == 0){
+ std::cerr << "warning: Invalid GR_SCHEDULER environment variable value \""
+ << v << "\". Using \"" << scheduler_table[0].name << "\"\n";
+ factory = scheduler_table[0].f;
+ }
+ }
+ }
+ return factory(ffg, max_noutput_items);
+}
+
+
+gr_top_block_impl::gr_top_block_impl(gr_top_block *owner)
+ : d_owner(owner), d_ffg(),
+ d_state(IDLE), d_lock_count(0)
+{
+}
+
+gr_top_block_impl::~gr_top_block_impl()
+{
+ d_owner = 0;
+}
+
+void
+gr_top_block_impl::start(int max_noutput_items)
+{
+ gruel::scoped_lock l(d_mutex);
+
+ d_max_noutput_items = max_noutput_items;
+
+ if (d_state != IDLE)
+ throw std::runtime_error("top_block::start: top block already running or wait() not called after previous stop()");
+
+ if (d_lock_count > 0)
+ throw std::runtime_error("top_block::start: can't start with flow graph locked");
+
+ // Create new flat flow graph by flattening hierarchy
+ d_ffg = d_owner->flatten();
+
+ // Validate new simple flow graph and wire it up
+ d_ffg->validate();
+ d_ffg->setup_connections();
+
+ d_scheduler = make_scheduler(d_ffg, d_max_noutput_items);
+ d_state = RUNNING;
+}
+
+void
+gr_top_block_impl::stop()
+{
+ if (d_scheduler)
+ d_scheduler->stop();
+}
+
+
+void
+gr_top_block_impl::wait()
+{
+ if (d_scheduler)
+ d_scheduler->wait();
+
+ d_state = IDLE;
+}
+
+// N.B. lock() and unlock() cannot be called from a flow graph thread or
+// deadlock will occur when reconfiguration happens
+void
+gr_top_block_impl::lock()
+{
+ gruel::scoped_lock lock(d_mutex);
+ d_lock_count++;
+}
+
+void
+gr_top_block_impl::unlock()
+{
+ gruel::scoped_lock lock(d_mutex);
+
+ if (d_lock_count <= 0){
+ d_lock_count = 0; // fix it, then complain
+ throw std::runtime_error("unpaired unlock() call");
+ }
+
+ d_lock_count--;
+ if (d_lock_count > 0 || d_state == IDLE) // nothing to do
+ return;
+
+ restart();
+}
+
+/*
+ * restart is called with d_mutex held
+ */
+void
+gr_top_block_impl::restart()
+{
+ stop(); // Stop scheduler and wait for completion
+ wait();
+
+ // Create new simple flow graph
+ gr_flat_flowgraph_sptr new_ffg = d_owner->flatten();
+ new_ffg->validate(); // check consistency, sanity, etc
+ new_ffg->merge_connections(d_ffg); // reuse buffers, etc
+ d_ffg = new_ffg;
+
+ // Create a new scheduler to execute it
+ d_scheduler = make_scheduler(d_ffg, d_max_noutput_items);
+ d_state = RUNNING;
+}
+
+void
+gr_top_block_impl::dump()
+{
+ if (d_ffg)
+ d_ffg->dump();
+}
+
+int
+gr_top_block_impl::max_noutput_items()
+{
+ return d_max_noutput_items;
+}
+
+void
+gr_top_block_impl::set_max_noutput_items(int nmax)
+{
+ d_max_noutput_items = nmax;
+}
diff --git a/gnuradio-core/src/lib/runtime/gr_top_block_impl.h b/gnuradio-core/src/lib/runtime/gr_top_block_impl.h
new file mode 100644
index 000000000..f55c3f021
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_top_block_impl.h
@@ -0,0 +1,85 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007,2008 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_TOP_BLOCK_IMPL_H
+#define INCLUDED_GR_TOP_BLOCK_IMPL_H
+
+#include <gr_core_api.h>
+#include <gr_scheduler.h>
+#include <gruel/thread.h>
+
+/*!
+ *\brief Abstract implementation details of gr_top_block
+ * \ingroup internal
+ *
+ * The actual implementation of gr_top_block. Separate class allows
+ * decoupling of changes from dependent classes.
+ *
+ */
+class GR_CORE_API gr_top_block_impl
+{
+public:
+ gr_top_block_impl(gr_top_block *owner);
+ ~gr_top_block_impl();
+
+ // Create and start scheduler threads
+ void start(int max_noutput_items=100000);
+
+ // Signal scheduler threads to stop
+ void stop();
+
+ // Wait for scheduler threads to exit
+ void wait();
+
+ // Lock the top block to allow reconfiguration
+ void lock();
+
+ // Unlock the top block at end of reconfiguration
+ void unlock();
+
+ // Dump the flowgraph to stdout
+ void dump();
+
+ // Get the number of max noutput_items in the flowgraph
+ int max_noutput_items();
+
+ // Set the maximum number of noutput_items in the flowgraph
+ void set_max_noutput_items(int nmax);
+
+protected:
+
+ enum tb_state { IDLE, RUNNING };
+
+ gr_top_block *d_owner;
+ gr_flat_flowgraph_sptr d_ffg;
+ gr_scheduler_sptr d_scheduler;
+
+ gruel::mutex d_mutex; // protects d_state and d_lock_count
+ tb_state d_state;
+ int d_lock_count;
+ int d_max_noutput_items;
+
+private:
+ void restart();
+};
+
+#endif /* INCLUDED_GR_TOP_BLOCK_IMPL_H */
diff --git a/gnuradio-core/src/lib/runtime/gr_tpb_detail.cc b/gnuradio-core/src/lib/runtime/gr_tpb_detail.cc
new file mode 100644
index 000000000..46eb6bbe0
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_tpb_detail.cc
@@ -0,0 +1,70 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008,2009 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <gr_tpb_detail.h>
+#include <gr_block.h>
+#include <gr_block_detail.h>
+#include <gr_buffer.h>
+
+using namespace pmt;
+
+/*
+ * We assume that no worker threads are ever running when the
+ * graph structure is being manipulated, thus it's safe for us to poke
+ * around in our neighbors w/o holding any locks.
+ */
+
+void
+gr_tpb_detail::notify_upstream(gr_block_detail *d)
+{
+ // For each of our inputs, tell the guy upstream that we've consumed
+ // some input, and that he most likely has more output buffer space
+ // available.
+
+ for (size_t i = 0; i < d->d_input.size(); i++){
+ // Can you say, "pointer chasing?"
+ d->d_input[i]->buffer()->link()->detail()->d_tpb.set_output_changed();
+ }
+}
+
+void
+gr_tpb_detail::notify_downstream(gr_block_detail *d)
+{
+ // For each of our outputs, tell the guys downstream that they have
+ // new input available.
+
+ for (size_t i = 0; i < d->d_output.size(); i++){
+ gr_buffer_sptr buf = d->d_output[i];
+ for (size_t j = 0, k = buf->nreaders(); j < k; j++)
+ buf->reader(j)->link()->detail()->d_tpb.set_input_changed();
+ }
+}
+
+void
+gr_tpb_detail::notify_neighbors(gr_block_detail *d)
+{
+ notify_downstream(d);
+ notify_upstream(d);
+}
+
diff --git a/gnuradio-core/src/lib/runtime/gr_tpb_detail.h b/gnuradio-core/src/lib/runtime/gr_tpb_detail.h
new file mode 100644
index 000000000..69feb6007
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_tpb_detail.h
@@ -0,0 +1,89 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008,2009 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+#ifndef INCLUDED_GR_TPB_DETAIL_H
+#define INCLUDED_GR_TPB_DETAIL_H
+
+#include <gr_core_api.h>
+#include <gruel/thread.h>
+#include <deque>
+#include <gruel/pmt.h>
+
+class gr_block_detail;
+
+/*!
+ * \brief used by thread-per-block scheduler
+ */
+struct GR_CORE_API gr_tpb_detail {
+
+ gruel::mutex mutex; //< protects all vars
+ bool input_changed;
+ gruel::condition_variable input_cond;
+ bool output_changed;
+ gruel::condition_variable output_cond;
+
+public:
+ gr_tpb_detail()
+ : input_changed(false), output_changed(false) { }
+
+ //! Called by us to tell all our upstream blocks that their output may have changed.
+ void notify_upstream(gr_block_detail *d);
+
+ //! Called by us to tell all our downstream blocks that their input may have changed.
+ void notify_downstream(gr_block_detail *d);
+
+ //! Called by us to notify both upstream and downstream
+ void notify_neighbors(gr_block_detail *d);
+
+ //! Called by pmt msg posters
+ void notify_msg(){
+ input_cond.notify_one();
+ output_cond.notify_one();
+ }
+
+ //! Called by us
+ void clear_changed()
+ {
+ gruel::scoped_lock guard(mutex);
+ input_changed = false;
+ output_changed = false;
+ }
+
+private:
+
+ //! Used by notify_downstream
+ void set_input_changed()
+ {
+ gruel::scoped_lock guard(mutex);
+ input_changed = true;
+ input_cond.notify_one();
+ }
+
+ //! Used by notify_upstream
+ void set_output_changed()
+ {
+ gruel::scoped_lock guard(mutex);
+ output_changed = true;
+ output_cond.notify_one();
+ }
+
+};
+
+#endif /* INCLUDED_GR_TPB_DETAIL_H */
diff --git a/gnuradio-core/src/lib/runtime/gr_tpb_thread_body.cc b/gnuradio-core/src/lib/runtime/gr_tpb_thread_body.cc
new file mode 100644
index 000000000..679fd1512
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_tpb_thread_body.cc
@@ -0,0 +1,151 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008,2009,2011 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <gr_tpb_thread_body.h>
+#include <gr_prefs.h>
+#include <iostream>
+#include <boost/thread.hpp>
+#include <gruel/pmt.h>
+#include <boost/foreach.hpp>
+
+using namespace pmt;
+
+gr_tpb_thread_body::gr_tpb_thread_body(gr_block_sptr block, int max_noutput_items)
+ : d_exec(block, max_noutput_items)
+{
+ //std::cerr << "gr_tpb_thread_body: " << block << std::endl;
+
+ gr_block_detail *d = block->detail().get();
+ gr_block_executor::state s;
+ pmt_t msg;
+
+ d->threaded = true;
+ d->thread = gruel::get_current_thread_id();
+
+ gr_prefs *p = gr_prefs::singleton();
+ size_t max_nmsgs = static_cast<size_t>(p->get_long("DEFAULT", "max_messages", 100));
+
+ // Set thread affinity if it was set before fg was started.
+ if(block->processor_affinity().size() > 0) {
+ gruel::thread_bind_to_processor(d->thread, block->processor_affinity());
+ }
+
+ while (1){
+ boost::this_thread::interruption_point();
+
+ // handle any queued up messages
+ //BOOST_FOREACH( pmt::pmt_t port, block->msg_queue.keys() )
+
+ BOOST_FOREACH( gr_basic_block::msg_queue_map_t::value_type &i, block->msg_queue )
+ {
+ // Check if we have a message handler attached before getting
+ // any messages. This is mostly a protection for the unknown
+ // startup sequence of the threads.
+ if(block->has_msg_handler(i.first)) {
+ while ((msg = block->delete_head_nowait(i.first))){
+ block->dispatch_msg(i.first,msg);
+ }
+ }
+ else {
+ // If we don't have a handler but are building up messages,
+ // prune the queue from the front to keep memory in check.
+ if(block->nmsgs(i.first) > max_nmsgs)
+ msg = block->delete_head_nowait(i.first);
+ }
+ }
+
+ d->d_tpb.clear_changed();
+ // run one iteration if we are a connected stream block
+ if(d->noutputs() >0 || d->ninputs()>0){
+ s = d_exec.run_one_iteration();
+ } else {
+ s = gr_block_executor::BLKD_IN;
+ }
+
+ switch(s){
+ case gr_block_executor::READY: // Tell neighbors we made progress.
+ d->d_tpb.notify_neighbors(d);
+ break;
+
+ case gr_block_executor::READY_NO_OUTPUT: // Notify upstream only
+ d->d_tpb.notify_upstream(d);
+ break;
+
+ case gr_block_executor::DONE: // Game over.
+ d->d_tpb.notify_neighbors(d);
+ return;
+
+ case gr_block_executor::BLKD_IN: // Wait for input.
+ {
+ gruel::scoped_lock guard(d->d_tpb.mutex);
+ while (!d->d_tpb.input_changed){
+
+ // wait for input or message
+ while(!d->d_tpb.input_changed && block->empty_p())
+ d->d_tpb.input_cond.wait(guard);
+
+ // handle all pending messages
+ BOOST_FOREACH( gr_basic_block::msg_queue_map_t::value_type &i, block->msg_queue )
+ {
+ while ((msg = block->delete_head_nowait(i.first))){
+ guard.unlock(); // release lock while processing msg
+ block->dispatch_msg(i.first, msg);
+ guard.lock();
+ }
+ }
+ }
+ }
+ break;
+
+
+ case gr_block_executor::BLKD_OUT: // Wait for output buffer space.
+ {
+ gruel::scoped_lock guard(d->d_tpb.mutex);
+ while (!d->d_tpb.output_changed){
+
+ // wait for output room or message
+ while(!d->d_tpb.output_changed && block->empty_p())
+ d->d_tpb.output_cond.wait(guard);
+
+ // handle all pending messages
+ BOOST_FOREACH( gr_basic_block::msg_queue_map_t::value_type &i, block->msg_queue )
+ {
+ while ((msg = block->delete_head_nowait(i.first))){
+ guard.unlock(); // release lock while processing msg
+ block->dispatch_msg(i.first,msg);
+ guard.lock();
+ }
+ }
+ }
+ }
+ break;
+
+ default:
+ assert(0);
+ }
+ }
+}
+
+gr_tpb_thread_body::~gr_tpb_thread_body()
+{
+}
diff --git a/gnuradio-core/src/lib/runtime/gr_tpb_thread_body.h b/gnuradio-core/src/lib/runtime/gr_tpb_thread_body.h
new file mode 100644
index 000000000..f920663a2
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_tpb_thread_body.h
@@ -0,0 +1,46 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+#ifndef INCLUDED_GR_TPB_THREAD_BODY_H
+#define INCLUDED_GR_TPB_THREAD_BODY_H
+
+#include <gr_core_api.h>
+#include <gr_block_executor.h>
+#include <gr_block.h>
+#include <gr_block_detail.h>
+
+/*!
+ * \brief The body of each thread-per-block thread.
+ *
+ * One of these is instantiated in its own thread for each block. The
+ * constructor turns into the main loop which returns when the block is
+ * done or is interrupted.
+ */
+
+class GR_CORE_API gr_tpb_thread_body {
+ gr_block_executor d_exec;
+
+public:
+ gr_tpb_thread_body(gr_block_sptr block, int max_noutput_items=100000);
+ ~gr_tpb_thread_body();
+};
+
+
+#endif /* INCLUDED_GR_TPB_THREAD_BODY_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
index 000000000..b7c297d61
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_types.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2012-2013 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GRNURADIO_TYPES_H
+#define INCLUDED_GRNURADIO_TYPES_H
+
+// this section is to satisfy swig includes for gras.i
+// since gras.i includes gr_types.h, we only have to edit this file
+#include <gras/element.hpp>
+#include <gras/block.hpp>
+#include <gras/top_block.hpp>
+#include <gras/hier_block.hpp>
+
+// and gnuradio apparently needs its own typedefs for stdint...
+#ifdef __cplusplus
+
+#include <boost/cstdint.hpp>
+typedef boost::int16_t gr_int16;
+typedef boost::int32_t gr_int32;
+typedef boost::int64_t gr_int64;
+typedef boost::uint16_t gr_uint16;
+typedef boost::uint32_t gr_uint32;
+typedef boost::uint64_t gr_uint64;
+
+typedef std::vector<int> gr_vector_int;
+typedef std::vector<unsigned int> gr_vector_uint;
+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 <complex>
+typedef std::complex<float> gr_complex;
+typedef std::complex<double> gr_complexd;
+
+#endif
+
+#endif /* INCLUDED_GRNURADIO_TYPES_H */
diff --git a/gnuradio-core/src/lib/runtime/gr_unittests.h b/gnuradio-core/src/lib/runtime/gr_unittests.h
new file mode 100644
index 000000000..9fbf228cd
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_unittests.h
@@ -0,0 +1,43 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2010,2011 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_core_api.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <string>
+
+#include <boost/filesystem/operations.hpp>
+#include <boost/filesystem/path.hpp>
+
+static std::string get_unittest_path(const std::string &filename){
+ boost::filesystem::path path = boost::filesystem::current_path() / ".unittests";
+ if (!boost::filesystem::is_directory(path)) boost::filesystem::create_directory(path);
+ return (path / filename).string();
+}
diff --git a/gnuradio-core/src/lib/runtime/gr_vmcircbuf.cc b/gnuradio-core/src/lib/runtime/gr_vmcircbuf.cc
new file mode 100644
index 000000000..522d9515d
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_vmcircbuf.cc
@@ -0,0 +1,295 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include <gr_vmcircbuf.h>
+#include <assert.h>
+#include <stdexcept>
+#include <gr_preferences.h>
+#include <stdio.h>
+#include <string.h>
+#include <gr_local_sighandler.h>
+#include <vector>
+#include <boost/format.hpp>
+
+// 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 ());
+#ifdef TRY_SHM_VMCIRCBUF
+ result.push_back (gr_vmcircbuf_sysv_shm_factory::singleton ());
+ result.push_back (gr_vmcircbuf_mmap_shm_open_factory::singleton ());
+#endif
+ 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, const 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 const char *
+memsize (int size)
+{
+ static std::string buf;
+ if (size >= (1 << 20)){
+ buf = str(boost::format("%dMB") % (size / (1 << 20)));
+ }
+ else if (size >= (1 << 10)){
+ buf = str(boost::format("%dKB") % (size / (1 << 10)));
+ }
+ else {
+ buf = str(boost::format("%d") % size);
+ }
+ return buf.c_str();
+}
+
+static bool
+test_a_bunch (gr_vmcircbuf_factory *factory, int n, int size, int *start_ptr, bool verbose)
+{
+ bool ok = true;
+ std::vector<int> counter(n);
+ std::vector<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++){
+ std::string msg = str(boost::format("test_a_bunch_%dx%s[%d]") % n % memsize (size) % i);
+ ok &= check_mapping (c[i], counter[i], size, msg.c_str(), 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); // 64 x 16KB = 1MB
+ ok &= test_a_bunch (f, 4, 4 * (1L << 20), &start, v); // 4 x 4MB = 16MB
+// 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
index 000000000..45c6f969c
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_vmcircbuf.h
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef _GR_VMCIRCBUF_H_
+#define _GR_VMCIRCBUF_H_
+
+#include <gr_core_api.h>
+#include <vector>
+
+/*!
+ * \brief abstract class to implement doubly mapped virtual memory circular buffers
+ * \ingroup internal
+ */
+class GR_CORE_API 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_CORE_API 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_CORE_API 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
index 000000000..1b4d9700a
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_vmcircbuf_createfilemapping.cc
@@ -0,0 +1,204 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003,2005,2011 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include <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_vmcircbuf_createfilemapping.h>
+#include <boost/format.hpp>
+
+#ifdef HAVE_CREATEFILEMAPPING
+// Print Windows error (could/should be global?)
+static void
+werror( char *where, DWORD last_error )
+{
+ char buf[1024];
+
+ FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM,
+ NULL,
+ last_error,
+ 0, // default language
+ buf,
+ sizeof(buf)/sizeof(TCHAR), // buffer size
+ NULL );
+ fprintf( stderr, "%s: Error %d: %s", where, last_error, buf );
+ return;
+}
+#endif
+
+
+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");
+ }
+
+ std::string seg_name = str(boost::format("/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.c_str()); // name of mapping object
+
+ s_seg_counter++;
+ if (d_handle == NULL || d_handle == INVALID_HANDLE_VALUE){
+ std::string msg = str(boost::format(
+ "gr_vmcircbuf_mmap_createfilemapping: CreateFileMapping [%s]") %
+ seg_name );
+ werror((char *) msg.c_str(), GetLastError() );
+ throw std::runtime_error ("gr_vmcircbuf_mmap_createfilemapping");
+ }
+
+ // Allocate virtual memory of the needed size, then free it so we can use it
+ LPVOID first_tmp;
+ first_tmp = VirtualAlloc( NULL, 2*size, MEM_RESERVE, PAGE_NOACCESS );
+ if (first_tmp == NULL){
+ werror( "gr_vmcircbuf_mmap_createfilemapping: VirtualAlloc", GetLastError());
+ CloseHandle(d_handle); // cleanup
+ throw std::runtime_error ("gr_vmcircbuf_mmap_createfilemapping");
+ }
+
+ if (VirtualFree(first_tmp, 0, MEM_RELEASE) == 0){
+ werror( "gr_vmcircbuf_mmap_createfilemapping: VirtualFree", GetLastError());
+ CloseHandle(d_handle); // cleanup
+ throw std::runtime_error ("gr_vmcircbuf_mmap_createfilemapping");
+ }
+
+ d_first_copy = MapViewOfFileEx((HANDLE)d_handle, // handle to map object
+ FILE_MAP_WRITE, // read/write permission
+ 0,
+ 0,
+ size,
+ first_tmp);
+ if (d_first_copy != first_tmp){
+ werror( "gr_vmcircbuf_mmap_createfilemapping: MapViewOfFileEx(1)", GetLastError());
+ CloseHandle(d_handle); // cleanup
+ throw std::runtime_error ("gr_vmcircbuf_mmap_createfilemapping");
+ }
+
+ d_second_copy = MapViewOfFileEx((HANDLE)d_handle, // handle to map object
+ FILE_MAP_WRITE, // read/write permission
+ 0,
+ 0,
+ size,
+ (char *)first_tmp + size);//(LPVOID) ((char *)d_first_copy + size));
+
+ if (d_second_copy != (char *)first_tmp + size){
+ werror( "gr_vmcircbuf_mmap_createfilemapping: MapViewOfFileEx(2)", GetLastError());
+ UnmapViewOfFile(d_first_copy);
+ CloseHandle(d_handle); // cleanup
+ throw std::runtime_error ("gr_vmcircbuf_mmap_createfilemapping");
+ }
+
+#ifdef DEBUG
+ fprintf (stderr,"gr_vmcircbuf_mmap_createfilemapping: contiguous? mmap %p %p %p %p\n",
+ (char *)d_first_copy, (char *)d_second_copy, size, (char *)d_first_copy + size);
+#endif
+
+ // 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)
+ {
+ werror("gr_vmcircbuf_createfilemapping: UnmapViewOfFile(d_first_copy)", GetLastError());
+ }
+ d_base=NULL;
+ if (UnmapViewOfFile(d_second_copy) == 0)
+ {
+ werror("gr_vmcircbuf_createfilemapping: UnmapViewOfFile(d_second_copy)", GetLastError());
+ }
+ //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
index 000000000..5ef31f5c6
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_vmcircbuf_createfilemapping.h
@@ -0,0 +1,76 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003,2005 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef _GR_VMCIRCBUF_CREATEFILEMAPPING_H_
+#define _GR_VMCIRCBUF_CREATEFILEMAPPING_H_
+
+#include <gr_core_api.h>
+#include <gr_vmcircbuf.h>
+
+#ifdef HAVE_CREATEFILEMAPPING
+#include <windows.h>
+#endif
+/*!
+ * \brief concrete class to implement circular buffers with mmap and shm_open
+ * \ingroup internal
+ */
+class GR_CORE_API 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_CORE_API 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
index 000000000..3d170081d
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_vmcircbuf_mmap_shm_open.cc
@@ -0,0 +1,205 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003,2011 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include <gr_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_sys_paths.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
index 000000000..bcbbbac42
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_vmcircbuf_mmap_shm_open.h
@@ -0,0 +1,67 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef _GR_VMCIRCBUF_MMAP_SHM_OPEN_H_
+#define _GR_VMCIRCBUF_MMAP_SHM_OPEN_H_
+
+#include <gr_core_api.h>
+#include <gr_vmcircbuf.h>
+
+/*!
+ * \brief concrete class to implement circular buffers with mmap and shm_open
+ * \ingroup internal
+ */
+class GR_CORE_API 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_CORE_API 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
index 000000000..35de64699
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_vmcircbuf_mmap_tmpfile.cc
@@ -0,0 +1,197 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003,2011 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include <gr_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_sys_paths.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
index 000000000..28ff31490
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_vmcircbuf_mmap_tmpfile.h
@@ -0,0 +1,67 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef _GR_VMCIRCBUF_MMAP_TMPFILE_H_
+#define _GR_VMCIRCBUF_MMAP_TMPFILE_H_
+
+#include <gr_core_api.h>
+#include <gr_vmcircbuf.h>
+
+/*!
+ * \brief concrete class to implement circular buffers with mmap and shm_open
+ * \ingroup internal
+ */
+class GR_CORE_API 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_CORE_API 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
index 000000000..d9cf75e70
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_vmcircbuf_sysv_shm.cc
@@ -0,0 +1,194 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include <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)");
+ shmctl (shmid_guard, IPC_RMID, 0);
+ 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 (shmid_guard, IPC_RMID, 0);
+ 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
index 000000000..9f5c04f0d
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_vmcircbuf_sysv_shm.h
@@ -0,0 +1,67 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef _GR_VMCIRCBUF_SYSV_SHM_H_
+#define _GR_VMCIRCBUF_SYSV_SHM_H_
+
+#include <gr_core_api.h>
+#include <gr_vmcircbuf.h>
+
+/*!
+ * \brief concrete class to implement circular buffers with mmap and shm_open
+ * \ingroup internal
+ */
+class GR_CORE_API 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_CORE_API 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/pmx_helper.hpp b/gnuradio-core/src/lib/runtime/pmx_helper.hpp
new file mode 100644
index 000000000..44cc2997c
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/pmx_helper.hpp
@@ -0,0 +1,268 @@
+/*
+ * Copyright 2012-2013 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_LIBGRAS_PMX_HELPER_HPP
+#define INCLUDED_LIBGRAS_PMX_HELPER_HPP
+
+#include <PMC/PMC.hpp>
+#include <PMC/Containers.hpp>
+#include <gruel/pmt.h>
+#include <boost/foreach.hpp>
+
+namespace pmt
+{
+
+inline pmt_t pmc_to_pmt(const PMCC &p)
+{
+ //the container is null
+ if (not p) return pmt::pmt_t();
+
+ #define decl_pmc_to_pmt(type, conv) if (p.is<type >()) return conv(p.as<type >())
+
+ //bool
+ decl_pmc_to_pmt(bool, pmt_from_bool);
+
+ //string
+ decl_pmc_to_pmt(std::string, pmt_string_to_symbol);
+
+ //numeric types
+ decl_pmc_to_pmt(int8_t, pmt_from_long);
+ decl_pmc_to_pmt(int16_t, pmt_from_long);
+ decl_pmc_to_pmt(int32_t, pmt_from_long);
+ decl_pmc_to_pmt(uint8_t, pmt_from_long);
+ decl_pmc_to_pmt(uint16_t, pmt_from_long);
+ decl_pmc_to_pmt(uint32_t, pmt_from_long);
+ decl_pmc_to_pmt(int64_t, pmt_from_uint64);
+ decl_pmc_to_pmt(uint64_t, pmt_from_uint64);
+ decl_pmc_to_pmt(float, pmt_from_double);
+ decl_pmc_to_pmt(double, pmt_from_double);
+ #define pmt_from_complex(x) pmt_make_rectangular((x).real(), (x).imag())
+ decl_pmc_to_pmt(std::complex<float>, pmt_from_complex);
+ decl_pmc_to_pmt(std::complex<double>, pmt_from_complex);
+
+ //pair container
+ if (p.is<PMCPair>())
+ {
+ const PMCPair &pr = p.as<PMCPair>();
+ return pmt_cons(pmc_to_pmt(pr.first), pmc_to_pmt(pr.second));
+ }
+
+ //fucking tuples
+/*
+for i in range(11):
+ args = list()
+ for j in range(i):
+ args.append('pmc_to_pmt(p.as<PMCTuple<%d> >()[%d])'%(i, j))
+ print ' if (p.is<PMCTuple<%d> >())'%i
+ print ' return pmt_make_tuple(%s);'%(', '.join(args),)
+*/
+ if (p.is<PMCTuple<0> >())
+ return pmt_make_tuple();
+ if (p.is<PMCTuple<1> >())
+ return pmt_make_tuple(pmc_to_pmt(p.as<PMCTuple<1> >()[0]));
+ if (p.is<PMCTuple<2> >())
+ return pmt_make_tuple(pmc_to_pmt(p.as<PMCTuple<2> >()[0]), pmc_to_pmt(p.as<PMCTuple<2> >()[1]));
+ if (p.is<PMCTuple<3> >())
+ return pmt_make_tuple(pmc_to_pmt(p.as<PMCTuple<3> >()[0]), pmc_to_pmt(p.as<PMCTuple<3> >()[1]), pmc_to_pmt(p.as<PMCTuple<3> >()[2]));
+ if (p.is<PMCTuple<4> >())
+ return pmt_make_tuple(pmc_to_pmt(p.as<PMCTuple<4> >()[0]), pmc_to_pmt(p.as<PMCTuple<4> >()[1]), pmc_to_pmt(p.as<PMCTuple<4> >()[2]), pmc_to_pmt(p.as<PMCTuple<4> >()[3]));
+ if (p.is<PMCTuple<5> >())
+ return pmt_make_tuple(pmc_to_pmt(p.as<PMCTuple<5> >()[0]), pmc_to_pmt(p.as<PMCTuple<5> >()[1]), pmc_to_pmt(p.as<PMCTuple<5> >()[2]), pmc_to_pmt(p.as<PMCTuple<5> >()[3]), pmc_to_pmt(p.as<PMCTuple<5> >()[4]));
+ if (p.is<PMCTuple<6> >())
+ return pmt_make_tuple(pmc_to_pmt(p.as<PMCTuple<6> >()[0]), pmc_to_pmt(p.as<PMCTuple<6> >()[1]), pmc_to_pmt(p.as<PMCTuple<6> >()[2]), pmc_to_pmt(p.as<PMCTuple<6> >()[3]), pmc_to_pmt(p.as<PMCTuple<6> >()[4]), pmc_to_pmt(p.as<PMCTuple<6> >()[5]));
+ if (p.is<PMCTuple<7> >())
+ return pmt_make_tuple(pmc_to_pmt(p.as<PMCTuple<7> >()[0]), pmc_to_pmt(p.as<PMCTuple<7> >()[1]), pmc_to_pmt(p.as<PMCTuple<7> >()[2]), pmc_to_pmt(p.as<PMCTuple<7> >()[3]), pmc_to_pmt(p.as<PMCTuple<7> >()[4]), pmc_to_pmt(p.as<PMCTuple<7> >()[5]), pmc_to_pmt(p.as<PMCTuple<7> >()[6]));
+ if (p.is<PMCTuple<8> >())
+ return pmt_make_tuple(pmc_to_pmt(p.as<PMCTuple<8> >()[0]), pmc_to_pmt(p.as<PMCTuple<8> >()[1]), pmc_to_pmt(p.as<PMCTuple<8> >()[2]), pmc_to_pmt(p.as<PMCTuple<8> >()[3]), pmc_to_pmt(p.as<PMCTuple<8> >()[4]), pmc_to_pmt(p.as<PMCTuple<8> >()[5]), pmc_to_pmt(p.as<PMCTuple<8> >()[6]), pmc_to_pmt(p.as<PMCTuple<8> >()[7]));
+ if (p.is<PMCTuple<9> >())
+ return pmt_make_tuple(pmc_to_pmt(p.as<PMCTuple<9> >()[0]), pmc_to_pmt(p.as<PMCTuple<9> >()[1]), pmc_to_pmt(p.as<PMCTuple<9> >()[2]), pmc_to_pmt(p.as<PMCTuple<9> >()[3]), pmc_to_pmt(p.as<PMCTuple<9> >()[4]), pmc_to_pmt(p.as<PMCTuple<9> >()[5]), pmc_to_pmt(p.as<PMCTuple<9> >()[6]), pmc_to_pmt(p.as<PMCTuple<9> >()[7]), pmc_to_pmt(p.as<PMCTuple<9> >()[8]));
+ if (p.is<PMCTuple<10> >())
+ return pmt_make_tuple(pmc_to_pmt(p.as<PMCTuple<10> >()[0]), pmc_to_pmt(p.as<PMCTuple<10> >()[1]), pmc_to_pmt(p.as<PMCTuple<10> >()[2]), pmc_to_pmt(p.as<PMCTuple<10> >()[3]), pmc_to_pmt(p.as<PMCTuple<10> >()[4]), pmc_to_pmt(p.as<PMCTuple<10> >()[5]), pmc_to_pmt(p.as<PMCTuple<10> >()[6]), pmc_to_pmt(p.as<PMCTuple<10> >()[7]), pmc_to_pmt(p.as<PMCTuple<10> >()[8]), pmc_to_pmt(p.as<PMCTuple<10> >()[9]));
+
+ //vector container
+ if (p.is<PMCList>())
+ {
+ const PMCList &l = p.as<PMCList>();
+ pmt_t v = pmt_make_vector(l.size(), pmt_t());
+ for (size_t i = 0; i < l.size(); i++)
+ {
+ pmt_vector_set(v, i, pmc_to_pmt(l[i]));
+ }
+ return v;
+ }
+
+ //numeric arrays
+ #define decl_pmc_to_pmt_numeric_array(type, suffix) \
+ if (p.is<std::vector<type> >()) return pmt_init_ ## suffix ## vector(p.as<std::vector<type> >().size(), &p.as<std::vector<type> >()[0])
+ decl_pmc_to_pmt_numeric_array(uint8_t, u8);
+ decl_pmc_to_pmt_numeric_array(uint16_t, u16);
+ decl_pmc_to_pmt_numeric_array(uint32_t, u32);
+ decl_pmc_to_pmt_numeric_array(uint64_t, u64);
+ decl_pmc_to_pmt_numeric_array(int8_t, s8);
+ decl_pmc_to_pmt_numeric_array(int16_t, s16);
+ decl_pmc_to_pmt_numeric_array(int32_t, s32);
+ decl_pmc_to_pmt_numeric_array(int64_t, s64);
+ decl_pmc_to_pmt_numeric_array(float, f32);
+ decl_pmc_to_pmt_numeric_array(double, f64);
+ decl_pmc_to_pmt_numeric_array(std::complex<float>, c32);
+ decl_pmc_to_pmt_numeric_array(std::complex<double>, c64);
+
+ //dictionary container
+ if (p.is<PMCDict>())
+ {
+ const PMCDict &m = p.as<PMCDict>();
+ pmt_t d = pmt_make_dict();
+ BOOST_FOREACH(const PMCPair &pr, m)
+ {
+ d = pmt_dict_add(d, pmc_to_pmt(pr.first), pmc_to_pmt(pr.second));
+ }
+ return d;
+ }
+
+ //set container
+ if (p.is<PMCSet>())
+ {
+ const PMCSet &s = p.as<PMCSet>();
+ pmt_t l = PMT_NIL;
+ BOOST_FOREACH(const PMCC &elem, s)
+ {
+ l = pmt_list_add(l, pmc_to_pmt(elem));
+ }
+ return l;
+ }
+
+ //is it already a pmt?
+ if (p.is<pmt_t>()) return p.as<pmt_t>();
+
+ //backup plan... boost::any
+ return pmt_make_any(p);
+
+}
+
+inline PMCC pmt_to_pmc(const pmt_t &p)
+{
+ //if the container null?
+ if (not p) return PMC();
+
+ #define decl_pmt_to_pmc(check, conv) if (check(p)) return PMC_M(conv(p))
+
+ //bool
+ decl_pmt_to_pmc(pmt_is_bool, pmt_to_bool);
+
+ //string (do object interning for strings)
+ decl_pmt_to_pmc(pmt_is_symbol, pmt_symbol_to_string).intern();
+
+ //numeric types
+ decl_pmt_to_pmc(pmt_is_integer, pmt_to_long);
+ decl_pmt_to_pmc(pmt_is_uint64, pmt_to_uint64);
+ decl_pmt_to_pmc(pmt_is_real, pmt_to_double);
+ decl_pmt_to_pmc(pmt_is_complex, pmt_to_complex);
+
+ //is it a boost any holding a PMCC?
+ if (pmt_is_any(p))
+ {
+ const boost::any a = pmt_any_ref(p);
+ if (a.type() == typeid(PMCC)) return boost::any_cast<PMCC>(a);
+ }
+
+ //pair container
+ if (pmt_is_pair(p))
+ {
+ PMCPair pr(pmt_to_pmc(pmt_car(p)), pmt_to_pmc(pmt_cdr(p)));
+ return PMC_M(pr);
+ }
+
+ //fucking tuples
+ #define decl_pmt_to_pmc_tuple(n) \
+ if (pmt_is_tuple(p) and pmt_length(p) == n) \
+ { \
+ PMCTuple<n> t; \
+ for (size_t i = 0; i < n; i++) t[i] = pmt_to_pmc(pmt_tuple_ref(p, i)); \
+ return PMC_M(t); \
+ }
+ decl_pmt_to_pmc_tuple(0);
+ decl_pmt_to_pmc_tuple(1);
+ decl_pmt_to_pmc_tuple(2);
+ decl_pmt_to_pmc_tuple(3);
+ decl_pmt_to_pmc_tuple(4);
+ decl_pmt_to_pmc_tuple(5);
+ decl_pmt_to_pmc_tuple(6);
+ decl_pmt_to_pmc_tuple(7);
+ decl_pmt_to_pmc_tuple(8);
+ decl_pmt_to_pmc_tuple(9);
+ decl_pmt_to_pmc_tuple(10);
+
+ //vector container
+ if (pmt_is_vector(p))
+ {
+ PMCList l(pmt_length(p));
+ for (size_t i = 0; i < l.size(); i++)
+ {
+ l[i] = pmt_to_pmc(pmt_vector_ref(p, i));
+ }
+ return PMC_M(l);
+ }
+
+ //numeric arrays
+ #define decl_pmt_to_pmc_numeric_array(type, suffix) \
+ if (pmt_is_ ## suffix ## vector(p)) \
+ { \
+ size_t n; const type* i = pmt_ ## suffix ## vector_elements(p, n); \
+ return PMC_M(std::vector<type>(i, i+n)); \
+ }
+ decl_pmt_to_pmc_numeric_array(uint8_t, u8);
+ decl_pmt_to_pmc_numeric_array(uint16_t, u16);
+ decl_pmt_to_pmc_numeric_array(uint32_t, u32);
+ decl_pmt_to_pmc_numeric_array(uint64_t, u64);
+ decl_pmt_to_pmc_numeric_array(int8_t, s8);
+ decl_pmt_to_pmc_numeric_array(int16_t, s16);
+ decl_pmt_to_pmc_numeric_array(int32_t, s32);
+ decl_pmt_to_pmc_numeric_array(int64_t, s64);
+ decl_pmt_to_pmc_numeric_array(float, f32);
+ decl_pmt_to_pmc_numeric_array(double, f64);
+ decl_pmt_to_pmc_numeric_array(std::complex<float>, c32);
+ decl_pmt_to_pmc_numeric_array(std::complex<double>, c64);
+
+ //dictionary container
+ if (pmt_is_dict(p))
+ {
+ PMCDict m;
+ pmt_t items = pmt_dict_items(p);
+ for (size_t i = 0; i < pmt_length(items); i++)
+ {
+ pmt_t item = pmt_nth(i, items);
+ PMCC key = pmt_to_pmc(pmt_car(item));
+ PMCC val = pmt_to_pmc(pmt_cdr(item));
+ m[key] = val;
+ }
+ return PMC_M(m);
+ }
+
+ //set container
+ //FIXME no pmt_is_list...
+
+ //backup plan... store the pmt
+ return PMC_M(p);
+}
+
+}
+
+#endif /*INCLUDED_LIBGRAS_PMX_HELPER_HPP*/
diff --git a/gnuradio-core/src/lib/runtime/qa_block_tags.cc b/gnuradio-core/src/lib/runtime/qa_block_tags.cc
new file mode 100644
index 000000000..d6b1065e3
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/qa_block_tags.cc
@@ -0,0 +1,450 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <qa_block_tags.h>
+#include <gr_block.h>
+#include <gr_top_block.h>
+#include <gr_null_source.h>
+#include <gr_null_sink.h>
+#include <gr_head.h>
+#include <gr_annotator_alltoall.h>
+#include <gr_annotator_1to1.h>
+#include <gr_keep_one_in_n.h>
+#include <gr_firdes.h>
+#include <gr_tags.h>
+
+
+// ----------------------------------------------------------------
+
+using namespace pmt;
+
+// set to 1 to turn on debug output
+// The debug output fully checks that the tags seen are what are expected. While
+// this behavior currently works with our implementation, there is no guarentee
+// that the tags will be coming in this specific order, so it's dangerous to
+// rely on this as a test of the tag system working. We would really want to
+// tags we know we should see and then test that they all occur once, but in no
+// particular order.
+#define QA_TAGS_DEBUG 0
+
+void
+qa_block_tags::t0 ()
+{
+ unsigned int N = 1000;
+ gr_top_block_sptr tb = gr_make_top_block("top");
+ gr_block_sptr src (gr_make_null_source(sizeof(int)));
+ gr_block_sptr head (gr_make_head(sizeof(int), N));
+ gr_block_sptr snk (gr_make_null_sink(sizeof(int)));
+
+ tb->connect(src, 0, head, 0);
+ tb->connect(head, 0, snk, 0);
+
+ //CPPUNIT_ASSERT_THROW(src->nitems_read(0), std::runtime_error);
+ //CPPUNIT_ASSERT_THROW(src->nitems_written(0), std::runtime_error);
+ CPPUNIT_ASSERT_EQUAL(src->nitems_read(0), (uint64_t)0);
+ CPPUNIT_ASSERT_EQUAL(src->nitems_written(0), (uint64_t)0);
+
+ tb->run();
+
+ CPPUNIT_ASSERT_THROW(src->nitems_read(0), std::invalid_argument);
+ CPPUNIT_ASSERT(src->nitems_written(0) >= N);
+ CPPUNIT_ASSERT_EQUAL(snk->nitems_read(0), (uint64_t)1000);
+ CPPUNIT_ASSERT_THROW(snk->nitems_written(0), std::invalid_argument);
+}
+
+
+void
+qa_block_tags::t1 ()
+{
+ int N = 40000;
+ gr_top_block_sptr tb = gr_make_top_block("top");
+ gr_block_sptr src (gr_make_null_source(sizeof(int)));
+ gr_block_sptr head (gr_make_head(sizeof(int), N));
+ gr_annotator_alltoall_sptr ann0 (gr_make_annotator_alltoall(10000, sizeof(int)));
+ gr_annotator_alltoall_sptr ann1 (gr_make_annotator_alltoall(10000, sizeof(int)));
+ gr_annotator_alltoall_sptr ann2 (gr_make_annotator_alltoall(10000, sizeof(int)));
+ gr_annotator_alltoall_sptr ann3 (gr_make_annotator_alltoall(10000, sizeof(int)));
+ gr_annotator_alltoall_sptr ann4 (gr_make_annotator_alltoall(10000, sizeof(int)));
+ gr_block_sptr snk0 (gr_make_null_sink(sizeof(int)));
+ gr_block_sptr snk1 (gr_make_null_sink(sizeof(int)));
+
+ tb->connect(src, 0, head, 0);
+ tb->connect(head, 0, ann0, 0);
+
+ tb->connect(ann0, 0, ann1, 0);
+ tb->connect(ann0, 1, ann2, 0);
+ tb->connect(ann1, 0, ann3, 0);
+ tb->connect(ann2, 0, ann4, 0);
+
+ tb->connect(ann3, 0, snk0, 0);
+ tb->connect(ann4, 0, snk1, 0);
+
+ tb->run();
+
+ std::vector<gr_tag_t> tags0 = ann0->data();
+ std::vector<gr_tag_t> tags3 = ann3->data();
+ std::vector<gr_tag_t> tags4 = ann4->data();
+
+ // The first annotator does not receive any tags from the null sink upstream
+ CPPUNIT_ASSERT_EQUAL(tags0.size(), (size_t)0);
+ CPPUNIT_ASSERT_EQUAL(tags3.size(), (size_t)8);
+ CPPUNIT_ASSERT_EQUAL(tags4.size(), (size_t)8);
+
+#if QA_TAGS_DEBUG
+ // Kludge together the tags that we know should result from the above graph
+ std::stringstream str0, str1, str2;
+ str0 << ann0->name() << ann0->unique_id();
+ str1 << ann1->name() << ann1->unique_id();
+ str2 << ann2->name() << ann2->unique_id();
+
+ pmt_t expected_tags3[8];
+ expected_tags3[0] = mp(pmt_from_uint64(0), mp(str1.str()), mp("seq"), mp(0));
+ expected_tags3[1] = mp(pmt_from_uint64(0), mp(str0.str()), mp("seq"), mp(0));
+ expected_tags3[2] = mp(pmt_from_uint64(10000), mp(str1.str()), mp("seq"), mp(1));
+ expected_tags3[3] = mp(pmt_from_uint64(10000), mp(str0.str()), mp("seq"), mp(2));
+ expected_tags3[4] = mp(pmt_from_uint64(20000), mp(str1.str()), mp("seq"), mp(2));
+ expected_tags3[5] = mp(pmt_from_uint64(20000), mp(str0.str()), mp("seq"), mp(4));
+ expected_tags3[6] = mp(pmt_from_uint64(30000), mp(str1.str()), mp("seq"), mp(3));
+ expected_tags3[7] = mp(pmt_from_uint64(30000), mp(str0.str()), mp("seq"), mp(6));
+
+ pmt_t expected_tags4[8];
+ expected_tags4[0] = mp(pmt_from_uint64(0), mp(str2.str()), mp("seq"), mp(0));
+ expected_tags4[1] = mp(pmt_from_uint64(0), mp(str0.str()), mp("seq"), mp(1));
+ expected_tags4[2] = mp(pmt_from_uint64(10000), mp(str2.str()), mp("seq"), mp(1));
+ expected_tags4[3] = mp(pmt_from_uint64(10000), mp(str0.str()), mp("seq"), mp(3));
+ expected_tags4[4] = mp(pmt_from_uint64(20000), mp(str2.str()), mp("seq"), mp(2));
+ expected_tags4[5] = mp(pmt_from_uint64(20000), mp(str0.str()), mp("seq"), mp(5));
+ expected_tags4[6] = mp(pmt_from_uint64(30000), mp(str2.str()), mp("seq"), mp(3));
+ expected_tags4[7] = mp(pmt_from_uint64(30000), mp(str0.str()), mp("seq"), mp(7));
+
+ std::cout << std::endl << "qa_block_tags::t1" << std::endl;
+
+ // For annotator 3, we know it gets tags from ann0 and ann1, test this
+ for(size_t i = 0; i < tags3.size(); i++) {
+ std::cout << "tags3[" << i << "] = " << tags3[i] << "\t\t" << expected_tags3[i] << std::endl;
+ CPPUNIT_ASSERT_EQUAL(pmt_write_string(tags3[i]), pmt_write_string(expected_tags3[i]));
+ }
+
+ // For annotator 4, we know it gets tags from ann0 and ann2, test this
+ std::cout << std::endl;
+ for(size_t i = 0; i < tags4.size(); i++) {
+ std::cout << "tags4[" << i << "] = " << tags4[i] << "\t\t" << expected_tags4[i] << std::endl;
+ CPPUNIT_ASSERT_EQUAL(pmt_write_string(tags4[i]), pmt_write_string(expected_tags4[i]));
+ }
+#endif
+}
+
+void
+qa_block_tags::t2 ()
+{
+ int N = 40000;
+ gr_top_block_sptr tb = gr_make_top_block("top");
+ gr_block_sptr src (gr_make_null_source(sizeof(int)));
+ gr_block_sptr head (gr_make_head(sizeof(int), N));
+ gr_annotator_alltoall_sptr ann0 (gr_make_annotator_alltoall(10000, sizeof(int)));
+ gr_annotator_alltoall_sptr ann1 (gr_make_annotator_alltoall(10000, sizeof(int)));
+ gr_annotator_alltoall_sptr ann2 (gr_make_annotator_alltoall(10000, sizeof(int)));
+ gr_annotator_alltoall_sptr ann3 (gr_make_annotator_alltoall(10000, sizeof(int)));
+ gr_annotator_alltoall_sptr ann4 (gr_make_annotator_alltoall(10000, sizeof(int)));
+ gr_block_sptr snk0 (gr_make_null_sink(sizeof(int)));
+ gr_block_sptr snk1 (gr_make_null_sink(sizeof(int)));
+ gr_block_sptr snk2 (gr_make_null_sink(sizeof(int)));
+
+ tb->connect(src, 0, head, 0);
+ tb->connect(head, 0, ann0, 0);
+
+ tb->connect(ann0, 0, ann1, 0);
+ tb->connect(ann0, 1, ann1, 1);
+ tb->connect(ann1, 0, ann2, 0);
+ tb->connect(ann1, 1, ann3, 0);
+ tb->connect(ann1, 2, ann4, 0);
+
+ tb->connect(ann2, 0, snk0, 0);
+ tb->connect(ann3, 0, snk1, 0);
+ tb->connect(ann4, 0, snk2, 0);
+
+ tb->run();
+
+ std::vector<gr_tag_t> tags0 = ann0->data();
+ std::vector<gr_tag_t> tags1 = ann1->data();
+ std::vector<gr_tag_t> tags2 = ann2->data();
+ std::vector<gr_tag_t> tags3 = ann4->data();
+ std::vector<gr_tag_t> tags4 = ann4->data();
+
+ // The first annotator does not receive any tags from the null sink upstream
+ CPPUNIT_ASSERT_EQUAL(tags0.size(), (size_t)0);
+ CPPUNIT_ASSERT_EQUAL(tags1.size(), (size_t)8);
+
+ // Make sure the rest all have 12 tags
+ CPPUNIT_ASSERT_EQUAL(tags2.size(), (size_t)12);
+ CPPUNIT_ASSERT_EQUAL(tags3.size(), (size_t)12);
+ CPPUNIT_ASSERT_EQUAL(tags4.size(), (size_t)12);
+
+
+#if QA_TAGS_DEBUG
+ // Kludge together the tags that we know should result from the above graph
+ std::stringstream str0, str1;
+ str0 << ann0->name() << ann0->unique_id();
+ str1 << ann1->name() << ann1->unique_id();
+
+ pmt_t expected_tags2[12];
+ expected_tags2[0] = mp(pmt_from_uint64(0), mp(str1.str()), mp("seq"), mp(0));
+ expected_tags2[1] = mp(pmt_from_uint64(0), mp(str0.str()), mp("seq"), mp(0));
+ expected_tags2[2] = mp(pmt_from_uint64(0), mp(str0.str()), mp("seq"), mp(1));
+ expected_tags2[3] = mp(pmt_from_uint64(10000), mp(str1.str()), mp("seq"), mp(3));
+ expected_tags2[4] = mp(pmt_from_uint64(10000), mp(str0.str()), mp("seq"), mp(2));
+ expected_tags2[5] = mp(pmt_from_uint64(10000), mp(str0.str()), mp("seq"), mp(3));
+ expected_tags2[6] = mp(pmt_from_uint64(20000), mp(str1.str()), mp("seq"), mp(6));
+ expected_tags2[7] = mp(pmt_from_uint64(20000), mp(str0.str()), mp("seq"), mp(4));
+ expected_tags2[8] = mp(pmt_from_uint64(20000), mp(str0.str()), mp("seq"), mp(5));
+ expected_tags2[9] = mp(pmt_from_uint64(30000), mp(str1.str()), mp("seq"), mp(9));
+ expected_tags2[10] = mp(pmt_from_uint64(30000), mp(str0.str()), mp("seq"), mp(6));
+ expected_tags2[11] = mp(pmt_from_uint64(30000), mp(str0.str()), mp("seq"), mp(7));
+
+ pmt_t expected_tags4[12];
+ expected_tags4[0] = mp(pmt_from_uint64(0), mp(str1.str()), mp("seq"), mp(2));
+ expected_tags4[1] = mp(pmt_from_uint64(0), mp(str0.str()), mp("seq"), mp(0));
+ expected_tags4[2] = mp(pmt_from_uint64(0), mp(str0.str()), mp("seq"), mp(1));
+ expected_tags4[3] = mp(pmt_from_uint64(10000), mp(str1.str()), mp("seq"), mp(5));
+ expected_tags4[4] = mp(pmt_from_uint64(10000), mp(str0.str()), mp("seq"), mp(2));
+ expected_tags4[5] = mp(pmt_from_uint64(10000), mp(str0.str()), mp("seq"), mp(3));
+ expected_tags4[6] = mp(pmt_from_uint64(20000), mp(str1.str()), mp("seq"), mp(8));
+ expected_tags4[7] = mp(pmt_from_uint64(20000), mp(str0.str()), mp("seq"), mp(4));
+ expected_tags4[8] = mp(pmt_from_uint64(20000), mp(str0.str()), mp("seq"), mp(5));
+ expected_tags4[9] = mp(pmt_from_uint64(30000), mp(str1.str()), mp("seq"), mp(11));
+ expected_tags4[10] = mp(pmt_from_uint64(30000), mp(str0.str()), mp("seq"), mp(6));
+ expected_tags4[11] = mp(pmt_from_uint64(30000), mp(str0.str()), mp("seq"), mp(7));
+
+ std::cout << std::endl << "qa_block_tags::t2" << std::endl;
+
+ // For annotator[2-4], we know it gets tags from ann0 and ann1
+ // but the tags from the different outputs of ann1 are different for each.
+ // Just testing ann2 and ann4; if they are correct it would be
+ // inconceivable for ann3 to have it wrong.
+ for(size_t i = 0; i < tags2.size(); i++) {
+ std::cout << "tags2[" << i << "] = " << tags2[i] << "\t\t" << expected_tags2[i] << std::endl;
+ CPPUNIT_ASSERT_EQUAL(pmt_write_string(tags2[i]), pmt_write_string(expected_tags2[i]));
+ }
+
+ std::cout << std::endl;
+ for(size_t i = 0; i < tags4.size(); i++) {
+ std::cout << "tags2[" << i << "] = " << tags4[i] << "\t\t" << expected_tags4[i] << std::endl;
+ CPPUNIT_ASSERT_EQUAL(pmt_write_string(tags4[i]), pmt_write_string(expected_tags4[i]));
+ }
+#endif
+}
+
+
+void
+qa_block_tags::t3 ()
+{
+ int N = 40000;
+ gr_top_block_sptr tb = gr_make_top_block("top");
+ gr_block_sptr src (gr_make_null_source(sizeof(int)));
+ gr_block_sptr head (gr_make_head(sizeof(int), N));
+ gr_annotator_1to1_sptr ann0 (gr_make_annotator_1to1(10000, sizeof(int)));
+ gr_annotator_alltoall_sptr ann1 (gr_make_annotator_alltoall(10000, sizeof(int)));
+ gr_annotator_alltoall_sptr ann2 (gr_make_annotator_alltoall(10000, sizeof(int)));
+ gr_annotator_1to1_sptr ann3 (gr_make_annotator_1to1(10000, sizeof(int)));
+ gr_annotator_1to1_sptr ann4 (gr_make_annotator_1to1(10000, sizeof(int)));
+ gr_block_sptr snk0 (gr_make_null_sink(sizeof(int)));
+ gr_block_sptr snk1 (gr_make_null_sink(sizeof(int)));
+
+ tb->connect(src, 0, head, 0);
+ tb->connect(head, 0, ann0, 0);
+ tb->connect(head, 0, ann0, 1);
+
+ tb->connect(ann0, 0, ann1, 0);
+ tb->connect(ann0, 1, ann2, 0);
+ tb->connect(ann1, 0, ann3, 0);
+ tb->connect(ann2, 0, ann4, 0);
+
+ tb->connect(ann3, 0, snk0, 0);
+ tb->connect(ann4, 0, snk1, 0);
+
+ tb->run();
+
+
+ std::vector<gr_tag_t> tags0 = ann0->data();
+ std::vector<gr_tag_t> tags3 = ann3->data();
+ std::vector<gr_tag_t> tags4 = ann4->data();
+
+ // The first annotator does not receive any tags from the null sink upstream
+ CPPUNIT_ASSERT_EQUAL(tags0.size(), (size_t)0);
+ CPPUNIT_ASSERT_EQUAL(tags3.size(), (size_t)8);
+ CPPUNIT_ASSERT_EQUAL(tags4.size(), (size_t)8);
+
+#if QA_TAGS_DEBUG
+ // Kludge together the tags that we know should result from the above graph
+ std::stringstream str0, str1, str2;
+ str0 << ann0->name() << ann0->unique_id();
+ str1 << ann1->name() << ann1->unique_id();
+ str2 << ann2->name() << ann2->unique_id();
+
+ pmt_t expected_tags3[8];
+ expected_tags3[0] = mp(pmt_from_uint64(0), mp(str1.str()), mp("seq"), mp(0));
+ expected_tags3[1] = mp(pmt_from_uint64(0), mp(str0.str()), mp("seq"), mp(0));
+ expected_tags3[2] = mp(pmt_from_uint64(10000), mp(str1.str()), mp("seq"), mp(1));
+ expected_tags3[3] = mp(pmt_from_uint64(10000), mp(str0.str()), mp("seq"), mp(2));
+ expected_tags3[4] = mp(pmt_from_uint64(20000), mp(str1.str()), mp("seq"), mp(2));
+ expected_tags3[5] = mp(pmt_from_uint64(20000), mp(str0.str()), mp("seq"), mp(4));
+ expected_tags3[6] = mp(pmt_from_uint64(30000), mp(str1.str()), mp("seq"), mp(3));
+ expected_tags3[7] = mp(pmt_from_uint64(30000), mp(str0.str()), mp("seq"), mp(6));
+
+ pmt_t expected_tags4[8];
+ expected_tags4[0] = mp(pmt_from_uint64(0), mp(str2.str()), mp("seq"), mp(0));
+ expected_tags4[1] = mp(pmt_from_uint64(0), mp(str0.str()), mp("seq"), mp(1));
+ expected_tags4[2] = mp(pmt_from_uint64(10000), mp(str2.str()), mp("seq"), mp(1));
+ expected_tags4[3] = mp(pmt_from_uint64(10000), mp(str0.str()), mp("seq"), mp(3));
+ expected_tags4[4] = mp(pmt_from_uint64(20000), mp(str2.str()), mp("seq"), mp(2));
+ expected_tags4[5] = mp(pmt_from_uint64(20000), mp(str0.str()), mp("seq"), mp(5));
+ expected_tags4[6] = mp(pmt_from_uint64(30000), mp(str2.str()), mp("seq"), mp(3));
+ expected_tags4[7] = mp(pmt_from_uint64(30000), mp(str0.str()), mp("seq"), mp(7));
+
+ std::cout << std::endl << "qa_block_tags::t3" << std::endl;
+
+ // For annotator 3, we know it gets tags from ann0 and ann1, test this
+ for(size_t i = 0; i < tags3.size(); i++) {
+ std::cout << "tags3[" << i << "] = " << tags3[i] << "\t\t" << expected_tags3[i] << std::endl;
+ CPPUNIT_ASSERT_EQUAL(pmt_write_string(tags3[i]), pmt_write_string(expected_tags3[i]));
+ }
+
+ // For annotator 4, we know it gets tags from ann0 and ann2, test this
+ std::cout << std::endl;
+ for(size_t i = 0; i < tags4.size(); i++) {
+ std::cout << "tags4[" << i << "] = " << tags4[i] << "\t\t" << expected_tags4[i] << std::endl;
+ CPPUNIT_ASSERT_EQUAL(pmt_write_string(tags4[i]), pmt_write_string(expected_tags4[i]));
+ }
+#endif
+}
+
+
+void
+qa_block_tags::t4 ()
+{
+ int N = 40000;
+ gr_top_block_sptr tb = gr_make_top_block("top");
+ gr_block_sptr src (gr_make_null_source(sizeof(int)));
+ gr_block_sptr head (gr_make_head(sizeof(int), N));
+ gr_annotator_1to1_sptr ann0 (gr_make_annotator_1to1(10000, sizeof(int)));
+ gr_annotator_1to1_sptr ann1 (gr_make_annotator_1to1(10000, sizeof(int)));
+ gr_annotator_1to1_sptr ann2 (gr_make_annotator_1to1(10000, sizeof(int)));
+ gr_block_sptr snk0 (gr_make_null_sink(sizeof(int)));
+ gr_block_sptr snk1 (gr_make_null_sink(sizeof(int)));
+
+ // using 1-to-1 tag propagation without having equal number of
+ // ins and outs. Make sure this works; will just exit run early.
+ tb->connect(src, 0, head, 0);
+ tb->connect(head, 0, ann0, 0);
+ tb->connect(ann0, 0, ann1, 0);
+ tb->connect(ann0, 1, ann2, 0);
+ tb->connect(ann1, 0, snk0, 0);
+ tb->connect(ann2, 0, snk1, 0);
+
+ std::cerr << std::endl
+ << "NOTE: This is supposed to produce an error from gr_block_executor"
+ << std::endl;
+ tb->run();
+}
+
+
+void
+qa_block_tags::t5 ()
+{
+ int N = 40000;
+ gr_top_block_sptr tb = gr_make_top_block("top");
+ gr_block_sptr src (gr_make_null_source(sizeof(float)));
+ gr_block_sptr head (gr_make_head(sizeof(float), N));
+ gr_annotator_alltoall_sptr ann0 (gr_make_annotator_alltoall(10000, sizeof(float)));
+ gr_annotator_alltoall_sptr ann1 (gr_make_annotator_alltoall(10000, sizeof(float)));
+ gr_annotator_alltoall_sptr ann2 (gr_make_annotator_alltoall(1000, sizeof(float)));
+ gr_block_sptr snk0 (gr_make_null_sink(sizeof(float)));
+
+ // Rate change blocks
+ gr_keep_one_in_n_sptr dec10 (gr_make_keep_one_in_n(sizeof(float), 10));
+
+ tb->connect(src, 0, head, 0);
+ tb->connect(head, 0, ann0, 0);
+ tb->connect(ann0, 0, ann1, 0);
+ tb->connect(ann1, 0, dec10, 0);
+ tb->connect(dec10, 0, ann2, 0);
+ tb->connect(ann2, 0, snk0, 0);
+
+ tb->run();
+
+ std::vector<gr_tag_t> tags0 = ann0->data();
+ std::vector<gr_tag_t> tags1 = ann1->data();
+ std::vector<gr_tag_t> tags2 = ann2->data();
+
+ // The first annotator does not receive any tags from the null sink upstream
+ CPPUNIT_ASSERT_EQUAL(tags0.size(), (size_t)0);
+ CPPUNIT_ASSERT_EQUAL(tags1.size(), (size_t)4);
+ CPPUNIT_ASSERT_EQUAL(tags2.size(), (size_t)8);
+
+
+#if QA_TAGS_DEBUG
+ // Kludge together the tags that we know should result from the above graph
+ std::stringstream str0, str1, str2;
+ str0 << ann0->name() << ann0->unique_id();
+ str1 << ann1->name() << ann1->unique_id();
+ str2 << ann2->name() << ann2->unique_id();
+
+ pmt_t expected_tags1[5];
+ expected_tags1[0] = mp(pmt_from_uint64(0), mp(str0.str()), mp("seq"), mp(0));
+ expected_tags1[1] = mp(pmt_from_uint64(10000), mp(str0.str()), mp("seq"), mp(1));
+ expected_tags1[2] = mp(pmt_from_uint64(20000), mp(str0.str()), mp("seq"), mp(2));
+ expected_tags1[3] = mp(pmt_from_uint64(30000), mp(str0.str()), mp("seq"), mp(3));
+
+ pmt_t expected_tags2[10];
+ expected_tags2[0] = mp(pmt_from_uint64(0), mp(str1.str()), mp("seq"), mp(0));
+ expected_tags2[1] = mp(pmt_from_uint64(0), mp(str0.str()), mp("seq"), mp(0));
+ expected_tags2[2] = mp(pmt_from_uint64(1000), mp(str1.str()), mp("seq"), mp(1));
+ expected_tags2[3] = mp(pmt_from_uint64(1000), mp(str0.str()), mp("seq"), mp(1));
+ expected_tags2[4] = mp(pmt_from_uint64(2000), mp(str1.str()), mp("seq"), mp(2));
+ expected_tags2[5] = mp(pmt_from_uint64(2000), mp(str0.str()), mp("seq"), mp(2));
+ expected_tags2[6] = mp(pmt_from_uint64(3000), mp(str1.str()), mp("seq"), mp(3));
+ expected_tags2[7] = mp(pmt_from_uint64(3000), mp(str0.str()), mp("seq"), mp(3));
+ expected_tags2[8] = mp(pmt_from_uint64(4000), mp(str1.str()), mp("seq"), mp(4));
+ expected_tags2[9] = mp(pmt_from_uint64(4000), mp(str0.str()), mp("seq"), mp(4));
+
+ std::cout << std::endl << "qa_block_tags::t5" << std::endl;
+
+ // annotator 1 gets tags from annotator 0
+ std::cout << "tags1.size(): " << tags1.size() << std::endl;
+ for(size_t i = 0; i < tags1.size(); i++) {
+ std::cout << "tags1[" << i << "] = " << tags1[i] << "\t\t" << expected_tags1[i] << std::endl;
+ CPPUNIT_ASSERT_EQUAL(pmt_write_string(tags1[i]), pmt_write_string(expected_tags1[i]));
+ }
+
+ // annotator 2 gets tags from annotators 0 and 1
+ std::cout << std::endl;
+ std::cout << "tags2.size(): " << tags2.size() << std::endl;
+ for(size_t i = 0; i < tags2.size(); i++) {
+ std::cout << "tags2[" << i << "] = " << tags2[i] << "\t\t" << expected_tags2[i] << std::endl;
+ CPPUNIT_ASSERT_EQUAL(pmt_write_string(tags2[i]), pmt_write_string(expected_tags2[i]));
+ }
+#endif
+}
+
diff --git a/gnuradio-core/src/lib/runtime/qa_block_tags.h b/gnuradio-core/src/lib/runtime/qa_block_tags.h
new file mode 100644
index 000000000..6b7e5975d
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/qa_block_tags.h
@@ -0,0 +1,52 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_QA_BLOCK_TAGS_H
+#define INCLUDED_QA_BLOCK_TAGS_H
+
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/TestCase.h>
+#include <stdexcept>
+
+class qa_block_tags : public CppUnit::TestCase {
+
+ CPPUNIT_TEST_SUITE (qa_block_tags);
+ 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_BLOCK_TAGS_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
index 000000000..aeab5b74a
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/qa_gr_block.cc
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <qa_gr_block.h>
+#include <gr_block.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 ((int) 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 ((int) 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 ((int) 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 ((int) 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
index 000000000..14c7c40d1
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/qa_gr_block.h
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_QA_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
index 000000000..c74baf398
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/qa_gr_buffer.cc
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <qa_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), gr_block_sptr()));
+
+ 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_block_sptr()));
+ gr_buffer_reader_sptr r1 (gr_buffer_add_reader (buf, 0, gr_block_sptr()));
+
+
+ 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_block_sptr()));
+ gr_buffer_reader_sptr r1 (gr_buffer_add_reader (buf, 0, gr_block_sptr()));
+
+ 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_block_sptr()));
+ 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, 0, gr_block_sptr());
+ }
+
+ 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
index 000000000..2937c24b6
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/qa_gr_buffer.h
@@ -0,0 +1,53 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#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_flowgraph.cc b/gnuradio-core/src/lib/runtime/qa_gr_flowgraph.cc
new file mode 100644
index 000000000..cce83cb0a
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/qa_gr_flowgraph.cc
@@ -0,0 +1,245 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <qa_gr_flowgraph.h>
+#include <gr_flowgraph.h>
+#include <gr_nop.h>
+#include <gr_null_source.h>
+#include <gr_null_sink.h>
+
+void qa_gr_flowgraph::t0()
+{
+ gr_flowgraph_sptr fg = gr_make_flowgraph();
+
+ CPPUNIT_ASSERT(fg);
+}
+
+void qa_gr_flowgraph::t1_connect()
+{
+ gr_flowgraph_sptr fg = gr_make_flowgraph();
+
+ gr_block_sptr nop1 = gr_make_nop(sizeof(int));
+ gr_block_sptr nop2 = gr_make_nop(sizeof(int));
+
+ fg->connect(nop1, 0, nop2, 0);
+}
+
+void qa_gr_flowgraph::t2_connect_invalid_src_port_neg()
+{
+ gr_flowgraph_sptr fg = gr_make_flowgraph();
+
+ gr_block_sptr nop1 = gr_make_nop(sizeof(int));
+ gr_block_sptr nop2 = gr_make_nop(sizeof(int));
+
+ CPPUNIT_ASSERT_THROW(fg->connect(nop1, -1, nop2, 0), std::invalid_argument);
+}
+
+void qa_gr_flowgraph::t3_connect_src_port_exceeds()
+{
+ gr_flowgraph_sptr fg = gr_make_flowgraph();
+
+ gr_block_sptr src = gr_make_null_source(sizeof(int));
+ gr_block_sptr dst = gr_make_null_sink(sizeof(int));
+
+ CPPUNIT_ASSERT_THROW(fg->connect(src, 1, dst, 0), std::invalid_argument);
+}
+
+void qa_gr_flowgraph::t4_connect_invalid_dst_port_neg()
+{
+ gr_flowgraph_sptr fg = gr_make_flowgraph();
+
+ gr_block_sptr nop1 = gr_make_nop(sizeof(int));
+ gr_block_sptr nop2 = gr_make_nop(sizeof(int));
+
+ CPPUNIT_ASSERT_THROW(fg->connect(nop1, 0, nop2, -1), std::invalid_argument);
+}
+
+void qa_gr_flowgraph::t5_connect_dst_port_exceeds()
+{
+ gr_flowgraph_sptr fg = gr_make_flowgraph();
+
+ gr_block_sptr src = gr_make_null_source(sizeof(int));
+ gr_block_sptr dst = gr_make_null_sink(sizeof(int));
+
+ CPPUNIT_ASSERT_THROW(fg->connect(src, 0, dst, 1), std::invalid_argument);
+}
+
+void qa_gr_flowgraph::t6_connect_dst_in_use()
+{
+ gr_flowgraph_sptr fg = gr_make_flowgraph();
+
+ gr_block_sptr src1 = gr_make_null_source(sizeof(int));
+ gr_block_sptr src2 = gr_make_null_source(sizeof(int));
+ gr_block_sptr dst = gr_make_null_sink(sizeof(int));
+
+ fg->connect(src1, 0, dst, 0);
+ CPPUNIT_ASSERT_THROW(fg->connect(src2, 0, dst, 0), std::invalid_argument);
+}
+
+void qa_gr_flowgraph::t7_connect_one_src_two_dst()
+{
+ gr_flowgraph_sptr fg = gr_make_flowgraph();
+
+ gr_block_sptr src = gr_make_null_source(sizeof(int));
+ gr_block_sptr dst1 = gr_make_null_sink(sizeof(int));
+ gr_block_sptr dst2 = gr_make_null_sink(sizeof(int));
+
+ fg->connect(src, 0, dst1, 0);
+ fg->connect(src, 0, dst2, 0);
+}
+
+void qa_gr_flowgraph::t8_connect_type_mismatch()
+{
+ gr_flowgraph_sptr fg = gr_make_flowgraph();
+
+ gr_block_sptr nop1 = gr_make_nop(sizeof(char));
+ gr_block_sptr nop2 = gr_make_nop(sizeof(int));
+
+ CPPUNIT_ASSERT_THROW(fg->connect(nop1, 0, nop2, 0), std::invalid_argument);
+}
+
+void qa_gr_flowgraph::t9_disconnect()
+{
+ gr_flowgraph_sptr fg = gr_make_flowgraph();
+
+ gr_block_sptr nop1 = gr_make_nop(sizeof(int));
+ gr_block_sptr nop2 = gr_make_nop(sizeof(int));
+
+ fg->connect(nop1, 0, nop2, 0);
+ fg->disconnect(nop1, 0, nop2, 0);
+}
+
+void qa_gr_flowgraph::t10_disconnect_unconnected_block()
+{
+ gr_flowgraph_sptr fg = gr_make_flowgraph();
+
+ gr_block_sptr nop1 = gr_make_nop(sizeof(int));
+ gr_block_sptr nop2 = gr_make_nop(sizeof(int));
+ gr_block_sptr nop3 = gr_make_nop(sizeof(int));
+
+ fg->connect(nop1, 0, nop2, 0);
+ CPPUNIT_ASSERT_THROW(fg->disconnect(nop1, 0, nop3, 0), std::invalid_argument);
+}
+
+void qa_gr_flowgraph::t11_disconnect_unconnected_port()
+{
+ gr_flowgraph_sptr fg = gr_make_flowgraph();
+
+ gr_block_sptr nop1 = gr_make_nop(sizeof(int));
+ gr_block_sptr nop2 = gr_make_nop(sizeof(int));
+
+ fg->connect(nop1, 0, nop2, 0);
+ CPPUNIT_ASSERT_THROW(fg->disconnect(nop1, 0, nop2, 1), std::invalid_argument);
+}
+
+void qa_gr_flowgraph::t12_validate()
+{
+ gr_flowgraph_sptr fg = gr_make_flowgraph();
+
+ gr_block_sptr nop1 = gr_make_nop(sizeof(int));
+ gr_block_sptr nop2 = gr_make_nop(sizeof(int));
+
+ fg->connect(nop1, 0, nop2, 0);
+ fg->validate();
+}
+
+void qa_gr_flowgraph::t13_validate_missing_input_assignment()
+{
+ gr_flowgraph_sptr fg = gr_make_flowgraph();
+
+ gr_block_sptr nop1 = gr_make_nop(sizeof(int));
+ gr_block_sptr nop2 = gr_make_nop(sizeof(int));
+
+ fg->connect(nop1, 0, nop2, 0);
+ fg->connect(nop1, 0, nop2, 2);
+ CPPUNIT_ASSERT_THROW(fg->validate(), std::runtime_error);
+}
+
+void qa_gr_flowgraph::t14_validate_missing_output_assignment()
+{
+ gr_flowgraph_sptr fg = gr_make_flowgraph();
+
+ gr_block_sptr nop1 = gr_make_nop(sizeof(int));
+ gr_block_sptr nop2 = gr_make_nop(sizeof(int));
+
+ fg->connect(nop1, 0, nop2, 0);
+ fg->connect(nop1, 2, nop2, 1);
+ CPPUNIT_ASSERT_THROW(fg->validate(), std::runtime_error);
+}
+
+void qa_gr_flowgraph::t15_clear()
+{
+ gr_flowgraph_sptr fg = gr_make_flowgraph();
+
+ gr_block_sptr nop1 = gr_make_nop(sizeof(int));
+ gr_block_sptr nop2 = gr_make_nop(sizeof(int));
+
+ fg->connect(nop1, 0, nop2, 0);
+
+ CPPUNIT_ASSERT(fg->edges().size() == 1);
+ CPPUNIT_ASSERT(fg->calc_used_blocks().size() == 2);
+
+ fg->clear();
+
+ CPPUNIT_ASSERT(fg->edges().size() == 0);
+ CPPUNIT_ASSERT(fg->calc_used_blocks().size() == 0);
+}
+
+void qa_gr_flowgraph::t16_partition()
+{
+ gr_flowgraph_sptr fg = gr_make_flowgraph();
+
+ gr_block_sptr nop11 = gr_make_nop(sizeof(int));
+ gr_block_sptr nop12 = gr_make_nop(sizeof(int));
+ gr_block_sptr nop13 = gr_make_nop(sizeof(int));
+ gr_block_sptr nop14 = gr_make_nop(sizeof(int));
+
+ gr_block_sptr nop21 = gr_make_nop(sizeof(int));
+ gr_block_sptr nop22 = gr_make_nop(sizeof(int));
+ gr_block_sptr nop23 = gr_make_nop(sizeof(int));
+
+ gr_block_sptr nop31 = gr_make_nop(sizeof(int));
+ gr_block_sptr nop32 = gr_make_nop(sizeof(int));
+
+ // Build disjoint graph #1
+ fg->connect(nop11, 0, nop12, 0);
+ fg->connect(nop12, 0, nop13, 0);
+ fg->connect(nop13, 0, nop14, 0);
+
+ // Build disjoint graph #2
+ fg->connect(nop21, 0, nop22, 0);
+ fg->connect(nop22, 0, nop23, 0);
+
+ // Build disjoint graph #3
+ fg->connect(nop31, 0, nop32, 0);
+
+ std::vector<gr_basic_block_vector_t> graphs = fg->partition();
+
+ CPPUNIT_ASSERT(graphs.size() == 3);
+ CPPUNIT_ASSERT(graphs[0].size() == 4);
+ CPPUNIT_ASSERT(graphs[1].size() == 3);
+ CPPUNIT_ASSERT(graphs[2].size() == 2);
+}
diff --git a/gnuradio-core/src/lib/runtime/qa_gr_flowgraph.h b/gnuradio-core/src/lib/runtime/qa_gr_flowgraph.h
new file mode 100644
index 000000000..2c2686f71
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/qa_gr_flowgraph.h
@@ -0,0 +1,75 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_QA_GR_FLOWGRAPH_H
+#define INCLUDED_QA_GR_FLOWGRAPH_H
+
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/TestCase.h>
+#include <stdexcept>
+
+class qa_gr_flowgraph : public CppUnit::TestCase
+{
+ CPPUNIT_TEST_SUITE(qa_gr_flowgraph);
+
+ CPPUNIT_TEST(t0);
+ CPPUNIT_TEST(t1_connect);
+ CPPUNIT_TEST(t2_connect_invalid_src_port_neg);
+ CPPUNIT_TEST(t3_connect_src_port_exceeds);
+ CPPUNIT_TEST(t4_connect_invalid_dst_port_neg);
+ CPPUNIT_TEST(t5_connect_dst_port_exceeds);
+ CPPUNIT_TEST(t6_connect_dst_in_use);
+ CPPUNIT_TEST(t7_connect_one_src_two_dst);
+ CPPUNIT_TEST(t8_connect_type_mismatch);
+ CPPUNIT_TEST(t9_disconnect);
+ CPPUNIT_TEST(t10_disconnect_unconnected_block);
+ CPPUNIT_TEST(t11_disconnect_unconnected_port);
+ CPPUNIT_TEST(t12_validate);
+ CPPUNIT_TEST(t13_validate_missing_input_assignment);
+ CPPUNIT_TEST(t14_validate_missing_output_assignment);
+ CPPUNIT_TEST(t15_clear);
+ CPPUNIT_TEST(t16_partition);
+
+ CPPUNIT_TEST_SUITE_END();
+
+private:
+
+ void t0();
+ void t1_connect();
+ void t2_connect_invalid_src_port_neg();
+ void t3_connect_src_port_exceeds();
+ void t4_connect_invalid_dst_port_neg();
+ void t5_connect_dst_port_exceeds();
+ void t6_connect_dst_in_use();
+ void t7_connect_one_src_two_dst();
+ void t8_connect_type_mismatch();
+ void t9_disconnect();
+ void t10_disconnect_unconnected_block();
+ void t11_disconnect_unconnected_port();
+ void t12_validate();
+ void t13_validate_missing_input_assignment();
+ void t14_validate_missing_output_assignment();
+ void t15_clear();
+ void t16_partition();
+};
+
+#endif /* INCLUDED_QA_GR_FLOWGRAPH_H */
diff --git a/gnuradio-core/src/lib/runtime/qa_gr_hier_block2.cc b/gnuradio-core/src/lib/runtime/qa_gr_hier_block2.cc
new file mode 100644
index 000000000..9844d3381
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/qa_gr_hier_block2.cc
@@ -0,0 +1,57 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006,2008,2009 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <qa_gr_hier_block2.h>
+#include <gr_hier_block2.h>
+#include <gr_io_signature.h>
+#include <gr_null_source.h>
+#include <gr_null_sink.h>
+
+void qa_gr_hier_block2::test_make()
+{
+ gr_hier_block2_sptr src1(gr_make_hier_block2("test",
+ gr_make_io_signature(1, 1, 1 * sizeof(int)),
+ gr_make_io_signature(1, 1, 1 * sizeof(int))));
+
+ CPPUNIT_ASSERT(src1);
+ CPPUNIT_ASSERT_EQUAL(std::string("test"), src1->name());
+
+ CPPUNIT_ASSERT_EQUAL(1 * (int) sizeof(int),
+ src1->input_signature()->sizeof_stream_item(0));
+
+ CPPUNIT_ASSERT_EQUAL(1, src1->input_signature()->min_streams());
+ CPPUNIT_ASSERT_EQUAL(1, src1->input_signature()->max_streams());
+
+
+ CPPUNIT_ASSERT_EQUAL(1 * (int) sizeof(int),
+ src1->output_signature()->sizeof_stream_item(0));
+
+ CPPUNIT_ASSERT_EQUAL(1, src1->output_signature()->min_streams());
+ CPPUNIT_ASSERT_EQUAL(1, src1->output_signature()->max_streams());
+
+}
+
+
diff --git a/gnuradio-core/src/lib/runtime/qa_gr_hier_block2.h b/gnuradio-core/src/lib/runtime/qa_gr_hier_block2.h
new file mode 100644
index 000000000..653cd2725
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/qa_gr_hier_block2.h
@@ -0,0 +1,42 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_QA_GR_HIER_BLOCK2_H
+#define INCLUDED_QA_GR_HIER_BLOCK2_H
+
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/TestCase.h>
+#include <stdexcept>
+
+class qa_gr_hier_block2 : public CppUnit::TestCase
+{
+ CPPUNIT_TEST_SUITE(qa_gr_hier_block2);
+
+ CPPUNIT_TEST(test_make);
+
+ CPPUNIT_TEST_SUITE_END();
+
+private:
+ void test_make();
+};
+
+#endif /* INCLUDED_QA_GR_HIER_BLOCK2_H */
diff --git a/gnuradio-core/src/lib/runtime/qa_gr_hier_block2_derived.cc b/gnuradio-core/src/lib/runtime/qa_gr_hier_block2_derived.cc
new file mode 100644
index 000000000..060c4e244
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/qa_gr_hier_block2_derived.cc
@@ -0,0 +1,87 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006,2008 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <qa_gr_hier_block2_derived.h>
+#include <gr_top_block.h>
+#include <gr_io_signature.h>
+#include <gr_null_source.h>
+#include <gr_null_sink.h>
+#include <gr_head.h>
+#include <gr_kludge_copy.h>
+
+// Declare a test C++ hierarchical block
+
+class gr_derived_block;
+typedef boost::shared_ptr<gr_derived_block> gr_derived_block_sptr;
+gr_derived_block_sptr gr_make_derived_block();
+
+class gr_derived_block : public gr_hier_block2
+{
+private:
+ friend gr_derived_block_sptr gr_make_derived_block();
+ gr_derived_block();
+
+public:
+ ~gr_derived_block();
+};
+
+
+gr_derived_block_sptr
+gr_make_derived_block()
+{
+ return gnuradio::get_initial_sptr(new gr_derived_block());
+}
+
+gr_derived_block::gr_derived_block()
+ : gr_hier_block2("gr_derived_block",
+ gr_make_io_signature(1, 1, sizeof(int)), // Input signature
+ gr_make_io_signature(1, 1, sizeof(int))) // Output signature
+{
+ gr_block_sptr copy(gr_make_kludge_copy(sizeof(int)));
+
+ connect(self(), 0, copy, 0);
+ connect(copy, 0, self(), 0);
+}
+
+gr_derived_block::~gr_derived_block()
+{
+}
+
+void qa_gr_hier_block2_derived::test_1()
+{
+ gr_top_block_sptr tb(gr_make_top_block("test"));
+
+ gr_block_sptr src(gr_make_null_source(sizeof(int)));
+ gr_block_sptr head(gr_make_head(sizeof(int), 1000));
+ gr_derived_block_sptr blk(gr_make_derived_block());
+ gr_block_sptr dst(gr_make_null_sink(sizeof(int)));
+
+ tb->connect(src, 0, head, 0);
+ tb->connect(head, 0, blk, 0);
+ tb->connect(blk, 0, dst, 0);
+
+ tb->run();
+}
diff --git a/gnuradio-core/src/lib/runtime/qa_gr_hier_block2_derived.h b/gnuradio-core/src/lib/runtime/qa_gr_hier_block2_derived.h
new file mode 100644
index 000000000..8e0a1880c
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/qa_gr_hier_block2_derived.h
@@ -0,0 +1,41 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006,2008 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_QA_GR_HIER_BLOCK2_DERIVED_H
+#define INCLUDED_QA_GR_HIER_BLOCK2_DERIVED_H
+
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/TestCase.h>
+#include <stdexcept>
+
+// Declare a QA test case
+class qa_gr_hier_block2_derived : public CppUnit::TestCase
+{
+ CPPUNIT_TEST_SUITE(qa_gr_hier_block2_derived);
+ CPPUNIT_TEST(test_1);
+ CPPUNIT_TEST_SUITE_END();
+
+private:
+ void test_1();
+};
+
+#endif /* INCLUDED_QA_GR_HIER_BLOCK2_DERIVED_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
index 000000000..c1737ffb8
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/qa_gr_io_signature.cc
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <qa_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), (int) sizeof (int));
+}
+
+void
+qa_gr_io_signature::t3 ()
+{
+ gr_io_signature_sptr p =
+ gr_make_io_signature3 (0, 5, 1, 2, 3);
+
+ CPPUNIT_ASSERT_EQUAL (p->min_streams (), 0);
+ CPPUNIT_ASSERT_EQUAL (p->max_streams (), 5);
+ CPPUNIT_ASSERT_EQUAL (p->sizeof_stream_item(0), 1);
+ CPPUNIT_ASSERT_EQUAL (p->sizeof_stream_item(1), 2);
+ CPPUNIT_ASSERT_EQUAL (p->sizeof_stream_item(2), 3);
+ CPPUNIT_ASSERT_EQUAL (p->sizeof_stream_item(3), 3);
+ CPPUNIT_ASSERT_EQUAL (p->sizeof_stream_item(4), 3);
+}
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
index 000000000..9cd6bb524
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/qa_gr_io_signature.h
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_QA_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_top_block.cc b/gnuradio-core/src/lib/runtime/qa_gr_top_block.cc
new file mode 100644
index 000000000..6bbc9ceb8
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/qa_gr_top_block.cc
@@ -0,0 +1,285 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <qa_gr_top_block.h>
+#include <gr_top_block.h>
+#include <gr_head.h>
+#include <gr_nop.h>
+#include <gr_null_source.h>
+#include <gr_null_sink.h>
+#include <iostream>
+
+#define VERBOSE 0
+
+void qa_gr_top_block::t0()
+{
+ if (VERBOSE) std::cout << "qa_gr_top_block::t0()\n";
+
+ gr_top_block_sptr tb = gr_make_top_block("top");
+
+ CPPUNIT_ASSERT(tb);
+}
+
+void qa_gr_top_block::t1_run()
+{
+ if (VERBOSE) std::cout << "qa_gr_top_block::t1()\n";
+
+ gr_top_block_sptr tb = gr_make_top_block("top");
+
+ gr_block_sptr src = gr_make_null_source(sizeof(int));
+ gr_block_sptr head = gr_make_head(sizeof(int), 100000);
+ gr_block_sptr dst = gr_make_null_sink(sizeof(int));
+
+ tb->connect(src, 0, head, 0);
+ tb->connect(head, 0, dst, 0);
+ tb->run();
+}
+
+void qa_gr_top_block::t2_start_stop_wait()
+{
+ if (VERBOSE) std::cout << "qa_gr_top_block::t2()\n";
+
+ gr_top_block_sptr tb = gr_make_top_block("top");
+
+ gr_block_sptr src = gr_make_null_source(sizeof(int));
+ gr_block_sptr head = gr_make_head(sizeof(int), 100000);
+ gr_block_sptr dst = gr_make_null_sink(sizeof(int));
+
+ tb->connect(src, 0, head, 0);
+ tb->connect(head, 0, dst, 0);
+
+ tb->start();
+ tb->stop();
+ tb->wait();
+}
+
+void qa_gr_top_block::t3_lock_unlock()
+{
+ if (VERBOSE) std::cout << "qa_gr_top_block::t3()\n";
+
+ gr_top_block_sptr tb = gr_make_top_block("top");
+
+ gr_block_sptr src = gr_make_null_source(sizeof(int));
+ gr_block_sptr dst = gr_make_null_sink(sizeof(int));
+
+ tb->connect(src, 0, dst, 0);
+
+ tb->start();
+
+ tb->lock();
+ tb->unlock();
+
+ tb->stop();
+ tb->wait();
+}
+
+void qa_gr_top_block::t4_reconfigure()
+{
+ if (VERBOSE) std::cout << "qa_gr_top_block::t4()\n";
+
+ gr_top_block_sptr tb = gr_make_top_block("top");
+
+ gr_block_sptr src = gr_make_null_source(sizeof(int));
+ gr_block_sptr head = gr_make_head(sizeof(int), 100000);
+ gr_block_sptr dst = gr_make_null_sink(sizeof(int));
+
+ // Start infinite flowgraph
+ tb->connect(src, 0, dst, 0);
+ tb->start();
+
+ // Reconfigure with gr_head in the middle
+ tb->lock();
+ tb->disconnect(src, 0, dst, 0);
+ tb->connect(src, 0, head, 0);
+ tb->connect(head, 0, dst, 0);
+ tb->unlock();
+
+ // Wait for flowgraph to end on its own
+ tb->wait();
+}
+
+
+void qa_gr_top_block::t5_max_noutputs()
+{
+ if (VERBOSE) std::cout << "qa_gr_top_block::t5()\n";
+
+ gr_top_block_sptr tb = gr_make_top_block("top");
+
+ gr_block_sptr src = gr_make_null_source(sizeof(int));
+ gr_block_sptr head = gr_make_head(sizeof(int), 100000);
+ gr_block_sptr dst = gr_make_null_sink(sizeof(int));
+
+ // Start infinite flowgraph
+ tb->connect(src, 0, head, 0);
+ tb->connect(head, 0, dst, 0);
+ tb->start(100);
+ tb->wait();
+}
+
+void qa_gr_top_block::t6_reconfig_max_noutputs()
+{
+ if (VERBOSE) std::cout << "qa_gr_top_block::t6()\n";
+
+ gr_top_block_sptr tb = gr_make_top_block("top");
+
+ gr_block_sptr src = gr_make_null_source(sizeof(int));
+ gr_block_sptr head = gr_make_head(sizeof(int), 100000);
+ gr_block_sptr dst = gr_make_null_sink(sizeof(int));
+
+ // Start infinite flowgraph
+ tb->connect(src, 0, dst, 0);
+ tb->start(100);
+
+ // Reconfigure with gr_head in the middle
+ tb->lock();
+ tb->disconnect(src, 0, dst, 0);
+ tb->connect(src, 0, head, 0);
+ tb->connect(head, 0, dst, 0);
+ tb->set_max_noutput_items(1000);
+ head->set_max_noutput_items(500);
+ tb->unlock();
+
+ // Wait for flowgraph to end on its own
+ tb->wait();
+}
+
+void qa_gr_top_block::t7_max_noutputs_per_block()
+{
+ if (VERBOSE) std::cout << "qa_gr_top_block::t7()\n";
+
+ gr_top_block_sptr tb = gr_make_top_block("top");
+
+ gr_block_sptr src = gr_make_null_source(sizeof(int));
+ gr_block_sptr head = gr_make_head(sizeof(int), 100000);
+ gr_block_sptr dst = gr_make_null_sink(sizeof(int));
+
+ head->set_max_noutput_items(100);
+
+ // Start infinite flowgraph
+ tb->connect(src, 0, head, 0);
+ tb->connect(head, 0, dst, 0);
+ tb->start();
+ tb->wait();
+}
+
+void qa_gr_top_block::t8_reconfig_max_noutputs_per_block()
+{
+ if (VERBOSE) std::cout << "qa_gr_top_block::t8()\n";
+
+ gr_top_block_sptr tb = gr_make_top_block("top");
+
+ gr_block_sptr src = gr_make_null_source(sizeof(int));
+ gr_block_sptr head = gr_make_head(sizeof(int), 100000);
+ gr_block_sptr dst = gr_make_null_sink(sizeof(int));
+
+ head->set_max_noutput_items(99);
+
+ // Start infinite flowgraph
+ tb->connect(src, 0, dst, 0);
+ tb->start(201);
+
+ // Reconfigure with gr_head in the middle
+ tb->lock();
+ tb->disconnect(src, 0, dst, 0);
+ tb->connect(src, 0, head, 0);
+ tb->connect(head, 0, dst, 0);
+ tb->set_max_noutput_items(1023);
+ head->set_max_noutput_items(513);
+ tb->unlock();
+
+ // Wait for flowgraph to end on its own
+ tb->wait();
+}
+
+void qa_gr_top_block::t9_max_output_buffer()
+{
+ if (VERBOSE) std::cout << "qa_gr_top_block::t9()\n";
+
+ gr_top_block_sptr tb = gr_make_top_block("top");
+
+ gr_block_sptr src = gr_make_null_source(sizeof(int));
+ gr_block_sptr head = gr_make_head(sizeof(int), 100000);
+ gr_block_sptr dst = gr_make_null_sink(sizeof(int));
+
+ head->set_max_output_buffer(1024);
+
+ // Start infinite flowgraph
+ tb->connect(src, 0, head, 0);
+ tb->connect(head, 0, dst, 0);
+ tb->start();
+ tb->wait();
+}
+
+void qa_gr_top_block::t10_reconfig_max_output_buffer()
+{
+ if (VERBOSE) std::cout << "qa_gr_top_block::t10()\n";
+
+ gr_top_block_sptr tb = gr_make_top_block("top");
+
+ gr_block_sptr src = gr_make_null_source(sizeof(int));
+ gr_block_sptr head = gr_make_head(sizeof(int), 100000);
+ gr_block_sptr dst = gr_make_null_sink(sizeof(int));
+
+ head->set_max_output_buffer(1000);
+
+ // Start infinite flowgraph
+ tb->connect(src, 0, dst, 0);
+ tb->start(201);
+
+ // Reconfigure with gr_head in the middle
+ tb->lock();
+ gr_block_sptr nop = gr_make_nop(sizeof(int));
+ nop->set_max_output_buffer(4000);
+ tb->disconnect(src, 0, dst, 0);
+ tb->connect(src, 0, head, 0);
+ tb->connect(head, 0, nop, 0);
+ tb->connect(nop, 0, dst, 0);
+ tb->unlock();
+
+ // Wait for flowgraph to end on its own
+ tb->wait();
+}
+
+void qa_gr_top_block::t11_set_block_affinity()
+{
+ gr_top_block_sptr tb = gr_make_top_block("top");
+ gr_block_sptr src (gr_make_null_source(sizeof(float)));
+ gr_block_sptr snk (gr_make_null_sink(sizeof(float)));
+
+ std::vector<int> set(1, 0), ret;
+ src->set_processor_affinity(set);
+
+ tb->connect(src, 0, snk, 0);
+ tb->start();
+ tb->stop();
+ tb->wait();
+
+ ret = src->processor_affinity();
+
+ // We only set the core affinity to 0 because we always know at
+ // least one thread core exists to use.
+ CPPUNIT_ASSERT_EQUAL(set[0], ret[0]);
+}
diff --git a/gnuradio-core/src/lib/runtime/qa_gr_top_block.h b/gnuradio-core/src/lib/runtime/qa_gr_top_block.h
new file mode 100644
index 000000000..634eeab1f
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/qa_gr_top_block.h
@@ -0,0 +1,66 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_QA_GR_TOP_BLOCK_H
+#define INCLUDED_QA_GR_TOP_BLOCK_H
+
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/TestCase.h>
+#include <stdexcept>
+
+class qa_gr_top_block : public CppUnit::TestCase
+{
+ CPPUNIT_TEST_SUITE(qa_gr_top_block);
+
+ CPPUNIT_TEST(t0);
+ CPPUNIT_TEST(t1_run);
+ CPPUNIT_TEST(t2_start_stop_wait);
+ CPPUNIT_TEST(t3_lock_unlock);
+ CPPUNIT_TEST(t4_reconfigure); // triggers 'join never returns' bug
+ CPPUNIT_TEST(t5_max_noutputs);
+ CPPUNIT_TEST(t6_reconfig_max_noutputs);
+ CPPUNIT_TEST(t7_max_noutputs_per_block);
+ CPPUNIT_TEST(t8_reconfig_max_noutputs_per_block);
+ CPPUNIT_TEST(t9_max_output_buffer);
+ CPPUNIT_TEST(t10_reconfig_max_output_buffer);
+ CPPUNIT_TEST(t11_set_block_affinity);
+
+ CPPUNIT_TEST_SUITE_END();
+
+private:
+
+ void t0();
+ void t1_run();
+ void t2_start_stop_wait();
+ void t3_lock_unlock();
+ void t4_reconfigure();
+ void t5_max_noutputs();
+ void t6_reconfig_max_noutputs();
+ void t7_max_noutputs_per_block();
+ void t8_reconfig_max_noutputs_per_block();
+ void t9_max_output_buffer();
+ void t10_reconfig_max_output_buffer();
+ void t11_set_block_affinity();
+
+};
+
+#endif /* INCLUDED_QA_GR_TOP_BLOCK_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
index 000000000..e3b36d882
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/qa_gr_vmcircbuf.cc
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <qa_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
index 000000000..3576660d5
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/qa_gr_vmcircbuf.h
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifndef _QA_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
index 000000000..9091d5c00
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/qa_runtime.cc
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2002,2007,2011 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+/*
+ * This class gathers together all the test cases for the 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_flowgraph.h>
+#include <qa_gr_top_block.h>
+#include <qa_gr_hier_block2.h>
+#include <qa_gr_hier_block2_derived.h>
+#include <qa_gr_buffer.h>
+#include <qa_block_tags.h>
+#include <qa_set_msg_handler.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_flowgraph::suite ());
+ s->addTest (qa_gr_top_block::suite ());
+ s->addTest (qa_gr_hier_block2::suite ());
+ s->addTest (qa_gr_hier_block2_derived::suite ());
+ s->addTest (qa_gr_buffer::suite ());
+ //s->addTest (qa_block_tags::suite ());
+ //s->addTest (qa_set_msg_handler::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
index 000000000..da71cbd0f
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/qa_runtime.h
@@ -0,0 +1,38 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef _QA_RUNTIME_H_
+#define _QA_RUNTIME_H_
+
+#include <gruel/attributes.h>
+#include <cppunit/TestSuite.h>
+
+//! collect all the tests for the runtime directory
+
+class __GR_ATTR_EXPORT 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/qa_set_msg_handler.cc b/gnuradio-core/src/lib/runtime/qa_set_msg_handler.cc
new file mode 100644
index 000000000..c84a219bd
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/qa_set_msg_handler.cc
@@ -0,0 +1,81 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007,2011 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <qa_set_msg_handler.h>
+#include <gr_top_block.h>
+#include <gr_head.h>
+#include <gr_null_source.h>
+#include <gr_null_sink.h>
+#include <gr_nop.h>
+#include <gruel/msg_passing.h>
+#include <iostream>
+#include <boost/thread/thread.hpp>
+
+
+#define VERBOSE 0
+
+using namespace pmt;
+
+/*
+ * The gr_nop block has been instrumented so that it counts
+ * the number of messages sent to it. We use this feature
+ * to confirm that gr_nop's call to set_msg_handler is working
+ * correctly.
+ */
+
+void qa_set_msg_handler::t0()
+{
+ static const int NMSGS = 10;
+
+ if (VERBOSE) std::cout << "qa_set_msg_handler::t0()\n";
+
+ gr_top_block_sptr tb = gr_make_top_block("top");
+
+ gr_block_sptr src = gr_make_null_source(sizeof(int));
+ gr_nop_sptr nop = gr_make_nop(sizeof(int));
+ gr_block_sptr dst = gr_make_null_sink(sizeof(int));
+
+ tb->connect(src, 0, nop, 0);
+ tb->connect(nop, 0, dst, 0);
+
+ // Must start graph before sending messages
+ tb->start();
+
+ // Send them...
+ pmt_t port(pmt_intern("port"));
+ for (int i = 0; i < NMSGS; i++){
+ send(nop, port, mp(mp("example-msg"), mp(i)));
+ }
+
+ // Give the messages a chance to be processed
+ boost::this_thread::sleep(boost::posix_time::milliseconds(100));
+
+ tb->stop();
+ tb->wait();
+
+ // Confirm that the nop block received the right number of messages.
+ CPPUNIT_ASSERT_EQUAL(NMSGS, nop->nmsgs_received());
+}
diff --git a/gnuradio-core/src/lib/runtime/qa_set_msg_handler.h b/gnuradio-core/src/lib/runtime/qa_set_msg_handler.h
new file mode 100644
index 000000000..60277a12c
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/qa_set_msg_handler.h
@@ -0,0 +1,43 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007,2011 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_QA_SET_MSG_HANDLER_H
+#define INCLUDED_QA_SET_MSG_HANDLER_H
+
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/TestCase.h>
+#include <stdexcept>
+
+class qa_set_msg_handler : public CppUnit::TestCase
+{
+ CPPUNIT_TEST_SUITE(qa_set_msg_handler);
+
+ CPPUNIT_TEST(t0);
+
+ CPPUNIT_TEST_SUITE_END();
+
+private:
+
+ void t0();
+};
+
+#endif /* INCLUDED_QA_SET_MSG_HANDLER_H */
diff --git a/gnuradio-core/src/lib/runtime/runtime.i b/gnuradio-core/src/lib/runtime/runtime.i
new file mode 100644
index 000000000..64c28c8e1
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/runtime.i
@@ -0,0 +1,123 @@
+/*
+ * Copyright 2012-2013 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#define GR_CORE_API
+
+//not here to fight you swig, reference() is ambigi with shared ptr, but whatevs
+%ignore gri_agc_cc::reference();
+%ignore gri_agc2_ff::reference();
+%ignore gri_agc2_cc::reference();
+
+//someone forgot about d_detail
+%ignore gr_block::d_setlock;
+
+//dont export work overloads
+%ignore general_work;
+%ignore work;
+%ignore forecast;
+
+%{
+
+#include <gras/block.hpp>
+#include <gras/hier_block.hpp>
+#include <gras/top_block.hpp>
+#include <gr_block.h>
+#include <gr_top_block.h>
+#include <gr_hier_block2.h>
+#include <gr_message.h>
+#include <gr_msg_handler.h>
+#include <gr_msg_queue.h>
+#include <gr_sync_block.h>
+#include <gr_sync_decimator.h>
+#include <gr_sync_interpolator.h>
+
+%}
+
+//const size types used by blocks in python
+%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 <gr_message.i>
+%include <gr_msg_handler.i>
+%include <gr_msg_queue.i>
+%include <gr_swig_block_magic.i>
+%include <gr_io_signature.i>
+
+#ifdef SW_RUNTIME
+
+%import <gras/block.i>
+%include <gr_block.h>
+%include <gr_hier_block2.h>
+%include <gr_top_block.h>
+%include <gr_sync_block.h>
+%include <gr_sync_decimator.h>
+%include <gr_sync_interpolator.h>
+
+#else
+
+//the bare minimum block inheritance interface to make things work but keep swig cxx file size down
+%include <gras/gras.hpp>
+%import <gras/element.i>
+namespace gras
+{
+ struct Block : gras::Element{};
+ struct HierBlock : gras::Element{};
+}
+struct gr_hier_block2 : gras::HierBlock{};
+struct gr_block : gras::Block
+{
+ gr_io_signature_sptr input_signature(void) const;
+ gr_io_signature_sptr output_signature(void) const;
+
+ unsigned history () const;
+
+ int output_multiple () const;
+ double relative_rate () const;
+
+ bool start();
+ bool stop();
+
+ uint64_t nitems_read(unsigned int which_input);
+ uint64_t nitems_written(unsigned int which_output);
+
+ // Methods to manage the block's max_noutput_items size.
+ int max_noutput_items();
+ void set_max_noutput_items(int m);
+ void unset_max_noutput_items();
+ bool is_set_max_noutput_items();
+
+ // Methods to manage block's min/max buffer sizes.
+ long max_output_buffer(int i);
+ void set_max_output_buffer(long max_output_buffer);
+ void set_max_output_buffer(int port, long max_output_buffer);
+ long min_output_buffer(int i);
+ void set_min_output_buffer(long min_output_buffer);
+ void set_min_output_buffer(int port, long min_output_buffer);
+};
+struct gr_sync_block : gr_block{};
+struct gr_sync_interpolator : gr_sync_block{};
+struct gr_sync_decimator : gr_sync_block{};
+
+#endif
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
index 000000000..bb4e86322
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/test_shared_block_ptr.cc
@@ -0,0 +1,53 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <gr_shared_block_sptr.h>
+#include <gr_vector_source_i.h>
+
+gr_block_sptr
+foo (gr_vector_source_i_sptr s)
+{
+ return gr_block_sptr (s);
+}
+
+typedef gr_shared_block_sptr<gr_vector_source_i> gr_vector_source_i_ptrX;
+//typedef boost::shared_ptr<gr_vector_source_i> gr_vector_source_i_ptrX;
+
+gr_vector_source_i_ptrX
+bar (gr_vector_source_i *s)
+{
+ return gr_vector_source_i_ptrX (s);
+}
+
+gr_block_sptr
+baz_1 (gr_vector_source_i_ptrX s)
+{
+ return gr_block_sptr (s);
+}
+
+#if 0
+gr_block_sptr
+baz_2 (gr_vector_source_i_ptrX s)
+{
+ return s.block_sptr ();
+}
+#endif
diff --git a/gnuradio-core/src/lib/swig/CMakeLists.txt b/gnuradio-core/src/lib/swig/CMakeLists.txt
new file mode 100644
index 000000000..d8a64cc0f
--- /dev/null
+++ b/gnuradio-core/src/lib/swig/CMakeLists.txt
@@ -0,0 +1,88 @@
+# Copyright 2010-2011 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+
+########################################################################
+include(GrPython)
+include(GrSwig)
+
+set(GR_SWIG_INCLUDE_DIRS
+ ${CMAKE_CURRENT_BINARY_DIR}
+ ${GNURADIO_CORE_SWIG_INCLUDE_DIRS}
+ ${GRUEL_INCLUDE_DIRS}
+ ${Boost_INCLUDE_DIRS}
+)
+set(GR_SWIG_LIBRARIES gnuradio-core)
+
+link_directories(${Boost_LIBRARY_DIRS})
+
+########################################################################
+# Build and install the swig targets
+########################################################################
+# ----------------------------------------------------------------
+# We've split the previously monstrous gnuradio_corethon into 6
+# smaller pieces. This reduces compile time coupling and creates
+# smaller pieces for the compiler to digest. prior to this change, on
+# X86_64, g++'s resident set size was 650MB!
+# ----------------------------------------------------------------
+
+set(GR_SWIG_TARGET_DEPS general_generated gengen_generated filter_generated pmt_swig)
+
+foreach(what runtime general gengen filter io hier)
+ SET(GR_SWIG_DOC_FILE ${CMAKE_CURRENT_BINARY_DIR}/${what}_swig_doc.i)
+ SET(GR_SWIG_DOC_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/../${what} ${CMAKE_CURRENT_BINARY_DIR}/../${what})
+ GR_SWIG_MAKE(gnuradio_core_${what} gnuradio_core_${what}.i)
+ GR_SWIG_INSTALL(
+ TARGETS gnuradio_core_${what}
+ DESTINATION ${GR_PYTHON_DIR}/gnuradio/gr
+ COMPONENT "core_python"
+ )
+ install(
+ FILES
+ gnuradio_core_${what}.i
+ ${CMAKE_CURRENT_BINARY_DIR}/${what}_swig_doc.i
+ DESTINATION ${GR_INCLUDE_DIR}/gnuradio/swig
+ COMPONENT "core_swig"
+ )
+ list(APPEND core_swig_deps ${SWIG_MODULE_gnuradio_core_${what}_REAL_NAME})
+endforeach(what)
+
+add_custom_target(core_swig DEPENDS ${core_swig_deps})
+
+########################################################################
+# Install various files
+########################################################################
+install(FILES
+ gnuradio.i
+ gr_swig_block_magic.i
+ gr_shared_ptr.i
+ DESTINATION ${GR_INCLUDE_DIR}/gnuradio/swig
+ COMPONENT "core_swig"
+)
+
+GR_PYTHON_INSTALL(
+ FILES gnuradio_core.py
+ DESTINATION ${GR_PYTHON_DIR}/gnuradio/gr
+ COMPONENT "core_python"
+)
+
+install(
+ FILES ${CMAKE_CURRENT_SOURCE_DIR}/gnuradio_swig_bug_workaround.h
+ DESTINATION ${GR_INCLUDE_DIR}/gnuradio
+ COMPONENT "core_swig"
+)
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
index 000000000..5e9f82e7d
--- /dev/null
+++ b/gnuradio-core/src/lib/swig/gen-swig-bug-fix
@@ -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 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+import sys
+import 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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_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
index 000000000..bf23bbbb2
--- /dev/null
+++ b/gnuradio-core/src/lib/swig/gnuradio.i
@@ -0,0 +1,91 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003,2004,2009 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+%pythoncode %{
+import gras
+%}
+
+// Disable warning about base class types
+#pragma SWIG nowarn=401
+
+////////////////////////////////////////////////////////////////////////
+// gnuradio.i
+// SWIG interface definition
+////////////////////////////////////////////////////////////////////////
+
+%include <gruel_common.i>
+
+////////////////////////////////////////////////////////////////////////
+// Headers
+
+%{
+#include "gnuradio_swig_bug_workaround.h" // mandatory bug fix
+#include <gr_types.h>
+#include <stddef.h> // size_t
+#include <complex>
+%}
+
+%feature("autodoc","1");
+
+// local file
+%include <gr_shared_ptr.i>
+%include <gr_types.h>
+%include <std_complex.i>
+%include <std_vector.i>
+%include <stl.i>
+%include <std_except.i>
+
+typedef std::complex<float> gr_complex;
+typedef std::complex<double> gr_complexd;
+typedef unsigned long long uint64_t;
+typedef long long int64_t;
+
+
+// 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() std::complex<float>;
+
+ %template() vector< std::complex<float> >;
+ %template() vector< std::vector< unsigned char > >;
+ %template() vector< std::vector< char > >;
+ %template() vector< std::vector< short > >;
+ %template() vector< std::vector< int > >;
+ %template() vector< std::vector< float > >;
+ %template() vector< std::vector< double > >;
+ %template() vector< std::vector< std::complex<float> > >;
+};
+
+////////////////////////////////////////////////////////////////////////
+
+#ifndef SW_RUNTIME
+// import runtime.i for all but sw_runtime, since it needs to %include
+%import <runtime.i>
+#endif
+
+////////////////////////////////////////////////////////////////////////
diff --git a/gnuradio-core/src/lib/swig/gnuradio_core.py b/gnuradio-core/src/lib/swig/gnuradio_core.py
new file mode 100644
index 000000000..23de74077
--- /dev/null
+++ b/gnuradio-core/src/lib/swig/gnuradio_core.py
@@ -0,0 +1,28 @@
+#
+# Copyright 2006,2009,2010 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+
+# This file implements the old gnuradio_core namespace
+
+from gnuradio_core_runtime import *
+from gnuradio_core_general import *
+from gnuradio_core_gengen import *
+from gnuradio_core_filter import *
+from gnuradio_core_io import *
+from gnuradio_core_hier import *
diff --git a/gnuradio-core/src/lib/swig/gnuradio_core_filter.i b/gnuradio-core/src/lib/swig/gnuradio_core_filter.i
new file mode 100644
index 000000000..e9a44e54b
--- /dev/null
+++ b/gnuradio-core/src/lib/swig/gnuradio_core_filter.i
@@ -0,0 +1,32 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006,2009,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+%include "filter_swig_doc.i"
+
+#ifndef SWIGIMPORTED
+%module(directors="1") gnuradio_core_filter
+#endif
+
+ //%feature("autodoc", "1"); // generate python docstrings
+
+%include "gnuradio.i" // the common stuff
+
+%include "filter.i"
diff --git a/gnuradio-core/src/lib/swig/gnuradio_core_general.i b/gnuradio-core/src/lib/swig/gnuradio_core_general.i
new file mode 100644
index 000000000..33f97815e
--- /dev/null
+++ b/gnuradio-core/src/lib/swig/gnuradio_core_general.i
@@ -0,0 +1,54 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006,2009,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+%include "general_swig_doc.i"
+
+#define GR_CORE_API
+
+#ifndef SWIGIMPORTED
+%module(directors="1") gnuradio_core_general
+#endif
+
+ //%feature("autodoc", "1"); // generate python docstrings
+
+%include "gnuradio.i" // the common stuff
+
+%include "general.i"
+
+ // Simple test case for complex input and output
+%inline
+%{
+ std::complex<float> complexf_add_2j(std::complex<float> x)
+ {
+ return std::complex<float>(x.real(), x.imag() + 2);
+ }
+
+ std::complex<double> complexd_add_2j(std::complex<double> x)
+ {
+ return std::complex<double>(x.real(), x.imag() + 2);
+ }
+
+ std::complex<float> complexf_add_x_2j(float x, std::complex<float> y)
+ {
+ return std::complex<float>(x + y.real(), y.imag() + 2);
+ }
+
+%}
diff --git a/gnuradio-core/src/lib/swig/gnuradio_core_gengen.i b/gnuradio-core/src/lib/swig/gnuradio_core_gengen.i
new file mode 100644
index 000000000..b90a5bab3
--- /dev/null
+++ b/gnuradio-core/src/lib/swig/gnuradio_core_gengen.i
@@ -0,0 +1,32 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006,2009,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+%include "gengen_swig_doc.i"
+
+#ifndef SWIGIMPORTED
+%module(directors="1") gnuradio_core_gengen
+#endif
+
+ //%feature("autodoc", "1"); // generate python docstrings
+
+%include "gnuradio.i" // the common stuff
+
+%include "gengen.i"
diff --git a/gnuradio-core/src/lib/swig/gnuradio_core_hier.i b/gnuradio-core/src/lib/swig/gnuradio_core_hier.i
new file mode 100644
index 000000000..141d9b163
--- /dev/null
+++ b/gnuradio-core/src/lib/swig/gnuradio_core_hier.i
@@ -0,0 +1,32 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2009,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+%include "hier_swig_doc.i"
+
+#ifndef SWIGIMPORTED
+%module(directors="1") gnuradio_hier_hier
+#endif
+
+ //%feature("autodoc", "1"); // generate python docstrings
+
+%include "gnuradio.i" // the common stuff
+
+%include "hier.i"
diff --git a/gnuradio-core/src/lib/swig/gnuradio_core_io.i b/gnuradio-core/src/lib/swig/gnuradio_core_io.i
new file mode 100644
index 000000000..522b12b34
--- /dev/null
+++ b/gnuradio-core/src/lib/swig/gnuradio_core_io.i
@@ -0,0 +1,32 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006,2009,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+%include "io_swig_doc.i"
+
+#ifndef SWIGIMPORTED
+%module(directors="1") gnuradio_core_io
+#endif
+
+ //%feature("autodoc", "1"); // generate python docstrings
+
+%include "gnuradio.i" // the common stuff
+
+%include "io.i"
diff --git a/gnuradio-core/src/lib/swig/gnuradio_core_runtime.i b/gnuradio-core/src/lib/swig/gnuradio_core_runtime.i
new file mode 100644
index 000000000..fb311d226
--- /dev/null
+++ b/gnuradio-core/src/lib/swig/gnuradio_core_runtime.i
@@ -0,0 +1,34 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2009,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+%include "runtime_swig_doc.i"
+
+#ifndef SWIGIMPORTED
+%module(directors="1") gnuradio_core_runtime
+#endif
+
+ //%feature("autodoc", "1"); // generate python docstrings
+
+#define SW_RUNTIME
+%include "gnuradio.i" // the common stuff
+
+%include "runtime.i"
diff --git a/gnuradio-core/src/lib/swig/gnuradio_swig_bug_workaround.h b/gnuradio-core/src/lib/swig/gnuradio_swig_bug_workaround.h
new file mode 100644
index 000000000..1994f0660
--- /dev/null
+++ b/gnuradio-core/src/lib/swig/gnuradio_swig_bug_workaround.h
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_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"
+ */
+
+class gr_base_error_handler;
+class gr_basic_block;
+class gr_block;
+class gr_error_handler;
+class gr_file_error_handler;
+class gr_hier_block2;
+class gr_msg_handler;
+class gr_msg_queue;
+class gr_sync_block;
+class gr_sync_decimator;
+class gr_sync_interpolator;
+class gr_top_block;
+
+#endif /* INCLUDED_GNURADIO_SWIG_BUG_WORKAROUND_H */
diff --git a/gnuradio-core/src/lib/swig/gr_shared_ptr.i b/gnuradio-core/src/lib/swig/gr_shared_ptr.i
new file mode 100644
index 000000000..323d33ad7
--- /dev/null
+++ b/gnuradio-core/src/lib/swig/gr_shared_ptr.i
@@ -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/lib/swig/gr_swig_block_magic.i b/gnuradio-core/src/lib/swig/gr_swig_block_magic.i
new file mode 100644
index 000000000..4016ae772
--- /dev/null
+++ b/gnuradio-core/src/lib/swig/gr_swig_block_magic.i
@@ -0,0 +1,50 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2010,2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+%define GR_SWIG_BLOCK_MAGIC(PKG, BASE_NAME)
+_GR_SWIG_BLOCK_MAGIC_HELPER(PKG, BASE_NAME, PKG ## _ ## BASE_NAME)
+%enddef
+
+%define _GR_SWIG_BLOCK_MAGIC_HELPER_COMMON(PKG, BASE_NAME, FULL_NAME)
+class FULL_NAME;
+typedef boost::shared_ptr<FULL_NAME> FULL_NAME ## _sptr;
+%template(FULL_NAME ## _sptr) boost::shared_ptr<FULL_NAME>;
+%rename(BASE_NAME) PKG ## _make_ ## BASE_NAME;
+%ignore FULL_NAME;
+%enddef
+
+#ifdef SWIGPYTHON
+%define _GR_SWIG_BLOCK_MAGIC_HELPER(PKG, BASE_NAME, FULL_NAME)
+_GR_SWIG_BLOCK_MAGIC_HELPER_COMMON(PKG, BASE_NAME, FULL_NAME)
+%pythoncode %{
+FULL_NAME ## _sptr.__repr__ = lambda self: "<gr_block %s (%d)>" % (self.name(), self.unique_id ())
+%}
+%enddef
+#endif
+
+%define GR_SWIG_BLOCK_MAGIC2(PKG, BASE_NAME)
+%template(BASE_NAME ## _sptr) boost::shared_ptr<gr:: ## PKG ## :: ## BASE_NAME>;
+%pythoncode %{
+BASE_NAME ## _sptr.__repr__ = lambda self: "<gr_block %s (%d)>" % (self.name(), self.unique_id())
+BASE_NAME = BASE_NAME.make;
+%}
+%enddef
diff --git a/gnuradio-core/src/lib/viterbi/CMakeLists.txt b/gnuradio-core/src/lib/viterbi/CMakeLists.txt
new file mode 100644
index 000000000..add5c77e8
--- /dev/null
+++ b/gnuradio-core/src/lib/viterbi/CMakeLists.txt
@@ -0,0 +1,63 @@
+# Copyright 2010-2011 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+
+########################################################################
+# This file included, use CMake directory variables
+########################################################################
+
+set(viterbi_sources
+ ${CMAKE_CURRENT_SOURCE_DIR}/metrics.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/tab.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/viterbi.c
+)
+
+########################################################################
+# define missing erf function with C linkage (hack for metrics.c)
+########################################################################
+if(MSVC)
+file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/boost_math_erf.cc "
+#include <boost/math/special_functions/erf.hpp>
+extern \"C\" double erf(double x){
+ return boost::math::erf(x);
+}
+")
+list(APPEND viterbi_sources ${CMAKE_CURRENT_BINARY_DIR}/boost_math_erf.cc)
+endif(MSVC)
+
+########################################################################
+# Append gnuradio-core library sources
+########################################################################
+list(APPEND gnuradio_core_sources ${viterbi_sources})
+
+########################################################################
+# Install runtime headers
+########################################################################
+install(
+ FILES ${CMAKE_CURRENT_SOURCE_DIR}/viterbi.h
+ DESTINATION ${GR_INCLUDE_DIR}/gnuradio
+ COMPONENT "core_devel"
+)
+
+########################################################################
+# Create some text executables (not registered tests)
+# Its not much to build so the sources are just re-listed,
+# rather than create a new library just for these two apps.
+########################################################################
+#ADD_EXECUTABLE(viterbi_encode ${CMAKE_CURRENT_SOURCE_DIR}/encode.cc ${viterbi_sources})
+#ADD_EXECUTABLE(viterbi_decode ${CMAKE_CURRENT_SOURCE_DIR}/decode.cc ${viterbi_sources})
diff --git a/gnuradio-core/src/lib/viterbi/decode.cc b/gnuradio-core/src/lib/viterbi/decode.cc
new file mode 100644
index 000000000..368e69713
--- /dev/null
+++ b/gnuradio-core/src/lib/viterbi/decode.cc
@@ -0,0 +1,88 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+/*
+ * This is a minimal example demonstrating how to call the Viterbi decoder
+ * in continuous streaming mode. It accepts data on stdin and writes to
+ * stdout.
+ *
+ */
+
+extern "C" {
+#include "viterbi.h"
+}
+
+#include <cstdio>
+#include <cmath>
+
+#define MAXCHUNKSIZE 4096
+#define MAXENCSIZE MAXCHUNKSIZE*16
+
+int main()
+{
+ unsigned char data[MAXCHUNKSIZE];
+ signed char syms[MAXENCSIZE];
+ int count = 0;
+
+ // Initialize metric table
+ int mettab[2][256];
+ int amp = 100;
+ float RATE=0.5;
+ float ebn0 = 12.0;
+ float esn0 = RATE*pow(10.0, ebn0/10);
+ gen_met(mettab, amp, esn0, 0.0, 4);
+
+ // Initialize decoder state
+ struct viterbi_state state0[64];
+ struct viterbi_state state1[64];
+ unsigned char viterbi_in[16];
+ viterbi_chunks_init(state0);
+
+ while (!feof(stdin)) {
+ unsigned int n = fread(syms, 1, MAXENCSIZE, stdin);
+ unsigned char *out = data;
+
+ for (unsigned int i = 0; i < n; i++) {
+
+ // FIXME: This implements hard decoding by slicing the input stream
+ unsigned char sym = syms[i] > 0 ? -amp : amp;
+
+ // Write the symbol to the decoder input
+ viterbi_in[count % 4] = sym;
+
+ // Every four symbols, perform the butterfly2 operation
+ if ((count % 4) == 3) {
+ viterbi_butterfly2(viterbi_in, mettab, state0, state1);
+
+ // Every sixteen symbols, perform the readback operation
+ if ((count > 64) && (count % 16) == 11) {
+ viterbi_get_output(state0, out);
+ fwrite(out++, 1, 1, stdout);
+ }
+ }
+
+ count++;
+ }
+ }
+
+ return 0;
+}
diff --git a/gnuradio-core/src/lib/viterbi/encode.cc b/gnuradio-core/src/lib/viterbi/encode.cc
new file mode 100644
index 000000000..83a85fcac
--- /dev/null
+++ b/gnuradio-core/src/lib/viterbi/encode.cc
@@ -0,0 +1,54 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+/*
+ * This is a minimal example demonstrating how to call the ECC encoder
+ * in continuous streaming mode. It accepts data on stdin and writes to
+ * stdout.
+ *
+ * FIXME: This does not flush the final bits out of the encoder.
+ *
+ */
+
+extern "C" {
+#include "viterbi.h"
+}
+
+#include <cstdio>
+
+#define MAXCHUNKSIZE 4096
+#define MAXENCSIZE MAXCHUNKSIZE*16
+
+int main()
+{
+ unsigned char encoder_state = 0;
+ unsigned char data[MAXCHUNKSIZE];
+ unsigned char syms[MAXENCSIZE];
+
+ while (!feof(stdin)) {
+ unsigned int n = fread(data, 1, MAXCHUNKSIZE, stdin);
+ encoder_state = encode(syms, data, n, encoder_state);
+ fwrite(syms, 1, n*16, stdout);
+ }
+
+ return 0;
+}
diff --git a/gnuradio-core/src/lib/viterbi/metrics.c b/gnuradio-core/src/lib/viterbi/metrics.c
new file mode 100644
index 000000000..0d91c301f
--- /dev/null
+++ b/gnuradio-core/src/lib/viterbi/metrics.c
@@ -0,0 +1,126 @@
+/*
+ * Copyright 1995 Phil Karn, KA9Q
+ * Copyright 2008 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+/*
+ * Generate metric tables for a soft-decision convolutional decoder
+ * assuming gaussian noise on a PSK channel.
+ *
+ * Works from "first principles" by evaluating the normal probability
+ * function and then computing the log-likelihood function
+ * for every possible received symbol value
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+/* Symbols are offset-binary, with 128 corresponding to an erased (no
+ * information) symbol
+ */
+#define OFFSET 128
+
+#include <stdlib.h>
+#include <math.h>
+
+//declare erf in case it was missing in math.h and provided for by the build system
+extern double erf(double x);
+
+/* Normal function integrated from -Inf to x. Range: 0-1 */
+#define normal(x) (0.5 + 0.5*erf((x)/M_SQRT2))
+
+/* Logarithm base 2 */
+#define gr_log2(x) (log(x)*M_LOG2E)
+
+/* Generate log-likelihood metrics for 8-bit soft quantized channel
+ * assuming AWGN and BPSK
+ */
+void
+gen_met(int mettab[2][256], /* Metric table, [sent sym][rx symbol] */
+ int amp, /* Signal amplitude, units */
+ double esn0, /* Es/N0 ratio in dB */
+ double bias, /* Metric bias; 0 for viterbi, rate for sequential */
+ int scale) /* Scale factor */
+{
+ double noise;
+ int s,bit;
+ double metrics[2][256];
+ double p0,p1;
+
+ /* Es/N0 as power ratio */
+ esn0 = pow(10.,esn0/10);
+
+ noise = 0.5/esn0; /* only half the noise for BPSK */
+ noise = sqrt(noise); /* noise/signal Voltage ratio */
+
+ /* Zero is a special value, since this sample includes all
+ * lower samples that were clipped to this value, i.e., it
+ * takes the whole lower tail of the curve
+ */
+ p1 = normal(((0-OFFSET+0.5)/amp - 1)/noise); /* P(s|1) */
+
+ /* Prob of this value occurring for a 0-bit */ /* P(s|0) */
+ p0 = normal(((0-OFFSET+0.5)/amp + 1)/noise);
+ metrics[0][0] = gr_log2(2*p0/(p1+p0)) - bias;
+ metrics[1][0] = gr_log2(2*p1/(p1+p0)) - bias;
+
+ for(s=1;s<255;s++){
+ /* P(s|1), prob of receiving s given 1 transmitted */
+ p1 = normal(((s-OFFSET+0.5)/amp - 1)/noise) -
+ normal(((s-OFFSET-0.5)/amp - 1)/noise);
+
+ /* P(s|0), prob of receiving s given 0 transmitted */
+ p0 = normal(((s-OFFSET+0.5)/amp + 1)/noise) -
+ normal(((s-OFFSET-0.5)/amp + 1)/noise);
+
+#ifdef notdef
+ printf("P(%d|1) = %lg, P(%d|0) = %lg\n",s,p1,s,p0);
+#endif
+ metrics[0][s] = gr_log2(2*p0/(p1+p0)) - bias;
+ metrics[1][s] = gr_log2(2*p1/(p1+p0)) - bias;
+ }
+ /* 255 is also a special value */
+ /* P(s|1) */
+ p1 = 1 - normal(((255-OFFSET-0.5)/amp - 1)/noise);
+ /* P(s|0) */
+ p0 = 1 - normal(((255-OFFSET-0.5)/amp + 1)/noise);
+
+ metrics[0][255] = gr_log2(2*p0/(p1+p0)) - bias;
+ metrics[1][255] = gr_log2(2*p1/(p1+p0)) - bias;
+#ifdef notdef
+ /* The probability of a raw symbol error is the probability
+ * that a 1-bit would be received as a sample with value
+ * 0-128. This is the offset normal curve integrated from -Inf to 0.
+ */
+ printf("symbol Pe = %lg\n",normal(-1/noise));
+#endif
+ for(bit=0;bit<2;bit++){
+ for(s=0;s<256;s++){
+ /* Scale and round to nearest integer */
+ mettab[bit][s] = floor(metrics[bit][s] * scale + 0.5);
+#ifdef notdef
+ printf("metrics[%d][%d] = %lg, mettab = %d\n",
+ bit,s,metrics[bit][s],mettab[bit][s]);
+#endif
+ }
+ }
+}
diff --git a/gnuradio-core/src/lib/viterbi/tab.c b/gnuradio-core/src/lib/viterbi/tab.c
new file mode 100644
index 000000000..1c135acfe
--- /dev/null
+++ b/gnuradio-core/src/lib/viterbi/tab.c
@@ -0,0 +1,57 @@
+/*
+ * Copyright 1995 Phil Karn, KA9Q
+ * Copyright 2008 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+/* 8-bit parity lookup table, generated by partab.c */
+unsigned char Partab[] = {
+ 0, 1, 1, 0, 1, 0, 0, 1,
+ 1, 0, 0, 1, 0, 1, 1, 0,
+ 1, 0, 0, 1, 0, 1, 1, 0,
+ 0, 1, 1, 0, 1, 0, 0, 1,
+ 1, 0, 0, 1, 0, 1, 1, 0,
+ 0, 1, 1, 0, 1, 0, 0, 1,
+ 0, 1, 1, 0, 1, 0, 0, 1,
+ 1, 0, 0, 1, 0, 1, 1, 0,
+ 1, 0, 0, 1, 0, 1, 1, 0,
+ 0, 1, 1, 0, 1, 0, 0, 1,
+ 0, 1, 1, 0, 1, 0, 0, 1,
+ 1, 0, 0, 1, 0, 1, 1, 0,
+ 0, 1, 1, 0, 1, 0, 0, 1,
+ 1, 0, 0, 1, 0, 1, 1, 0,
+ 1, 0, 0, 1, 0, 1, 1, 0,
+ 0, 1, 1, 0, 1, 0, 0, 1,
+ 1, 0, 0, 1, 0, 1, 1, 0,
+ 0, 1, 1, 0, 1, 0, 0, 1,
+ 0, 1, 1, 0, 1, 0, 0, 1,
+ 1, 0, 0, 1, 0, 1, 1, 0,
+ 0, 1, 1, 0, 1, 0, 0, 1,
+ 1, 0, 0, 1, 0, 1, 1, 0,
+ 1, 0, 0, 1, 0, 1, 1, 0,
+ 0, 1, 1, 0, 1, 0, 0, 1,
+ 0, 1, 1, 0, 1, 0, 0, 1,
+ 1, 0, 0, 1, 0, 1, 1, 0,
+ 1, 0, 0, 1, 0, 1, 1, 0,
+ 0, 1, 1, 0, 1, 0, 0, 1,
+ 1, 0, 0, 1, 0, 1, 1, 0,
+ 0, 1, 1, 0, 1, 0, 0, 1,
+ 0, 1, 1, 0, 1, 0, 0, 1,
+ 1, 0, 0, 1, 0, 1, 1, 0,
+};
diff --git a/gnuradio-core/src/lib/viterbi/viterbi.c b/gnuradio-core/src/lib/viterbi/viterbi.c
new file mode 100644
index 000000000..fc8886603
--- /dev/null
+++ b/gnuradio-core/src/lib/viterbi/viterbi.c
@@ -0,0 +1,355 @@
+/*
+ * Copyright 1995 Phil Karn, KA9Q
+ * Copyright 2008 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+/*
+ * Viterbi decoder for K=7 rate=1/2 convolutional code
+ * Some modifications from original Karn code by Matt Ettus
+ */
+
+#include "viterbi.h"
+
+/* The two generator polynomials for the NASA Standard K=7 code.
+ * Since these polynomials are known to be optimal for this constraint
+ * length there is not much point in changing them. But if you do, you
+ * will have to regenerate the BUTTERFLY macro calls in viterbi()
+ */
+#define POLYA 0x6d
+#define POLYB 0x4f
+
+/* The basic Viterbi decoder operation, called a "butterfly"
+ * operation because of the way it looks on a trellis diagram. Each
+ * butterfly involves an Add-Compare-Select (ACS) operation on the two nodes
+ * where the 0 and 1 paths from the current node merge at the next step of
+ * the trellis.
+ *
+ * The code polynomials are assumed to have 1's on both ends. Given a
+ * function encode_state() that returns the two symbols for a given
+ * encoder state in the low two bits, such a code will have the following
+ * identities for even 'n' < 64:
+ *
+ * encode_state(n) = encode_state(n+65)
+ * encode_state(n+1) = encode_state(n+64) = (3 ^ encode_state(n))
+ *
+ * Any convolutional code you would actually want to use will have
+ * these properties, so these assumptions aren't too limiting.
+ *
+ * Doing this as a macro lets the compiler evaluate at compile time the
+ * many expressions that depend on the loop index and encoder state and
+ * emit them as immediate arguments.
+ * This makes an enormous difference on register-starved machines such
+ * as the Intel x86 family where evaluating these expressions at runtime
+ * would spill over into memory.
+ */
+#define BUTTERFLY(i,sym) { \
+ int m0,m1;\
+\
+ /* ACS for 0 branch */\
+ m0 = state[i].metric + mets[sym]; /* 2*i */\
+ m1 = state[i+32].metric + mets[3^sym]; /* 2*i + 64 */\
+ if(m0 > m1){\
+ next[2*i].metric = m0;\
+ next[2*i].path = state[i].path << 1;\
+ } else {\
+ next[2*i].metric = m1;\
+ next[2*i].path = (state[i+32].path << 1)|1;\
+ }\
+ /* ACS for 1 branch */\
+ m0 = state[i].metric + mets[3^sym]; /* 2*i + 1 */\
+ m1 = state[i+32].metric + mets[sym]; /* 2*i + 65 */\
+ if(m0 > m1){\
+ next[2*i+1].metric = m0;\
+ next[2*i+1].path = state[i].path << 1;\
+ } else {\
+ next[2*i+1].metric = m1;\
+ next[2*i+1].path = (state[i+32].path << 1)|1;\
+ }\
+}
+
+extern unsigned char Partab[]; /* Parity lookup table */
+
+/* Convolutionally encode data into binary symbols */
+unsigned char
+encode(unsigned char *symbols,
+ unsigned char *data,
+ unsigned int nbytes,
+ unsigned char encstate)
+{
+ int i;
+
+ while(nbytes-- != 0){
+ for(i=7;i>=0;i--){
+ encstate = (encstate << 1) | ((*data >> i) & 1);
+ *symbols++ = Partab[encstate & POLYA];
+ *symbols++ = Partab[encstate & POLYB];
+ }
+ data++;
+ }
+
+ return encstate;
+}
+
+/* Viterbi decoder */
+int
+viterbi(unsigned long *metric, /* Final path metric (returned value) */
+ unsigned char *data, /* Decoded output data */
+ unsigned char *symbols, /* Raw deinterleaved input symbols */
+ unsigned int nbits, /* Number of output bits */
+ int mettab[2][256] /* Metric table, [sent sym][rx symbol] */
+ ){
+ unsigned int bitcnt = 0;
+ int mets[4];
+ long bestmetric;
+ int beststate,i;
+ struct viterbi_state state0[64],state1[64],*state,*next;
+
+ state = state0;
+ next = state1;
+
+ /* Initialize starting metrics to prefer 0 state */
+ state[0].metric = 0;
+ for(i=1;i<64;i++)
+ state[i].metric = -999999;
+ state[0].path = 0;
+
+ for(bitcnt = 0;bitcnt < nbits;bitcnt++){
+ /* Read input symbol pair and compute all possible branch
+ * metrics
+ */
+ mets[0] = mettab[0][symbols[0]] + mettab[0][symbols[1]];
+ mets[1] = mettab[0][symbols[0]] + mettab[1][symbols[1]];
+ mets[2] = mettab[1][symbols[0]] + mettab[0][symbols[1]];
+ mets[3] = mettab[1][symbols[0]] + mettab[1][symbols[1]];
+ symbols += 2;
+
+ /* These macro calls were generated by genbut.c */
+ BUTTERFLY(0,0);
+ BUTTERFLY(1,1);
+ BUTTERFLY(2,3);
+ BUTTERFLY(3,2);
+ BUTTERFLY(4,3);
+ BUTTERFLY(5,2);
+ BUTTERFLY(6,0);
+ BUTTERFLY(7,1);
+ BUTTERFLY(8,0);
+ BUTTERFLY(9,1);
+ BUTTERFLY(10,3);
+ BUTTERFLY(11,2);
+ BUTTERFLY(12,3);
+ BUTTERFLY(13,2);
+ BUTTERFLY(14,0);
+ BUTTERFLY(15,1);
+ BUTTERFLY(16,2);
+ BUTTERFLY(17,3);
+ BUTTERFLY(18,1);
+ BUTTERFLY(19,0);
+ BUTTERFLY(20,1);
+ BUTTERFLY(21,0);
+ BUTTERFLY(22,2);
+ BUTTERFLY(23,3);
+ BUTTERFLY(24,2);
+ BUTTERFLY(25,3);
+ BUTTERFLY(26,1);
+ BUTTERFLY(27,0);
+ BUTTERFLY(28,1);
+ BUTTERFLY(29,0);
+ BUTTERFLY(30,2);
+ BUTTERFLY(31,3);
+
+ /* Swap current and next states */
+ if(bitcnt & 1){
+ state = state0;
+ next = state1;
+ } else {
+ state = state1;
+ next = state0;
+ }
+ // ETTUS
+ //if(bitcnt > nbits-7){
+ /* In tail, poison non-zero nodes */
+ //for(i=1;i<64;i += 2)
+ // state[i].metric = -9999999;
+ //}
+ /* Produce output every 8 bits once path memory is full */
+ if((bitcnt % 8) == 5 && bitcnt > 32){
+ /* Find current best path */
+ bestmetric = state[0].metric;
+ beststate = 0;
+ for(i=1;i<64;i++){
+ if(state[i].metric > bestmetric){
+ bestmetric = state[i].metric;
+ beststate = i;
+ }
+ }
+#ifdef notdef
+ printf("metrics[%d] = %d state = %lx\n",beststate,
+ state[beststate].metric,state[beststate].path);
+#endif
+ *data++ = state[beststate].path >> 24;
+ }
+
+ }
+ /* Output remaining bits from 0 state */
+ // ETTUS Find best state instead
+ bestmetric = state[0].metric;
+ beststate = 0;
+ for(i=1;i<64;i++){
+ if(state[i].metric > bestmetric){
+ bestmetric = state[i].metric;
+ beststate = i;
+ }
+ }
+ if((i = bitcnt % 8) != 6)
+ state[beststate].path <<= 6-i;
+
+ *data++ = state[beststate].path >> 24;
+ *data++ = state[beststate].path >> 16;
+ *data++ = state[beststate].path >> 8;
+ *data = state[beststate].path;
+ //printf ("BS = %d\tBSM = %d\tM0 = %d\n",beststate,state[beststate].metric,state[0].metric);
+ *metric = state[beststate].metric;
+ return 0;
+}
+
+
+void
+viterbi_chunks_init(struct viterbi_state* state) {
+ // Initialize starting metrics to prefer 0 state
+ int i;
+ state[0].metric = 0;
+ state[0].path = 0;
+ for(i=1;i<64;i++)
+ state[i].metric = -999999;
+}
+
+void
+viterbi_butterfly8(unsigned char *symbols, int mettab[2][256], struct viterbi_state *state0, struct viterbi_state *state1)
+{
+ unsigned int bitcnt;
+ int mets[4];
+
+ struct viterbi_state *state, *next;
+ state = state0;
+ next = state1;
+ // Operate on 16 symbols (8 bits) at a time
+ for(bitcnt = 0;bitcnt < 8;bitcnt++){
+ // Read input symbol pair and compute all possible branch metrics
+ mets[0] = mettab[0][symbols[0]] + mettab[0][symbols[1]];
+ mets[1] = mettab[0][symbols[0]] + mettab[1][symbols[1]];
+ mets[2] = mettab[1][symbols[0]] + mettab[0][symbols[1]];
+ mets[3] = mettab[1][symbols[0]] + mettab[1][symbols[1]];
+ symbols += 2;
+
+ // These macro calls were generated by genbut.c
+ BUTTERFLY(0,0);BUTTERFLY(1,1);BUTTERFLY(2,3);BUTTERFLY(3,2);
+ BUTTERFLY(4,3);BUTTERFLY(5,2);BUTTERFLY(6,0);BUTTERFLY(7,1);
+ BUTTERFLY(8,0);BUTTERFLY(9,1);BUTTERFLY(10,3);BUTTERFLY(11,2);
+ BUTTERFLY(12,3);BUTTERFLY(13,2);BUTTERFLY(14,0);BUTTERFLY(15,1);
+ BUTTERFLY(16,2);BUTTERFLY(17,3);BUTTERFLY(18,1);BUTTERFLY(19,0);
+ BUTTERFLY(20,1);BUTTERFLY(21,0);BUTTERFLY(22,2);BUTTERFLY(23,3);
+ BUTTERFLY(24,2);BUTTERFLY(25,3);BUTTERFLY(26,1);BUTTERFLY(27,0);
+ BUTTERFLY(28,1);BUTTERFLY(29,0);BUTTERFLY(30,2);BUTTERFLY(31,3);
+
+ // Swap current and next states
+ if(bitcnt & 1){
+ state = state0;
+ next = state1;
+ } else {
+ state = state1;
+ next = state0;
+ }
+ }
+}
+
+void
+viterbi_butterfly2(unsigned char *symbols, int mettab[2][256], struct viterbi_state *state0, struct viterbi_state *state1)
+{
+ //unsigned int bitcnt;
+ int mets[4];
+
+ struct viterbi_state *state, *next;
+ state = state0;
+ next = state1;
+ // Operate on 4 symbols (2 bits) at a time
+
+ // Read input symbol pair and compute all possible branch metrics
+ mets[0] = mettab[0][symbols[0]] + mettab[0][symbols[1]];
+ mets[1] = mettab[0][symbols[0]] + mettab[1][symbols[1]];
+ mets[2] = mettab[1][symbols[0]] + mettab[0][symbols[1]];
+ mets[3] = mettab[1][symbols[0]] + mettab[1][symbols[1]];
+
+ // These macro calls were generated by genbut.c
+ BUTTERFLY(0,0);BUTTERFLY(1,1);BUTTERFLY(2,3);BUTTERFLY(3,2);
+ BUTTERFLY(4,3);BUTTERFLY(5,2);BUTTERFLY(6,0);BUTTERFLY(7,1);
+ BUTTERFLY(8,0);BUTTERFLY(9,1);BUTTERFLY(10,3);BUTTERFLY(11,2);
+ BUTTERFLY(12,3);BUTTERFLY(13,2);BUTTERFLY(14,0);BUTTERFLY(15,1);
+ BUTTERFLY(16,2);BUTTERFLY(17,3);BUTTERFLY(18,1);BUTTERFLY(19,0);
+ BUTTERFLY(20,1);BUTTERFLY(21,0);BUTTERFLY(22,2);BUTTERFLY(23,3);
+ BUTTERFLY(24,2);BUTTERFLY(25,3);BUTTERFLY(26,1);BUTTERFLY(27,0);
+ BUTTERFLY(28,1);BUTTERFLY(29,0);BUTTERFLY(30,2);BUTTERFLY(31,3);
+
+ state = state1;
+ next = state0;
+
+ // Read input symbol pair and compute all possible branch metrics
+ mets[0] = mettab[0][symbols[2]] + mettab[0][symbols[3]];
+ mets[1] = mettab[0][symbols[2]] + mettab[1][symbols[3]];
+ mets[2] = mettab[1][symbols[2]] + mettab[0][symbols[3]];
+ mets[3] = mettab[1][symbols[2]] + mettab[1][symbols[3]];
+
+ // These macro calls were generated by genbut.c
+ BUTTERFLY(0,0);BUTTERFLY(1,1);BUTTERFLY(2,3);BUTTERFLY(3,2);
+ BUTTERFLY(4,3);BUTTERFLY(5,2);BUTTERFLY(6,0);BUTTERFLY(7,1);
+ BUTTERFLY(8,0);BUTTERFLY(9,1);BUTTERFLY(10,3);BUTTERFLY(11,2);
+ BUTTERFLY(12,3);BUTTERFLY(13,2);BUTTERFLY(14,0);BUTTERFLY(15,1);
+ BUTTERFLY(16,2);BUTTERFLY(17,3);BUTTERFLY(18,1);BUTTERFLY(19,0);
+ BUTTERFLY(20,1);BUTTERFLY(21,0);BUTTERFLY(22,2);BUTTERFLY(23,3);
+ BUTTERFLY(24,2);BUTTERFLY(25,3);BUTTERFLY(26,1);BUTTERFLY(27,0);
+ BUTTERFLY(28,1);BUTTERFLY(29,0);BUTTERFLY(30,2);BUTTERFLY(31,3);
+}
+
+unsigned char
+viterbi_get_output(struct viterbi_state *state, unsigned char *outbuf) {
+ // Produce output every 8 bits once path memory is full
+ // if((bitcnt % 8) == 5 && bitcnt > 32) {
+
+ // Find current best path
+ unsigned int i,beststate;
+ int bestmetric;
+
+ bestmetric = state[0].metric;
+ beststate = 0;
+ for(i=1;i<64;i++)
+ if(state[i].metric > bestmetric) {
+ bestmetric = state[i].metric;
+ beststate = i;
+ }
+ *outbuf = state[beststate].path >> 24;
+ return bestmetric;
+}
+
+
+//printf ("BS = %d\tBSM = %d\tM0 = %d\n",beststate,state[beststate].metric,state[0].metric);
+// In tail, poison non-zero nodes
+//if(bits_out > packet_size-7)
+// for(i=1;i<64;i += 2)
+// state[i].metric = -9999999;
+
diff --git a/gnuradio-core/src/lib/viterbi/viterbi.h b/gnuradio-core/src/lib/viterbi/viterbi.h
new file mode 100644
index 000000000..bcdbe116d
--- /dev/null
+++ b/gnuradio-core/src/lib/viterbi/viterbi.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2008 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+/* The path memory for each state is 32 bits. This is slightly shorter
+ * than we'd like for K=7, especially since we chain back every 8 bits.
+ * But it fits so nicely into a 32-bit machine word...
+ */
+
+#include <gr_core_api.h>
+
+struct viterbi_state {
+ unsigned long path; /* Decoded path to this state */
+ long metric; /* Cumulative metric to this state */
+};
+
+GR_CORE_API
+int gen_met(int mettab[2][256], /* Metric table */
+ int amp, /* Signal amplitude */
+ double esn0, /* Es/N0 ratio in dB */
+ double bias, /* Metric bias */
+ int scale); /* Scale factor */
+
+GR_CORE_API unsigned char
+encode(unsigned char *symbols, unsigned char *data,
+ unsigned int nbytes,unsigned char encstate);
+
+GR_CORE_API void
+viterbi_chunks_init(struct viterbi_state* state);
+
+ GR_CORE_API void
+viterbi_butterfly2(unsigned char *symbols, int mettab[2][256],
+ struct viterbi_state *state0, struct viterbi_state *state1);
+
+GR_CORE_API unsigned char
+viterbi_get_output(struct viterbi_state *state, unsigned char *outbuf);
diff --git a/gnuradio-core/src/python/bin/microtune.py b/gnuradio-core/src/python/bin/microtune.py
new file mode 100755
index 000000000..fbe743f39
--- /dev/null
+++ b/gnuradio-core/src/python/bin/microtune.py
@@ -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
index 000000000..cf58a9763
--- /dev/null
+++ b/gnuradio-core/src/python/build_utils.py
@@ -0,0 +1,226 @@
+#
+# Copyright 2004,2009,2012 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, 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 + '/'
+
+# set do_makefile to either true or false dependeing on the environment
+try:
+ if os.environ['do_makefile'] == '0':
+ do_makefile = False
+ else:
+ do_makefile = True
+except KeyError, e:
+ do_makefile = False
+
+# set do_sources to either true or false dependeing on the environment
+try:
+ if os.environ['do_sources'] == '0':
+ do_sources = False
+ else:
+ do_sources = True
+except KeyError, e:
+ do_sources = True
+
+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):
+ global do_sources
+ if do_sources:
+ f = open (name, dir)
+ else:
+ f = None
+ 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
+ '''
+ global do_sources
+ output_extension = extract_extension (template_filename)
+ template = open_src (template_filename, 'r')
+ output_name = d['NAME'] + extra + '.' + output_extension
+ log_output_name (output_name)
+ if do_sources:
+ output = open (output_name, 'w')
+ do_substitution (d, template, output)
+ output.close ()
+ template.close ()
+
+def output_glue (dirname):
+ output_makefile_fragment ()
+ output_ifile_include (dirname)
+
+def output_makefile_fragment ():
+ global do_makefile
+ if not do_makefile:
+ return
+# overwrite the source, which must be writable; this should have been
+# checked for beforehand in the top-level Makefile.gen.gen .
+ f = open (os.path.join (os.environ.get('gendir', os.environ.get('srcdir', '.')), '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):
+ global do_sources
+ if do_sources:
+ 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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+'''
+
+def is_complex (code3):
+ if i_code (code3) == 'c' or o_code (code3) == 'c':
+ return '1'
+ else:
+ return '0'
+
+
+def standard_dict (name, code3, package='gr'):
+ d = {}
+ d['NAME'] = name
+ d['NAME_IMPL'] = name+'_impl'
+ d['GUARD_NAME'] = 'INCLUDED_%s_%s_H' % (package.upper(), name.upper())
+ d['GUARD_NAME_IMPL'] = 'INCLUDED_%s_%s_IMPL_H' % (package.upper(), name.upper())
+ d['BASE_NAME'] = re.sub ('^' + package + '_', '', name)
+ d['SPTR_NAME'] = '%s_sptr' % name
+ d['WARNING'] = 'WARNING: this file is machine generated. Edits will be overwritten'
+ 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
+
+
+def standard_dict2 (name, code3, package):
+ d = {}
+ d['NAME'] = name
+ d['BASE_NAME'] = name
+ d['GUARD_NAME'] = 'INCLUDED_%s_%s_H' % (package.upper(), name.upper())
+ d['WARNING'] = 'WARNING: this file is machine generated. Edits will be overwritten'
+ 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
+
+def standard_impl_dict2 (name, code3, package):
+ d = {}
+ d['NAME'] = name
+ d['IMPL_NAME'] = name
+ d['BASE_NAME'] = name.rstrip("impl").rstrip("_")
+ d['GUARD_NAME'] = 'INCLUDED_%s_%s_H' % (package.upper(), name.upper())
+ d['WARNING'] = 'WARNING: this file is machine generated. Edits will be overwritten'
+ d['COPYRIGHT'] = copyright
+ d['FIR_TYPE'] = "fir_filter_" + code3
+ d['CFIR_TYPE'] = "fir_filter_" + code3[0:2] + 'c'
+ 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
index 000000000..9ea96baae
--- /dev/null
+++ b/gnuradio-core/src/python/build_utils_codes.py
@@ -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 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+def 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/CMakeLists.txt b/gnuradio-core/src/python/gnuradio/CMakeLists.txt
new file mode 100644
index 000000000..bf696e0d3
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/CMakeLists.txt
@@ -0,0 +1,38 @@
+# Copyright 2010-2011 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+
+include(GrPython)
+
+add_subdirectory(gr)
+add_subdirectory(gru)
+add_subdirectory(gruimpl)
+add_subdirectory(blks2)
+add_subdirectory(blks2impl)
+
+GR_PYTHON_INSTALL(FILES
+ __init__.py
+ eng_notation.py
+ eng_option.py
+ gr_unittest.py
+ gr_xmlrunner.py
+ optfir.py
+ window.py
+ DESTINATION ${GR_PYTHON_DIR}/gnuradio
+ COMPONENT "core_python"
+)
diff --git a/gnuradio-core/src/python/gnuradio/__init__.py b/gnuradio-core/src/python/gnuradio/__init__.py
new file mode 100644
index 000000000..a4917cf64
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/__init__.py
@@ -0,0 +1 @@
+# make this a package
diff --git a/gnuradio-core/src/python/gnuradio/blks2/CMakeLists.txt b/gnuradio-core/src/python/gnuradio/blks2/CMakeLists.txt
new file mode 100644
index 000000000..83d11dd83
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/blks2/CMakeLists.txt
@@ -0,0 +1,26 @@
+# Copyright 2010-2011 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+
+include(GrPython)
+
+GR_PYTHON_INSTALL(
+ FILES __init__.py
+ DESTINATION ${GR_PYTHON_DIR}/gnuradio/blks2
+ COMPONENT "core_python"
+)
diff --git a/gnuradio-core/src/python/gnuradio/blks2/__init__.py b/gnuradio-core/src/python/gnuradio/blks2/__init__.py
new file mode 100644
index 000000000..2dfdc77f4
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/blks2/__init__.py
@@ -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 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+import glob
+import os.path
+
+# Semi-hideous kludge to import everything in the blksimpl2 directory
+# into the gnuradio.blks2 namespace. This keeps us from having to remember
+# to manually update this file.
+
+for p in __path__:
+ filenames = glob.glob (os.path.join (p, "..", "blks2impl", "*.py"))
+ for f in filenames:
+ f = os.path.basename(f).lower()
+ f = f[:-3]
+ if f == '__init__':
+ continue
+ # print f
+ exec "from gnuradio.blks2impl.%s import *" % (f,)
diff --git a/gnuradio-core/src/python/gnuradio/blks2impl/CMakeLists.txt b/gnuradio-core/src/python/gnuradio/blks2impl/CMakeLists.txt
new file mode 100644
index 000000000..61fcdda42
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/blks2impl/CMakeLists.txt
@@ -0,0 +1,45 @@
+# Copyright 2010-2011 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+
+include(GrPython)
+
+GR_PYTHON_INSTALL(FILES
+ __init__.py
+ am_demod.py
+ channel_model.py
+ filterbank.py
+ fm_demod.py
+ fm_emph.py
+ logpwrfft.py
+ nbfm_rx.py
+ nbfm_tx.py
+ pfb_arb_resampler.py
+ pfb_channelizer.py
+ pfb_decimator.py
+ pfb_interpolator.py
+ rational_resampler.py
+ standard_squelch.py
+ stream_to_vector_decimator.py
+ wfm_rcv.py
+ wfm_rcv_fmdet.py
+ wfm_rcv_pll.py
+ wfm_tx.py
+ DESTINATION ${GR_PYTHON_DIR}/gnuradio/blks2impl
+ COMPONENT "core_python"
+)
diff --git a/gnuradio-core/src/python/gnuradio/blks2impl/__init__.py b/gnuradio-core/src/python/gnuradio/blks2impl/__init__.py
new file mode 100644
index 000000000..a4917cf64
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/blks2impl/__init__.py
@@ -0,0 +1 @@
+# make this a package
diff --git a/gnuradio-core/src/python/gnuradio/blks2impl/am_demod.py b/gnuradio-core/src/python/gnuradio/blks2impl/am_demod.py
new file mode 100644
index 000000000..68d024565
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/blks2impl/am_demod.py
@@ -0,0 +1,75 @@
+#
+# Copyright 2006,2007 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr, optfir
+
+class am_demod_cf(gr.hier_block2):
+ """
+ Generalized AM demodulation block with audio filtering.
+
+ This block demodulates a band-limited, complex down-converted AM
+ channel into the the original baseband signal, applying low pass
+ filtering to the audio output. It produces a float stream in the
+ range [-1.0, +1.0].
+
+ @param channel_rate: incoming sample rate of the AM baseband
+ @type sample_rate: integer
+ @param audio_decim: input to output decimation rate
+ @type audio_decim: integer
+ @param audio_pass: audio low pass filter passband frequency
+ @type audio_pass: float
+ @param audio_stop: audio low pass filter stop frequency
+ @type audio_stop: float
+ """
+ def __init__(self, channel_rate, audio_decim, audio_pass, audio_stop):
+ gr.hier_block2.__init__(self, "am_demod_cf",
+ gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature
+ gr.io_signature(1, 1, gr.sizeof_float)) # Input signature
+
+ MAG = gr.complex_to_mag()
+ DCR = gr.add_const_ff(-1.0)
+
+ audio_taps = optfir.low_pass(0.5, # Filter gain
+ channel_rate, # Sample rate
+ audio_pass, # Audio passband
+ audio_stop, # Audio stopband
+ 0.1, # Passband ripple
+ 60) # Stopband attenuation
+ LPF = gr.fir_filter_fff(audio_decim, audio_taps)
+
+ self.connect(self, MAG, DCR, LPF, self)
+
+class demod_10k0a3e_cf(am_demod_cf):
+ """
+ AM demodulation block, 10 KHz channel.
+
+ This block demodulates an AM channel conformant to 10K0A3E emission
+ standards, such as broadcast band AM transmissions.
+
+ @param channel_rate: incoming sample rate of the AM baseband
+ @type sample_rate: integer
+ @param audio_decim: input to output decimation rate
+ @type audio_decim: integer
+ """
+ def __init__(self, channel_rate, audio_decim):
+ am_demod_cf.__init__(self, channel_rate, audio_decim,
+ 5000, # Audio passband
+ 5500) # Audio stopband
diff --git a/gnuradio-core/src/python/gnuradio/blks2impl/channel_model.py b/gnuradio-core/src/python/gnuradio/blks2impl/channel_model.py
new file mode 100644
index 000000000..e5cd471df
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/blks2impl/channel_model.py
@@ -0,0 +1,26 @@
+#!/usr/bin/env python
+#
+# Copyright 2009 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr
+
+# This block is now a C++ hierarchical block, gr.channel_model
+channel_model = gr.channel_model
diff --git a/gnuradio-core/src/python/gnuradio/blks2impl/digital_voice.py.real b/gnuradio-core/src/python/gnuradio/blks2impl/digital_voice.py.real
new file mode 100644
index 000000000..6ec66825c
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/blks2impl/digital_voice.py.real
@@ -0,0 +1,102 @@
+#!/usr/bin/env python
+#
+# Copyright 2005 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+"""
+Digital voice Tx and Rx using GSM 13kbit vocoder and GMSK.
+
+Runs channel at 32kbit/sec. Currently uses fake channel coding,
+but there's room for a rate 1/2 coder.
+"""
+
+from gnuradio import gr, gru
+from gnuradio.blksimpl.gmsk import gmsk_mod, gmsk_demod
+
+from gnuradio.vocoder import gsm_full_rate
+
+# Size of gsm full rate speech encoder output packet in bytes
+
+GSM_FRAME_SIZE = 33
+
+# Size of packet in bytes that we send to GMSK modulator:
+#
+# Target: 256kS/sec air rate.
+#
+# 256kS 1 sym 1 bit 1 byte 0.020 sec 80 bytes
+# ---- * ----- * ----- * ------ * --------- = --------
+# sec 8 S 1 sym 8 bits frame frame
+#
+# gr_simple_framer add 10 bytes of overhead.
+
+AIR_FRAME_SIZE = 70
+
+
+class digital_voice_tx(gr.hier_block):
+ """
+ Hierarchical block for digital voice tranmission.
+
+ The input is 8kS/sec floating point audio in the range [-1,+1]
+ The output is 256kS/sec GMSK modulated complex baseband signal in the range [-1,+1].
+ """
+ def __init__(self, fg):
+ samples_per_symbol = 8
+ symbol_rate = 32000
+ bt = 0.3 # Gaussian filter bandwidth * symbol time
+
+ src_scale = gr.multiply_const_ff(32767)
+ f2s = gr.float_to_short()
+ voice_coder = gsm_full_rate.encode_sp()
+
+ channel_coder = gr.fake_channel_encoder_pp(GSM_FRAME_SIZE, AIR_FRAME_SIZE)
+ p2s = gr.parallel_to_serial(gr.sizeof_char, AIR_FRAME_SIZE)
+
+ mod = gmsk_mod(fg, sps=samples_per_symbol,
+ symbol_rate=symbol_rate, bt=bt,
+ p_size=AIR_FRAME_SIZE)
+
+ fg.connect(src_scale, f2s, voice_coder, channel_coder, p2s, mod)
+ gr.hier_block.__init__(self, fg, src_scale, mod)
+
+
+class digital_voice_rx(gr.hier_block):
+ """
+ Hierarchical block for digital voice reception.
+
+ The input is 256kS/sec GMSK modulated complex baseband signal.
+ The output is 8kS/sec floating point audio in the range [-1,+1]
+ """
+ def __init__(self, fg):
+ samples_per_symbol = 8
+ symbol_rate = 32000
+
+ demod = gmsk_demod(fg, sps=samples_per_symbol,
+ symbol_rate=symbol_rate,
+ p_size=AIR_FRAME_SIZE)
+
+ s2p = gr.serial_to_parallel(gr.sizeof_char, AIR_FRAME_SIZE)
+ channel_decoder = gr.fake_channel_decoder_pp(AIR_FRAME_SIZE, GSM_FRAME_SIZE)
+
+ voice_decoder = gsm_full_rate.decode_ps()
+ s2f = gr.short_to_float ()
+ sink_scale = gr.multiply_const_ff(1.0/32767.)
+
+ fg.connect(demod, s2p, channel_decoder, voice_decoder, s2f, sink_scale)
+ gr.hier_block.__init__(self, fg, demod, sink_scale)
diff --git a/gnuradio-core/src/python/gnuradio/blks2impl/filterbank.py b/gnuradio-core/src/python/gnuradio/blks2impl/filterbank.py
new file mode 100644
index 000000000..08f1d450b
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/blks2impl/filterbank.py
@@ -0,0 +1,169 @@
+#
+# Copyright 2005,2007 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+import 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_block2):
+ """
+ Uniformly modulated polyphase DFT filter bank: synthesis
+
+ See http://cnx.org/content/m10424/latest
+ """
+ def __init__(self, mpoints, taps=None):
+ """
+ Takes M complex streams in, produces single complex stream out
+ that runs at M times the input sample rate
+
+ @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
+ gr.hier_block2.__init__(self, "synthesis_filterbank",
+ gr.io_signature(mpoints, mpoints, item_size), # Input signature
+ gr.io_signature(1, 1, item_size)) # Output signature
+
+
+ if taps is None:
+ taps = _generate_synthesis_taps(mpoints)
+
+ # 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)
+
+ for i in range(mpoints):
+ self.connect((self, i), (self.ss2v, i))
+
+ self.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])
+ self.connect((self.v2ss, i), f)
+ self.connect(f, (self.ss2s, i))
+
+ self.connect(self.ss2s, self)
+
+class analysis_filterbank(gr.hier_block2):
+ """
+ Uniformly modulated polyphase DFT filter bank: analysis
+
+ See http://cnx.org/content/m10424/latest
+ """
+ def __init__(self, mpoints, taps=None):
+ """
+ Takes 1 complex stream in, produces M complex streams out
+ that runs at 1/M times the input sample rate
+
+ @param mpoints: number of freq bins/interpolation factor/subbands
+ @param taps: filter taps for subband filter
+
+ Same channel to frequency mapping as described above.
+ """
+ item_size = gr.sizeof_gr_complex
+ gr.hier_block2.__init__(self, "analysis_filterbank",
+ gr.io_signature(1, 1, item_size), # Input signature
+ gr.io_signature(mpoints, mpoints, item_size)) # Output signature
+
+ 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)
+
+ self.connect(self, self.s2ss)
+
+ # build mpoints fir filters...
+ for i in range(mpoints):
+ f = gr.fft_filter_ccc(1, sub_taps[mpoints-i-1])
+ self.connect((self.s2ss, i), f)
+ self.connect(f, (self.ss2v, i))
+ self.connect((self.v2ss, i), (self, i))
+
+ self.connect(self.ss2v, self.fft, self.v2ss)
diff --git a/gnuradio-core/src/python/gnuradio/blks2impl/fm_demod.py b/gnuradio-core/src/python/gnuradio/blks2impl/fm_demod.py
new file mode 100644
index 000000000..6bc0d7ed0
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/blks2impl/fm_demod.py
@@ -0,0 +1,111 @@
+#
+# Copyright 2006,2007 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr, optfir
+from gnuradio.blks2impl.fm_emph import fm_deemph
+from math import pi
+
+class fm_demod_cf(gr.hier_block2):
+ """
+ Generalized FM demodulation block with deemphasis and audio
+ filtering.
+
+ This block demodulates a band-limited, complex down-converted FM
+ channel into the the original baseband signal, optionally applying
+ deemphasis. Low pass filtering is done on the resultant signal. It
+ produces an output float strem in the range of [-1.0, +1.0].
+
+ @param channel_rate: incoming sample rate of the FM baseband
+ @type sample_rate: integer
+ @param deviation: maximum FM deviation (default = 5000)
+ @type deviation: float
+ @param audio_decim: input to output decimation rate
+ @type audio_decim: integer
+ @param audio_pass: audio low pass filter passband frequency
+ @type audio_pass: float
+ @param audio_stop: audio low pass filter stop frequency
+ @type audio_stop: float
+ @param gain: gain applied to audio output (default = 1.0)
+ @type gain: float
+ @param tau: deemphasis time constant (default = 75e-6), specify 'None'
+ to prevent deemphasis
+ """
+ def __init__(self, channel_rate, audio_decim, deviation,
+ audio_pass, audio_stop, gain=1.0, tau=75e-6):
+ gr.hier_block2.__init__(self, "fm_demod_cf",
+ gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature
+ gr.io_signature(1, 1, gr.sizeof_float)) # Output signature
+
+ k = channel_rate/(2*pi*deviation)
+ QUAD = gr.quadrature_demod_cf(k)
+
+ audio_taps = optfir.low_pass(gain, # Filter gain
+ channel_rate, # Sample rate
+ audio_pass, # Audio passband
+ audio_stop, # Audio stopband
+ 0.1, # Passband ripple
+ 60) # Stopband attenuation
+ LPF = gr.fir_filter_fff(audio_decim, audio_taps)
+
+ if tau is not None:
+ DEEMPH = fm_deemph(channel_rate, tau)
+ self.connect(self, QUAD, DEEMPH, LPF, self)
+ else:
+ self.connect(self, QUAD, LPF, self)
+
+class demod_20k0f3e_cf(fm_demod_cf):
+ """
+ NBFM demodulation block, 20 KHz channels
+
+ This block demodulates a complex, downconverted, narrowband FM
+ channel conforming to 20K0F3E emission standards, outputting
+ floats in the range [-1.0, +1.0].
+
+ @param sample_rate: incoming sample rate of the FM baseband
+ @type sample_rate: integer
+ @param audio_decim: input to output decimation rate
+ @type audio_decim: integer
+ """
+ def __init__(self, channel_rate, audio_decim):
+ fm_demod_cf.__init__(self, channel_rate, audio_decim,
+ 5000, # Deviation
+ 3000, # Audio passband frequency
+ 4500) # Audio stopband frequency
+
+class demod_200kf3e_cf(fm_demod_cf):
+ """
+ WFM demodulation block, mono.
+
+ This block demodulates a complex, downconverted, wideband FM
+ channel conforming to 200KF3E emission standards, outputting
+ floats in the range [-1.0, +1.0].
+
+ @param sample_rate: incoming sample rate of the FM baseband
+ @type sample_rate: integer
+ @param audio_decim: input to output decimation rate
+ @type audio_decim: integer
+ """
+ def __init__(self, channel_rate, audio_decim):
+ fm_demod_cf.__init__(self, channel_rate, audio_decim,
+ 75000, # Deviation
+ 15000, # Audio passband
+ 16000, # Audio stopband
+ 20.0) # Audio gain
diff --git a/gnuradio-core/src/python/gnuradio/blks2impl/fm_emph.py b/gnuradio-core/src/python/gnuradio/blks2impl/fm_emph.py
new file mode 100644
index 000000000..fc3f2d60d
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/blks2impl/fm_emph.py
@@ -0,0 +1,151 @@
+#
+# Copyright 2005,2007 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr
+import math
+
+
+#
+# 1
+# H(s) = -------
+# 1 + s
+#
+# tau is the RC time constant.
+# critical frequency: w_p = 1/tau
+#
+# We prewarp and use the bilinear z-transform to get our IIR coefficients.
+# See "Digital Signal Processing: A Practical Approach" by Ifeachor and Jervis
+#
+
+class fm_deemph(gr.hier_block2):
+ """
+ FM Deemphasis IIR filter.
+ """
+
+
+ def __init__(self, fs, tau=75e-6):
+ """
+ @param fs: sampling frequency in Hz
+ @type fs: float
+ @param tau: Time constant in seconds (75us in US, 50us in EUR)
+ @type tau: float
+ """
+ gr.hier_block2.__init__(self, "fm_deemph",
+ gr.io_signature(1, 1, gr.sizeof_float), # Input signature
+ gr.io_signature(1, 1, gr.sizeof_float)) # Output signature
+
+ w_p = 1/tau
+ w_pp = math.tan (w_p / (fs * 2)) # prewarped analog freq
+
+ a1 = (w_pp - 1)/(w_pp + 1)
+ b0 = w_pp/(1 + w_pp)
+ b1 = b0
+
+ btaps = [b0, b1]
+ ataps = [1, a1]
+
+ if 0:
+ print "btaps =", btaps
+ print "ataps =", ataps
+ global plot1
+ plot1 = gru.gnuplot_freqz (gru.freqz (btaps, ataps), fs, True)
+
+ deemph = gr.iir_filter_ffd(btaps, ataps)
+ self.connect(self, deemph, self)
+
+#
+# 1 + s*t1
+# H(s) = ----------
+# 1 + s*t2
+#
+# I think this is the right transfer function.
+#
+#
+# This fine ASCII rendition is based on Figure 5-15
+# in "Digital and Analog Communication Systems", Leon W. Couch II
+#
+#
+# R1
+# +-----||------+
+# | |
+# o------+ +-----+--------o
+# | C1 | |
+# +----/\/\/\/--+ \
+# /
+# \ R2
+# /
+# \
+# |
+# o--------------------------+--------o
+#
+# f1 = 1/(2*pi*t1) = 1/(2*pi*R1*C)
+#
+# 1 R1 + R2
+# f2 = ------- = ------------
+# 2*pi*t2 2*pi*R1*R2*C
+#
+# t1 is 75us in US, 50us in EUR
+# f2 should be higher than our audio bandwidth.
+#
+#
+# The Bode plot looks like this:
+#
+#
+# /----------------
+# /
+# / <-- slope = 20dB/decade
+# /
+# -------------/
+# f1 f2
+#
+# We prewarp and use the bilinear z-transform to get our IIR coefficients.
+# See "Digital Signal Processing: A Practical Approach" by Ifeachor and Jervis
+#
+
+class fm_preemph(gr.hier_block2):
+ """
+ FM Preemphasis IIR filter.
+ """
+ def __init__(self, fs, tau=75e-6):
+ """
+ @param fs: sampling frequency in Hz
+ @type fs: float
+ @param tau: Time constant in seconds (75us in US, 50us in EUR)
+ @type tau: float
+ """
+
+ gr.hier_block2.__init__(self, "fm_deemph",
+ gr.io_signature(1, 1, gr.sizeof_float), # Input signature
+ gr.io_signature(1, 1, gr.sizeof_float)) # Output signature
+
+ # FIXME make this compute the right answer
+
+ btaps = [1]
+ ataps = [1]
+
+ if 0:
+ print "btaps =", btaps
+ print "ataps =", ataps
+ global plot2
+ plot2 = gru.gnuplot_freqz (gru.freqz (btaps, ataps), fs, True)
+
+ preemph = gr.iir_filter_ffd(btaps, ataps)
+ self.connect(self, preemph, self)
diff --git a/gnuradio-core/src/python/gnuradio/blks2impl/logpwrfft.py b/gnuradio-core/src/python/gnuradio/blks2impl/logpwrfft.py
new file mode 100644
index 000000000..6f7fc520f
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/blks2impl/logpwrfft.py
@@ -0,0 +1,155 @@
+#
+# Copyright 2008 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr, window
+from stream_to_vector_decimator import stream_to_vector_decimator
+import math
+
+class _logpwrfft_base(gr.hier_block2):
+ """
+ Create a log10(abs(fft)) stream chain, with real or complex input.
+ """
+
+ def __init__(self, sample_rate, fft_size, ref_scale, frame_rate, avg_alpha, average, win=None):
+ """
+ Create an log10(abs(fft)) stream chain.
+ Provide access to the setting the filter and sample rate.
+ @param sample_rate Incoming stream sample rate
+ @param fft_size Number of FFT bins
+ @param ref_scale Sets 0 dB value input amplitude
+ @param frame_rate Output frame rate
+ @param avg_alpha FFT averaging (over time) constant [0.0-1.0]
+ @param average Whether to average [True, False]
+ @param win the window taps generation function
+ """
+ gr.hier_block2.__init__(self, self._name,
+ gr.io_signature(1, 1, self._item_size), # Input signature
+ gr.io_signature(1, 1, gr.sizeof_float*fft_size)) # Output signature
+
+ self._sd = stream_to_vector_decimator(item_size=self._item_size,
+ sample_rate=sample_rate,
+ vec_rate=frame_rate,
+ vec_len=fft_size)
+
+ if win is None: win = window.blackmanharris
+ fft_window = win(fft_size)
+ fft = self._fft_block[0](fft_size, True, fft_window)
+ window_power = sum(map(lambda x: x*x, fft_window))
+
+ c2magsq = gr.complex_to_mag_squared(fft_size)
+ self._avg = gr.single_pole_iir_filter_ff(1.0, fft_size)
+ self._log = gr.nlog10_ff(10, fft_size,
+ -20*math.log10(fft_size) # Adjust for number of bins
+ -10*math.log10(window_power/fft_size) # Adjust for windowing loss
+ -20*math.log10(ref_scale/2)) # Adjust for reference scale
+ self.connect(self, self._sd, fft, c2magsq, self._avg, self._log, self)
+
+ self._average = average
+ self._avg_alpha = avg_alpha
+ self.set_avg_alpha(avg_alpha)
+ self.set_average(average)
+
+ def set_decimation(self, decim):
+ """
+ Set the decimation on stream decimator.
+ @param decim the new decimation
+ """
+ self._sd.set_decimation(decim)
+
+ def set_vec_rate(self, vec_rate):
+ """
+ Set the vector rate on stream decimator.
+ @param vec_rate the new vector rate
+ """
+ self._sd.set_vec_rate(vec_rate)
+
+ def set_sample_rate(self, sample_rate):
+ """
+ Set the new sampling rate
+ @param sample_rate the new rate
+ """
+ self._sd.set_sample_rate(sample_rate)
+
+ def set_average(self, average):
+ """
+ Set the averaging filter on/off.
+ @param average true to set averaging on
+ """
+ self._average = average
+ if self._average:
+ self._avg.set_taps(self._avg_alpha)
+ else:
+ self._avg.set_taps(1.0)
+
+ def set_avg_alpha(self, avg_alpha):
+ """
+ Set the average alpha and set the taps if average was on.
+ @param avg_alpha the new iir filter tap
+ """
+ self._avg_alpha = avg_alpha
+ self.set_average(self._average)
+
+ def sample_rate(self):
+ """
+ Return the current sample rate.
+ """
+ return self._sd.sample_rate()
+
+ def decimation(self):
+ """
+ Return the current decimation.
+ """
+ return self._sd.decimation()
+
+ def frame_rate(self):
+ """
+ Return the current frame rate.
+ """
+ return self._sd.frame_rate()
+
+ def average(self):
+ """
+ Return whether or not averaging is being performed.
+ """
+ return self._average
+
+ def avg_alpha(self):
+ """
+ Return averaging filter constant.
+ """
+ return self._avg_alpha
+
+class logpwrfft_f(_logpwrfft_base):
+ """
+ Create an fft block chain, with real input.
+ """
+ _name = "logpwrfft_f"
+ _item_size = gr.sizeof_float
+ _fft_block = (gr.fft_vfc, )
+
+class logpwrfft_c(_logpwrfft_base):
+ """
+ Create an fft block chain, with complex input.
+ """
+ _name = "logpwrfft_c"
+ _item_size = gr.sizeof_gr_complex
+ _fft_block = (gr.fft_vcc, )
+
diff --git a/gnuradio-core/src/python/gnuradio/blks2impl/nbfm_rx.py b/gnuradio-core/src/python/gnuradio/blks2impl/nbfm_rx.py
new file mode 100644
index 000000000..8bcb47ae1
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/blks2impl/nbfm_rx.py
@@ -0,0 +1,88 @@
+#
+# Copyright 2005 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+import math
+from gnuradio import gr, optfir
+from gnuradio.blks2impl.fm_emph import fm_deemph
+#from gnuradio.blks2impl.standard_squelch import standard_squelch
+
+class nbfm_rx(gr.hier_block2):
+ def __init__(self, audio_rate, quad_rate, tau=75e-6, max_dev=5e3):
+ """
+ Narrow Band FM Receiver.
+
+ Takes a single complex baseband input stream and produces a single
+ float output stream of audio sample in the range [-1, +1].
+
+ @param audio_rate: sample rate of audio stream, >= 16k
+ @type audio_rate: integer
+ @param quad_rate: sample rate of output stream
+ @type quad_rate: integer
+ @param tau: preemphasis time constant (default 75e-6)
+ @type tau: float
+ @param max_dev: maximum deviation in Hz (default 5e3)
+ @type max_dev: float
+
+ quad_rate must be an integer multiple of audio_rate.
+
+ Exported sub-blocks (attributes):
+ squelch
+ quad_demod
+ deemph
+ audio_filter
+ """
+
+ gr.hier_block2.__init__(self, "nbfm_rx",
+ gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature
+ gr.io_signature(1, 1, gr.sizeof_float)) # Output signature
+
+ # FIXME audio_rate and quad_rate ought to be exact rationals
+ audio_rate = int(audio_rate)
+ quad_rate = int(quad_rate)
+
+ if quad_rate % audio_rate != 0:
+ raise ValueError, "quad_rate is not an integer multiple of audio_rate"
+
+ squelch_threshold = 20 # dB
+ #self.squelch = gr.simple_squelch_cc(squelch_threshold, 0.001)
+
+ # FM Demodulator input: complex; output: float
+ k = quad_rate/(2*math.pi*max_dev)
+ self.quad_demod = gr.quadrature_demod_cf(k)
+
+ # FM Deemphasis IIR filter
+ self.deemph = fm_deemph (quad_rate, tau=tau)
+
+ # compute FIR taps for audio filter
+ audio_decim = quad_rate // audio_rate
+ audio_taps = gr.firdes.low_pass (1.0, # gain
+ quad_rate, # sampling rate
+ 2.7e3, # Audio LPF cutoff
+ 0.5e3, # Transition band
+ gr.firdes.WIN_HAMMING) # filter type
+
+ print "len(audio_taps) =", len(audio_taps)
+
+ # Decimating audio filter
+ # input: float; output: float; taps: float
+ self.audio_filter = gr.fir_filter_fff(audio_decim, audio_taps)
+
+ self.connect(self, self.quad_demod, self.deemph, self.audio_filter, self)
diff --git a/gnuradio-core/src/python/gnuradio/blks2impl/nbfm_tx.py b/gnuradio-core/src/python/gnuradio/blks2impl/nbfm_tx.py
new file mode 100644
index 000000000..839cf6784
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/blks2impl/nbfm_tx.py
@@ -0,0 +1,92 @@
+#
+# Copyright 2005 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+import math
+from gnuradio import gr, optfir
+from gnuradio.blks2impl.fm_emph import fm_preemph
+
+#from gnuradio import ctcss
+
+class nbfm_tx(gr.hier_block2):
+ def __init__(self, audio_rate, quad_rate, tau=75e-6, max_dev=5e3):
+ """
+ Narrow Band FM Transmitter.
+
+ Takes a single float input stream of audio samples in the range [-1,+1]
+ and produces a single FM modulated complex baseband output.
+
+ @param audio_rate: sample rate of audio stream, >= 16k
+ @type audio_rate: integer
+ @param quad_rate: sample rate of output stream
+ @type quad_rate: integer
+ @param tau: preemphasis time constant (default 75e-6)
+ @type tau: float
+ @param max_dev: maximum deviation in Hz (default 5e3)
+ @type max_dev: float
+
+ quad_rate must be an integer multiple of audio_rate.
+ """
+
+ gr.hier_block2.__init__(self, "nbfm_tx",
+ gr.io_signature(1, 1, gr.sizeof_float), # Input signature
+ gr.io_signature(1, 1, gr.sizeof_gr_complex)) # Output signature
+
+ # FIXME audio_rate and quad_rate ought to be exact rationals
+ audio_rate = int(audio_rate)
+ quad_rate = int(quad_rate)
+
+ if quad_rate % audio_rate != 0:
+ raise ValueError, "quad_rate is not an integer multiple of audio_rate"
+
+
+ do_interp = audio_rate != quad_rate
+
+ if do_interp:
+ interp_factor = quad_rate / audio_rate
+ interp_taps = optfir.low_pass (interp_factor, # gain
+ quad_rate, # Fs
+ 4500, # passband cutoff
+ 7000, # stopband cutoff
+ 0.1, # passband ripple dB
+ 40) # stopband atten dB
+
+ #print "len(interp_taps) =", len(interp_taps)
+ self.interpolator = gr.interp_fir_filter_fff (interp_factor, interp_taps)
+
+ self.preemph = fm_preemph (quad_rate, tau=tau)
+
+ k = 2 * math.pi * max_dev / quad_rate
+ self.modulator = gr.frequency_modulator_fc (k)
+
+ if do_interp:
+ self.connect (self, self.interpolator, self.preemph, self.modulator, self)
+ else:
+ self.connect(self, self.preemph, self.modulator, self)
+
+
+class ctcss_gen_f(gr.hier_block2):
+ def __init__(self, sample_rate, tone_freq):
+ gr.hier_block2.__init__(self, "ctcss_gen_f",
+ gr.io_signature(0, 0, 0), # Input signature
+ gr.io_signature(1, 1, gr.sizeof_float)) # Output signature
+
+ self.plgen = gr.sig_source_f(sample_rate, gr.GR_SIN_WAVE, tone_freq, 0.1, 0.0)
+ self.connect(self.plgen, self)
diff --git a/gnuradio-core/src/python/gnuradio/blks2impl/pfb_arb_resampler.py b/gnuradio-core/src/python/gnuradio/blks2impl/pfb_arb_resampler.py
new file mode 100644
index 000000000..e83c327fc
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/blks2impl/pfb_arb_resampler.py
@@ -0,0 +1,128 @@
+#!/usr/bin/env python
+#
+# Copyright 2009 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr, optfir
+
+class pfb_arb_resampler_ccf(gr.hier_block2):
+ '''
+ Convenience wrapper for the polyphase filterbank arbitrary resampler.
+
+ The block takes a single complex stream in and outputs a single complex
+ stream out. As such, it requires no extra glue to handle the input/output
+ streams. This block is provided to be consistent with the interface to the
+ other PFB block.
+ '''
+ def __init__(self, rate, taps=None, flt_size=32, atten=100):
+ gr.hier_block2.__init__(self, "pfb_arb_resampler_ccf",
+ gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature
+ gr.io_signature(1, 1, gr.sizeof_gr_complex)) # Output signature
+
+ self._rate = rate
+ self._size = flt_size
+
+ if taps is not None:
+ self._taps = taps
+ else:
+ # Create a filter that covers the full bandwidth of the input signal
+ bw = 0.4
+ tb = 0.2
+ ripple = 0.1
+ #self._taps = gr.firdes.low_pass_2(self._size, self._size, bw, tb, atten)
+ made = False
+ while not made:
+ try:
+ self._taps = optfir.low_pass(self._size, self._size, bw, bw+tb, ripple, atten)
+ made = True
+ except RuntimeError:
+ ripple += 0.01
+ made = False
+ print("Warning: set ripple to %.4f dB. If this is a problem, adjust the attenuation or create your own filter taps." % (ripple))
+
+ # Build in an exit strategy; if we've come this far, it ain't working.
+ if(ripple >= 1.0):
+ raise RuntimeError("optfir could not generate an appropriate filter.")
+
+ self.pfb = gr.pfb_arb_resampler_ccf(self._rate, self._taps, self._size)
+ #print "PFB has %d taps\n" % (len(self._taps),)
+
+ self.connect(self, self.pfb)
+ self.connect(self.pfb, self)
+
+ # Note -- set_taps not implemented in base class yet
+ def set_taps(self, taps):
+ self.pfb.set_taps(taps)
+
+ def set_rate(self, rate):
+ self.pfb.set_rate(rate)
+
+
+class pfb_arb_resampler_fff(gr.hier_block2):
+ '''
+ Convenience wrapper for the polyphase filterbank arbitrary resampler.
+
+ The block takes a single float stream in and outputs a single float
+ stream out. As such, it requires no extra glue to handle the input/output
+ streams. This block is provided to be consistent with the interface to the
+ other PFB block.
+ '''
+ def __init__(self, rate, taps=None, flt_size=32, atten=100):
+ gr.hier_block2.__init__(self, "pfb_arb_resampler_fff",
+ gr.io_signature(1, 1, gr.sizeof_float), # Input signature
+ gr.io_signature(1, 1, gr.sizeof_float)) # Output signature
+
+ self._rate = rate
+ self._size = flt_size
+
+ if taps is not None:
+ self._taps = taps
+ else:
+ # Create a filter that covers the full bandwidth of the input signal
+ bw = 0.4
+ tb = 0.2
+ ripple = 0.1
+ #self._taps = gr.firdes.low_pass_2(self._size, self._size, bw, tb, atten)
+ made = False
+ while not made:
+ try:
+ self._taps = optfir.low_pass(self._size, self._size, bw, bw+tb, ripple, atten)
+ made = True
+ except RuntimeError:
+ ripple += 0.01
+ made = False
+ print("Warning: set ripple to %.4f dB. If this is a problem, adjust the attenuation or create your own filter taps." % (ripple))
+
+ # Build in an exit strategy; if we've come this far, it ain't working.
+ if(ripple >= 1.0):
+ raise RuntimeError("optfir could not generate an appropriate filter.")
+
+ self.pfb = gr.pfb_arb_resampler_fff(self._rate, self._taps, self._size)
+ #print "PFB has %d taps\n" % (len(self._taps),)
+
+ self.connect(self, self.pfb)
+ self.connect(self.pfb, self)
+
+ # Note -- set_taps not implemented in base class yet
+ def set_taps(self, taps):
+ self.pfb.set_taps(taps)
+
+ def set_rate(self, rate):
+ self.pfb.set_rate(rate)
diff --git a/gnuradio-core/src/python/gnuradio/blks2impl/pfb_channelizer.py b/gnuradio-core/src/python/gnuradio/blks2impl/pfb_channelizer.py
new file mode 100644
index 000000000..4bbe1bec6
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/blks2impl/pfb_channelizer.py
@@ -0,0 +1,73 @@
+#!/usr/bin/env python
+#
+# Copyright 2009,2010 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr, optfir
+
+class pfb_channelizer_ccf(gr.hier_block2):
+ '''
+ Make a Polyphase Filter channelizer (complex in, complex out, floating-point taps)
+
+ This simplifies the interface by allowing a single input stream to connect to this block.
+ It will then output a stream for each channel.
+ '''
+ def __init__(self, numchans, taps=None, oversample_rate=1, atten=100):
+ gr.hier_block2.__init__(self, "pfb_channelizer_ccf",
+ gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature
+ gr.io_signature(numchans, numchans, gr.sizeof_gr_complex)) # Output signature
+
+ self._nchans = numchans
+ self._oversample_rate = oversample_rate
+
+ if taps is not None:
+ self._taps = taps
+ else:
+ # Create a filter that covers the full bandwidth of the input signal
+ bw = 0.4
+ tb = 0.2
+ ripple = 0.1
+ made = False
+ while not made:
+ try:
+ self._taps = optfir.low_pass(1, self._nchans, bw, bw+tb, ripple, atten)
+ made = True
+ except RuntimeError:
+ ripple += 0.01
+ made = False
+ print("Warning: set ripple to %.4f dB. If this is a problem, adjust the attenuation or create your own filter taps." % (ripple))
+
+ # Build in an exit strategy; if we've come this far, it ain't working.
+ if(ripple >= 1.0):
+ raise RuntimeError("optfir could not generate an appropriate filter.")
+
+ self.s2ss = gr.stream_to_streams(gr.sizeof_gr_complex, self._nchans)
+ self.pfb = gr.pfb_channelizer_ccf(self._nchans, self._taps,
+ self._oversample_rate)
+ self.connect(self, self.s2ss)
+
+ for i in xrange(self._nchans):
+ self.connect((self.s2ss,i), (self.pfb,i))
+ self.connect((self.pfb,i), (self,i))
+
+ def set_channel_map(self, newmap):
+ self.pfb.set_channel_map(newmap)
+
+
diff --git a/gnuradio-core/src/python/gnuradio/blks2impl/pfb_decimator.py b/gnuradio-core/src/python/gnuradio/blks2impl/pfb_decimator.py
new file mode 100644
index 000000000..adcdfe9ba
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/blks2impl/pfb_decimator.py
@@ -0,0 +1,69 @@
+#!/usr/bin/env python
+#
+# Copyright 2009 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr, optfir
+
+class pfb_decimator_ccf(gr.hier_block2):
+ '''
+ Make a Polyphase Filter decimator (complex in, complex out, floating-point taps)
+
+ This simplifies the interface by allowing a single input stream to connect to this block.
+ It will then output a stream that is the decimated output stream.
+ '''
+ def __init__(self, decim, taps=None, channel=0, atten=100):
+ gr.hier_block2.__init__(self, "pfb_decimator_ccf",
+ gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature
+ gr.io_signature(1, 1, gr.sizeof_gr_complex)) # Output signature
+
+ self._decim = decim
+ self._channel = channel
+
+ if taps is not None:
+ self._taps = taps
+ else:
+ # Create a filter that covers the full bandwidth of the input signal
+ bw = 0.4
+ tb = 0.2
+ ripple = 0.1
+ made = False
+ while not made:
+ try:
+ self._taps = optfir.low_pass(1, self._decim, bw, bw+tb, ripple, atten)
+ made = True
+ except RuntimeError:
+ ripple += 0.01
+ made = False
+ print("Warning: set ripple to %.4f dB. If this is a problem, adjust the attenuation or create your own filter taps." % (ripple))
+
+ # Build in an exit strategy; if we've come this far, it ain't working.
+ if(ripple >= 1.0):
+ raise RuntimeError("optfir could not generate an appropriate filter.")
+
+ self.s2ss = gr.stream_to_streams(gr.sizeof_gr_complex, self._decim)
+ self.pfb = gr.pfb_decimator_ccf(self._decim, self._taps, self._channel)
+
+ self.connect(self, self.s2ss)
+
+ for i in xrange(self._decim):
+ self.connect((self.s2ss,i), (self.pfb,i))
+
+ self.connect(self.pfb, self)
diff --git a/gnuradio-core/src/python/gnuradio/blks2impl/pfb_interpolator.py b/gnuradio-core/src/python/gnuradio/blks2impl/pfb_interpolator.py
new file mode 100644
index 000000000..5492dfcac
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/blks2impl/pfb_interpolator.py
@@ -0,0 +1,70 @@
+#!/usr/bin/env python
+#
+# Copyright 2009 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr, optfir
+
+class pfb_interpolator_ccf(gr.hier_block2):
+ '''
+ Make a Polyphase Filter interpolator (complex in, complex out, floating-point taps)
+
+ The block takes a single complex stream in and outputs a single complex
+ stream out. As such, it requires no extra glue to handle the input/output
+ streams. This block is provided to be consistent with the interface to the
+ other PFB block.
+ '''
+ def __init__(self, interp, taps=None, atten=100):
+ gr.hier_block2.__init__(self, "pfb_interpolator_ccf",
+ gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature
+ gr.io_signature(1, 1, gr.sizeof_gr_complex)) # Output signature
+
+ self._interp = interp
+ self._taps = taps
+
+ if taps is not None:
+ self._taps = taps
+ else:
+ # Create a filter that covers the full bandwidth of the input signal
+ bw = 0.4
+ tb = 0.2
+ ripple = 0.99
+ made = False
+ while not made:
+ try:
+ self._taps = optfir.low_pass(self._interp, self._interp, bw, bw+tb, ripple, atten)
+ made = True
+ except RuntimeError:
+ ripple += 0.01
+ made = False
+ print("Warning: set ripple to %.4f dB. If this is a problem, adjust the attenuation or create your own filter taps." % (ripple))
+
+ # Build in an exit strategy; if we've come this far, it ain't working.
+ if(ripple >= 1.0):
+ raise RuntimeError("optfir could not generate an appropriate filter.")
+
+ self.pfb = gr.pfb_interpolator_ccf(self._interp, self._taps)
+
+ self.connect(self, self.pfb)
+ self.connect(self.pfb, self)
+
+
+
+
diff --git a/gnuradio-core/src/python/gnuradio/blks2impl/rational_resampler.py b/gnuradio-core/src/python/gnuradio/blks2impl/rational_resampler.py
new file mode 100644
index 000000000..eea12af95
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/blks2impl/rational_resampler.py
@@ -0,0 +1,131 @@
+#
+# Copyright 2005,2007 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr, gru
+
+_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
+ """
+
+ 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
+ )
+
+ return taps
+
+
+
+class _rational_resampler_base(gr.hier_block2):
+ """
+ base class for all rational resampler variants.
+ """
+ def __init__(self, resampler_base,
+ 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 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_block2.__init__(self, "rational_resampler",
+ gr.io_signature(1, 1, resampler.input_signature().sizeof_stream_item(0)),
+ gr.io_signature(1, 1, resampler.output_signature().sizeof_stream_item(0)))
+
+ self.connect(self, resampler, self)
+
+
+class rational_resampler_fff(_rational_resampler_base):
+ def __init__(self, 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,
+ interpolation, decimation, taps, fractional_bw)
+
+class rational_resampler_ccf(_rational_resampler_base):
+ def __init__(self, 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,
+ interpolation, decimation, taps, fractional_bw)
+
+class rational_resampler_ccc(_rational_resampler_base):
+ def __init__(self, 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,
+ interpolation, decimation, taps, fractional_bw)
diff --git a/gnuradio-core/src/python/gnuradio/blks2impl/standard_squelch.py b/gnuradio-core/src/python/gnuradio/blks2impl/standard_squelch.py
new file mode 100644
index 000000000..bd7fb535a
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/blks2impl/standard_squelch.py
@@ -0,0 +1,76 @@
+#
+# Copyright 2005,2007 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+import math
+from gnuradio import gr, optfir
+
+class standard_squelch(gr.hier_block2):
+ def __init__(self, audio_rate):
+ gr.hier_block2.__init__(self, "standard_squelch",
+ gr.io_signature(1, 1, gr.sizeof_float), # Input signature
+ gr.io_signature(1, 1, gr.sizeof_float)) # Output signature
+
+ self.input_node = gr.add_const_ff(0) # FIXME kludge
+
+ self.low_iir = gr.iir_filter_ffd((0.0193,0,-0.0193),(1,1.9524,-0.9615))
+ self.low_square = gr.multiply_ff()
+ self.low_smooth = gr.single_pole_iir_filter_ff(1/(0.01*audio_rate)) # 100ms time constant
+
+ self.hi_iir = gr.iir_filter_ffd((0.0193,0,-0.0193),(1,1.3597,-0.9615))
+ self.hi_square = gr.multiply_ff()
+ self.hi_smooth = gr.single_pole_iir_filter_ff(1/(0.01*audio_rate))
+
+ self.sub = gr.sub_ff();
+ self.add = gr.add_ff();
+ self.gate = gr.threshold_ff(0.3,0.43,0)
+ self.squelch_lpf = gr.single_pole_iir_filter_ff(1/(0.01*audio_rate))
+
+ self.div = gr.divide_ff()
+ self.squelch_mult = gr.multiply_ff()
+
+ self.connect (self, self.input_node)
+ self.connect (self.input_node, (self.squelch_mult, 0))
+
+ self.connect (self.input_node,self.low_iir)
+ self.connect (self.low_iir,(self.low_square,0))
+ self.connect (self.low_iir,(self.low_square,1))
+ self.connect (self.low_square,self.low_smooth,(self.sub,0))
+ self.connect (self.low_smooth, (self.add,0))
+
+ self.connect (self.input_node,self.hi_iir)
+ self.connect (self.hi_iir,(self.hi_square,0))
+ self.connect (self.hi_iir,(self.hi_square,1))
+ self.connect (self.hi_square,self.hi_smooth,(self.sub,1))
+ self.connect (self.hi_smooth, (self.add,1))
+
+ self.connect (self.sub, (self.div, 0))
+ self.connect (self.add, (self.div, 1))
+ self.connect (self.div, self.gate, self.squelch_lpf, (self.squelch_mult,1))
+ self.connect (self.squelch_mult, self)
+
+ def set_threshold(self, threshold):
+ self.gate.set_hi(threshold)
+
+ def threshold(self):
+ return self.gate.hi()
+
+ def squelch_range(self):
+ return (0.0, 1.0, 1.0/100)
diff --git a/gnuradio-core/src/python/gnuradio/blks2impl/stream_to_vector_decimator.py b/gnuradio-core/src/python/gnuradio/blks2impl/stream_to_vector_decimator.py
new file mode 100644
index 000000000..8f75729c9
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/blks2impl/stream_to_vector_decimator.py
@@ -0,0 +1,93 @@
+#
+# Copyright 2008 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr
+
+class stream_to_vector_decimator(gr.hier_block2):
+ """
+ Convert the stream to a vector, decimate the vector stream to achieve the vector rate.
+ """
+
+ def __init__(self, item_size, sample_rate, vec_rate, vec_len):
+ """
+ Create the block chain.
+ @param item_size the number of bytes per sample
+ @param sample_rate the rate of incoming samples
+ @param vec_rate the rate of outgoing vectors (same units as sample_rate)
+ @param vec_len the length of the outgoing vectors in items
+ """
+ self._vec_rate = vec_rate
+ self._vec_len = vec_len
+ self._sample_rate = sample_rate
+
+ gr.hier_block2.__init__(self, "stream_to_vector_decimator",
+ gr.io_signature(1, 1, item_size), # Input signature
+ gr.io_signature(1, 1, item_size*vec_len)) # Output signature
+
+ s2v = gr.stream_to_vector(item_size, vec_len)
+ self.one_in_n = gr.keep_one_in_n(item_size*vec_len, 1)
+ self._update_decimator()
+ self.connect(self, s2v, self.one_in_n, self)
+
+ def set_sample_rate(self, sample_rate):
+ """
+ Set the new sampling rate and update the decimator.
+ @param sample_rate the new rate
+ """
+ self._sample_rate = sample_rate
+ self._update_decimator()
+
+ def set_vec_rate(self, vec_rate):
+ """
+ Set the new vector rate and update the decimator.
+ @param vec_rate the new rate
+ """
+ self._vec_rate = vec_rate
+ self._update_decimator()
+
+ def set_decimation(self, decim):
+ """
+ Set the decimation parameter directly.
+ @param decim the new decimation
+ """
+ self._decim = max(1, int(round(decim)))
+ self.one_in_n.set_n(self._decim)
+
+ def _update_decimator(self):
+ self.set_decimation(self._sample_rate/self._vec_len/self._vec_rate)
+
+ def decimation(self):
+ """
+ Returns the actual decimation.
+ """
+ return self._decim
+
+ def sample_rate(self):
+ """
+ Returns configured sample rate.
+ """
+ return self._sample_rate
+
+ def frame_rate(self):
+ """
+ Returns actual frame rate
+ """
+ return self._sample_rate/self._vec_len/self._decim
diff --git a/gnuradio-core/src/python/gnuradio/blks2impl/wfm_rcv.py b/gnuradio-core/src/python/gnuradio/blks2impl/wfm_rcv.py
new file mode 100644
index 000000000..d1cbcf912
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/blks2impl/wfm_rcv.py
@@ -0,0 +1,69 @@
+#
+# Copyright 2005,2007 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr
+from gnuradio.blks2impl.fm_emph import fm_deemph
+import math
+
+class wfm_rcv(gr.hier_block2):
+ def __init__ (self, quad_rate, audio_decimation):
+ """
+ Hierarchical block for demodulating a broadcast FM signal.
+
+ The input is the downconverted complex baseband signal (gr_complex).
+ The output is the demodulated audio (float).
+
+ @param quad_rate: input sample rate of complex baseband input.
+ @type quad_rate: float
+ @param audio_decimation: how much to decimate quad_rate to get to audio.
+ @type audio_decimation: integer
+ """
+ gr.hier_block2.__init__(self, "wfm_rcv",
+ gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature
+ gr.io_signature(1, 1, gr.sizeof_float)) # Output signature
+
+ volume = 20.
+
+ max_dev = 75e3
+ fm_demod_gain = quad_rate/(2*math.pi*max_dev)
+ audio_rate = quad_rate / audio_decimation
+
+
+ # We assign to self so that outsiders can grab the demodulator
+ # if they need to. E.g., to plot its output.
+ #
+ # input: complex; output: float
+ self.fm_demod = gr.quadrature_demod_cf (fm_demod_gain)
+
+ # input: float; output: float
+ self.deemph = fm_deemph (audio_rate)
+
+ # compute FIR filter taps for audio filter
+ width_of_transition_band = audio_rate / 32
+ audio_coeffs = gr.firdes.low_pass (1.0, # gain
+ quad_rate, # sampling rate
+ audio_rate/2 - width_of_transition_band,
+ width_of_transition_band,
+ gr.firdes.WIN_HAMMING)
+ # input: float; output: float
+ self.audio_filter = gr.fir_filter_fff (audio_decimation, audio_coeffs)
+
+ self.connect (self, self.fm_demod, self.audio_filter, self.deemph, self)
diff --git a/gnuradio-core/src/python/gnuradio/blks2impl/wfm_rcv_fmdet.py b/gnuradio-core/src/python/gnuradio/blks2impl/wfm_rcv_fmdet.py
new file mode 100755
index 000000000..e229bcc2e
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/blks2impl/wfm_rcv_fmdet.py
@@ -0,0 +1,216 @@
+#
+# Copyright 2005,2006 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr
+from gnuradio.blks2impl.fm_emph import fm_deemph
+import math
+
+class wfm_rcv_fmdet(gr.hier_block2):
+ def __init__ (self, demod_rate, audio_decimation):
+ """
+ Hierarchical block for demodulating a broadcast FM signal.
+
+ The input is the downconverted complex baseband signal
+ (gr_complex). The output is two streams of the demodulated
+ audio (float) 0=Left, 1=Right.
+
+ @param demod_rate: input sample rate of complex baseband input.
+ @type demod_rate: float
+ @param audio_decimation: how much to decimate demod_rate to get to audio.
+ @type audio_decimation: integer
+ """
+ gr.hier_block2.__init__(self, "wfm_rcv_fmdet",
+ gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature
+ gr.io_signature(2, 2, gr.sizeof_float)) # Output signature
+ lowfreq = -125e3/demod_rate
+ highfreq = 125e3/demod_rate
+ 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
+
+ self.fm_demod = gr.fmdet_cf (demod_rate, lowfreq, highfreq, 0.05)
+
+ # input: float; output: float
+ self.deemph_Left = fm_deemph (audio_rate)
+ self.deemph_Right = fm_deemph (audio_rate)
+
+ # compute FIR filter taps for audio filter
+ width_of_transition_band = audio_rate / 32
+ audio_coeffs = gr.firdes.low_pass (1.0 , # gain
+ demod_rate, # sampling rate
+ 15000 ,
+ width_of_transition_band,
+ gr.firdes.WIN_HAMMING)
+
+ # input: float; output: float
+ self.audio_filter = gr.fir_filter_fff (audio_decimation, audio_coeffs)
+ if 1:
+ # Pick off the stereo carrier/2 with this filter. It
+ # attenuated 10 dB so apply 10 dB gain We pick off the
+ # negative frequency half because we want to base band by
+ # it!
+ ## NOTE THIS WAS HACKED TO OFFSET INSERTION LOSS DUE TO
+ ## DEEMPHASIS
+
+ stereo_carrier_filter_coeffs = gr.firdes.complex_band_pass(10.0,
+ demod_rate,
+ -19020,
+ -18980,
+ width_of_transition_band,
+ gr.firdes.WIN_HAMMING)
+
+ #print "len stereo carrier filter = ",len(stereo_carrier_filter_coeffs)
+ #print "stereo carrier filter ", stereo_carrier_filter_coeffs
+ #print "width of transition band = ",width_of_transition_band, " audio rate = ", audio_rate
+
+ # Pick off the double side band suppressed carrier
+ # Left-Right audio. It is attenuated 10 dB so apply 10 dB
+ # gain
+
+ stereo_dsbsc_filter_coeffs = gr.firdes.complex_band_pass(20.0,
+ demod_rate,
+ 38000-15000/2,
+ 38000+15000/2,
+ width_of_transition_band,
+ gr.firdes.WIN_HAMMING)
+ #print "len stereo dsbsc filter = ",len(stereo_dsbsc_filter_coeffs)
+ #print "stereo dsbsc filter ", stereo_dsbsc_filter_coeffs
+
+ # construct overlap add filter system from coefficients
+ # for stereo carrier
+ self.stereo_carrier_filter = gr.fir_filter_fcc(audio_decimation,
+ stereo_carrier_filter_coeffs)
+
+ # carrier is twice the picked off carrier so arrange to do
+ # a commplex multiply
+ self.stereo_carrier_generator = gr.multiply_cc();
+
+ # Pick off the rds signal
+ stereo_rds_filter_coeffs = gr.firdes.complex_band_pass(30.0,
+ demod_rate,
+ 57000 - 1500,
+ 57000 + 1500,
+ width_of_transition_band,
+ gr.firdes.WIN_HAMMING)
+ #print "len stereo dsbsc filter = ",len(stereo_dsbsc_filter_coeffs)
+ #print "stereo dsbsc filter ", stereo_dsbsc_filter_coeffs
+ # construct overlap add filter system from coefficients for stereo carrier
+
+ self.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);
+
+ loop_bw = 2*math.pi/100.0
+ max_freq = -2.0*math.pi*18990/audio_rate;
+ min_freq = -2.0*math.pi*19010/audio_rate;
+ self.stereo_carrier_pll_recovery = gr.pll_refout_cc(loop_bw,
+ max_freq,
+ min_freq);
+
+ #self.stereo_carrier_pll_recovery.squelch_enable(False)
+ ##pll_refout does not have squelch yet, so disabled for
+ #now
+
+ # set up mixer (multiplier) to get the L-R signal at
+ # baseband
+
+ self.stereo_basebander = gr.multiply_cc();
+
+ # pick off the real component of the basebanded L-R
+ # signal. The imaginary SHOULD be zero
+
+ self.LmR_real = gr.complex_to_real();
+ self.Make_Left = gr.add_ff();
+ self.Make_Right = gr.sub_ff();
+
+ self.stereo_dsbsc_filter = gr.fir_filter_fcc(audio_decimation,
+ stereo_dsbsc_filter_coeffs)
+
+
+ if 1:
+
+ # send the real signal to complex filter to pick off the
+ # carrier and then to one side of a multiplier
+ self.connect (self, self.fm_demod, self.stereo_carrier_filter,
+ self.stereo_carrier_pll_recovery,
+ (self.stereo_carrier_generator,0))
+
+ # send the already filtered carrier to the otherside of the carrier
+ # the resulting signal from this multiplier is the carrier
+ # with correct phase but at -38000 Hz.
+ self.connect (self.stereo_carrier_pll_recovery, (self.stereo_carrier_generator,1))
+
+ # send the new carrier to one side of the mixer (multiplier)
+ self.connect (self.stereo_carrier_generator, (self.stereo_basebander,0))
+
+ # send the demphasized audio to the DSBSC pick off filter, the complex
+ # DSBSC signal at +38000 Hz is sent to the other side of the mixer/multiplier
+ # the result is BASEBANDED DSBSC with phase zero!
+ self.connect (self.fm_demod,self.stereo_dsbsc_filter, (self.stereo_basebander,1))
+
+ # Pick off the real part since the imaginary is
+ # theoretically zero and then to one side of a summer
+ self.connect (self.stereo_basebander, self.LmR_real, (self.Make_Left,0))
+
+ #take the same real part of the DSBSC baseband signal and
+ #send it to negative side of a subtracter
+ self.connect (self.LmR_real,(self.Make_Right,1))
+
+ # Make rds carrier by taking the squared pilot tone and
+ # multiplying by pilot tone
+ self.connect (self.stereo_basebander,(self.rds_carrier_generator,0))
+ self.connect (self.stereo_carrier_pll_recovery,(self.rds_carrier_generator,1))
+
+ # take signal, filter off rds, send into mixer 0 channel
+ self.connect (self.fm_demod,self.rds_signal_filter,(self.rds_signal_generator,0))
+
+ # take rds_carrier_generator output and send into mixer 1
+ # channel
+ self.connect (self.rds_carrier_generator,(self.rds_signal_generator,1))
+
+ # send basebanded rds signal and send into "processor"
+ # which for now is a null sink
+ self.connect (self.rds_signal_generator,self_rds_signal_processor)
+
+
+ if 1:
+ # pick off the audio, L+R that is what we used to have and
+ # send it to the summer
+ self.connect(self.fm_demod, self.audio_filter, (self.Make_Left, 1))
+
+ # take the picked off L+R audio and send it to the PLUS
+ # side of the subtractor
+ self.connect(self.audio_filter,(self.Make_Right, 0))
+
+ # The result of Make_Left gets (L+R) + (L-R) and results in 2*L
+ # The result of Make_Right gets (L+R) - (L-R) and results in 2*R
+ self.connect(self.Make_Left , self.deemph_Left, (self, 0))
+ self.connect(self.Make_Right, self.deemph_Right, (self, 1))
+
+ # NOTE: mono support will require variable number of outputs in hier_block2s
+ # See ticket:174 in Trac database
+ #else:
+ # self.connect (self.fm_demod, self.audio_filter, self)
diff --git a/gnuradio-core/src/python/gnuradio/blks2impl/wfm_rcv_pll.py b/gnuradio-core/src/python/gnuradio/blks2impl/wfm_rcv_pll.py
new file mode 100644
index 000000000..d4ce6d223
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/blks2impl/wfm_rcv_pll.py
@@ -0,0 +1,190 @@
+#
+# Copyright 2005,2006 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr
+from gnuradio.blks2impl.fm_emph import fm_deemph
+import math
+
+class wfm_rcv_pll(gr.hier_block2):
+ def __init__ (self, demod_rate, audio_decimation):
+ """
+ Hierarchical block for demodulating a broadcast FM signal.
+
+ The input is the downconverted complex baseband signal (gr_complex).
+ The output is two streams of the demodulated audio (float) 0=Left, 1=Right.
+
+ @param demod_rate: input sample rate of complex baseband input.
+ @type demod_rate: float
+ @param audio_decimation: how much to decimate demod_rate to get to audio.
+ @type audio_decimation: integer
+ """
+ gr.hier_block2.__init__(self, "wfm_rcv_pll",
+ gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature
+ gr.io_signature(2, 2, gr.sizeof_float)) # Output signature
+ bandwidth = 250e3
+ 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
+ loop_bw = 2*math.pi/100.0
+ max_freq = 2.0*math.pi*90e3/demod_rate
+ self.fm_demod = gr.pll_freqdet_cf (loop_bw, max_freq,-max_freq)
+
+ # input: float; output: float
+ self.deemph_Left = fm_deemph (audio_rate)
+ self.deemph_Right = fm_deemph (audio_rate)
+
+ # compute FIR filter taps for audio filter
+ width_of_transition_band = audio_rate / 32
+ audio_coeffs = gr.firdes.low_pass (1.0 , # gain
+ demod_rate, # sampling rate
+ 15000 ,
+ width_of_transition_band,
+ gr.firdes.WIN_HAMMING)
+ # input: float; output: float
+ self.audio_filter = gr.fir_filter_fff (audio_decimation, audio_coeffs)
+ if 1:
+ # Pick off the stereo carrier/2 with this filter. It attenuated 10 dB so apply 10 dB gain
+ # We pick off the negative frequency half because we want to base band by it!
+ ## NOTE THIS WAS HACKED TO OFFSET INSERTION LOSS DUE TO DEEMPHASIS
+
+ stereo_carrier_filter_coeffs = gr.firdes.complex_band_pass(10.0,
+ demod_rate,
+ -19020,
+ -18980,
+ width_of_transition_band,
+ gr.firdes.WIN_HAMMING)
+
+ #print "len stereo carrier filter = ",len(stereo_carrier_filter_coeffs)
+ #print "stereo carrier filter ", stereo_carrier_filter_coeffs
+ #print "width of transition band = ",width_of_transition_band, " audio rate = ", audio_rate
+
+ # Pick off the double side band suppressed carrier Left-Right audio. It is attenuated 10 dB so apply 10 dB gain
+
+ stereo_dsbsc_filter_coeffs = gr.firdes.complex_band_pass(20.0,
+ demod_rate,
+ 38000-15000/2,
+ 38000+15000/2,
+ width_of_transition_band,
+ gr.firdes.WIN_HAMMING)
+ #print "len stereo dsbsc filter = ",len(stereo_dsbsc_filter_coeffs)
+ #print "stereo dsbsc filter ", stereo_dsbsc_filter_coeffs
+ # construct overlap add filter system from coefficients for stereo carrier
+
+ self.stereo_carrier_filter = gr.fir_filter_fcc(audio_decimation, stereo_carrier_filter_coeffs)
+
+ # carrier is twice the picked off carrier so arrange to do a commplex multiply
+
+ self.stereo_carrier_generator = gr.multiply_cc();
+
+ # Pick off the rds signal
+
+ stereo_rds_filter_coeffs = gr.firdes.complex_band_pass(30.0,
+ demod_rate,
+ 57000 - 1500,
+ 57000 + 1500,
+ width_of_transition_band,
+ gr.firdes.WIN_HAMMING)
+ #print "len stereo dsbsc filter = ",len(stereo_dsbsc_filter_coeffs)
+ #print "stereo dsbsc filter ", stereo_dsbsc_filter_coeffs
+ # construct overlap add filter system from coefficients for stereo carrier
+
+ self.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);
+
+
+
+ loop_bw = 2*math.pi/100.0
+ max_freq = -2.0*math.pi*18990/audio_rate;
+ min_freq = -2.0*math.pi*19010/audio_rate;
+
+ self.stereo_carrier_pll_recovery = gr.pll_refout_cc(loop_bw, max_freq, min_freq);
+ #self.stereo_carrier_pll_recovery.squelch_enable(False) #pll_refout does not have squelch yet, so disabled for now
+
+
+ # set up mixer (multiplier) to get the L-R signal at baseband
+
+ self.stereo_basebander = gr.multiply_cc();
+
+ # pick off the real component of the basebanded L-R signal. The imaginary SHOULD be zero
+
+ self.LmR_real = gr.complex_to_real();
+ self.Make_Left = gr.add_ff();
+ self.Make_Right = gr.sub_ff();
+
+ self.stereo_dsbsc_filter = gr.fir_filter_fcc(audio_decimation, stereo_dsbsc_filter_coeffs)
+
+
+ if 1:
+
+ # send the real signal to complex filter to pick off the carrier and then to one side of a multiplier
+ self.connect (self, self.fm_demod,self.stereo_carrier_filter,self.stereo_carrier_pll_recovery, (self.stereo_carrier_generator,0))
+ # send the already filtered carrier to the otherside of the carrier
+ self.connect (self.stereo_carrier_pll_recovery, (self.stereo_carrier_generator,1))
+ # the resulting signal from this multiplier is the carrier with correct phase but at -38000 Hz.
+
+ # send the new carrier to one side of the mixer (multiplier)
+ self.connect (self.stereo_carrier_generator, (self.stereo_basebander,0))
+ # send the demphasized audio to the DSBSC pick off filter, the complex
+ # DSBSC signal at +38000 Hz is sent to the other side of the mixer/multiplier
+ self.connect (self.fm_demod,self.stereo_dsbsc_filter, (self.stereo_basebander,1))
+ # the result is BASEBANDED DSBSC with phase zero!
+
+ # Pick off the real part since the imaginary is theoretically zero and then to one side of a summer
+ self.connect (self.stereo_basebander, self.LmR_real, (self.Make_Left,0))
+ #take the same real part of the DSBSC baseband signal and send it to negative side of a subtracter
+ self.connect (self.LmR_real,(self.Make_Right,1))
+
+ # Make rds carrier by taking the squared pilot tone and multiplying by pilot tone
+ self.connect (self.stereo_basebander,(self.rds_carrier_generator,0))
+ self.connect (self.stereo_carrier_pll_recovery,(self.rds_carrier_generator,1))
+ # take signal, filter off rds, send into mixer 0 channel
+ self.connect (self.fm_demod,self.rds_signal_filter,(self.rds_signal_generator,0))
+ # take rds_carrier_generator output and send into mixer 1 channel
+ self.connect (self.rds_carrier_generator,(self.rds_signal_generator,1))
+ # send basebanded rds signal and send into "processor" which for now is a null sink
+ self.connect (self.rds_signal_generator,self_rds_signal_processor)
+
+
+ if 1:
+ # pick off the audio, L+R that is what we used to have and send it to the summer
+ self.connect(self.fm_demod, self.audio_filter, (self.Make_Left, 1))
+ # take the picked off L+R audio and send it to the PLUS side of the subtractor
+ self.connect(self.audio_filter,(self.Make_Right, 0))
+ # The result of Make_Left gets (L+R) + (L-R) and results in 2*L
+ # The result of Make_Right gets (L+R) - (L-R) and results in 2*R
+ self.connect(self.Make_Left , self.deemph_Left, (self, 0))
+ self.connect(self.Make_Right, self.deemph_Right, (self, 1))
+ # NOTE: mono support will require variable number of outputs in hier_block2s
+ # See ticket:174 in Trac database
+ #else:
+ # self.connect (self.fm_demod, self.audio_filter, self)
diff --git a/gnuradio-core/src/python/gnuradio/blks2impl/wfm_tx.py b/gnuradio-core/src/python/gnuradio/blks2impl/wfm_tx.py
new file mode 100644
index 000000000..3fcf98f89
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/blks2impl/wfm_tx.py
@@ -0,0 +1,79 @@
+#
+# Copyright 2005,2007 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+import math
+from gnuradio import gr, optfir
+from gnuradio.blks2impl.fm_emph import fm_preemph
+
+class wfm_tx(gr.hier_block2):
+ def __init__(self, audio_rate, quad_rate, tau=75e-6, max_dev=75e3):
+ """
+ Wide Band FM Transmitter.
+
+ Takes a single float input stream of audio samples in the range [-1,+1]
+ and produces a single FM modulated complex baseband output.
+
+ @param audio_rate: sample rate of audio stream, >= 16k
+ @type audio_rate: integer
+ @param quad_rate: sample rate of output stream
+ @type quad_rate: integer
+ @param tau: preemphasis time constant (default 75e-6)
+ @type tau: float
+ @param max_dev: maximum deviation in Hz (default 75e3)
+ @type max_dev: float
+
+ quad_rate must be an integer multiple of audio_rate.
+ """
+ gr.hier_block2.__init__(self, "wfm_tx",
+ gr.io_signature(1, 1, gr.sizeof_float), # Input signature
+ gr.io_signature(1, 1, gr.sizeof_gr_complex)) # Output signature
+
+ # FIXME audio_rate and quad_rate ought to be exact rationals
+ audio_rate = int(audio_rate)
+ quad_rate = int(quad_rate)
+
+ if quad_rate % audio_rate != 0:
+ raise ValueError, "quad_rate is not an integer multiple of audio_rate"
+
+
+ do_interp = audio_rate != quad_rate
+
+ if do_interp:
+ interp_factor = quad_rate / audio_rate
+ interp_taps = optfir.low_pass (interp_factor, # gain
+ quad_rate, # Fs
+ 16000, # passband cutoff
+ 18000, # stopband cutoff
+ 0.1, # passband ripple dB
+ 40) # stopband atten dB
+
+ print "len(interp_taps) =", len(interp_taps)
+ self.interpolator = gr.interp_fir_filter_fff (interp_factor, interp_taps)
+
+ self.preemph = fm_preemph (quad_rate, tau=tau)
+
+ k = 2 * math.pi * max_dev / quad_rate
+ self.modulator = gr.frequency_modulator_fc (k)
+
+ if do_interp:
+ self.connect (self, self.interpolator, self.preemph, self.modulator, self)
+ else:
+ self.connect(self, self.preemph, self.modulator, self)
diff --git a/gnuradio-core/src/python/gnuradio/eng_notation.py b/gnuradio-core/src/python/gnuradio/eng_notation.py
new file mode 100644
index 000000000..c552a45f5
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/eng_notation.py
@@ -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 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, 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
index 000000000..02e9b0b6d
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/eng_option.py
@@ -0,0 +1,62 @@
+#
+# Copyright 2004 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+'''Add support for engineering notation to optparse.OptionParser'''
+
+from copy import copy
+from optparse import Option, OptionValueError
+import eng_notation
+
+def check_eng_float (option, opt, value):
+ try:
+ return eng_notation.str_to_num(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), 'A:2' : (0, 2),
+ 'B' : (1, 0), 'B:0' : (1, 0), 'B:1' : (1, 1), 'B:2' : (1, 2) }
+ try:
+ return d[value.upper()]
+ except:
+ raise OptionValueError(
+ "option %s: invalid subdev: '%r', must be one of %s" % (opt, value, ', '.join(sorted(d.keys()))))
+
+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/CMakeLists.txt b/gnuradio-core/src/python/gnuradio/gr/CMakeLists.txt
new file mode 100644
index 000000000..da22a5f98
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/gr/CMakeLists.txt
@@ -0,0 +1,49 @@
+# Copyright 2010-2012 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+
+########################################################################
+include(GrPython)
+
+GR_PYTHON_INSTALL(FILES
+ __init__.py
+ exceptions.py
+ gateway.py
+ gr_threading.py
+ gr_threading_23.py
+ gr_threading_24.py
+ hier_block2.py
+ prefs.py
+ tag_utils.py
+ top_block.py
+ pubsub.py
+ DESTINATION ${GR_PYTHON_DIR}/gnuradio/gr
+ COMPONENT "core_python"
+)
+
+########################################################################
+# Handle the unit tests
+########################################################################
+if(ENABLE_TESTING)
+include(GrTest)
+file(GLOB py_qa_test_files "qa_*.py")
+foreach(py_qa_test_file ${py_qa_test_files})
+ get_filename_component(py_qa_test_name ${py_qa_test_file} NAME_WE)
+ GR_ADD_TEST(${py_qa_test_name} ${PYTHON_EXECUTABLE} ${PYTHON_DASH_B} ${py_qa_test_file})
+endforeach(py_qa_test_file)
+endif(ENABLE_TESTING)
diff --git a/gnuradio-core/src/python/gnuradio/gr/__init__.py b/gnuradio-core/src/python/gnuradio/gr/__init__.py
new file mode 100644
index 000000000..768d88595
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/gr/__init__.py
@@ -0,0 +1,116 @@
+#
+# Copyright 2003-2012 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+# The presence of this file turns this directory into a Python package
+
+# This is the main GNU Radio python module.
+# We pull the swig output and the other modules into the gnuradio.gr namespace
+
+from gnuradio_core import *
+from exceptions import *
+#from hier_block2 import *
+#from top_block import *
+from gateway import basic_block, sync_block, decim_block, interp_block
+from tag_utils import tag_to_python, tag_to_pmt
+
+import gras
+
+RT_OK = 0
+RT_NOT_IMPLEMENTED = 1
+RT_NO_PRIVS = 2
+RT_OTHER_ERROR = 3
+
+
+def enable_realtime_scheduling():
+ """
+ This call is for backward compat purposes.
+ See gras/thread_pool.hpp for greater options.
+ """
+
+ #any prio greater than 0 means realtime scheduling
+ prio_value = 0.5
+
+ #test that prio
+ if not gras.ThreadPool.test_thread_priority(prio_value):
+ return RT_NO_PRIVS
+
+ #create a new thread pool with thread priority set
+ config = gras.ThreadPoolConfig()
+ config.thread_priority = prio_value
+ tp = gras.ThreadPool(config)
+ tp.set_active()
+
+ return RT_OK
+
+class top_block(gras.TopBlock):
+ def __init__(self, name="Top"):
+ gras.TopBlock.__init__(self, name)
+
+ def lock(self):
+ pass
+
+ def unlock(self):
+ self.commit()
+
+ def start(self, *args):
+ if args: self.global_config().maximum_output_items = args[0]
+ gras.TopBlock.start(self)
+
+ def run(self, *args):
+ if args: self.global_config().maximum_output_items = args[0]
+ gras.TopBlock.run(self)
+
+class hier_block2(gras.HierBlock):
+ def __init__(self, name="Hier", in_sig=None, out_sig=None):
+ gras.HierBlock.__init__(self, name)
+
+ self.__in_sig = in_sig
+ self.__out_sig = out_sig
+
+ #backwards compatible silliness
+ import weakref
+ self._hb = weakref.proxy(self)
+
+ def lock(self):
+ pass
+
+ def unlock(self):
+ self.commit()
+
+ def input_signature(self): return self.__in_sig
+ def output_signature(self): return self.__out_sig
+
+# create a couple of aliases
+serial_to_parallel = stream_to_vector
+parallel_to_serial = vector_to_stream
+
+# Force the preference database to be initialized
+prefs = gr_prefs.singleton
+
+#alias old gr_add_vXX and gr_multiply_vXX
+add_vcc = add_cc
+add_vff = add_ff
+add_vii = add_ii
+add_vss = add_ss
+multiply_vcc = multiply_cc
+multiply_vff = multiply_ff
+multiply_vii = multiply_ii
+multiply_vss = multiply_ss
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
index 000000000..4fc10b721
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/gr/benchmark_filters.py
@@ -0,0 +1,75 @@
+#!/usr/bin/env python
+#
+# Copyright 2005,2006,2007 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+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
+
+ tb = gr.top_block()
+ 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)
+ tb.connect(src, head, op, dst)
+ start = time.time()
+ tb.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
index 000000000..dba04750b
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/gr/exceptions.py
@@ -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 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+
+class NotDAG (Exception):
+ """Not a directed acyclic graph"""
+ pass
+
+class CantHappen (Exception):
+ """Can't happen"""
+ pass
diff --git a/gnuradio-core/src/python/gnuradio/gr/gateway.py b/gnuradio-core/src/python/gnuradio/gr/gateway.py
new file mode 100644
index 000000000..53fda17a4
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/gr/gateway.py
@@ -0,0 +1,246 @@
+#
+# Copyright 2011-2012 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+import gnuradio_core as gr_core
+from gnuradio_core import io_signature, io_signaturev
+from gnuradio_core import gr_block_gw_message_type
+from gnuradio_core import block_gateway
+import numpy
+
+########################################################################
+# Magic to turn pointers into numpy arrays
+# http://docs.scipy.org/doc/numpy/reference/arrays.interface.html
+########################################################################
+def pointer_to_ndarray(addr, dtype, nitems):
+ class array_like:
+ __array_interface__ = {
+ 'data' : (int(addr), False),
+ 'typestr' : dtype.base.str,
+ 'descr' : dtype.base.descr,
+ 'shape' : (nitems,) + dtype.shape,
+ 'strides' : None,
+ 'version' : 3
+ }
+ return numpy.asarray(array_like()).view(dtype.base)
+
+########################################################################
+# Handler that does callbacks from C++
+########################################################################
+class gateway_handler(gr_core.feval_ll):
+
+ #dont put a constructor, it wont work
+
+ def init(self, callback):
+ self._callback = callback
+
+ def eval(self, arg):
+ try: self._callback()
+ except Exception as ex:
+ print("handler caught exception: %s"%ex)
+ import traceback; traceback.print_exc()
+ raise ex
+ return 0
+
+########################################################################
+# Handler that does callbacks from C++
+########################################################################
+class msg_handler(gr_core.feval_p):
+
+ #dont put a constructor, it wont work
+
+ def init(self, callback):
+ self._callback = callback
+
+ def eval(self, arg):
+ try: self._callback(arg)
+ except Exception as ex:
+ print("handler caught exception: %s"%ex)
+ import traceback; traceback.print_exc()
+ raise ex
+ return 0
+
+########################################################################
+# The guts that make this into a gr block
+########################################################################
+class gateway_block(object):
+
+ def __init__(self, name, in_sig, out_sig, work_type, factor):
+
+ #ensure that the sigs are iterable dtypes
+ def sig_to_dtype_sig(sig):
+ if sig is None: sig = ()
+ return map(numpy.dtype, sig)
+ self.__in_sig = sig_to_dtype_sig(in_sig)
+ self.__out_sig = sig_to_dtype_sig(out_sig)
+
+ #cache the ranges to iterate when dispatching work
+ self.__in_indexes = range(len(self.__in_sig))
+ self.__out_indexes = range(len(self.__out_sig))
+
+ #convert the signatures into gr.io_signatures
+ def sig_to_gr_io_sigv(sig):
+ if not len(sig): return io_signature(0, 0, 0)
+ return io_signaturev(len(sig), len(sig), [s.itemsize for s in sig])
+ gr_in_sig = sig_to_gr_io_sigv(self.__in_sig)
+ gr_out_sig = sig_to_gr_io_sigv(self.__out_sig)
+
+ #create internal gateway block
+ self.__handler = gateway_handler()
+ self.__handler.init(self.__gr_block_handle)
+ self.__gateway = block_gateway(
+ self.__handler, name, gr_in_sig, gr_out_sig, work_type, factor)
+ self.__message = self.__gateway.gr_block_message()
+
+ #dict to keep references to all message handlers
+ self.__msg_handlers = {}
+
+ #register gr_block functions
+ prefix = 'gr_block__'
+ for attr in [x for x in dir(self.__gateway) if x.startswith(prefix)]:
+ setattr(self, attr.replace(prefix, ''), getattr(self.__gateway, attr))
+ self.pop_msg_queue = lambda: gr_core.gr_block_gw_pop_msg_queue_safe(self.__gateway)
+
+ #gras version of the to_basic_block()
+ def to_element(self): return self.__gateway.to_element()
+
+ def to_basic_block(self):
+ """
+ Makes this block connectable by hier/top block python
+ """
+ return self.__gateway.to_basic_block()
+
+ def __gr_block_handle(self):
+ """
+ Dispatch tasks according to the action type specified in the message.
+ """
+ if self.__message.action == gr_block_gw_message_type.ACTION_GENERAL_WORK:
+ self.__message.general_work_args_return_value = self.general_work(
+
+ input_items=[pointer_to_ndarray(
+ self.__message.general_work_args_input_items[i],
+ self.__in_sig[i],
+ self.__message.general_work_args_ninput_items[i]
+ ) for i in self.__in_indexes],
+
+ output_items=[pointer_to_ndarray(
+ self.__message.general_work_args_output_items[i],
+ self.__out_sig[i],
+ self.__message.general_work_args_noutput_items
+ ) for i in self.__out_indexes],
+ )
+
+ elif self.__message.action == gr_block_gw_message_type.ACTION_WORK:
+ self.__message.work_args_return_value = self.work(
+
+ input_items=[pointer_to_ndarray(
+ self.__message.work_args_input_items[i],
+ self.__in_sig[i],
+ self.__message.work_args_ninput_items
+ ) for i in self.__in_indexes],
+
+ output_items=[pointer_to_ndarray(
+ self.__message.work_args_output_items[i],
+ self.__out_sig[i],
+ self.__message.work_args_noutput_items
+ ) for i in self.__out_indexes],
+ )
+
+ elif self.__message.action == gr_block_gw_message_type.ACTION_FORECAST:
+ self.forecast(
+ noutput_items=self.__message.forecast_args_noutput_items,
+ ninput_items_required=self.__message.forecast_args_ninput_items_required,
+ )
+
+ elif self.__message.action == gr_block_gw_message_type.ACTION_START:
+ self.__message.start_args_return_value = self.start()
+
+ elif self.__message.action == gr_block_gw_message_type.ACTION_STOP:
+ self.__message.stop_args_return_value = self.stop()
+
+ def forecast(self, noutput_items, ninput_items_required):
+ """
+ forecast is only called from a general block
+ this is the default implementation
+ """
+ for ninput_item in ninput_items_required:
+ ninput_item = noutput_items + self.history() - 1;
+ return
+
+ def general_work(self, *args, **kwargs):
+ """general work to be overloaded in a derived class"""
+ raise NotImplementedError("general work not implemented")
+
+ def work(self, *args, **kwargs):
+ """work to be overloaded in a derived class"""
+ raise NotImplementedError("work not implemented")
+
+ def start(self): return True
+ def stop(self): return True
+
+ def set_msg_handler(self, which_port, handler_func):
+ handler = msg_handler()
+ handler.init(handler_func)
+ self.__gateway.set_msg_handler_feval(which_port, handler)
+ # Save handler object in class so it's not garbage collected
+ self.__msg_handlers[which_port] = handler
+
+########################################################################
+# Wrappers for the user to inherit from
+########################################################################
+class basic_block(gateway_block):
+ def __init__(self, name, in_sig, out_sig):
+ gateway_block.__init__(self,
+ name=name,
+ in_sig=in_sig,
+ out_sig=out_sig,
+ work_type=gr_core.GR_BLOCK_GW_WORK_GENERAL,
+ factor=1, #not relevant factor
+ )
+
+class sync_block(gateway_block):
+ def __init__(self, name, in_sig, out_sig):
+ gateway_block.__init__(self,
+ name=name,
+ in_sig=in_sig,
+ out_sig=out_sig,
+ work_type=gr_core.GR_BLOCK_GW_WORK_SYNC,
+ factor=1,
+ )
+
+class decim_block(gateway_block):
+ def __init__(self, name, in_sig, out_sig, decim):
+ gateway_block.__init__(self,
+ name=name,
+ in_sig=in_sig,
+ out_sig=out_sig,
+ work_type=gr_core.GR_BLOCK_GW_WORK_DECIM,
+ factor=decim,
+ )
+
+class interp_block(gateway_block):
+ def __init__(self, name, in_sig, out_sig, interp):
+ gateway_block.__init__(self,
+ name=name,
+ in_sig=in_sig,
+ out_sig=out_sig,
+ work_type=gr_core.GR_BLOCK_GW_WORK_INTERP,
+ factor=interp,
+ )
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
index 000000000..5d6f0fdaf
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/gr/gr_threading.py
@@ -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 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from 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
index 000000000..dee8034c1
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/gr/gr_threading_23.py
@@ -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
index 000000000..8539bfc04
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/gr/gr_threading_24.py
@@ -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_block2.py b/gnuradio-core/src/python/gnuradio/gr/hier_block2.py
new file mode 100644
index 000000000..b95782238
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/gr/hier_block2.py
@@ -0,0 +1,129 @@
+#
+# Copyright 2006,2007 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio_core import hier_block2_swig
+try:
+ import pmt
+except ImportError:
+ from gruel import pmt
+
+#
+# This hack forces a 'has-a' relationship to look like an 'is-a' one.
+#
+# It allows Python classes to subclass this one, while passing through
+# method calls to the C++ class shared pointer from SWIG.
+#
+# It also allows us to intercept method calls if needed
+#
+class hier_block2(object):
+ """
+ Python wrapper around the C++ hierarchical block implementation.
+ Provides convenience functions and allows proper Python subclassing.
+ """
+
+ def __init__(self, name, input_signature, output_signature):
+ """
+ Create a hierarchical block with a given name and I/O signatures.
+ """
+ self._hb = hier_block2_swig(name, input_signature, output_signature)
+
+ def __getattr__(self, name):
+ """
+ Pass-through member requests to the C++ object.
+ """
+ if not hasattr(self, "_hb"):
+ raise RuntimeError("hier_block2: invalid state--did you forget to call gr.hier_block2.__init__ in a derived class?")
+ return getattr(self._hb, name)
+
+ def connect(self, *points):
+ """
+ Connect two or more block endpoints. An endpoint is either a (block, port)
+ tuple or a block instance. In the latter case, the port number is assumed
+ to be zero.
+
+ To connect the hierarchical block external inputs or outputs to internal block
+ inputs or outputs, use 'self' in the connect call.
+
+ If multiple arguments are provided, connect will attempt to wire them in series,
+ interpreting the endpoints as inputs or outputs as appropriate.
+ """
+
+ if len (points) < 1:
+ raise ValueError, ("connect requires at least one endpoint; %d provided." % (len (points),))
+ else:
+ if len(points) == 1:
+ self._hb.primitive_connect(points[0].to_basic_block())
+ else:
+ for i in range (1, len (points)):
+ self._connect(points[i-1], points[i])
+
+ def _connect(self, src, dst):
+ (src_block, src_port) = self._coerce_endpoint(src)
+ (dst_block, dst_port) = self._coerce_endpoint(dst)
+ self._hb.primitive_connect(src_block.to_basic_block(), src_port,
+ dst_block.to_basic_block(), dst_port)
+
+ def _coerce_endpoint(self, endp):
+ if hasattr(endp, 'to_basic_block'):
+ return (endp, 0)
+ else:
+ if hasattr(endp, "__getitem__") and len(endp) == 2:
+ return endp # Assume user put (block, port)
+ else:
+ raise ValueError("unable to coerce endpoint")
+
+ def disconnect(self, *points):
+ """
+ Disconnect two endpoints in the flowgraph.
+
+ To disconnect the hierarchical block external inputs or outputs to internal block
+ inputs or outputs, use 'self' in the connect call.
+
+ If more than two arguments are provided, they are disconnected successively.
+ """
+
+ if len (points) < 1:
+ raise ValueError, ("disconnect requires at least one endpoint; %d provided." % (len (points),))
+ else:
+ if len (points) == 1:
+ self._hb.primitive_disconnect(points[0].to_basic_block())
+ else:
+ for i in range (1, len (points)):
+ self._disconnect(points[i-1], points[i])
+
+ def _disconnect(self, src, dst):
+ (src_block, src_port) = self._coerce_endpoint(src)
+ (dst_block, dst_port) = self._coerce_endpoint(dst)
+ self._hb.primitive_disconnect(src_block.to_basic_block(), src_port,
+ dst_block.to_basic_block(), dst_port)
+
+ def msg_connect(self, src, srcport, dst, dstport):
+ self.primitive_msg_connect(src.to_basic_block(), srcport, dst.to_basic_block(), dstport);
+
+ def msg_disconnect(self, src, srcport, dst, dstport):
+ self.primitive_msg_disconnect(src.to_basic_block(), srcport, dst.to_basic_block(), dstport);
+
+ def message_port_register_hier_in(self, portname):
+ self.primitive_message_port_register_hier_in(pmt.pmt_intern(portname));
+
+ def message_port_register_hier_out(self, portname):
+ self.primitive_message_port_register_hier_out(pmt.pmt_intern(portname));
+
diff --git a/gnuradio-core/src/python/gnuradio/gr/prefs.py b/gnuradio-core/src/python/gnuradio/gr/prefs.py
new file mode 100644
index 000000000..25fa8cd6a
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/gr/prefs.py
@@ -0,0 +1,127 @@
+#
+# Copyright 2006,2009 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+import gnuradio_core as gsp
+_prefs_base = gsp.gr_prefs
+
+
+import ConfigParser
+import os
+import os.path
+import sys
+import glob
+
+
+def _user_prefs_filename():
+ return os.path.expanduser('~/.gnuradio/config.conf')
+
+def _sys_prefs_dirname():
+ return gsp.prefsdir()
+
+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()
+ self.__getattr__ = lambda self, name: getattr(self.cp, name)
+
+ def _sys_prefs_filenames(self):
+ dir = _sys_prefs_dirname()
+ try:
+ fnames = glob.glob(os.path.join(dir, '*.conf'))
+ except (IOError, OSError):
+ return []
+ fnames.sort()
+ return fnames
+
+ def _read_files(self):
+ filenames = self._sys_prefs_filenames()
+ filenames.append(_user_prefs_filename())
+ #print "filenames: ", filenames
+ self.cp.read(filenames)
+
+ # ----------------------------------------------------------------
+ # 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/pubsub.py b/gnuradio-core/src/python/gnuradio/gr/pubsub.py
new file mode 100644
index 000000000..90568418f
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/gr/pubsub.py
@@ -0,0 +1,153 @@
+#!/usr/bin/env python
+#
+# Copyright 2008,2009 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+"""
+Abstract GNU Radio publisher/subscriber interface
+
+This is a proof of concept implementation, will likely change significantly.
+"""
+
+class pubsub(dict):
+ def __init__(self):
+ self._publishers = { }
+ self._subscribers = { }
+ self._proxies = { }
+
+ def __missing__(self, key, value=None):
+ dict.__setitem__(self, key, value)
+ self._publishers[key] = None
+ self._subscribers[key] = []
+ self._proxies[key] = None
+
+ def __setitem__(self, key, val):
+ if not self.has_key(key):
+ self.__missing__(key, val)
+ elif self._proxies[key] is not None:
+ (p, newkey) = self._proxies[key]
+ p[newkey] = val
+ else:
+ dict.__setitem__(self, key, val)
+ for sub in self._subscribers[key]:
+ # Note this means subscribers will get called in the thread
+ # context of the 'set' caller.
+ sub(val)
+
+ def __getitem__(self, key):
+ if not self.has_key(key): self.__missing__(key)
+ if self._proxies[key] is not None:
+ (p, newkey) = self._proxies[key]
+ return p[newkey]
+ elif self._publishers[key] is not None:
+ return self._publishers[key]()
+ else:
+ return dict.__getitem__(self, key)
+
+ def publish(self, key, publisher):
+ if not self.has_key(key): self.__missing__(key)
+ if self._proxies[key] is not None:
+ (p, newkey) = self._proxies[key]
+ p.publish(newkey, publisher)
+ else:
+ self._publishers[key] = publisher
+
+ def subscribe(self, key, subscriber):
+ if not self.has_key(key): self.__missing__(key)
+ if self._proxies[key] is not None:
+ (p, newkey) = self._proxies[key]
+ p.subscribe(newkey, subscriber)
+ else:
+ self._subscribers[key].append(subscriber)
+
+ def unpublish(self, key):
+ if self._proxies[key] is not None:
+ (p, newkey) = self._proxies[key]
+ p.unpublish(newkey)
+ else:
+ self._publishers[key] = None
+
+ def unsubscribe(self, key, subscriber):
+ if self._proxies[key] is not None:
+ (p, newkey) = self._proxies[key]
+ p.unsubscribe(newkey, subscriber)
+ else:
+ self._subscribers[key].remove(subscriber)
+
+ def proxy(self, key, p, newkey=None):
+ if not self.has_key(key): self.__missing__(key)
+ if newkey is None: newkey = key
+ self._proxies[key] = (p, newkey)
+
+ def unproxy(self, key):
+ self._proxies[key] = None
+
+# Test code
+if __name__ == "__main__":
+ import sys
+ o = pubsub()
+
+ # Non-existent key gets auto-created with None value
+ print "Auto-created key 'foo' value:", o['foo']
+
+ # Add some subscribers
+ # First is a bare function
+ def print_len(x):
+ print "len=%i" % (len(x), )
+ o.subscribe('foo', print_len)
+
+ # The second is a class member function
+ class subber(object):
+ def __init__(self, param):
+ self._param = param
+ def printer(self, x):
+ print self._param, `x`
+ s = subber('param')
+ o.subscribe('foo', s.printer)
+
+ # The third is a lambda function
+ o.subscribe('foo', lambda x: sys.stdout.write('val='+`x`+'\n'))
+
+ # Update key 'foo', will notify subscribers
+ print "Updating 'foo' with three subscribers:"
+ o['foo'] = 'bar';
+
+ # Remove first subscriber
+ o.unsubscribe('foo', print_len)
+
+ # Update now will only trigger second and third subscriber
+ print "Updating 'foo' after removing a subscriber:"
+ o['foo'] = 'bar2';
+
+ # Publish a key as a function, in this case, a lambda function
+ o.publish('baz', lambda : 42)
+ print "Published value of 'baz':", o['baz']
+
+ # Unpublish the key
+ o.unpublish('baz')
+
+ # This will return None, as there is no publisher
+ print "Value of 'baz' with no publisher:", o['baz']
+
+ # Set 'baz' key, it gets cached
+ o['baz'] = 'bazzz'
+
+ # Now will return cached value, since no provider
+ print "Cached value of 'baz' after being set:", o['baz']
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
index 000000000..7ccbbe8ad
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/gr/qa_add_and_friends.py
@@ -0,0 +1,163 @@
+#!/usr/bin/env python
+#
+# Copyright 2004,2007,2010 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr, gr_unittest
+
+class test_add_and_friends (gr_unittest.TestCase):
+
+ def setUp (self):
+ self.tb = gr.top_block ()
+
+ def tearDown (self):
+ self.tb = 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.tb.connect (src, (op, s[0]))
+ dst = gr.vector_sink_i ()
+ self.tb.connect (op, dst)
+ self.tb.run ()
+ result_data = dst.data ()
+ self.assertEqual (exp_data, result_data)
+
+ def 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.tb.connect (src, (op, s[0]))
+ dst = gr.vector_sink_f ()
+ self.tb.connect (op, dst)
+ self.tb.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.tb.connect (src, (op, s[0]))
+ dst = gr.vector_sink_c ()
+ self.tb.connect (op, dst)
+ self.tb.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_mult_const_ff (self):
+ src_data = (-1, 0, 1, 2, 3)
+ expected_result = (-5, 0, 5, 10, 15)
+ op = gr.multiply_const_cc (5)
+ self.help_cc ((src_data,), expected_result, op)
+
+ def test_mult_const_cc (self):
+ src_data = (-1-1j, 0+0j, 1+1j, 2+2j, 3+3j)
+ expected_result = (-5-5j, 0+0j, 5+5j, 10+10j, 15+15j)
+ op = gr.multiply_const_cc (5)
+ self.help_cc ((src_data,), expected_result, op)
+
+ def test_mult_const_cc2 (self):
+ src_data = (-1-1j, 0+0j, 1+1j, 2+2j, 3+3j)
+ expected_result = (-3-7j, 0+0j, 3+7j, 6+14j, 9+21j)
+ op = gr.multiply_const_cc (5+2j)
+ self.help_cc ((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_mult_ff (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_ff ()
+ self.help_ff ((src1_data, src2_data),
+ expected_result, op)
+
+ def test_mult_cc (self):
+ src1_data = (1+1j, 2+2j, 3+3j, 4+4j, 5+5j)
+ src2_data = (8, -3, 4, 8, 2)
+ expected_result = (8+8j, -6-6j, 12+12j, 32+32j, 10+10j)
+ op = gr.multiply_cc ()
+ self.help_cc ((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.run(test_add_and_friends, "test_add_and_friends.xml")
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
index 000000000..c8df47b39
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/gr/qa_add_v_and_friends.py
@@ -0,0 +1,353 @@
+#!/usr/bin/env python
+#
+# Copyright 2004,2007,2010 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr, gr_unittest
+
+class test_add_v_and_friends(gr_unittest.TestCase):
+
+ def setUp(self):
+ self.tb = gr.top_block()
+
+ def tearDown(self):
+ self.tb = 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.tb.connect(src, srcv)
+ self.tb.connect(srcv, (op, s[0]))
+ rhs = gr.vector_to_stream(gr.sizeof_short, size)
+ dst = gr.vector_sink_s()
+ self.tb.connect(op, rhs, dst)
+ self.tb.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.tb.connect(src, srcv)
+ self.tb.connect(srcv, (op, s[0]))
+ rhs = gr.vector_to_stream(gr.sizeof_int, size)
+ dst = gr.vector_sink_i()
+ self.tb.connect(op, rhs, dst)
+ self.tb.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.tb.connect(src, srcv)
+ self.tb.connect(srcv, (op, s[0]))
+ rhs = gr.vector_to_stream(gr.sizeof_float, size)
+ dst = gr.vector_sink_f()
+ self.tb.connect(op, rhs, dst)
+ self.tb.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.tb.connect(src, srcv)
+ self.tb.connect(srcv, (op, s[0]))
+ rhs = gr.vector_to_stream(gr.sizeof_gr_complex, size)
+ dst = gr.vector_sink_c()
+ self.tb.connect(op, rhs, dst)
+ self.tb.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.tb.connect(src, srcv, op, rhs, dst)
+ self.tb.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.tb.connect(src, srcv, op, rhs, dst)
+ self.tb.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.tb.connect(src, srcv, op, rhs, dst)
+ self.tb.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.tb.connect(src, srcv, op, rhs, dst)
+ self.tb.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.run(test_add_v_and_friends, "test_add_v_and_friends.xml")
diff --git a/gnuradio-core/src/python/gnuradio/gr/qa_affinity.py b/gnuradio-core/src/python/gnuradio/gr/qa_affinity.py
new file mode 100644
index 000000000..7b3ca6ed6
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/gr/qa_affinity.py
@@ -0,0 +1,49 @@
+#!/usr/bin/env python
+#
+# Copyright 2013 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr, gr_unittest
+
+class test_affinity(gr_unittest.TestCase):
+
+ def setUp(self):
+ self.tb = gr.top_block()
+
+ def tearDown(self):
+ self.tb = None
+
+ def test_000(self):
+ # Just run some data through and make sure it doesn't puke.
+ src_data = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
+
+ src = gr.vector_source_f(src_data)
+ snk = gr.vector_sink_f()
+
+ src.set_processor_affinity([0,])
+ self.tb.connect(src, snk)
+ self.tb.run()
+
+ a = src.processor_affinity()
+
+ self.assertEqual((0,), a)
+
+if __name__ == '__main__':
+ gr_unittest.run(test_affinity, "test_affinity.xml")
diff --git a/gnuradio-core/src/python/gnuradio/gr/qa_agc.py b/gnuradio-core/src/python/gnuradio/gr/qa_agc.py
new file mode 100755
index 000000000..9fd633576
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/gr/qa_agc.py
@@ -0,0 +1,433 @@
+#!/usr/bin/env python
+#
+# Copyright 2004,2007,2010 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr, gr_unittest
+import math
+
+test_output = False
+
+class test_agc (gr_unittest.TestCase):
+
+ def setUp (self):
+ self.tb = gr.top_block ()
+
+ def tearDown (self):
+ self.tb = None
+
+
+ def test_001(self):
+ ''' Test the complex AGC loop (single rate input) '''
+ tb = self.tb
+
+ expected_result = (
+ (100.000244140625+7.2191943445432116e-07j),
+ (72.892257690429688+52.959323883056641j),
+ (25.089065551757812+77.216217041015625j),
+ (-22.611061096191406+69.589706420898438j),
+ (-53.357715606689453+38.766635894775391j),
+ (-59.458671569824219+3.4792964243024471e-07j),
+ (-43.373462677001953-31.512666702270508j),
+ (-14.94139289855957-45.984889984130859j),
+ (13.478158950805664-41.48150634765625j),
+ (31.838506698608398-23.132022857666016j),
+ (35.519271850585938-3.1176801940091536e-07j),
+ (25.942903518676758+18.848621368408203j),
+ (8.9492912292480469+27.5430908203125j),
+ (-8.0852642059326172+24.883890151977539j),
+ (-19.131628036499023+13.899936676025391j),
+ (-21.383295059204102+3.1281737733479531e-07j),
+ (-15.650330543518066-11.370632171630859j),
+ (-5.4110145568847656-16.65339469909668j),
+ (4.9008159637451172-15.083160400390625j),
+ (11.628337860107422-8.4484796524047852j),
+ (13.036135673522949-2.288476110834381e-07j),
+ (9.5726661682128906+6.954948902130127j),
+ (3.3216962814331055+10.223132133483887j),
+ (-3.0204284191131592+9.2959251403808594j),
+ (-7.1977195739746094+5.2294478416442871j),
+ (-8.1072216033935547+1.8976157889483147e-07j),
+ (-5.9838657379150391-4.3475332260131836j),
+ (-2.0879747867584229-6.4261269569396973j),
+ (1.9100792407989502-5.8786196708679199j),
+ (4.5814824104309082-3.3286411762237549j),
+ (5.1967458724975586-1.3684227440080576e-07j),
+ (3.8647139072418213+2.8078789710998535j),
+ (1.3594740629196167+4.1840314865112305j),
+ (-1.2544282674789429+3.8607344627380371j),
+ (-3.0366206169128418+2.2062335014343262j),
+ (-3.4781389236450195+1.1194014604143376e-07j),
+ (-2.6133756637573242-1.8987287282943726j),
+ (-0.9293016791343689-2.8600969314575195j),
+ (0.86727333068847656-2.6691930294036865j),
+ (2.1243946552276611-1.5434627532958984j),
+ (2.4633183479309082-8.6486437567145913e-08j),
+ (1.8744727373123169+1.3618841171264648j),
+ (0.67528903484344482+2.0783262252807617j),
+ (-0.63866174221038818+1.965599536895752j),
+ (-1.5857341289520264+1.152103066444397j),
+ (-1.8640764951705933+7.6355092915036948e-08j),
+ (-1.4381576776504517-1.0448826551437378j),
+ (-0.52529704570770264-1.6166983842849731j),
+ (0.50366902351379395-1.5501341819763184j),
+ (1.26766037940979-0.92100900411605835j))
+
+ sampling_freq = 100
+ src1 = gr.sig_source_c (sampling_freq, gr.GR_SIN_WAVE,
+ sampling_freq * 0.10, 100.0)
+ dst1 = gr.vector_sink_c ()
+ head = gr.head (gr.sizeof_gr_complex, int (5*sampling_freq * 0.10))
+
+ agc = gr.agc_cc(1e-3, 1, 1, 1000)
+
+ tb.connect (src1, head)
+ tb.connect (head, agc)
+ tb.connect (agc, dst1)
+
+ if test_output == True:
+ tb.connect (agc, gr.file_sink(gr.sizeof_gr_complex, "test_agc_cc.dat"))
+
+ tb.run ()
+ dst_data = dst1.data ()
+ self.assertComplexTuplesAlmostEqual (expected_result, dst_data, 4)
+
+ def test_002(self):
+ ''' Test the floating point AGC loop (single rate input) '''
+ tb = self.tb
+
+ expected_result = (
+ 7.2191943445432116e-07,
+ 58.837181091308594,
+ 89.700050354003906,
+ 81.264183044433594,
+ 45.506141662597656,
+ 4.269894304798072e-07,
+ -42.948936462402344,
+ -65.50335693359375,
+ -59.368724822998047,
+ -33.261005401611328,
+ -4.683740257860336e-07,
+ 31.423542022705078,
+ 47.950984954833984,
+ 43.485683441162109,
+ 24.378345489501953,
+ 5.7254135299444897e-07,
+ -23.062990188598633,
+ -35.218441009521484,
+ -31.964075088500977,
+ -17.934831619262695,
+ -5.0591745548445033e-07,
+ 16.998210906982422,
+ 25.982204437255859,
+ 23.606258392333984,
+ 13.260685920715332,
+ 4.9936483037527069e-07,
+ -12.59880542755127,
+ -19.28221321105957,
+ -17.54347038269043,
+ -9.8700437545776367,
+ -4.188150626305287e-07,
+ 9.4074573516845703,
+ 14.422011375427246,
+ 13.145503044128418,
+ 7.41046142578125,
+ 3.8512698097292741e-07,
+ -7.0924453735351562,
+ -10.896408081054688,
+ -9.9552040100097656,
+ -5.6262712478637695,
+ -3.1982864356905338e-07,
+ 5.4131259918212891,
+ 8.3389215469360352,
+ 7.6409502029418945,
+ 4.3320145606994629,
+ 2.882407841298118e-07,
+ -4.194943904876709,
+ -6.4837145805358887,
+ -5.9621825218200684,
+ -3.3931560516357422)
+
+ sampling_freq = 100
+ src1 = gr.sig_source_f (sampling_freq, gr.GR_SIN_WAVE,
+ sampling_freq * 0.10, 100.0)
+ dst1 = gr.vector_sink_f ()
+ head = gr.head (gr.sizeof_float, int (5*sampling_freq * 0.10))
+
+ agc = gr.agc_ff(1e-3, 1, 1, 1000)
+
+ tb.connect (src1, head)
+ tb.connect (head, agc)
+ tb.connect (agc, dst1)
+
+ if test_output == True:
+ tb.connect (agc, gr.file_sink(gr.sizeof_float, "test_agc_ff.dat"))
+
+ tb.run ()
+ dst_data = dst1.data ()
+ self.assertFloatTuplesAlmostEqual (expected_result, dst_data, 4)
+
+ def test_003(self):
+ ''' Test the complex AGC loop (attack and decay rate inputs) '''
+ tb = self.tb
+
+ expected_result = \
+ ((100.000244140625+7.2191943445432116e-07j),
+ (0.80881959199905396+0.58764183521270752j),
+ (0.30894950032234192+0.95084899663925171j),
+ (-0.30895623564720154+0.95086973905563354j),
+ (-0.80887287855148315+0.58768033981323242j),
+ (-0.99984413385391235+5.850709250410091e-09j),
+ (-0.80889981985092163-0.58770018815994263j),
+ (-0.30897706747055054-0.95093393325805664j),
+ (0.30898112058639526-0.95094609260559082j),
+ (0.80893135070800781-0.58772283792495728j),
+ (0.99990922212600708-8.7766354184282136e-09j),
+ (0.80894720554351807+0.58773452043533325j),
+ (0.30899339914321899+0.95098406076431274j),
+ (-0.30899572372436523+0.95099133253097534j),
+ (-0.80896598100662231+0.58774799108505249j),
+ (-0.99994778633117676+1.4628290578855285e-08j),
+ (-0.80897533893585205-0.58775502443313599j),
+ (-0.30900305509567261-0.95101380348205566j),
+ (0.30900448560714722-0.95101797580718994j),
+ (0.80898630619049072-0.58776277303695679j),
+ (0.99997037649154663-1.7554345532744264e-08j),
+ (0.80899184942245483+0.58776694536209106j),
+ (0.30900871753692627+0.95103120803833008j),
+ (-0.30900952219963074+0.95103377103805542j),
+ (-0.8089984655380249+0.58777159452438354j),
+ (-0.99998390674591064+2.3406109050938539e-08j),
+ (-0.809001624584198-0.58777409791946411j),
+ (-0.30901208519935608-0.95104163885116577j),
+ (0.30901262164115906-0.95104306936264038j),
+ (0.80900543928146362-0.587776780128479j),
+ (0.99999171495437622-2.6332081404234486e-08j),
+ (0.80900734663009644+0.58777821063995361j),
+ (0.30901408195495605+0.95104765892028809j),
+ (-0.30901429057121277+0.95104855298995972j),
+ (-0.80900967121124268+0.58777981996536255j),
+ (-0.99999648332595825+3.2183805842578295e-08j),
+ (-0.80901080369949341-0.58778077363967896j),
+ (-0.30901527404785156-0.95105135440826416j),
+ (0.30901545286178589-0.95105189085006714j),
+ (0.80901217460632324-0.58778166770935059j),
+ (0.99999916553497314-3.5109700036173308e-08j),
+ (0.809012770652771+0.58778214454650879j),
+ (0.30901595950126648+0.9510534405708313j),
+ (-0.30901598930358887+0.95105385780334473j),
+ (-0.80901366472244263+0.58778274059295654j),
+ (-1.0000008344650269+4.0961388947380328e-08j),
+ (-0.8090139627456665-0.58778303861618042j),
+ (-0.30901634693145752-0.95105475187301636j),
+ (0.30901640653610229-0.95105493068695068j),
+ (0.80901449918746948-0.5877833366394043j))
+
+ sampling_freq = 100
+ src1 = gr.sig_source_c (sampling_freq, gr.GR_SIN_WAVE,
+ sampling_freq * 0.10, 100)
+ dst1 = gr.vector_sink_c ()
+ head = gr.head (gr.sizeof_gr_complex, int (5*sampling_freq * 0.10))
+
+ agc = gr.agc2_cc(1e-2, 1e-3, 1, 1, 1000)
+
+ tb.connect (src1, head)
+ tb.connect (head, agc)
+ tb.connect (agc, dst1)
+
+ if test_output == True:
+ tb.connect (agc, gr.file_sink(gr.sizeof_gr_complex, "test_agc2_cc.dat"))
+
+ tb.run ()
+ dst_data = dst1.data ()
+ self.assertComplexTuplesAlmostEqual (expected_result, dst_data, 4)
+
+ def test_004(self):
+ ''' Test the floating point AGC loop (attack and decay rate inputs) '''
+ tb = self.tb
+
+ expected_result = \
+ (7.2191943445432116e-07,
+ 58.837181091308594,
+ 40.194305419921875,
+ 2.9183335304260254,
+ 0.67606079578399658,
+ 8.6260438791896377e-09,
+ -1.4542514085769653,
+ -1.9210131168365479,
+ -1.0450780391693115,
+ -0.61939650774002075,
+ -1.2590258613442984e-08,
+ 1.4308931827545166,
+ 1.9054338932037354,
+ 1.0443156957626343,
+ 0.61937344074249268,
+ 2.0983527804219193e-08,
+ -1.4308838844299316,
+ -1.9054274559020996,
+ -1.0443152189254761,
+ -0.61937344074249268,
+ -2.5180233009791664e-08,
+ 1.4308837652206421,
+ 1.9054274559020996,
+ 1.0443154573440552,
+ 0.61937344074249268,
+ 3.3573645197293445e-08,
+ -1.4308838844299316,
+ -1.9054274559020996,
+ -1.0443152189254761,
+ -0.61937350034713745,
+ -3.7770352179222755e-08,
+ 1.4308837652206421,
+ 1.9054274559020996,
+ 1.0443154573440552,
+ 0.61937350034713745,
+ 4.6163762590367696e-08,
+ -1.4308838844299316,
+ -1.9054274559020996,
+ -1.0443153381347656,
+ -0.61937344074249268,
+ -5.0360466019583328e-08,
+ 1.4308837652206421,
+ 1.9054274559020996,
+ 1.0443155765533447,
+ 0.61937344074249268,
+ 5.8753879983441948e-08,
+ -1.4308837652206421,
+ -1.9054274559020996,
+ -1.0443153381347656,
+ -0.61937344074249268)
+
+ sampling_freq = 100
+ src1 = gr.sig_source_f (sampling_freq, gr.GR_SIN_WAVE,
+ sampling_freq * 0.10, 100)
+ dst1 = gr.vector_sink_f ()
+ head = gr.head (gr.sizeof_float, int (5*sampling_freq * 0.10))
+
+ agc = gr.agc2_ff(1e-2, 1e-3, 1, 1, 1000)
+
+ tb.connect (src1, head)
+ tb.connect (head, agc)
+ tb.connect (agc, dst1)
+
+ if test_output == True:
+ tb.connect (agc, gr.file_sink(gr.sizeof_float, "test_agc2_ff.dat"))
+
+ tb.run ()
+ dst_data = dst1.data ()
+ self.assertFloatTuplesAlmostEqual (expected_result, dst_data, 4)
+
+
+ def test_005(self):
+ ''' Test the complex AGC loop (attack and decay rate inputs) '''
+ tb = self.tb
+
+ expected_result = \
+ ((100.000244140625+7.2191943445432116e-07j),
+ (0.80881959199905396+0.58764183521270752j),
+ (0.30894950032234192+0.95084899663925171j),
+ (-0.30895623564720154+0.95086973905563354j),
+ (-0.80887287855148315+0.58768033981323242j),
+ (-0.99984413385391235+5.850709250410091e-09j),
+ (-0.80889981985092163-0.58770018815994263j),
+ (-0.30897706747055054-0.95093393325805664j),
+ (0.30898112058639526-0.95094609260559082j),
+ (0.80893135070800781-0.58772283792495728j),
+ (0.99990922212600708-8.7766354184282136e-09j),
+ (0.80894720554351807+0.58773452043533325j),
+ (0.30899339914321899+0.95098406076431274j),
+ (-0.30899572372436523+0.95099133253097534j),
+ (-0.80896598100662231+0.58774799108505249j),
+ (-0.99994778633117676+1.4628290578855285e-08j),
+ (-0.80897533893585205-0.58775502443313599j),
+ (-0.30900305509567261-0.95101380348205566j),
+ (0.30900448560714722-0.95101797580718994j),
+ (0.80898630619049072-0.58776277303695679j),
+ (0.99997037649154663-1.7554345532744264e-08j),
+ (0.80899184942245483+0.58776694536209106j),
+ (0.30900871753692627+0.95103120803833008j),
+ (-0.30900952219963074+0.95103377103805542j),
+ (-0.8089984655380249+0.58777159452438354j),
+ (-0.99998390674591064+2.3406109050938539e-08j),
+ (-0.809001624584198-0.58777409791946411j),
+ (-0.30901208519935608-0.95104163885116577j),
+ (0.30901262164115906-0.95104306936264038j),
+ (0.80900543928146362-0.587776780128479j),
+ (0.99999171495437622-2.6332081404234486e-08j),
+ (0.80900734663009644+0.58777821063995361j),
+ (0.30901408195495605+0.95104765892028809j),
+ (-0.30901429057121277+0.95104855298995972j),
+ (-0.80900967121124268+0.58777981996536255j),
+ (-0.99999648332595825+3.2183805842578295e-08j),
+ (-0.80901080369949341-0.58778077363967896j),
+ (-0.30901527404785156-0.95105135440826416j),
+ (0.30901545286178589-0.95105189085006714j),
+ (0.80901217460632324-0.58778166770935059j),
+ (0.99999916553497314-3.5109700036173308e-08j),
+ (0.809012770652771+0.58778214454650879j),
+ (0.30901595950126648+0.9510534405708313j),
+ (-0.30901598930358887+0.95105385780334473j),
+ (-0.80901366472244263+0.58778274059295654j),
+ (-1.0000008344650269+4.0961388947380328e-08j),
+ (-0.8090139627456665-0.58778303861618042j),
+ (-0.30901634693145752-0.95105475187301636j),
+ (0.30901640653610229-0.95105493068695068j),
+ (0.80901449918746948-0.5877833366394043j))
+
+ sampling_freq = 100
+ src1 = gr.sig_source_c (sampling_freq, gr.GR_SIN_WAVE,
+ sampling_freq * 0.10, 100)
+ dst1 = gr.vector_sink_c ()
+ head = gr.head (gr.sizeof_gr_complex, int (5*sampling_freq * 0.10))
+
+ agc = gr.agc2_cc(1e-2, 1e-3, 1, 1, 1000)
+
+ tb.connect (src1, head)
+ tb.connect (head, agc)
+ tb.connect (agc, dst1)
+
+ if test_output == True:
+ tb.connect (agc, gr.file_sink(gr.sizeof_gr_complex, "test_agc2_cc.dat"))
+
+ tb.run ()
+ dst_data = dst1.data ()
+ self.assertComplexTuplesAlmostEqual (expected_result, dst_data, 4)
+
+
+ def test_100(self): # FIXME needs work
+ ''' Test complex feedforward agc with constant input '''
+ input_data = 16*(0.0,) + 64*(1.0,) + 64*(0.0,)
+ expected_result = ()
+
+ src = gr.vector_source_c(input_data)
+ agc = gr.feedforward_agc_cc(16, 2.0)
+ dst = gr.vector_sink_c ()
+ self.tb.connect (src, agc, dst)
+
+ if test_output == True:
+ self.tb.connect (agc, gr.file_sink(gr.sizeof_gr_complex, "test_feedforward_cc.dat"))
+
+ self.tb.run ()
+ dst_data = dst.data ()
+ #self.assertComplexTuplesAlmostEqual (expected_result, dst_data, 4)
+
+
+if __name__ == '__main__':
+ gr_unittest.run(test_agc, "test_agc.xml")
diff --git a/gnuradio-core/src/python/gnuradio/gr/qa_argmax.py b/gnuradio-core/src/python/gnuradio/gr/qa_argmax.py
new file mode 100644
index 000000000..564eb620b
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/gr/qa_argmax.py
@@ -0,0 +1,77 @@
+#!/usr/bin/env python
+#
+# Copyright 2007,2010 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr, gr_unittest
+import math
+
+
+class test_arg_max (gr_unittest.TestCase):
+
+ def setUp (self):
+ self.tb = gr.top_block ()
+
+
+ def tearDown (self):
+ self.tb = None
+
+
+ def test_001(self):
+ tb = self.tb
+
+ src1_data = (0,0.2,-0.3,0,12,0)
+ src2_data = (0,0.0,3.0,0,10,0)
+ src3_data = (0,0.0,3.0,0,1,0)
+
+ src1 = gr.vector_source_f (src1_data)
+ s2v1 = gr.stream_to_vector(gr.sizeof_float, len(src1_data))
+ tb.connect( src1, s2v1 )
+
+ src2 = gr.vector_source_f (src2_data)
+ s2v2 = gr.stream_to_vector(gr.sizeof_float, len(src1_data))
+ tb.connect( src2, s2v2 )
+
+ src3 = gr.vector_source_f (src3_data)
+ s2v3 = gr.stream_to_vector(gr.sizeof_float, len(src1_data))
+ tb.connect( src3, s2v3 )
+
+ dst1 = gr.vector_sink_s ()
+ dst2 = gr.vector_sink_s ()
+ argmax = gr.argmax_fs (len(src1_data))
+
+ tb.connect (s2v1, (argmax, 0))
+ tb.connect (s2v2, (argmax, 1))
+ tb.connect (s2v3, (argmax, 2))
+
+ tb.connect ((argmax,0), dst1)
+ tb.connect ((argmax,1), dst2)
+
+ tb.run ()
+ index = dst1.data ()
+ source = dst2.data ()
+ self.assertEqual ( index, (4,))
+ self.assertEqual ( source, (0,))
+
+
+
+if __name__ == '__main__':
+ gr_unittest.run(test_arg_max, "test_arg_max.xml")
+
diff --git a/gnuradio-core/src/python/gnuradio/gr/qa_bin_statistics.py b/gnuradio-core/src/python/gnuradio/gr/qa_bin_statistics.py
new file mode 100755
index 000000000..8a6dd9056
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/gr/qa_bin_statistics.py
@@ -0,0 +1,230 @@
+#!/usr/bin/env python
+#
+# Copyright 2006,2007,2010 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr, gr_unittest
+import random
+import struct
+
+#import os
+#print "pid =", os.getpid()
+#raw_input("Attach gdb and press return...")
+
+"""
+Note: The QA tests below have been disabled by renaming them from test_*
+to xtest_*. See ticket:199 on http://gnuradio.org/trac/ticket/199
+"""
+
+class counter(gr.feval_dd):
+ def __init__(self, step_size=1):
+ gr.feval_dd.__init__(self)
+ self.step_size = step_size
+ self.count = 0
+
+ def eval(self, input):
+ #print "eval: self.count =", self.count
+ t = self.count
+ self.count = self.count + self.step_size
+ return t
+
+
+class counter3(gr.feval_dd):
+ def __init__(self, f, step_size):
+ gr.feval_dd.__init__(self)
+ self.f = f
+ self.step_size = step_size
+ self.count = 0
+
+ def eval(self, input):
+ try:
+ #print "eval: self.count =", self.count
+ t = self.count
+ self.count = self.count + self.step_size
+ self.f(self.count)
+ except Exception, e:
+ print "Exception: ", e
+ return t
+
+def foobar3(new_t):
+ #print "foobar3: new_t =", new_t
+ pass
+
+
+class counter4(gr.feval_dd):
+ def __init__(self, obj_instance, step_size):
+ gr.feval_dd.__init__(self)
+ self.obj_instance = obj_instance
+ self.step_size = step_size
+ self.count = 0
+
+ def eval(self, input):
+ try:
+ #print "eval: self.count =", self.count
+ t = self.count
+ self.count = self.count + self.step_size
+ self.obj_instance.foobar4(self.count)
+ except Exception, e:
+ print "Exception: ", e
+ return t
+
+
+class parse_msg(object):
+ def __init__(self, msg):
+ self.center_freq = msg.arg1()
+ self.vlen = int(msg.arg2())
+ assert(msg.length() == self.vlen * gr.sizeof_float)
+ self.data = struct.unpack('%df' % (self.vlen,), msg.to_string())
+
+# FIXME: see ticket:199
+class xtest_bin_statistics(gr_unittest.TestCase):
+
+ def setUp(self):
+ self.tb = gr.top_block ()
+
+ def tearDown(self):
+ self.tb = None
+
+ def xtest_001(self):
+ vlen = 4
+ tune = counter(1)
+ tune_delay = 0
+ dwell_delay = 1
+ msgq = gr.msg_queue()
+
+ src_data = tuple([float(x) for x in
+ ( 1, 2, 3, 4,
+ 5, 6, 7, 8,
+ 9, 10, 11, 12,
+ 13, 14, 15, 16
+ )])
+
+ expected_results = tuple([float(x) for x in
+ ( 1, 2, 3, 4,
+ 5, 6, 7, 8,
+ 9, 10, 11, 12,
+ 13, 14, 15, 16
+ )])
+
+ src = gr.vector_source_f(src_data, False)
+ s2v = gr.stream_to_vector(gr.sizeof_float, vlen)
+ stats = gr.bin_statistics_f(vlen, msgq, tune, tune_delay, dwell_delay)
+ self.tb.connect(src, s2v, stats)
+ self.tb.run()
+ self.assertEqual(4, msgq.count())
+ for i in range(4):
+ m = parse_msg(msgq.delete_head())
+ #print "m =", m.center_freq, m.data
+ self.assertEqual(expected_results[vlen*i:vlen*i + vlen], m.data)
+
+ def xtest_002(self):
+ vlen = 4
+ tune = counter(1)
+ tune_delay = 1
+ dwell_delay = 2
+ msgq = gr.msg_queue()
+
+ src_data = tuple([float(x) for x in
+ ( 1, 2, 3, 4,
+ 9, 6, 11, 8,
+ 5, 10, 7, 12,
+ 13, 14, 15, 16
+ )])
+
+ expected_results = tuple([float(x) for x in
+ ( 9, 10, 11, 12)])
+
+ src = gr.vector_source_f(src_data, False)
+ s2v = gr.stream_to_vector(gr.sizeof_float, vlen)
+ stats = gr.bin_statistics_f(vlen, msgq, tune, tune_delay, dwell_delay)
+ self.tb.connect(src, s2v, stats)
+ self.tb.run()
+ self.assertEqual(1, msgq.count())
+ for i in range(1):
+ m = parse_msg(msgq.delete_head())
+ #print "m =", m.center_freq, m.data
+ self.assertEqual(expected_results[vlen*i:vlen*i + vlen], m.data)
+
+
+
+ def xtest_003(self):
+ vlen = 4
+ tune = counter3(foobar3, 1)
+ tune_delay = 1
+ dwell_delay = 2
+ msgq = gr.msg_queue()
+
+ src_data = tuple([float(x) for x in
+ ( 1, 2, 3, 4,
+ 9, 6, 11, 8,
+ 5, 10, 7, 12,
+ 13, 14, 15, 16
+ )])
+
+ expected_results = tuple([float(x) for x in
+ ( 9, 10, 11, 12)])
+
+ src = gr.vector_source_f(src_data, False)
+ s2v = gr.stream_to_vector(gr.sizeof_float, vlen)
+ stats = gr.bin_statistics_f(vlen, msgq, tune, tune_delay, dwell_delay)
+ self.tb.connect(src, s2v, stats)
+ self.tb.run()
+ self.assertEqual(1, msgq.count())
+ for i in range(1):
+ m = parse_msg(msgq.delete_head())
+ #print "m =", m.center_freq, m.data
+ self.assertEqual(expected_results[vlen*i:vlen*i + vlen], m.data)
+
+
+ def foobar4(self, new_t):
+ #print "foobar4: new_t =", new_t
+ pass
+
+ def xtest_004(self):
+ vlen = 4
+ tune = counter4(self, 1)
+ tune_delay = 1
+ dwell_delay = 2
+ msgq = gr.msg_queue()
+
+ src_data = tuple([float(x) for x in
+ ( 1, 2, 3, 4,
+ 9, 6, 11, 8,
+ 5, 10, 7, 12,
+ 13, 14, 15, 16
+ )])
+
+ expected_results = tuple([float(x) for x in
+ ( 9, 10, 11, 12)])
+
+ src = gr.vector_source_f(src_data, False)
+ s2v = gr.stream_to_vector(gr.sizeof_float, vlen)
+ stats = gr.bin_statistics_f(vlen, msgq, tune, tune_delay, dwell_delay)
+ self.tb.connect(src, s2v, stats)
+ self.tb.run()
+ self.assertEqual(1, msgq.count())
+ for i in range(1):
+ m = parse_msg(msgq.delete_head())
+ #print "m =", m.center_freq, m.data
+ self.assertEqual(expected_results[vlen*i:vlen*i + vlen], m.data)
+
+
+if __name__ == '__main__':
+ gr_unittest.run(xtest_bin_statistics, "test_bin_statistics.xml")
diff --git a/gnuradio-core/src/python/gnuradio/gr/qa_block_gateway.py b/gnuradio-core/src/python/gnuradio/gr/qa_block_gateway.py
new file mode 100644
index 000000000..911879f6f
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/gr/qa_block_gateway.py
@@ -0,0 +1,235 @@
+#
+# Copyright 2011-2012 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr, gr_unittest
+import pmt
+import numpy
+
+class add_2_f32_1_f32(gr.sync_block):
+ def __init__(self):
+ gr.sync_block.__init__(
+ self,
+ name = "add 2 f32",
+ in_sig = [numpy.float32, numpy.float32],
+ out_sig = [numpy.float32],
+ )
+
+ def work(self, input_items, output_items):
+ output_items[0][:] = input_items[0] + input_items[1]
+ return len(output_items[0])
+
+class add_2_fc32_1_fc32(gr.sync_block):
+ def __init__(self):
+ gr.sync_block.__init__(
+ self,
+ name = "add 2 fc32",
+ in_sig = [numpy.complex64, numpy.complex64],
+ out_sig = [numpy.complex64],
+ )
+
+ def work(self, input_items, output_items):
+ output_items[0][:] = input_items[0] + input_items[1]
+ return len(output_items[0])
+
+class convolve(gr.sync_block):
+ """
+ A demonstration using block history to properly perform a convolution.
+ """
+ def __init__(self):
+ gr.sync_block.__init__(
+ self,
+ name = "convolve",
+ in_sig = [numpy.float32],
+ out_sig = [numpy.float32]
+ )
+ self._taps = [1, 0, 0, 0]
+ self.set_history(len(self._taps))
+
+ def work(self, input_items, output_items):
+ output_items[0][:] = numpy.convolve(input_items[0], self._taps, mode='valid')
+ return len(output_items[0])
+
+class decim2x(gr.decim_block):
+ def __init__(self):
+ gr.decim_block.__init__(
+ self,
+ name = "decim2x",
+ in_sig = [numpy.float32],
+ out_sig = [numpy.float32],
+ decim = 2
+ )
+
+ def work(self, input_items, output_items):
+ output_items[0][:] = input_items[0][::2]
+ return len(output_items[0])
+
+class interp2x(gr.interp_block):
+ def __init__(self):
+ gr.interp_block.__init__(
+ self,
+ name = "interp2x",
+ in_sig = [numpy.float32],
+ out_sig = [numpy.float32],
+ interp = 2
+ )
+
+ def work(self, input_items, output_items):
+ output_items[0][1::2] = input_items[0]
+ output_items[0][::2] = input_items[0]
+ return len(output_items[0])
+
+class tag_source(gr.sync_block):
+ def __init__(self):
+ gr.sync_block.__init__(
+ self,
+ name = "tag source",
+ in_sig = None,
+ out_sig = [numpy.float32],
+ )
+
+ def work(self, input_items, output_items):
+ num_output_items = len(output_items[0])
+
+ #put code here to fill the output items...
+
+ #make a new tag on the middle element every time work is called
+ count = self.nitems_written(0) + num_output_items/2
+ key = pmt.pmt_string_to_symbol("example_key")
+ value = pmt.pmt_string_to_symbol("example_value")
+ self.add_item_tag(0, count, key, value)
+
+ return num_output_items
+
+class tag_sink(gr.sync_block):
+ def __init__(self):
+ gr.sync_block.__init__(
+ self,
+ name = "tag sink",
+ in_sig = [numpy.float32],
+ out_sig = None,
+ )
+ self.key = None
+
+ def work(self, input_items, output_items):
+ num_input_items = len(input_items[0])
+
+ #put code here to process the input items...
+
+ #print all the tags received in this work call
+ nread = self.nitems_read(0)
+ tags = self.get_tags_in_range(0, nread, nread+num_input_items)
+ for tag in tags:
+ #print tag.offset
+ #print pmt.pmt_symbol_to_string(tag.key)
+ #print pmt.pmt_symbol_to_string(tag.value)
+ self.key = pmt.pmt_symbol_to_string(tag.key)
+
+ return num_input_items
+
+class fc32_to_f32_2(gr.sync_block):
+ def __init__(self):
+ gr.sync_block.__init__(
+ self,
+ name = "fc32_to_f32_2",
+ in_sig = [numpy.complex64],
+ out_sig = [(numpy.float32, 2)],
+ )
+
+ def work(self, input_items, output_items):
+ output_items[0][::,0] = numpy.real(input_items[0])
+ output_items[0][::,1] = numpy.imag(input_items[0])
+ return len(output_items[0])
+
+class test_block_gateway(gr_unittest.TestCase):
+
+ def test_add_f32(self):
+ tb = gr.top_block()
+ src0 = gr.vector_source_f([1, 3, 5, 7, 9], False)
+ src1 = gr.vector_source_f([0, 2, 4, 6, 8], False)
+ adder = add_2_f32_1_f32()
+ sink = gr.vector_sink_f()
+ tb.connect((src0, 0), (adder, 0))
+ tb.connect((src1, 0), (adder, 1))
+ tb.connect(adder, sink)
+ tb.run()
+ self.assertEqual(sink.data(), (1, 5, 9, 13, 17))
+
+ def test_add_fc32(self):
+ tb = gr.top_block()
+ src0 = gr.vector_source_c([1, 3j, 5, 7j, 9], False)
+ src1 = gr.vector_source_c([0, 2j, 4, 6j, 8], False)
+ adder = add_2_fc32_1_fc32()
+ sink = gr.vector_sink_c()
+ tb.connect((src0, 0), (adder, 0))
+ tb.connect((src1, 0), (adder, 1))
+ tb.connect(adder, sink)
+ tb.run()
+ self.assertEqual(sink.data(), (1, 5j, 9, 13j, 17))
+
+ def test_convolve(self):
+ tb = gr.top_block()
+ src = gr.vector_source_f([1, 2, 3, 4, 5, 6, 7, 8], False)
+ cv = convolve()
+ sink = gr.vector_sink_f()
+ tb.connect(src, cv, sink)
+ tb.run()
+ self.assertEqual(sink.data(), (1, 2, 3, 4, 5, 6, 7, 8))
+
+ def test_decim2x(self):
+ tb = gr.top_block()
+ src = gr.vector_source_f([1, 2, 3, 4, 5, 6, 7, 8], False)
+ d2x = decim2x()
+ sink = gr.vector_sink_f()
+ tb.connect(src, d2x, sink)
+ tb.run()
+ self.assertEqual(sink.data(), (1, 3, 5, 7))
+
+ def test_interp2x(self):
+ tb = gr.top_block()
+ src = gr.vector_source_f([1, 3, 5, 7, 9], False)
+ i2x = interp2x()
+ sink = gr.vector_sink_f()
+ tb.connect(src, i2x, sink)
+ tb.run()
+ self.assertEqual(sink.data(), (1, 1, 3, 3, 5, 5, 7, 7, 9, 9))
+
+ def test_tags(self):
+ src = tag_source()
+ sink = tag_sink()
+ head = gr.head(gr.sizeof_float, 50000) #should be enough items to get a tag through
+ tb = gr.top_block()
+ tb.connect(src, head, sink)
+ tb.run()
+ self.assertEqual(sink.key, "example_key")
+
+ def test_fc32_to_f32_2(self):
+ tb = gr.top_block()
+ src = gr.vector_source_c([1+2j, 3+4j, 5+6j, 7+8j, 9+10j], False)
+ convert = fc32_to_f32_2()
+ v2s = gr.vector_to_stream(gr.sizeof_float, 2)
+ sink = gr.vector_sink_f()
+ tb.connect(src, convert, v2s, sink)
+ tb.run()
+ self.assertEqual(sink.data(), (1, 2, 3, 4, 5, 6, 7, 8, 9, 10))
+
+if __name__ == '__main__':
+ gr_unittest.run(test_block_gateway, "test_block_gateway.xml")
+
diff --git a/gnuradio-core/src/python/gnuradio/gr/qa_boolean_operators.py b/gnuradio-core/src/python/gnuradio/gr/qa_boolean_operators.py
new file mode 100755
index 000000000..d7d134dcb
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/gr/qa_boolean_operators.py
@@ -0,0 +1,162 @@
+#!/usr/bin/env python
+#
+# Copyright 2004,2007,2008,2010 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr, gr_unittest
+
+class test_boolean_operators (gr_unittest.TestCase):
+
+ def setUp (self):
+ self.tb = gr.top_block ()
+
+ def tearDown (self):
+ self.tb = None
+
+ def help_ss (self, src_data, exp_data, op):
+ for s in zip (range (len (src_data)), src_data):
+ src = gr.vector_source_s (s[1])
+ self.tb.connect (src, (op, s[0]))
+ dst = gr.vector_sink_s ()
+ self.tb.connect (op, dst)
+ self.tb.run ()
+ result_data = dst.data ()
+ self.assertEqual (exp_data, result_data)
+
+ def help_bb (self, src_data, exp_data, op):
+ for s in zip (range (len (src_data)), src_data):
+ src = gr.vector_source_b (s[1])
+ self.tb.connect (src, (op, s[0]))
+ dst = gr.vector_sink_b ()
+ self.tb.connect (op, dst)
+ self.tb.run ()
+ result_data = dst.data ()
+ self.assertEqual (exp_data, result_data)
+
+ def help_ii (self, src_data, exp_data, op):
+ for s in zip (range (len (src_data)), src_data):
+ src = gr.vector_source_i (s[1])
+ self.tb.connect (src, (op, s[0]))
+ dst = gr.vector_sink_i ()
+ self.tb.connect (op, dst)
+ self.tb.run ()
+ result_data = dst.data ()
+ self.assertEqual (exp_data, result_data)
+
+ def test_xor_ss (self):
+ src1_data = (1, 2, 3, 0x5004, 0x1150)
+ src2_data = (8, 2, 1 , 0x0508, 0x1105)
+ expected_result = (9, 0, 2, 0x550C, 0x0055)
+ op = gr.xor_ss ()
+ self.help_ss ((src1_data, src2_data),
+ expected_result, op)
+
+ def test_xor_bb (self):
+ src1_data = (1, 2, 3, 4, 0x50)
+ src2_data = (8, 2, 1 , 8, 0x05)
+ expected_result = (9, 0, 2, 0xC, 0x55)
+ op = gr.xor_bb ()
+ self.help_bb ((src1_data, src2_data),
+ expected_result, op)
+
+
+ def test_xor_ii (self):
+ src1_data = (1, 2, 3, 0x5000004, 0x11000050)
+ src2_data = (8, 2, 1 , 0x0500008, 0x11000005)
+ expected_result = (9, 0, 2, 0x550000C, 0x00000055)
+ op = gr.xor_ii ()
+ self.help_ii ((src1_data, src2_data),
+ expected_result, op)
+
+ def test_and_ss (self):
+ src1_data = (1, 2, 3, 0x5004, 0x1150)
+ src2_data = (8, 2, 1 , 0x0508, 0x1105)
+ expected_result = (0, 2, 1, 0x0000, 0x1100)
+ op = gr.and_ss ()
+ self.help_ss ((src1_data, src2_data),
+ expected_result, op)
+
+ def test_and_bb (self):
+ src1_data = (1, 2, 2, 3, 0x04, 0x50)
+ src2_data = (8, 2, 2, 1, 0x08, 0x05)
+ src3_data = (8, 2, 1, 1, 0x08, 0x05)
+ expected_result = (0, 2, 0, 1, 0x00, 0x00)
+ op = gr.and_bb ()
+ self.help_bb ((src1_data, src2_data, src3_data),
+ expected_result, op)
+
+ def test_and_ii (self):
+ src1_data = (1, 2, 3, 0x50005004, 0x11001150)
+ src2_data = (8, 2, 1 , 0x05000508, 0x11001105)
+ expected_result = (0, 2, 1, 0x00000000, 0x11001100)
+ op = gr.and_ii ()
+ self.help_ii ((src1_data, src2_data),
+ expected_result, op)
+
+ def test_or_ss (self):
+ src1_data = (1, 2, 3, 0x5004, 0x1150)
+ src2_data = (8, 2, 1 , 0x0508, 0x1105)
+ expected_result = (9, 2, 3, 0x550C, 0x1155)
+ op = gr.or_ss ()
+ self.help_ss ((src1_data, src2_data),
+ expected_result, op)
+
+ def test_or_bb (self):
+ src1_data = (1, 2, 2, 3, 0x04, 0x50)
+ src2_data = (8, 2, 2, 1 , 0x08, 0x05)
+ src3_data = (8, 2, 1, 1 , 0x08, 0x05)
+ expected_result = (9, 2, 3, 3, 0x0C, 0x55)
+ op = gr.or_bb ()
+ self.help_bb ((src1_data, src2_data, src3_data),
+ expected_result, op)
+
+ def test_or_ii (self):
+ src1_data = (1, 2, 3, 0x50005004, 0x11001150)
+ src2_data = (8, 2, 1 , 0x05000508, 0x11001105)
+ expected_result = (9, 2, 3, 0x5500550C, 0x11001155)
+ op = gr.or_ii ()
+ self.help_ii ((src1_data, src2_data),
+ expected_result, op)
+
+ def test_not_ss (self):
+ src1_data = (1, 2, 3, 0x5004, 0x1150)
+ expected_result = (~1, ~2, ~3, ~0x5004, ~0x1150)
+ op = gr.not_ss ()
+ self.help_ss ((((src1_data),)),
+ expected_result, op)
+
+ def test_not_bb (self):
+ src1_data = (1, 2, 2, 3, 0x04, 0x50)
+ expected_result = (0xFE, 0xFD, 0xFD, 0xFC, 0xFB, 0xAF)
+ op = gr.not_bb ()
+ self.help_bb (((src1_data), ),
+ expected_result, op)
+
+ def test_not_ii (self):
+ src1_data = (1, 2, 3, 0x50005004, 0x11001150)
+ expected_result = (~1 , ~2, ~3, ~0x50005004, ~0x11001150)
+ op = gr.not_ii ()
+ self.help_ii (((src1_data),),
+ expected_result, op)
+
+
+
+if __name__ == '__main__':
+ gr_unittest.run(test_boolean_operators, "test_boolean_operators.xml")
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
index 000000000..946c0d7f8
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/gr/qa_complex_to_xxx.py
@@ -0,0 +1,142 @@
+#!/usr/bin/env python
+#
+# Copyright 2004,2007,2010 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr, gr_unittest
+import math
+
+class test_complex_ops (gr_unittest.TestCase):
+
+ def setUp (self):
+ self.tb = gr.top_block ()
+
+ def tearDown (self):
+ self.tb = 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.tb.connect (src, op)
+ self.tb.connect (op, dst)
+ self.tb.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.tb.connect (src, op)
+ self.tb.connect ((op, 0), dst0)
+ self.tb.connect ((op, 1), dst1)
+ self.tb.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.tb.connect (src, op)
+ self.tb.connect (op, dst)
+ self.tb.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.tb.connect (src, op)
+ self.tb.connect (op, dst)
+ self.tb.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.tb.connect (src, op)
+ self.tb.connect (op, dst)
+ self.tb.run ()
+ actual_result = dst.data ()
+ self.assertFloatTuplesAlmostEqual (expected_result, actual_result,5)
+
+ def test_complex_to_mag_squared (self):
+ src_data = (0, 1, -1, 3+4j, -3-4j, -3+4j)
+ expected_result = (0, 1, 1, 25, 25, 25)
+ src = gr.vector_source_c (src_data)
+ op = gr.complex_to_mag_squared ()
+ dst = gr.vector_sink_f ()
+ self.tb.connect (src, op)
+ self.tb.connect (op, dst)
+ self.tb.run ()
+ actual_result = dst.data ()
+ self.assertFloatTuplesAlmostEqual (expected_result, actual_result,5)
+
+ def test_complex_to_arg (self):
+ pi = math.pi
+ input_data = (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)
+
+ expected_result = (0.0, # 0
+ 0.52382522821426392, # pi/6
+ 0.78539806604385376, # pi/4
+ 1.5707963705062866, # pi/2
+ 2.3561947345733643, # 3pi/4
+ 2.7491819858551025, # 7pi/8
+ -0.52382522821426392, # -pi/6
+ -0.78539806604385376, # -pi/4
+ -1.5707963705062866, # -pi/2
+ -2.3561947345733643, # -3pi/4
+ -2.7491819858551025) # -7pi/8
+
+ src_data = tuple ([math.cos (x) + math.sin (x) * 1j for x in input_data])
+ src = gr.vector_source_c (src_data)
+ op = gr.complex_to_arg ()
+ dst = gr.vector_sink_f ()
+ self.tb.connect (src, op)
+ self.tb.connect (op, dst)
+ self.tb.run ()
+ actual_result = dst.data ()
+
+ self.assertFloatTuplesAlmostEqual (expected_result, actual_result, 3)
+
+
+if __name__ == '__main__':
+ gr_unittest.run(test_complex_ops, "test_complex_ops.xml")
+
diff --git a/gnuradio-core/src/python/gnuradio/gr/qa_conjugate.py b/gnuradio-core/src/python/gnuradio/gr/qa_conjugate.py
new file mode 100644
index 000000000..17fa891e2
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/gr/qa_conjugate.py
@@ -0,0 +1,53 @@
+#!/usr/bin/env python
+#
+# Copyright 2012 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr, gr_unittest
+
+class test_conjugate (gr_unittest.TestCase):
+
+ def setUp (self):
+ self.tb = gr.top_block ()
+
+ def tearDown (self):
+ self.tb = None
+
+ def test_000 (self):
+ src_data = (-2-2j, -1-1j, -2+2j, -1+1j,
+ 2-2j, 1-1j, 2+2j, 1+1j,
+ 0+0j)
+
+ exp_data = (-2+2j, -1+1j, -2-2j, -1-1j,
+ 2+2j, 1+1j, 2-2j, 1-1j,
+ 0-0j)
+
+ src = gr.vector_source_c(src_data)
+ op = gr.conjugate_cc ()
+ dst = gr.vector_sink_c ()
+
+ self.tb.connect(src, op)
+ self.tb.connect(op, dst)
+ self.tb.run()
+ result_data = dst.data ()
+ self.assertEqual (exp_data, result_data)
+
+if __name__ == '__main__':
+ gr_unittest.run(test_conjugate, "test_conjugate.xml")
diff --git a/gnuradio-core/src/python/gnuradio/gr/qa_copy.py b/gnuradio-core/src/python/gnuradio/gr/qa_copy.py
new file mode 100755
index 000000000..68c8e451f
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/gr/qa_copy.py
@@ -0,0 +1,58 @@
+#!/usr/bin/env python
+#
+# Copyright 2009,2010 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr, gr_unittest
+
+class test_copy(gr_unittest.TestCase):
+
+ def setUp (self):
+ self.tb = gr.top_block ()
+
+ def tearDown (self):
+ self.tb = None
+
+ def test_copy (self):
+ src_data = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
+ expected_result = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
+ src = gr.vector_source_b(src_data)
+ op = gr.copy(gr.sizeof_char)
+ dst = gr.vector_sink_b()
+ self.tb.connect(src, op, dst)
+ self.tb.run()
+ dst_data = dst.data()
+ self.assertEqual(expected_result, dst_data)
+
+ def test_copy_drop (self):
+ src_data = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
+ expected_result = ()
+ src = gr.vector_source_b(src_data)
+ op = gr.copy(gr.sizeof_char)
+ op.set_enabled(False)
+ dst = gr.vector_sink_b()
+ self.tb.connect(src, op, dst)
+ self.tb.run()
+ dst_data = dst.data()
+ self.assertEqual(expected_result, dst_data)
+
+
+if __name__ == '__main__':
+ gr_unittest.run(test_copy, "test_copy.xml")
diff --git a/gnuradio-core/src/python/gnuradio/gr/qa_dc_blocker.py b/gnuradio-core/src/python/gnuradio/gr/qa_dc_blocker.py
new file mode 100755
index 000000000..175735867
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/gr/qa_dc_blocker.py
@@ -0,0 +1,108 @@
+#!/usr/bin/env python
+#
+# Copyright 2011 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr, gr_unittest
+
+class test_dc_blocker(gr_unittest.TestCase):
+
+ def setUp (self):
+ self.tb = gr.top_block ()
+
+ def tearDown (self):
+ self.tb = None
+
+ def test_001(self):
+ ''' Test impulse response - long form, cc '''
+ src_data = [1,] + 100*[0,]
+ expected_result = ((-0.02072429656982422+0j), (-0.02081298828125+0j),
+ (0.979156494140625+0j), (-0.02081298828125+0j),
+ (-0.02072429656982422+0j))
+
+ src = gr.vector_source_c(src_data)
+ op = gr.dc_blocker_cc(32, True)
+ dst = gr.vector_sink_c()
+
+ self.tb.connect (src, op, dst)
+ self.tb.run()
+
+ # only test samples around 2D-2
+ result_data = dst.data()[60:65]
+ self.assertComplexTuplesAlmostEqual (expected_result, result_data)
+
+ def test_002(self):
+ ''' Test impulse response - short form, cc '''
+ src_data = [1,] + 100*[0,]
+ expected_result = ((-0.029296875+0j), (-0.0302734375+0j),
+ (0.96875+0j), (-0.0302734375+0j),
+ (-0.029296875+0j))
+
+ src = gr.vector_source_c(src_data)
+ op = gr.dc_blocker_cc(32, False)
+ dst = gr.vector_sink_c()
+
+ self.tb.connect (src, op, dst)
+ self.tb.run()
+
+ # only test samples around D-1
+ result_data = dst.data()[29:34]
+ self.assertComplexTuplesAlmostEqual (expected_result, result_data)
+
+
+ def test_003(self):
+ ''' Test impulse response - long form, ff '''
+ src_data = [1,] + 100*[0,]
+ expected_result = ((-0.02072429656982422), (-0.02081298828125),
+ (0.979156494140625), (-0.02081298828125),
+ (-0.02072429656982422))
+
+ src = gr.vector_source_f(src_data)
+ op = gr.dc_blocker_ff(32, True)
+ dst = gr.vector_sink_f()
+
+ self.tb.connect (src, op, dst)
+ self.tb.run()
+
+ # only test samples around 2D-2
+ result_data = dst.data()[60:65]
+ self.assertFloatTuplesAlmostEqual (expected_result, result_data)
+
+ def test_004(self):
+ ''' Test impulse response - short form, ff '''
+ src_data = [1,] + 100*[0,]
+ expected_result = ((-0.029296875), (-0.0302734375),
+ (0.96875), (-0.0302734375),
+ (-0.029296875))
+
+ src = gr.vector_source_f(src_data)
+ op = gr.dc_blocker_ff(32, False)
+ dst = gr.vector_sink_f()
+
+ self.tb.connect (src, op, dst)
+ self.tb.run()
+
+ # only test samples around D-1
+ result_data = dst.data()[29:34]
+ self.assertFloatTuplesAlmostEqual (expected_result, result_data)
+
+if __name__ == '__main__':
+ gr_unittest.run(test_dc_blocker, "test_dc_blocker.xml")
+
diff --git a/gnuradio-core/src/python/gnuradio/gr/qa_delay.py b/gnuradio-core/src/python/gnuradio/gr/qa_delay.py
new file mode 100755
index 000000000..0d0bc1330
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/gr/qa_delay.py
@@ -0,0 +1,65 @@
+#!/usr/bin/env python
+#
+# Copyright 2004,2007,2010 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr, gr_unittest
+import math
+
+class test_delay (gr_unittest.TestCase):
+
+ def setUp (self):
+ self.tb = gr.top_block ()
+
+ def tearDown (self):
+ self.tb = None
+
+ def test_000 (self):
+ delta_t = 0
+ tb = self.tb
+ src_data = [float(x) for x in range(0, 100)]
+ expected_result = tuple(delta_t*[0.0] + src_data)
+
+ src = gr.vector_source_f(src_data)
+ op = gr.delay(gr.sizeof_float, delta_t)
+ dst = gr.vector_sink_f ()
+
+ tb.connect (src, op, dst)
+ tb.run ()
+ dst_data = dst.data ()
+ self.assertEqual (expected_result, dst_data)
+
+ def test_010 (self):
+ delta_t = 10
+ tb = self.tb
+ src_data = [float(x) for x in range(0, 100)]
+ expected_result = tuple(delta_t*[0.0] + src_data)
+
+ src = gr.vector_source_f(src_data)
+ op = gr.delay(gr.sizeof_float, delta_t)
+ dst = gr.vector_sink_f ()
+
+ tb.connect (src, op, dst)
+ tb.run ()
+ dst_data = dst.data ()
+ self.assertEqual (expected_result, dst_data)
+
+if __name__ == '__main__':
+ gr_unittest.run(test_delay, "test_delay.xml")
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
index 000000000..c1fe2a700
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/gr/qa_diff_encoder.py
@@ -0,0 +1,86 @@
+#!/usr/bin/env python
+#
+# Copyright 2006,2007,2010 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr, gr_unittest
+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_diff_encoder (gr_unittest.TestCase):
+
+ def setUp (self):
+ self.tb = gr.top_block ()
+
+ def tearDown (self):
+ self.tb = 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.tb.connect(src, enc, dec, dst)
+ self.tb.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.tb.connect(src, enc, dec, dst)
+ self.tb.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.tb.connect(src, enc, dec, dst)
+ self.tb.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.run(test_diff_encoder, "test_diff_encoder.xml")
+
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
index 000000000..41f96aa61
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/gr/qa_diff_phasor_cc.py
@@ -0,0 +1,50 @@
+#!/usr/bin/env python
+#
+# Copyright 2004,2007,2010 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr, gr_unittest
+import math
+
+class test_diff_phasor (gr_unittest.TestCase):
+
+ def setUp (self):
+ self.tb = gr.top_block ()
+
+ def tearDown (self):
+ self.tb = 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.tb.connect (src, op)
+ self.tb.connect (op, dst)
+ self.tb.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.run(test_diff_phasor, "test_diff_phasor.xml")
+
diff --git a/gnuradio-core/src/python/gnuradio/gr/qa_ecc_ccsds_27.py b/gnuradio-core/src/python/gnuradio/gr/qa_ecc_ccsds_27.py
new file mode 100755
index 000000000..29122ff3e
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/gr/qa_ecc_ccsds_27.py
@@ -0,0 +1,50 @@
+#!/usr/bin/env python
+#
+# Copyright 2004,2007,2010 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr, gr_unittest
+
+class test_ccsds_27 (gr_unittest.TestCase):
+
+ def setUp (self):
+ self.tb = gr.top_block ()
+
+ def tearDown (self):
+ self.tb = None
+
+ def xtest_ccsds_27 (self):
+ src_data = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
+ expected = (0, 0, 0, 0, 1, 2, 3, 4, 5, 6)
+ src = gr.vector_source_b(src_data)
+ enc = gr.encode_ccsds_27_bb()
+ b2f = gr.char_to_float()
+ add = gr.add_const_ff(-0.5)
+ mul = gr.multiply_const_ff(2.0)
+ dec = gr.decode_ccsds_27_fb()
+ dst = gr.vector_sink_b()
+ self.tb.connect(src, enc, b2f, add, mul, dec, dst)
+ self.tb.run()
+ dst_data = dst.data()
+ self.assertEqual(expected, dst_data)
+
+
+if __name__ == '__main__':
+ gr_unittest.run(test_ccsds_27, "test_ccsds_27.xml")
diff --git a/gnuradio-core/src/python/gnuradio/gr/qa_endian_swap.py b/gnuradio-core/src/python/gnuradio/gr/qa_endian_swap.py
new file mode 100644
index 000000000..4d2555cc4
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/gr/qa_endian_swap.py
@@ -0,0 +1,66 @@
+#!/usr/bin/env python
+#
+# Copyright 2011,2012 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr, gr_unittest
+import ctypes
+
+class test_endian_swap (gr_unittest.TestCase):
+
+ def setUp (self):
+ self.tb = gr.top_block ()
+
+ def tearDown (self):
+ self.tb = None
+
+ def test_001(self):
+
+ src_data = [1,2,3,4]
+ expected_result = [256, 512, 768, 1024];
+
+ src = gr.vector_source_s(src_data)
+ op = gr.endian_swap(2)
+ dst = gr.vector_sink_s()
+
+ self.tb.connect(src, op, dst)
+ self.tb.run()
+ result_data = list(dst.data())
+
+ self.assertEqual(expected_result, result_data)
+
+ def test_002(self):
+
+ src_data = [1,2,3,4]
+ expected_result = [16777216, 33554432, 50331648, 67108864];
+
+ src = gr.vector_source_i(src_data)
+ op = gr.endian_swap(4)
+ dst = gr.vector_sink_i()
+
+ self.tb.connect(src, op, dst)
+ self.tb.run()
+ result_data = list(dst.data())
+
+ self.assertEqual(expected_result, result_data)
+
+if __name__ == '__main__':
+ gr_unittest.run(test_endian_swap, "test_endian_swap.xml")
+
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
index 000000000..9018e12f3
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/gr/qa_feval.py
@@ -0,0 +1,110 @@
+#!/usr/bin/env python
+#
+# Copyright 2006,2007,2010 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr, gr_unittest
+
+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 my_feval(gr.feval):
+ def __init__(self):
+ gr.feval.__init__(self)
+ self.fired = False
+ def eval(self):
+ self.fired = True
+
+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)
+
+ def test_void_1(self):
+ # this is all in python
+ f = my_feval()
+ f.eval()
+ self.assertEqual(True, f.fired)
+
+ def test_void_2(self):
+ # this is python -> C++ -> python and back again
+ f = my_feval()
+ gr.feval_example(f)
+ self.assertEqual(True, f.fired)
+
+
+if __name__ == '__main__':
+ gr_unittest.run(test_feval, "test_feval.xml")
diff --git a/gnuradio-core/src/python/gnuradio/gr/qa_fft.py b/gnuradio-core/src/python/gnuradio/gr/qa_fft.py
new file mode 100755
index 000000000..693d0e67c
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/gr/qa_fft.py
@@ -0,0 +1,212 @@
+#!/usr/bin/env python
+#
+# Copyright 2008,2010 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+
+from gnuradio import gr, gr_unittest
+import sys
+import random
+
+primes = (2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,
+ 59,61,67,71,73,79,83,89,97,101,103,107,109,113,127,131,
+ 137,139,149,151,157,163,167,173,179,181,191,193,197,199,211,223,
+ 227,229,233,239,241,251,257,263,269,271,277,281,283,293,307,311)
+
+
+class test_fft(gr_unittest.TestCase):
+
+ def setUp(self):
+ pass
+
+ def tearDown(self):
+ pass
+
+ 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_001(self):
+ tb = gr.top_block()
+ fft_size = 32
+ src_data = tuple([complex(primes[2*i], primes[2*i+1]) for i in range(fft_size)])
+
+ expected_result = ((4377+4516j),
+ (-1706.1268310546875+1638.4256591796875j),
+ (-915.2083740234375+660.69427490234375j),
+ (-660.370361328125+381.59600830078125j),
+ (-499.96044921875+238.41630554199219j),
+ (-462.26748657226562+152.88948059082031j),
+ (-377.98440551757812+77.5928955078125j),
+ (-346.85821533203125+47.152004241943359j),
+ (-295+20j),
+ (-286.33609008789062-22.257017135620117j),
+ (-271.52999877929688-33.081821441650391j),
+ (-224.6358642578125-67.019538879394531j),
+ (-244.24473571777344-91.524826049804688j),
+ (-203.09068298339844-108.54627227783203j),
+ (-198.45195007324219-115.90768432617188j),
+ (-182.97744750976562-128.12318420410156j),
+ (-167-180j),
+ (-130.33688354492188-173.83778381347656j),
+ (-141.19784545898438-190.28807067871094j),
+ (-111.09677124023438-214.48896789550781j),
+ (-70.039543151855469-242.41630554199219j),
+ (-68.960540771484375-228.30015563964844j),
+ (-53.049201965332031-291.47097778320312j),
+ (-28.695289611816406-317.64553833007812j),
+ (57-300j),
+ (45.301143646240234-335.69509887695312j),
+ (91.936195373535156-373.32437133789062j),
+ (172.09465026855469-439.275146484375j),
+ (242.24473571777344-504.47515869140625j),
+ (387.81732177734375-666.6788330078125j),
+ (689.48553466796875-918.2142333984375j),
+ (1646.539306640625-1694.1956787109375j))
+
+ src = gr.vector_source_c(src_data)
+ s2v = gr.stream_to_vector(gr.sizeof_gr_complex, fft_size)
+ fft = gr.fft_vcc(fft_size, True, [], False)
+ v2s = gr.vector_to_stream(gr.sizeof_gr_complex, fft_size)
+ dst = gr.vector_sink_c()
+ tb.connect(src, s2v, fft, v2s, dst)
+ tb.run()
+ result_data = dst.data()
+ #print 'expected:', expected_result
+ #print 'results: ', result_data
+ #self.assertComplexTuplesAlmostEqual (expected_result, result_data, 5)
+ self.assert_fft_ok2(expected_result, result_data)
+
+ def test_002(self):
+ tb = gr.top_block()
+ fft_size = 32
+
+ tmp_data = ((4377+4516j),
+ (-1706.1268310546875+1638.4256591796875j),
+ (-915.2083740234375+660.69427490234375j),
+ (-660.370361328125+381.59600830078125j),
+ (-499.96044921875+238.41630554199219j),
+ (-462.26748657226562+152.88948059082031j),
+ (-377.98440551757812+77.5928955078125j),
+ (-346.85821533203125+47.152004241943359j),
+ (-295+20j),
+ (-286.33609008789062-22.257017135620117j),
+ (-271.52999877929688-33.081821441650391j),
+ (-224.6358642578125-67.019538879394531j),
+ (-244.24473571777344-91.524826049804688j),
+ (-203.09068298339844-108.54627227783203j),
+ (-198.45195007324219-115.90768432617188j),
+ (-182.97744750976562-128.12318420410156j),
+ (-167-180j),
+ (-130.33688354492188-173.83778381347656j),
+ (-141.19784545898438-190.28807067871094j),
+ (-111.09677124023438-214.48896789550781j),
+ (-70.039543151855469-242.41630554199219j),
+ (-68.960540771484375-228.30015563964844j),
+ (-53.049201965332031-291.47097778320312j),
+ (-28.695289611816406-317.64553833007812j),
+ (57-300j),
+ (45.301143646240234-335.69509887695312j),
+ (91.936195373535156-373.32437133789062j),
+ (172.09465026855469-439.275146484375j),
+ (242.24473571777344-504.47515869140625j),
+ (387.81732177734375-666.6788330078125j),
+ (689.48553466796875-918.2142333984375j),
+ (1646.539306640625-1694.1956787109375j))
+
+ src_data = tuple([x/fft_size for x in tmp_data])
+
+ expected_result = tuple([complex(primes[2*i], primes[2*i+1]) for i in range(fft_size)])
+
+ src = gr.vector_source_c(src_data)
+ s2v = gr.stream_to_vector(gr.sizeof_gr_complex, fft_size)
+ fft = gr.fft_vcc(fft_size, False, [], False)
+ v2s = gr.vector_to_stream(gr.sizeof_gr_complex, fft_size)
+ dst = gr.vector_sink_c()
+ tb.connect(src, s2v, fft, v2s, dst)
+ tb.run()
+ result_data = dst.data()
+ #print 'expected:', expected_result
+ #print 'results: ', result_data
+ #self.assertComplexTuplesAlmostEqual (expected_result, result_data, 5)
+ self.assert_fft_ok2(expected_result, result_data)
+
+ def test_003(self):
+ # Same test as above, only use 2 threads
+
+ tb = gr.top_block()
+ fft_size = 32
+
+ tmp_data = ((4377+4516j),
+ (-1706.1268310546875+1638.4256591796875j),
+ (-915.2083740234375+660.69427490234375j),
+ (-660.370361328125+381.59600830078125j),
+ (-499.96044921875+238.41630554199219j),
+ (-462.26748657226562+152.88948059082031j),
+ (-377.98440551757812+77.5928955078125j),
+ (-346.85821533203125+47.152004241943359j),
+ (-295+20j),
+ (-286.33609008789062-22.257017135620117j),
+ (-271.52999877929688-33.081821441650391j),
+ (-224.6358642578125-67.019538879394531j),
+ (-244.24473571777344-91.524826049804688j),
+ (-203.09068298339844-108.54627227783203j),
+ (-198.45195007324219-115.90768432617188j),
+ (-182.97744750976562-128.12318420410156j),
+ (-167-180j),
+ (-130.33688354492188-173.83778381347656j),
+ (-141.19784545898438-190.28807067871094j),
+ (-111.09677124023438-214.48896789550781j),
+ (-70.039543151855469-242.41630554199219j),
+ (-68.960540771484375-228.30015563964844j),
+ (-53.049201965332031-291.47097778320312j),
+ (-28.695289611816406-317.64553833007812j),
+ (57-300j),
+ (45.301143646240234-335.69509887695312j),
+ (91.936195373535156-373.32437133789062j),
+ (172.09465026855469-439.275146484375j),
+ (242.24473571777344-504.47515869140625j),
+ (387.81732177734375-666.6788330078125j),
+ (689.48553466796875-918.2142333984375j),
+ (1646.539306640625-1694.1956787109375j))
+
+ src_data = tuple([x/fft_size for x in tmp_data])
+
+ expected_result = tuple([complex(primes[2*i], primes[2*i+1]) for i in range(fft_size)])
+
+ nthreads = 2
+
+ src = gr.vector_source_c(src_data)
+ s2v = gr.stream_to_vector(gr.sizeof_gr_complex, fft_size)
+ fft = gr.fft_vcc(fft_size, False, [], False, nthreads)
+ v2s = gr.vector_to_stream(gr.sizeof_gr_complex, fft_size)
+ dst = gr.vector_sink_c()
+ tb.connect(src, s2v, fft, v2s, dst)
+ tb.run()
+ result_data = dst.data()
+ self.assert_fft_ok2(expected_result, result_data)
+
+if __name__ == '__main__':
+ gr_unittest.run(test_fft, "test_fft.xml")
+
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
index 000000000..c0aadc306
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/gr/qa_fft_filter.py
@@ -0,0 +1,383 @@
+#!/usr/bin/env python
+#
+# Copyright 2004,2005,2007,2010 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr, gr_unittest
+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
+ """
+ tb = gr.top_block()
+ #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()
+ tb.connect(src, op, dst)
+ tb.run()
+ return dst.data()
+
+def reference_filter_fff(dec, taps, input):
+ """
+ compute result using conventional fir filter
+ """
+ tb = gr.top_block()
+ #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()
+ tb.connect(src, op, dst)
+ tb.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):
+ pass
+
+ def tearDown(self):
+ pass
+
+ 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):
+ tb = gr.top_block()
+ 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()
+ tb.connect(src, op, dst)
+ tb.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):
+ # Test nthreads
+ tb = gr.top_block()
+ src_data = (0,1,2,3,4,5,6,7)
+ taps = (2,)
+ nthreads = 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, nthreads)
+ dst = gr.vector_sink_c()
+ tb.connect(src, op, dst)
+ tb.run()
+ result_data = dst.data()
+ #print 'expected:', expected_result
+ #print 'results: ', result_data
+ self.assertComplexTuplesAlmostEqual (expected_result, result_data, 5)
+
+ def test_ccc_003(self):
+ tb = gr.top_block()
+ 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()
+ tb.connect(src, op, dst)
+ tb.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()
+ tb = gr.top_block()
+ tb.connect(src, op, dst)
+ tb.run()
+ result_data = dst.data()
+ del tb
+
+ 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()
+ tb = gr.top_block()
+ tb.connect(src, op, dst)
+ tb.run()
+ del tb
+ result_data = dst.data()
+
+ self.assert_fft_ok2(expected_result, result_data)
+
+ def test_ccc_006(self):
+ # Test decimating with nthreads=2
+ random.seed(0)
+ nthreads = 2
+ 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, nthreads)
+ dst = gr.vector_sink_c()
+ tb = gr.top_block()
+ tb.connect(src, op, dst)
+ tb.run()
+ del tb
+ result_data = dst.data()
+
+ self.assert_fft_ok2(expected_result, result_data)
+
+ # ----------------------------------------------------------------
+ # test _fff version
+ # ----------------------------------------------------------------
+
+ def test_fff_001(self):
+ tb = gr.top_block()
+ 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()
+ tb.connect(src, op, dst)
+ tb.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):
+ tb = gr.top_block()
+ 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()
+ tb.connect(src, op, dst)
+ tb.run()
+ result_data = dst.data()
+ #print 'expected:', expected_result
+ #print 'results: ', result_data
+ self.assertFloatTuplesAlmostEqual (expected_result, result_data, 5)
+
+ def test_fff_003(self):
+ # Test 02 with nthreads
+ tb = gr.top_block()
+ src_data = (0,1,2,3,4,5,6,7)
+ taps = (2,)
+ nthreads = 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, nthreads)
+ dst = gr.vector_sink_f()
+ tb.connect(src, op, dst)
+ tb.run()
+ result_data = dst.data()
+ self.assertFloatTuplesAlmostEqual (expected_result, result_data, 5)
+
+ def xtest_fff_004(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()
+ tb = gr.top_block()
+ tb.connect(src, op, dst)
+ tb.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_005(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()
+ tb = gr.top_block()
+ tb.connect(src, op, dst)
+ tb.run()
+ result_data = dst.data()
+
+ self.assert_fft_float_ok2(expected_result, result_data, abs_eps=2.0)
+
+ def xtest_fff_006(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()
+ tb = gr.top_block()
+ tb.connect(src, op, dst)
+ tb.run()
+ result_data = dst.data()
+
+ self.assert_fft_float_ok2(expected_result, result_data)
+
+ def xtest_fff_007(self):
+ # test decimation with nthreads
+ random.seed(0)
+ nthreads = 2
+ 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, nthreads)
+ dst = gr.vector_sink_f()
+ tb = gr.top_block()
+ tb.connect(src, op, dst)
+ tb.run()
+ result_data = dst.data()
+
+ self.assert_fft_float_ok2(expected_result, result_data)
+
+ def test_fff_get0(self):
+ random.seed(0)
+ for i in xrange(25):
+ ntaps = int(random.uniform(2, 100))
+ taps = make_random_float_tuple(ntaps)
+
+ op = gr.fft_filter_fff(1, taps)
+ result_data = op.taps()
+ #print result_data
+
+ self.assertEqual(taps, result_data)
+
+ def test_ccc_get0(self):
+ random.seed(0)
+ for i in xrange(25):
+ ntaps = int(random.uniform(2, 100))
+ taps = make_random_complex_tuple(ntaps)
+
+ op = gr.fft_filter_ccc(1, taps)
+ result_data = op.taps()
+ #print result_data
+
+ self.assertComplexTuplesAlmostEqual(taps, result_data, 4)
+
+
+if __name__ == '__main__':
+ gr_unittest.run(test_fft_filter, "test_fft_filter.xml")
+
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
index 000000000..8d325fc3e
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/gr/qa_filter_delay_fc.py
@@ -0,0 +1,317 @@
+#!/usr/bin/env python
+#
+# Copyright 2004,2007,2010 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr, gr_unittest
+import math
+
+class test_filter_delay_fc (gr_unittest.TestCase):
+
+ def setUp (self):
+ self.tb = gr.top_block ()
+
+ def tearDown (self):
+ self.tb = 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))
+
+ tb = self.tb
+
+ 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)
+
+ tb.connect (src1, head)
+ tb.connect (head, hd)
+ tb.connect (hd,dst2)
+
+ tb.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))
+
+
+ tb = self.tb
+
+ 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)
+
+ tb.connect (src1, head)
+ tb.connect (head, (hd,0))
+ tb.connect (head, (hd,1))
+ tb.connect (hd,dst2)
+ tb.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))
+
+ tb = self.tb
+
+ 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 ()
+
+ tb.connect (src1, head1)
+ tb.connect (src2, head2)
+
+ tb.connect (head1, (hd,0))
+ tb.connect (head2, (hd,1))
+ tb.connect (hd, dst2)
+
+ tb.run ()
+
+ # get output
+ result_data = dst2.data ()
+
+ self.assertComplexTuplesAlmostEqual (expected_result, result_data, 5)
+
+
+if __name__ == '__main__':
+ gr_unittest.run(test_filter_delay_fc, "test_filter_delay_fc.xml")
diff --git a/gnuradio-core/src/python/gnuradio/gr/qa_float_to_char.py b/gnuradio-core/src/python/gnuradio/gr/qa_float_to_char.py
new file mode 100755
index 000000000..057e297f9
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/gr/qa_float_to_char.py
@@ -0,0 +1,82 @@
+#!/usr/bin/env python
+#
+# Copyright 2011,2012 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr, gr_unittest
+class test_float_to_char (gr_unittest.TestCase):
+
+ def setUp (self):
+ self.tb = gr.top_block ()
+
+ def tearDown (self):
+ self.tb = None
+
+ def test_001(self):
+
+ src_data = (0.0, 1.1, 2.2, 3.3, 4.4, 5.5, -1.1, -2.2, -3.3)
+ expected_result = [0, 1, 2, 3, 4, 5, 255, 254, 253]
+ src = gr.vector_source_f(src_data)
+ op = gr.float_to_char()
+ dst = gr.vector_sink_b()
+
+ self.tb.connect(src, op, dst)
+ self.tb.run()
+ result_data = list(dst.data())
+
+ self.assertEqual(expected_result, result_data)
+
+ def test_002(self):
+
+ src_data = ( 126.0, 127.0, 128.0)
+ expected_result = [ 126, 127, 127 ]
+
+ src = gr.vector_source_f(src_data)
+ op = gr.float_to_char()
+ # Note: vector_sink_b returns uchar
+ dst = gr.vector_sink_b()
+
+ self.tb.connect(src, op, dst)
+ self.tb.run()
+ result_data = list(dst.data())
+
+ self.assertEqual(expected_result, result_data)
+
+ def test_003(self):
+
+ scale = 2
+ vlen = 3
+ src_data = (0.0, 1.1, 2.2, 3.3, 4.4, 5.5, -1.1, -2.2, -3.3)
+ expected_result = [0, 2, 4, 6, 8, 11, 254, 252, 250]
+ src = gr.vector_source_f(src_data)
+ s2v = gr.stream_to_vector(gr.sizeof_float, vlen)
+ op = gr.float_to_char(vlen, scale)
+ v2s = gr.vector_to_stream(gr.sizeof_char, vlen)
+ dst = gr.vector_sink_b()
+
+ self.tb.connect(src, s2v, op, v2s, dst)
+ self.tb.run()
+ result_data = list(dst.data())
+
+ self.assertEqual(expected_result, result_data)
+
+if __name__ == '__main__':
+ gr_unittest.run(test_float_to_char, "test_float_to_char.xml")
+
diff --git a/gnuradio-core/src/python/gnuradio/gr/qa_float_to_int.py b/gnuradio-core/src/python/gnuradio/gr/qa_float_to_int.py
new file mode 100755
index 000000000..5c7a412d2
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/gr/qa_float_to_int.py
@@ -0,0 +1,85 @@
+#!/usr/bin/env python
+#
+# Copyright 2011 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr, gr_unittest
+
+class test_float_to_int (gr_unittest.TestCase):
+
+ def setUp (self):
+ self.tb = gr.top_block ()
+
+ def tearDown (self):
+ self.tb = None
+
+ def test_001(self):
+
+ src_data = (0.0, 1.1, 2.2, 3.3, 4.4, 5.5, -1.1, -2.2, -3.3, -4.4, -5.5)
+ expected_result = [0, 1, 2, 3, 4, 6, -1, -2, -3, -4, -6]
+
+ src = gr.vector_source_f(src_data)
+ op = gr.float_to_int()
+ dst = gr.vector_sink_i()
+
+ self.tb.connect(src, op, dst)
+ self.tb.run()
+ result_data = list(dst.data())
+
+ self.assertEqual(expected_result, result_data)
+
+ def test_002(self):
+
+ src_data = ( 2147483647, 2147483648, 2200000000,
+ -2147483648, -2147483649, -2200000000)
+ expected_result = [ 2147483647, 2147483647, 2147483647,
+ -2147483647, -2147483647, -2147483647]
+ src = gr.vector_source_f(src_data)
+ op = gr.float_to_int()
+ dst = gr.vector_sink_i()
+
+ self.tb.connect(src, op, dst)
+ self.tb.run()
+ result_data = list(dst.data())
+
+ self.assertEqual(expected_result, result_data)
+
+
+ def test_003(self):
+
+ scale = 2
+ vlen = 3
+ src_data = (0.0, 1.1, 2.2, 3.3, 4.4, 5.5, -1.1, -2.2, -3.3)
+ expected_result = [0, 2, 4, 7, 9, 11, -2, -4, -7,]
+ src = gr.vector_source_f(src_data)
+ s2v = gr.stream_to_vector(gr.sizeof_float, vlen)
+ op = gr.float_to_int(vlen, scale)
+ v2s = gr.vector_to_stream(gr.sizeof_int, vlen)
+ dst = gr.vector_sink_i()
+
+ self.tb.connect(src, s2v, op, v2s, dst)
+ self.tb.run()
+ result_data = list(dst.data())
+
+ self.assertEqual(expected_result, result_data)
+
+if __name__ == '__main__':
+ gr_unittest.run(test_float_to_int, "test_float_to_int.xml")
+
diff --git a/gnuradio-core/src/python/gnuradio/gr/qa_float_to_short.py b/gnuradio-core/src/python/gnuradio/gr/qa_float_to_short.py
new file mode 100755
index 000000000..3f8b66975
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/gr/qa_float_to_short.py
@@ -0,0 +1,86 @@
+#!/usr/bin/env python
+#
+# Copyright 2011,2012 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr, gr_unittest
+import ctypes
+
+class test_float_to_short (gr_unittest.TestCase):
+
+ def setUp (self):
+ self.tb = gr.top_block ()
+
+ def tearDown (self):
+ self.tb = None
+
+ def test_001(self):
+
+ src_data = (0.0, 1.1, 2.2, 3.3, 4.4, 5.5, -1.1, -2.2, -3.3, -4.4, -5.5)
+ expected_result = [0, 1, 2, 3, 4, 6, -1, -2, -3, -4, -6]
+
+ src = gr.vector_source_f(src_data)
+ op = gr.float_to_short()
+ dst = gr.vector_sink_s()
+
+ self.tb.connect(src, op, dst)
+ self.tb.run()
+ result_data = list(dst.data())
+
+ self.assertEqual(expected_result, result_data)
+
+ def test_002(self):
+
+ src_data = ( 32766, 32767, 32768,
+ -32767, -32768, -32769)
+ expected_result = [ 32766, 32767, 32767,
+ -32767, -32768, -32768 ]
+
+ src = gr.vector_source_f(src_data)
+ op = gr.float_to_short()
+ dst = gr.vector_sink_s()
+
+ self.tb.connect(src, op, dst)
+ self.tb.run()
+ result_data = list(dst.data())
+
+ self.assertEqual(expected_result, result_data)
+
+ def test_003(self):
+
+ scale = 2
+ vlen = 3
+ src_data = (0.0, 1.1, 2.2, 3.3, 4.4, 5.5, -1.1, -2.2, -3.3)
+ expected_result = [0, 2, 4, 7, 9, 11, -2, -4, -7]
+ src = gr.vector_source_f(src_data)
+ s2v = gr.stream_to_vector(gr.sizeof_float, vlen)
+ op = gr.float_to_short(vlen, scale)
+ v2s = gr.vector_to_stream(gr.sizeof_short, vlen)
+ dst = gr.vector_sink_s()
+
+ self.tb.connect(src, s2v, op, v2s, dst)
+ self.tb.run()
+ result_data = list(dst.data())
+
+ self.assertEqual(expected_result, result_data)
+
+if __name__ == '__main__':
+ gr_unittest.run(test_float_to_short, "test_float_to_short.xml")
+
diff --git a/gnuradio-core/src/python/gnuradio/gr/qa_float_to_uchar.py b/gnuradio-core/src/python/gnuradio/gr/qa_float_to_uchar.py
new file mode 100755
index 000000000..831bed93e
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/gr/qa_float_to_uchar.py
@@ -0,0 +1,64 @@
+#!/usr/bin/env python
+#
+# Copyright 2011 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr, gr_unittest
+import ctypes
+
+class test_float_to_uchar (gr_unittest.TestCase):
+
+ def setUp (self):
+ self.tb = gr.top_block ()
+
+ def tearDown (self):
+ self.tb = None
+
+ def test_001(self):
+
+ src_data = (0.0, 1.1, 2.2, 3.3, 4.4, 5.5, -1.1, -2.2, -3.3, -4.4, -5.5)
+ expected_result = [0, 1, 2, 3, 4, 6, 0, 0, 0, 0, 0]
+ src = gr.vector_source_f(src_data)
+ op = gr.float_to_uchar()
+ dst = gr.vector_sink_b()
+
+ self.tb.connect(src, op, dst)
+ self.tb.run()
+ result_data = list(dst.data())
+
+ self.assertEqual(expected_result, result_data)
+
+ def test_002(self):
+
+ src_data = ( 254.0, 255.0, 256.0)
+ expected_result = [ 254, 255, 255 ]
+ src = gr.vector_source_f(src_data)
+ op = gr.float_to_uchar()
+ dst = gr.vector_sink_b()
+
+ self.tb.connect(src, op, dst)
+ self.tb.run()
+ result_data = list(dst.data())
+
+ self.assertEqual(expected_result, result_data)
+
+if __name__ == '__main__':
+ gr_unittest.run(test_float_to_uchar, "test_float_to_uchar.xml")
+
diff --git a/gnuradio-core/src/python/gnuradio/gr/qa_fractional_interpolator.py b/gnuradio-core/src/python/gnuradio/gr/qa_fractional_interpolator.py
new file mode 100755
index 000000000..e19bb28f3
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/gr/qa_fractional_interpolator.py
@@ -0,0 +1,38 @@
+#!/usr/bin/env python
+#
+# Copyright 2007,2010 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr, gr_unittest
+
+class test_fractional_resampler (gr_unittest.TestCase):
+
+ def setUp(self):
+ self.tb = gr.top_block()
+
+ def tearDown(self):
+ self.tb = None
+
+ def test_000_make(self):
+ op = gr.fractional_interpolator_ff(0.0, 1.0)
+ op2 = gr.fractional_interpolator_cc(0.0, 1.0)
+
+if __name__ == '__main__':
+ gr_unittest.run(test_fractional_resampler, "test_fractional_resampler.xml")
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
index 000000000..23459fff3
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/gr/qa_frequency_modulator.py
@@ -0,0 +1,56 @@
+#!/usr/bin/env python
+#
+# Copyright 2004,2007,2010 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr, gr_unittest
+import math
+
+def sincos(x):
+ return math.cos(x) + math.sin(x) * 1j
+
+
+class test_frequency_modulator (gr_unittest.TestCase):
+
+ def setUp (self):
+ self.tb = gr.top_block ()
+
+ def tearDown (self):
+ self.tb = 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.tb.connect (src, op)
+ self.tb.connect (op, dst)
+ self.tb.run ()
+ result_data = dst.data ()
+ self.assertComplexTuplesAlmostEqual (expected_result, result_data, 5)
+
+
+if __name__ == '__main__':
+ gr_unittest.run(test_frequency_modulator, "test_frequency_modulator.xml")
+
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
index 000000000..95b8c0664
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/gr/qa_fsk_stuff.py
@@ -0,0 +1,75 @@
+#!/usr/bin/env python
+#
+# Copyright 2004,2007,2010 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr, gr_unittest
+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.tb = gr.top_block ()
+
+ def tearDown (self):
+ self.tb = 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.tb.connect (src, op)
+ self.tb.connect (op, dst)
+ self.tb.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.tb.connect (src, op)
+ self.tb.connect (op, dst)
+ self.tb.run ()
+ result_data = dst.data ()
+ self.assertEqual (expected_result, result_data)
+
+
+if __name__ == '__main__':
+ gr_unittest.run(test_bytes_to_syms, "test_bytes_to_syms.xml")
+
diff --git a/gnuradio-core/src/python/gnuradio/gr/qa_glfsr_source.py b/gnuradio-core/src/python/gnuradio/gr/qa_glfsr_source.py
new file mode 100755
index 000000000..161e4a5cc
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/gr/qa_glfsr_source.py
@@ -0,0 +1,94 @@
+#!/usr/bin/env python
+#
+# Copyright 2007,2010 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr, gr_unittest
+
+class test_glfsr_source(gr_unittest.TestCase):
+
+ def setUp (self):
+ self.tb = gr.top_block ()
+
+ def tearDown (self):
+ self.tb = None
+
+ def test_000_make_b(self):
+ src = gr.glfsr_source_b(16)
+ self.assertEquals(src.mask(), 0x8016)
+ self.assertEquals(src.period(), 2**16-1)
+
+ def test_001_degree_b(self):
+ self.assertRaises(RuntimeError,
+ lambda: gr.glfsr_source_b(0))
+ self.assertRaises(RuntimeError,
+ lambda: gr.glfsr_source_b(33))
+
+ def test_002_correlation_b(self):
+ for degree in range(1,11): # Higher degrees take too long to correlate
+ src = gr.glfsr_source_b(degree, False)
+ b2f = gr.chunks_to_symbols_bf((-1.0,1.0), 1)
+ dst = gr.vector_sink_f()
+ del self.tb # Discard existing top block
+ self.tb = gr.top_block()
+ self.tb.connect(src, b2f, dst)
+ self.tb.run()
+ self.tb.disconnect_all()
+ actual_result = dst.data()
+ R = auto_correlate(actual_result)
+ self.assertEqual(R[0], float(len(R))) # Auto-correlation peak at origin
+ for i in range(len(R)-1):
+ self.assertEqual(R[i+1], -1.0) # Auto-correlation minimum everywhere else
+
+ def test_003_make_f(self):
+ src = gr.glfsr_source_f(16)
+ self.assertEquals(src.mask(), 0x8016)
+ self.assertEquals(src.period(), 2**16-1)
+
+ def test_004_degree_f(self):
+ self.assertRaises(RuntimeError,
+ lambda: gr.glfsr_source_f(0))
+ self.assertRaises(RuntimeError,
+ lambda: gr.glfsr_source_f(33))
+ def test_005_correlation_f(self):
+ for degree in range(1,11): # Higher degrees take too long to correlate
+ src = gr.glfsr_source_f(degree, False)
+ dst = gr.vector_sink_f()
+ del self.tb # Discard existing top block
+ self.tb = gr.top_block()
+ self.tb.connect(src, dst)
+ self.tb.run()
+
+ actual_result = dst.data()
+ R = auto_correlate(actual_result)
+ self.assertEqual(R[0], float(len(R))) # Auto-correlation peak at origin
+ for i in range(len(R)-1):
+ self.assertEqual(R[i+1], -1.0) # Auto-correlation minimum everywhere else
+
+def auto_correlate(data):
+ l = len(data)
+ R = [0,]*l
+ for lag in range(l):
+ for i in range(l):
+ R[lag] += data[i]*data[i-lag]
+ return R
+
+if __name__ == '__main__':
+ gr_unittest.run(test_glfsr_source, "test_glfsr_source.xml")
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
index 000000000..77f1b5f89
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/gr/qa_goertzel.py
@@ -0,0 +1,64 @@
+#!/usr/bin/env python
+#
+# Copyright 2006,2007,2010 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr, gr_unittest
+from math import pi, cos
+
+class test_goertzel(gr_unittest.TestCase):
+
+ def setUp(self):
+ self.tb = gr.top_block()
+
+ def tearDown(self):
+ self.tb = 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.tb.connect(src, dft, dst)
+ self.tb.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=4)
+
+ 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=4)
+
+if __name__ == '__main__':
+ gr_unittest.run(test_goertzel, "test_goertzel.xml")
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
index 000000000..d7cb354dc
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/gr/qa_head.py
@@ -0,0 +1,47 @@
+#!/usr/bin/env python
+#
+# Copyright 2004,2007,2010 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr, gr_unittest
+
+class test_head (gr_unittest.TestCase):
+
+ def setUp (self):
+ self.tb = gr.top_block ()
+
+ def tearDown (self):
+ self.tb = 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.tb.connect (src1, op)
+ self.tb.connect (op, dst1)
+ self.tb.run ()
+ dst_data = dst1.data ()
+ self.assertEqual (expected_result, dst_data)
+
+
+if __name__ == '__main__':
+ gr_unittest.run(test_head, "test_head.xml")
diff --git a/gnuradio-core/src/python/gnuradio/gr/qa_hier_block2.py b/gnuradio-core/src/python/gnuradio/gr/qa_hier_block2.py
new file mode 100755
index 000000000..3132d91b0
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/gr/qa_hier_block2.py
@@ -0,0 +1,369 @@
+#!/usr/bin/env python
+
+from gnuradio import gr, gr_unittest
+
+class test_hier_block2(gr_unittest.TestCase):
+
+ def setUp(self):
+ pass
+
+ def tearDown(self):
+ pass
+
+ def test_001_make(self):
+ hblock = gr.hier_block2("test_block",
+ gr.io_signature(1,1,gr.sizeof_int),
+ gr.io_signature(1,1,gr.sizeof_int))
+ self.assertEqual("test_block", hblock.name())
+ self.assertEqual(1, hblock.input_signature().max_streams())
+ self.assertEqual(1, hblock.output_signature().min_streams())
+ self.assertEqual(1, hblock.output_signature().max_streams())
+ self.assertEqual(gr.sizeof_int, hblock.output_signature().sizeof_stream_item(0))
+
+ def test_002_connect_input(self):
+ hblock = gr.hier_block2("test_block",
+ gr.io_signature(1,1,gr.sizeof_int),
+ gr.io_signature(1,1,gr.sizeof_int))
+ nop1 = gr.nop(gr.sizeof_int)
+ hblock.connect(hblock, nop1)
+
+ def test_004_connect_output(self):
+ hblock = gr.hier_block2("test_block",
+ gr.io_signature(1,1,gr.sizeof_int),
+ gr.io_signature(1,1,gr.sizeof_int))
+ nop1 = gr.nop(gr.sizeof_int)
+ hblock.connect(nop1, hblock)
+
+ def test_005_connect_output_in_use(self):
+ hblock = gr.hier_block2("test_block",
+ gr.io_signature(1,1,gr.sizeof_int),
+ gr.io_signature(1,1,gr.sizeof_int))
+ nop1 = gr.nop(gr.sizeof_int)
+ nop2 = gr.nop(gr.sizeof_int)
+ hblock.connect(nop1, hblock)
+ self.assertRaises(ValueError,
+ lambda: hblock.connect(nop2, hblock))
+
+ def test_006_connect_invalid_src_port_neg(self):
+ hblock = gr.hier_block2("test_block",
+ gr.io_signature(1,1,gr.sizeof_int),
+ gr.io_signature(1,1,gr.sizeof_int))
+ nop1 = gr.nop(gr.sizeof_int)
+ self.assertRaises(ValueError,
+ lambda: hblock.connect((hblock, -1), nop1))
+
+ def test_005_connect_invalid_src_port_exceeds(self):
+ hblock = gr.hier_block2("test_block",
+ gr.io_signature(1,1,gr.sizeof_int),
+ gr.io_signature(1,1,gr.sizeof_int))
+ nop1 = gr.nop(gr.sizeof_int)
+ self.assertRaises(ValueError,
+ lambda: hblock.connect((hblock, 1), nop1))
+
+ def test_007_connect_invalid_dst_port_neg(self):
+ hblock = gr.hier_block2("test_block",
+ gr.io_signature(1,1,gr.sizeof_int),
+ gr.io_signature(1,1,gr.sizeof_int))
+ nop1 = gr.nop(gr.sizeof_int)
+ nop2 = gr.nop(gr.sizeof_int)
+ self.assertRaises(ValueError,
+ lambda: hblock.connect(nop1, (nop2, -1)))
+
+ def test_008_connect_invalid_dst_port_exceeds(self):
+ hblock = gr.hier_block2("test_block",
+ gr.io_signature(1,1,gr.sizeof_int),
+ gr.io_signature(1,1,gr.sizeof_int))
+ nop1 = gr.null_sink(gr.sizeof_int)
+ nop2 = gr.null_sink(gr.sizeof_int)
+ self.assertRaises(ValueError,
+ lambda: hblock.connect(nop1, (nop2, 1)))
+
+ def test_009_check_topology(self):
+ hblock = gr.top_block("test_block")
+ hblock.check_topology(0, 0)
+
+ def test_010_run(self):
+ expected = (1.0, 2.0, 3.0, 4.0)
+ hblock = gr.top_block("test_block")
+ src = gr.vector_source_f(expected, False)
+ sink1 = gr.vector_sink_f()
+ sink2 = gr.vector_sink_f()
+ hblock.connect(src, sink1)
+ hblock.connect(src, sink2)
+ hblock.run()
+ actual1 = sink1.data()
+ actual2 = sink2.data()
+ self.assertEquals(expected, actual1)
+ self.assertEquals(expected, actual2)
+
+ def test_012_disconnect_input(self):
+ hblock = gr.hier_block2("test_block",
+ gr.io_signature(1,1,gr.sizeof_int),
+ gr.io_signature(1,1,gr.sizeof_int))
+ nop1 = gr.nop(gr.sizeof_int)
+ hblock.connect(hblock, nop1)
+ hblock.disconnect(hblock, nop1)
+
+ def test_013_disconnect_input_not_connected(self):
+ hblock = gr.hier_block2("test_block",
+ gr.io_signature(1,1,gr.sizeof_int),
+ gr.io_signature(1,1,gr.sizeof_int))
+ nop1 = gr.nop(gr.sizeof_int)
+ nop2 = gr.nop(gr.sizeof_int)
+ hblock.connect(hblock, nop1)
+ self.assertRaises(ValueError,
+ lambda: hblock.disconnect(hblock, nop2))
+
+ def test_014_disconnect_input_neg(self):
+ hblock = gr.hier_block2("test_block",
+ gr.io_signature(1,1,gr.sizeof_int),
+ gr.io_signature(1,1,gr.sizeof_int))
+ nop1 = gr.nop(gr.sizeof_int)
+ hblock.connect(hblock, nop1)
+ self.assertRaises(ValueError,
+ lambda: hblock.disconnect((hblock, -1), nop1))
+
+ def test_015_disconnect_input_exceeds(self):
+ hblock = gr.hier_block2("test_block",
+ gr.io_signature(1,1,gr.sizeof_int),
+ gr.io_signature(1,1,gr.sizeof_int))
+ nop1 = gr.nop(gr.sizeof_int)
+ hblock.connect(hblock, nop1)
+ self.assertRaises(ValueError,
+ lambda: hblock.disconnect((hblock, 1), nop1))
+
+ def test_016_disconnect_output(self):
+ hblock = gr.hier_block2("test_block",
+ gr.io_signature(1,1,gr.sizeof_int),
+ gr.io_signature(1,1,gr.sizeof_int))
+ nop1 = gr.nop(gr.sizeof_int)
+ hblock.connect(nop1, hblock)
+ hblock.disconnect(nop1, hblock)
+
+ def test_017_disconnect_output_not_connected(self):
+ hblock = gr.hier_block2("test_block",
+ gr.io_signature(1,1,gr.sizeof_int),
+ gr.io_signature(1,1,gr.sizeof_int))
+ nop1 = gr.nop(gr.sizeof_int)
+ nop2 = gr.nop(gr.sizeof_int)
+ hblock.connect(nop1, hblock)
+ self.assertRaises(ValueError,
+ lambda: hblock.disconnect(nop2, hblock))
+
+ def test_018_disconnect_output_neg(self):
+ hblock = gr.hier_block2("test_block",
+ gr.io_signature(1,1,gr.sizeof_int),
+ gr.io_signature(1,1,gr.sizeof_int))
+ nop1 = gr.nop(gr.sizeof_int)
+ hblock.connect(hblock, nop1)
+ self.assertRaises(ValueError,
+ lambda: hblock.disconnect(nop1, (hblock, -1)))
+
+ def test_019_disconnect_output_exceeds(self):
+ hblock = gr.hier_block2("test_block",
+ gr.io_signature(1,1,gr.sizeof_int),
+ gr.io_signature(1,1,gr.sizeof_int))
+ nop1 = gr.nop(gr.sizeof_int)
+ hblock.connect(nop1, hblock)
+ self.assertRaises(ValueError,
+ lambda: hblock.disconnect(nop1, (hblock, 1)))
+
+ def test_020_run(self):
+ hblock = gr.top_block("test_block")
+ data = (1.0, 2.0, 3.0, 4.0)
+ src = gr.vector_source_f(data, False)
+ dst = gr.vector_sink_f()
+ hblock.connect(src, dst)
+ hblock.run()
+ self.assertEquals(data, dst.data())
+
+ def test_021_connect_single(self):
+ hblock = gr.top_block("test_block")
+ blk = gr.hier_block2("block",
+ gr.io_signature(0, 0, 0),
+ gr.io_signature(0, 0, 0))
+ hblock.connect(blk)
+
+ def test_022_connect_single_with_ports(self):
+ hblock = gr.top_block("test_block")
+ blk = gr.hier_block2("block",
+ gr.io_signature(1, 1, 1),
+ gr.io_signature(1, 1, 1))
+ self.assertRaises(ValueError,
+ lambda: hblock.connect(blk))
+
+ def test_023_connect_single_twice(self):
+ hblock = gr.top_block("test_block")
+ blk = gr.hier_block2("block",
+ gr.io_signature(0, 0, 0),
+ gr.io_signature(0, 0, 0))
+ hblock.connect(blk)
+ self.assertRaises(ValueError,
+ lambda: hblock.connect(blk))
+
+ def test_024_disconnect_single(self):
+ hblock = gr.top_block("test_block")
+ blk = gr.hier_block2("block",
+ gr.io_signature(0, 0, 0),
+ gr.io_signature(0, 0, 0))
+ hblock.connect(blk)
+ hblock.disconnect(blk)
+
+ def test_025_disconnect_single_not_connected(self):
+ hblock = gr.top_block("test_block")
+ blk = gr.hier_block2("block",
+ gr.io_signature(0, 0, 0),
+ gr.io_signature(0, 0, 0))
+ self.assertRaises(ValueError,
+ lambda: hblock.disconnect(blk))
+
+ def test_026_run_single(self):
+ expected_data = (1.0,)
+ tb = gr.top_block("top_block")
+ hb = gr.hier_block2("block",
+ gr.io_signature(0, 0, 0),
+ gr.io_signature(0, 0, 0))
+ src = gr.vector_source_f(expected_data)
+ dst = gr.vector_sink_f()
+ hb.connect(src, dst)
+ tb.connect(hb)
+ tb.run()
+ self.assertEquals(expected_data, dst.data())
+
+ def test_027a_internally_unconnected_input(self):
+ tb = gr.top_block()
+ hb = gr.hier_block2("block",
+ gr.io_signature(1, 1, 1),
+ gr.io_signature(1, 1, 1))
+ hsrc = gr.vector_source_b([1,])
+ hb.connect(hsrc, hb) # wire output internally
+ src = gr.vector_source_b([1, ])
+ dst = gr.vector_sink_b()
+ tb.connect(src, hb, dst) # hb's input is not connected internally
+ self.assertRaises(RuntimeError,
+ lambda: tb.run())
+
+ def test_027b_internally_unconnected_output(self):
+ tb = gr.top_block()
+
+ hb = gr.hier_block2("block",
+ gr.io_signature(1, 1, 1),
+ gr.io_signature(1, 1, 1))
+ hdst = gr.vector_sink_b()
+ hb.connect(hb, hdst) # wire input internally
+ src = gr.vector_source_b([1, ])
+ dst = gr.vector_sink_b()
+ tb.connect(src, hb, dst) # hb's output is not connected internally
+ self.assertRaises(RuntimeError,
+ lambda: tb.run())
+
+ def test_027c_fully_unconnected_output(self):
+ tb = gr.top_block()
+ hb = gr.hier_block2("block",
+ gr.io_signature(1, 1, 1),
+ gr.io_signature(1, 1, 1))
+ hsrc = gr.vector_sink_b()
+ hb.connect(hb, hsrc) # wire input internally
+ src = gr.vector_source_b([1, ])
+ dst = gr.vector_sink_b()
+ tb.connect(src, hb) # hb's output is not connected internally or externally
+ self.assertRaises(RuntimeError,
+ lambda: tb.run())
+
+ def test_027d_fully_unconnected_input(self):
+ tb = gr.top_block()
+ hb = gr.hier_block2("block",
+ gr.io_signature(1, 1, 1),
+ gr.io_signature(1, 1, 1))
+ hdst = gr.vector_source_b([1,])
+ hb.connect(hdst, hb) # wire output internally
+ dst = gr.vector_sink_b()
+ tb.connect(hb, dst) # hb's input is not connected internally or externally
+ self.assertRaises(RuntimeError,
+ lambda: tb.run())
+
+ def test_028_singleton_reconfigure(self):
+ tb = gr.top_block()
+ hb = gr.hier_block2("block",
+ gr.io_signature(0, 0, 0), gr.io_signature(0, 0, 0))
+ src = gr.vector_source_b([1, ])
+ dst = gr.vector_sink_b()
+ hb.connect(src, dst)
+ tb.connect(hb) # Singleton connect
+ tb.lock()
+ tb.disconnect_all()
+ tb.connect(src, dst)
+ tb.unlock()
+
+ def test_029_singleton_disconnect(self):
+ tb = gr.top_block()
+ src = gr.vector_source_b([1, ])
+ dst = gr.vector_sink_b()
+ tb.connect(src, dst)
+ tb.disconnect(src) # Singleton disconnect
+ tb.connect(src, dst)
+ tb.run()
+ self.assertEquals(dst.data(), (1,))
+
+ def test_030_nested_input(self):
+ tb = gr.top_block()
+ src = gr.vector_source_b([1,])
+ hb1 = gr.hier_block2("hb1",
+ gr.io_signature(1, 1, gr.sizeof_char),
+ gr.io_signature(0, 0, 0))
+ hb2 = gr.hier_block2("hb2",
+ gr.io_signature(1, 1, gr.sizeof_char),
+ gr.io_signature(0, 0, 0))
+ dst = gr.vector_sink_b()
+ tb.connect(src, hb1)
+ hb1.connect(hb1, hb2)
+ hb2.connect(hb2, gr.kludge_copy(gr.sizeof_char), dst)
+ tb.run()
+ self.assertEquals(dst.data(), (1,))
+
+ def test_031_multiple_internal_inputs(self):
+ tb = gr.top_block()
+ src = gr.vector_source_f([1.0,])
+ hb = gr.hier_block2("hb",
+ gr.io_signature(1, 1, gr.sizeof_float),
+ gr.io_signature(1, 1, gr.sizeof_float))
+ m1 = gr.multiply_const_ff(1.0)
+ m2 = gr.multiply_const_ff(2.0)
+ add = gr.add_ff()
+ hb.connect(hb, m1) # m1 is connected to hb external input #0
+ hb.connect(hb, m2) # m2 is also connected to hb external input #0
+ hb.connect(m1, (add, 0))
+ hb.connect(m2, (add, 1))
+ hb.connect(add, hb) # add is connected to hb external output #0
+ dst = gr.vector_sink_f()
+ tb.connect(src, hb, dst)
+ tb.run()
+ self.assertEquals(dst.data(), (3.0,))
+
+ def test_032_nested_multiple_internal_inputs(self):
+ tb = gr.top_block()
+ src = gr.vector_source_f([1.0,])
+ hb = gr.hier_block2("hb",
+ gr.io_signature(1, 1, gr.sizeof_float),
+ gr.io_signature(1, 1, gr.sizeof_float))
+ hb2 = gr.hier_block2("hb",
+ gr.io_signature(1, 1, gr.sizeof_float),
+ gr.io_signature(1, 1, gr.sizeof_float))
+
+ m1 = gr.multiply_const_ff(1.0)
+ m2 = gr.multiply_const_ff(2.0)
+ add = gr.add_ff()
+ hb2.connect(hb2, m1) # m1 is connected to hb2 external input #0
+ hb2.connect(hb2, m2) # m2 is also connected to hb2 external input #0
+ hb2.connect(m1, (add, 0))
+ hb2.connect(m2, (add, 1))
+ hb2.connect(add, hb2) # add is connected to hb2 external output #0
+ hb.connect(hb, hb2, hb) # hb as hb2 as nested internal block
+ dst = gr.vector_sink_f()
+ tb.connect(src, hb, dst)
+ tb.run()
+ self.assertEquals(dst.data(), (3.0,))
+
+
+if __name__ == "__main__":
+ gr_unittest.run(test_hier_block2, "test_hier_block2.xml")
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
index 000000000..27d01092b
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/gr/qa_hilbert.py
@@ -0,0 +1,116 @@
+#!/usr/bin/env python
+#
+# Copyright 2004,2007,2010 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr, gr_unittest
+import math
+
+class test_hilbert (gr_unittest.TestCase):
+
+ def setUp (self):
+ self.tb = gr.top_block ()
+
+ def tearDown (self):
+ self.tb = None
+
+ def test_hilbert (self):
+ tb = self.tb
+ 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 ()
+ tb.connect (src1, head)
+ tb.connect (head, hilb)
+ tb.connect (hilb, dst1)
+ tb.run ()
+ dst_data = dst1.data ()
+ self.assertComplexTuplesAlmostEqual (expected_result, dst_data, 5)
+
+if __name__ == '__main__':
+ gr_unittest.run(test_hilbert, "test_hilbert.xml")
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
index 000000000..06b8d767e
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/gr/qa_iir.py
@@ -0,0 +1,159 @@
+#!/usr/bin/env python
+#
+# Copyright 2004,2007,2010 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr, gr_unittest
+
+class test_iir (gr_unittest.TestCase):
+
+ def setUp (self):
+ self.tb = gr.top_block ()
+
+ def tearDown (self):
+ self.tb = 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.tb.connect (src, op)
+ self.tb.connect (op, dst)
+ self.tb.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.tb.connect (src, op)
+ self.tb.connect (op, dst)
+ self.tb.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.tb.connect (src, op)
+ self.tb.connect (op, dst)
+ self.tb.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.tb.connect (src, op)
+ self.tb.connect (op, dst)
+ self.tb.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.tb.connect (src, op)
+ self.tb.connect (op, dst)
+ self.tb.run ()
+ result_data = dst.data ()
+ self.assertFloatTuplesAlmostEqual (expected_result, result_data)
+
+ def test_iir_direct_006 (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.tb.connect (src, op)
+ self.tb.connect (op, dst)
+ self.tb.run ()
+ result_data = dst.data ()
+ self.assertFloatTuplesAlmostEqual (expected_result, result_data)
+
+ def test_iir_direct_007 (self):
+ src_data = (1, 2, 3, 4, 5, 6, 7, 8)
+ expected_result = (2,2,5,5,8,8,11,11)
+ fftaps = (2, 1)
+ fbtaps = (0, -1)
+ src = gr.vector_source_f (src_data)
+ op = gr.iir_filter_ffd (fftaps, fbtaps)
+ fftaps = (2,0,1)
+ fbtaps = (0, -1)
+ op.set_taps (fftaps, fbtaps)
+ dst = gr.vector_sink_f ()
+ self.tb.connect (src, op)
+ self.tb.connect (op, dst)
+ self.tb.run ()
+ result_data = dst.data ()
+ self.assertFloatTuplesAlmostEqual (expected_result, result_data)
+
+ def test_iir_direct_008 (self):
+ src_data = (1, 2, 3, 4, 5, 6, 7, 8)
+ expected_result = (2,4,4,10,18,14,26,56)
+ fftaps = (2,)
+ fbtaps = (0, 1)
+ src = gr.vector_source_f (src_data)
+ op = gr.iir_filter_ffd (fftaps, fbtaps)
+ fftaps_data = (1)
+ fbtaps = (0,0, -1,3)
+ op.set_taps (fftaps, fbtaps)
+ dst = gr.vector_sink_f ()
+ self.tb.connect (src, op)
+ self.tb.connect (op, dst)
+ self.tb.run ()
+ result_data = dst.data ()
+ self.assertFloatTuplesAlmostEqual (expected_result, result_data)
+
+
+
+
+if __name__ == '__main__':
+ gr_unittest.run(test_iir, "test_iir.xml")
+
diff --git a/gnuradio-core/src/python/gnuradio/gr/qa_int_to_float.py b/gnuradio-core/src/python/gnuradio/gr/qa_int_to_float.py
new file mode 100755
index 000000000..7536b3820
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/gr/qa_int_to_float.py
@@ -0,0 +1,69 @@
+#!/usr/bin/env python
+#
+# Copyright 2011 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr, gr_unittest
+
+class test_int_to_float (gr_unittest.TestCase):
+
+ def setUp (self):
+ self.tb = gr.top_block ()
+
+ def tearDown (self):
+ self.tb = None
+
+ def test_001(self):
+
+ src_data = (0, 1, 2, 3, 4, 5, -1, -2, -3, -4, -5)
+ expected_result = [float(s) for s in src_data]
+ src = gr.vector_source_i(src_data)
+ op = gr.int_to_float()
+ dst = gr.vector_sink_f()
+
+ self.tb.connect(src, op, dst)
+ self.tb.run()
+ result_data = dst.data()
+
+ self.assertFloatTuplesAlmostEqual(expected_result, result_data)
+
+ def test_002(self):
+
+ vlen = 3
+ src_data = ( 65000, 65001, 65002, 65003, 65004, 65005,
+ -65001, -65002, -65003)
+ expected_result = [ 65000.0, 65001.0, 65002.0,
+ 65003.0, 65004.0, 65005.0,
+ -65001.0, -65002.0, -65003.0]
+ src = gr.vector_source_i(src_data)
+ s2v = gr.stream_to_vector(gr.sizeof_int, vlen)
+ op = gr.int_to_float(vlen)
+ v2s = gr.vector_to_stream(gr.sizeof_float, vlen)
+ dst = gr.vector_sink_f()
+
+ self.tb.connect(src, s2v, op, v2s, dst)
+ self.tb.run()
+ result_data = list(dst.data())
+
+ self.assertEqual(expected_result, result_data)
+
+if __name__ == '__main__':
+ gr_unittest.run(test_int_to_float, "test_int_to_float.xml")
+
diff --git a/gnuradio-core/src/python/gnuradio/gr/qa_integrate.py b/gnuradio-core/src/python/gnuradio/gr/qa_integrate.py
new file mode 100755
index 000000000..ddb1310b6
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/gr/qa_integrate.py
@@ -0,0 +1,75 @@
+#!/usr/bin/env python
+#
+# Copyright 2008,2010 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr, gr_unittest
+import math
+
+class test_integrate (gr_unittest.TestCase):
+
+ def setUp (self):
+ self.tb = gr.top_block ()
+
+ def tearDown (self):
+ self.tb = None
+
+ def test_000_ss(self):
+ src_data = (1, 2, 3, 4, 5, 6)
+ dst_data = (6, 15)
+ src = gr.vector_source_s(src_data)
+ itg = gr.integrate_ss(3)
+ dst = gr.vector_sink_s()
+ self.tb.connect(src, itg, dst)
+ self.tb.run()
+ self.assertEqual(dst_data, dst.data())
+
+ def test_001_ii(self):
+ src_data = (1, 2, 3, 4, 5, 6)
+ dst_data = (6, 15)
+ src = gr.vector_source_i(src_data)
+ itg = gr.integrate_ii(3)
+ dst = gr.vector_sink_i()
+ self.tb.connect(src, itg, dst)
+ self.tb.run()
+ self.assertEqual(dst_data, dst.data())
+
+ def test_002_ff(self):
+ src_data = [1.0, 2.0, 3.0, 4.0, 5.0, 6.0]
+ dst_data = [6.0, 15.0]
+ src = gr.vector_source_f(src_data)
+ itg = gr.integrate_ff(3)
+ dst = gr.vector_sink_f()
+ self.tb.connect(src, itg, dst)
+ self.tb.run()
+ self.assertFloatTuplesAlmostEqual(dst_data, dst.data(), 6)
+
+ def test_003_cc(self):
+ src_data = [1.0+1.0j, 2.0+2.0j, 3.0+3.0j, 4.0+4.0j, 5.0+5.0j, 6.0+6.0j]
+ dst_data = [6.0+6.0j, 15.0+15.0j]
+ src = gr.vector_source_c(src_data)
+ itg = gr.integrate_cc(3)
+ dst = gr.vector_sink_c()
+ self.tb.connect(src, itg, dst)
+ self.tb.run()
+ self.assertComplexTuplesAlmostEqual(dst_data, dst.data(), 6)
+
+if __name__ == '__main__':
+ gr_unittest.run(test_integrate, "test_integrate.xml")
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
index 000000000..1ff178251
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/gr/qa_interleave.py
@@ -0,0 +1,81 @@
+#!/usr/bin/env python
+#
+# Copyright 2004,2007,2010 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr, gr_unittest
+import math
+
+class test_interleave (gr_unittest.TestCase):
+
+ def setUp (self):
+ self.tb = gr.top_block ()
+
+ def tearDown (self):
+ self.tb = 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.tb.connect (src0, (op, 0))
+ self.tb.connect (src1, (op, 1))
+ self.tb.connect (src2, (op, 2))
+ self.tb.connect (src3, (op, 3))
+ self.tb.connect (op, dst)
+ self.tb.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.tb.connect (src, op)
+ self.tb.connect ((op, 0), dst0)
+ self.tb.connect ((op, 1), dst1)
+ self.tb.connect ((op, 2), dst2)
+ self.tb.connect ((op, 3), dst3)
+ self.tb.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.run(test_interleave, "test_interleave.xml")
+
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
index 000000000..9bd9977c7
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/gr/qa_interp_fir_filter.py
@@ -0,0 +1,54 @@
+#!/usr/bin/env python
+#
+# Copyright 2004,2007,2010 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr, gr_unittest
+import math
+
+class test_interp_fir_filter (gr_unittest.TestCase):
+
+ def setUp (self):
+ self.tb = gr.top_block ()
+
+ def tearDown (self):
+ self.tb = 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.tb.connect (src, op)
+ self.tb.connect (op, dst)
+ self.tb.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.run(test_interp_fir_filter, "test_interp_fir_filter.xml")
+
diff --git a/gnuradio-core/src/python/gnuradio/gr/qa_keep_m_in_n.py b/gnuradio-core/src/python/gnuradio/gr/qa_keep_m_in_n.py
new file mode 100755
index 000000000..922671d02
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/gr/qa_keep_m_in_n.py
@@ -0,0 +1,58 @@
+#!/usr/bin/env python
+#
+# Copyright 2008,2010 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+
+from gnuradio import gr, gr_unittest
+import sys
+import random
+
+class test_keep_m_in_n(gr_unittest.TestCase):
+
+ def setUp(self):
+ pass
+
+ def tearDown(self):
+ pass
+
+ def test_001(self):
+ self.maxDiff = None;
+ tb = gr.top_block()
+ src = gr.vector_source_b( range(0,100) )
+
+ # itemsize, M, N, offset
+ km2 = gr.keep_m_in_n( 1, 1, 2, 0 );
+ km3 = gr.keep_m_in_n( 1, 1, 3, 1 );
+ km7 = gr.keep_m_in_n( 1, 1, 7, 2 );
+ snk2 = gr.vector_sink_b();
+ snk3 = gr.vector_sink_b();
+ snk7 = gr.vector_sink_b();
+ tb.connect(src,km2,snk2);
+ tb.connect(src,km3,snk3);
+ tb.connect(src,km7,snk7);
+ tb.run();
+
+ self.assertEqual(range(0,100,2), list(snk2.data()));
+ self.assertEqual(range(1,100,3), list(snk3.data()));
+ self.assertEqual(range(2,100,7), list(snk7.data()));
+
+
+if __name__ == '__main__':
+ gr_unittest.run(test_keep_m_in_n, "test_keep_m_in_n.xml")
+
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
index 000000000..2a3aa44b1
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/gr/qa_kludge_copy.py
@@ -0,0 +1,91 @@
+#!/usr/bin/env python
+#
+# Copyright 2006,2010 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr, gr_unittest
+import math
+import random
+
+
+class test_kludge_copy(gr_unittest.TestCase):
+
+ def setUp(self):
+ self.tb = gr.top_block()
+ self.rng = random.Random()
+ self.rng.seed(0)
+
+ def tearDown(self):
+ del self.tb
+ del self.rng
+
+ 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.tb.connect(src0, op, dst0)
+ self.tb.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.tb.connect(src0, (op, 0), dst0)
+ self.tb.connect(src1, (op, 1), dst1)
+ self.tb.run()
+ dst0_data = dst0.data()
+ dst1_data = dst1.data()
+ self.assertEqual(src0_data, dst0_data)
+ self.assertEqual(src1_data, dst1_data)
+
+ # Note: this is disabled due to triggering bug in ticket:181
+ # It only occurs with new top block code
+ def xtest_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.tb.connect(src0, (op, 0), dst0)
+ self.tb.connect(src1, (op, 1))
+ self.assertRaises(ValueError, self.tb.run)
+
+if __name__ == '__main__':
+ gr_unittest.run(test_kludge_copy, "test_kludge_copy.xml")
+
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
index 000000000..39b5d781e
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/gr/qa_kludged_imports.py
@@ -0,0 +1,43 @@
+#!/usr/bin/env python
+#
+# Copyright 2005,2008,2010 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr, gr_unittest
+
+class test_kludged_imports (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 blks2
+
+ def test_gru_import(self):
+ # make sure that this somewhat magic import works
+ from gnuradio import gru
+
+
+if __name__ == '__main__':
+ gr_unittest.run(test_kludged_imports, "test_kludged_imports.xml")
diff --git a/gnuradio-core/src/python/gnuradio/gr/qa_max.py b/gnuradio-core/src/python/gnuradio/gr/qa_max.py
new file mode 100755
index 000000000..f962df457
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/gr/qa_max.py
@@ -0,0 +1,70 @@
+#!/usr/bin/env python
+#
+# Copyright 2007,2010 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr, gr_unittest
+import math
+
+
+class test_max (gr_unittest.TestCase):
+
+ def setUp (self):
+ self.tb = gr.top_block ()
+
+
+ def tearDown (self):
+ self.tb = None
+
+
+ def test_001(self):
+
+ src_data = (0,0.2,-0.3,0,12,0)
+ expected_result = (float(max(src_data)), )
+
+ src = gr.vector_source_f(src_data)
+ s2v = gr.stream_to_vector(gr.sizeof_float, len(src_data))
+ op = gr.max_ff( len(src_data) )
+ dst = gr.vector_sink_f()
+
+
+ self.tb.connect(src, s2v, op, dst)
+ self.tb.run()
+ result_data = dst.data()
+ self.assertEqual(expected_result, result_data)
+
+ def test_002(self):
+
+ src_data=(-100,-99,-98,-97,-96,-1)
+ expected_result = (float(max(src_data)), )
+
+ src = gr.vector_source_f(src_data)
+ s2v = gr.stream_to_vector(gr.sizeof_float, len(src_data))
+ op = gr.max_ff( len(src_data) )
+ dst = gr.vector_sink_f()
+
+ self.tb.connect(src, s2v, op, dst)
+ self.tb.run()
+ result_data = dst.data()
+ self.assertEqual(expected_result, result_data)
+
+if __name__ == '__main__':
+ gr_unittest.run(test_max, "test_max.xml")
+
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
index 000000000..4cef39bd7
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/gr/qa_message.py
@@ -0,0 +1,131 @@
+#!/usr/bin/env python
+#
+# Copyright 2004,2010 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr, gr_unittest
+
+
+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.msgq = gr.msg_queue ()
+
+ def tearDown (self):
+ 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()
+ tb = gr.top_block()
+ tb.connect(src, dst)
+ tb.run()
+ self.assertEquals(input_data, dst.data())
+
+ def test_301(self):
+ # Use itemsize, limit constructor
+ src = gr.message_source(gr.sizeof_char)
+ dst = gr.vector_sink_b()
+ tb = gr.top_block()
+ tb.connect(src, dst)
+ src.msgq().insert_tail(gr.message_from_string('01234'))
+ src.msgq().insert_tail(gr.message_from_string('5'))
+ src.msgq().insert_tail(gr.message_from_string(''))
+ src.msgq().insert_tail(gr.message_from_string('6789'))
+ src.msgq().insert_tail(gr.message(1)) # send EOF
+ tb.run()
+ self.assertEquals(tuple(map(ord, '0123456789')), dst.data())
+
+ def test_302(self):
+ # Use itemsize, msgq constructor
+ msgq = gr.msg_queue()
+ src = gr.message_source(gr.sizeof_char, msgq)
+ dst = gr.vector_sink_b()
+ tb = gr.top_block()
+ tb.connect(src, dst)
+ src.msgq().insert_tail(gr.message_from_string('01234'))
+ src.msgq().insert_tail(gr.message_from_string('5'))
+ src.msgq().insert_tail(gr.message_from_string(''))
+ src.msgq().insert_tail(gr.message_from_string('6789'))
+ src.msgq().insert_tail(gr.message(1)) # send EOF
+ tb.run()
+ self.assertEquals(tuple(map(ord, '0123456789')), dst.data())
+
+if __name__ == '__main__':
+ gr_unittest.run(test_message, "test_message.xml")
diff --git a/gnuradio-core/src/python/gnuradio/gr/qa_multiply_conjugate.py b/gnuradio-core/src/python/gnuradio/gr/qa_multiply_conjugate.py
new file mode 100644
index 000000000..1601a109e
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/gr/qa_multiply_conjugate.py
@@ -0,0 +1,57 @@
+#!/usr/bin/env python
+#
+# Copyright 2012 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr, gr_unittest
+
+class test_multiply_conjugate (gr_unittest.TestCase):
+
+ def setUp (self):
+ self.tb = gr.top_block ()
+
+ def tearDown (self):
+ self.tb = None
+
+ def test_000 (self):
+ src_data0 = (-2-2j, -1-1j, -2+2j, -1+1j,
+ 2-2j, 1-1j, 2+2j, 1+1j,
+ 0+0j)
+ src_data1 = (-3-3j, -4-4j, -3+3j, -4+4j,
+ 3-3j, 4-4j, 3+3j, 4+4j,
+ 0+0j)
+
+ exp_data = (12+0j, 8+0j, 12+0j, 8+0j,
+ 12+0j, 8+0j, 12+0j, 8+0j,
+ 0+0j)
+ src0 = gr.vector_source_c(src_data0)
+ src1 = gr.vector_source_c(src_data1)
+ op = gr.multiply_conjugate_cc ()
+ dst = gr.vector_sink_c ()
+
+ self.tb.connect(src0, (op,0))
+ self.tb.connect(src1, (op,1))
+ self.tb.connect(op, dst)
+ self.tb.run()
+ result_data = dst.data ()
+ self.assertEqual (exp_data, result_data)
+
+if __name__ == '__main__':
+ gr_unittest.run(test_multiply_conjugate, "test_multiply_conjugate.xml")
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
index 000000000..afdfdfe13
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/gr/qa_mute.py
@@ -0,0 +1,89 @@
+#!/usr/bin/env python
+#
+# Copyright 2004,2005,2007,2010 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr, gr_unittest
+
+class test_mute (gr_unittest.TestCase):
+
+ def setUp (self):
+ self.tb = gr.top_block ()
+
+ def tearDown (self):
+ self.tb = 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.tb.connect (src, (op, s[0]))
+ dst = gr.vector_sink_i ()
+ self.tb.connect (op, dst)
+ self.tb.run ()
+ result_data = dst.data ()
+ self.assertEqual (exp_data, result_data)
+
+ def 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.tb.connect (src, (op, s[0]))
+ dst = gr.vector_sink_f ()
+ self.tb.connect (op, dst)
+ self.tb.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.tb.connect (src, (op, s[0]))
+ dst = gr.vector_sink_c ()
+ self.tb.connect (op, dst)
+ self.tb.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.run(test_mute, "test_mute.xml")
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
index 000000000..a87ed87ee
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/gr/qa_nlog10.py
@@ -0,0 +1,47 @@
+#!/usr/bin/env python
+#
+# Copyright 2005,2007,2010 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr, gr_unittest
+
+class test_nlog10(gr_unittest.TestCase):
+
+ def setUp (self):
+ self.tb = gr.top_block ()
+
+ def tearDown (self):
+ self.tb = 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.tb.connect (src, op, dst)
+ self.tb.run()
+ result_data = dst.data()
+ self.assertFloatTuplesAlmostEqual (expected_result, result_data)
+
+
+if __name__ == '__main__':
+ gr_unittest.run(test_nlog10, "test_nlog10.xml")
+
diff --git a/gnuradio-core/src/python/gnuradio/gr/qa_noise.py b/gnuradio-core/src/python/gnuradio/gr/qa_noise.py
new file mode 100755
index 000000000..e87519150
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/gr/qa_noise.py
@@ -0,0 +1,51 @@
+#!/usr/bin/env python
+#
+# Copyright 2007,2010 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr, gr_unittest
+
+class test_noise_source(gr_unittest.TestCase):
+
+ def setUp (self):
+ self.tb = gr.top_block ()
+
+ def tearDown (self):
+ self.tb = None
+
+ def test_001(self):
+ # Just confirm that we can instantiate a noise source
+ op = gr.noise_source_f(gr.GR_GAUSSIAN, 10, 10)
+
+ def test_002(self):
+ # Test get methods
+ set_type = gr.GR_GAUSSIAN
+ set_ampl = 10
+ op = gr.noise_source_f(set_type, set_ampl, 10)
+ get_type = op.type()
+ get_ampl = op.amplitude()
+
+ self.assertEqual(get_type, set_type)
+ self.assertEqual(get_ampl, set_ampl)
+
+
+if __name__ == '__main__':
+ gr_unittest.run(test_noise_source, "test_noise_source.xml")
+
diff --git a/gnuradio-core/src/python/gnuradio/gr/qa_pack_k_bits.py b/gnuradio-core/src/python/gnuradio/gr/qa_pack_k_bits.py
new file mode 100755
index 000000000..25fc5e9fc
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/gr/qa_pack_k_bits.py
@@ -0,0 +1,67 @@
+#!/usr/bin/env python
+#
+# Copyright 2006,2010 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr, gr_unittest
+import random
+
+class test_pack(gr_unittest.TestCase):
+
+ def setUp(self):
+ self.tb = gr.top_block ()
+
+ def tearDown(self):
+ self.tb = 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.pack_k_bits_bb(1)
+ dst = gr.vector_sink_b()
+ self.tb.connect(src, op, dst)
+ self.tb.run()
+ self.assertEqual(expected_results, dst.data())
+
+ def test_002(self):
+ src_data = (1,0,1,1,0,0,0,1)
+ expected_results = ( 2, 3, 0, 1)
+ src = gr.vector_source_b(src_data,False)
+ op = gr.pack_k_bits_bb(2)
+ dst = gr.vector_sink_b()
+ self.tb.connect(src, op, dst)
+ self.tb.run()
+ #self.assertEqual(expected_results, dst.data())
+ self.assertEqual(expected_results, dst.data())
+
+ def test_003(self):
+ src_data = expected_results = map(lambda x: random.randint(0,3), range(10));
+ src = gr.vector_source_b( src_data );
+ pack = gr.pack_k_bits_bb(2);
+ unpack = gr.unpack_k_bits_bb(2);
+ snk = gr.vector_sink_b();
+ self.tb.connect(src,unpack,pack,snk);
+ self.tb.run()
+ self.assertEqual(list(expected_results), list(snk.data()));
+
+if __name__ == '__main__':
+ gr_unittest.run(test_pack, "test_pack.xml")
+
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
index 000000000..08accd0ad
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/gr/qa_packed_to_unpacked.py
@@ -0,0 +1,405 @@
+#!/usr/bin/env python
+#
+# Copyright 2005,2007,2010 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr, gr_unittest
+import random
+
+class test_packing(gr_unittest.TestCase):
+
+ def setUp(self):
+ self.tb = gr.top_block ()
+
+ def tearDown(self):
+ self.tb = 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.tb.connect(src, op)
+
+ dst = gr.vector_sink_b()
+ self.tb.connect(op, dst)
+
+ self.tb.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.tb.connect(src, op)
+
+ dst = gr.vector_sink_b()
+ self.tb.connect(op, dst)
+
+ self.tb.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.tb.connect(src, op)
+
+ dst = gr.vector_sink_b()
+ self.tb.connect(op, dst)
+
+ self.tb.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.tb.connect(src, op)
+
+ dst = gr.vector_sink_b()
+ self.tb.connect(op, dst)
+
+ self.tb.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.tb.connect(src, op)
+
+ dst = gr.vector_sink_b()
+ self.tb.connect(op, dst)
+
+ self.tb.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.tb.connect(src, op)
+
+ dst = gr.vector_sink_b()
+ self.tb.connect(op, dst)
+
+ self.tb.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.tb.connect(src, op)
+
+ dst = gr.vector_sink_b()
+ self.tb.connect(op, dst)
+
+ self.tb.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.tb.connect(src, op)
+
+ dst = gr.vector_sink_b()
+ self.tb.connect(op, dst)
+
+ self.tb.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.tb.connect(src, op1, op2)
+
+ dst = gr.vector_sink_b()
+ self.tb.connect(op2, dst)
+
+ self.tb.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.tb.connect(src, op1, op2)
+ dst = gr.vector_sink_b()
+ self.tb.connect(op2, dst)
+
+ self.tb.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.tb.connect(src, op1, op2)
+ dst = gr.vector_sink_b()
+ self.tb.connect(op2, dst)
+
+ self.tb.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.tb.connect(src, op1, op2)
+ dst = gr.vector_sink_s()
+ self.tb.connect(op2, dst)
+
+ self.tb.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.tb.connect(src, op1, op2)
+ dst = gr.vector_sink_s()
+ self.tb.connect(op2, dst)
+
+ self.tb.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.tb.connect(src, op1, op2)
+ dst = gr.vector_sink_s()
+ self.tb.connect(op2, dst)
+
+ self.tb.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.tb.connect(src, op1, op2)
+ dst = gr.vector_sink_s()
+ self.tb.connect(op2, dst)
+
+ self.tb.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.tb.connect(src, op1, op2)
+ dst = gr.vector_sink_i()
+ self.tb.connect(op2, dst)
+
+ self.tb.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.tb.connect(src, op1, op2)
+ dst = gr.vector_sink_i()
+ self.tb.connect(op2, dst)
+
+ self.tb.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.tb.connect(src, op1, op2)
+ dst = gr.vector_sink_i()
+ self.tb.connect(op2, dst)
+
+ self.tb.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.tb.connect(src, op1, op2)
+ dst = gr.vector_sink_i()
+ self.tb.connect(op2, dst)
+
+ self.tb.run()
+ self.assertEqual(expected_results, dst.data())
+
+
+if __name__ == '__main__':
+ gr_unittest.run(test_packing, "test_packing.xml")
+
diff --git a/gnuradio-core/src/python/gnuradio/gr/qa_pdu.py b/gnuradio-core/src/python/gnuradio/gr/qa_pdu.py
new file mode 100755
index 000000000..098aabb4a
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/gr/qa_pdu.py
@@ -0,0 +1,109 @@
+#!/usr/bin/env python
+#
+# Copyright 2012 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr, gr_unittest
+import pmt
+import time
+
+class test_pdu(gr_unittest.TestCase):
+
+ def setUp(self):
+ self.tb = gr.top_block()
+
+ def tearDown(self):
+ self.tb = None
+
+ def test_000(self):
+ # Just run some data through and make sure it doesn't puke.
+ src_data = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
+
+ src = gr.pdu_to_tagged_stream(gr.pdu_byte)
+ snk3 = gr.tagged_stream_to_pdu(gr.pdu_byte)
+ snk2 = gr.vector_sink_b()
+ snk = gr.tag_debug(1, "test")
+
+ dbg = gr.message_debug()
+
+ # Test that the right number of ports exist.
+ pi = dbg.message_ports_in()
+ po = dbg.message_ports_out()
+ self.assertEqual(pmt.pmt_length(pi), 3)
+ self.assertEqual(pmt.pmt_length(po), 0)
+
+ pi = snk3.message_ports_in()
+ po = snk3.message_ports_out()
+ self.assertEqual(pmt.pmt_length(pi), 0)
+ self.assertEqual(pmt.pmt_length(po), 1)
+
+ #print "Message Debug input ports: "
+ #pmt.pmt_print(pi)
+ #print "Message Debug output ports: "
+ #pmt.pmt_print(po)
+
+ #print "Stream to PDU input ports: "
+ #pmt.pmt_print(pi)
+ #print "Stream to PDU output ports: "
+ #pmt.pmt_print(po)
+
+ self.tb.connect(src, snk)
+ self.tb.connect(src, snk2)
+ self.tb.connect(src, snk3)
+
+ self.tb.msg_connect(snk3, "pdus", dbg, "store")
+ self.tb.start()
+
+ # make our reference and message pmts
+ port = pmt.pmt_intern("pdus")
+ msg = pmt.pmt_cons( pmt.PMT_NIL, pmt.pmt_make_u8vector(16, 0xFF) )
+
+ #print "printing port & msg"
+ #pmt.pmt_print(port)
+ #pmt.pmt_print(msg)
+
+ # post the message
+ src.to_basic_block()._post( port, msg )
+
+ while(dbg.num_messages() < 1):
+ time.sleep(0.1)
+ self.tb.stop()
+ self.tb.wait()
+
+ # Get the vector of data from the vector sink
+ result_data = snk2.data()
+
+ # Get the vector of data from the message sink
+ # Convert the message PMT as a pair into its vector
+ result_msg = dbg.get_message(0)
+ msg_vec = pmt.pmt_cdr(result_msg)
+ pmt.pmt_print(msg_vec)
+
+ # Convert the PMT vector into a Python list
+ msg_data = []
+ for i in xrange(16):
+ msg_data.append(pmt.pmt_u8vector_ref(msg_vec, i))
+
+ actual_data = 16*[0xFF,]
+ self.assertEqual(actual_data, list(result_data))
+ self.assertEqual(actual_data, msg_data)
+
+if __name__ == '__main__':
+ gr_unittest.run(test_pdu, "test_pdu.xml")
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
index 000000000..1f24062b1
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/gr/qa_pipe_fittings.py
@@ -0,0 +1,143 @@
+#!/usr/bin/env python
+#
+# Copyright 2005,2007,2010 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr, gr_unittest
+
+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.tb = gr.top_block ()
+
+ def tearDown(self):
+ self.tb = 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.tb.connect(src, op)
+
+ dsts = []
+ for i in range(n):
+ dst = gr.vector_sink_i()
+ self.tb.connect((op, i), (dst, 0))
+ dsts.append(dst)
+
+ self.tb.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.tb.connect(src, op1)
+ for i in range(n):
+ self.tb.connect((op1, i), (op2, i))
+ self.tb.connect(op2, dst)
+
+ self.tb.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.tb.connect(src, op1)
+ for i in range(n):
+ self.tb.connect((op1, i), (op2, i))
+ self.tb.connect(op2, op3, dst)
+
+ self.tb.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.tb.connect(src, op1, op2)
+ for i in range(n):
+ self.tb.connect((op2, i), (op3, i))
+ self.tb.connect(op3, dst)
+
+ self.tb.run()
+ self.assertEqual(expected_results, dst.data())
+
+if __name__ == '__main__':
+ gr_unittest.run(test_pipe_fittings, "test_pipe_fittings.xml")
+
diff --git a/gnuradio-core/src/python/gnuradio/gr/qa_pll_carriertracking.py b/gnuradio-core/src/python/gnuradio/gr/qa_pll_carriertracking.py
new file mode 100755
index 000000000..8964db53d
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/gr/qa_pll_carriertracking.py
@@ -0,0 +1,156 @@
+#!/usr/bin/env python
+#
+# Copyright 2004,2007,2010,2011 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr, gr_unittest
+import math
+
+class test_pll_carriertracking (gr_unittest.TestCase):
+
+ def setUp (self):
+ self.tb = gr.top_block()
+
+ def tearDown (self):
+ self.tb = None
+
+ def test_pll_carriertracking (self):
+ expected_result = ((1.00000238419+7.21919457547e-09j),
+ (0.998025715351+0.062790453434j),
+ (0.992777824402+0.119947694242j),
+ (0.985192835331+0.171441286802j),
+ (0.976061582565+0.217501848936j),
+ (0.966034710407+0.258409559727j),
+ (0.95565611124+0.294477283955j),
+ (0.945357382298+0.326030552387j),
+ (0.935475051403+0.353395611048j),
+ (0.926258146763+0.376889169216j),
+ (0.917895197868+0.39681750536j),
+ (0.910515546799+0.413470208645j),
+ (0.904196679592+0.427117019892j),
+ (0.898972511292+0.438006043434j),
+ (0.894769787788+0.446523308754j),
+ (0.891652584076+0.452715367079j),
+ (0.8895829916+0.456773489714j),
+ (0.888502895832+0.458873122931j),
+ (0.888343691826+0.459175437689j),
+ (0.889035582542+0.457833081484j),
+ (0.890497922897+0.454985737801j),
+ (0.892645597458+0.450762689114j),
+ (0.895388305187+0.445282936096j),
+ (0.898648142815+0.438664674759j),
+ (0.902342617512+0.431016951799j),
+ (0.906392872334+0.422441422939j),
+ (0.910642921925+0.413191765547j),
+ (0.915039420128+0.403358519077j),
+ (0.919594764709+0.392864197493j),
+ (0.92425006628+0.381792247295j),
+ (0.928944349289+0.370217680931j),
+ (0.933634519577+0.358220815659j),
+ (0.938279032707+0.345874190331j),
+ (0.942840516567+0.333247303963j),
+ (0.947280526161+0.32040438056j),
+ (0.951574921608+0.307409763336j),
+ (0.955703914165+0.294323593378j),
+ (0.959648966789+0.281201630831j),
+ (0.963392794132+0.268095195293j),
+ (0.966880619526+0.255221515894j),
+ (0.970162451267+0.242447137833j),
+ (0.973235487938+0.229809194803j),
+ (0.97609680891+0.217341512442j),
+ (0.978744983673+0.20507311821j),
+ (0.981189727783+0.193033605814j),
+ (0.983436584473+0.181248426437j),
+ (0.985490739346+0.169738590717j),
+ (0.987353682518+0.158523857594j),
+ (0.989041447639+0.147622272372j),
+ (0.990563035011+0.137049794197j),
+ (0.991928339005+0.126818582416j),
+ (0.993117690086+0.117111675441j),
+ (0.994156062603+0.107930034399j),
+ (0.995076179504+0.0990980416536j),
+ (0.995887458324+0.0906178802252j),
+ (0.996591091156+0.0824909061193j),
+ (0.997202515602+0.0747182965279j),
+ (0.997730851173+0.0672992765903j),
+ (0.998185396194+0.0602316558361j),
+ (0.99856698513+0.0535135567188j),
+ (0.998885989189+0.0471420884132j),
+ (0.99915266037+0.0411129891872j),
+ (0.999372899532+0.0354214012623j),
+ (0.999548316002+0.0300626158714j),
+ (0.999680638313+0.0252036750317j),
+ (0.999784469604+0.020652115345j),
+ (0.999865531921+0.0163950324059j),
+ (0.999923825264+0.0124222636223j),
+ (0.999960243702+0.00872156023979j),
+ (0.999983668327+0.00528120994568j),
+ (0.999997138977+0.00209015607834j),
+ (1.00000119209-0.00086285173893j),
+ (0.999992132187-0.00358882546425j),
+ (0.999979138374-0.00609711557627j),
+ (0.999963641167-0.00839691981673j),
+ (0.999947249889-0.0104993218556j),
+ (0.999924004078-0.0122378543019j),
+ (0.999904811382-0.0136305987835j),
+ (0.999888062477-0.0148707330227j),
+ (0.9998742342-0.0159679055214j),
+ (0.999856114388-0.0169314742088j),
+ (0.999839782715-0.0177700817585j),
+ (0.999826967716-0.0184917747974j),
+ (0.999818325043-0.0191045701504j),
+ (0.999807476997-0.0196143388748j),
+ (0.999797284603-0.0200265944004j),
+ (0.999791204929-0.0203481912613j),
+ (0.99978852272-0.0205836892128j),
+ (0.99978530407-0.0207380950451j),
+ (0.999785065651-0.0206423997879j),
+ (0.999787807465-0.0204866230488j),
+ (0.999794304371-0.0202808082104j),
+ (0.999800384045-0.0200312435627j),
+ (0.999803245068-0.0197458267212j),
+ (0.9998087883-0.0194311738014j),
+ (0.999816894531-0.0190933048725j),
+ (0.999825954437-0.0187371373177j),
+ (0.999829888344-0.0183679759502j),
+ (0.999835848808-0.017987690866j),
+ (0.999844014645-0.0176006518304j))
+
+ sampling_freq = 10e3
+ freq = sampling_freq / 100
+
+ loop_bw = math.pi/100.0
+ maxf = 1
+ minf = -1
+
+ src = gr.sig_source_c (sampling_freq, gr.GR_COS_WAVE, freq, 1.0)
+ pll = gr.pll_carriertracking_cc(loop_bw, maxf, minf)
+ head = gr.head (gr.sizeof_gr_complex, int (freq))
+ dst = gr.vector_sink_c ()
+
+ self.tb.connect (src, pll, head)
+ self.tb.connect (head, dst)
+
+ self.tb.run ()
+ dst_data = dst.data ()
+ self.assertComplexTuplesAlmostEqual (expected_result, dst_data, 5)
+
+if __name__ == '__main__':
+ gr_unittest.run(test_pll_carriertracking, "test_pll_carriertracking.xml")
diff --git a/gnuradio-core/src/python/gnuradio/gr/qa_pll_freqdet.py b/gnuradio-core/src/python/gnuradio/gr/qa_pll_freqdet.py
new file mode 100755
index 000000000..219e9b84b
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/gr/qa_pll_freqdet.py
@@ -0,0 +1,160 @@
+#!/usr/bin/env python
+#
+# Copyright 2004,2007,2010,2011 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr, gr_unittest
+import math
+
+class test_pll_freqdet (gr_unittest.TestCase):
+
+ def setUp (self):
+ self.tb = gr.top_block()
+
+ def tearDown (self):
+ self.tb = None
+
+ def test_pll_freqdet (self):
+ expected_result = (0.0,
+ 4.33888922882e-08,
+ 0.367369994515,
+ 1.08135249597,
+ 2.10983253908,
+ 3.42221529438,
+ 4.98940390402,
+ 6.78379190842,
+ 8.77923286024,
+ 10.9510106794,
+ 13.2758363182,
+ 15.7317829127,
+ 18.2982902299,
+ 20.9561068599,
+ 23.6755271122,
+ 26.452952094,
+ 29.2731265301,
+ 32.1219053479,
+ 34.9862418188,
+ 37.8540971414,
+ 40.7144315483,
+ 43.5571390869,
+ 46.3730179743,
+ 49.1537231663,
+ 51.8917218889,
+ 54.58026103,
+ 57.2015358514,
+ 59.7513664199,
+ 62.2380533124,
+ 64.657612252,
+ 67.006640002,
+ 69.2822432184,
+ 71.4820384499,
+ 73.6041047056,
+ 75.6469478817,
+ 77.6094829742,
+ 79.4909866472,
+ 81.2911031615,
+ 83.0097850853,
+ 84.6355598352,
+ 86.1820937186,
+ 87.6504420946,
+ 89.0418441206,
+ 90.3577286819,
+ 91.5996432431,
+ 92.7692775646,
+ 93.8684162704,
+ 94.8989269904,
+ 95.8627662892,
+ 96.7619381633,
+ 97.598505899,
+ 98.362769679,
+ 99.0579904444,
+ 99.6992633875,
+ 100.288805948,
+ 100.828805921,
+ 101.321421457,
+ 101.76878699,
+ 102.17300138,
+ 102.536116055,
+ 102.860158727,
+ 103.147085962,
+ 103.398830608,
+ 103.617254366,
+ 103.792467691,
+ 103.939387906,
+ 104.060030865,
+ 104.15631756,
+ 104.230085975,
+ 104.283067372,
+ 104.316933727,
+ 104.333238432,
+ 104.333440018,
+ 104.318914008,
+ 104.290941063,
+ 104.250742554,
+ 104.187634452,
+ 104.103822339,
+ 104.013227468,
+ 103.916810336,
+ 103.815448432,
+ 103.709936239,
+ 103.600997093,
+ 103.489283183,
+ 103.375351833,
+ 103.259712936,
+ 103.142828952,
+ 103.025091195,
+ 102.90686726,
+ 102.776726069,
+ 102.648078982,
+ 102.521459607,
+ 102.397294831,
+ 102.275999684,
+ 102.157882471,
+ 102.043215927,
+ 101.93218978,
+ 101.824958181,
+ 101.72159228,
+ 101.622151366)
+
+ sampling_freq = 10e3
+ freq = sampling_freq / 100
+
+ loop_bw = math.pi/100.0
+ maxf = 1
+ minf = -1
+
+ src = gr.sig_source_c (sampling_freq, gr.GR_COS_WAVE, freq, 1.0)
+ pll = gr.pll_freqdet_cf(loop_bw, maxf, minf)
+ head = gr.head (gr.sizeof_float, int (freq))
+ dst = gr.vector_sink_f ()
+
+ self.tb.connect (src, pll, head)
+ self.tb.connect (head, dst)
+
+ self.tb.run ()
+ dst_data = dst.data ()
+
+ # convert it from normalized frequency to absolute frequency (Hz)
+ dst_data = [i*(sampling_freq/(2*math.pi)) for i in dst_data]
+
+ self.assertFloatTuplesAlmostEqual (expected_result, dst_data, 3)
+
+if __name__ == '__main__':
+ gr_unittest.run(test_pll_freqdet, "test_pll_freqdet.xml")
diff --git a/gnuradio-core/src/python/gnuradio/gr/qa_pll_refout.py b/gnuradio-core/src/python/gnuradio/gr/qa_pll_refout.py
new file mode 100755
index 000000000..f319f6381
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/gr/qa_pll_refout.py
@@ -0,0 +1,156 @@
+#!/usr/bin/env python
+#
+# Copyright 2004,2010 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr, gr_unittest
+import math
+
+class test_pll_refout (gr_unittest.TestCase):
+
+ def setUp (self):
+ self.tb = gr.top_block()
+
+ def tearDown (self):
+ self.tb = None
+
+ def test_pll_refout (self):
+ expected_result = ((1+0j),
+ (1+6.4087357643e-10j),
+ (0.999985277653+0.00542619498447j),
+ (0.999868750572+0.0162021834403j),
+ (0.99948567152+0.0320679470897j),
+ (0.99860727787+0.0527590736747j),
+ (0.996953129768+0.0780025869608j),
+ (0.994203746319+0.107512556016j),
+ (0.990011692047+0.140985429287j),
+ (0.984013140202+0.178095817566j),
+ (0.975838363171+0.218493551016j),
+ (0.965121984482+0.261800557375j),
+ (0.95151245594+0.307610183954j),
+ (0.934681296349+0.355486690998j),
+ (0.914401650429+0.404808044434j),
+ (0.890356600285+0.455263823271j),
+ (0.862329125404+0.506348133087j),
+ (0.830152392387+0.557536482811j),
+ (0.793714106083+0.608290970325j),
+ (0.752960026264+0.658066213131j),
+ (0.707896590233+0.706316053867j),
+ (0.658591926098+0.752500295639j),
+ (0.605175673962+0.796091973782j),
+ (0.547837555408+0.836584687233j),
+ (0.48682525754+0.873499393463j),
+ (0.42244040966+0.906390726566j),
+ (0.355197101831+0.934791445732j),
+ (0.285494059324+0.958380460739j),
+ (0.213591173291+0.976923108101j),
+ (0.139945343137+0.990159213543j),
+ (0.065038472414+0.997882783413j),
+ (-0.0106285437942+0.999943494797j),
+ (-0.0865436866879+0.996248066425j),
+ (-0.162189796567+0.986759603024j),
+ (-0.23705175519+0.971496999264j),
+ (-0.310622543097+0.950533330441j),
+ (-0.38240903616+0.923993110657j),
+ (-0.451937526464+0.89204955101j),
+ (-0.518758952618+0.854920566082j),
+ (-0.582311093807+0.812966048717j),
+ (-0.642372369766+0.76639264822j),
+ (-0.698591887951+0.715520322323j),
+ (-0.750654160976+0.660695314407j),
+ (-0.798280358315+0.602286040783j),
+ (-0.841228663921+0.540679454803j),
+ (-0.87929558754+0.476276367903j),
+ (-0.912315964699+0.409486919641j),
+ (-0.940161883831+0.340728074312j),
+ (-0.962742805481+0.270418733358j),
+ (-0.980004072189+0.198977485299j),
+ (-0.991925954819+0.126818284392j),
+ (-0.99851256609+0.0545223206282j),
+ (-0.999846458435-0.0175215266645j),
+ (-0.996021270752-0.0891158208251j),
+ (-0.987133920193-0.159895718098j),
+ (-0.973306238651-0.2295101583j),
+ (-0.954683184624-0.297624111176j),
+ (-0.931430280209-0.363919824362j),
+ (-0.903732538223-0.428097635508j),
+ (-0.871792256832-0.489875763655j),
+ (-0.835827112198-0.548992812634j),
+ (-0.796068251133-0.605206847191j),
+ (-0.752758979797-0.658296227455j),
+ (-0.706152498722-0.70805978775j),
+ (-0.656641483307-0.754202902317j),
+ (-0.604367733002-0.79670548439j),
+ (-0.549597978592-0.835429251194j),
+ (-0.492602348328-0.870254516602j),
+ (-0.433654457331-0.901079237461j),
+ (-0.373029649258-0.927819430828j),
+ (-0.31100410223-0.950408577919j),
+ (-0.247853919864-0.968797445297j),
+ (-0.183855071664-0.982953369617j),
+ (-0.119282215834-0.992860376835j),
+ (-0.0544078871608-0.998518764973j),
+ (0.0104992967099-0.999944865704j),
+ (0.0749994292855-0.997183561325j),
+ (0.138844624162-0.990314185619j),
+ (0.201967850327-0.979392170906j),
+ (0.264124274254-0.964488625526j),
+ (0.325075358152-0.945688128471j),
+ (0.3845885396-0.92308807373j),
+ (0.442438393831-0.89679890871j),
+ (0.498407125473-0.866943061352j),
+ (0.552284479141-0.833655714989j),
+ (0.603869199753-0.797083437443j),
+ (0.652970373631-0.757383465767j),
+ (0.69940674305-0.714723825455j),
+ (0.743007957935-0.66928255558j),
+ (0.78350687027-0.62138313055j),
+ (0.820889055729-0.571087777615j),
+ (0.855021059513-0.51859331131j),
+ (0.885780930519-0.46410369873j),
+ (0.913058102131-0.407829582691j),
+ (0.936754107475-0.349988251925j),
+ (0.956783294678-0.290801793337j),
+ (0.973072886467-0.230497643352j),
+ (0.985563337803-0.169307261705j),
+ (0.9942086339-0.1074674353j),
+ (0.9989772439-0.0452152714133j))
+
+ sampling_freq = 10e3
+ freq = sampling_freq / 100
+
+ loop_bw = math.pi/100.0
+ maxf = 1
+ minf = -1
+
+ src = gr.sig_source_c (sampling_freq, gr.GR_COS_WAVE, freq, 1.0)
+ pll = gr.pll_refout_cc(loop_bw, maxf, minf)
+ head = gr.head (gr.sizeof_gr_complex, int (freq))
+ dst = gr.vector_sink_c ()
+
+ self.tb.connect (src, pll, head)
+ self.tb.connect (head, dst)
+
+ self.tb.run ()
+ dst_data = dst.data ()
+ self.assertComplexTuplesAlmostEqual (expected_result, dst_data, 4)
+
+if __name__ == '__main__':
+ gr_unittest.run(test_pll_refout, "test_pll_refout.xml")
diff --git a/gnuradio-core/src/python/gnuradio/gr/qa_pn_correlator_cc.py b/gnuradio-core/src/python/gnuradio/gr/qa_pn_correlator_cc.py
new file mode 100755
index 000000000..6a62a6997
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/gr/qa_pn_correlator_cc.py
@@ -0,0 +1,50 @@
+#!/usr/bin/env python
+#
+# Copyright 2007,2010 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr, gr_unittest
+
+class test_pn_correlator_cc(gr_unittest.TestCase):
+
+ def setUp(self):
+ self.tb = gr.top_block ()
+
+ def tearDown(self):
+ self.tb = None
+
+ def test_000_make(self):
+ c = gr.pn_correlator_cc(10)
+
+ def test_001_correlate(self):
+ degree = 10
+ length = 2**degree-1
+ src = gr.glfsr_source_f(degree)
+ head = gr.head(gr.sizeof_float, length*length)
+ f2c = gr.float_to_complex()
+ corr = gr.pn_correlator_cc(degree)
+ dst = gr.vector_sink_c()
+ self.tb.connect(src, head, f2c, corr, dst)
+ self.tb.run()
+ data = dst.data()
+ self.assertEqual(data[-1], (1.0+0j))
+
+if __name__ == '__main__':
+ gr_unittest.run(test_pn_correlator_cc, "test_pn_correlator_cc.xml")
diff --git a/gnuradio-core/src/python/gnuradio/gr/qa_probe_signal.py b/gnuradio-core/src/python/gnuradio/gr/qa_probe_signal.py
new file mode 100644
index 000000000..4e10afdb6
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/gr/qa_probe_signal.py
@@ -0,0 +1,67 @@
+#!/usr/bin/env python
+#
+# Copyright 2012 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+import time
+
+from gnuradio import gr, gr_unittest
+
+class test_probe_signal (gr_unittest.TestCase):
+
+ def setUp (self):
+ self.tb = gr.top_block()
+
+ def tearDown (self):
+ self.tb = None
+
+ def test_001(self):
+
+ value = 12.3
+ repeats = 100
+ src_data = [value] * repeats
+
+ src = gr.vector_source_f(src_data)
+ dst = gr.probe_signal_f()
+
+ self.tb.connect(src, dst)
+ self.tb.run()
+ output = dst.level()
+ self.assertAlmostEqual(value, output, places=6)
+
+ def test_002(self):
+
+ vector_length = 10
+ repeats = 10
+ value = [0.5+i for i in range(0, vector_length)]
+ src_data = value * repeats
+
+ src = gr.vector_source_f(src_data)
+ s2v = gr.stream_to_vector(gr.sizeof_float, vector_length)
+ dst = gr.probe_signal_vf(vector_length)
+
+ self.tb.connect(src, s2v, dst)
+ self.tb.run()
+ output = dst.level()
+ self.assertEqual(len(output), vector_length)
+ self.assertAlmostEqual(value[3], output[3], places=6)
+
+if __name__ == '__main__':
+ gr_unittest.run(test_probe_signal, "test_probe_signal.xml")
diff --git a/gnuradio-core/src/python/gnuradio/gr/qa_python_message_passing.py b/gnuradio-core/src/python/gnuradio/gr/qa_python_message_passing.py
new file mode 100644
index 000000000..06bb96947
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/gr/qa_python_message_passing.py
@@ -0,0 +1,123 @@
+#!/usr/bin/env python
+#
+# Copyright 2013 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr, gr_unittest
+try: import pmt
+except: from gruel import pmt
+import numpy
+import time
+
+# Simple block to generate messages
+class message_generator(gr.sync_block):
+ def __init__(self, msg_list, msg_interval):
+ gr.sync_block.__init__(
+ self,
+ name = "message generator",
+ in_sig = [numpy.float32],
+ out_sig = None
+ )
+ self.msg_list = msg_list
+ self.msg_interval = msg_interval
+ self.msg_ctr = 0
+ self.message_port_register_out(pmt.pmt_intern('out_port'))
+
+
+ def work(self, input_items, output_items):
+ inLen = len(input_items[0])
+ while self.msg_ctr < len(self.msg_list) and \
+ (self.msg_ctr * self.msg_interval) < \
+ (self.nitems_read(0) + inLen):
+ self.message_port_pub(pmt.pmt_intern('out_port'),
+ self.msg_list[self.msg_ctr])
+ self.msg_ctr += 1
+ return inLen
+
+# Simple block to consume messages
+class message_consumer(gr.sync_block):
+ def __init__(self):
+ gr.sync_block.__init__(
+ self,
+ name = "message consumer",
+ in_sig = None,
+ out_sig = None
+ )
+ self.msg_list = []
+ self.message_port_register_in(pmt.pmt_intern('in_port'))
+ self.set_msg_handler(pmt.pmt_intern('in_port'),
+ self.handle_msg)
+
+ def handle_msg(self, msg):
+ # Create a new PMT from long value and put in list
+ self.msg_list.append(pmt.pmt_from_long(pmt.pmt_to_long(msg)))
+
+class test_python_message_passing(gr_unittest.TestCase):
+
+ def setUp(self):
+ self.tb = gr.top_block()
+
+ def tearDown(self):
+ self.tb = None
+
+ def test_000(self):
+ num_msgs = 10
+ msg_interval = 1000
+ msg_list = []
+ for i in range(num_msgs):
+ msg_list.append(pmt.pmt_from_long(i))
+
+ # Create vector source with dummy data to trigger messages
+ src_data = []
+ for i in range(num_msgs*msg_interval):
+ src_data.append(float(i))
+ src = gr.vector_source_f(src_data, False)
+ msg_gen = message_generator(msg_list, msg_interval)
+ msg_cons = message_consumer()
+
+ # Connect vector source to message gen
+ self.tb.connect(src, msg_gen)
+
+ # Connect message generator to message consumer
+ self.tb.msg_connect(msg_gen, 'out_port', msg_cons, 'in_port')
+
+ # Verify that the messgae port query functions work
+ self.assertEqual(pmt.pmt_symbol_to_string(pmt.pmt_vector_ref(
+ msg_gen.message_ports_out(), 0)), 'out_port')
+ self.assertEqual(pmt.pmt_symbol_to_string(pmt.pmt_vector_ref(
+ msg_cons.message_ports_in(), 0)), 'in_port')
+
+ # Run to verify message passing
+ self.tb.start()
+
+ # Wait for all messages to be sent
+ while msg_gen.msg_ctr < num_msgs:
+ time.sleep(0.5)
+ self.tb.stop()
+ self.tb.wait()
+
+ # Verify that the message consumer got all the messages
+ self.assertEqual(num_msgs, len(msg_cons.msg_list))
+ for i in range(num_msgs):
+ self.assertTrue(pmt.pmt_equal(msg_list[i], msg_cons.msg_list[i]))
+
+if __name__ == '__main__':
+ gr_unittest.run(test_python_message_passing,
+ 'test_python_message_passing.xml')
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
index 000000000..cc963d757
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/gr/qa_rational_resampler.py
@@ -0,0 +1,298 @@
+#!/usr/bin/env python
+#
+# Copyright 2005,2006,2007,2010 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr, gr_unittest
+from gnuradio import blks2
+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):
+ tb = gr.top_block()
+ src = gr.vector_source_f(src_data)
+ op = gr.fir_filter_fff(decim, taps)
+ dst = gr.vector_sink_f()
+ tb.connect(src, op, dst)
+ tb.run()
+ result_data = dst.data()
+ tb = None
+ return result_data
+
+def reference_interp_filter(src_data, interp, taps):
+ tb = gr.top_block()
+ src = gr.vector_source_f(src_data)
+ op = gr.interp_fir_filter_fff(interp, taps)
+ dst = gr.vector_sink_f()
+ tb.connect(src, op, dst)
+ tb.run()
+ result_data = dst.data()
+ tb = None
+ return result_data
+
+def reference_interp_dec_filter(src_data, interp, decim, taps):
+ tb = gr.top_block()
+ 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()
+ tb.connect(src, up, dn, dst)
+ tb.run()
+ result_data = dst.data()
+ tb = None
+ return result_data
+
+
+class test_rational_resampler (gr_unittest.TestCase):
+
+ def setUp(self):
+ pass
+
+ def tearDown(self):
+ pass
+
+ #
+ # 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])
+
+ tb = gr.top_block()
+ src = gr.vector_source_f(src_data)
+ op = gr.rational_resampler_base_fff(1, 1, taps)
+ dst = gr.vector_sink_f()
+ tb.connect(src, op)
+ tb.connect(op, dst)
+ tb.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])
+
+ tb = gr.top_block()
+ src = gr.vector_source_f(src_data)
+ op = gr.rational_resampler_base_fff(interpolation, 1, taps)
+ dst = gr.vector_sink_f()
+ tb.connect(src, op)
+ tb.connect(op, dst)
+ tb.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)
+
+ tb = gr.top_block()
+ src = gr.vector_source_f(src_data)
+ op = gr.rational_resampler_base_fff(interpolation, 1, taps)
+ dst = gr.vector_sink_f()
+ tb.connect(src, op)
+ tb.connect(op, dst)
+ tb.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)
+
+ tb = gr.top_block()
+ src = gr.vector_source_f(src_data)
+ op = gr.rational_resampler_base_fff(1, decimation, taps)
+ dst = gr.vector_sink_f()
+ tb.connect(src, op)
+ tb.connect(op, dst)
+ tb.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)
+
+ tb = gr.top_block()
+ src = gr.vector_source_f(src_data)
+ op = gr.rational_resampler_base_fff(1, decim, taps)
+ dst = gr.vector_sink_f()
+ tb.connect(src, op, dst)
+ tb.run()
+ tb = 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)
+
+ tb = gr.top_block()
+ src = gr.vector_source_f(src_data)
+ op = gr.rational_resampler_base_fff(interp, 1, taps)
+ dst = gr.vector_sink_f()
+ tb.connect(src, op, dst)
+ tb.run()
+ tb = 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)
+
+ tb = gr.top_block()
+ src = gr.vector_source_f(src_data)
+ op = gr.rational_resampler_base_fff(interp, decimation, taps)
+ dst = gr.vector_sink_f()
+ tb.connect(src, op)
+ tb.connect(op, dst)
+ tb.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 blks2.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])
+
+ tb = gr.top_block()
+ src = gr.vector_source_f(src_data)
+ op = blks2.rational_resampler_fff(interpolation, 1, taps=taps)
+ dst = gr.vector_sink_f()
+ tb.connect(src, op)
+ tb.connect(op, dst)
+ tb.run()
+ result_data = dst.data()
+ self.assertEqual(expected_result, result_data)
+
+
+if __name__ == '__main__':
+ pass
+ # FIXME: Disabled, see ticket:210
+ # gr_unittest.run(test_rational_resampler, "test_rational_resampler.xml")
+
diff --git a/gnuradio-core/src/python/gnuradio/gr/qa_regenerate.py b/gnuradio-core/src/python/gnuradio/gr/qa_regenerate.py
new file mode 100755
index 000000000..5aca03b77
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/gr/qa_regenerate.py
@@ -0,0 +1,90 @@
+#!/usr/bin/env python
+#
+# Copyright 2007,2010 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr, gr_unittest
+import math
+
+class test_regenerate (gr_unittest.TestCase):
+
+ def setUp (self):
+ self.tb = gr.top_block ()
+
+ def tearDown (self):
+ self.tb = None
+
+ def test_regen1 (self):
+ tb = self.tb
+
+ data = [0, 0, 0,
+ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
+
+ expected_result = (0, 0, 0,
+ 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
+ 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
+
+
+ src = gr.vector_source_b(data, False)
+ regen = gr.regenerate_bb(5, 2)
+ dst = gr.vector_sink_b()
+
+ tb.connect (src, regen)
+ tb.connect (regen, dst)
+ tb.run ()
+
+ dst_data = dst.data ()
+
+ self.assertEqual (expected_result, dst_data)
+
+ def test_regen2 (self):
+ tb = self.tb
+
+ data = 200*[0,]
+ data[9] = 1
+ data[99] = 1
+
+ expected_result = 200*[0,]
+ expected_result[9] = 1
+ expected_result[19] = 1
+ expected_result[29] = 1
+ expected_result[39] = 1
+
+ expected_result[99] = 1
+ expected_result[109] = 1
+ expected_result[119] = 1
+ expected_result[129] = 1
+
+ src = gr.vector_source_b(data, False)
+ regen = gr.regenerate_bb(10, 3)
+ dst = gr.vector_sink_b()
+
+ tb.connect (src, regen)
+ tb.connect (regen, dst)
+ tb.run ()
+
+ dst_data = dst.data ()
+
+ self.assertEqual (tuple(expected_result), dst_data)
+
+
+if __name__ == '__main__':
+ gr_unittest.run(test_regenerate, "test_regenerate.xml")
diff --git a/gnuradio-core/src/python/gnuradio/gr/qa_repeat.py b/gnuradio-core/src/python/gnuradio/gr/qa_repeat.py
new file mode 100755
index 000000000..116f37115
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/gr/qa_repeat.py
@@ -0,0 +1,48 @@
+#!/usr/bin/env python
+#
+# Copyright 2008,2010 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr, gr_unittest
+import math
+
+class test_repeat (gr_unittest.TestCase):
+
+ def setUp (self):
+ self.tb = gr.top_block ()
+
+ def tearDown (self):
+ self.tb = None
+
+ def test_001_float(self):
+ src_data = [n*1.0 for n in range(100)];
+ dst_data = []
+ for n in range(100):
+ dst_data += [1.0*n, 1.0*n, 1.0*n]
+
+ src = gr.vector_source_f(src_data)
+ rpt = gr.repeat(gr.sizeof_float, 3)
+ dst = gr.vector_sink_f()
+ self.tb.connect(src, rpt, dst)
+ self.tb.run()
+ self.assertFloatTuplesAlmostEqual(dst_data, dst.data(), 6)
+
+if __name__ == '__main__':
+ gr_unittest.run(test_repeat, "test_repeat.xml")
diff --git a/gnuradio-core/src/python/gnuradio/gr/qa_scrambler.py b/gnuradio-core/src/python/gnuradio/gr/qa_scrambler.py
new file mode 100755
index 000000000..5fe89bdc7
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/gr/qa_scrambler.py
@@ -0,0 +1,64 @@
+#!/usr/bin/env python
+#
+# Copyright 2008,2010 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr, gr_unittest
+
+class test_scrambler(gr_unittest.TestCase):
+
+ def setUp (self):
+ self.tb = gr.top_block()
+
+ def tearDown(self):
+ self.tb = None
+
+ def test_scrambler_descrambler(self):
+ src_data = (1,)*1000
+ src = gr.vector_source_b(src_data, False)
+ scrambler = gr.scrambler_bb(0x8a, 0x7F, 7) # CCSDS 7-bit scrambler
+ descrambler = gr.descrambler_bb(0x8a, 0x7F, 7)
+ dst = gr.vector_sink_b()
+ self.tb.connect(src, scrambler, descrambler, dst)
+ self.tb.run()
+ self.assertEqual(tuple(src_data[:-8]), dst.data()[8:]) # skip garbage during synchronization
+
+ def test_additive_scrambler(self):
+ src_data = (1,)*1000
+ src = gr.vector_source_b(src_data, False)
+ scrambler = gr.additive_scrambler_bb(0x8a, 0x7f, 7)
+ descrambler = gr.additive_scrambler_bb(0x8a, 0x7f, 7)
+ dst = gr.vector_sink_b()
+ self.tb.connect(src, scrambler, descrambler, dst)
+ self.tb.run()
+ self.assertEqual(src_data, dst.data())
+
+ def test_additive_scrambler_reset(self):
+ src_data = (1,)*1000
+ src = gr.vector_source_b(src_data, False)
+ scrambler = gr.additive_scrambler_bb(0x8a, 0x7f, 7, 100)
+ descrambler = gr.additive_scrambler_bb(0x8a, 0x7f, 7, 100)
+ dst = gr.vector_sink_b()
+ self.tb.connect(src, scrambler, descrambler, dst)
+ self.tb.run()
+ self.assertEqual(src_data, dst.data())
+
+if __name__ == '__main__':
+ gr_unittest.run(test_scrambler, "test_scrambler.xml")
diff --git a/gnuradio-core/src/python/gnuradio/gr/qa_short_to_char.py b/gnuradio-core/src/python/gnuradio/gr/qa_short_to_char.py
new file mode 100755
index 000000000..490b149c7
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/gr/qa_short_to_char.py
@@ -0,0 +1,69 @@
+#!/usr/bin/env python
+#
+# Copyright 2011,2012 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr, gr_unittest
+import ctypes
+
+class test_short_to_char (gr_unittest.TestCase):
+
+ def setUp (self):
+ self.tb = gr.top_block ()
+
+ def tearDown (self):
+ self.tb = None
+
+ def test_001(self):
+
+ src_data = range(0, 32767, 32767/127)
+ src_data = [int(s) for s in src_data]
+ expected_result = range(0, 128)
+ src = gr.vector_source_s(src_data)
+ op = gr.short_to_char()
+ dst = gr.vector_sink_b()
+
+ self.tb.connect(src, op, dst)
+ self.tb.run()
+ result_data = list(dst.data())
+
+ self.assertEqual(expected_result, result_data)
+
+ def test_002(self):
+
+ vlen = 3
+ src_data = range(0, 32400, 32767/127)
+ src_data = [int(s) for s in src_data]
+ expected_result = range(0, 126)
+ src = gr.vector_source_s(src_data)
+ s2v = gr.stream_to_vector(gr.sizeof_short, vlen)
+ op = gr.short_to_char(vlen)
+ v2s = gr.vector_to_stream(gr.sizeof_char, vlen)
+ dst = gr.vector_sink_b()
+
+ self.tb.connect(src, s2v, op, v2s, dst)
+ self.tb.run()
+ result_data = list(dst.data())
+
+ self.assertEqual(expected_result, result_data)
+
+if __name__ == '__main__':
+ gr_unittest.run(test_short_to_char, "test_short_to_char.xml")
+
diff --git a/gnuradio-core/src/python/gnuradio/gr/qa_short_to_float.py b/gnuradio-core/src/python/gnuradio/gr/qa_short_to_float.py
new file mode 100755
index 000000000..130f034ec
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/gr/qa_short_to_float.py
@@ -0,0 +1,70 @@
+#!/usr/bin/env python
+#
+# Copyright 2011,2012 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr, gr_unittest
+import ctypes
+
+class test_short_to_float (gr_unittest.TestCase):
+
+ def setUp (self):
+ self.tb = gr.top_block ()
+
+ def tearDown (self):
+ self.tb = None
+
+ def test_001(self):
+
+ src_data = (0, 1, 2, 3, 4, 5, -1, -2, -3, -4, -5)
+ expected_result = [ 0.0, 1.0, 2.0, 3.0, 4.0, 5.0,
+ -1.0, -2.0, -3.0, -4.0, -5.0]
+
+ src = gr.vector_source_s(src_data)
+ op = gr.short_to_float()
+ dst = gr.vector_sink_f()
+
+ self.tb.connect(src, op, dst)
+ self.tb.run()
+ result_data = list(dst.data())
+
+ self.assertEqual(expected_result, result_data)
+
+ def test_002(self):
+
+ vlen = 3
+ src_data = (0, 1, 2, 3, 4, 5, -1, -2, -3)
+ expected_result = [0.0, 1.0, 2.0, 3.0, 4.0,
+ 5.0, -1.0, -2.0, -3.0]
+ src = gr.vector_source_s(src_data)
+ s2v = gr.stream_to_vector(gr.sizeof_short, vlen)
+ op = gr.short_to_float(vlen)
+ v2s = gr.vector_to_stream(gr.sizeof_float, vlen)
+ dst = gr.vector_sink_f()
+
+ self.tb.connect(src, s2v, op, v2s, dst)
+ self.tb.run()
+ result_data = list(dst.data())
+
+ self.assertEqual(expected_result, result_data)
+
+if __name__ == '__main__':
+ gr_unittest.run(test_short_to_float, "test_short_to_float.xml")
+
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
index 000000000..122b169b7
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/gr/qa_sig_source.py
@@ -0,0 +1,157 @@
+#!/usr/bin/env python
+#
+# Copyright 2004,2007,2010 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr, gr_unittest
+import math
+
+class test_sig_source (gr_unittest.TestCase):
+
+ def setUp (self):
+ self.tb = gr.top_block ()
+
+ def tearDown (self):
+ self.tb = None
+
+ def test_const_f (self):
+ tb = self.tb
+ 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 ()
+ tb.connect (src1, op)
+ tb.connect (op, dst1)
+ tb.run ()
+ dst_data = dst1.data ()
+ self.assertEqual (expected_result, dst_data)
+
+ def test_const_i (self):
+ tb = self.tb
+ 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 ()
+ tb.connect (src1, op)
+ tb.connect (op, dst1)
+ tb.run ()
+ dst_data = dst1.data ()
+ self.assertEqual (expected_result, dst_data)
+
+ def test_sine_f (self):
+ tb = self.tb
+ 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 ()
+ tb.connect (src1, op)
+ tb.connect (op, dst1)
+ tb.run ()
+ dst_data = dst1.data ()
+ self.assertFloatTuplesAlmostEqual (expected_result, dst_data, 5)
+
+ def test_cosine_f (self):
+ tb = self.tb
+ 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 ()
+ tb.connect (src1, op)
+ tb.connect (op, dst1)
+ tb.run ()
+ dst_data = dst1.data ()
+ self.assertFloatTuplesAlmostEqual (expected_result, dst_data, 5)
+
+ def test_sqr_c (self):
+ tb = self.tb #arg6 is a bit before -PI/2
+ expected_result = (1j, 1j, 0, 0, 1, 1, 1+0j, 1+1j, 1j)
+ src1 = gr.sig_source_c (8, gr.GR_SQR_WAVE, 1.0, 1.0)
+ op = gr.head (gr.sizeof_gr_complex, 9)
+ dst1 = gr.vector_sink_c ()
+ tb.connect (src1, op)
+ tb.connect (op, dst1)
+ tb.run ()
+ dst_data = dst1.data ()
+ self.assertEqual (expected_result, dst_data)
+
+ def test_tri_c (self):
+ tb = self.tb
+ expected_result = (1+.5j, .75+.75j, .5+1j, .25+.75j, 0+.5j, .25+.25j, .5+0j, .75+.25j, 1+.5j)
+ src1 = gr.sig_source_c (8, gr.GR_TRI_WAVE, 1.0, 1.0)
+ op = gr.head (gr.sizeof_gr_complex, 9)
+ dst1 = gr.vector_sink_c ()
+ tb.connect (src1, op)
+ tb.connect (op, dst1)
+ tb.run ()
+ dst_data = dst1.data ()
+ self.assertComplexTuplesAlmostEqual (expected_result, dst_data, 5)
+
+ def test_saw_c (self):
+ tb = self.tb
+ expected_result = (.5+.25j, .625+.375j, .75+.5j, .875+.625j, 0+.75j, .125+.875j, .25+1j, .375+.125j, .5+.25j)
+ src1 = gr.sig_source_c (8, gr.GR_SAW_WAVE, 1.0, 1.0)
+ op = gr.head (gr.sizeof_gr_complex, 9)
+ dst1 = gr.vector_sink_c ()
+ tb.connect (src1, op)
+ tb.connect (op, dst1)
+ tb.run ()
+ dst_data = dst1.data ()
+ self.assertComplexTuplesAlmostEqual (expected_result, dst_data, 5)
+
+ def test_sqr_f (self):
+ tb = self.tb
+ expected_result = (0, 0, 0, 0, 1, 1, 1, 1, 0)
+ src1 = gr.sig_source_f (8, gr.GR_SQR_WAVE, 1.0, 1.0)
+ op = gr.head (gr.sizeof_float, 9)
+ dst1 = gr.vector_sink_f ()
+ tb.connect (src1, op)
+ tb.connect (op, dst1)
+ tb.run ()
+ dst_data = dst1.data ()
+ self.assertEqual (expected_result, dst_data)
+
+ def test_tri_f (self):
+ tb = self.tb
+ expected_result = (1, .75, .5, .25, 0, .25, .5, .75, 1)
+ src1 = gr.sig_source_f (8, gr.GR_TRI_WAVE, 1.0, 1.0)
+ op = gr.head (gr.sizeof_float, 9)
+ dst1 = gr.vector_sink_f ()
+ tb.connect (src1, op)
+ tb.connect (op, dst1)
+ tb.run ()
+ dst_data = dst1.data ()
+ self.assertFloatTuplesAlmostEqual (expected_result, dst_data, 5)
+
+ def test_saw_f (self):
+ tb = self.tb
+ expected_result = (.5, .625, .75, .875, 0, .125, .25, .375, .5)
+ src1 = gr.sig_source_f (8, gr.GR_SAW_WAVE, 1.0, 1.0)
+ op = gr.head (gr.sizeof_float, 9)
+ dst1 = gr.vector_sink_f ()
+ tb.connect (src1, op)
+ tb.connect (op, dst1)
+ tb.run ()
+ dst_data = dst1.data ()
+ self.assertFloatTuplesAlmostEqual (expected_result, dst_data, 5)
+
+if __name__ == '__main__':
+ gr_unittest.run(test_sig_source, "test_sig_source.xml")
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
index 000000000..bfe2d8fc8
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/gr/qa_single_pole_iir.py
@@ -0,0 +1,72 @@
+#!/usr/bin/env python
+#
+# Copyright 2005,2007,2010 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr, gr_unittest
+
+class test_single_pole_iir(gr_unittest.TestCase):
+
+ def setUp (self):
+ self.tb = gr.top_block ()
+
+ def tearDown (self):
+ self.tb = 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.tb.connect (src, op, dst)
+ self.tb.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.tb.connect (src, op, dst)
+ self.tb.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.tb.connect (src, s2p, op, p2s, dst)
+ self.tb.run()
+ result_data = dst.data()
+ self.assertFloatTuplesAlmostEqual (expected_result, result_data, 3)
+
+
+if __name__ == '__main__':
+ gr_unittest.run(test_single_pole_iir, "test_single_pole_iir.xml")
+
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
index 000000000..353df1bc0
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/gr/qa_single_pole_iir_cc.py
@@ -0,0 +1,72 @@
+#!/usr/bin/env python
+#
+# Copyright 2005,2006,2007,2010 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr, gr_unittest
+
+class test_single_pole_iir_cc(gr_unittest.TestCase):
+
+ def setUp (self):
+ self.tb = gr.top_block ()
+
+ def tearDown (self):
+ self.tb = 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.tb.connect (src, op, dst)
+ self.tb.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.tb.connect (src, op, dst)
+ self.tb.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.tb.connect (src, s2p, op, p2s, dst)
+ self.tb.run()
+ result_data = dst.data()
+ self.assertComplexTuplesAlmostEqual (expected_result, result_data, 3)
+
+
+if __name__ == '__main__':
+ gr_unittest.run(test_single_pole_iir_cc, "test_single_pole_iir_cc.xml")
+
diff --git a/gnuradio-core/src/python/gnuradio/gr/qa_skiphead.py b/gnuradio-core/src/python/gnuradio/gr/qa_skiphead.py
new file mode 100755
index 000000000..1e730398c
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/gr/qa_skiphead.py
@@ -0,0 +1,102 @@
+#!/usr/bin/env python
+#
+# Copyright 2007,2010 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr, gr_unittest
+
+class test_skiphead (gr_unittest.TestCase):
+
+ def setUp(self):
+ self.tb = gr.top_block ()
+ self.src_data = [int(x) for x in range(65536)]
+
+ def tearDown(self):
+ self.tb = None
+
+ def test_skip_0(self):
+ skip_cnt = 0
+ expected_result = tuple(self.src_data[skip_cnt:])
+ src1 = gr.vector_source_i (self.src_data)
+ op = gr.skiphead (gr.sizeof_int, skip_cnt)
+ dst1 = gr.vector_sink_i ()
+ self.tb.connect (src1, op, dst1)
+ self.tb.run ()
+ dst_data = dst1.data ()
+ self.assertEqual (expected_result, dst_data)
+
+ def test_skip_1(self):
+ skip_cnt = 1
+ expected_result = tuple(self.src_data[skip_cnt:])
+ src1 = gr.vector_source_i (self.src_data)
+ op = gr.skiphead (gr.sizeof_int, skip_cnt)
+ dst1 = gr.vector_sink_i ()
+ self.tb.connect (src1, op, dst1)
+ self.tb.run ()
+ dst_data = dst1.data ()
+ self.assertEqual (expected_result, dst_data)
+
+ def test_skip_1023(self):
+ skip_cnt = 1023
+ expected_result = tuple(self.src_data[skip_cnt:])
+ src1 = gr.vector_source_i (self.src_data)
+ op = gr.skiphead (gr.sizeof_int, skip_cnt)
+ dst1 = gr.vector_sink_i ()
+ self.tb.connect (src1, op, dst1)
+ self.tb.run ()
+ dst_data = dst1.data ()
+ self.assertEqual (expected_result, dst_data)
+
+ def test_skip_6339(self):
+ skip_cnt = 6339
+ expected_result = tuple(self.src_data[skip_cnt:])
+ src1 = gr.vector_source_i (self.src_data)
+ op = gr.skiphead (gr.sizeof_int, skip_cnt)
+ dst1 = gr.vector_sink_i ()
+ self.tb.connect (src1, op, dst1)
+ self.tb.run ()
+ dst_data = dst1.data ()
+ self.assertEqual (expected_result, dst_data)
+
+ def test_skip_12678(self):
+ skip_cnt = 12678
+ expected_result = tuple(self.src_data[skip_cnt:])
+ src1 = gr.vector_source_i (self.src_data)
+ op = gr.skiphead (gr.sizeof_int, skip_cnt)
+ dst1 = gr.vector_sink_i ()
+ self.tb.connect (src1, op, dst1)
+ self.tb.run ()
+ dst_data = dst1.data ()
+ self.assertEqual (expected_result, dst_data)
+
+ def test_skip_all(self):
+ skip_cnt = len(self.src_data)
+ expected_result = tuple(self.src_data[skip_cnt:])
+ src1 = gr.vector_source_i (self.src_data)
+ op = gr.skiphead (gr.sizeof_int, skip_cnt)
+ dst1 = gr.vector_sink_i ()
+ self.tb.connect (src1, op, dst1)
+ self.tb.run ()
+ dst_data = dst1.data ()
+ self.assertEqual (expected_result, dst_data)
+
+
+if __name__ == '__main__':
+ gr_unittest.run(test_skiphead, "test_skiphead.xml")
diff --git a/gnuradio-core/src/python/gnuradio/gr/qa_stream_mux.py b/gnuradio-core/src/python/gnuradio/gr/qa_stream_mux.py
new file mode 100755
index 000000000..779d0b25e
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/gr/qa_stream_mux.py
@@ -0,0 +1,168 @@
+#!/usr/bin/env python
+#
+# Copyright 2004,2005,2007,2010 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr, gr_unittest
+
+class test_stream_mux (gr_unittest.TestCase):
+
+ def setUp (self):
+ self.tb = gr.top_block ()
+
+ def tearDown (self):
+ self.tb = None
+
+ def help_stream_2ff(self, N, stream_sizes):
+ v0 = gr.vector_source_f(N*[1,], False)
+ v1 = gr.vector_source_f(N*[2,], False)
+
+ mux = gr.stream_mux(gr.sizeof_float, stream_sizes)
+
+ dst = gr.vector_sink_f ()
+
+ self.tb.connect (v0, (mux,0))
+ self.tb.connect (v1, (mux,1))
+ self.tb.connect (mux, dst)
+ self.tb.run ()
+
+ return dst.data ()
+
+ def help_stream_ramp_2ff(self, N, stream_sizes):
+ r1 = range(N)
+ r2 = range(N)
+ r2.reverse()
+
+ v0 = gr.vector_source_f(r1, False)
+ v1 = gr.vector_source_f(r2, False)
+
+ mux = gr.stream_mux(gr.sizeof_float, stream_sizes)
+
+ dst = gr.vector_sink_f ()
+
+ self.tb.connect (v0, (mux,0))
+ self.tb.connect (v1, (mux,1))
+ self.tb.connect (mux, dst)
+ self.tb.run ()
+
+ return dst.data ()
+
+ def test_stream_2NN_ff(self):
+ N = 40
+ stream_sizes = [10, 10]
+ result_data = self.help_stream_2ff(N, stream_sizes)
+
+ exp_data = (1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
+ 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0,
+ 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
+ 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0,
+ 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
+ 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0,
+ 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
+ 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0)
+ self.assertEqual (exp_data, result_data)
+
+ def test_stream_ramp_2NN_ff(self):
+ N = 40
+ stream_sizes = [10, 10]
+ result_data = self.help_stream_ramp_2ff(N, stream_sizes)
+
+ exp_data = ( 0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0,
+ 39.0, 38.0, 37.0, 36.0, 35.0, 34.0, 33.0, 32.0, 31.0, 30.0,
+ 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, 17.0, 18.0, 19.0,
+ 29.0, 28.0, 27.0, 26.0, 25.0, 24.0, 23.0, 22.0, 21.0, 20.0,
+ 20.0, 21.0, 22.0, 23.0, 24.0, 25.0, 26.0, 27.0, 28.0, 29.0,
+ 19.0, 18.0, 17.0, 16.0, 15.0, 14.0, 13.0, 12.0, 11.0, 10.0,
+ 30.0, 31.0, 32.0, 33.0, 34.0, 35.0, 36.0, 37.0, 38.0, 39.0,
+ 9.0, 8.0, 7.0, 6.0, 5.0, 4.0, 3.0, 2.0, 1.0, 0.0)
+ self.assertEqual (exp_data, result_data)
+
+ def test_stream_2NM_ff(self):
+ N = 40
+ stream_sizes = [7, 9]
+ self.help_stream_2ff(N, stream_sizes)
+
+ result_data = self.help_stream_2ff(N, stream_sizes)
+
+ exp_data = (1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
+ 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0,
+ 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
+ 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0,
+ 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
+ 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0,
+ 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
+ 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0,
+ 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
+ 2.0, 2.0, 2.0, 2.0)
+
+ self.assertEqual (exp_data, result_data)
+
+
+ def test_stream_2MN_ff(self):
+ N = 37
+ stream_sizes = [7, 9]
+ self.help_stream_2ff(N, stream_sizes)
+
+ result_data = self.help_stream_2ff(N, stream_sizes)
+
+ exp_data = (1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
+ 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0,
+ 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
+ 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0,
+ 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
+ 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0,
+ 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
+ 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0,
+ 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
+ 2.0)
+
+ self.assertEqual (exp_data, result_data)
+
+ def test_stream_2N0_ff(self):
+ N = 30
+ stream_sizes = [7, 0]
+ self.help_stream_2ff(N, stream_sizes)
+
+ result_data = self.help_stream_2ff(N, stream_sizes)
+
+ exp_data = (1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
+ 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
+ 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
+ 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
+ 1.0, 1.0)
+
+ self.assertEqual (exp_data, result_data)
+
+ def test_stream_20N_ff(self):
+ N = 30
+ stream_sizes = [0, 9]
+ self.help_stream_2ff(N, stream_sizes)
+
+ result_data = self.help_stream_2ff(N, stream_sizes)
+
+ exp_data = (2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0,
+ 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0,
+ 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0,
+ 2.0, 2.0, 2.0)
+
+ self.assertEqual (exp_data, result_data)
+
+if __name__ == '__main__':
+ gr_unittest.run(test_stream_mux, "test_stream_mux.xml")
diff --git a/gnuradio-core/src/python/gnuradio/gr/qa_tag_debug.py b/gnuradio-core/src/python/gnuradio/gr/qa_tag_debug.py
new file mode 100755
index 000000000..81babca04
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/gr/qa_tag_debug.py
@@ -0,0 +1,43 @@
+#!/usr/bin/env python
+#
+# Copyright 2012 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr, gr_unittest
+
+class test_tag_debug(gr_unittest.TestCase):
+
+ def setUp(self):
+ self.tb = gr.top_block()
+
+ def tearDown(self):
+ self.tb = None
+
+ def test_001(self):
+ # Just run some data through and make sure it doesn't puke.
+ src_data = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
+ src = gr.vector_source_i(src_data)
+ op = gr.tag_debug(gr.sizeof_int, "tag QA")
+ self.tb.connect(src, op)
+ self.tb.run()
+ x = op.current_tags()
+
+if __name__ == '__main__':
+ gr_unittest.run(test_tag_debug, "test_tag_debug.xml")
diff --git a/gnuradio-core/src/python/gnuradio/gr/qa_tag_utils.py b/gnuradio-core/src/python/gnuradio/gr/qa_tag_utils.py
new file mode 100755
index 000000000..ca1184979
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/gr/qa_tag_utils.py
@@ -0,0 +1,55 @@
+#!/usr/bin/env python
+#
+# Copyright 2007,2010 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr, gr_unittest
+import tag_utils
+
+try:
+ import pmt_swig as pmt
+except ImportError:
+ import pmt
+
+class test_tag_utils (gr_unittest.TestCase):
+
+ def setUp (self):
+ self.tb = gr.top_block ()
+
+
+ def tearDown (self):
+ self.tb = None
+
+ def test_001(self):
+ t = gr.gr_tag_t()
+ t.offset = 10
+ t.key = pmt.pmt_string_to_symbol('key')
+ t.value = pmt.pmt_from_long(23)
+ t.srcid = pmt.pmt_from_bool(False)
+ pt = tag_utils.tag_to_python(t)
+ self.assertEqual(pt.key, 'key')
+ self.assertEqual(pt.value, 23)
+ self.assertEqual(pt.offset, 10)
+
+
+if __name__ == '__main__':
+ print 'hi'
+ gr_unittest.run(test_tag_utils, "test_tag_utils.xml")
+
diff --git a/gnuradio-core/src/python/gnuradio/gr/qa_udp_sink_source.py b/gnuradio-core/src/python/gnuradio/gr/qa_udp_sink_source.py
new file mode 100755
index 000000000..0a719990e
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/gr/qa_udp_sink_source.py
@@ -0,0 +1,99 @@
+#!/usr/bin/env python
+#
+# Copyright 2008,2010 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr, gr_unittest
+from threading import Timer
+
+class test_udp_sink_source(gr_unittest.TestCase):
+
+ def setUp(self):
+ self.tb_snd = gr.top_block()
+ self.tb_rcv = gr.top_block()
+
+ def tearDown(self):
+ self.tb_rcv = None
+ self.tb_snd = None
+
+ def test_001(self):
+ port = 65500
+
+ n_data = 16
+ src_data = [float(x) for x in range(n_data)]
+ expected_result = tuple(src_data)
+ src = gr.vector_source_f(src_data)
+ udp_snd = gr.udp_sink( gr.sizeof_float, 'localhost', port )
+ self.tb_snd.connect( src, udp_snd )
+
+ udp_rcv = gr.udp_source( gr.sizeof_float, 'localhost', port )
+ dst = gr.vector_sink_f()
+ self.tb_rcv.connect( udp_rcv, dst )
+
+ self.tb_rcv.start()
+ self.tb_snd.run()
+ udp_snd.disconnect()
+ self.timeout = False
+ q = Timer(3.0,self.stop_rcv)
+ q.start()
+ self.tb_rcv.wait()
+ q.cancel()
+
+ result_data = dst.data()
+ self.assertEqual(expected_result, result_data)
+ self.assert_(not self.timeout)
+
+ def test_002(self):
+ udp_rcv = gr.udp_source( gr.sizeof_float, '0.0.0.0', 0, eof=False )
+ rcv_port = udp_rcv.get_port()
+
+ udp_snd = gr.udp_sink( gr.sizeof_float, '127.0.0.1', 65500 )
+ udp_snd.connect( 'localhost', rcv_port )
+
+ n_data = 16
+ src_data = [float(x) for x in range(n_data)]
+ expected_result = tuple(src_data)
+ src = gr.vector_source_f(src_data)
+ dst = gr.vector_sink_f()
+
+ self.tb_snd.connect( src, udp_snd )
+ self.tb_rcv.connect( udp_rcv, dst )
+
+ self.tb_rcv.start()
+ self.tb_snd.run()
+ udp_snd.disconnect()
+ self.timeout = False
+ q = Timer(3.0,self.stop_rcv)
+ q.start()
+ self.tb_rcv.wait()
+ q.cancel()
+
+ result_data = dst.data()
+ self.assertEqual(expected_result, result_data)
+ self.assert_(self.timeout) # source ignores EOF?
+
+ def stop_rcv(self):
+ self.timeout = True
+ self.tb_rcv.stop()
+ #print "tb_rcv stopped by Timer"
+
+if __name__ == '__main__':
+ gr_unittest.run(test_udp_sink_source, "test_udp_sink_source.xml")
+
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
index 000000000..bb4e7733d
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/gr/qa_unpack_k_bits.py
@@ -0,0 +1,57 @@
+#!/usr/bin/env python
+#
+# Copyright 2006,2010 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr, gr_unittest
+import random
+
+class test_unpack(gr_unittest.TestCase):
+
+ def setUp(self):
+ self.tb = gr.top_block ()
+
+ def tearDown(self):
+ self.tb = 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.tb.connect(src, op, dst)
+ self.tb.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.tb.connect(src, op, dst)
+ self.tb.run()
+ self.assertEqual(expected_results, dst.data())
+
+
+if __name__ == '__main__':
+ gr_unittest.run(test_unpack, "test_unpack.xml")
+
diff --git a/gnuradio-core/src/python/gnuradio/gr/qa_vector_insert.py b/gnuradio-core/src/python/gnuradio/gr/qa_vector_insert.py
new file mode 100755
index 000000000..acc06dfde
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/gr/qa_vector_insert.py
@@ -0,0 +1,58 @@
+#!/usr/bin/env python
+#
+# Copyright 2012 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr, gr_unittest
+import math
+
+class test_vector_insert(gr_unittest.TestCase):
+
+ def setUp (self):
+ self.tb = gr.top_block ()
+
+ def tearDown (self):
+ self.tb = None
+
+ def test_001(self):
+ src_data = [float(x) for x in range(16)]
+ expected_result = tuple(src_data)
+
+ period = 9177;
+ offset = 0;
+
+ src = gr.null_source(1)
+ head = gr.head(1, 10000000);
+ ins = gr.vector_insert_b([1], period, offset);
+ dst = gr.vector_sink_b()
+
+ self.tb.connect(src, head, ins, dst)
+ self.tb.run()
+ result_data = dst.data()
+
+ for i in range(10000):
+ if(i%period == offset):
+ self.assertEqual(1, result_data[i])
+ else:
+ self.assertEqual(0, result_data[i])
+
+if __name__ == '__main__':
+ gr_unittest.run(test_vector_insert, "test_vector_insert.xml")
+
diff --git a/gnuradio-core/src/python/gnuradio/gr/qa_vector_map.py b/gnuradio-core/src/python/gnuradio/gr/qa_vector_map.py
new file mode 100644
index 000000000..12f4be589
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/gr/qa_vector_map.py
@@ -0,0 +1,105 @@
+#!/usr/bin/env python
+#
+# Copyright 2012 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr, gr_unittest
+import math
+
+class test_vector_map(gr_unittest.TestCase):
+
+ def setUp (self):
+ self.tb = gr.top_block()
+
+ def tearDown (self):
+ self.tb = None
+
+ def test_reversing(self):
+ # Chunk data in blocks of N and reverse the block contents.
+ N = 5
+ src_data = range(0, 20)
+ expected_result = []
+ for i in range(N-1, len(src_data), N):
+ for j in range(0, N):
+ expected_result.append(1.0*(i-j))
+ mapping = [list(reversed([(0, i) for i in range(0, N)]))]
+ src = gr.vector_source_f(src_data, False, N)
+ vmap = gr.vector_map(gr.sizeof_float, (N, ), mapping)
+ dst = gr.vector_sink_f(N)
+ self.tb.connect(src, vmap, dst)
+ self.tb.run()
+ result_data = list(dst.data())
+ self.assertEqual(expected_result, result_data)
+
+ def test_vector_to_streams(self):
+ # Split an input vector into N streams.
+ N = 5
+ M = 20
+ src_data = range(0, M)
+ expected_results = []
+ for n in range(0, N):
+ expected_results.append(range(n, M, N))
+ mapping = [[(0, n)] for n in range(0, N)]
+ src = gr.vector_source_f(src_data, False, N)
+ vmap = gr.vector_map(gr.sizeof_float, (N, ), mapping)
+ dsts = [gr.vector_sink_f(1) for n in range(0, N)]
+ self.tb.connect(src, vmap)
+ for n in range(0, N):
+ self.tb.connect((vmap, n), dsts[n])
+ self.tb.run()
+ for n in range(0, N):
+ result_data = list(dsts[n].data())
+ self.assertEqual(expected_results[n], result_data)
+
+ def test_interleaving(self):
+ # Takes 3 streams (a, b and c)
+ # Outputs 2 streams.
+ # First (d) is interleaving of a and b.
+ # Second (e) is interleaving of a and b and c. c is taken in
+ # chunks of 2 which are reversed.
+ A = (1, 2, 3, 4, 5)
+ B = (11, 12, 13, 14, 15)
+ C = (99, 98, 97, 96, 95, 94, 93, 92, 91, 90)
+ expected_D = (1, 11, 2, 12, 3, 13, 4, 14, 5, 15)
+ expected_E = (1, 11, 98, 99, 2, 12, 96, 97, 3, 13, 94, 95,
+ 4, 14, 92, 93, 5, 15, 90, 91)
+ mapping = [[(0, 0), (1, 0)], # mapping to produce D
+ [(0, 0), (1, 0), (2, 1), (2, 0)], # mapping to produce E
+ ]
+ srcA = gr.vector_source_f(A, False, 1)
+ srcB = gr.vector_source_f(B, False, 1)
+ srcC = gr.vector_source_f(C, False, 2)
+ vmap = gr.vector_map(gr.sizeof_int, (1, 1, 2), mapping)
+ dstD = gr.vector_sink_f(2)
+ dstE = gr.vector_sink_f(4)
+ self.tb.connect(srcA, (vmap, 0))
+ self.tb.connect(srcB, (vmap, 1))
+ self.tb.connect(srcC, (vmap, 2))
+ self.tb.connect((vmap, 0), dstD)
+ self.tb.connect((vmap, 1), dstE)
+ self.tb.run()
+ self.assertEqual(expected_D, dstD.data())
+ self.assertEqual(expected_E, dstE.data())
+
+
+
+if __name__ == '__main__':
+ gr_unittest.run(test_vector_map, "test_vector_map.xml")
+
diff --git a/gnuradio-core/src/python/gnuradio/gr/qa_vector_sink_source.py b/gnuradio-core/src/python/gnuradio/gr/qa_vector_sink_source.py
new file mode 100755
index 000000000..64cbbe72a
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/gr/qa_vector_sink_source.py
@@ -0,0 +1,65 @@
+#!/usr/bin/env python
+#
+# Copyright 2008,2010 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr, gr_unittest
+import math
+
+class test_vector_sink_source(gr_unittest.TestCase):
+
+ def setUp (self):
+ self.tb = gr.top_block ()
+
+ def tearDown (self):
+ self.tb = None
+
+ def test_001(self):
+ src_data = [float(x) for x in range(16)]
+ expected_result = tuple(src_data)
+
+ src = gr.vector_source_f(src_data)
+ dst = gr.vector_sink_f()
+
+ self.tb.connect(src, dst)
+ self.tb.run()
+ result_data = dst.data()
+ self.assertEqual(expected_result, result_data)
+
+ def test_002(self):
+ src_data = [float(x) for x in range(16)]
+ expected_result = tuple(src_data)
+
+ src = gr.vector_source_f(src_data, False, 2)
+ dst = gr.vector_sink_f(2)
+
+ self.tb.connect(src, dst)
+ self.tb.run()
+ result_data = dst.data()
+ self.assertEqual(expected_result, result_data)
+
+ def test_003(self):
+ src_data = [float(x) for x in range(16)]
+ expected_result = tuple(src_data)
+ self.assertRaises(ValueError, lambda : gr.vector_source_f(src_data, False, 3))
+
+if __name__ == '__main__':
+ gr_unittest.run(test_vector_sink_source, "test_vector_sink_source.xml")
+
diff --git a/gnuradio-core/src/python/gnuradio/gr/qa_wavefile.py b/gnuradio-core/src/python/gnuradio/gr/qa_wavefile.py
new file mode 100755
index 000000000..3b9a3eb20
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/gr/qa_wavefile.py
@@ -0,0 +1,69 @@
+#!/usr/bin/env python
+#
+# Copyright 2008,2010 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr, gr_unittest
+
+import os
+from os.path import getsize
+
+g_in_file = os.path.join (os.getenv ("srcdir"), "test_16bit_1chunk.wav")
+
+class test_wavefile(gr_unittest.TestCase):
+
+ def setUp (self):
+ self.tb = gr.top_block ()
+
+ def tearDown (self):
+ self.tb = None
+
+ def test_001_checkwavread (self):
+ wf = gr.wavfile_source(g_in_file)
+ self.assertEqual(wf.sample_rate(), 8000)
+
+ def test_002_checkwavcopy (self):
+ infile = g_in_file
+ outfile = "test_out.wav"
+
+ wf_in = gr.wavfile_source(infile)
+ wf_out = gr.wavfile_sink(outfile,
+ wf_in.channels(),
+ wf_in.sample_rate(),
+ wf_in.bits_per_sample())
+ self.tb.connect(wf_in, wf_out)
+ self.tb.run()
+ wf_out.close()
+
+ self.assertEqual(getsize(infile), getsize(outfile))
+
+ in_f = file(infile, 'rb')
+ out_f = file(outfile, 'rb')
+
+ in_data = in_f.read()
+ out_data = out_f.read()
+ out_f.close()
+ os.remove(outfile)
+
+ self.assertEqual(in_data, out_data)
+
+
+if __name__ == '__main__':
+ gr_unittest.run(test_wavefile, "test_wavefile.xml")
diff --git a/gnuradio-core/src/python/gnuradio/gr/tag_utils.py b/gnuradio-core/src/python/gnuradio/gr/tag_utils.py
new file mode 100644
index 000000000..923718fc9
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/gr/tag_utils.py
@@ -0,0 +1,54 @@
+#
+# Copyright 2003-2012 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+""" Conversion tools between stream tags and Python objects """
+
+try: import pmt
+except: from gruel import pmt
+
+from gnuradio_core import gr_tag_t
+
+class PythonTag(object):
+ " Python container for tags "
+ def __init__(self):
+ self.offset = None
+ self.key = None
+ self.value = None
+ self.srcid = None
+
+def tag_to_python(tag):
+ """ Convert a stream tag to a Python-readable object """
+ newtag = PythonTag()
+ newtag.offset = tag.offset
+ newtag.key = pmt.to_python(tag.key)
+ newtag.value = pmt.to_python(tag.value)
+ newtag.srcid = pmt.to_python(tag.srcid)
+ return newtag
+
+def tag_to_pmt(tag):
+ """ Convert a Python-readable object to a stream tag """
+ newtag = gr_tag_t()
+ newtag.offset = tag.offset
+ newtag.key = pmt.to_python(tag.key)
+ newtag.value = pmt.from_python(tag.value)
+ newtag.srcid = pmt.from_python(tag.srcid)
+ return newtag
+
+
diff --git a/gnuradio-core/src/python/gnuradio/gr/test_16bit_1chunk.wav b/gnuradio-core/src/python/gnuradio/gr/test_16bit_1chunk.wav
new file mode 100644
index 000000000..0fe12a7a1
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/gr/test_16bit_1chunk.wav
Binary files differ
diff --git a/gnuradio-core/src/python/gnuradio/gr/top_block.py b/gnuradio-core/src/python/gnuradio/gr/top_block.py
new file mode 100644
index 000000000..dc1f443aa
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/gr/top_block.py
@@ -0,0 +1,165 @@
+#
+# Copyright 2007 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio_core import top_block_swig, \
+ top_block_wait_unlocked, top_block_run_unlocked
+
+#import gnuradio.gr.gr_threading as _threading
+import gr_threading as _threading
+
+
+#
+# There is no problem that can't be solved with an additional
+# level of indirection...
+#
+# This kludge allows ^C to interrupt top_block.run and top_block.wait
+#
+# The problem that we are working around is that Python only services
+# signals (e.g., KeyboardInterrupt) in its main thread. If the main
+# thread is blocked in our C++ version of wait, even though Python's
+# SIGINT handler fires, and even though there may be other python
+# threads running, no one will know. Thus instead of directly waiting
+# in the thread that calls wait (which is likely to be the Python main
+# thread), we create a separate thread that does the blocking wait,
+# and then use the thread that called wait to do a slow poll of an
+# event queue. That thread, which is executing "wait" below is
+# interruptable, and if it sees a KeyboardInterrupt, executes a stop
+# on the top_block, then goes back to waiting for it to complete.
+# This ensures that the unlocked wait that was in progress (in the
+# _top_block_waiter thread) can complete, release its mutex and back
+# out. If we don't do that, we are never able to clean up, and nasty
+# things occur like leaving the USRP transmitter sending a carrier.
+#
+# See also top_block.wait (below), which uses this class to implement
+# the interruptable wait.
+#
+class _top_block_waiter(_threading.Thread):
+ def __init__(self, tb):
+ _threading.Thread.__init__(self)
+ self.setDaemon(1)
+ self.tb = tb
+ self.event = _threading.Event()
+ self.start()
+
+ def run(self):
+ top_block_wait_unlocked(self.tb)
+ self.event.set()
+
+ def wait(self):
+ try:
+ while not self.event.isSet():
+ self.event.wait(0.100)
+ except KeyboardInterrupt:
+ self.tb.stop()
+ self.wait()
+
+
+#
+# This hack forces a 'has-a' relationship to look like an 'is-a' one.
+#
+# It allows Python classes to subclass this one, while passing through
+# method calls to the C++ class shared pointer from SWIG.
+#
+# It also allows us to intercept method calls if needed.
+#
+# This allows the 'run_locked' methods, which are defined in gr_top_block.i,
+# to release the Python global interpreter lock before calling the actual
+# method in gr_top_block
+#
+class top_block(object):
+ def __init__(self, name="top_block"):
+ self._tb = top_block_swig(name)
+
+ def __getattr__(self, name):
+ if not hasattr(self, "_tb"):
+ raise RuntimeError("top_block: invalid state--did you forget to call gr.top_block.__init__ in a derived class?")
+ return getattr(self._tb, name)
+
+ def start(self, max_noutput_items=100000):
+ self._tb.start(max_noutput_items)
+
+ def stop(self):
+ self._tb.stop()
+
+ def run(self, max_noutput_items=100000):
+ self.start(max_noutput_items)
+ self.wait()
+
+ def wait(self):
+ _top_block_waiter(self._tb).wait()
+
+
+ # FIXME: these are duplicated from hier_block2.py; they should really be implemented
+ # in the original C++ class (gr_hier_block2), then they would all be inherited here
+
+ def connect(self, *points):
+ '''connect requires one or more arguments that can be coerced to endpoints.
+ If more than two arguments are provided, they are connected together successively.
+ '''
+ if len (points) < 1:
+ raise ValueError, ("connect requires at least one endpoint; %d provided." % (len (points),))
+ else:
+ if len(points) == 1:
+ self._tb.primitive_connect(points[0].to_basic_block())
+ else:
+ for i in range (1, len (points)):
+ self._connect(points[i-1], points[i])
+
+ def msg_connect(self, src, srcport, dst, dstport):
+ self.primitive_msg_connect(src.to_basic_block(), srcport, dst.to_basic_block(), dstport);
+
+ def msg_disconnect(self, src, srcport, dst, dstport):
+ self.primitive_msg_disconnect(src.to_basic_block(), srcport, dst.to_basic_block(), dstport);
+
+ def _connect(self, src, dst):
+ (src_block, src_port) = self._coerce_endpoint(src)
+ (dst_block, dst_port) = self._coerce_endpoint(dst)
+ self._tb.primitive_connect(src_block.to_basic_block(), src_port,
+ dst_block.to_basic_block(), dst_port)
+
+ def _coerce_endpoint(self, endp):
+ if hasattr(endp, 'to_basic_block'):
+ return (endp, 0)
+ else:
+ if hasattr(endp, "__getitem__") and len(endp) == 2:
+ return endp # Assume user put (block, port)
+ else:
+ raise ValueError("unable to coerce endpoint")
+
+ def disconnect(self, *points):
+ '''disconnect requires one or more arguments that can be coerced to endpoints.
+ If more than two arguments are provided, they are disconnected successively.
+ '''
+ if len (points) < 1:
+ raise ValueError, ("disconnect requires at least one endpoint; %d provided." % (len (points),))
+ else:
+ if len(points) == 1:
+ self._tb.primitive_disconnect(points[0].to_basic_block())
+ else:
+ for i in range (1, len (points)):
+ self._disconnect(points[i-1], points[i])
+
+ def _disconnect(self, src, dst):
+ (src_block, src_port) = self._coerce_endpoint(src)
+ (dst_block, dst_port) = self._coerce_endpoint(dst)
+ self._tb.primitive_disconnect(src_block.to_basic_block(), src_port,
+ dst_block.to_basic_block(), dst_port)
+
diff --git a/gnuradio-core/src/python/gnuradio/gr_unittest.py b/gnuradio-core/src/python/gnuradio/gr_unittest.py
new file mode 100755
index 000000000..e4510a6eb
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/gr_unittest.py
@@ -0,0 +1,167 @@
+#!/usr/bin/env python
+#
+# Copyright 2004,2010 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+import unittest
+import gr_xmlrunner
+import sys, os, stat
+
+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
+
+def run(PUT, filename=None):
+ '''
+ Runs the unittest on a TestCase and produces an optional XML report
+ PUT: the program under test and should be a gr_unittest.TestCase
+ filename: an optional filename to save the XML report of the tests
+ this will live in ./.unittests/python
+ '''
+
+ # Run this is given a file name
+ if(filename is not None):
+ basepath = "./.unittests"
+ path = basepath + "/python"
+
+ if not os.path.exists(basepath):
+ os.makedirs(basepath, 0750)
+
+ xmlrunner = None
+ # only proceed if .unittests is writable
+ st = os.stat(basepath)[stat.ST_MODE]
+ if(st & stat.S_IWUSR > 0):
+ # Test if path exists; if not, build it
+ if not os.path.exists(path):
+ os.makedirs(path, 0750)
+
+ # Just for safety: make sure we can write here, too
+ st = os.stat(path)[stat.ST_MODE]
+ if(st & stat.S_IWUSR > 0):
+ # Create an XML runner to filename
+ fout = file(path+"/"+filename, "w")
+ xmlrunner = gr_xmlrunner.XMLTestRunner(fout)
+
+ txtrunner = TextTestRunner(verbosity=1)
+
+ # Run the test; runner also creates XML output file
+ # FIXME: make xmlrunner output to screen so we don't have to do run and main
+ suite = TestLoader().loadTestsFromTestCase(PUT)
+
+ # use the xmlrunner if we can write the the directory
+ if(xmlrunner is not None):
+ xmlrunner.run(suite)
+
+ main()
+
+ # This will run and fail make check if problem
+ # but does not output to screen.
+ #main(testRunner = xmlrunner)
+
+ else:
+ # If no filename is given, just run the test
+ main()
+
+
+##############################################################################
+# Executing this module from the command line
+##############################################################################
+
+if __name__ == "__main__":
+ main(module=None)
diff --git a/gnuradio-core/src/python/gnuradio/gr_xmlrunner.py b/gnuradio-core/src/python/gnuradio/gr_xmlrunner.py
new file mode 100644
index 000000000..31298197f
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/gr_xmlrunner.py
@@ -0,0 +1,387 @@
+"""
+XML Test Runner for PyUnit
+"""
+
+# Written by Sebastian Rittau <srittau@jroger.in-berlin.de> and placed in
+# the Public Domain. With contributions by Paolo Borelli and others.
+# Added to GNU Radio Oct. 3, 2010
+
+__version__ = "0.1"
+
+import os.path
+import re
+import sys
+import time
+import traceback
+import unittest
+from xml.sax.saxutils import escape
+
+try:
+ from StringIO import StringIO
+except ImportError:
+ from io import StringIO
+
+
+class _TestInfo(object):
+
+ """Information about a particular test.
+
+ Used by _XMLTestResult.
+
+ """
+
+ def __init__(self, test, time):
+ (self._class, self._method) = test.id().rsplit(".", 1)
+ self._time = time
+ self._error = None
+ self._failure = None
+
+ @staticmethod
+ def create_success(test, time):
+ """Create a _TestInfo instance for a successful test."""
+ return _TestInfo(test, time)
+
+ @staticmethod
+ def create_failure(test, time, failure):
+ """Create a _TestInfo instance for a failed test."""
+ info = _TestInfo(test, time)
+ info._failure = failure
+ return info
+
+ @staticmethod
+ def create_error(test, time, error):
+ """Create a _TestInfo instance for an erroneous test."""
+ info = _TestInfo(test, time)
+ info._error = error
+ return info
+
+ def print_report(self, stream):
+ """Print information about this test case in XML format to the
+ supplied stream.
+
+ """
+ stream.write(' <testcase classname="%(class)s" name="%(method)s" time="%(time).4f">' % \
+ {
+ "class": self._class,
+ "method": self._method,
+ "time": self._time,
+ })
+ if self._failure is not None:
+ self._print_error(stream, 'failure', self._failure)
+ if self._error is not None:
+ self._print_error(stream, 'error', self._error)
+ stream.write('</testcase>\n')
+
+ def _print_error(self, stream, tagname, error):
+ """Print information from a failure or error to the supplied stream."""
+ text = escape(str(error[1]))
+ stream.write('\n')
+ stream.write(' <%s type="%s">%s\n' \
+ % (tagname, _clsname(error[0]), text))
+ tb_stream = StringIO()
+ traceback.print_tb(error[2], None, tb_stream)
+ stream.write(escape(tb_stream.getvalue()))
+ stream.write(' </%s>\n' % tagname)
+ stream.write(' ')
+
+
+def _clsname(cls):
+ return cls.__module__ + "." + cls.__name__
+
+
+class _XMLTestResult(unittest.TestResult):
+
+ """A test result class that stores result as XML.
+
+ Used by XMLTestRunner.
+
+ """
+
+ def __init__(self, classname):
+ unittest.TestResult.__init__(self)
+ self._test_name = classname
+ self._start_time = None
+ self._tests = []
+ self._error = None
+ self._failure = None
+
+ def startTest(self, test):
+ unittest.TestResult.startTest(self, test)
+ self._error = None
+ self._failure = None
+ self._start_time = time.time()
+
+ def stopTest(self, test):
+ time_taken = time.time() - self._start_time
+ unittest.TestResult.stopTest(self, test)
+ if self._error:
+ info = _TestInfo.create_error(test, time_taken, self._error)
+ elif self._failure:
+ info = _TestInfo.create_failure(test, time_taken, self._failure)
+ else:
+ info = _TestInfo.create_success(test, time_taken)
+ self._tests.append(info)
+
+ def addError(self, test, err):
+ unittest.TestResult.addError(self, test, err)
+ self._error = err
+
+ def addFailure(self, test, err):
+ unittest.TestResult.addFailure(self, test, err)
+ self._failure = err
+
+ def print_report(self, stream, time_taken, out, err):
+ """Prints the XML report to the supplied stream.
+
+ The time the tests took to perform as well as the captured standard
+ output and standard error streams must be passed in.a
+
+ """
+ stream.write('<testsuite errors="%(e)d" failures="%(f)d" ' % \
+ { "e": len(self.errors), "f": len(self.failures) })
+ stream.write('name="%(n)s" tests="%(t)d" time="%(time).3f">\n' % \
+ {
+ "n": self._test_name,
+ "t": self.testsRun,
+ "time": time_taken,
+ })
+ for info in self._tests:
+ info.print_report(stream)
+ stream.write(' <system-out><![CDATA[%s]]></system-out>\n' % out)
+ stream.write(' <system-err><![CDATA[%s]]></system-err>\n' % err)
+ stream.write('</testsuite>\n')
+
+
+class XMLTestRunner(object):
+
+ """A test runner that stores results in XML format compatible with JUnit.
+
+ XMLTestRunner(stream=None) -> XML test runner
+
+ The XML file is written to the supplied stream. If stream is None, the
+ results are stored in a file called TEST-<module>.<class>.xml in the
+ current working directory (if not overridden with the path property),
+ where <module> and <class> are the module and class name of the test class.
+
+ """
+
+ def __init__(self, stream=None):
+ self._stream = stream
+ self._path = "."
+
+ def run(self, test):
+ """Run the given test case or test suite."""
+ class_ = test.__class__
+ classname = class_.__module__ + "." + class_.__name__
+ if self._stream == None:
+ filename = "TEST-%s.xml" % classname
+ stream = file(os.path.join(self._path, filename), "w")
+ stream.write('<?xml version="1.0" encoding="utf-8"?>\n')
+ else:
+ stream = self._stream
+
+ result = _XMLTestResult(classname)
+ start_time = time.time()
+
+ fss = _fake_std_streams()
+ fss.__enter__()
+ try:
+ test(result)
+ try:
+ out_s = sys.stdout.getvalue()
+ except AttributeError:
+ out_s = ""
+ try:
+ err_s = sys.stderr.getvalue()
+ except AttributeError:
+ err_s = ""
+ finally:
+ fss.__exit__(None, None, None)
+
+ time_taken = time.time() - start_time
+ result.print_report(stream, time_taken, out_s, err_s)
+ if self._stream is None:
+ stream.close()
+
+ return result
+
+ def _set_path(self, path):
+ self._path = path
+
+ path = property(lambda self: self._path, _set_path, None,
+ """The path where the XML files are stored.
+
+ This property is ignored when the XML file is written to a file
+ stream.""")
+
+
+class _fake_std_streams(object):
+
+ def __enter__(self):
+ self._orig_stdout = sys.stdout
+ self._orig_stderr = sys.stderr
+ #sys.stdout = StringIO()
+ #sys.stderr = StringIO()
+
+ def __exit__(self, exc_type, exc_val, exc_tb):
+ sys.stdout = self._orig_stdout
+ sys.stderr = self._orig_stderr
+
+
+class XMLTestRunnerTest(unittest.TestCase):
+
+ def setUp(self):
+ self._stream = StringIO()
+
+ def _try_test_run(self, test_class, expected):
+
+ """Run the test suite against the supplied test class and compare the
+ XML result against the expected XML string. Fail if the expected
+ string doesn't match the actual string. All time attributes in the
+ expected string should have the value "0.000". All error and failure
+ messages are reduced to "Foobar".
+
+ """
+
+ runner = XMLTestRunner(self._stream)
+ runner.run(unittest.makeSuite(test_class))
+
+ got = self._stream.getvalue()
+ # Replace all time="X.YYY" attributes by time="0.000" to enable a
+ # simple string comparison.
+ got = re.sub(r'time="\d+\.\d+"', 'time="0.000"', got)
+ # Likewise, replace all failure and error messages by a simple "Foobar"
+ # string.
+ got = re.sub(r'(?s)<failure (.*?)>.*?</failure>', r'<failure \1>Foobar</failure>', got)
+ got = re.sub(r'(?s)<error (.*?)>.*?</error>', r'<error \1>Foobar</error>', got)
+ # And finally Python 3 compatibility.
+ got = got.replace('type="builtins.', 'type="exceptions.')
+
+ self.assertEqual(expected, got)
+
+ def test_no_tests(self):
+ """Regression test: Check whether a test run without any tests
+ matches a previous run.
+
+ """
+ class TestTest(unittest.TestCase):
+ pass
+ self._try_test_run(TestTest, """<testsuite errors="0" failures="0" name="unittest.TestSuite" tests="0" time="0.000">
+ <system-out><![CDATA[]]></system-out>
+ <system-err><![CDATA[]]></system-err>
+</testsuite>
+""")
+
+ def test_success(self):
+ """Regression test: Check whether a test run with a successful test
+ matches a previous run.
+
+ """
+ class TestTest(unittest.TestCase):
+ def test_foo(self):
+ pass
+ self._try_test_run(TestTest, """<testsuite errors="0" failures="0" name="unittest.TestSuite" tests="1" time="0.000">
+ <testcase classname="__main__.TestTest" name="test_foo" time="0.000"></testcase>
+ <system-out><![CDATA[]]></system-out>
+ <system-err><![CDATA[]]></system-err>
+</testsuite>
+""")
+
+ def test_failure(self):
+ """Regression test: Check whether a test run with a failing test
+ matches a previous run.
+
+ """
+ class TestTest(unittest.TestCase):
+ def test_foo(self):
+ self.assert_(False)
+ self._try_test_run(TestTest, """<testsuite errors="0" failures="1" name="unittest.TestSuite" tests="1" time="0.000">
+ <testcase classname="__main__.TestTest" name="test_foo" time="0.000">
+ <failure type="exceptions.AssertionError">Foobar</failure>
+ </testcase>
+ <system-out><![CDATA[]]></system-out>
+ <system-err><![CDATA[]]></system-err>
+</testsuite>
+""")
+
+ def test_error(self):
+ """Regression test: Check whether a test run with a erroneous test
+ matches a previous run.
+
+ """
+ class TestTest(unittest.TestCase):
+ def test_foo(self):
+ raise IndexError()
+ self._try_test_run(TestTest, """<testsuite errors="1" failures="0" name="unittest.TestSuite" tests="1" time="0.000">
+ <testcase classname="__main__.TestTest" name="test_foo" time="0.000">
+ <error type="exceptions.IndexError">Foobar</error>
+ </testcase>
+ <system-out><![CDATA[]]></system-out>
+ <system-err><![CDATA[]]></system-err>
+</testsuite>
+""")
+
+ def test_stdout_capture(self):
+ """Regression test: Check whether a test run with output to stdout
+ matches a previous run.
+
+ """
+ class TestTest(unittest.TestCase):
+ def test_foo(self):
+ sys.stdout.write("Test\n")
+ self._try_test_run(TestTest, """<testsuite errors="0" failures="0" name="unittest.TestSuite" tests="1" time="0.000">
+ <testcase classname="__main__.TestTest" name="test_foo" time="0.000"></testcase>
+ <system-out><![CDATA[Test
+]]></system-out>
+ <system-err><![CDATA[]]></system-err>
+</testsuite>
+""")
+
+ def test_stderr_capture(self):
+ """Regression test: Check whether a test run with output to stderr
+ matches a previous run.
+
+ """
+ class TestTest(unittest.TestCase):
+ def test_foo(self):
+ sys.stderr.write("Test\n")
+ self._try_test_run(TestTest, """<testsuite errors="0" failures="0" name="unittest.TestSuite" tests="1" time="0.000">
+ <testcase classname="__main__.TestTest" name="test_foo" time="0.000"></testcase>
+ <system-out><![CDATA[]]></system-out>
+ <system-err><![CDATA[Test
+]]></system-err>
+</testsuite>
+""")
+
+ class NullStream(object):
+ """A file-like object that discards everything written to it."""
+ def write(self, buffer):
+ pass
+
+ def test_unittests_changing_stdout(self):
+ """Check whether the XMLTestRunner recovers gracefully from unit tests
+ that change stdout, but don't change it back properly.
+
+ """
+ class TestTest(unittest.TestCase):
+ def test_foo(self):
+ sys.stdout = XMLTestRunnerTest.NullStream()
+
+ runner = XMLTestRunner(self._stream)
+ runner.run(unittest.makeSuite(TestTest))
+
+ def test_unittests_changing_stderr(self):
+ """Check whether the XMLTestRunner recovers gracefully from unit tests
+ that change stderr, but don't change it back properly.
+
+ """
+ class TestTest(unittest.TestCase):
+ def test_foo(self):
+ sys.stderr = XMLTestRunnerTest.NullStream()
+
+ runner = XMLTestRunner(self._stream)
+ runner.run(unittest.makeSuite(TestTest))
+
+
+if __name__ == "__main__":
+ unittest.main()
diff --git a/gnuradio-core/src/python/gnuradio/gru/CMakeLists.txt b/gnuradio-core/src/python/gnuradio/gru/CMakeLists.txt
new file mode 100644
index 000000000..1c50989d9
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/gru/CMakeLists.txt
@@ -0,0 +1,26 @@
+# Copyright 2010-2011 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+
+include(GrPython)
+
+GR_PYTHON_INSTALL(
+ FILES __init__.py
+ DESTINATION ${GR_PYTHON_DIR}/gnuradio/gru
+ COMPONENT "core_python"
+)
diff --git a/gnuradio-core/src/python/gnuradio/gru/__init__.py b/gnuradio-core/src/python/gnuradio/gru/__init__.py
new file mode 100644
index 000000000..c24439ff5
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/gru/__init__.py
@@ -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 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+import 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/CMakeLists.txt b/gnuradio-core/src/python/gnuradio/gruimpl/CMakeLists.txt
new file mode 100644
index 000000000..7d48f3512
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/gruimpl/CMakeLists.txt
@@ -0,0 +1,38 @@
+# Copyright 2010-2011 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+
+include(GrPython)
+
+GR_PYTHON_INSTALL(FILES
+ __init__.py
+ freqz.py
+ gnuplot_freqz.py
+ hexint.py
+ listmisc.py
+ mathmisc.py
+ lmx2306.py
+ msgq_runner.py
+ os_read_exactly.py
+ sdr_1000.py
+ seq_with_cursor.py
+ socket_stuff.py
+ daemon.py
+ DESTINATION ${GR_PYTHON_DIR}/gnuradio/gruimpl
+ COMPONENT "core_python"
+)
diff --git a/gnuradio-core/src/python/gnuradio/gruimpl/__init__.py b/gnuradio-core/src/python/gnuradio/gruimpl/__init__.py
new file mode 100644
index 000000000..a4917cf64
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/gruimpl/__init__.py
@@ -0,0 +1 @@
+# make this a package
diff --git a/gnuradio-core/src/python/gnuradio/gruimpl/daemon.py b/gnuradio-core/src/python/gnuradio/gruimpl/daemon.py
new file mode 100644
index 000000000..e04702152
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/gruimpl/daemon.py
@@ -0,0 +1,102 @@
+#
+# Copyright 2008 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+import os, sys, signal
+
+# Turn application into a background daemon process.
+#
+# When this function returns:
+#
+# 1) The calling process is disconnected from its controlling terminal
+# and will not exit when the controlling session exits
+# 2) If a pidfile name is provided, it is created and the new pid is
+# written into it.
+# 3) If a logfile name is provided, it is opened and stdout/stderr are
+# redirected to it.
+# 4) The process current working directory is changed to '/' to avoid
+# pinning any filesystem mounts.
+# 5) The process umask is set to 0111.
+#
+# The return value is the new pid.
+#
+# To create GNU Radio applications that operate as daemons, add a call to this
+# function after all initialization but just before calling gr.top_block.run()
+# or .start().
+#
+# Daemonized GNU Radio applications may be stopped by sending them a
+# SIGINT, SIGKILL, or SIGTERM, e.g., using 'kill pid' from the command line.
+#
+# If your application uses gr.top_block.run(), the flowgraph will be stopped
+# and the function will return. You should allow your daemon program to exit
+# at this point.
+#
+# If your application uses gr.top_block.start(), you are responsible for hooking
+# the Python signal handler (see 'signal' module) and calling gr.top_block.stop()
+# on your top block, and otherwise causing your daemon process to exit.
+#
+
+def daemonize(pidfile=None, logfile=None):
+ # fork() into background
+ try:
+ pid = os.fork()
+ except OSError, e:
+ raise Exception, "%s [%d]" % (e.strerror, e.errno)
+
+ if pid == 0: # First child of first fork()
+ # Become session leader of new session
+ os.setsid()
+
+ # fork() into background again
+ try:
+ pid = os.fork()
+ except OSError, e:
+ raise Exception, "%s [%d]" % (e.strerror, e.errno)
+
+ if pid != 0:
+ os._exit(0) # Second child of second fork()
+
+ else: # Second child of first fork()
+ os._exit(0)
+
+ os.umask(0111)
+
+ # Write pid
+ pid = os.getpid()
+ if pidfile is not None:
+ open(pidfile, 'w').write('%d\n'%pid)
+
+ # Redirect streams
+ if logfile is not None:
+ lf = open(logfile, 'a+')
+ sys.stdout = lf
+ sys.stderr = lf
+
+ # Prevent pinning any filesystem mounts
+ os.chdir('/')
+
+ # Tell caller what pid to send future signals to
+ return pid
+
+if __name__ == "__main__":
+ import time
+ daemonize()
+ print "Hello, world, from daemon process."
+ time.sleep(20)
+ print "Goodbye, world, from daemon process."
diff --git a/gnuradio-core/src/python/gnuradio/gruimpl/freqz.py b/gnuradio-core/src/python/gnuradio/gruimpl/freqz.py
new file mode 100644
index 000000000..60dca64a5
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/gruimpl/freqz.py
@@ -0,0 +1,344 @@
+#!/usr/bin/env python
+#
+# Copyright 2005,2007 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+# 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 numpy
+from numpy import *
+Num=numpy
+
+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 = numpy.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 = numpy.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 = numpy.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 = numpy.zeros(key-self.order,self.coeffs.typecode())
+ self.__dict__['coeffs'] = numpy.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
index 000000000..defc47b59
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/gruimpl/gnuplot_freqz.py
@@ -0,0 +1,82 @@
+#!/usr/bin/env python
+#
+# Copyright 2005,2007 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+__all__ = ['gnuplot_freqz']
+
+import tempfile
+import os
+import math
+import numpy
+
+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 * numpy.log10 (numpy.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
index 000000000..0fb5ecde0
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/gruimpl/hexint.py
@@ -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 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+def 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
+
+def hexshort(mask):
+ """
+ Convert unsigned masks into signed shorts.
+
+ This allows us to use hex constants like 0x8000 when talking to
+ our hardware and not get screwed by them getting treated as python
+ longs.
+ """
+ if mask >= 2**15:
+ return int(mask-2**16)
+ return mask
diff --git a/gnuradio-core/src/python/gnuradio/gruimpl/listmisc.py b/gnuradio-core/src/python/gnuradio/gruimpl/listmisc.py
new file mode 100644
index 000000000..9e70eb863
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/gruimpl/listmisc.py
@@ -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 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+def 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
index 000000000..aa4efc3e9
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/gruimpl/lmx2306.py
@@ -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 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, 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
index 000000000..7e6f23a34
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/gruimpl/mathmisc.py
@@ -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 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+import math
+
+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/msgq_runner.py b/gnuradio-core/src/python/gnuradio/gruimpl/msgq_runner.py
new file mode 100644
index 000000000..767a74a71
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/gruimpl/msgq_runner.py
@@ -0,0 +1,82 @@
+#
+# Copyright 2009 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+"""
+Convenience class for dequeuing messages from a gr.msg_queue and
+invoking a callback.
+
+Creates a Python thread that does a blocking read on the supplied
+gr.msg_queue, then invokes callback each time a msg is received.
+
+If the msg type is not 0, then it is treated as a signal to exit
+its loop.
+
+If the callback raises an exception, and the runner was created
+with 'exit_on_error' equal to True, then the runner will store the
+exception and exit its loop, otherwise the exception is ignored.
+
+To get the exception that the callback raised, if any, call
+exit_error() on the object.
+
+To manually stop the runner, call stop() on the object.
+
+To determine if the runner has exited, call exited() on the object.
+"""
+
+from gnuradio import gr
+import gnuradio.gr.gr_threading as _threading
+
+class msgq_runner(_threading.Thread):
+
+ def __init__(self, msgq, callback, exit_on_error=False):
+ _threading.Thread.__init__(self)
+
+ self._msgq = msgq
+ self._callback = callback
+ self._exit_on_error = exit_on_error
+ self._done = False
+ self._exited = False
+ self._exit_error = None
+ self.setDaemon(1)
+ self.start()
+
+ def run(self):
+ while not self._done:
+ msg = self._msgq.delete_head()
+ if msg.type() != 0:
+ self.stop()
+ else:
+ try:
+ self._callback(msg)
+ except Exception, e:
+ if self._exit_on_error:
+ self._exit_error = e
+ self.stop()
+ self._exited = True
+
+ def stop(self):
+ self._done = True
+
+ def exited(self):
+ return self._exited
+
+ def exit_error(self):
+ return self._exit_error
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
index 000000000..40b053770
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/gruimpl/os_read_exactly.py
@@ -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 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+import 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
index 000000000..5192a7155
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/gruimpl/sdr_1000.py
@@ -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 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr
+
+class 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
index 000000000..def3299b6
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/gruimpl/seq_with_cursor.py
@@ -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 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, 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
index 000000000..329fd2ed3
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/gruimpl/socket_stuff.py
@@ -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 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, 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
index 000000000..bbf9ead74
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/optfir.py
@@ -0,0 +1,341 @@
+#
+# Copyright 2004,2005,2009 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+'''
+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, cmath
+from gnuradio import gr
+
+remez = gr.remez
+
+# ----------------------------------------------------------------
+
+## Builds a low pass filter.
+# @param gain Filter gain in the passband (linear)
+# @param Fs Sampling rate (sps)
+# @param freq1 End of pass band (in Hz)
+# @param freq2 Start of stop band (in Hz)
+# @param passband_ripple_db Pass band ripple in dB (should be small, < 1)
+# @param stopband_atten_db Stop band attenuation in dB (should be large, >= 60)
+# @param nextra_taps Extra taps to use in the filter (default=2)
+def low_pass (gain, Fs, freq1, freq2, passband_ripple_db, stopband_atten_db,
+ nextra_taps=2):
+ passband_dev = passband_ripple_to_dev (passband_ripple_db)
+ stopband_dev = stopband_atten_to_dev (stopband_atten_db)
+ desired_ampls = (gain, 0)
+ (n, fo, ao, w) = remezord ([freq1, freq2], desired_ampls,
+ [passband_dev, stopband_dev], Fs)
+ # The remezord typically under-estimates the filter order, so add 2 taps by default
+ taps = gr.remez (n + nextra_taps, fo, ao, w, "bandpass")
+ return taps
+
+## Builds a band pass filter.
+# @param gain Filter gain in the passband (linear)
+# @param Fs Sampling rate (sps)
+# @param freq_sb1 End of stop band (in Hz)
+# @param freq_pb1 Start of pass band (in Hz)
+# @param freq_pb2 End of pass band (in Hz)
+# @param freq_sb2 Start of stop band (in Hz)
+# @param passband_ripple_db Pass band ripple in dB (should be small, < 1)
+# @param stopband_atten_db Stop band attenuation in dB (should be large, >= 60)
+# @param nextra_taps Extra taps to use in the filter (default=2)
+def band_pass (gain, Fs, freq_sb1, freq_pb1, freq_pb2, freq_sb2,
+ passband_ripple_db, stopband_atten_db,
+ nextra_taps=2):
+ passband_dev = passband_ripple_to_dev (passband_ripple_db)
+ stopband_dev = stopband_atten_to_dev (stopband_atten_db)
+ desired_ampls = (0, gain, 0)
+ desired_freqs = [freq_sb1, freq_pb1, freq_pb2, freq_sb2]
+ desired_ripple = [stopband_dev, passband_dev, stopband_dev]
+ (n, fo, ao, w) = remezord (desired_freqs, desired_ampls,
+ desired_ripple, Fs)
+ # The remezord typically under-estimates the filter order, so add 2 taps by default
+ taps = gr.remez (n + nextra_taps, fo, ao, w, "bandpass")
+ return taps
+
+
+## Builds a band pass filter with complex taps by making an LPF and
+# spinning it up to the right center frequency
+# @param gain Filter gain in the passband (linear)
+# @param Fs Sampling rate (sps)
+# @param freq_sb1 End of stop band (in Hz)
+# @param freq_pb1 Start of pass band (in Hz)
+# @param freq_pb2 End of pass band (in Hz)
+# @param freq_sb2 Start of stop band (in Hz)
+# @param passband_ripple_db Pass band ripple in dB (should be small, < 1)
+# @param stopband_atten_db Stop band attenuation in dB (should be large, >= 60)
+# @param nextra_taps Extra taps to use in the filter (default=2)
+def complex_band_pass (gain, Fs, freq_sb1, freq_pb1, freq_pb2, freq_sb2,
+ passband_ripple_db, stopband_atten_db,
+ nextra_taps=2):
+ center_freq = (freq_pb2 + freq_pb1) / 2.0
+ lp_pb = (freq_pb2 - center_freq)/1.0
+ lp_sb = freq_sb2 - center_freq
+ lptaps = low_pass(gain, Fs, lp_pb, lp_sb, passband_ripple_db,
+ stopband_atten_db, nextra_taps)
+ spinner = [cmath.exp(2j*cmath.pi*center_freq/Fs*i) for i in xrange(len(lptaps))]
+ taps = [s*t for s,t in zip(spinner, lptaps)]
+ return taps
+
+
+## Builds a band reject filter
+# spinning it up to the right center frequency
+# @param gain Filter gain in the passband (linear)
+# @param Fs Sampling rate (sps)
+# @param freq_pb1 End of pass band (in Hz)
+# @param freq_sb1 Start of stop band (in Hz)
+# @param freq_sb2 End of stop band (in Hz)
+# @param freq_pb2 Start of pass band (in Hz)
+# @param passband_ripple_db Pass band ripple in dB (should be small, < 1)
+# @param stopband_atten_db Stop band attenuation in dB (should be large, >= 60)
+# @param nextra_taps Extra taps to use in the filter (default=2)
+def band_reject (gain, Fs, freq_pb1, freq_sb1, freq_sb2, freq_pb2,
+ passband_ripple_db, stopband_atten_db,
+ nextra_taps=2):
+ passband_dev = passband_ripple_to_dev (passband_ripple_db)
+ stopband_dev = stopband_atten_to_dev (stopband_atten_db)
+ desired_ampls = (gain, 0, gain)
+ desired_freqs = [freq_pb1, freq_sb1, freq_sb2, freq_pb2]
+ desired_ripple = [passband_dev, stopband_dev, passband_dev]
+ (n, fo, ao, w) = remezord (desired_freqs, desired_ampls,
+ desired_ripple, Fs)
+ # Make sure we use an odd number of taps
+ if((n+nextra_taps)%2 == 1):
+ n += 1
+ # The remezord typically under-estimates the filter order, so add 2 taps by default
+ taps = gr.remez (n + nextra_taps, fo, ao, w, "bandpass")
+ return taps
+
+
+## Builds a high pass filter.
+# @param gain Filter gain in the passband (linear)
+# @param Fs Sampling rate (sps)
+# @param freq1 End of stop band (in Hz)
+# @param freq2 Start of pass band (in Hz)
+# @param passband_ripple_db Pass band ripple in dB (should be small, < 1)
+# @param stopband_atten_db Stop band attenuation in dB (should be large, >= 60)
+# @param nextra_taps Extra taps to use in the filter (default=2)
+def high_pass (gain, Fs, freq1, freq2, passband_ripple_db, stopband_atten_db,
+ nextra_taps=2):
+ passband_dev = passband_ripple_to_dev (passband_ripple_db)
+ stopband_dev = stopband_atten_to_dev (stopband_atten_db)
+ desired_ampls = (0, 1)
+ (n, fo, ao, w) = remezord ([freq1, freq2], desired_ampls,
+ [stopband_dev, passband_dev], Fs)
+ # For a HPF, we need to use an odd number of taps
+ # In gr.remez, ntaps = n+1, so n must be even
+ if((n+nextra_taps)%2 == 1):
+ n += 1
+
+ # The remezord typically under-estimates the filter order, so add 2 taps by default
+ taps = gr.remez (n + nextra_taps, fo, ao, w, "bandpass")
+ return taps
+
+# ----------------------------------------------------------------
+
+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/window.py b/gnuradio-core/src/python/gnuradio/window.py
new file mode 100644
index 000000000..4a1d0c516
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/window.py
@@ -0,0 +1,180 @@
+#
+# Copyright 2004,2005,2009 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+'''
+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 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
+
+# Closure to generate functions to create cos windows
+
+def coswindow(coeffs):
+ def closure(fft_size):
+ window = [0] * fft_size
+ #print list(enumerate(coeffs))
+ for w_index in range(fft_size):
+ for (c_index, coeff) in enumerate(coeffs):
+ window[w_index] += (-1)**c_index * coeff * math.cos(2.0*c_index*math.pi*(w_index+0.5)/(fft_size-1))
+ return window
+ return closure
+
+blackmanharris = coswindow((0.35875,0.48829,0.14128,0.01168))
+nuttall = coswindow((0.3635819,0.4891775,0.1365995,0.0106411)) # Wikipedia calls this Blackman-Nuttall
+nuttall_cfd = coswindow((0.355768,0.487396,0.144232,0.012604)) # Wikipedia calls this Nuttall, continuous first deriv
+flattop = coswindow((1.0,1.93,1.29,0.388,0.032)) # Flat top window, coeffs from Wikipedia
+rectangular = lambda fft_size: [1]*fft_size
diff --git a/gnuradio-core/src/tests/CMakeLists.txt b/gnuradio-core/src/tests/CMakeLists.txt
new file mode 100644
index 000000000..dbd52f05c
--- /dev/null
+++ b/gnuradio-core/src/tests/CMakeLists.txt
@@ -0,0 +1,72 @@
+# Copyright 2010-2012 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+
+########################################################################
+include(GrMiscUtils) #check n def
+GR_CHECK_HDR_N_DEF(sys/resource.h HAVE_SYS_RESOURCE_H)
+
+########################################################################
+# Setup the include and linker paths
+########################################################################
+include_directories(
+ ${GNURADIO_CORE_INCLUDE_DIRS}
+ ${GRUEL_INCLUDE_DIRS}
+ ${Boost_INCLUDE_DIRS}
+ ${CPPUNIT_INCLUDE_DIRS}
+)
+
+link_directories(
+ ${Boost_LIBRARY_DIRS}
+ ${CPPUNIT_LIBRARY_DIRS}
+)
+
+########################################################################
+# Build benchmarks and non-registered tests
+########################################################################
+set(tests_not_run #single source per test
+ benchmark_dotprod_fff.cc
+ benchmark_dotprod_fsf.cc
+ benchmark_dotprod_ccf.cc
+ benchmark_dotprod_fcc.cc
+ benchmark_dotprod_scc.cc
+ benchmark_dotprod_ccc.cc
+ benchmark_nco.cc
+ benchmark_vco.cc
+ test_runtime.cc
+ test_general.cc
+ test_filter.cc
+ #test_atsc.cc
+ test_vmcircbuf.cc
+)
+
+foreach(test_not_run_src ${tests_not_run})
+ get_filename_component(name ${test_not_run_src} NAME_WE)
+ add_executable(${name} ${test_not_run_src})
+ target_link_libraries(${name} test-gnuradio-core)
+endforeach(test_not_run_src)
+
+########################################################################
+# Build the test-all test to end all tests
+# Set the test environment so the build libs will be found under MSVC.
+########################################################################
+include(GrTest)
+list(APPEND GR_TEST_TARGET_DEPS test-gnuradio-core)
+add_executable(gr_core_test_all test_all.cc)
+target_link_libraries(gr_core_test_all test-gnuradio-core)
+GR_ADD_TEST(gr-core-test-all gr_core_test_all)
diff --git a/gnuradio-core/src/tests/benchmark_dotprod b/gnuradio-core/src/tests/benchmark_dotprod
new file mode 100755
index 000000000..82f3b5c3f
--- /dev/null
+++ b/gnuradio-core/src/tests/benchmark_dotprod
@@ -0,0 +1,46 @@
+#!/bin/sh
+#
+# Copyright 2008 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+
+DIR=.
+
+tests="
+benchmark_dotprod_fff
+benchmark_dotprod_ccf
+benchmark_dotprod_ccc
+benchmark_dotprod_fcc
+benchmark_dotprod_scc
+benchmark_dotprod_fsf
+"
+
+echo "uname -a"
+uname -a
+
+if test -e /proc/cpuinfo
+then
+ cat /proc/cpuinfo
+fi
+
+for t in $tests
+do
+ echo
+ echo "$t":
+ $DIR/$t
+done
diff --git a/gnuradio-core/src/tests/benchmark_dotprod_ccc.cc b/gnuradio-core/src/tests/benchmark_dotprod_ccc.cc
new file mode 100644
index 000000000..8ef26a40d
--- /dev/null
+++ b/gnuradio-core/src/tests/benchmark_dotprod_ccc.cc
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include <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]; // not always 16-bit aligned
+ gr_complex *input = new gr_complex[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() / 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() / 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;
+ delete [] input;
+}
+
+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
index 000000000..ed3c49165
--- /dev/null
+++ b/gnuradio-core/src/tests/benchmark_dotprod_ccf.cc
@@ -0,0 +1,153 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include <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]; // not always 16-bit aligned
+ gr_complex *input = new gr_complex[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() / 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() / 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;
+ delete [] input;
+}
+
+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
index 000000000..e9eeee43a
--- /dev/null
+++ b/gnuradio-core/src/tests/benchmark_dotprod_fcc.cc
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include <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_fff.cc b/gnuradio-core/src/tests/benchmark_dotprod_fff.cc
new file mode 100644
index 000000000..56e064506
--- /dev/null
+++ b/gnuradio-core/src/tests/benchmark_dotprod_fff.cc
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include <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_fsf.cc b/gnuradio-core/src/tests/benchmark_dotprod_fsf.cc
new file mode 100644
index 000000000..a254a8eab
--- /dev/null
+++ b/gnuradio-core/src/tests/benchmark_dotprod_fsf.cc
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include <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
index 000000000..9a65bb4c6
--- /dev/null
+++ b/gnuradio-core/src/tests/benchmark_dotprod_scc.cc
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include <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
index 000000000..20d53e410
--- /dev/null
+++ b/gnuradio-core/src/tests/benchmark_nco.cc
@@ -0,0 +1,220 @@
+/* -*- 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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include <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>
+#include <string.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
index 000000000..3a6ade78c
--- /dev/null
+++ b/gnuradio-core/src/tests/benchmark_vco.cc
@@ -0,0 +1,167 @@
+/* -*- 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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include <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>
+#include <string.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(double(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
index 000000000..5bdf5dd1c
--- /dev/null
+++ b/gnuradio-core/src/tests/nco_results
@@ -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
index 000000000..8a1423e9e
--- /dev/null
+++ b/gnuradio-core/src/tests/test_all.cc
@@ -0,0 +1,50 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002,2010,2011 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <cppunit/TextTestRunner.h>
+#include <cppunit/XmlOutputter.h>
+
+#include <gr_unittests.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;
+ std::ofstream xmlfile(get_unittest_path("gnuradio_core_all.xml").c_str());
+ CppUnit::XmlOutputter *xmlout = new CppUnit::XmlOutputter(&runner.result(), xmlfile);
+
+ runner.addTest (qa_runtime::suite ());
+ runner.addTest (qa_general::suite ());
+ runner.addTest (qa_filter::suite ());
+ // runner.addTest (qa_atsc::suite ());
+ runner.setOutputter(xmlout);
+
+ 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
index 000000000..d99bccce5
--- /dev/null
+++ b/gnuradio-core/src/tests/test_atsc.cc
@@ -0,0 +1,42 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002,2011 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <cppunit/TextTestRunner.h>
+#include <cppunit/XmlOutputter.h>
+
+#include <gr_unittests.h>
+#include <qa_atsc.h>
+
+int
+main (int argc, char **argv)
+{
+ CppUnit::TextTestRunner runner;
+ std::ofstream xmlfile(get_unittest_path("gnuradio_core_atsc.xml").c_str());
+ CppUnit::XmlOutputter *xmlout = new CppUnit::XmlOutputter(&runner.result(), xmlfile);
+
+ runner.addTest (qa_atsc::suite ());
+ runner.setOutputter(xmlout);
+
+ 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
index 000000000..b867c727c
--- /dev/null
+++ b/gnuradio-core/src/tests/test_buffers.py
@@ -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 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr, gru
+from gnuradio import 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.top_block):
+
+ def __init__(self, seconds,history,output_multiple):
+ gr.top_block.__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
index 000000000..8b17034c6
--- /dev/null
+++ b/gnuradio-core/src/tests/test_filter.cc
@@ -0,0 +1,42 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002,2010,2011 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <cppunit/TextTestRunner.h>
+#include <cppunit/XmlOutputter.h>
+
+#include <gr_unittests.h>
+#include <qa_filter.h>
+
+int
+main (int argc, char **argv)
+{
+ CppUnit::TextTestRunner runner;
+ std::ofstream xmlfile(get_unittest_path("gnuradio_core_filter.xml").c_str());
+ CppUnit::XmlOutputter *xmlout = new CppUnit::XmlOutputter(&runner.result(), xmlfile);
+
+ runner.addTest (qa_filter::suite ());
+ runner.setOutputter(xmlout);
+
+ 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
index 000000000..32fac1b35
--- /dev/null
+++ b/gnuradio-core/src/tests/test_general.cc
@@ -0,0 +1,42 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002,2010,2011 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <cppunit/TextTestRunner.h>
+#include <cppunit/XmlOutputter.h>
+
+#include <gr_unittests.h>
+#include <qa_general.h>
+
+int
+main (int argc, char **argv)
+{
+ CppUnit::TextTestRunner runner;
+ std::ofstream xmlfile(get_unittest_path("gnuradio_core_general.xml").c_str());
+ CppUnit::XmlOutputter *xmlout = new CppUnit::XmlOutputter(&runner.result(), xmlfile);
+
+ runner.addTest (qa_general::suite ());
+ runner.setOutputter(xmlout);
+
+ 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
index 000000000..bd5378332
--- /dev/null
+++ b/gnuradio-core/src/tests/test_runtime.cc
@@ -0,0 +1,42 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002,2010,2011 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <cppunit/TextTestRunner.h>
+#include <cppunit/XmlOutputter.h>
+
+#include <gr_unittests.h>
+#include <qa_runtime.h>
+
+int
+main (int argc, char **argv)
+{
+ CppUnit::TextTestRunner runner;
+ std::ofstream xmlfile(get_unittest_path("gnuradio_core_runtime.xml").c_str());
+ CppUnit::XmlOutputter *xmlout = new CppUnit::XmlOutputter(&runner.result(), xmlfile);
+
+ runner.addTest (qa_runtime::suite ());
+ runner.setOutputter(xmlout);
+
+ 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
index 000000000..ee24b6d62
--- /dev/null
+++ b/gnuradio-core/src/tests/test_vmcircbuf.cc
@@ -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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <gr_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/cic_comp_taps.m b/gnuradio-core/src/utils/cic_comp_taps.m
new file mode 100644
index 000000000..9ae5cb167
--- /dev/null
+++ b/gnuradio-core/src/utils/cic_comp_taps.m
@@ -0,0 +1,45 @@
+#
+# Copyright 2008 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+# See Altera Application Note AN455
+#
+# R = decimation factor, 8-256
+# Fc = passband (one-sided) cutoff frequency
+# L = number of taps
+
+function taps = cic_comp_taps(R, Fc, L)
+ M = 1; %% Differential delay
+ N = 4; %% Number of stages
+ B = 18; %% Coeffi. Bit-width
+ Fs = 64e6; %% (High) Sampling freq in Hz before decimation
+ Fo = R*Fc/Fs; %% Normalized Cutoff freq; 0<Fo<=0.5/M;
+ p = 2e3; %% Granularity
+ s = 0.25/p; %% Step size
+ fp = [0:s:Fo]; %% Pass band frequency samples
+ fs = (Fo+s):s:0.5; %% Stop band frequency samples
+ f = [fp fs]*2; %% Normalized frequency samples; 0<=f<=1
+ Mp = ones(1,length(fp)); %% Pass band response; Mp(1)=1
+ Mp(2:end) = abs( M*R*sin(pi*fp(2:end)/R)./sin(pi*M*fp(2:end))).^N;
+ Mf = [Mp zeros(1,length(fs))];
+ f(end) = 1;
+ h = fir2(L,f,Mf); %% Filter length L+1
+ taps = h/sum(h); %% Floating point coefficients
+endfunction
diff --git a/gnuradio-core/src/utils/cool.m b/gnuradio-core/src/utils/cool.m
new file mode 100644
index 000000000..f8b8a5cea
--- /dev/null
+++ b/gnuradio-core/src/utils/cool.m
@@ -0,0 +1,50 @@
+%% Copyright (C) 1999,2000 Kai Habel
+%%
+%% This program is free software; you can redistribute it and/or modify
+%% it under the terms of the GNU General Public License as published by
+%% the Free Software Foundation; either version 3 of the License, or
+%% (at your option) any later version.
+%%
+%% This program is distributed in the hope that it will be useful,
+%% but WITHOUT ANY WARRANTY; without even the implied warranty of
+%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+%% GNU General Public License for more details.
+%%
+%% You should have received a copy of the GNU General Public License
+%% along with this program; if not, write to the Free Software
+%% Foundation, Inc., 51 Franklin Street, Boston, MA 02110-1301 USA
+
+%% -*- texinfo -*-
+%% @deftypefn {Function File} {} cool (@var{n})
+%% Create color colormap.
+%% (cyan to magenta)
+%% The argument @var{n} should be a scalar. If it
+%% is omitted, the length of the current colormap or 64 is assumed.
+%% @end deftypefn
+%% @seealso{colormap}
+
+%% Author: Kai Habel <kai.habel@gmx.de>
+
+function map = cool (number)
+
+ if (nargin == 0)
+ number = rows (colormap);
+ elseif (nargin == 1)
+ if (! is_scalar (number))
+ error ("cool: argument must be a scalar");
+ end
+ else
+ usage ("cool (number)");
+ end
+
+ if (number == 1)
+ map = [0, 1, 1];
+ elseif (number > 1)
+ r = (0:number - 1)' ./ (number - 1);
+ g = 1 - r;
+ b = ones (number, 1);
+ map = [r, g, b];
+ else
+ map = [];
+ end
+
diff --git a/gnuradio-core/src/utils/db_width.m b/gnuradio-core/src/utils/db_width.m
new file mode 100644
index 000000000..e9c64cc79
--- /dev/null
+++ b/gnuradio-core/src/utils/db_width.m
@@ -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 3, or (at your option)
+% any later version.
+%
+% GNU Radio is distributed in the hope that it will be useful,
+% but WITHOUT ANY WARRANTY; without even the implied warranty of
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+% GNU General Public License for more details.
+%
+% You should have received a copy of the GNU General Public License
+% along with GNU Radio; see the file COPYING. If not, write to
+% the Free Software Foundation, Inc., 51 Franklin Street,
+% Boston, MA 02110-1301, 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
index 000000000..552791e33
--- /dev/null
+++ b/gnuradio-core/src/utils/filter_tools.m
@@ -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 3, or (at your option)
+% any later version.
+%
+% GNU Radio is distributed in the hope that it will be useful,
+% but WITHOUT ANY WARRANTY; without even the implied warranty of
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+% GNU General Public License for more details.
+%
+% You should have received a copy of the GNU General Public License
+% along with GNU Radio; see the file COPYING. If not, write to
+% the Free Software Foundation, Inc., 51 Franklin Street,
+% Boston, MA 02110-1301, 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
index 000000000..4700467b1
--- /dev/null
+++ b/gnuradio-core/src/utils/is_complex.m
@@ -0,0 +1,24 @@
+#
+# Copyright 2004 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+function p = is_complex (x)
+ p = any (imag (x) != 0);
+endfunction;
diff --git a/gnuradio-core/src/utils/lp_to_bp.m b/gnuradio-core/src/utils/lp_to_bp.m
new file mode 100644
index 000000000..4e73f6cc7
--- /dev/null
+++ b/gnuradio-core/src/utils/lp_to_bp.m
@@ -0,0 +1,27 @@
+#
+# Copyright 2002 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+## transform low pass coefficients into bandpass coefficients
+
+function bp_taps = lp_to_bp (lp_taps, center_freq, sampling_freq)
+ arg = 2 * pi * center_freq / sampling_freq;
+ bp_taps = lp_taps .* exp (j*arg*(0:length(lp_taps)-1)');
+endfunction
diff --git a/gnuradio-core/src/utils/partition-cascaded-decimating-filters.scm b/gnuradio-core/src/utils/partition-cascaded-decimating-filters.scm
new file mode 100644
index 000000000..6ae7877f9
--- /dev/null
+++ b/gnuradio-core/src/utils/partition-cascaded-decimating-filters.scm
@@ -0,0 +1,67 @@
+;; 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)
+
diff --git a/gnuradio-core/src/utils/permute.scm b/gnuradio-core/src/utils/permute.scm
new file mode 100644
index 000000000..23ddfc999
--- /dev/null
+++ b/gnuradio-core/src/utils/permute.scm
@@ -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
index 000000000..8f06aeafe
--- /dev/null
+++ b/gnuradio-core/src/utils/plot_cic_decimator_response.m
@@ -0,0 +1,44 @@
+#
+# Copyright 2004 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+function plot_cic_decimator_response (R, N, M)
+ ## R = decimation rate
+ ## N = number of stages (4)
+ ## M = 1
+ gain = (R*M)^N
+ npoints = 1024;
+ w = 0:1/npoints:1-1/npoints;
+ w = w * 1 * pi;
+ ## w = w * R;
+ length(w);
+ num = sin (w*R*M/2);
+ length (num);
+ ## H = sin (w*R*M/2) ./ sin (w/2)
+ denom = sin(w/2);
+ length (denom);
+ H = (num ./ denom) .^ N;
+ H(1) = gain;
+ H = H ./ gain;
+ plot (R*w/(2*pi), 10 * log10 (H));
+ ## plot (R*w/(2*pi), H);
+endfunction
+
+
diff --git a/gnuradio-core/src/utils/plot_freq_response.m b/gnuradio-core/src/utils/plot_freq_response.m
new file mode 100644
index 000000000..335c51d62
--- /dev/null
+++ b/gnuradio-core/src/utils/plot_freq_response.m
@@ -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 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+function plot_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
index 000000000..10ce7d6e1
--- /dev/null
+++ b/gnuradio-core/src/utils/plot_freq_response_db.m
@@ -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 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+function plot_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
index 000000000..591bd5b94
--- /dev/null
+++ b/gnuradio-core/src/utils/plot_freq_response_phase.m
@@ -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 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+function plot_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
index 000000000..20a2efd4c
--- /dev/null
+++ b/gnuradio-core/src/utils/plotfft.m
@@ -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 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+function 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
index 000000000..c82c540f3
--- /dev/null
+++ b/gnuradio-core/src/utils/plotfftavgk.m
@@ -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 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+function 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
index 000000000..73cee140d
--- /dev/null
+++ b/gnuradio-core/src/utils/plotfftavgk_db.m
@@ -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 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+function 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
index 000000000..df2bf3aca
--- /dev/null
+++ b/gnuradio-core/src/utils/plotfftk.m
@@ -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 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+function 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
index 000000000..b2c85412f
--- /dev/null
+++ b/gnuradio-core/src/utils/plotfftk_db.m
@@ -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 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+function 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
index 000000000..1244d31aa
--- /dev/null
+++ b/gnuradio-core/src/utils/put_markers.m
@@ -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 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+function 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
index 000000000..35fab19b8
--- /dev/null
+++ b/gnuradio-core/src/utils/rainbow.m
@@ -0,0 +1,53 @@
+## Copyright (C) 1999,2000 Kai Habel
+##
+## This program is free software; you can redistribute it and/or modify
+## it under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or
+## (at your option) any later version.
+##
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 51 Franklin Street, Boston, MA 02110-1301 USA
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} rainbow (@var{n})
+## Create color colormap.
+## (red through yellow, green, cyan,blue,magenta to red)
+## The argument @var{n} should be a scalar. If it
+## is omitted, the length of the current colormap or 64 is assumed.
+## @end deftypefn
+## @seealso{colormap}
+
+## Author: Kai Habel <kai.habel@gmx.de>
+
+## 2001-09-13 Paul Kienzle <pkienzle@users.sf.net>
+## * renamed to rainbow for use with tk_octave
+## * remove reference to __current_color_map__
+
+function map = rainbow (number)
+
+ if (nargin == 0)
+ number = length(colormap);
+ elseif (nargin == 1)
+ if (! is_scalar (number))
+ error ("rainbow: argument must be a scalar");
+ endif
+ else
+ usage ("rainbow (number)");
+ endif
+
+ if (number == 1)
+ map = [1, 0, 0];
+ elseif (number > 1)
+ h = linspace (0, 1, number)';
+ map = hsv2rgb ([h, ones(number, 1), ones(number, 1)]);
+ else
+ map = [];
+ endif
+
+endfunction
diff --git a/gnuradio-core/src/utils/read_char_binary.m b/gnuradio-core/src/utils/read_char_binary.m
new file mode 100644
index 000000000..029cea783
--- /dev/null
+++ b/gnuradio-core/src/utils/read_char_binary.m
@@ -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 3, or (at your option)
+% any later version.
+%
+% GNU Radio is distributed in the hope that it will be useful,
+% but WITHOUT ANY WARRANTY; without even the implied warranty of
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+% GNU General Public License for more details.
+%
+% You should have received a copy of the GNU General Public License
+% along with GNU Radio; see the file COPYING. If not, write to
+% the Free Software Foundation, Inc., 51 Franklin Street,
+% Boston, MA 02110-1301, USA.
+%
+
+function v = read_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
index 000000000..eb81f0fa0
--- /dev/null
+++ b/gnuradio-core/src/utils/read_complex_binary.m
@@ -0,0 +1,48 @@
+%
+% Copyright 2001 Free Software Foundation, Inc.
+%
+% This file is part of GNU Radio
+%
+% GNU Radio is free software; you can redistribute it and/or modify
+% it under the terms of the GNU General Public License as published by
+% the Free Software Foundation; either version 3, or (at your option)
+% any later version.
+%
+% GNU Radio is distributed in the hope that it will be useful,
+% but WITHOUT ANY WARRANTY; without even the implied warranty of
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+% GNU General Public License for more details.
+%
+% You should have received a copy of the GNU General Public License
+% along with GNU Radio; see the file COPYING. If not, write to
+% the Free Software Foundation, Inc., 51 Franklin Street,
+% Boston, MA 02110-1301, USA.
+%
+
+function v = read_complex_binary (filename, count)
+
+ %% usage: read_complex_binary (filename, [count])
+ %%
+ %% open filename and return the contents as a column vector,
+ %% treating them as 32 bit complex numbers
+ %%
+
+ m = nargchk (1,2,nargin);
+ if (m)
+ usage (m);
+ end
+
+ if (nargin < 2)
+ count = Inf;
+ end
+
+ f = fopen (filename, 'rb');
+ if (f < 0)
+ v = 0;
+ else
+ t = fread (f, [2, count], 'float');
+ fclose (f);
+ v = t(1,:) + t(2,:)*i;
+ [r, c] = size (v);
+ v = reshape (v, c, r);
+ end
diff --git a/gnuradio-core/src/utils/read_cshort_binary.m b/gnuradio-core/src/utils/read_cshort_binary.m
new file mode 100644
index 000000000..149b6ca88
--- /dev/null
+++ b/gnuradio-core/src/utils/read_cshort_binary.m
@@ -0,0 +1,46 @@
+%
+% Copyright 2001,2008 Free Software Foundation, Inc.
+%
+% This file is part of GNU Radio
+%
+% GNU Radio is free software; you can redistribute it and/or modify
+% it under the terms of the GNU General Public License as published by
+% the Free Software Foundation; either version 3, or (at your option)
+% any later version.
+%
+% GNU Radio is distributed in the hope that it will be useful,
+% but WITHOUT ANY WARRANTY; without even the implied warranty of
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+% GNU General Public License for more details.
+%
+% You should have received a copy of the GNU General Public License
+% along with GNU Radio; see the file COPYING. If not, write to
+% the Free Software Foundation, Inc., 51 Franklin Street,
+% Boston, MA 02110-1301, USA.
+%
+
+function cv = read_cshort_binary (filename, count)
+
+ %% usage: read_cshort_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)
+ cv = 0;
+ else
+ v = fread (f, count, 'short');
+ fclose (f);
+ cv = v(1:2:end)+v(2:2:end)*j;
+ 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
index 000000000..d27d09b9c
--- /dev/null
+++ b/gnuradio-core/src/utils/read_float_binary.m
@@ -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 3, or (at your option)
+% any later version.
+%
+% GNU Radio is distributed in the hope that it will be useful,
+% but WITHOUT ANY WARRANTY; without even the implied warranty of
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+% GNU General Public License for more details.
+%
+% You should have received a copy of the GNU General Public License
+% along with GNU Radio; see the file COPYING. If not, write to
+% the Free Software Foundation, Inc., 51 Franklin Street,
+% Boston, MA 02110-1301, USA.
+%
+
+function v = read_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
index 000000000..cd83bb663
--- /dev/null
+++ b/gnuradio-core/src/utils/read_int_binary.m
@@ -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 3, or (at your option)
+% any later version.
+%
+% GNU Radio is distributed in the hope that it will be useful,
+% but WITHOUT ANY WARRANTY; without even the implied warranty of
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+% GNU General Public License for more details.
+%
+% You should have received a copy of the GNU General Public License
+% along with GNU Radio; see the file COPYING. If not, write to
+% the Free Software Foundation, Inc., 51 Franklin Street,
+% Boston, MA 02110-1301, USA.
+%
+
+function v = read_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
index 000000000..7b42f5e2b
--- /dev/null
+++ b/gnuradio-core/src/utils/read_short_binary.m
@@ -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 3, or (at your option)
+% any later version.
+%
+% GNU Radio is distributed in the hope that it will be useful,
+% but WITHOUT ANY WARRANTY; without even the implied warranty of
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+% GNU General Public License for more details.
+%
+% You should have received a copy of the GNU General Public License
+% along with GNU Radio; see the file COPYING. If not, write to
+% the Free Software Foundation, Inc., 51 Franklin Street,
+% Boston, MA 02110-1301, USA.
+%
+
+function v = read_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
index 000000000..5adb94264
--- /dev/null
+++ b/gnuradio-core/src/utils/read_xambi.m
@@ -0,0 +1,46 @@
+#
+# Copyright 2001,2005 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+function v = read_xambi (filename)
+
+ ## usage: read_xambi (filename)
+ ##
+ ## read binary cross-ambiguity data from radar tools.
+ ## The file has an 8 float header, the first word of which specifies
+ ## the number of doppler bins.
+ ## returns a matrix
+
+ if ((m = nargchk (1,1,nargin)))
+ usage (m);
+ endif;
+
+ f = fopen (filename, "rb");
+ if (f < 0)
+ v = 0;
+ else
+ header = fread(f, 8, "float");
+ ndoppler_bins = header(1)
+ min_doppler = header(2)
+ max_doppler = header(3)
+ v = fread (f, [ndoppler_bins, Inf], "float");
+ fclose (f);
+ endif;
+endfunction;
diff --git a/gnuradio-core/src/utils/runsum.m b/gnuradio-core/src/utils/runsum.m
new file mode 100644
index 000000000..0f530b015
--- /dev/null
+++ b/gnuradio-core/src/utils/runsum.m
@@ -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
index 000000000..12e21f2ac
--- /dev/null
+++ b/gnuradio-core/src/utils/single_pole_iir.m
@@ -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 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+function [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/split_vect.m b/gnuradio-core/src/utils/split_vect.m
new file mode 100644
index 000000000..aef5c5c38
--- /dev/null
+++ b/gnuradio-core/src/utils/split_vect.m
@@ -0,0 +1,15 @@
+% split vector into packets
+
+function y = split_vect(vect,N)
+ Z = floor(max(size(vect))/N);
+ y = [];
+ if(size(vect)(1)>size(vect)(2))
+ v = vect';
+ else
+ v = vect;
+ end
+ for i=1:Z
+ y(i,1:N) = v((i-1)*N+1:i*N);
+ end
+end
+
diff --git a/gnuradio-core/src/utils/write_float_binary.m b/gnuradio-core/src/utils/write_float_binary.m
new file mode 100644
index 000000000..79414878b
--- /dev/null
+++ b/gnuradio-core/src/utils/write_float_binary.m
@@ -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 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+function v = 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
index 000000000..72b3c408e
--- /dev/null
+++ b/gnuradio-core/src/utils/write_short_binary.m
@@ -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 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+function v = 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;